From 45c179c14cd08cc962b8ede02acf39d5f1782cfa Mon Sep 17 00:00:00 2001 From: skarg Date: Sat, 13 Oct 2007 23:40:47 +0000 Subject: [PATCH] Split out bacnet string modules. --- bacnet-stack/lib/Makefile | 4 +- bacnet-stack/lib/makefile.b32 | 4 +- bacnet-stack/ports/at91sam7s/makefile | 4 +- bacnet-stack/ports/atmega168/Makefile | 4 +- .../src/bacdcode/{bitstring.mak => Makefile} | 0 bacnet-stack/src/bacdcode/bitstring.c | 481 ----- bacnet-stack/src/bacdcode/bitstring_test.c | 567 ------ bacnet-stack/src/bacdcode/characterstring.c | 233 +++ .../src/bacdcode/characterstring_test.c | 537 ----- bacnet-stack/src/bacdcode/charstring.c | 637 ------ bacnet-stack/src/bacdcode/main.c | 1775 +---------------- bacnet-stack/src/bacdcode/octetstring.c | 487 ----- bacnet-stack/src/bacdcode/octetstring_test.c | 534 ----- 13 files changed, 251 insertions(+), 5016 deletions(-) rename bacnet-stack/src/bacdcode/{bitstring.mak => Makefile} (100%) create mode 100644 bacnet-stack/src/bacdcode/characterstring.c delete mode 100644 bacnet-stack/src/bacdcode/charstring.c diff --git a/bacnet-stack/lib/Makefile b/bacnet-stack/lib/Makefile index acc9f22a..9af74650 100644 --- a/bacnet-stack/lib/Makefile +++ b/bacnet-stack/lib/Makefile @@ -29,7 +29,9 @@ CORE_SRC = \ $(BACNET_CORE)/npdu.c \ $(BACNET_CORE)/bacdcode/bacdcode.c \ $(BACNET_CORE)/bacdcode/bacint.c \ - $(BACNET_CORE)/bacdcode/bacstr.c \ + $(BACNET_CORE)/bacdcode/bitstring.c \ + $(BACNET_CORE)/bacdcode/octetstring.c \ + $(BACNET_CORE)/bacdcode/characterstring.c \ $(BACNET_CORE)/bacapp.c \ $(BACNET_CORE)/bacprop.c \ $(BACNET_CORE)/bactext.c \ diff --git a/bacnet-stack/lib/makefile.b32 b/bacnet-stack/lib/makefile.b32 index d59161d5..95433bc6 100644 --- a/bacnet-stack/lib/makefile.b32 +++ b/bacnet-stack/lib/makefile.b32 @@ -39,7 +39,9 @@ CORE1_SRC = $(BACNET_CORE)\apdu.c \ $(BACNET_CORE)\npdu.c \ $(BACNET_CORE)\bacdcode\bacdcode.c \ $(BACNET_CORE)\bacdcode\bacint.c \ - $(BACNET_CORE)\bacdcode\bacstr.c \ + $(BACNET_CORE)\bacdcode\bitstring.c \ + $(BACNET_CORE)\bacdcode\octetstring.c \ + $(BACNET_CORE)\bacdcode\characterstring.c \ $(BACNET_CORE)\bacapp.c \ $(BACNET_CORE)\bacprop.c \ $(BACNET_CORE)\bactext.c \ diff --git a/bacnet-stack/ports/at91sam7s/makefile b/bacnet-stack/ports/at91sam7s/makefile index 2de448a8..bd041635 100644 --- a/bacnet-stack/ports/at91sam7s/makefile +++ b/bacnet-stack/ports/at91sam7s/makefile @@ -63,7 +63,9 @@ CORESRC = $(BACNET_CORE)/npdu.c \ $(BACNET_CORE)/apdu.c \ $(BACNET_CORE)/bacdcode/bacint.c \ $(BACNET_CORE)/bacdcode/bacdcode.c \ - $(BACNET_CORE)/bacdcode/bacstr.c \ + $(BACNET_CORE)/bacdcode/bitstring.c \ + $(BACNET_CORE)/bacdcode/octetstring.c \ + $(BACNET_CORE)/bacdcode/characterstring.c \ $(BACNET_CORE)/bacaddr.c \ $(BACNET_CORE)/abort.c \ $(BACNET_CORE)/bacerror.c \ diff --git a/bacnet-stack/ports/atmega168/Makefile b/bacnet-stack/ports/atmega168/Makefile index ddb466a4..4d2b6439 100644 --- a/bacnet-stack/ports/atmega168/Makefile +++ b/bacnet-stack/ports/atmega168/Makefile @@ -38,7 +38,9 @@ CORESRC = \ $(BACNET_CORE)/npdu.c \ $(BACNET_CORE)/bacdcode/bacdcode.c \ $(BACNET_CORE)/bacdcode/bacint.c \ - $(BACNET_CORE)/bacdcode/bacstr.c \ + $(BACNET_CORE)/bacdcode/bitstring.c \ + $(BACNET_CORE)/bacdcode/octetstring.c \ + $(BACNET_CORE)/bacdcode/characterstring.c \ $(BACNET_CORE)/bacapp.c \ $(BACNET_CORE)/bacprop.c \ $(BACNET_CORE)/bactext.c \ diff --git a/bacnet-stack/src/bacdcode/bitstring.mak b/bacnet-stack/src/bacdcode/Makefile similarity index 100% rename from bacnet-stack/src/bacdcode/bitstring.mak rename to bacnet-stack/src/bacdcode/Makefile diff --git a/bacnet-stack/src/bacdcode/bitstring.c b/bacnet-stack/src/bacdcode/bitstring.c index cd142503..d4386ba2 100644 --- a/bacnet-stack/src/bacdcode/bitstring.c +++ b/bacnet-stack/src/bacdcode/bitstring.c @@ -154,484 +154,3 @@ uint8_t bitstring_bits_capacity(BACNET_BIT_STRING * bit_string) else return 0; } - -#define CHARACTER_STRING_CAPACITY (MAX_CHARACTER_STRING_BYTES - 1) -/* returns false if the string exceeds capacity - initialize by using length=0 */ -bool characterstring_init(BACNET_CHARACTER_STRING * char_string, - uint8_t encoding, char *value, size_t length) -{ - bool status = false; /* return value */ - size_t i; /* counter */ - - if (char_string) { - char_string->length = 0; - char_string->encoding = encoding; - /* save a byte at the end for NULL - - note: assumes printable characters */ - if (length <= CHARACTER_STRING_CAPACITY) { - if (value) { - for (i = 0; i < MAX_CHARACTER_STRING_BYTES; i++) { - if (i < length) { - char_string->value[char_string->length] = value[i]; - char_string->length++; - } else - char_string->value[i] = 0; - } - } else { - for (i = 0; i < MAX_CHARACTER_STRING_BYTES; i++) { - char_string->value[i] = 0; - } - } - status = true; - } - } - - return status; -} - -bool characterstring_init_ansi(BACNET_CHARACTER_STRING * char_string, - char *value) -{ - return characterstring_init(char_string, - CHARACTER_ANSI_X34, value, value ? strlen(value) : 0); -} - -bool characterstring_copy(BACNET_CHARACTER_STRING * dest, - BACNET_CHARACTER_STRING * src) -{ - return characterstring_init(dest, - characterstring_encoding(src), - characterstring_value(src), characterstring_length(src)); -} - -bool characterstring_same(BACNET_CHARACTER_STRING * dest, - BACNET_CHARACTER_STRING * src) -{ - size_t i; /* counter */ - bool same_status = false; - - if (src && dest) { - if ((src->length == dest->length) && - (src->encoding == dest->encoding)) { - same_status = true; - for (i = 0; i < src->length; i++) { - if (src->value[i] != dest->value[i]) { - same_status = false; - break; - } - } - } - } else if (src) { - if (src->length == 0) - same_status = true; - } else if (dest) { - if (dest->length == 0) - same_status = true; - } - - return same_status; -} - -bool characterstring_ansi_same(BACNET_CHARACTER_STRING * dest, - const char *src) -{ - size_t i; /* counter */ - bool same_status = false; - - if (src && dest) { - if ((dest->length == strlen(src)) && - (dest->encoding == CHARACTER_ANSI_X34)) { - same_status = true; - for (i = 0; i < dest->length; i++) { - if (src[i] != dest->value[i]) { - same_status = false; - break; - } - } - } - } - /* NULL matches an empty string in our world */ - else if (src) { - if (strlen(src) == 0) - same_status = true; - } else if (dest) { - if (dest->length == 0) - same_status = true; - } - - return same_status; -} - -/* returns false if the string exceeds capacity */ -bool characterstring_append(BACNET_CHARACTER_STRING * char_string, - char *value, size_t length) -{ - size_t i; /* counter */ - bool status = false; /* return value */ - - if (char_string) { - if ((length + char_string->length) <= CHARACTER_STRING_CAPACITY) { - for (i = 0; i < length; i++) { - char_string->value[char_string->length] = value[i]; - char_string->length++; - } - status = true; - } - } - - return status; -} - -/* This function sets a new length without changing the value. - If length exceeds capacity, no modification happens and - function returns false. */ -bool characterstring_truncate(BACNET_CHARACTER_STRING * char_string, - size_t length) -{ - bool status = false; /* return value */ - - if (char_string) { - if (length <= CHARACTER_STRING_CAPACITY) { - char_string->length = length; - status = true; - } - } - - return status; -} - -/* Returns the value. */ -char *characterstring_value(BACNET_CHARACTER_STRING * char_string) -{ - char *value = NULL; - - if (char_string) { - value = char_string->value; - } - - return value; -} - -/* returns the length. */ -size_t characterstring_length(BACNET_CHARACTER_STRING * char_string) -{ - size_t length = 0; - - if (char_string) { - /* FIXME: validate length is within bounds? */ - length = char_string->length; - } - - return length; -} - -size_t characterstring_capacity(BACNET_CHARACTER_STRING * char_string) -{ - size_t length = 0; - - if (char_string) { - length = CHARACTER_STRING_CAPACITY; - } - - return length; -} - -/* returns the encoding. */ -uint8_t characterstring_encoding(BACNET_CHARACTER_STRING * char_string) -{ - uint8_t encoding = 0; - - if (char_string) { - encoding = char_string->encoding; - } - - return encoding; -} - -/* returns false if the string exceeds capacity - initialize by using length=0 */ -bool octetstring_init(BACNET_OCTET_STRING * octet_string, - uint8_t * value, size_t length) -{ - bool status = false; /* return value */ - size_t i; /* counter */ - - if (octet_string) { - octet_string->length = 0; - if (length <= sizeof(octet_string->value)) { - if (value) { - for (i = 0; i < length; i++) { - octet_string->value[octet_string->length] = value[i]; - octet_string->length++; - } - } else { - for (i = 0; i < sizeof(octet_string->value); i++) { - octet_string->value[i] = 0; - } - } - status = true; - } - } - - return status; -} - -bool octetstring_copy(BACNET_OCTET_STRING * dest, - BACNET_OCTET_STRING * src) -{ - return octetstring_init(dest, - octetstring_value(src), octetstring_length(src)); -} - -/* returns false if the string exceeds capacity */ -bool octetstring_append(BACNET_OCTET_STRING * octet_string, - uint8_t * value, size_t length) -{ - size_t i; /* counter */ - bool status = false; /* return value */ - - if (octet_string) { - if ((length + octet_string->length) <= sizeof(octet_string->value)) { - for (i = 0; i < length; i++) { - octet_string->value[octet_string->length] = value[i]; - octet_string->length++; - } - status = true; - } - } - - return status; -} - -/* This function sets a new length without changing the value. - If length exceeds capacity, no modification happens and - function returns false. */ -bool octetstring_truncate(BACNET_OCTET_STRING * octet_string, - size_t length) -{ - bool status = false; /* return value */ - - if (octet_string) { - if (length <= sizeof(octet_string->value)) { - octet_string->length = length; - status = true; - } - } - - return status; -} - -/* returns the length. Returns the value in parameter. */ -uint8_t *octetstring_value(BACNET_OCTET_STRING * octet_string) -{ - uint8_t *value = NULL; - - if (octet_string) { - value = octet_string->value; - } - - return value; -} - -/* returns the length. */ -size_t octetstring_length(BACNET_OCTET_STRING * octet_string) -{ - size_t length = 0; - - if (octet_string) { - /* FIXME: validate length is within bounds? */ - length = octet_string->length; - } - - return length; -} - -/* returns the length. */ -size_t octetstring_capacity(BACNET_OCTET_STRING * octet_string) -{ - size_t length = 0; - - if (octet_string) { - /* FIXME: validate length is within bounds? */ - length = sizeof(octet_string->value); - } - - return length; -} - -#ifdef TEST -#include -#include -#include "ctest.h" - -void testBitString(Test * pTest) -{ - uint8_t bit = 0; - BACNET_BIT_STRING bit_string; - - bitstring_init(&bit_string); - /* verify initialization */ - ct_test(pTest, bitstring_bits_used(&bit_string) == 0); - for (bit = 0; bit < (MAX_BITSTRING_BYTES * 8); bit++) { - ct_test(pTest, bitstring_bit(&bit_string, bit) == false); - } - - /* test for true */ - for (bit = 0; bit < (MAX_BITSTRING_BYTES * 8); bit++) { - bitstring_set_bit(&bit_string, bit, true); - ct_test(pTest, bitstring_bits_used(&bit_string) == (bit + 1)); - ct_test(pTest, bitstring_bit(&bit_string, bit) == true); - } - /* test for false */ - bitstring_init(&bit_string); - for (bit = 0; bit < (MAX_BITSTRING_BYTES * 8); bit++) { - bitstring_set_bit(&bit_string, bit, false); - ct_test(pTest, bitstring_bits_used(&bit_string) == (bit + 1)); - ct_test(pTest, bitstring_bit(&bit_string, bit) == false); - } -} - -void testCharacterString(Test * pTest) -{ - BACNET_CHARACTER_STRING bacnet_string; - char *value = "Joshua,Mary,Anna,Christopher"; - char test_value[MAX_APDU] = "Patricia"; - char test_append_value[MAX_APDU] = " and the Kids"; - char test_append_string[MAX_APDU] = ""; - bool status = false; - size_t length = 0; - size_t test_length = 0; - size_t i = 0; - - /* verify initialization */ - status = - characterstring_init(&bacnet_string, CHARACTER_ANSI_X34, NULL, 0); - ct_test(pTest, status == true); - ct_test(pTest, characterstring_length(&bacnet_string) == 0); - ct_test(pTest, - characterstring_encoding(&bacnet_string) == CHARACTER_ANSI_X34); - /* bounds check */ - status = characterstring_init(&bacnet_string, - CHARACTER_ANSI_X34, - NULL, characterstring_capacity(&bacnet_string) + 1); - ct_test(pTest, status == false); - status = - characterstring_truncate(&bacnet_string, - characterstring_capacity(&bacnet_string) + 1); - ct_test(pTest, status == false); - status = - characterstring_truncate(&bacnet_string, - characterstring_capacity(&bacnet_string)); - ct_test(pTest, status == true); - - test_length = strlen(test_value); - status = characterstring_init(&bacnet_string, - CHARACTER_ANSI_X34, &test_value[0], test_length); - ct_test(pTest, status == true); - value = characterstring_value(&bacnet_string); - length = characterstring_length(&bacnet_string); - ct_test(pTest, length == test_length); - for (i = 0; i < test_length; i++) { - ct_test(pTest, value[i] == test_value[i]); - } - test_length = strlen(test_append_value); - status = characterstring_append(&bacnet_string, - &test_append_value[0], test_length); - strcat(test_append_string, test_value); - strcat(test_append_string, test_append_value); - test_length = strlen(test_append_string); - ct_test(pTest, status == true); - length = characterstring_length(&bacnet_string); - value = characterstring_value(&bacnet_string); - ct_test(pTest, length == test_length); - for (i = 0; i < test_length; i++) { - ct_test(pTest, value[i] == test_append_string[i]); - } -} - -void testOctetString(Test * pTest) -{ - BACNET_OCTET_STRING bacnet_string; - uint8_t *value = NULL; - uint8_t test_value[MAX_APDU] = "Patricia"; - uint8_t test_append_value[MAX_APDU] = " and the Kids"; - uint8_t test_append_string[MAX_APDU] = ""; - bool status = false; - size_t length = 0; - size_t test_length = 0; - size_t i = 0; - - /* verify initialization */ - status = octetstring_init(&bacnet_string, NULL, 0); - ct_test(pTest, status == true); - ct_test(pTest, octetstring_length(&bacnet_string) == 0); - value = octetstring_value(&bacnet_string); - for (i = 0; i < octetstring_capacity(&bacnet_string); i++) { - ct_test(pTest, value[i] == 0); - } - /* bounds check */ - status = octetstring_init(&bacnet_string, NULL, - octetstring_capacity(&bacnet_string) + 1); - ct_test(pTest, status == false); - status = octetstring_init(&bacnet_string, NULL, - octetstring_capacity(&bacnet_string)); - ct_test(pTest, status == true); - status = - octetstring_truncate(&bacnet_string, - octetstring_capacity(&bacnet_string) + 1); - ct_test(pTest, status == false); - status = - octetstring_truncate(&bacnet_string, - octetstring_capacity(&bacnet_string)); - ct_test(pTest, status == true); - - test_length = strlen((char *) test_value); - status = octetstring_init(&bacnet_string, &test_value[0], test_length); - ct_test(pTest, status == true); - length = octetstring_length(&bacnet_string); - value = octetstring_value(&bacnet_string); - ct_test(pTest, length == test_length); - for (i = 0; i < test_length; i++) { - ct_test(pTest, value[i] == test_value[i]); - } - - test_length = strlen((char *) test_append_value); - status = octetstring_append(&bacnet_string, - &test_append_value[0], test_length); - strcat((char *) test_append_string, (char *) test_value); - strcat((char *) test_append_string, (char *) test_append_value); - test_length = strlen((char *) test_append_string); - ct_test(pTest, status == true); - length = octetstring_length(&bacnet_string); - value = octetstring_value(&bacnet_string); - ct_test(pTest, length == test_length); - for (i = 0; i < test_length; i++) { - ct_test(pTest, value[i] == test_append_string[i]); - } -} - -#ifdef TEST_BACSTR -int main(void) -{ - Test *pTest; - bool rc; - - pTest = ct_create("BACnet Strings", NULL); - /* individual tests */ - rc = ct_addTestFunction(pTest, testBitString); - assert(rc); - rc = ct_addTestFunction(pTest, testCharacterString); - assert(rc); - rc = ct_addTestFunction(pTest, testOctetString); - assert(rc); - /* configure output */ - ct_setStream(pTest, stdout); - ct_run(pTest); - (void) ct_report(pTest); - ct_destroy(pTest); - - return 0; -} -#endif /* TEST_BACSTR */ -#endif /* TEST */ diff --git a/bacnet-stack/src/bacdcode/bitstring_test.c b/bacnet-stack/src/bacdcode/bitstring_test.c index cd142503..0363163d 100644 --- a/bacnet-stack/src/bacdcode/bitstring_test.c +++ b/bacnet-stack/src/bacdcode/bitstring_test.c @@ -38,429 +38,6 @@ #include "bacstr.h" #include "bits.h" -void bitstring_init(BACNET_BIT_STRING * bit_string) -{ - int i; - - bit_string->bits_used = 0; - for (i = 0; i < MAX_BITSTRING_BYTES; i++) { - bit_string->value[i] = 0; - } -} - -void bitstring_set_bit(BACNET_BIT_STRING * bit_string, uint8_t bit, - bool value) -{ - uint8_t byte_number = bit / 8; - uint8_t bit_mask = 1; - - if (byte_number < MAX_BITSTRING_BYTES) { - /* set max bits used */ - if (bit_string->bits_used < (bit + 1)) - bit_string->bits_used = bit + 1; - bit_mask = bit_mask << (bit - (byte_number * 8)); - if (value) - bit_string->value[byte_number] |= bit_mask; - else - bit_string->value[byte_number] &= (~(bit_mask)); - } -} - -bool bitstring_bit(BACNET_BIT_STRING * bit_string, uint8_t bit) -{ - bool value = false; - uint8_t byte_number = bit / 8; - uint8_t bit_mask = 1; - - if (bit < (MAX_BITSTRING_BYTES * 8)) { - bit_mask = bit_mask << (bit - (byte_number * 8)); - if (bit_string->value[byte_number] & bit_mask) - value = true; - } - - return value; -} - -uint8_t bitstring_bits_used(BACNET_BIT_STRING * bit_string) -{ - return bit_string->bits_used; -} - -/* returns the number of bytes that a bit string is using */ -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; -} - -uint8_t bitstring_octet(BACNET_BIT_STRING * bit_string, uint8_t index) -{ - uint8_t octet = 0; - - if (bit_string) { - if (index < MAX_BITSTRING_BYTES) { - octet = bit_string->value[index]; - } - } - - return octet; -} - -bool bitstring_set_octet(BACNET_BIT_STRING * bit_string, - uint8_t index, uint8_t octet) -{ - bool status = false; - - if (bit_string) { - if (index < MAX_BITSTRING_BYTES) { - bit_string->value[index] = octet; - status = true; - } - } - - return status; -} - -bool bitstring_set_bits_used(BACNET_BIT_STRING * bit_string, - uint8_t bytes_used, uint8_t unused_bits) -{ - bool status = false; - - if (bit_string) { - /* FIXME: check that bytes_used is at least one? */ - bit_string->bits_used = bytes_used * 8; - bit_string->bits_used -= unused_bits; - status = true; - } - - return status; -} - -uint8_t bitstring_bits_capacity(BACNET_BIT_STRING * bit_string) -{ - if (bit_string) - return (sizeof(bit_string->value) * 8); - else - return 0; -} - -#define CHARACTER_STRING_CAPACITY (MAX_CHARACTER_STRING_BYTES - 1) -/* returns false if the string exceeds capacity - initialize by using length=0 */ -bool characterstring_init(BACNET_CHARACTER_STRING * char_string, - uint8_t encoding, char *value, size_t length) -{ - bool status = false; /* return value */ - size_t i; /* counter */ - - if (char_string) { - char_string->length = 0; - char_string->encoding = encoding; - /* save a byte at the end for NULL - - note: assumes printable characters */ - if (length <= CHARACTER_STRING_CAPACITY) { - if (value) { - for (i = 0; i < MAX_CHARACTER_STRING_BYTES; i++) { - if (i < length) { - char_string->value[char_string->length] = value[i]; - char_string->length++; - } else - char_string->value[i] = 0; - } - } else { - for (i = 0; i < MAX_CHARACTER_STRING_BYTES; i++) { - char_string->value[i] = 0; - } - } - status = true; - } - } - - return status; -} - -bool characterstring_init_ansi(BACNET_CHARACTER_STRING * char_string, - char *value) -{ - return characterstring_init(char_string, - CHARACTER_ANSI_X34, value, value ? strlen(value) : 0); -} - -bool characterstring_copy(BACNET_CHARACTER_STRING * dest, - BACNET_CHARACTER_STRING * src) -{ - return characterstring_init(dest, - characterstring_encoding(src), - characterstring_value(src), characterstring_length(src)); -} - -bool characterstring_same(BACNET_CHARACTER_STRING * dest, - BACNET_CHARACTER_STRING * src) -{ - size_t i; /* counter */ - bool same_status = false; - - if (src && dest) { - if ((src->length == dest->length) && - (src->encoding == dest->encoding)) { - same_status = true; - for (i = 0; i < src->length; i++) { - if (src->value[i] != dest->value[i]) { - same_status = false; - break; - } - } - } - } else if (src) { - if (src->length == 0) - same_status = true; - } else if (dest) { - if (dest->length == 0) - same_status = true; - } - - return same_status; -} - -bool characterstring_ansi_same(BACNET_CHARACTER_STRING * dest, - const char *src) -{ - size_t i; /* counter */ - bool same_status = false; - - if (src && dest) { - if ((dest->length == strlen(src)) && - (dest->encoding == CHARACTER_ANSI_X34)) { - same_status = true; - for (i = 0; i < dest->length; i++) { - if (src[i] != dest->value[i]) { - same_status = false; - break; - } - } - } - } - /* NULL matches an empty string in our world */ - else if (src) { - if (strlen(src) == 0) - same_status = true; - } else if (dest) { - if (dest->length == 0) - same_status = true; - } - - return same_status; -} - -/* returns false if the string exceeds capacity */ -bool characterstring_append(BACNET_CHARACTER_STRING * char_string, - char *value, size_t length) -{ - size_t i; /* counter */ - bool status = false; /* return value */ - - if (char_string) { - if ((length + char_string->length) <= CHARACTER_STRING_CAPACITY) { - for (i = 0; i < length; i++) { - char_string->value[char_string->length] = value[i]; - char_string->length++; - } - status = true; - } - } - - return status; -} - -/* This function sets a new length without changing the value. - If length exceeds capacity, no modification happens and - function returns false. */ -bool characterstring_truncate(BACNET_CHARACTER_STRING * char_string, - size_t length) -{ - bool status = false; /* return value */ - - if (char_string) { - if (length <= CHARACTER_STRING_CAPACITY) { - char_string->length = length; - status = true; - } - } - - return status; -} - -/* Returns the value. */ -char *characterstring_value(BACNET_CHARACTER_STRING * char_string) -{ - char *value = NULL; - - if (char_string) { - value = char_string->value; - } - - return value; -} - -/* returns the length. */ -size_t characterstring_length(BACNET_CHARACTER_STRING * char_string) -{ - size_t length = 0; - - if (char_string) { - /* FIXME: validate length is within bounds? */ - length = char_string->length; - } - - return length; -} - -size_t characterstring_capacity(BACNET_CHARACTER_STRING * char_string) -{ - size_t length = 0; - - if (char_string) { - length = CHARACTER_STRING_CAPACITY; - } - - return length; -} - -/* returns the encoding. */ -uint8_t characterstring_encoding(BACNET_CHARACTER_STRING * char_string) -{ - uint8_t encoding = 0; - - if (char_string) { - encoding = char_string->encoding; - } - - return encoding; -} - -/* returns false if the string exceeds capacity - initialize by using length=0 */ -bool octetstring_init(BACNET_OCTET_STRING * octet_string, - uint8_t * value, size_t length) -{ - bool status = false; /* return value */ - size_t i; /* counter */ - - if (octet_string) { - octet_string->length = 0; - if (length <= sizeof(octet_string->value)) { - if (value) { - for (i = 0; i < length; i++) { - octet_string->value[octet_string->length] = value[i]; - octet_string->length++; - } - } else { - for (i = 0; i < sizeof(octet_string->value); i++) { - octet_string->value[i] = 0; - } - } - status = true; - } - } - - return status; -} - -bool octetstring_copy(BACNET_OCTET_STRING * dest, - BACNET_OCTET_STRING * src) -{ - return octetstring_init(dest, - octetstring_value(src), octetstring_length(src)); -} - -/* returns false if the string exceeds capacity */ -bool octetstring_append(BACNET_OCTET_STRING * octet_string, - uint8_t * value, size_t length) -{ - size_t i; /* counter */ - bool status = false; /* return value */ - - if (octet_string) { - if ((length + octet_string->length) <= sizeof(octet_string->value)) { - for (i = 0; i < length; i++) { - octet_string->value[octet_string->length] = value[i]; - octet_string->length++; - } - status = true; - } - } - - return status; -} - -/* This function sets a new length without changing the value. - If length exceeds capacity, no modification happens and - function returns false. */ -bool octetstring_truncate(BACNET_OCTET_STRING * octet_string, - size_t length) -{ - bool status = false; /* return value */ - - if (octet_string) { - if (length <= sizeof(octet_string->value)) { - octet_string->length = length; - status = true; - } - } - - return status; -} - -/* returns the length. Returns the value in parameter. */ -uint8_t *octetstring_value(BACNET_OCTET_STRING * octet_string) -{ - uint8_t *value = NULL; - - if (octet_string) { - value = octet_string->value; - } - - return value; -} - -/* returns the length. */ -size_t octetstring_length(BACNET_OCTET_STRING * octet_string) -{ - size_t length = 0; - - if (octet_string) { - /* FIXME: validate length is within bounds? */ - length = octet_string->length; - } - - return length; -} - -/* returns the length. */ -size_t octetstring_capacity(BACNET_OCTET_STRING * octet_string) -{ - size_t length = 0; - - if (octet_string) { - /* FIXME: validate length is within bounds? */ - length = sizeof(octet_string->value); - } - - return length; -} - -#ifdef TEST #include #include #include "ctest.h" @@ -491,147 +68,3 @@ void testBitString(Test * pTest) ct_test(pTest, bitstring_bit(&bit_string, bit) == false); } } - -void testCharacterString(Test * pTest) -{ - BACNET_CHARACTER_STRING bacnet_string; - char *value = "Joshua,Mary,Anna,Christopher"; - char test_value[MAX_APDU] = "Patricia"; - char test_append_value[MAX_APDU] = " and the Kids"; - char test_append_string[MAX_APDU] = ""; - bool status = false; - size_t length = 0; - size_t test_length = 0; - size_t i = 0; - - /* verify initialization */ - status = - characterstring_init(&bacnet_string, CHARACTER_ANSI_X34, NULL, 0); - ct_test(pTest, status == true); - ct_test(pTest, characterstring_length(&bacnet_string) == 0); - ct_test(pTest, - characterstring_encoding(&bacnet_string) == CHARACTER_ANSI_X34); - /* bounds check */ - status = characterstring_init(&bacnet_string, - CHARACTER_ANSI_X34, - NULL, characterstring_capacity(&bacnet_string) + 1); - ct_test(pTest, status == false); - status = - characterstring_truncate(&bacnet_string, - characterstring_capacity(&bacnet_string) + 1); - ct_test(pTest, status == false); - status = - characterstring_truncate(&bacnet_string, - characterstring_capacity(&bacnet_string)); - ct_test(pTest, status == true); - - test_length = strlen(test_value); - status = characterstring_init(&bacnet_string, - CHARACTER_ANSI_X34, &test_value[0], test_length); - ct_test(pTest, status == true); - value = characterstring_value(&bacnet_string); - length = characterstring_length(&bacnet_string); - ct_test(pTest, length == test_length); - for (i = 0; i < test_length; i++) { - ct_test(pTest, value[i] == test_value[i]); - } - test_length = strlen(test_append_value); - status = characterstring_append(&bacnet_string, - &test_append_value[0], test_length); - strcat(test_append_string, test_value); - strcat(test_append_string, test_append_value); - test_length = strlen(test_append_string); - ct_test(pTest, status == true); - length = characterstring_length(&bacnet_string); - value = characterstring_value(&bacnet_string); - ct_test(pTest, length == test_length); - for (i = 0; i < test_length; i++) { - ct_test(pTest, value[i] == test_append_string[i]); - } -} - -void testOctetString(Test * pTest) -{ - BACNET_OCTET_STRING bacnet_string; - uint8_t *value = NULL; - uint8_t test_value[MAX_APDU] = "Patricia"; - uint8_t test_append_value[MAX_APDU] = " and the Kids"; - uint8_t test_append_string[MAX_APDU] = ""; - bool status = false; - size_t length = 0; - size_t test_length = 0; - size_t i = 0; - - /* verify initialization */ - status = octetstring_init(&bacnet_string, NULL, 0); - ct_test(pTest, status == true); - ct_test(pTest, octetstring_length(&bacnet_string) == 0); - value = octetstring_value(&bacnet_string); - for (i = 0; i < octetstring_capacity(&bacnet_string); i++) { - ct_test(pTest, value[i] == 0); - } - /* bounds check */ - status = octetstring_init(&bacnet_string, NULL, - octetstring_capacity(&bacnet_string) + 1); - ct_test(pTest, status == false); - status = octetstring_init(&bacnet_string, NULL, - octetstring_capacity(&bacnet_string)); - ct_test(pTest, status == true); - status = - octetstring_truncate(&bacnet_string, - octetstring_capacity(&bacnet_string) + 1); - ct_test(pTest, status == false); - status = - octetstring_truncate(&bacnet_string, - octetstring_capacity(&bacnet_string)); - ct_test(pTest, status == true); - - test_length = strlen((char *) test_value); - status = octetstring_init(&bacnet_string, &test_value[0], test_length); - ct_test(pTest, status == true); - length = octetstring_length(&bacnet_string); - value = octetstring_value(&bacnet_string); - ct_test(pTest, length == test_length); - for (i = 0; i < test_length; i++) { - ct_test(pTest, value[i] == test_value[i]); - } - - test_length = strlen((char *) test_append_value); - status = octetstring_append(&bacnet_string, - &test_append_value[0], test_length); - strcat((char *) test_append_string, (char *) test_value); - strcat((char *) test_append_string, (char *) test_append_value); - test_length = strlen((char *) test_append_string); - ct_test(pTest, status == true); - length = octetstring_length(&bacnet_string); - value = octetstring_value(&bacnet_string); - ct_test(pTest, length == test_length); - for (i = 0; i < test_length; i++) { - ct_test(pTest, value[i] == test_append_string[i]); - } -} - -#ifdef TEST_BACSTR -int main(void) -{ - Test *pTest; - bool rc; - - pTest = ct_create("BACnet Strings", NULL); - /* individual tests */ - rc = ct_addTestFunction(pTest, testBitString); - assert(rc); - rc = ct_addTestFunction(pTest, testCharacterString); - assert(rc); - rc = ct_addTestFunction(pTest, testOctetString); - assert(rc); - /* configure output */ - ct_setStream(pTest, stdout); - ct_run(pTest); - (void) ct_report(pTest); - ct_destroy(pTest); - - return 0; -} -#endif /* TEST_BACSTR */ -#endif /* TEST */ diff --git a/bacnet-stack/src/bacdcode/characterstring.c b/bacnet-stack/src/bacdcode/characterstring.c new file mode 100644 index 00000000..91d70ac8 --- /dev/null +++ b/bacnet-stack/src/bacdcode/characterstring.c @@ -0,0 +1,233 @@ +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2004 Steve Karg + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ + +#include +#include +#include /* for strlen */ +#include "bacstr.h" +#include "bits.h" + +#define CHARACTER_STRING_CAPACITY (MAX_CHARACTER_STRING_BYTES - 1) +/* returns false if the string exceeds capacity + initialize by using length=0 */ +bool characterstring_init(BACNET_CHARACTER_STRING * char_string, + uint8_t encoding, char *value, size_t length) +{ + bool status = false; /* return value */ + size_t i; /* counter */ + + if (char_string) { + char_string->length = 0; + char_string->encoding = encoding; + /* save a byte at the end for NULL - + note: assumes printable characters */ + if (length <= CHARACTER_STRING_CAPACITY) { + if (value) { + for (i = 0; i < MAX_CHARACTER_STRING_BYTES; i++) { + if (i < length) { + char_string->value[char_string->length] = value[i]; + char_string->length++; + } else + char_string->value[i] = 0; + } + } else { + for (i = 0; i < MAX_CHARACTER_STRING_BYTES; i++) { + char_string->value[i] = 0; + } + } + status = true; + } + } + + return status; +} + +bool characterstring_init_ansi(BACNET_CHARACTER_STRING * char_string, + char *value) +{ + return characterstring_init(char_string, + CHARACTER_ANSI_X34, value, value ? strlen(value) : 0); +} + +bool characterstring_copy(BACNET_CHARACTER_STRING * dest, + BACNET_CHARACTER_STRING * src) +{ + return characterstring_init(dest, + characterstring_encoding(src), + characterstring_value(src), characterstring_length(src)); +} + +bool characterstring_same(BACNET_CHARACTER_STRING * dest, + BACNET_CHARACTER_STRING * src) +{ + size_t i; /* counter */ + bool same_status = false; + + if (src && dest) { + if ((src->length == dest->length) && + (src->encoding == dest->encoding)) { + same_status = true; + for (i = 0; i < src->length; i++) { + if (src->value[i] != dest->value[i]) { + same_status = false; + break; + } + } + } + } else if (src) { + if (src->length == 0) + same_status = true; + } else if (dest) { + if (dest->length == 0) + same_status = true; + } + + return same_status; +} + +bool characterstring_ansi_same(BACNET_CHARACTER_STRING * dest, + const char *src) +{ + size_t i; /* counter */ + bool same_status = false; + + if (src && dest) { + if ((dest->length == strlen(src)) && + (dest->encoding == CHARACTER_ANSI_X34)) { + same_status = true; + for (i = 0; i < dest->length; i++) { + if (src[i] != dest->value[i]) { + same_status = false; + break; + } + } + } + } + /* NULL matches an empty string in our world */ + else if (src) { + if (strlen(src) == 0) + same_status = true; + } else if (dest) { + if (dest->length == 0) + same_status = true; + } + + return same_status; +} + +/* returns false if the string exceeds capacity */ +bool characterstring_append(BACNET_CHARACTER_STRING * char_string, + char *value, size_t length) +{ + size_t i; /* counter */ + bool status = false; /* return value */ + + if (char_string) { + if ((length + char_string->length) <= CHARACTER_STRING_CAPACITY) { + for (i = 0; i < length; i++) { + char_string->value[char_string->length] = value[i]; + char_string->length++; + } + status = true; + } + } + + return status; +} + +/* This function sets a new length without changing the value. + If length exceeds capacity, no modification happens and + function returns false. */ +bool characterstring_truncate(BACNET_CHARACTER_STRING * char_string, + size_t length) +{ + bool status = false; /* return value */ + + if (char_string) { + if (length <= CHARACTER_STRING_CAPACITY) { + char_string->length = length; + status = true; + } + } + + return status; +} + +/* Returns the value. */ +char *characterstring_value(BACNET_CHARACTER_STRING * char_string) +{ + char *value = NULL; + + if (char_string) { + value = char_string->value; + } + + return value; +} + +/* returns the length. */ +size_t characterstring_length(BACNET_CHARACTER_STRING * char_string) +{ + size_t length = 0; + + if (char_string) { + /* FIXME: validate length is within bounds? */ + length = char_string->length; + } + + return length; +} + +size_t characterstring_capacity(BACNET_CHARACTER_STRING * char_string) +{ + size_t length = 0; + + if (char_string) { + length = CHARACTER_STRING_CAPACITY; + } + + return length; +} + +/* returns the encoding. */ +uint8_t characterstring_encoding(BACNET_CHARACTER_STRING * char_string) +{ + uint8_t encoding = 0; + + if (char_string) { + encoding = char_string->encoding; + } + + return encoding; +} diff --git a/bacnet-stack/src/bacdcode/characterstring_test.c b/bacnet-stack/src/bacdcode/characterstring_test.c index cd142503..03cd54e9 100644 --- a/bacnet-stack/src/bacdcode/characterstring_test.c +++ b/bacnet-stack/src/bacdcode/characterstring_test.c @@ -37,461 +37,10 @@ #include /* for strlen */ #include "bacstr.h" #include "bits.h" - -void bitstring_init(BACNET_BIT_STRING * bit_string) -{ - int i; - - bit_string->bits_used = 0; - for (i = 0; i < MAX_BITSTRING_BYTES; i++) { - bit_string->value[i] = 0; - } -} - -void bitstring_set_bit(BACNET_BIT_STRING * bit_string, uint8_t bit, - bool value) -{ - uint8_t byte_number = bit / 8; - uint8_t bit_mask = 1; - - if (byte_number < MAX_BITSTRING_BYTES) { - /* set max bits used */ - if (bit_string->bits_used < (bit + 1)) - bit_string->bits_used = bit + 1; - bit_mask = bit_mask << (bit - (byte_number * 8)); - if (value) - bit_string->value[byte_number] |= bit_mask; - else - bit_string->value[byte_number] &= (~(bit_mask)); - } -} - -bool bitstring_bit(BACNET_BIT_STRING * bit_string, uint8_t bit) -{ - bool value = false; - uint8_t byte_number = bit / 8; - uint8_t bit_mask = 1; - - if (bit < (MAX_BITSTRING_BYTES * 8)) { - bit_mask = bit_mask << (bit - (byte_number * 8)); - if (bit_string->value[byte_number] & bit_mask) - value = true; - } - - return value; -} - -uint8_t bitstring_bits_used(BACNET_BIT_STRING * bit_string) -{ - return bit_string->bits_used; -} - -/* returns the number of bytes that a bit string is using */ -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; -} - -uint8_t bitstring_octet(BACNET_BIT_STRING * bit_string, uint8_t index) -{ - uint8_t octet = 0; - - if (bit_string) { - if (index < MAX_BITSTRING_BYTES) { - octet = bit_string->value[index]; - } - } - - return octet; -} - -bool bitstring_set_octet(BACNET_BIT_STRING * bit_string, - uint8_t index, uint8_t octet) -{ - bool status = false; - - if (bit_string) { - if (index < MAX_BITSTRING_BYTES) { - bit_string->value[index] = octet; - status = true; - } - } - - return status; -} - -bool bitstring_set_bits_used(BACNET_BIT_STRING * bit_string, - uint8_t bytes_used, uint8_t unused_bits) -{ - bool status = false; - - if (bit_string) { - /* FIXME: check that bytes_used is at least one? */ - bit_string->bits_used = bytes_used * 8; - bit_string->bits_used -= unused_bits; - status = true; - } - - return status; -} - -uint8_t bitstring_bits_capacity(BACNET_BIT_STRING * bit_string) -{ - if (bit_string) - return (sizeof(bit_string->value) * 8); - else - return 0; -} - -#define CHARACTER_STRING_CAPACITY (MAX_CHARACTER_STRING_BYTES - 1) -/* returns false if the string exceeds capacity - initialize by using length=0 */ -bool characterstring_init(BACNET_CHARACTER_STRING * char_string, - uint8_t encoding, char *value, size_t length) -{ - bool status = false; /* return value */ - size_t i; /* counter */ - - if (char_string) { - char_string->length = 0; - char_string->encoding = encoding; - /* save a byte at the end for NULL - - note: assumes printable characters */ - if (length <= CHARACTER_STRING_CAPACITY) { - if (value) { - for (i = 0; i < MAX_CHARACTER_STRING_BYTES; i++) { - if (i < length) { - char_string->value[char_string->length] = value[i]; - char_string->length++; - } else - char_string->value[i] = 0; - } - } else { - for (i = 0; i < MAX_CHARACTER_STRING_BYTES; i++) { - char_string->value[i] = 0; - } - } - status = true; - } - } - - return status; -} - -bool characterstring_init_ansi(BACNET_CHARACTER_STRING * char_string, - char *value) -{ - return characterstring_init(char_string, - CHARACTER_ANSI_X34, value, value ? strlen(value) : 0); -} - -bool characterstring_copy(BACNET_CHARACTER_STRING * dest, - BACNET_CHARACTER_STRING * src) -{ - return characterstring_init(dest, - characterstring_encoding(src), - characterstring_value(src), characterstring_length(src)); -} - -bool characterstring_same(BACNET_CHARACTER_STRING * dest, - BACNET_CHARACTER_STRING * src) -{ - size_t i; /* counter */ - bool same_status = false; - - if (src && dest) { - if ((src->length == dest->length) && - (src->encoding == dest->encoding)) { - same_status = true; - for (i = 0; i < src->length; i++) { - if (src->value[i] != dest->value[i]) { - same_status = false; - break; - } - } - } - } else if (src) { - if (src->length == 0) - same_status = true; - } else if (dest) { - if (dest->length == 0) - same_status = true; - } - - return same_status; -} - -bool characterstring_ansi_same(BACNET_CHARACTER_STRING * dest, - const char *src) -{ - size_t i; /* counter */ - bool same_status = false; - - if (src && dest) { - if ((dest->length == strlen(src)) && - (dest->encoding == CHARACTER_ANSI_X34)) { - same_status = true; - for (i = 0; i < dest->length; i++) { - if (src[i] != dest->value[i]) { - same_status = false; - break; - } - } - } - } - /* NULL matches an empty string in our world */ - else if (src) { - if (strlen(src) == 0) - same_status = true; - } else if (dest) { - if (dest->length == 0) - same_status = true; - } - - return same_status; -} - -/* returns false if the string exceeds capacity */ -bool characterstring_append(BACNET_CHARACTER_STRING * char_string, - char *value, size_t length) -{ - size_t i; /* counter */ - bool status = false; /* return value */ - - if (char_string) { - if ((length + char_string->length) <= CHARACTER_STRING_CAPACITY) { - for (i = 0; i < length; i++) { - char_string->value[char_string->length] = value[i]; - char_string->length++; - } - status = true; - } - } - - return status; -} - -/* This function sets a new length without changing the value. - If length exceeds capacity, no modification happens and - function returns false. */ -bool characterstring_truncate(BACNET_CHARACTER_STRING * char_string, - size_t length) -{ - bool status = false; /* return value */ - - if (char_string) { - if (length <= CHARACTER_STRING_CAPACITY) { - char_string->length = length; - status = true; - } - } - - return status; -} - -/* Returns the value. */ -char *characterstring_value(BACNET_CHARACTER_STRING * char_string) -{ - char *value = NULL; - - if (char_string) { - value = char_string->value; - } - - return value; -} - -/* returns the length. */ -size_t characterstring_length(BACNET_CHARACTER_STRING * char_string) -{ - size_t length = 0; - - if (char_string) { - /* FIXME: validate length is within bounds? */ - length = char_string->length; - } - - return length; -} - -size_t characterstring_capacity(BACNET_CHARACTER_STRING * char_string) -{ - size_t length = 0; - - if (char_string) { - length = CHARACTER_STRING_CAPACITY; - } - - return length; -} - -/* returns the encoding. */ -uint8_t characterstring_encoding(BACNET_CHARACTER_STRING * char_string) -{ - uint8_t encoding = 0; - - if (char_string) { - encoding = char_string->encoding; - } - - return encoding; -} - -/* returns false if the string exceeds capacity - initialize by using length=0 */ -bool octetstring_init(BACNET_OCTET_STRING * octet_string, - uint8_t * value, size_t length) -{ - bool status = false; /* return value */ - size_t i; /* counter */ - - if (octet_string) { - octet_string->length = 0; - if (length <= sizeof(octet_string->value)) { - if (value) { - for (i = 0; i < length; i++) { - octet_string->value[octet_string->length] = value[i]; - octet_string->length++; - } - } else { - for (i = 0; i < sizeof(octet_string->value); i++) { - octet_string->value[i] = 0; - } - } - status = true; - } - } - - return status; -} - -bool octetstring_copy(BACNET_OCTET_STRING * dest, - BACNET_OCTET_STRING * src) -{ - return octetstring_init(dest, - octetstring_value(src), octetstring_length(src)); -} - -/* returns false if the string exceeds capacity */ -bool octetstring_append(BACNET_OCTET_STRING * octet_string, - uint8_t * value, size_t length) -{ - size_t i; /* counter */ - bool status = false; /* return value */ - - if (octet_string) { - if ((length + octet_string->length) <= sizeof(octet_string->value)) { - for (i = 0; i < length; i++) { - octet_string->value[octet_string->length] = value[i]; - octet_string->length++; - } - status = true; - } - } - - return status; -} - -/* This function sets a new length without changing the value. - If length exceeds capacity, no modification happens and - function returns false. */ -bool octetstring_truncate(BACNET_OCTET_STRING * octet_string, - size_t length) -{ - bool status = false; /* return value */ - - if (octet_string) { - if (length <= sizeof(octet_string->value)) { - octet_string->length = length; - status = true; - } - } - - return status; -} - -/* returns the length. Returns the value in parameter. */ -uint8_t *octetstring_value(BACNET_OCTET_STRING * octet_string) -{ - uint8_t *value = NULL; - - if (octet_string) { - value = octet_string->value; - } - - return value; -} - -/* returns the length. */ -size_t octetstring_length(BACNET_OCTET_STRING * octet_string) -{ - size_t length = 0; - - if (octet_string) { - /* FIXME: validate length is within bounds? */ - length = octet_string->length; - } - - return length; -} - -/* returns the length. */ -size_t octetstring_capacity(BACNET_OCTET_STRING * octet_string) -{ - size_t length = 0; - - if (octet_string) { - /* FIXME: validate length is within bounds? */ - length = sizeof(octet_string->value); - } - - return length; -} - -#ifdef TEST #include #include #include "ctest.h" -void testBitString(Test * pTest) -{ - uint8_t bit = 0; - BACNET_BIT_STRING bit_string; - - bitstring_init(&bit_string); - /* verify initialization */ - ct_test(pTest, bitstring_bits_used(&bit_string) == 0); - for (bit = 0; bit < (MAX_BITSTRING_BYTES * 8); bit++) { - ct_test(pTest, bitstring_bit(&bit_string, bit) == false); - } - - /* test for true */ - for (bit = 0; bit < (MAX_BITSTRING_BYTES * 8); bit++) { - bitstring_set_bit(&bit_string, bit, true); - ct_test(pTest, bitstring_bits_used(&bit_string) == (bit + 1)); - ct_test(pTest, bitstring_bit(&bit_string, bit) == true); - } - /* test for false */ - bitstring_init(&bit_string); - for (bit = 0; bit < (MAX_BITSTRING_BYTES * 8); bit++) { - bitstring_set_bit(&bit_string, bit, false); - ct_test(pTest, bitstring_bits_used(&bit_string) == (bit + 1)); - ct_test(pTest, bitstring_bit(&bit_string, bit) == false); - } -} - void testCharacterString(Test * pTest) { BACNET_CHARACTER_STRING bacnet_string; @@ -549,89 +98,3 @@ void testCharacterString(Test * pTest) ct_test(pTest, value[i] == test_append_string[i]); } } - -void testOctetString(Test * pTest) -{ - BACNET_OCTET_STRING bacnet_string; - uint8_t *value = NULL; - uint8_t test_value[MAX_APDU] = "Patricia"; - uint8_t test_append_value[MAX_APDU] = " and the Kids"; - uint8_t test_append_string[MAX_APDU] = ""; - bool status = false; - size_t length = 0; - size_t test_length = 0; - size_t i = 0; - - /* verify initialization */ - status = octetstring_init(&bacnet_string, NULL, 0); - ct_test(pTest, status == true); - ct_test(pTest, octetstring_length(&bacnet_string) == 0); - value = octetstring_value(&bacnet_string); - for (i = 0; i < octetstring_capacity(&bacnet_string); i++) { - ct_test(pTest, value[i] == 0); - } - /* bounds check */ - status = octetstring_init(&bacnet_string, NULL, - octetstring_capacity(&bacnet_string) + 1); - ct_test(pTest, status == false); - status = octetstring_init(&bacnet_string, NULL, - octetstring_capacity(&bacnet_string)); - ct_test(pTest, status == true); - status = - octetstring_truncate(&bacnet_string, - octetstring_capacity(&bacnet_string) + 1); - ct_test(pTest, status == false); - status = - octetstring_truncate(&bacnet_string, - octetstring_capacity(&bacnet_string)); - ct_test(pTest, status == true); - - test_length = strlen((char *) test_value); - status = octetstring_init(&bacnet_string, &test_value[0], test_length); - ct_test(pTest, status == true); - length = octetstring_length(&bacnet_string); - value = octetstring_value(&bacnet_string); - ct_test(pTest, length == test_length); - for (i = 0; i < test_length; i++) { - ct_test(pTest, value[i] == test_value[i]); - } - - test_length = strlen((char *) test_append_value); - status = octetstring_append(&bacnet_string, - &test_append_value[0], test_length); - strcat((char *) test_append_string, (char *) test_value); - strcat((char *) test_append_string, (char *) test_append_value); - test_length = strlen((char *) test_append_string); - ct_test(pTest, status == true); - length = octetstring_length(&bacnet_string); - value = octetstring_value(&bacnet_string); - ct_test(pTest, length == test_length); - for (i = 0; i < test_length; i++) { - ct_test(pTest, value[i] == test_append_string[i]); - } -} - -#ifdef TEST_BACSTR -int main(void) -{ - Test *pTest; - bool rc; - - pTest = ct_create("BACnet Strings", NULL); - /* individual tests */ - rc = ct_addTestFunction(pTest, testBitString); - assert(rc); - rc = ct_addTestFunction(pTest, testCharacterString); - assert(rc); - rc = ct_addTestFunction(pTest, testOctetString); - assert(rc); - /* configure output */ - ct_setStream(pTest, stdout); - ct_run(pTest); - (void) ct_report(pTest); - ct_destroy(pTest); - - return 0; -} -#endif /* TEST_BACSTR */ -#endif /* TEST */ diff --git a/bacnet-stack/src/bacdcode/charstring.c b/bacnet-stack/src/bacdcode/charstring.c deleted file mode 100644 index cd142503..00000000 --- a/bacnet-stack/src/bacdcode/charstring.c +++ /dev/null @@ -1,637 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2004 Steve Karg - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ - -#include -#include -#include /* for strlen */ -#include "bacstr.h" -#include "bits.h" - -void bitstring_init(BACNET_BIT_STRING * bit_string) -{ - int i; - - bit_string->bits_used = 0; - for (i = 0; i < MAX_BITSTRING_BYTES; i++) { - bit_string->value[i] = 0; - } -} - -void bitstring_set_bit(BACNET_BIT_STRING * bit_string, uint8_t bit, - bool value) -{ - uint8_t byte_number = bit / 8; - uint8_t bit_mask = 1; - - if (byte_number < MAX_BITSTRING_BYTES) { - /* set max bits used */ - if (bit_string->bits_used < (bit + 1)) - bit_string->bits_used = bit + 1; - bit_mask = bit_mask << (bit - (byte_number * 8)); - if (value) - bit_string->value[byte_number] |= bit_mask; - else - bit_string->value[byte_number] &= (~(bit_mask)); - } -} - -bool bitstring_bit(BACNET_BIT_STRING * bit_string, uint8_t bit) -{ - bool value = false; - uint8_t byte_number = bit / 8; - uint8_t bit_mask = 1; - - if (bit < (MAX_BITSTRING_BYTES * 8)) { - bit_mask = bit_mask << (bit - (byte_number * 8)); - if (bit_string->value[byte_number] & bit_mask) - value = true; - } - - return value; -} - -uint8_t bitstring_bits_used(BACNET_BIT_STRING * bit_string) -{ - return bit_string->bits_used; -} - -/* returns the number of bytes that a bit string is using */ -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; -} - -uint8_t bitstring_octet(BACNET_BIT_STRING * bit_string, uint8_t index) -{ - uint8_t octet = 0; - - if (bit_string) { - if (index < MAX_BITSTRING_BYTES) { - octet = bit_string->value[index]; - } - } - - return octet; -} - -bool bitstring_set_octet(BACNET_BIT_STRING * bit_string, - uint8_t index, uint8_t octet) -{ - bool status = false; - - if (bit_string) { - if (index < MAX_BITSTRING_BYTES) { - bit_string->value[index] = octet; - status = true; - } - } - - return status; -} - -bool bitstring_set_bits_used(BACNET_BIT_STRING * bit_string, - uint8_t bytes_used, uint8_t unused_bits) -{ - bool status = false; - - if (bit_string) { - /* FIXME: check that bytes_used is at least one? */ - bit_string->bits_used = bytes_used * 8; - bit_string->bits_used -= unused_bits; - status = true; - } - - return status; -} - -uint8_t bitstring_bits_capacity(BACNET_BIT_STRING * bit_string) -{ - if (bit_string) - return (sizeof(bit_string->value) * 8); - else - return 0; -} - -#define CHARACTER_STRING_CAPACITY (MAX_CHARACTER_STRING_BYTES - 1) -/* returns false if the string exceeds capacity - initialize by using length=0 */ -bool characterstring_init(BACNET_CHARACTER_STRING * char_string, - uint8_t encoding, char *value, size_t length) -{ - bool status = false; /* return value */ - size_t i; /* counter */ - - if (char_string) { - char_string->length = 0; - char_string->encoding = encoding; - /* save a byte at the end for NULL - - note: assumes printable characters */ - if (length <= CHARACTER_STRING_CAPACITY) { - if (value) { - for (i = 0; i < MAX_CHARACTER_STRING_BYTES; i++) { - if (i < length) { - char_string->value[char_string->length] = value[i]; - char_string->length++; - } else - char_string->value[i] = 0; - } - } else { - for (i = 0; i < MAX_CHARACTER_STRING_BYTES; i++) { - char_string->value[i] = 0; - } - } - status = true; - } - } - - return status; -} - -bool characterstring_init_ansi(BACNET_CHARACTER_STRING * char_string, - char *value) -{ - return characterstring_init(char_string, - CHARACTER_ANSI_X34, value, value ? strlen(value) : 0); -} - -bool characterstring_copy(BACNET_CHARACTER_STRING * dest, - BACNET_CHARACTER_STRING * src) -{ - return characterstring_init(dest, - characterstring_encoding(src), - characterstring_value(src), characterstring_length(src)); -} - -bool characterstring_same(BACNET_CHARACTER_STRING * dest, - BACNET_CHARACTER_STRING * src) -{ - size_t i; /* counter */ - bool same_status = false; - - if (src && dest) { - if ((src->length == dest->length) && - (src->encoding == dest->encoding)) { - same_status = true; - for (i = 0; i < src->length; i++) { - if (src->value[i] != dest->value[i]) { - same_status = false; - break; - } - } - } - } else if (src) { - if (src->length == 0) - same_status = true; - } else if (dest) { - if (dest->length == 0) - same_status = true; - } - - return same_status; -} - -bool characterstring_ansi_same(BACNET_CHARACTER_STRING * dest, - const char *src) -{ - size_t i; /* counter */ - bool same_status = false; - - if (src && dest) { - if ((dest->length == strlen(src)) && - (dest->encoding == CHARACTER_ANSI_X34)) { - same_status = true; - for (i = 0; i < dest->length; i++) { - if (src[i] != dest->value[i]) { - same_status = false; - break; - } - } - } - } - /* NULL matches an empty string in our world */ - else if (src) { - if (strlen(src) == 0) - same_status = true; - } else if (dest) { - if (dest->length == 0) - same_status = true; - } - - return same_status; -} - -/* returns false if the string exceeds capacity */ -bool characterstring_append(BACNET_CHARACTER_STRING * char_string, - char *value, size_t length) -{ - size_t i; /* counter */ - bool status = false; /* return value */ - - if (char_string) { - if ((length + char_string->length) <= CHARACTER_STRING_CAPACITY) { - for (i = 0; i < length; i++) { - char_string->value[char_string->length] = value[i]; - char_string->length++; - } - status = true; - } - } - - return status; -} - -/* This function sets a new length without changing the value. - If length exceeds capacity, no modification happens and - function returns false. */ -bool characterstring_truncate(BACNET_CHARACTER_STRING * char_string, - size_t length) -{ - bool status = false; /* return value */ - - if (char_string) { - if (length <= CHARACTER_STRING_CAPACITY) { - char_string->length = length; - status = true; - } - } - - return status; -} - -/* Returns the value. */ -char *characterstring_value(BACNET_CHARACTER_STRING * char_string) -{ - char *value = NULL; - - if (char_string) { - value = char_string->value; - } - - return value; -} - -/* returns the length. */ -size_t characterstring_length(BACNET_CHARACTER_STRING * char_string) -{ - size_t length = 0; - - if (char_string) { - /* FIXME: validate length is within bounds? */ - length = char_string->length; - } - - return length; -} - -size_t characterstring_capacity(BACNET_CHARACTER_STRING * char_string) -{ - size_t length = 0; - - if (char_string) { - length = CHARACTER_STRING_CAPACITY; - } - - return length; -} - -/* returns the encoding. */ -uint8_t characterstring_encoding(BACNET_CHARACTER_STRING * char_string) -{ - uint8_t encoding = 0; - - if (char_string) { - encoding = char_string->encoding; - } - - return encoding; -} - -/* returns false if the string exceeds capacity - initialize by using length=0 */ -bool octetstring_init(BACNET_OCTET_STRING * octet_string, - uint8_t * value, size_t length) -{ - bool status = false; /* return value */ - size_t i; /* counter */ - - if (octet_string) { - octet_string->length = 0; - if (length <= sizeof(octet_string->value)) { - if (value) { - for (i = 0; i < length; i++) { - octet_string->value[octet_string->length] = value[i]; - octet_string->length++; - } - } else { - for (i = 0; i < sizeof(octet_string->value); i++) { - octet_string->value[i] = 0; - } - } - status = true; - } - } - - return status; -} - -bool octetstring_copy(BACNET_OCTET_STRING * dest, - BACNET_OCTET_STRING * src) -{ - return octetstring_init(dest, - octetstring_value(src), octetstring_length(src)); -} - -/* returns false if the string exceeds capacity */ -bool octetstring_append(BACNET_OCTET_STRING * octet_string, - uint8_t * value, size_t length) -{ - size_t i; /* counter */ - bool status = false; /* return value */ - - if (octet_string) { - if ((length + octet_string->length) <= sizeof(octet_string->value)) { - for (i = 0; i < length; i++) { - octet_string->value[octet_string->length] = value[i]; - octet_string->length++; - } - status = true; - } - } - - return status; -} - -/* This function sets a new length without changing the value. - If length exceeds capacity, no modification happens and - function returns false. */ -bool octetstring_truncate(BACNET_OCTET_STRING * octet_string, - size_t length) -{ - bool status = false; /* return value */ - - if (octet_string) { - if (length <= sizeof(octet_string->value)) { - octet_string->length = length; - status = true; - } - } - - return status; -} - -/* returns the length. Returns the value in parameter. */ -uint8_t *octetstring_value(BACNET_OCTET_STRING * octet_string) -{ - uint8_t *value = NULL; - - if (octet_string) { - value = octet_string->value; - } - - return value; -} - -/* returns the length. */ -size_t octetstring_length(BACNET_OCTET_STRING * octet_string) -{ - size_t length = 0; - - if (octet_string) { - /* FIXME: validate length is within bounds? */ - length = octet_string->length; - } - - return length; -} - -/* returns the length. */ -size_t octetstring_capacity(BACNET_OCTET_STRING * octet_string) -{ - size_t length = 0; - - if (octet_string) { - /* FIXME: validate length is within bounds? */ - length = sizeof(octet_string->value); - } - - return length; -} - -#ifdef TEST -#include -#include -#include "ctest.h" - -void testBitString(Test * pTest) -{ - uint8_t bit = 0; - BACNET_BIT_STRING bit_string; - - bitstring_init(&bit_string); - /* verify initialization */ - ct_test(pTest, bitstring_bits_used(&bit_string) == 0); - for (bit = 0; bit < (MAX_BITSTRING_BYTES * 8); bit++) { - ct_test(pTest, bitstring_bit(&bit_string, bit) == false); - } - - /* test for true */ - for (bit = 0; bit < (MAX_BITSTRING_BYTES * 8); bit++) { - bitstring_set_bit(&bit_string, bit, true); - ct_test(pTest, bitstring_bits_used(&bit_string) == (bit + 1)); - ct_test(pTest, bitstring_bit(&bit_string, bit) == true); - } - /* test for false */ - bitstring_init(&bit_string); - for (bit = 0; bit < (MAX_BITSTRING_BYTES * 8); bit++) { - bitstring_set_bit(&bit_string, bit, false); - ct_test(pTest, bitstring_bits_used(&bit_string) == (bit + 1)); - ct_test(pTest, bitstring_bit(&bit_string, bit) == false); - } -} - -void testCharacterString(Test * pTest) -{ - BACNET_CHARACTER_STRING bacnet_string; - char *value = "Joshua,Mary,Anna,Christopher"; - char test_value[MAX_APDU] = "Patricia"; - char test_append_value[MAX_APDU] = " and the Kids"; - char test_append_string[MAX_APDU] = ""; - bool status = false; - size_t length = 0; - size_t test_length = 0; - size_t i = 0; - - /* verify initialization */ - status = - characterstring_init(&bacnet_string, CHARACTER_ANSI_X34, NULL, 0); - ct_test(pTest, status == true); - ct_test(pTest, characterstring_length(&bacnet_string) == 0); - ct_test(pTest, - characterstring_encoding(&bacnet_string) == CHARACTER_ANSI_X34); - /* bounds check */ - status = characterstring_init(&bacnet_string, - CHARACTER_ANSI_X34, - NULL, characterstring_capacity(&bacnet_string) + 1); - ct_test(pTest, status == false); - status = - characterstring_truncate(&bacnet_string, - characterstring_capacity(&bacnet_string) + 1); - ct_test(pTest, status == false); - status = - characterstring_truncate(&bacnet_string, - characterstring_capacity(&bacnet_string)); - ct_test(pTest, status == true); - - test_length = strlen(test_value); - status = characterstring_init(&bacnet_string, - CHARACTER_ANSI_X34, &test_value[0], test_length); - ct_test(pTest, status == true); - value = characterstring_value(&bacnet_string); - length = characterstring_length(&bacnet_string); - ct_test(pTest, length == test_length); - for (i = 0; i < test_length; i++) { - ct_test(pTest, value[i] == test_value[i]); - } - test_length = strlen(test_append_value); - status = characterstring_append(&bacnet_string, - &test_append_value[0], test_length); - strcat(test_append_string, test_value); - strcat(test_append_string, test_append_value); - test_length = strlen(test_append_string); - ct_test(pTest, status == true); - length = characterstring_length(&bacnet_string); - value = characterstring_value(&bacnet_string); - ct_test(pTest, length == test_length); - for (i = 0; i < test_length; i++) { - ct_test(pTest, value[i] == test_append_string[i]); - } -} - -void testOctetString(Test * pTest) -{ - BACNET_OCTET_STRING bacnet_string; - uint8_t *value = NULL; - uint8_t test_value[MAX_APDU] = "Patricia"; - uint8_t test_append_value[MAX_APDU] = " and the Kids"; - uint8_t test_append_string[MAX_APDU] = ""; - bool status = false; - size_t length = 0; - size_t test_length = 0; - size_t i = 0; - - /* verify initialization */ - status = octetstring_init(&bacnet_string, NULL, 0); - ct_test(pTest, status == true); - ct_test(pTest, octetstring_length(&bacnet_string) == 0); - value = octetstring_value(&bacnet_string); - for (i = 0; i < octetstring_capacity(&bacnet_string); i++) { - ct_test(pTest, value[i] == 0); - } - /* bounds check */ - status = octetstring_init(&bacnet_string, NULL, - octetstring_capacity(&bacnet_string) + 1); - ct_test(pTest, status == false); - status = octetstring_init(&bacnet_string, NULL, - octetstring_capacity(&bacnet_string)); - ct_test(pTest, status == true); - status = - octetstring_truncate(&bacnet_string, - octetstring_capacity(&bacnet_string) + 1); - ct_test(pTest, status == false); - status = - octetstring_truncate(&bacnet_string, - octetstring_capacity(&bacnet_string)); - ct_test(pTest, status == true); - - test_length = strlen((char *) test_value); - status = octetstring_init(&bacnet_string, &test_value[0], test_length); - ct_test(pTest, status == true); - length = octetstring_length(&bacnet_string); - value = octetstring_value(&bacnet_string); - ct_test(pTest, length == test_length); - for (i = 0; i < test_length; i++) { - ct_test(pTest, value[i] == test_value[i]); - } - - test_length = strlen((char *) test_append_value); - status = octetstring_append(&bacnet_string, - &test_append_value[0], test_length); - strcat((char *) test_append_string, (char *) test_value); - strcat((char *) test_append_string, (char *) test_append_value); - test_length = strlen((char *) test_append_string); - ct_test(pTest, status == true); - length = octetstring_length(&bacnet_string); - value = octetstring_value(&bacnet_string); - ct_test(pTest, length == test_length); - for (i = 0; i < test_length; i++) { - ct_test(pTest, value[i] == test_append_string[i]); - } -} - -#ifdef TEST_BACSTR -int main(void) -{ - Test *pTest; - bool rc; - - pTest = ct_create("BACnet Strings", NULL); - /* individual tests */ - rc = ct_addTestFunction(pTest, testBitString); - assert(rc); - rc = ct_addTestFunction(pTest, testCharacterString); - assert(rc); - rc = ct_addTestFunction(pTest, testOctetString); - assert(rc); - /* configure output */ - ct_setStream(pTest, stdout); - ct_run(pTest); - (void) ct_report(pTest); - ct_destroy(pTest); - - return 0; -} -#endif /* TEST_BACSTR */ -#endif /* TEST */ diff --git a/bacnet-stack/src/bacdcode/main.c b/bacnet-stack/src/bacdcode/main.c index 92d0d094..992c3682 100644 --- a/bacnet-stack/src/bacdcode/main.c +++ b/bacnet-stack/src/bacdcode/main.c @@ -47,1778 +47,11 @@ #error Define BIG_ENDIAN=0 or BIG_ENDIAN=1 for BACnet Stack in compiler settings #endif -/* max-segments-accepted - B'000' Unspecified number of segments accepted. - B'001' 2 segments accepted. - B'010' 4 segments accepted. - B'011' 8 segments accepted. - B'100' 16 segments accepted. - B'101' 32 segments accepted. - B'110' 64 segments accepted. - B'111' Greater than 64 segments accepted. -*/ - -/* max-APDU-length-accepted - B'0000' Up to MinimumMessageSize (50 octets) - B'0001' Up to 128 octets - B'0010' Up to 206 octets (fits in a LonTalk frame) - B'0011' Up to 480 octets (fits in an ARCNET frame) - B'0100' Up to 1024 octets - B'0101' Up to 1476 octets (fits in an ISO 8802-3 frame) - B'0110' reserved by ASHRAE - B'0111' reserved by ASHRAE - B'1000' reserved by ASHRAE - B'1001' reserved by ASHRAE - B'1010' reserved by ASHRAE - B'1011' reserved by ASHRAE - B'1100' reserved by ASHRAE - B'1101' reserved by ASHRAE - B'1110' reserved by ASHRAE - B'1111' reserved by ASHRAE -*/ -/* from clause 20.1.2.4 max-segments-accepted */ -/* and clause 20.1.2.5 max-APDU-length-accepted */ -/* returns the encoded octet */ -uint8_t encode_max_segs_max_apdu(int max_segs, int max_apdu) -{ - uint8_t octet = 0; - - if (max_segs < 2) - octet = 0; - else if (max_segs < 4) - octet = 0x10; - else if (max_segs < 8) - octet = 0x20; - else if (max_segs < 16) - octet = 0x30; - else if (max_segs < 32) - octet = 0x40; - else if (max_segs < 64) - octet = 0x50; - else if (max_segs == 64) - octet = 0x60; - else - octet = 0x70; - - /* max_apdu must be 50 octets minimum */ - if (max_apdu <= 50) - octet |= 0x00; - else if (max_apdu <= 128) - octet |= 0x01; - /*fits in a LonTalk frame */ - else if (max_apdu <= 206) - octet |= 0x02; - /*fits in an ARCNET or MS/TP frame */ - else if (max_apdu <= 480) - octet |= 0x03; - else if (max_apdu <= 1024) - octet |= 0x04; - /* fits in an ISO 8802-3 frame */ - else if (max_apdu <= 1476) - octet |= 0x05; - - return octet; -} - -/* from clause 20.1.2.4 max-segments-accepted */ -/* and clause 20.1.2.5 max-APDU-length-accepted */ -/* returns the encoded octet */ -int decode_max_segs(uint8_t octet) -{ - int max_segs = 0; - - switch (octet & 0xF0) { - case 0: - max_segs = 0; - break; - case 0x10: - max_segs = 2; - break; - case 0x20: - max_segs = 4; - break; - case 0x30: - max_segs = 8; - break; - case 0x40: - max_segs = 16; - break; - case 0x50: - max_segs = 32; - break; - case 0x60: - max_segs = 64; - break; - case 0x70: - max_segs = 65; - break; - default: - break; - } - - return max_segs; -} - -int decode_max_apdu(uint8_t octet) -{ - int max_apdu = 0; - - switch (octet & 0x0F) { - case 0: - max_apdu = 50; - break; - case 1: - max_apdu = 128; - break; - case 2: - max_apdu = 206; - break; - case 3: - max_apdu = 480; - break; - case 4: - max_apdu = 1024; - break; - case 5: - max_apdu = 1476; - break; - default: - break; - } - - return max_apdu; -} - -/* 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, - uint32_t len_value_type) -{ - int len = 1; /* return value */ - - apdu[0] = 0; - if (context_specific) - apdu[0] = BIT3; - - /* additional tag byte after this byte */ - /* for extended tag byte */ - if (tag_number <= 14) - apdu[0] |= (tag_number << 4); - else { - apdu[0] |= 0xF0; - apdu[1] = tag_number; - len++; - } - - /* NOTE: additional len byte(s) after extended tag byte */ - /* if larger than 4 */ - if (len_value_type <= 4) - apdu[0] |= len_value_type; - else { - apdu[0] |= 5; - if (len_value_type <= 253) { - apdu[len++] = (uint8_t) len_value_type; - } else if (len_value_type <= 65535) { - apdu[len++] = 254; - len += - encode_unsigned16(&apdu[len], (uint16_t) len_value_type); - } else { - apdu[len++] = 255; - len += encode_unsigned32(&apdu[len], len_value_type); - } - } - - return len; -} - -/* from clause 20.2.1.3.2 Constructed Data */ -/* returns the number of apdu bytes consumed */ -int encode_opening_tag(uint8_t * apdu, uint8_t tag_number) -{ - int len = 1; - - /* set class field to context specific */ - apdu[0] = BIT3; - /* additional tag byte after this byte for extended tag byte */ - if (tag_number <= 14) - apdu[0] |= (tag_number << 4); - else { - apdu[0] |= 0xF0; - apdu[1] = tag_number; - len++; - } - /* set type field to opening tag */ - apdu[0] |= 6; - - return len; -} - -/* from clause 20.2.1.3.2 Constructed Data */ -/* returns the number of apdu bytes consumed */ -int encode_closing_tag(uint8_t * apdu, uint8_t tag_number) -{ - int len = 1; - - /* set class field to context specific */ - apdu[0] = BIT3; - /* additional tag byte after this byte for extended tag byte */ - if (tag_number <= 14) - apdu[0] |= (tag_number << 4); - else { - apdu[0] |= 0xF0; - apdu[1] = tag_number; - len++; - } - /* set type field to closing tag */ - apdu[0] |= 7; - - return len; -} - -/* from clause 20.2.1.3.2 Constructed Data */ -/* returns true if extended tag numbering is used */ -static bool decode_is_extended_tag_number(uint8_t * apdu) -{ - return ((apdu[0] & 0xF0) == 0xF0); -} - -/* from clause 20.2.1.3.2 Constructed Data */ -/* returns true if the extended value is used */ -static bool decode_is_extended_value(uint8_t * apdu) -{ - return ((apdu[0] & 0x07) == 5); -} - -/* from clause 20.2.1.3.2 Constructed Data */ -/* returns true if the tag is context specific */ -bool decode_is_context_specific(uint8_t * apdu) -{ - return ((apdu[0] & BIT3) == BIT3); -} - -int decode_tag_number(uint8_t * apdu, uint8_t * tag_number) -{ - int len = 1; /* return value */ - - /* decode the tag number first */ - if (decode_is_extended_tag_number(&apdu[0])) { - /* extended tag */ - if (tag_number) - *tag_number = apdu[1]; - len++; - } else { - if (tag_number) - *tag_number = (apdu[0] >> 4); - } - - return len; -} - -bool decode_is_opening_tag(uint8_t * apdu) -{ - return ((apdu[0] & 0x07) == 6); -} - -/* from clause 20.2.1.3.2 Constructed Data */ -/* returns the number of apdu bytes consumed */ -bool decode_is_closing_tag(uint8_t * apdu) -{ - return ((apdu[0] & 0x07) == 7); -} - -/* from clause 20.2.1.3.2 Constructed Data */ -/* returns the number of apdu bytes consumed */ -int decode_tag_number_and_value(uint8_t * apdu, - uint8_t * tag_number, uint32_t * value) -{ - int len = 1; - uint16_t value16; - uint32_t value32; - - len = decode_tag_number(&apdu[0], tag_number); - /* decode the value */ - if (decode_is_extended_value(&apdu[0])) { - /* tagged as uint32_t */ - if (apdu[len] == 255) { - len++; - len += decode_unsigned32(&apdu[len], &value32); - if (value) - *value = value32; - } - /* tagged as uint16_t */ - else if (apdu[len] == 254) { - len++; - len += decode_unsigned16(&apdu[len], &value16); - if (value) - *value = value16; - } - /* no tag - must be uint8_t */ - else { - if (value) - *value = apdu[len]; - len++; - } - } else if (decode_is_opening_tag(&apdu[0]) && value) - *value = 0; - /* closing tag */ - else if (decode_is_closing_tag(&apdu[0]) && value) - *value = 0; - /* small value */ - else if (value) - *value = apdu[0] & 0x07; - - return len; -} - -/* from clause 20.2.1.3.2 Constructed Data */ -/* returns true if the tag is context specific and matches */ -bool decode_is_context_tag(uint8_t * apdu, uint8_t tag_number) -{ - uint8_t my_tag_number = 0; - bool context_specific = false; - - context_specific = decode_is_context_specific(apdu); - decode_tag_number(apdu, &my_tag_number); - - return (context_specific && (my_tag_number == tag_number)); -} - -/* from clause 20.2.1.3.2 Constructed Data */ -/* returns the number of apdu bytes consumed */ -bool decode_is_opening_tag_number(uint8_t * apdu, uint8_t tag_number) -{ - uint8_t my_tag_number = 0; - bool opening_tag = false; - - opening_tag = ((apdu[0] & 0x07) == 6); - decode_tag_number(apdu, &my_tag_number); - - return (opening_tag && (my_tag_number == tag_number)); -} - -/* from clause 20.2.1.3.2 Constructed Data */ -/* returns the number of apdu bytes consumed */ -bool decode_is_closing_tag_number(uint8_t * apdu, uint8_t tag_number) -{ - uint8_t my_tag_number = 0; - bool closing_tag = false; - - closing_tag = ((apdu[0] & 0x07) == 7); - decode_tag_number(apdu, &my_tag_number); - - return (closing_tag && (my_tag_number == tag_number)); -} - -/* from clause 20.2.3 Encoding of a Boolean Value */ -/* and 20.2.1 General Rules for Encoding BACnet Tags */ -/* returns the number of apdu bytes consumed */ -int encode_application_boolean(uint8_t * apdu, bool boolean_value) -{ - int len = 0; - uint32_t len_value = 0; - - if (boolean_value) - len_value = 1; - - len = encode_tag(&apdu[0], BACNET_APPLICATION_TAG_BOOLEAN, false, - len_value); - - return len; -} - -/* context tagged is encoded differently */ -int encode_context_boolean(uint8_t * apdu, int tag_number, - bool boolean_value) -{ - int len = 0; /* return value */ - - len = encode_tag(&apdu[0], (uint8_t) tag_number, true, 1); - apdu[len] = boolean_value ? 1 : 0; - len++; - - return len; -} - -bool decode_context_boolean(uint8_t * apdu) -{ - bool boolean_value = false; - - if (apdu[0]) - boolean_value = true; - - return boolean_value; -} - -/* from clause 20.2.3 Encoding of a Boolean Value */ -/* and 20.2.1 General Rules for Encoding BACnet Tags */ -/* returns the number of apdu bytes consumed */ -bool decode_boolean(uint32_t len_value) -{ - bool boolean_value = false; - - if (len_value) - boolean_value = true; - - return boolean_value; -} - -/* from clause 20.2.2 Encoding of a Null Value */ -/* and 20.2.1 General Rules for Encoding BACnet Tags */ -/* returns the number of apdu bytes consumed */ -int encode_application_null(uint8_t * apdu) -{ - return encode_tag(&apdu[0], BACNET_APPLICATION_TAG_NULL, false, 0); -} - -int encode_context_null(uint8_t * apdu, int tag_number) -{ - return encode_tag(&apdu[0], (uint8_t)tag_number, true, 0); -} - -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, - BACNET_BIT_STRING * bit_string) -{ - int len = 0; - uint8_t unused_bits = 0; - uint32_t i = 0; - uint32_t bytes_used = 0; - - - bitstring_init(bit_string); - if (len_value) { - /* the first octet contains the unused bits */ - bytes_used = len_value - 1; - if (bytes_used <= MAX_BITSTRING_BYTES) { - len = 1; - for (i = 0; i < bytes_used; i++) { - bitstring_set_octet(bit_string, (uint8_t) i, - byte_reverse_bits(apdu[len++])); - } - unused_bits = apdu[0] & 0x07; - bitstring_set_bits_used(bit_string, - (uint8_t) bytes_used, unused_bits); - } - } - - return len; -} - -/* from clause 20.2.10 Encoding of a Bit String Value */ -/* returns the number of apdu bytes consumed */ -int encode_bitstring(uint8_t * apdu, BACNET_BIT_STRING * bit_string) -{ - int len = 0; - uint8_t remaining_used_bits = 0; - uint8_t used_bytes = 0; - uint8_t i = 0; - - /* if the bit string is empty, then the first octet shall be zero */ - if (bitstring_bits_used(bit_string) == 0) - apdu[len++] = 0; - else { - used_bytes = bitstring_bytes_used(bit_string); - remaining_used_bits = bitstring_bits_used(bit_string) - - ((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++] = - byte_reverse_bits(bitstring_octet(bit_string, i)); - } - } - - return len; -} - -int encode_application_bitstring(uint8_t * apdu, BACNET_BIT_STRING * bit_string) -{ - int len = 0; - int bit_string_encoded_length = 1; /* 1 for the bits remaining octet */ - - /* bit string may use more than 1 octet for the tag, so find out how many */ - bit_string_encoded_length += bitstring_bytes_used(bit_string); - len = encode_tag(&apdu[0], BACNET_APPLICATION_TAG_BIT_STRING, false, - bit_string_encoded_length); - len += encode_bitstring(&apdu[len], bit_string); - - return len; -} - -int encode_context_bitstring(uint8_t * apdu, int tag_number, - BACNET_BIT_STRING * bit_string) -{ - int len = 0; - int bit_string_encoded_length = 1; /* 1 for the bits remaining octet */ - - /* bit string may use more than 1 octet for the tag, so find out how many */ - bit_string_encoded_length += bitstring_bytes_used(bit_string); - len = - encode_tag(&apdu[0], (uint8_t)tag_number, true, bit_string_encoded_length); - len += encode_bitstring(&apdu[len], bit_string); - - return len; -} - -/* from clause 20.2.6 Encoding of a Real Number Value */ -/* returns the number of apdu bytes consumed */ -int decode_real(uint8_t * apdu, float *real_value) -{ - union { - uint8_t byte[4]; - float real_value; - } my_data; - - /* NOTE: assumes the compiler stores float as IEEE-754 float */ -#if BIG_ENDIAN - my_data.byte[0] = apdu[0]; - my_data.byte[1] = apdu[1]; - my_data.byte[2] = apdu[2]; - my_data.byte[3] = apdu[3]; -#else - my_data.byte[0] = apdu[3]; - my_data.byte[1] = apdu[2]; - my_data.byte[2] = apdu[1]; - my_data.byte[3] = apdu[0]; -#endif - - *real_value = my_data.real_value; - - return 4; -} - -/* from clause 20.2.6 Encoding of a Real Number Value */ -/* returns the number of apdu bytes consumed */ -int encode_bacnet_real(float value, uint8_t * apdu) -{ - union { - uint8_t byte[4]; - float real_value; - } my_data; - - /* NOTE: assumes the compiler stores float as IEEE-754 float */ - my_data.real_value = value; -#if BIG_ENDIAN - apdu[0] = my_data.byte[0]; - apdu[1] = my_data.byte[1]; - apdu[2] = my_data.byte[2]; - apdu[3] = my_data.byte[3]; -#else - apdu[0] = my_data.byte[3]; - apdu[1] = my_data.byte[2]; - apdu[2] = my_data.byte[1]; - apdu[3] = my_data.byte[0]; -#endif - - return 4; -} - -/* 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 */ -int encode_application_real(uint8_t * apdu, float value) -{ - int len = 0; - - /* assumes that the tag only consumes 1 octet */ - len = encode_bacnet_real(value, &apdu[1]); - len += encode_tag(&apdu[0], BACNET_APPLICATION_TAG_REAL, false, len); - - return len; -} - -int encode_context_real(uint8_t * apdu, int tag_number, float value) -{ - int len = 0; - - /* assumes that the tag only consumes 1 octet */ - len = encode_bacnet_real(value, &apdu[1]); - /* we only reserved 1 byte for encoding the tag - check the limits */ - if (tag_number <= 14) - len += encode_tag(&apdu[0], (uint8_t) tag_number, true, len); - else - len = 0; - - return len; -} - -/* from clause 20.2.14 Encoding of an Object Identifier Value */ -/* returns the number of apdu bytes consumed */ -int decode_object_id(uint8_t * apdu, int *object_type, uint32_t * instance) -{ - uint32_t value = 0; - int len = 0; - - len = decode_unsigned32(apdu, &value); - *object_type = ((value >> BACNET_INSTANCE_BITS) & BACNET_MAX_OBJECT); - *instance = (value & BACNET_MAX_INSTANCE); - - return len; -} - -/* from clause 20.2.14 Encoding of an Object Identifier Value */ -/* returns the number of apdu bytes consumed */ -int encode_bacnet_object_id(uint8_t * apdu, - int object_type, uint32_t instance) -{ - uint32_t value = 0; - uint32_t type = 0; - int len = 0; - - type = object_type; - value = ((type & BACNET_MAX_OBJECT) << BACNET_INSTANCE_BITS) | - (instance & BACNET_MAX_INSTANCE); - len = encode_unsigned32(apdu, value); - - return len; -} - -/* from clause 20.2.14 Encoding of an Object Identifier Value */ -/* and 20.2.1 General Rules for Encoding BACnet Tags */ -/* returns the number of apdu bytes consumed */ -int encode_context_object_id(uint8_t * apdu, - int tag_number, int object_type, uint32_t instance) -{ - int len = 0; - - /* assumes that the tag only consumes 1 octet */ - len = encode_bacnet_object_id(&apdu[1], object_type, instance); - /* we only reserved 1 byte for encoding the tag - check the limits */ - if ((tag_number <= 14) && (len <= 4)) - len += encode_tag(&apdu[0], (uint8_t) tag_number, true, len); - else - len = 0; - - return len; -} - -/* from clause 20.2.14 Encoding of an Object Identifier Value */ -/* and 20.2.1 General Rules for Encoding BACnet Tags */ -/* returns the number of apdu bytes consumed */ -int encode_application_object_id(uint8_t * apdu, - int object_type, uint32_t instance) -{ - int len = 0; - - /* assumes that the tag only consumes 1 octet */ - len = encode_bacnet_object_id(&apdu[1], object_type, instance); - len += encode_tag(&apdu[0], BACNET_APPLICATION_TAG_OBJECT_ID, - false, len); - - return len; -} - -/* from clause 20.2.8 Encoding of an Octet String Value */ -/* returns the number of apdu bytes consumed */ -int encode_octet_string(uint8_t * apdu, BACNET_OCTET_STRING * octet_string) -{ - int len = 0; /* return value */ - uint8_t *value; - int i = 0; /* loop counter */ - - if (octet_string) { - /* FIXME: might need to pass in the length of the APDU - to bounds check since it might not be the only data chunk */ - len = octetstring_length(octet_string); - value = octetstring_value(octet_string); - for (i = 0; i < len; i++) { - apdu[i] = value[i]; - } - } - - return len; -} - -/* from clause 20.2.8 Encoding of an Octet String Value */ -/* and 20.2.1 General Rules for Encoding BACnet Tags */ -/* returns the number of apdu bytes consumed */ -int encode_application_octet_string(uint8_t * apdu, - BACNET_OCTET_STRING * octet_string) -{ - int apdu_len = 0; - - if (octet_string) { - apdu_len = - encode_tag(&apdu[0], BACNET_APPLICATION_TAG_OCTET_STRING, - false, octetstring_length(octet_string)); - /* FIXME: probably need to pass in the length of the APDU - to bounds check since it might not be the only data chunk */ - if ((apdu_len + octetstring_length(octet_string)) < MAX_APDU) - apdu_len += encode_octet_string(&apdu[apdu_len], octet_string); - else - apdu_len = 0; - } - - return apdu_len; -} - -/* from clause 20.2.8 Encoding of an Octet String Value */ -/* and 20.2.1 General Rules for Encoding BACnet Tags */ -/* returns the number of apdu bytes consumed */ -int encode_context_octet_string(uint8_t * apdu, - int tag_number, BACNET_OCTET_STRING * octet_string) -{ - int apdu_len = 0; - - if (apdu && octet_string) { - apdu_len = encode_tag(&apdu[0], (uint8_t) tag_number, - true, octetstring_length(octet_string)); - if ((apdu_len + octetstring_length(octet_string)) < MAX_APDU) - apdu_len += encode_octet_string(&apdu[apdu_len], octet_string); - else - apdu_len = 0; - } - - return apdu_len; -} - -/* from clause 20.2.8 Encoding of an Octet String Value */ -/* and 20.2.1 General Rules for Encoding BACnet Tags */ -/* returns the number of apdu bytes consumed */ -int decode_octet_string(uint8_t * apdu, uint32_t len_value, - BACNET_OCTET_STRING * octet_string) -{ - int len = 0; /* return value */ - bool status = false; - - status = octetstring_init(octet_string, &apdu[0], len_value); - if (status) - len = len_value; - - return len; -} - -/* from clause 20.2.9 Encoding of a Character String Value */ -/* returns the number of apdu bytes consumed */ -int encode_bacnet_character_string(uint8_t * apdu, - BACNET_CHARACTER_STRING * char_string) -{ - int len, i; - char *pString; - - len = characterstring_length(char_string); - apdu[0] = characterstring_encoding(char_string); - pString = characterstring_value(char_string); - for (i = 0; i < len; i++) { - apdu[1 + i] = pString[i]; - } - - return len + 1 /* for encoding */ ; -} - -/* from clause 20.2.9 Encoding of a Character String Value */ -/* and 20.2.1 General Rules for Encoding BACnet Tags */ -/* returns the number of apdu bytes consumed */ -int encode_application_character_string(uint8_t * apdu, - BACNET_CHARACTER_STRING * char_string) -{ - int len = 0; - int string_len = 0; - - string_len = - characterstring_length(char_string) + 1 /* for encoding */ ; - len = - encode_tag(&apdu[0], BACNET_APPLICATION_TAG_CHARACTER_STRING, - false, string_len); - if ((len + string_len) < MAX_APDU) - len += encode_bacnet_character_string(&apdu[len], char_string); - else - len = 0; - - return len; -} - -int encode_context_character_string(uint8_t * apdu, int tag_number, - BACNET_CHARACTER_STRING * char_string) -{ - int len = 0; - int string_len = 0; - - string_len = - characterstring_length(char_string) + 1 /* for encoding */ ; - len += encode_tag(&apdu[0], (uint8_t) tag_number, true, string_len); - if ((len + string_len) < MAX_APDU) - len += encode_bacnet_character_string(&apdu[len], char_string); - else - len = 0; - - return len; -} - -/* from clause 20.2.9 Encoding of a Character String Value */ -/* and 20.2.1 General Rules for Encoding BACnet Tags */ -/* returns the number of apdu bytes consumed */ -int decode_character_string(uint8_t * apdu, uint32_t len_value, - BACNET_CHARACTER_STRING * char_string) -{ - int len = 0; /* return value */ - bool status = false; - - status = characterstring_init(char_string, apdu[0], (char *) &apdu[1], - len_value - 1); - if (status) - len = 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 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.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 */ -int encode_context_unsigned(uint8_t * apdu, int tag_number, uint32_t value) -{ - int len = 0; - - len = encode_bacnet_unsigned(&apdu[1], value); - /* we only reserved 1 byte for encoding the tag - check the limits */ - if ((tag_number <= 14) && (len <= 4)) - len += encode_tag(&apdu[0], (uint8_t) tag_number, true, len); - else - len = 0; - - 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_application_unsigned(uint8_t * apdu, uint32_t value) -{ - int len = 0; - - len = encode_bacnet_unsigned(&apdu[1], value); - len += encode_tag(&apdu[0], BACNET_APPLICATION_TAG_UNSIGNED_INT, - false, len); - - return len; -} - -/* 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 */ -int decode_enumerated(uint8_t * apdu, uint32_t len_value, int *value) -{ - uint32_t unsigned_value = 0; - int len; - - len = decode_unsigned(apdu, len_value, &unsigned_value); - if (value) - *value = unsigned_value; - - return len; -} - -/* 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 */ -int encode_bacnet_enumerated(uint8_t * apdu, int value) -{ - return encode_bacnet_unsigned(apdu, 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 */ -int encode_application_enumerated(uint8_t * apdu, int value) -{ - int len = 0; /* return value */ - - /* assumes that the tag only consumes 1 octet */ - len = encode_bacnet_enumerated(&apdu[1], value); - len += encode_tag(&apdu[0], BACNET_APPLICATION_TAG_ENUMERATED, - false, len); - - return len; -} - -/* 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 */ -int encode_context_enumerated(uint8_t * apdu, int tag_number, int value) -{ - int len = 0; /* return value */ - - /* assumes that the tag only consumes 1 octet */ - len = encode_bacnet_enumerated(&apdu[1], value); - /* we only reserved 1 byte for encoding the tag - check the limits */ - if ((tag_number <= 14) && (len <= 4)) - len += encode_tag(&apdu[0], (uint8_t) tag_number, true, len); - else - len = 0; - - 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 */ -int encode_application_signed(uint8_t * apdu, int32_t value) -{ - int len = 0; /* return value */ - - /* assumes that the tag only consumes 1 octet */ - len = encode_bacnet_signed(&apdu[1], value); - len += encode_tag(&apdu[0], BACNET_APPLICATION_TAG_SIGNED_INT, - false, len); - - 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 encode_context_signed(uint8_t * apdu, int tag_number, int32_t value) -{ - int len = 0; /* return value */ - - /* assumes that the tag only consumes 1 octet */ - len = encode_bacnet_signed(&apdu[1], value); - /* we only reserved 1 byte for encoding the tag - check the limits */ - if ((tag_number <= 14) && (len <= 4)) - len += encode_tag(&apdu[0], (uint8_t) tag_number, true, len); - else - len = 0; - - return len; -} - -/* from clause 20.2.13 Encoding of a Time Value */ -/* and 20.2.1 General Rules for Encoding BACnet Tags */ -/* returns the number of apdu bytes consumed */ -int encode_bacnet_time(uint8_t * apdu, BACNET_TIME * btime) -{ - apdu[0] = btime->hour; - apdu[1] = btime->min; - apdu[2] = btime->sec; - apdu[3] = btime->hundredths; - - return 4; -} - -/* from clause 20.2.13 Encoding of a Time Value */ -/* and 20.2.1 General Rules for Encoding BACnet Tags */ -/* returns the number of apdu bytes consumed */ -int encode_application_time(uint8_t * apdu, BACNET_TIME * btime) -{ - int len = 0; - - /* assumes that the tag only consumes 1 octet */ - len = encode_bacnet_time(&apdu[1], btime); - len += encode_tag(&apdu[0], BACNET_APPLICATION_TAG_TIME, false, len); - - return len; -} - -int encode_context_time(uint8_t * apdu, int tag_number, - BACNET_TIME * btime) -{ - int len = 0; /* return value */ - - /* assumes that the tag only consumes 1 octet */ - len = encode_bacnet_time(&apdu[1], btime); - /* we only reserved 1 byte for encoding the tag - check the limits */ - if ((tag_number <= 14) && (len <= 4)) - len += encode_tag(&apdu[0], (uint8_t) tag_number, true, len); - else - len = 0; - - return len; -} - -/* from clause 20.2.13 Encoding of a Time Value */ -/* and 20.2.1 General Rules for Encoding BACnet Tags */ -/* returns the number of apdu bytes consumed */ -int decode_bacnet_time(uint8_t * apdu, BACNET_TIME * btime) -{ - btime->hour = apdu[0]; - btime->min = apdu[1]; - btime->sec = apdu[2]; - btime->hundredths = apdu[3]; - - return 4; -} - -/* BACnet Date */ -/* year = years since 1900 */ -/* month 1=Jan */ -/* day = day of month */ -/* wday 1=Monday...7=Sunday */ - -/* from clause 20.2.12 Encoding of a Date Value */ -/* and 20.2.1 General Rules for Encoding BACnet Tags */ -/* returns the number of apdu bytes consumed */ -int encode_bacnet_date(uint8_t * apdu, BACNET_DATE * bdate) -{ - /* allow 2 digit years */ - if (bdate->year < 1900) { - if (bdate->year <= 38) - bdate->year += 2000; - else - bdate->year += 1900; - } - apdu[0] = bdate->year - 1900; - apdu[1] = bdate->month; - apdu[2] = bdate->day; - apdu[3] = bdate->wday; - - return 4; -} - -/* from clause 20.2.12 Encoding of a Date Value */ -/* and 20.2.1 General Rules for Encoding BACnet Tags */ -/* returns the number of apdu bytes consumed */ -int encode_application_date(uint8_t * apdu, BACNET_DATE * bdate) -{ - int len = 0; - - /* assumes that the tag only consumes 1 octet */ - len = encode_bacnet_date(&apdu[1], bdate); - len += encode_tag(&apdu[0], BACNET_APPLICATION_TAG_DATE, false, len); - - return len; - -} - -int encode_context_date(uint8_t * apdu, int tag_number, - BACNET_DATE * bdate) -{ - int len = 0; /* return value */ - - /* assumes that the tag only consumes 1 octet */ - len = encode_bacnet_date(&apdu[1], bdate); - /* we only reserved 1 byte for encoding the tag - check the limits */ - if ((tag_number <= 14) && (len <= 4)) - len += encode_tag(&apdu[0], (uint8_t) tag_number, true, len); - else - len = 0; - - return len; -} - -/* from clause 20.2.12 Encoding of a Date Value */ -/* and 20.2.1 General Rules for Encoding BACnet Tags */ -/* returns the number of apdu bytes consumed */ -int decode_date(uint8_t * apdu, BACNET_DATE * bdate) -{ - bdate->year = apdu[0] + 1900; - bdate->month = apdu[1]; - bdate->day = apdu[2]; - bdate->wday = apdu[3]; - - return 4; -} - -/* returns the number of apdu bytes consumed */ -int encode_simple_ack(uint8_t * apdu, uint8_t invoke_id, - uint8_t service_choice) -{ - apdu[0] = PDU_TYPE_SIMPLE_ACK; - apdu[1] = invoke_id; - apdu[2] = service_choice; - - return 3; -} - -/* end of decoding_encoding.c */ -#ifdef TEST #include #include #include #include "ctest.h" -static int get_apdu_len(bool extended_tag, uint32_t value) -{ - int test_len = 1; - - if (extended_tag) - test_len++; - if (value <= 4) - test_len += 0; /* do nothing... */ - else if (value <= 253) - test_len += 1; - else if (value <= 65535) - test_len += 3; - else - test_len += 5; - - return test_len; -} - -static void print_apdu(uint8_t * pBlock, uint32_t num) -{ - size_t lines = 0; /* number of lines to print */ - size_t line = 0; /* line of text counter */ - size_t last_line = 0; /* line on which the last text resided */ - unsigned long count = 0; /* address to print */ - unsigned int i = 0; /* counter */ - - if (pBlock && num) { - /* how many lines to print? */ - num--; /* adjust */ - lines = (num / 16) + 1; - last_line = num % 16; - - /* create the line */ - for (line = 0; line < lines; line++) { - /* start with the address */ - printf("%08lX: ", count); - /* hex representation */ - for (i = 0; i < 16; i++) { - if (((line == (lines - 1)) && (i <= last_line)) || - (line != (lines - 1))) { - printf("%02X ", (unsigned) (0x00FF & pBlock[i])); - } else - printf("-- "); - } - printf(" "); - /* print the characters if valid */ - for (i = 0; i < 16; i++) { - if (((line == (lines - 1)) && (i <= last_line)) || - (line != (lines - 1))) { - if (isprint(pBlock[i])) { - printf("%c", pBlock[i]); - } else - printf("."); - } else - printf("."); - } - printf("\r\n"); - pBlock += 16; - count += 16; - } - } - - return; -} - -void testBACDCodeTags(Test * pTest) -{ - uint8_t apdu[MAX_APDU] = { 0 }; - uint8_t tag_number = 0, test_tag_number = 0; - int len = 0, test_len = 0; - uint32_t value = 0, test_value = 0; - - for (tag_number = 0;; tag_number++) { - len = encode_opening_tag(&apdu[0], tag_number); - test_len = - get_apdu_len(decode_is_extended_tag_number(&apdu[0]), 0); - ct_test(pTest, len == test_len); - len = - decode_tag_number_and_value(&apdu[0], &test_tag_number, - &value); - ct_test(pTest, value == 0); - ct_test(pTest, len == test_len); - ct_test(pTest, tag_number == test_tag_number); - ct_test(pTest, decode_is_opening_tag(&apdu[0]) == true); - ct_test(pTest, decode_is_closing_tag(&apdu[0]) == false); - len = encode_closing_tag(&apdu[0], tag_number); - ct_test(pTest, len == test_len); - len = - decode_tag_number_and_value(&apdu[0], &test_tag_number, - &value); - ct_test(pTest, len == test_len); - ct_test(pTest, value == 0); - ct_test(pTest, tag_number == test_tag_number); - ct_test(pTest, decode_is_opening_tag(&apdu[0]) == false); - ct_test(pTest, decode_is_closing_tag(&apdu[0]) == true); - /* test the len-value-type portion */ - for (value = 1;; value = value << 1) { - len = encode_tag(&apdu[0], tag_number, false, value); - len = decode_tag_number_and_value(&apdu[0], &test_tag_number, - &test_value); - ct_test(pTest, tag_number == test_tag_number); - ct_test(pTest, value == test_value); - test_len = - get_apdu_len(decode_is_extended_tag_number(&apdu[0]), - value); - ct_test(pTest, len == test_len); - /* stop at the the last value */ - if (value & BIT31) - break; - } - /* stop after the last tag number */ - if (tag_number == 255) - break; - } - - return; -} - -void testBACDCodeReal(Test * pTest) -{ - uint8_t real_array[4] = { 0 }; - uint8_t encoded_array[4] = { 0 }; - float value = 42.123; - float decoded_value = 0; - uint8_t apdu[MAX_APDU] = { 0 }; - int len = 0, apdu_len = 0; - uint8_t tag_number = 0; - uint32_t long_value = 0; - - encode_bacnet_real(value, &real_array[0]); - decode_real(&real_array[0], &decoded_value); - ct_test(pTest, decoded_value == value); - encode_bacnet_real(value, &encoded_array[0]); - ct_test(pTest, memcmp(&real_array, &encoded_array, - sizeof(real_array)) == 0); - - /* a real will take up 4 octects plus a one octet tag */ - apdu_len = encode_application_real(&apdu[0], value); - ct_test(pTest, apdu_len == 5); - /* len tells us how many octets were used for encoding the value */ - len = decode_tag_number_and_value(&apdu[0], &tag_number, &long_value); - ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_REAL); - ct_test(pTest, decode_is_context_specific(&apdu[0]) == false); - ct_test(pTest, len == 1); - ct_test(pTest, long_value == 4); - decode_real(&apdu[len], &decoded_value); - ct_test(pTest, decoded_value == value); - - return; -} - -void testBACDCodeEnumerated(Test * pTest) -{ - uint8_t array[5] = { 0 }; - uint8_t encoded_array[5] = { 0 }; - int value = 1; - int decoded_value = 0; - int i = 0, apdu_len = 0; - int len = 0; - uint8_t apdu[MAX_APDU] = { 0 }; - uint8_t tag_number = 0; - uint32_t len_value = 0; - - for (i = 0; i < 31; i++) { - apdu_len = encode_application_enumerated(&array[0], value); - len = - decode_tag_number_and_value(&array[0], &tag_number, - &len_value); - len += decode_enumerated(&array[len], len_value, &decoded_value); - ct_test(pTest, decoded_value == value); - ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_ENUMERATED); - ct_test(pTest, len == apdu_len); - /* encode back the value */ - encode_application_enumerated(&encoded_array[0], decoded_value); - ct_test(pTest, memcmp(&array[0], &encoded_array[0], - sizeof(array)) == 0); - /* an enumerated will take up to 4 octects */ - /* plus a one octet for the tag */ - apdu_len = encode_application_enumerated(&apdu[0], value); - len = decode_tag_number_and_value(&apdu[0], &tag_number, NULL); - ct_test(pTest, len == 1); - ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_ENUMERATED); - ct_test(pTest, decode_is_context_specific(&apdu[0]) == false); - /* context specific encoding */ - apdu_len = encode_context_enumerated(&apdu[0], 3, value); - ct_test(pTest, decode_is_context_specific(&apdu[0]) == true); - len = decode_tag_number_and_value(&apdu[0], &tag_number, NULL); - ct_test(pTest, len == 1); - ct_test(pTest, tag_number == 3); - /* test the interesting values */ - value = value << 1; - } - - return; -} - -void testBACDCodeUnsignedValue(Test * pTest, uint32_t value) -{ - uint8_t array[5] = { 0 }; - uint8_t encoded_array[5] = { 0 }; - uint32_t decoded_value = 0; - int len, apdu_len; - uint8_t apdu[MAX_APDU] = { 0 }; - uint8_t tag_number = 0; - uint32_t len_value = 0; - - len_value = encode_application_unsigned(&array[0], value); - len = decode_tag_number_and_value(&array[0], &tag_number, &len_value); - len = decode_unsigned(&array[len], len_value, &decoded_value); - ct_test(pTest, decoded_value == value); - if (decoded_value != value) { - printf("value=%u decoded_value=%u\n", value, decoded_value); - print_apdu(&array[0], sizeof(array)); - } - encode_application_unsigned(&encoded_array[0], decoded_value); - ct_test(pTest, memcmp(&array[0], &encoded_array[0], - sizeof(array)) == 0); - /* an unsigned will take up to 4 octects */ - /* plus a one octet for the tag */ - apdu_len = encode_application_unsigned(&apdu[0], value); - /* apdu_len varies... */ - /*ct_test(pTest, apdu_len == 5); */ - len = decode_tag_number_and_value(&apdu[0], &tag_number, NULL); - ct_test(pTest, len == 1); - ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_UNSIGNED_INT); - ct_test(pTest, decode_is_context_specific(&apdu[0]) == false); -} - -void testBACDCodeUnsigned(Test * pTest) -{ - uint32_t value = 1; - int i; - - for (i = 0; i < 32; i++) { - testBACDCodeUnsignedValue(pTest, value - 1); - testBACDCodeUnsignedValue(pTest, value); - testBACDCodeUnsignedValue(pTest, value + 1); - value = value << 1; - } - - return; -} - -void testBACnetUnsigned(Test * pTest) -{ - uint8_t apdu[32] = { 0 }; - uint32_t value = 0, test_value = 0; - int len = 0, test_len = 0; - - for (value = 0; ;value+=0xFF) { - len = encode_bacnet_unsigned(&apdu[0], value); - test_len = decode_unsigned(&apdu[0], len, &test_value); - ct_test(pTest, len == test_len); - ct_test(pTest, value == test_value); - if (value == 0xFFFFFFFF) - break; - } -} - -void testBACDCodeSignedValue(Test * pTest, int32_t value) -{ - uint8_t array[5] = { 0 }; - uint8_t encoded_array[5] = { 0 }; - int32_t decoded_value = 0; - int len = 0, apdu_len = 0; - uint8_t apdu[MAX_APDU] = { 0 }; - uint8_t tag_number = 0; - uint32_t len_value = 0; - int diff = 0; - - len = encode_application_signed(&array[0], value); - len = decode_tag_number_and_value(&array[0], &tag_number, &len_value); - len = decode_signed(&array[len], len_value, &decoded_value); - ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_SIGNED_INT); - ct_test(pTest, decoded_value == value); - if (decoded_value != value) { - printf("value=%d decoded_value=%d\n", value, decoded_value); - print_apdu(&array[0], sizeof(array)); - } - encode_application_signed(&encoded_array[0], decoded_value); - diff = memcmp(&array[0], &encoded_array[0], sizeof(array)); - ct_test(pTest, diff == 0); - if (diff) { - printf("value=%d decoded_value=%d\n", value, decoded_value); - print_apdu(&array[0], sizeof(array)); - print_apdu(&encoded_array[0], sizeof(array)); - } - /* a signed int will take up to 4 octects */ - /* plus a one octet for the tag */ - apdu_len = encode_application_signed(&apdu[0], value); - len = decode_tag_number_and_value(&apdu[0], &tag_number, NULL); - ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_SIGNED_INT); - ct_test(pTest, decode_is_context_specific(&apdu[0]) == false); - - return; -} - -void testBACDCodeSigned(Test * pTest) -{ - int value = 1; - int i = 0; - - for (i = 0; i < 32; i++) { - testBACDCodeSignedValue(pTest, value - 1); - testBACDCodeSignedValue(pTest, value); - testBACDCodeSignedValue(pTest, value + 1); - value = value << 1; - } - - testBACDCodeSignedValue(pTest, -1); - value = -2; - for (i = 0; i < 32; i++) { - testBACDCodeSignedValue(pTest, value - 1); - testBACDCodeSignedValue(pTest, value); - testBACDCodeSignedValue(pTest, value + 1); - value = value << 1; - } - - return; -} - -void testBACnetSigned(Test * pTest) -{ - uint8_t apdu[32] = { 0 }; - int32_t value = 0, test_value = 0; - int len = 0, test_len = 0; - - for (value = -2147483647; value < 0; value+=127) { - len = encode_bacnet_signed(&apdu[0], value); - test_len = decode_signed(&apdu[0], len, &test_value); - ct_test(pTest, len == test_len); - ct_test(pTest, value == test_value); - } - for (value = 2147483647; value > 0; value-=127) { - len = encode_bacnet_signed(&apdu[0], value); - test_len = decode_signed(&apdu[0], len, &test_value); - ct_test(pTest, len == test_len); - ct_test(pTest, value == test_value); - } -} - -void testBACDCodeOctetString(Test * pTest) -{ - uint8_t array[MAX_APDU] = { 0 }; - uint8_t encoded_array[MAX_APDU] = { 0 }; - BACNET_OCTET_STRING octet_string; - BACNET_OCTET_STRING test_octet_string; - uint8_t test_value[MAX_APDU] = { "" }; - int i; /* for loop counter */ - int apdu_len; - int len; - uint8_t tag_number = 0; - uint32_t len_value = 0; - bool status = false; - int diff = 0; /* for memcmp */ - - status = octetstring_init(&octet_string, NULL, 0); - ct_test(pTest, status == true); - apdu_len = encode_application_octet_string(&array[0], &octet_string); - len = decode_tag_number_and_value(&array[0], &tag_number, &len_value); - ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OCTET_STRING); - len += decode_octet_string(&array[len], len_value, &test_octet_string); - ct_test(pTest, apdu_len == len); - diff = memcmp(octetstring_value(&octet_string), &test_value[0], - octetstring_length(&octet_string)); - ct_test(pTest, diff == 0); - - for (i = 0; i < (MAX_APDU - 6); i++) { - test_value[i] = '0' + (i % 10); - status = octetstring_init(&octet_string, test_value, i); - ct_test(pTest, status == true); - apdu_len = - encode_application_octet_string(&encoded_array[0], &octet_string); - len = - decode_tag_number_and_value(&encoded_array[0], &tag_number, - &len_value); - ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OCTET_STRING); - len += decode_octet_string(&encoded_array[len], len_value, - &test_octet_string); - if (apdu_len != len) { - printf("test octet string=#%d\n", i); - } - ct_test(pTest, apdu_len == len); - diff = memcmp(octetstring_value(&octet_string), &test_value[0], - octetstring_length(&octet_string)); - if (diff) { - printf("test octet string=#%d\n", i); - } - ct_test(pTest, diff == 0); - } - - return; -} - -void testBACDCodeCharacterString(Test * pTest) -{ - uint8_t array[MAX_APDU] = { 0 }; - uint8_t encoded_array[MAX_APDU] = { 0 }; - BACNET_CHARACTER_STRING char_string; - BACNET_CHARACTER_STRING test_char_string; - char test_value[MAX_APDU] = { "" }; - int i; /* for loop counter */ - int apdu_len; - int len; - uint8_t tag_number = 0; - uint32_t len_value = 0; - int diff = 0; /* for comparison */ - bool status = false; - - status = characterstring_init(&char_string, - CHARACTER_ANSI_X34, NULL, 0); - ct_test(pTest, status == true); - apdu_len = encode_application_character_string(&array[0], &char_string); - len = decode_tag_number_and_value(&array[0], &tag_number, &len_value); - ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_CHARACTER_STRING); - len += - decode_character_string(&array[len], len_value, &test_char_string); - ct_test(pTest, apdu_len == len); - diff = memcmp(characterstring_value(&char_string), &test_value[0], - characterstring_length(&char_string)); - ct_test(pTest, diff == 0); - for (i = 0; i < MAX_CHARACTER_STRING_BYTES - 1; i++) { - test_value[i] = 'S'; - test_value[i + 1] = '\0'; - status = characterstring_init_ansi(&char_string, test_value); - ct_test(pTest, status == true); - apdu_len = - encode_application_character_string(&encoded_array[0], - &char_string); - len = - decode_tag_number_and_value(&encoded_array[0], &tag_number, - &len_value); - ct_test(pTest, - tag_number == BACNET_APPLICATION_TAG_CHARACTER_STRING); - len += - decode_character_string(&encoded_array[len], len_value, - &test_char_string); - if (apdu_len != len) { - printf("test string=#%d apdu_len=%d len=%d\n", i, apdu_len, - len); - } - ct_test(pTest, apdu_len == len); - diff = memcmp(characterstring_value(&char_string), &test_value[0], - characterstring_length(&char_string)); - if (diff) { - printf("test string=#%d\n", i); - } - ct_test(pTest, diff == 0); - } - - return; -} - -void testBACDCodeObject(Test * pTest) -{ - uint8_t object_array[4] = { - 0 - }; - uint8_t encoded_array[4] = { - 0 - }; - BACNET_OBJECT_TYPE type = OBJECT_BINARY_INPUT; - BACNET_OBJECT_TYPE decoded_type = OBJECT_ANALOG_OUTPUT; - uint32_t instance = 123; - uint32_t decoded_instance = 0; - - encode_bacnet_object_id(&encoded_array[0], type, instance); - decode_object_id(&encoded_array[0], - (int *) &decoded_type, &decoded_instance); - ct_test(pTest, decoded_type == type); - ct_test(pTest, decoded_instance == instance); - encode_bacnet_object_id(&object_array[0], type, instance); - ct_test(pTest, memcmp(&object_array[0], &encoded_array[0], - sizeof(object_array)) == 0); - for (type = 0; type < 1024; type++) { - for (instance = 0; instance <= BACNET_MAX_INSTANCE; - instance += 1024) { - encode_bacnet_object_id(&encoded_array[0], type, instance); - decode_object_id(&encoded_array[0], - (int *) &decoded_type, &decoded_instance); - ct_test(pTest, decoded_type == type); - ct_test(pTest, decoded_instance == instance); - encode_bacnet_object_id(&object_array[0], type, instance); - ct_test(pTest, memcmp(&object_array[0], - &encoded_array[0], sizeof(object_array)) == 0); - } - } - - return; -} - -void testBACDCodeMaxSegsApdu(Test * pTest) -{ - int max_segs[8] = { 0, 2, 4, 8, 16, 32, 64, 65 }; - int max_apdu[6] = { 50, 128, 206, 480, 1024, 1476 }; - int i = 0; - int j = 0; - uint8_t octet = 0; - - /* test */ - for (i = 0; i < 8; i++) { - for (j = 0; j < 6; j++) { - octet = encode_max_segs_max_apdu(max_segs[i], max_apdu[j]); - ct_test(pTest, max_segs[i] == decode_max_segs(octet)); - ct_test(pTest, max_apdu[j] == decode_max_apdu(octet)); - } - } -} - -void testBACDCodeBitString(Test * pTest) -{ - uint8_t bit = 0; - BACNET_BIT_STRING bit_string; - BACNET_BIT_STRING decoded_bit_string; - uint8_t apdu[MAX_APDU] = { 0 }; - uint32_t len_value = 0; - uint8_t tag_number = 0; - int len = 0; - - bitstring_init(&bit_string); - /* verify initialization */ - ct_test(pTest, bitstring_bits_used(&bit_string) == 0); - for (bit = 0; bit < (MAX_BITSTRING_BYTES * 8); bit++) { - ct_test(pTest, bitstring_bit(&bit_string, bit) == false); - } - /* test encode/decode -- true */ - for (bit = 0; bit < (MAX_BITSTRING_BYTES * 8); bit++) { - bitstring_set_bit(&bit_string, bit, true); - ct_test(pTest, bitstring_bits_used(&bit_string) == (bit + 1)); - ct_test(pTest, bitstring_bit(&bit_string, bit) == true); - /* encode */ - len = encode_application_bitstring(&apdu[0], &bit_string); - /* decode */ - len = - decode_tag_number_and_value(&apdu[0], &tag_number, &len_value); - ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_BIT_STRING); - len += - decode_bitstring(&apdu[len], len_value, &decoded_bit_string); - ct_test(pTest, - bitstring_bits_used(&decoded_bit_string) == (bit + 1)); - ct_test(pTest, bitstring_bit(&decoded_bit_string, bit) == true); - } - /* test encode/decode -- false */ - bitstring_init(&bit_string); - for (bit = 0; bit < (MAX_BITSTRING_BYTES * 8); bit++) { - bitstring_set_bit(&bit_string, bit, false); - ct_test(pTest, bitstring_bits_used(&bit_string) == (bit + 1)); - ct_test(pTest, bitstring_bit(&bit_string, bit) == false); - /* encode */ - len = encode_application_bitstring(&apdu[0], &bit_string); - /* decode */ - len = - decode_tag_number_and_value(&apdu[0], &tag_number, &len_value); - ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_BIT_STRING); - len += - decode_bitstring(&apdu[len], len_value, &decoded_bit_string); - ct_test(pTest, - bitstring_bits_used(&decoded_bit_string) == (bit + 1)); - ct_test(pTest, bitstring_bit(&decoded_bit_string, bit) == false); - } -} - -#ifdef TEST_DECODE int main(void) { Test *pTest; @@ -1850,6 +83,12 @@ int main(void) assert(rc); rc = ct_addTestFunction(pTest, testBACDCodeBitString); assert(rc); + rc = ct_addTestFunction(pTest, testBitString); + assert(rc); + rc = ct_addTestFunction(pTest, testCharacterString); + assert(rc); + rc = ct_addTestFunction(pTest, testOctetString); + assert(rc); /* configure output */ ct_setStream(pTest, stdout); ct_run(pTest); @@ -1858,5 +97,3 @@ int main(void) return 0; } -#endif /* TEST_DECODE */ -#endif /* TEST */ diff --git a/bacnet-stack/src/bacdcode/octetstring.c b/bacnet-stack/src/bacdcode/octetstring.c index cd142503..90c3fab3 100644 --- a/bacnet-stack/src/bacdcode/octetstring.c +++ b/bacnet-stack/src/bacdcode/octetstring.c @@ -38,317 +38,6 @@ #include "bacstr.h" #include "bits.h" -void bitstring_init(BACNET_BIT_STRING * bit_string) -{ - int i; - - bit_string->bits_used = 0; - for (i = 0; i < MAX_BITSTRING_BYTES; i++) { - bit_string->value[i] = 0; - } -} - -void bitstring_set_bit(BACNET_BIT_STRING * bit_string, uint8_t bit, - bool value) -{ - uint8_t byte_number = bit / 8; - uint8_t bit_mask = 1; - - if (byte_number < MAX_BITSTRING_BYTES) { - /* set max bits used */ - if (bit_string->bits_used < (bit + 1)) - bit_string->bits_used = bit + 1; - bit_mask = bit_mask << (bit - (byte_number * 8)); - if (value) - bit_string->value[byte_number] |= bit_mask; - else - bit_string->value[byte_number] &= (~(bit_mask)); - } -} - -bool bitstring_bit(BACNET_BIT_STRING * bit_string, uint8_t bit) -{ - bool value = false; - uint8_t byte_number = bit / 8; - uint8_t bit_mask = 1; - - if (bit < (MAX_BITSTRING_BYTES * 8)) { - bit_mask = bit_mask << (bit - (byte_number * 8)); - if (bit_string->value[byte_number] & bit_mask) - value = true; - } - - return value; -} - -uint8_t bitstring_bits_used(BACNET_BIT_STRING * bit_string) -{ - return bit_string->bits_used; -} - -/* returns the number of bytes that a bit string is using */ -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; -} - -uint8_t bitstring_octet(BACNET_BIT_STRING * bit_string, uint8_t index) -{ - uint8_t octet = 0; - - if (bit_string) { - if (index < MAX_BITSTRING_BYTES) { - octet = bit_string->value[index]; - } - } - - return octet; -} - -bool bitstring_set_octet(BACNET_BIT_STRING * bit_string, - uint8_t index, uint8_t octet) -{ - bool status = false; - - if (bit_string) { - if (index < MAX_BITSTRING_BYTES) { - bit_string->value[index] = octet; - status = true; - } - } - - return status; -} - -bool bitstring_set_bits_used(BACNET_BIT_STRING * bit_string, - uint8_t bytes_used, uint8_t unused_bits) -{ - bool status = false; - - if (bit_string) { - /* FIXME: check that bytes_used is at least one? */ - bit_string->bits_used = bytes_used * 8; - bit_string->bits_used -= unused_bits; - status = true; - } - - return status; -} - -uint8_t bitstring_bits_capacity(BACNET_BIT_STRING * bit_string) -{ - if (bit_string) - return (sizeof(bit_string->value) * 8); - else - return 0; -} - -#define CHARACTER_STRING_CAPACITY (MAX_CHARACTER_STRING_BYTES - 1) -/* returns false if the string exceeds capacity - initialize by using length=0 */ -bool characterstring_init(BACNET_CHARACTER_STRING * char_string, - uint8_t encoding, char *value, size_t length) -{ - bool status = false; /* return value */ - size_t i; /* counter */ - - if (char_string) { - char_string->length = 0; - char_string->encoding = encoding; - /* save a byte at the end for NULL - - note: assumes printable characters */ - if (length <= CHARACTER_STRING_CAPACITY) { - if (value) { - for (i = 0; i < MAX_CHARACTER_STRING_BYTES; i++) { - if (i < length) { - char_string->value[char_string->length] = value[i]; - char_string->length++; - } else - char_string->value[i] = 0; - } - } else { - for (i = 0; i < MAX_CHARACTER_STRING_BYTES; i++) { - char_string->value[i] = 0; - } - } - status = true; - } - } - - return status; -} - -bool characterstring_init_ansi(BACNET_CHARACTER_STRING * char_string, - char *value) -{ - return characterstring_init(char_string, - CHARACTER_ANSI_X34, value, value ? strlen(value) : 0); -} - -bool characterstring_copy(BACNET_CHARACTER_STRING * dest, - BACNET_CHARACTER_STRING * src) -{ - return characterstring_init(dest, - characterstring_encoding(src), - characterstring_value(src), characterstring_length(src)); -} - -bool characterstring_same(BACNET_CHARACTER_STRING * dest, - BACNET_CHARACTER_STRING * src) -{ - size_t i; /* counter */ - bool same_status = false; - - if (src && dest) { - if ((src->length == dest->length) && - (src->encoding == dest->encoding)) { - same_status = true; - for (i = 0; i < src->length; i++) { - if (src->value[i] != dest->value[i]) { - same_status = false; - break; - } - } - } - } else if (src) { - if (src->length == 0) - same_status = true; - } else if (dest) { - if (dest->length == 0) - same_status = true; - } - - return same_status; -} - -bool characterstring_ansi_same(BACNET_CHARACTER_STRING * dest, - const char *src) -{ - size_t i; /* counter */ - bool same_status = false; - - if (src && dest) { - if ((dest->length == strlen(src)) && - (dest->encoding == CHARACTER_ANSI_X34)) { - same_status = true; - for (i = 0; i < dest->length; i++) { - if (src[i] != dest->value[i]) { - same_status = false; - break; - } - } - } - } - /* NULL matches an empty string in our world */ - else if (src) { - if (strlen(src) == 0) - same_status = true; - } else if (dest) { - if (dest->length == 0) - same_status = true; - } - - return same_status; -} - -/* returns false if the string exceeds capacity */ -bool characterstring_append(BACNET_CHARACTER_STRING * char_string, - char *value, size_t length) -{ - size_t i; /* counter */ - bool status = false; /* return value */ - - if (char_string) { - if ((length + char_string->length) <= CHARACTER_STRING_CAPACITY) { - for (i = 0; i < length; i++) { - char_string->value[char_string->length] = value[i]; - char_string->length++; - } - status = true; - } - } - - return status; -} - -/* This function sets a new length without changing the value. - If length exceeds capacity, no modification happens and - function returns false. */ -bool characterstring_truncate(BACNET_CHARACTER_STRING * char_string, - size_t length) -{ - bool status = false; /* return value */ - - if (char_string) { - if (length <= CHARACTER_STRING_CAPACITY) { - char_string->length = length; - status = true; - } - } - - return status; -} - -/* Returns the value. */ -char *characterstring_value(BACNET_CHARACTER_STRING * char_string) -{ - char *value = NULL; - - if (char_string) { - value = char_string->value; - } - - return value; -} - -/* returns the length. */ -size_t characterstring_length(BACNET_CHARACTER_STRING * char_string) -{ - size_t length = 0; - - if (char_string) { - /* FIXME: validate length is within bounds? */ - length = char_string->length; - } - - return length; -} - -size_t characterstring_capacity(BACNET_CHARACTER_STRING * char_string) -{ - size_t length = 0; - - if (char_string) { - length = CHARACTER_STRING_CAPACITY; - } - - return length; -} - -/* returns the encoding. */ -uint8_t characterstring_encoding(BACNET_CHARACTER_STRING * char_string) -{ - uint8_t encoding = 0; - - if (char_string) { - encoding = char_string->encoding; - } - - return encoding; -} - /* returns false if the string exceeds capacity initialize by using length=0 */ bool octetstring_init(BACNET_OCTET_STRING * octet_string, @@ -459,179 +148,3 @@ size_t octetstring_capacity(BACNET_OCTET_STRING * octet_string) return length; } - -#ifdef TEST -#include -#include -#include "ctest.h" - -void testBitString(Test * pTest) -{ - uint8_t bit = 0; - BACNET_BIT_STRING bit_string; - - bitstring_init(&bit_string); - /* verify initialization */ - ct_test(pTest, bitstring_bits_used(&bit_string) == 0); - for (bit = 0; bit < (MAX_BITSTRING_BYTES * 8); bit++) { - ct_test(pTest, bitstring_bit(&bit_string, bit) == false); - } - - /* test for true */ - for (bit = 0; bit < (MAX_BITSTRING_BYTES * 8); bit++) { - bitstring_set_bit(&bit_string, bit, true); - ct_test(pTest, bitstring_bits_used(&bit_string) == (bit + 1)); - ct_test(pTest, bitstring_bit(&bit_string, bit) == true); - } - /* test for false */ - bitstring_init(&bit_string); - for (bit = 0; bit < (MAX_BITSTRING_BYTES * 8); bit++) { - bitstring_set_bit(&bit_string, bit, false); - ct_test(pTest, bitstring_bits_used(&bit_string) == (bit + 1)); - ct_test(pTest, bitstring_bit(&bit_string, bit) == false); - } -} - -void testCharacterString(Test * pTest) -{ - BACNET_CHARACTER_STRING bacnet_string; - char *value = "Joshua,Mary,Anna,Christopher"; - char test_value[MAX_APDU] = "Patricia"; - char test_append_value[MAX_APDU] = " and the Kids"; - char test_append_string[MAX_APDU] = ""; - bool status = false; - size_t length = 0; - size_t test_length = 0; - size_t i = 0; - - /* verify initialization */ - status = - characterstring_init(&bacnet_string, CHARACTER_ANSI_X34, NULL, 0); - ct_test(pTest, status == true); - ct_test(pTest, characterstring_length(&bacnet_string) == 0); - ct_test(pTest, - characterstring_encoding(&bacnet_string) == CHARACTER_ANSI_X34); - /* bounds check */ - status = characterstring_init(&bacnet_string, - CHARACTER_ANSI_X34, - NULL, characterstring_capacity(&bacnet_string) + 1); - ct_test(pTest, status == false); - status = - characterstring_truncate(&bacnet_string, - characterstring_capacity(&bacnet_string) + 1); - ct_test(pTest, status == false); - status = - characterstring_truncate(&bacnet_string, - characterstring_capacity(&bacnet_string)); - ct_test(pTest, status == true); - - test_length = strlen(test_value); - status = characterstring_init(&bacnet_string, - CHARACTER_ANSI_X34, &test_value[0], test_length); - ct_test(pTest, status == true); - value = characterstring_value(&bacnet_string); - length = characterstring_length(&bacnet_string); - ct_test(pTest, length == test_length); - for (i = 0; i < test_length; i++) { - ct_test(pTest, value[i] == test_value[i]); - } - test_length = strlen(test_append_value); - status = characterstring_append(&bacnet_string, - &test_append_value[0], test_length); - strcat(test_append_string, test_value); - strcat(test_append_string, test_append_value); - test_length = strlen(test_append_string); - ct_test(pTest, status == true); - length = characterstring_length(&bacnet_string); - value = characterstring_value(&bacnet_string); - ct_test(pTest, length == test_length); - for (i = 0; i < test_length; i++) { - ct_test(pTest, value[i] == test_append_string[i]); - } -} - -void testOctetString(Test * pTest) -{ - BACNET_OCTET_STRING bacnet_string; - uint8_t *value = NULL; - uint8_t test_value[MAX_APDU] = "Patricia"; - uint8_t test_append_value[MAX_APDU] = " and the Kids"; - uint8_t test_append_string[MAX_APDU] = ""; - bool status = false; - size_t length = 0; - size_t test_length = 0; - size_t i = 0; - - /* verify initialization */ - status = octetstring_init(&bacnet_string, NULL, 0); - ct_test(pTest, status == true); - ct_test(pTest, octetstring_length(&bacnet_string) == 0); - value = octetstring_value(&bacnet_string); - for (i = 0; i < octetstring_capacity(&bacnet_string); i++) { - ct_test(pTest, value[i] == 0); - } - /* bounds check */ - status = octetstring_init(&bacnet_string, NULL, - octetstring_capacity(&bacnet_string) + 1); - ct_test(pTest, status == false); - status = octetstring_init(&bacnet_string, NULL, - octetstring_capacity(&bacnet_string)); - ct_test(pTest, status == true); - status = - octetstring_truncate(&bacnet_string, - octetstring_capacity(&bacnet_string) + 1); - ct_test(pTest, status == false); - status = - octetstring_truncate(&bacnet_string, - octetstring_capacity(&bacnet_string)); - ct_test(pTest, status == true); - - test_length = strlen((char *) test_value); - status = octetstring_init(&bacnet_string, &test_value[0], test_length); - ct_test(pTest, status == true); - length = octetstring_length(&bacnet_string); - value = octetstring_value(&bacnet_string); - ct_test(pTest, length == test_length); - for (i = 0; i < test_length; i++) { - ct_test(pTest, value[i] == test_value[i]); - } - - test_length = strlen((char *) test_append_value); - status = octetstring_append(&bacnet_string, - &test_append_value[0], test_length); - strcat((char *) test_append_string, (char *) test_value); - strcat((char *) test_append_string, (char *) test_append_value); - test_length = strlen((char *) test_append_string); - ct_test(pTest, status == true); - length = octetstring_length(&bacnet_string); - value = octetstring_value(&bacnet_string); - ct_test(pTest, length == test_length); - for (i = 0; i < test_length; i++) { - ct_test(pTest, value[i] == test_append_string[i]); - } -} - -#ifdef TEST_BACSTR -int main(void) -{ - Test *pTest; - bool rc; - - pTest = ct_create("BACnet Strings", NULL); - /* individual tests */ - rc = ct_addTestFunction(pTest, testBitString); - assert(rc); - rc = ct_addTestFunction(pTest, testCharacterString); - assert(rc); - rc = ct_addTestFunction(pTest, testOctetString); - assert(rc); - /* configure output */ - ct_setStream(pTest, stdout); - ct_run(pTest); - (void) ct_report(pTest); - ct_destroy(pTest); - - return 0; -} -#endif /* TEST_BACSTR */ -#endif /* TEST */ diff --git a/bacnet-stack/src/bacdcode/octetstring_test.c b/bacnet-stack/src/bacdcode/octetstring_test.c index cd142503..1c1a7aab 100644 --- a/bacnet-stack/src/bacdcode/octetstring_test.c +++ b/bacnet-stack/src/bacdcode/octetstring_test.c @@ -37,519 +37,10 @@ #include /* for strlen */ #include "bacstr.h" #include "bits.h" - -void bitstring_init(BACNET_BIT_STRING * bit_string) -{ - int i; - - bit_string->bits_used = 0; - for (i = 0; i < MAX_BITSTRING_BYTES; i++) { - bit_string->value[i] = 0; - } -} - -void bitstring_set_bit(BACNET_BIT_STRING * bit_string, uint8_t bit, - bool value) -{ - uint8_t byte_number = bit / 8; - uint8_t bit_mask = 1; - - if (byte_number < MAX_BITSTRING_BYTES) { - /* set max bits used */ - if (bit_string->bits_used < (bit + 1)) - bit_string->bits_used = bit + 1; - bit_mask = bit_mask << (bit - (byte_number * 8)); - if (value) - bit_string->value[byte_number] |= bit_mask; - else - bit_string->value[byte_number] &= (~(bit_mask)); - } -} - -bool bitstring_bit(BACNET_BIT_STRING * bit_string, uint8_t bit) -{ - bool value = false; - uint8_t byte_number = bit / 8; - uint8_t bit_mask = 1; - - if (bit < (MAX_BITSTRING_BYTES * 8)) { - bit_mask = bit_mask << (bit - (byte_number * 8)); - if (bit_string->value[byte_number] & bit_mask) - value = true; - } - - return value; -} - -uint8_t bitstring_bits_used(BACNET_BIT_STRING * bit_string) -{ - return bit_string->bits_used; -} - -/* returns the number of bytes that a bit string is using */ -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; -} - -uint8_t bitstring_octet(BACNET_BIT_STRING * bit_string, uint8_t index) -{ - uint8_t octet = 0; - - if (bit_string) { - if (index < MAX_BITSTRING_BYTES) { - octet = bit_string->value[index]; - } - } - - return octet; -} - -bool bitstring_set_octet(BACNET_BIT_STRING * bit_string, - uint8_t index, uint8_t octet) -{ - bool status = false; - - if (bit_string) { - if (index < MAX_BITSTRING_BYTES) { - bit_string->value[index] = octet; - status = true; - } - } - - return status; -} - -bool bitstring_set_bits_used(BACNET_BIT_STRING * bit_string, - uint8_t bytes_used, uint8_t unused_bits) -{ - bool status = false; - - if (bit_string) { - /* FIXME: check that bytes_used is at least one? */ - bit_string->bits_used = bytes_used * 8; - bit_string->bits_used -= unused_bits; - status = true; - } - - return status; -} - -uint8_t bitstring_bits_capacity(BACNET_BIT_STRING * bit_string) -{ - if (bit_string) - return (sizeof(bit_string->value) * 8); - else - return 0; -} - -#define CHARACTER_STRING_CAPACITY (MAX_CHARACTER_STRING_BYTES - 1) -/* returns false if the string exceeds capacity - initialize by using length=0 */ -bool characterstring_init(BACNET_CHARACTER_STRING * char_string, - uint8_t encoding, char *value, size_t length) -{ - bool status = false; /* return value */ - size_t i; /* counter */ - - if (char_string) { - char_string->length = 0; - char_string->encoding = encoding; - /* save a byte at the end for NULL - - note: assumes printable characters */ - if (length <= CHARACTER_STRING_CAPACITY) { - if (value) { - for (i = 0; i < MAX_CHARACTER_STRING_BYTES; i++) { - if (i < length) { - char_string->value[char_string->length] = value[i]; - char_string->length++; - } else - char_string->value[i] = 0; - } - } else { - for (i = 0; i < MAX_CHARACTER_STRING_BYTES; i++) { - char_string->value[i] = 0; - } - } - status = true; - } - } - - return status; -} - -bool characterstring_init_ansi(BACNET_CHARACTER_STRING * char_string, - char *value) -{ - return characterstring_init(char_string, - CHARACTER_ANSI_X34, value, value ? strlen(value) : 0); -} - -bool characterstring_copy(BACNET_CHARACTER_STRING * dest, - BACNET_CHARACTER_STRING * src) -{ - return characterstring_init(dest, - characterstring_encoding(src), - characterstring_value(src), characterstring_length(src)); -} - -bool characterstring_same(BACNET_CHARACTER_STRING * dest, - BACNET_CHARACTER_STRING * src) -{ - size_t i; /* counter */ - bool same_status = false; - - if (src && dest) { - if ((src->length == dest->length) && - (src->encoding == dest->encoding)) { - same_status = true; - for (i = 0; i < src->length; i++) { - if (src->value[i] != dest->value[i]) { - same_status = false; - break; - } - } - } - } else if (src) { - if (src->length == 0) - same_status = true; - } else if (dest) { - if (dest->length == 0) - same_status = true; - } - - return same_status; -} - -bool characterstring_ansi_same(BACNET_CHARACTER_STRING * dest, - const char *src) -{ - size_t i; /* counter */ - bool same_status = false; - - if (src && dest) { - if ((dest->length == strlen(src)) && - (dest->encoding == CHARACTER_ANSI_X34)) { - same_status = true; - for (i = 0; i < dest->length; i++) { - if (src[i] != dest->value[i]) { - same_status = false; - break; - } - } - } - } - /* NULL matches an empty string in our world */ - else if (src) { - if (strlen(src) == 0) - same_status = true; - } else if (dest) { - if (dest->length == 0) - same_status = true; - } - - return same_status; -} - -/* returns false if the string exceeds capacity */ -bool characterstring_append(BACNET_CHARACTER_STRING * char_string, - char *value, size_t length) -{ - size_t i; /* counter */ - bool status = false; /* return value */ - - if (char_string) { - if ((length + char_string->length) <= CHARACTER_STRING_CAPACITY) { - for (i = 0; i < length; i++) { - char_string->value[char_string->length] = value[i]; - char_string->length++; - } - status = true; - } - } - - return status; -} - -/* This function sets a new length without changing the value. - If length exceeds capacity, no modification happens and - function returns false. */ -bool characterstring_truncate(BACNET_CHARACTER_STRING * char_string, - size_t length) -{ - bool status = false; /* return value */ - - if (char_string) { - if (length <= CHARACTER_STRING_CAPACITY) { - char_string->length = length; - status = true; - } - } - - return status; -} - -/* Returns the value. */ -char *characterstring_value(BACNET_CHARACTER_STRING * char_string) -{ - char *value = NULL; - - if (char_string) { - value = char_string->value; - } - - return value; -} - -/* returns the length. */ -size_t characterstring_length(BACNET_CHARACTER_STRING * char_string) -{ - size_t length = 0; - - if (char_string) { - /* FIXME: validate length is within bounds? */ - length = char_string->length; - } - - return length; -} - -size_t characterstring_capacity(BACNET_CHARACTER_STRING * char_string) -{ - size_t length = 0; - - if (char_string) { - length = CHARACTER_STRING_CAPACITY; - } - - return length; -} - -/* returns the encoding. */ -uint8_t characterstring_encoding(BACNET_CHARACTER_STRING * char_string) -{ - uint8_t encoding = 0; - - if (char_string) { - encoding = char_string->encoding; - } - - return encoding; -} - -/* returns false if the string exceeds capacity - initialize by using length=0 */ -bool octetstring_init(BACNET_OCTET_STRING * octet_string, - uint8_t * value, size_t length) -{ - bool status = false; /* return value */ - size_t i; /* counter */ - - if (octet_string) { - octet_string->length = 0; - if (length <= sizeof(octet_string->value)) { - if (value) { - for (i = 0; i < length; i++) { - octet_string->value[octet_string->length] = value[i]; - octet_string->length++; - } - } else { - for (i = 0; i < sizeof(octet_string->value); i++) { - octet_string->value[i] = 0; - } - } - status = true; - } - } - - return status; -} - -bool octetstring_copy(BACNET_OCTET_STRING * dest, - BACNET_OCTET_STRING * src) -{ - return octetstring_init(dest, - octetstring_value(src), octetstring_length(src)); -} - -/* returns false if the string exceeds capacity */ -bool octetstring_append(BACNET_OCTET_STRING * octet_string, - uint8_t * value, size_t length) -{ - size_t i; /* counter */ - bool status = false; /* return value */ - - if (octet_string) { - if ((length + octet_string->length) <= sizeof(octet_string->value)) { - for (i = 0; i < length; i++) { - octet_string->value[octet_string->length] = value[i]; - octet_string->length++; - } - status = true; - } - } - - return status; -} - -/* This function sets a new length without changing the value. - If length exceeds capacity, no modification happens and - function returns false. */ -bool octetstring_truncate(BACNET_OCTET_STRING * octet_string, - size_t length) -{ - bool status = false; /* return value */ - - if (octet_string) { - if (length <= sizeof(octet_string->value)) { - octet_string->length = length; - status = true; - } - } - - return status; -} - -/* returns the length. Returns the value in parameter. */ -uint8_t *octetstring_value(BACNET_OCTET_STRING * octet_string) -{ - uint8_t *value = NULL; - - if (octet_string) { - value = octet_string->value; - } - - return value; -} - -/* returns the length. */ -size_t octetstring_length(BACNET_OCTET_STRING * octet_string) -{ - size_t length = 0; - - if (octet_string) { - /* FIXME: validate length is within bounds? */ - length = octet_string->length; - } - - return length; -} - -/* returns the length. */ -size_t octetstring_capacity(BACNET_OCTET_STRING * octet_string) -{ - size_t length = 0; - - if (octet_string) { - /* FIXME: validate length is within bounds? */ - length = sizeof(octet_string->value); - } - - return length; -} - -#ifdef TEST #include #include #include "ctest.h" -void testBitString(Test * pTest) -{ - uint8_t bit = 0; - BACNET_BIT_STRING bit_string; - - bitstring_init(&bit_string); - /* verify initialization */ - ct_test(pTest, bitstring_bits_used(&bit_string) == 0); - for (bit = 0; bit < (MAX_BITSTRING_BYTES * 8); bit++) { - ct_test(pTest, bitstring_bit(&bit_string, bit) == false); - } - - /* test for true */ - for (bit = 0; bit < (MAX_BITSTRING_BYTES * 8); bit++) { - bitstring_set_bit(&bit_string, bit, true); - ct_test(pTest, bitstring_bits_used(&bit_string) == (bit + 1)); - ct_test(pTest, bitstring_bit(&bit_string, bit) == true); - } - /* test for false */ - bitstring_init(&bit_string); - for (bit = 0; bit < (MAX_BITSTRING_BYTES * 8); bit++) { - bitstring_set_bit(&bit_string, bit, false); - ct_test(pTest, bitstring_bits_used(&bit_string) == (bit + 1)); - ct_test(pTest, bitstring_bit(&bit_string, bit) == false); - } -} - -void testCharacterString(Test * pTest) -{ - BACNET_CHARACTER_STRING bacnet_string; - char *value = "Joshua,Mary,Anna,Christopher"; - char test_value[MAX_APDU] = "Patricia"; - char test_append_value[MAX_APDU] = " and the Kids"; - char test_append_string[MAX_APDU] = ""; - bool status = false; - size_t length = 0; - size_t test_length = 0; - size_t i = 0; - - /* verify initialization */ - status = - characterstring_init(&bacnet_string, CHARACTER_ANSI_X34, NULL, 0); - ct_test(pTest, status == true); - ct_test(pTest, characterstring_length(&bacnet_string) == 0); - ct_test(pTest, - characterstring_encoding(&bacnet_string) == CHARACTER_ANSI_X34); - /* bounds check */ - status = characterstring_init(&bacnet_string, - CHARACTER_ANSI_X34, - NULL, characterstring_capacity(&bacnet_string) + 1); - ct_test(pTest, status == false); - status = - characterstring_truncate(&bacnet_string, - characterstring_capacity(&bacnet_string) + 1); - ct_test(pTest, status == false); - status = - characterstring_truncate(&bacnet_string, - characterstring_capacity(&bacnet_string)); - ct_test(pTest, status == true); - - test_length = strlen(test_value); - status = characterstring_init(&bacnet_string, - CHARACTER_ANSI_X34, &test_value[0], test_length); - ct_test(pTest, status == true); - value = characterstring_value(&bacnet_string); - length = characterstring_length(&bacnet_string); - ct_test(pTest, length == test_length); - for (i = 0; i < test_length; i++) { - ct_test(pTest, value[i] == test_value[i]); - } - test_length = strlen(test_append_value); - status = characterstring_append(&bacnet_string, - &test_append_value[0], test_length); - strcat(test_append_string, test_value); - strcat(test_append_string, test_append_value); - test_length = strlen(test_append_string); - ct_test(pTest, status == true); - length = characterstring_length(&bacnet_string); - value = characterstring_value(&bacnet_string); - ct_test(pTest, length == test_length); - for (i = 0; i < test_length; i++) { - ct_test(pTest, value[i] == test_append_string[i]); - } -} - void testOctetString(Test * pTest) { BACNET_OCTET_STRING bacnet_string; @@ -610,28 +101,3 @@ void testOctetString(Test * pTest) ct_test(pTest, value[i] == test_append_string[i]); } } - -#ifdef TEST_BACSTR -int main(void) -{ - Test *pTest; - bool rc; - - pTest = ct_create("BACnet Strings", NULL); - /* individual tests */ - rc = ct_addTestFunction(pTest, testBitString); - assert(rc); - rc = ct_addTestFunction(pTest, testCharacterString); - assert(rc); - rc = ct_addTestFunction(pTest, testOctetString); - assert(rc); - /* configure output */ - ct_setStream(pTest, stdout); - ct_run(pTest); - (void) ct_report(pTest); - ct_destroy(pTest); - - return 0; -} -#endif /* TEST_BACSTR */ -#endif /* TEST */