From b1d46ffa8c9bb5f4893eaf18e2a9f1e672f5c004 Mon Sep 17 00:00:00 2001 From: skarg Date: Sat, 18 Feb 2006 22:34:36 +0000 Subject: [PATCH] ran the indent program on the source files to make them consistent. --- bacnet-stack/abort.c | 204 ++- bacnet-stack/abort.h | 30 +- bacnet-stack/address.c | 502 ++++--- bacnet-stack/address.h | 55 +- bacnet-stack/apdu.c | 708 +++++----- bacnet-stack/apdu.h | 155 +-- bacnet-stack/arcnet.h | 41 +- bacnet-stack/arf.c | 739 +++++------ bacnet-stack/arf.h | 90 +- bacnet-stack/awf.c | 605 ++++----- bacnet-stack/awf.h | 84 +- bacnet-stack/bacapp.c | 1226 ++++++++--------- bacnet-stack/bacapp.h | 78 +- bacnet-stack/bacdcode.c | 1107 ++++++++-------- bacnet-stack/bacdcode.h | 161 +-- bacnet-stack/bacdef.h | 44 +- bacnet-stack/bacenum.h | 1829 +++++++++++++------------- bacnet-stack/bacerror.c | 391 +++--- bacnet-stack/bacerror.h | 54 +- bacnet-stack/bacprop.c | 104 +- bacnet-stack/bacprop.h | 20 +- bacnet-stack/bacstr.c | 918 ++++++------- bacnet-stack/bacstr.h | 140 +- bacnet-stack/bactext.c | 1877 ++++++++++++++++---------- bacnet-stack/bactext.h | 43 +- bacnet-stack/bigend.h | 7 +- bacnet-stack/bip.c | 214 ++- bacnet-stack/bip.h | 58 +- bacnet-stack/bytes.h | 19 +- bacnet-stack/crc.c | 128 +- bacnet-stack/crc.h | 9 +- bacnet-stack/datalink.c | 107 +- bacnet-stack/datalink.h | 29 +- bacnet-stack/dcc.c | 367 +++--- bacnet-stack/dcc.h | 59 +- bacnet-stack/dlmstp.c | 53 +- bacnet-stack/dlmstp.h | 32 +- bacnet-stack/ethernet.h | 43 +- bacnet-stack/filename.c | 80 +- bacnet-stack/filename.h | 7 +- bacnet-stack/iam.c | 348 +++-- bacnet-stack/iam.h | 40 +- bacnet-stack/ihave.c | 240 ++-- bacnet-stack/ihave.h | 33 +- bacnet-stack/indtext.c | 275 ++-- bacnet-stack/indtext.h | 63 +- bacnet-stack/main.c | 31 +- bacnet-stack/mstp.c | 2752 +++++++++++++++++++-------------------- bacnet-stack/mstp.h | 250 ++-- bacnet-stack/npdu.c | 749 +++++------ bacnet-stack/npdu.h | 59 +- bacnet-stack/rd.c | 203 ++- bacnet-stack/rd.h | 39 +- bacnet-stack/reject.c | 204 ++- bacnet-stack/reject.h | 30 +- bacnet-stack/ringbuf.c | 291 ++--- bacnet-stack/ringbuf.h | 38 +- bacnet-stack/rp.c | 530 ++++---- bacnet-stack/rp.h | 68 +- bacnet-stack/rpm.c | 1319 +++++++++---------- bacnet-stack/rpm.h | 117 +- bacnet-stack/rs485.h | 19 +- bacnet-stack/sbuf.c | 239 ++-- bacnet-stack/sbuf.h | 52 +- bacnet-stack/tsm.c | 299 ++--- bacnet-stack/tsm.h | 106 +- bacnet-stack/whohas.c | 333 +++-- bacnet-stack/whohas.h | 42 +- bacnet-stack/whois.c | 227 ++-- bacnet-stack/whois.h | 30 +- bacnet-stack/wp.c | 505 ++++--- bacnet-stack/wp.h | 49 +- 72 files changed, 10446 insertions(+), 11551 deletions(-) diff --git a/bacnet-stack/abort.c b/bacnet-stack/abort.c index 865a5f7d..cdf4d767 100644 --- a/bacnet-stack/abort.c +++ b/bacnet-stack/abort.c @@ -37,71 +37,56 @@ #include "bacdef.h" // encode service -int abort_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - uint8_t abort_reason) +int abort_encode_apdu(uint8_t * apdu, + uint8_t invoke_id, uint8_t abort_reason) { - int apdu_len = 0; // total length of the apdu, return value + int apdu_len = 0; // total length of the apdu, return value - if (apdu) - { - apdu[0] = PDU_TYPE_ABORT; - apdu[1] = invoke_id; - apdu[2] = abort_reason; - apdu_len = 3; - } - - return apdu_len; + if (apdu) { + apdu[0] = PDU_TYPE_ABORT; + apdu[1] = invoke_id; + apdu[2] = abort_reason; + apdu_len = 3; + } + + return apdu_len; } // decode the service request only -int abort_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - uint8_t *abort_reason) +int abort_decode_service_request(uint8_t * apdu, + unsigned apdu_len, uint8_t * invoke_id, uint8_t * abort_reason) { - int len = 0; + int len = 0; - if (apdu_len) - { - if (invoke_id) - *invoke_id = apdu[0]; - if (abort_reason) - *abort_reason = apdu[1]; - } - - return len; + if (apdu_len) { + if (invoke_id) + *invoke_id = apdu[0]; + if (abort_reason) + *abort_reason = apdu[1]; + } + + return len; } // decode the whole APDU - mainly used for unit testing -int abort_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - uint8_t *abort_reason) +int abort_decode_apdu(uint8_t * apdu, + unsigned apdu_len, uint8_t * invoke_id, uint8_t * abort_reason) { - int len = 0; + int len = 0; - if (!apdu) - return -1; - // optional checking - most likely was already done prior to this call - if (apdu_len) - { - if (apdu[0] != PDU_TYPE_ABORT) - return -1; - if (apdu_len > 1) - { - len = abort_decode_service_request( - &apdu[1], - apdu_len - 1, - invoke_id, - abort_reason); + if (!apdu) + return -1; + // optional checking - most likely was already done prior to this call + if (apdu_len) { + if (apdu[0] != PDU_TYPE_ABORT) + return -1; + if (apdu_len > 1) { + len = abort_decode_service_request(&apdu[1], + apdu_len - 1, invoke_id, abort_reason); + } } - } - - return len; + + return len; } #ifdef TEST @@ -111,83 +96,54 @@ int abort_decode_apdu( void testAbort(Test * pTest) { - uint8_t apdu[480] = {0}; - int len = 0; - int apdu_len = 0; - uint8_t invoke_id = 0; - uint8_t abort_reason = 0; - uint8_t test_invoke_id = 0; - uint8_t test_abort_reason = 0; - - len = abort_encode_apdu( - &apdu[0], - invoke_id, - abort_reason); - ct_test(pTest, len != 0); - apdu_len = len; + uint8_t apdu[480] = { 0 }; + int len = 0; + int apdu_len = 0; + uint8_t invoke_id = 0; + uint8_t abort_reason = 0; + uint8_t test_invoke_id = 0; + uint8_t test_abort_reason = 0; - len = abort_decode_apdu( - &apdu[0], - apdu_len, - &test_invoke_id, - &test_abort_reason); - ct_test(pTest, len != -1); - ct_test(pTest, test_invoke_id == invoke_id); - ct_test(pTest, test_abort_reason == abort_reason); + len = abort_encode_apdu(&apdu[0], invoke_id, abort_reason); + ct_test(pTest, len != 0); + apdu_len = len; - // change type to get negative response - apdu[0] = PDU_TYPE_REJECT; - len = abort_decode_apdu( - &apdu[0], - apdu_len, - &test_invoke_id, - &test_abort_reason); - ct_test(pTest, len == -1); + len = abort_decode_apdu(&apdu[0], + apdu_len, &test_invoke_id, &test_abort_reason); + ct_test(pTest, len != -1); + ct_test(pTest, test_invoke_id == invoke_id); + ct_test(pTest, test_abort_reason == abort_reason); - // test NULL APDU - len = abort_decode_apdu( - NULL, - apdu_len, - &test_invoke_id, - &test_abort_reason); - ct_test(pTest, len == -1); + // change type to get negative response + apdu[0] = PDU_TYPE_REJECT; + len = abort_decode_apdu(&apdu[0], + apdu_len, &test_invoke_id, &test_abort_reason); + ct_test(pTest, len == -1); - // force a zero length - len = abort_decode_apdu( - &apdu[0], - 0, - &test_invoke_id, - &test_abort_reason); - ct_test(pTest, len == 0); - - - // check them all... - for ( - invoke_id = 0; - invoke_id < 255; - invoke_id++) - { - for ( - abort_reason = 0; - abort_reason < 255; - abort_reason++) - { - len = abort_encode_apdu( - &apdu[0], - invoke_id, - abort_reason); - apdu_len = len; - ct_test(pTest, len != 0); - len = abort_decode_apdu( - &apdu[0], - apdu_len, - &test_invoke_id, - &test_abort_reason); - ct_test(pTest, len != -1); - ct_test(pTest, test_invoke_id == invoke_id); - ct_test(pTest, test_abort_reason == abort_reason); + // test NULL APDU + len = abort_decode_apdu(NULL, + apdu_len, &test_invoke_id, &test_abort_reason); + ct_test(pTest, len == -1); + + // force a zero length + len = abort_decode_apdu(&apdu[0], + 0, &test_invoke_id, &test_abort_reason); + ct_test(pTest, len == 0); + + + // check them all... + for (invoke_id = 0; invoke_id < 255; invoke_id++) { + for (abort_reason = 0; abort_reason < 255; abort_reason++) { + len = abort_encode_apdu(&apdu[0], invoke_id, abort_reason); + apdu_len = len; + ct_test(pTest, len != 0); + len = abort_decode_apdu(&apdu[0], + apdu_len, &test_invoke_id, &test_abort_reason); + ct_test(pTest, len != -1); + ct_test(pTest, test_invoke_id == invoke_id); + ct_test(pTest, test_abort_reason == abort_reason); + } } - } } #ifdef TEST_ABORT diff --git a/bacnet-stack/abort.h b/bacnet-stack/abort.h index 9a6ff1dc..376dc271 100644 --- a/bacnet-stack/abort.h +++ b/bacnet-stack/abort.h @@ -39,33 +39,23 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ -int abort_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - uint8_t abort_reason); + int abort_encode_apdu(uint8_t * apdu, + uint8_t invoke_id, uint8_t abort_reason); -int abort_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - uint8_t *abort_reason); - -int abort_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - uint8_t *abort_reason); + int abort_decode_service_request(uint8_t * apdu, + unsigned apdu_len, uint8_t * invoke_id, uint8_t * abort_reason); + + int abort_decode_apdu(uint8_t * apdu, + unsigned apdu_len, uint8_t * invoke_id, uint8_t * abort_reason); #ifdef TEST #include "ctest.h" -void testAbort(Test * pTest); + void testAbort(Test * pTest); #endif #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif - diff --git a/bacnet-stack/address.c b/bacnet-stack/address.c index 03639b0c..0f13dd23 100644 --- a/bacnet-stack/address.c +++ b/bacnet-stack/address.c @@ -44,287 +44,241 @@ // occurs in BACnet. A device id is bound to a MAC address. // The normal method is using Who-Is, and using the data from I-Am -static struct Address_Cache_Entry -{ - bool valid; - bool bind_request; - uint32_t device_id; - unsigned max_apdu; - BACNET_ADDRESS address; +static struct Address_Cache_Entry { + bool valid; + bool bind_request; + uint32_t device_id; + unsigned max_apdu; + BACNET_ADDRESS address; } Address_Cache[MAX_ADDRESS_CACHE]; -void address_copy( - BACNET_ADDRESS *dest, - BACNET_ADDRESS *src) +void address_copy(BACNET_ADDRESS * dest, BACNET_ADDRESS * src) { - unsigned i = 0; // counter - - if (dest && src) - { - for (i = 0; i < MAX_MAC_LEN; i++) - { - dest->mac[i] = src->mac[i]; - } - dest->mac_len = src->mac_len; - dest->net = src->net; - dest->len = src->len; - for (i = 0; i < MAX_MAC_LEN; i++) - { - dest->adr[i] = src->adr[i]; - } - } + unsigned i = 0; // counter - return; + if (dest && src) { + for (i = 0; i < MAX_MAC_LEN; i++) { + dest->mac[i] = src->mac[i]; + } + dest->mac_len = src->mac_len; + dest->net = src->net; + dest->len = src->len; + for (i = 0; i < MAX_MAC_LEN; i++) { + dest->adr[i] = src->adr[i]; + } + } + + return; } -void address_remove_device( - uint32_t device_id) +void address_remove_device(uint32_t device_id) { - unsigned i; + unsigned i; - for (i = 0; i < MAX_ADDRESS_CACHE; i++) - { - if ((Address_Cache[i].valid || - Address_Cache[i].bind_request) && - (Address_Cache[i].device_id == device_id)) - { - Address_Cache[i].valid = false; - break; + for (i = 0; i < MAX_ADDRESS_CACHE; i++) { + if ((Address_Cache[i].valid || + Address_Cache[i].bind_request) && + (Address_Cache[i].device_id == device_id)) { + Address_Cache[i].valid = false; + break; + } } - } - return; + return; } void address_init(void) { - unsigned i; + unsigned i; - for (i = 0; i < MAX_ADDRESS_CACHE; i++) - { - Address_Cache[i].valid = false; - Address_Cache[i].bind_request = false; - } + for (i = 0; i < MAX_ADDRESS_CACHE; i++) { + Address_Cache[i].valid = false; + Address_Cache[i].bind_request = false; + } - return; + return; } -bool address_get_by_device( - uint32_t device_id, - unsigned *max_apdu, - BACNET_ADDRESS *src) +bool address_get_by_device(uint32_t device_id, + unsigned *max_apdu, BACNET_ADDRESS * src) { - unsigned i; - bool found = false; // return value + unsigned i; + bool found = false; // return value - for (i = 0; i < MAX_ADDRESS_CACHE; i++) - { - if (Address_Cache[i].valid && - (Address_Cache[i].device_id == device_id)) - { - address_copy(src, &Address_Cache[i].address); - *max_apdu = Address_Cache[i].max_apdu; - found = true; - break; + for (i = 0; i < MAX_ADDRESS_CACHE; i++) { + if (Address_Cache[i].valid && + (Address_Cache[i].device_id == device_id)) { + address_copy(src, &Address_Cache[i].address); + *max_apdu = Address_Cache[i].max_apdu; + found = true; + break; + } } - } - return found; + return found; } -void address_add( - uint32_t device_id, - unsigned max_apdu, - BACNET_ADDRESS *src) +void address_add(uint32_t device_id, + unsigned max_apdu, BACNET_ADDRESS * src) { - unsigned i; - bool found = false; // return value + unsigned i; + bool found = false; // return value - // existing device - update address - for (i = 0; i < MAX_ADDRESS_CACHE; i++) - { - if (Address_Cache[i].valid && - (Address_Cache[i].device_id == device_id)) - { - address_copy(&Address_Cache[i].address,src); - Address_Cache[i].max_apdu = max_apdu; - found = true; - break; + // existing device - update address + for (i = 0; i < MAX_ADDRESS_CACHE; i++) { + if (Address_Cache[i].valid && + (Address_Cache[i].device_id == device_id)) { + address_copy(&Address_Cache[i].address, src); + Address_Cache[i].max_apdu = max_apdu; + found = true; + break; + } } - } - // new device - if (!found) - { - for (i = 0; i < MAX_ADDRESS_CACHE; i++) - { - if (!Address_Cache[i].valid) - { - Address_Cache[i].valid = true; - Address_Cache[i].device_id = device_id; - Address_Cache[i].max_apdu = max_apdu; - address_copy(&Address_Cache[i].address,src); - break; - } + // new device + if (!found) { + for (i = 0; i < MAX_ADDRESS_CACHE; i++) { + if (!Address_Cache[i].valid) { + Address_Cache[i].valid = true; + Address_Cache[i].device_id = device_id; + Address_Cache[i].max_apdu = max_apdu; + address_copy(&Address_Cache[i].address, src); + break; + } + } } - } - return; + return; } // returns true if device is already bound // also returns the address and max apdu if already bound -bool address_bind_request( - uint32_t device_id, - unsigned *max_apdu, - BACNET_ADDRESS *src) +bool address_bind_request(uint32_t device_id, + unsigned *max_apdu, BACNET_ADDRESS * src) { - unsigned i; - bool found = false; // return value + unsigned i; + bool found = false; // return value - // existing device - update address - for (i = 0; i < MAX_ADDRESS_CACHE; i++) - { - if (Address_Cache[i].valid && - (Address_Cache[i].device_id == device_id)) - { - found = true; - address_copy(src, &Address_Cache[i].address); - *max_apdu = Address_Cache[i].max_apdu; - break; + // existing device - update address + for (i = 0; i < MAX_ADDRESS_CACHE; i++) { + if (Address_Cache[i].valid && + (Address_Cache[i].device_id == device_id)) { + found = true; + address_copy(src, &Address_Cache[i].address); + *max_apdu = Address_Cache[i].max_apdu; + break; + } + // already have a bind request active for this puppy + else if (Address_Cache[i].bind_request && + (Address_Cache[i].device_id == device_id)) { + return found; + } } - // already have a bind request active for this puppy - else if (Address_Cache[i].bind_request && - (Address_Cache[i].device_id == device_id)) - { - return found; + + if (!found) { + for (i = 0; i < MAX_ADDRESS_CACHE; i++) { + if (!(Address_Cache[i].bind_request || Address_Cache[i].valid)) { + Address_Cache[i].bind_request = true; + Address_Cache[i].device_id = device_id; + // now would be a good time to do a Who-Is request + break; + } + } } - } - - if (!found) - { - for (i = 0; i < MAX_ADDRESS_CACHE; i++) - { - if (!(Address_Cache[i].bind_request || Address_Cache[i].valid)) - { - Address_Cache[i].bind_request = true; - Address_Cache[i].device_id = device_id; - // now would be a good time to do a Who-Is request - break; - } - } - } - - return found; + + return found; } -void address_add_binding( - uint32_t device_id, - unsigned max_apdu, - BACNET_ADDRESS *src) +void address_add_binding(uint32_t device_id, + unsigned max_apdu, BACNET_ADDRESS * src) { - unsigned i; - bool found = false; // return value + unsigned i; + bool found = false; // return value - // existing device - update address - for (i = 0; i < MAX_ADDRESS_CACHE; i++) - { - if (Address_Cache[i].valid && - (Address_Cache[i].device_id == device_id)) - { - address_copy(&Address_Cache[i].address,src); - Address_Cache[i].max_apdu = max_apdu; - found = true; - break; + // existing device - update address + for (i = 0; i < MAX_ADDRESS_CACHE; i++) { + if (Address_Cache[i].valid && + (Address_Cache[i].device_id == device_id)) { + address_copy(&Address_Cache[i].address, src); + Address_Cache[i].max_apdu = max_apdu; + found = true; + break; + } } - } - // add new device - but only if bind requested - if (!found) - { - for (i = 0; i < MAX_ADDRESS_CACHE; i++) - { - if (!Address_Cache[i].valid && Address_Cache[i].bind_request) - { - Address_Cache[i].valid = true; - Address_Cache[i].bind_request = false; - Address_Cache[i].device_id = device_id; - Address_Cache[i].max_apdu = max_apdu; - address_copy(&Address_Cache[i].address,src); - break; - } + // add new device - but only if bind requested + if (!found) { + for (i = 0; i < MAX_ADDRESS_CACHE; i++) { + if (!Address_Cache[i].valid && Address_Cache[i].bind_request) { + Address_Cache[i].valid = true; + Address_Cache[i].bind_request = false; + Address_Cache[i].device_id = device_id; + Address_Cache[i].max_apdu = max_apdu; + address_copy(&Address_Cache[i].address, src); + break; + } + } } - } - return; + return; } -bool address_get_by_index( - unsigned index, - uint32_t *device_id, - unsigned *max_apdu, - BACNET_ADDRESS *src) +bool address_get_by_index(unsigned index, + uint32_t * device_id, unsigned *max_apdu, BACNET_ADDRESS * src) { - bool found = false; // return value + bool found = false; // return value - if (index < MAX_ADDRESS_CACHE) - { - if (Address_Cache[index].valid) - { - address_copy(src, &Address_Cache[index].address); - *device_id = Address_Cache[index].device_id; - *max_apdu = Address_Cache[index].max_apdu; - found = true; + if (index < MAX_ADDRESS_CACHE) { + if (Address_Cache[index].valid) { + address_copy(src, &Address_Cache[index].address); + *device_id = Address_Cache[index].device_id; + *max_apdu = Address_Cache[index].max_apdu; + found = true; + } } - } - return found; + return found; } unsigned address_count(void) { - unsigned i; - unsigned count = 0; // return value + unsigned i; + unsigned count = 0; // return value - for (i = 0; i < MAX_ADDRESS_CACHE; i++) - { - if (Address_Cache[i].valid) - count++; - } + for (i = 0; i < MAX_ADDRESS_CACHE; i++) { + if (Address_Cache[i].valid) + count++; + } - return count; + return count; } -bool address_match( - BACNET_ADDRESS *dest, - BACNET_ADDRESS *src) +bool address_match(BACNET_ADDRESS * dest, BACNET_ADDRESS * src) { - unsigned i; - unsigned max_len; - bool match = true; // return value + unsigned i; + unsigned max_len; + bool match = true; // return value - if (dest->mac_len != src->mac_len) - match = false; - max_len = dest->mac_len; - if (max_len > MAX_MAC_LEN) - max_len = MAX_MAC_LEN; - for (i = 0; i < max_len; i++) - { - if (dest->mac[i] != src->mac[i]) - match = false; - } - if (dest->net != src->net) - match = false; - if (dest->len != src->len) - match = false; - max_len = dest->len; - if (max_len > MAX_MAC_LEN) - max_len = MAX_MAC_LEN; - for (i = 0; i < max_len; i++) - { - if (dest->adr[i] != src->adr[i]) - match = false; - } - - return match; + if (dest->mac_len != src->mac_len) + match = false; + max_len = dest->mac_len; + if (max_len > MAX_MAC_LEN) + max_len = MAX_MAC_LEN; + for (i = 0; i < max_len; i++) { + if (dest->mac[i] != src->mac[i]) + match = false; + } + if (dest->net != src->net) + match = false; + if (dest->len != src->len) + match = false; + max_len = dest->len; + if (max_len > MAX_MAC_LEN) + max_len = MAX_MAC_LEN; + for (i = 0; i < max_len; i++) { + if (dest->adr[i] != src->adr[i]) + match = false; + } + + return match; } #ifdef TEST @@ -332,72 +286,62 @@ bool address_match( #include #include "ctest.h" -static void set_address( - unsigned index, - BACNET_ADDRESS *dest) +static void set_address(unsigned index, BACNET_ADDRESS * dest) { - unsigned i; - - for (i = 0; i < MAX_MAC_LEN; i++) - { - dest->mac[i] = index; - } - dest->mac_len = MAX_MAC_LEN; - dest->net = 7; - dest->len = MAX_MAC_LEN; - for (i = 0; i < MAX_MAC_LEN; i++) - { - dest->adr[i] = index; - } + unsigned i; + + for (i = 0; i < MAX_MAC_LEN; i++) { + dest->mac[i] = index; + } + dest->mac_len = MAX_MAC_LEN; + dest->net = 7; + dest->len = MAX_MAC_LEN; + for (i = 0; i < MAX_MAC_LEN; i++) { + dest->adr[i] = index; + } } void testAddress(Test * pTest) { - unsigned i, count; - BACNET_ADDRESS src; - uint32_t device_id = 0; - unsigned max_apdu = 480; - BACNET_ADDRESS test_address; - uint32_t test_device_id = 0; - unsigned test_max_apdu = 0; + unsigned i, count; + BACNET_ADDRESS src; + uint32_t device_id = 0; + unsigned max_apdu = 480; + BACNET_ADDRESS test_address; + uint32_t test_device_id = 0; + unsigned test_max_apdu = 0; - for (i = 0; i < MAX_ADDRESS_CACHE; i++) - { - set_address(i,&src); - device_id = i * 255; - address_add( - device_id, - max_apdu, - &src); - count = address_count(); - ct_test(pTest, count == (i + 1)); - } + for (i = 0; i < MAX_ADDRESS_CACHE; i++) { + set_address(i, &src); + device_id = i * 255; + address_add(device_id, max_apdu, &src); + count = address_count(); + ct_test(pTest, count == (i + 1)); + } - for (i = 0; i < MAX_ADDRESS_CACHE; i++) - { - device_id = i * 255; - ct_test(pTest, address_get_by_device(device_id, &test_max_apdu, - &test_address)); - set_address(i,&src); - ct_test(pTest, test_max_apdu == max_apdu); - ct_test(pTest, address_match(&test_address,&src)); - ct_test(pTest, address_get_by_index(i, &test_device_id, - &test_max_apdu,&test_address)); - ct_test(pTest, test_device_id == device_id); - ct_test(pTest, test_max_apdu == max_apdu); - ct_test(pTest, address_match(&test_address,&src)); - ct_test(pTest, address_count() == MAX_ADDRESS_CACHE); - } + for (i = 0; i < MAX_ADDRESS_CACHE; i++) { + device_id = i * 255; + ct_test(pTest, address_get_by_device(device_id, &test_max_apdu, + &test_address)); + set_address(i, &src); + ct_test(pTest, test_max_apdu == max_apdu); + ct_test(pTest, address_match(&test_address, &src)); + ct_test(pTest, address_get_by_index(i, &test_device_id, + &test_max_apdu, &test_address)); + ct_test(pTest, test_device_id == device_id); + ct_test(pTest, test_max_apdu == max_apdu); + ct_test(pTest, address_match(&test_address, &src)); + ct_test(pTest, address_count() == MAX_ADDRESS_CACHE); + } - for (i = 0; i < MAX_ADDRESS_CACHE; i++) - { - device_id = i * 255; - address_remove_device(device_id); - ct_test(pTest, !address_get_by_device(device_id, &test_max_apdu, - &test_address)); - count = address_count(); - ct_test(pTest, count == (MAX_ADDRESS_CACHE-i-1)); - } + for (i = 0; i < MAX_ADDRESS_CACHE; i++) { + device_id = i * 255; + address_remove_device(device_id); + ct_test(pTest, !address_get_by_device(device_id, &test_max_apdu, + &test_address)); + count = address_count(); + ct_test(pTest, count == (MAX_ADDRESS_CACHE - i - 1)); + } } #ifdef TEST_ADDRESS diff --git a/bacnet-stack/address.h b/bacnet-stack/address.h index cfa36325..7c5fd3e4 100644 --- a/bacnet-stack/address.h +++ b/bacnet-stack/address.h @@ -41,51 +41,34 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ -void address_init(void); + void address_init(void); -void address_copy( - BACNET_ADDRESS *dest, - BACNET_ADDRESS *src); + void address_copy(BACNET_ADDRESS * dest, BACNET_ADDRESS * src); -void address_add( - uint32_t device_id, - unsigned max_apdu, - BACNET_ADDRESS *src); + void address_add(uint32_t device_id, + unsigned max_apdu, BACNET_ADDRESS * src); -void address_remove_device( - uint32_t device_id); + void address_remove_device(uint32_t device_id); -bool address_get_by_device( - uint32_t device_id, - unsigned *max_apdu, - BACNET_ADDRESS *src); + bool address_get_by_device(uint32_t device_id, + unsigned *max_apdu, BACNET_ADDRESS * src); -bool address_get_by_index( - unsigned index, - uint32_t *device_id, - unsigned *max_apdu, - BACNET_ADDRESS *src); + bool address_get_by_index(unsigned index, + uint32_t * device_id, unsigned *max_apdu, BACNET_ADDRESS * src); -unsigned address_count(void); + unsigned address_count(void); -bool address_match( - BACNET_ADDRESS *dest, - BACNET_ADDRESS *src); - -bool address_bind_request( - uint32_t device_id, - unsigned *max_apdu, - BACNET_ADDRESS *src); - -void address_add_binding( - uint32_t device_id, - unsigned max_apdu, - BACNET_ADDRESS *src); + bool address_match(BACNET_ADDRESS * dest, BACNET_ADDRESS * src); + + bool address_bind_request(uint32_t device_id, + unsigned *max_apdu, BACNET_ADDRESS * src); + + void address_add_binding(uint32_t device_id, + unsigned max_apdu, BACNET_ADDRESS * src); #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif diff --git a/bacnet-stack/apdu.c b/bacnet-stack/apdu.c index ba1e86d6..d973517f 100644 --- a/bacnet-stack/apdu.c +++ b/bacnet-stack/apdu.c @@ -44,482 +44,434 @@ #include "iam.h" /* a simple table for crossing the services supported */ -static BACNET_SERVICES_SUPPORTED confirmed_service_supported[MAX_BACNET_CONFIRMED_SERVICE] = -{ - SERVICE_SUPPORTED_ACKNOWLEDGE_ALARM, - SERVICE_SUPPORTED_CONFIRMED_COV_NOTIFICATION, - SERVICE_SUPPORTED_CONFIRMED_EVENT_NOTIFICATION, - SERVICE_SUPPORTED_GET_ALARM_SUMMARY, - SERVICE_SUPPORTED_GET_ENROLLMENT_SUMMARY, - SERVICE_SUPPORTED_SUBSCRIBE_COV, - SERVICE_SUPPORTED_ATOMIC_READ_FILE, - SERVICE_SUPPORTED_ATOMIC_WRITE_FILE, - SERVICE_SUPPORTED_ADD_LIST_ELEMENT, - SERVICE_SUPPORTED_REMOVE_LIST_ELEMENT, - SERVICE_SUPPORTED_CREATE_OBJECT, - SERVICE_SUPPORTED_DELETE_OBJECT, - SERVICE_SUPPORTED_READ_PROPERTY, - SERVICE_SUPPORTED_READ_PROPERTY_CONDITIONAL, - SERVICE_SUPPORTED_READ_PROPERTY_MULTIPLE, - SERVICE_SUPPORTED_WRITE_PROPERTY, - SERVICE_SUPPORTED_WRITE_PROPERTY_MULTIPLE, - SERVICE_SUPPORTED_DEVICE_COMMUNICATION_CONTROL, - SERVICE_SUPPORTED_PRIVATE_TRANSFER, - SERVICE_SUPPORTED_TEXT_MESSAGE, - SERVICE_SUPPORTED_REINITIALIZE_DEVICE, - SERVICE_SUPPORTED_VT_OPEN, - SERVICE_SUPPORTED_VT_CLOSE, - SERVICE_SUPPORTED_VT_DATA, - SERVICE_SUPPORTED_AUTHENTICATE, - SERVICE_SUPPORTED_REQUEST_KEY, - SERVICE_SUPPORTED_READ_RANGE, - SERVICE_SUPPORTED_LIFE_SAFETY_OPERATION, - SERVICE_SUPPORTED_SUBSCRIBE_COV_PROPERTY, - SERVICE_SUPPORTED_GET_EVENT_INFORMATION +static BACNET_SERVICES_SUPPORTED + confirmed_service_supported[MAX_BACNET_CONFIRMED_SERVICE] = { + SERVICE_SUPPORTED_ACKNOWLEDGE_ALARM, + SERVICE_SUPPORTED_CONFIRMED_COV_NOTIFICATION, + SERVICE_SUPPORTED_CONFIRMED_EVENT_NOTIFICATION, + SERVICE_SUPPORTED_GET_ALARM_SUMMARY, + SERVICE_SUPPORTED_GET_ENROLLMENT_SUMMARY, + SERVICE_SUPPORTED_SUBSCRIBE_COV, + SERVICE_SUPPORTED_ATOMIC_READ_FILE, + SERVICE_SUPPORTED_ATOMIC_WRITE_FILE, + SERVICE_SUPPORTED_ADD_LIST_ELEMENT, + SERVICE_SUPPORTED_REMOVE_LIST_ELEMENT, + SERVICE_SUPPORTED_CREATE_OBJECT, + SERVICE_SUPPORTED_DELETE_OBJECT, + SERVICE_SUPPORTED_READ_PROPERTY, + SERVICE_SUPPORTED_READ_PROPERTY_CONDITIONAL, + SERVICE_SUPPORTED_READ_PROPERTY_MULTIPLE, + SERVICE_SUPPORTED_WRITE_PROPERTY, + SERVICE_SUPPORTED_WRITE_PROPERTY_MULTIPLE, + SERVICE_SUPPORTED_DEVICE_COMMUNICATION_CONTROL, + SERVICE_SUPPORTED_PRIVATE_TRANSFER, + SERVICE_SUPPORTED_TEXT_MESSAGE, + SERVICE_SUPPORTED_REINITIALIZE_DEVICE, + SERVICE_SUPPORTED_VT_OPEN, + SERVICE_SUPPORTED_VT_CLOSE, + SERVICE_SUPPORTED_VT_DATA, + SERVICE_SUPPORTED_AUTHENTICATE, + SERVICE_SUPPORTED_REQUEST_KEY, + SERVICE_SUPPORTED_READ_RANGE, + SERVICE_SUPPORTED_LIFE_SAFETY_OPERATION, + SERVICE_SUPPORTED_SUBSCRIBE_COV_PROPERTY, + SERVICE_SUPPORTED_GET_EVENT_INFORMATION }; /* a simple table for crossing the services supported */ -static BACNET_SERVICES_SUPPORTED unconfirmed_service_supported[MAX_BACNET_UNCONFIRMED_SERVICE] = -{ - SERVICE_SUPPORTED_I_AM, - SERVICE_SUPPORTED_I_HAVE, - SERVICE_SUPPORTED_UNCONFIRMED_COV_NOTIFICATION, - SERVICE_SUPPORTED_UNCONFIRMED_EVENT_NOTIFICATION, - SERVICE_SUPPORTED_UNCONFIRMED_PRIVATE_TRANSFER, - SERVICE_SUPPORTED_UNCONFIRMED_TEXT_MESSAGE, - SERVICE_SUPPORTED_TIME_SYNCHRONIZATION, - SERVICE_SUPPORTED_WHO_HAS, - SERVICE_SUPPORTED_WHO_IS, - SERVICE_SUPPORTED_UTC_TIME_SYNCHRONIZATION +static BACNET_SERVICES_SUPPORTED + unconfirmed_service_supported[MAX_BACNET_UNCONFIRMED_SERVICE] = { + SERVICE_SUPPORTED_I_AM, + SERVICE_SUPPORTED_I_HAVE, + SERVICE_SUPPORTED_UNCONFIRMED_COV_NOTIFICATION, + SERVICE_SUPPORTED_UNCONFIRMED_EVENT_NOTIFICATION, + SERVICE_SUPPORTED_UNCONFIRMED_PRIVATE_TRANSFER, + SERVICE_SUPPORTED_UNCONFIRMED_TEXT_MESSAGE, + SERVICE_SUPPORTED_TIME_SYNCHRONIZATION, + SERVICE_SUPPORTED_WHO_HAS, + SERVICE_SUPPORTED_WHO_IS, + SERVICE_SUPPORTED_UTC_TIME_SYNCHRONIZATION }; // Confirmed Function Handlers // If they are not set, they are handled by a reject message -static confirmed_function -Confirmed_Function[MAX_BACNET_CONFIRMED_SERVICE]; +static confirmed_function Confirmed_Function[MAX_BACNET_CONFIRMED_SERVICE]; -void apdu_set_confirmed_handler( - BACNET_CONFIRMED_SERVICE service_choice, - confirmed_function pFunction) +void apdu_set_confirmed_handler(BACNET_CONFIRMED_SERVICE service_choice, + confirmed_function pFunction) { - if (service_choice < MAX_BACNET_CONFIRMED_SERVICE) - Confirmed_Function[service_choice] = pFunction; + if (service_choice < MAX_BACNET_CONFIRMED_SERVICE) + Confirmed_Function[service_choice] = pFunction; } /* returns true if the handler is set */ -bool apdu_confirmed_handler( - BACNET_CONFIRMED_SERVICE service_choice) +bool apdu_confirmed_handler(BACNET_CONFIRMED_SERVICE service_choice) { - bool status = false; - if ((service_choice < MAX_BACNET_CONFIRMED_SERVICE) && - (Confirmed_Function[service_choice] != NULL)) - status = true; + bool status = false; + if ((service_choice < MAX_BACNET_CONFIRMED_SERVICE) && + (Confirmed_Function[service_choice] != NULL)) + status = true; - return status; + return status; } bool apdu_service_supported(BACNET_SERVICES_SUPPORTED service_supported) { - int i = 0; - bool status = false; - bool found = false; + int i = 0; + bool status = false; + bool found = false; - if (service_supported < MAX_BACNET_SERVICES_SUPPORTED) - { - /* is it a confirmed service? */ - for (i = 0; i < MAX_BACNET_CONFIRMED_SERVICE; i++) - { - if (confirmed_service_supported[i] == service_supported) - { - if (apdu_confirmed_handler(i)) - status = true; - found = true; - break; - } - } - - if (!found) - { - /* is it an unconfirmed service? */ - for (i = 0; i < MAX_BACNET_UNCONFIRMED_SERVICE; i++) - { - if (unconfirmed_service_supported[i] == service_supported) - { - if (apdu_unconfirmed_handler(i)) - status = true; - break; + if (service_supported < MAX_BACNET_SERVICES_SUPPORTED) { + /* is it a confirmed service? */ + for (i = 0; i < MAX_BACNET_CONFIRMED_SERVICE; i++) { + if (confirmed_service_supported[i] == service_supported) { + if (apdu_confirmed_handler(i)) + status = true; + found = true; + break; + } + } + + if (!found) { + /* is it an unconfirmed service? */ + for (i = 0; i < MAX_BACNET_UNCONFIRMED_SERVICE; i++) { + if (unconfirmed_service_supported[i] == service_supported) { + if (apdu_unconfirmed_handler(i)) + status = true; + break; + } + } } - } } - } - return status; + return status; } // Allow the APDU handler to automatically reject static confirmed_function Unrecognized_Service_Handler; -void apdu_set_unrecognized_service_handler_handler( - confirmed_function pFunction) +void apdu_set_unrecognized_service_handler_handler(confirmed_function + pFunction) { Unrecognized_Service_Handler = pFunction; } // Unconfirmed Function Handlers // If they are not set, they are not handled -static unconfirmed_function -Unconfirmed_Function[MAX_BACNET_UNCONFIRMED_SERVICE] = -{ +static unconfirmed_function + Unconfirmed_Function[MAX_BACNET_UNCONFIRMED_SERVICE] = { NULL }; -void apdu_set_unconfirmed_handler( - BACNET_UNCONFIRMED_SERVICE service_choice, - unconfirmed_function pFunction) +void apdu_set_unconfirmed_handler(BACNET_UNCONFIRMED_SERVICE + service_choice, unconfirmed_function pFunction) { - if (service_choice < MAX_BACNET_UNCONFIRMED_SERVICE) - Unconfirmed_Function[service_choice] = pFunction; + if (service_choice < MAX_BACNET_UNCONFIRMED_SERVICE) + Unconfirmed_Function[service_choice] = pFunction; } -bool apdu_unconfirmed_handler( - BACNET_UNCONFIRMED_SERVICE service_choice) +bool apdu_unconfirmed_handler(BACNET_UNCONFIRMED_SERVICE service_choice) { - bool status = false; - - if ((service_choice < MAX_BACNET_UNCONFIRMED_SERVICE) && - (Unconfirmed_Function[service_choice] != NULL)) - status = true; + bool status = false; - return status; + if ((service_choice < MAX_BACNET_UNCONFIRMED_SERVICE) && + (Unconfirmed_Function[service_choice] != NULL)) + status = true; + + return status; } + // Confirmed ACK Function Handlers static void *Confirmed_ACK_Function[MAX_BACNET_CONFIRMED_SERVICE]; -void apdu_set_confirmed_simple_ack_handler( - BACNET_CONFIRMED_SERVICE service_choice, - confirmed_simple_ack_function pFunction) +void apdu_set_confirmed_simple_ack_handler(BACNET_CONFIRMED_SERVICE + service_choice, confirmed_simple_ack_function pFunction) { - switch (service_choice) - { + switch (service_choice) { case SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM: case SERVICE_CONFIRMED_COV_NOTIFICATION: case SERVICE_CONFIRMED_EVENT_NOTIFICATION: case SERVICE_CONFIRMED_SUBSCRIBE_COV: case SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY: case SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION: - // Object Access Services + // Object Access Services case SERVICE_CONFIRMED_ADD_LIST_ELEMENT: case SERVICE_CONFIRMED_REMOVE_LIST_ELEMENT: case SERVICE_CONFIRMED_DELETE_OBJECT: case SERVICE_CONFIRMED_WRITE_PROPERTY: case SERVICE_CONFIRMED_WRITE_PROPERTY_MULTIPLE: - // Remote Device Management Services + // Remote Device Management Services case SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL: case SERVICE_CONFIRMED_TEXT_MESSAGE: case SERVICE_CONFIRMED_REINITIALIZE_DEVICE: - // Virtual Terminal Services + // Virtual Terminal Services case SERVICE_CONFIRMED_VT_CLOSE: - // Security Services + // Security Services case SERVICE_CONFIRMED_REQUEST_KEY: - Confirmed_ACK_Function[service_choice] = (void *)pFunction; - break; + Confirmed_ACK_Function[service_choice] = (void *) pFunction; + break; default: - break; - } + break; + } } -void apdu_set_confirmed_ack_handler( - BACNET_CONFIRMED_SERVICE service_choice, - confirmed_ack_function pFunction) +void apdu_set_confirmed_ack_handler(BACNET_CONFIRMED_SERVICE + service_choice, confirmed_ack_function pFunction) { - switch (service_choice) - { + switch (service_choice) { case SERVICE_CONFIRMED_GET_ALARM_SUMMARY: case SERVICE_CONFIRMED_GET_ENROLLMENT_SUMMARY: case SERVICE_CONFIRMED_GET_EVENT_INFORMATION: - // File Access Services + // File Access Services case SERVICE_CONFIRMED_ATOMIC_READ_FILE: case SERVICE_CONFIRMED_ATOMIC_WRITE_FILE: - // Object Access Services + // Object Access Services case SERVICE_CONFIRMED_CREATE_OBJECT: case SERVICE_CONFIRMED_READ_PROPERTY: case SERVICE_CONFIRMED_READ_PROPERTY_CONDITIONAL: case SERVICE_CONFIRMED_READ_PROPERTY_MULTIPLE: case SERVICE_CONFIRMED_READ_RANGE: - // Remote Device Management Services + // Remote Device Management Services case SERVICE_CONFIRMED_PRIVATE_TRANSFER: - // Virtual Terminal Services + // Virtual Terminal Services case SERVICE_CONFIRMED_VT_OPEN: case SERVICE_CONFIRMED_VT_DATA: - // Security Services + // Security Services case SERVICE_CONFIRMED_AUTHENTICATE: - Confirmed_ACK_Function[service_choice] = (void *)pFunction; - break; + Confirmed_ACK_Function[service_choice] = (void *) pFunction; + break; default: - break; - } + break; + } } -static error_function -Error_Function[MAX_BACNET_CONFIRMED_SERVICE]; +static error_function Error_Function[MAX_BACNET_CONFIRMED_SERVICE]; -void apdu_set_error_handler( - BACNET_CONFIRMED_SERVICE service_choice, - error_function pFunction) +void apdu_set_error_handler(BACNET_CONFIRMED_SERVICE service_choice, + error_function pFunction) { - if (service_choice < MAX_BACNET_CONFIRMED_SERVICE) - Error_Function[service_choice] = pFunction; + if (service_choice < MAX_BACNET_CONFIRMED_SERVICE) + Error_Function[service_choice] = pFunction; } static abort_function Abort_Function; -void apdu_set_abort_handler( - abort_function pFunction) +void apdu_set_abort_handler(abort_function pFunction) { - Abort_Function = pFunction; + Abort_Function = pFunction; } static reject_function Reject_Function; -void apdu_set_reject_handler( - reject_function pFunction) +void apdu_set_reject_handler(reject_function pFunction) { - Reject_Function = pFunction; + Reject_Function = pFunction; } -uint16_t apdu_decode_confirmed_service_request( - uint8_t *apdu, // APDU data - uint16_t apdu_len, - BACNET_CONFIRMED_SERVICE_DATA *service_data, - uint8_t *service_choice, - uint8_t **service_request, - uint16_t *service_request_len) +uint16_t apdu_decode_confirmed_service_request(uint8_t * apdu, // APDU data + uint16_t apdu_len, + BACNET_CONFIRMED_SERVICE_DATA * service_data, + uint8_t * service_choice, + uint8_t ** service_request, uint16_t * service_request_len) { - uint16_t len = 0; // counts where we are in PDU - - service_data->segmented_message = (apdu[0] & BIT3) ? true : false; - service_data->more_follows = (apdu[0] & BIT2) ? true : false; - service_data->segmented_response_accepted = (apdu[0] & BIT1) ? true : false; - service_data->max_segs = decode_max_segs(apdu[1]); - service_data->max_resp = decode_max_apdu(apdu[1]); - service_data->invoke_id = apdu[2]; - len = 3; - if (service_data->segmented_message) - { - service_data->sequence_number = apdu[len++]; - service_data->proposed_window_number = apdu[len++]; - } - *service_choice = apdu[len++]; - *service_request = &apdu[len]; - *service_request_len = apdu_len - len; + uint16_t len = 0; // counts where we are in PDU - return len; -} - -void apdu_handler( - BACNET_ADDRESS *src, // source address - bool data_expecting_reply, - uint8_t *apdu, // APDU data - uint16_t apdu_len) -{ - BACNET_CONFIRMED_SERVICE_DATA service_data = {0}; - BACNET_CONFIRMED_SERVICE_ACK_DATA service_ack_data = {0}; - uint8_t invoke_id = 0; - uint8_t service_choice = 0; - uint8_t *service_request = NULL; - uint16_t service_request_len = 0; - uint16_t len = 0; // counts where we are in PDU - uint8_t tag_number = 0; - uint32_t len_value = 0; - int error_code = 0; - int error_class = 0; - uint8_t reason = 0; - - (void)data_expecting_reply; - if (apdu) - { - // PDU Type - switch (apdu[0] & 0xF0) - { - case PDU_TYPE_CONFIRMED_SERVICE_REQUEST: - len = apdu_decode_confirmed_service_request( - &apdu[0], // APDU data - apdu_len, - &service_data, - &service_choice, - &service_request, - &service_request_len); - /* When network communications are completely disabled, - only DeviceCommunicationControl and ReinitializeDevice APDUs - shall be processed and no messages shall be initiated.*/ - if (dcc_communication_disabled() && - ((service_choice != SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL) && - (service_choice != SERVICE_CONFIRMED_REINITIALIZE_DEVICE))) - break; - if ((service_choice < MAX_BACNET_CONFIRMED_SERVICE) && - (Confirmed_Function[service_choice])) - Confirmed_Function[service_choice]( - service_request, - service_request_len, - src, - &service_data); - else if (Unrecognized_Service_Handler) - Unrecognized_Service_Handler( - service_request, - service_request_len, - src, - &service_data); - break; - case PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST: - if (dcc_communication_disabled()) - break; - service_choice = apdu[1]; - service_request = &apdu[2]; - service_request_len = apdu_len - 2; - if (service_choice < MAX_BACNET_UNCONFIRMED_SERVICE) - { - if (Unconfirmed_Function[service_choice]) - Unconfirmed_Function[service_choice]( - service_request, - service_request_len, - src); - } - break; - case PDU_TYPE_SIMPLE_ACK: - invoke_id = apdu[1]; - service_choice = apdu[2]; - switch (service_choice) - { - case SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM: - case SERVICE_CONFIRMED_COV_NOTIFICATION: - case SERVICE_CONFIRMED_EVENT_NOTIFICATION: - case SERVICE_CONFIRMED_SUBSCRIBE_COV: - case SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY: - case SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION: - // Object Access Services - case SERVICE_CONFIRMED_ADD_LIST_ELEMENT: - case SERVICE_CONFIRMED_REMOVE_LIST_ELEMENT: - case SERVICE_CONFIRMED_DELETE_OBJECT: - case SERVICE_CONFIRMED_WRITE_PROPERTY: - case SERVICE_CONFIRMED_WRITE_PROPERTY_MULTIPLE: - // Remote Device Management Services - case SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL: - case SERVICE_CONFIRMED_REINITIALIZE_DEVICE: - case SERVICE_CONFIRMED_TEXT_MESSAGE: - // Virtual Terminal Services - case SERVICE_CONFIRMED_VT_CLOSE: - // Security Services - case SERVICE_CONFIRMED_REQUEST_KEY: - if (Confirmed_ACK_Function[service_choice]) - { - ((confirmed_simple_ack_function) - Confirmed_ACK_Function[service_choice])( - src, - invoke_id); - } - tsm_free_invoke_id(invoke_id); - break; - default: - break; - } - break; - case PDU_TYPE_COMPLEX_ACK: - service_ack_data.segmented_message = (apdu[0] & BIT3) ? true : false; - service_ack_data.more_follows = (apdu[0] & BIT2) ? true : false; - invoke_id = service_ack_data.invoke_id = apdu[1]; - len = 2; - if (service_ack_data.segmented_message) - { - service_ack_data.sequence_number = apdu[len++]; - service_ack_data.proposed_window_number = apdu[len++]; - } - service_choice = apdu[len++]; - service_request = &apdu[len]; - service_request_len = apdu_len - len; - switch (service_choice) - { - case SERVICE_CONFIRMED_GET_ALARM_SUMMARY: - case SERVICE_CONFIRMED_GET_ENROLLMENT_SUMMARY: - case SERVICE_CONFIRMED_GET_EVENT_INFORMATION: - // File Access Services - case SERVICE_CONFIRMED_ATOMIC_READ_FILE: - case SERVICE_CONFIRMED_ATOMIC_WRITE_FILE: - // Object Access Services - case SERVICE_CONFIRMED_CREATE_OBJECT: - case SERVICE_CONFIRMED_READ_PROPERTY: - case SERVICE_CONFIRMED_READ_PROPERTY_CONDITIONAL: - case SERVICE_CONFIRMED_READ_PROPERTY_MULTIPLE: - case SERVICE_CONFIRMED_READ_RANGE: - case SERVICE_CONFIRMED_PRIVATE_TRANSFER: - // Virtual Terminal Services - case SERVICE_CONFIRMED_VT_OPEN: - case SERVICE_CONFIRMED_VT_DATA: - // Security Services - case SERVICE_CONFIRMED_AUTHENTICATE: - if (Confirmed_ACK_Function[service_choice]) - { - ((confirmed_ack_function) - Confirmed_ACK_Function[service_choice])( - service_request, - service_request_len, - src, - &service_ack_data); - } - tsm_free_invoke_id(invoke_id); - break; - default: - break; - } - break; - case PDU_TYPE_SEGMENT_ACK: - /* FIXME: what about a denial of service attack here? - we could check src to see if that matched the tsm */ - tsm_free_invoke_id(invoke_id); - break; - case PDU_TYPE_ERROR: - invoke_id = apdu[1]; - service_choice = apdu[2]; - len = 3; - len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); - /* FIXME: we could validate that the tag is enumerated... */ - len += decode_enumerated(&apdu[len],len_value, &error_class); - len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); - /* FIXME: we could validate that the tag is enumerated... */ - len += decode_enumerated(&apdu[len],len_value, &error_code); - if (service_choice < MAX_BACNET_CONFIRMED_SERVICE) - { - if (Error_Function[service_choice]) - Error_Function[service_choice]( - src, - invoke_id, - error_class, - error_code); - } - tsm_free_invoke_id(invoke_id); - break; - case PDU_TYPE_REJECT: - invoke_id = apdu[1]; - reason = apdu[2]; - if (Reject_Function) - Reject_Function( - src, - invoke_id, - reason); - tsm_free_invoke_id(invoke_id); - break; - case PDU_TYPE_ABORT: - invoke_id = apdu[1]; - reason = apdu[2]; - if (Abort_Function) - Abort_Function( - src, - invoke_id, - reason); - tsm_free_invoke_id(invoke_id); - break; - default: - break; + service_data->segmented_message = (apdu[0] & BIT3) ? true : false; + service_data->more_follows = (apdu[0] & BIT2) ? true : false; + service_data->segmented_response_accepted = + (apdu[0] & BIT1) ? true : false; + service_data->max_segs = decode_max_segs(apdu[1]); + service_data->max_resp = decode_max_apdu(apdu[1]); + service_data->invoke_id = apdu[2]; + len = 3; + if (service_data->segmented_message) { + service_data->sequence_number = apdu[len++]; + service_data->proposed_window_number = apdu[len++]; } - } - return; + *service_choice = apdu[len++]; + *service_request = &apdu[len]; + *service_request_len = apdu_len - len; + + return len; } +void apdu_handler(BACNET_ADDRESS * src, // source address + bool data_expecting_reply, uint8_t * apdu, // APDU data + uint16_t apdu_len) +{ + BACNET_CONFIRMED_SERVICE_DATA service_data = { 0 }; + BACNET_CONFIRMED_SERVICE_ACK_DATA service_ack_data = { 0 }; + uint8_t invoke_id = 0; + uint8_t service_choice = 0; + uint8_t *service_request = NULL; + uint16_t service_request_len = 0; + uint16_t len = 0; // counts where we are in PDU + uint8_t tag_number = 0; + uint32_t len_value = 0; + int error_code = 0; + int error_class = 0; + uint8_t reason = 0; + + (void) data_expecting_reply; + if (apdu) { + // PDU Type + switch (apdu[0] & 0xF0) { + case PDU_TYPE_CONFIRMED_SERVICE_REQUEST: + len = apdu_decode_confirmed_service_request(&apdu[0], // APDU data + apdu_len, + &service_data, + &service_choice, &service_request, &service_request_len); + /* When network communications are completely disabled, + only DeviceCommunicationControl and ReinitializeDevice APDUs + shall be processed and no messages shall be initiated. */ + if (dcc_communication_disabled() && + ((service_choice != + SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL) + && (service_choice != + SERVICE_CONFIRMED_REINITIALIZE_DEVICE))) + break; + if ((service_choice < MAX_BACNET_CONFIRMED_SERVICE) && + (Confirmed_Function[service_choice])) + Confirmed_Function[service_choice] (service_request, + service_request_len, src, &service_data); + else if (Unrecognized_Service_Handler) + Unrecognized_Service_Handler(service_request, + service_request_len, src, &service_data); + break; + case PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST: + if (dcc_communication_disabled()) + break; + service_choice = apdu[1]; + service_request = &apdu[2]; + service_request_len = apdu_len - 2; + if (service_choice < MAX_BACNET_UNCONFIRMED_SERVICE) { + if (Unconfirmed_Function[service_choice]) + Unconfirmed_Function[service_choice] (service_request, + service_request_len, src); + } + break; + case PDU_TYPE_SIMPLE_ACK: + invoke_id = apdu[1]; + service_choice = apdu[2]; + switch (service_choice) { + case SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM: + case SERVICE_CONFIRMED_COV_NOTIFICATION: + case SERVICE_CONFIRMED_EVENT_NOTIFICATION: + case SERVICE_CONFIRMED_SUBSCRIBE_COV: + case SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY: + case SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION: + // Object Access Services + case SERVICE_CONFIRMED_ADD_LIST_ELEMENT: + case SERVICE_CONFIRMED_REMOVE_LIST_ELEMENT: + case SERVICE_CONFIRMED_DELETE_OBJECT: + case SERVICE_CONFIRMED_WRITE_PROPERTY: + case SERVICE_CONFIRMED_WRITE_PROPERTY_MULTIPLE: + // Remote Device Management Services + case SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL: + case SERVICE_CONFIRMED_REINITIALIZE_DEVICE: + case SERVICE_CONFIRMED_TEXT_MESSAGE: + // Virtual Terminal Services + case SERVICE_CONFIRMED_VT_CLOSE: + // Security Services + case SERVICE_CONFIRMED_REQUEST_KEY: + if (Confirmed_ACK_Function[service_choice]) { + ((confirmed_simple_ack_function) + Confirmed_ACK_Function[service_choice]) (src, + invoke_id); + } + tsm_free_invoke_id(invoke_id); + break; + default: + break; + } + break; + case PDU_TYPE_COMPLEX_ACK: + service_ack_data.segmented_message = + (apdu[0] & BIT3) ? true : false; + service_ack_data.more_follows = + (apdu[0] & BIT2) ? true : false; + invoke_id = service_ack_data.invoke_id = apdu[1]; + len = 2; + if (service_ack_data.segmented_message) { + service_ack_data.sequence_number = apdu[len++]; + service_ack_data.proposed_window_number = apdu[len++]; + } + service_choice = apdu[len++]; + service_request = &apdu[len]; + service_request_len = apdu_len - len; + switch (service_choice) { + case SERVICE_CONFIRMED_GET_ALARM_SUMMARY: + case SERVICE_CONFIRMED_GET_ENROLLMENT_SUMMARY: + case SERVICE_CONFIRMED_GET_EVENT_INFORMATION: + // File Access Services + case SERVICE_CONFIRMED_ATOMIC_READ_FILE: + case SERVICE_CONFIRMED_ATOMIC_WRITE_FILE: + // Object Access Services + case SERVICE_CONFIRMED_CREATE_OBJECT: + case SERVICE_CONFIRMED_READ_PROPERTY: + case SERVICE_CONFIRMED_READ_PROPERTY_CONDITIONAL: + case SERVICE_CONFIRMED_READ_PROPERTY_MULTIPLE: + case SERVICE_CONFIRMED_READ_RANGE: + case SERVICE_CONFIRMED_PRIVATE_TRANSFER: + // Virtual Terminal Services + case SERVICE_CONFIRMED_VT_OPEN: + case SERVICE_CONFIRMED_VT_DATA: + // Security Services + case SERVICE_CONFIRMED_AUTHENTICATE: + if (Confirmed_ACK_Function[service_choice]) { + ((confirmed_ack_function) + Confirmed_ACK_Function[service_choice]) + (service_request, service_request_len, src, + &service_ack_data); + } + tsm_free_invoke_id(invoke_id); + break; + default: + break; + } + break; + case PDU_TYPE_SEGMENT_ACK: + /* FIXME: what about a denial of service attack here? + we could check src to see if that matched the tsm */ + tsm_free_invoke_id(invoke_id); + break; + case PDU_TYPE_ERROR: + invoke_id = apdu[1]; + service_choice = apdu[2]; + len = 3; + len += + decode_tag_number_and_value(&apdu[len], &tag_number, + &len_value); + /* FIXME: we could validate that the tag is enumerated... */ + len += decode_enumerated(&apdu[len], len_value, &error_class); + len += + decode_tag_number_and_value(&apdu[len], &tag_number, + &len_value); + /* FIXME: we could validate that the tag is enumerated... */ + len += decode_enumerated(&apdu[len], len_value, &error_code); + if (service_choice < MAX_BACNET_CONFIRMED_SERVICE) { + if (Error_Function[service_choice]) + Error_Function[service_choice] (src, + invoke_id, error_class, error_code); + } + tsm_free_invoke_id(invoke_id); + break; + case PDU_TYPE_REJECT: + invoke_id = apdu[1]; + reason = apdu[2]; + if (Reject_Function) + Reject_Function(src, invoke_id, reason); + tsm_free_invoke_id(invoke_id); + break; + case PDU_TYPE_ABORT: + invoke_id = apdu[1]; + reason = apdu[2]; + if (Abort_Function) + Abort_Function(src, invoke_id, reason); + tsm_free_invoke_id(invoke_id); + break; + default: + break; + } + } + return; +} diff --git a/bacnet-stack/apdu.h b/bacnet-stack/apdu.h index 0f8ded8f..fb6f1932 100644 --- a/bacnet-stack/apdu.h +++ b/bacnet-stack/apdu.h @@ -41,28 +41,26 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ -typedef struct _confirmed_service_data -{ - bool segmented_message; - bool more_follows; - bool segmented_response_accepted; - int max_segs; - int max_resp; - uint8_t invoke_id; - uint8_t sequence_number; - uint8_t proposed_window_number; -} BACNET_CONFIRMED_SERVICE_DATA; + typedef struct _confirmed_service_data { + bool segmented_message; + bool more_follows; + bool segmented_response_accepted; + int max_segs; + int max_resp; + uint8_t invoke_id; + uint8_t sequence_number; + uint8_t proposed_window_number; + } BACNET_CONFIRMED_SERVICE_DATA; -typedef struct _confirmed_service_ack_data -{ - bool segmented_message; - bool more_follows; - uint8_t invoke_id; - uint8_t sequence_number; - uint8_t proposed_window_number; -} BACNET_CONFIRMED_SERVICE_ACK_DATA; + typedef struct _confirmed_service_ack_data { + bool segmented_message; + bool more_follows; + uint8_t invoke_id; + uint8_t sequence_number; + uint8_t proposed_window_number; + } BACNET_CONFIRMED_SERVICE_ACK_DATA; // generic unconfirmed function handler // Suitable to handle the following services: @@ -70,10 +68,8 @@ typedef struct _confirmed_service_ack_data // Unconfirmed_Event_Notification, Unconfirmed_Private_Transfer, // Unconfirmed_Text_Message, Time_Synchronization, Who_Has, // UTC_Time_Synchronization -typedef void (*unconfirmed_function)( - uint8_t *service_request, - uint16_t len, - BACNET_ADDRESS *src); + typedef void (*unconfirmed_function) (uint8_t * service_request, + uint16_t len, BACNET_ADDRESS * src); // generic confirmed function handler // Suitable to handle the following services: @@ -91,100 +87,79 @@ typedef void (*unconfirmed_function)( // Confirmed_Text_Message, Reinitialize_Device, // VT_Open, VT_Close, VT_Data_Handler, // Authenticate, Request_Key -typedef void (*confirmed_function)( - uint8_t *service_request, - uint16_t service_len, - BACNET_ADDRESS *src, - BACNET_CONFIRMED_SERVICE_DATA *service_data); + typedef void (*confirmed_function) (uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_DATA * service_data); // generic confirmed simple ack function handler -typedef void (*confirmed_simple_ack_function)( - BACNET_ADDRESS *src, - uint8_t invoke_id); + typedef void (*confirmed_simple_ack_function) (BACNET_ADDRESS * src, + uint8_t invoke_id); // generic confirmed ack function handler -typedef void (*confirmed_ack_function)( - uint8_t *service_request, - uint16_t service_len, - BACNET_ADDRESS *src, - BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data); + typedef void (*confirmed_ack_function) (uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data); // generic error reply function -typedef void (*error_function)( - BACNET_ADDRESS *src, - uint8_t invoke_id, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code); + typedef void (*error_function) (BACNET_ADDRESS * src, + uint8_t invoke_id, + BACNET_ERROR_CLASS error_class, BACNET_ERROR_CODE error_code); // generic abort reply function -typedef void (*abort_function)( - BACNET_ADDRESS *src, - uint8_t invoke_id, - uint8_t abort_reason); + typedef void (*abort_function) (BACNET_ADDRESS * src, + uint8_t invoke_id, uint8_t abort_reason); // generic reject reply function -typedef void (*reject_function)( - BACNET_ADDRESS *src, - uint8_t invoke_id, - uint8_t reject_reason); + typedef void (*reject_function) (BACNET_ADDRESS * src, + uint8_t invoke_id, uint8_t reject_reason); -void apdu_set_confirmed_ack_handler( - BACNET_CONFIRMED_SERVICE service_choice, - confirmed_ack_function pFunction); + void apdu_set_confirmed_ack_handler(BACNET_CONFIRMED_SERVICE + service_choice, confirmed_ack_function pFunction); -void apdu_set_confirmed_simple_ack_handler( - BACNET_CONFIRMED_SERVICE service_choice, - confirmed_simple_ack_function pFunction); + void apdu_set_confirmed_simple_ack_handler(BACNET_CONFIRMED_SERVICE + service_choice, confirmed_simple_ack_function pFunction); // configure reject for confirmed services that are not supported -void apdu_set_unrecognized_service_handler_handler( - confirmed_function pFunction); + void apdu_set_unrecognized_service_handler_handler(confirmed_function + pFunction); -void apdu_set_confirmed_handler( - BACNET_CONFIRMED_SERVICE service_choice, - confirmed_function pFunction); + void apdu_set_confirmed_handler(BACNET_CONFIRMED_SERVICE + service_choice, confirmed_function pFunction); /* returns true if the handler is set */ -bool apdu_confirmed_handler( - BACNET_CONFIRMED_SERVICE service_choice); + bool apdu_confirmed_handler(BACNET_CONFIRMED_SERVICE service_choice); -void apdu_set_unconfirmed_handler( - BACNET_UNCONFIRMED_SERVICE service_choice, - unconfirmed_function pFunction); + void apdu_set_unconfirmed_handler(BACNET_UNCONFIRMED_SERVICE + service_choice, unconfirmed_function pFunction); /* returns true if the handler is set */ -bool apdu_unconfirmed_handler( - BACNET_UNCONFIRMED_SERVICE service_choice); + bool apdu_unconfirmed_handler(BACNET_UNCONFIRMED_SERVICE + service_choice); /* returns true if the service is supported by a handler */ -bool apdu_service_supported(BACNET_SERVICES_SUPPORTED service_supported); + bool apdu_service_supported(BACNET_SERVICES_SUPPORTED + service_supported); -void apdu_set_error_handler( - BACNET_CONFIRMED_SERVICE service_choice, - error_function pFunction); + void apdu_set_error_handler(BACNET_CONFIRMED_SERVICE service_choice, + error_function pFunction); -void apdu_set_abort_handler( - abort_function pFunction); + void apdu_set_abort_handler(abort_function pFunction); -void apdu_set_reject_handler( - reject_function pFunction); + void apdu_set_reject_handler(reject_function pFunction); -uint16_t apdu_decode_confirmed_service_request( - uint8_t *apdu, // APDU data - uint16_t apdu_len, - BACNET_CONFIRMED_SERVICE_DATA *service_data, - uint8_t *service_choice, - uint8_t **service_request, - uint16_t *service_request_len); + uint16_t apdu_decode_confirmed_service_request(uint8_t * apdu, // APDU data + uint16_t apdu_len, + BACNET_CONFIRMED_SERVICE_DATA * service_data, + uint8_t * service_choice, + uint8_t ** service_request, uint16_t * service_request_len); -void apdu_handler( - BACNET_ADDRESS *src, // source address - bool data_expecting_reply, - uint8_t *apdu, // APDU data - uint16_t pdu_len); // for confirmed messages + void apdu_handler(BACNET_ADDRESS * src, // source address + bool data_expecting_reply, uint8_t * apdu, // APDU data + uint16_t pdu_len); // for confirmed messages #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif diff --git a/bacnet-stack/arcnet.h b/bacnet-stack/arcnet.h index 93726c26..c9e8dc0c 100644 --- a/bacnet-stack/arcnet.h +++ b/bacnet-stack/arcnet.h @@ -45,41 +45,36 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ -bool arcnet_valid(void); -void arcnet_cleanup(void); -bool arcnet_init(char *interface_name); + bool arcnet_valid(void); + void arcnet_cleanup(void); + bool arcnet_init(char *interface_name); /* function to send a packet out the 802.2 socket */ /* returns 0 on success, non-zero on failure */ -int arcnet_send( - BACNET_ADDRESS *dest, // destination address - BACNET_ADDRESS *src, // source address - uint8_t *pdu, // any data to be sent - may be null - unsigned pdu_len); // number of bytes of data + int arcnet_send(BACNET_ADDRESS * dest, // destination address + BACNET_ADDRESS * src, // source address + uint8_t * pdu, // any data to be sent - may be null + unsigned pdu_len); // number of bytes of data /* function to send a packet out the 802.2 socket */ /* returns zero on success, non-zero on failure */ -int arcnet_send_pdu( - BACNET_ADDRESS *dest, // destination address - uint8_t *pdu, // any data to be sent - may be null - unsigned pdu_len); // number of bytes of data + int arcnet_send_pdu(BACNET_ADDRESS * dest, // destination address + uint8_t * pdu, // any data to be sent - may be null + unsigned pdu_len); // number of bytes of data // receives an framed packet // returns the number of octets in the PDU, or zero on failure -uint16_t arcnet_receive( - BACNET_ADDRESS *src, // source address - uint8_t *pdu, // PDU data - uint16_t max_pdu, // amount of space available in the PDU - unsigned timeout); // milliseconds to wait for a packet + uint16_t arcnet_receive(BACNET_ADDRESS * src, // source address + uint8_t * pdu, // PDU data + uint16_t max_pdu, // amount of space available in the PDU + unsigned timeout); // milliseconds to wait for a packet -void arcnet_get_my_address(BACNET_ADDRESS *my_address); -void arcnet_get_broadcast_address( - BACNET_ADDRESS *dest); // destination address + void arcnet_get_my_address(BACNET_ADDRESS * my_address); + void arcnet_get_broadcast_address(BACNET_ADDRESS * dest); // destination address #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif diff --git a/bacnet-stack/arf.c b/bacnet-stack/arf.c index c2ab9c79..a001c53a 100644 --- a/bacnet-stack/arf.c +++ b/bacnet-stack/arf.c @@ -41,324 +41,289 @@ // Atomic Read File // encode service -int arf_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - BACNET_ATOMIC_READ_FILE_DATA *data) +int arf_encode_apdu(uint8_t * apdu, + uint8_t invoke_id, BACNET_ATOMIC_READ_FILE_DATA * data) { - int apdu_len = 0; // total length of the apdu, return value + int apdu_len = 0; // total length of the apdu, return value - if (apdu) - { - apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST; - apdu[1] = encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); - apdu[2] = invoke_id; - apdu[3] = SERVICE_CONFIRMED_ATOMIC_READ_FILE; // service choice - apdu_len = 4; - apdu_len += encode_tagged_object_id(&apdu[apdu_len], - data->object_type, data->object_instance); - switch (data->access) - { - case FILE_STREAM_ACCESS: - apdu_len += encode_opening_tag(&apdu[apdu_len], 0); - apdu_len += encode_tagged_signed(&apdu[apdu_len], - data->type.stream.fileStartPosition); - apdu_len += encode_tagged_unsigned(&apdu[apdu_len], - data->type.stream.requestedOctetCount); - apdu_len += encode_closing_tag(&apdu[apdu_len], 0); - break; - case FILE_RECORD_ACCESS: - apdu_len += encode_opening_tag(&apdu[apdu_len], 1); - apdu_len += encode_tagged_signed(&apdu[apdu_len], - data->type.record.fileStartRecord); - apdu_len += encode_tagged_unsigned(&apdu[apdu_len], - data->type.record.RecordCount); - apdu_len += encode_closing_tag(&apdu[apdu_len], 1); - break; - default: - break; + if (apdu) { + apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST; + apdu[1] = + encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); + apdu[2] = invoke_id; + apdu[3] = SERVICE_CONFIRMED_ATOMIC_READ_FILE; // service choice + apdu_len = 4; + apdu_len += encode_tagged_object_id(&apdu[apdu_len], + data->object_type, data->object_instance); + switch (data->access) { + case FILE_STREAM_ACCESS: + apdu_len += encode_opening_tag(&apdu[apdu_len], 0); + apdu_len += encode_tagged_signed(&apdu[apdu_len], + data->type.stream.fileStartPosition); + apdu_len += encode_tagged_unsigned(&apdu[apdu_len], + data->type.stream.requestedOctetCount); + apdu_len += encode_closing_tag(&apdu[apdu_len], 0); + break; + case FILE_RECORD_ACCESS: + apdu_len += encode_opening_tag(&apdu[apdu_len], 1); + apdu_len += encode_tagged_signed(&apdu[apdu_len], + data->type.record.fileStartRecord); + apdu_len += encode_tagged_unsigned(&apdu[apdu_len], + data->type.record.RecordCount); + apdu_len += encode_closing_tag(&apdu[apdu_len], 1); + break; + default: + break; + } } - } - - return apdu_len; + + return apdu_len; } // decode the service request only -int arf_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - BACNET_ATOMIC_READ_FILE_DATA *data) +int arf_decode_service_request(uint8_t * apdu, + unsigned apdu_len, BACNET_ATOMIC_READ_FILE_DATA * data) { - int len = 0; - int tag_len = 0; - uint8_t tag_number = 0; - uint32_t len_value_type = 0; - int type = 0; // for decoding + int len = 0; + int tag_len = 0; + uint8_t tag_number = 0; + uint32_t len_value_type = 0; + int type = 0; // for decoding - // check for value pointers - if (apdu_len && data) - { - len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value_type); - if (tag_number != BACNET_APPLICATION_TAG_OBJECT_ID) - return -1; - len += decode_object_id(&apdu[len], &type, &data->object_instance); - data->object_type = type; - if (decode_is_opening_tag_number(&apdu[len], 0)) - { - data->access = FILE_STREAM_ACCESS; - // a tag number is not extended so only one octet - len++; - // fileStartPosition - tag_len = decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) - return -1; - len += decode_signed(&apdu[len], - len_value_type, - &data->type.stream.fileStartPosition); - // requestedOctetCount - tag_len = decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) - return -1; - len += decode_unsigned(&apdu[len], - len_value_type, - &data->type.stream.requestedOctetCount); - if (!decode_is_closing_tag_number(&apdu[len], 0)) - return -1; - // a tag number is not extended so only one octet - len++; + // check for value pointers + if (apdu_len && data) { + len = + decode_tag_number_and_value(&apdu[0], &tag_number, + &len_value_type); + if (tag_number != BACNET_APPLICATION_TAG_OBJECT_ID) + return -1; + len += decode_object_id(&apdu[len], &type, &data->object_instance); + data->object_type = type; + if (decode_is_opening_tag_number(&apdu[len], 0)) { + data->access = FILE_STREAM_ACCESS; + // a tag number is not extended so only one octet + len++; + // fileStartPosition + tag_len = decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + len += tag_len; + if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) + return -1; + len += decode_signed(&apdu[len], + len_value_type, &data->type.stream.fileStartPosition); + // requestedOctetCount + tag_len = decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + len += tag_len; + if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) + return -1; + len += decode_unsigned(&apdu[len], + len_value_type, &data->type.stream.requestedOctetCount); + if (!decode_is_closing_tag_number(&apdu[len], 0)) + return -1; + // a tag number is not extended so only one octet + len++; + } else if (decode_is_opening_tag_number(&apdu[len], 1)) { + data->access = FILE_RECORD_ACCESS; + // a tag number is not extended so only one octet + len++; + // fileStartRecord + tag_len = decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + len += tag_len; + if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) + return -1; + len += decode_signed(&apdu[len], + len_value_type, &data->type.record.fileStartRecord); + // RecordCount + tag_len = decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + len += tag_len; + if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) + return -1; + len += decode_unsigned(&apdu[len], + len_value_type, &data->type.record.RecordCount); + if (!decode_is_closing_tag_number(&apdu[len], 1)) + return -1; + // a tag number is not extended so only one octet + len++; + } else + return -1; } - else if (decode_is_opening_tag_number(&apdu[len], 1)) - { - data->access = FILE_RECORD_ACCESS; - // a tag number is not extended so only one octet - len++; - // fileStartRecord - tag_len = decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) - return -1; - len += decode_signed(&apdu[len], - len_value_type, - &data->type.record.fileStartRecord); - // RecordCount - tag_len = decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) - return -1; - len += decode_unsigned(&apdu[len], - len_value_type, - &data->type.record.RecordCount); - if (!decode_is_closing_tag_number(&apdu[len], 1)) - return -1; - // a tag number is not extended so only one octet - len++; - } - else - return -1; - } - return len; + return len; } -int arf_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - BACNET_ATOMIC_READ_FILE_DATA *data) +int arf_decode_apdu(uint8_t * apdu, + unsigned apdu_len, + uint8_t * invoke_id, BACNET_ATOMIC_READ_FILE_DATA * data) { - int len = 0; - unsigned offset = 0; + int len = 0; + unsigned offset = 0; - if (!apdu) - return -1; - // optional checking - most likely was already done prior to this call - if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) - return -1; - // apdu[1] = encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); - *invoke_id = apdu[2]; /* invoke id - filled in by net layer */ - if (apdu[3] != SERVICE_CONFIRMED_ATOMIC_READ_FILE) - return -1; - offset = 4; + if (!apdu) + return -1; + // optional checking - most likely was already done prior to this call + if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) + return -1; + // apdu[1] = encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); + *invoke_id = apdu[2]; /* invoke id - filled in by net layer */ + if (apdu[3] != SERVICE_CONFIRMED_ATOMIC_READ_FILE) + return -1; + offset = 4; - if (apdu_len > offset) - { - len = arf_decode_service_request( - &apdu[offset], - apdu_len - offset, - data); - } - - return len; + if (apdu_len > offset) { + len = arf_decode_service_request(&apdu[offset], + apdu_len - offset, data); + } + + return len; } // encode service -int arf_ack_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - BACNET_ATOMIC_READ_FILE_DATA *data) +int arf_ack_encode_apdu(uint8_t * apdu, + uint8_t invoke_id, BACNET_ATOMIC_READ_FILE_DATA * data) { - int apdu_len = 0; // total length of the apdu, return value + int apdu_len = 0; // total length of the apdu, return value - if (apdu) - { - apdu[0] = PDU_TYPE_COMPLEX_ACK; - apdu[1] = invoke_id; - apdu[2] = SERVICE_CONFIRMED_ATOMIC_READ_FILE; // service choice - apdu_len = 3; - // endOfFile - apdu_len += encode_tagged_boolean(&apdu[apdu_len], data->endOfFile); - switch (data->access) - { - case FILE_STREAM_ACCESS: - apdu_len += encode_opening_tag(&apdu[apdu_len], 0); - apdu_len += encode_tagged_signed(&apdu[apdu_len], - data->type.stream.fileStartPosition); - apdu_len += encode_tagged_octet_string(&apdu[apdu_len], - &data->fileData); - apdu_len += encode_closing_tag(&apdu[apdu_len], 0); - break; - case FILE_RECORD_ACCESS: - apdu_len += encode_opening_tag(&apdu[apdu_len], 1); - apdu_len += encode_tagged_signed(&apdu[apdu_len], - data->type.record.fileStartRecord); - apdu_len += encode_tagged_unsigned(&apdu[apdu_len], - data->type.record.RecordCount); - apdu_len += encode_tagged_octet_string(&apdu[apdu_len], - &data->fileData); - apdu_len += encode_closing_tag(&apdu[apdu_len], 1); - break; - default: - break; + if (apdu) { + apdu[0] = PDU_TYPE_COMPLEX_ACK; + apdu[1] = invoke_id; + apdu[2] = SERVICE_CONFIRMED_ATOMIC_READ_FILE; // service choice + apdu_len = 3; + // endOfFile + apdu_len += + encode_tagged_boolean(&apdu[apdu_len], data->endOfFile); + switch (data->access) { + case FILE_STREAM_ACCESS: + apdu_len += encode_opening_tag(&apdu[apdu_len], 0); + apdu_len += encode_tagged_signed(&apdu[apdu_len], + data->type.stream.fileStartPosition); + apdu_len += encode_tagged_octet_string(&apdu[apdu_len], + &data->fileData); + apdu_len += encode_closing_tag(&apdu[apdu_len], 0); + break; + case FILE_RECORD_ACCESS: + apdu_len += encode_opening_tag(&apdu[apdu_len], 1); + apdu_len += encode_tagged_signed(&apdu[apdu_len], + data->type.record.fileStartRecord); + apdu_len += encode_tagged_unsigned(&apdu[apdu_len], + data->type.record.RecordCount); + apdu_len += encode_tagged_octet_string(&apdu[apdu_len], + &data->fileData); + apdu_len += encode_closing_tag(&apdu[apdu_len], 1); + break; + default: + break; + } } - } - - return apdu_len; + + return apdu_len; } // decode the service request only -int arf_ack_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - BACNET_ATOMIC_READ_FILE_DATA *data) +int arf_ack_decode_service_request(uint8_t * apdu, + unsigned apdu_len, BACNET_ATOMIC_READ_FILE_DATA * data) { - int len = 0; - int tag_len = 0; - uint8_t tag_number = 0; - uint32_t len_value_type = 0; + int len = 0; + int tag_len = 0; + uint8_t tag_number = 0; + uint32_t len_value_type = 0; - // check for value pointers - if (apdu_len && data) - { - len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value_type); - if (tag_number != BACNET_APPLICATION_TAG_BOOLEAN) - return -1; - data->endOfFile = decode_boolean(len_value_type); - if (decode_is_opening_tag_number(&apdu[len], 0)) - { - data->access = FILE_STREAM_ACCESS; - // a tag number is not extended so only one octet - len++; - // fileStartPosition - tag_len = decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) - return -1; - len += decode_signed(&apdu[len], - len_value_type, - &data->type.stream.fileStartPosition); - // fileData - tag_len = decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_OCTET_STRING) - return -1; - len += decode_octet_string(&apdu[len], - len_value_type, - &data->fileData); - if (!decode_is_closing_tag_number(&apdu[len], 0)) - return -1; - // a tag number is not extended so only one octet - len++; + // check for value pointers + if (apdu_len && data) { + len = + decode_tag_number_and_value(&apdu[0], &tag_number, + &len_value_type); + if (tag_number != BACNET_APPLICATION_TAG_BOOLEAN) + return -1; + data->endOfFile = decode_boolean(len_value_type); + if (decode_is_opening_tag_number(&apdu[len], 0)) { + data->access = FILE_STREAM_ACCESS; + // a tag number is not extended so only one octet + len++; + // fileStartPosition + tag_len = decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + len += tag_len; + if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) + return -1; + len += decode_signed(&apdu[len], + len_value_type, &data->type.stream.fileStartPosition); + // fileData + tag_len = decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + len += tag_len; + if (tag_number != BACNET_APPLICATION_TAG_OCTET_STRING) + return -1; + len += decode_octet_string(&apdu[len], + len_value_type, &data->fileData); + if (!decode_is_closing_tag_number(&apdu[len], 0)) + return -1; + // a tag number is not extended so only one octet + len++; + } else if (decode_is_opening_tag_number(&apdu[len], 1)) { + data->access = FILE_RECORD_ACCESS; + // a tag number is not extended so only one octet + len++; + // fileStartRecord + tag_len = decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + len += tag_len; + if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) + return -1; + len += decode_signed(&apdu[len], + len_value_type, &data->type.record.fileStartRecord); + // returnedRecordCount + tag_len = decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + len += tag_len; + if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) + return -1; + len += decode_unsigned(&apdu[len], + len_value_type, &data->type.record.RecordCount); + // fileData + tag_len = decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + len += tag_len; + if (tag_number != BACNET_APPLICATION_TAG_OCTET_STRING) + return -1; + len += decode_octet_string(&apdu[len], + len_value_type, &data->fileData); + if (!decode_is_closing_tag_number(&apdu[len], 1)) + return -1; + // a tag number is not extended so only one octet + len++; + } else + return -1; } - else if (decode_is_opening_tag_number(&apdu[len], 1)) - { - data->access = FILE_RECORD_ACCESS; - // a tag number is not extended so only one octet - len++; - // fileStartRecord - tag_len = decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) - return -1; - len += decode_signed(&apdu[len], - len_value_type, - &data->type.record.fileStartRecord); - // returnedRecordCount - tag_len = decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) - return -1; - len += decode_unsigned(&apdu[len], - len_value_type, - &data->type.record.RecordCount); - // fileData - tag_len = decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_OCTET_STRING) - return -1; - len += decode_octet_string(&apdu[len], - len_value_type, - &data->fileData); - if (!decode_is_closing_tag_number(&apdu[len], 1)) - return -1; - // a tag number is not extended so only one octet - len++; - } - else - return -1; - } - return len; + return len; } -int arf_ack_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - BACNET_ATOMIC_READ_FILE_DATA *data) +int arf_ack_decode_apdu(uint8_t * apdu, + unsigned apdu_len, + uint8_t * invoke_id, BACNET_ATOMIC_READ_FILE_DATA * data) { - int len = 0; - unsigned offset = 0; + int len = 0; + unsigned offset = 0; - if (!apdu) - return -1; - // optional checking - most likely was already done prior to this call - if (apdu[0] != PDU_TYPE_COMPLEX_ACK) - return -1; - *invoke_id = apdu[1]; /* invoke id - filled in by net layer */ - if (apdu[2] != SERVICE_CONFIRMED_ATOMIC_READ_FILE) - return -1; - offset = 3; + if (!apdu) + return -1; + // optional checking - most likely was already done prior to this call + if (apdu[0] != PDU_TYPE_COMPLEX_ACK) + return -1; + *invoke_id = apdu[1]; /* invoke id - filled in by net layer */ + if (apdu[2] != SERVICE_CONFIRMED_ATOMIC_READ_FILE) + return -1; + offset = 3; - if (apdu_len > offset) - { - len = arf_ack_decode_service_request( - &apdu[offset], - apdu_len - offset, - data); - } - - return len; + if (apdu_len > offset) { + len = arf_ack_decode_service_request(&apdu[offset], + apdu_len - offset, data); + } + + return len; } @@ -368,143 +333,121 @@ int arf_ack_decode_apdu( #include "ctest.h" void testAtomicReadFileAckAccess(Test * pTest, - BACNET_ATOMIC_READ_FILE_DATA *data) + BACNET_ATOMIC_READ_FILE_DATA * data) { - BACNET_ATOMIC_READ_FILE_DATA test_data = {0}; - uint8_t apdu[480] = {0}; - int len = 0; - int apdu_len = 0; - uint8_t invoke_id = 128; - uint8_t test_invoke_id = 0; + BACNET_ATOMIC_READ_FILE_DATA test_data = { 0 }; + uint8_t apdu[480] = { 0 }; + int len = 0; + int apdu_len = 0; + uint8_t invoke_id = 128; + uint8_t test_invoke_id = 0; - len = arf_ack_encode_apdu( - &apdu[0], - invoke_id, - data); - ct_test(pTest, len != 0); - apdu_len = len; + len = arf_ack_encode_apdu(&apdu[0], invoke_id, data); + ct_test(pTest, len != 0); + apdu_len = len; - len = arf_ack_decode_apdu( - &apdu[0], - apdu_len, - &test_invoke_id, - &test_data); - ct_test(pTest, len != -1); - ct_test(pTest, test_data.endOfFile == data->endOfFile); - ct_test(pTest, test_data.access == data->access); - if (test_data.access == FILE_STREAM_ACCESS) - { - ct_test(pTest, test_data.type.stream.fileStartPosition == - data->type.stream.fileStartPosition); - } - else if (test_data.access == FILE_RECORD_ACCESS) - { - ct_test(pTest, test_data.type.record.fileStartRecord == - data->type.record.fileStartRecord); - ct_test(pTest, test_data.type.record.RecordCount == - data->type.record.RecordCount); - } - ct_test(pTest, octetstring_length(&test_data.fileData) == - octetstring_length(&data->fileData)); - ct_test(pTest, memcmp( - octetstring_value(&test_data.fileData), - octetstring_value(&data->fileData), - octetstring_length(&test_data.fileData)) == 0); + len = arf_ack_decode_apdu(&apdu[0], + apdu_len, &test_invoke_id, &test_data); + ct_test(pTest, len != -1); + ct_test(pTest, test_data.endOfFile == data->endOfFile); + ct_test(pTest, test_data.access == data->access); + if (test_data.access == FILE_STREAM_ACCESS) { + ct_test(pTest, test_data.type.stream.fileStartPosition == + data->type.stream.fileStartPosition); + } else if (test_data.access == FILE_RECORD_ACCESS) { + ct_test(pTest, test_data.type.record.fileStartRecord == + data->type.record.fileStartRecord); + ct_test(pTest, test_data.type.record.RecordCount == + data->type.record.RecordCount); + } + ct_test(pTest, octetstring_length(&test_data.fileData) == + octetstring_length(&data->fileData)); + ct_test(pTest, memcmp(octetstring_value(&test_data.fileData), + octetstring_value(&data->fileData), + octetstring_length(&test_data.fileData)) == 0); } void testAtomicReadFileAck(Test * pTest) { - BACNET_ATOMIC_READ_FILE_DATA data = {0}; - uint8_t test_octet_string[32] = "Joshua-Mary-Anna-Christopher"; - - - data.endOfFile = true; - data.access = FILE_STREAM_ACCESS; - data.type.stream.fileStartPosition = 0; - octetstring_init(&data.fileData, - test_octet_string, - sizeof(test_octet_string)); - testAtomicReadFileAckAccess(pTest, &data); + BACNET_ATOMIC_READ_FILE_DATA data = { 0 }; + uint8_t test_octet_string[32] = "Joshua-Mary-Anna-Christopher"; - data.endOfFile = false; - data.access = FILE_RECORD_ACCESS; - data.type.record.fileStartRecord = 1; - data.type.record.RecordCount = 2; - octetstring_init(&data.fileData, - test_octet_string, - sizeof(test_octet_string)); - testAtomicReadFileAckAccess(pTest, &data); - - return; + + data.endOfFile = true; + data.access = FILE_STREAM_ACCESS; + data.type.stream.fileStartPosition = 0; + octetstring_init(&data.fileData, + test_octet_string, sizeof(test_octet_string)); + testAtomicReadFileAckAccess(pTest, &data); + + data.endOfFile = false; + data.access = FILE_RECORD_ACCESS; + data.type.record.fileStartRecord = 1; + data.type.record.RecordCount = 2; + octetstring_init(&data.fileData, + test_octet_string, sizeof(test_octet_string)); + testAtomicReadFileAckAccess(pTest, &data); + + return; } void testAtomicReadFileAccess(Test * pTest, - BACNET_ATOMIC_READ_FILE_DATA *data) + BACNET_ATOMIC_READ_FILE_DATA * data) { - BACNET_ATOMIC_READ_FILE_DATA test_data = {0}; - uint8_t apdu[480] = {0}; - int len = 0; - int apdu_len = 0; - uint8_t invoke_id = 128; - uint8_t test_invoke_id = 0; + BACNET_ATOMIC_READ_FILE_DATA test_data = { 0 }; + uint8_t apdu[480] = { 0 }; + int len = 0; + int apdu_len = 0; + uint8_t invoke_id = 128; + uint8_t test_invoke_id = 0; - len = arf_encode_apdu( - &apdu[0], - invoke_id, - data); - ct_test(pTest, len != 0); - apdu_len = len; + len = arf_encode_apdu(&apdu[0], invoke_id, data); + ct_test(pTest, len != 0); + apdu_len = len; - len = arf_decode_apdu( - &apdu[0], - apdu_len, - &test_invoke_id, - &test_data); - ct_test(pTest, len != -1); - ct_test(pTest, test_data.object_type == data->object_type); - ct_test(pTest, test_data.object_instance == data->object_instance); - ct_test(pTest, test_data.access == data->access); - if (test_data.access == FILE_STREAM_ACCESS) - { - ct_test(pTest, test_data.type.stream.fileStartPosition == - data->type.stream.fileStartPosition); - ct_test(pTest, test_data.type.stream.requestedOctetCount == - data->type.stream.requestedOctetCount); - } - else if (test_data.access == FILE_RECORD_ACCESS) - { - ct_test(pTest, test_data.type.record.fileStartRecord == - data->type.record.fileStartRecord); - ct_test(pTest, test_data.type.record.RecordCount == - data->type.record.RecordCount); - } + len = arf_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, &test_data); + ct_test(pTest, len != -1); + ct_test(pTest, test_data.object_type == data->object_type); + ct_test(pTest, test_data.object_instance == data->object_instance); + ct_test(pTest, test_data.access == data->access); + if (test_data.access == FILE_STREAM_ACCESS) { + ct_test(pTest, test_data.type.stream.fileStartPosition == + data->type.stream.fileStartPosition); + ct_test(pTest, test_data.type.stream.requestedOctetCount == + data->type.stream.requestedOctetCount); + } else if (test_data.access == FILE_RECORD_ACCESS) { + ct_test(pTest, test_data.type.record.fileStartRecord == + data->type.record.fileStartRecord); + ct_test(pTest, test_data.type.record.RecordCount == + data->type.record.RecordCount); + } } void testAtomicReadFile(Test * pTest) { - BACNET_ATOMIC_READ_FILE_DATA data = {0}; - - data.object_type = OBJECT_FILE; - data.object_instance = 1; - data.access = FILE_STREAM_ACCESS; - data.type.stream.fileStartPosition = 0; - data.type.stream.requestedOctetCount = 128; - testAtomicReadFileAccess(pTest, &data); + BACNET_ATOMIC_READ_FILE_DATA data = { 0 }; - data.object_type = OBJECT_FILE; - data.object_instance = 2; - data.access = FILE_RECORD_ACCESS; - data.type.record.fileStartRecord = 1; - data.type.record.RecordCount = 2; - testAtomicReadFileAccess(pTest, &data); - - return; + data.object_type = OBJECT_FILE; + data.object_instance = 1; + data.access = FILE_STREAM_ACCESS; + data.type.stream.fileStartPosition = 0; + data.type.stream.requestedOctetCount = 128; + testAtomicReadFileAccess(pTest, &data); + + data.object_type = OBJECT_FILE; + data.object_instance = 2; + data.access = FILE_RECORD_ACCESS; + data.type.record.fileStartRecord = 1; + data.type.record.RecordCount = 2; + testAtomicReadFileAccess(pTest, &data); + + return; } #ifdef TEST_ATOMIC_READ_FILE uint16_t Device_Max_APDU_Length_Accepted(void) { - return MAX_APDU; + return MAX_APDU; } int main(void) diff --git a/bacnet-stack/arf.h b/bacnet-stack/arf.h index ab75ffee..0b260e7f 100644 --- a/bacnet-stack/arf.h +++ b/bacnet-stack/arf.h @@ -39,82 +39,64 @@ #include "bacdcode.h" #include "bacstr.h" -typedef struct BACnet_Atomic_Read_File_Data -{ - BACNET_OBJECT_TYPE object_type; - uint32_t object_instance; - BACNET_FILE_ACCESS_METHOD access; - union - { - struct - { - int32_t fileStartPosition; - uint32_t requestedOctetCount; - } stream; - struct - { - int32_t fileStartRecord; - // requested or returned record count - uint32_t RecordCount; - } record; - } type; - BACNET_OCTET_STRING fileData; - bool endOfFile; +typedef struct BACnet_Atomic_Read_File_Data { + BACNET_OBJECT_TYPE object_type; + uint32_t object_instance; + BACNET_FILE_ACCESS_METHOD access; + union { + struct { + int32_t fileStartPosition; + uint32_t requestedOctetCount; + } stream; + struct { + int32_t fileStartRecord; + // requested or returned record count + uint32_t RecordCount; + } record; + } type; + BACNET_OCTET_STRING fileData; + bool endOfFile; } BACNET_ATOMIC_READ_FILE_DATA; #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ // Atomic Read File // encode service -int arf_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - BACNET_ATOMIC_READ_FILE_DATA *data); + int arf_encode_apdu(uint8_t * apdu, + uint8_t invoke_id, BACNET_ATOMIC_READ_FILE_DATA * data); // decode the service request only -int arf_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - BACNET_ATOMIC_READ_FILE_DATA *data); - -int arf_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - BACNET_ATOMIC_READ_FILE_DATA *data); + int arf_decode_service_request(uint8_t * apdu, + unsigned apdu_len, BACNET_ATOMIC_READ_FILE_DATA * data); + + int arf_decode_apdu(uint8_t * apdu, + unsigned apdu_len, + uint8_t * invoke_id, BACNET_ATOMIC_READ_FILE_DATA * data); // Atomic Read File Ack // encode service -int arf_ack_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - BACNET_ATOMIC_READ_FILE_DATA *data); + int arf_ack_encode_apdu(uint8_t * apdu, + uint8_t invoke_id, BACNET_ATOMIC_READ_FILE_DATA * data); // decode the service request only -int arf_ack_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - BACNET_ATOMIC_READ_FILE_DATA *data); + int arf_ack_decode_service_request(uint8_t * apdu, + unsigned apdu_len, BACNET_ATOMIC_READ_FILE_DATA * data); -int arf_ack_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - BACNET_ATOMIC_READ_FILE_DATA *data); + int arf_ack_decode_apdu(uint8_t * apdu, + unsigned apdu_len, + uint8_t * invoke_id, BACNET_ATOMIC_READ_FILE_DATA * data); #ifdef TEST #include "ctest.h" -void test_AtomicReadFile(Test * pTest); -void test_AtomicReadFileAck(Test * pTest); + void test_AtomicReadFile(Test * pTest); + void test_AtomicReadFileAck(Test * pTest); #endif #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif - diff --git a/bacnet-stack/awf.c b/bacnet-stack/awf.c index 4292b826..159c5440 100644 --- a/bacnet-stack/awf.c +++ b/bacnet-stack/awf.c @@ -41,267 +41,233 @@ // Atomic Write File // encode service -int awf_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - BACNET_ATOMIC_WRITE_FILE_DATA *data) +int awf_encode_apdu(uint8_t * apdu, + uint8_t invoke_id, BACNET_ATOMIC_WRITE_FILE_DATA * data) { - int apdu_len = 0; // total length of the apdu, return value + int apdu_len = 0; // total length of the apdu, return value - if (apdu) - { - apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST; - apdu[1] = encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); - apdu[2] = invoke_id; - apdu[3] = SERVICE_CONFIRMED_ATOMIC_WRITE_FILE; // service choice - apdu_len = 4; - apdu_len += encode_tagged_object_id(&apdu[apdu_len], - data->object_type, data->object_instance); - switch (data->access) - { - case FILE_STREAM_ACCESS: - apdu_len += encode_opening_tag(&apdu[apdu_len], 0); - apdu_len += encode_tagged_signed(&apdu[apdu_len], - data->type.stream.fileStartPosition); - apdu_len += encode_tagged_octet_string(&apdu[apdu_len], - &data->fileData); - apdu_len += encode_closing_tag(&apdu[apdu_len], 0); - break; - case FILE_RECORD_ACCESS: - apdu_len += encode_opening_tag(&apdu[apdu_len], 1); - apdu_len += encode_tagged_signed(&apdu[apdu_len], - data->type.record.fileStartRecord); - apdu_len += encode_tagged_unsigned(&apdu[apdu_len], - data->type.record.returnedRecordCount); - apdu_len += encode_tagged_octet_string(&apdu[apdu_len], - &data->fileData); - apdu_len += encode_closing_tag(&apdu[apdu_len], 1); - break; - default: - break; + if (apdu) { + apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST; + apdu[1] = + encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); + apdu[2] = invoke_id; + apdu[3] = SERVICE_CONFIRMED_ATOMIC_WRITE_FILE; // service choice + apdu_len = 4; + apdu_len += encode_tagged_object_id(&apdu[apdu_len], + data->object_type, data->object_instance); + switch (data->access) { + case FILE_STREAM_ACCESS: + apdu_len += encode_opening_tag(&apdu[apdu_len], 0); + apdu_len += encode_tagged_signed(&apdu[apdu_len], + data->type.stream.fileStartPosition); + apdu_len += encode_tagged_octet_string(&apdu[apdu_len], + &data->fileData); + apdu_len += encode_closing_tag(&apdu[apdu_len], 0); + break; + case FILE_RECORD_ACCESS: + apdu_len += encode_opening_tag(&apdu[apdu_len], 1); + apdu_len += encode_tagged_signed(&apdu[apdu_len], + data->type.record.fileStartRecord); + apdu_len += encode_tagged_unsigned(&apdu[apdu_len], + data->type.record.returnedRecordCount); + apdu_len += encode_tagged_octet_string(&apdu[apdu_len], + &data->fileData); + apdu_len += encode_closing_tag(&apdu[apdu_len], 1); + break; + default: + break; + } } - } - - return apdu_len; + + return apdu_len; } // decode the service request only -int awf_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - BACNET_ATOMIC_WRITE_FILE_DATA *data) +int awf_decode_service_request(uint8_t * apdu, + unsigned apdu_len, BACNET_ATOMIC_WRITE_FILE_DATA * data) { - int len = 0; - int tag_len = 0; - uint8_t tag_number = 0; - uint32_t len_value_type = 0; - int type = 0; // for decoding + int len = 0; + int tag_len = 0; + uint8_t tag_number = 0; + uint32_t len_value_type = 0; + int type = 0; // for decoding - // check for value pointers - if (apdu_len && data) - { - len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value_type); - if (tag_number != BACNET_APPLICATION_TAG_OBJECT_ID) - return -1; - len += decode_object_id(&apdu[len], &type, &data->object_instance); - data->object_type = type; - if (decode_is_opening_tag_number(&apdu[len], 0)) - { - data->access = FILE_STREAM_ACCESS; - // a tag number of 2 is not extended so only one octet - len++; - // fileStartPosition - tag_len = decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) - return -1; - len += decode_signed(&apdu[len], - len_value_type, - &data->type.stream.fileStartPosition); - // fileData - tag_len = decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_OCTET_STRING) - return -1; - len += decode_octet_string(&apdu[len], - len_value_type, - &data->fileData); - if (!decode_is_closing_tag_number(&apdu[len], 0)) - return -1; - // a tag number is not extended so only one octet - len++; + // check for value pointers + if (apdu_len && data) { + len = + decode_tag_number_and_value(&apdu[0], &tag_number, + &len_value_type); + if (tag_number != BACNET_APPLICATION_TAG_OBJECT_ID) + return -1; + len += decode_object_id(&apdu[len], &type, &data->object_instance); + data->object_type = type; + if (decode_is_opening_tag_number(&apdu[len], 0)) { + data->access = FILE_STREAM_ACCESS; + // a tag number of 2 is not extended so only one octet + len++; + // fileStartPosition + tag_len = decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + len += tag_len; + if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) + return -1; + len += decode_signed(&apdu[len], + len_value_type, &data->type.stream.fileStartPosition); + // fileData + tag_len = decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + len += tag_len; + if (tag_number != BACNET_APPLICATION_TAG_OCTET_STRING) + return -1; + len += decode_octet_string(&apdu[len], + len_value_type, &data->fileData); + if (!decode_is_closing_tag_number(&apdu[len], 0)) + return -1; + // a tag number is not extended so only one octet + len++; + } else if (decode_is_opening_tag_number(&apdu[len], 1)) { + data->access = FILE_RECORD_ACCESS; + // a tag number is not extended so only one octet + len++; + // fileStartRecord + tag_len = decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + len += tag_len; + if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) + return -1; + len += decode_signed(&apdu[len], + len_value_type, &data->type.record.fileStartRecord); + // returnedRecordCount + tag_len = decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + len += tag_len; + if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) + return -1; + len += decode_unsigned(&apdu[len], + len_value_type, &data->type.record.returnedRecordCount); + // fileData + tag_len = decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + len += tag_len; + if (tag_number != BACNET_APPLICATION_TAG_OCTET_STRING) + return -1; + len += decode_octet_string(&apdu[len], + len_value_type, &data->fileData); + if (!decode_is_closing_tag_number(&apdu[len], 1)) + return -1; + // a tag number is not extended so only one octet + len++; + } else + return -1; } - else if (decode_is_opening_tag_number(&apdu[len], 1)) - { - data->access = FILE_RECORD_ACCESS; - // a tag number is not extended so only one octet - len++; - // fileStartRecord - tag_len = decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT) - return -1; - len += decode_signed(&apdu[len], - len_value_type, - &data->type.record.fileStartRecord); - // returnedRecordCount - tag_len = decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) - return -1; - len += decode_unsigned(&apdu[len], - len_value_type, - &data->type.record.returnedRecordCount); - // fileData - tag_len = decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - len += tag_len; - if (tag_number != BACNET_APPLICATION_TAG_OCTET_STRING) - return -1; - len += decode_octet_string(&apdu[len], - len_value_type, - &data->fileData); - if (!decode_is_closing_tag_number(&apdu[len], 1)) - return -1; - // a tag number is not extended so only one octet - len++; - } - else - return -1; - } - return len; + return len; } -int awf_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - BACNET_ATOMIC_WRITE_FILE_DATA *data) +int awf_decode_apdu(uint8_t * apdu, + unsigned apdu_len, + uint8_t * invoke_id, BACNET_ATOMIC_WRITE_FILE_DATA * data) { - int len = 0; - unsigned offset = 0; + int len = 0; + unsigned offset = 0; - if (!apdu) - return -1; - // optional checking - most likely was already done prior to this call - if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) - return -1; - // apdu[1] = encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); - *invoke_id = apdu[2]; /* invoke id - filled in by net layer */ - if (apdu[3] != SERVICE_CONFIRMED_ATOMIC_WRITE_FILE) - return -1; - offset = 4; + if (!apdu) + return -1; + // optional checking - most likely was already done prior to this call + if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) + return -1; + // apdu[1] = encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); + *invoke_id = apdu[2]; /* invoke id - filled in by net layer */ + if (apdu[3] != SERVICE_CONFIRMED_ATOMIC_WRITE_FILE) + return -1; + offset = 4; - if (apdu_len > offset) - { - len = awf_decode_service_request( - &apdu[offset], - apdu_len - offset, - data); - } - - return len; + if (apdu_len > offset) { + len = awf_decode_service_request(&apdu[offset], + apdu_len - offset, data); + } + + return len; } -int awf_ack_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - BACNET_ATOMIC_WRITE_FILE_DATA *data) +int awf_ack_encode_apdu(uint8_t * apdu, + uint8_t invoke_id, BACNET_ATOMIC_WRITE_FILE_DATA * data) { - int apdu_len = 0; // total length of the apdu, return value + int apdu_len = 0; // total length of the apdu, return value - if (apdu) - { - apdu[0] = PDU_TYPE_COMPLEX_ACK; - apdu[1] = invoke_id; - apdu[2] = SERVICE_CONFIRMED_ATOMIC_WRITE_FILE; // service choice - apdu_len = 3; - switch (data->access) - { - case FILE_STREAM_ACCESS: - apdu_len += encode_context_signed(&apdu[apdu_len], 0, - data->type.stream.fileStartPosition); - break; - case FILE_RECORD_ACCESS: - apdu_len += encode_context_signed(&apdu[apdu_len], 1, - data->type.record.fileStartRecord); - break; - default: - break; + if (apdu) { + apdu[0] = PDU_TYPE_COMPLEX_ACK; + apdu[1] = invoke_id; + apdu[2] = SERVICE_CONFIRMED_ATOMIC_WRITE_FILE; // service choice + apdu_len = 3; + switch (data->access) { + case FILE_STREAM_ACCESS: + apdu_len += encode_context_signed(&apdu[apdu_len], 0, + data->type.stream.fileStartPosition); + break; + case FILE_RECORD_ACCESS: + apdu_len += encode_context_signed(&apdu[apdu_len], 1, + data->type.record.fileStartRecord); + break; + default: + break; + } } - } - - return apdu_len; + + return apdu_len; } // decode the service request only -int awf_ack_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - BACNET_ATOMIC_WRITE_FILE_DATA *data) +int awf_ack_decode_service_request(uint8_t * apdu, + unsigned apdu_len, BACNET_ATOMIC_WRITE_FILE_DATA * data) { - int len = 0; - uint8_t tag_number = 0; - uint32_t len_value_type = 0; + int len = 0; + uint8_t tag_number = 0; + uint32_t len_value_type = 0; - // check for value pointers - if (apdu_len && data) - { - len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value_type); - if (tag_number == 0) - { - data->access = FILE_STREAM_ACCESS; - len += decode_signed(&apdu[len], - len_value_type, - &data->type.stream.fileStartPosition); + // check for value pointers + if (apdu_len && data) { + len = + decode_tag_number_and_value(&apdu[0], &tag_number, + &len_value_type); + if (tag_number == 0) { + data->access = FILE_STREAM_ACCESS; + len += decode_signed(&apdu[len], + len_value_type, &data->type.stream.fileStartPosition); + } else if (tag_number == 1) { + data->access = FILE_RECORD_ACCESS; + len += decode_signed(&apdu[len], + len_value_type, &data->type.record.fileStartRecord); + } else + return -1; } - else if (tag_number == 1) - { - data->access = FILE_RECORD_ACCESS; - len += decode_signed(&apdu[len], - len_value_type, - &data->type.record.fileStartRecord); - } - else - return -1; - } - return len; + return len; } -int awf_ack_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - BACNET_ATOMIC_WRITE_FILE_DATA *data) +int awf_ack_decode_apdu(uint8_t * apdu, + unsigned apdu_len, + uint8_t * invoke_id, BACNET_ATOMIC_WRITE_FILE_DATA * data) { - int len = 0; - unsigned offset = 0; + int len = 0; + unsigned offset = 0; - if (!apdu) - return -1; - // optional checking - most likely was already done prior to this call - if (apdu[0] != PDU_TYPE_COMPLEX_ACK) - return -1; - *invoke_id = apdu[1]; /* invoke id - filled in by net layer */ - if (apdu[2] != SERVICE_CONFIRMED_ATOMIC_WRITE_FILE) - return -1; - offset = 3; + if (!apdu) + return -1; + // optional checking - most likely was already done prior to this call + if (apdu[0] != PDU_TYPE_COMPLEX_ACK) + return -1; + *invoke_id = apdu[1]; /* invoke id - filled in by net layer */ + if (apdu[2] != SERVICE_CONFIRMED_ATOMIC_WRITE_FILE) + return -1; + offset = 3; - if (apdu_len > offset) - { - len = awf_decode_service_request( - &apdu[offset], - apdu_len - offset, - data); - } - - return len; + if (apdu_len > offset) { + len = awf_decode_service_request(&apdu[offset], + apdu_len - offset, data); + } + + return len; } #ifdef TEST @@ -310,133 +276,110 @@ int awf_ack_decode_apdu( #include "ctest.h" void testAtomicWriteFileAccess(Test * pTest, - BACNET_ATOMIC_WRITE_FILE_DATA *data) + BACNET_ATOMIC_WRITE_FILE_DATA * data) { - BACNET_ATOMIC_WRITE_FILE_DATA test_data = {0}; - uint8_t apdu[480] = {0}; - int len = 0; - int apdu_len = 0; - uint8_t invoke_id = 128; - uint8_t test_invoke_id = 0; + BACNET_ATOMIC_WRITE_FILE_DATA test_data = { 0 }; + uint8_t apdu[480] = { 0 }; + int len = 0; + int apdu_len = 0; + uint8_t invoke_id = 128; + uint8_t test_invoke_id = 0; - len = awf_encode_apdu( - &apdu[0], - invoke_id, - data); - ct_test(pTest, len != 0); - apdu_len = len; + len = awf_encode_apdu(&apdu[0], invoke_id, data); + ct_test(pTest, len != 0); + apdu_len = len; - len = awf_decode_apdu( - &apdu[0], - apdu_len, - &test_invoke_id, - &test_data); - ct_test(pTest, len != -1); - ct_test(pTest, test_data.object_type == data->object_type); - ct_test(pTest, test_data.object_instance == data->object_instance); - ct_test(pTest, test_data.access == data->access); - if (test_data.access == FILE_STREAM_ACCESS) - { - ct_test(pTest, test_data.type.stream.fileStartPosition == - data->type.stream.fileStartPosition); - } - else if (test_data.access == FILE_RECORD_ACCESS) - { - ct_test(pTest, test_data.type.record.fileStartRecord == - data->type.record.fileStartRecord); - ct_test(pTest, test_data.type.record.returnedRecordCount == - data->type.record.returnedRecordCount); - } - ct_test(pTest, octetstring_length(&test_data.fileData) == - octetstring_length(&data->fileData)); - ct_test(pTest, memcmp( - octetstring_value(&test_data.fileData), - octetstring_value(&data->fileData), - octetstring_length(&test_data.fileData)) == 0); + len = awf_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, &test_data); + ct_test(pTest, len != -1); + ct_test(pTest, test_data.object_type == data->object_type); + ct_test(pTest, test_data.object_instance == data->object_instance); + ct_test(pTest, test_data.access == data->access); + if (test_data.access == FILE_STREAM_ACCESS) { + ct_test(pTest, test_data.type.stream.fileStartPosition == + data->type.stream.fileStartPosition); + } else if (test_data.access == FILE_RECORD_ACCESS) { + ct_test(pTest, test_data.type.record.fileStartRecord == + data->type.record.fileStartRecord); + ct_test(pTest, test_data.type.record.returnedRecordCount == + data->type.record.returnedRecordCount); + } + ct_test(pTest, octetstring_length(&test_data.fileData) == + octetstring_length(&data->fileData)); + ct_test(pTest, memcmp(octetstring_value(&test_data.fileData), + octetstring_value(&data->fileData), + octetstring_length(&test_data.fileData)) == 0); } void testAtomicWriteFile(Test * pTest) { - BACNET_ATOMIC_WRITE_FILE_DATA data = {0}; - uint8_t test_octet_string[32] = "Joshua-Mary-Anna-Christopher"; + BACNET_ATOMIC_WRITE_FILE_DATA data = { 0 }; + uint8_t test_octet_string[32] = "Joshua-Mary-Anna-Christopher"; - data.object_type = OBJECT_FILE; - data.object_instance = 1; - data.access = FILE_STREAM_ACCESS; - data.type.stream.fileStartPosition = 0; - octetstring_init(&data.fileData, - test_octet_string, - sizeof(test_octet_string)); - testAtomicWriteFileAccess(pTest, &data); + data.object_type = OBJECT_FILE; + data.object_instance = 1; + data.access = FILE_STREAM_ACCESS; + data.type.stream.fileStartPosition = 0; + octetstring_init(&data.fileData, + test_octet_string, sizeof(test_octet_string)); + testAtomicWriteFileAccess(pTest, &data); - data.object_type = OBJECT_FILE; - data.object_instance = 1; - data.access = FILE_RECORD_ACCESS; - data.type.record.fileStartRecord = 1; - data.type.record.returnedRecordCount = 2; - octetstring_init(&data.fileData, - test_octet_string, - sizeof(test_octet_string)); - testAtomicWriteFileAccess(pTest, &data); - - return; + data.object_type = OBJECT_FILE; + data.object_instance = 1; + data.access = FILE_RECORD_ACCESS; + data.type.record.fileStartRecord = 1; + data.type.record.returnedRecordCount = 2; + octetstring_init(&data.fileData, + test_octet_string, sizeof(test_octet_string)); + testAtomicWriteFileAccess(pTest, &data); + + return; } void testAtomicWriteFileAckAccess(Test * pTest, - BACNET_ATOMIC_WRITE_FILE_DATA *data) + BACNET_ATOMIC_WRITE_FILE_DATA * data) { - BACNET_ATOMIC_WRITE_FILE_DATA test_data = {0}; - uint8_t apdu[480] = {0}; - int len = 0; - int apdu_len = 0; - uint8_t invoke_id = 128; - uint8_t test_invoke_id = 0; + BACNET_ATOMIC_WRITE_FILE_DATA test_data = { 0 }; + uint8_t apdu[480] = { 0 }; + int len = 0; + int apdu_len = 0; + uint8_t invoke_id = 128; + uint8_t test_invoke_id = 0; - len = awf_encode_apdu( - &apdu[0], - invoke_id, - data); - ct_test(pTest, len != 0); - apdu_len = len; + len = awf_encode_apdu(&apdu[0], invoke_id, data); + ct_test(pTest, len != 0); + apdu_len = len; - len = awf_decode_apdu( - &apdu[0], - apdu_len, - &test_invoke_id, - &test_data); - ct_test(pTest, len != -1); - ct_test(pTest, test_data.access == data->access); - if (test_data.access == FILE_STREAM_ACCESS) - { - ct_test(pTest, test_data.type.stream.fileStartPosition == - data->type.stream.fileStartPosition); - } - else if (test_data.access == FILE_RECORD_ACCESS) - { - ct_test(pTest, test_data.type.record.fileStartRecord == - data->type.record.fileStartRecord); - } + len = awf_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, &test_data); + ct_test(pTest, len != -1); + ct_test(pTest, test_data.access == data->access); + if (test_data.access == FILE_STREAM_ACCESS) { + ct_test(pTest, test_data.type.stream.fileStartPosition == + data->type.stream.fileStartPosition); + } else if (test_data.access == FILE_RECORD_ACCESS) { + ct_test(pTest, test_data.type.record.fileStartRecord == + data->type.record.fileStartRecord); + } } void testAtomicWriteFileAck(Test * pTest) { - BACNET_ATOMIC_WRITE_FILE_DATA data = {0}; - - data.access = FILE_STREAM_ACCESS; - data.type.stream.fileStartPosition = 42; - testAtomicWriteFileAckAccess(pTest, &data); + BACNET_ATOMIC_WRITE_FILE_DATA data = { 0 }; - data.access = FILE_RECORD_ACCESS; - data.type.record.fileStartRecord = 54; - testAtomicWriteFileAckAccess(pTest, &data); - - return; + data.access = FILE_STREAM_ACCESS; + data.type.stream.fileStartPosition = 42; + testAtomicWriteFileAckAccess(pTest, &data); + + data.access = FILE_RECORD_ACCESS; + data.type.record.fileStartRecord = 54; + testAtomicWriteFileAckAccess(pTest, &data); + + return; } #ifdef TEST_ATOMIC_WRITE_FILE uint16_t Device_Max_APDU_Length_Accepted(void) { - return MAX_APDU; + return MAX_APDU; } int main(void) diff --git a/bacnet-stack/awf.h b/bacnet-stack/awf.h index 136e703d..cc0af1b2 100644 --- a/bacnet-stack/awf.h +++ b/bacnet-stack/awf.h @@ -38,78 +38,60 @@ #include #include "bacdcode.h" -typedef struct BACnet_Atomic_Write_File_Data -{ - BACNET_OBJECT_TYPE object_type; - uint32_t object_instance; - BACNET_FILE_ACCESS_METHOD access; - union - { - struct - { - int32_t fileStartPosition; - } stream; - struct - { - int32_t fileStartRecord; - uint32_t returnedRecordCount; - } record; - } type; - BACNET_OCTET_STRING fileData; +typedef struct BACnet_Atomic_Write_File_Data { + BACNET_OBJECT_TYPE object_type; + uint32_t object_instance; + BACNET_FILE_ACCESS_METHOD access; + union { + struct { + int32_t fileStartPosition; + } stream; + struct { + int32_t fileStartRecord; + uint32_t returnedRecordCount; + } record; + } type; + BACNET_OCTET_STRING fileData; } BACNET_ATOMIC_WRITE_FILE_DATA; #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ // Atomic Write File // encode service -int awf_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - BACNET_ATOMIC_WRITE_FILE_DATA *data); + int awf_encode_apdu(uint8_t * apdu, + uint8_t invoke_id, BACNET_ATOMIC_WRITE_FILE_DATA * data); // decode the service request only -int awf_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - BACNET_ATOMIC_WRITE_FILE_DATA *data); - -int awf_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - BACNET_ATOMIC_WRITE_FILE_DATA *data); + int awf_decode_service_request(uint8_t * apdu, + unsigned apdu_len, BACNET_ATOMIC_WRITE_FILE_DATA * data); + + int awf_decode_apdu(uint8_t * apdu, + unsigned apdu_len, + uint8_t * invoke_id, BACNET_ATOMIC_WRITE_FILE_DATA * data); // Atomic Write File Ack // encode service -int awf_ack_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - BACNET_ATOMIC_WRITE_FILE_DATA *data); + int awf_ack_encode_apdu(uint8_t * apdu, + uint8_t invoke_id, BACNET_ATOMIC_WRITE_FILE_DATA * data); // decode the service request only -int awf_ack_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - BACNET_ATOMIC_WRITE_FILE_DATA *data); + int awf_ack_decode_service_request(uint8_t * apdu, + unsigned apdu_len, BACNET_ATOMIC_WRITE_FILE_DATA * data); -int awf_ack_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - BACNET_ATOMIC_WRITE_FILE_DATA *data); + int awf_ack_decode_apdu(uint8_t * apdu, + unsigned apdu_len, + uint8_t * invoke_id, BACNET_ATOMIC_WRITE_FILE_DATA * data); #ifdef TEST #include "ctest.h" -void test_AtomicWriteFile(Test * pTest); -void test_AtomicWriteFileAck(Test * pTest); + void test_AtomicWriteFile(Test * pTest); + void test_AtomicWriteFileAck(Test * pTest); #endif #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif - diff --git a/bacnet-stack/bacapp.c b/bacnet-stack/bacapp.c index 630acb23..89c65275 100644 --- a/bacnet-stack/bacapp.c +++ b/bacnet-stack/bacapp.c @@ -43,543 +43,485 @@ #include "bacapp.h" #include "bactext.h" -int bacapp_encode_application_data( - uint8_t *apdu, - BACNET_APPLICATION_DATA_VALUE *value) +int bacapp_encode_application_data(uint8_t * apdu, + BACNET_APPLICATION_DATA_VALUE * value) { - int apdu_len = 0; // total length of the apdu, return value + int apdu_len = 0; // total length of the apdu, return value - if (apdu) - { - if (value->tag == BACNET_APPLICATION_TAG_NULL) - apdu[apdu_len++] = value->tag; - else if (value->tag == BACNET_APPLICATION_TAG_BOOLEAN) - apdu_len += encode_tagged_boolean(&apdu[apdu_len], - value->type.Boolean); - else if (value->tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) - apdu_len += encode_tagged_unsigned(&apdu[apdu_len], - value->type.Unsigned_Int); - else if (value->tag == BACNET_APPLICATION_TAG_SIGNED_INT) - apdu_len += encode_tagged_signed(&apdu[apdu_len], - value->type.Signed_Int); - else if (value->tag == BACNET_APPLICATION_TAG_REAL) - apdu_len += encode_tagged_real(&apdu[apdu_len], - value->type.Real); + if (apdu) { + if (value->tag == BACNET_APPLICATION_TAG_NULL) + apdu[apdu_len++] = value->tag; + else if (value->tag == BACNET_APPLICATION_TAG_BOOLEAN) + apdu_len += encode_tagged_boolean(&apdu[apdu_len], + value->type.Boolean); + else if (value->tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) + apdu_len += encode_tagged_unsigned(&apdu[apdu_len], + value->type.Unsigned_Int); + else if (value->tag == BACNET_APPLICATION_TAG_SIGNED_INT) + apdu_len += encode_tagged_signed(&apdu[apdu_len], + value->type.Signed_Int); + else if (value->tag == BACNET_APPLICATION_TAG_REAL) + apdu_len += encode_tagged_real(&apdu[apdu_len], + value->type.Real); #if 0 - else if (value->tag == BACNET_APPLICATION_TAG_DOUBLE) - apdu_len += encode_tagged_double(&apdu[apdu_len], - value->type.Double); + else if (value->tag == BACNET_APPLICATION_TAG_DOUBLE) + apdu_len += encode_tagged_double(&apdu[apdu_len], + value->type.Double); #endif - else if (value->tag == BACNET_APPLICATION_TAG_OCTET_STRING) - apdu_len += encode_tagged_octet_string( - &apdu[apdu_len], - &value->type.Octet_String); - else if (value->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) - apdu_len += encode_tagged_character_string( - &apdu[apdu_len], - &value->type.Character_String); - else if (value->tag == BACNET_APPLICATION_TAG_BIT_STRING) - apdu_len += encode_tagged_bitstring( - &apdu[apdu_len], - &value->type.Bit_String); - else if (value->tag == BACNET_APPLICATION_TAG_ENUMERATED) - apdu_len += encode_tagged_enumerated(&apdu[apdu_len], - value->type.Enumerated); - else if (value->tag == BACNET_APPLICATION_TAG_DATE) - apdu_len += encode_tagged_date(&apdu[apdu_len], - value->type.Date.year, - value->type.Date.month, - value->type.Date.day, - value->type.Date.wday); - else if (value->tag == BACNET_APPLICATION_TAG_TIME) - apdu_len += encode_tagged_time(&apdu[apdu_len], - value->type.Time.hour, - value->type.Time.min, - value->type.Time.sec, - value->type.Time.hundredths); - else if (value->tag == BACNET_APPLICATION_TAG_OBJECT_ID) - apdu_len += encode_tagged_object_id(&apdu[apdu_len], - value->type.Object_Id.type,value->type.Object_Id.instance); - } + else if (value->tag == BACNET_APPLICATION_TAG_OCTET_STRING) + apdu_len += encode_tagged_octet_string(&apdu[apdu_len], + &value->type.Octet_String); + else if (value->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) + apdu_len += encode_tagged_character_string(&apdu[apdu_len], + &value->type.Character_String); + else if (value->tag == BACNET_APPLICATION_TAG_BIT_STRING) + apdu_len += encode_tagged_bitstring(&apdu[apdu_len], + &value->type.Bit_String); + else if (value->tag == BACNET_APPLICATION_TAG_ENUMERATED) + apdu_len += encode_tagged_enumerated(&apdu[apdu_len], + value->type.Enumerated); + else if (value->tag == BACNET_APPLICATION_TAG_DATE) + apdu_len += encode_tagged_date(&apdu[apdu_len], + value->type.Date.year, + value->type.Date.month, + value->type.Date.day, value->type.Date.wday); + else if (value->tag == BACNET_APPLICATION_TAG_TIME) + apdu_len += encode_tagged_time(&apdu[apdu_len], + value->type.Time.hour, + value->type.Time.min, + value->type.Time.sec, value->type.Time.hundredths); + else if (value->tag == BACNET_APPLICATION_TAG_OBJECT_ID) + apdu_len += encode_tagged_object_id(&apdu[apdu_len], + value->type.Object_Id.type, + value->type.Object_Id.instance); + } - return apdu_len; + return apdu_len; } -int bacapp_decode_application_data( - uint8_t *apdu, - uint8_t apdu_len, - BACNET_APPLICATION_DATA_VALUE *value) +int bacapp_decode_application_data(uint8_t * apdu, + uint8_t apdu_len, BACNET_APPLICATION_DATA_VALUE * value) { - int len = 0; - int tag_len = 0; - uint8_t tag_number = 0; - uint32_t len_value_type = 0; - int hour, min, sec, hundredths; - int year, month, day, wday; - int object_type = 0; - uint32_t instance = 0; + int len = 0; + int tag_len = 0; + uint8_t tag_number = 0; + uint32_t len_value_type = 0; + int hour, min, sec, hundredths; + int year, month, day, wday; + int object_type = 0; + uint32_t instance = 0; - /* FIXME: use apdu_len! */ - (void)apdu_len; - if (apdu) - { - tag_len = decode_tag_number_and_value(&apdu[0], - &tag_number, &len_value_type); - if (tag_len) - { - len += tag_len; - value->tag = tag_number; - if (tag_number == BACNET_APPLICATION_TAG_NULL) - { - /* nothing else to do */ - } - else if (tag_number == BACNET_APPLICATION_TAG_BOOLEAN) - value->type.Boolean = decode_boolean(len_value_type); - else if (tag_number == BACNET_APPLICATION_TAG_UNSIGNED_INT) - len += decode_unsigned(&apdu[len], - len_value_type, - &value->type.Unsigned_Int); - else if (tag_number == BACNET_APPLICATION_TAG_SIGNED_INT) - len += decode_signed(&apdu[len], - len_value_type, - &value->type.Signed_Int); - else if (tag_number == BACNET_APPLICATION_TAG_REAL) - len += decode_real(&apdu[len],&(value->type.Real)); + /* FIXME: use apdu_len! */ + (void) apdu_len; + if (apdu) { + tag_len = decode_tag_number_and_value(&apdu[0], + &tag_number, &len_value_type); + if (tag_len) { + len += tag_len; + value->tag = tag_number; + if (tag_number == BACNET_APPLICATION_TAG_NULL) { + /* nothing else to do */ + } else if (tag_number == BACNET_APPLICATION_TAG_BOOLEAN) + value->type.Boolean = decode_boolean(len_value_type); + else if (tag_number == BACNET_APPLICATION_TAG_UNSIGNED_INT) + len += decode_unsigned(&apdu[len], + len_value_type, &value->type.Unsigned_Int); + else if (tag_number == BACNET_APPLICATION_TAG_SIGNED_INT) + len += decode_signed(&apdu[len], + len_value_type, &value->type.Signed_Int); + else if (tag_number == BACNET_APPLICATION_TAG_REAL) + len += decode_real(&apdu[len], &(value->type.Real)); #if 0 - else if (tag_number == BACNET_APPLICATION_TAG_DOUBLE) - len += decode_double(&apdu[len],&(value->type.Double)); + else if (tag_number == BACNET_APPLICATION_TAG_DOUBLE) + len += decode_double(&apdu[len], &(value->type.Double)); #endif - else if (tag_number == BACNET_APPLICATION_TAG_OCTET_STRING) - len += decode_octet_string(&apdu[len], - len_value_type, - &value->type.Octet_String); - else if (tag_number == BACNET_APPLICATION_TAG_CHARACTER_STRING) - len += decode_character_string(&apdu[len], - len_value_type, - &value->type.Character_String); - else if (tag_number == BACNET_APPLICATION_TAG_BIT_STRING) - len += decode_bitstring(&apdu[len], - len_value_type, - &value->type.Bit_String); - else if (tag_number == BACNET_APPLICATION_TAG_ENUMERATED) - len += decode_enumerated(&apdu[len], - len_value_type, - &value->type.Enumerated); - else if (tag_number == BACNET_APPLICATION_TAG_DATE) - { - len += decode_date(&apdu[len], &year, &month, &day, &wday); - value->type.Date.year = year; - value->type.Date.month = month; - value->type.Date.day = day; - value->type.Date.wday = wday; - } - else if (tag_number == BACNET_APPLICATION_TAG_TIME) - { - len += decode_bacnet_time(&apdu[len], &hour, &min, &sec, &hundredths); - value->type.Time.hour = hour; - value->type.Time.min = min; - value->type.Time.sec = sec; - value->type.Time.hundredths = hundredths; - } - else if (tag_number == BACNET_APPLICATION_TAG_OBJECT_ID) - { - len += decode_object_id(&apdu[len], - &object_type, - &instance); - value->type.Object_Id.type = object_type; - value->type.Object_Id.instance = instance; - } + else if (tag_number == BACNET_APPLICATION_TAG_OCTET_STRING) + len += decode_octet_string(&apdu[len], + len_value_type, &value->type.Octet_String); + else if (tag_number == BACNET_APPLICATION_TAG_CHARACTER_STRING) + len += decode_character_string(&apdu[len], + len_value_type, &value->type.Character_String); + else if (tag_number == BACNET_APPLICATION_TAG_BIT_STRING) + len += decode_bitstring(&apdu[len], + len_value_type, &value->type.Bit_String); + else if (tag_number == BACNET_APPLICATION_TAG_ENUMERATED) + len += decode_enumerated(&apdu[len], + len_value_type, &value->type.Enumerated); + else if (tag_number == BACNET_APPLICATION_TAG_DATE) { + len += decode_date(&apdu[len], &year, &month, &day, &wday); + value->type.Date.year = year; + value->type.Date.month = month; + value->type.Date.day = day; + value->type.Date.wday = wday; + } else if (tag_number == BACNET_APPLICATION_TAG_TIME) { + len += + decode_bacnet_time(&apdu[len], &hour, &min, &sec, + &hundredths); + value->type.Time.hour = hour; + value->type.Time.min = min; + value->type.Time.sec = sec; + value->type.Time.hundredths = hundredths; + } else if (tag_number == BACNET_APPLICATION_TAG_OBJECT_ID) { + len += decode_object_id(&apdu[len], + &object_type, &instance); + value->type.Object_Id.type = object_type; + value->type.Object_Id.instance = instance; + } + } } - } - return len; + return len; } -bool bacapp_copy( - BACNET_APPLICATION_DATA_VALUE *dest_value, - BACNET_APPLICATION_DATA_VALUE *src_value) +bool bacapp_copy(BACNET_APPLICATION_DATA_VALUE * dest_value, + BACNET_APPLICATION_DATA_VALUE * src_value) { - bool status = true; /*return value*/ + bool status = true; /*return value */ - if (dest_value && src_value) - { - dest_value->tag = src_value->tag; - switch (src_value->tag) - { - case BACNET_APPLICATION_TAG_NULL: - break; - case BACNET_APPLICATION_TAG_BOOLEAN: - dest_value->type.Boolean = src_value->type.Boolean; - break; - case BACNET_APPLICATION_TAG_UNSIGNED_INT: - dest_value->type.Unsigned_Int = src_value->type.Unsigned_Int; - break; - case BACNET_APPLICATION_TAG_SIGNED_INT: - dest_value->type.Signed_Int = src_value->type.Signed_Int; - break; - case BACNET_APPLICATION_TAG_REAL: - dest_value->type.Real = src_value->type.Real; - break; - case BACNET_APPLICATION_TAG_DOUBLE: - dest_value->type.Double = src_value->type.Double; - break; - case BACNET_APPLICATION_TAG_ENUMERATED: - dest_value->type.Enumerated = src_value->type.Enumerated; - break; - case BACNET_APPLICATION_TAG_DATE: - dest_value->type.Date.year = src_value->type.Date.year; - dest_value->type.Date.month = src_value->type.Date.month; - dest_value->type.Date.day = src_value->type.Date.day; - dest_value->type.Date.wday = src_value->type.Date.wday; - break; - case BACNET_APPLICATION_TAG_TIME: - dest_value->type.Time.hour = src_value->type.Time.hour; - dest_value->type.Time.min = src_value->type.Time.min; - dest_value->type.Time.sec = src_value->type.Time.sec; - dest_value->type.Time.hundredths = src_value->type.Time.hundredths; - break; - case BACNET_APPLICATION_TAG_OBJECT_ID: - dest_value->type.Object_Id.type = src_value->type.Object_Id.type; - dest_value->type.Object_Id.instance = src_value->type.Object_Id.instance; - break; - case BACNET_APPLICATION_TAG_OCTET_STRING: - octetstring_copy( - &dest_value->type.Octet_String, - &src_value->type.Octet_String); - break; - case BACNET_APPLICATION_TAG_CHARACTER_STRING: - characterstring_copy( - &dest_value->type.Character_String, - &src_value->type.Character_String); - break; - case BACNET_APPLICATION_TAG_BIT_STRING: - default: - status = false; - break; + if (dest_value && src_value) { + dest_value->tag = src_value->tag; + switch (src_value->tag) { + case BACNET_APPLICATION_TAG_NULL: + break; + case BACNET_APPLICATION_TAG_BOOLEAN: + dest_value->type.Boolean = src_value->type.Boolean; + break; + case BACNET_APPLICATION_TAG_UNSIGNED_INT: + dest_value->type.Unsigned_Int = src_value->type.Unsigned_Int; + break; + case BACNET_APPLICATION_TAG_SIGNED_INT: + dest_value->type.Signed_Int = src_value->type.Signed_Int; + break; + case BACNET_APPLICATION_TAG_REAL: + dest_value->type.Real = src_value->type.Real; + break; + case BACNET_APPLICATION_TAG_DOUBLE: + dest_value->type.Double = src_value->type.Double; + break; + case BACNET_APPLICATION_TAG_ENUMERATED: + dest_value->type.Enumerated = src_value->type.Enumerated; + break; + case BACNET_APPLICATION_TAG_DATE: + dest_value->type.Date.year = src_value->type.Date.year; + dest_value->type.Date.month = src_value->type.Date.month; + dest_value->type.Date.day = src_value->type.Date.day; + dest_value->type.Date.wday = src_value->type.Date.wday; + break; + case BACNET_APPLICATION_TAG_TIME: + dest_value->type.Time.hour = src_value->type.Time.hour; + dest_value->type.Time.min = src_value->type.Time.min; + dest_value->type.Time.sec = src_value->type.Time.sec; + dest_value->type.Time.hundredths = + src_value->type.Time.hundredths; + break; + case BACNET_APPLICATION_TAG_OBJECT_ID: + dest_value->type.Object_Id.type = + src_value->type.Object_Id.type; + dest_value->type.Object_Id.instance = + src_value->type.Object_Id.instance; + break; + case BACNET_APPLICATION_TAG_OCTET_STRING: + octetstring_copy(&dest_value->type.Octet_String, + &src_value->type.Octet_String); + break; + case BACNET_APPLICATION_TAG_CHARACTER_STRING: + characterstring_copy(&dest_value->type.Character_String, + &src_value->type.Character_String); + break; + case BACNET_APPLICATION_TAG_BIT_STRING: + default: + status = false; + break; + } } - } - return status; + return status; } + /* generic - can be used by other unit tests */ -bool bacapp_compare( - BACNET_APPLICATION_DATA_VALUE *value, - BACNET_APPLICATION_DATA_VALUE *test_value) +bool bacapp_compare(BACNET_APPLICATION_DATA_VALUE * value, + BACNET_APPLICATION_DATA_VALUE * test_value) { - bool status = true; /*return value*/ + bool status = true; /*return value */ - /* does the tag match? */ - if (test_value->tag != value->tag) - status = false; - if (status) - { - /* does the value match? */ - switch (test_value->tag) - { - case BACNET_APPLICATION_TAG_NULL: - break; - case BACNET_APPLICATION_TAG_BOOLEAN: - if (test_value->type.Boolean != value->type.Boolean) - status = false; - break; - case BACNET_APPLICATION_TAG_UNSIGNED_INT: - if (test_value->type.Unsigned_Int != value->type.Unsigned_Int) - status = false; - break; - case BACNET_APPLICATION_TAG_SIGNED_INT: - if (test_value->type.Signed_Int != value->type.Signed_Int) - status = false; - break; - case BACNET_APPLICATION_TAG_REAL: - if (test_value->type.Real != value->type.Real) - status = false; - break; - case BACNET_APPLICATION_TAG_DOUBLE: - if (test_value->type.Double != value->type.Double) - status = false; - break; - case BACNET_APPLICATION_TAG_ENUMERATED: - if (test_value->type.Enumerated != value->type.Enumerated) - status = false; - break; - case BACNET_APPLICATION_TAG_DATE: - if (test_value->type.Date.year != value->type.Date.year) - status = false; - if (test_value->type.Date.month != value->type.Date.month) - status = false; - if (test_value->type.Date.day != value->type.Date.day) - status = false; - if(test_value->type.Date.wday != value->type.Date.wday) - status = false; - break; - case BACNET_APPLICATION_TAG_TIME: - if (test_value->type.Time.hour != value->type.Time.hour) - status = false; - if (test_value->type.Time.min != value->type.Time.min) - status = false; - if (test_value->type.Time.sec != value->type.Time.sec) - status = false; - if (test_value->type.Time.hundredths != value->type.Time.hundredths) - status = false; - break; - case BACNET_APPLICATION_TAG_OBJECT_ID: - if (test_value->type.Object_Id.type != value->type.Object_Id.type) - status = false; - if (test_value->type.Object_Id.instance != value->type.Object_Id.instance) - status = false; - break; - case BACNET_APPLICATION_TAG_CHARACTER_STRING: - status = !characterstring_same( - &value->type.Character_String, - &test_value->type.Character_String); - break; - case BACNET_APPLICATION_TAG_BIT_STRING: - default: + /* does the tag match? */ + if (test_value->tag != value->tag) status = false; - break; + if (status) { + /* does the value match? */ + switch (test_value->tag) { + case BACNET_APPLICATION_TAG_NULL: + break; + case BACNET_APPLICATION_TAG_BOOLEAN: + if (test_value->type.Boolean != value->type.Boolean) + status = false; + break; + case BACNET_APPLICATION_TAG_UNSIGNED_INT: + if (test_value->type.Unsigned_Int != value->type.Unsigned_Int) + status = false; + break; + case BACNET_APPLICATION_TAG_SIGNED_INT: + if (test_value->type.Signed_Int != value->type.Signed_Int) + status = false; + break; + case BACNET_APPLICATION_TAG_REAL: + if (test_value->type.Real != value->type.Real) + status = false; + break; + case BACNET_APPLICATION_TAG_DOUBLE: + if (test_value->type.Double != value->type.Double) + status = false; + break; + case BACNET_APPLICATION_TAG_ENUMERATED: + if (test_value->type.Enumerated != value->type.Enumerated) + status = false; + break; + case BACNET_APPLICATION_TAG_DATE: + if (test_value->type.Date.year != value->type.Date.year) + status = false; + if (test_value->type.Date.month != value->type.Date.month) + status = false; + if (test_value->type.Date.day != value->type.Date.day) + status = false; + if (test_value->type.Date.wday != value->type.Date.wday) + status = false; + break; + case BACNET_APPLICATION_TAG_TIME: + if (test_value->type.Time.hour != value->type.Time.hour) + status = false; + if (test_value->type.Time.min != value->type.Time.min) + status = false; + if (test_value->type.Time.sec != value->type.Time.sec) + status = false; + if (test_value->type.Time.hundredths != + value->type.Time.hundredths) + status = false; + break; + case BACNET_APPLICATION_TAG_OBJECT_ID: + if (test_value->type.Object_Id.type != + value->type.Object_Id.type) + status = false; + if (test_value->type.Object_Id.instance != + value->type.Object_Id.instance) + status = false; + break; + case BACNET_APPLICATION_TAG_CHARACTER_STRING: + status = !characterstring_same(&value->type.Character_String, + &test_value->type.Character_String); + break; + case BACNET_APPLICATION_TAG_BIT_STRING: + default: + status = false; + break; + } } - } - return status; + return status; } -bool bacapp_print_value( - FILE *stream, - BACNET_APPLICATION_DATA_VALUE *value, - BACNET_PROPERTY_ID property) +bool bacapp_print_value(FILE * stream, + BACNET_APPLICATION_DATA_VALUE * value, BACNET_PROPERTY_ID property) { - bool status = true; /*return value*/ - size_t len = 0, i = 0; - char *char_str; - uint8_t *octet_str; + bool status = true; /*return value */ + size_t len = 0, i = 0; + char *char_str; + uint8_t *octet_str; - if (value) - { - switch (value->tag) - { - case BACNET_APPLICATION_TAG_NULL: - fprintf(stream,"Null"); - break; - case BACNET_APPLICATION_TAG_BOOLEAN: - fprintf(stream,"%s",value->type.Boolean?"TRUE":"FALSE"); - break; - case BACNET_APPLICATION_TAG_UNSIGNED_INT: - fprintf(stream,"%u",value->type.Unsigned_Int); - break; - case BACNET_APPLICATION_TAG_SIGNED_INT: - fprintf(stream,"%d",value->type.Signed_Int); - break; - case BACNET_APPLICATION_TAG_REAL: - fprintf(stream,"%f",(double)value->type.Real); - break; - case BACNET_APPLICATION_TAG_DOUBLE: - fprintf(stream,"%f",value->type.Double); - break; - case BACNET_APPLICATION_TAG_ENUMERATED: - switch (property) - { - case PROP_OBJECT_TYPE: - fprintf(stream,"%s", - bactext_object_type_name(value->type.Enumerated)); + if (value) { + switch (value->tag) { + case BACNET_APPLICATION_TAG_NULL: + fprintf(stream, "Null"); break; - case PROP_EVENT_STATE: - fprintf(stream,"%s", - bactext_event_state_name(value->type.Enumerated)); + case BACNET_APPLICATION_TAG_BOOLEAN: + fprintf(stream, "%s", value->type.Boolean ? "TRUE" : "FALSE"); break; - case PROP_UNITS: - fprintf(stream,"%s", - bactext_engineering_unit_name(value->type.Enumerated)); + case BACNET_APPLICATION_TAG_UNSIGNED_INT: + fprintf(stream, "%u", value->type.Unsigned_Int); break; - case PROP_PRESENT_VALUE: - fprintf(stream,"%s", - bactext_binary_present_value_name(value->type.Enumerated)); + case BACNET_APPLICATION_TAG_SIGNED_INT: + fprintf(stream, "%d", value->type.Signed_Int); break; - case PROP_RELIABILITY: - fprintf(stream,"%s", - bactext_reliability_name(value->type.Enumerated)); + case BACNET_APPLICATION_TAG_REAL: + fprintf(stream, "%f", (double) value->type.Real); break; - case PROP_SYSTEM_STATUS: - fprintf(stream,"%s", - bactext_device_status_name(value->type.Enumerated)); + case BACNET_APPLICATION_TAG_DOUBLE: + fprintf(stream, "%f", value->type.Double); break; - case PROP_SEGMENTATION_SUPPORTED: - fprintf(stream,"%s", - bactext_segmentation_name(value->type.Enumerated)); + case BACNET_APPLICATION_TAG_ENUMERATED: + switch (property) { + case PROP_OBJECT_TYPE: + fprintf(stream, "%s", + bactext_object_type_name(value->type.Enumerated)); + break; + case PROP_EVENT_STATE: + fprintf(stream, "%s", + bactext_event_state_name(value->type.Enumerated)); + break; + case PROP_UNITS: + fprintf(stream, "%s", + bactext_engineering_unit_name(value->type.Enumerated)); + break; + case PROP_PRESENT_VALUE: + fprintf(stream, "%s", + bactext_binary_present_value_name(value->type. + Enumerated)); + break; + case PROP_RELIABILITY: + fprintf(stream, "%s", + bactext_reliability_name(value->type.Enumerated)); + break; + case PROP_SYSTEM_STATUS: + fprintf(stream, "%s", + bactext_device_status_name(value->type.Enumerated)); + break; + case PROP_SEGMENTATION_SUPPORTED: + fprintf(stream, "%s", + bactext_segmentation_name(value->type.Enumerated)); + break; + default: + fprintf(stream, "%u", value->type.Enumerated); + break; + } break; - default: - fprintf(stream,"%u",value->type.Enumerated); + case BACNET_APPLICATION_TAG_DATE: + fprintf(stream, "%s, %s %u, %u", + bactext_day_of_week_name(value->type.Date.wday), + bactext_month_name(value->type.Date.month), + (unsigned) value->type.Date.day, + (unsigned) value->type.Date.year); + break; + case BACNET_APPLICATION_TAG_TIME: + fprintf(stream, "%02u:%02u:%02u.%03u", + (unsigned) value->type.Time.hour, + (unsigned) value->type.Time.min, + (unsigned) value->type.Time.sec, + (unsigned) value->type.Time.hundredths); + break; + case BACNET_APPLICATION_TAG_OBJECT_ID: + fprintf(stream, "%s %u", + bactext_object_type_name(value->type.Object_Id.type), + value->type.Object_Id.instance); + break; + case BACNET_APPLICATION_TAG_OCTET_STRING: + len = octetstring_length(&value->type.Octet_String); + octet_str = octetstring_value(&value->type.Octet_String); + for (i = 0; i < len; i++) { + fprintf(stream, "%02X", *octet_str); + octet_str++; + } + break; + case BACNET_APPLICATION_TAG_CHARACTER_STRING: + len = characterstring_length(&value->type.Character_String); + char_str = + characterstring_value(&value->type.Character_String); + fprintf(stream, "\""); + for (i = 0; i < len; i++) { + if (isprint(*char_str)) + fprintf(stream, "%c", *char_str); + else + fprintf(stream, "."); + char_str++; + } + fprintf(stream, "\""); + break; + case BACNET_APPLICATION_TAG_BIT_STRING: + len = bitstring_bits_used(&value->type.Bit_String); + fprintf(stream, "{"); + for (i = 0; i < len; i++) { + fprintf(stream, "%s", + bitstring_bit(&value->type.Bit_String, + i) ? "true" : "false"); + if (i < len - 1) + fprintf(stream, ","); + } + fprintf(stream, "}"); + break; + default: + status = false; break; } - break; - case BACNET_APPLICATION_TAG_DATE: - fprintf(stream,"%s, %s %u, %u", - bactext_day_of_week_name(value->type.Date.wday), - bactext_month_name(value->type.Date.month), - (unsigned)value->type.Date.day, - (unsigned)value->type.Date.year); - break; - case BACNET_APPLICATION_TAG_TIME: - fprintf(stream,"%02u:%02u:%02u.%03u", - (unsigned)value->type.Time.hour, - (unsigned)value->type.Time.min, - (unsigned)value->type.Time.sec, - (unsigned)value->type.Time.hundredths); - break; - case BACNET_APPLICATION_TAG_OBJECT_ID: - fprintf(stream,"%s %u", - bactext_object_type_name(value->type.Object_Id.type), - value->type.Object_Id.instance); - break; - case BACNET_APPLICATION_TAG_OCTET_STRING: - len = octetstring_length(&value->type.Octet_String); - octet_str = octetstring_value(&value->type.Octet_String); - for (i = 0; i < len; i++) - { - fprintf(stream,"%02X",*octet_str); - octet_str++; - } - break; - case BACNET_APPLICATION_TAG_CHARACTER_STRING: - len = characterstring_length(&value->type.Character_String); - char_str = characterstring_value(&value->type.Character_String); - fprintf(stream,"\""); - for (i = 0; i < len; i++) - { - if (isprint(*char_str)) - fprintf(stream,"%c",*char_str); - else - fprintf(stream,"."); - char_str++; - } - fprintf(stream,"\""); - break; - case BACNET_APPLICATION_TAG_BIT_STRING: - len = bitstring_bits_used(&value->type.Bit_String); - fprintf(stream,"{"); - for (i = 0; i < len; i++) - { - fprintf(stream,"%s", - bitstring_bit(&value->type.Bit_String,i)?"true":"false"); - if (i < len-1) - fprintf(stream,","); - } - fprintf(stream,"}"); - break; - default: - status = false; - break; } - } - return status; + return status; } /* used to load the app data struct with the proper data converted from a command line argument */ -bool bacapp_parse_application_data( - BACNET_APPLICATION_TAG tag_number, - const char *argv, - BACNET_APPLICATION_DATA_VALUE *value) +bool bacapp_parse_application_data(BACNET_APPLICATION_TAG tag_number, + const char *argv, BACNET_APPLICATION_DATA_VALUE * value) { - int hour, min, sec, hundredths; - int year, month, day, wday; - int object_type = 0; - uint32_t instance = 0; - bool status = false; - long long_value = 0; - unsigned long unsigned_long_value = 0; - double double_value = 0.0; - int count = 0; + int hour, min, sec, hundredths; + int year, month, day, wday; + int object_type = 0; + uint32_t instance = 0; + bool status = false; + long long_value = 0; + unsigned long unsigned_long_value = 0; + double double_value = 0.0; + int count = 0; - if (value && (tag_number < MAX_BACNET_APPLICATION_TAG)) - { - status = true; - value->tag = tag_number; - if (tag_number == BACNET_APPLICATION_TAG_BOOLEAN) - { - long_value = strtol(argv,NULL,0); - if (long_value) - value->type.Boolean = true; - else - value->type.Boolean = false; + if (value && (tag_number < MAX_BACNET_APPLICATION_TAG)) { + status = true; + value->tag = tag_number; + if (tag_number == BACNET_APPLICATION_TAG_BOOLEAN) { + long_value = strtol(argv, NULL, 0); + if (long_value) + value->type.Boolean = true; + else + value->type.Boolean = false; + } else if (tag_number == BACNET_APPLICATION_TAG_UNSIGNED_INT) { + unsigned_long_value = strtoul(argv, NULL, 0); + value->type.Unsigned_Int = unsigned_long_value; + } else if (tag_number == BACNET_APPLICATION_TAG_SIGNED_INT) { + long_value = strtol(argv, NULL, 0); + value->type.Signed_Int = long_value; + } else if (tag_number == BACNET_APPLICATION_TAG_REAL) { + double_value = strtod(argv, NULL); + value->type.Real = double_value; + } else if (tag_number == BACNET_APPLICATION_TAG_DOUBLE) { + double_value = strtod(argv, NULL); + value->type.Double = double_value; + } else if (tag_number == BACNET_APPLICATION_TAG_CHARACTER_STRING) { + status = + characterstring_init_ansi(&value->type.Character_String, + (char *) argv); + } else if (tag_number == BACNET_APPLICATION_TAG_OCTET_STRING) { + status = octetstring_init(&value->type.Octet_String, + (uint8_t *) argv, strlen(argv)); + } else if (tag_number == BACNET_APPLICATION_TAG_ENUMERATED) { + unsigned_long_value = strtoul(argv, NULL, 0); + value->type.Enumerated = unsigned_long_value; + } else if (tag_number == BACNET_APPLICATION_TAG_DATE) { + count = + sscanf(argv, "%d/%d/%d:%d", &year, &month, &day, &wday); + if (count == 4) { + value->type.Date.year = year; + value->type.Date.month = month; + value->type.Date.day = day; + value->type.Date.wday = wday; + } else + status = false; + } else if (tag_number == BACNET_APPLICATION_TAG_TIME) { + count = + sscanf(argv, "%d:%d:%d.%d", &hour, &min, &sec, + &hundredths); + if (count == 4) { + value->type.Time.hour = hour; + value->type.Time.min = min; + value->type.Time.sec = sec; + value->type.Time.hundredths = hundredths; + } else + status = false; + } else if (tag_number == BACNET_APPLICATION_TAG_OBJECT_ID) { + count = sscanf(argv, "%d:%d", &object_type, &instance); + if (count == 2) { + value->type.Object_Id.type = object_type; + value->type.Object_Id.instance = instance; + } else + status = false; + } } - else if (tag_number == BACNET_APPLICATION_TAG_UNSIGNED_INT) - { - unsigned_long_value = strtoul(argv,NULL,0); - value->type.Unsigned_Int = unsigned_long_value; - } - else if (tag_number == BACNET_APPLICATION_TAG_SIGNED_INT) - { - long_value = strtol(argv,NULL,0); - value->type.Signed_Int = long_value; - } - else if (tag_number == BACNET_APPLICATION_TAG_REAL) - { - double_value = strtod(argv,NULL); - value->type.Real = double_value; - } - else if (tag_number == BACNET_APPLICATION_TAG_DOUBLE) - { - double_value = strtod(argv,NULL); - value->type.Double = double_value; - } - else if (tag_number == BACNET_APPLICATION_TAG_CHARACTER_STRING) - { - status = characterstring_init_ansi( - &value->type.Character_String, - (char *)argv); - } - else if (tag_number == BACNET_APPLICATION_TAG_OCTET_STRING) - { - status = octetstring_init( - &value->type.Octet_String, - (uint8_t *)argv, - strlen(argv)); - } - else if (tag_number == BACNET_APPLICATION_TAG_ENUMERATED) - { - unsigned_long_value = strtoul(argv,NULL,0); - value->type.Enumerated = unsigned_long_value; - } - else if (tag_number == BACNET_APPLICATION_TAG_DATE) - { - count = sscanf(argv,"%d/%d/%d:%d", &year, &month, &day, &wday); - if (count == 4) - { - value->type.Date.year = year; - value->type.Date.month = month; - value->type.Date.day = day; - value->type.Date.wday = wday; - } - else - status = false; - } - else if (tag_number == BACNET_APPLICATION_TAG_TIME) - { - count = sscanf(argv,"%d:%d:%d.%d", &hour, &min, &sec, &hundredths); - if (count == 4) - { - value->type.Time.hour = hour; - value->type.Time.min = min; - value->type.Time.sec = sec; - value->type.Time.hundredths = hundredths; - } - else - status = false; - } - else if (tag_number == BACNET_APPLICATION_TAG_OBJECT_ID) - { - count = sscanf(argv,"%d:%d", &object_type, &instance); - if (count == 2) - { - value->type.Object_Id.type = object_type; - value->type.Object_Id.instance = instance; - } - else - status = false; - } - } - return status; + return status; } @@ -588,194 +530,160 @@ bool bacapp_parse_application_data( #include #include "ctest.h" -static bool testBACnetApplicationDataValue(BACNET_APPLICATION_DATA_VALUE *value) +static bool testBACnetApplicationDataValue(BACNET_APPLICATION_DATA_VALUE * + value) { - uint8_t apdu[480] = {0}; - int len = 0; - int apdu_len = 0; - BACNET_APPLICATION_DATA_VALUE test_value; + uint8_t apdu[480] = { 0 }; + int len = 0; + int apdu_len = 0; + BACNET_APPLICATION_DATA_VALUE test_value; - apdu_len = bacapp_encode_application_data(&apdu[0],value); - len = bacapp_decode_application_data( - &apdu[0], - apdu_len, - &test_value); + apdu_len = bacapp_encode_application_data(&apdu[0], value); + len = bacapp_decode_application_data(&apdu[0], apdu_len, &test_value); - return bacapp_compare(value, &test_value); + return bacapp_compare(value, &test_value); } void testBACnetApplicationData(Test * pTest) { - BACNET_APPLICATION_DATA_VALUE value = {0}; - bool status = false; + BACNET_APPLICATION_DATA_VALUE value = { 0 }; + bool status = false; - status = bacapp_parse_application_data( - BACNET_APPLICATION_TAG_NULL, - NULL, - &value); - ct_test(pTest,status == true); - ct_test(pTest,testBACnetApplicationDataValue(&value)); + status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_NULL, + NULL, &value); + ct_test(pTest, status == true); + ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data( - BACNET_APPLICATION_TAG_BOOLEAN, - "1", - &value); - ct_test(pTest,status == true); - ct_test(pTest,value.type.Boolean == true); - ct_test(pTest,testBACnetApplicationDataValue(&value)); + status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_BOOLEAN, + "1", &value); + ct_test(pTest, status == true); + ct_test(pTest, value.type.Boolean == true); + ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data( - BACNET_APPLICATION_TAG_BOOLEAN, - "0", - &value); - ct_test(pTest,status == true); - ct_test(pTest,value.type.Boolean == false); - ct_test(pTest,testBACnetApplicationDataValue(&value)); + status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_BOOLEAN, + "0", &value); + ct_test(pTest, status == true); + ct_test(pTest, value.type.Boolean == false); + ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data( - BACNET_APPLICATION_TAG_UNSIGNED_INT, - "0", - &value); - ct_test(pTest,status == true); - ct_test(pTest,value.type.Unsigned_Int == 0); - ct_test(pTest,testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data( - BACNET_APPLICATION_TAG_UNSIGNED_INT, - "0xFFFF", - &value); - ct_test(pTest,status == true); - ct_test(pTest,value.type.Unsigned_Int == 0xFFFF); - ct_test(pTest,testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data( - BACNET_APPLICATION_TAG_UNSIGNED_INT, - "0xFFFFFFFF", - &value); - ct_test(pTest,status == true); - ct_test(pTest,value.type.Unsigned_Int == 0xFFFFFFFF); - ct_test(pTest,testBACnetApplicationDataValue(&value)); + status = + bacapp_parse_application_data(BACNET_APPLICATION_TAG_UNSIGNED_INT, + "0", &value); + ct_test(pTest, status == true); + ct_test(pTest, value.type.Unsigned_Int == 0); + ct_test(pTest, testBACnetApplicationDataValue(&value)); + status = + bacapp_parse_application_data(BACNET_APPLICATION_TAG_UNSIGNED_INT, + "0xFFFF", &value); + ct_test(pTest, status == true); + ct_test(pTest, value.type.Unsigned_Int == 0xFFFF); + ct_test(pTest, testBACnetApplicationDataValue(&value)); + status = + bacapp_parse_application_data(BACNET_APPLICATION_TAG_UNSIGNED_INT, + "0xFFFFFFFF", &value); + ct_test(pTest, status == true); + ct_test(pTest, value.type.Unsigned_Int == 0xFFFFFFFF); + ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data( - BACNET_APPLICATION_TAG_SIGNED_INT, - "0", - &value); - ct_test(pTest,status == true); - ct_test(pTest,value.type.Signed_Int == 0); - ct_test(pTest,testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data( - BACNET_APPLICATION_TAG_SIGNED_INT, - "-1", - &value); - ct_test(pTest,status == true); - ct_test(pTest,value.type.Signed_Int == -1); - ct_test(pTest,testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data( - BACNET_APPLICATION_TAG_SIGNED_INT, - "32768", - &value); - ct_test(pTest,status == true); - ct_test(pTest,value.type.Signed_Int == 32768); - ct_test(pTest,testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data( - BACNET_APPLICATION_TAG_SIGNED_INT, - "-32768", - &value); - ct_test(pTest,status == true); - ct_test(pTest,value.type.Signed_Int == -32768); - ct_test(pTest,testBACnetApplicationDataValue(&value)); + status = + bacapp_parse_application_data(BACNET_APPLICATION_TAG_SIGNED_INT, + "0", &value); + ct_test(pTest, status == true); + ct_test(pTest, value.type.Signed_Int == 0); + ct_test(pTest, testBACnetApplicationDataValue(&value)); + status = + bacapp_parse_application_data(BACNET_APPLICATION_TAG_SIGNED_INT, + "-1", &value); + ct_test(pTest, status == true); + ct_test(pTest, value.type.Signed_Int == -1); + ct_test(pTest, testBACnetApplicationDataValue(&value)); + status = + bacapp_parse_application_data(BACNET_APPLICATION_TAG_SIGNED_INT, + "32768", &value); + ct_test(pTest, status == true); + ct_test(pTest, value.type.Signed_Int == 32768); + ct_test(pTest, testBACnetApplicationDataValue(&value)); + status = + bacapp_parse_application_data(BACNET_APPLICATION_TAG_SIGNED_INT, + "-32768", &value); + ct_test(pTest, status == true); + ct_test(pTest, value.type.Signed_Int == -32768); + ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data( - BACNET_APPLICATION_TAG_REAL, - "0.0", - &value); - ct_test(pTest,status == true); - ct_test(pTest,testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data( - BACNET_APPLICATION_TAG_REAL, - "-1.0", - &value); - ct_test(pTest,status == true); - ct_test(pTest,testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data( - BACNET_APPLICATION_TAG_REAL, - "1.0", - &value); - ct_test(pTest,status == true); - ct_test(pTest,testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data( - BACNET_APPLICATION_TAG_REAL, - "3.14159", - &value); - ct_test(pTest,status == true); - ct_test(pTest,testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data( - BACNET_APPLICATION_TAG_REAL, - "-3.14159", - &value); - ct_test(pTest,status == true); - ct_test(pTest,testBACnetApplicationDataValue(&value)); + status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_REAL, + "0.0", &value); + ct_test(pTest, status == true); + ct_test(pTest, testBACnetApplicationDataValue(&value)); + status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_REAL, + "-1.0", &value); + ct_test(pTest, status == true); + ct_test(pTest, testBACnetApplicationDataValue(&value)); + status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_REAL, + "1.0", &value); + ct_test(pTest, status == true); + ct_test(pTest, testBACnetApplicationDataValue(&value)); + status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_REAL, + "3.14159", &value); + ct_test(pTest, status == true); + ct_test(pTest, testBACnetApplicationDataValue(&value)); + status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_REAL, + "-3.14159", &value); + ct_test(pTest, status == true); + ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data( - BACNET_APPLICATION_TAG_ENUMERATED, - "0", - &value); - ct_test(pTest,status == true); - ct_test(pTest,value.type.Enumerated == 0); - ct_test(pTest,testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data( - BACNET_APPLICATION_TAG_ENUMERATED, - "0xFFFF", - &value); - ct_test(pTest,status == true); - ct_test(pTest,value.type.Enumerated == 0xFFFF); - ct_test(pTest,testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data( - BACNET_APPLICATION_TAG_ENUMERATED, - "0xFFFFFFFF", - &value); - ct_test(pTest,status == true); - ct_test(pTest,value.type.Enumerated == 0xFFFFFFFF); - ct_test(pTest,testBACnetApplicationDataValue(&value)); + status = + bacapp_parse_application_data(BACNET_APPLICATION_TAG_ENUMERATED, + "0", &value); + ct_test(pTest, status == true); + ct_test(pTest, value.type.Enumerated == 0); + ct_test(pTest, testBACnetApplicationDataValue(&value)); + status = + bacapp_parse_application_data(BACNET_APPLICATION_TAG_ENUMERATED, + "0xFFFF", &value); + ct_test(pTest, status == true); + ct_test(pTest, value.type.Enumerated == 0xFFFF); + ct_test(pTest, testBACnetApplicationDataValue(&value)); + status = + bacapp_parse_application_data(BACNET_APPLICATION_TAG_ENUMERATED, + "0xFFFFFFFF", &value); + ct_test(pTest, status == true); + ct_test(pTest, value.type.Enumerated == 0xFFFFFFFF); + ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data( - BACNET_APPLICATION_TAG_DATE, - "2005/5/22:1", - &value); - ct_test(pTest,status == true); - ct_test(pTest,value.type.Date.year == 2005); - ct_test(pTest,value.type.Date.month == 5); - ct_test(pTest,value.type.Date.day == 22); - ct_test(pTest,value.type.Date.wday == 1); - ct_test(pTest,testBACnetApplicationDataValue(&value)); + status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_DATE, + "2005/5/22:1", &value); + ct_test(pTest, status == true); + ct_test(pTest, value.type.Date.year == 2005); + ct_test(pTest, value.type.Date.month == 5); + ct_test(pTest, value.type.Date.day == 22); + ct_test(pTest, value.type.Date.wday == 1); + ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data( - BACNET_APPLICATION_TAG_TIME, - "23:59:59.12", - &value); - ct_test(pTest,status == true); - ct_test(pTest,value.type.Time.hour == 23); - ct_test(pTest,value.type.Time.min == 59); - ct_test(pTest,value.type.Time.sec == 59); - ct_test(pTest,value.type.Time.hundredths == 12); - ct_test(pTest,testBACnetApplicationDataValue(&value)); + status = bacapp_parse_application_data(BACNET_APPLICATION_TAG_TIME, + "23:59:59.12", &value); + ct_test(pTest, status == true); + ct_test(pTest, value.type.Time.hour == 23); + ct_test(pTest, value.type.Time.min == 59); + ct_test(pTest, value.type.Time.sec == 59); + ct_test(pTest, value.type.Time.hundredths == 12); + ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data( - BACNET_APPLICATION_TAG_OBJECT_ID, - "0:100", - &value); - ct_test(pTest,status == true); - ct_test(pTest,value.type.Object_Id.type == 0); - ct_test(pTest,value.type.Object_Id.instance == 100); - ct_test(pTest,testBACnetApplicationDataValue(&value)); + status = + bacapp_parse_application_data(BACNET_APPLICATION_TAG_OBJECT_ID, + "0:100", &value); + ct_test(pTest, status == true); + ct_test(pTest, value.type.Object_Id.type == 0); + ct_test(pTest, value.type.Object_Id.instance == 100); + ct_test(pTest, testBACnetApplicationDataValue(&value)); - status = bacapp_parse_application_data( - BACNET_APPLICATION_TAG_CHARACTER_STRING, - "Karg!", - &value); - ct_test(pTest,status == true); - ct_test(pTest,testBACnetApplicationDataValue(&value)); + status = + bacapp_parse_application_data + (BACNET_APPLICATION_TAG_CHARACTER_STRING, "Karg!", &value); + ct_test(pTest, status == true); + ct_test(pTest, testBACnetApplicationDataValue(&value)); - return; + return; } #ifdef TEST_BACNET_APPLICATION_DATA @@ -796,5 +704,5 @@ int main(void) return 0; } -#endif /* TEST_BACNET_APPLICATION_DATA */ -#endif /* TEST */ +#endif /* TEST_BACNET_APPLICATION_DATA */ +#endif /* TEST */ diff --git a/bacnet-stack/bacapp.h b/bacnet-stack/bacapp.h index 72b16337..c528eb17 100644 --- a/bacnet-stack/bacapp.h +++ b/bacnet-stack/bacapp.h @@ -40,66 +40,54 @@ #include "bacdef.h" #include "bacstr.h" -typedef struct BACnet_Application_Data_Value -{ - uint8_t tag; - union - { - /* NULL - not needed as it is encoded in the tag alone */ - bool Boolean; - uint32_t Unsigned_Int; - int32_t Signed_Int; - float Real; - double Double; - BACNET_OCTET_STRING Octet_String; - BACNET_CHARACTER_STRING Character_String; - BACNET_BIT_STRING Bit_String; - int Enumerated; - BACNET_DATE Date; - BACNET_TIME Time; - BACNET_OBJECT_ID Object_Id; - } type; +typedef struct BACnet_Application_Data_Value { + uint8_t tag; + union { + /* NULL - not needed as it is encoded in the tag alone */ + bool Boolean; + uint32_t Unsigned_Int; + int32_t Signed_Int; + float Real; + double Double; + BACNET_OCTET_STRING Octet_String; + BACNET_CHARACTER_STRING Character_String; + BACNET_BIT_STRING Bit_String; + int Enumerated; + BACNET_DATE Date; + BACNET_TIME Time; + BACNET_OBJECT_ID Object_Id; + } type; } BACNET_APPLICATION_DATA_VALUE; #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ -int bacapp_decode_application_data( - uint8_t *apdu, - uint8_t apdu_len, - BACNET_APPLICATION_DATA_VALUE *value); + int bacapp_decode_application_data(uint8_t * apdu, + uint8_t apdu_len, BACNET_APPLICATION_DATA_VALUE * value); -int bacapp_encode_application_data( - uint8_t *apdu, - BACNET_APPLICATION_DATA_VALUE *value); + int bacapp_encode_application_data(uint8_t * apdu, + BACNET_APPLICATION_DATA_VALUE * value); -bool bacapp_copy( - BACNET_APPLICATION_DATA_VALUE *dest_value, - BACNET_APPLICATION_DATA_VALUE *src_value); + bool bacapp_copy(BACNET_APPLICATION_DATA_VALUE * dest_value, + BACNET_APPLICATION_DATA_VALUE * src_value); -bool bacapp_compare( - BACNET_APPLICATION_DATA_VALUE *value, - BACNET_APPLICATION_DATA_VALUE *test_value); + bool bacapp_compare(BACNET_APPLICATION_DATA_VALUE * value, + BACNET_APPLICATION_DATA_VALUE * test_value); -bool bacapp_parse_application_data( - BACNET_APPLICATION_TAG tag_number, - const char *argv, - BACNET_APPLICATION_DATA_VALUE *value); + bool bacapp_parse_application_data(BACNET_APPLICATION_TAG tag_number, + const char *argv, BACNET_APPLICATION_DATA_VALUE * value); -bool bacapp_print_value( - FILE *stream, - BACNET_APPLICATION_DATA_VALUE *value, - BACNET_PROPERTY_ID property); + bool bacapp_print_value(FILE * stream, + BACNET_APPLICATION_DATA_VALUE * value, + BACNET_PROPERTY_ID property); #ifdef TEST #include "ctest.h" -void testBACnetApplicationData(Test * pTest); + void testBACnetApplicationData(Test * pTest); #endif #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif - diff --git a/bacnet-stack/bacdcode.c b/bacnet-stack/bacdcode.c index 15a4adcf..4f25a533 100644 --- a/bacnet-stack/bacdcode.c +++ b/bacnet-stack/bacdcode.c @@ -99,20 +99,20 @@ uint8_t encode_max_segs_max_apdu(int max_segs, int max_apdu) // max_apdu must be 50 octets minimum if (max_apdu <= 50) - octet |= 0x00; + octet |= 0x00; else if (max_apdu <= 128) - octet |= 0x01; + octet |= 0x01; //fits in a LonTalk frame else if (max_apdu <= 206) - octet |= 0x02; + octet |= 0x02; //fits in an ARCNET or MS/TP frame else if (max_apdu <= 480) - octet |= 0x03; + octet |= 0x03; else if (max_apdu <= 1024) - octet |= 0x04; + octet |= 0x04; // fits in an ISO 8802-3 frame else if (max_apdu <= 1476) - octet |= 0x05; + octet |= 0x05; return octet; } @@ -124,33 +124,32 @@ int decode_max_segs(uint8_t octet) { int max_segs = 0; - switch (octet & 0xF0) - { - case 0: + switch (octet & 0xF0) { + case 0: max_segs = 0; break; - case 0x10: + case 0x10: max_segs = 2; break; - case 0x20: + case 0x20: max_segs = 4; break; - case 0x30: + case 0x30: max_segs = 8; break; - case 0x40: + case 0x40: max_segs = 16; break; - case 0x50: + case 0x50: max_segs = 32; break; - case 0x60: + case 0x60: max_segs = 64; break; - case 0x70: + case 0x70: max_segs = 65; break; - default: + default: break; } @@ -161,27 +160,26 @@ int decode_max_apdu(uint8_t octet) { int max_apdu = 0; - switch (octet & 0x0F) - { - case 0: + switch (octet & 0x0F) { + case 0: max_apdu = 50; break; - case 1: + case 1: max_apdu = 128; break; - case 2: + case 2: max_apdu = 206; break; - case 3: + case 3: max_apdu = 480; break; - case 4: + case 4: max_apdu = 1024; break; - case 5: + case 5: max_apdu = 1476; break; - default: + default: break; } @@ -193,7 +191,8 @@ int encode_unsigned16(uint8_t * apdu, uint16_t value) union { uint8_t byte[2]; uint16_t value; - } short_data = {{0}}; + } short_data = { { + 0}}; short_data.value = value; if (big_endian()) { @@ -207,12 +206,13 @@ int encode_unsigned16(uint8_t * apdu, uint16_t value) return 2; } -int decode_unsigned16(uint8_t * apdu, uint16_t *value) +int decode_unsigned16(uint8_t * apdu, uint16_t * value) { union { uint8_t byte[2]; uint16_t value; - } short_data = {{0}}; + } short_data = { { + 0}}; if (big_endian()) { short_data.byte[0] = apdu[0]; @@ -229,45 +229,47 @@ int decode_unsigned16(uint8_t * apdu, uint16_t *value) int encode_unsigned24(uint8_t * apdu, uint32_t value) { - union { - uint8_t byte[4]; - uint32_t value; - } long_data = {{0}}; + union { + uint8_t byte[4]; + uint32_t value; + } long_data = { { + 0}}; - long_data.value = value; - if (big_endian()) { - apdu[0] = long_data.byte[1]; - apdu[1] = long_data.byte[2]; - apdu[2] = long_data.byte[3]; - } else { - apdu[0] = long_data.byte[2]; - apdu[1] = long_data.byte[1]; - apdu[2] = long_data.byte[0]; - } + long_data.value = value; + if (big_endian()) { + apdu[0] = long_data.byte[1]; + apdu[1] = long_data.byte[2]; + apdu[2] = long_data.byte[3]; + } else { + apdu[0] = long_data.byte[2]; + apdu[1] = long_data.byte[1]; + apdu[2] = long_data.byte[0]; + } - return 3; + return 3; } -int decode_unsigned24(uint8_t * apdu, uint32_t *value) +int decode_unsigned24(uint8_t * apdu, uint32_t * value) { - union { - uint8_t byte[4]; - uint32_t value; - } long_data = {{0}}; + union { + uint8_t byte[4]; + uint32_t value; + } long_data = { { + 0}}; - if (big_endian()) { - long_data.byte[1] = apdu[0]; - long_data.byte[2] = apdu[1]; - long_data.byte[3] = apdu[2]; - } else { - long_data.byte[2] = apdu[0]; - long_data.byte[1] = apdu[1]; - long_data.byte[0] = apdu[2]; - } - if (value) - *value = long_data.value; + if (big_endian()) { + long_data.byte[1] = apdu[0]; + long_data.byte[2] = apdu[1]; + long_data.byte[3] = apdu[2]; + } else { + long_data.byte[2] = apdu[0]; + long_data.byte[1] = apdu[1]; + long_data.byte[0] = apdu[2]; + } + if (value) + *value = long_data.value; - return 3; + return 3; } int encode_unsigned32(uint8_t * apdu, uint32_t value) @@ -275,7 +277,8 @@ int encode_unsigned32(uint8_t * apdu, uint32_t value) union { uint8_t byte[4]; uint32_t value; - } long_data = {{0}}; + } long_data = { { + 0}}; long_data.value = value; if (big_endian()) { @@ -293,12 +296,13 @@ int encode_unsigned32(uint8_t * apdu, uint32_t value) return 4; } -int decode_unsigned32(uint8_t * apdu, uint32_t *value) +int decode_unsigned32(uint8_t * apdu, uint32_t * value) { union { uint8_t byte[4]; uint32_t value; - } long_data = {{0}}; + } long_data = { { + 0}}; if (big_endian()) { long_data.byte[0] = apdu[0]; @@ -319,166 +323,174 @@ int decode_unsigned32(uint8_t * apdu, uint32_t *value) int encode_signed8(uint8_t * apdu, int8_t value) { - union { - uint8_t byte; - int8_t value; - } byte_data = {0}; + union { + uint8_t byte; + int8_t value; + } byte_data = { + 0}; - byte_data.value = value; - apdu[0] = byte_data.byte; + byte_data.value = value; + apdu[0] = byte_data.byte; - return 1; + return 1; } -int decode_signed8(uint8_t * apdu, int8_t *value) +int decode_signed8(uint8_t * apdu, int8_t * value) { - union { - uint8_t byte; - int8_t value; - } byte_data = {0}; + union { + uint8_t byte; + int8_t value; + } byte_data = { + 0}; - byte_data.byte = apdu[0]; - if (value) - *value = byte_data.value; + byte_data.byte = apdu[0]; + if (value) + *value = byte_data.value; - return 1; + return 1; } int encode_signed16(uint8_t * apdu, int16_t value) { - union { - uint8_t byte[2]; - int16_t value; - } short_data = {{0}}; + union { + uint8_t byte[2]; + int16_t value; + } short_data = { { + 0}}; - short_data.value = value; - if (big_endian()) { - apdu[0] = short_data.byte[0]; - apdu[1] = short_data.byte[1]; - } else { - apdu[0] = short_data.byte[1]; - apdu[1] = short_data.byte[0]; - } + short_data.value = value; + if (big_endian()) { + apdu[0] = short_data.byte[0]; + apdu[1] = short_data.byte[1]; + } else { + apdu[0] = short_data.byte[1]; + apdu[1] = short_data.byte[0]; + } - return 2; + return 2; } -int decode_signed16(uint8_t * apdu, int16_t *value) +int decode_signed16(uint8_t * apdu, int16_t * value) { - union { - uint8_t byte[2]; - int16_t value; - } short_data = {{0}}; + union { + uint8_t byte[2]; + int16_t value; + } short_data = { { + 0}}; - if (big_endian()) { - short_data.byte[0] = apdu[0]; - short_data.byte[1] = apdu[1]; - } else { - short_data.byte[1] = apdu[0]; - short_data.byte[0] = apdu[1]; - } - if (value) - *value = short_data.value; + if (big_endian()) { + short_data.byte[0] = apdu[0]; + short_data.byte[1] = apdu[1]; + } else { + short_data.byte[1] = apdu[0]; + short_data.byte[0] = apdu[1]; + } + if (value) + *value = short_data.value; - return 2; + return 2; } int encode_signed24(uint8_t * apdu, int32_t value) { - union { - uint8_t byte[4]; - int32_t value; - } long_data = {{0}}; + union { + uint8_t byte[4]; + int32_t value; + } long_data = { { + 0}}; - long_data.value = value; - if (big_endian()) { - apdu[0] = long_data.byte[1]; - apdu[1] = long_data.byte[2]; - apdu[2] = long_data.byte[3]; - } else { - apdu[0] = long_data.byte[2]; - apdu[1] = long_data.byte[1]; - apdu[2] = long_data.byte[0]; - } + long_data.value = value; + if (big_endian()) { + apdu[0] = long_data.byte[1]; + apdu[1] = long_data.byte[2]; + apdu[2] = long_data.byte[3]; + } else { + apdu[0] = long_data.byte[2]; + apdu[1] = long_data.byte[1]; + apdu[2] = long_data.byte[0]; + } - return 3; + return 3; } -int decode_signed24(uint8_t * apdu, int32_t *value) +int decode_signed24(uint8_t * apdu, int32_t * value) { - union { - uint8_t byte[4]; - int32_t value; - } long_data = {{0}}; + union { + uint8_t byte[4]; + int32_t value; + } long_data = { { + 0}}; - if (big_endian()) { - /* negative - bit 7 is set */ - if (apdu[0] & 0x80) - long_data.byte[0] = 0xFF; - /* fill in the rest */ - long_data.byte[1] = apdu[0]; - long_data.byte[2] = apdu[1]; - long_data.byte[3] = apdu[2]; - } else { - /* negative - bit 7 is set */ - if (apdu[0] & 0x80) - long_data.byte[3] = 0xFF; - /* fill in the rest */ - long_data.byte[2] = apdu[0]; - long_data.byte[1] = apdu[1]; - long_data.byte[0] = apdu[2]; - } - if (value) - *value = long_data.value; + if (big_endian()) { + /* negative - bit 7 is set */ + if (apdu[0] & 0x80) + long_data.byte[0] = 0xFF; + /* fill in the rest */ + long_data.byte[1] = apdu[0]; + long_data.byte[2] = apdu[1]; + long_data.byte[3] = apdu[2]; + } else { + /* negative - bit 7 is set */ + if (apdu[0] & 0x80) + long_data.byte[3] = 0xFF; + /* fill in the rest */ + long_data.byte[2] = apdu[0]; + long_data.byte[1] = apdu[1]; + long_data.byte[0] = apdu[2]; + } + if (value) + *value = long_data.value; - return 3; + return 3; } int encode_signed32(uint8_t * apdu, int32_t value) { - union { - uint8_t byte[4]; - int32_t value; - } long_data = {{0}}; + union { + uint8_t byte[4]; + int32_t value; + } long_data = { { + 0}}; - long_data.value = value; - if (big_endian()) { - apdu[0] = long_data.byte[0]; - apdu[1] = long_data.byte[1]; - apdu[2] = long_data.byte[2]; - apdu[3] = long_data.byte[3]; - } else { - apdu[0] = long_data.byte[3]; - apdu[1] = long_data.byte[2]; - apdu[2] = long_data.byte[1]; - apdu[3] = long_data.byte[0]; - } + long_data.value = value; + if (big_endian()) { + apdu[0] = long_data.byte[0]; + apdu[1] = long_data.byte[1]; + apdu[2] = long_data.byte[2]; + apdu[3] = long_data.byte[3]; + } else { + apdu[0] = long_data.byte[3]; + apdu[1] = long_data.byte[2]; + apdu[2] = long_data.byte[1]; + apdu[3] = long_data.byte[0]; + } - return 4; + return 4; } -int decode_signed32(uint8_t * apdu, int32_t *value) +int decode_signed32(uint8_t * apdu, int32_t * value) { - union { - uint8_t byte[4]; - int32_t value; - } long_data = {{0}}; + union { + uint8_t byte[4]; + int32_t value; + } long_data = { { + 0}}; - if (big_endian()) { - long_data.byte[0] = apdu[0]; - long_data.byte[1] = apdu[1]; - long_data.byte[2] = apdu[2]; - long_data.byte[3] = apdu[3]; - } else { - long_data.byte[3] = apdu[0]; - long_data.byte[2] = apdu[1]; - long_data.byte[1] = apdu[2]; - long_data.byte[0] = apdu[3]; - } - if (value) - *value = long_data.value; + if (big_endian()) { + long_data.byte[0] = apdu[0]; + long_data.byte[1] = apdu[1]; + long_data.byte[2] = apdu[2]; + long_data.byte[3] = apdu[3]; + } else { + long_data.byte[3] = apdu[0]; + long_data.byte[2] = apdu[1]; + long_data.byte[1] = apdu[2]; + long_data.byte[0] = apdu[3]; + } + if (value) + *value = long_data.value; - return 4; + return 4; } // from clause 20.2.1 General Rules for Encoding BACnet Tags @@ -509,10 +521,11 @@ int encode_tag(uint8_t * apdu, uint8_t tag_number, bool context_specific, else { apdu[0] |= 5; if (len_value_type <= 253) { - apdu[len++] = (uint8_t)len_value_type; + 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); + len += + encode_unsigned16(&apdu[len], (uint16_t) len_value_type); } else { apdu[len++] = 255; len += encode_unsigned32(&apdu[len], len_value_type); @@ -636,14 +649,14 @@ int decode_tag_number_and_value(uint8_t * apdu, len++; len += decode_unsigned32(&apdu[len], &value32); if (value) - *value = value32; + *value = value32; } // tagged as uint16_t else if (apdu[len] == 254) { len++; len += decode_unsigned16(&apdu[len], &value16); if (value) - *value = value16; + *value = value16; } // no tag - must be uint8_t else { @@ -722,19 +735,19 @@ int encode_tagged_boolean(uint8_t * apdu, bool boolean_value) // context tagged is encoded differently int encode_context_boolean(uint8_t * apdu, bool boolean_value) { - apdu[0] = boolean_value ? 1 : 0; + apdu[0] = boolean_value ? 1 : 0; - return 1; + return 1; } bool decode_context_boolean(uint8_t * apdu) { - bool boolean_value = false; + bool boolean_value = false; - if (apdu[0]) - boolean_value = true; + if (apdu[0]) + boolean_value = true; - return boolean_value; + return boolean_value; } // from clause 20.2.3 Encoding of a Boolean Value @@ -742,12 +755,12 @@ bool decode_context_boolean(uint8_t * apdu) // returns the number of apdu bytes consumed bool decode_boolean(uint32_t len_value) { - bool boolean_value = false; + bool boolean_value = false; - if (len_value) - boolean_value = true; + if (len_value) + boolean_value = true; - return boolean_value; + return boolean_value; } // from clause 20.2.2 Encoding of a Null Value @@ -760,32 +773,32 @@ int encode_tagged_null(uint8_t * apdu) static uint8_t byte_reverse_bits(uint8_t in_byte) { - uint8_t out_byte = 0; + 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; + 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; + 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) + BACNET_BIT_STRING * bit_string) { int len = 0; uint8_t unused_bits = 0; @@ -794,21 +807,19 @@ int decode_bitstring(uint8_t * apdu, uint32_t len_value, 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++])); + 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); } - unused_bits = apdu[0] & 0x07; - bitstring_set_bits_used(bit_string, - (uint8_t)bytes_used, unused_bits); - } } return len; @@ -816,7 +827,7 @@ int decode_bitstring(uint8_t * apdu, uint32_t len_value, // 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 encode_bitstring(uint8_t * apdu, BACNET_BIT_STRING * bit_string) { int len = 0; uint8_t remaining_used_bits = 0; @@ -825,32 +836,31 @@ int encode_bitstring(uint8_t * apdu, BACNET_BIT_STRING *bit_string) // 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)); - } + 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_tagged_bitstring(uint8_t * apdu, BACNET_BIT_STRING *bit_string) +int encode_tagged_bitstring(uint8_t * apdu, BACNET_BIT_STRING * bit_string) { int len = 0; - int bit_string_encoded_length = 1;// 1 for the bits remaining octet + 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); + bit_string_encoded_length); len += encode_bitstring(&apdu[len], bit_string); return len; @@ -924,15 +934,12 @@ int encode_tagged_real(uint8_t * apdu, float value) // 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) +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); + len = decode_unsigned32(apdu, &value); *object_type = ((value >> BACNET_INSTANCE_BITS) & BACNET_MAX_OBJECT); *instance = (value & BACNET_MAX_INSTANCE); @@ -941,10 +948,8 @@ int decode_object_id( // 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) +int encode_bacnet_object_id(uint8_t * apdu, + int object_type, uint32_t instance) { uint32_t value = 0; uint32_t type = 0; @@ -953,7 +958,7 @@ int encode_bacnet_object_id( type = object_type; value = ((type & BACNET_MAX_OBJECT) << BACNET_INSTANCE_BITS) | (instance & BACNET_MAX_INSTANCE); - len = encode_unsigned32(apdu,value); + len = encode_unsigned32(apdu, value); return len; } @@ -961,17 +966,14 @@ int encode_bacnet_object_id( // 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 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); - len += encode_tag(&apdu[0], (uint8_t)tag_number, true, len); + len += encode_tag(&apdu[0], (uint8_t) tag_number, true, len); return len; } @@ -979,10 +981,8 @@ int encode_context_object_id( // 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_tagged_object_id( - uint8_t * apdu, - int object_type, - uint32_t instance) +int encode_tagged_object_id(uint8_t * apdu, + int object_type, uint32_t instance) { int len = 0; @@ -996,12 +996,11 @@ int encode_tagged_object_id( // 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 encode_octet_string(uint8_t * apdu, BACNET_OCTET_STRING * octet_string) { - int len = 0; /* return value */ + int len = 0; /* return value */ - if (octet_string) - { + 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); @@ -1015,16 +1014,16 @@ int encode_octet_string(uint8_t * apdu, BACNET_OCTET_STRING *octet_string) // and 20.2.1 General Rules for Encoding BACnet Tags // returns the number of apdu bytes consumed int encode_tagged_octet_string(uint8_t * apdu, - BACNET_OCTET_STRING *octet_string) + BACNET_OCTET_STRING * octet_string) { int apdu_len = 0; - if (octet_string) - { - apdu_len = encode_tag(&apdu[0], BACNET_APPLICATION_TAG_OCTET_STRING, + 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 */ + 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 @@ -1038,12 +1037,12 @@ int encode_tagged_octet_string(uint8_t * apdu, // 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) + BACNET_OCTET_STRING * octet_string) { - int len = 0; // return value + int len = 0; // return value bool status = false; - status = octetstring_init(octet_string,&apdu[0],len_value); + status = octetstring_init(octet_string, &apdu[0], len_value); if (status) len = len_value; @@ -1053,7 +1052,7 @@ int decode_octet_string(uint8_t * apdu, uint32_t len_value, // 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) + BACNET_CHARACTER_STRING * char_string) { int len; @@ -1061,41 +1060,44 @@ int encode_bacnet_character_string(uint8_t * apdu, apdu[0] = characterstring_encoding(char_string); memmove(&apdu[1], characterstring_value(char_string), len); - return len + 1 /* for encoding */; + 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_tagged_character_string(uint8_t * apdu, - BACNET_CHARACTER_STRING *char_string) + 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, + 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); + len += encode_bacnet_character_string(&apdu[len], char_string); else - len = 0; + len = 0; return len; } int encode_context_character_string(uint8_t * apdu, int tag_number, - BACNET_CHARACTER_STRING *char_string) + 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); + 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); + len += encode_bacnet_character_string(&apdu[len], char_string); else - len = 0; + len = 0; return len; } @@ -1104,15 +1106,15 @@ int encode_context_character_string(uint8_t * apdu, int tag_number, // 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) + BACNET_CHARACTER_STRING * char_string) { - int len = 0; // return value + int len = 0; // return value bool status = false; - status = characterstring_init(char_string, apdu[0], (char *)&apdu[1], - len_value-1); + status = characterstring_init(char_string, apdu[0], (char *) &apdu[1], + len_value - 1); if (status) - len = len_value; + len = len_value; return len; } @@ -1126,14 +1128,14 @@ int encode_bacnet_unsigned(uint8_t * apdu, uint32_t value) int len = 0; // return value if (value < 0x100) { - apdu[0] = (uint8_t)value; + apdu[0] = (uint8_t) value; len = 1; } else if (value < 0x10000) { - len = encode_unsigned16(&apdu[0],(uint16_t)value); + len = encode_unsigned16(&apdu[0], (uint16_t) value); } else if (value < 0x1000000) { - len = encode_unsigned24(&apdu[0],value); + len = encode_unsigned24(&apdu[0], value); } else { - len = encode_unsigned32(&apdu[0],value); + len = encode_unsigned32(&apdu[0], value); } return len; @@ -1147,7 +1149,7 @@ int encode_context_unsigned(uint8_t * apdu, int tag_number, uint32_t value) int len = 0; len = encode_bacnet_unsigned(&apdu[1], value); - len += encode_tag(&apdu[0], (uint8_t)tag_number, true, len); + len += encode_tag(&apdu[0], (uint8_t) tag_number, true, len); return len; } @@ -1170,7 +1172,7 @@ int encode_tagged_unsigned(uint8_t * apdu, uint32_t value) // and 20.2.1 General Rules for Encoding BACnet Tags // returns the number of apdu bytes consumed // FIXME: What about endian? -int decode_unsigned(uint8_t * apdu, uint32_t len_value, uint32_t *value) +int decode_unsigned(uint8_t * apdu, uint32_t len_value, uint32_t * value) { uint16_t unsigned16_value = 0; @@ -1180,14 +1182,14 @@ int decode_unsigned(uint8_t * apdu, uint32_t len_value, uint32_t *value) *value = apdu[0]; break; case 2: - decode_unsigned16(&apdu[0],&unsigned16_value); + decode_unsigned16(&apdu[0], &unsigned16_value); *value = unsigned16_value; break; case 3: - decode_unsigned24(&apdu[0],value); + decode_unsigned24(&apdu[0], value); break; case 4: - decode_unsigned32(&apdu[0],value); + decode_unsigned32(&apdu[0], value); break; default: *value = 0; @@ -1245,7 +1247,7 @@ int encode_context_enumerated(uint8_t * apdu, int tag_number, int value) // assumes that the tag only consumes 1 octet len = encode_bacnet_enumerated(&apdu[1], value); - len += encode_tag(&apdu[0], (uint8_t)tag_number, true, len); + len += encode_tag(&apdu[0], (uint8_t) tag_number, true, len); return len; } @@ -1253,7 +1255,7 @@ int encode_context_enumerated(uint8_t * apdu, int tag_number, int 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 decode_signed(uint8_t * apdu, uint32_t len_value, int32_t *value) +int decode_signed(uint8_t * apdu, uint32_t len_value, int32_t * value) { int8_t signed8_value = 0; int16_t signed16_value = 0; @@ -1261,18 +1263,18 @@ int decode_signed(uint8_t * apdu, uint32_t len_value, int32_t *value) if (value) { switch (len_value) { case 1: - decode_signed8(&apdu[0],&signed8_value); + decode_signed8(&apdu[0], &signed8_value); *value = signed8_value; break; case 2: - decode_signed16(&apdu[0],&signed16_value); + decode_signed16(&apdu[0], &signed16_value); *value = signed16_value; break; case 3: - decode_signed24(&apdu[0],value); + decode_signed24(&apdu[0], value); break; case 4: - decode_signed32(&apdu[0],value); + decode_signed32(&apdu[0], value); break; default: *value = 0; @@ -1288,24 +1290,24 @@ int decode_signed(uint8_t * apdu, uint32_t len_value, int32_t *value) // returns the number of apdu bytes consumed int encode_bacnet_signed(uint8_t * apdu, int32_t value) { - int len = 0; // return 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); - } + /* 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; + return len; } // from clause 20.2.5 Encoding of a Signed Integer Value @@ -1332,7 +1334,7 @@ int encode_context_signed(uint8_t * apdu, int tag_number, int32_t value) // assumes that the tag only consumes 1 octet len = encode_bacnet_signed(&apdu[1], value); - len += encode_tag(&apdu[0], (uint8_t)tag_number, true, len); + len += encode_tag(&apdu[0], (uint8_t) tag_number, true, len); return len; } @@ -1394,12 +1396,11 @@ int encode_bacnet_date(uint8_t * apdu, int year, int month, int day, int wday) { /* allow 2 digit years */ - if (year < 1900) - { - if (year <= 38) - year += 2000; - else - year += 1900; + if (year < 1900) { + if (year <= 38) + year += 2000; + else + year += 1900; } apdu[0] = year - 1900; apdu[1] = month; @@ -1440,7 +1441,7 @@ int decode_date(uint8_t * apdu, int *year, int *month, int *day, int *wday) // returns the number of apdu bytes consumed int encode_simple_ack(uint8_t * apdu, uint8_t invoke_id, - uint8_t service_choice) + uint8_t service_choice) { apdu[0] = PDU_TYPE_SIMPLE_ACK; apdu[1] = invoke_id; @@ -1474,51 +1475,51 @@ static int get_apdu_len(bool extended_tag, uint32_t value) return test_len; } -static void print_apdu(uint8_t *pBlock, uint32_t num) +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 + 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; + 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; + /* 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; + return; } void testBACDCodeTags(Test * pTest) @@ -1621,8 +1622,10 @@ void testBACDCodeEnumerated(Test * pTest) for (i = 0; i < 31; i++) { apdu_len = encode_tagged_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); + 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); @@ -1652,35 +1655,34 @@ void testBACDCodeEnumerated(Test * pTest) 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; + 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_tagged_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_tagged_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_tagged_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); + len_value = encode_tagged_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_tagged_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_tagged_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) @@ -1689,10 +1691,10 @@ void testBACDCodeUnsigned(Test * pTest) int i; for (i = 0; i < 32; i++) { - testBACDCodeUnsignedValue(pTest, value-1); - testBACDCodeUnsignedValue(pTest, value); - testBACDCodeUnsignedValue(pTest, value+1); - value = value << 1; + testBACDCodeUnsignedValue(pTest, value - 1); + testBACDCodeUnsignedValue(pTest, value); + testBACDCodeUnsignedValue(pTest, value + 1); + value = value << 1; } return; @@ -1700,63 +1702,61 @@ void testBACDCodeUnsigned(Test * pTest) void testBACDCodeSignedValue(Test * pTest, int32_t value) { - uint8_t array[5] = { 0 }; - uint8_t encoded_array[5] = { 0 }; - int 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; + uint8_t array[5] = { 0 }; + uint8_t encoded_array[5] = { 0 }; + int 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_tagged_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_tagged_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_tagged_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); + len = encode_tagged_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_tagged_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_tagged_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; + return; } void testBACDCodeSigned(Test * pTest) { - int value = 1; - int i = 0; + 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, value - 1); + testBACDCodeSignedValue(pTest, value); + testBACDCodeSignedValue(pTest, value + 1); + value = value << 1; } - testBACDCodeSignedValue(pTest,-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; + testBACDCodeSignedValue(pTest, value - 1); + testBACDCodeSignedValue(pTest, value); + testBACDCodeSignedValue(pTest, value + 1); + value = value << 1; } return; @@ -1775,45 +1775,41 @@ void testBACDCodeOctetString(Test * pTest) uint8_t tag_number = 0; uint32_t len_value = 0; bool status = false; - int diff = 0; /* for memcmp */ + int diff = 0; /* for memcmp */ - status = octetstring_init( - &octet_string, - NULL, - 0); - ct_test(pTest,status == true); + status = octetstring_init(&octet_string, NULL, 0); + ct_test(pTest, status == true); apdu_len = encode_tagged_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); + 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_tagged_octet_string(&encoded_array[0],&octet_string); - len = decode_tag_number_and_value(&encoded_array[0], - &tag_number, &len_value); + status = octetstring_init(&octet_string, test_value, i); + ct_test(pTest, status == true); + apdu_len = + encode_tagged_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); + &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)); + octetstring_length(&octet_string)); if (diff) { printf("test octet string=#%d\n", i); } - ct_test(pTest,diff == 0); + ct_test(pTest, diff == 0); } return; @@ -1831,41 +1827,44 @@ void testBACDCodeCharacterString(Test * pTest) int len; uint8_t tag_number = 0; uint32_t len_value = 0; - int diff = 0; /* for comparison */ + int diff = 0; /* for comparison */ bool status = false; - status = characterstring_init( - &char_string, - CHARACTER_ANSI_X34, - NULL, - 0); - ct_test(pTest,status == true); + status = characterstring_init(&char_string, + CHARACTER_ANSI_X34, NULL, 0); + ct_test(pTest, status == true); apdu_len = encode_tagged_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, 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)); + characterstring_length(&char_string)); ct_test(pTest, diff == 0); - for (i = 0; i < MAX_CHARACTER_STRING_BYTES-1; i++) { + 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); + ct_test(pTest, status == true); apdu_len = - encode_tagged_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); + encode_tagged_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); + 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)); + characterstring_length(&char_string)); if (diff) { printf("test string=#%d\n", i); } @@ -1897,7 +1896,8 @@ void testBACDCodeObject(Test * pTest) 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) { + 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); @@ -1914,72 +1914,73 @@ void testBACDCodeObject(Test * pTest) 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; + 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)); + // 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; + 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_tagged_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_tagged_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); - } + 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_tagged_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_tagged_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 diff --git a/bacnet-stack/bacdcode.h b/bacnet-stack/bacdcode.h index 523a4e72..224f7e98 100644 --- a/bacnet-stack/bacdcode.h +++ b/bacnet-stack/bacdcode.h @@ -42,117 +42,125 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ // 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 encode_tag(uint8_t * apdu, uint8_t tag_number, + bool context_specific, uint32_t len_value_type); // 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 encode_closing_tag(uint8_t * apdu, uint8_t tag_number); -int decode_tag_number_and_value(uint8_t * apdu, uint8_t * tag_number, - uint32_t * value); + int encode_opening_tag(uint8_t * apdu, uint8_t tag_number); + int encode_closing_tag(uint8_t * apdu, uint8_t tag_number); + int decode_tag_number_and_value(uint8_t * apdu, uint8_t * tag_number, + uint32_t * value); // returns true if the tag is context specific -bool decode_is_context_specific(uint8_t * apdu); + bool decode_is_context_specific(uint8_t * apdu); // returns true if the tag is an opening tag and matches -bool decode_is_opening_tag_number(uint8_t * apdu, uint8_t tag_number); + bool decode_is_opening_tag_number(uint8_t * apdu, uint8_t tag_number); // returns true if the tag is a closing tag and matches -bool decode_is_closing_tag_number(uint8_t * apdu, uint8_t tag_number); + bool decode_is_closing_tag_number(uint8_t * apdu, uint8_t tag_number); // returns true if the tag is context specific and matches -bool decode_is_context_tag(uint8_t * apdu, uint8_t tag_number); + bool decode_is_context_tag(uint8_t * apdu, uint8_t tag_number); // from clause 20.2.2 Encoding of a Null Value -int encode_tagged_null(uint8_t * apdu); + int encode_tagged_null(uint8_t * apdu); // from clause 20.2.3 Encoding of a Boolean Value -int encode_tagged_boolean(uint8_t * apdu, bool boolean_value); -bool decode_boolean(uint32_t len_value); -int encode_context_boolean(uint8_t * apdu, bool boolean_value); -bool decode_context_boolean(uint8_t * apdu); + int encode_tagged_boolean(uint8_t * apdu, bool boolean_value); + bool decode_boolean(uint32_t len_value); + int encode_context_boolean(uint8_t * apdu, bool boolean_value); + bool decode_context_boolean(uint8_t * apdu); // 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 decode_bitstring(uint8_t * apdu, uint32_t len_value, + BACNET_BIT_STRING * bit_string); // returns the number of apdu bytes consumed -int encode_bitstring(uint8_t * apdu, BACNET_BIT_STRING *bit_string); -int encode_tagged_bitstring(uint8_t * apdu, BACNET_BIT_STRING *bit_string); + int encode_bitstring(uint8_t * apdu, BACNET_BIT_STRING * bit_string); + int encode_tagged_bitstring(uint8_t * apdu, + BACNET_BIT_STRING * bit_string); // from clause 20.2.6 Encoding of a Real Number Value // and 20.2.1 General Rules for Encoding BACnet Tags // returns the number of apdu bytes consumed -int decode_real(uint8_t * apdu, float *real_value); -int encode_bacnet_real(float value, uint8_t * apdu); -int encode_tagged_real(uint8_t * apdu, float value); + int decode_real(uint8_t * apdu, float *real_value); + int encode_bacnet_real(float value, uint8_t * apdu); + int encode_tagged_real(uint8_t * apdu, float value); // 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 decode_object_id(uint8_t * apdu, int *object_type, uint32_t *instance); -int encode_bacnet_object_id(uint8_t * apdu, int object_type, uint32_t instance); -int encode_context_object_id(uint8_t * apdu, int tag_number, - int object_type, uint32_t instance); -int encode_tagged_object_id(uint8_t * apdu, int object_type, uint32_t instance); + int decode_object_id(uint8_t * apdu, int *object_type, + uint32_t * instance); + int encode_bacnet_object_id(uint8_t * apdu, int object_type, + uint32_t instance); + int encode_context_object_id(uint8_t * apdu, int tag_number, + int object_type, uint32_t instance); + int encode_tagged_object_id(uint8_t * apdu, int object_type, + uint32_t instance); // 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_octet_string(uint8_t * apdu, - BACNET_OCTET_STRING *octet_string); -int encode_tagged_octet_string(uint8_t * apdu, - BACNET_OCTET_STRING *octet_string); -int decode_octet_string(uint8_t * apdu, uint32_t len_value, - BACNET_OCTET_STRING *octet_string); + int encode_octet_string(uint8_t * apdu, + BACNET_OCTET_STRING * octet_string); + int encode_tagged_octet_string(uint8_t * apdu, + BACNET_OCTET_STRING * octet_string); + int decode_octet_string(uint8_t * apdu, uint32_t len_value, + BACNET_OCTET_STRING * octet_string); // 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_bacnet_character_string(uint8_t * apdu, - BACNET_CHARACTER_STRING *char_string); -int encode_tagged_character_string(uint8_t * apdu, - BACNET_CHARACTER_STRING *char_string); -int encode_context_character_string(uint8_t * apdu, int tag_number, - BACNET_CHARACTER_STRING *char_string); -int decode_character_string(uint8_t * apdu, uint32_t len_value, - BACNET_CHARACTER_STRING *char_string); + int encode_bacnet_character_string(uint8_t * apdu, + BACNET_CHARACTER_STRING * char_string); + int encode_tagged_character_string(uint8_t * apdu, + BACNET_CHARACTER_STRING * char_string); + int encode_context_character_string(uint8_t * apdu, int tag_number, + BACNET_CHARACTER_STRING * char_string); + int decode_character_string(uint8_t * apdu, uint32_t len_value, + BACNET_CHARACTER_STRING * char_string); // 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 encode_context_unsigned(uint8_t * apdu, int tag_number, uint32_t value); -int encode_tagged_unsigned(uint8_t * apdu, uint32_t value); -int decode_unsigned(uint8_t * apdu, uint32_t len_value, uint32_t *value); + int encode_bacnet_unsigned(uint8_t * apdu, uint32_t value); + int encode_context_unsigned(uint8_t * apdu, int tag_number, + uint32_t value); + int encode_tagged_unsigned(uint8_t * apdu, uint32_t value); + int decode_unsigned(uint8_t * apdu, uint32_t len_value, + uint32_t * 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 encode_tagged_signed(uint8_t * apdu, int32_t value); -int encode_context_signed(uint8_t * apdu, int tag_number, int32_t value); -int decode_signed(uint8_t * apdu, uint32_t len_value, int32_t *value); + int encode_bacnet_signed(uint8_t * apdu, int32_t value); + int encode_tagged_signed(uint8_t * apdu, int32_t value); + int encode_context_signed(uint8_t * apdu, int tag_number, + int32_t value); + int decode_signed(uint8_t * apdu, uint32_t len_value, int32_t * 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 decode_enumerated(uint8_t * apdu, uint32_t len_value, int *value); -int encode_bacnet_enumerated(uint8_t * apdu, int value); -int encode_tagged_enumerated(uint8_t * apdu, int value); -int encode_context_enumerated(uint8_t * apdu, int tag_number, int value); + int decode_enumerated(uint8_t * apdu, uint32_t len_value, int *value); + int encode_bacnet_enumerated(uint8_t * apdu, int value); + int encode_tagged_enumerated(uint8_t * apdu, int value); + int encode_context_enumerated(uint8_t * apdu, int tag_number, + int value); // 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, int hour, int min, int sec, - int hundredths); -int encode_tagged_time(uint8_t * apdu, int hour, int min, int sec, - int hundredths); -int decode_bacnet_time(uint8_t * apdu, int *hour, int *min, int *sec, - int *hundredths); + int encode_bacnet_time(uint8_t * apdu, int hour, int min, int sec, + int hundredths); + int encode_tagged_time(uint8_t * apdu, int hour, int min, int sec, + int hundredths); + int decode_bacnet_time(uint8_t * apdu, int *hour, int *min, int *sec, + int *hundredths); // BACnet Date // year = years since 1900 @@ -163,33 +171,32 @@ int decode_bacnet_time(uint8_t * apdu, int *hour, int *min, int *sec, // 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, int year, int month, int day, - int wday); -int encode_tagged_date(uint8_t * apdu, int year, int month, int day, - int wday); -int decode_date(uint8_t * apdu, int *year, int *month, int *day, - int *wday); + int encode_bacnet_date(uint8_t * apdu, int year, int month, int day, + int wday); + int encode_tagged_date(uint8_t * apdu, int year, int month, int day, + int wday); + int decode_date(uint8_t * apdu, int *year, int *month, int *day, + int *wday); // two octet unsigned16 -int encode_unsigned16(uint8_t * apdu, uint16_t value); -int decode_unsigned16(uint8_t * apdu, uint16_t *value); + int encode_unsigned16(uint8_t * apdu, uint16_t value); + int decode_unsigned16(uint8_t * apdu, uint16_t * value); // four octet unsigned32 -int encode_unsigned32(uint8_t * apdu, uint32_t value); -int decode_unsigned32(uint8_t * apdu, uint32_t *value); + int encode_unsigned32(uint8_t * apdu, uint32_t value); + int decode_unsigned32(uint8_t * apdu, uint32_t * value); // 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); -int decode_max_segs(uint8_t octet); -int decode_max_apdu(uint8_t octet); + uint8_t encode_max_segs_max_apdu(int max_segs, int max_apdu); + int decode_max_segs(uint8_t octet); + int decode_max_apdu(uint8_t octet); // returns the number of apdu bytes consumed -int encode_simple_ack(uint8_t * apdu, uint8_t invoke_id, - uint8_t service_choice); + int encode_simple_ack(uint8_t * apdu, uint8_t invoke_id, + uint8_t service_choice); #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif diff --git a/bacnet-stack/bacdef.h b/bacnet-stack/bacdef.h index af9f6660..ce45e912 100644 --- a/bacnet-stack/bacdef.h +++ b/bacnet-stack/bacdef.h @@ -56,11 +56,10 @@ // embedded systems need fixed name sizes #define MAX_OBJECT_NAME 10 // common object properties -typedef struct BACnet_Object_Data -{ - uint32_t Object_Identifier; - char Object_Name[MAX_OBJECT_NAME]; - BACNET_OBJECT_TYPE Object_Type; +typedef struct BACnet_Object_Data { + uint32_t Object_Identifier; + char Object_Name[MAX_OBJECT_NAME]; + BACNET_OBJECT_TYPE Object_Type; } BACNET_OBJECT_DATA; #define BACNET_BROADCAST_NETWORK 0xFFFF @@ -75,39 +74,36 @@ struct BACnet_Device_Address { // DNET,DLEN,DADR or SNET,SLEN,SADR // the following are used if the device is behind a router // net = 0 indicates local - uint16_t net; /* BACnet network number */ + uint16_t net; /* BACnet network number */ // LEN = 0 denotes broadcast MAC ADR and ADR field is absent // LEN > 0 specifies length of ADR field - int len; /* length of MAC address */ - uint8_t adr[MAX_MAC_LEN]; /* hwaddr (MAC) address */ + int len; /* length of MAC address */ + uint8_t adr[MAX_MAC_LEN]; /* hwaddr (MAC) address */ }; typedef struct BACnet_Device_Address BACNET_ADDRESS; /* date */ -typedef struct BACnet_Date -{ - uint16_t year; /* AD */ - uint8_t month; /* 1=Jan */ - uint8_t day; /* 1..31 */ - uint8_t wday; /* 1=Monday */ +typedef struct BACnet_Date { + uint16_t year; /* AD */ + uint8_t month; /* 1=Jan */ + uint8_t day; /* 1..31 */ + uint8_t wday; /* 1=Monday */ } BACNET_DATE; /* time */ -typedef struct BACnet_Time -{ - uint8_t hour; - uint8_t min; - uint8_t sec; - uint8_t hundredths; +typedef struct BACnet_Time { + uint8_t hour; + uint8_t min; + uint8_t sec; + uint8_t hundredths; } BACNET_TIME; /* note: with microprocessors having lots more code space than memory, it might be better to have a packed encoding with a library to easily access the data. */ -typedef struct BACnet_Object_Id -{ - uint16_t type; - uint32_t instance; +typedef struct BACnet_Object_Id { + uint16_t type; + uint32_t instance; } BACNET_OBJECT_ID; #define MAX_NPDU (1+1+2+1+MAX_MAC_LEN+2+1+MAX_MAC_LEN+1+1+2) diff --git a/bacnet-stack/bacenum.h b/bacnet-stack/bacenum.h index d9134c99..ef1a2214 100644 --- a/bacnet-stack/bacenum.h +++ b/bacnet-stack/bacenum.h @@ -34,709 +34,686 @@ #ifndef BACENUM_H #define BACENUM_H -typedef enum -{ - PROP_ACKED_TRANSITIONS = 0, - PROP_ACK_REQUIRED = 1, - PROP_ACTION = 2, - PROP_ACTION_TEXT = 3, - PROP_ACTIVE_TEXT = 4, - PROP_ACTIVE_VT_SESSIONS = 5, - PROP_ALARM_VALUE = 6, - PROP_ALARM_VALUES = 7, - PROP_ALL = 8, - PROP_ALL_WRITES_SUCCESSFUL = 9, - PROP_APDU_SEGMENT_TIMEOUT = 10, - PROP_APDU_TIMEOUT = 11, - PROP_APPLICATION_SOFTWARE_VERSION = 12, - PROP_ARCHIVE = 13, - PROP_BIAS = 14, - PROP_CHANGE_OF_STATE_COUNT = 15, - PROP_CHANGE_OF_STATE_TIME = 16, - PROP_NOTIFICATION_CLASS = 17, - PROP_BLANK_1 = 18, - PROP_CONTROLLED_VARIABLE_REFERENCE = 19, - PROP_CONTROLLED_VARIABLE_UNITS = 20, - PROP_CONTROLLED_VARIABLE_VALUE = 21, - PROP_COV_INCREMENT = 22, - PROP_DATE_LIST = 23, - PROP_DAYLIGHT_SAVINGS_STATUS = 24, - PROP_DEADBAND = 25, - PROP_DERIVATIVE_CONSTANT = 26, - PROP_DERIVATIVE_CONSTANT_UNITS = 27, - PROP_DESCRIPTION = 28, - PROP_DESCRIPTION_OF_HALT = 29, - PROP_DEVICE_ADDRESS_BINDING = 30, - PROP_DEVICE_TYPE = 31, - PROP_EFFECTIVE_PERIOD = 32, - PROP_ELAPSED_ACTIVE_TIME = 33, - PROP_ERROR_LIMIT = 34, - PROP_EVENT_ENABLE = 35, - PROP_EVENT_STATE = 36, - PROP_EVENT_TYPE = 37, - PROP_EXCEPTION_SCHEDULE = 38, - PROP_FAULT_VALUES = 39, - PROP_FEEDBACK_VALUE = 40, - PROP_FILE_ACCESS_METHOD = 41, - PROP_FILE_SIZE = 42, - PROP_FILE_TYPE = 43, - PROP_FIRMWARE_REVISION = 44, - PROP_HIGH_LIMIT = 45, - PROP_INACTIVE_TEXT = 46, - PROP_IN_PROCESS = 47, - PROP_INSTANCE_OF = 48, - PROP_INTEGRAL_CONSTANT = 49, - PROP_INTEGRAL_CONSTANT_UNITS = 50, - PROP_ISSUE_CONFIRMED_NOTIFICATIONS = 51, - PROP_LIMIT_ENABLE = 52, - PROP_LIST_OF_GROUP_MEMBERS = 53, - PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES = 54, - PROP_LIST_OF_SESSION_KEYS = 55, - PROP_LOCAL_DATE = 56, - PROP_LOCAL_TIME = 57, - PROP_LOCATION = 58, - PROP_LOW_LIMIT = 59, - PROP_MANIPULATED_VARIABLE_REFERENCE = 60, - PROP_MAXIMUM_OUTPUT = 61, - PROP_MAX_APDU_LENGTH_ACCEPTED = 62, - PROP_MAX_INFO_FRAMES = 63, - PROP_MAX_MASTER = 64, - PROP_MAX_PRES_VALUE = 65, - PROP_MINIMUM_OFF_TIME = 66, - PROP_MINIMUM_ON_TIME = 67, - PROP_MINIMUM_OUTPUT = 68, - PROP_MIN_PRES_VALUE = 69, - PROP_MODEL_NAME = 70, - PROP_MODIFICATION_DATE = 71, - PROP_NOTIFY_TYPE = 72, - PROP_NUMBER_OF_APDU_RETRIES = 73, - PROP_NUMBER_OF_STATES = 74, - PROP_OBJECT_IDENTIFIER = 75, - PROP_OBJECT_LIST = 76, - PROP_OBJECT_NAME = 77, - PROP_OBJECT_PROPERTY_REFERENCE = 78, - PROP_OBJECT_TYPE = 79, - PROP_OPTIONAL = 80, - PROP_OUT_OF_SERVICE = 81, - PROP_OUTPUT_UNITS = 82, - PROP_EVENT_PARAMETERS = 83, - PROP_POLARITY = 84, - PROP_PRESENT_VALUE = 85, - PROP_PRIORITY = 86, - PROP_PRIORITY_ARRAY = 87, - PROP_PRIORITY_FOR_WRITING = 88, - PROP_PROCESS_IDENTIFIER = 89, - PROP_PROGRAM_CHANGE = 90, - PROP_PROGRAM_LOCATION = 91, - PROP_PROGRAM_STATE = 92, - PROP_PROPORTIONAL_CONSTANT = 93, - PROP_PROPORTIONAL_CONSTANT_UNITS = 94, - PROP_PROTOCOL_CONFORMANCE_CLASS = 95, // deleted in version 1 revision 2 - PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED = 96, - PROP_PROTOCOL_SERVICES_SUPPORTED = 97, - PROP_PROTOCOL_VERSION = 98, - PROP_READ_ONLY = 99, - PROP_REASON_FOR_HALT = 100, - PROP_RECIPIENT = 101, - PROP_RECIPIENT_LIST = 102, - PROP_RELIABILITY = 103, - PROP_RELINQUISH_DEFAULT = 104, - PROP_REQUIRED = 105, - PROP_RESOLUTION = 106, - PROP_SEGMENTATION_SUPPORTED = 107, - PROP_SETPOINT = 108, - PROP_SETPOINT_REFERENCE = 109, - PROP_STATE_TEXT = 110, - PROP_STATUS_FLAGS = 111, - PROP_SYSTEM_STATUS = 112, - PROP_TIME_DELAY = 113, - PROP_TIME_OF_ACTIVE_TIME_RESET = 114, - PROP_TIME_OF_STATE_COUNT_RESET = 115, - PROP_TIME_SYNCHRONIZATION_RECIPIENTS = 116, - PROP_UNITS = 117, - PROP_UPDATE_INTERVAL = 118, - PROP_UTC_OFFSET = 119, - PROP_VENDOR_IDENTIFIER = 120, - PROP_VENDOR_NAME = 121, - PROP_VT_CLASSES_SUPPORTED = 122, - PROP_WEEKLY_SCHEDULE = 123, - PROP_ATTEMPTED_SAMPLES = 124, - PROP_AVERAGE_VALUE = 125, - PROP_BUFFER_SIZE = 126, - PROP_CLIENT_COV_INCREMENT = 127, - PROP_COV_RESUBSCRIPTION_INTERVAL = 128, - PROP_CURRENT_NOTIFY_TIME = 129, - PROP_EVENT_TIME_STAMPS = 130, - PROP_LOG_BUFFER = 131, - PROP_LOG_DEVICE_OBJECT = 132, - PROP_LOG_ENABLE = 133, - PROP_LOG_INTERVAL = 134, - PROP_MAXIMUM_VALUE = 135, - PROP_MINIMUM_VALUE = 136, - PROP_NOTIFICATION_THRESHOLD = 137, - PROP_PREVIOUS_NOTIFY_TIME = 138, - PROP_PROTOCOL_REVISION = 139, - PROP_RECORDS_SINCE_NOTIFICATION = 140, - PROP_RECORD_COUNT = 141, - PROP_START_TIME = 142, - PROP_STOP_TIME = 143, - PROP_STOP_WHEN_FULL = 144, - PROP_TOTAL_RECORD_COUNT = 145, - PROP_VALID_SAMPLES = 146, - PROP_WINDOW_INTERVAL = 147, - PROP_WINDOW_SAMPLES = 148, - PROP_MAXIMUM_VALUE_TIMESTAMP = 149, - PROP_MINIMUM_VALUE_TIMESTAMP = 150, - PROP_VARIANCE_VALUE = 151, - PROP_ACTIVE_COV_SUBSCRIPTIONS = 152, - PROP_BACKUP_FAILURE_TIMEOUT = 153, - PROP_CONFIGURATION_FILES = 154, - PROP_DATABASE_REVISION = 155, - PROP_DIRECT_READING = 156, - PROP_LAST_RESTORE_TIME = 157, - PROP_MAINTENANCE_REQUIRED = 158, - PROP_MEMBER_OF = 159, - PROP_MODE = 160, - PROP_OPERATION_EXPECTED = 161, - PROP_SETTING = 162, - PROP_SILENCED = 163, - PROP_TRACKING_VALUE = 164, - PROP_ZONE_MEMBERS = 165, - PROP_LIFE_SAFETY_ALARM_VALUES = 166, - PROP_MAX_SEGMENTS_ACCEPTED = 167, - PROP_PROFILE_NAME = 168, - PROP_AUTO_SLAVE_DISCOVERY = 169, - PROP_MANUAL_SLAVE_ADDRESS_BINDING = 170, - PROP_SLAVE_ADDRESS_BINDING = 171, - PROP_SLAVE_PROXY_ENABLE = 172, - PROP_LAST_NOTIFY_TIME = 173, - PROP_SCHEDULE_DEFAULT = 174, - PROP_ACCEPTED_MODES = 175, - PROP_ADJUST_VALUE = 176, - PROP_COUNT = 177, - PROP_COUNT_BEFORE_CHANGE = 178, - PROP_COUNT_CHANGE_TIME = 179, - PROP_COV_PERIOD = 180, - PROP_INPUT_REFERENCE = 181, - PROP_LIMIT_MONITORING_INTERVAL = 182, - PROP_LOGGING_DEVICE = 183, - PROP_LOGGING_RECORD = 184, - PROP_PRESCALE = 185, - PROP_PULSE_RATE = 186, - PROP_SCALE = 187, - PROP_SCALE_FACTOR = 188, - PROP_UPDATE_TIME = 189, - PROP_VALUE_BEFORE_CHANGE = 190, - PROP_VALUE_SET = 191, - PROP_VALUE_CHANGE_TIME = 192, +typedef enum { + PROP_ACKED_TRANSITIONS = 0, + PROP_ACK_REQUIRED = 1, + PROP_ACTION = 2, + PROP_ACTION_TEXT = 3, + PROP_ACTIVE_TEXT = 4, + PROP_ACTIVE_VT_SESSIONS = 5, + PROP_ALARM_VALUE = 6, + PROP_ALARM_VALUES = 7, + PROP_ALL = 8, + PROP_ALL_WRITES_SUCCESSFUL = 9, + PROP_APDU_SEGMENT_TIMEOUT = 10, + PROP_APDU_TIMEOUT = 11, + PROP_APPLICATION_SOFTWARE_VERSION = 12, + PROP_ARCHIVE = 13, + PROP_BIAS = 14, + PROP_CHANGE_OF_STATE_COUNT = 15, + PROP_CHANGE_OF_STATE_TIME = 16, + PROP_NOTIFICATION_CLASS = 17, + PROP_BLANK_1 = 18, + PROP_CONTROLLED_VARIABLE_REFERENCE = 19, + PROP_CONTROLLED_VARIABLE_UNITS = 20, + PROP_CONTROLLED_VARIABLE_VALUE = 21, + PROP_COV_INCREMENT = 22, + PROP_DATE_LIST = 23, + PROP_DAYLIGHT_SAVINGS_STATUS = 24, + PROP_DEADBAND = 25, + PROP_DERIVATIVE_CONSTANT = 26, + PROP_DERIVATIVE_CONSTANT_UNITS = 27, + PROP_DESCRIPTION = 28, + PROP_DESCRIPTION_OF_HALT = 29, + PROP_DEVICE_ADDRESS_BINDING = 30, + PROP_DEVICE_TYPE = 31, + PROP_EFFECTIVE_PERIOD = 32, + PROP_ELAPSED_ACTIVE_TIME = 33, + PROP_ERROR_LIMIT = 34, + PROP_EVENT_ENABLE = 35, + PROP_EVENT_STATE = 36, + PROP_EVENT_TYPE = 37, + PROP_EXCEPTION_SCHEDULE = 38, + PROP_FAULT_VALUES = 39, + PROP_FEEDBACK_VALUE = 40, + PROP_FILE_ACCESS_METHOD = 41, + PROP_FILE_SIZE = 42, + PROP_FILE_TYPE = 43, + PROP_FIRMWARE_REVISION = 44, + PROP_HIGH_LIMIT = 45, + PROP_INACTIVE_TEXT = 46, + PROP_IN_PROCESS = 47, + PROP_INSTANCE_OF = 48, + PROP_INTEGRAL_CONSTANT = 49, + PROP_INTEGRAL_CONSTANT_UNITS = 50, + PROP_ISSUE_CONFIRMED_NOTIFICATIONS = 51, + PROP_LIMIT_ENABLE = 52, + PROP_LIST_OF_GROUP_MEMBERS = 53, + PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES = 54, + PROP_LIST_OF_SESSION_KEYS = 55, + PROP_LOCAL_DATE = 56, + PROP_LOCAL_TIME = 57, + PROP_LOCATION = 58, + PROP_LOW_LIMIT = 59, + PROP_MANIPULATED_VARIABLE_REFERENCE = 60, + PROP_MAXIMUM_OUTPUT = 61, + PROP_MAX_APDU_LENGTH_ACCEPTED = 62, + PROP_MAX_INFO_FRAMES = 63, + PROP_MAX_MASTER = 64, + PROP_MAX_PRES_VALUE = 65, + PROP_MINIMUM_OFF_TIME = 66, + PROP_MINIMUM_ON_TIME = 67, + PROP_MINIMUM_OUTPUT = 68, + PROP_MIN_PRES_VALUE = 69, + PROP_MODEL_NAME = 70, + PROP_MODIFICATION_DATE = 71, + PROP_NOTIFY_TYPE = 72, + PROP_NUMBER_OF_APDU_RETRIES = 73, + PROP_NUMBER_OF_STATES = 74, + PROP_OBJECT_IDENTIFIER = 75, + PROP_OBJECT_LIST = 76, + PROP_OBJECT_NAME = 77, + PROP_OBJECT_PROPERTY_REFERENCE = 78, + PROP_OBJECT_TYPE = 79, + PROP_OPTIONAL = 80, + PROP_OUT_OF_SERVICE = 81, + PROP_OUTPUT_UNITS = 82, + PROP_EVENT_PARAMETERS = 83, + PROP_POLARITY = 84, + PROP_PRESENT_VALUE = 85, + PROP_PRIORITY = 86, + PROP_PRIORITY_ARRAY = 87, + PROP_PRIORITY_FOR_WRITING = 88, + PROP_PROCESS_IDENTIFIER = 89, + PROP_PROGRAM_CHANGE = 90, + PROP_PROGRAM_LOCATION = 91, + PROP_PROGRAM_STATE = 92, + PROP_PROPORTIONAL_CONSTANT = 93, + PROP_PROPORTIONAL_CONSTANT_UNITS = 94, + PROP_PROTOCOL_CONFORMANCE_CLASS = 95, // deleted in version 1 revision 2 + PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED = 96, + PROP_PROTOCOL_SERVICES_SUPPORTED = 97, + PROP_PROTOCOL_VERSION = 98, + PROP_READ_ONLY = 99, + PROP_REASON_FOR_HALT = 100, + PROP_RECIPIENT = 101, + PROP_RECIPIENT_LIST = 102, + PROP_RELIABILITY = 103, + PROP_RELINQUISH_DEFAULT = 104, + PROP_REQUIRED = 105, + PROP_RESOLUTION = 106, + PROP_SEGMENTATION_SUPPORTED = 107, + PROP_SETPOINT = 108, + PROP_SETPOINT_REFERENCE = 109, + PROP_STATE_TEXT = 110, + PROP_STATUS_FLAGS = 111, + PROP_SYSTEM_STATUS = 112, + PROP_TIME_DELAY = 113, + PROP_TIME_OF_ACTIVE_TIME_RESET = 114, + PROP_TIME_OF_STATE_COUNT_RESET = 115, + PROP_TIME_SYNCHRONIZATION_RECIPIENTS = 116, + PROP_UNITS = 117, + PROP_UPDATE_INTERVAL = 118, + PROP_UTC_OFFSET = 119, + PROP_VENDOR_IDENTIFIER = 120, + PROP_VENDOR_NAME = 121, + PROP_VT_CLASSES_SUPPORTED = 122, + PROP_WEEKLY_SCHEDULE = 123, + PROP_ATTEMPTED_SAMPLES = 124, + PROP_AVERAGE_VALUE = 125, + PROP_BUFFER_SIZE = 126, + PROP_CLIENT_COV_INCREMENT = 127, + PROP_COV_RESUBSCRIPTION_INTERVAL = 128, + PROP_CURRENT_NOTIFY_TIME = 129, + PROP_EVENT_TIME_STAMPS = 130, + PROP_LOG_BUFFER = 131, + PROP_LOG_DEVICE_OBJECT = 132, + PROP_LOG_ENABLE = 133, + PROP_LOG_INTERVAL = 134, + PROP_MAXIMUM_VALUE = 135, + PROP_MINIMUM_VALUE = 136, + PROP_NOTIFICATION_THRESHOLD = 137, + PROP_PREVIOUS_NOTIFY_TIME = 138, + PROP_PROTOCOL_REVISION = 139, + PROP_RECORDS_SINCE_NOTIFICATION = 140, + PROP_RECORD_COUNT = 141, + PROP_START_TIME = 142, + PROP_STOP_TIME = 143, + PROP_STOP_WHEN_FULL = 144, + PROP_TOTAL_RECORD_COUNT = 145, + PROP_VALID_SAMPLES = 146, + PROP_WINDOW_INTERVAL = 147, + PROP_WINDOW_SAMPLES = 148, + PROP_MAXIMUM_VALUE_TIMESTAMP = 149, + PROP_MINIMUM_VALUE_TIMESTAMP = 150, + PROP_VARIANCE_VALUE = 151, + PROP_ACTIVE_COV_SUBSCRIPTIONS = 152, + PROP_BACKUP_FAILURE_TIMEOUT = 153, + PROP_CONFIGURATION_FILES = 154, + PROP_DATABASE_REVISION = 155, + PROP_DIRECT_READING = 156, + PROP_LAST_RESTORE_TIME = 157, + PROP_MAINTENANCE_REQUIRED = 158, + PROP_MEMBER_OF = 159, + PROP_MODE = 160, + PROP_OPERATION_EXPECTED = 161, + PROP_SETTING = 162, + PROP_SILENCED = 163, + PROP_TRACKING_VALUE = 164, + PROP_ZONE_MEMBERS = 165, + PROP_LIFE_SAFETY_ALARM_VALUES = 166, + PROP_MAX_SEGMENTS_ACCEPTED = 167, + PROP_PROFILE_NAME = 168, + PROP_AUTO_SLAVE_DISCOVERY = 169, + PROP_MANUAL_SLAVE_ADDRESS_BINDING = 170, + PROP_SLAVE_ADDRESS_BINDING = 171, + PROP_SLAVE_PROXY_ENABLE = 172, + PROP_LAST_NOTIFY_TIME = 173, + PROP_SCHEDULE_DEFAULT = 174, + PROP_ACCEPTED_MODES = 175, + PROP_ADJUST_VALUE = 176, + PROP_COUNT = 177, + PROP_COUNT_BEFORE_CHANGE = 178, + PROP_COUNT_CHANGE_TIME = 179, + PROP_COV_PERIOD = 180, + PROP_INPUT_REFERENCE = 181, + PROP_LIMIT_MONITORING_INTERVAL = 182, + PROP_LOGGING_DEVICE = 183, + PROP_LOGGING_RECORD = 184, + PROP_PRESCALE = 185, + PROP_PULSE_RATE = 186, + PROP_SCALE = 187, + PROP_SCALE_FACTOR = 188, + PROP_UPDATE_TIME = 189, + PROP_VALUE_BEFORE_CHANGE = 190, + PROP_VALUE_SET = 191, + PROP_VALUE_CHANGE_TIME = 192, - // The special property identifiers all, optional, and required - // are reserved for use in the ReadPropertyConditional and - // ReadPropertyMultiple services or services not defined in this standard. - // Enumerated values 0-511 are reserved for definition by ASHRAE. - // Enumerated values 512-4194303 may be used by others subject to the - // procedures and constraints described in Clause 23. - // The highest enumeration used in this version is 168. - MAX_BACNET_PROPERTY_ID = 4194303 + // The special property identifiers all, optional, and required + // are reserved for use in the ReadPropertyConditional and + // ReadPropertyMultiple services or services not defined in this standard. + // Enumerated values 0-511 are reserved for definition by ASHRAE. + // Enumerated values 512-4194303 may be used by others subject to the + // procedures and constraints described in Clause 23. + // The highest enumeration used in this version is 168. + MAX_BACNET_PROPERTY_ID = 4194303 } BACNET_PROPERTY_ID; -typedef enum -{ - ACTION_DIRECT = 0, - ACTION_REVERSE = 1 +typedef enum { + ACTION_DIRECT = 0, + ACTION_REVERSE = 1 } BACNET_ACTION; -typedef enum -{ - BINARY_INACTIVE = 0, - BINARY_ACTIVE = 1 +typedef enum { + BINARY_INACTIVE = 0, + BINARY_ACTIVE = 1 } BACNET_BINARY_PV; -typedef enum -{ - ACTION_BINARY_PV, - ACTION_UNSIGNED, - ACTION_FLOAT -} BACNET_ACTION_VALUE_TYPE ; +typedef enum { + ACTION_BINARY_PV, + ACTION_UNSIGNED, + ACTION_FLOAT +} BACNET_ACTION_VALUE_TYPE; -typedef enum -{ - EVENT_STATE_NORMAL = 0, - EVENT_STATE_FAULT = 1, - EVENT_STATE_OFFNORMAL = 2, - EVENT_STATE_HIGH_LIMIT = 3, - EVENT_STATE_LOW_LIMIT = 4 +typedef enum { + EVENT_STATE_NORMAL = 0, + EVENT_STATE_FAULT = 1, + EVENT_STATE_OFFNORMAL = 2, + EVENT_STATE_HIGH_LIMIT = 3, + EVENT_STATE_LOW_LIMIT = 4 } BACNET_EVENT_STATE; -typedef enum -{ - STATUS_OPERATIONAL = 0, - STATUS_OPERATIONAL_READ_ONLY = 1, - STATUS_DOWNLOAD_REQUIRED = 2, - STATUS_DOWNLOAD_IN_PROGRESS = 3, - STATUS_NON_OPERATIONAL = 4 +typedef enum { + STATUS_OPERATIONAL = 0, + STATUS_OPERATIONAL_READ_ONLY = 1, + STATUS_DOWNLOAD_REQUIRED = 2, + STATUS_DOWNLOAD_IN_PROGRESS = 3, + STATUS_NON_OPERATIONAL = 4 } BACNET_DEVICE_STATUS; -typedef enum -{ - /* Acceleration */ - UNITS_METERS_PER_SECOND_PER_SECOND = 166, - /* Area */ - UNITS_SQUARE_METERS = 0, - UNITS_SQUARE_CENTIMETERS = 116, - UNITS_SQUARE_FEET = 1, - UNITS_SQUARE_INCHES = 115, - /* Currency */ - UNITS_CURRENCY1 = 105, - UNITS_CURRENCY2 = 106, - UNITS_CURRENCY3 = 107, - UNITS_CURRENCY4 = 108, - UNITS_CURRENCY5 = 109, - UNITS_CURRENCY6 = 110, - UNITS_CURRENCY7 = 111, - UNITS_CURRENCY8 = 112, - UNITS_CURRENCY9 = 113, - UNITS_CURRENCY10 = 114, - /* Electrical */ - UNITS_MILLIAMPERES = 2, - UNITS_AMPERES = 3, - UNITS_AMPERES_PER_METER = 167, - UNITS_AMPERES_PER_SQUARE_METER = 168, - UNITS_AMPERE_SQUARE_METERS = 169, - UNITS_FARADS = 170, - UNITS_HENRYS = 171, - UNITS_OHMS = 4, - UNITS_OHM_METERS = 172, - UNITS_MILLIOHMS = 145, - UNITS_KILOHMS = 122, - UNITS_MEGOHMS = 123, - UNITS_SIEMENS = 173, /* 1 mho equals 1 siemens */ - UNITS_SIEMENS_PER_METER = 174, - UNITS_TESLAS = 175, - UNITS_VOLTS = 5, - UNITS_MILLIVOLTS = 124, - UNITS_KILOVOLTS = 6, - UNITS_MEGAVOLTS = 7, - UNITS_VOLT_AMPERES = 8, - UNITS_KILOVOLT_AMPERES = 9, - UNITS_MEGAVOLT_AMPERES = 10, - UNITS_VOLT_AMPERES_REACTIVE = 11, - UNITS_KILOVOLT_AMPERES_REACTIVE = 12, - UNITS_MEGAVOLT_AMPERES_REACTIVE = 13, - UNITS_VOLTS_PER_DEGREE_KELVIN = 176, - UNITS_VOLTS_PER_METER = 177, - UNITS_DEGREES_PHASE = 14, - UNITS_POWER_FACTOR = 15, - UNITS_WEBERS = 178, - /* Energy */ - UNITS_JOULES = 16, - UNITS_KILOJOULES = 17, - UNITS_KILOJOULES_PER_KILOGRAM = 125, - UNITS_MEGAJOULES = 126, - UNITS_WATT_HOURS = 18, - UNITS_KILOWATT_HOURS = 19, - UNITS_MEGAWATT_HOURS = 146, - UNITS_BTUS = 20, - UNITS_KILO_BTUS = 147, - UNITS_MEGA_BTUS = 148, - UNITS_THERMS = 21, - UNITS_TON_HOURS = 22, - /* Enthalpy */ - UNITS_JOULES_PER_KILOGRAM_DRY_AIR = 23, - UNITS_KILOJOULES_PER_KILOGRAM_DRY_AIR = 149, - UNITS_MEGAJOULES_PER_KILOGRAM_DRY_AIR = 150, - UNITS_BTUS_PER_POUND_DRY_AIR = 24, - UNITS_BTUS_PER_POUND = 117, - /* Entropy */ - UNITS_JOULES_PER_DEGREE_KELVIN = 127, - UNITS_KILOJOULES_PER_DEGREE_KELVIN = 151, - UNITS_MEGAJOULES_PER_DEGREE_KELVIN = 152, - UNITS_JOULES_PER_KILOGRAM_DEGREE_KELVIN = 128, - /* Force */ - UNITS_NEWTON = 153, - /* Frequency */ - UNITS_CYCLES_PER_HOUR = 25, - UNITS_CYCLES_PER_MINUTE = 26, - UNITS_HERTZ = 27, - UNITS_KILOHERTZ = 129, - UNITS_MEGAHERTZ = 130, - UNITS_PER_HOUR = 131, - /* Humidity */ - UNITS_GRAMS_OF_WATER_PER_KILOGRAM_DRY_AIR = 28, - UNITS_PERCENT_RELATIVE_HUMIDITY = 29, - /* Length */ - UNITS_MILLIMETERS = 30, - UNITS_CENTIMETERS = 118, - UNITS_METERS = 31, - UNITS_INCHES = 32, - UNITS_FEET = 33, - /* Light */ - UNITS_CANDELAS = 179, - UNITS_CANDELAS_PER_SQUARE_METER = 180, - UNITS_WATTS_PER_SQUARE_FOOT = 34, - UNITS_WATTS_PER_SQUARE_METER = 35, - UNITS_LUMENS = 36, - UNITS_LUXES = 37, - UNITS_FOOT_CANDLES = 38, - /* Mass */ - UNITS_KILOGRAMS = 39, - UNITS_POUNDS_MASS = 40, - UNITS_TONS = 41, - /* Mass Flow */ - UNITS_GRAMS_PER_SECOND = 154, - UNITS_GRAMS_PER_MINUTE = 155, - UNITS_KILOGRAMS_PER_SECOND = 42, - UNITS_KILOGRAMS_PER_MINUTE = 43, - UNITS_KILOGRAMS_PER_HOUR = 44, - UNITS_POUNDS_MASS_PER_SECOND = 119, - UNITS_POUNDS_MASS_PER_MINUTE = 45, - UNITS_POUNDS_MASS_PER_HOUR = 46, - UNITS_TONS_PER_HOUR = 156, - /* Power */ - UNITS_MILLIWATTS = 132, - UNITS_WATTS = 47, - UNITS_KILOWATTS = 48, - UNITS_MEGAWATTS = 49, - UNITS_BTUS_PER_HOUR = 50, - UNITS_KILO_BTUS_PER_HOUR = 157, - UNITS_HORSEPOWER = 51, - UNITS_TONS_REFRIGERATION = 52, - /* Pressure */ - UNITS_PASCALS = 53, - UNITS_HECTOPASCALS = 133, - UNITS_KILOPASCALS = 54, - UNITS_MILLIBARS = 134, - UNITS_BARS = 55, - UNITS_POUNDS_FORCE_PER_SQUARE_INCH = 56, - UNITS_CENTIMETERS_OF_WATER = 57, - UNITS_INCHES_OF_WATER = 58, - UNITS_MILLIMETERS_OF_MERCURY = 59, - UNITS_CENTIMETERS_OF_MERCURY = 60, - UNITS_INCHES_OF_MERCURY = 61, - /* Temperature */ - UNITS_DEGREES_CELSIUS = 62, - UNITS_DEGREES_KELVIN = 63, - UNITS_DEGREES_KELVIN_PER_HOUR = 181, - UNITS_DEGREES_KELVIN_PER_MINUTE = 182, - UNITS_DEGREES_FAHRENHEIT = 64, - UNITS_DEGREE_DAYS_CELSIUS = 65, - UNITS_DEGREE_DAYS_FAHRENHEIT = 66, - UNITS_DELTA_DEGREES_FAHRENHEIT = 120, - UNITS_DELTA_DEGREES_KELVIN = 121, - /* Time */ - UNITS_YEARS = 67, - UNITS_MONTHS = 68, - UNITS_WEEKS = 69, - UNITS_DAYS = 70, - UNITS_HOURS = 71, - UNITS_MINUTES = 72, - UNITS_SECONDS = 73, - UNITS_HUNDREDTHS_SECONDS = 158, - UNITS_MILLISECONDS = 159, - /* Torque */ - UNITS_NEWTON_METERS = 160, - /* Velocity */ - UNITS_MILLIMETERS_PER_SECOND = 161, - UNITS_MILLIMETERS_PER_MINUTE = 162, - UNITS_METERS_PER_SECOND = 74, - UNITS_METERS_PER_MINUTE = 163, - UNITS_METERS_PER_HOUR = 164, - UNITS_KILOMETERS_PER_HOUR = 75, - UNITS_FEET_PER_SECOND = 76, - UNITS_FEET_PER_MINUTE = 77, - UNITS_MILES_PER_HOUR = 78, - /* Volume */ - UNITS_CUBIC_FEET = 79, - UNITS_CUBIC_METERS = 80, - UNITS_IMPERIAL_GALLONS = 81, - UNITS_LITERS = 82, - UNITS_US_GALLONS = 83, - /* Volumetric Flow */ - UNITS_CUBIC_FEET_PER_SECOND = 142, - UNITS_CUBIC_FEET_PER_MINUTE = 84, - UNITS_CUBIC_METERS_PER_SECOND = 85, - UNITS_CUBIC_METERS_PER_MINUTE = 165, - UNITS_CUBIC_METERS_PER_HOUR = 135, - UNITS_IMPERIAL_GALLONS_PER_MINUTE = 86, - UNITS_LITERS_PER_SECOND = 87, - UNITS_LITERS_PER_MINUTE = 88, - UNITS_LITERS_PER_HOUR = 136, - UNITS_US_GALLONS_PER_MINUTE = 89, - /* Other */ - UNITS_DEGREES_ANGULAR = 90, - UNITS_DEGREES_CELSIUS_PER_HOUR = 91, - UNITS_DEGREES_CELSIUS_PER_MINUTE = 92, - UNITS_DEGREES_FAHRENHEIT_PER_HOUR = 93, - UNITS_DEGREES_FAHRENHEIT_PER_MINUTE = 94, - UNITS_JOULE_SECONDS = 183, - UNITS_KILOGRAMS_PER_CUBIC_METER = 186, - UNITS_KILOWATT_HOURS_PER_SQUARE_METER = 137, - UNITS_KILOWATT_HOURS_PER_SQUARE_FOOT = 138, - UNITS_MEGAJOULES_PER_SQUARE_METER = 139, - UNITS_MEGAJOULES_PER_SQUARE_FOOT = 140, - UNITS_NO_UNITS = 95, - UNITS_NEWTON_SECONDS = 187, - UNITS_NEWTONS_PER_METER = 188, - UNITS_PARTS_PER_MILLION = 96, - UNITS_PARTS_PER_BILLION = 97, - UNITS_PERCENT = 98, - UNITS_PERCENT_OBSCURATION_PER_FOOT = 143, - UNITS_PERCENT_OBSCURATION_PER_METER = 144, - UNITS_PERCENT_PER_SECOND = 99, - UNITS_PER_MINUTE = 100, - UNITS_PER_SECOND = 101, - UNITS_PSI_PER_DEGREE_FAHRENHEIT = 102, - UNITS_RADIANS = 103, - UNITS_RADIANS_PER_SECOND = 184, - UNITS_REVOLUTIONS_PER_MINUTE = 104, - UNITS_SQUARE_METERS_PER_NEWTON = 185, - UNITS_WATTS_PER_METER_PER_DEGREE_KELVIN = 189, - UNITS_WATTS_PER_SQUARE_METER_DEGREE_KELVIN = 141 - /* Enumerated values 0-255 are reserved for definition by ASHRAE. - Enumerated values 256-65535 may be used by others subject to - the procedures and constraints described in Clause 23. - The last enumeration used in this version is 189. */ +typedef enum { + /* Acceleration */ + UNITS_METERS_PER_SECOND_PER_SECOND = 166, + /* Area */ + UNITS_SQUARE_METERS = 0, + UNITS_SQUARE_CENTIMETERS = 116, + UNITS_SQUARE_FEET = 1, + UNITS_SQUARE_INCHES = 115, + /* Currency */ + UNITS_CURRENCY1 = 105, + UNITS_CURRENCY2 = 106, + UNITS_CURRENCY3 = 107, + UNITS_CURRENCY4 = 108, + UNITS_CURRENCY5 = 109, + UNITS_CURRENCY6 = 110, + UNITS_CURRENCY7 = 111, + UNITS_CURRENCY8 = 112, + UNITS_CURRENCY9 = 113, + UNITS_CURRENCY10 = 114, + /* Electrical */ + UNITS_MILLIAMPERES = 2, + UNITS_AMPERES = 3, + UNITS_AMPERES_PER_METER = 167, + UNITS_AMPERES_PER_SQUARE_METER = 168, + UNITS_AMPERE_SQUARE_METERS = 169, + UNITS_FARADS = 170, + UNITS_HENRYS = 171, + UNITS_OHMS = 4, + UNITS_OHM_METERS = 172, + UNITS_MILLIOHMS = 145, + UNITS_KILOHMS = 122, + UNITS_MEGOHMS = 123, + UNITS_SIEMENS = 173, /* 1 mho equals 1 siemens */ + UNITS_SIEMENS_PER_METER = 174, + UNITS_TESLAS = 175, + UNITS_VOLTS = 5, + UNITS_MILLIVOLTS = 124, + UNITS_KILOVOLTS = 6, + UNITS_MEGAVOLTS = 7, + UNITS_VOLT_AMPERES = 8, + UNITS_KILOVOLT_AMPERES = 9, + UNITS_MEGAVOLT_AMPERES = 10, + UNITS_VOLT_AMPERES_REACTIVE = 11, + UNITS_KILOVOLT_AMPERES_REACTIVE = 12, + UNITS_MEGAVOLT_AMPERES_REACTIVE = 13, + UNITS_VOLTS_PER_DEGREE_KELVIN = 176, + UNITS_VOLTS_PER_METER = 177, + UNITS_DEGREES_PHASE = 14, + UNITS_POWER_FACTOR = 15, + UNITS_WEBERS = 178, + /* Energy */ + UNITS_JOULES = 16, + UNITS_KILOJOULES = 17, + UNITS_KILOJOULES_PER_KILOGRAM = 125, + UNITS_MEGAJOULES = 126, + UNITS_WATT_HOURS = 18, + UNITS_KILOWATT_HOURS = 19, + UNITS_MEGAWATT_HOURS = 146, + UNITS_BTUS = 20, + UNITS_KILO_BTUS = 147, + UNITS_MEGA_BTUS = 148, + UNITS_THERMS = 21, + UNITS_TON_HOURS = 22, + /* Enthalpy */ + UNITS_JOULES_PER_KILOGRAM_DRY_AIR = 23, + UNITS_KILOJOULES_PER_KILOGRAM_DRY_AIR = 149, + UNITS_MEGAJOULES_PER_KILOGRAM_DRY_AIR = 150, + UNITS_BTUS_PER_POUND_DRY_AIR = 24, + UNITS_BTUS_PER_POUND = 117, + /* Entropy */ + UNITS_JOULES_PER_DEGREE_KELVIN = 127, + UNITS_KILOJOULES_PER_DEGREE_KELVIN = 151, + UNITS_MEGAJOULES_PER_DEGREE_KELVIN = 152, + UNITS_JOULES_PER_KILOGRAM_DEGREE_KELVIN = 128, + /* Force */ + UNITS_NEWTON = 153, + /* Frequency */ + UNITS_CYCLES_PER_HOUR = 25, + UNITS_CYCLES_PER_MINUTE = 26, + UNITS_HERTZ = 27, + UNITS_KILOHERTZ = 129, + UNITS_MEGAHERTZ = 130, + UNITS_PER_HOUR = 131, + /* Humidity */ + UNITS_GRAMS_OF_WATER_PER_KILOGRAM_DRY_AIR = 28, + UNITS_PERCENT_RELATIVE_HUMIDITY = 29, + /* Length */ + UNITS_MILLIMETERS = 30, + UNITS_CENTIMETERS = 118, + UNITS_METERS = 31, + UNITS_INCHES = 32, + UNITS_FEET = 33, + /* Light */ + UNITS_CANDELAS = 179, + UNITS_CANDELAS_PER_SQUARE_METER = 180, + UNITS_WATTS_PER_SQUARE_FOOT = 34, + UNITS_WATTS_PER_SQUARE_METER = 35, + UNITS_LUMENS = 36, + UNITS_LUXES = 37, + UNITS_FOOT_CANDLES = 38, + /* Mass */ + UNITS_KILOGRAMS = 39, + UNITS_POUNDS_MASS = 40, + UNITS_TONS = 41, + /* Mass Flow */ + UNITS_GRAMS_PER_SECOND = 154, + UNITS_GRAMS_PER_MINUTE = 155, + UNITS_KILOGRAMS_PER_SECOND = 42, + UNITS_KILOGRAMS_PER_MINUTE = 43, + UNITS_KILOGRAMS_PER_HOUR = 44, + UNITS_POUNDS_MASS_PER_SECOND = 119, + UNITS_POUNDS_MASS_PER_MINUTE = 45, + UNITS_POUNDS_MASS_PER_HOUR = 46, + UNITS_TONS_PER_HOUR = 156, + /* Power */ + UNITS_MILLIWATTS = 132, + UNITS_WATTS = 47, + UNITS_KILOWATTS = 48, + UNITS_MEGAWATTS = 49, + UNITS_BTUS_PER_HOUR = 50, + UNITS_KILO_BTUS_PER_HOUR = 157, + UNITS_HORSEPOWER = 51, + UNITS_TONS_REFRIGERATION = 52, + /* Pressure */ + UNITS_PASCALS = 53, + UNITS_HECTOPASCALS = 133, + UNITS_KILOPASCALS = 54, + UNITS_MILLIBARS = 134, + UNITS_BARS = 55, + UNITS_POUNDS_FORCE_PER_SQUARE_INCH = 56, + UNITS_CENTIMETERS_OF_WATER = 57, + UNITS_INCHES_OF_WATER = 58, + UNITS_MILLIMETERS_OF_MERCURY = 59, + UNITS_CENTIMETERS_OF_MERCURY = 60, + UNITS_INCHES_OF_MERCURY = 61, + /* Temperature */ + UNITS_DEGREES_CELSIUS = 62, + UNITS_DEGREES_KELVIN = 63, + UNITS_DEGREES_KELVIN_PER_HOUR = 181, + UNITS_DEGREES_KELVIN_PER_MINUTE = 182, + UNITS_DEGREES_FAHRENHEIT = 64, + UNITS_DEGREE_DAYS_CELSIUS = 65, + UNITS_DEGREE_DAYS_FAHRENHEIT = 66, + UNITS_DELTA_DEGREES_FAHRENHEIT = 120, + UNITS_DELTA_DEGREES_KELVIN = 121, + /* Time */ + UNITS_YEARS = 67, + UNITS_MONTHS = 68, + UNITS_WEEKS = 69, + UNITS_DAYS = 70, + UNITS_HOURS = 71, + UNITS_MINUTES = 72, + UNITS_SECONDS = 73, + UNITS_HUNDREDTHS_SECONDS = 158, + UNITS_MILLISECONDS = 159, + /* Torque */ + UNITS_NEWTON_METERS = 160, + /* Velocity */ + UNITS_MILLIMETERS_PER_SECOND = 161, + UNITS_MILLIMETERS_PER_MINUTE = 162, + UNITS_METERS_PER_SECOND = 74, + UNITS_METERS_PER_MINUTE = 163, + UNITS_METERS_PER_HOUR = 164, + UNITS_KILOMETERS_PER_HOUR = 75, + UNITS_FEET_PER_SECOND = 76, + UNITS_FEET_PER_MINUTE = 77, + UNITS_MILES_PER_HOUR = 78, + /* Volume */ + UNITS_CUBIC_FEET = 79, + UNITS_CUBIC_METERS = 80, + UNITS_IMPERIAL_GALLONS = 81, + UNITS_LITERS = 82, + UNITS_US_GALLONS = 83, + /* Volumetric Flow */ + UNITS_CUBIC_FEET_PER_SECOND = 142, + UNITS_CUBIC_FEET_PER_MINUTE = 84, + UNITS_CUBIC_METERS_PER_SECOND = 85, + UNITS_CUBIC_METERS_PER_MINUTE = 165, + UNITS_CUBIC_METERS_PER_HOUR = 135, + UNITS_IMPERIAL_GALLONS_PER_MINUTE = 86, + UNITS_LITERS_PER_SECOND = 87, + UNITS_LITERS_PER_MINUTE = 88, + UNITS_LITERS_PER_HOUR = 136, + UNITS_US_GALLONS_PER_MINUTE = 89, + /* Other */ + UNITS_DEGREES_ANGULAR = 90, + UNITS_DEGREES_CELSIUS_PER_HOUR = 91, + UNITS_DEGREES_CELSIUS_PER_MINUTE = 92, + UNITS_DEGREES_FAHRENHEIT_PER_HOUR = 93, + UNITS_DEGREES_FAHRENHEIT_PER_MINUTE = 94, + UNITS_JOULE_SECONDS = 183, + UNITS_KILOGRAMS_PER_CUBIC_METER = 186, + UNITS_KILOWATT_HOURS_PER_SQUARE_METER = 137, + UNITS_KILOWATT_HOURS_PER_SQUARE_FOOT = 138, + UNITS_MEGAJOULES_PER_SQUARE_METER = 139, + UNITS_MEGAJOULES_PER_SQUARE_FOOT = 140, + UNITS_NO_UNITS = 95, + UNITS_NEWTON_SECONDS = 187, + UNITS_NEWTONS_PER_METER = 188, + UNITS_PARTS_PER_MILLION = 96, + UNITS_PARTS_PER_BILLION = 97, + UNITS_PERCENT = 98, + UNITS_PERCENT_OBSCURATION_PER_FOOT = 143, + UNITS_PERCENT_OBSCURATION_PER_METER = 144, + UNITS_PERCENT_PER_SECOND = 99, + UNITS_PER_MINUTE = 100, + UNITS_PER_SECOND = 101, + UNITS_PSI_PER_DEGREE_FAHRENHEIT = 102, + UNITS_RADIANS = 103, + UNITS_RADIANS_PER_SECOND = 184, + UNITS_REVOLUTIONS_PER_MINUTE = 104, + UNITS_SQUARE_METERS_PER_NEWTON = 185, + UNITS_WATTS_PER_METER_PER_DEGREE_KELVIN = 189, + UNITS_WATTS_PER_SQUARE_METER_DEGREE_KELVIN = 141 + /* Enumerated values 0-255 are reserved for definition by ASHRAE. + Enumerated values 256-65535 may be used by others subject to + the procedures and constraints described in Clause 23. + The last enumeration used in this version is 189. */ } BACNET_ENGINEERING_UNITS; -typedef enum -{ - POLARITY_NORMAL = 0, - POLARITY_REVERSE = 1 +typedef enum { + POLARITY_NORMAL = 0, + POLARITY_REVERSE = 1 } BACNET_POLARITY; -typedef enum -{ - PROGRAM_REQUEST_READY = 0, - PROGRAM_REQUEST_LOAD = 1, - PROGRAM_REQUEST_RUN = 2, - PROGRAM_REQUEST_HALT = 3, - PROGRAM_REQUEST_RESTART = 4, - PROGRAM_REQUEST_UNLOAD = 5 +typedef enum { + PROGRAM_REQUEST_READY = 0, + PROGRAM_REQUEST_LOAD = 1, + PROGRAM_REQUEST_RUN = 2, + PROGRAM_REQUEST_HALT = 3, + PROGRAM_REQUEST_RESTART = 4, + PROGRAM_REQUEST_UNLOAD = 5 } BACNET_PROGRAM_REQUEST; -typedef enum -{ - PROGRAM_STATE_IDLE = 0, - PROGRAM_STATE_LOADING = 1, - PROGRAM_STATE_RUNNING = 2, - PROGRAM_STATE_WAITING = 3, - PROGRAM_STATE_HALTED = 4, - PROGRAM_STATE_UNLOADING = 5 +typedef enum { + PROGRAM_STATE_IDLE = 0, + PROGRAM_STATE_LOADING = 1, + PROGRAM_STATE_RUNNING = 2, + PROGRAM_STATE_WAITING = 3, + PROGRAM_STATE_HALTED = 4, + PROGRAM_STATE_UNLOADING = 5 } BACNET_PROGRAM_STATE; -typedef enum -{ - PROGRAM_ERROR_NORMAL = 0, - PROGRAM_ERROR_LOAD_FAILED = 1, - PROGRAM_ERROR_INTERNAL = 2, - PROGRAM_ERROR_PROGRAM = 3, - PROGRAM_ERROR_OTHER = 4 - // Enumerated values 0-63 are reserved for definition by ASHRAE. - // Enumerated values 64-65535 may be used by others subject to - // the procedures and constraints described in Clause 23. +typedef enum { + PROGRAM_ERROR_NORMAL = 0, + PROGRAM_ERROR_LOAD_FAILED = 1, + PROGRAM_ERROR_INTERNAL = 2, + PROGRAM_ERROR_PROGRAM = 3, + PROGRAM_ERROR_OTHER = 4 + // Enumerated values 0-63 are reserved for definition by ASHRAE. + // Enumerated values 64-65535 may be used by others subject to + // the procedures and constraints described in Clause 23. } BACNET_PROGRAM_ERROR; -typedef enum -{ - RELIABILITY_NO_FAULT_DETECTED = 0, - RELIABILITY_NO_SENSOR = 1, - RELIABILITY_OVER_RANGE = 2, - RELIABILITY_UNDER_RANGE = 3, - RELIABILITY_OPEN_LOOP = 4, - RELIABILITY_SHORTED_LOOP = 5, - RELIABILITY_NO_OUTPUT = 6, - RELIABILITY_UNRELIABLE_OTHER = 7, - RELIABILITY_PROCESS_ERROR = 8, - RELIABILITY_MULTI_STATE_FAULT = 9, - RELIABILITY_CONFIGURATION_ERROR = 10 - // Enumerated values 0-63 are reserved for definition by ASHRAE. - // Enumerated values 64-65535 may be used by others subject to - // the procedures and constraints described in Clause 23. +typedef enum { + RELIABILITY_NO_FAULT_DETECTED = 0, + RELIABILITY_NO_SENSOR = 1, + RELIABILITY_OVER_RANGE = 2, + RELIABILITY_UNDER_RANGE = 3, + RELIABILITY_OPEN_LOOP = 4, + RELIABILITY_SHORTED_LOOP = 5, + RELIABILITY_NO_OUTPUT = 6, + RELIABILITY_UNRELIABLE_OTHER = 7, + RELIABILITY_PROCESS_ERROR = 8, + RELIABILITY_MULTI_STATE_FAULT = 9, + RELIABILITY_CONFIGURATION_ERROR = 10 + // Enumerated values 0-63 are reserved for definition by ASHRAE. + // Enumerated values 64-65535 may be used by others subject to + // the procedures and constraints described in Clause 23. } BACNET_RELIABILITY; -typedef enum -{ - EVENT_CHANGE_OF_BITSTRING = 0, - EVENT_CHANGE_OF_STATE = 1, - EVENT_CHANGE_OF_VALUE = 2, - EVENT_COMMAND_FAILURE = 3, - EVENT_FLOATING_LIMIT = 4, - EVENT_OUT_OF_RANGE = 5, - /* complex-event-type (6), -- see comment below */ - /* event-buffer-ready (7), -- context tag 7 is deprecated */ - EVENT_CHANGE_OF_LIFE_SAFETY = 8, - EVENT_EXTENDED = 9, - EVENT_BUFFER_READY = 10, - EVENT_UNSIGNED_RANGE = 11, - // Enumerated values 0-63 are reserved for definition by ASHRAE. - // Enumerated values 64-65535 may be used by others subject to - // the procedures and constraints described in Clause 23. - // It is expected that these enumerated values will correspond to - // the use of the complex-event-type CHOICE [6] of the - // BACnetNotificationParameters production. - // The last enumeration used in this version is 11. +typedef enum { + EVENT_CHANGE_OF_BITSTRING = 0, + EVENT_CHANGE_OF_STATE = 1, + EVENT_CHANGE_OF_VALUE = 2, + EVENT_COMMAND_FAILURE = 3, + EVENT_FLOATING_LIMIT = 4, + EVENT_OUT_OF_RANGE = 5, + /* complex-event-type (6), -- see comment below */ + /* event-buffer-ready (7), -- context tag 7 is deprecated */ + EVENT_CHANGE_OF_LIFE_SAFETY = 8, + EVENT_EXTENDED = 9, + EVENT_BUFFER_READY = 10, + EVENT_UNSIGNED_RANGE = 11, + // Enumerated values 0-63 are reserved for definition by ASHRAE. + // Enumerated values 64-65535 may be used by others subject to + // the procedures and constraints described in Clause 23. + // It is expected that these enumerated values will correspond to + // the use of the complex-event-type CHOICE [6] of the + // BACnetNotificationParameters production. + // The last enumeration used in this version is 11. } BACNET_EVENT_TYPE; - -typedef enum -{ - FILE_RECORD_ACCESS = 0, - FILE_STREAM_ACCESS = 1, - FILE_RECORD_AND_STREAM_ACCESS = 2 + +typedef enum { + FILE_RECORD_ACCESS = 0, + FILE_STREAM_ACCESS = 1, + FILE_RECORD_AND_STREAM_ACCESS = 2 } BACNET_FILE_ACCESS_METHOD; -typedef enum -{ - LIFE_SAFETY_MODE_OFF = 0, - LIFE_SAFETY_MODE_ON = 1, - LIFE_SAFETY_MODE_TEST = 2, - LIFE_SAFETY_MODE_MANNED = 3, - LIFE_SAFETY_MODE_UNMANNED = 4, - LIFE_SAFETY_MODE_ARMED = 5, - LIFE_SAFETY_MODE_DISARMED = 6, - LIFE_SAFETY_MODE_PREARMED = 7, - LIFE_SAFETY_MODE_SLOW = 8, - LIFE_SAFETY_MODE_FAST = 9, - LIFE_SAFETY_MODE_DISCONNECTED = 10, - LIFE_SAFETY_MODE_ENABLED = 11, - LIFE_SAFETY_MODE_DISABLED = 12, - LIFE_SAFETY_MODE_AUTOMATIC_RELEASE_DISABLED = 13, - LIFE_SAFETY_MODE_DEFAULT = 14 - // Enumerated values 0-255 are reserved for definition by ASHRAE. - // Enumerated values 256-65535 may be used by others subject to - // procedures and constraints described in Clause 23. +typedef enum { + LIFE_SAFETY_MODE_OFF = 0, + LIFE_SAFETY_MODE_ON = 1, + LIFE_SAFETY_MODE_TEST = 2, + LIFE_SAFETY_MODE_MANNED = 3, + LIFE_SAFETY_MODE_UNMANNED = 4, + LIFE_SAFETY_MODE_ARMED = 5, + LIFE_SAFETY_MODE_DISARMED = 6, + LIFE_SAFETY_MODE_PREARMED = 7, + LIFE_SAFETY_MODE_SLOW = 8, + LIFE_SAFETY_MODE_FAST = 9, + LIFE_SAFETY_MODE_DISCONNECTED = 10, + LIFE_SAFETY_MODE_ENABLED = 11, + LIFE_SAFETY_MODE_DISABLED = 12, + LIFE_SAFETY_MODE_AUTOMATIC_RELEASE_DISABLED = 13, + LIFE_SAFETY_MODE_DEFAULT = 14 + // Enumerated values 0-255 are reserved for definition by ASHRAE. + // Enumerated values 256-65535 may be used by others subject to + // procedures and constraints described in Clause 23. } BACNET_LIFE_SAFETY_MODE; -typedef enum -{ - LIFE_SAFETY_OPERATION_NONE = 0, - LIFE_SAFETY_OPERATION_SILENCE = 1, - LIFE_SAFETY_OPERATION_SILENCE_AUDIBLE = 2, - LIFE_SAFETY_OPERATION_SILENCE_VISUAL = 3, - LIFE_SAFETY_OPERATION_RESET = 4, - LIFE_SAFETY_OPERATION_RESET_ALARM = 5, - LIFE_SAFETY_OPERATION_RESET_FAULT = 6, - LIFE_SAFETY_OPERATION_UNSILENCE = 7, - LIFE_SAFETY_OPERATION_UNSILENCE_AUDIBLE = 8, - LIFE_SAFETY_OPERATION_UNSILENCE_VISUAL = 9 - // Enumerated values 0-63 are reserved for definition by ASHRAE. - // Enumerated values 64-65535 may be used by others subject to - // procedures and constraints described in Clause 23. +typedef enum { + LIFE_SAFETY_OPERATION_NONE = 0, + LIFE_SAFETY_OPERATION_SILENCE = 1, + LIFE_SAFETY_OPERATION_SILENCE_AUDIBLE = 2, + LIFE_SAFETY_OPERATION_SILENCE_VISUAL = 3, + LIFE_SAFETY_OPERATION_RESET = 4, + LIFE_SAFETY_OPERATION_RESET_ALARM = 5, + LIFE_SAFETY_OPERATION_RESET_FAULT = 6, + LIFE_SAFETY_OPERATION_UNSILENCE = 7, + LIFE_SAFETY_OPERATION_UNSILENCE_AUDIBLE = 8, + LIFE_SAFETY_OPERATION_UNSILENCE_VISUAL = 9 + // Enumerated values 0-63 are reserved for definition by ASHRAE. + // Enumerated values 64-65535 may be used by others subject to + // procedures and constraints described in Clause 23. } BACNET_LIFE_SAFETY_OPERATION; -typedef enum -{ - LIFE_SAFETY_STATE_QUIET = 0, - LIFE_SAFETY_STATE_PRE_ALARM = 1, - LIFE_SAFETY_STATE_ALARM = 2, - LIFE_SAFETY_STATE_FAULT = 3, - LIFE_SAFETY_STATE_FAULT_PRE_ALARM = 4, - LIFE_SAFETY_STATE_FAULT_ALARM = 5, - LIFE_SAFETY_STATE_NOT_READY = 6, - LIFE_SAFETY_STATE_ACTIVE = 7, - LIFE_SAFETY_STATE_TAMPER = 8, - LIFE_SAFETY_STATE_TEST_ALARM = 9, - LIFE_SAFETY_STATE_TEST_ACTIVE = 10, - LIFE_SAFETY_STATE_TEST_FAULT = 11, - LIFE_SAFETY_STATE_TEST_FAULT_ALARM = 12, - LIFE_SAFETY_STATE_HOLDUP = 13, - LIFE_SAFETY_STATE_DURESS = 14, - LIFE_SAFETY_STATE_TAMPER_ALARM = 15, - LIFE_SAFETY_STATE_ABNORMAL = 16, - LIFE_SAFETY_STATE_EMERGENCY_POWER = 17, - LIFE_SAFETY_STATE_DELAYED = 18, - LIFE_SAFETY_STATE_BLOCKED = 19, - LIFE_SAFETY_STATE_LOCAL_ALARM = 20, - LIFE_SAFETY_STATE_GENERAL_ALARM = 21, - LIFE_SAFETY_STATE_SUPERVISORY = 22, - LIFE_SAFETY_STATE_TEST_SUPERVISORY = 23 - // Enumerated values 0-255 are reserved for definition by ASHRAE. - // Enumerated values 256-65535 may be used by others subject to - // procedures and constraints described in Clause 23. +typedef enum { + LIFE_SAFETY_STATE_QUIET = 0, + LIFE_SAFETY_STATE_PRE_ALARM = 1, + LIFE_SAFETY_STATE_ALARM = 2, + LIFE_SAFETY_STATE_FAULT = 3, + LIFE_SAFETY_STATE_FAULT_PRE_ALARM = 4, + LIFE_SAFETY_STATE_FAULT_ALARM = 5, + LIFE_SAFETY_STATE_NOT_READY = 6, + LIFE_SAFETY_STATE_ACTIVE = 7, + LIFE_SAFETY_STATE_TAMPER = 8, + LIFE_SAFETY_STATE_TEST_ALARM = 9, + LIFE_SAFETY_STATE_TEST_ACTIVE = 10, + LIFE_SAFETY_STATE_TEST_FAULT = 11, + LIFE_SAFETY_STATE_TEST_FAULT_ALARM = 12, + LIFE_SAFETY_STATE_HOLDUP = 13, + LIFE_SAFETY_STATE_DURESS = 14, + LIFE_SAFETY_STATE_TAMPER_ALARM = 15, + LIFE_SAFETY_STATE_ABNORMAL = 16, + LIFE_SAFETY_STATE_EMERGENCY_POWER = 17, + LIFE_SAFETY_STATE_DELAYED = 18, + LIFE_SAFETY_STATE_BLOCKED = 19, + LIFE_SAFETY_STATE_LOCAL_ALARM = 20, + LIFE_SAFETY_STATE_GENERAL_ALARM = 21, + LIFE_SAFETY_STATE_SUPERVISORY = 22, + LIFE_SAFETY_STATE_TEST_SUPERVISORY = 23 + // Enumerated values 0-255 are reserved for definition by ASHRAE. + // Enumerated values 256-65535 may be used by others subject to + // procedures and constraints described in Clause 23. } BACNET_LIFE_SAFETY_STATE; -typedef enum -{ - MAINTENANCE_NONE = 0, - MAINTENANCE_PERIODIC_TEST = 1, - AINTENANCE_NEED_SERVICE_OPERATIONAL = 2, - MAINTENANCE_NEED_SERVICE_INOPERATIVE = 3 - // Enumerated values 0-255 are reserved for definition by ASHRAE. - // Enumerated values 256-65535 may be used by others subject to - // procedures and constraints described in Clause 23. +typedef enum { + MAINTENANCE_NONE = 0, + MAINTENANCE_PERIODIC_TEST = 1, + AINTENANCE_NEED_SERVICE_OPERATIONAL = 2, + MAINTENANCE_NEED_SERVICE_INOPERATIVE = 3 + // Enumerated values 0-255 are reserved for definition by ASHRAE. + // Enumerated values 256-65535 may be used by others subject to + // procedures and constraints described in Clause 23. } BACNET_MAINTENANCE; -typedef enum -{ - NOTIFY_ALARM = 0, - NOTIFY_EVENT = 1, - NOTIFY_ACK_NOTIFICATION = 2 +typedef enum { + NOTIFY_ALARM = 0, + NOTIFY_EVENT = 1, + NOTIFY_ACK_NOTIFICATION = 2 } BACNET_NOTIFY_TYPE; -typedef enum -{ - OBJECT_ANALOG_INPUT = 0, - OBJECT_ANALOG_OUTPUT = 1, - OBJECT_ANALOG_VALUE = 2, - OBJECT_BINARY_INPUT = 3, - OBJECT_BINARY_OUTPUT = 4, - OBJECT_BINARY_VALUE = 5, - OBJECT_CALENDAR = 6, - OBJECT_COMMAND = 7, - OBJECT_DEVICE = 8, - OBJECT_EVENT_ENROLLMENT = 9, - OBJECT_FILE = 10, - OBJECT_GROUP = 11, - OBJECT_LOOP = 12, - OBJECT_MULTI_STATE_INPUT = 13, - OBJECT_MULTI_STATE_OUTPUT = 14, - OBJECT_NOTIFICATION_CLASS = 15, - OBJECT_PROGRAM = 16, - OBJECT_SCHEDULE = 17, - OBJECT_AVERAGING = 18, - OBJECT_MULTI_STATE_VALUE = 19, - OBJECT_TRENDLOG = 20, - OBJECT_LIFE_SAFETY_POINT = 21, - OBJECT_LIFE_SAFETY_ZONE = 22, - OBJECT_ACCUMULATOR = 23, - OBJECT_PULSE_CONVERTER = 24, - // Enumerated values 0-127 are reserved for definition by ASHRAE. - // Enumerated values 128-1023 may be used by others subject to - // the procedures and constraints described in Clause 23. - MAX_ASHRAE_OBJECT_TYPE = 25, // used for bit string loop - MAX_BACNET_OBJECT_TYPE = 1023 +typedef enum { + OBJECT_ANALOG_INPUT = 0, + OBJECT_ANALOG_OUTPUT = 1, + OBJECT_ANALOG_VALUE = 2, + OBJECT_BINARY_INPUT = 3, + OBJECT_BINARY_OUTPUT = 4, + OBJECT_BINARY_VALUE = 5, + OBJECT_CALENDAR = 6, + OBJECT_COMMAND = 7, + OBJECT_DEVICE = 8, + OBJECT_EVENT_ENROLLMENT = 9, + OBJECT_FILE = 10, + OBJECT_GROUP = 11, + OBJECT_LOOP = 12, + OBJECT_MULTI_STATE_INPUT = 13, + OBJECT_MULTI_STATE_OUTPUT = 14, + OBJECT_NOTIFICATION_CLASS = 15, + OBJECT_PROGRAM = 16, + OBJECT_SCHEDULE = 17, + OBJECT_AVERAGING = 18, + OBJECT_MULTI_STATE_VALUE = 19, + OBJECT_TRENDLOG = 20, + OBJECT_LIFE_SAFETY_POINT = 21, + OBJECT_LIFE_SAFETY_ZONE = 22, + OBJECT_ACCUMULATOR = 23, + OBJECT_PULSE_CONVERTER = 24, + // Enumerated values 0-127 are reserved for definition by ASHRAE. + // Enumerated values 128-1023 may be used by others subject to + // the procedures and constraints described in Clause 23. + MAX_ASHRAE_OBJECT_TYPE = 25, // used for bit string loop + MAX_BACNET_OBJECT_TYPE = 1023 } BACNET_OBJECT_TYPE; -typedef enum -{ - SEGMENTATION_BOTH = 0, - SEGMENTATION_TRANSMIT = 1, - SEGMENTATION_RECEIVE = 2, - SEGMENTATION_NONE = 3, - MAX_BACNET_SEGMENTATION = 4 +typedef enum { + SEGMENTATION_BOTH = 0, + SEGMENTATION_TRANSMIT = 1, + SEGMENTATION_RECEIVE = 2, + SEGMENTATION_NONE = 3, + MAX_BACNET_SEGMENTATION = 4 } BACNET_SEGMENTATION; -typedef enum -{ - VT_CLASS_DEFAULT = 0, - VT_CLASS_ANSI_X34 = 1, /* real name is ANSI X3.64*/ - VT_CLASS_DEC_VT52 = 2, - VT_CLASS_DEC_VT100 = 3, - VT_CLASS_DEC_VT220 = 4, - VT_CLASS_HP_700_94 = 5, /* real name is HP 700/94 */ - VT_CLASS_IBM_3130 = 6 - // Enumerated values 0-63 are reserved for definition by ASHRAE. - // Enumerated values 64-65535 may be used by others subject to - // the procedures and constraints described in Clause 23. +typedef enum { + VT_CLASS_DEFAULT = 0, + VT_CLASS_ANSI_X34 = 1, /* real name is ANSI X3.64 */ + VT_CLASS_DEC_VT52 = 2, + VT_CLASS_DEC_VT100 = 3, + VT_CLASS_DEC_VT220 = 4, + VT_CLASS_HP_700_94 = 5, /* real name is HP 700/94 */ + VT_CLASS_IBM_3130 = 6 + // Enumerated values 0-63 are reserved for definition by ASHRAE. + // Enumerated values 64-65535 may be used by others subject to + // the procedures and constraints described in Clause 23. } BACNET_VT_CLASS; -typedef enum -{ - CHARACTER_ANSI_X34 = 0, - CHARACTER_MS_DBCS = 1, - CHARACTER_JISC_6226 = 2, - CHARACTER_UCS4 = 3, - CHARACTER_UCS2 = 4, - CHARACTER_ISO8859 = 5 +typedef enum { + CHARACTER_ANSI_X34 = 0, + CHARACTER_MS_DBCS = 1, + CHARACTER_JISC_6226 = 2, + CHARACTER_UCS4 = 3, + CHARACTER_UCS2 = 4, + CHARACTER_ISO8859 = 5 } BACNET_CHARACTER_STRING_ENCODING; typedef enum { @@ -772,175 +749,173 @@ typedef enum { PDU_TYPE_ABORT = 0x70 } BACNET_PDU_TYPE; -typedef enum -{ - // Alarm and Event Services - SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM = 0, - SERVICE_CONFIRMED_COV_NOTIFICATION = 1, - SERVICE_CONFIRMED_EVENT_NOTIFICATION = 2, - SERVICE_CONFIRMED_GET_ALARM_SUMMARY = 3, - SERVICE_CONFIRMED_GET_ENROLLMENT_SUMMARY = 4, - SERVICE_CONFIRMED_GET_EVENT_INFORMATION = 29, - SERVICE_CONFIRMED_SUBSCRIBE_COV = 5, - SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY = 28, - SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION = 27, - // File Access Services - SERVICE_CONFIRMED_ATOMIC_READ_FILE = 6, - SERVICE_CONFIRMED_ATOMIC_WRITE_FILE = 7, - // Object Access Services - SERVICE_CONFIRMED_ADD_LIST_ELEMENT = 8, - SERVICE_CONFIRMED_REMOVE_LIST_ELEMENT = 9, - SERVICE_CONFIRMED_CREATE_OBJECT = 10, - SERVICE_CONFIRMED_DELETE_OBJECT = 11, - SERVICE_CONFIRMED_READ_PROPERTY = 12, - SERVICE_CONFIRMED_READ_PROPERTY_CONDITIONAL = 13, - SERVICE_CONFIRMED_READ_PROPERTY_MULTIPLE = 14, - SERVICE_CONFIRMED_READ_RANGE = 26, - SERVICE_CONFIRMED_WRITE_PROPERTY = 15, - SERVICE_CONFIRMED_WRITE_PROPERTY_MULTIPLE = 16, - // Remote Device Management Services - SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL = 17, - SERVICE_CONFIRMED_PRIVATE_TRANSFER = 18, - SERVICE_CONFIRMED_TEXT_MESSAGE = 19, - SERVICE_CONFIRMED_REINITIALIZE_DEVICE = 20, - // Virtual Terminal Services - SERVICE_CONFIRMED_VT_OPEN = 21, - SERVICE_CONFIRMED_VT_CLOSE = 22, - SERVICE_CONFIRMED_VT_DATA = 23, - // Security Services - SERVICE_CONFIRMED_AUTHENTICATE = 24, - SERVICE_CONFIRMED_REQUEST_KEY = 25, - // Services added after 1995 - // readRange (26) see Object Access Services - // lifeSafetyOperation (27) see Alarm and Event Services - // subscribeCOVProperty (28) see Alarm and Event Services - // getEventInformation (29) see Alarm and Event Services - MAX_BACNET_CONFIRMED_SERVICE = 30 +typedef enum { + // Alarm and Event Services + SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM = 0, + SERVICE_CONFIRMED_COV_NOTIFICATION = 1, + SERVICE_CONFIRMED_EVENT_NOTIFICATION = 2, + SERVICE_CONFIRMED_GET_ALARM_SUMMARY = 3, + SERVICE_CONFIRMED_GET_ENROLLMENT_SUMMARY = 4, + SERVICE_CONFIRMED_GET_EVENT_INFORMATION = 29, + SERVICE_CONFIRMED_SUBSCRIBE_COV = 5, + SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY = 28, + SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION = 27, + // File Access Services + SERVICE_CONFIRMED_ATOMIC_READ_FILE = 6, + SERVICE_CONFIRMED_ATOMIC_WRITE_FILE = 7, + // Object Access Services + SERVICE_CONFIRMED_ADD_LIST_ELEMENT = 8, + SERVICE_CONFIRMED_REMOVE_LIST_ELEMENT = 9, + SERVICE_CONFIRMED_CREATE_OBJECT = 10, + SERVICE_CONFIRMED_DELETE_OBJECT = 11, + SERVICE_CONFIRMED_READ_PROPERTY = 12, + SERVICE_CONFIRMED_READ_PROPERTY_CONDITIONAL = 13, + SERVICE_CONFIRMED_READ_PROPERTY_MULTIPLE = 14, + SERVICE_CONFIRMED_READ_RANGE = 26, + SERVICE_CONFIRMED_WRITE_PROPERTY = 15, + SERVICE_CONFIRMED_WRITE_PROPERTY_MULTIPLE = 16, + // Remote Device Management Services + SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL = 17, + SERVICE_CONFIRMED_PRIVATE_TRANSFER = 18, + SERVICE_CONFIRMED_TEXT_MESSAGE = 19, + SERVICE_CONFIRMED_REINITIALIZE_DEVICE = 20, + // Virtual Terminal Services + SERVICE_CONFIRMED_VT_OPEN = 21, + SERVICE_CONFIRMED_VT_CLOSE = 22, + SERVICE_CONFIRMED_VT_DATA = 23, + // Security Services + SERVICE_CONFIRMED_AUTHENTICATE = 24, + SERVICE_CONFIRMED_REQUEST_KEY = 25, + // Services added after 1995 + // readRange (26) see Object Access Services + // lifeSafetyOperation (27) see Alarm and Event Services + // subscribeCOVProperty (28) see Alarm and Event Services + // getEventInformation (29) see Alarm and Event Services + MAX_BACNET_CONFIRMED_SERVICE = 30 } BACNET_CONFIRMED_SERVICE; typedef enum { - SERVICE_UNCONFIRMED_I_AM = 0, - SERVICE_UNCONFIRMED_I_HAVE = 1, - SERVICE_UNCONFIRMED_COV_NOTIFICATION = 2, - SERVICE_UNCONFIRMED_EVENT_NOTIFICATION = 3, - SERVICE_UNCONFIRMED_PRIVATE_TRANSFER = 4, - SERVICE_UNCONFIRMED_TEXT_MESSAGE = 5, - SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION = 6, - SERVICE_UNCONFIRMED_WHO_HAS = 7, - SERVICE_UNCONFIRMED_WHO_IS = 8, - SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION = 9, - // Other services to be added as they are defined. - // All choice values in this production are reserved - // for definition by ASHRAE. - // Proprietary extensions are made by using the - // UnconfirmedPrivateTransfer service. See Clause 23. - MAX_BACNET_UNCONFIRMED_SERVICE = 10 + SERVICE_UNCONFIRMED_I_AM = 0, + SERVICE_UNCONFIRMED_I_HAVE = 1, + SERVICE_UNCONFIRMED_COV_NOTIFICATION = 2, + SERVICE_UNCONFIRMED_EVENT_NOTIFICATION = 3, + SERVICE_UNCONFIRMED_PRIVATE_TRANSFER = 4, + SERVICE_UNCONFIRMED_TEXT_MESSAGE = 5, + SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION = 6, + SERVICE_UNCONFIRMED_WHO_HAS = 7, + SERVICE_UNCONFIRMED_WHO_IS = 8, + SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION = 9, + // Other services to be added as they are defined. + // All choice values in this production are reserved + // for definition by ASHRAE. + // Proprietary extensions are made by using the + // UnconfirmedPrivateTransfer service. See Clause 23. + MAX_BACNET_UNCONFIRMED_SERVICE = 10 } BACNET_UNCONFIRMED_SERVICE; // Bit String Enumerations -typedef enum -{ - // Alarm and Event Services - SERVICE_SUPPORTED_ACKNOWLEDGE_ALARM = 0, - SERVICE_SUPPORTED_CONFIRMED_COV_NOTIFICATION = 1, - SERVICE_SUPPORTED_CONFIRMED_EVENT_NOTIFICATION = 2, - SERVICE_SUPPORTED_GET_ALARM_SUMMARY = 3, - SERVICE_SUPPORTED_GET_ENROLLMENT_SUMMARY = 4, - SERVICE_SUPPORTED_GET_EVENT_INFORMATION = 39, - SERVICE_SUPPORTED_SUBSCRIBE_COV = 5, - SERVICE_SUPPORTED_SUBSCRIBE_COV_PROPERTY = 38, - SERVICE_SUPPORTED_LIFE_SAFETY_OPERATION = 37, - // File Access Services - SERVICE_SUPPORTED_ATOMIC_READ_FILE = 6, - SERVICE_SUPPORTED_ATOMIC_WRITE_FILE = 7, - // Object Access Services - SERVICE_SUPPORTED_ADD_LIST_ELEMENT = 8, - SERVICE_SUPPORTED_REMOVE_LIST_ELEMENT = 9, - SERVICE_SUPPORTED_CREATE_OBJECT = 10, - SERVICE_SUPPORTED_DELETE_OBJECT = 11, - SERVICE_SUPPORTED_READ_PROPERTY = 12, - SERVICE_SUPPORTED_READ_PROPERTY_CONDITIONAL = 13, - SERVICE_SUPPORTED_READ_PROPERTY_MULTIPLE = 14, - SERVICE_SUPPORTED_READ_RANGE = 35, - SERVICE_SUPPORTED_WRITE_PROPERTY = 15, - SERVICE_SUPPORTED_WRITE_PROPERTY_MULTIPLE = 16, - // Remote Device Management Services - SERVICE_SUPPORTED_DEVICE_COMMUNICATION_CONTROL = 17, - SERVICE_SUPPORTED_PRIVATE_TRANSFER = 18, - SERVICE_SUPPORTED_TEXT_MESSAGE = 19, - SERVICE_SUPPORTED_REINITIALIZE_DEVICE = 20, - // Virtual Terminal Services - SERVICE_SUPPORTED_VT_OPEN = 21, - SERVICE_SUPPORTED_VT_CLOSE = 22, - SERVICE_SUPPORTED_VT_DATA = 23, - // Security Services - SERVICE_SUPPORTED_AUTHENTICATE = 24, - SERVICE_SUPPORTED_REQUEST_KEY = 25, - SERVICE_SUPPORTED_I_AM = 26, - SERVICE_SUPPORTED_I_HAVE = 27, - SERVICE_SUPPORTED_UNCONFIRMED_COV_NOTIFICATION = 28, - SERVICE_SUPPORTED_UNCONFIRMED_EVENT_NOTIFICATION = 29, - SERVICE_SUPPORTED_UNCONFIRMED_PRIVATE_TRANSFER = 30, - SERVICE_SUPPORTED_UNCONFIRMED_TEXT_MESSAGE = 31, - SERVICE_SUPPORTED_TIME_SYNCHRONIZATION = 32, - SERVICE_SUPPORTED_UTC_TIME_SYNCHRONIZATION = 36, - SERVICE_SUPPORTED_WHO_HAS = 33, - SERVICE_SUPPORTED_WHO_IS = 34, - // Other services to be added as they are defined. - // All values in this production are reserved - // for definition by ASHRAE. - MAX_BACNET_SERVICES_SUPPORTED = 40 +typedef enum { + // Alarm and Event Services + SERVICE_SUPPORTED_ACKNOWLEDGE_ALARM = 0, + SERVICE_SUPPORTED_CONFIRMED_COV_NOTIFICATION = 1, + SERVICE_SUPPORTED_CONFIRMED_EVENT_NOTIFICATION = 2, + SERVICE_SUPPORTED_GET_ALARM_SUMMARY = 3, + SERVICE_SUPPORTED_GET_ENROLLMENT_SUMMARY = 4, + SERVICE_SUPPORTED_GET_EVENT_INFORMATION = 39, + SERVICE_SUPPORTED_SUBSCRIBE_COV = 5, + SERVICE_SUPPORTED_SUBSCRIBE_COV_PROPERTY = 38, + SERVICE_SUPPORTED_LIFE_SAFETY_OPERATION = 37, + // File Access Services + SERVICE_SUPPORTED_ATOMIC_READ_FILE = 6, + SERVICE_SUPPORTED_ATOMIC_WRITE_FILE = 7, + // Object Access Services + SERVICE_SUPPORTED_ADD_LIST_ELEMENT = 8, + SERVICE_SUPPORTED_REMOVE_LIST_ELEMENT = 9, + SERVICE_SUPPORTED_CREATE_OBJECT = 10, + SERVICE_SUPPORTED_DELETE_OBJECT = 11, + SERVICE_SUPPORTED_READ_PROPERTY = 12, + SERVICE_SUPPORTED_READ_PROPERTY_CONDITIONAL = 13, + SERVICE_SUPPORTED_READ_PROPERTY_MULTIPLE = 14, + SERVICE_SUPPORTED_READ_RANGE = 35, + SERVICE_SUPPORTED_WRITE_PROPERTY = 15, + SERVICE_SUPPORTED_WRITE_PROPERTY_MULTIPLE = 16, + // Remote Device Management Services + SERVICE_SUPPORTED_DEVICE_COMMUNICATION_CONTROL = 17, + SERVICE_SUPPORTED_PRIVATE_TRANSFER = 18, + SERVICE_SUPPORTED_TEXT_MESSAGE = 19, + SERVICE_SUPPORTED_REINITIALIZE_DEVICE = 20, + // Virtual Terminal Services + SERVICE_SUPPORTED_VT_OPEN = 21, + SERVICE_SUPPORTED_VT_CLOSE = 22, + SERVICE_SUPPORTED_VT_DATA = 23, + // Security Services + SERVICE_SUPPORTED_AUTHENTICATE = 24, + SERVICE_SUPPORTED_REQUEST_KEY = 25, + SERVICE_SUPPORTED_I_AM = 26, + SERVICE_SUPPORTED_I_HAVE = 27, + SERVICE_SUPPORTED_UNCONFIRMED_COV_NOTIFICATION = 28, + SERVICE_SUPPORTED_UNCONFIRMED_EVENT_NOTIFICATION = 29, + SERVICE_SUPPORTED_UNCONFIRMED_PRIVATE_TRANSFER = 30, + SERVICE_SUPPORTED_UNCONFIRMED_TEXT_MESSAGE = 31, + SERVICE_SUPPORTED_TIME_SYNCHRONIZATION = 32, + SERVICE_SUPPORTED_UTC_TIME_SYNCHRONIZATION = 36, + SERVICE_SUPPORTED_WHO_HAS = 33, + SERVICE_SUPPORTED_WHO_IS = 34, + // Other services to be added as they are defined. + // All values in this production are reserved + // for definition by ASHRAE. + MAX_BACNET_SERVICES_SUPPORTED = 40 } BACNET_SERVICES_SUPPORTED; // Bit String Enumerations typedef enum { - STATUS_FLAG_IN_ALARM = 0, - STATUS_FLAG_FAULT = 1, - STATUS_FLAG_OVERRIDDEN = 2, - STATUS_FLAG_OUT_OF_SERVICE = 3 + STATUS_FLAG_IN_ALARM = 0, + STATUS_FLAG_FAULT = 1, + STATUS_FLAG_OVERRIDDEN = 2, + STATUS_FLAG_OUT_OF_SERVICE = 3 } BACNET_STATUS_FLAGS; typedef enum { - ACKNOWLEDGMENT_FILTER_ALL = 0, - ACKNOWLEDGMENT_FILTER_ACKED = 1, - ACKNOWLEDGMENT_FILTER_NOT_ACKED = 2 + ACKNOWLEDGMENT_FILTER_ALL = 0, + ACKNOWLEDGMENT_FILTER_ACKED = 1, + ACKNOWLEDGMENT_FILTER_NOT_ACKED = 2 } BACNET_ACKNOWLEDGMENT_FILTER; typedef enum { - EVENT_STATE_FILTER_OFFNORMAL = 0, - EVENT_STATE_FILTER_FAULT = 1, - EVENT_STATE_FILTER_NORMAL = 2, - EVENT_STATE_FILTER_ALL = 3, - EVENT_STATE_FILTER_ACTIVE = 4 + EVENT_STATE_FILTER_OFFNORMAL = 0, + EVENT_STATE_FILTER_FAULT = 1, + EVENT_STATE_FILTER_NORMAL = 2, + EVENT_STATE_FILTER_ALL = 3, + EVENT_STATE_FILTER_ACTIVE = 4 } BACNET_EVENT_STATE_FILTER; typedef enum { - SELECTION_LOGIC_AND = 0, - SELECTION_LOGIC_OR = 1, - SELECTION_LOGIC_ALL = 2 + SELECTION_LOGIC_AND = 0, + SELECTION_LOGIC_OR = 1, + SELECTION_LOGIC_ALL = 2 } BACNET_SELECTION_LOGIC; typedef enum { - RELATION_SPECIFIER_EQUAL = 0, - RELATION_SPECIFIER_NOT_EQUAL = 1, - RELATION_SPECIFIER_LESS_THAN = 2, - RELATION_SPECIFIER_GREATER_THAN = 3, - RELATION_SPECIFIER_LESS_THAN_OR_EQUAL = 4, - RELATION_SPECIFIER_GREATER_THAN_OR_EQUAL = 5 + RELATION_SPECIFIER_EQUAL = 0, + RELATION_SPECIFIER_NOT_EQUAL = 1, + RELATION_SPECIFIER_LESS_THAN = 2, + RELATION_SPECIFIER_GREATER_THAN = 3, + RELATION_SPECIFIER_LESS_THAN_OR_EQUAL = 4, + RELATION_SPECIFIER_GREATER_THAN_OR_EQUAL = 5 } BACNET_RELATION_SPECIFIER; typedef enum { - COMMUNICATION_ENABLE = 0, - COMMUNICATION_DISABLE = 1, - COMMUNICATION_DISABLE_INITIATION = 2, - MAX_BACNET_COMMUNICATION_ENABLE_DISABLE = 3 + COMMUNICATION_ENABLE = 0, + COMMUNICATION_DISABLE = 1, + COMMUNICATION_DISABLE_INITIATION = 2, + MAX_BACNET_COMMUNICATION_ENABLE_DISABLE = 3 } BACNET_COMMUNICATION_ENABLE_DISABLE; typedef enum { - MESSAGE_PRIORITY_NORMAL = 0, - MESSAGE_PRIORITY_URGENT = 1, - MESSAGE_PRIORITY_CRITICAL_EQUIPMENT = 2, - MESSAGE_PRIORITY_LIFE_SAFETY = 3 + MESSAGE_PRIORITY_NORMAL = 0, + MESSAGE_PRIORITY_URGENT = 1, + MESSAGE_PRIORITY_CRITICAL_EQUIPMENT = 2, + MESSAGE_PRIORITY_LIFE_SAFETY = 3 } BACNET_MESSAGE_PRIORITY; //Network Layer Message Type @@ -948,43 +923,43 @@ typedef enum { // a message type octet shall be present as shown in Figure 6-1. // The following message types are indicated: typedef enum { - NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK = 0, - NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK = 1, - NETWORK_MESSAGE_I_COULD_BE_ROUTER_TO_NETWORK = 2, - NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK = 3, - NETWORK_MESSAGE_ROUTER_BUSY_TO_NETWORK = 4, - NETWORK_MESSAGE_ROUTER_AVAILABLE_TO_NETWORK = 5, - NETWORK_MESSAGE_INITIALIZE_ROUTING_TABLE = 6, - NETWORK_MESSAGE_INITIALIZE_ROUTING_TABLE_ACK = 7, - NETWORK_MESSAGE_ESTABLISH_CONNECTION_TO_NETWORK = 8, - NETWORK_MESSAGE_DISCONNECT_CONNECTION_TO_NETWORK = 9 - // X'0A' to X'7F': Reserved for use by ASHRAE, - // X'80' to X'FF': Available for vendor proprietary messages + NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK = 0, + NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK = 1, + NETWORK_MESSAGE_I_COULD_BE_ROUTER_TO_NETWORK = 2, + NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK = 3, + NETWORK_MESSAGE_ROUTER_BUSY_TO_NETWORK = 4, + NETWORK_MESSAGE_ROUTER_AVAILABLE_TO_NETWORK = 5, + NETWORK_MESSAGE_INITIALIZE_ROUTING_TABLE = 6, + NETWORK_MESSAGE_INITIALIZE_ROUTING_TABLE_ACK = 7, + NETWORK_MESSAGE_ESTABLISH_CONNECTION_TO_NETWORK = 8, + NETWORK_MESSAGE_DISCONNECT_CONNECTION_TO_NETWORK = 9 + // X'0A' to X'7F': Reserved for use by ASHRAE, + // X'80' to X'FF': Available for vendor proprietary messages } BACNET_NETWORK_MESSAGE_TYPE; typedef enum { - REINITIALIZED_STATE_COLD_START = 0, - REINITIALIZED_STATE_WARM_START = 1, - REINITIALIZED_STATE_START_BACKUP = 2, - REINITIALIZED_STATE_END_BACKUP = 3, - REINITIALIZED_STATE_START_RESTORE = 4, - REINITIALIZED_STATE_END_RESTORE = 5, - REINITIALIZED_STATE_ABORT_RESTORE = 6 + REINITIALIZED_STATE_COLD_START = 0, + REINITIALIZED_STATE_WARM_START = 1, + REINITIALIZED_STATE_START_BACKUP = 2, + REINITIALIZED_STATE_END_BACKUP = 3, + REINITIALIZED_STATE_START_RESTORE = 4, + REINITIALIZED_STATE_END_RESTORE = 5, + REINITIALIZED_STATE_ABORT_RESTORE = 6 } BACNET_REINITIALIZED_STATE_OF_DEVICE; typedef enum { - ABORT_REASON_OTHER = 0, - ABORT_REASON_BUFFER_OVERFLOW = 1, - ABORT_REASON_INVALID_APDU_IN_THIS_STATE = 2, - ABORT_REASON_PREEMPTED_BY_HIGHER_PRIORITY_TASK = 3, - ABORT_REASON_SEGMENTATION_NOT_SUPPORTED = 4, - // Enumerated values 0-63 are reserved for definition by ASHRAE. - // Enumerated values 64-65535 may be used by others subject to - // the procedures and constraints described in Clause 23. - MAX_BACNET_ABORT_REASON = 5, - FIRST_PROPRIETARY_ABORT_REASON = 64, - LAST_PROPRIETARY_ABORT_REASON = 65535 + ABORT_REASON_OTHER = 0, + ABORT_REASON_BUFFER_OVERFLOW = 1, + ABORT_REASON_INVALID_APDU_IN_THIS_STATE = 2, + ABORT_REASON_PREEMPTED_BY_HIGHER_PRIORITY_TASK = 3, + ABORT_REASON_SEGMENTATION_NOT_SUPPORTED = 4, + // Enumerated values 0-63 are reserved for definition by ASHRAE. + // Enumerated values 64-65535 may be used by others subject to + // the procedures and constraints described in Clause 23. + MAX_BACNET_ABORT_REASON = 5, + FIRST_PROPRIETARY_ABORT_REASON = 64, + LAST_PROPRIETARY_ABORT_REASON = 65535 } BACNET_ABORT_REASON; typedef enum { @@ -998,110 +973,108 @@ typedef enum { REJECT_REASON_TOO_MANY_ARGUMENTS = 7, REJECT_REASON_UNDEFINED_ENUMERATION = 8, REJECT_REASON_UNRECOGNIZED_SERVICE = 9, - // Enumerated values 0-63 are reserved for definition by ASHRAE. - // Enumerated values 64-65535 may be used by others subject to - // the procedures and constraints described in Clause 23. - MAX_BACNET_REJECT_REASON = 10, - FIRST_PROPRIETARY_REJECT_REASON = 64, - LAST_PROPRIETARY_REJECT_REASON = 65535 + // Enumerated values 0-63 are reserved for definition by ASHRAE. + // Enumerated values 64-65535 may be used by others subject to + // the procedures and constraints described in Clause 23. + MAX_BACNET_REJECT_REASON = 10, + FIRST_PROPRIETARY_REJECT_REASON = 64, + LAST_PROPRIETARY_REJECT_REASON = 65535 } BACNET_BACNET_REJECT_REASON; typedef enum { - ERROR_CLASS_DEVICE = 0, - ERROR_CLASS_OBJECT = 1, - ERROR_CLASS_PROPERTY = 2, - ERROR_CLASS_RESOURCES = 3, - ERROR_CLASS_SECURITY = 4, - ERROR_CLASS_SERVICES = 5, - ERROR_CLASS_VT = 6, - // Enumerated values 0-63 are reserved for definition by ASHRAE. - // Enumerated values 64-65535 may be used by others subject to - // the procedures and constraints described in Clause 23. - MAX_BACNET_ERROR_CLASS = 7, - FIRST_PROPRIETARY_ERROR_CLASS = 64, - LAST_PROPRIETARY_ERROR_CLASS = 65535 + ERROR_CLASS_DEVICE = 0, + ERROR_CLASS_OBJECT = 1, + ERROR_CLASS_PROPERTY = 2, + ERROR_CLASS_RESOURCES = 3, + ERROR_CLASS_SECURITY = 4, + ERROR_CLASS_SERVICES = 5, + ERROR_CLASS_VT = 6, + // Enumerated values 0-63 are reserved for definition by ASHRAE. + // Enumerated values 64-65535 may be used by others subject to + // the procedures and constraints described in Clause 23. + MAX_BACNET_ERROR_CLASS = 7, + FIRST_PROPRIETARY_ERROR_CLASS = 64, + LAST_PROPRIETARY_ERROR_CLASS = 65535 } BACNET_ERROR_CLASS; typedef enum { - ERROR_CODE_OTHER = 0, - ERROR_CODE_AUTHENTICATION_FAILED = 1, - ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED = 41, - ERROR_CODE_CONFIGURATION_IN_PROGRESS = 2, - ERROR_CODE_DATATYPE_NOT_SUPPORTED = 47, - ERROR_CODE_DEVICE_BUSY = 3, - ERROR_CODE_DUPLICATE_NAME = 48, - ERROR_CODE_DUPLICATE_OBJECT_ID = 49, - ERROR_CODE_DYNAMIC_CREATION_NOT_SUPPORTED = 4, - ERROR_CODE_FILE_ACCESS_DENIED = 5, - ERROR_CODE_INCOMPATIBLE_SECURITY_LEVELS = 6, - ERROR_CODE_INCONSISTENT_PARAMETERS = 7, - ERROR_CODE_INCONSISTENT_SELECTION_CRITERION = 8, - ERROR_CODE_INVALID_ARRAY_INDEX = 42, - ERROR_CODE_INVALID_CONFIGURATION_DATA = 46, - ERROR_CODE_INVALID_DATA_TYPE = 9, - ERROR_CODE_INVALID_FILE_ACCESS_METHOD = 10, - ERROR_CODE_ERROR_CODE_INVALID_FILE_START_POSITION = 11, - ERROR_CODE_INVALID_OPERATOR_NAME = 12, - ERROR_CODE_INVALID_PARAMETER_DATA_TYPE = 13, - ERROR_CODE_INVALID_TIME_STAMP = 14, - ERROR_CODE_KEY_GENERATION_ERROR = 15, - ERROR_CODE_MISSING_REQUIRED_PARAMETER = 16, - ERROR_CODE_NO_OBJECTS_OF_SPECIFIED_TYPE = 17, - ERROR_CODE_NO_SPACE_FOR_OBJECT = 18, - ERROR_CODE_NO_SPACE_TO_ADD_LIST_ELEMENT = 19, - ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY = 20, - ERROR_CODE_NO_VT_SESSIONS_AVAILABLE = 21, - ERROR_CODE_OBJECT_DELETION_NOT_PERMITTED = 23, - ERROR_CODE_OBJECT_IDENTIFIER_ALREADY_EXISTS = 24, - ERROR_CODE_OPERATIONAL_PROBLEM = 25, - ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED = 45, - ERROR_CODE_PASSWORD_FAILURE = 26, - ERROR_CODE_PROPERTY_IS_NOT_A_LIST = 22, - ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY = 50, - ERROR_CODE_READ_ACCESS_DENIED = 27, - ERROR_CODE_SECURITY_NOT_SUPPORTED = 28, - ERROR_CODE_SERVICE_REQUEST_DENIED = 29, - ERROR_CODE_TIMEOUT = 30, - ERROR_CODE_UNKNOWN_OBJECT = 31, - ERROR_CODE_UNKNOWN_PROPERTY = 32, - ERROR_CODE_RESERVED1 = 33, - ERROR_CODE_UNKNOWN_VT_CLASS = 34, - ERROR_CODE_UNKNOWN_VT_SESSION = 35, - ERROR_CODE_UNSUPPORTED_OBJECT_TYPE = 36, - ERROR_CODE_VALUE_OUT_OF_RANGE = 37, - ERROR_CODE_VT_SESSION_ALREADY_CLOSED = 38, - ERROR_CODE_VT_SESSION_TERMINATION_FAILURE = 39, - ERROR_CODE_WRITE_ACCESS_DENIED = 40, - /* see character-set-not-supported (41), */ - /* see invalid-array-index (42), */ - ERROR_CODE_COV_SUBSCRIPTION_FAILED = 43, - ERROR_CODE_NOT_COV_PROPERTY = 44, - /* see optional-functionality-not-supported (45), */ - /* see invalid-configuration-data (46), */ - /* see datatype-not-supported (47), */ - /* see duplicate-name (48), */ - /* see duplicate-object-id (49), */ - /* see property-is-not-an-array (50), */ - // Enumerated values 0-255 are reserved for definition by ASHRAE. - // Enumerated values 256-65535 may be used by others subject to - // the procedures and constraints described in Clause 23. - // The last enumeration used in this version is 50. - MAX_BACNET_ERROR_CODE = 51, - FIRST_PROPRIETARY_ERROR_CODE = 256, - LAST_PROPRIETARY_ERROR_CODE = 65535 + ERROR_CODE_OTHER = 0, + ERROR_CODE_AUTHENTICATION_FAILED = 1, + ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED = 41, + ERROR_CODE_CONFIGURATION_IN_PROGRESS = 2, + ERROR_CODE_DATATYPE_NOT_SUPPORTED = 47, + ERROR_CODE_DEVICE_BUSY = 3, + ERROR_CODE_DUPLICATE_NAME = 48, + ERROR_CODE_DUPLICATE_OBJECT_ID = 49, + ERROR_CODE_DYNAMIC_CREATION_NOT_SUPPORTED = 4, + ERROR_CODE_FILE_ACCESS_DENIED = 5, + ERROR_CODE_INCOMPATIBLE_SECURITY_LEVELS = 6, + ERROR_CODE_INCONSISTENT_PARAMETERS = 7, + ERROR_CODE_INCONSISTENT_SELECTION_CRITERION = 8, + ERROR_CODE_INVALID_ARRAY_INDEX = 42, + ERROR_CODE_INVALID_CONFIGURATION_DATA = 46, + ERROR_CODE_INVALID_DATA_TYPE = 9, + ERROR_CODE_INVALID_FILE_ACCESS_METHOD = 10, + ERROR_CODE_ERROR_CODE_INVALID_FILE_START_POSITION = 11, + ERROR_CODE_INVALID_OPERATOR_NAME = 12, + ERROR_CODE_INVALID_PARAMETER_DATA_TYPE = 13, + ERROR_CODE_INVALID_TIME_STAMP = 14, + ERROR_CODE_KEY_GENERATION_ERROR = 15, + ERROR_CODE_MISSING_REQUIRED_PARAMETER = 16, + ERROR_CODE_NO_OBJECTS_OF_SPECIFIED_TYPE = 17, + ERROR_CODE_NO_SPACE_FOR_OBJECT = 18, + ERROR_CODE_NO_SPACE_TO_ADD_LIST_ELEMENT = 19, + ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY = 20, + ERROR_CODE_NO_VT_SESSIONS_AVAILABLE = 21, + ERROR_CODE_OBJECT_DELETION_NOT_PERMITTED = 23, + ERROR_CODE_OBJECT_IDENTIFIER_ALREADY_EXISTS = 24, + ERROR_CODE_OPERATIONAL_PROBLEM = 25, + ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED = 45, + ERROR_CODE_PASSWORD_FAILURE = 26, + ERROR_CODE_PROPERTY_IS_NOT_A_LIST = 22, + ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY = 50, + ERROR_CODE_READ_ACCESS_DENIED = 27, + ERROR_CODE_SECURITY_NOT_SUPPORTED = 28, + ERROR_CODE_SERVICE_REQUEST_DENIED = 29, + ERROR_CODE_TIMEOUT = 30, + ERROR_CODE_UNKNOWN_OBJECT = 31, + ERROR_CODE_UNKNOWN_PROPERTY = 32, + ERROR_CODE_RESERVED1 = 33, + ERROR_CODE_UNKNOWN_VT_CLASS = 34, + ERROR_CODE_UNKNOWN_VT_SESSION = 35, + ERROR_CODE_UNSUPPORTED_OBJECT_TYPE = 36, + ERROR_CODE_VALUE_OUT_OF_RANGE = 37, + ERROR_CODE_VT_SESSION_ALREADY_CLOSED = 38, + ERROR_CODE_VT_SESSION_TERMINATION_FAILURE = 39, + ERROR_CODE_WRITE_ACCESS_DENIED = 40, + /* see character-set-not-supported (41), */ + /* see invalid-array-index (42), */ + ERROR_CODE_COV_SUBSCRIPTION_FAILED = 43, + ERROR_CODE_NOT_COV_PROPERTY = 44, + /* see optional-functionality-not-supported (45), */ + /* see invalid-configuration-data (46), */ + /* see datatype-not-supported (47), */ + /* see duplicate-name (48), */ + /* see duplicate-object-id (49), */ + /* see property-is-not-an-array (50), */ + // Enumerated values 0-255 are reserved for definition by ASHRAE. + // Enumerated values 256-65535 may be used by others subject to + // the procedures and constraints described in Clause 23. + // The last enumeration used in this version is 50. + MAX_BACNET_ERROR_CODE = 51, + FIRST_PROPRIETARY_ERROR_CODE = 256, + LAST_PROPRIETARY_ERROR_CODE = 65535 } BACNET_ERROR_CODE; -typedef enum -{ - BACNET_REINIT_COLDSTART = 0, - BACNET_REINIT_WARMSTART = 1, - BACNET_REINIT_STARTBACKUP = 2, - BACNET_REINIT_ENDBACKUP = 3, - BACNET_REINIT_STARTRESTORE = 4, - BACNET_REINIT_ENDRESTORE = 5, - BACNET_REINIT_ABORTRESTORE = 6, - MAX_BACNET_REINITIALIZED_STATE = 7 +typedef enum { + BACNET_REINIT_COLDSTART = 0, + BACNET_REINIT_WARMSTART = 1, + BACNET_REINIT_STARTBACKUP = 2, + BACNET_REINIT_ENDBACKUP = 3, + BACNET_REINIT_STARTRESTORE = 4, + BACNET_REINIT_ENDRESTORE = 5, + BACNET_REINIT_ABORTRESTORE = 6, + MAX_BACNET_REINITIALIZED_STATE = 7 } BACNET_REINITIALIZED_STATE; -#endif // end of BACENUM_H - +#endif // end of BACENUM_H diff --git a/bacnet-stack/bacerror.c b/bacnet-stack/bacerror.c index 178471f0..52b7684b 100644 --- a/bacnet-stack/bacerror.c +++ b/bacnet-stack/bacerror.c @@ -37,125 +37,104 @@ #include "bacdef.h" // encode service -int bacerror_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - BACNET_CONFIRMED_SERVICE service, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code) +int bacerror_encode_apdu(uint8_t * apdu, + uint8_t invoke_id, + BACNET_CONFIRMED_SERVICE service, + BACNET_ERROR_CLASS error_class, BACNET_ERROR_CODE error_code) { - int apdu_len = 0; // total length of the apdu, return value + int apdu_len = 0; // total length of the apdu, return value - if (apdu) - { - apdu[0] = PDU_TYPE_ERROR; - apdu[1] = invoke_id; - apdu[2] = service; - apdu_len = 3; - // service parameters - apdu_len += encode_tagged_enumerated(&apdu[apdu_len], - error_class); - apdu_len += encode_tagged_enumerated(&apdu[apdu_len], - error_code); - } - - return apdu_len; + if (apdu) { + apdu[0] = PDU_TYPE_ERROR; + apdu[1] = invoke_id; + apdu[2] = service; + apdu_len = 3; + // service parameters + apdu_len += encode_tagged_enumerated(&apdu[apdu_len], error_class); + apdu_len += encode_tagged_enumerated(&apdu[apdu_len], error_code); + } + + return apdu_len; } // decode the application class and code -int bacerror_decode_error_class_and_code( - uint8_t *apdu, - unsigned apdu_len, - BACNET_ERROR_CLASS *error_class, - BACNET_ERROR_CODE *error_code) +int bacerror_decode_error_class_and_code(uint8_t * apdu, + unsigned apdu_len, + BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code) { - int len = 0; - uint8_t tag_number = 0; - uint32_t len_value_type = 0; - int decoded_value = 0; + int len = 0; + uint8_t tag_number = 0; + uint32_t len_value_type = 0; + int decoded_value = 0; - if (apdu_len) - { - // error class - len += decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - if (tag_number != BACNET_APPLICATION_TAG_ENUMERATED) - return 0; - len += decode_enumerated(&apdu[len],len_value_type, &decoded_value); - if (error_class) - *error_class = decoded_value; - // error code - len += decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - if (tag_number != BACNET_APPLICATION_TAG_ENUMERATED) - return 0; - len += decode_enumerated(&apdu[len],len_value_type, &decoded_value); - if (error_code) - *error_code = decoded_value; - } - - return len; + if (apdu_len) { + // error class + len += decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + if (tag_number != BACNET_APPLICATION_TAG_ENUMERATED) + return 0; + len += + decode_enumerated(&apdu[len], len_value_type, &decoded_value); + if (error_class) + *error_class = decoded_value; + // error code + len += decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + if (tag_number != BACNET_APPLICATION_TAG_ENUMERATED) + return 0; + len += + decode_enumerated(&apdu[len], len_value_type, &decoded_value); + if (error_code) + *error_code = decoded_value; + } + + return len; } // decode the service request only -int bacerror_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - BACNET_CONFIRMED_SERVICE *service, - BACNET_ERROR_CLASS *error_class, - BACNET_ERROR_CODE *error_code) +int bacerror_decode_service_request(uint8_t * apdu, + unsigned apdu_len, + uint8_t * invoke_id, + BACNET_CONFIRMED_SERVICE * service, + BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code) { - int len = 0; + int len = 0; - if (apdu_len > 2) - { - if (invoke_id) - *invoke_id = apdu[0]; - if (service) - *service = apdu[1]; - // decode the application class and code - len = bacerror_decode_error_class_and_code( - &apdu[2], - apdu_len - 2, - error_class, - error_code); - } - - return len; + if (apdu_len > 2) { + if (invoke_id) + *invoke_id = apdu[0]; + if (service) + *service = apdu[1]; + // decode the application class and code + len = bacerror_decode_error_class_and_code(&apdu[2], + apdu_len - 2, error_class, error_code); + } + + return len; } // decode the whole APDU - mainly used for unit testing -int bacerror_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - BACNET_CONFIRMED_SERVICE *service, - BACNET_ERROR_CLASS *error_class, - BACNET_ERROR_CODE *error_code) +int bacerror_decode_apdu(uint8_t * apdu, + unsigned apdu_len, + uint8_t * invoke_id, + BACNET_CONFIRMED_SERVICE * service, + BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code) { - int len = 0; + int len = 0; - if (!apdu) - return -1; - // optional checking - most likely was already done prior to this call - if (apdu_len) - { - if (apdu[0] != PDU_TYPE_ERROR) - return -1; - if (apdu_len > 1) - { - len = bacerror_decode_service_request( - &apdu[1], - apdu_len - 1, - invoke_id, - service, - error_class, - error_code); + if (!apdu) + return -1; + // optional checking - most likely was already done prior to this call + if (apdu_len) { + if (apdu[0] != PDU_TYPE_ERROR) + return -1; + if (apdu_len > 1) { + len = bacerror_decode_service_request(&apdu[1], + apdu_len - 1, invoke_id, service, error_class, error_code); + } } - } - - return len; + + return len; } #ifdef TEST @@ -165,137 +144,97 @@ int bacerror_decode_apdu( void testBACError(Test * pTest) { - uint8_t apdu[480] = {0}; - int len = 0; - int apdu_len = 0; - uint8_t invoke_id = 0; - BACNET_CONFIRMED_SERVICE service = 0; - BACNET_ERROR_CLASS error_class = 0; - BACNET_ERROR_CODE error_code = 0; - uint8_t test_invoke_id = 0; - BACNET_CONFIRMED_SERVICE test_service = 0; - BACNET_ERROR_CLASS test_error_class = 0; - BACNET_ERROR_CODE test_error_code = 0; - - len = bacerror_encode_apdu( - &apdu[0], - invoke_id, - service, - error_class, - error_code); - ct_test(pTest, len != 0); - apdu_len = len; + uint8_t apdu[480] = { 0 }; + int len = 0; + int apdu_len = 0; + uint8_t invoke_id = 0; + BACNET_CONFIRMED_SERVICE service = 0; + BACNET_ERROR_CLASS error_class = 0; + BACNET_ERROR_CODE error_code = 0; + uint8_t test_invoke_id = 0; + BACNET_CONFIRMED_SERVICE test_service = 0; + BACNET_ERROR_CLASS test_error_class = 0; + BACNET_ERROR_CODE test_error_code = 0; - len = bacerror_decode_apdu( - &apdu[0], - apdu_len, - &test_invoke_id, - &test_service, - &test_error_class, - &test_error_code); - ct_test(pTest, len != -1); - ct_test(pTest, test_invoke_id == invoke_id); - ct_test(pTest, test_service == service); - ct_test(pTest, test_error_class == error_class); - ct_test(pTest, test_error_code == error_code); + len = bacerror_encode_apdu(&apdu[0], + invoke_id, service, error_class, error_code); + ct_test(pTest, len != 0); + apdu_len = len; - // change type to get negative response - apdu[0] = PDU_TYPE_ABORT; - len = bacerror_decode_apdu( - &apdu[0], - apdu_len, - &test_invoke_id, - &test_service, - &test_error_class, - &test_error_code); - ct_test(pTest, len == -1); + len = bacerror_decode_apdu(&apdu[0], + apdu_len, + &test_invoke_id, + &test_service, &test_error_class, &test_error_code); + ct_test(pTest, len != -1); + ct_test(pTest, test_invoke_id == invoke_id); + ct_test(pTest, test_service == service); + ct_test(pTest, test_error_class == error_class); + ct_test(pTest, test_error_code == error_code); - // test NULL APDU - len = bacerror_decode_apdu( - NULL, - apdu_len, - &test_invoke_id, - &test_service, - &test_error_class, - &test_error_code); - ct_test(pTest, len == -1); + // change type to get negative response + apdu[0] = PDU_TYPE_ABORT; + len = bacerror_decode_apdu(&apdu[0], + apdu_len, + &test_invoke_id, + &test_service, &test_error_class, &test_error_code); + ct_test(pTest, len == -1); - // force a zero length - len = bacerror_decode_apdu( - &apdu[0], - 0, - &test_invoke_id, - &test_service, - &test_error_class, - &test_error_code); - ct_test(pTest, len == 0); - - - // check them all... - for ( - service = 0; - service < MAX_BACNET_CONFIRMED_SERVICE; - service++) - { - for ( - error_class = 0; - error_class < MAX_BACNET_ERROR_CLASS; - error_class++) - { - for ( - error_code = 0; - error_code < MAX_BACNET_ERROR_CODE; - error_code++) - { - len = bacerror_encode_apdu( - &apdu[0], - invoke_id, - service, - error_class, - error_code); - apdu_len = len; - ct_test(pTest, len != 0); - len = bacerror_decode_apdu( - &apdu[0], - apdu_len, - &test_invoke_id, - &test_service, - &test_error_class, - &test_error_code); - ct_test(pTest, len != -1); - ct_test(pTest, test_invoke_id == invoke_id); - ct_test(pTest, test_service == service); - ct_test(pTest, test_error_class == error_class); - ct_test(pTest, test_error_code == error_code); - } + // test NULL APDU + len = bacerror_decode_apdu(NULL, + apdu_len, + &test_invoke_id, + &test_service, &test_error_class, &test_error_code); + ct_test(pTest, len == -1); + + // force a zero length + len = bacerror_decode_apdu(&apdu[0], + 0, + &test_invoke_id, + &test_service, &test_error_class, &test_error_code); + ct_test(pTest, len == 0); + + + // check them all... + for (service = 0; service < MAX_BACNET_CONFIRMED_SERVICE; service++) { + for (error_class = 0; + error_class < MAX_BACNET_ERROR_CLASS; error_class++) { + for (error_code = 0; + error_code < MAX_BACNET_ERROR_CODE; error_code++) { + len = bacerror_encode_apdu(&apdu[0], + invoke_id, service, error_class, error_code); + apdu_len = len; + ct_test(pTest, len != 0); + len = bacerror_decode_apdu(&apdu[0], + apdu_len, + &test_invoke_id, + &test_service, &test_error_class, &test_error_code); + ct_test(pTest, len != -1); + ct_test(pTest, test_invoke_id == invoke_id); + ct_test(pTest, test_service == service); + ct_test(pTest, test_error_class == error_class); + ct_test(pTest, test_error_code == error_code); + } + } } - } - // max boundaries - service = 255; - error_class = LAST_PROPRIETARY_ERROR_CLASS; - error_code = LAST_PROPRIETARY_ERROR_CODE; - len = bacerror_encode_apdu( - &apdu[0], - invoke_id, - service, - error_class, - error_code); - apdu_len = len; - ct_test(pTest, len != 0); - len = bacerror_decode_apdu( - &apdu[0], - apdu_len, - &test_invoke_id, - &test_service, - &test_error_class, - &test_error_code); - ct_test(pTest, len != -1); - ct_test(pTest, test_invoke_id == invoke_id); - ct_test(pTest, test_service == service); - ct_test(pTest, test_error_class == error_class); - ct_test(pTest, test_error_code == error_code); - + // max boundaries + service = 255; + error_class = LAST_PROPRIETARY_ERROR_CLASS; + error_code = LAST_PROPRIETARY_ERROR_CODE; + len = bacerror_encode_apdu(&apdu[0], + invoke_id, service, error_class, error_code); + apdu_len = len; + ct_test(pTest, len != 0); + len = bacerror_decode_apdu(&apdu[0], + apdu_len, + &test_invoke_id, + &test_service, &test_error_class, &test_error_code); + ct_test(pTest, len != -1); + ct_test(pTest, test_invoke_id == invoke_id); + ct_test(pTest, test_service == service); + ct_test(pTest, test_error_class == error_class); + ct_test(pTest, test_error_code == error_code); + } #ifdef TEST_BACERROR diff --git a/bacnet-stack/bacerror.h b/bacnet-stack/bacerror.h index f4c480c9..06920f4e 100644 --- a/bacnet-stack/bacerror.h +++ b/bacnet-stack/bacerror.h @@ -40,45 +40,35 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ -int bacerror_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - BACNET_CONFIRMED_SERVICE service, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code); + int bacerror_encode_apdu(uint8_t * apdu, + uint8_t invoke_id, + BACNET_CONFIRMED_SERVICE service, + BACNET_ERROR_CLASS error_class, BACNET_ERROR_CODE error_code); -int bacerror_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - BACNET_CONFIRMED_SERVICE *service, - BACNET_ERROR_CLASS *error_class, - BACNET_ERROR_CODE *error_code); - -int bacerror_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - BACNET_CONFIRMED_SERVICE *service, - BACNET_ERROR_CLASS *error_class, - BACNET_ERROR_CODE *error_code); + int bacerror_decode_service_request(uint8_t * apdu, + unsigned apdu_len, + uint8_t * invoke_id, + BACNET_CONFIRMED_SERVICE * service, + BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code); + + int bacerror_decode_apdu(uint8_t * apdu, + unsigned apdu_len, + uint8_t * invoke_id, + BACNET_CONFIRMED_SERVICE * service, + BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code); + + int bacerror_decode_error_class_and_code(uint8_t * apdu, + unsigned apdu_len, + BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code); -int bacerror_decode_error_class_and_code( - uint8_t *apdu, - unsigned apdu_len, - BACNET_ERROR_CLASS *error_class, - BACNET_ERROR_CODE *error_code); - #ifdef TEST #include "ctest.h" -void testBACError(Test * pTest); + void testBACError(Test * pTest); #endif #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif - diff --git a/bacnet-stack/bacprop.c b/bacnet-stack/bacprop.c index 56d203ac..7bfa0013 100644 --- a/bacnet-stack/bacprop.c +++ b/bacnet-stack/bacprop.c @@ -37,63 +37,75 @@ #include "bacprop.h" PROP_TAG_DATA bacnet_object_device_property_tag_map[] = { - {PROP_OBJECT_IDENTIFIER, BACNET_APPLICATION_TAG_OBJECT_ID}, - {PROP_OBJECT_NAME, BACNET_APPLICATION_TAG_CHARACTER_STRING}, - {PROP_OBJECT_TYPE, BACNET_APPLICATION_TAG_ENUMERATED}, - {PROP_SYSTEM_STATUS, BACNET_APPLICATION_TAG_ENUMERATED}, - {PROP_VENDOR_NAME, BACNET_APPLICATION_TAG_CHARACTER_STRING}, - {PROP_VENDOR_IDENTIFIER, BACNET_APPLICATION_TAG_UNSIGNED_INT}, - {PROP_MODEL_NAME, BACNET_APPLICATION_TAG_CHARACTER_STRING}, - {PROP_FIRMWARE_REVISION, BACNET_APPLICATION_TAG_CHARACTER_STRING}, - {PROP_APPLICATION_SOFTWARE_VERSION, BACNET_APPLICATION_TAG_CHARACTER_STRING}, - {PROP_PROTOCOL_VERSION, BACNET_APPLICATION_TAG_UNSIGNED_INT}, - {PROP_PROTOCOL_CONFORMANCE_CLASS, BACNET_APPLICATION_TAG_UNSIGNED_INT}, - {PROP_PROTOCOL_SERVICES_SUPPORTED, BACNET_APPLICATION_TAG_BIT_STRING}, - {PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, BACNET_APPLICATION_TAG_BIT_STRING}, - {PROP_MAX_APDU_LENGTH_ACCEPTED, BACNET_APPLICATION_TAG_UNSIGNED_INT}, - {PROP_SEGMENTATION_SUPPORTED, BACNET_APPLICATION_TAG_ENUMERATED}, - {PROP_APDU_TIMEOUT, BACNET_APPLICATION_TAG_UNSIGNED_INT}, - {PROP_NUMBER_OF_APDU_RETRIES, BACNET_APPLICATION_TAG_UNSIGNED_INT}, - { -1, -1 } + {PROP_OBJECT_IDENTIFIER, BACNET_APPLICATION_TAG_OBJECT_ID} + , + {PROP_OBJECT_NAME, BACNET_APPLICATION_TAG_CHARACTER_STRING} + , + {PROP_OBJECT_TYPE, BACNET_APPLICATION_TAG_ENUMERATED} + , + {PROP_SYSTEM_STATUS, BACNET_APPLICATION_TAG_ENUMERATED} + , + {PROP_VENDOR_NAME, BACNET_APPLICATION_TAG_CHARACTER_STRING} + , + {PROP_VENDOR_IDENTIFIER, BACNET_APPLICATION_TAG_UNSIGNED_INT} + , + {PROP_MODEL_NAME, BACNET_APPLICATION_TAG_CHARACTER_STRING} + , + {PROP_FIRMWARE_REVISION, BACNET_APPLICATION_TAG_CHARACTER_STRING} + , + {PROP_APPLICATION_SOFTWARE_VERSION, + BACNET_APPLICATION_TAG_CHARACTER_STRING} + , + {PROP_PROTOCOL_VERSION, BACNET_APPLICATION_TAG_UNSIGNED_INT} + , + {PROP_PROTOCOL_CONFORMANCE_CLASS, BACNET_APPLICATION_TAG_UNSIGNED_INT} + , + {PROP_PROTOCOL_SERVICES_SUPPORTED, BACNET_APPLICATION_TAG_BIT_STRING} + , + {PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, + BACNET_APPLICATION_TAG_BIT_STRING} + , + {PROP_MAX_APDU_LENGTH_ACCEPTED, BACNET_APPLICATION_TAG_UNSIGNED_INT} + , + {PROP_SEGMENTATION_SUPPORTED, BACNET_APPLICATION_TAG_ENUMERATED} + , + {PROP_APDU_TIMEOUT, BACNET_APPLICATION_TAG_UNSIGNED_INT} + , + {PROP_NUMBER_OF_APDU_RETRIES, BACNET_APPLICATION_TAG_UNSIGNED_INT} + , + {-1, -1} }; -signed bacprop_tag_by_index_default( - PROP_TAG_DATA *data_list, - signed index, - signed default_ret) +signed bacprop_tag_by_index_default(PROP_TAG_DATA * data_list, + signed index, signed default_ret) { - signed pUnsigned = 0; + signed pUnsigned = 0; - if (data_list) - { - while (data_list->prop_id != -1) - { - if (data_list->prop_id == index) - { - pUnsigned = data_list->tag_id; - break; - } - data_list++; + if (data_list) { + while (data_list->prop_id != -1) { + if (data_list->prop_id == index) { + pUnsigned = data_list->tag_id; + break; + } + data_list++; + } } - } - return pUnsigned?pUnsigned:default_ret; + return pUnsigned ? pUnsigned : default_ret; } signed bacprop_property_tag(BACNET_OBJECT_TYPE type, signed prop) { - switch (type) - { - case OBJECT_DEVICE: - return bacprop_tag_by_index_default( - bacnet_object_device_property_tag_map, - prop, - -1); + switch (type) { + case OBJECT_DEVICE: + return + bacprop_tag_by_index_default + (bacnet_object_device_property_tag_map, prop, -1); default: - fprintf(stderr, "Unsupported object type"); - break; - } + fprintf(stderr, "Unsupported object type"); + break; + } - return -1; + return -1; } diff --git a/bacnet-stack/bacprop.h b/bacnet-stack/bacprop.h index 46278cce..9fb34dc8 100644 --- a/bacnet-stack/bacprop.h +++ b/bacnet-stack/bacprop.h @@ -38,25 +38,21 @@ #include #include "bacenum.h" -typedef struct -{ - signed prop_id; /* index number that matches the text */ - signed tag_id; /* text pair - use NULL to end the list */ +typedef struct { + signed prop_id; /* index number that matches the text */ + signed tag_id; /* text pair - use NULL to end the list */ } PROP_TAG_DATA; #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ -signed bacprop_tag_by_index_default( - PROP_TAG_DATA *data_list, - signed index, - signed default_ret); + signed bacprop_tag_by_index_default(PROP_TAG_DATA * data_list, + signed index, signed default_ret); -signed bacprop_property_tag(BACNET_OBJECT_TYPE type, signed prop); + signed bacprop_property_tag(BACNET_OBJECT_TYPE type, signed prop); #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif diff --git a/bacnet-stack/bacstr.c b/bacnet-stack/bacstr.c index d69170d8..8f847f87 100644 --- a/bacnet-stack/bacstr.c +++ b/bacnet-stack/bacstr.c @@ -34,510 +34,430 @@ #include #include -#include /* for strlen */ +#include /* for strlen */ #include "bacstr.h" #include "bits.h" -void bitstring_init(BACNET_BIT_STRING *bit_string) +void bitstring_init(BACNET_BIT_STRING * bit_string) { - int i; + int i; - bit_string->bits_used = 0; - for (i = 0; i < MAX_BITSTRING_BYTES; i++) - { - bit_string->value[i] = 0; - } + 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) +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; + 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)); - } + 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 bitstring_bit(BACNET_BIT_STRING * bit_string, uint8_t bit) { - bool value = false; - uint8_t byte_number = bit/8; - uint8_t bit_mask = 1; + 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; - } + 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; + return value; } -uint8_t bitstring_bits_used(BACNET_BIT_STRING *bit_string) +uint8_t bitstring_bits_used(BACNET_BIT_STRING * bit_string) { - return bit_string->bits_used; + 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 bitstring_bytes_used(BACNET_BIT_STRING * bit_string) { - int len = 0; // return value - uint8_t used_bytes = 0; - uint8_t last_bit = 0; + 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]; + 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 octet; + return len; } -bool bitstring_set_octet( - BACNET_BIT_STRING *bit_string, - uint8_t index, - uint8_t octet) +uint8_t bitstring_octet(BACNET_BIT_STRING * bit_string, uint8_t index) { - bool status = false; + uint8_t octet = 0; - if (bit_string) - { - if (index < MAX_BITSTRING_BYTES) - { - bit_string->value[index] = octet; - status = true; + if (bit_string) { + if (index < MAX_BITSTRING_BYTES) { + octet = bit_string->value[index]; + } } - } - return status; + return octet; } -bool bitstring_set_bits_used( - BACNET_BIT_STRING *bit_string, - uint8_t bytes_used, - uint8_t unused_bits) +bool bitstring_set_octet(BACNET_BIT_STRING * bit_string, + uint8_t index, uint8_t octet) { - bool status = false; + 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; - } + if (bit_string) { + if (index < MAX_BITSTRING_BYTES) { + bit_string->value[index] = octet; + status = true; + } + } - return status; + return status; } -uint8_t bitstring_bits_capacity(BACNET_BIT_STRING *bit_string) +bool bitstring_set_bits_used(BACNET_BIT_STRING * bit_string, + uint8_t bytes_used, uint8_t unused_bits) { - if (bit_string) - return (sizeof(bit_string->value) * 8); - else - return 0; + 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 characterstring_init(BACNET_CHARACTER_STRING * char_string, + uint8_t encoding, char *value, size_t length) { - bool status = false; /* return value */ - size_t i; /* counter */ + 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; + 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; } - } - else - { - for (i = 0; i < MAX_CHARACTER_STRING_BYTES; i++) - { - char_string->value[i] = 0; - } - } - status = true; } - } - return status; + return status; } -bool characterstring_init_ansi( - BACNET_CHARACTER_STRING *char_string, - char *value) +bool characterstring_init_ansi(BACNET_CHARACTER_STRING * char_string, + char *value) { - return characterstring_init( - char_string, - CHARACTER_ANSI_X34, - value, value?strlen(value):0); + return characterstring_init(char_string, + CHARACTER_ANSI_X34, value, value ? strlen(value) : 0); } -bool characterstring_copy( - BACNET_CHARACTER_STRING *dest, - BACNET_CHARACTER_STRING *src) +bool characterstring_copy(BACNET_CHARACTER_STRING * dest, + BACNET_CHARACTER_STRING * src) { - return characterstring_init(dest, - characterstring_encoding(src), - characterstring_value(src), - characterstring_length(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) +bool characterstring_same(BACNET_CHARACTER_STRING * dest, + BACNET_CHARACTER_STRING * src) { - size_t i; /* counter */ - bool same_status = false; + 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; + 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; } - } - else if (src) - { - if (src->length == 0) - same_status = true; - } - else if (dest) - { - if (dest->length == 0) - same_status = true; - } - return same_status; + return same_status; } -bool characterstring_ansi_same( - BACNET_CHARACTER_STRING *dest, - const char *src) +bool characterstring_ansi_same(BACNET_CHARACTER_STRING * dest, + const char *src) { - size_t i; /* counter */ - bool same_status = false; + 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; + 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; - } + /* 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; + return same_status; } /* returns false if the string exceeds capacity */ -bool characterstring_append( - BACNET_CHARACTER_STRING *char_string, - char *value, - size_t length) +bool characterstring_append(BACNET_CHARACTER_STRING * char_string, + char *value, size_t length) { - size_t i; /* counter */ - bool status = false; /* return value */ + 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; + 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; + 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 characterstring_truncate(BACNET_CHARACTER_STRING * char_string, + size_t length) { - bool status = false; /* return value */ + bool status = false; /* return value */ - if (char_string) - { - if (length <= CHARACTER_STRING_CAPACITY) - { - char_string->length = length; - status = true; + if (char_string) { + if (length <= CHARACTER_STRING_CAPACITY) { + char_string->length = length; + status = true; + } } - } - return status; + return status; } /* Returns the value. */ -char *characterstring_value(BACNET_CHARACTER_STRING *char_string) +char *characterstring_value(BACNET_CHARACTER_STRING * char_string) { - char *value = NULL; + char *value = NULL; - if (char_string) - { - value = char_string->value; - } + if (char_string) { + value = char_string->value; + } - return value; + return value; } /* returns the length. */ -size_t characterstring_length(BACNET_CHARACTER_STRING *char_string) +size_t characterstring_length(BACNET_CHARACTER_STRING * char_string) { - size_t length = 0; + size_t length = 0; - if (char_string) - { - /* FIXME: validate length is within bounds? */ - length = char_string->length; - } + if (char_string) { + /* FIXME: validate length is within bounds? */ + length = char_string->length; + } - return length; + return length; } -size_t characterstring_capacity(BACNET_CHARACTER_STRING *char_string) +size_t characterstring_capacity(BACNET_CHARACTER_STRING * char_string) { - size_t length = 0; + size_t length = 0; - if (char_string) - { - length = CHARACTER_STRING_CAPACITY; - } + if (char_string) { + length = CHARACTER_STRING_CAPACITY; + } - return length; + return length; } /* returns the encoding. */ -uint8_t characterstring_encoding(BACNET_CHARACTER_STRING *char_string) +uint8_t characterstring_encoding(BACNET_CHARACTER_STRING * char_string) { - uint8_t encoding = 0; + uint8_t encoding = 0; - if (char_string) - { - encoding = char_string->encoding; - } + if (char_string) { + encoding = char_string->encoding; + } - return 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 octetstring_init(BACNET_OCTET_STRING * octet_string, + uint8_t * value, size_t length) { - bool status = false; /* return value */ - size_t i; /* counter */ + 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++; + 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; } - } - else - { - for (i = 0; i < sizeof(octet_string->value); i++) - { - octet_string->value[i] = 0; - } - } - status = true; } - } - return status; + return status; } -bool octetstring_copy( - BACNET_OCTET_STRING *dest, - BACNET_OCTET_STRING *src) +bool octetstring_copy(BACNET_OCTET_STRING * dest, + BACNET_OCTET_STRING * src) { - return octetstring_init(dest, - octetstring_value(src), - octetstring_length(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) +bool octetstring_append(BACNET_OCTET_STRING * octet_string, + uint8_t * value, size_t length) { - size_t i; /* counter */ - bool status = false; /* return value */ + 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; + 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; + 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 octetstring_truncate(BACNET_OCTET_STRING * octet_string, + size_t length) { - bool status = false; /* return value */ + bool status = false; /* return value */ - if (octet_string) - { - if (length <= sizeof(octet_string->value)) - { - octet_string->length = length; - status = true; + if (octet_string) { + if (length <= sizeof(octet_string->value)) { + octet_string->length = length; + status = true; + } } - } - return status; + return status; } /* returns the length. Returns the value in parameter. */ -uint8_t *octetstring_value(BACNET_OCTET_STRING *octet_string) +uint8_t *octetstring_value(BACNET_OCTET_STRING * octet_string) { - uint8_t *value = NULL; + uint8_t *value = NULL; - if (octet_string) - { - value = octet_string->value; - } + if (octet_string) { + value = octet_string->value; + } - return value; + return value; } /* returns the length. */ -size_t octetstring_length(BACNET_OCTET_STRING *octet_string) +size_t octetstring_length(BACNET_OCTET_STRING * octet_string) { - size_t length = 0; + size_t length = 0; - if (octet_string) - { - /* FIXME: validate length is within bounds? */ - length = octet_string->length; - } + if (octet_string) { + /* FIXME: validate length is within bounds? */ + length = octet_string->length; + } - return length; + return length; } /* returns the length. */ -size_t octetstring_capacity(BACNET_OCTET_STRING *octet_string) +size_t octetstring_capacity(BACNET_OCTET_STRING * octet_string) { - size_t length = 0; + size_t length = 0; - if (octet_string) - { - /* FIXME: validate length is within bounds? */ - length = sizeof(octet_string->value); - } + if (octet_string) { + /* FIXME: validate length is within bounds? */ + length = sizeof(octet_string->value); + } - return length; + return length; } #ifdef TEST @@ -547,183 +467,171 @@ size_t octetstring_capacity(BACNET_OCTET_STRING *octet_string) void testBitString(Test * pTest) { - uint8_t bit = 0; - BACNET_BIT_STRING bit_string; + 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); - } + 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); - } + // 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; + 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); + // 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]); - } + 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; + 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); + // 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_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]); - } + 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; + 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); + 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); + ct_setStream(pTest, stdout); + ct_run(pTest); + (void) ct_report(pTest); + ct_destroy(pTest); - return 0; + return 0; } #endif /* TEST_BACSTR */ #endif /* TEST */ diff --git a/bacnet-stack/bacstr.h b/bacnet-stack/bacstr.h index 2a664295..4f6939e1 100644 --- a/bacnet-stack/bacstr.h +++ b/bacnet-stack/bacstr.h @@ -42,122 +42,100 @@ /* bit strings They could be as large as 256/8=32 octets */ #define MAX_BITSTRING_BYTES 15 -typedef struct BACnet_Bit_String -{ - uint8_t bits_used; - uint8_t value[MAX_BITSTRING_BYTES]; +typedef struct BACnet_Bit_String { + uint8_t bits_used; + uint8_t value[MAX_BITSTRING_BYTES]; } BACNET_BIT_STRING; #define MAX_CHARACTER_STRING_BYTES (MAX_APDU-6) -typedef struct BACnet_Character_String -{ - size_t length; - uint8_t encoding; - /* limit - 6 octets is the most our tag and type could be */ - char value[MAX_CHARACTER_STRING_BYTES]; +typedef struct BACnet_Character_String { + size_t length; + uint8_t encoding; + /* limit - 6 octets is the most our tag and type could be */ + char value[MAX_CHARACTER_STRING_BYTES]; } BACNET_CHARACTER_STRING; /* FIXME: convert the bacdcode library to use BACNET_OCTET_STRING for APDU buffer to prevent buffer overflows */ -typedef struct BACnet_Octet_String -{ - size_t length; - /* limit - 6 octets is the most our tag and type could be */ - uint8_t value[MAX_APDU-6]; +typedef struct BACnet_Octet_String { + size_t length; + /* limit - 6 octets is the most our tag and type could be */ + uint8_t value[MAX_APDU - 6]; } BACNET_OCTET_STRING; #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ -void bitstring_init(BACNET_BIT_STRING *bit_string); -void bitstring_set_bit(BACNET_BIT_STRING *bit_string, uint8_t bit, bool value); -bool bitstring_bit(BACNET_BIT_STRING *bit_string, uint8_t bit); -uint8_t bitstring_bits_used(BACNET_BIT_STRING *bit_string); + void bitstring_init(BACNET_BIT_STRING * bit_string); + void bitstring_set_bit(BACNET_BIT_STRING * bit_string, uint8_t bit, + bool value); + bool bitstring_bit(BACNET_BIT_STRING * bit_string, uint8_t bit); + uint8_t bitstring_bits_used(BACNET_BIT_STRING * bit_string); // returns the number of bytes that a bit string is using -int bitstring_bytes_used(BACNET_BIT_STRING *bit_string); -uint8_t bitstring_bits_capacity(BACNET_BIT_STRING *bit_string); + int bitstring_bytes_used(BACNET_BIT_STRING * bit_string); + uint8_t bitstring_bits_capacity(BACNET_BIT_STRING * bit_string); /* used for encoding and decoding from the APDU */ -uint8_t bitstring_octet(BACNET_BIT_STRING *bit_string, uint8_t octet_index); -bool bitstring_set_octet( - BACNET_BIT_STRING *bit_string, - uint8_t index, - uint8_t octet); -bool bitstring_set_bits_used( - BACNET_BIT_STRING *bit_string, - uint8_t bytes_used, - uint8_t unused_bits); + uint8_t bitstring_octet(BACNET_BIT_STRING * bit_string, + uint8_t octet_index); + bool bitstring_set_octet(BACNET_BIT_STRING * bit_string, uint8_t index, + uint8_t octet); + bool bitstring_set_bits_used(BACNET_BIT_STRING * bit_string, + uint8_t bytes_used, uint8_t unused_bits); /* 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 characterstring_init(BACNET_CHARACTER_STRING * char_string, + uint8_t encoding, char *value, size_t length); /* used for ANSI C-Strings */ -bool characterstring_init_ansi( - BACNET_CHARACTER_STRING *char_string, - char *value); -bool characterstring_copy( - BACNET_CHARACTER_STRING *dest, - BACNET_CHARACTER_STRING *src); + bool characterstring_init_ansi(BACNET_CHARACTER_STRING * char_string, + char *value); + bool characterstring_copy(BACNET_CHARACTER_STRING * dest, + BACNET_CHARACTER_STRING * src); /* returns true if the strings are the same length, encoding, value */ -bool characterstring_same( - BACNET_CHARACTER_STRING *dest, - BACNET_CHARACTER_STRING *src); -bool characterstring_ansi_same( - BACNET_CHARACTER_STRING *dest, - const char *src); + bool characterstring_same(BACNET_CHARACTER_STRING * dest, + BACNET_CHARACTER_STRING * src); + bool characterstring_ansi_same(BACNET_CHARACTER_STRING * dest, + const char *src); /* returns false if the string exceeds capacity */ -bool characterstring_append( - BACNET_CHARACTER_STRING *char_string, - char *value, - size_t length); + bool characterstring_append(BACNET_CHARACTER_STRING * char_string, + char *value, size_t length); /* 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 characterstring_set_encoding( - BACNET_CHARACTER_STRING *char_string, - uint8_t encoding); + bool characterstring_truncate(BACNET_CHARACTER_STRING * char_string, + size_t length); + bool characterstring_set_encoding(BACNET_CHARACTER_STRING * + char_string, uint8_t encoding); /* Returns the value */ -char *characterstring_value(BACNET_CHARACTER_STRING *char_string); + char *characterstring_value(BACNET_CHARACTER_STRING * char_string); /* returns the length */ -size_t characterstring_length(BACNET_CHARACTER_STRING *char_string); -uint8_t characterstring_encoding(BACNET_CHARACTER_STRING *char_string); -size_t characterstring_capacity(BACNET_CHARACTER_STRING *char_string); + size_t characterstring_length(BACNET_CHARACTER_STRING * char_string); + uint8_t characterstring_encoding(BACNET_CHARACTER_STRING * + char_string); + size_t characterstring_capacity(BACNET_CHARACTER_STRING * char_string); /* 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 octetstring_copy( - BACNET_OCTET_STRING *dest, - BACNET_OCTET_STRING *src); + bool octetstring_init(BACNET_OCTET_STRING * octet_string, + uint8_t * value, size_t length); + bool octetstring_copy(BACNET_OCTET_STRING * dest, + BACNET_OCTET_STRING * src); /* returns false if the string exceeds capacity */ -bool octetstring_append( - BACNET_OCTET_STRING *octet_string, - uint8_t *value, - size_t length); + bool octetstring_append(BACNET_OCTET_STRING * octet_string, + uint8_t * value, size_t length); /* 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 octetstring_truncate(BACNET_OCTET_STRING * octet_string, + size_t length); /* Returns the value */ -uint8_t *octetstring_value(BACNET_OCTET_STRING *octet_string); + uint8_t *octetstring_value(BACNET_OCTET_STRING * octet_string); /* Returns the length.*/ -size_t octetstring_length(BACNET_OCTET_STRING *octet_string); -size_t octetstring_capacity(BACNET_OCTET_STRING *octet_string); + size_t octetstring_length(BACNET_OCTET_STRING * octet_string); + size_t octetstring_capacity(BACNET_OCTET_STRING * octet_string); #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif diff --git a/bacnet-stack/bactext.c b/bacnet-stack/bactext.c index f0182416..14b0a6e0 100644 --- a/bacnet-stack/bactext.c +++ b/bacnet-stack/bactext.c @@ -40,121 +40,172 @@ static const char *ASHRAE_Reserved_String = "Reserved for Use by ASHRAE"; static const char *Vendor_Proprietary_String = "Vendor Proprietary Value"; INDTEXT_DATA bacnet_confirmed_service_names[] = { - { SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM, "Acknowledge-Alarm" }, - { SERVICE_CONFIRMED_COV_NOTIFICATION, "COV-Notification" }, - { SERVICE_CONFIRMED_EVENT_NOTIFICATION, "Event-Notification" }, - { SERVICE_CONFIRMED_GET_ALARM_SUMMARY, "Get-Alarm-Summary" }, - { SERVICE_CONFIRMED_GET_ENROLLMENT_SUMMARY, "Get-Enrollment-Summary" }, - { SERVICE_CONFIRMED_SUBSCRIBE_COV, "Subscribe-COV" }, - { SERVICE_CONFIRMED_ATOMIC_READ_FILE, "Atomic-Read-File" }, - { SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, "Atomic-Write-File" }, - { SERVICE_CONFIRMED_ADD_LIST_ELEMENT, "Add-List-Element" }, - { SERVICE_CONFIRMED_REMOVE_LIST_ELEMENT, "Remove-List-Element" }, - { SERVICE_CONFIRMED_CREATE_OBJECT, "Create-Object" }, - { SERVICE_CONFIRMED_DELETE_OBJECT, "Delete-Object" }, - { SERVICE_CONFIRMED_READ_PROPERTY, "Read-Property" }, - { SERVICE_CONFIRMED_READ_PROPERTY_CONDITIONAL, "Read-Property-Conditional" }, - { SERVICE_CONFIRMED_READ_PROPERTY_MULTIPLE, "Read-Property-Multiple" }, - { SERVICE_CONFIRMED_WRITE_PROPERTY, "Write-Property" }, - { SERVICE_CONFIRMED_WRITE_PROPERTY_MULTIPLE, "Write-Property-Multiple" }, - { SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, "Device-Communication-Control" }, - { SERVICE_CONFIRMED_PRIVATE_TRANSFER, "Private-Transfer" }, - { SERVICE_CONFIRMED_TEXT_MESSAGE, "Text-Message" }, - { SERVICE_CONFIRMED_REINITIALIZE_DEVICE, "Reinitialize-Device" }, - { SERVICE_CONFIRMED_VT_OPEN, "VT-Open" }, - { SERVICE_CONFIRMED_VT_CLOSE, "VT-Close" }, - { SERVICE_CONFIRMED_VT_DATA, "VT-Data" }, - { SERVICE_CONFIRMED_AUTHENTICATE, "Authenticate" }, - { SERVICE_CONFIRMED_REQUEST_KEY, "Request-Key" }, - { SERVICE_CONFIRMED_READ_RANGE, "Read-Range" }, - { SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION, "Life-Safety_Operation" }, - { SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY, "Subscribe-COV-Property" }, - { SERVICE_CONFIRMED_GET_EVENT_INFORMATION, "Get-Event-Information" }, - { 0, NULL } + {SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM, "Acknowledge-Alarm"}, + {SERVICE_CONFIRMED_COV_NOTIFICATION, "COV-Notification"}, + {SERVICE_CONFIRMED_EVENT_NOTIFICATION, "Event-Notification"}, + {SERVICE_CONFIRMED_GET_ALARM_SUMMARY, "Get-Alarm-Summary"}, + {SERVICE_CONFIRMED_GET_ENROLLMENT_SUMMARY, "Get-Enrollment-Summary"}, + {SERVICE_CONFIRMED_SUBSCRIBE_COV, "Subscribe-COV"}, + {SERVICE_CONFIRMED_ATOMIC_READ_FILE, "Atomic-Read-File"}, + {SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, "Atomic-Write-File"}, + {SERVICE_CONFIRMED_ADD_LIST_ELEMENT, "Add-List-Element"}, + {SERVICE_CONFIRMED_REMOVE_LIST_ELEMENT, "Remove-List-Element"}, + {SERVICE_CONFIRMED_CREATE_OBJECT, "Create-Object"}, + {SERVICE_CONFIRMED_DELETE_OBJECT, "Delete-Object"}, + {SERVICE_CONFIRMED_READ_PROPERTY, "Read-Property"}, + {SERVICE_CONFIRMED_READ_PROPERTY_CONDITIONAL, + "Read-Property-Conditional"}, + {SERVICE_CONFIRMED_READ_PROPERTY_MULTIPLE, "Read-Property-Multiple"}, + {SERVICE_CONFIRMED_WRITE_PROPERTY, "Write-Property"}, + {SERVICE_CONFIRMED_WRITE_PROPERTY_MULTIPLE, "Write-Property-Multiple"}, + {SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, + "Device-Communication-Control"}, + {SERVICE_CONFIRMED_PRIVATE_TRANSFER, "Private-Transfer"}, + {SERVICE_CONFIRMED_TEXT_MESSAGE, "Text-Message"}, + {SERVICE_CONFIRMED_REINITIALIZE_DEVICE, "Reinitialize-Device"}, + {SERVICE_CONFIRMED_VT_OPEN, "VT-Open"}, + {SERVICE_CONFIRMED_VT_CLOSE, "VT-Close"}, + {SERVICE_CONFIRMED_VT_DATA, "VT-Data"}, + {SERVICE_CONFIRMED_AUTHENTICATE, "Authenticate"}, + {SERVICE_CONFIRMED_REQUEST_KEY, "Request-Key"}, + {SERVICE_CONFIRMED_READ_RANGE, "Read-Range"}, + {SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION, "Life-Safety_Operation"}, + {SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY, "Subscribe-COV-Property"}, + {SERVICE_CONFIRMED_GET_EVENT_INFORMATION, "Get-Event-Information"}, + {0, NULL} }; const char *bactext_confirmed_service_name(int index) { - return indtext_by_index_default( - bacnet_confirmed_service_names, - index,ASHRAE_Reserved_String); + return indtext_by_index_default(bacnet_confirmed_service_names, + index, ASHRAE_Reserved_String); } INDTEXT_DATA bacnet_unconfirmed_service_names[] = { - { SERVICE_UNCONFIRMED_I_AM, "I-Am" }, - { SERVICE_UNCONFIRMED_I_HAVE, "I-Have" }, - { SERVICE_UNCONFIRMED_COV_NOTIFICATION, "COV-Notification" }, - { SERVICE_UNCONFIRMED_EVENT_NOTIFICATION, "Event-Notification" }, - { SERVICE_UNCONFIRMED_PRIVATE_TRANSFER, "Private-Transfer" }, - { SERVICE_UNCONFIRMED_TEXT_MESSAGE, "Text-Message" }, - { SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, "Time-Synchronization" }, - { SERVICE_UNCONFIRMED_WHO_HAS, "Who-Has" }, - { SERVICE_UNCONFIRMED_WHO_IS, "Who-Is" }, - { SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, "UTC-Time-Synchronization" }, - { 0, NULL } + {SERVICE_UNCONFIRMED_I_AM, "I-Am"} + , + {SERVICE_UNCONFIRMED_I_HAVE, "I-Have"} + , + {SERVICE_UNCONFIRMED_COV_NOTIFICATION, "COV-Notification"} + , + {SERVICE_UNCONFIRMED_EVENT_NOTIFICATION, "Event-Notification"} + , + {SERVICE_UNCONFIRMED_PRIVATE_TRANSFER, "Private-Transfer"} + , + {SERVICE_UNCONFIRMED_TEXT_MESSAGE, "Text-Message"} + , + {SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, "Time-Synchronization"} + , + {SERVICE_UNCONFIRMED_WHO_HAS, "Who-Has"} + , + {SERVICE_UNCONFIRMED_WHO_IS, "Who-Is"} + , + {SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, + "UTC-Time-Synchronization"} + , + {0, NULL} }; const char *bactext_unconfirmed_service_name(int index) { - return indtext_by_index_default( - bacnet_unconfirmed_service_names, - index,ASHRAE_Reserved_String); + return indtext_by_index_default(bacnet_unconfirmed_service_names, + index, ASHRAE_Reserved_String); } INDTEXT_DATA bacnet_application_tag_names[] = { - { BACNET_APPLICATION_TAG_NULL, "Null" }, - { BACNET_APPLICATION_TAG_BOOLEAN, "Boolean" }, - { BACNET_APPLICATION_TAG_UNSIGNED_INT, "Unsigned Int" }, - { BACNET_APPLICATION_TAG_SIGNED_INT, "Signed Int" }, - { BACNET_APPLICATION_TAG_REAL, "Real" }, - { BACNET_APPLICATION_TAG_DOUBLE, "Double" }, - { BACNET_APPLICATION_TAG_OCTET_STRING, "Octet String" }, - { BACNET_APPLICATION_TAG_CHARACTER_STRING, "Character String" }, - { BACNET_APPLICATION_TAG_BIT_STRING, "Bit String" }, - { BACNET_APPLICATION_TAG_ENUMERATED, "Enumerated" }, - { BACNET_APPLICATION_TAG_DATE, "Date" }, - { BACNET_APPLICATION_TAG_TIME, "Time" }, - { BACNET_APPLICATION_TAG_OBJECT_ID, "Object ID" }, - { BACNET_APPLICATION_TAG_RESERVED1, "Reserved 1" }, - { BACNET_APPLICATION_TAG_RESERVED2, "Reserved 2" }, - { BACNET_APPLICATION_TAG_RESERVED3, "Reserved 3" }, - { 0, NULL } + {BACNET_APPLICATION_TAG_NULL, "Null"} + , + {BACNET_APPLICATION_TAG_BOOLEAN, "Boolean"} + , + {BACNET_APPLICATION_TAG_UNSIGNED_INT, "Unsigned Int"} + , + {BACNET_APPLICATION_TAG_SIGNED_INT, "Signed Int"} + , + {BACNET_APPLICATION_TAG_REAL, "Real"} + , + {BACNET_APPLICATION_TAG_DOUBLE, "Double"} + , + {BACNET_APPLICATION_TAG_OCTET_STRING, "Octet String"} + , + {BACNET_APPLICATION_TAG_CHARACTER_STRING, "Character String"} + , + {BACNET_APPLICATION_TAG_BIT_STRING, "Bit String"} + , + {BACNET_APPLICATION_TAG_ENUMERATED, "Enumerated"} + , + {BACNET_APPLICATION_TAG_DATE, "Date"} + , + {BACNET_APPLICATION_TAG_TIME, "Time"} + , + {BACNET_APPLICATION_TAG_OBJECT_ID, "Object ID"} + , + {BACNET_APPLICATION_TAG_RESERVED1, "Reserved 1"} + , + {BACNET_APPLICATION_TAG_RESERVED2, "Reserved 2"} + , + {BACNET_APPLICATION_TAG_RESERVED3, "Reserved 3"} + , + {0, NULL} }; const char *bactext_application_tag_name(int index) { - return indtext_by_index_default( - bacnet_application_tag_names, - index,ASHRAE_Reserved_String); + return indtext_by_index_default(bacnet_application_tag_names, + index, ASHRAE_Reserved_String); } INDTEXT_DATA bacnet_object_type_names[] = { - { OBJECT_ANALOG_INPUT, "Analog Input" }, - { OBJECT_ANALOG_OUTPUT, "Analog Output" }, - { OBJECT_ANALOG_VALUE, "Analog Value" }, - { OBJECT_BINARY_INPUT, "Binary Input" }, - { OBJECT_BINARY_OUTPUT, "Binary Output" }, - { OBJECT_BINARY_VALUE, "Binary Value" }, - { OBJECT_CALENDAR, "Calendar" }, - { OBJECT_COMMAND, "Command" }, - { OBJECT_DEVICE, "Device" }, - { OBJECT_EVENT_ENROLLMENT, "Event Enrollment" }, - { OBJECT_FILE, "File" }, - { OBJECT_GROUP, "Group" }, - { OBJECT_LOOP, "Loop" }, - { OBJECT_MULTI_STATE_INPUT, "Multi-State Input" }, - { OBJECT_MULTI_STATE_OUTPUT, "Multi-State Output" }, - { OBJECT_NOTIFICATION_CLASS, "Notification Class" }, - { OBJECT_PROGRAM, "Program" }, - { OBJECT_SCHEDULE, "Schedule" }, - { OBJECT_AVERAGING, "Averaging" }, - { OBJECT_MULTI_STATE_VALUE, "Multi-State Value" }, - { OBJECT_TRENDLOG, "Trendlog" }, - { OBJECT_LIFE_SAFETY_POINT, "Life Safety Point" }, - { OBJECT_LIFE_SAFETY_ZONE, "Life Safety Zone" }, - { OBJECT_ACCUMULATOR, "Accumulator" }, - { OBJECT_PULSE_CONVERTER, "Pulse-Converter" }, - { 0, NULL } + {OBJECT_ANALOG_INPUT, "Analog Input"} + , + {OBJECT_ANALOG_OUTPUT, "Analog Output"} + , + {OBJECT_ANALOG_VALUE, "Analog Value"} + , + {OBJECT_BINARY_INPUT, "Binary Input"} + , + {OBJECT_BINARY_OUTPUT, "Binary Output"} + , + {OBJECT_BINARY_VALUE, "Binary Value"} + , + {OBJECT_CALENDAR, "Calendar"} + , + {OBJECT_COMMAND, "Command"} + , + {OBJECT_DEVICE, "Device"} + , + {OBJECT_EVENT_ENROLLMENT, "Event Enrollment"} + , + {OBJECT_FILE, "File"} + , + {OBJECT_GROUP, "Group"} + , + {OBJECT_LOOP, "Loop"} + , + {OBJECT_MULTI_STATE_INPUT, "Multi-State Input"} + , + {OBJECT_MULTI_STATE_OUTPUT, "Multi-State Output"} + , + {OBJECT_NOTIFICATION_CLASS, "Notification Class"} + , + {OBJECT_PROGRAM, "Program"} + , + {OBJECT_SCHEDULE, "Schedule"} + , + {OBJECT_AVERAGING, "Averaging"} + , + {OBJECT_MULTI_STATE_VALUE, "Multi-State Value"} + , + {OBJECT_TRENDLOG, "Trendlog"} + , + {OBJECT_LIFE_SAFETY_POINT, "Life Safety Point"} + , + {OBJECT_LIFE_SAFETY_ZONE, "Life Safety Zone"} + , + {OBJECT_ACCUMULATOR, "Accumulator"} + , + {OBJECT_PULSE_CONVERTER, "Pulse-Converter"} + , + {0, NULL} /* Enumerated values 0-127 are reserved for definition by ASHRAE. Enumerated values 128-1023 may be used by others subject to the procedures and constraints described in Clause 23. */ @@ -162,693 +213,1163 @@ INDTEXT_DATA bacnet_object_type_names[] = { const char *bactext_object_type_name(int index) { - return indtext_by_index_split_default( - bacnet_object_type_names, - index, - 128, - ASHRAE_Reserved_String, - Vendor_Proprietary_String); + return indtext_by_index_split_default(bacnet_object_type_names, + index, 128, ASHRAE_Reserved_String, Vendor_Proprietary_String); } INDTEXT_DATA bacnet_property_names[] = { /* FIXME: use the enumerations from bacenum.h */ - { PROP_ACKED_TRANSITIONS, "acked-transitions"}, - { PROP_ACK_REQUIRED, "ack-required"}, - { PROP_ACTION, "action"}, - { PROP_ACTION_TEXT, "action-text"}, - { PROP_ACTIVE_TEXT, "active-text"}, - { PROP_ACTIVE_VT_SESSIONS, "active-vt-sessions"}, - { PROP_ALARM_VALUE, "alarm-value"}, - { PROP_ALARM_VALUES, "alarm-values"}, - { PROP_ALL, "all"}, - { PROP_ALL_WRITES_SUCCESSFUL, "all-writes-successful"}, - { PROP_APDU_SEGMENT_TIMEOUT, "apdu-segment-timeout"}, - { PROP_APDU_TIMEOUT, "apdu-timeout"}, - { PROP_APPLICATION_SOFTWARE_VERSION, "application-software-version"}, - { PROP_ARCHIVE, "archive"}, - { PROP_BIAS, "bias"}, - { PROP_CHANGE_OF_STATE_COUNT, "change-of-state-count"}, - { PROP_CHANGE_OF_STATE_TIME, "change-of-state-time"}, - { PROP_NOTIFICATION_CLASS, "notification-class"}, - { PROP_BLANK_1, "(deleted in 135-2001)"}, - { PROP_CONTROLLED_VARIABLE_REFERENCE, "controlled-variable-reference"}, - { PROP_CONTROLLED_VARIABLE_UNITS, "controlled-variable-units"}, - { PROP_CONTROLLED_VARIABLE_VALUE, "controlled-variable-value"}, - { PROP_COV_INCREMENT, "COV-increment"}, - { PROP_DATE_LIST, "datelist"}, - { PROP_DAYLIGHT_SAVINGS_STATUS, "daylight-savings-status"}, - { PROP_DEADBAND, "deadband"}, - { PROP_DERIVATIVE_CONSTANT, "derivative-constant"}, - { PROP_DERIVATIVE_CONSTANT_UNITS, "derivative-constant-units"}, - { PROP_DESCRIPTION, "description"}, - { PROP_DESCRIPTION_OF_HALT, "description-of-halt"}, - { PROP_DEVICE_ADDRESS_BINDING, "device-address-binding"}, - { PROP_DEVICE_TYPE, "device-type"}, - { PROP_EFFECTIVE_PERIOD, "effective-period"}, - { PROP_ELAPSED_ACTIVE_TIME, "elapsed-active-time"}, - { PROP_ERROR_LIMIT, "error-limit"}, - { PROP_EVENT_ENABLE, "event-enable"}, - { PROP_EVENT_STATE, "event-state"}, - { PROP_EVENT_TYPE, "event-type"}, - { PROP_EXCEPTION_SCHEDULE, "exception-schedule"}, - { PROP_FAULT_VALUES, "fault-values"}, - { PROP_FEEDBACK_VALUE, "feedback-value"}, - { PROP_FILE_ACCESS_METHOD, "file-access-method"}, - { PROP_FILE_SIZE, "file-size"}, - { PROP_FILE_TYPE, "file-type"}, - { PROP_FIRMWARE_REVISION, "firmware-version"}, - { PROP_HIGH_LIMIT, "high-limit"}, - { PROP_INACTIVE_TEXT, "inactive-text"}, - { PROP_IN_PROCESS, "in-process"}, - { PROP_INSTANCE_OF, "instance-of"}, - { PROP_INTEGRAL_CONSTANT, "integral-constant"}, - { PROP_INTEGRAL_CONSTANT_UNITS, "integral-constant-units"}, - { PROP_ISSUE_CONFIRMED_NOTIFICATIONS, "issue-confirmednotifications"}, - { PROP_LIMIT_ENABLE, "limit-enable"}, - { PROP_LIST_OF_GROUP_MEMBERS, "list-of-group-members"}, - { PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES, "list-of-object-property-references"}, - { PROP_LIST_OF_SESSION_KEYS, "list-of-session-keys"}, - { PROP_LOCAL_DATE, "local-date"}, - { PROP_LOCAL_TIME, "local-time"}, - { PROP_LOCATION, "location"}, - { PROP_LOW_LIMIT, "low-limit"}, - { PROP_MANIPULATED_VARIABLE_REFERENCE, "manipulated-variable-reference"}, - { PROP_MAXIMUM_OUTPUT, "maximum-output"}, - { PROP_MAX_APDU_LENGTH_ACCEPTED, "max-apdu-length-accepted"}, - { PROP_MAX_INFO_FRAMES, "max-info-frames"}, - { PROP_MAX_MASTER, "max-master"}, - { PROP_MAX_PRES_VALUE, "max-pres-value"}, - { PROP_MINIMUM_OFF_TIME, "minimum-off-time"}, - { PROP_MINIMUM_ON_TIME, "minimum-on-time"}, - { PROP_MINIMUM_OUTPUT, "minimum-output"}, - { PROP_MIN_PRES_VALUE, "min-pres-value"}, - { PROP_MODEL_NAME, "model-name"}, - { PROP_MODIFICATION_DATE, "modification-date"}, - { PROP_NOTIFY_TYPE, "notify-type"}, - { PROP_NUMBER_OF_APDU_RETRIES, "number-of-APDU-retries"}, - { PROP_NUMBER_OF_STATES, "number-of-states"}, - { PROP_OBJECT_IDENTIFIER, "object-identifier"}, - { PROP_OBJECT_LIST, "object-list"}, - { PROP_OBJECT_NAME, "object-name"}, - { PROP_OBJECT_PROPERTY_REFERENCE, "object-property-reference"}, - { PROP_OBJECT_TYPE, "object-type"}, - { PROP_OPTIONAL, "optional"}, - { PROP_OUT_OF_SERVICE, "out-of-service"}, - { PROP_OUTPUT_UNITS, "output-units"}, - { PROP_EVENT_PARAMETERS, "event-parameters"}, - { PROP_POLARITY, "polarity"}, - { PROP_PRESENT_VALUE, "present-value"}, - { PROP_PRIORITY, "priority"}, - { PROP_PRIORITY_ARRAY, "priority-array"}, - { PROP_PRIORITY_FOR_WRITING, "priority-for-writing"}, - { PROP_PROCESS_IDENTIFIER, "process-identifier"}, - { PROP_PROGRAM_CHANGE, "program-change"}, - { PROP_PROGRAM_LOCATION, "program-location"}, - { PROP_PROGRAM_STATE, "program-state"}, - { PROP_PROPORTIONAL_CONSTANT, "proportional-constant"}, - { PROP_PROPORTIONAL_CONSTANT_UNITS, "proportional-constant-units"}, - { PROP_PROTOCOL_CONFORMANCE_CLASS, "protocol-conformance-class"}, - { PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, "protocol-object-types-supported"}, - { PROP_PROTOCOL_SERVICES_SUPPORTED, "protocol-services-supported"}, - { PROP_PROTOCOL_VERSION, "protocol-version"}, - { PROP_READ_ONLY, "read-only"}, - { PROP_REASON_FOR_HALT, "reason-for-halt"}, - { PROP_RECIPIENT, "recipient"}, - { PROP_RECIPIENT_LIST, "recipient-list"}, - { PROP_RELIABILITY, "reliability"}, - { PROP_RELINQUISH_DEFAULT, "relinquish-default"}, - { PROP_REQUIRED, "required"}, - { PROP_RESOLUTION, "resolution"}, - { PROP_SEGMENTATION_SUPPORTED, "segmentation-supported"}, - { PROP_SETPOINT, "setpoint"}, - { PROP_SETPOINT_REFERENCE, "setpoint-reference"}, - { PROP_STATE_TEXT, "state-text"}, - { PROP_STATUS_FLAGS, "status-flags"}, - { PROP_SYSTEM_STATUS, "system-status"}, - { PROP_TIME_DELAY, "time-delay"}, - { PROP_TIME_OF_ACTIVE_TIME_RESET, "time-of-active-time-reset"}, - { PROP_TIME_OF_STATE_COUNT_RESET, "time-of-state-count-reset"}, - { PROP_TIME_SYNCHRONIZATION_RECIPIENTS, "time-synchronization-recipients"}, - { PROP_UNITS, "units"}, - { PROP_UPDATE_INTERVAL, "update-interval"}, - { PROP_UTC_OFFSET, "utc-offset"}, - { PROP_VENDOR_IDENTIFIER, "vendor-identifier"}, - { PROP_VENDOR_NAME, "vendor-name"}, - { PROP_VT_CLASSES_SUPPORTED, "vt-classes-supported"}, - { PROP_WEEKLY_SCHEDULE, "weekly-schedule"}, - { PROP_ATTEMPTED_SAMPLES, "attempted-samples"}, - { PROP_AVERAGE_VALUE, "average-value"}, - { PROP_BUFFER_SIZE, "buffer-size"}, - { PROP_CLIENT_COV_INCREMENT, "client-cov-increment"}, - { PROP_COV_RESUBSCRIPTION_INTERVAL, "cov-resubscription-interval"}, - { PROP_CURRENT_NOTIFY_TIME, "current-notify-time"}, - { PROP_EVENT_TIME_STAMPS, "event-time-stamps"}, - { PROP_LOG_BUFFER, "log-buffer"}, - { PROP_LOG_DEVICE_OBJECT, "log-device-object-property"}, - { PROP_LOG_ENABLE, "log-enable"}, - { PROP_LOG_INTERVAL, "log-interval"}, - { PROP_MAXIMUM_VALUE, "maximum-value"}, - { PROP_MINIMUM_VALUE, "minimum-value"}, - { PROP_NOTIFICATION_THRESHOLD, "notification-threshold"}, - { PROP_PREVIOUS_NOTIFY_TIME, "previous-notify-time"}, - { PROP_PROTOCOL_REVISION, "protocol-revision"}, - { PROP_RECORDS_SINCE_NOTIFICATION, "records-since-notification"}, - { PROP_RECORD_COUNT, "record-count"}, - { PROP_START_TIME, "start-time"}, - { PROP_STOP_TIME, "stop-time"}, - { PROP_STOP_WHEN_FULL, "stop-when-full"}, - { PROP_TOTAL_RECORD_COUNT, "total-record-count"}, - { PROP_VALID_SAMPLES, "valid-samples"}, - { PROP_WINDOW_INTERVAL, "window-interval"}, - { PROP_WINDOW_SAMPLES, "window-samples"}, - { PROP_MAXIMUM_VALUE_TIMESTAMP, "maximum-value-timestamp"}, - { PROP_MINIMUM_VALUE_TIMESTAMP, "minimum-value-timestamp"}, - { PROP_VARIANCE_VALUE, "variance-value"}, - { PROP_ACTIVE_COV_SUBSCRIPTIONS, "active-cov-subscriptions"}, - { PROP_BACKUP_FAILURE_TIMEOUT, "backup-failure-timeout"}, - { PROP_CONFIGURATION_FILES, "configuration-files"}, - { PROP_DATABASE_REVISION, "database-revision"}, - { PROP_DIRECT_READING, "direct-reading"}, - { PROP_LAST_RESTORE_TIME, "last-restore-time"}, - { PROP_MAINTENANCE_REQUIRED, "maintenance-required"}, - { PROP_MEMBER_OF, "member-of"}, - { PROP_MODE, "mode"}, - { PROP_OPERATION_EXPECTED, "operation-expected"}, - { PROP_SETTING, "setting"}, - { PROP_SILENCED, "silenced"}, - { PROP_TRACKING_VALUE, "tracking-value"}, - { PROP_ZONE_MEMBERS, "zone-members"}, - { PROP_LIFE_SAFETY_ALARM_VALUES, "life-safety-alarm-values"}, - { PROP_MAX_SEGMENTS_ACCEPTED, "max-segments-accepted"}, - { PROP_PROFILE_NAME, "profile-name"}, - { 0, NULL } - /* Enumerated values 0-511 are reserved for definition by ASHRAE. - Enumerated values 512-4194303 may be used by others subject to the - procedures and constraints described in Clause 23. */ + {PROP_ACKED_TRANSITIONS, "acked-transitions"} + , + {PROP_ACK_REQUIRED, "ack-required"} + , + {PROP_ACTION, "action"} + , + {PROP_ACTION_TEXT, "action-text"} + , + {PROP_ACTIVE_TEXT, "active-text"} + , + {PROP_ACTIVE_VT_SESSIONS, "active-vt-sessions"} + , + {PROP_ALARM_VALUE, "alarm-value"} + , + {PROP_ALARM_VALUES, "alarm-values"} + , + {PROP_ALL, "all"} + , + {PROP_ALL_WRITES_SUCCESSFUL, "all-writes-successful"} + , + {PROP_APDU_SEGMENT_TIMEOUT, "apdu-segment-timeout"} + , + {PROP_APDU_TIMEOUT, "apdu-timeout"} + , + {PROP_APPLICATION_SOFTWARE_VERSION, "application-software-version"} + , + {PROP_ARCHIVE, "archive"} + , + {PROP_BIAS, "bias"} + , + {PROP_CHANGE_OF_STATE_COUNT, "change-of-state-count"} + , + {PROP_CHANGE_OF_STATE_TIME, "change-of-state-time"} + , + {PROP_NOTIFICATION_CLASS, "notification-class"} + , + {PROP_BLANK_1, "(deleted in 135-2001)"} + , + {PROP_CONTROLLED_VARIABLE_REFERENCE, "controlled-variable-reference"} + , + {PROP_CONTROLLED_VARIABLE_UNITS, "controlled-variable-units"} + , + {PROP_CONTROLLED_VARIABLE_VALUE, "controlled-variable-value"} + , + {PROP_COV_INCREMENT, "COV-increment"} + , + {PROP_DATE_LIST, "datelist"} + , + {PROP_DAYLIGHT_SAVINGS_STATUS, "daylight-savings-status"} + , + {PROP_DEADBAND, "deadband"} + , + {PROP_DERIVATIVE_CONSTANT, "derivative-constant"} + , + {PROP_DERIVATIVE_CONSTANT_UNITS, "derivative-constant-units"} + , + {PROP_DESCRIPTION, "description"} + , + {PROP_DESCRIPTION_OF_HALT, "description-of-halt"} + , + {PROP_DEVICE_ADDRESS_BINDING, "device-address-binding"} + , + {PROP_DEVICE_TYPE, "device-type"} + , + {PROP_EFFECTIVE_PERIOD, "effective-period"} + , + {PROP_ELAPSED_ACTIVE_TIME, "elapsed-active-time"} + , + {PROP_ERROR_LIMIT, "error-limit"} + , + {PROP_EVENT_ENABLE, "event-enable"} + , + {PROP_EVENT_STATE, "event-state"} + , + {PROP_EVENT_TYPE, "event-type"} + , + {PROP_EXCEPTION_SCHEDULE, "exception-schedule"} + , + {PROP_FAULT_VALUES, "fault-values"} + , + {PROP_FEEDBACK_VALUE, "feedback-value"} + , + {PROP_FILE_ACCESS_METHOD, "file-access-method"} + , + {PROP_FILE_SIZE, "file-size"} + , + {PROP_FILE_TYPE, "file-type"} + , + {PROP_FIRMWARE_REVISION, "firmware-version"} + , + {PROP_HIGH_LIMIT, "high-limit"} + , + {PROP_INACTIVE_TEXT, "inactive-text"} + , + {PROP_IN_PROCESS, "in-process"} + , + {PROP_INSTANCE_OF, "instance-of"} + , + {PROP_INTEGRAL_CONSTANT, "integral-constant"} + , + {PROP_INTEGRAL_CONSTANT_UNITS, "integral-constant-units"} + , + {PROP_ISSUE_CONFIRMED_NOTIFICATIONS, "issue-confirmednotifications"} + , + {PROP_LIMIT_ENABLE, "limit-enable"} + , + {PROP_LIST_OF_GROUP_MEMBERS, "list-of-group-members"} + , + {PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES, + "list-of-object-property-references"} + , + {PROP_LIST_OF_SESSION_KEYS, "list-of-session-keys"} + , + {PROP_LOCAL_DATE, "local-date"} + , + {PROP_LOCAL_TIME, "local-time"} + , + {PROP_LOCATION, "location"} + , + {PROP_LOW_LIMIT, "low-limit"} + , + {PROP_MANIPULATED_VARIABLE_REFERENCE, "manipulated-variable-reference"} + , + {PROP_MAXIMUM_OUTPUT, "maximum-output"} + , + {PROP_MAX_APDU_LENGTH_ACCEPTED, "max-apdu-length-accepted"} + , + {PROP_MAX_INFO_FRAMES, "max-info-frames"} + , + {PROP_MAX_MASTER, "max-master"} + , + {PROP_MAX_PRES_VALUE, "max-pres-value"} + , + {PROP_MINIMUM_OFF_TIME, "minimum-off-time"} + , + {PROP_MINIMUM_ON_TIME, "minimum-on-time"} + , + {PROP_MINIMUM_OUTPUT, "minimum-output"} + , + {PROP_MIN_PRES_VALUE, "min-pres-value"} + , + {PROP_MODEL_NAME, "model-name"} + , + {PROP_MODIFICATION_DATE, "modification-date"} + , + {PROP_NOTIFY_TYPE, "notify-type"} + , + {PROP_NUMBER_OF_APDU_RETRIES, "number-of-APDU-retries"} + , + {PROP_NUMBER_OF_STATES, "number-of-states"} + , + {PROP_OBJECT_IDENTIFIER, "object-identifier"} + , + {PROP_OBJECT_LIST, "object-list"} + , + {PROP_OBJECT_NAME, "object-name"} + , + {PROP_OBJECT_PROPERTY_REFERENCE, "object-property-reference"} + , + {PROP_OBJECT_TYPE, "object-type"} + , + {PROP_OPTIONAL, "optional"} + , + {PROP_OUT_OF_SERVICE, "out-of-service"} + , + {PROP_OUTPUT_UNITS, "output-units"} + , + {PROP_EVENT_PARAMETERS, "event-parameters"} + , + {PROP_POLARITY, "polarity"} + , + {PROP_PRESENT_VALUE, "present-value"} + , + {PROP_PRIORITY, "priority"} + , + {PROP_PRIORITY_ARRAY, "priority-array"} + , + {PROP_PRIORITY_FOR_WRITING, "priority-for-writing"} + , + {PROP_PROCESS_IDENTIFIER, "process-identifier"} + , + {PROP_PROGRAM_CHANGE, "program-change"} + , + {PROP_PROGRAM_LOCATION, "program-location"} + , + {PROP_PROGRAM_STATE, "program-state"} + , + {PROP_PROPORTIONAL_CONSTANT, "proportional-constant"} + , + {PROP_PROPORTIONAL_CONSTANT_UNITS, "proportional-constant-units"} + , + {PROP_PROTOCOL_CONFORMANCE_CLASS, "protocol-conformance-class"} + , + {PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, + "protocol-object-types-supported"} + , + {PROP_PROTOCOL_SERVICES_SUPPORTED, "protocol-services-supported"} + , + {PROP_PROTOCOL_VERSION, "protocol-version"} + , + {PROP_READ_ONLY, "read-only"} + , + {PROP_REASON_FOR_HALT, "reason-for-halt"} + , + {PROP_RECIPIENT, "recipient"} + , + {PROP_RECIPIENT_LIST, "recipient-list"} + , + {PROP_RELIABILITY, "reliability"} + , + {PROP_RELINQUISH_DEFAULT, "relinquish-default"} + , + {PROP_REQUIRED, "required"} + , + {PROP_RESOLUTION, "resolution"} + , + {PROP_SEGMENTATION_SUPPORTED, "segmentation-supported"} + , + {PROP_SETPOINT, "setpoint"} + , + {PROP_SETPOINT_REFERENCE, "setpoint-reference"} + , + {PROP_STATE_TEXT, "state-text"} + , + {PROP_STATUS_FLAGS, "status-flags"} + , + {PROP_SYSTEM_STATUS, "system-status"} + , + {PROP_TIME_DELAY, "time-delay"} + , + {PROP_TIME_OF_ACTIVE_TIME_RESET, "time-of-active-time-reset"} + , + {PROP_TIME_OF_STATE_COUNT_RESET, "time-of-state-count-reset"} + , + {PROP_TIME_SYNCHRONIZATION_RECIPIENTS, + "time-synchronization-recipients"} + , + {PROP_UNITS, "units"} + , + {PROP_UPDATE_INTERVAL, "update-interval"} + , + {PROP_UTC_OFFSET, "utc-offset"} + , + {PROP_VENDOR_IDENTIFIER, "vendor-identifier"} + , + {PROP_VENDOR_NAME, "vendor-name"} + , + {PROP_VT_CLASSES_SUPPORTED, "vt-classes-supported"} + , + {PROP_WEEKLY_SCHEDULE, "weekly-schedule"} + , + {PROP_ATTEMPTED_SAMPLES, "attempted-samples"} + , + {PROP_AVERAGE_VALUE, "average-value"} + , + {PROP_BUFFER_SIZE, "buffer-size"} + , + {PROP_CLIENT_COV_INCREMENT, "client-cov-increment"} + , + {PROP_COV_RESUBSCRIPTION_INTERVAL, "cov-resubscription-interval"} + , + {PROP_CURRENT_NOTIFY_TIME, "current-notify-time"} + , + {PROP_EVENT_TIME_STAMPS, "event-time-stamps"} + , + {PROP_LOG_BUFFER, "log-buffer"} + , + {PROP_LOG_DEVICE_OBJECT, "log-device-object-property"} + , + {PROP_LOG_ENABLE, "log-enable"} + , + {PROP_LOG_INTERVAL, "log-interval"} + , + {PROP_MAXIMUM_VALUE, "maximum-value"} + , + {PROP_MINIMUM_VALUE, "minimum-value"} + , + {PROP_NOTIFICATION_THRESHOLD, "notification-threshold"} + , + {PROP_PREVIOUS_NOTIFY_TIME, "previous-notify-time"} + , + {PROP_PROTOCOL_REVISION, "protocol-revision"} + , + {PROP_RECORDS_SINCE_NOTIFICATION, "records-since-notification"} + , + {PROP_RECORD_COUNT, "record-count"} + , + {PROP_START_TIME, "start-time"} + , + {PROP_STOP_TIME, "stop-time"} + , + {PROP_STOP_WHEN_FULL, "stop-when-full"} + , + {PROP_TOTAL_RECORD_COUNT, "total-record-count"} + , + {PROP_VALID_SAMPLES, "valid-samples"} + , + {PROP_WINDOW_INTERVAL, "window-interval"} + , + {PROP_WINDOW_SAMPLES, "window-samples"} + , + {PROP_MAXIMUM_VALUE_TIMESTAMP, "maximum-value-timestamp"} + , + {PROP_MINIMUM_VALUE_TIMESTAMP, "minimum-value-timestamp"} + , + {PROP_VARIANCE_VALUE, "variance-value"} + , + {PROP_ACTIVE_COV_SUBSCRIPTIONS, "active-cov-subscriptions"} + , + {PROP_BACKUP_FAILURE_TIMEOUT, "backup-failure-timeout"} + , + {PROP_CONFIGURATION_FILES, "configuration-files"} + , + {PROP_DATABASE_REVISION, "database-revision"} + , + {PROP_DIRECT_READING, "direct-reading"} + , + {PROP_LAST_RESTORE_TIME, "last-restore-time"} + , + {PROP_MAINTENANCE_REQUIRED, "maintenance-required"} + , + {PROP_MEMBER_OF, "member-of"} + , + {PROP_MODE, "mode"} + , + {PROP_OPERATION_EXPECTED, "operation-expected"} + , + {PROP_SETTING, "setting"} + , + {PROP_SILENCED, "silenced"} + , + {PROP_TRACKING_VALUE, "tracking-value"} + , + {PROP_ZONE_MEMBERS, "zone-members"} + , + {PROP_LIFE_SAFETY_ALARM_VALUES, "life-safety-alarm-values"} + , + {PROP_MAX_SEGMENTS_ACCEPTED, "max-segments-accepted"} + , + {PROP_PROFILE_NAME, "profile-name"} + , + {0, NULL} + /* Enumerated values 0-511 are reserved for definition by ASHRAE. + Enumerated values 512-4194303 may be used by others subject to the + procedures and constraints described in Clause 23. */ }; const char *bactext_property_name(int index) { - return indtext_by_index_split_default( - bacnet_property_names, - index, - 512, - ASHRAE_Reserved_String, - Vendor_Proprietary_String); + return indtext_by_index_split_default(bacnet_property_names, + index, 512, ASHRAE_Reserved_String, Vendor_Proprietary_String); } -unsigned bactext_property_id(const char* name) +unsigned bactext_property_id(const char *name) { - return indtext_by_istring_default( - bacnet_property_names, - name, - 0); + return indtext_by_istring_default(bacnet_property_names, name, 0); } INDTEXT_DATA bacnet_engineering_unit_names[] = { - { UNITS_SQUARE_METERS , "square-meters"}, - { UNITS_SQUARE_FEET , "square-feet"}, - { UNITS_MILLIAMPERES , "milliamperes"}, - { UNITS_AMPERES, "amperes"}, - { UNITS_OHMS, "ohms"}, - { UNITS_VOLTS, "volts"}, - { UNITS_KILOVOLTS, "kilovolts"}, - { UNITS_MEGAVOLTS, "megavolts"}, - { UNITS_VOLT_AMPERES, "volt-amperes"}, - { UNITS_KILOVOLT_AMPERES, "kilovolt-amperes"}, - { UNITS_MEGAVOLT_AMPERES, "megavolt-amperes"}, - { UNITS_VOLT_AMPERES_REACTIVE, "volt-amperes-reactive"}, - { UNITS_KILOVOLT_AMPERES_REACTIVE, "kilovolt-amperes-reactive"}, - { UNITS_MEGAVOLT_AMPERES_REACTIVE, "megavolt-amperes-reactive"}, - { UNITS_DEGREES_PHASE, "degrees-phase"}, - { UNITS_POWER_FACTOR, "power-factor"}, - { UNITS_JOULES, "joules"}, - { UNITS_KILOJOULES, "kilojoules"}, - { UNITS_WATT_HOURS, "watt-hours"}, - { UNITS_KILOWATT_HOURS, "kilowatt-hours"}, - { UNITS_BTUS, "btus"}, - { UNITS_THERMS, "therms"}, - { UNITS_TON_HOURS, "ton-hours"}, - { UNITS_JOULES_PER_KILOGRAM_DRY_AIR, "joules-per-kilogram-dry-air"}, - { UNITS_BTUS_PER_POUND_DRY_AIR, "btus-per-pound-dry-air"}, - { UNITS_CYCLES_PER_HOUR, "cycles-per-hour"}, - { UNITS_CYCLES_PER_MINUTE, "cycles-per-minute"}, - { UNITS_HERTZ, "hertz"}, - { UNITS_GRAMS_OF_WATER_PER_KILOGRAM_DRY_AIR, "grams-of-water-per-kilogram-dry-air"}, - { UNITS_PERCENT_RELATIVE_HUMIDITY, "percent-relative-humidity"}, - { UNITS_MILLIMETERS, "millimeters"}, - { UNITS_METERS, "meters"}, - { UNITS_INCHES, "inches"}, - { UNITS_FEET, "feet"}, - { UNITS_WATTS_PER_SQUARE_FOOT, "watts-per-square-foot"}, - { UNITS_WATTS_PER_SQUARE_METER, "watts-per-square-meter"}, - { UNITS_LUMENS, "lumens"}, - { UNITS_LUXES, "luxes"}, - { UNITS_FOOT_CANDLES, "foot-candles"}, - { UNITS_KILOGRAMS, "kilograms"}, - { UNITS_POUNDS_MASS, "pounds-mass"}, - { UNITS_TONS, "tons"}, - { UNITS_KILOGRAMS_PER_SECOND, "kilograms-per-second"}, - { UNITS_KILOGRAMS_PER_MINUTE, "kilograms-per-minute"}, - { UNITS_KILOGRAMS_PER_HOUR, "kilograms-per-hour"}, - { UNITS_POUNDS_MASS_PER_MINUTE, "pounds-mass-per-minute"}, - { UNITS_POUNDS_MASS_PER_HOUR, "pounds-mass-per-hour"}, - { UNITS_WATTS, "watts"}, - { UNITS_KILOWATTS, "kilowatts"}, - { UNITS_MEGAWATTS, "megawatts"}, - { UNITS_BTUS_PER_HOUR, "btus-per-hour"}, - { UNITS_HORSEPOWER, "horsepower"}, - { UNITS_TONS_REFRIGERATION, "tons-refrigeration"}, - { UNITS_PASCALS, "pascals"}, - { UNITS_KILOPASCALS, "kilopascals"}, - { UNITS_BARS, "bars"}, - { UNITS_POUNDS_FORCE_PER_SQUARE_INCH, "pounds-force-per-square-inch"}, - { UNITS_CENTIMETERS_OF_WATER, "centimeters-of-water"}, - { UNITS_INCHES_OF_WATER, "inches-of-water"}, - { UNITS_MILLIMETERS_OF_MERCURY, "millimeters-of-mercury"}, - { UNITS_CENTIMETERS_OF_MERCURY, "centimeters-of-mercury"}, - { UNITS_INCHES_OF_MERCURY, "inches-of-mercury"}, - { UNITS_DEGREES_CELSIUS, "degrees-celsius"}, - { UNITS_DEGREES_KELVIN, "degrees-kelvin"}, - { UNITS_DEGREES_FAHRENHEIT, "degrees-fahrenheit"}, - { UNITS_DEGREE_DAYS_CELSIUS, "degree-days-celsius"}, - { UNITS_DEGREE_DAYS_FAHRENHEIT, "degree-days-fahrenheit"}, - { UNITS_YEARS, "years"}, - { UNITS_MONTHS, "months"}, - { UNITS_WEEKS, "weeks"}, - { UNITS_DAYS, "days"}, - { UNITS_HOURS, "hours"}, - { UNITS_MINUTES, "minutes"}, - { UNITS_SECONDS, "secondS"}, - { UNITS_METERS_PER_SECOND, "meters-per-second"}, - { UNITS_KILOMETERS_PER_HOUR, "kilometers-per-hour"}, - { UNITS_FEET_PER_SECOND, "feet-per-second"}, - { UNITS_FEET_PER_MINUTE, "feet-per-minute"}, - { UNITS_MILES_PER_HOUR, "miles-per-hour"}, - { UNITS_CUBIC_FEET, "cubic-feet"}, - { UNITS_CUBIC_METERS, "cubic-meters"}, - { UNITS_IMPERIAL_GALLONS, "imperial-gallons"}, - { UNITS_LITERS, "liters"}, - { UNITS_US_GALLONS, "us-gallons"}, - { UNITS_CUBIC_FEET_PER_MINUTE, "cubic-feet-per-minute"}, - { UNITS_CUBIC_METERS_PER_SECOND, "cubic-meters-per-second"}, - { UNITS_IMPERIAL_GALLONS_PER_MINUTE, "imperial-gallons-per-minute"}, - { UNITS_LITERS_PER_SECOND, "liters-per-second"}, - { UNITS_LITERS_PER_MINUTE, "liters-per-minute"}, - { UNITS_US_GALLONS_PER_MINUTE, "us-gallons-per-minute"}, - { UNITS_DEGREES_ANGULAR, "degrees-angular"}, - { UNITS_DEGREES_CELSIUS_PER_HOUR, "degrees-celsius-per-hour"}, - { UNITS_DEGREES_CELSIUS_PER_MINUTE, "degrees-celsius-per-minute"}, - { UNITS_DEGREES_FAHRENHEIT_PER_HOUR, "degrees-fahrenheit-per-hour"}, - { UNITS_DEGREES_FAHRENHEIT_PER_MINUTE, "degrees-fahrenheit-per-minute"}, - { UNITS_NO_UNITS, "no-units"}, - { UNITS_PARTS_PER_MILLION, "parts-per-million"}, - { UNITS_PARTS_PER_BILLION, "parts-per-billion"}, - { UNITS_PERCENT, "percent"}, - { UNITS_PERCENT_PER_SECOND, "percent-per-second"}, - { UNITS_PER_MINUTE, "per-minute"}, - { UNITS_PER_SECOND, "per-second"}, - { UNITS_PSI_PER_DEGREE_FAHRENHEIT, "psi-per-degree-fahrenheit"}, - { UNITS_RADIANS, "radians"}, - { UNITS_REVOLUTIONS_PER_MINUTE, "revolutions-per-minute"}, - { UNITS_CURRENCY1, "currency1"}, - { UNITS_CURRENCY2, "currency2"}, - { UNITS_CURRENCY3, "currency3"}, - { UNITS_CURRENCY4, "currency4"}, - { UNITS_CURRENCY5, "currency5"}, - { UNITS_CURRENCY6, "currency6"}, - { UNITS_CURRENCY7, "currency7"}, - { UNITS_CURRENCY8, "currency8"}, - { UNITS_CURRENCY9, "currency9"}, - { UNITS_CURRENCY10, "currency10"}, - { UNITS_SQUARE_INCHES, "square-inches"}, - { UNITS_SQUARE_CENTIMETERS, "square-centimeters"}, - { UNITS_BTUS_PER_POUND, "btus_per-pound"}, - { UNITS_CENTIMETERS, "centimeters"}, - { UNITS_POUNDS_MASS_PER_SECOND, "pounds-mass-per-second"}, - { UNITS_DELTA_DEGREES_FAHRENHEIT, "delta-degrees-fahrenheit"}, - { UNITS_DELTA_DEGREES_KELVIN, "delta-degrees-kelvin"}, - { UNITS_KILOHMS, "kilohms"}, - { UNITS_MEGOHMS, "megohms"}, - { UNITS_MILLIVOLTS, "millivolts"}, - { UNITS_KILOJOULES_PER_KILOGRAM, "kilojoules-per-kilogram"}, - { UNITS_MEGAJOULES, "megajoules"}, - { UNITS_JOULES_PER_DEGREE_KELVIN, "joules-per-degree-kelvin"}, - { UNITS_JOULES_PER_KILOGRAM_DEGREE_KELVIN, "joules-per-kilogram-degree-kelvin"}, - { UNITS_KILOHERTZ, "kilohertz"}, - { UNITS_MEGAHERTZ, "megahertz"}, - { UNITS_PER_HOUR, "per-hour"}, - { UNITS_MILLIWATTS, "milliwatts"}, - { UNITS_HECTOPASCALS, "hectopascals"}, - { UNITS_MILLIBARS, "millibars"}, - { UNITS_CUBIC_METERS_PER_HOUR, "cubic-meters-per-hour"}, - { UNITS_LITERS_PER_HOUR, "liters-per-hour"}, - { UNITS_KILOWATT_HOURS_PER_SQUARE_METER, "kilowatt-hours-per-square-meter"}, - { UNITS_KILOWATT_HOURS_PER_SQUARE_FOOT, "kilowatt-hours-per-square-foot"}, - { UNITS_MEGAJOULES_PER_SQUARE_METER, "megajoules-per-square-meter"}, - { UNITS_MEGAJOULES_PER_SQUARE_FOOT, "megajoules-per-square-foot"}, - { UNITS_CUBIC_FEET_PER_SECOND, "cubic-feet-per-second"}, - { UNITS_WATTS_PER_SQUARE_METER_DEGREE_KELVIN, "watts-per-square-meter-degree-kelvin"}, - { UNITS_PERCENT_OBSCURATION_PER_FOOT, "percent-obscuration-per-foot"}, - { UNITS_PERCENT_OBSCURATION_PER_METER, "percent-obscuration-per-meter"}, - { UNITS_MILLIOHMS, "milliohms"}, - { UNITS_MEGAWATT_HOURS, "megawatt-hours"}, - { UNITS_KILO_BTUS, "kilo-btus"}, - { UNITS_MEGA_BTUS, "mega-btus"}, - { UNITS_KILOJOULES_PER_KILOGRAM_DRY_AIR, "kilojoules-per-kilogram-dry-air"}, - { UNITS_MEGAJOULES_PER_KILOGRAM_DRY_AIR, "megajoules-per-kilogram-dry-air"}, - { UNITS_KILOJOULES_PER_DEGREE_KELVIN, "kilojoules-per-degree-Kelvin"}, - { UNITS_MEGAJOULES_PER_DEGREE_KELVIN, "megajoules-per-degree-Kelvin"}, - { UNITS_NEWTON, "newton"}, - { UNITS_GRAMS_PER_SECOND, "grams-per-second"}, - { UNITS_GRAMS_PER_MINUTE, "grams-per-minute"}, - { UNITS_TONS_PER_HOUR, "tons-per-hour"}, - { UNITS_KILO_BTUS_PER_HOUR, "kilo-btus-per-hour"}, - { UNITS_HUNDREDTHS_SECONDS, "hundredths-seconds"}, - { UNITS_MILLISECONDS, "milliseconds"}, - { UNITS_NEWTON_METERS, "newton-meters"}, - { UNITS_MILLIMETERS_PER_SECOND, "millimeters-per-second"}, - { UNITS_MILLIMETERS_PER_MINUTE, "millimeters-per-minute"}, - { UNITS_METERS_PER_MINUTE, "meters-per-minute"}, - { UNITS_METERS_PER_HOUR, "meters-per-hour"}, - { UNITS_CUBIC_METERS_PER_MINUTE, "cubic-meters-per-minute"}, - { UNITS_METERS_PER_SECOND_PER_SECOND, "meters-per-second-per-second"}, - { UNITS_AMPERES_PER_METER, "amperes-per-meter"}, - { UNITS_AMPERES_PER_SQUARE_METER, "amperes-per-square-meter"}, - { UNITS_AMPERE_SQUARE_METERS, "ampere-square-meters"}, - { UNITS_FARADS, "farads"}, - { UNITS_HENRYS, "henrys"}, - { UNITS_OHM_METERS, "ohm-meters"}, - { UNITS_SIEMENS, "siemens"}, - { UNITS_SIEMENS_PER_METER, "siemens-per-meter"}, - { UNITS_TESLAS, "teslas"}, - { UNITS_VOLTS_PER_DEGREE_KELVIN, "volts-per-degree-Kelvin"}, - { UNITS_VOLTS_PER_METER, "volts-per-meter"}, - { UNITS_WEBERS, "webers"}, - { UNITS_CANDELAS, "candelas"}, - { UNITS_CANDELAS_PER_SQUARE_METER, "candelas-per-square-meter"}, - { UNITS_DEGREES_KELVIN_PER_HOUR, "degrees-Kelvin-per-hour"}, - { UNITS_DEGREES_KELVIN_PER_MINUTE, "degrees-Kelvin-per-minute"}, - { UNITS_JOULE_SECONDS, "joule-seconds"}, - { UNITS_RADIANS_PER_SECOND, "radians-per-second"}, - { UNITS_SQUARE_METERS_PER_NEWTON, "square-meters-per-Newton"}, - { UNITS_KILOGRAMS_PER_CUBIC_METER, "kilograms-per-cubic-meter"}, - { UNITS_NEWTON_SECONDS, "newton-seconds"}, - { UNITS_NEWTONS_PER_METER, "newtons-per-meter"}, - { UNITS_WATTS_PER_METER_PER_DEGREE_KELVIN, "watts-per-meter-per-degree-Kelvin"}, - { 0, NULL} + {UNITS_SQUARE_METERS, "square-meters"} + , + {UNITS_SQUARE_FEET, "square-feet"} + , + {UNITS_MILLIAMPERES, "milliamperes"} + , + {UNITS_AMPERES, "amperes"} + , + {UNITS_OHMS, "ohms"} + , + {UNITS_VOLTS, "volts"} + , + {UNITS_KILOVOLTS, "kilovolts"} + , + {UNITS_MEGAVOLTS, "megavolts"} + , + {UNITS_VOLT_AMPERES, "volt-amperes"} + , + {UNITS_KILOVOLT_AMPERES, "kilovolt-amperes"} + , + {UNITS_MEGAVOLT_AMPERES, "megavolt-amperes"} + , + {UNITS_VOLT_AMPERES_REACTIVE, "volt-amperes-reactive"} + , + {UNITS_KILOVOLT_AMPERES_REACTIVE, "kilovolt-amperes-reactive"} + , + {UNITS_MEGAVOLT_AMPERES_REACTIVE, "megavolt-amperes-reactive"} + , + {UNITS_DEGREES_PHASE, "degrees-phase"} + , + {UNITS_POWER_FACTOR, "power-factor"} + , + {UNITS_JOULES, "joules"} + , + {UNITS_KILOJOULES, "kilojoules"} + , + {UNITS_WATT_HOURS, "watt-hours"} + , + {UNITS_KILOWATT_HOURS, "kilowatt-hours"} + , + {UNITS_BTUS, "btus"} + , + {UNITS_THERMS, "therms"} + , + {UNITS_TON_HOURS, "ton-hours"} + , + {UNITS_JOULES_PER_KILOGRAM_DRY_AIR, "joules-per-kilogram-dry-air"} + , + {UNITS_BTUS_PER_POUND_DRY_AIR, "btus-per-pound-dry-air"} + , + {UNITS_CYCLES_PER_HOUR, "cycles-per-hour"} + , + {UNITS_CYCLES_PER_MINUTE, "cycles-per-minute"} + , + {UNITS_HERTZ, "hertz"} + , + {UNITS_GRAMS_OF_WATER_PER_KILOGRAM_DRY_AIR, + "grams-of-water-per-kilogram-dry-air"} + , + {UNITS_PERCENT_RELATIVE_HUMIDITY, "percent-relative-humidity"} + , + {UNITS_MILLIMETERS, "millimeters"} + , + {UNITS_METERS, "meters"} + , + {UNITS_INCHES, "inches"} + , + {UNITS_FEET, "feet"} + , + {UNITS_WATTS_PER_SQUARE_FOOT, "watts-per-square-foot"} + , + {UNITS_WATTS_PER_SQUARE_METER, "watts-per-square-meter"} + , + {UNITS_LUMENS, "lumens"} + , + {UNITS_LUXES, "luxes"} + , + {UNITS_FOOT_CANDLES, "foot-candles"} + , + {UNITS_KILOGRAMS, "kilograms"} + , + {UNITS_POUNDS_MASS, "pounds-mass"} + , + {UNITS_TONS, "tons"} + , + {UNITS_KILOGRAMS_PER_SECOND, "kilograms-per-second"} + , + {UNITS_KILOGRAMS_PER_MINUTE, "kilograms-per-minute"} + , + {UNITS_KILOGRAMS_PER_HOUR, "kilograms-per-hour"} + , + {UNITS_POUNDS_MASS_PER_MINUTE, "pounds-mass-per-minute"} + , + {UNITS_POUNDS_MASS_PER_HOUR, "pounds-mass-per-hour"} + , + {UNITS_WATTS, "watts"} + , + {UNITS_KILOWATTS, "kilowatts"} + , + {UNITS_MEGAWATTS, "megawatts"} + , + {UNITS_BTUS_PER_HOUR, "btus-per-hour"} + , + {UNITS_HORSEPOWER, "horsepower"} + , + {UNITS_TONS_REFRIGERATION, "tons-refrigeration"} + , + {UNITS_PASCALS, "pascals"} + , + {UNITS_KILOPASCALS, "kilopascals"} + , + {UNITS_BARS, "bars"} + , + {UNITS_POUNDS_FORCE_PER_SQUARE_INCH, "pounds-force-per-square-inch"} + , + {UNITS_CENTIMETERS_OF_WATER, "centimeters-of-water"} + , + {UNITS_INCHES_OF_WATER, "inches-of-water"} + , + {UNITS_MILLIMETERS_OF_MERCURY, "millimeters-of-mercury"} + , + {UNITS_CENTIMETERS_OF_MERCURY, "centimeters-of-mercury"} + , + {UNITS_INCHES_OF_MERCURY, "inches-of-mercury"} + , + {UNITS_DEGREES_CELSIUS, "degrees-celsius"} + , + {UNITS_DEGREES_KELVIN, "degrees-kelvin"} + , + {UNITS_DEGREES_FAHRENHEIT, "degrees-fahrenheit"} + , + {UNITS_DEGREE_DAYS_CELSIUS, "degree-days-celsius"} + , + {UNITS_DEGREE_DAYS_FAHRENHEIT, "degree-days-fahrenheit"} + , + {UNITS_YEARS, "years"} + , + {UNITS_MONTHS, "months"} + , + {UNITS_WEEKS, "weeks"} + , + {UNITS_DAYS, "days"} + , + {UNITS_HOURS, "hours"} + , + {UNITS_MINUTES, "minutes"} + , + {UNITS_SECONDS, "secondS"} + , + {UNITS_METERS_PER_SECOND, "meters-per-second"} + , + {UNITS_KILOMETERS_PER_HOUR, "kilometers-per-hour"} + , + {UNITS_FEET_PER_SECOND, "feet-per-second"} + , + {UNITS_FEET_PER_MINUTE, "feet-per-minute"} + , + {UNITS_MILES_PER_HOUR, "miles-per-hour"} + , + {UNITS_CUBIC_FEET, "cubic-feet"} + , + {UNITS_CUBIC_METERS, "cubic-meters"} + , + {UNITS_IMPERIAL_GALLONS, "imperial-gallons"} + , + {UNITS_LITERS, "liters"} + , + {UNITS_US_GALLONS, "us-gallons"} + , + {UNITS_CUBIC_FEET_PER_MINUTE, "cubic-feet-per-minute"} + , + {UNITS_CUBIC_METERS_PER_SECOND, "cubic-meters-per-second"} + , + {UNITS_IMPERIAL_GALLONS_PER_MINUTE, "imperial-gallons-per-minute"} + , + {UNITS_LITERS_PER_SECOND, "liters-per-second"} + , + {UNITS_LITERS_PER_MINUTE, "liters-per-minute"} + , + {UNITS_US_GALLONS_PER_MINUTE, "us-gallons-per-minute"} + , + {UNITS_DEGREES_ANGULAR, "degrees-angular"} + , + {UNITS_DEGREES_CELSIUS_PER_HOUR, "degrees-celsius-per-hour"} + , + {UNITS_DEGREES_CELSIUS_PER_MINUTE, "degrees-celsius-per-minute"} + , + {UNITS_DEGREES_FAHRENHEIT_PER_HOUR, "degrees-fahrenheit-per-hour"} + , + {UNITS_DEGREES_FAHRENHEIT_PER_MINUTE, "degrees-fahrenheit-per-minute"} + , + {UNITS_NO_UNITS, "no-units"} + , + {UNITS_PARTS_PER_MILLION, "parts-per-million"} + , + {UNITS_PARTS_PER_BILLION, "parts-per-billion"} + , + {UNITS_PERCENT, "percent"} + , + {UNITS_PERCENT_PER_SECOND, "percent-per-second"} + , + {UNITS_PER_MINUTE, "per-minute"} + , + {UNITS_PER_SECOND, "per-second"} + , + {UNITS_PSI_PER_DEGREE_FAHRENHEIT, "psi-per-degree-fahrenheit"} + , + {UNITS_RADIANS, "radians"} + , + {UNITS_REVOLUTIONS_PER_MINUTE, "revolutions-per-minute"} + , + {UNITS_CURRENCY1, "currency1"} + , + {UNITS_CURRENCY2, "currency2"} + , + {UNITS_CURRENCY3, "currency3"} + , + {UNITS_CURRENCY4, "currency4"} + , + {UNITS_CURRENCY5, "currency5"} + , + {UNITS_CURRENCY6, "currency6"} + , + {UNITS_CURRENCY7, "currency7"} + , + {UNITS_CURRENCY8, "currency8"} + , + {UNITS_CURRENCY9, "currency9"} + , + {UNITS_CURRENCY10, "currency10"} + , + {UNITS_SQUARE_INCHES, "square-inches"} + , + {UNITS_SQUARE_CENTIMETERS, "square-centimeters"} + , + {UNITS_BTUS_PER_POUND, "btus_per-pound"} + , + {UNITS_CENTIMETERS, "centimeters"} + , + {UNITS_POUNDS_MASS_PER_SECOND, "pounds-mass-per-second"} + , + {UNITS_DELTA_DEGREES_FAHRENHEIT, "delta-degrees-fahrenheit"} + , + {UNITS_DELTA_DEGREES_KELVIN, "delta-degrees-kelvin"} + , + {UNITS_KILOHMS, "kilohms"} + , + {UNITS_MEGOHMS, "megohms"} + , + {UNITS_MILLIVOLTS, "millivolts"} + , + {UNITS_KILOJOULES_PER_KILOGRAM, "kilojoules-per-kilogram"} + , + {UNITS_MEGAJOULES, "megajoules"} + , + {UNITS_JOULES_PER_DEGREE_KELVIN, "joules-per-degree-kelvin"} + , + {UNITS_JOULES_PER_KILOGRAM_DEGREE_KELVIN, + "joules-per-kilogram-degree-kelvin"} + , + {UNITS_KILOHERTZ, "kilohertz"} + , + {UNITS_MEGAHERTZ, "megahertz"} + , + {UNITS_PER_HOUR, "per-hour"} + , + {UNITS_MILLIWATTS, "milliwatts"} + , + {UNITS_HECTOPASCALS, "hectopascals"} + , + {UNITS_MILLIBARS, "millibars"} + , + {UNITS_CUBIC_METERS_PER_HOUR, "cubic-meters-per-hour"} + , + {UNITS_LITERS_PER_HOUR, "liters-per-hour"} + , + {UNITS_KILOWATT_HOURS_PER_SQUARE_METER, + "kilowatt-hours-per-square-meter"} + , + {UNITS_KILOWATT_HOURS_PER_SQUARE_FOOT, "kilowatt-hours-per-square-foot"} + , + {UNITS_MEGAJOULES_PER_SQUARE_METER, "megajoules-per-square-meter"} + , + {UNITS_MEGAJOULES_PER_SQUARE_FOOT, "megajoules-per-square-foot"} + , + {UNITS_CUBIC_FEET_PER_SECOND, "cubic-feet-per-second"} + , + {UNITS_WATTS_PER_SQUARE_METER_DEGREE_KELVIN, + "watts-per-square-meter-degree-kelvin"} + , + {UNITS_PERCENT_OBSCURATION_PER_FOOT, "percent-obscuration-per-foot"} + , + {UNITS_PERCENT_OBSCURATION_PER_METER, "percent-obscuration-per-meter"} + , + {UNITS_MILLIOHMS, "milliohms"} + , + {UNITS_MEGAWATT_HOURS, "megawatt-hours"} + , + {UNITS_KILO_BTUS, "kilo-btus"} + , + {UNITS_MEGA_BTUS, "mega-btus"} + , + {UNITS_KILOJOULES_PER_KILOGRAM_DRY_AIR, + "kilojoules-per-kilogram-dry-air"} + , + {UNITS_MEGAJOULES_PER_KILOGRAM_DRY_AIR, + "megajoules-per-kilogram-dry-air"} + , + {UNITS_KILOJOULES_PER_DEGREE_KELVIN, "kilojoules-per-degree-Kelvin"} + , + {UNITS_MEGAJOULES_PER_DEGREE_KELVIN, "megajoules-per-degree-Kelvin"} + , + {UNITS_NEWTON, "newton"} + , + {UNITS_GRAMS_PER_SECOND, "grams-per-second"} + , + {UNITS_GRAMS_PER_MINUTE, "grams-per-minute"} + , + {UNITS_TONS_PER_HOUR, "tons-per-hour"} + , + {UNITS_KILO_BTUS_PER_HOUR, "kilo-btus-per-hour"} + , + {UNITS_HUNDREDTHS_SECONDS, "hundredths-seconds"} + , + {UNITS_MILLISECONDS, "milliseconds"} + , + {UNITS_NEWTON_METERS, "newton-meters"} + , + {UNITS_MILLIMETERS_PER_SECOND, "millimeters-per-second"} + , + {UNITS_MILLIMETERS_PER_MINUTE, "millimeters-per-minute"} + , + {UNITS_METERS_PER_MINUTE, "meters-per-minute"} + , + {UNITS_METERS_PER_HOUR, "meters-per-hour"} + , + {UNITS_CUBIC_METERS_PER_MINUTE, "cubic-meters-per-minute"} + , + {UNITS_METERS_PER_SECOND_PER_SECOND, "meters-per-second-per-second"} + , + {UNITS_AMPERES_PER_METER, "amperes-per-meter"} + , + {UNITS_AMPERES_PER_SQUARE_METER, "amperes-per-square-meter"} + , + {UNITS_AMPERE_SQUARE_METERS, "ampere-square-meters"} + , + {UNITS_FARADS, "farads"} + , + {UNITS_HENRYS, "henrys"} + , + {UNITS_OHM_METERS, "ohm-meters"} + , + {UNITS_SIEMENS, "siemens"} + , + {UNITS_SIEMENS_PER_METER, "siemens-per-meter"} + , + {UNITS_TESLAS, "teslas"} + , + {UNITS_VOLTS_PER_DEGREE_KELVIN, "volts-per-degree-Kelvin"} + , + {UNITS_VOLTS_PER_METER, "volts-per-meter"} + , + {UNITS_WEBERS, "webers"} + , + {UNITS_CANDELAS, "candelas"} + , + {UNITS_CANDELAS_PER_SQUARE_METER, "candelas-per-square-meter"} + , + {UNITS_DEGREES_KELVIN_PER_HOUR, "degrees-Kelvin-per-hour"} + , + {UNITS_DEGREES_KELVIN_PER_MINUTE, "degrees-Kelvin-per-minute"} + , + {UNITS_JOULE_SECONDS, "joule-seconds"} + , + {UNITS_RADIANS_PER_SECOND, "radians-per-second"} + , + {UNITS_SQUARE_METERS_PER_NEWTON, "square-meters-per-Newton"} + , + {UNITS_KILOGRAMS_PER_CUBIC_METER, "kilograms-per-cubic-meter"} + , + {UNITS_NEWTON_SECONDS, "newton-seconds"} + , + {UNITS_NEWTONS_PER_METER, "newtons-per-meter"} + , + {UNITS_WATTS_PER_METER_PER_DEGREE_KELVIN, + "watts-per-meter-per-degree-Kelvin"} + , + {0, NULL} /* Enumerated values 0-255 are reserved for definition by ASHRAE. Enumerated values 256-65535 may be used by others subject to the procedures and constraints described in Clause 23. */ - }; +}; const char *bactext_engineering_unit_name(int index) { - return indtext_by_index_split_default( - bacnet_engineering_unit_names, - index, - 256, - ASHRAE_Reserved_String, - Vendor_Proprietary_String); + return indtext_by_index_split_default(bacnet_engineering_unit_names, + index, 256, ASHRAE_Reserved_String, Vendor_Proprietary_String); } INDTEXT_DATA bacnet_reject_reason_names[] = { - {REJECT_REASON_OTHER, "Other"}, - {REJECT_REASON_BUFFER_OVERFLOW, "Buffer Overflow"}, - {REJECT_REASON_INCONSISTENT_PARAMETERS, "Inconsistent Parameters"}, - {REJECT_REASON_INVALID_PARAMETER_DATA_TYPE, "Invalid Parameter Data Type"}, - {REJECT_REASON_INVALID_TAG, "Invalid Tag"}, - {REJECT_REASON_MISSING_REQUIRED_PARAMETER, "Missing Required Parameter"}, - {REJECT_REASON_PARAMETER_OUT_OF_RANGE, "Parameter Out of Range"}, - {REJECT_REASON_TOO_MANY_ARGUMENTS, "Too Many Arguments"}, - {REJECT_REASON_UNDEFINED_ENUMERATION, "Undefined Enumeration"}, - {REJECT_REASON_UNRECOGNIZED_SERVICE, "Unrecognized Service"}, - {0,NULL} + {REJECT_REASON_OTHER, "Other"} + , + {REJECT_REASON_BUFFER_OVERFLOW, "Buffer Overflow"} + , + {REJECT_REASON_INCONSISTENT_PARAMETERS, "Inconsistent Parameters"} + , + {REJECT_REASON_INVALID_PARAMETER_DATA_TYPE, + "Invalid Parameter Data Type"} + , + {REJECT_REASON_INVALID_TAG, "Invalid Tag"} + , + {REJECT_REASON_MISSING_REQUIRED_PARAMETER, "Missing Required Parameter"} + , + {REJECT_REASON_PARAMETER_OUT_OF_RANGE, "Parameter Out of Range"} + , + {REJECT_REASON_TOO_MANY_ARGUMENTS, "Too Many Arguments"} + , + {REJECT_REASON_UNDEFINED_ENUMERATION, "Undefined Enumeration"} + , + {REJECT_REASON_UNRECOGNIZED_SERVICE, "Unrecognized Service"} + , + {0, NULL} }; const char *bactext_reject_reason_name(int index) { - return indtext_by_index_split_default( - bacnet_reject_reason_names, - index, - FIRST_PROPRIETARY_REJECT_REASON, - ASHRAE_Reserved_String, - Vendor_Proprietary_String); + return indtext_by_index_split_default(bacnet_reject_reason_names, + index, + FIRST_PROPRIETARY_REJECT_REASON, + ASHRAE_Reserved_String, Vendor_Proprietary_String); } INDTEXT_DATA bacnet_abort_reason_names[] = { - { ABORT_REASON_OTHER, "Other"}, - { ABORT_REASON_BUFFER_OVERFLOW, "Buffer Overflow"}, - { ABORT_REASON_INVALID_APDU_IN_THIS_STATE, "Invalid APDU in this State"}, - { ABORT_REASON_PREEMPTED_BY_HIGHER_PRIORITY_TASK, "Preempted by Higher Priority Task"}, - { ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, "Segmentation Not Supported"}, - {0,NULL} + {ABORT_REASON_OTHER, "Other"} + , + {ABORT_REASON_BUFFER_OVERFLOW, "Buffer Overflow"} + , + {ABORT_REASON_INVALID_APDU_IN_THIS_STATE, "Invalid APDU in this State"} + , + {ABORT_REASON_PREEMPTED_BY_HIGHER_PRIORITY_TASK, + "Preempted by Higher Priority Task"} + , + {ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, "Segmentation Not Supported"} + , + {0, NULL} }; const char *bactext_abort_reason_name(int index) { - return indtext_by_index_split_default( - bacnet_abort_reason_names, - index, - FIRST_PROPRIETARY_ABORT_REASON, - ASHRAE_Reserved_String, - Vendor_Proprietary_String); + return indtext_by_index_split_default(bacnet_abort_reason_names, + index, + FIRST_PROPRIETARY_ABORT_REASON, + ASHRAE_Reserved_String, Vendor_Proprietary_String); } INDTEXT_DATA bacnet_error_class_names[] = { - { ERROR_CLASS_DEVICE, "device"}, - { ERROR_CLASS_OBJECT, "object"}, - { ERROR_CLASS_PROPERTY, "property"}, - { ERROR_CLASS_RESOURCES, "resources"}, - { ERROR_CLASS_SECURITY, "security"}, - { ERROR_CLASS_SERVICES, "services"}, - { ERROR_CLASS_VT, "vt"}, - {0,NULL} + {ERROR_CLASS_DEVICE, "device"} + , + {ERROR_CLASS_OBJECT, "object"} + , + {ERROR_CLASS_PROPERTY, "property"} + , + {ERROR_CLASS_RESOURCES, "resources"} + , + {ERROR_CLASS_SECURITY, "security"} + , + {ERROR_CLASS_SERVICES, "services"} + , + {ERROR_CLASS_VT, "vt"} + , + {0, NULL} }; const char *bactext_error_class_name(int index) { - return indtext_by_index_split_default( - bacnet_error_class_names, - index, - FIRST_PROPRIETARY_ERROR_CLASS, - ASHRAE_Reserved_String, - Vendor_Proprietary_String); + return indtext_by_index_split_default(bacnet_error_class_names, + index, + FIRST_PROPRIETARY_ERROR_CLASS, + ASHRAE_Reserved_String, Vendor_Proprietary_String); } INDTEXT_DATA bacnet_error_code_names[] = { - { ERROR_CODE_OTHER, "other"}, - { ERROR_CODE_AUTHENTICATION_FAILED, "authentication-failed"}, - { ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED, "character-set-not-supported"}, - { ERROR_CODE_CONFIGURATION_IN_PROGRESS, "configuration-in-progress"}, - { ERROR_CODE_DATATYPE_NOT_SUPPORTED, "datatype-not-supported"}, - { ERROR_CODE_DEVICE_BUSY, "device-busy"}, - { ERROR_CODE_DUPLICATE_NAME, "duplicate-name"}, - { ERROR_CODE_DUPLICATE_OBJECT_ID, "duplicate-object-id"}, - { ERROR_CODE_DYNAMIC_CREATION_NOT_SUPPORTED, "dynamic-creation-not-supported"}, - { ERROR_CODE_FILE_ACCESS_DENIED, "file-access-denied"}, - { ERROR_CODE_INCOMPATIBLE_SECURITY_LEVELS, "incompatible-security-levels"}, - { ERROR_CODE_INCONSISTENT_PARAMETERS, "inconsistent-parameters"}, - { ERROR_CODE_INCONSISTENT_SELECTION_CRITERION, "inconsistent-selection-criterion"}, - { ERROR_CODE_INVALID_ARRAY_INDEX, "invalid-array-index"}, - { ERROR_CODE_INVALID_CONFIGURATION_DATA, "invalid-configuration-data"}, - { ERROR_CODE_INVALID_DATA_TYPE, "invalid-data-type"}, - { ERROR_CODE_INVALID_FILE_ACCESS_METHOD, "invalid-file-access-method"}, - { ERROR_CODE_ERROR_CODE_INVALID_FILE_START_POSITION, "error-code-invalid-file-start-position"}, - { ERROR_CODE_INVALID_OPERATOR_NAME, "invalid-operator-name"}, - { ERROR_CODE_INVALID_PARAMETER_DATA_TYPE, "invalid-parameter-data-type"}, - { ERROR_CODE_INVALID_TIME_STAMP, "invalid-time-stamp"}, - { ERROR_CODE_KEY_GENERATION_ERROR, "key-generation-error"}, - { ERROR_CODE_MISSING_REQUIRED_PARAMETER, "missing-required-parameter"}, - { ERROR_CODE_NO_OBJECTS_OF_SPECIFIED_TYPE, "no-objects-of-specified-type"}, - { ERROR_CODE_NO_SPACE_FOR_OBJECT, "no-space-for-object"}, - { ERROR_CODE_NO_SPACE_TO_ADD_LIST_ELEMENT, "no-space-to-add-list-element"}, - { ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY, "no-space-to-write-property"}, - { ERROR_CODE_NO_VT_SESSIONS_AVAILABLE, "no-vt-sessions-available"}, - { ERROR_CODE_OBJECT_DELETION_NOT_PERMITTED, "object-deletion-not-permitted"}, - { ERROR_CODE_OBJECT_IDENTIFIER_ALREADY_EXISTS, "object-identifier-already-exists"}, - { ERROR_CODE_OPERATIONAL_PROBLEM, "operational-problem"}, - { ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED, "optional-functionality-not-supported"}, - { ERROR_CODE_PASSWORD_FAILURE, "password-failure"}, - { ERROR_CODE_PROPERTY_IS_NOT_A_LIST, "property-is-not-a-list"}, - { ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY, "property-is-not-an-array"}, - { ERROR_CODE_READ_ACCESS_DENIED, "read-access-denied"}, - { ERROR_CODE_SECURITY_NOT_SUPPORTED, "security-not-supported"}, - { ERROR_CODE_SERVICE_REQUEST_DENIED, "service-request-denied"}, - { ERROR_CODE_TIMEOUT, "timeout"}, - { ERROR_CODE_UNKNOWN_OBJECT, "unknown-object"}, - { ERROR_CODE_UNKNOWN_PROPERTY, "unknown-property"}, - { ERROR_CODE_RESERVED1, "reserved1"}, - { ERROR_CODE_UNKNOWN_VT_CLASS, "unknown-vt-class"}, - { ERROR_CODE_UNKNOWN_VT_SESSION, "unknown-vt-session"}, - { ERROR_CODE_UNSUPPORTED_OBJECT_TYPE, "unsupported-object-type"}, - { ERROR_CODE_VALUE_OUT_OF_RANGE, "value-out-of-range"}, - { ERROR_CODE_VT_SESSION_ALREADY_CLOSED, "vt-session-already-closed"}, - { ERROR_CODE_VT_SESSION_TERMINATION_FAILURE, "vt-session-termination-failure"}, - { ERROR_CODE_WRITE_ACCESS_DENIED, "write-access-denied"}, - { ERROR_CODE_COV_SUBSCRIPTION_FAILED, "cov-subscription-failed"}, - { ERROR_CODE_NOT_COV_PROPERTY, "not-cov-property"}, - {0,NULL} + {ERROR_CODE_OTHER, "other"} + , + {ERROR_CODE_AUTHENTICATION_FAILED, "authentication-failed"} + , + {ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED, "character-set-not-supported"} + , + {ERROR_CODE_CONFIGURATION_IN_PROGRESS, "configuration-in-progress"} + , + {ERROR_CODE_DATATYPE_NOT_SUPPORTED, "datatype-not-supported"} + , + {ERROR_CODE_DEVICE_BUSY, "device-busy"} + , + {ERROR_CODE_DUPLICATE_NAME, "duplicate-name"} + , + {ERROR_CODE_DUPLICATE_OBJECT_ID, "duplicate-object-id"} + , + {ERROR_CODE_DYNAMIC_CREATION_NOT_SUPPORTED, + "dynamic-creation-not-supported"} + , + {ERROR_CODE_FILE_ACCESS_DENIED, "file-access-denied"} + , + {ERROR_CODE_INCOMPATIBLE_SECURITY_LEVELS, + "incompatible-security-levels"} + , + {ERROR_CODE_INCONSISTENT_PARAMETERS, "inconsistent-parameters"} + , + {ERROR_CODE_INCONSISTENT_SELECTION_CRITERION, + "inconsistent-selection-criterion"} + , + {ERROR_CODE_INVALID_ARRAY_INDEX, "invalid-array-index"} + , + {ERROR_CODE_INVALID_CONFIGURATION_DATA, "invalid-configuration-data"} + , + {ERROR_CODE_INVALID_DATA_TYPE, "invalid-data-type"} + , + {ERROR_CODE_INVALID_FILE_ACCESS_METHOD, "invalid-file-access-method"} + , + {ERROR_CODE_ERROR_CODE_INVALID_FILE_START_POSITION, + "error-code-invalid-file-start-position"} + , + {ERROR_CODE_INVALID_OPERATOR_NAME, "invalid-operator-name"} + , + {ERROR_CODE_INVALID_PARAMETER_DATA_TYPE, "invalid-parameter-data-type"} + , + {ERROR_CODE_INVALID_TIME_STAMP, "invalid-time-stamp"} + , + {ERROR_CODE_KEY_GENERATION_ERROR, "key-generation-error"} + , + {ERROR_CODE_MISSING_REQUIRED_PARAMETER, "missing-required-parameter"} + , + {ERROR_CODE_NO_OBJECTS_OF_SPECIFIED_TYPE, + "no-objects-of-specified-type"} + , + {ERROR_CODE_NO_SPACE_FOR_OBJECT, "no-space-for-object"} + , + {ERROR_CODE_NO_SPACE_TO_ADD_LIST_ELEMENT, + "no-space-to-add-list-element"} + , + {ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY, "no-space-to-write-property"} + , + {ERROR_CODE_NO_VT_SESSIONS_AVAILABLE, "no-vt-sessions-available"} + , + {ERROR_CODE_OBJECT_DELETION_NOT_PERMITTED, + "object-deletion-not-permitted"} + , + {ERROR_CODE_OBJECT_IDENTIFIER_ALREADY_EXISTS, + "object-identifier-already-exists"} + , + {ERROR_CODE_OPERATIONAL_PROBLEM, "operational-problem"} + , + {ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED, + "optional-functionality-not-supported"} + , + {ERROR_CODE_PASSWORD_FAILURE, "password-failure"} + , + {ERROR_CODE_PROPERTY_IS_NOT_A_LIST, "property-is-not-a-list"} + , + {ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY, "property-is-not-an-array"} + , + {ERROR_CODE_READ_ACCESS_DENIED, "read-access-denied"} + , + {ERROR_CODE_SECURITY_NOT_SUPPORTED, "security-not-supported"} + , + {ERROR_CODE_SERVICE_REQUEST_DENIED, "service-request-denied"} + , + {ERROR_CODE_TIMEOUT, "timeout"} + , + {ERROR_CODE_UNKNOWN_OBJECT, "unknown-object"} + , + {ERROR_CODE_UNKNOWN_PROPERTY, "unknown-property"} + , + {ERROR_CODE_RESERVED1, "reserved1"} + , + {ERROR_CODE_UNKNOWN_VT_CLASS, "unknown-vt-class"} + , + {ERROR_CODE_UNKNOWN_VT_SESSION, "unknown-vt-session"} + , + {ERROR_CODE_UNSUPPORTED_OBJECT_TYPE, "unsupported-object-type"} + , + {ERROR_CODE_VALUE_OUT_OF_RANGE, "value-out-of-range"} + , + {ERROR_CODE_VT_SESSION_ALREADY_CLOSED, "vt-session-already-closed"} + , + {ERROR_CODE_VT_SESSION_TERMINATION_FAILURE, + "vt-session-termination-failure"} + , + {ERROR_CODE_WRITE_ACCESS_DENIED, "write-access-denied"} + , + {ERROR_CODE_COV_SUBSCRIPTION_FAILED, "cov-subscription-failed"} + , + {ERROR_CODE_NOT_COV_PROPERTY, "not-cov-property"} + , + {0, NULL} }; const char *bactext_error_code_name(int index) { - return indtext_by_index_split_default( - bacnet_error_code_names, - index, - FIRST_PROPRIETARY_ERROR_CLASS, - ASHRAE_Reserved_String, - Vendor_Proprietary_String); + return indtext_by_index_split_default(bacnet_error_code_names, + index, + FIRST_PROPRIETARY_ERROR_CLASS, + ASHRAE_Reserved_String, Vendor_Proprietary_String); } INDTEXT_DATA bacnet_month_names[] = { - {1, "January"}, - {2, "February"}, - {3, "March"}, - {4, "April"}, - {5, "May"}, - {6, "June"}, - {7, "July"}, - {8, "August"}, - {9, "September"}, - {10, "October"}, - {11, "November"}, - {12, "December"}, - {255,"Any Month"}, - {0,NULL} + {1, "January"} + , + {2, "February"} + , + {3, "March"} + , + {4, "April"} + , + {5, "May"} + , + {6, "June"} + , + {7, "July"} + , + {8, "August"} + , + {9, "September"} + , + {10, "October"} + , + {11, "November"} + , + {12, "December"} + , + {255, "Any Month"} + , + {0, NULL} }; const char *bactext_month_name(int index) { - return indtext_by_index_default( - bacnet_month_names, - index, - ASHRAE_Reserved_String); + return indtext_by_index_default(bacnet_month_names, + index, ASHRAE_Reserved_String); } INDTEXT_DATA bacnet_week_of_month_names[] = { - {1, "days numbered 1-7"}, - {2, "days numbered 8-14"}, - {3, "days numbered 15-21"}, - {4, "days numbered 22-28"}, - {5, "days numbered 29-31"}, - {6, "last 7 days of this month"}, - {255, "any week of this month"}, - {0,NULL} + {1, "days numbered 1-7"} + , + {2, "days numbered 8-14"} + , + {3, "days numbered 15-21"} + , + {4, "days numbered 22-28"} + , + {5, "days numbered 29-31"} + , + {6, "last 7 days of this month"} + , + {255, "any week of this month"} + , + {0, NULL} }; const char *bactext_week_of_month_name(int index) { - return indtext_by_index_default( - bacnet_week_of_month_names, - index, - ASHRAE_Reserved_String); + return indtext_by_index_default(bacnet_week_of_month_names, + index, ASHRAE_Reserved_String); } /* note: different than DaysOfWeek bit string where 0=monday */ INDTEXT_DATA bacnet_day_of_week_names[] = { - {1, "Monday"}, - {2, "Tuesday"}, - {3, "Wednesday"}, - {4, "Thursday"}, - {5, "Friday"}, - {6, "Saturday"}, - {7, "Sunday"}, - {255, "any day of week"}, - {0,NULL} + {1, "Monday"} + , + {2, "Tuesday"} + , + {3, "Wednesday"} + , + {4, "Thursday"} + , + {5, "Friday"} + , + {6, "Saturday"} + , + {7, "Sunday"} + , + {255, "any day of week"} + , + {0, NULL} }; const char *bactext_day_of_week_name(int index) { - return indtext_by_index_default( - bacnet_day_of_week_names, - index, - ASHRAE_Reserved_String); + return indtext_by_index_default(bacnet_day_of_week_names, + index, ASHRAE_Reserved_String); } INDTEXT_DATA bacnet_event_state_names[] = { - {EVENT_STATE_NORMAL, "normal"}, - {EVENT_STATE_FAULT, "fault"}, - {EVENT_STATE_OFFNORMAL, "offnormal"}, - {EVENT_STATE_HIGH_LIMIT, "high limit"}, - {EVENT_STATE_LOW_LIMIT, "low limit"}, - {0,NULL} + {EVENT_STATE_NORMAL, "normal"} + , + {EVENT_STATE_FAULT, "fault"} + , + {EVENT_STATE_OFFNORMAL, "offnormal"} + , + {EVENT_STATE_HIGH_LIMIT, "high limit"} + , + {EVENT_STATE_LOW_LIMIT, "low limit"} + , + {0, NULL} }; const char *bactext_event_state_name(int index) { - return indtext_by_index_default( - bacnet_event_state_names, - index, - ASHRAE_Reserved_String); + return indtext_by_index_default(bacnet_event_state_names, + index, ASHRAE_Reserved_String); } INDTEXT_DATA bacnet_binary_present_value_names[] = { - {BINARY_INACTIVE,"inactive"}, - {BINARY_ACTIVE,"active"}, - {0,NULL} + {BINARY_INACTIVE, "inactive"} + , + {BINARY_ACTIVE, "active"} + , + {0, NULL} }; const char *bactext_binary_present_value_name(int index) { - return indtext_by_index_default( - bacnet_binary_present_value_names, - index, - ASHRAE_Reserved_String); + return indtext_by_index_default(bacnet_binary_present_value_names, + index, ASHRAE_Reserved_String); } INDTEXT_DATA bacnet_reliability_names[] = { - {RELIABILITY_NO_FAULT_DETECTED,"no-fault-detected"}, - {RELIABILITY_NO_SENSOR,"no-sensor"}, - {RELIABILITY_OVER_RANGE,"over-range"}, - {RELIABILITY_UNDER_RANGE,"under-range"}, - {RELIABILITY_OPEN_LOOP,"open-loop"}, - {RELIABILITY_SHORTED_LOOP,"shorted-loop"}, - {RELIABILITY_NO_OUTPUT,"no-output"}, - {RELIABILITY_UNRELIABLE_OTHER,"unreliable-other"}, - {RELIABILITY_PROCESS_ERROR,"process-error"}, - {RELIABILITY_MULTI_STATE_FAULT,"mult-state-fault"}, - {RELIABILITY_CONFIGURATION_ERROR,"configuration-error"}, - {0,NULL} + {RELIABILITY_NO_FAULT_DETECTED, "no-fault-detected"} + , + {RELIABILITY_NO_SENSOR, "no-sensor"} + , + {RELIABILITY_OVER_RANGE, "over-range"} + , + {RELIABILITY_UNDER_RANGE, "under-range"} + , + {RELIABILITY_OPEN_LOOP, "open-loop"} + , + {RELIABILITY_SHORTED_LOOP, "shorted-loop"} + , + {RELIABILITY_NO_OUTPUT, "no-output"} + , + {RELIABILITY_UNRELIABLE_OTHER, "unreliable-other"} + , + {RELIABILITY_PROCESS_ERROR, "process-error"} + , + {RELIABILITY_MULTI_STATE_FAULT, "mult-state-fault"} + , + {RELIABILITY_CONFIGURATION_ERROR, "configuration-error"} + , + {0, NULL} }; const char *bactext_reliability_name(int index) { - return indtext_by_index_default( - bacnet_reliability_names, - index, - ASHRAE_Reserved_String); + return indtext_by_index_default(bacnet_reliability_names, + index, ASHRAE_Reserved_String); } INDTEXT_DATA bacnet_device_status_names[] = { - {STATUS_OPERATIONAL,"operational"}, - {STATUS_OPERATIONAL_READ_ONLY,"operational-read-only"}, - {STATUS_DOWNLOAD_REQUIRED,"download-required"}, - {STATUS_DOWNLOAD_IN_PROGRESS,"download-in-progress"}, - {STATUS_NON_OPERATIONAL,"non-operational"}, - {0,NULL} + {STATUS_OPERATIONAL, "operational"} + , + {STATUS_OPERATIONAL_READ_ONLY, "operational-read-only"} + , + {STATUS_DOWNLOAD_REQUIRED, "download-required"} + , + {STATUS_DOWNLOAD_IN_PROGRESS, "download-in-progress"} + , + {STATUS_NON_OPERATIONAL, "non-operational"} + , + {0, NULL} }; const char *bactext_device_status_name(int index) { - return indtext_by_index_default( - bacnet_device_status_names, - index, - ASHRAE_Reserved_String); + return indtext_by_index_default(bacnet_device_status_names, + index, ASHRAE_Reserved_String); } INDTEXT_DATA bacnet_segmentation_names[] = { - {SEGMENTATION_BOTH,"segmented-both"}, - {SEGMENTATION_TRANSMIT,"segmented-transmit"}, - {SEGMENTATION_RECEIVE,"segmented-receive"}, - {SEGMENTATION_NONE,"no-segmentation"}, - {0,NULL} + {SEGMENTATION_BOTH, "segmented-both"} + , + {SEGMENTATION_TRANSMIT, "segmented-transmit"} + , + {SEGMENTATION_RECEIVE, "segmented-receive"} + , + {SEGMENTATION_NONE, "no-segmentation"} + , + {0, NULL} }; const char *bactext_segmentation_name(int index) { - return indtext_by_index_default( - bacnet_segmentation_names, - index, - ASHRAE_Reserved_String); + return indtext_by_index_default(bacnet_segmentation_names, + index, ASHRAE_Reserved_String); } diff --git a/bacnet-stack/bactext.h b/bacnet-stack/bactext.h index 67f547da..351af244 100644 --- a/bacnet-stack/bactext.h +++ b/bacnet-stack/bactext.h @@ -40,31 +40,30 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ -const char *bactext_confirmed_service_name(int index); -const char *bactext_unconfirmed_service_name(int index); -const char *bactext_application_tag_name(int index); -const char *bactext_object_type_name(int index); -const char *bactext_property_name(int index); -const char *bactext_engineering_unit_name(int index); -const char *bactext_reject_reason_name(int index); -const char *bactext_abort_reason_name(int index); -const char *bactext_error_class_name(int index); -const char *bactext_error_code_name(int index); -unsigned bactext_property_id(const char* name); -const char *bactext_month_name(int index); -const char *bactext_week_of_month_name(int index); -const char *bactext_day_of_week_name(int index); -const char *bactext_event_state_name(int index); -const char *bactext_binary_present_value_name(int index); -const char *bactext_reliability_name(int index); -const char *bactext_device_status_name(int index); -const char *bactext_segmentation_name(int index); + const char *bactext_confirmed_service_name(int index); + const char *bactext_unconfirmed_service_name(int index); + const char *bactext_application_tag_name(int index); + const char *bactext_object_type_name(int index); + const char *bactext_property_name(int index); + const char *bactext_engineering_unit_name(int index); + const char *bactext_reject_reason_name(int index); + const char *bactext_abort_reason_name(int index); + const char *bactext_error_class_name(int index); + const char *bactext_error_code_name(int index); + unsigned bactext_property_id(const char *name); + const char *bactext_month_name(int index); + const char *bactext_week_of_month_name(int index); + const char *bactext_day_of_week_name(int index); + const char *bactext_event_state_name(int index); + const char *bactext_binary_present_value_name(int index); + const char *bactext_reliability_name(int index); + const char *bactext_device_status_name(int index); + const char *bactext_segmentation_name(int index); #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif diff --git a/bacnet-stack/bigend.h b/bacnet-stack/bigend.h index 1d1ad2d6..9841e07b 100644 --- a/bacnet-stack/bigend.h +++ b/bacnet-stack/bigend.h @@ -3,7 +3,7 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ // Big-Endian systems save the most significant byte first. // Sun and Motorola processors, IBM-370s and PDP-10s are big-endian. @@ -21,10 +21,9 @@ extern "C" { // x[2] = 0x03 // x[3] = 0x04 -int big_endian(void); + int big_endian(void); #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif diff --git a/bacnet-stack/bip.c b/bacnet-stack/bip.c index c0dcb35a..ed72b10b 100644 --- a/bacnet-stack/bip.c +++ b/bacnet-stack/bip.c @@ -36,7 +36,7 @@ #include // for the standard bool type. #include "bacdcode.h" #include "bip.h" -#include "net.h" // custom per port +#include "net.h" // custom per port static int BIP_Socket = -1; /* port to use - stored in host byte order */ @@ -48,21 +48,21 @@ static struct in_addr BIP_Broadcast_Address; void bip_set_socket(int sock_fd) { - BIP_Socket = sock_fd; + BIP_Socket = sock_fd; } bool bip_valid(void) { - return (BIP_Socket != -1); + return (BIP_Socket != -1); } void bip_cleanup(void) { - if (bip_valid()) - close(BIP_Socket); - BIP_Socket = -1; + if (bip_valid()) + close(BIP_Socket); + BIP_Socket = -1; - return; + return; } static void set_network_address(struct in_addr *net_address, @@ -71,32 +71,28 @@ static void set_network_address(struct in_addr *net_address, union { uint8_t byte[4]; uint32_t value; - } long_data = {{0}}; + } long_data = { { + 0}}; long_data.byte[0] = octet1; long_data.byte[1] = octet2; long_data.byte[2] = octet3; long_data.byte[3] = octet4; - + net_address->s_addr = long_data.value; } -void bip_set_address( - uint8_t octet1, - uint8_t octet2, - uint8_t octet3, - uint8_t octet4) +void bip_set_address(uint8_t octet1, + uint8_t octet2, uint8_t octet3, uint8_t octet4) { set_network_address(&BIP_Address, octet1, octet2, octet3, octet4); } -void bip_set_broadcast_address( - uint8_t octet1, - uint8_t octet2, - uint8_t octet3, - uint8_t octet4) +void bip_set_broadcast_address(uint8_t octet1, + uint8_t octet2, uint8_t octet3, uint8_t octet4) { - set_network_address(&BIP_Broadcast_Address, octet1, octet2, octet3, octet4); + set_network_address(&BIP_Broadcast_Address, octet1, octet2, octet3, + octet4); } // set using network byte order @@ -137,86 +133,81 @@ uint16_t bip_get_port(void) /* function to send a packet out the BACnet/IP socket (Annex J) */ /* returns number of bytes sent on success, negative number on failure */ -static int bip_send( - struct sockaddr_in *bip_dest, - uint8_t *pdu, // any data to be sent - may be null - unsigned pdu_len) // number of bytes of data +static int bip_send(struct sockaddr_in *bip_dest, uint8_t * pdu, // any data to be sent - may be null + unsigned pdu_len) // number of bytes of data { uint8_t mtu[MAX_MPDU] = { 0 }; int mtu_len = 0; int bytes_sent = 0; - + // assumes that the driver has already been initialized if (BIP_Socket < 0) return BIP_Socket; - mtu[0] = 0x81; /* BVLL for BACnet/IP */ + mtu[0] = 0x81; /* BVLL for BACnet/IP */ if (bip_dest->sin_addr.s_addr == htonl(BIP_Broadcast_Address.s_addr)) - mtu[1] = 0x0B; /* Original-Broadcast-NPDU */ + mtu[1] = 0x0B; /* Original-Broadcast-NPDU */ else - mtu[1] = 0x0A; /* Original-Unicast-NPDU */ + mtu[1] = 0x0A; /* Original-Unicast-NPDU */ mtu_len = 2; - mtu_len += encode_unsigned16(&mtu[mtu_len], (uint16_t)(pdu_len + 4/*inclusive*/) ); + mtu_len += + encode_unsigned16(&mtu[mtu_len], + (uint16_t) (pdu_len + 4 /*inclusive */ )); memcpy(&mtu[mtu_len], pdu, pdu_len); mtu_len += pdu_len; - + /* Send the packet */ - bytes_sent = sendto(BIP_Socket, (char *)mtu, mtu_len, 0, - (struct sockaddr *)bip_dest, - sizeof(struct sockaddr)); - + bytes_sent = sendto(BIP_Socket, (char *) mtu, mtu_len, 0, + (struct sockaddr *) bip_dest, sizeof(struct sockaddr)); + return bytes_sent; } /* function to send a packet out the BACnet/IP socket (Annex J) */ /* returns number of bytes sent on success, negative number on failure */ -int bip_send_pdu( - BACNET_ADDRESS *dest, // destination address - uint8_t *pdu, // any data to be sent - may be null - unsigned pdu_len) // number of bytes of data +int bip_send_pdu(BACNET_ADDRESS * dest, // destination address + uint8_t * pdu, // any data to be sent - may be null + unsigned pdu_len) // number of bytes of data { struct sockaddr_in bip_dest; /* load destination IP address */ bip_dest.sin_family = AF_INET; - if (dest->mac_len == 6) - { - (void)decode_unsigned32(&dest->mac[0], &(bip_dest.sin_addr.s_addr)); - (void)decode_unsigned16(&dest->mac[4], &(bip_dest.sin_port)); + if (dest->mac_len == 6) { + (void) decode_unsigned32(&dest->mac[0], + &(bip_dest.sin_addr.s_addr)); + (void) decode_unsigned16(&dest->mac[4], &(bip_dest.sin_port)); memset(&(bip_dest.sin_zero), '\0', 8); } /* broadcast */ - else if (dest->mac_len == 0) - { + else if (dest->mac_len == 0) { bip_dest.sin_addr.s_addr = htonl(BIP_Broadcast_Address.s_addr); bip_dest.sin_port = htons(BIP_Port); memset(&(bip_dest.sin_zero), '\0', 8); - } - else + } else return -1; /* function to send a packet out the BACnet/IP socket */ /* returns 1 on success, 0 on failure */ return bip_send(&bip_dest, // destination address - pdu, // any data to be sent - may be null - pdu_len); // number of bytes of data + pdu, // any data to be sent - may be null + pdu_len); // number of bytes of data } // receives a BACnet/IP packet // returns the number of octets in the PDU, or zero on failure -uint16_t bip_receive( - BACNET_ADDRESS *src, // source address - uint8_t *pdu, // PDU data - uint16_t max_pdu, // amount of space available in the PDU - unsigned timeout) // number of milliseconds to wait for a packet +uint16_t bip_receive(BACNET_ADDRESS * src, // source address + uint8_t * pdu, // PDU data + uint16_t max_pdu, // amount of space available in the PDU + unsigned timeout) // number of milliseconds to wait for a packet { int received_bytes; - uint8_t buf[MAX_MPDU] = {0}; // data - uint16_t pdu_len = 0; // return value + uint8_t buf[MAX_MPDU] = { 0 }; // data + uint16_t pdu_len = 0; // return value fd_set read_fds; int max; struct timeval select_timeout; - struct sockaddr_in sin = {-1}; + struct sockaddr_in sin = { -1 }; socklen_t sin_len = sizeof(sin); /* Make sure the socket is open */ @@ -226,25 +217,22 @@ uint16_t bip_receive( /* we could just use a non-blocking socket, but that consumes all the CPU time. We can use a timeout; it is only supported as a select. */ - if (timeout >= 1000) - { + if (timeout >= 1000) { select_timeout.tv_sec = timeout / 1000; - select_timeout.tv_usec = - 1000 * (timeout - select_timeout.tv_sec * 1000); - } - else - { + select_timeout.tv_usec = + 1000 * (timeout - select_timeout.tv_sec * 1000); + } else { select_timeout.tv_sec = 0; select_timeout.tv_usec = 1000 * timeout; } FD_ZERO(&read_fds); - FD_SET((unsigned int)BIP_Socket, &read_fds); + FD_SET((unsigned int) BIP_Socket, &read_fds); max = BIP_Socket; /* see if there is a packet for us */ if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) - received_bytes = recvfrom(BIP_Socket, - (char *)&buf[0], MAX_MPDU, 0, - (struct sockaddr *)&sin, &sin_len); + received_bytes = recvfrom(BIP_Socket, + (char *) &buf[0], MAX_MPDU, 0, + (struct sockaddr *) &sin, &sin_len); else return 0; @@ -256,33 +244,29 @@ uint16_t bip_receive( /* no problem, just no bytes */ if (received_bytes == 0) return 0; - + /* the signature of a BACnet/IP packet */ if (buf[0] != 0x81) return 0; /* Original-Broadcast-NPDU or Original-Unicast-NPDU */ - if ((buf[1] == 0x0B) || (buf[1] == 0x0A)) - { + if ((buf[1] == 0x0B) || (buf[1] == 0x0A)) { /* ignore messages from me */ if (sin.sin_addr.s_addr == BIP_Address.s_addr) pdu_len = 0; - else - { + else { /* copy the source address - FIXME: IPv6? */ + FIXME: IPv6? */ src->mac_len = 6; - (void)encode_unsigned32(&src->mac[0], - sin.sin_addr.s_addr); - (void)encode_unsigned16(&src->mac[4], - sin.sin_port); + (void) encode_unsigned32(&src->mac[0], sin.sin_addr.s_addr); + (void) encode_unsigned16(&src->mac[4], sin.sin_port); // FIXME: check destination address // see if it is broadcast or for us /* decode the length of the PDU - length is inclusive of BVLC */ - (void)decode_unsigned16(&buf[2],&pdu_len); + (void) decode_unsigned16(&buf[2], &pdu_len); /* copy the buffer into the PDU */ - pdu_len -= 4; /* BVLC header */ + pdu_len -= 4; /* BVLC header */ if (pdu_len < max_pdu) - memmove(&pdu[0],&buf[4],pdu_len); + memmove(&pdu[0], &buf[4], pdu_len); // ignore packets that are too large // clients should check my max-apdu first else @@ -293,46 +277,40 @@ uint16_t bip_receive( return pdu_len; } -void bip_get_my_address(BACNET_ADDRESS *my_address) +void bip_get_my_address(BACNET_ADDRESS * my_address) { - int i = 0; - - my_address->mac_len = 6; - (void)encode_unsigned32(&my_address->mac[0], - htonl(BIP_Address.s_addr)); - (void)encode_unsigned16(&my_address->mac[4], - htons(BIP_Port)); - my_address->net = 0; /* local only, no routing */ - my_address->len = 0; /* no SLEN */ - for (i = 0; i < MAX_MAC_LEN; i++) - { - /* no SADR */ - my_address->adr[i] = 0; - } + int i = 0; - return; -} - -void bip_get_broadcast_address( - BACNET_ADDRESS *dest) // destination address -{ - int i = 0; // counter - - if (dest) - { - dest->mac_len = 6; - (void)encode_unsigned32(&dest->mac[0], - htonl(BIP_Broadcast_Address.s_addr)); - (void)encode_unsigned16(&dest->mac[4], - htons(BIP_Port)); - dest->net = BACNET_BROADCAST_NETWORK; - dest->len = 0; /* no SLEN */ - for (i = 0; i < MAX_MAC_LEN; i++) - { - /* no SADR */ - dest->adr[i] = 0; + my_address->mac_len = 6; + (void) encode_unsigned32(&my_address->mac[0], + htonl(BIP_Address.s_addr)); + (void) encode_unsigned16(&my_address->mac[4], htons(BIP_Port)); + my_address->net = 0; /* local only, no routing */ + my_address->len = 0; /* no SLEN */ + for (i = 0; i < MAX_MAC_LEN; i++) { + /* no SADR */ + my_address->adr[i] = 0; } - } - return; + return; +} + +void bip_get_broadcast_address(BACNET_ADDRESS * dest) // destination address +{ + int i = 0; // counter + + if (dest) { + dest->mac_len = 6; + (void) encode_unsigned32(&dest->mac[0], + htonl(BIP_Broadcast_Address.s_addr)); + (void) encode_unsigned16(&dest->mac[4], htons(BIP_Port)); + dest->net = BACNET_BROADCAST_NETWORK; + dest->len = 0; /* no SLEN */ + for (i = 0; i < MAX_MAC_LEN; i++) { + /* no SADR */ + dest->adr[i] = 0; + } + } + + return; } diff --git a/bacnet-stack/bip.h b/bacnet-stack/bip.h index 6a59701a..f8d9e96d 100644 --- a/bacnet-stack/bip.h +++ b/bacnet-stack/bip.h @@ -46,58 +46,54 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ // note: define init and cleanup in your ports section -bool bip_init(void); + bool bip_init(void); // normal functions... -void bip_cleanup(void); -void bip_set_socket(int sock_fd); -bool bip_valid(void); -void bip_get_broadcast_address( - BACNET_ADDRESS *dest); // destination address -void bip_get_my_address(BACNET_ADDRESS *my_address); + void bip_cleanup(void); + void bip_set_socket(int sock_fd); + bool bip_valid(void); + void bip_get_broadcast_address(BACNET_ADDRESS * dest); // destination address + void bip_get_my_address(BACNET_ADDRESS * my_address); /* function to send a packet out the BACnet/IP socket */ /* returns zero on success, non-zero on failure */ -int bip_send_pdu( - BACNET_ADDRESS *dest, // destination address - uint8_t *pdu, // any data to be sent - may be null - unsigned pdu_len); // number of bytes of data + int bip_send_pdu(BACNET_ADDRESS * dest, // destination address + uint8_t * pdu, // any data to be sent - may be null + unsigned pdu_len); // number of bytes of data // receives a BACnet/IP packet // returns the number of octets in the PDU, or zero on failure -uint16_t bip_receive( - BACNET_ADDRESS *src, // source address - uint8_t *pdu, // PDU data - uint16_t max_pdu, // amount of space available in the PDU - unsigned timeout); // milliseconds to wait for a packet + uint16_t bip_receive(BACNET_ADDRESS * src, // source address + uint8_t * pdu, // PDU data + uint16_t max_pdu, // amount of space available in the PDU + unsigned timeout); // milliseconds to wait for a packet + + void bip_set_address(uint8_t octet1, uint8_t octet2, + uint8_t octet3, uint8_t octet4); + void bip_set_broadcast_address(uint8_t octet1, uint8_t octet2, + uint8_t octet3, uint8_t octet4); -void bip_set_address(uint8_t octet1, uint8_t octet2, - uint8_t octet3, uint8_t octet4); -void bip_set_broadcast_address(uint8_t octet1, uint8_t octet2, - uint8_t octet3, uint8_t octet4); - // use host byte order for setting -void bip_set_port(uint16_t port); + void bip_set_port(uint16_t port); // returns host byte order -uint16_t bip_get_port(void); + uint16_t bip_get_port(void); // use network byte order for setting -void bip_set_addr(uint32_t net_address); + void bip_set_addr(uint32_t net_address); // returns host byte order -uint32_t bip_get_addr(void); + uint32_t bip_get_addr(void); // use network byte order for setting -void bip_set_broadcast_addr(uint32_t net_address); + void bip_set_broadcast_addr(uint32_t net_address); // returns host byte order -uint32_t bip_get_broadcast_addr(void); + uint32_t bip_get_broadcast_addr(void); -void bip_set_interface(char *ifname); + void bip_set_interface(char *ifname); #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif diff --git a/bacnet-stack/bytes.h b/bacnet-stack/bytes.h index da209113..b77dd87b 100644 --- a/bacnet-stack/bytes.h +++ b/bacnet-stack/bytes.h @@ -7,11 +7,11 @@ #include #ifndef LO_NIB - #define LO_NIB(b) ((b) & 0xF) +#define LO_NIB(b) ((b) & 0xF) #endif #ifndef HI_NIB - #define HI_NIB(b) ((b) >> 4) +#define HI_NIB(b) ((b) >> 4) #endif @@ -19,7 +19,7 @@ #ifndef LO_BYTE - #define LO_BYTE(w) ((uint8_t)(w)) +#define LO_BYTE(w) ((uint8_t)(w)) #endif @@ -27,7 +27,7 @@ #ifndef HI_BYTE - #define HI_BYTE(w) ((uint8_t)((uint16_t)(w) >> 8)) +#define HI_BYTE(w) ((uint8_t)((uint16_t)(w) >> 8)) #endif @@ -35,7 +35,7 @@ #ifndef LO_WORD - #define LO_WORD(x) ((uint16_t)(x)) +#define LO_WORD(x) ((uint16_t)(x)) #endif @@ -43,7 +43,7 @@ #ifndef HI_WORD - #define HI_WORD(x) ((uint16_t)((uint32_t)(x) >> 16)) +#define HI_WORD(x) ((uint16_t)((uint32_t)(x) >> 16)) #endif @@ -51,7 +51,7 @@ #ifndef MAKE_WORD - #define MAKE_WORD(lo,hi) \ +#define MAKE_WORD(lo,hi) \ ((uint16_t)(((uint8_t)(lo))|(((uint16_t)((uint8_t)(hi)))<<8))) #endif @@ -60,12 +60,11 @@ #ifndef MAKE_LONG - #define MAKE_LONG(lo,hi) \ +#define MAKE_LONG(lo,hi) \ ((uint32_t)(((uint16_t)(lo))|(((uint32_t)((uint16_t)(hi)))<<16))) #endif -#endif // end of header file - +#endif // end of header file diff --git a/bacnet-stack/crc.c b/bacnet-stack/crc.c index 6c429155..3d088d03 100644 --- a/bacnet-stack/crc.c +++ b/bacnet-stack/crc.c @@ -43,17 +43,17 @@ // Note: This function is copied directly from the BACnet standard. uint8_t CRC_Calc_Header(uint8_t dataValue, uint8_t crcValue) { - uint16_t crc; + uint16_t crc; - crc = crcValue ^ dataValue; /* XOR C7..C0 with D7..D0 */ + crc = crcValue ^ dataValue; /* XOR C7..C0 with D7..D0 */ - /* Exclusive OR the terms in the table (top down) */ - crc = crc ^ (crc << 1) ^ (crc << 2) ^ (crc << 3) - ^ (crc << 4) ^ (crc << 5) ^ (crc << 6) - ^ (crc << 7); + /* Exclusive OR the terms in the table (top down) */ + crc = crc ^ (crc << 1) ^ (crc << 2) ^ (crc << 3) + ^ (crc << 4) ^ (crc << 5) ^ (crc << 6) + ^ (crc << 7); - /* Combine bits shifted out left hand end */ - return (crc & 0xfe) ^ ((crc >> 8) & 1); + /* Combine bits shifted out left hand end */ + return (crc & 0xfe) ^ ((crc >> 8) & 1); } // Accumulate "dataValue" into the CRC in crcValue. @@ -63,14 +63,14 @@ uint8_t CRC_Calc_Header(uint8_t dataValue, uint8_t crcValue) // Note: This function is copied directly from the BACnet standard. uint16_t CRC_Calc_Data(uint8_t dataValue, uint16_t crcValue) { - uint16_t crcLow; + uint16_t crcLow; - crcLow = (crcValue & 0xff) ^ dataValue; /* XOR C7..C0 with D7..D0 */ + crcLow = (crcValue & 0xff) ^ dataValue; /* XOR C7..C0 with D7..D0 */ - /* Exclusive OR the terms in the table (top down) */ - return (crcValue >>8) ^ (crcLow << 8) ^ (crcLow <<3) - ^ (crcLow <<12) ^ (crcLow >> 4) - ^ (crcLow & 0x0f) ^ ((crcLow & 0x0f) << 7); + /* Exclusive OR the terms in the table (top down) */ + return (crcValue >> 8) ^ (crcLow << 8) ^ (crcLow << 3) + ^ (crcLow << 12) ^ (crcLow >> 4) + ^ (crcLow & 0x0f) ^ ((crcLow & 0x0f) << 7); } #ifdef TEST @@ -80,50 +80,50 @@ uint16_t CRC_Calc_Data(uint8_t dataValue, uint16_t crcValue) #include "bytes.h" // test from Annex G 1.0 of BACnet Standard -void testCRC8(Test* pTest) +void testCRC8(Test * pTest) { - uint8_t crc = 0xff; // accumulates the crc value - uint8_t frame_crc; // appended to the end of the frame + uint8_t crc = 0xff; // accumulates the crc value + uint8_t frame_crc; // appended to the end of the frame - crc = CRC_Calc_Header(0x00,crc); - ct_test(pTest,crc == 0x55); - crc = CRC_Calc_Header(0x10,crc); - ct_test(pTest,crc == 0xC2); - crc = CRC_Calc_Header(0x05,crc); - ct_test(pTest,crc == 0xBC); - crc = CRC_Calc_Header(0x00,crc); - ct_test(pTest,crc == 0x95); - crc = CRC_Calc_Header(0x00,crc); - ct_test(pTest,crc == 0x73); - // send the ones complement of the CRC in place of - // the CRC, and the resulting CRC will always equal 0x55. - frame_crc = ~crc; - ct_test(pTest,frame_crc == 0x8C); - // use the ones complement value and the next to last CRC value - crc = CRC_Calc_Header(frame_crc,crc); - ct_test(pTest,crc == 0x55); + crc = CRC_Calc_Header(0x00, crc); + ct_test(pTest, crc == 0x55); + crc = CRC_Calc_Header(0x10, crc); + ct_test(pTest, crc == 0xC2); + crc = CRC_Calc_Header(0x05, crc); + ct_test(pTest, crc == 0xBC); + crc = CRC_Calc_Header(0x00, crc); + ct_test(pTest, crc == 0x95); + crc = CRC_Calc_Header(0x00, crc); + ct_test(pTest, crc == 0x73); + // send the ones complement of the CRC in place of + // the CRC, and the resulting CRC will always equal 0x55. + frame_crc = ~crc; + ct_test(pTest, frame_crc == 0x8C); + // use the ones complement value and the next to last CRC value + crc = CRC_Calc_Header(frame_crc, crc); + ct_test(pTest, crc == 0x55); } // test from Annex G 2.0 of BACnet Standard -void testCRC16(Test* pTest) +void testCRC16(Test * pTest) { - uint16_t crc = 0xffff; - uint16_t data_crc; + uint16_t crc = 0xffff; + uint16_t data_crc; - crc = CRC_Calc_Data(0x01,crc); - ct_test(pTest,crc == 0x1E0E); - crc = CRC_Calc_Data(0x22,crc); - ct_test(pTest,crc == 0xEB70); - crc = CRC_Calc_Data(0x30,crc); - ct_test(pTest,crc == 0x42EF); - // send the ones complement of the CRC in place of - // the CRC, and the resulting CRC will always equal 0xF0B8. - data_crc = ~crc; - ct_test(pTest,data_crc == 0xBD10); - crc = CRC_Calc_Data(LO_BYTE(data_crc),crc); - ct_test(pTest,crc == 0x0F3A); - crc = CRC_Calc_Data(HI_BYTE(data_crc),crc); - ct_test(pTest,crc == 0xF0B8); + crc = CRC_Calc_Data(0x01, crc); + ct_test(pTest, crc == 0x1E0E); + crc = CRC_Calc_Data(0x22, crc); + ct_test(pTest, crc == 0xEB70); + crc = CRC_Calc_Data(0x30, crc); + ct_test(pTest, crc == 0x42EF); + // send the ones complement of the CRC in place of + // the CRC, and the resulting CRC will always equal 0xF0B8. + data_crc = ~crc; + ct_test(pTest, data_crc == 0xBD10); + crc = CRC_Calc_Data(LO_BYTE(data_crc), crc); + ct_test(pTest, crc == 0x0F3A); + crc = CRC_Calc_Data(HI_BYTE(data_crc), crc); + ct_test(pTest, crc == 0xF0B8); } #endif @@ -131,23 +131,23 @@ void testCRC16(Test* pTest) #ifdef TEST_CRC int main(void) { - Test *pTest; - bool rc; + Test *pTest; + bool rc; - pTest = ct_create("crc", NULL); + pTest = ct_create("crc", NULL); - /* individual tests */ - rc = ct_addTestFunction(pTest, testCRC8); - assert(rc); - rc = ct_addTestFunction(pTest, testCRC16); - assert(rc); + /* individual tests */ + rc = ct_addTestFunction(pTest, testCRC8); + assert(rc); + rc = ct_addTestFunction(pTest, testCRC16); + assert(rc); - ct_setStream(pTest, stdout); - ct_run(pTest); - (void)ct_report(pTest); + ct_setStream(pTest, stdout); + ct_run(pTest); + (void) ct_report(pTest); - ct_destroy(pTest); + ct_destroy(pTest); - return 0; + return 0; } #endif diff --git a/bacnet-stack/crc.h b/bacnet-stack/crc.h index 2fc221cd..c0af37fc 100644 --- a/bacnet-stack/crc.h +++ b/bacnet-stack/crc.h @@ -40,13 +40,12 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ -uint8_t CRC_Calc_Header(uint8_t dataValue, uint8_t crcValue); -uint16_t CRC_Calc_Data(uint8_t dataValue, uint16_t crcValue); + uint8_t CRC_Calc_Header(uint8_t dataValue, uint8_t crcValue); + uint16_t CRC_Calc_Data(uint8_t dataValue, uint16_t crcValue); #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif diff --git a/bacnet-stack/datalink.c b/bacnet-stack/datalink.c index 77df8ba1..c638ab8f 100644 --- a/bacnet-stack/datalink.c +++ b/bacnet-stack/datalink.c @@ -41,121 +41,88 @@ // as part of the calls. /* returns number of bytes sent on success, negative on failure */ -int datalink_send_pdu( - BACNET_ADDRESS *dest, // destination address - uint8_t *pdu, // any data to be sent - may be null - unsigned pdu_len) // number of bytes of data +int datalink_send_pdu(BACNET_ADDRESS * dest, // destination address + uint8_t * pdu, // any data to be sent - may be null + unsigned pdu_len) // number of bytes of data { #ifdef BACDL_ARCNET - return arcnet_send_pdu( - dest, - pdu, - pdu_len); + return arcnet_send_pdu(dest, pdu, pdu_len); #endif #ifdef BACDL_MSTP - return dlmstp_send_pdu( - dest, - pdu, - pdu_len); + return dlmstp_send_pdu(dest, pdu, pdu_len); #endif #ifdef BACDL_ETHERNET - return ethernet_send_pdu( - dest, - pdu, - pdu_len); + return ethernet_send_pdu(dest, pdu, pdu_len); #endif #ifdef BACDL_BIP - return bip_send_pdu( - dest, - pdu, - pdu_len); + return bip_send_pdu(dest, pdu, pdu_len); #endif } // returns the number of octets in the PDU, or zero on failure -uint16_t datalink_receive( - BACNET_ADDRESS *src, // source address - uint8_t *pdu, // PDU data - uint16_t max_pdu, // amount of space available in the PDU - unsigned timeout) // number of milliseconds to wait for a packet +uint16_t datalink_receive(BACNET_ADDRESS * src, // source address + uint8_t * pdu, // PDU data + uint16_t max_pdu, // amount of space available in the PDU + unsigned timeout) // number of milliseconds to wait for a packet { - #ifdef BACDL_ARCNET - return arcnet_receive( - src, - pdu, - max_pdu, - timeout); - #endif - #ifdef BACDL_MSTP - return dlmstp_receive( - src, - pdu, - max_pdu, - timeout); - #endif - #ifdef BACDL_ETHERNET - return ethernet_receive( - src, - pdu, - max_pdu, - timeout); - #endif - #ifdef BACDL_BIP - return bip_receive( - src, - pdu, - max_pdu, - timeout); - #endif +#ifdef BACDL_ARCNET + return arcnet_receive(src, pdu, max_pdu, timeout); +#endif +#ifdef BACDL_MSTP + return dlmstp_receive(src, pdu, max_pdu, timeout); +#endif +#ifdef BACDL_ETHERNET + return ethernet_receive(src, pdu, max_pdu, timeout); +#endif +#ifdef BACDL_BIP + return bip_receive(src, pdu, max_pdu, timeout); +#endif } void datalink_cleanup(void) { #ifdef BACDL_ETHERNET - ethernet_cleanup(); + ethernet_cleanup(); #endif #ifdef BACDL_BIP - bip_cleanup(); + bip_cleanup(); #endif #ifdef BACDL_ARCNET - arcnet_cleanup(); + arcnet_cleanup(); #endif #ifdef BACDL_MSTP - dlmstp_cleanup(); + dlmstp_cleanup(); #endif } -void datalink_get_broadcast_address( - BACNET_ADDRESS *dest) // destination address +void datalink_get_broadcast_address(BACNET_ADDRESS * dest) // destination address { #ifdef BACDL_ARCNET - arcnet_get_broadcast_address(dest); + arcnet_get_broadcast_address(dest); #endif #ifdef BACDL_MSTP - dlmstp_get_broadcast_address(dest); + dlmstp_get_broadcast_address(dest); #endif #ifdef BACDL_ETHERNET - ethernet_get_broadcast_address(dest); + ethernet_get_broadcast_address(dest); #endif #ifdef BACDL_BIP - bip_get_broadcast_address(dest); + bip_get_broadcast_address(dest); #endif } -void datalink_get_my_address( - BACNET_ADDRESS *my_address) +void datalink_get_my_address(BACNET_ADDRESS * my_address) { #ifdef BACDL_ARCNET - arcnet_get_my_address(my_address); + arcnet_get_my_address(my_address); #endif #ifdef BACDL_MSTP - dlmstp_get_my_address(my_address); + dlmstp_get_my_address(my_address); #endif #ifdef BACDL_ETHERNET - ethernet_get_my_address(my_address); + ethernet_get_my_address(my_address); #endif #ifdef BACDL_BIP - bip_get_my_address(my_address); + bip_get_my_address(my_address); #endif } - diff --git a/bacnet-stack/datalink.h b/bacnet-stack/datalink.h index 6c2e89ad..bf7613d7 100644 --- a/bacnet-stack/datalink.h +++ b/bacnet-stack/datalink.h @@ -57,31 +57,26 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ /* returns number of bytes sent on success, negative on failure */ -int datalink_send_pdu( - BACNET_ADDRESS *dest, // destination address - uint8_t *pdu, // any data to be sent - may be null - unsigned pdu_len); // number of bytes of data + int datalink_send_pdu(BACNET_ADDRESS * dest, // destination address + uint8_t * pdu, // any data to be sent - may be null + unsigned pdu_len); // number of bytes of data // returns the number of octets in the PDU, or zero on failure -uint16_t datalink_receive( - BACNET_ADDRESS *src, // source address - uint8_t *pdu, // PDU data - uint16_t max_pdu, // amount of space available in the PDU - unsigned timeout); // number of milliseconds to wait for a packet + uint16_t datalink_receive(BACNET_ADDRESS * src, // source address + uint8_t * pdu, // PDU data + uint16_t max_pdu, // amount of space available in the PDU + unsigned timeout); // number of milliseconds to wait for a packet -void datalink_cleanup(void); + void datalink_cleanup(void); -void datalink_get_broadcast_address( - BACNET_ADDRESS *dest); // destination address + void datalink_get_broadcast_address(BACNET_ADDRESS * dest); // destination address -void datalink_get_my_address( - BACNET_ADDRESS *my_address); + void datalink_get_my_address(BACNET_ADDRESS * my_address); #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif diff --git a/bacnet-stack/dcc.c b/bacnet-stack/dcc.c index 4df97828..2a6bb84d 100644 --- a/bacnet-stack/dcc.c +++ b/bacnet-stack/dcc.c @@ -42,18 +42,18 @@ /* note: time duration is given in Minutes, but in order to be accurate, we need to count down in seconds. */ static uint32_t DCC_Time_Duration_Seconds = 0; -static BACNET_COMMUNICATION_ENABLE_DISABLE DCC_Enable_Disable = - COMMUNICATION_ENABLE; +static BACNET_COMMUNICATION_ENABLE_DISABLE DCC_Enable_Disable = + COMMUNICATION_ENABLE; /* password is optionally supported */ BACNET_COMMUNICATION_ENABLE_DISABLE dcc_enable_status(void) { - return DCC_Enable_Disable; + return DCC_Enable_Disable; } bool dcc_communication_enabled(void) { - return (DCC_Enable_Disable == COMMUNICATION_ENABLE); + return (DCC_Enable_Disable == COMMUNICATION_ENABLE); } /* When network communications are completely disabled, @@ -61,7 +61,7 @@ bool dcc_communication_enabled(void) shall be processed and no messages shall be initiated.*/ bool dcc_communication_disabled(void) { - return (DCC_Enable_Disable == COMMUNICATION_DISABLE); + return (DCC_Enable_Disable == COMMUNICATION_DISABLE); } /* When the initiation of communications is disabled, @@ -75,174 +75,159 @@ bool dcc_communication_disabled(void) the device is included in the address range. */ bool dcc_communication_initiation_disabled(void) { - return (DCC_Enable_Disable == COMMUNICATION_DISABLE_INITIATION); + return (DCC_Enable_Disable == COMMUNICATION_DISABLE_INITIATION); } uint32_t dcc_duration_seconds(void) { - return DCC_Time_Duration_Seconds; + return DCC_Time_Duration_Seconds; } /* called every second or so. If more than one second, then seconds should be the number of seconds to tick away */ void dcc_timer_seconds(uint32_t seconds) { - if (DCC_Time_Duration_Seconds) - { - if (DCC_Time_Duration_Seconds > seconds) - DCC_Time_Duration_Seconds -= seconds; - else - DCC_Time_Duration_Seconds = 0; - /* just expired - do something */ - if (DCC_Time_Duration_Seconds == 0) - DCC_Enable_Disable = COMMUNICATION_ENABLE; - } + if (DCC_Time_Duration_Seconds) { + if (DCC_Time_Duration_Seconds > seconds) + DCC_Time_Duration_Seconds -= seconds; + else + DCC_Time_Duration_Seconds = 0; + /* just expired - do something */ + if (DCC_Time_Duration_Seconds == 0) + DCC_Enable_Disable = COMMUNICATION_ENABLE; + } } -bool dcc_set_status_duration( - BACNET_COMMUNICATION_ENABLE_DISABLE status, - uint16_t minutes) +bool dcc_set_status_duration(BACNET_COMMUNICATION_ENABLE_DISABLE status, + uint16_t minutes) { - bool valid = false; + bool valid = false; - /* valid? */ - if (status < MAX_BACNET_COMMUNICATION_ENABLE_DISABLE) - { - DCC_Enable_Disable = status; - if (status == COMMUNICATION_ENABLE) - DCC_Time_Duration_Seconds = 0; - else - DCC_Time_Duration_Seconds = minutes * 60; - valid = true; - } + /* valid? */ + if (status < MAX_BACNET_COMMUNICATION_ENABLE_DISABLE) { + DCC_Enable_Disable = status; + if (status == COMMUNICATION_ENABLE) + DCC_Time_Duration_Seconds = 0; + else + DCC_Time_Duration_Seconds = minutes * 60; + valid = true; + } - return valid; + return valid; } /* encode service */ -int dcc_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - uint16_t timeDuration, /* 0=optional */ - BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable, - BACNET_CHARACTER_STRING *password) /* NULL=optional */ -{ - int len = 0; /* length of each encoding */ - int apdu_len = 0; /* total length of the apdu, return value */ +int dcc_encode_apdu(uint8_t * apdu, uint8_t invoke_id, uint16_t timeDuration, /* 0=optional */ + BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable, + BACNET_CHARACTER_STRING * password) +{ /* NULL=optional */ + int len = 0; /* length of each encoding */ + int apdu_len = 0; /* total length of the apdu, return value */ - if (apdu) - { - apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST; - apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU); - apdu[2] = invoke_id; - apdu[3] = SERVICE_CONFIRMED_REINITIALIZE_DEVICE; - apdu_len = 4; - /* optional timeDuration */ - if (timeDuration) - { - len = encode_context_unsigned(&apdu[apdu_len], 0, timeDuration); - apdu_len += len; + if (apdu) { + apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST; + apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU); + apdu[2] = invoke_id; + apdu[3] = SERVICE_CONFIRMED_REINITIALIZE_DEVICE; + apdu_len = 4; + /* optional timeDuration */ + if (timeDuration) { + len = + encode_context_unsigned(&apdu[apdu_len], 0, timeDuration); + apdu_len += len; + } + /* enable disable */ + len = + encode_context_enumerated(&apdu[apdu_len], 1, enable_disable); + apdu_len += len; + /* optional password */ + if (password) { + /* FIXME: must be at least 1 character, limited to 20 characters */ + len = + encode_context_character_string(&apdu[apdu_len], 2, + password); + apdu_len += len; + } } - /* enable disable */ - len = encode_context_enumerated(&apdu[apdu_len], 1, enable_disable); - apdu_len += len; - /* optional password */ - if (password) - { - /* FIXME: must be at least 1 character, limited to 20 characters */ - len = encode_context_character_string(&apdu[apdu_len], 2, password); - apdu_len += len; - } - } - return apdu_len; + return apdu_len; } /* decode the service request only */ -int dcc_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - uint16_t *timeDuration, - BACNET_COMMUNICATION_ENABLE_DISABLE *enable_disable, - BACNET_CHARACTER_STRING *password) +int dcc_decode_service_request(uint8_t * apdu, + unsigned apdu_len, + uint16_t * timeDuration, + BACNET_COMMUNICATION_ENABLE_DISABLE * enable_disable, + BACNET_CHARACTER_STRING * password) { - unsigned len = 0; - uint8_t tag_number = 0; - uint32_t len_value_type = 0; - int value = 0; - uint32_t value32 = 0; - - /* check for value pointers */ - if (apdu_len) - { - /* Tag 0: timeDuration --optional-- */ - if (decode_is_context_tag(&apdu[len], 0)) - { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value_type); - len += decode_unsigned(&apdu[len], len_value_type, &value32); - if (timeDuration) - *timeDuration = value32; - } - else if (timeDuration) - *timeDuration = 0; - /* Tag 1: enable_disable */ - if (!decode_is_context_tag(&apdu[len], 1)) - return -1; - len += decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - len += decode_enumerated(&apdu[len], len_value_type, &value); - if (enable_disable) - *enable_disable = value; - /* Tag 2: password --optional-- */ - if (len < apdu_len) - { - if (!decode_is_context_tag(&apdu[len], 2)) - return -1; - len += decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - len += decode_character_string(&apdu[len], len_value_type, password); - } - else if (password) - characterstring_init_ansi(password,NULL); - } + unsigned len = 0; + uint8_t tag_number = 0; + uint32_t len_value_type = 0; + int value = 0; + uint32_t value32 = 0; - return (int)len; + /* check for value pointers */ + if (apdu_len) { + /* Tag 0: timeDuration --optional-- */ + if (decode_is_context_tag(&apdu[len], 0)) { + len += decode_tag_number_and_value(&apdu[len], &tag_number, + &len_value_type); + len += decode_unsigned(&apdu[len], len_value_type, &value32); + if (timeDuration) + *timeDuration = value32; + } else if (timeDuration) + *timeDuration = 0; + /* Tag 1: enable_disable */ + if (!decode_is_context_tag(&apdu[len], 1)) + return -1; + len += decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + len += decode_enumerated(&apdu[len], len_value_type, &value); + if (enable_disable) + *enable_disable = value; + /* Tag 2: password --optional-- */ + if (len < apdu_len) { + if (!decode_is_context_tag(&apdu[len], 2)) + return -1; + len += decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + len += + decode_character_string(&apdu[len], len_value_type, + password); + } else if (password) + characterstring_init_ansi(password, NULL); + } + + return (int) len; } -int dcc_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - uint16_t *timeDuration, - BACNET_COMMUNICATION_ENABLE_DISABLE *enable_disable, - BACNET_CHARACTER_STRING *password) +int dcc_decode_apdu(uint8_t * apdu, + unsigned apdu_len, + uint8_t * invoke_id, + uint16_t * timeDuration, + BACNET_COMMUNICATION_ENABLE_DISABLE * enable_disable, + BACNET_CHARACTER_STRING * password) { - int len = 0; - unsigned offset = 0; + int len = 0; + unsigned offset = 0; - if (!apdu) - return -1; - // optional checking - most likely was already done prior to this call - if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) - return -1; - // apdu[1] = encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); - *invoke_id = apdu[2]; /* invoke id - filled in by net layer */ - if (apdu[3] != SERVICE_CONFIRMED_REINITIALIZE_DEVICE) - return -1; - offset = 4; + if (!apdu) + return -1; + // optional checking - most likely was already done prior to this call + if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) + return -1; + // apdu[1] = encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); + *invoke_id = apdu[2]; /* invoke id - filled in by net layer */ + if (apdu[3] != SERVICE_CONFIRMED_REINITIALIZE_DEVICE) + return -1; + offset = 4; - if (apdu_len > offset) - { - len = dcc_decode_service_request( - &apdu[offset], - apdu_len - offset, - timeDuration, - enable_disable, - password); - } + if (apdu_len > offset) { + len = dcc_decode_service_request(&apdu[offset], + apdu_len - offset, timeDuration, enable_disable, password); + } - return len; + return len; } #ifdef TEST @@ -250,71 +235,55 @@ int dcc_decode_apdu( #include #include "ctest.h" -void test_DeviceCommunicationControlData( - Test * pTest, - uint8_t invoke_id, - uint16_t timeDuration, - BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable, - BACNET_CHARACTER_STRING *password) +void test_DeviceCommunicationControlData(Test * pTest, + uint8_t invoke_id, + uint16_t timeDuration, + BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable, + BACNET_CHARACTER_STRING * password) { - uint8_t apdu[480] = {0}; - int len = 0; - int apdu_len = 0; - uint8_t test_invoke_id = 0; - uint16_t test_timeDuration = 0; - BACNET_COMMUNICATION_ENABLE_DISABLE test_enable_disable; - BACNET_CHARACTER_STRING test_password; - - len = dcc_encode_apdu( - &apdu[0], - invoke_id, - timeDuration, - enable_disable, - password); - ct_test(pTest, len != 0); - apdu_len = len; + uint8_t apdu[480] = { 0 }; + int len = 0; + int apdu_len = 0; + uint8_t test_invoke_id = 0; + uint16_t test_timeDuration = 0; + BACNET_COMMUNICATION_ENABLE_DISABLE test_enable_disable; + BACNET_CHARACTER_STRING test_password; - len = dcc_decode_apdu( - &apdu[0], - apdu_len, - &test_invoke_id, - &test_timeDuration, - &test_enable_disable, - &test_password); - ct_test(pTest, len != -1); - ct_test(pTest, test_invoke_id == invoke_id); - ct_test(pTest, test_timeDuration == timeDuration); - ct_test(pTest, test_enable_disable == enable_disable); - ct_test(pTest, characterstring_same(&test_password,password)); + len = dcc_encode_apdu(&apdu[0], + invoke_id, timeDuration, enable_disable, password); + ct_test(pTest, len != 0); + apdu_len = len; + + len = dcc_decode_apdu(&apdu[0], + apdu_len, + &test_invoke_id, + &test_timeDuration, &test_enable_disable, &test_password); + ct_test(pTest, len != -1); + ct_test(pTest, test_invoke_id == invoke_id); + ct_test(pTest, test_timeDuration == timeDuration); + ct_test(pTest, test_enable_disable == enable_disable); + ct_test(pTest, characterstring_same(&test_password, password)); } void test_DeviceCommunicationControl(Test * pTest) { - uint8_t invoke_id = 128; - uint16_t timeDuration = 0; - BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable; - BACNET_CHARACTER_STRING password; + uint8_t invoke_id = 128; + uint16_t timeDuration = 0; + BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable; + BACNET_CHARACTER_STRING password; - timeDuration = 0; - enable_disable = COMMUNICATION_DISABLE_INITIATION; - characterstring_init_ansi(&password,"John 3:16"); - test_DeviceCommunicationControlData( - pTest, - invoke_id, - timeDuration, - enable_disable, - &password); + timeDuration = 0; + enable_disable = COMMUNICATION_DISABLE_INITIATION; + characterstring_init_ansi(&password, "John 3:16"); + test_DeviceCommunicationControlData(pTest, + invoke_id, timeDuration, enable_disable, &password); - timeDuration = 12345; - enable_disable = COMMUNICATION_DISABLE; - test_DeviceCommunicationControlData( - pTest, - invoke_id, - timeDuration, - enable_disable, - NULL); + timeDuration = 12345; + enable_disable = COMMUNICATION_DISABLE; + test_DeviceCommunicationControlData(pTest, + invoke_id, timeDuration, enable_disable, NULL); - return; + return; } #ifdef TEST_DEVICE_COMMUNICATION_CONTROL @@ -335,5 +304,5 @@ int main(void) return 0; } -#endif /* TEST_DEVICE_COMMUNICATION_CONTROL */ -#endif /* TEST */ +#endif /* TEST_DEVICE_COMMUNICATION_CONTROL */ +#endif /* TEST */ diff --git a/bacnet-stack/dcc.h b/bacnet-stack/dcc.h index f2bc4a01..0899fe4d 100644 --- a/bacnet-stack/dcc.h +++ b/bacnet-stack/dcc.h @@ -41,55 +41,46 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ /* return the status */ -BACNET_COMMUNICATION_ENABLE_DISABLE dcc_enable_status(void); -bool dcc_communication_enabled(void); -bool dcc_communication_disabled(void); -bool dcc_communication_initiation_disabled(void); + BACNET_COMMUNICATION_ENABLE_DISABLE dcc_enable_status(void); + bool dcc_communication_enabled(void); + bool dcc_communication_disabled(void); + bool dcc_communication_initiation_disabled(void); /* return the time */ -uint32_t dcc_duration_seconds(void); + uint32_t dcc_duration_seconds(void); /* called every second or so. If more than one second, then seconds should be the number of seconds to tick away */ -void dcc_timer_seconds(uint32_t seconds); + void dcc_timer_seconds(uint32_t seconds); /* setup the communication values */ -bool dcc_set_status_duration( - BACNET_COMMUNICATION_ENABLE_DISABLE status, - uint16_t minutes); + bool dcc_set_status_duration(BACNET_COMMUNICATION_ENABLE_DISABLE + status, uint16_t minutes); // encode service -int dcc_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - uint16_t timeDuration, /* 0=optional */ - BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable, - BACNET_CHARACTER_STRING *password); /* NULL=optional */ + int dcc_encode_apdu(uint8_t * apdu, uint8_t invoke_id, uint16_t timeDuration, /* 0=optional */ + BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable, BACNET_CHARACTER_STRING * password); /* NULL=optional */ // decode the service request only -int dcc_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - uint16_t *timeDuration, - BACNET_COMMUNICATION_ENABLE_DISABLE *enable_disable, - BACNET_CHARACTER_STRING *password); - -int dcc_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - uint16_t *timeDuration, - BACNET_COMMUNICATION_ENABLE_DISABLE *enable_disable, - BACNET_CHARACTER_STRING *password); + int dcc_decode_service_request(uint8_t * apdu, + unsigned apdu_len, + uint16_t * timeDuration, + BACNET_COMMUNICATION_ENABLE_DISABLE * enable_disable, + BACNET_CHARACTER_STRING * password); + + int dcc_decode_apdu(uint8_t * apdu, + unsigned apdu_len, + uint8_t * invoke_id, + uint16_t * timeDuration, + BACNET_COMMUNICATION_ENABLE_DISABLE * enable_disable, + BACNET_CHARACTER_STRING * password); #ifdef TEST #include "ctest.h" -void test_DeviceCommunicationControl(Test * pTest); + void test_DeviceCommunicationControl(Test * pTest); #endif #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif - diff --git a/bacnet-stack/dlmstp.c b/bacnet-stack/dlmstp.c index 272ec82c..ea0eafcb 100644 --- a/bacnet-stack/dlmstp.c +++ b/bacnet-stack/dlmstp.c @@ -41,55 +41,52 @@ void dlmstp_init(void) { - + } void dlmstp_cleanup(void) { - + } /* returns number of bytes sent on success, negative on failure */ -int dlmstp_send_pdu( - BACNET_ADDRESS *dest, // destination address - uint8_t *pdu, // any data to be sent - may be null - unsigned pdu_len) // number of bytes of data +int dlmstp_send_pdu(BACNET_ADDRESS * dest, // destination address + uint8_t * pdu, // any data to be sent - may be null + unsigned pdu_len) // number of bytes of data { - (void)dest; - (void)pdu; - (void)pdu_len; + (void) dest; + (void) pdu; + (void) pdu_len; - return 0; + return 0; } // returns the number of octets in the PDU, or zero on failure -uint16_t dlmstp_receive( - BACNET_ADDRESS *src, // source address - uint8_t *pdu, // PDU data - uint16_t max_pdu, // amount of space available in the PDU - unsigned timeout) // milliseconds to wait for a packet +uint16_t dlmstp_receive(BACNET_ADDRESS * src, // source address + uint8_t * pdu, // PDU data + uint16_t max_pdu, // amount of space available in the PDU + unsigned timeout) // milliseconds to wait for a packet { - (void)src; - (void)pdu; - (void)max_pdu; - (void)timeout; - - return 0; + (void) src; + (void) pdu; + (void) max_pdu; + (void) timeout; + + return 0; } -void dlmstp_set_my_address(BACNET_ADDRESS *my_address) +void dlmstp_set_my_address(BACNET_ADDRESS * my_address) { - return; + return; } -void dlmstp_get_my_address(BACNET_ADDRESS *my_address) +void dlmstp_get_my_address(BACNET_ADDRESS * my_address) { - return; + return; } -void dlmstp_get_broadcast_address( - BACNET_ADDRESS *dest) // destination address +void dlmstp_get_broadcast_address(BACNET_ADDRESS * dest) // destination address { - return; + return; } diff --git a/bacnet-stack/dlmstp.h b/bacnet-stack/dlmstp.h index f19c296c..d21dc7c2 100644 --- a/bacnet-stack/dlmstp.h +++ b/bacnet-stack/dlmstp.h @@ -46,31 +46,27 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ -void dlmstp_init(void); -void dlmstp_cleanup(void); + void dlmstp_init(void); + void dlmstp_cleanup(void); /* returns number of bytes sent on success, negative on failure */ -int dlmstp_send_pdu( - BACNET_ADDRESS *dest, // destination address - uint8_t *pdu, // any data to be sent - may be null - unsigned pdu_len); // number of bytes of data + int dlmstp_send_pdu(BACNET_ADDRESS * dest, // destination address + uint8_t * pdu, // any data to be sent - may be null + unsigned pdu_len); // number of bytes of data // returns the number of octets in the PDU, or zero on failure -uint16_t dlmstp_receive( - BACNET_ADDRESS *src, // source address - uint8_t *pdu, // PDU data - uint16_t max_pdu, // amount of space available in the PDU - unsigned timeout); // milliseconds to wait for a packet + uint16_t dlmstp_receive(BACNET_ADDRESS * src, // source address + uint8_t * pdu, // PDU data + uint16_t max_pdu, // amount of space available in the PDU + unsigned timeout); // milliseconds to wait for a packet -void dlmstp_set_my_address(BACNET_ADDRESS *my_address); -void dlmstp_get_my_address(BACNET_ADDRESS *my_address); -void dlmstp_get_broadcast_address( - BACNET_ADDRESS *dest); // destination address + void dlmstp_set_my_address(BACNET_ADDRESS * my_address); + void dlmstp_get_my_address(BACNET_ADDRESS * my_address); + void dlmstp_get_broadcast_address(BACNET_ADDRESS * dest); // destination address #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif diff --git a/bacnet-stack/ethernet.h b/bacnet-stack/ethernet.h index 9d11db4a..2f4ee673 100644 --- a/bacnet-stack/ethernet.h +++ b/bacnet-stack/ethernet.h @@ -45,42 +45,37 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ -bool ethernet_valid(void); -void ethernet_cleanup(void); -bool ethernet_init(char *interface_name); + bool ethernet_valid(void); + void ethernet_cleanup(void); + bool ethernet_init(char *interface_name); /* function to send a packet out the 802.2 socket */ /* returns number of bytes sent on success, negative on failure */ -int ethernet_send( - BACNET_ADDRESS *dest, // destination address - BACNET_ADDRESS *src, // source address - uint8_t *pdu, // any data to be sent - may be null - unsigned pdu_len); // number of bytes of data + int ethernet_send(BACNET_ADDRESS * dest, // destination address + BACNET_ADDRESS * src, // source address + uint8_t * pdu, // any data to be sent - may be null + unsigned pdu_len); // number of bytes of data /* function to send a packet out the 802.2 socket */ /* returns number of bytes sent on success, negative on failure */ -int ethernet_send_pdu( - BACNET_ADDRESS *dest, // destination address - uint8_t *pdu, // any data to be sent - may be null - unsigned pdu_len); // number of bytes of data + int ethernet_send_pdu(BACNET_ADDRESS * dest, // destination address + uint8_t * pdu, // any data to be sent - may be null + unsigned pdu_len); // number of bytes of data // receives an 802.2 framed packet // returns the number of octets in the PDU, or zero on failure -uint16_t ethernet_receive( - BACNET_ADDRESS *src, // source address - uint8_t *pdu, // PDU data - uint16_t max_pdu, // amount of space available in the PDU - unsigned timeout); // milliseconds to wait for a packet + uint16_t ethernet_receive(BACNET_ADDRESS * src, // source address + uint8_t * pdu, // PDU data + uint16_t max_pdu, // amount of space available in the PDU + unsigned timeout); // milliseconds to wait for a packet -void ethernet_set_my_address(BACNET_ADDRESS *my_address); -void ethernet_get_my_address(BACNET_ADDRESS *my_address); -void ethernet_get_broadcast_address( - BACNET_ADDRESS *dest); // destination address + void ethernet_set_my_address(BACNET_ADDRESS * my_address); + void ethernet_get_my_address(BACNET_ADDRESS * my_address); + void ethernet_get_broadcast_address(BACNET_ADDRESS * dest); // destination address #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif diff --git a/bacnet-stack/filename.c b/bacnet-stack/filename.c index dd9313b8..449ad3f8 100644 --- a/bacnet-stack/filename.c +++ b/bacnet-stack/filename.c @@ -36,20 +36,19 @@ char *filename_remove_path(const char *filename_in) { - char *filename_out = NULL; + char *filename_out = NULL; - /* allow the device ID to be set */ - if (filename_in) - { - filename_out = strrchr(filename_in,'\\'); - if (!filename_out) - filename_out = strrchr(filename_in,'/'); - /* go beyond the slash */ - if (filename_out) - filename_out++; - } + /* allow the device ID to be set */ + if (filename_in) { + filename_out = strrchr(filename_in, '\\'); + if (!filename_out) + filename_out = strrchr(filename_in, '/'); + /* go beyond the slash */ + if (filename_out) + filename_out++; + } - return filename_out; + return filename_out; } #ifdef TEST @@ -58,46 +57,45 @@ char *filename_remove_path(const char *filename_in) #include "ctest.h" -void testFilename(Test* pTest) +void testFilename(Test * pTest) { - char *data1 = "c:\\Joshua\\run"; - char *data2 = "/home/Anna/run"; - char *data3 = "c:\\Program Files\\Christopher\\run.exe"; - char *data4 = "//Mary/data/run"; - char *filename = NULL; + char *data1 = "c:\\Joshua\\run"; + char *data2 = "/home/Anna/run"; + char *data3 = "c:\\Program Files\\Christopher\\run.exe"; + char *data4 = "//Mary/data/run"; + char *filename = NULL; - filename = filename_remove_path(data1); - ct_test(pTest,strcmp("run",filename) == 0); - filename = filename_remove_path(data2); - ct_test(pTest,strcmp("run",filename) == 0); - filename = filename_remove_path(data3); - ct_test(pTest,strcmp("run.exe",filename) == 0); - filename = filename_remove_path(data4); - ct_test(pTest,strcmp("run",filename) == 0); + filename = filename_remove_path(data1); + ct_test(pTest, strcmp("run", filename) == 0); + filename = filename_remove_path(data2); + ct_test(pTest, strcmp("run", filename) == 0); + filename = filename_remove_path(data3); + ct_test(pTest, strcmp("run.exe", filename) == 0); + filename = filename_remove_path(data4); + ct_test(pTest, strcmp("run", filename) == 0); - return; + return; } #ifdef TEST_FILENAME int main(void) { - Test *pTest; - bool rc; + Test *pTest; + bool rc; - pTest = ct_create("filename remove path", NULL); + pTest = ct_create("filename remove path", NULL); - /* individual tests */ - rc = ct_addTestFunction(pTest, testFilename); - assert(rc); + /* individual tests */ + rc = ct_addTestFunction(pTest, testFilename); + assert(rc); - ct_setStream(pTest, stdout); - ct_run(pTest); - (void)ct_report(pTest); + ct_setStream(pTest, stdout); + ct_run(pTest); + (void) ct_report(pTest); - ct_destroy(pTest); + ct_destroy(pTest); - return 0; + return 0; } -#endif /* TEST_FILENAME */ -#endif /* TEST */ - +#endif /* TEST_FILENAME */ +#endif /* TEST */ diff --git a/bacnet-stack/filename.h b/bacnet-stack/filename.h index 8ef78d22..38ad0cd6 100644 --- a/bacnet-stack/filename.h +++ b/bacnet-stack/filename.h @@ -36,12 +36,11 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ -char *filename_remove_path(const char *filename_in); + char *filename_remove_path(const char *filename_in); #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif diff --git a/bacnet-stack/iam.c b/bacnet-stack/iam.c index a070841b..81a305ab 100755 --- a/bacnet-stack/iam.c +++ b/bacnet-stack/iam.c @@ -41,162 +41,141 @@ #include "address.h" // encode I-Am service -int iam_encode_apdu( - uint8_t *apdu, - uint32_t device_id, - unsigned max_apdu, - int segmentation, - uint16_t vendor_id) +int iam_encode_apdu(uint8_t * apdu, + uint32_t device_id, + unsigned max_apdu, int segmentation, uint16_t vendor_id) { - int len = 0; // length of each encoding - int apdu_len = 0; // total length of the apdu, return value + int len = 0; // length of each encoding + int apdu_len = 0; // total length of the apdu, return value - if (apdu) { - apdu[0] = PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST; - apdu[1] = SERVICE_UNCONFIRMED_I_AM; // service choice - apdu_len = 2; - len = encode_tagged_object_id( - &apdu[apdu_len], - OBJECT_DEVICE, - device_id); - apdu_len += len; - len = encode_tagged_unsigned( - &apdu[apdu_len], - max_apdu); - apdu_len += len; - len = encode_tagged_enumerated( - &apdu[apdu_len], - segmentation); - apdu_len += len; - len = encode_tagged_unsigned( - &apdu[apdu_len], - vendor_id); - apdu_len += len; - } - - return apdu_len; + if (apdu) { + apdu[0] = PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST; + apdu[1] = SERVICE_UNCONFIRMED_I_AM; // service choice + apdu_len = 2; + len = encode_tagged_object_id(&apdu[apdu_len], + OBJECT_DEVICE, device_id); + apdu_len += len; + len = encode_tagged_unsigned(&apdu[apdu_len], max_apdu); + apdu_len += len; + len = encode_tagged_enumerated(&apdu[apdu_len], segmentation); + apdu_len += len; + len = encode_tagged_unsigned(&apdu[apdu_len], vendor_id); + apdu_len += len; + } + + return apdu_len; } -int iam_decode_service_request( - uint8_t *apdu, - uint32_t *pDevice_id, - unsigned *pMax_apdu, - int *pSegmentation, - uint16_t *pVendor_id) +int iam_decode_service_request(uint8_t * apdu, + uint32_t * pDevice_id, + unsigned *pMax_apdu, int *pSegmentation, uint16_t * pVendor_id) { - int len = 0; - int apdu_len = 0; // total length of the apdu, return value - int object_type = 0; // should be a Device Object - uint32_t object_instance = 0; - uint8_t tag_number = 0; - uint32_t len_value = 0; - uint32_t decoded_value = 0; - int decoded_integer = 0; + int len = 0; + int apdu_len = 0; // total length of the apdu, return value + int object_type = 0; // should be a Device Object + uint32_t object_instance = 0; + uint8_t tag_number = 0; + uint32_t len_value = 0; + uint32_t decoded_value = 0; + int decoded_integer = 0; - // OBJECT ID - object id - len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value); - apdu_len += len; - if (tag_number != BACNET_APPLICATION_TAG_OBJECT_ID) - return -1; - len = decode_object_id(&apdu[apdu_len], &object_type, &object_instance); - apdu_len += len; - if (object_type != OBJECT_DEVICE) - return -1; - if (pDevice_id) - *pDevice_id = object_instance; - // MAX APDU - unsigned - len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value); - apdu_len += len; - if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) - return -1; - len = decode_unsigned(&apdu[apdu_len], len_value, &decoded_value); - apdu_len += len; - if (pMax_apdu) - *pMax_apdu = decoded_value; - // Segmentation - enumerated - len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value); - apdu_len += len; - if (tag_number != BACNET_APPLICATION_TAG_ENUMERATED) - return -1; - len = decode_enumerated(&apdu[apdu_len],len_value, &decoded_integer); - apdu_len += len; - if (decoded_integer >= MAX_BACNET_SEGMENTATION) - return -1; - if (pSegmentation) - *pSegmentation = decoded_integer; - // Vendor ID - unsigned16 - len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value); - apdu_len += len; - if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) - return -1; - len = decode_unsigned(&apdu[apdu_len], len_value, &decoded_value); - apdu_len += len; - if (decoded_value > 0xFFFF) - return -1; - if (pVendor_id) - *pVendor_id = (uint16_t)decoded_value; - - return apdu_len; + // OBJECT ID - object id + len = + decode_tag_number_and_value(&apdu[apdu_len], &tag_number, + &len_value); + apdu_len += len; + if (tag_number != BACNET_APPLICATION_TAG_OBJECT_ID) + return -1; + len = + decode_object_id(&apdu[apdu_len], &object_type, &object_instance); + apdu_len += len; + if (object_type != OBJECT_DEVICE) + return -1; + if (pDevice_id) + *pDevice_id = object_instance; + // MAX APDU - unsigned + len = + decode_tag_number_and_value(&apdu[apdu_len], &tag_number, + &len_value); + apdu_len += len; + if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) + return -1; + len = decode_unsigned(&apdu[apdu_len], len_value, &decoded_value); + apdu_len += len; + if (pMax_apdu) + *pMax_apdu = decoded_value; + // Segmentation - enumerated + len = + decode_tag_number_and_value(&apdu[apdu_len], &tag_number, + &len_value); + apdu_len += len; + if (tag_number != BACNET_APPLICATION_TAG_ENUMERATED) + return -1; + len = decode_enumerated(&apdu[apdu_len], len_value, &decoded_integer); + apdu_len += len; + if (decoded_integer >= MAX_BACNET_SEGMENTATION) + return -1; + if (pSegmentation) + *pSegmentation = decoded_integer; + // Vendor ID - unsigned16 + len = + decode_tag_number_and_value(&apdu[apdu_len], &tag_number, + &len_value); + apdu_len += len; + if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) + return -1; + len = decode_unsigned(&apdu[apdu_len], len_value, &decoded_value); + apdu_len += len; + if (decoded_value > 0xFFFF) + return -1; + if (pVendor_id) + *pVendor_id = (uint16_t) decoded_value; + + return apdu_len; } -int iam_decode_apdu( - uint8_t *apdu, - uint32_t *pDevice_id, - unsigned *pMax_apdu, - int *pSegmentation, - uint16_t *pVendor_id) +int iam_decode_apdu(uint8_t * apdu, + uint32_t * pDevice_id, + unsigned *pMax_apdu, int *pSegmentation, uint16_t * pVendor_id) { - int apdu_len = 0; // total length of the apdu, return value + int apdu_len = 0; // total length of the apdu, return value - // valid data? - if (!apdu) - return -1; - // optional checking - most likely was already done prior to this call - if (apdu[0] != PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST) - return -1; - if (apdu[1] != SERVICE_UNCONFIRMED_I_AM) - return -1; - apdu_len = iam_decode_service_request( - &apdu[2], - pDevice_id, - pMax_apdu, - pSegmentation, - pVendor_id); - - return apdu_len; + // valid data? + if (!apdu) + return -1; + // optional checking - most likely was already done prior to this call + if (apdu[0] != PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST) + return -1; + if (apdu[1] != SERVICE_UNCONFIRMED_I_AM) + return -1; + apdu_len = iam_decode_service_request(&apdu[2], + pDevice_id, pMax_apdu, pSegmentation, pVendor_id); + + return apdu_len; } -int iam_send(uint8_t *buffer) +int iam_send(uint8_t * buffer) { - int pdu_len = 0; - BACNET_ADDRESS dest; - int bytes_sent = 0; + int pdu_len = 0; + BACNET_ADDRESS dest; + int bytes_sent = 0; - // I-Am is a global broadcast - datalink_get_broadcast_address(&dest); + // I-Am is a global broadcast + datalink_get_broadcast_address(&dest); - // encode the NPDU portion of the packet - pdu_len = npdu_encode_apdu( - &buffer[0], - &dest, - NULL, - false, // true for confirmed messages - MESSAGE_PRIORITY_NORMAL); + // encode the NPDU portion of the packet + pdu_len = npdu_encode_apdu(&buffer[0], &dest, NULL, false, // true for confirmed messages + MESSAGE_PRIORITY_NORMAL); - // encode the APDU portion of the packet - pdu_len += iam_encode_apdu( - &buffer[pdu_len], - Device_Object_Instance_Number(), - MAX_APDU, - SEGMENTATION_NONE, - Device_Vendor_Identifier()); + // encode the APDU portion of the packet + pdu_len += iam_encode_apdu(&buffer[pdu_len], + Device_Object_Instance_Number(), + MAX_APDU, SEGMENTATION_NONE, Device_Vendor_Identifier()); - bytes_sent = datalink_send_pdu( - &dest, // destination address - &buffer[0], - pdu_len); // number of bytes of data - - return bytes_sent; + bytes_sent = datalink_send_pdu(&dest, // destination address + &buffer[0], pdu_len); // number of bytes of data + + return bytes_sent; } #ifdef TEST @@ -206,83 +185,72 @@ int iam_send(uint8_t *buffer) void testIAm(Test * pTest) { - uint8_t apdu[480] = {0}; - int len = 0; - uint32_t device_id = 42; - unsigned max_apdu = 480; - int segmentation = SEGMENTATION_NONE; - uint16_t vendor_id = 42; - uint32_t test_device_id = 0; - unsigned test_max_apdu = 0; - int test_segmentation = 0; - uint16_t test_vendor_id = 0; - - len = iam_encode_apdu( - &apdu[0], - device_id, - max_apdu, - segmentation, - vendor_id); - ct_test(pTest, len != 0); + uint8_t apdu[480] = { 0 }; + int len = 0; + uint32_t device_id = 42; + unsigned max_apdu = 480; + int segmentation = SEGMENTATION_NONE; + uint16_t vendor_id = 42; + uint32_t test_device_id = 0; + unsigned test_max_apdu = 0; + int test_segmentation = 0; + uint16_t test_vendor_id = 0; - len = iam_decode_apdu( - &apdu[0], - &test_device_id, - &test_max_apdu, - &test_segmentation, - &test_vendor_id); - - ct_test(pTest, len != -1); - ct_test(pTest, test_device_id == device_id); - ct_test(pTest, test_vendor_id == vendor_id); - ct_test(pTest, test_max_apdu == max_apdu); - ct_test(pTest, test_segmentation == segmentation); + len = iam_encode_apdu(&apdu[0], + device_id, max_apdu, segmentation, vendor_id); + ct_test(pTest, len != 0); + + len = iam_decode_apdu(&apdu[0], + &test_device_id, + &test_max_apdu, &test_segmentation, &test_vendor_id); + + ct_test(pTest, len != -1); + ct_test(pTest, test_device_id == device_id); + ct_test(pTest, test_vendor_id == vendor_id); + ct_test(pTest, test_max_apdu == max_apdu); + ct_test(pTest, test_segmentation == segmentation); } #ifdef TEST_IAM // Dummy stubs to eliminate depencies -void datalink_get_broadcast_address( - BACNET_ADDRESS *dest) // destination address +void datalink_get_broadcast_address(BACNET_ADDRESS * dest) // destination address { - (void)dest; + (void) dest; } -int datalink_send_pdu( - BACNET_ADDRESS *dest, // destination address - uint8_t *pdu, // any data to be sent - may be null - unsigned pdu_len) // number of bytes of data +int datalink_send_pdu(BACNET_ADDRESS * dest, // destination address + uint8_t * pdu, // any data to be sent - may be null + unsigned pdu_len) // number of bytes of data { - (void)dest; - (void)pdu; + (void) dest; + (void) pdu; - return pdu_len; + return pdu_len; } uint16_t Device_Vendor_Identifier(void) { - return 0; + return 0; } uint32_t Device_Object_Instance_Number(void) { - return 0; + return 0; } -void address_add_binding( - uint32_t device_id, - unsigned max_apdu, - BACNET_ADDRESS *src) +void address_add_binding(uint32_t device_id, + unsigned max_apdu, BACNET_ADDRESS * src) { - (void)device_id; - (void)max_apdu; - (void)src; + (void) device_id; + (void) max_apdu; + (void) src; } // dummy for apdu dependency void tsm_free_invoke_id(uint8_t invokeID) { - // dummy stub for testing - (void)invokeID; + // dummy stub for testing + (void) invokeID; } diff --git a/bacnet-stack/iam.h b/bacnet-stack/iam.h index ebce3ea8..555436be 100644 --- a/bacnet-stack/iam.h +++ b/bacnet-stack/iam.h @@ -40,38 +40,28 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ -int iam_encode_apdu( - uint8_t *apdu, - uint32_t device_id, - unsigned max_apdu, - int segmentation, - uint16_t vendor_id); + int iam_encode_apdu(uint8_t * apdu, + uint32_t device_id, + unsigned max_apdu, int segmentation, uint16_t vendor_id); -int iam_decode_service_request( - uint8_t *apdu, - uint32_t *pDevice_id, - unsigned *pMax_apdu, - int *pSegmentation, - uint16_t *pVendor_id); - -int iam_decode_apdu( - uint8_t *apdu, - uint32_t *pDevice_id, - unsigned *pMax_apdu, - int *pSegmentation, - uint16_t *pVendor_id); - -int iam_send(uint8_t *buffer); + int iam_decode_service_request(uint8_t * apdu, + uint32_t * pDevice_id, + unsigned *pMax_apdu, int *pSegmentation, uint16_t * pVendor_id); + + int iam_decode_apdu(uint8_t * apdu, + uint32_t * pDevice_id, + unsigned *pMax_apdu, int *pSegmentation, uint16_t * pVendor_id); + + int iam_send(uint8_t * buffer); #ifdef TEST #include "ctest.h" -void testIAm(Test * pTest); + void testIAm(Test * pTest); #endif #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif diff --git a/bacnet-stack/ihave.c b/bacnet-stack/ihave.c index 5ba6ab3c..902fc2f2 100644 --- a/bacnet-stack/ihave.c +++ b/bacnet-stack/ihave.c @@ -37,108 +37,92 @@ #include "bacdef.h" #include "ihave.h" -int ihave_encode_apdu( - uint8_t *apdu, - BACNET_I_HAVE_DATA *data) +int ihave_encode_apdu(uint8_t * apdu, BACNET_I_HAVE_DATA * data) { - int len = 0; /* length of each encoding */ - int apdu_len = 0; /* total length of the apdu, return value */ + int len = 0; /* length of each encoding */ + int apdu_len = 0; /* total length of the apdu, return value */ - if (apdu && data) { - apdu[0] = PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST; - apdu[1] = SERVICE_UNCONFIRMED_I_HAVE; - apdu_len = 2; - /* deviceIdentifier */ - len = encode_tagged_object_id( - &apdu[apdu_len], - data->device_id.type, - data->device_id.instance); - apdu_len += len; - /* objectIdentifier */ - len = encode_tagged_object_id( - &apdu[apdu_len], - data->object_id.type, - data->object_id.instance); - apdu_len += len; - /* objectName */ - len = encode_tagged_character_string( - &apdu[apdu_len], - &data->object_name); - apdu_len += len; - } + if (apdu && data) { + apdu[0] = PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST; + apdu[1] = SERVICE_UNCONFIRMED_I_HAVE; + apdu_len = 2; + /* deviceIdentifier */ + len = encode_tagged_object_id(&apdu[apdu_len], + data->device_id.type, data->device_id.instance); + apdu_len += len; + /* objectIdentifier */ + len = encode_tagged_object_id(&apdu[apdu_len], + data->object_id.type, data->object_id.instance); + apdu_len += len; + /* objectName */ + len = encode_tagged_character_string(&apdu[apdu_len], + &data->object_name); + apdu_len += len; + } - return apdu_len; + return apdu_len; } /* decode the service request only */ -int ihave_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - BACNET_I_HAVE_DATA *data) +int ihave_decode_service_request(uint8_t * apdu, + unsigned apdu_len, BACNET_I_HAVE_DATA * data) { - int len = 0; - uint8_t tag_number = 0; - uint32_t len_value = 0; - int decoded_type = 0; /* for decoding */ + int len = 0; + uint8_t tag_number = 0; + uint32_t len_value = 0; + int decoded_type = 0; /* for decoding */ - if (apdu_len && data) - { - /* deviceIdentifier */ - len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); - if (tag_number == BACNET_APPLICATION_TAG_OBJECT_ID) - { - len += decode_object_id(&apdu[len], &decoded_type, - &data->device_id.instance); - data->device_id.type = decoded_type; - } - else - return -1; - /* objectIdentifier */ - len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); - if (tag_number == BACNET_APPLICATION_TAG_OBJECT_ID) - { - len += decode_object_id(&apdu[len], &decoded_type, - &data->object_id.instance); - data->object_id.type = decoded_type; - } - else - return -1; - /* objectName */ - len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); - if (tag_number == BACNET_APPLICATION_TAG_CHARACTER_STRING) - { - len += decode_character_string(&apdu[len], len_value, - &data->object_name); - } - else - return -1; - } - else - return -1; + if (apdu_len && data) { + /* deviceIdentifier */ + len += + decode_tag_number_and_value(&apdu[len], &tag_number, + &len_value); + if (tag_number == BACNET_APPLICATION_TAG_OBJECT_ID) { + len += decode_object_id(&apdu[len], &decoded_type, + &data->device_id.instance); + data->device_id.type = decoded_type; + } else + return -1; + /* objectIdentifier */ + len += + decode_tag_number_and_value(&apdu[len], &tag_number, + &len_value); + if (tag_number == BACNET_APPLICATION_TAG_OBJECT_ID) { + len += decode_object_id(&apdu[len], &decoded_type, + &data->object_id.instance); + data->object_id.type = decoded_type; + } else + return -1; + /* objectName */ + len += + decode_tag_number_and_value(&apdu[len], &tag_number, + &len_value); + if (tag_number == BACNET_APPLICATION_TAG_CHARACTER_STRING) { + len += decode_character_string(&apdu[len], len_value, + &data->object_name); + } else + return -1; + } else + return -1; - return len; + return len; } -int ihave_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - BACNET_I_HAVE_DATA *data) +int ihave_decode_apdu(uint8_t * apdu, + unsigned apdu_len, BACNET_I_HAVE_DATA * data) { - int len = 0; + int len = 0; - if (!apdu) - return -1; - /* optional checking - most likely was already done prior to this call */ - if (apdu[0] != PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST) - return -1; - if (apdu[1] != SERVICE_UNCONFIRMED_I_HAVE) - return -1; - len = ihave_decode_service_request( - &apdu[2], - apdu_len - 2, - data); + if (!apdu) + return -1; + /* optional checking - most likely was already done prior to this call */ + if (apdu[0] != PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST) + return -1; + if (apdu[1] != SERVICE_UNCONFIRMED_I_HAVE) + return -1; + len = ihave_decode_service_request(&apdu[2], apdu_len - 2, data); - return len; + return len; } #ifdef TEST @@ -146,62 +130,48 @@ int ihave_decode_apdu( #include #include "ctest.h" -void testIHaveData(Test * pTest, BACNET_I_HAVE_DATA *data) +void testIHaveData(Test * pTest, BACNET_I_HAVE_DATA * data) { - uint8_t apdu[480] = {0}; - int len = 0; - int apdu_len = 0; - BACNET_I_HAVE_DATA test_data; + uint8_t apdu[480] = { 0 }; + int len = 0; + int apdu_len = 0; + BACNET_I_HAVE_DATA test_data; - len = ihave_encode_apdu( - &apdu[0], - data); - ct_test(pTest, len != 0); - apdu_len = len; + len = ihave_encode_apdu(&apdu[0], data); + ct_test(pTest, len != 0); + apdu_len = len; - len = ihave_decode_apdu( - &apdu[0], - apdu_len, - &test_data); - ct_test(pTest, len != -1); - ct_test(pTest, test_data.device_id.type == - data->device_id.type); - ct_test(pTest, test_data.device_id.instance == - data->device_id.instance); - ct_test(pTest, test_data.object_id.type == - data->object_id.type); - ct_test(pTest, test_data.object_id.instance == - data->object_id.instance); - ct_test(pTest, characterstring_same( - &test_data.object_name,&data->object_name)); + len = ihave_decode_apdu(&apdu[0], apdu_len, &test_data); + ct_test(pTest, len != -1); + ct_test(pTest, test_data.device_id.type == data->device_id.type); + ct_test(pTest, test_data.device_id.instance == + data->device_id.instance); + ct_test(pTest, test_data.object_id.type == data->object_id.type); + ct_test(pTest, test_data.object_id.instance == + data->object_id.instance); + ct_test(pTest, characterstring_same(&test_data.object_name, + &data->object_name)); } void testIHave(Test * pTest) { - BACNET_I_HAVE_DATA data; + BACNET_I_HAVE_DATA data; - characterstring_init_ansi( - &data.object_name,"patricia"); - data.device_id.type = OBJECT_DEVICE; - for ( - data.device_id.instance = 1; - data.device_id.instance <= BACNET_MAX_INSTANCE; - data.device_id.instance <<= 1) - { - for ( - data.object_id.type = OBJECT_ANALOG_INPUT; - data.object_id.type <= MAX_BACNET_OBJECT_TYPE; - data.object_id.type++) - { - for ( - data.object_id.instance = 1; - data.object_id.instance <= BACNET_MAX_INSTANCE; - data.object_id.instance <<= 1) - { - testIHaveData(pTest,&data); - } + characterstring_init_ansi(&data.object_name, "patricia"); + data.device_id.type = OBJECT_DEVICE; + for (data.device_id.instance = 1; + data.device_id.instance <= BACNET_MAX_INSTANCE; + data.device_id.instance <<= 1) { + for (data.object_id.type = OBJECT_ANALOG_INPUT; + data.object_id.type <= MAX_BACNET_OBJECT_TYPE; + data.object_id.type++) { + for (data.object_id.instance = 1; + data.object_id.instance <= BACNET_MAX_INSTANCE; + data.object_id.instance <<= 1) { + testIHaveData(pTest, &data); + } + } } - } } #ifdef TEST_I_HAVE diff --git a/bacnet-stack/ihave.h b/bacnet-stack/ihave.h index 532b6b4f..827815d4 100644 --- a/bacnet-stack/ihave.h +++ b/bacnet-stack/ihave.h @@ -38,39 +38,30 @@ #include #include "bacstr.h" -typedef struct BACnet_I_Have_Data -{ - BACNET_OBJECT_ID device_id; - BACNET_OBJECT_ID object_id; - BACNET_CHARACTER_STRING object_name; +typedef struct BACnet_I_Have_Data { + BACNET_OBJECT_ID device_id; + BACNET_OBJECT_ID object_id; + BACNET_CHARACTER_STRING object_name; } BACNET_I_HAVE_DATA; #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ -int ihave_encode_apdu( - uint8_t *apdu, - BACNET_I_HAVE_DATA *data); + int ihave_encode_apdu(uint8_t * apdu, BACNET_I_HAVE_DATA * data); -int ihave_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - BACNET_I_HAVE_DATA *data); + int ihave_decode_service_request(uint8_t * apdu, + unsigned apdu_len, BACNET_I_HAVE_DATA * data); -int ihave_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - BACNET_I_HAVE_DATA *data); + int ihave_decode_apdu(uint8_t * apdu, + unsigned apdu_len, BACNET_I_HAVE_DATA * data); #ifdef TEST #include "ctest.h" -void testIHave(Test * pTest); + void testIHave(Test * pTest); #endif #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif - diff --git a/bacnet-stack/indtext.c b/bacnet-stack/indtext.c index 2c64d82c..02cd41c6 100644 --- a/bacnet-stack/indtext.c +++ b/bacnet-stack/indtext.c @@ -39,219 +39,190 @@ #define strcasecmp stricmp #endif -bool indtext_by_string( - INDTEXT_DATA *data_list, - const char *search_name, - unsigned *found_index) +bool indtext_by_string(INDTEXT_DATA * data_list, + const char *search_name, unsigned *found_index) { - bool found = false; - unsigned index = 0; + bool found = false; + unsigned index = 0; - if (data_list && search_name) - { - while (data_list->pString) - { - if (strcmp(data_list->pString,search_name) == 0) - { - index = data_list->index; - found = true; - break; - } - data_list++; + if (data_list && search_name) { + while (data_list->pString) { + if (strcmp(data_list->pString, search_name) == 0) { + index = data_list->index; + found = true; + break; + } + data_list++; + } } - } - if (found && found_index) - *found_index = index; + if (found && found_index) + *found_index = index; - return found; + return found; } /* case insensitive version */ -bool indtext_by_istring( - INDTEXT_DATA *data_list, - const char *search_name, - unsigned *found_index) +bool indtext_by_istring(INDTEXT_DATA * data_list, + const char *search_name, unsigned *found_index) { - bool found = false; - unsigned index = 0; + bool found = false; + unsigned index = 0; - if (data_list && search_name) - { - while (data_list->pString) - { - if (strcasecmp(data_list->pString,search_name) == 0) - { - index = data_list->index; - found = true; - break; - } - data_list++; + if (data_list && search_name) { + while (data_list->pString) { + if (strcasecmp(data_list->pString, search_name) == 0) { + index = data_list->index; + found = true; + break; + } + data_list++; + } } - } - if (found && found_index) - *found_index = index; + if (found && found_index) + *found_index = index; - return found; + return found; } -unsigned indtext_by_string_default( - INDTEXT_DATA *data_list, - const char *search_name, - unsigned default_index) +unsigned indtext_by_string_default(INDTEXT_DATA * data_list, + const char *search_name, unsigned default_index) { - unsigned index = 0; + unsigned index = 0; - if (!indtext_by_string(data_list,search_name,&index)) - index = default_index; + if (!indtext_by_string(data_list, search_name, &index)) + index = default_index; - return index; + return index; } -unsigned indtext_by_istring_default( - INDTEXT_DATA *data_list, - const char *search_name, - unsigned default_index) +unsigned indtext_by_istring_default(INDTEXT_DATA * data_list, + const char *search_name, unsigned default_index) { - unsigned index = 0; + unsigned index = 0; - if (!indtext_by_istring(data_list,search_name,&index)) - index = default_index; + if (!indtext_by_istring(data_list, search_name, &index)) + index = default_index; - return index; + return index; } -const char *indtext_by_index_default( - INDTEXT_DATA *data_list, - unsigned index, - const char *default_string) +const char *indtext_by_index_default(INDTEXT_DATA * data_list, + unsigned index, const char *default_string) { - const char *pString = NULL; + const char *pString = NULL; - if (data_list) - { - while (data_list->pString) - { - if (data_list->index == index) - { - pString = data_list->pString; - break; - } - data_list++; + if (data_list) { + while (data_list->pString) { + if (data_list->index == index) { + pString = data_list->pString; + break; + } + data_list++; + } } - } - return pString?pString:default_string; + return pString ? pString : default_string; } -const char *indtext_by_index_split_default( - INDTEXT_DATA *data_list, - int index, - int split_index, - const char *before_split_default_name, - const char *default_name) +const char *indtext_by_index_split_default(INDTEXT_DATA * data_list, + int index, + int split_index, + const char *before_split_default_name, const char *default_name) { - if (index < split_index) - return indtext_by_index_default(data_list, index, before_split_default_name); - else - return indtext_by_index_default(data_list, index, default_name); + if (index < split_index) + return indtext_by_index_default(data_list, index, + before_split_default_name); + else + return indtext_by_index_default(data_list, index, default_name); }; -const char *indtext_by_index( - INDTEXT_DATA *data_list, - unsigned index) +const char *indtext_by_index(INDTEXT_DATA * data_list, unsigned index) { - return indtext_by_index_default( - data_list, - index, - NULL); + return indtext_by_index_default(data_list, index, NULL); } -unsigned indtext_count( - INDTEXT_DATA *data_list) +unsigned indtext_count(INDTEXT_DATA * data_list) { - unsigned count = 0; /* return value */ + unsigned count = 0; /* return value */ - if (data_list) - { - while (data_list->pString) - { - count++; - data_list++; + if (data_list) { + while (data_list->pString) { + count++; + data_list++; + } } - } - return count; + return count; } #ifdef TEST #include #include "ctest.h" -static INDTEXT_DATA data_list[] = -{ - {1, "Joshua"}, - {2, "Mary"}, - {3, "Anna"}, - {4, "Christopher"}, - {5, "Patricia"}, - {0, NULL} +static INDTEXT_DATA data_list[] = { + {1, "Joshua"}, + {2, "Mary"}, + {3, "Anna"}, + {4, "Christopher"}, + {5, "Patricia"}, + {0, NULL} }; -void testIndexText(Test* pTest) +void testIndexText(Test * pTest) { - unsigned i; /*counter */ - const char *pString; - unsigned index; - bool valid; - unsigned count = 0; + unsigned i; /*counter */ + const char *pString; + unsigned index; + bool valid; + unsigned count = 0; - for (i = 0; i < 10; i++) - { - pString = indtext_by_index(data_list,i); - if (pString) - { - count++; - valid = indtext_by_string(data_list,pString,&index); - ct_test(pTest,valid == true); - ct_test(pTest,index == i); - ct_test(pTest,index == indtext_by_string_default(data_list,pString,index)); + for (i = 0; i < 10; i++) { + pString = indtext_by_index(data_list, i); + if (pString) { + count++; + valid = indtext_by_string(data_list, pString, &index); + ct_test(pTest, valid == true); + ct_test(pTest, index == i); + ct_test(pTest, index == indtext_by_string_default(data_list, + pString, index)); + } } - } - ct_test(pTest,indtext_count(data_list) == count); - ct_test(pTest,indtext_by_string(data_list,"Harry",NULL) == false); - ct_test(pTest,indtext_by_string(data_list,NULL,NULL) == false); - ct_test(pTest,indtext_by_string(NULL,NULL,NULL) == false); - ct_test(pTest,indtext_by_index(data_list,0) == NULL); - ct_test(pTest,indtext_by_index(data_list,10) == NULL); - ct_test(pTest,indtext_by_index(NULL,10) == NULL); - /* case insensitive versions */ - ct_test(pTest,indtext_by_istring(data_list,"JOSHUA",NULL) == true); - ct_test(pTest,indtext_by_istring(data_list,"joshua",NULL) == true); - valid = indtext_by_istring(data_list,"ANNA",&index); - ct_test(pTest,index == indtext_by_istring_default(data_list,"ANNA",index)); + ct_test(pTest, indtext_count(data_list) == count); + ct_test(pTest, indtext_by_string(data_list, "Harry", NULL) == false); + ct_test(pTest, indtext_by_string(data_list, NULL, NULL) == false); + ct_test(pTest, indtext_by_string(NULL, NULL, NULL) == false); + ct_test(pTest, indtext_by_index(data_list, 0) == NULL); + ct_test(pTest, indtext_by_index(data_list, 10) == NULL); + ct_test(pTest, indtext_by_index(NULL, 10) == NULL); + /* case insensitive versions */ + ct_test(pTest, indtext_by_istring(data_list, "JOSHUA", NULL) == true); + ct_test(pTest, indtext_by_istring(data_list, "joshua", NULL) == true); + valid = indtext_by_istring(data_list, "ANNA", &index); + ct_test(pTest, index == indtext_by_istring_default(data_list, "ANNA", + index)); } #endif #ifdef TEST_INDEX_TEXT int main(void) { - Test *pTest; - bool rc; + Test *pTest; + bool rc; - pTest = ct_create("index text", NULL); + pTest = ct_create("index text", NULL); - /* individual tests */ - rc = ct_addTestFunction(pTest, testIndexText); - assert(rc); + /* individual tests */ + rc = ct_addTestFunction(pTest, testIndexText); + assert(rc); - ct_setStream(pTest, stdout); - ct_run(pTest); - (void)ct_report(pTest); + ct_setStream(pTest, stdout); + ct_run(pTest); + (void) ct_report(pTest); - ct_destroy(pTest); + ct_destroy(pTest); - return 0; + return 0; } -#endif /* TEST_INDEX_TEXT */ +#endif /* TEST_INDEX_TEXT */ diff --git a/bacnet-stack/indtext.h b/bacnet-stack/indtext.h index 3e9596ef..01f61f70 100644 --- a/bacnet-stack/indtext.h +++ b/bacnet-stack/indtext.h @@ -39,74 +39,57 @@ #include /* index and text pairs */ -typedef struct -{ - unsigned index; /* index number that matches the text */ - const char *pString; /* text pair - use NULL to end the list */ +typedef struct { + unsigned index; /* index number that matches the text */ + const char *pString; /* text pair - use NULL to end the list */ } INDTEXT_DATA; #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ /* Searches for a matching string and returns the index to the string in the parameter found_index. If the string is not found, false is returned If the string is found, true is returned and the found_index contains the first index where the string was found. */ -bool indtext_by_string( - INDTEXT_DATA *data_list, - const char *search_name, - unsigned *found_index); + bool indtext_by_string(INDTEXT_DATA * data_list, + const char *search_name, unsigned *found_index); /* case insensitive version */ -bool indtext_by_istring( - INDTEXT_DATA *data_list, - const char *search_name, - unsigned *found_index); + bool indtext_by_istring(INDTEXT_DATA * data_list, + const char *search_name, unsigned *found_index); /* Searches for a matching string and returns the index to the string or the default_index if the string is not found. */ -unsigned indtext_by_string_default( - INDTEXT_DATA *data_list, - const char *search_name, - unsigned default_index); + unsigned indtext_by_string_default(INDTEXT_DATA * data_list, + const char *search_name, unsigned default_index); /* case insensitive version */ -unsigned indtext_by_istring_default( - INDTEXT_DATA *data_list, - const char *search_name, - unsigned default_index); + unsigned indtext_by_istring_default(INDTEXT_DATA * data_list, + const char *search_name, unsigned default_index); /* for a given index, return the matching string, or NULL if not found */ -const char *indtext_by_index( - INDTEXT_DATA *data_list, - unsigned index); + const char *indtext_by_index(INDTEXT_DATA * data_list, unsigned index); /* for a given index, return the matching string, or default_name if not found */ -const char *indtext_by_index_default( - INDTEXT_DATA *data_list, - unsigned index, - const char *default_name); + const char *indtext_by_index_default(INDTEXT_DATA * data_list, + unsigned index, const char *default_name); /* for a given index, return the matching string, or default_name if not found. if the index is before the split, the before_split_default_name is used */ -const char *indtext_by_index_split_default( - INDTEXT_DATA *data_list, - int index, - int split_index, - const char *before_split_default_name, - const char *default_name); + const char *indtext_by_index_split_default(INDTEXT_DATA * data_list, + int index, + int split_index, + const char *before_split_default_name, const char *default_name); /* returns the number of elements in the list */ -unsigned indtext_count( - INDTEXT_DATA *data_list); + unsigned indtext_count(INDTEXT_DATA * data_list); #ifdef TEST - #include "ctest.h" - void testIndexText(Test* pTest); +#include "ctest.h" + void testIndexText(Test * pTest); #endif #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif diff --git a/bacnet-stack/main.c b/bacnet-stack/main.c index 39b6862f..63ed7f23 100644 --- a/bacnet-stack/main.c +++ b/bacnet-stack/main.c @@ -43,23 +43,22 @@ int main(void) { - struct mstp_port_struct_t mstp_port; // port data - uint8_t my_mac = 0x05; // local MAC address + struct mstp_port_struct_t mstp_port; // port data + uint8_t my_mac = 0x05; // local MAC address - MSTP_Init(&mstp_port,my_mac); + MSTP_Init(&mstp_port, my_mac); - // loop forever - for (;;) - { - // input - RS485_Check_UART_Data(&mstp_port); - MSTP_Receive_Frame_FSM(&mstp_port); - // process + // loop forever + for (;;) { + // input + RS485_Check_UART_Data(&mstp_port); + MSTP_Receive_Frame_FSM(&mstp_port); + // process - // output - MSTP_Master_Node_FSM(&mstp_port); - - } - - return 0; + // output + MSTP_Master_Node_FSM(&mstp_port); + + } + + return 0; } diff --git a/bacnet-stack/mstp.c b/bacnet-stack/mstp.c index 01908576..52c5fd84 100644 --- a/bacnet-stack/mstp.c +++ b/bacnet-stack/mstp.c @@ -38,11 +38,11 @@ // ISO 8802-2 Logical Link Control. It uses services provided by the // EIA-485 physical layer. Relevant clauses of EIA-485 are deemed to be // included in this standard by reference. The following hardware is assumed: -// (a) A UART (Universal Asynchronous Receiver/Transmitter) capable of +// (a) A UART (Universal Asynchronous Receiver/Transmitter) capable of // transmitting and receiving eight data bits with one stop bit // and no parity. -// (b) An EIA-485 transceiver whose driver may be disabled. -// (c) A timer with a resolution of five milliseconds or less +// (b) An EIA-485 transceiver whose driver may be disabled. +// (c) A timer with a resolution of five milliseconds or less #include #include @@ -128,1069 +128,978 @@ const unsigned Tusage_delay = 15; // larger values for this timeout, not to exceed 100 milliseconds.) const unsigned Tusage_timeout = 20; -unsigned MSTP_Create_Frame( - uint8_t *buffer, // where frame is loaded - unsigned buffer_len, // amount of space available - uint8_t frame_type, // type of frame to send - see defines - uint8_t destination, // destination address - uint8_t source, // source address - uint8_t *data, // any data to be sent - may be null - unsigned data_len) // number of bytes of data (up to 501) +unsigned MSTP_Create_Frame(uint8_t * buffer, // where frame is loaded + unsigned buffer_len, // amount of space available + uint8_t frame_type, // type of frame to send - see defines + uint8_t destination, // destination address + uint8_t source, // source address + uint8_t * data, // any data to be sent - may be null + unsigned data_len) // number of bytes of data (up to 501) { - uint8_t crc8 = 0xFF; // used to calculate the crc value - uint16_t crc16 = 0xFFFF; // used to calculate the crc value - unsigned index = 0; // used to load the data portion of the frame + uint8_t crc8 = 0xFF; // used to calculate the crc value + uint16_t crc16 = 0xFFFF; // used to calculate the crc value + unsigned index = 0; // used to load the data portion of the frame - // not enough to do a header - if (buffer_len < 8) - return 0; + // not enough to do a header + if (buffer_len < 8) + return 0; - buffer[0] = 0x55; - buffer[1] = 0xFF; - buffer[2] = frame_type; - crc8 = CRC_Calc_Header(buffer[2],crc8); - buffer[3] = destination; - crc8 = CRC_Calc_Header(buffer[3],crc8); - buffer[4] = source; - crc8 = CRC_Calc_Header(buffer[4],crc8); - buffer[5] = data_len / 256; - crc8 = CRC_Calc_Header(buffer[5],crc8); - buffer[6] = data_len % 256; - crc8 = CRC_Calc_Header(buffer[6],crc8); - buffer[7] = ~crc8; + buffer[0] = 0x55; + buffer[1] = 0xFF; + buffer[2] = frame_type; + crc8 = CRC_Calc_Header(buffer[2], crc8); + buffer[3] = destination; + crc8 = CRC_Calc_Header(buffer[3], crc8); + buffer[4] = source; + crc8 = CRC_Calc_Header(buffer[4], crc8); + buffer[5] = data_len / 256; + crc8 = CRC_Calc_Header(buffer[5], crc8); + buffer[6] = data_len % 256; + crc8 = CRC_Calc_Header(buffer[6], crc8); + buffer[7] = ~crc8; - index = 8; - while (data_len && data && (index < buffer_len)) - { - buffer[index] = *data; - crc16 = CRC_Calc_Data(buffer[index],crc16); - data++; - index++; - data_len--; - } - // append the data CRC if necessary - if (index > 8) - { - if ((index + 2) <= buffer_len) - { - crc16 = ~crc16; - buffer[index] = LO_BYTE(crc16); - index++; - buffer[index] = HI_BYTE(crc16); - index++; + index = 8; + while (data_len && data && (index < buffer_len)) { + buffer[index] = *data; + crc16 = CRC_Calc_Data(buffer[index], crc16); + data++; + index++; + data_len--; + } + // append the data CRC if necessary + if (index > 8) { + if ((index + 2) <= buffer_len) { + crc16 = ~crc16; + buffer[index] = LO_BYTE(crc16); + index++; + buffer[index] = HI_BYTE(crc16); + index++; + } else + return 0; } - else - return 0; - } - return index; // returns the frame length + return index; // returns the frame length } -void MSTP_Create_And_Send_Frame( - volatile struct mstp_port_struct_t *mstp_port, // port to send from - uint8_t frame_type, // type of frame to send - see defines - uint8_t destination, // destination address - uint8_t source, // source address - uint8_t *data, // any data to be sent - may be null - unsigned data_len) // number of bytes of data (up to 501) +void MSTP_Create_And_Send_Frame(volatile struct mstp_port_struct_t *mstp_port, // port to send from + uint8_t frame_type, // type of frame to send - see defines + uint8_t destination, // destination address + uint8_t source, // source address + uint8_t * data, // any data to be sent - may be null + unsigned data_len) // number of bytes of data (up to 501) { - uint8_t buffer[MAX_MPDU] = {0}; - uint16_t len = 0; // number of bytes to send + uint8_t buffer[MAX_MPDU] = { 0 }; + uint16_t len = 0; // number of bytes to send - len = (uint16_t)MSTP_Create_Frame( - buffer, // where frame is loaded - sizeof(buffer), // amount of space available - frame_type, // type of frame to send - see defines - destination, // destination address - source, // source address - data, // any data to be sent - may be null - data_len); // number of bytes of data (up to 501) + len = (uint16_t) MSTP_Create_Frame(buffer, // where frame is loaded + sizeof(buffer), // amount of space available + frame_type, // type of frame to send - see defines + destination, // destination address + source, // source address + data, // any data to be sent - may be null + data_len); // number of bytes of data (up to 501) - RS485_Send_Frame(mstp_port, buffer, len); + RS485_Send_Frame(mstp_port, buffer, len); } // Millisecond Timer - called every millisecond void MSTP_Millisecond_Timer(volatile struct mstp_port_struct_t *mstp_port) { - if (mstp_port->SilenceTimer < 255) - mstp_port->SilenceTimer++; - if (mstp_port->ReplyPostponedTimer < 255) - mstp_port->ReplyPostponedTimer++; + if (mstp_port->SilenceTimer < 255) + mstp_port->SilenceTimer++; + if (mstp_port->ReplyPostponedTimer < 255) + mstp_port->ReplyPostponedTimer++; - return; + return; } void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port) { - switch (mstp_port->receive_state) - { - // In the IDLE state, the node waits for the beginning of a frame. + switch (mstp_port->receive_state) { + // In the IDLE state, the node waits for the beginning of a frame. case MSTP_RECEIVE_STATE_IDLE: - // EatAnError - if (mstp_port->ReceiveError == true) - { - mstp_port->ReceiveError = false; - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - // wait for the start of a frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - else - { - if (mstp_port->DataAvailable == true) - { - // Preamble1 - if (mstp_port->DataRegister == 0x55) - { - mstp_port->DataAvailable = false; - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - // receive the remainder of the frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_PREAMBLE; - } - // EatAnOctet - else - { - mstp_port->DataAvailable = false; + // EatAnError + if (mstp_port->ReceiveError == true) { + mstp_port->ReceiveError = false; mstp_port->SilenceTimer = 0; mstp_port->EventCount++; // wait for the start of a frame. mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } + } else { + if (mstp_port->DataAvailable == true) { + // Preamble1 + if (mstp_port->DataRegister == 0x55) { + mstp_port->DataAvailable = false; + mstp_port->SilenceTimer = 0; + mstp_port->EventCount++; + // receive the remainder of the frame. + mstp_port->receive_state = MSTP_RECEIVE_STATE_PREAMBLE; + } + // EatAnOctet + else { + mstp_port->DataAvailable = false; + mstp_port->SilenceTimer = 0; + mstp_port->EventCount++; + // wait for the start of a frame. + mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; + } + } } - } - break; - // In the PREAMBLE state, the node waits for the second octet of the preamble. + break; + // In the PREAMBLE state, the node waits for the second octet of the preamble. case MSTP_RECEIVE_STATE_PREAMBLE: - // Timeout - if (mstp_port->SilenceTimer > Tframe_abort) - { - // a correct preamble has not been received - // wait for the start of a frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - - // Error - else if (mstp_port->ReceiveError == true) - { - mstp_port->ReceiveError = false; - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - // wait for the start of a frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - else - { - if (mstp_port->DataAvailable == true) - { - // Preamble2 - if (mstp_port->DataRegister == 0xFF) - { - mstp_port->DataAvailable = false; - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - mstp_port->Index = 0; - mstp_port->HeaderCRC = 0xFF; - // receive the remainder of the frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; - } - // ignore RepeatedPreamble1 - else if (mstp_port->DataRegister == 0x55) - { - mstp_port->DataAvailable = false; - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - // wait for the second preamble octet. - mstp_port->receive_state = MSTP_RECEIVE_STATE_PREAMBLE; - } - // NotPreamble - else - { - mstp_port->DataAvailable = false; + // Timeout + if (mstp_port->SilenceTimer > Tframe_abort) { + // a correct preamble has not been received + // wait for the start of a frame. + mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; + } + // Error + else if (mstp_port->ReceiveError == true) { + mstp_port->ReceiveError = false; mstp_port->SilenceTimer = 0; mstp_port->EventCount++; // wait for the start of a frame. mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } + } else { + if (mstp_port->DataAvailable == true) { + // Preamble2 + if (mstp_port->DataRegister == 0xFF) { + mstp_port->DataAvailable = false; + mstp_port->SilenceTimer = 0; + mstp_port->EventCount++; + mstp_port->Index = 0; + mstp_port->HeaderCRC = 0xFF; + // receive the remainder of the frame. + mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; + } + // ignore RepeatedPreamble1 + else if (mstp_port->DataRegister == 0x55) { + mstp_port->DataAvailable = false; + mstp_port->SilenceTimer = 0; + mstp_port->EventCount++; + // wait for the second preamble octet. + mstp_port->receive_state = MSTP_RECEIVE_STATE_PREAMBLE; + } + // NotPreamble + else { + mstp_port->DataAvailable = false; + mstp_port->SilenceTimer = 0; + mstp_port->EventCount++; + // wait for the start of a frame. + mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; + } + } } - } - break; - // In the HEADER state, the node waits for the fixed message header. + break; + // In the HEADER state, the node waits for the fixed message header. case MSTP_RECEIVE_STATE_HEADER: - // Timeout - if (mstp_port->SilenceTimer > Tframe_abort) - { - // indicate that an error has occurred during the reception of a frame - mstp_port->ReceivedInvalidFrame = true; - // wait for the start of a frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - - // Error - else if (mstp_port->ReceiveError == true) - { - mstp_port->ReceiveError = false; - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - // indicate that an error has occurred during the reception of a frame - mstp_port->ReceivedInvalidFrame = true; - // wait for the start of a frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - else if (mstp_port->DataAvailable == true) - { - // FrameType - if (mstp_port->Index == 0) - { - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - mstp_port->HeaderCRC = CRC_Calc_Header( - mstp_port->DataRegister, - mstp_port->HeaderCRC); - mstp_port->FrameType = mstp_port->DataRegister; - mstp_port->DataAvailable = false; - mstp_port->Index = 1; - mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; + // Timeout + if (mstp_port->SilenceTimer > Tframe_abort) { + // indicate that an error has occurred during the reception of a frame + mstp_port->ReceivedInvalidFrame = true; + // wait for the start of a frame. + mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; } - // Destination - else if (mstp_port->Index == 1) - { - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - mstp_port->HeaderCRC = CRC_Calc_Header( - mstp_port->DataRegister, - mstp_port->HeaderCRC); - mstp_port->DestinationAddress = mstp_port->DataRegister; - mstp_port->DataAvailable = false; - mstp_port->Index = 2; - mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; + // Error + else if (mstp_port->ReceiveError == true) { + mstp_port->ReceiveError = false; + mstp_port->SilenceTimer = 0; + mstp_port->EventCount++; + // indicate that an error has occurred during the reception of a frame + mstp_port->ReceivedInvalidFrame = true; + // wait for the start of a frame. + mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; + } else if (mstp_port->DataAvailable == true) { + // FrameType + if (mstp_port->Index == 0) { + mstp_port->SilenceTimer = 0; + mstp_port->EventCount++; + mstp_port->HeaderCRC = + CRC_Calc_Header(mstp_port->DataRegister, + mstp_port->HeaderCRC); + mstp_port->FrameType = mstp_port->DataRegister; + mstp_port->DataAvailable = false; + mstp_port->Index = 1; + mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; + } + // Destination + else if (mstp_port->Index == 1) { + mstp_port->SilenceTimer = 0; + mstp_port->EventCount++; + mstp_port->HeaderCRC = + CRC_Calc_Header(mstp_port->DataRegister, + mstp_port->HeaderCRC); + mstp_port->DestinationAddress = mstp_port->DataRegister; + mstp_port->DataAvailable = false; + mstp_port->Index = 2; + mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; + } + // Source + else if (mstp_port->Index == 2) { + mstp_port->SilenceTimer = 0; + mstp_port->EventCount++; + mstp_port->HeaderCRC = + CRC_Calc_Header(mstp_port->DataRegister, + mstp_port->HeaderCRC); + mstp_port->SourceAddress = mstp_port->DataRegister; + mstp_port->DataAvailable = false; + mstp_port->Index = 3; + mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; + } + // Length1 + else if (mstp_port->Index == 3) { + mstp_port->SilenceTimer = 0; + mstp_port->EventCount++; + mstp_port->HeaderCRC = + CRC_Calc_Header(mstp_port->DataRegister, + mstp_port->HeaderCRC); + mstp_port->DataLength = mstp_port->DataRegister * 256; + mstp_port->DataAvailable = false; + mstp_port->Index = 4; + mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; + } + // Length2 + else if (mstp_port->Index == 4) { + mstp_port->SilenceTimer = 0; + mstp_port->EventCount++; + mstp_port->HeaderCRC = + CRC_Calc_Header(mstp_port->DataRegister, + mstp_port->HeaderCRC); + mstp_port->DataLength += mstp_port->DataRegister; + mstp_port->DataAvailable = false; + mstp_port->Index = 5; + mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; + } + // HeaderCRC + else if (mstp_port->Index == 5) { + mstp_port->SilenceTimer = 0; + mstp_port->EventCount++; + mstp_port->HeaderCRC = + CRC_Calc_Header(mstp_port->DataRegister, + mstp_port->HeaderCRC); + mstp_port->DataAvailable = false; + mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER_CRC; + } + // not per MS/TP standard, but it is a case not covered + else { + mstp_port->ReceiveError = false; + mstp_port->SilenceTimer = 0; + mstp_port->EventCount++; + // indicate that an error has occurred during + // the reception of a frame + mstp_port->ReceivedInvalidFrame = true; + // wait for the start of a frame. + mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; + } } - // Source - else if (mstp_port->Index == 2) - { - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - mstp_port->HeaderCRC = CRC_Calc_Header( - mstp_port->DataRegister, - mstp_port->HeaderCRC); - mstp_port->SourceAddress = mstp_port->DataRegister; - mstp_port->DataAvailable = false; - mstp_port->Index = 3; - mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; - } - // Length1 - else if (mstp_port->Index == 3) - { - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - mstp_port->HeaderCRC = CRC_Calc_Header( - mstp_port->DataRegister, - mstp_port->HeaderCRC); - mstp_port->DataLength = mstp_port->DataRegister * 256; - mstp_port->DataAvailable = false; - mstp_port->Index = 4; - mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; - } - // Length2 - else if (mstp_port->Index == 4) - { - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - mstp_port->HeaderCRC = CRC_Calc_Header( - mstp_port->DataRegister, - mstp_port->HeaderCRC); - mstp_port->DataLength += mstp_port->DataRegister; - mstp_port->DataAvailable = false; - mstp_port->Index = 5; - mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; - } - // HeaderCRC - else if (mstp_port->Index == 5) - { - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - mstp_port->HeaderCRC = CRC_Calc_Header( - mstp_port->DataRegister, - mstp_port->HeaderCRC); - mstp_port->DataAvailable = false; - mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER_CRC; - } - // not per MS/TP standard, but it is a case not covered - else - { - mstp_port->ReceiveError = false; - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - // indicate that an error has occurred during - // the reception of a frame - mstp_port->ReceivedInvalidFrame = true; - // wait for the start of a frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - } - break; - // In the HEADER_CRC state, the node validates the CRC on the fixed - // message header. + break; + // In the HEADER_CRC state, the node validates the CRC on the fixed + // message header. case MSTP_RECEIVE_STATE_HEADER_CRC: - // BadCRC - if (mstp_port->HeaderCRC != 0x55) - { - // indicate that an error has occurred during the reception of a frame - mstp_port->ReceivedInvalidFrame = true; - // wait for the start of the next frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - else - { - if ((mstp_port->DestinationAddress == mstp_port->This_Station) || - (mstp_port->DestinationAddress == MSTP_BROADCAST_ADDRESS)) - { - // FrameTooLong - if (mstp_port->DataLength > MAX_MPDU) - { - // indicate that a frame with an illegal or - // unacceptable data length has been received + // BadCRC + if (mstp_port->HeaderCRC != 0x55) { + // indicate that an error has occurred during the reception of a frame mstp_port->ReceivedInvalidFrame = true; // wait for the start of the next frame. mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - // NoData - else if (mstp_port->DataLength == 0) - { - // indicate that a frame with no data has been received - mstp_port->ReceivedValidFrame = true; + } else { + if ((mstp_port->DestinationAddress == mstp_port->This_Station) + || (mstp_port->DestinationAddress == + MSTP_BROADCAST_ADDRESS)) { + // FrameTooLong + if (mstp_port->DataLength > MAX_MPDU) { + // indicate that a frame with an illegal or + // unacceptable data length has been received + mstp_port->ReceivedInvalidFrame = true; + // wait for the start of the next frame. + mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; + } + // NoData + else if (mstp_port->DataLength == 0) { + // indicate that a frame with no data has been received + mstp_port->ReceivedValidFrame = true; + // wait for the start of the next frame. + mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; + } + // Data + else { + mstp_port->Index = 0; + mstp_port->DataCRC = 0xFFFF; + // receive the data portion of the frame. + mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA; + } + } + // NotForUs + else { + // wait for the start of the next frame. + mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; + } + } + break; + // In the DATA state, the node waits for the data portion of a frame. + case MSTP_RECEIVE_STATE_DATA: + // Timeout + if (mstp_port->SilenceTimer > Tframe_abort) { + // indicate that an error has occurred during the reception of a frame + mstp_port->ReceivedInvalidFrame = true; // wait for the start of the next frame. mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - // Data - else - { - mstp_port->Index = 0; - mstp_port->DataCRC = 0xFFFF; - // receive the data portion of the frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA; - } } - // NotForUs - else - { - // wait for the start of the next frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; + // Error + else if (mstp_port->ReceiveError == true) { + mstp_port->ReceiveError = false; + mstp_port->SilenceTimer = 0; + // indicate that an error has occurred during the reception of a frame + mstp_port->ReceivedInvalidFrame = true; + // wait for the start of the next frame. + mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; + } else if (mstp_port->DataAvailable == true) { + // DataOctet + if (mstp_port->Index < mstp_port->DataLength) { + mstp_port->SilenceTimer = 0; + mstp_port->DataCRC = CRC_Calc_Data(mstp_port->DataRegister, + mstp_port->DataCRC); + mstp_port->InputBuffer[mstp_port->Index] = + mstp_port->DataRegister; + mstp_port->DataAvailable = false; + mstp_port->Index++; + mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA; + } + // CRC1 + else if (mstp_port->Index == mstp_port->DataLength) { + mstp_port->SilenceTimer = 0; + mstp_port->DataCRC = CRC_Calc_Data(mstp_port->DataRegister, + mstp_port->DataCRC); + mstp_port->DataAvailable = false; + mstp_port->Index++; // Index now becomes the number of data octets + mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA; + } + // CRC2 + else if (mstp_port->Index == (mstp_port->DataLength + 1)) { + mstp_port->SilenceTimer = 0; + mstp_port->DataCRC = CRC_Calc_Data(mstp_port->DataRegister, + mstp_port->DataCRC); + mstp_port->DataAvailable = false; + mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA_CRC; + } } - } - break; - // In the DATA state, the node waits for the data portion of a frame. - case MSTP_RECEIVE_STATE_DATA: - // Timeout - if (mstp_port->SilenceTimer > Tframe_abort) - { - // indicate that an error has occurred during the reception of a frame - mstp_port->ReceivedInvalidFrame = true; - // wait for the start of the next frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - // Error - else if (mstp_port->ReceiveError == true) - { - mstp_port->ReceiveError = false; - mstp_port->SilenceTimer = 0; - // indicate that an error has occurred during the reception of a frame - mstp_port->ReceivedInvalidFrame = true; - // wait for the start of the next frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - else if (mstp_port->DataAvailable == true) - { - // DataOctet - if (mstp_port->Index < mstp_port->DataLength) - { - mstp_port->SilenceTimer = 0; - mstp_port->DataCRC = CRC_Calc_Data( - mstp_port->DataRegister, - mstp_port->DataCRC); - mstp_port->InputBuffer[mstp_port->Index] = mstp_port->DataRegister; - mstp_port->DataAvailable = false; - mstp_port->Index++; - mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA; - } - // CRC1 - else if (mstp_port->Index == mstp_port->DataLength) - { - mstp_port->SilenceTimer = 0; - mstp_port->DataCRC = CRC_Calc_Data( - mstp_port->DataRegister, - mstp_port->DataCRC); - mstp_port->DataAvailable = false; - mstp_port->Index++; // Index now becomes the number of data octets - mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA; - } - // CRC2 - else if (mstp_port->Index == (mstp_port->DataLength + 1)) - { - mstp_port->SilenceTimer = 0; - mstp_port->DataCRC = CRC_Calc_Data( - mstp_port->DataRegister, - mstp_port->DataCRC); - mstp_port->DataAvailable = false; - mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA_CRC; - } - } - break; - // In the DATA_CRC state, the node validates the CRC of the message data. + break; + // In the DATA_CRC state, the node validates the CRC of the message data. case MSTP_RECEIVE_STATE_DATA_CRC: - // GoodCRC - if (mstp_port->DataCRC == 0xF0B8) - { - // indicate the complete reception of a valid frame - mstp_port->ReceivedValidFrame = true; + // GoodCRC + if (mstp_port->DataCRC == 0xF0B8) { + // indicate the complete reception of a valid frame + mstp_port->ReceivedValidFrame = true; - // now might be a good time to process the message or - // copy the data to a buffer so that we can process the message + // now might be a good time to process the message or + // copy the data to a buffer so that we can process the message - // wait for the start of the next frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - // BadCRC - else - { - // to indicate that an error has occurred during the reception of a frame - mstp_port->ReceivedInvalidFrame = true; - // wait for the start of the next frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - break; + // wait for the start of the next frame. + mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; + } + // BadCRC + else { + // to indicate that an error has occurred during the reception of a frame + mstp_port->ReceivedInvalidFrame = true; + // wait for the start of the next frame. + mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; + } + break; default: - // shouldn't get here - but if we do... - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - break; - } + // shouldn't get here - but if we do... + mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; + break; + } - return; + return; } void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port) { - switch (mstp_port->master_state) - { + switch (mstp_port->master_state) { case MSTP_MASTER_STATE_INITIALIZE: - // DoneInitializing - mstp_port->This_Station = 0; // FIXME: the node's station address - // indicate that the next station is unknown - mstp_port->Next_Station = mstp_port->This_Station; - mstp_port->Poll_Station = mstp_port->This_Station; - // cause a Poll For Master to be sent when this node first - // receives the token - mstp_port->TokenCount = Npoll; - mstp_port->SoleMaster = false; - mstp_port->ReceivedValidFrame = false; - mstp_port->ReceivedInvalidFrame = false; - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - break; - // In the IDLE state, the node waits for a frame. - case MSTP_MASTER_STATE_IDLE: - // LostToken - if (mstp_port->SilenceTimer >= Tno_token) - { - // assume that the token has been lost - mstp_port->master_state = MSTP_MASTER_STATE_NO_TOKEN; - } - // mstp_port->ReceivedInvalidFrame - else if (mstp_port->ReceivedInvalidFrame == true) - { - // invalid frame was received + // DoneInitializing + mstp_port->This_Station = 0; // FIXME: the node's station address + // indicate that the next station is unknown + mstp_port->Next_Station = mstp_port->This_Station; + mstp_port->Poll_Station = mstp_port->This_Station; + // cause a Poll For Master to be sent when this node first + // receives the token + mstp_port->TokenCount = Npoll; + mstp_port->SoleMaster = false; + mstp_port->ReceivedValidFrame = false; mstp_port->ReceivedInvalidFrame = false; - // wait for the next frame - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } - // ReceivedUnwantedFrame - else if (mstp_port->ReceivedValidFrame == true) - { - if ((mstp_port->DestinationAddress != mstp_port->This_Station) || - (mstp_port->DestinationAddress != MSTP_BROADCAST_ADDRESS)) - { - // an unexpected or unwanted frame was received. - mstp_port->ReceivedValidFrame = false; - // wait for the next frame - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; + mstp_port->master_state = MSTP_MASTER_STATE_IDLE; + break; + // In the IDLE state, the node waits for a frame. + case MSTP_MASTER_STATE_IDLE: + // LostToken + if (mstp_port->SilenceTimer >= Tno_token) { + // assume that the token has been lost + mstp_port->master_state = MSTP_MASTER_STATE_NO_TOKEN; } - // DestinationAddress is equal to 255 (broadcast) and - // FrameType has a value of Token, BACnet Data Expecting Reply, Test_Request, - // or a proprietary type known to this node that expects a reply - // (such frames may not be broadcast), or - else if ((mstp_port->DestinationAddress == MSTP_BROADCAST_ADDRESS) && - ((mstp_port->FrameType == FRAME_TYPE_TOKEN) || - (mstp_port->FrameType == FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY) || - (mstp_port->FrameType == FRAME_TYPE_TEST_REQUEST))) - { - // an unexpected or unwanted frame was received. - mstp_port->ReceivedValidFrame = false; - // wait for the next frame - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; + // mstp_port->ReceivedInvalidFrame + else if (mstp_port->ReceivedInvalidFrame == true) { + // invalid frame was received + mstp_port->ReceivedInvalidFrame = false; + // wait for the next frame + mstp_port->master_state = MSTP_MASTER_STATE_IDLE; } - // FrameType has a value that indicates a standard or proprietary type - // that is not known to this node. - // FIXME: change this if you add a proprietary type - else if /*(*/(mstp_port->FrameType >= FRAME_TYPE_PROPRIETARY_MIN) /*&&*/ - /*(FrameType <= FRAME_TYPE_PROPRIETARY_MAX))*/ - /* unnecessary if FrameType is uint8_t with max of 255 */ - { - // an unexpected or unwanted frame was received. - mstp_port->ReceivedValidFrame = false; - // wait for the next frame - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; + // ReceivedUnwantedFrame + else if (mstp_port->ReceivedValidFrame == true) { + if ((mstp_port->DestinationAddress != mstp_port->This_Station) + || (mstp_port->DestinationAddress != + MSTP_BROADCAST_ADDRESS)) { + // an unexpected or unwanted frame was received. + mstp_port->ReceivedValidFrame = false; + // wait for the next frame + mstp_port->master_state = MSTP_MASTER_STATE_IDLE; + } + // DestinationAddress is equal to 255 (broadcast) and + // FrameType has a value of Token, BACnet Data Expecting Reply, Test_Request, + // or a proprietary type known to this node that expects a reply + // (such frames may not be broadcast), or + else if ((mstp_port->DestinationAddress == + MSTP_BROADCAST_ADDRESS) + && ((mstp_port->FrameType == FRAME_TYPE_TOKEN) + || (mstp_port->FrameType == + FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY) + || (mstp_port->FrameType == FRAME_TYPE_TEST_REQUEST))) { + // an unexpected or unwanted frame was received. + mstp_port->ReceivedValidFrame = false; + // wait for the next frame + mstp_port->master_state = MSTP_MASTER_STATE_IDLE; + } + // FrameType has a value that indicates a standard or proprietary type + // that is not known to this node. + // FIXME: change this if you add a proprietary type + else if /*( */ (mstp_port->FrameType >= + FRAME_TYPE_PROPRIETARY_MIN) + { /*&& */ + /*(FrameType <= FRAME_TYPE_PROPRIETARY_MAX)) */ + /* unnecessary if FrameType is uint8_t with max of 255 */ + // an unexpected or unwanted frame was received. + mstp_port->ReceivedValidFrame = false; + // wait for the next frame + mstp_port->master_state = MSTP_MASTER_STATE_IDLE; + } + // ReceivedToken + else if ((mstp_port->DestinationAddress == + mstp_port->This_Station) + && (mstp_port->FrameType == FRAME_TYPE_TOKEN)) { + mstp_port->ReceivedValidFrame = false; + mstp_port->FrameCount = 0; + mstp_port->SoleMaster = false; + mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; + } + // ReceivedPFM + else if ((mstp_port->DestinationAddress == + mstp_port->This_Station) + && (mstp_port->FrameType == FRAME_TYPE_POLL_FOR_MASTER)) { + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER, + mstp_port->SourceAddress, mstp_port->This_Station, + NULL, 0); + mstp_port->ReceivedValidFrame = false; + // wait for the next frame + mstp_port->master_state = MSTP_MASTER_STATE_IDLE; + } + // ReceivedDataNoReply + // or a proprietary type known to this node that does not expect a reply + else if (((mstp_port->DestinationAddress == + mstp_port->This_Station) + || (mstp_port->DestinationAddress == + MSTP_BROADCAST_ADDRESS)) + && ((mstp_port->FrameType == + FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY) || + // (mstp_port->FrameType == FRAME_TYPE_PROPRIETARY_0) || + (mstp_port->FrameType == FRAME_TYPE_TEST_RESPONSE))) { + // FIXME: indicate successful reception to the higher layers + // i.e. Process this frame! + mstp_port->ReceivedValidFrame = false; + // wait for the next frame + mstp_port->master_state = MSTP_MASTER_STATE_IDLE; + } + // ReceivedDataNeedingReply + // or a proprietary type known to this node that expects a reply + else if ((mstp_port->DestinationAddress == + mstp_port->This_Station) + && ((mstp_port->FrameType == + FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY) || + // (mstp_port->FrameType == FRAME_TYPE_PROPRIETARY) || + (mstp_port->FrameType == FRAME_TYPE_TEST_REQUEST))) { + mstp_port->ReplyPostponedTimer = 0; + // indicate successful reception to the higher layers + // (management entity in the case of Test_Request); + mstp_port->ReceivedValidFrame = false; + mstp_port->master_state = + MSTP_MASTER_STATE_ANSWER_DATA_REQUEST; + } } - // ReceivedToken - else if ((mstp_port->DestinationAddress == mstp_port->This_Station) && - (mstp_port->FrameType == FRAME_TYPE_TOKEN)) - { - mstp_port->ReceivedValidFrame = false; - mstp_port->FrameCount = 0; - mstp_port->SoleMaster = false; - mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; - } - // ReceivedPFM - else if ((mstp_port->DestinationAddress == mstp_port->This_Station) && - (mstp_port->FrameType == FRAME_TYPE_POLL_FOR_MASTER)) - { - MSTP_Create_And_Send_Frame( - mstp_port, - FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER, - mstp_port->SourceAddress, - mstp_port->This_Station, - NULL,0); - mstp_port->ReceivedValidFrame = false; - // wait for the next frame - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } - // ReceivedDataNoReply - // or a proprietary type known to this node that does not expect a reply - else if (((mstp_port->DestinationAddress == mstp_port->This_Station) || - (mstp_port->DestinationAddress == MSTP_BROADCAST_ADDRESS)) && - ((mstp_port->FrameType == FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY) || - // (mstp_port->FrameType == FRAME_TYPE_PROPRIETARY_0) || - (mstp_port->FrameType == FRAME_TYPE_TEST_RESPONSE))) - { - // FIXME: indicate successful reception to the higher layers - // i.e. Process this frame! - mstp_port->ReceivedValidFrame = false; - // wait for the next frame - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } - // ReceivedDataNeedingReply - // or a proprietary type known to this node that expects a reply - else if ((mstp_port->DestinationAddress == mstp_port->This_Station) && - ((mstp_port->FrameType == FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY) || - // (mstp_port->FrameType == FRAME_TYPE_PROPRIETARY) || - (mstp_port->FrameType == FRAME_TYPE_TEST_REQUEST))) - { - mstp_port->ReplyPostponedTimer = 0; - // indicate successful reception to the higher layers - // (management entity in the case of Test_Request); - mstp_port->ReceivedValidFrame = false; - mstp_port->master_state = MSTP_MASTER_STATE_ANSWER_DATA_REQUEST; - } - } - break; - // In the USE_TOKEN state, the node is allowed to send one or - // more data frames. These may be BACnet Data frames or - // proprietary frames. + break; + // In the USE_TOKEN state, the node is allowed to send one or + // more data frames. These may be BACnet Data frames or + // proprietary frames. case MSTP_MASTER_STATE_USE_TOKEN: - // NothingToSend - // FIXME: If there is no data frame awaiting transmission, - { - mstp_port->FrameCount = mstp_port->Nmax_info_frames; - mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; - } - // SendNoWait - // FIXME: If there is a frame awaiting transmission that - // is of type Test_Response, BACnet Data Not Expecting Reply, - // or a proprietary type that does not expect a reply, + // NothingToSend + // FIXME: If there is no data frame awaiting transmission, + { + mstp_port->FrameCount = mstp_port->Nmax_info_frames; + mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; + } + // SendNoWait + // FIXME: If there is a frame awaiting transmission that + // is of type Test_Response, BACnet Data Not Expecting Reply, + // or a proprietary type that does not expect a reply, // { // // transmit the data frame // MSTP_Create_And_Send_Frame(?????????????); // FrameCount++; // mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; // } - // SendAndWait - // FIXME: If there is a frame awaiting transmission that is of - // type Test_Request, BACnet Data Expecting Reply, or - // a proprietary type that expects a reply, + // SendAndWait + // FIXME: If there is a frame awaiting transmission that is of + // type Test_Request, BACnet Data Expecting Reply, or + // a proprietary type that expects a reply, // { // // transmit the data frame // MSTP_Create_And_Send_Frame(); // FrameCount++; // mstp_port->master_state = MSTP_MASTER_STATE_WAIT_FOR_REPLY; // } - // In the WAIT_FOR_REPLY state, the node waits for - // a reply from another node. + // In the WAIT_FOR_REPLY state, the node waits for + // a reply from another node. case MSTP_MASTER_STATE_WAIT_FOR_REPLY: - // ReplyTimeout - if (mstp_port->SilenceTimer >= Treply_timeout) - { - // assume that the request has failed - mstp_port->FrameCount = mstp_port->Nmax_info_frames; - mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; - // Any retry of the data frame shall await the next entry - // to the USE_TOKEN state. (Because of the length of the timeout, - // this transition will cause the token to be passed regardless - // of the initial value of FrameCount.) - } - // InvalidFrame - else if ((mstp_port->SilenceTimer < Treply_timeout) && - (mstp_port->ReceivedInvalidFrame == true)) - { - // error in frame reception - mstp_port->ReceivedInvalidFrame = false; - mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; - } - // ReceivedReply - // or a proprietary type that indicates a reply - else if ((mstp_port->SilenceTimer < Treply_timeout) && - (mstp_port->ReceivedValidFrame == true) && - (mstp_port->DestinationAddress == mstp_port->This_Station) && - ((mstp_port->FrameType == FRAME_TYPE_TEST_RESPONSE) || - //(mstp_port->FrameType == FRAME_TYPE_PROPRIETARY_0) || - (mstp_port->FrameType == FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY))) - { - // FIXME: indicate successful reception to the higher layers - mstp_port->ReceivedValidFrame = false; - mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; - } - // ReceivedPostpone - else if ((mstp_port->SilenceTimer < Treply_timeout) && - (mstp_port->ReceivedValidFrame == true) && - (mstp_port->DestinationAddress == mstp_port->This_Station) && - (mstp_port->FrameType == FRAME_TYPE_REPLY_POSTPONED)) - { - // FIXME: then the reply to the message has been postponed until a later time. - // So, what does this really mean? - mstp_port->ReceivedValidFrame = false; - mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; - } - // ReceivedUnexpectedFrame - else if ((mstp_port->SilenceTimer < Treply_timeout) && - (mstp_port->ReceivedValidFrame == true) && - (mstp_port->DestinationAddress != mstp_port->This_Station)) - //the expected reply should not be broadcast) - { - // an unexpected frame was received - // This may indicate the presence of multiple tokens. - mstp_port->ReceivedValidFrame = false; - // Synchronize with the network. - // This action drops the token. - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } - // ReceivedUnexpectedFrame - else if ((mstp_port->SilenceTimer < Treply_timeout) && - (mstp_port->ReceivedValidFrame == true) && - ((mstp_port->FrameType == FRAME_TYPE_TEST_RESPONSE) || - //(mstp_port->FrameType == FRAME_TYPE_PROPRIETARY_0) || - (mstp_port->FrameType == FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY))) - { - // An unexpected frame was received. - // This may indicate the presence of multiple tokens. - mstp_port->ReceivedValidFrame = false; - // Synchronize with the network. - // This action drops the token. - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } - break; - // The DONE_WITH_TOKEN state either sends another data frame, - // passes the token, or initiates a Poll For Master cycle. - case MSTP_MASTER_STATE_DONE_WITH_TOKEN: - // SendAnotherFrame - if (mstp_port->FrameCount < mstp_port->Nmax_info_frames) - { - // then this node may send another information frame - // before passing the token. - mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; - } - // mstp_port->SoleMaster - else if ((mstp_port->FrameCount >= mstp_port->Nmax_info_frames) && - (mstp_port->TokenCount < Npoll) && - (mstp_port->SoleMaster == true)) - { - // there are no other known master nodes to - // which the token may be sent (true master-slave operation). - mstp_port->FrameCount = 0; - mstp_port->TokenCount++; - mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; - } - // SendToken - else if (((mstp_port->FrameCount >= mstp_port->Nmax_info_frames) && - (mstp_port->TokenCount < Npoll) && - (mstp_port->SoleMaster == false)) || - // The comparison of NS and TS+1 eliminates the Poll For Master - // if there are no addresses between TS and NS, since there is no - // address at which a new master node may be found in that case. - (mstp_port->Next_Station == - (uint8_t)((mstp_port->This_Station +1) % (mstp_port->Nmax_master + 1)))) - { - mstp_port->TokenCount++; - // transmit a Token frame to NS - MSTP_Create_And_Send_Frame( - mstp_port, - FRAME_TYPE_TOKEN, - mstp_port->Next_Station, - mstp_port->This_Station, - NULL,0); - mstp_port->RetryCount = 0; - mstp_port->EventCount = 0; - mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; - } - // SendMaintenancePFM - else if ((mstp_port->FrameCount >= mstp_port->Nmax_info_frames) && - (mstp_port->TokenCount >= Npoll) && - ((uint8_t)((mstp_port->Poll_Station + 1) % (mstp_port->Nmax_master + 1)) != mstp_port->Next_Station)) - { - mstp_port->Poll_Station = (mstp_port->Poll_Station + 1) % (mstp_port->Nmax_master + 1); - MSTP_Create_And_Send_Frame( - mstp_port, - FRAME_TYPE_POLL_FOR_MASTER, - mstp_port->Poll_Station, - mstp_port->This_Station, - NULL,0); - mstp_port->RetryCount = 0; - mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; - } - // ResetMaintenancePFM - else if ((mstp_port->FrameCount >= mstp_port->Nmax_info_frames) && - (mstp_port->TokenCount >= Npoll) && - ((uint8_t)((mstp_port->Poll_Station + 1) % (mstp_port->Nmax_master + 1)) == mstp_port->Next_Station) && - (mstp_port->SoleMaster == false)) - { - mstp_port->Poll_Station = mstp_port->This_Station; - // transmit a Token frame to NS - MSTP_Create_And_Send_Frame( - mstp_port, - FRAME_TYPE_TOKEN, - mstp_port->Next_Station, - mstp_port->This_Station, - NULL,0); - mstp_port->RetryCount = 0; - mstp_port->TokenCount = 0; - mstp_port->EventCount = 0; - mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; - } - // SoleMasterRestartMaintenancePFM - else if ((mstp_port->FrameCount >= mstp_port->Nmax_info_frames) && - (mstp_port->TokenCount >= Npoll) && - ((uint8_t)((mstp_port->Poll_Station + 1) % (mstp_port->Nmax_master + 1)) == mstp_port->Next_Station) && - (mstp_port->SoleMaster == true)) - { - mstp_port->Poll_Station = (mstp_port->Next_Station +1) % (mstp_port->Nmax_master + 1); - MSTP_Create_And_Send_Frame( - mstp_port, - FRAME_TYPE_POLL_FOR_MASTER, - mstp_port->Poll_Station, - mstp_port->This_Station, - NULL,0); - // no known successor node - mstp_port->Next_Station = mstp_port->This_Station; - mstp_port->RetryCount = 0; - mstp_port->TokenCount = 0; - mstp_port->EventCount = 0; - // find a new successor to TS - mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; - } - // The PASS_TOKEN state listens for a successor to begin using - // the token that this node has just attempted to pass. - case MSTP_MASTER_STATE_PASS_TOKEN: - // SawTokenUser - if ((mstp_port->SilenceTimer < Tusage_timeout) && - (mstp_port->EventCount > Nmin_octets)) - { - // Assume that a frame has been sent by the new token user. - // Enter the IDLE state to process the frame. - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } - // RetrySendToken - else if ((mstp_port->SilenceTimer >= Tusage_timeout) && - (mstp_port->RetryCount < Nretry_token)) - { - mstp_port->RetryCount++; - // Transmit a Token frame to NS - MSTP_Create_And_Send_Frame( - mstp_port, - FRAME_TYPE_TOKEN, - mstp_port->Next_Station, - mstp_port->This_Station, - NULL,0); - mstp_port->EventCount = 0; - // re-enter the current state to listen for NS - // to begin using the token. - } - // FindNewSuccessor - else if ((mstp_port->SilenceTimer >= Tusage_timeout) && - (mstp_port->RetryCount >= Nretry_token)) - { - // Assume that NS has failed. - mstp_port->Poll_Station = (mstp_port->Next_Station + 1) % (mstp_port->Nmax_master + 1); - // Transmit a Poll For Master frame to PS. - MSTP_Create_And_Send_Frame( - mstp_port, - FRAME_TYPE_POLL_FOR_MASTER, - mstp_port->Poll_Station, - mstp_port->This_Station, - NULL,0); - // no known successor node - mstp_port->Next_Station = mstp_port->This_Station; - mstp_port->RetryCount = 0; - mstp_port->TokenCount = 0; - mstp_port->EventCount = 0; - // find a new successor to TS - mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; - } - break; - // The NO_TOKEN state is entered if mstp_port->SilenceTimer becomes greater - // than Tno_token, indicating that there has been no network activity - // for that period of time. The timeout is continued to determine - // whether or not this node may create a token. - case MSTP_MASTER_STATE_NO_TOKEN: - // SawFrame - if ((mstp_port->SilenceTimer < (Tno_token + (Tslot * mstp_port->This_Station))) && - (mstp_port->EventCount > Nmin_octets)) - { - // Some other node exists at a lower address. - // Enter the IDLE state to receive and process the incoming frame. - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } - // GenerateToken - else if ((mstp_port->SilenceTimer >= (Tno_token + (Tslot * mstp_port->This_Station))) && - (mstp_port->SilenceTimer < (Tno_token + (Tslot * (mstp_port->This_Station + 1))))) - { - // Assume that this node is the lowest numerical address - // on the network and is empowered to create a token. - mstp_port->Poll_Station = (mstp_port->This_Station + 1) % (mstp_port->Nmax_master + 1); - // Transmit a Poll For Master frame to PS. - MSTP_Create_And_Send_Frame( - mstp_port, - FRAME_TYPE_POLL_FOR_MASTER, - mstp_port->Poll_Station, - mstp_port->This_Station, - NULL,0); - // indicate that the next station is unknown - mstp_port->Next_Station = mstp_port->This_Station; - mstp_port->RetryCount = 0; - mstp_port->TokenCount = 0; - mstp_port->EventCount = 0; - // enter the POLL_FOR_MASTER state to find a new successor to TS. - mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; - } - break; - // In the POLL_FOR_MASTER state, the node listens for a reply to - // a previously sent Poll For Master frame in order to find - // a successor node. - case MSTP_MASTER_STATE_POLL_FOR_MASTER: - // ReceivedReplyToPFM - if ((mstp_port->ReceivedValidFrame == true) && - (mstp_port->DestinationAddress == mstp_port->This_Station) && - (mstp_port->FrameType == FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) - { - mstp_port->SoleMaster = false; - mstp_port->Next_Station = mstp_port->SourceAddress; - mstp_port->EventCount = 0; - // Transmit a Token frame to NS - MSTP_Create_And_Send_Frame( - mstp_port, - FRAME_TYPE_TOKEN, - mstp_port->Next_Station, - mstp_port->This_Station, - NULL,0); - mstp_port->Poll_Station = mstp_port->This_Station; - mstp_port->TokenCount = 0; - mstp_port->RetryCount = 0; - mstp_port->ReceivedValidFrame = false; - mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; - } - // ReceivedUnexpectedFrame - else if ((mstp_port->ReceivedValidFrame == true) && - ((mstp_port->DestinationAddress != mstp_port->This_Station) || - (mstp_port->FrameType != FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER))) - { - // An unexpected frame was received. - // This may indicate the presence of multiple tokens. - mstp_port->ReceivedValidFrame = false; - // enter the IDLE state to synchronize with the network. - // This action drops the token. - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } - // mstp_port->SoleMaster - else if ((mstp_port->SoleMaster == true) && - ((mstp_port->SilenceTimer >= Tusage_timeout) || - (mstp_port->ReceivedInvalidFrame == true))) - { - // There was no valid reply to the periodic poll - // by the sole known master for other masters. - mstp_port->FrameCount = 0; - mstp_port->ReceivedInvalidFrame = false; - mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; - } - // DoneWithPFM - else if ((mstp_port->SoleMaster == false) && - (mstp_port->Next_Station != mstp_port->This_Station) && - ((mstp_port->SilenceTimer >= Tusage_timeout) || - (mstp_port->ReceivedInvalidFrame == true))) - { - // There was no valid reply to the maintenance - // poll for a master at address PS. - mstp_port->EventCount = 0; - // transmit a Token frame to NS - MSTP_Create_And_Send_Frame( - mstp_port, - FRAME_TYPE_TOKEN, - mstp_port->Next_Station, - mstp_port->This_Station, - NULL,0); - mstp_port->RetryCount = 0; - mstp_port->ReceivedInvalidFrame = false; - mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; - } - // SendNextPFM - else if ((mstp_port->SoleMaster == false) && - (mstp_port->Next_Station == mstp_port->This_Station) && // no known successor node - ((uint8_t)((mstp_port->Poll_Station + 1) % (mstp_port->Nmax_master + 1)) != mstp_port->This_Station) && - ((mstp_port->SilenceTimer >= Tusage_timeout) || - (mstp_port->ReceivedInvalidFrame == true))) - { - mstp_port->Poll_Station = - (mstp_port->Poll_Station + 1) % (mstp_port->Nmax_master + 1); - // Transmit a Poll For Master frame to PS. - MSTP_Create_And_Send_Frame( - mstp_port, - FRAME_TYPE_POLL_FOR_MASTER, - mstp_port->Poll_Station, - mstp_port->This_Station, - NULL,0); - mstp_port->RetryCount = 0; - mstp_port->ReceivedInvalidFrame = false; - // Re-enter the current state. - } - // DeclareSoleMaster - else if ((mstp_port->SoleMaster == false) && - (mstp_port->Next_Station == mstp_port->This_Station) && // no known successor node - ((uint8_t)((mstp_port->Poll_Station + 1) % - (mstp_port->Nmax_master + 1)) == mstp_port->This_Station) && - ((mstp_port->SilenceTimer >= Tusage_timeout) || - (mstp_port->ReceivedInvalidFrame == true))) - { - // to indicate that this station is the only master - mstp_port->SoleMaster = true; - mstp_port->FrameCount = 0; - mstp_port->ReceivedInvalidFrame = false; - mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; - } - break; - // The ANSWER_DATA_REQUEST state is entered when a - // BACnet Data Expecting Reply, a Test_Request, or - // a proprietary frame that expects a reply is received. - case MSTP_MASTER_STATE_ANSWER_DATA_REQUEST: - if (mstp_port->ReplyPostponedTimer <= Treply_delay) - { - // Reply - // If a reply is available from the higher layers - // within Treply_delay after the reception of the - // final octet of the requesting frame - // (the mechanism used to determine this is a local matter), - // then call MSTP_Create_And_Send_Frame to transmit the reply frame - // and enter the IDLE state to wait for the next frame. - - // Test Request - // If a receiving node can successfully receive and return - // the information field, it shall do so. If it cannot receive - // and return the entire information field but can detect - // the reception of a valid Test_Request frame - // (for example, by computing the CRC on octets as - // they are received), then the receiving node shall discard - // the information field and return a Test_Response containing - // no information field. If the receiving node cannot detect - // the valid reception of frames with overlength information fields, - // then no response shall be returned. - if (mstp_port->FrameType == FRAME_TYPE_TEST_REQUEST) - { - MSTP_Create_And_Send_Frame( - mstp_port, - FRAME_TYPE_TEST_RESPONSE, - mstp_port->SourceAddress, - mstp_port->This_Station, - (uint8_t *)&mstp_port->InputBuffer[0], - mstp_port->Index); + // ReplyTimeout + if (mstp_port->SilenceTimer >= Treply_timeout) { + // assume that the request has failed + mstp_port->FrameCount = mstp_port->Nmax_info_frames; + mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; + // Any retry of the data frame shall await the next entry + // to the USE_TOKEN state. (Because of the length of the timeout, + // this transition will cause the token to be passed regardless + // of the initial value of FrameCount.) } - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } + // InvalidFrame + else if ((mstp_port->SilenceTimer < Treply_timeout) && + (mstp_port->ReceivedInvalidFrame == true)) { + // error in frame reception + mstp_port->ReceivedInvalidFrame = false; + mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; + } + // ReceivedReply + // or a proprietary type that indicates a reply + else if ((mstp_port->SilenceTimer < Treply_timeout) && + (mstp_port->ReceivedValidFrame == true) && + (mstp_port->DestinationAddress == mstp_port->This_Station) && + ((mstp_port->FrameType == FRAME_TYPE_TEST_RESPONSE) || + //(mstp_port->FrameType == FRAME_TYPE_PROPRIETARY_0) || + (mstp_port->FrameType == + FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY))) { + // FIXME: indicate successful reception to the higher layers + mstp_port->ReceivedValidFrame = false; + mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; + } + // ReceivedPostpone + else if ((mstp_port->SilenceTimer < Treply_timeout) && + (mstp_port->ReceivedValidFrame == true) && + (mstp_port->DestinationAddress == mstp_port->This_Station) && + (mstp_port->FrameType == FRAME_TYPE_REPLY_POSTPONED)) { + // FIXME: then the reply to the message has been postponed until a later time. + // So, what does this really mean? + mstp_port->ReceivedValidFrame = false; + mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; + } + // ReceivedUnexpectedFrame + else if ((mstp_port->SilenceTimer < Treply_timeout) && + (mstp_port->ReceivedValidFrame == true) && + (mstp_port->DestinationAddress != mstp_port->This_Station)) + //the expected reply should not be broadcast) + { + // an unexpected frame was received + // This may indicate the presence of multiple tokens. + mstp_port->ReceivedValidFrame = false; + // Synchronize with the network. + // This action drops the token. + mstp_port->master_state = MSTP_MASTER_STATE_IDLE; + } + // ReceivedUnexpectedFrame + else if ((mstp_port->SilenceTimer < Treply_timeout) && + (mstp_port->ReceivedValidFrame == true) && + ((mstp_port->FrameType == FRAME_TYPE_TEST_RESPONSE) || + //(mstp_port->FrameType == FRAME_TYPE_PROPRIETARY_0) || + (mstp_port->FrameType == + FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY))) { + // An unexpected frame was received. + // This may indicate the presence of multiple tokens. + mstp_port->ReceivedValidFrame = false; + // Synchronize with the network. + // This action drops the token. + mstp_port->master_state = MSTP_MASTER_STATE_IDLE; + } + break; + // The DONE_WITH_TOKEN state either sends another data frame, + // passes the token, or initiates a Poll For Master cycle. + case MSTP_MASTER_STATE_DONE_WITH_TOKEN: + // SendAnotherFrame + if (mstp_port->FrameCount < mstp_port->Nmax_info_frames) { + // then this node may send another information frame + // before passing the token. + mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; + } + // mstp_port->SoleMaster + else if ((mstp_port->FrameCount >= mstp_port->Nmax_info_frames) && + (mstp_port->TokenCount < Npoll) && + (mstp_port->SoleMaster == true)) { + // there are no other known master nodes to + // which the token may be sent (true master-slave operation). + mstp_port->FrameCount = 0; + mstp_port->TokenCount++; + mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; + } + // SendToken + else if (((mstp_port->FrameCount >= mstp_port->Nmax_info_frames) && + (mstp_port->TokenCount < Npoll) && + (mstp_port->SoleMaster == false)) || + // The comparison of NS and TS+1 eliminates the Poll For Master + // if there are no addresses between TS and NS, since there is no + // address at which a new master node may be found in that case. + (mstp_port->Next_Station == + (uint8_t) ((mstp_port->This_Station + + 1) % (mstp_port->Nmax_master + 1)))) { + mstp_port->TokenCount++; + // transmit a Token frame to NS + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_TOKEN, + mstp_port->Next_Station, mstp_port->This_Station, NULL, 0); + mstp_port->RetryCount = 0; + mstp_port->EventCount = 0; + mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; + } + // SendMaintenancePFM + else if ((mstp_port->FrameCount >= mstp_port->Nmax_info_frames) && + (mstp_port->TokenCount >= Npoll) && + ((uint8_t) ((mstp_port->Poll_Station + + 1) % (mstp_port->Nmax_master + 1)) != + mstp_port->Next_Station)) { + mstp_port->Poll_Station = + (mstp_port->Poll_Station + 1) % (mstp_port->Nmax_master + + 1); + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_POLL_FOR_MASTER, mstp_port->Poll_Station, + mstp_port->This_Station, NULL, 0); + mstp_port->RetryCount = 0; + mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; + } + // ResetMaintenancePFM + else if ((mstp_port->FrameCount >= mstp_port->Nmax_info_frames) && + (mstp_port->TokenCount >= Npoll) && + ((uint8_t) ((mstp_port->Poll_Station + + 1) % (mstp_port->Nmax_master + 1)) == + mstp_port->Next_Station) + && (mstp_port->SoleMaster == false)) { + mstp_port->Poll_Station = mstp_port->This_Station; + // transmit a Token frame to NS + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_TOKEN, + mstp_port->Next_Station, mstp_port->This_Station, NULL, 0); + mstp_port->RetryCount = 0; + mstp_port->TokenCount = 0; + mstp_port->EventCount = 0; + mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; + } + // SoleMasterRestartMaintenancePFM + else if ((mstp_port->FrameCount >= mstp_port->Nmax_info_frames) && + (mstp_port->TokenCount >= Npoll) && + ((uint8_t) ((mstp_port->Poll_Station + + 1) % (mstp_port->Nmax_master + 1)) == + mstp_port->Next_Station) + && (mstp_port->SoleMaster == true)) { + mstp_port->Poll_Station = + (mstp_port->Next_Station + 1) % (mstp_port->Nmax_master + + 1); + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_POLL_FOR_MASTER, mstp_port->Poll_Station, + mstp_port->This_Station, NULL, 0); + // no known successor node + mstp_port->Next_Station = mstp_port->This_Station; + mstp_port->RetryCount = 0; + mstp_port->TokenCount = 0; + mstp_port->EventCount = 0; + // find a new successor to TS + mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; + } + // The PASS_TOKEN state listens for a successor to begin using + // the token that this node has just attempted to pass. + case MSTP_MASTER_STATE_PASS_TOKEN: + // SawTokenUser + if ((mstp_port->SilenceTimer < Tusage_timeout) && + (mstp_port->EventCount > Nmin_octets)) { + // Assume that a frame has been sent by the new token user. + // Enter the IDLE state to process the frame. + mstp_port->master_state = MSTP_MASTER_STATE_IDLE; + } + // RetrySendToken + else if ((mstp_port->SilenceTimer >= Tusage_timeout) && + (mstp_port->RetryCount < Nretry_token)) { + mstp_port->RetryCount++; + // Transmit a Token frame to NS + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_TOKEN, + mstp_port->Next_Station, mstp_port->This_Station, NULL, 0); + mstp_port->EventCount = 0; + // re-enter the current state to listen for NS + // to begin using the token. + } + // FindNewSuccessor + else if ((mstp_port->SilenceTimer >= Tusage_timeout) && + (mstp_port->RetryCount >= Nretry_token)) { + // Assume that NS has failed. + mstp_port->Poll_Station = + (mstp_port->Next_Station + 1) % (mstp_port->Nmax_master + + 1); + // Transmit a Poll For Master frame to PS. + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_POLL_FOR_MASTER, + mstp_port->Poll_Station, mstp_port->This_Station, NULL, 0); + // no known successor node + mstp_port->Next_Station = mstp_port->This_Station; + mstp_port->RetryCount = 0; + mstp_port->TokenCount = 0; + mstp_port->EventCount = 0; + // find a new successor to TS + mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; + } + break; + // The NO_TOKEN state is entered if mstp_port->SilenceTimer becomes greater + // than Tno_token, indicating that there has been no network activity + // for that period of time. The timeout is continued to determine + // whether or not this node may create a token. + case MSTP_MASTER_STATE_NO_TOKEN: + // SawFrame + if ((mstp_port->SilenceTimer < + (Tno_token + (Tslot * mstp_port->This_Station))) + && (mstp_port->EventCount > Nmin_octets)) { + // Some other node exists at a lower address. + // Enter the IDLE state to receive and process the incoming frame. + mstp_port->master_state = MSTP_MASTER_STATE_IDLE; + } + // GenerateToken + else if ((mstp_port->SilenceTimer >= + (Tno_token + (Tslot * mstp_port->This_Station))) + && (mstp_port->SilenceTimer < + (Tno_token + (Tslot * (mstp_port->This_Station + 1))))) { + // Assume that this node is the lowest numerical address + // on the network and is empowered to create a token. + mstp_port->Poll_Station = + (mstp_port->This_Station + 1) % (mstp_port->Nmax_master + + 1); + // Transmit a Poll For Master frame to PS. + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_POLL_FOR_MASTER, + mstp_port->Poll_Station, mstp_port->This_Station, NULL, 0); + // indicate that the next station is unknown + mstp_port->Next_Station = mstp_port->This_Station; + mstp_port->RetryCount = 0; + mstp_port->TokenCount = 0; + mstp_port->EventCount = 0; + // enter the POLL_FOR_MASTER state to find a new successor to TS. + mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; + } + break; + // In the POLL_FOR_MASTER state, the node listens for a reply to + // a previously sent Poll For Master frame in order to find + // a successor node. + case MSTP_MASTER_STATE_POLL_FOR_MASTER: + // ReceivedReplyToPFM + if ((mstp_port->ReceivedValidFrame == true) && + (mstp_port->DestinationAddress == mstp_port->This_Station) && + (mstp_port->FrameType == FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) + { + mstp_port->SoleMaster = false; + mstp_port->Next_Station = mstp_port->SourceAddress; + mstp_port->EventCount = 0; + // Transmit a Token frame to NS + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_TOKEN, + mstp_port->Next_Station, mstp_port->This_Station, NULL, 0); + mstp_port->Poll_Station = mstp_port->This_Station; + mstp_port->TokenCount = 0; + mstp_port->RetryCount = 0; + mstp_port->ReceivedValidFrame = false; + mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; + } + // ReceivedUnexpectedFrame + else if ((mstp_port->ReceivedValidFrame == true) && + ((mstp_port->DestinationAddress != mstp_port->This_Station) || + (mstp_port->FrameType != + FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER))) { + // An unexpected frame was received. + // This may indicate the presence of multiple tokens. + mstp_port->ReceivedValidFrame = false; + // enter the IDLE state to synchronize with the network. + // This action drops the token. + mstp_port->master_state = MSTP_MASTER_STATE_IDLE; + } + // mstp_port->SoleMaster + else if ((mstp_port->SoleMaster == true) && + ((mstp_port->SilenceTimer >= Tusage_timeout) || + (mstp_port->ReceivedInvalidFrame == true))) { + // There was no valid reply to the periodic poll + // by the sole known master for other masters. + mstp_port->FrameCount = 0; + mstp_port->ReceivedInvalidFrame = false; + mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; + } + // DoneWithPFM + else if ((mstp_port->SoleMaster == false) && + (mstp_port->Next_Station != mstp_port->This_Station) && + ((mstp_port->SilenceTimer >= Tusage_timeout) || + (mstp_port->ReceivedInvalidFrame == true))) { + // There was no valid reply to the maintenance + // poll for a master at address PS. + mstp_port->EventCount = 0; + // transmit a Token frame to NS + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_TOKEN, + mstp_port->Next_Station, mstp_port->This_Station, NULL, 0); + mstp_port->RetryCount = 0; + mstp_port->ReceivedInvalidFrame = false; + mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; + } + // SendNextPFM + else if ((mstp_port->SoleMaster == false) && (mstp_port->Next_Station == mstp_port->This_Station) && // no known successor node + ((uint8_t) ((mstp_port->Poll_Station + + 1) % (mstp_port->Nmax_master + 1)) != + mstp_port->This_Station) + && ((mstp_port->SilenceTimer >= Tusage_timeout) + || (mstp_port->ReceivedInvalidFrame == true))) { + mstp_port->Poll_Station = + (mstp_port->Poll_Station + 1) % (mstp_port->Nmax_master + + 1); + // Transmit a Poll For Master frame to PS. + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_POLL_FOR_MASTER, + mstp_port->Poll_Station, mstp_port->This_Station, NULL, 0); + mstp_port->RetryCount = 0; + mstp_port->ReceivedInvalidFrame = false; + // Re-enter the current state. + } + // DeclareSoleMaster + else if ((mstp_port->SoleMaster == false) && (mstp_port->Next_Station == mstp_port->This_Station) && // no known successor node + ((uint8_t) ((mstp_port->Poll_Station + 1) % + (mstp_port->Nmax_master + 1)) == + mstp_port->This_Station) + && ((mstp_port->SilenceTimer >= Tusage_timeout) + || (mstp_port->ReceivedInvalidFrame == true))) { + // to indicate that this station is the only master + mstp_port->SoleMaster = true; + mstp_port->FrameCount = 0; + mstp_port->ReceivedInvalidFrame = false; + mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; + } + break; + // The ANSWER_DATA_REQUEST state is entered when a + // BACnet Data Expecting Reply, a Test_Request, or + // a proprietary frame that expects a reply is received. + case MSTP_MASTER_STATE_ANSWER_DATA_REQUEST: + if (mstp_port->ReplyPostponedTimer <= Treply_delay) { + // Reply + // If a reply is available from the higher layers + // within Treply_delay after the reception of the + // final octet of the requesting frame + // (the mechanism used to determine this is a local matter), + // then call MSTP_Create_And_Send_Frame to transmit the reply frame + // and enter the IDLE state to wait for the next frame. - // - // DeferredReply - // If no reply will be available from the higher layers - // within Treply_delay after the reception of the - // final octet of the requesting frame (the mechanism - // used to determine this is a local matter), - // then an immediate reply is not possible. - // Any reply shall wait until this node receives the token. - // Call MSTP_Create_And_Send_Frame to transmit a Reply Postponed frame, - // and enter the IDLE state. + // Test Request + // If a receiving node can successfully receive and return + // the information field, it shall do so. If it cannot receive + // and return the entire information field but can detect + // the reception of a valid Test_Request frame + // (for example, by computing the CRC on octets as + // they are received), then the receiving node shall discard + // the information field and return a Test_Response containing + // no information field. If the receiving node cannot detect + // the valid reception of frames with overlength information fields, + // then no response shall be returned. + if (mstp_port->FrameType == FRAME_TYPE_TEST_REQUEST) { + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_TEST_RESPONSE, + mstp_port->SourceAddress, + mstp_port->This_Station, + (uint8_t *) & mstp_port->InputBuffer[0], + mstp_port->Index); + } + mstp_port->master_state = MSTP_MASTER_STATE_IDLE; + } + // + // DeferredReply + // If no reply will be available from the higher layers + // within Treply_delay after the reception of the + // final octet of the requesting frame (the mechanism + // used to determine this is a local matter), + // then an immediate reply is not possible. + // Any reply shall wait until this node receives the token. + // Call MSTP_Create_And_Send_Frame to transmit a Reply Postponed frame, + // and enter the IDLE state. - else - { - MSTP_Create_And_Send_Frame( - mstp_port, - FRAME_TYPE_REPLY_POSTPONED, - mstp_port->SourceAddress, - mstp_port->This_Station, - NULL,0); - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } - break; + else { + MSTP_Create_And_Send_Frame(mstp_port, + FRAME_TYPE_REPLY_POSTPONED, + mstp_port->SourceAddress, + mstp_port->This_Station, NULL, 0); + mstp_port->master_state = MSTP_MASTER_STATE_IDLE; + } + break; default: - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - break; - } + mstp_port->master_state = MSTP_MASTER_STATE_IDLE; + break; + } - return; + return; } -void MSTP_Init( - volatile struct mstp_port_struct_t *mstp_port, - uint8_t this_station_mac) +void MSTP_Init(volatile struct mstp_port_struct_t *mstp_port, + uint8_t this_station_mac) { - int i; //loop counter + int i; //loop counter - if (mstp_port) - { - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - mstp_port->master_state = MSTP_MASTER_STATE_INITIALIZE; - mstp_port->ReceiveError = false; - mstp_port->DataAvailable = false; - mstp_port->DataRegister = 0; - mstp_port->DataCRC = 0; - mstp_port->DataCRC = 0; - mstp_port->DataLength = 0; - mstp_port->DestinationAddress = 0; - mstp_port->EventCount = 0; - mstp_port->FrameType = FRAME_TYPE_TOKEN; - mstp_port->FrameCount = 0; - mstp_port->HeaderCRC = 0; - mstp_port->Index = 0; - mstp_port->Index = 0; - for (i = 0; i < sizeof(mstp_port->InputBuffer); i++) - { - mstp_port->InputBuffer[i] = 0; + if (mstp_port) { + mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; + mstp_port->master_state = MSTP_MASTER_STATE_INITIALIZE; + mstp_port->ReceiveError = false; + mstp_port->DataAvailable = false; + mstp_port->DataRegister = 0; + mstp_port->DataCRC = 0; + mstp_port->DataCRC = 0; + mstp_port->DataLength = 0; + mstp_port->DestinationAddress = 0; + mstp_port->EventCount = 0; + mstp_port->FrameType = FRAME_TYPE_TOKEN; + mstp_port->FrameCount = 0; + mstp_port->HeaderCRC = 0; + mstp_port->Index = 0; + mstp_port->Index = 0; + for (i = 0; i < sizeof(mstp_port->InputBuffer); i++) { + mstp_port->InputBuffer[i] = 0; + } + mstp_port->Next_Station = this_station_mac; + mstp_port->Poll_Station = this_station_mac; + mstp_port->ReceivedInvalidFrame = false; + mstp_port->ReceivedValidFrame = false; + mstp_port->RetryCount = 0; + mstp_port->SilenceTimer = 0; + mstp_port->ReplyPostponedTimer = 0; + mstp_port->SoleMaster = false; + mstp_port->SourceAddress = 0; + mstp_port->TokenCount = 0; + mstp_port->This_Station = this_station_mac; + mstp_port->Nmax_info_frames = DEFAULT_MAX_INFO_FRAMES; + mstp_port->Nmax_master = DEFAULT_MAX_MASTER; } - mstp_port->Next_Station = this_station_mac; - mstp_port->Poll_Station = this_station_mac; - mstp_port->ReceivedInvalidFrame = false; - mstp_port->ReceivedValidFrame = false; - mstp_port->RetryCount = 0; - mstp_port->SilenceTimer = 0; - mstp_port->ReplyPostponedTimer = 0; - mstp_port->SoleMaster = false; - mstp_port->SourceAddress = 0; - mstp_port->TokenCount = 0; - mstp_port->This_Station = this_station_mac; - mstp_port->Nmax_info_frames = DEFAULT_MAX_INFO_FRAMES; - mstp_port->Nmax_master = DEFAULT_MAX_MASTER; - } } #ifdef TEST @@ -1199,464 +1108,437 @@ void MSTP_Init( #include "ctest.h" // test stub functions -void RS485_Send_Frame( - volatile struct mstp_port_struct_t *mstp_port, // port specific data - uint8_t *buffer, // frame to send (up to 501 bytes of data) - uint16_t nbytes) // number of bytes of data (up to 501) +void RS485_Send_Frame(volatile struct mstp_port_struct_t *mstp_port, // port specific data + uint8_t * buffer, // frame to send (up to 501 bytes of data) + uint16_t nbytes) // number of bytes of data (up to 501) { - (void)mstp_port; - (void)buffer; - (void)nbytes; + (void) mstp_port; + (void) buffer; + (void) nbytes; } #define RING_BUFFER_DATA_SIZE 1 #define RING_BUFFER_SIZE MAX_MPDU static RING_BUFFER Test_Buffer; static uint8_t Test_Buffer_Data[RING_BUFFER_DATA_SIZE * RING_BUFFER_SIZE]; -static void Load_Input_Buffer(uint8_t *buffer,size_t len) +static void Load_Input_Buffer(uint8_t * buffer, size_t len) { - static bool initialized = false; // tracks our init + static bool initialized = false; // tracks our init - if (!initialized) - { - initialized = true; - Ringbuf_Init( - &Test_Buffer, - (char *)Test_Buffer_Data, - RING_BUFFER_DATA_SIZE, - RING_BUFFER_SIZE); - } - - // empty any the existing data - while (!Ringbuf_Empty(&Test_Buffer)) - { - (void)Ringbuf_Pop_Front(&Test_Buffer); - } - - if (buffer) - { - while (len) - { - (void)Ringbuf_Put(&Test_Buffer,(char *)buffer); - len--; - buffer++; + if (!initialized) { + initialized = true; + Ringbuf_Init(&Test_Buffer, + (char *) Test_Buffer_Data, + RING_BUFFER_DATA_SIZE, RING_BUFFER_SIZE); } - } -} - -void RS485_Check_UART_Data( - volatile struct mstp_port_struct_t *mstp_port) // port specific data -{ - char *data; - if (!Ringbuf_Empty(&Test_Buffer) && mstp_port && - (mstp_port->DataAvailable == false)) - { - data = Ringbuf_Pop_Front(&Test_Buffer); - if (data) - { - mstp_port->DataRegister = *data; - mstp_port->DataAvailable = true; + // empty any the existing data + while (!Ringbuf_Empty(&Test_Buffer)) { + (void) Ringbuf_Pop_Front(&Test_Buffer); + } + + if (buffer) { + while (len) { + (void) Ringbuf_Put(&Test_Buffer, (char *) buffer); + len--; + buffer++; + } } - } } -void testReceiveNodeFSM(Test* pTest) +void RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port) // port specific data { - volatile struct mstp_port_struct_t mstp_port; // port data - unsigned EventCount = 0; // local counter - uint8_t my_mac = 0x05; // local MAC address - uint8_t HeaderCRC = 0; // for local CRC calculation - uint8_t FrameType = 0; // type of packet that was sent - unsigned len; // used for the size of the message packet - size_t i; // used to loop through the message bytes - uint8_t buffer[MAX_MPDU] = {0}; - uint8_t data[MAX_MPDU - 8 /*header*/ - 2 /*CRC*/] = {0}; - - MSTP_Init(&mstp_port,my_mac); - - // check the receive error during idle - mstp_port.receive_state = MSTP_RECEIVE_STATE_IDLE; - mstp_port.ReceiveError = true; - mstp_port.SilenceTimer = 255; - mstp_port.EventCount = 0; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.ReceiveError == false); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - - // check for bad packet header - mstp_port.DataAvailable = true; - mstp_port.DataRegister = 0x11; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - - // check for good packet header, but timeout - mstp_port.DataAvailable = true; - mstp_port.DataRegister = 0x55; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); - // force the timeout - mstp_port.SilenceTimer = Tframe_abort + 1; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - - // check for good packet header preamble, but receive error - mstp_port.DataAvailable = true; - mstp_port.DataRegister = 0x55; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); - // force the error - mstp_port.ReceiveError = true; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.ReceiveError == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - - // check for good packet header preamble1, but bad preamble2 - mstp_port.DataAvailable = true; - mstp_port.DataRegister = 0x55; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); - MSTP_Receive_Frame_FSM(&mstp_port); - // no change of state if no data yet - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); - // repeated preamble1 - mstp_port.DataAvailable = true; - mstp_port.DataRegister = 0x55; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); - // repeated preamble1 - mstp_port.DataAvailable = true; - mstp_port.DataRegister = 0x55; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); - // bad data - mstp_port.DataAvailable = true; - mstp_port.DataRegister = 0x11; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.ReceiveError == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - - // check for good packet header preamble, but timeout in packet - mstp_port.DataAvailable = true; - mstp_port.DataRegister = 0x55; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); - MSTP_Receive_Frame_FSM(&mstp_port); - // preamble2 - mstp_port.DataAvailable = true; - mstp_port.DataRegister = 0xFF; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.Index == 0); - ct_test(pTest,mstp_port.HeaderCRC == 0xFF); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); - // force the timeout - mstp_port.SilenceTimer = Tframe_abort + 1; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - ct_test(pTest,mstp_port.ReceivedInvalidFrame == true); - - // check for good packet header preamble, but error in packet - mstp_port.DataAvailable = true; - mstp_port.DataRegister = 0x55; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); - MSTP_Receive_Frame_FSM(&mstp_port); - // preamble2 - mstp_port.DataAvailable = true; - mstp_port.DataRegister = 0xFF; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.Index == 0); - ct_test(pTest,mstp_port.HeaderCRC == 0xFF); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); - // force the error - mstp_port.ReceiveError = true; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.ReceiveError == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - - // check for good packet header preamble - mstp_port.DataAvailable = true; - mstp_port.DataRegister = 0x55; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); - MSTP_Receive_Frame_FSM(&mstp_port); - // preamble2 - mstp_port.DataAvailable = true; - mstp_port.DataRegister = 0xFF; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.Index == 0); - ct_test(pTest,mstp_port.HeaderCRC == 0xFF); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); - // no change of state if no data yet - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); - // Data is received - index is incremented - // FrameType - mstp_port.DataAvailable = true; - mstp_port.DataRegister = FRAME_TYPE_TOKEN; - HeaderCRC = 0xFF; - HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister,HeaderCRC); - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.Index == 1); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); - ct_test(pTest,FrameType == FRAME_TYPE_TOKEN); - // Destination - mstp_port.DataAvailable = true; - mstp_port.DataRegister = 0x10; - HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister,HeaderCRC); - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.Index == 2); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); - ct_test(pTest,mstp_port.DestinationAddress == 0x10); - // Source - mstp_port.DataAvailable = true; - mstp_port.DataRegister = my_mac; - HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister,HeaderCRC); - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.Index == 3); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); - ct_test(pTest,mstp_port.SourceAddress == my_mac); - // Length1 = length*256 - mstp_port.DataAvailable = true; - mstp_port.DataRegister = 0; - HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister,HeaderCRC); - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.Index == 4); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); - ct_test(pTest,mstp_port.DataLength == 0); - // Length2 - mstp_port.DataAvailable = true; - mstp_port.DataRegister = 0; - HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister,HeaderCRC); - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.Index == 5); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); - ct_test(pTest,mstp_port.DataLength == 0); - // HeaderCRC - mstp_port.DataAvailable = true; - ct_test(pTest,HeaderCRC == 0x73); // per Annex G example - mstp_port.DataRegister = ~HeaderCRC; // one's compliment of CRC is sent - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.Index == 5); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER_CRC); - ct_test(pTest,mstp_port.HeaderCRC == 0x55); - // NotForUs - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - - // BadCRC in header check - mstp_port.ReceivedInvalidFrame = false; - mstp_port.ReceivedValidFrame = false; - len = MSTP_Create_Frame( - buffer, - sizeof(buffer), - FRAME_TYPE_TOKEN, - 0x10, // destination - my_mac, // source - NULL, // data - 0); // data size - ct_test(pTest,len > 0); - // make the header CRC bad - buffer[7] = 0x00; - Load_Input_Buffer(buffer,len); - for (i = 0; i < len; i++) - { - RS485_Check_UART_Data(&mstp_port); - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - } - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER_CRC); - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.ReceivedInvalidFrame == true); - ct_test(pTest,mstp_port.ReceivedValidFrame == false); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - - // NoData for us - mstp_port.ReceivedInvalidFrame = false; - mstp_port.ReceivedValidFrame = false; - len = MSTP_Create_Frame( - buffer, - sizeof(buffer), - FRAME_TYPE_TOKEN, - my_mac, // destination - my_mac, // source - NULL, // data - 0); // data size - ct_test(pTest,len > 0); - Load_Input_Buffer(buffer,len); - for (i = 0; i < len; i++) - { - RS485_Check_UART_Data(&mstp_port); - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - } - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER_CRC); - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.ReceivedInvalidFrame == false); - ct_test(pTest,mstp_port.ReceivedValidFrame == true); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - - // FrameTooLong - mstp_port.ReceivedInvalidFrame = false; - mstp_port.ReceivedValidFrame = false; - len = MSTP_Create_Frame( - buffer, - sizeof(buffer), - FRAME_TYPE_TOKEN, - my_mac, // destination - my_mac, // source - NULL, // data - 0); // data size - ct_test(pTest,len > 0); - // make the header data length bad - buffer[5] = 0x02; - Load_Input_Buffer(buffer,len); - for (i = 0; i < len; i++) - { - RS485_Check_UART_Data(&mstp_port); - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == false); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - } - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER_CRC); - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.ReceivedInvalidFrame == true); - ct_test(pTest,mstp_port.ReceivedValidFrame == false); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - - // Data - mstp_port.ReceivedInvalidFrame = false; - mstp_port.ReceivedValidFrame = false; - memset(data,0,sizeof(data)); - len = MSTP_Create_Frame( - buffer, - sizeof(buffer), - FRAME_TYPE_PROPRIETARY_MIN, - my_mac, // destination - my_mac, // source - data, // data - sizeof(data)); // data size - ct_test(pTest,len > 0); - Load_Input_Buffer(buffer,len); - RS485_Check_UART_Data(&mstp_port); - MSTP_Receive_Frame_FSM(&mstp_port); - while (mstp_port.receive_state != MSTP_RECEIVE_STATE_IDLE) - { - RS485_Check_UART_Data(&mstp_port); - MSTP_Receive_Frame_FSM(&mstp_port); - } - ct_test(pTest,mstp_port.DataLength == sizeof(data)); - ct_test(pTest,mstp_port.ReceivedInvalidFrame == false); - ct_test(pTest,mstp_port.ReceivedValidFrame == true); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - - return; + char *data; + if (!Ringbuf_Empty(&Test_Buffer) && mstp_port && + (mstp_port->DataAvailable == false)) { + data = Ringbuf_Pop_Front(&Test_Buffer); + if (data) { + mstp_port->DataRegister = *data; + mstp_port->DataAvailable = true; + } + } } -void testMasterNodeFSM(Test* pTest) +void testReceiveNodeFSM(Test * pTest) { - volatile struct mstp_port_struct_t mstp_port; // port data - uint8_t my_mac = 0x05; // local MAC address + volatile struct mstp_port_struct_t mstp_port; // port data + unsigned EventCount = 0; // local counter + uint8_t my_mac = 0x05; // local MAC address + uint8_t HeaderCRC = 0; // for local CRC calculation + uint8_t FrameType = 0; // type of packet that was sent + unsigned len; // used for the size of the message packet + size_t i; // used to loop through the message bytes + uint8_t buffer[MAX_MPDU] = { 0 }; + uint8_t data[MAX_MPDU - 8 /*header */ - 2 /*CRC*/] = { 0 }; - MSTP_Init(&mstp_port,my_mac); - ct_test(pTest,mstp_port.master_state == MSTP_MASTER_STATE_INITIALIZE); + MSTP_Init(&mstp_port, my_mac); + + // check the receive error during idle + mstp_port.receive_state = MSTP_RECEIVE_STATE_IDLE; + mstp_port.ReceiveError = true; + mstp_port.SilenceTimer = 255; + mstp_port.EventCount = 0; + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.EventCount == EventCount); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.ReceiveError == false); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); + + // check for bad packet header + mstp_port.DataAvailable = true; + mstp_port.DataRegister = 0x11; + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.DataAvailable == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); + + // check for good packet header, but timeout + mstp_port.DataAvailable = true; + mstp_port.DataRegister = 0x55; + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.DataAvailable == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); + // force the timeout + mstp_port.SilenceTimer = Tframe_abort + 1; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); + + // check for good packet header preamble, but receive error + mstp_port.DataAvailable = true; + mstp_port.DataRegister = 0x55; + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.DataAvailable == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); + // force the error + mstp_port.ReceiveError = true; + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.ReceiveError == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); + + // check for good packet header preamble1, but bad preamble2 + mstp_port.DataAvailable = true; + mstp_port.DataRegister = 0x55; + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.DataAvailable == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); + MSTP_Receive_Frame_FSM(&mstp_port); + // no change of state if no data yet + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); + // repeated preamble1 + mstp_port.DataAvailable = true; + mstp_port.DataRegister = 0x55; + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.DataAvailable == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); + // repeated preamble1 + mstp_port.DataAvailable = true; + mstp_port.DataRegister = 0x55; + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.DataAvailable == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); + // bad data + mstp_port.DataAvailable = true; + mstp_port.DataRegister = 0x11; + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.ReceiveError == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); + + // check for good packet header preamble, but timeout in packet + mstp_port.DataAvailable = true; + mstp_port.DataRegister = 0x55; + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.DataAvailable == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); + MSTP_Receive_Frame_FSM(&mstp_port); + // preamble2 + mstp_port.DataAvailable = true; + mstp_port.DataRegister = 0xFF; + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.DataAvailable == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + ct_test(pTest, mstp_port.Index == 0); + ct_test(pTest, mstp_port.HeaderCRC == 0xFF); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); + // force the timeout + mstp_port.SilenceTimer = Tframe_abort + 1; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); + ct_test(pTest, mstp_port.ReceivedInvalidFrame == true); + + // check for good packet header preamble, but error in packet + mstp_port.DataAvailable = true; + mstp_port.DataRegister = 0x55; + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.DataAvailable == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); + MSTP_Receive_Frame_FSM(&mstp_port); + // preamble2 + mstp_port.DataAvailable = true; + mstp_port.DataRegister = 0xFF; + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.DataAvailable == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + ct_test(pTest, mstp_port.Index == 0); + ct_test(pTest, mstp_port.HeaderCRC == 0xFF); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); + // force the error + mstp_port.ReceiveError = true; + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.ReceiveError == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); + + // check for good packet header preamble + mstp_port.DataAvailable = true; + mstp_port.DataRegister = 0x55; + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.DataAvailable == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); + MSTP_Receive_Frame_FSM(&mstp_port); + // preamble2 + mstp_port.DataAvailable = true; + mstp_port.DataRegister = 0xFF; + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.DataAvailable == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + ct_test(pTest, mstp_port.Index == 0); + ct_test(pTest, mstp_port.HeaderCRC == 0xFF); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); + // no change of state if no data yet + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); + // Data is received - index is incremented + // FrameType + mstp_port.DataAvailable = true; + mstp_port.DataRegister = FRAME_TYPE_TOKEN; + HeaderCRC = 0xFF; + HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister, HeaderCRC); + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.DataAvailable == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + ct_test(pTest, mstp_port.Index == 1); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); + ct_test(pTest, FrameType == FRAME_TYPE_TOKEN); + // Destination + mstp_port.DataAvailable = true; + mstp_port.DataRegister = 0x10; + HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister, HeaderCRC); + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.DataAvailable == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + ct_test(pTest, mstp_port.Index == 2); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); + ct_test(pTest, mstp_port.DestinationAddress == 0x10); + // Source + mstp_port.DataAvailable = true; + mstp_port.DataRegister = my_mac; + HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister, HeaderCRC); + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.DataAvailable == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + ct_test(pTest, mstp_port.Index == 3); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); + ct_test(pTest, mstp_port.SourceAddress == my_mac); + // Length1 = length*256 + mstp_port.DataAvailable = true; + mstp_port.DataRegister = 0; + HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister, HeaderCRC); + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.DataAvailable == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + ct_test(pTest, mstp_port.Index == 4); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); + ct_test(pTest, mstp_port.DataLength == 0); + // Length2 + mstp_port.DataAvailable = true; + mstp_port.DataRegister = 0; + HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister, HeaderCRC); + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.DataAvailable == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + ct_test(pTest, mstp_port.Index == 5); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); + ct_test(pTest, mstp_port.DataLength == 0); + // HeaderCRC + mstp_port.DataAvailable = true; + ct_test(pTest, HeaderCRC == 0x73); // per Annex G example + mstp_port.DataRegister = ~HeaderCRC; // one's compliment of CRC is sent + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.DataAvailable == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + ct_test(pTest, mstp_port.Index == 5); + ct_test(pTest, + mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER_CRC); + ct_test(pTest, mstp_port.HeaderCRC == 0x55); + // NotForUs + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); + + // BadCRC in header check + mstp_port.ReceivedInvalidFrame = false; + mstp_port.ReceivedValidFrame = false; + len = MSTP_Create_Frame(buffer, sizeof(buffer), FRAME_TYPE_TOKEN, 0x10, // destination + my_mac, // source + NULL, // data + 0); // data size + ct_test(pTest, len > 0); + // make the header CRC bad + buffer[7] = 0x00; + Load_Input_Buffer(buffer, len); + for (i = 0; i < len; i++) { + RS485_Check_UART_Data(&mstp_port); + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.DataAvailable == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + } + ct_test(pTest, + mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER_CRC); + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.ReceivedInvalidFrame == true); + ct_test(pTest, mstp_port.ReceivedValidFrame == false); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); + + // NoData for us + mstp_port.ReceivedInvalidFrame = false; + mstp_port.ReceivedValidFrame = false; + len = MSTP_Create_Frame(buffer, sizeof(buffer), FRAME_TYPE_TOKEN, my_mac, // destination + my_mac, // source + NULL, // data + 0); // data size + ct_test(pTest, len > 0); + Load_Input_Buffer(buffer, len); + for (i = 0; i < len; i++) { + RS485_Check_UART_Data(&mstp_port); + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.DataAvailable == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + } + ct_test(pTest, + mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER_CRC); + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.ReceivedInvalidFrame == false); + ct_test(pTest, mstp_port.ReceivedValidFrame == true); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); + + // FrameTooLong + mstp_port.ReceivedInvalidFrame = false; + mstp_port.ReceivedValidFrame = false; + len = MSTP_Create_Frame(buffer, sizeof(buffer), FRAME_TYPE_TOKEN, my_mac, // destination + my_mac, // source + NULL, // data + 0); // data size + ct_test(pTest, len > 0); + // make the header data length bad + buffer[5] = 0x02; + Load_Input_Buffer(buffer, len); + for (i = 0; i < len; i++) { + RS485_Check_UART_Data(&mstp_port); + EventCount++; + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.DataAvailable == false); + ct_test(pTest, mstp_port.SilenceTimer == 0); + ct_test(pTest, mstp_port.EventCount == EventCount); + } + ct_test(pTest, + mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER_CRC); + MSTP_Receive_Frame_FSM(&mstp_port); + ct_test(pTest, mstp_port.ReceivedInvalidFrame == true); + ct_test(pTest, mstp_port.ReceivedValidFrame == false); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); + + // Data + mstp_port.ReceivedInvalidFrame = false; + mstp_port.ReceivedValidFrame = false; + memset(data, 0, sizeof(data)); + len = MSTP_Create_Frame(buffer, sizeof(buffer), FRAME_TYPE_PROPRIETARY_MIN, my_mac, // destination + my_mac, // source + data, // data + sizeof(data)); // data size + ct_test(pTest, len > 0); + Load_Input_Buffer(buffer, len); + RS485_Check_UART_Data(&mstp_port); + MSTP_Receive_Frame_FSM(&mstp_port); + while (mstp_port.receive_state != MSTP_RECEIVE_STATE_IDLE) { + RS485_Check_UART_Data(&mstp_port); + MSTP_Receive_Frame_FSM(&mstp_port); + } + ct_test(pTest, mstp_port.DataLength == sizeof(data)); + ct_test(pTest, mstp_port.ReceivedInvalidFrame == false); + ct_test(pTest, mstp_port.ReceivedValidFrame == true); + ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); + + return; +} + +void testMasterNodeFSM(Test * pTest) +{ + volatile struct mstp_port_struct_t mstp_port; // port data + uint8_t my_mac = 0x05; // local MAC address + + MSTP_Init(&mstp_port, my_mac); + ct_test(pTest, mstp_port.master_state == MSTP_MASTER_STATE_INITIALIZE); } @@ -1665,23 +1547,23 @@ void testMasterNodeFSM(Test* pTest) #ifdef TEST_MSTP int main(void) { - Test *pTest; - bool rc; + Test *pTest; + bool rc; - pTest = ct_create("mstp", NULL); + pTest = ct_create("mstp", NULL); - /* individual tests */ - rc = ct_addTestFunction(pTest, testReceiveNodeFSM); - assert(rc); - rc = ct_addTestFunction(pTest, testMasterNodeFSM); - assert(rc); + /* individual tests */ + rc = ct_addTestFunction(pTest, testReceiveNodeFSM); + assert(rc); + rc = ct_addTestFunction(pTest, testMasterNodeFSM); + assert(rc); - ct_setStream(pTest, stdout); - ct_run(pTest); - (void)ct_report(pTest); + ct_setStream(pTest, stdout); + ct_run(pTest); + (void) ct_report(pTest); - ct_destroy(pTest); + ct_destroy(pTest); - return 0; + return 0; } #endif diff --git a/bacnet-stack/mstp.h b/bacnet-stack/mstp.h index b6c51f85..b241f91c 100644 --- a/bacnet-stack/mstp.h +++ b/bacnet-stack/mstp.h @@ -66,134 +66,131 @@ #define FRAME_TYPE_PROPRIETARY_MAX 255 // receive FSM states -typedef enum -{ - MSTP_RECEIVE_STATE_IDLE, - MSTP_RECEIVE_STATE_PREAMBLE, - MSTP_RECEIVE_STATE_HEADER, - MSTP_RECEIVE_STATE_HEADER_CRC, - MSTP_RECEIVE_STATE_DATA, - MSTP_RECEIVE_STATE_DATA_CRC +typedef enum { + MSTP_RECEIVE_STATE_IDLE, + MSTP_RECEIVE_STATE_PREAMBLE, + MSTP_RECEIVE_STATE_HEADER, + MSTP_RECEIVE_STATE_HEADER_CRC, + MSTP_RECEIVE_STATE_DATA, + MSTP_RECEIVE_STATE_DATA_CRC } MSTP_RECEIVE_STATE; // master node FSM states -typedef enum -{ - MSTP_MASTER_STATE_INITIALIZE, - MSTP_MASTER_STATE_IDLE, - MSTP_MASTER_STATE_USE_TOKEN, - MSTP_MASTER_STATE_WAIT_FOR_REPLY, - MSTP_MASTER_STATE_DONE_WITH_TOKEN, - MSTP_MASTER_STATE_PASS_TOKEN, - MSTP_MASTER_STATE_NO_TOKEN, - MSTP_MASTER_STATE_POLL_FOR_MASTER, - MSTP_MASTER_STATE_ANSWER_DATA_REQUEST +typedef enum { + MSTP_MASTER_STATE_INITIALIZE, + MSTP_MASTER_STATE_IDLE, + MSTP_MASTER_STATE_USE_TOKEN, + MSTP_MASTER_STATE_WAIT_FOR_REPLY, + MSTP_MASTER_STATE_DONE_WITH_TOKEN, + MSTP_MASTER_STATE_PASS_TOKEN, + MSTP_MASTER_STATE_NO_TOKEN, + MSTP_MASTER_STATE_POLL_FOR_MASTER, + MSTP_MASTER_STATE_ANSWER_DATA_REQUEST } MSTP_MASTER_STATE; -struct mstp_port_struct_t -{ - MSTP_RECEIVE_STATE receive_state; - // When a master node is powered up or reset, - // it shall unconditionally enter the INITIALIZE state. - MSTP_MASTER_STATE master_state; - // A Boolean flag set to TRUE by the Receive State Machine - // if an error is detected during the reception of a frame. - // Set to FALSE by the main state machine. - unsigned ReceiveError:1; - // There is data in the buffer - unsigned DataAvailable:1; - unsigned FramingError:1; // TRUE if we got a framing error - unsigned ReceivedInvalidFrame:1; - // A Boolean flag set to TRUE by the Receive State Machine - // if a valid frame is received. - // Set to FALSE by the main state machine. - unsigned ReceivedValidFrame:1; - // A Boolean flag set to TRUE by the master machine if this node is the - // only known master node. - unsigned SoleMaster:1; - // After receiving a frame this value will be TRUE until Tturnaround - // has expired - unsigned Turn_Around_Waiting:1; - // stores the latest received data - uint8_t DataRegister; - // Used to accumulate the CRC on the data field of a frame. - uint16_t DataCRC; - // Used to store the data length of a received frame. - unsigned DataLength; - // Used to store the destination address of a received frame. - uint8_t DestinationAddress; - // Used to count the number of received octets or errors. - // This is used in the detection of link activity. - unsigned EventCount; - // Used to store the frame type of a received frame. - uint8_t FrameType; - // The number of frames sent by this node during a single token hold. - // When this counter reaches the value Nmax_info_frames, the node must - // pass the token. - unsigned FrameCount; - // Used to accumulate the CRC on the header of a frame. - uint8_t HeaderCRC; - // Used as an index by the Receive State Machine, up to a maximum value of - // InputBufferSize. - unsigned Index; - // An array of octets, used to store octets as they are received. - // InputBuffer is indexed from 0 to InputBufferSize-1. - // The maximum size of a frame is 501 octets. - uint8_t InputBuffer[MAX_MPDU]; - // "Next Station," the MAC address of the node to which This Station passes - // the token. If the Next_Station is unknown, Next_Station shall be equal to - // This_Station. - uint8_t Next_Station; - // "Poll Station," the MAC address of the node to which This Station last - // sent a Poll For Master. This is used during token maintenance. - uint8_t Poll_Station; - // A counter of transmission retries used for Token and Poll For Master - // transmission. - unsigned RetryCount; - // A timer with nominal 5 millisecond resolution used to measure and - // generate silence on the medium between octets. It is incremented by a - // timer process and is cleared by the Receive State Machine when activity - // is detected and by the SendFrame procedure as each octet is transmitted. - // Since the timer resolution is limited and the timer is not necessarily - // synchronized to other machine events, a timer value of N will actually - // denote intervals between N-1 and N - unsigned SilenceTimer; +struct mstp_port_struct_t { + MSTP_RECEIVE_STATE receive_state; + // When a master node is powered up or reset, + // it shall unconditionally enter the INITIALIZE state. + MSTP_MASTER_STATE master_state; + // A Boolean flag set to TRUE by the Receive State Machine + // if an error is detected during the reception of a frame. + // Set to FALSE by the main state machine. + unsigned ReceiveError:1; + // There is data in the buffer + unsigned DataAvailable:1; + unsigned FramingError:1; // TRUE if we got a framing error + unsigned ReceivedInvalidFrame:1; + // A Boolean flag set to TRUE by the Receive State Machine + // if a valid frame is received. + // Set to FALSE by the main state machine. + unsigned ReceivedValidFrame:1; + // A Boolean flag set to TRUE by the master machine if this node is the + // only known master node. + unsigned SoleMaster:1; + // After receiving a frame this value will be TRUE until Tturnaround + // has expired + unsigned Turn_Around_Waiting:1; + // stores the latest received data + uint8_t DataRegister; + // Used to accumulate the CRC on the data field of a frame. + uint16_t DataCRC; + // Used to store the data length of a received frame. + unsigned DataLength; + // Used to store the destination address of a received frame. + uint8_t DestinationAddress; + // Used to count the number of received octets or errors. + // This is used in the detection of link activity. + unsigned EventCount; + // Used to store the frame type of a received frame. + uint8_t FrameType; + // The number of frames sent by this node during a single token hold. + // When this counter reaches the value Nmax_info_frames, the node must + // pass the token. + unsigned FrameCount; + // Used to accumulate the CRC on the header of a frame. + uint8_t HeaderCRC; + // Used as an index by the Receive State Machine, up to a maximum value of + // InputBufferSize. + unsigned Index; + // An array of octets, used to store octets as they are received. + // InputBuffer is indexed from 0 to InputBufferSize-1. + // The maximum size of a frame is 501 octets. + uint8_t InputBuffer[MAX_MPDU]; + // "Next Station," the MAC address of the node to which This Station passes + // the token. If the Next_Station is unknown, Next_Station shall be equal to + // This_Station. + uint8_t Next_Station; + // "Poll Station," the MAC address of the node to which This Station last + // sent a Poll For Master. This is used during token maintenance. + uint8_t Poll_Station; + // A counter of transmission retries used for Token and Poll For Master + // transmission. + unsigned RetryCount; + // A timer with nominal 5 millisecond resolution used to measure and + // generate silence on the medium between octets. It is incremented by a + // timer process and is cleared by the Receive State Machine when activity + // is detected and by the SendFrame procedure as each octet is transmitted. + // Since the timer resolution is limited and the timer is not necessarily + // synchronized to other machine events, a timer value of N will actually + // denote intervals between N-1 and N + unsigned SilenceTimer; - // A timer used to measure and generate Reply Postponed frames. It is - // incremented by a timer process and is cleared by the Master Node State - // Machine when a Data Expecting Reply Answer activity is completed. - unsigned ReplyPostponedTimer; + // A timer used to measure and generate Reply Postponed frames. It is + // incremented by a timer process and is cleared by the Master Node State + // Machine when a Data Expecting Reply Answer activity is completed. + unsigned ReplyPostponedTimer; - // Used to store the Source Address of a received frame. - uint8_t SourceAddress; + // Used to store the Source Address of a received frame. + uint8_t SourceAddress; - // The number of tokens received by this node. When this counter reaches the - // value Npoll, the node polls the address range between TS and NS for - // additional master nodes. TokenCount is set to zero at the end of the - // polling process. - unsigned TokenCount; + // The number of tokens received by this node. When this counter reaches the + // value Npoll, the node polls the address range between TS and NS for + // additional master nodes. TokenCount is set to zero at the end of the + // polling process. + unsigned TokenCount; - // "This Station," the MAC address of this node. TS is generally read from a - // hardware DIP switch, or from nonvolatile memory. Valid values for TS are - // 0 to 254. The value 255 is used to denote broadcast when used as a - // destination address but is not allowed as a value for TS. - uint8_t This_Station; + // "This Station," the MAC address of this node. TS is generally read from a + // hardware DIP switch, or from nonvolatile memory. Valid values for TS are + // 0 to 254. The value 255 is used to denote broadcast when used as a + // destination address but is not allowed as a value for TS. + uint8_t This_Station; - // This parameter represents the value of the Max_Info_Frames property of - // the node's Device object. The value of Max_Info_Frames specifies the - // maximum number of information frames the node may send before it must - // pass the token. Max_Info_Frames may have different values on different - // nodes. This may be used to allocate more or less of the available link - // bandwidth to particular nodes. If Max_Info_Frames is not writable in a - // node, its value shall be 1. - unsigned Nmax_info_frames; + // This parameter represents the value of the Max_Info_Frames property of + // the node's Device object. The value of Max_Info_Frames specifies the + // maximum number of information frames the node may send before it must + // pass the token. Max_Info_Frames may have different values on different + // nodes. This may be used to allocate more or less of the available link + // bandwidth to particular nodes. If Max_Info_Frames is not writable in a + // node, its value shall be 1. + unsigned Nmax_info_frames; - // This parameter represents the value of the Max_Master property of the - // node's Device object. The value of Max_Master specifies the highest - // allowable address for master nodes. The value of Max_Master shall be - // less than or equal to 127. If Max_Master is not writable in a node, - // its value shall be 127. - unsigned Nmax_master; + // This parameter represents the value of the Max_Master property of the + // node's Device object. The value of Max_Master specifies the highest + // allowable address for master nodes. The value of Max_Master shall be + // less than or equal to 127. If Max_Master is not writable in a node, + // its value shall be 127. + unsigned Nmax_master; }; #define DEFAULT_MAX_INFO_FRAMES 1 @@ -206,17 +203,18 @@ struct mstp_port_struct_t #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ -void MSTP_Init( - volatile struct mstp_port_struct_t *mstp_port, - uint8_t this_station_mac); -void MSTP_Millisecond_Timer(volatile struct mstp_port_struct_t *mstp_port); -void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port); -void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port); + void MSTP_Init(volatile struct mstp_port_struct_t *mstp_port, + uint8_t this_station_mac); + void MSTP_Millisecond_Timer(volatile struct mstp_port_struct_t + *mstp_port); + void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t + *mstp_port); + void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t + *mstp_port); #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif diff --git a/bacnet-stack/npdu.c b/bacnet-stack/npdu.c index 6bab0efd..1a960a80 100644 --- a/bacnet-stack/npdu.c +++ b/bacnet-stack/npdu.c @@ -40,299 +40,256 @@ #include "npdu.h" #include "apdu.h" -int npdu_encode_raw( - uint8_t *npdu, - BACNET_ADDRESS *dest, - BACNET_ADDRESS *src, - BACNET_NPDU_DATA *npdu_data) +int npdu_encode_raw(uint8_t * npdu, + BACNET_ADDRESS * dest, + BACNET_ADDRESS * src, BACNET_NPDU_DATA * npdu_data) { - int len = 0; // return value - number of octets loaded in this function - int i = 0; // counter + int len = 0; // return value - number of octets loaded in this function + int i = 0; // counter - if (npdu && npdu_data) - { - // Protocol Version - npdu[0] = 1; - // control octet - npdu[1] = 0; - // Bit 7: 1 indicates that the NSDU conveys a network layer message. - // Message Type field is present. - // 0 indicates that the NSDU contains a BACnet APDU. - // Message Type field is absent. - if (npdu_data->network_layer_message) - npdu[1] |= BIT7; - //Bit 6: Reserved. Shall be zero. - //Bit 5: Destination specifier where: - // 0 = DNET, DLEN, DADR, and Hop Count absent - // 1 = DNET, DLEN, and Hop Count present - // DLEN = 0 denotes broadcast MAC DADR and DADR field is absent - // DLEN > 0 specifies length of DADR field - if (dest && dest->net) - npdu[1] |= BIT5; - // Bit 4: Reserved. Shall be zero. - // Bit 3: Source specifier where: - // 0 = SNET, SLEN, and SADR absent - // 1 = SNET, SLEN, and SADR present - // SLEN = 0 Invalid - // SLEN > 0 specifies length of SADR field - if (src && src->net) - npdu[1] |= BIT3; - // Bit 2: The value of this bit corresponds to the data_expecting_reply - // parameter in the N-UNITDATA primitives. - // 1 indicates that a BACnet-Confirmed-Request-PDU, - // a segment of a BACnet-ComplexACK-PDU, - // or a network layer message expecting a reply is present. - // 0 indicates that other than a BACnet-Confirmed-Request-PDU, - // a segment of a BACnet-ComplexACK-PDU, - // or a network layer message expecting a reply is present. - if (npdu_data->data_expecting_reply) - npdu[1] |= BIT2; - // Bits 1,0: Network priority where: - // B'11' = Life Safety message - // B'10' = Critical Equipment message - // B'01' = Urgent message - // B'00' = Normal message - npdu[1] |= (npdu_data->priority & 0x03); - len = 2; - if (dest && dest->net) - { - len += encode_unsigned16(&npdu[len], dest->net); - npdu[len++] = dest->len; - // DLEN = 0 denotes broadcast MAC DADR and DADR field is absent - // DLEN > 0 specifies length of DADR field - if (dest->len) - { - for (i = 0; i < dest->len; i++) - { - npdu[len++] = dest->adr[i]; + if (npdu && npdu_data) { + // Protocol Version + npdu[0] = 1; + // control octet + npdu[1] = 0; + // Bit 7: 1 indicates that the NSDU conveys a network layer message. + // Message Type field is present. + // 0 indicates that the NSDU contains a BACnet APDU. + // Message Type field is absent. + if (npdu_data->network_layer_message) + npdu[1] |= BIT7; + //Bit 6: Reserved. Shall be zero. + //Bit 5: Destination specifier where: + // 0 = DNET, DLEN, DADR, and Hop Count absent + // 1 = DNET, DLEN, and Hop Count present + // DLEN = 0 denotes broadcast MAC DADR and DADR field is absent + // DLEN > 0 specifies length of DADR field + if (dest && dest->net) + npdu[1] |= BIT5; + // Bit 4: Reserved. Shall be zero. + // Bit 3: Source specifier where: + // 0 = SNET, SLEN, and SADR absent + // 1 = SNET, SLEN, and SADR present + // SLEN = 0 Invalid + // SLEN > 0 specifies length of SADR field + if (src && src->net) + npdu[1] |= BIT3; + // Bit 2: The value of this bit corresponds to the data_expecting_reply + // parameter in the N-UNITDATA primitives. + // 1 indicates that a BACnet-Confirmed-Request-PDU, + // a segment of a BACnet-ComplexACK-PDU, + // or a network layer message expecting a reply is present. + // 0 indicates that other than a BACnet-Confirmed-Request-PDU, + // a segment of a BACnet-ComplexACK-PDU, + // or a network layer message expecting a reply is present. + if (npdu_data->data_expecting_reply) + npdu[1] |= BIT2; + // Bits 1,0: Network priority where: + // B'11' = Life Safety message + // B'10' = Critical Equipment message + // B'01' = Urgent message + // B'00' = Normal message + npdu[1] |= (npdu_data->priority & 0x03); + len = 2; + if (dest && dest->net) { + len += encode_unsigned16(&npdu[len], dest->net); + npdu[len++] = dest->len; + // DLEN = 0 denotes broadcast MAC DADR and DADR field is absent + // DLEN > 0 specifies length of DADR field + if (dest->len) { + for (i = 0; i < dest->len; i++) { + npdu[len++] = dest->adr[i]; + } + } } - } - } - if (src && src->net) - { - len += encode_unsigned16(&npdu[len], src->net); - npdu[len++] = src->len; - // SLEN = 0 denotes broadcast MAC SADR and SADR field is absent - // SLEN > 0 specifies length of SADR field - if (src->len) - { - for (i = 0; i < src->len; i++) - { - npdu[len++] = src->adr[i]; + if (src && src->net) { + len += encode_unsigned16(&npdu[len], src->net); + npdu[len++] = src->len; + // SLEN = 0 denotes broadcast MAC SADR and SADR field is absent + // SLEN > 0 specifies length of SADR field + if (src->len) { + for (i = 0; i < src->len; i++) { + npdu[len++] = src->adr[i]; + } + } + } + // The Hop Count field shall be present only if the message is + // destined for a remote network, i.e., if DNET is present. + // This is a one-octet field that is initialized to a value of 0xff. + if (dest && dest->net) { + npdu[len] = 0xFF; + len++; + } + if (npdu_data->network_layer_message) { + npdu[len] = npdu_data->network_message_type; + len++; + // Message Type field contains a value in the range 0x80 - 0xFF, + // then a Vendor ID field shall be present + if (npdu_data->network_message_type >= 0x80) + len += encode_unsigned16(&npdu[len], npdu_data->vendor_id); } - } } - // The Hop Count field shall be present only if the message is - // destined for a remote network, i.e., if DNET is present. - // This is a one-octet field that is initialized to a value of 0xff. - if (dest && dest->net) - { - npdu[len] = 0xFF; - len++; - } - if (npdu_data->network_layer_message) - { - npdu[len] = npdu_data->network_message_type; - len++; - // Message Type field contains a value in the range 0x80 - 0xFF, - // then a Vendor ID field shall be present - if (npdu_data->network_message_type >= 0x80) - len += encode_unsigned16(&npdu[len], npdu_data->vendor_id); - } - } - return len; + return len; } // encode the NPDU portion of the packet for an APDU // This function does not handle the network messages, just APDUs. -int npdu_encode_apdu( - uint8_t *npdu, - BACNET_ADDRESS *dest, - BACNET_ADDRESS *src, - bool data_expecting_reply, // true for confirmed messages - BACNET_MESSAGE_PRIORITY priority) +int npdu_encode_apdu(uint8_t * npdu, BACNET_ADDRESS * dest, BACNET_ADDRESS * src, bool data_expecting_reply, // true for confirmed messages + BACNET_MESSAGE_PRIORITY priority) { - BACNET_NPDU_DATA npdu_data = {0}; + BACNET_NPDU_DATA npdu_data = { 0 }; - npdu_data.data_expecting_reply = data_expecting_reply; - npdu_data.network_layer_message = false; // false if APDU - npdu_data.network_message_type = 0; // optional - npdu_data.vendor_id = 0; // optional, if net message type is > 0x80 - npdu_data.priority = priority; - // call the real function... - return npdu_encode_raw( - npdu, - dest, - src, - &npdu_data); + npdu_data.data_expecting_reply = data_expecting_reply; + npdu_data.network_layer_message = false; // false if APDU + npdu_data.network_message_type = 0; // optional + npdu_data.vendor_id = 0; // optional, if net message type is > 0x80 + npdu_data.priority = priority; + // call the real function... + return npdu_encode_raw(npdu, dest, src, &npdu_data); } -int npdu_decode( - uint8_t *npdu, - BACNET_ADDRESS *dest, - BACNET_ADDRESS *src, - BACNET_NPDU_DATA *npdu_data) +int npdu_decode(uint8_t * npdu, + BACNET_ADDRESS * dest, + BACNET_ADDRESS * src, BACNET_NPDU_DATA * npdu_data) { - int len = 0; // return value - number of octets loaded in this function - int i = 0; // counter - uint16_t src_net = 0; - uint16_t dest_net = 0; - uint8_t address_len = 0; - uint8_t mac_octet = 0; + int len = 0; // return value - number of octets loaded in this function + int i = 0; // counter + uint16_t src_net = 0; + uint16_t dest_net = 0; + uint8_t address_len = 0; + uint8_t mac_octet = 0; - if (npdu && npdu_data) - { - // Protocol Version - npdu_data->protocol_version = npdu[0]; - // control octet - // Bit 7: 1 indicates that the NSDU conveys a network layer message. - // Message Type field is present. - // 0 indicates that the NSDU contains a BACnet APDU. - // Message Type field is absent. - npdu_data->network_layer_message = (npdu[1] & BIT7) ? true : false; - //Bit 6: Reserved. Shall be zero. - // Bit 4: Reserved. Shall be zero. - // Bit 2: The value of this bit corresponds to the data_expecting_reply - // parameter in the N-UNITDATA primitives. - // 1 indicates that a BACnet-Confirmed-Request-PDU, - // a segment of a BACnet-ComplexACK-PDU, - // or a network layer message expecting a reply is present. - // 0 indicates that other than a BACnet-Confirmed-Request-PDU, - // a segment of a BACnet-ComplexACK-PDU, - // or a network layer message expecting a reply is present. - npdu_data->data_expecting_reply = (npdu[1] & BIT2) ? true : false; - // Bits 1,0: Network priority where: - // B'11' = Life Safety message - // B'10' = Critical Equipment message - // B'01' = Urgent message - // B'00' = Normal message - npdu_data->priority = npdu[1] & 0x03; - // set the offset to where the optional stuff starts - len = 2; - //Bit 5: Destination specifier where: - // 0 = DNET, DLEN, DADR, and Hop Count absent - // 1 = DNET, DLEN, and Hop Count present - // DLEN = 0 denotes broadcast MAC DADR and DADR field is absent - // DLEN > 0 specifies length of DADR field - if (npdu[1] & BIT5) - { - len += decode_unsigned16(&npdu[len], &dest_net); - // DLEN = 0 denotes broadcast MAC DADR and DADR field is absent - // DLEN > 0 specifies length of DADR field - address_len = npdu[len++]; - if (dest) - { - dest->net = dest_net; - dest->len = address_len; - } - if (address_len) - { - for (i = 0; i < address_len; i++) - { - mac_octet = npdu[len++]; - if (dest) - dest->adr[i] = mac_octet; + if (npdu && npdu_data) { + // Protocol Version + npdu_data->protocol_version = npdu[0]; + // control octet + // Bit 7: 1 indicates that the NSDU conveys a network layer message. + // Message Type field is present. + // 0 indicates that the NSDU contains a BACnet APDU. + // Message Type field is absent. + npdu_data->network_layer_message = (npdu[1] & BIT7) ? true : false; + //Bit 6: Reserved. Shall be zero. + // Bit 4: Reserved. Shall be zero. + // Bit 2: The value of this bit corresponds to the data_expecting_reply + // parameter in the N-UNITDATA primitives. + // 1 indicates that a BACnet-Confirmed-Request-PDU, + // a segment of a BACnet-ComplexACK-PDU, + // or a network layer message expecting a reply is present. + // 0 indicates that other than a BACnet-Confirmed-Request-PDU, + // a segment of a BACnet-ComplexACK-PDU, + // or a network layer message expecting a reply is present. + npdu_data->data_expecting_reply = (npdu[1] & BIT2) ? true : false; + // Bits 1,0: Network priority where: + // B'11' = Life Safety message + // B'10' = Critical Equipment message + // B'01' = Urgent message + // B'00' = Normal message + npdu_data->priority = npdu[1] & 0x03; + // set the offset to where the optional stuff starts + len = 2; + //Bit 5: Destination specifier where: + // 0 = DNET, DLEN, DADR, and Hop Count absent + // 1 = DNET, DLEN, and Hop Count present + // DLEN = 0 denotes broadcast MAC DADR and DADR field is absent + // DLEN > 0 specifies length of DADR field + if (npdu[1] & BIT5) { + len += decode_unsigned16(&npdu[len], &dest_net); + // DLEN = 0 denotes broadcast MAC DADR and DADR field is absent + // DLEN > 0 specifies length of DADR field + address_len = npdu[len++]; + if (dest) { + dest->net = dest_net; + dest->len = address_len; + } + if (address_len) { + for (i = 0; i < address_len; i++) { + mac_octet = npdu[len++]; + if (dest) + dest->adr[i] = mac_octet; + } + } } - } - } - // zero out the destination address - else if (dest) - { - dest->net = 0; - dest->len = 0; - for (i = 0; i < MAX_MAC_LEN; i++) - { - dest->adr[i] = 0; - } - } - // Bit 3: Source specifier where: - // 0 = SNET, SLEN, and SADR absent - // 1 = SNET, SLEN, and SADR present - // SLEN = 0 Invalid - // SLEN > 0 specifies length of SADR field - if (npdu[1] & BIT3) - { - len += decode_unsigned16(&npdu[len], &src_net); - // SLEN = 0 denotes broadcast MAC SADR and SADR field is absent - // SLEN > 0 specifies length of SADR field - address_len = npdu[len++]; - if (src) - { - src->net = src_net; - src->len = address_len; - } - if (address_len) - { - for (i = 0; i < address_len; i++) - { - mac_octet = npdu[len++]; - if (src) - src->adr[i] = mac_octet; + // zero out the destination address + else if (dest) { + dest->net = 0; + dest->len = 0; + for (i = 0; i < MAX_MAC_LEN; i++) { + dest->adr[i] = 0; + } } - } + // Bit 3: Source specifier where: + // 0 = SNET, SLEN, and SADR absent + // 1 = SNET, SLEN, and SADR present + // SLEN = 0 Invalid + // SLEN > 0 specifies length of SADR field + if (npdu[1] & BIT3) { + len += decode_unsigned16(&npdu[len], &src_net); + // SLEN = 0 denotes broadcast MAC SADR and SADR field is absent + // SLEN > 0 specifies length of SADR field + address_len = npdu[len++]; + if (src) { + src->net = src_net; + src->len = address_len; + } + if (address_len) { + for (i = 0; i < address_len; i++) { + mac_octet = npdu[len++]; + if (src) + src->adr[i] = mac_octet; + } + } + } else if (src) { + src->net = 0; + src->len = 0; + for (i = 0; i < MAX_MAC_LEN; i++) { + src->adr[i] = 0; + } + } + // The Hop Count field shall be present only if the message is + // destined for a remote network, i.e., if DNET is present. + // This is a one-octet field that is initialized to a value of 0xff. + if (dest_net) + npdu_data->hop_count = npdu[len++]; + else + npdu_data->hop_count = 0; + // Indicates that the NSDU conveys a network layer message. + // Message Type field is present. + if (npdu_data->network_layer_message) { + npdu_data->network_message_type = npdu[len++]; + // Message Type field contains a value in the range 0x80 - 0xFF, + // then a Vendor ID field shall be present + if (npdu_data->network_message_type >= 0x80) + len += + decode_unsigned16(&npdu[len], &npdu_data->vendor_id); + } else + npdu_data->network_message_type = 0; } - else if (src) - { - src->net = 0; - src->len = 0; - for (i = 0; i < MAX_MAC_LEN; i++) - { - src->adr[i] = 0; - } - } - // The Hop Count field shall be present only if the message is - // destined for a remote network, i.e., if DNET is present. - // This is a one-octet field that is initialized to a value of 0xff. - if (dest_net) - npdu_data->hop_count = npdu[len++]; - else - npdu_data->hop_count = 0; - // Indicates that the NSDU conveys a network layer message. - // Message Type field is present. - if (npdu_data->network_layer_message) - { - npdu_data->network_message_type = npdu[len++]; - // Message Type field contains a value in the range 0x80 - 0xFF, - // then a Vendor ID field shall be present - if (npdu_data->network_message_type >= 0x80) - len += decode_unsigned16(&npdu[len], &npdu_data->vendor_id); - } - else - npdu_data->network_message_type = 0; - } - return len; + return len; } -void npdu_handler( - BACNET_ADDRESS *src, // source address - uint8_t *pdu, // PDU data - uint16_t pdu_len) // length PDU +void npdu_handler(BACNET_ADDRESS * src, // source address + uint8_t * pdu, // PDU data + uint16_t pdu_len) // length PDU { - int apdu_offset = 0; - BACNET_ADDRESS dest = {0}; - BACNET_NPDU_DATA npdu_data = {0}; - - apdu_offset = npdu_decode( - &pdu[0], // data to decode - &dest, // destination address - get the DNET/DLEN/DADR if in there - src, // source address - get the SNET/SLEN/SADR if in there - &npdu_data); // amount of data to decode - if (npdu_data.network_layer_message) - { - //FIXME: network layer message received! Handle it! - } - else - { - apdu_handler( - src, - npdu_data.data_expecting_reply, - &pdu[apdu_offset], - pdu_len - apdu_offset); - } + int apdu_offset = 0; + BACNET_ADDRESS dest = { 0 }; + BACNET_NPDU_DATA npdu_data = { 0 }; - return; + apdu_offset = npdu_decode(&pdu[0], // data to decode + &dest, // destination address - get the DNET/DLEN/DADR if in there + src, // source address - get the SNET/SLEN/SADR if in there + &npdu_data); // amount of data to decode + if (npdu_data.network_layer_message) { + //FIXME: network layer message received! Handle it! + } else { + apdu_handler(src, + npdu_data.data_expecting_reply, + &pdu[apdu_offset], pdu_len - apdu_offset); + } + + return; } @@ -343,161 +300,135 @@ void npdu_handler( void testNPDU2(Test * pTest) { - uint8_t pdu[480] = {0}; - BACNET_ADDRESS dest = {0}; - BACNET_ADDRESS src = {0}; - BACNET_ADDRESS npdu_dest = {0}; - BACNET_ADDRESS npdu_src = {0}; - int len = 0; - bool data_expecting_reply = false; // true for confirmed messages - BACNET_MESSAGE_PRIORITY priority = MESSAGE_PRIORITY_NORMAL; - BACNET_NPDU_DATA npdu_data = {0}; - int i = 0; // counter - int npdu_len = 0; - bool network_layer_message = false; // false if APDU - BACNET_NETWORK_MESSAGE_TYPE network_message_type = 0;// optional - uint16_t vendor_id = 0; // optional, if net message type is > 0x80 + uint8_t pdu[480] = { 0 }; + BACNET_ADDRESS dest = { 0 }; + BACNET_ADDRESS src = { 0 }; + BACNET_ADDRESS npdu_dest = { 0 }; + BACNET_ADDRESS npdu_src = { 0 }; + int len = 0; + bool data_expecting_reply = false; // true for confirmed messages + BACNET_MESSAGE_PRIORITY priority = MESSAGE_PRIORITY_NORMAL; + BACNET_NPDU_DATA npdu_data = { 0 }; + int i = 0; // counter + int npdu_len = 0; + bool network_layer_message = false; // false if APDU + BACNET_NETWORK_MESSAGE_TYPE network_message_type = 0; // optional + uint16_t vendor_id = 0; // optional, if net message type is > 0x80 - // mac_len = 0 if global address - dest.mac_len = 6; - for (i = 0; i < dest.mac_len; i++) - { - dest.mac[i] = i; - } - // DNET,DLEN,DADR - dest.net = 1; - dest.len = 6; - for (i = 0; i < dest.len; i++) - { - dest.adr[i] = i * 10; - } - src.mac_len = 1; - for (i = 0; i < src.mac_len; i++) - { - src.mac[i] = 0x80; - } - // SNET,SLEN,SADR - src.net = 2; - src.len = 1; - for (i = 0; i < src.len; i++) - { - src.adr[i] = 0x40; - } - len = npdu_encode_apdu( - &pdu[0], - &dest, - &src, - data_expecting_reply, - priority); - ct_test(pTest, len != 0); - // can we get the info back? - npdu_len = npdu_decode( - &pdu[0], - &npdu_dest, - &npdu_src, - &npdu_data); - ct_test(pTest, npdu_len != 0); - ct_test(pTest, npdu_data.data_expecting_reply == data_expecting_reply); - ct_test(pTest, npdu_data.network_layer_message == network_layer_message); - ct_test(pTest, npdu_data.network_message_type == network_message_type); - ct_test(pTest, npdu_data.vendor_id == vendor_id); - ct_test(pTest, npdu_data.priority == priority); - // DNET,DLEN,DADR - ct_test(pTest, npdu_dest.net == dest.net); - ct_test(pTest, npdu_dest.len == dest.len); - for (i = 0; i < dest.len; i++) - { - ct_test(pTest, npdu_dest.adr[i] == dest.adr[i]); - } - // SNET,SLEN,SADR - ct_test(pTest, npdu_src.net == src.net); - ct_test(pTest, npdu_src.len == src.len); - for (i = 0; i < src.len; i++) - { - ct_test(pTest, npdu_src.adr[i] == src.adr[i]); - } + // mac_len = 0 if global address + dest.mac_len = 6; + for (i = 0; i < dest.mac_len; i++) { + dest.mac[i] = i; + } + // DNET,DLEN,DADR + dest.net = 1; + dest.len = 6; + for (i = 0; i < dest.len; i++) { + dest.adr[i] = i * 10; + } + src.mac_len = 1; + for (i = 0; i < src.mac_len; i++) { + src.mac[i] = 0x80; + } + // SNET,SLEN,SADR + src.net = 2; + src.len = 1; + for (i = 0; i < src.len; i++) { + src.adr[i] = 0x40; + } + len = npdu_encode_apdu(&pdu[0], + &dest, &src, data_expecting_reply, priority); + ct_test(pTest, len != 0); + // can we get the info back? + npdu_len = npdu_decode(&pdu[0], &npdu_dest, &npdu_src, &npdu_data); + ct_test(pTest, npdu_len != 0); + ct_test(pTest, npdu_data.data_expecting_reply == data_expecting_reply); + ct_test(pTest, + npdu_data.network_layer_message == network_layer_message); + ct_test(pTest, npdu_data.network_message_type == network_message_type); + ct_test(pTest, npdu_data.vendor_id == vendor_id); + ct_test(pTest, npdu_data.priority == priority); + // DNET,DLEN,DADR + ct_test(pTest, npdu_dest.net == dest.net); + ct_test(pTest, npdu_dest.len == dest.len); + for (i = 0; i < dest.len; i++) { + ct_test(pTest, npdu_dest.adr[i] == dest.adr[i]); + } + // SNET,SLEN,SADR + ct_test(pTest, npdu_src.net == src.net); + ct_test(pTest, npdu_src.len == src.len); + for (i = 0; i < src.len; i++) { + ct_test(pTest, npdu_src.adr[i] == src.adr[i]); + } } void testNPDU1(Test * pTest) { - uint8_t pdu[480] = {0}; - BACNET_ADDRESS dest = {0}; - BACNET_ADDRESS src = {0}; - BACNET_ADDRESS npdu_dest = {0}; - BACNET_ADDRESS npdu_src = {0}; - int len = 0; - bool data_expecting_reply = false; // true for confirmed messages - BACNET_MESSAGE_PRIORITY priority = MESSAGE_PRIORITY_NORMAL; - BACNET_NPDU_DATA npdu_data = {0}; - int i = 0; // counter - int npdu_len = 0; - bool network_layer_message = false; // false if APDU - BACNET_NETWORK_MESSAGE_TYPE network_message_type = 0;// optional - uint16_t vendor_id = 0; // optional, if net message type is > 0x80 + uint8_t pdu[480] = { 0 }; + BACNET_ADDRESS dest = { 0 }; + BACNET_ADDRESS src = { 0 }; + BACNET_ADDRESS npdu_dest = { 0 }; + BACNET_ADDRESS npdu_src = { 0 }; + int len = 0; + bool data_expecting_reply = false; // true for confirmed messages + BACNET_MESSAGE_PRIORITY priority = MESSAGE_PRIORITY_NORMAL; + BACNET_NPDU_DATA npdu_data = { 0 }; + int i = 0; // counter + int npdu_len = 0; + bool network_layer_message = false; // false if APDU + BACNET_NETWORK_MESSAGE_TYPE network_message_type = 0; // optional + uint16_t vendor_id = 0; // optional, if net message type is > 0x80 - // mac_len = 0 if global address - dest.mac_len = 0; - for (i = 0; i < MAX_MAC_LEN; i++) - { - dest.mac[i] = 0; - } - // DNET,DLEN,DADR - dest.net = 0; - dest.len = 0; - for (i = 0; i < MAX_MAC_LEN; i++) - { - dest.adr[i] = 0; - } - src.mac_len = 0; - for (i = 0; i < MAX_MAC_LEN; i++) - { - src.mac[i] = 0; - } - // SNET,SLEN,SADR - src.net = 0; - src.len = 0; - for (i = 0; i < MAX_MAC_LEN; i++) - { - src.adr[i] = 0; - } - len = npdu_encode_apdu( - &pdu[0], - &dest, - &src, - data_expecting_reply, - priority); - ct_test(pTest, len != 0); - // can we get the info back? - npdu_len = npdu_decode( - &pdu[0], - &npdu_dest, - &npdu_src, - &npdu_data); - ct_test(pTest, npdu_len != 0); - ct_test(pTest, npdu_data.data_expecting_reply == data_expecting_reply); - ct_test(pTest, npdu_data.network_layer_message == network_layer_message); - ct_test(pTest, npdu_data.network_message_type == network_message_type); - ct_test(pTest, npdu_data.vendor_id == vendor_id); - ct_test(pTest, npdu_data.priority == priority); - ct_test(pTest, npdu_dest.mac_len == src.mac_len); - ct_test(pTest, npdu_src.mac_len == dest.mac_len); + // mac_len = 0 if global address + dest.mac_len = 0; + for (i = 0; i < MAX_MAC_LEN; i++) { + dest.mac[i] = 0; + } + // DNET,DLEN,DADR + dest.net = 0; + dest.len = 0; + for (i = 0; i < MAX_MAC_LEN; i++) { + dest.adr[i] = 0; + } + src.mac_len = 0; + for (i = 0; i < MAX_MAC_LEN; i++) { + src.mac[i] = 0; + } + // SNET,SLEN,SADR + src.net = 0; + src.len = 0; + for (i = 0; i < MAX_MAC_LEN; i++) { + src.adr[i] = 0; + } + len = npdu_encode_apdu(&pdu[0], + &dest, &src, data_expecting_reply, priority); + ct_test(pTest, len != 0); + // can we get the info back? + npdu_len = npdu_decode(&pdu[0], &npdu_dest, &npdu_src, &npdu_data); + ct_test(pTest, npdu_len != 0); + ct_test(pTest, npdu_data.data_expecting_reply == data_expecting_reply); + ct_test(pTest, + npdu_data.network_layer_message == network_layer_message); + ct_test(pTest, npdu_data.network_message_type == network_message_type); + ct_test(pTest, npdu_data.vendor_id == vendor_id); + ct_test(pTest, npdu_data.priority == priority); + ct_test(pTest, npdu_dest.mac_len == src.mac_len); + ct_test(pTest, npdu_src.mac_len == dest.mac_len); } #ifdef TEST_NPDU // dummy stub for testing void tsm_free_invoke_id(uint8_t invokeID) { - (void)invokeID; + (void) invokeID; } -void iam_handler( - uint8_t *service_request, - uint16_t service_len, - BACNET_ADDRESS *src) +void iam_handler(uint8_t * service_request, + uint16_t service_len, BACNET_ADDRESS * src) { - (void)service_request; - (void)service_len; - (void)src; + (void) service_request; + (void) service_len; + (void) src; } int main(void) diff --git a/bacnet-stack/npdu.h b/bacnet-stack/npdu.h index df5516a3..41549d07 100644 --- a/bacnet-stack/npdu.h +++ b/bacnet-stack/npdu.h @@ -40,50 +40,39 @@ #include "bacenum.h" // an NPDU structure keeps the parameter stack to a minimum -typedef struct bacnet_npdu_data_t -{ - uint8_t protocol_version; - // parts of the control octet: - bool data_expecting_reply; // true for confirmed messages - bool network_layer_message; // false if APDU - BACNET_MESSAGE_PRIORITY priority; - // optional network message info - BACNET_NETWORK_MESSAGE_TYPE network_message_type; // optional - uint16_t vendor_id; // optional, if net message type is > 0x80 - uint8_t hop_count; +typedef struct bacnet_npdu_data_t { + uint8_t protocol_version; + // parts of the control octet: + bool data_expecting_reply; // true for confirmed messages + bool network_layer_message; // false if APDU + BACNET_MESSAGE_PRIORITY priority; + // optional network message info + BACNET_NETWORK_MESSAGE_TYPE network_message_type; // optional + uint16_t vendor_id; // optional, if net message type is > 0x80 + uint8_t hop_count; } BACNET_NPDU_DATA; #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ -uint8_t npdu_encode_max_seg_max_apdu(int max_segs, int max_apdu); -int npdu_encode_raw( - uint8_t *npdu, - BACNET_ADDRESS *dest, - BACNET_ADDRESS *src, - BACNET_NPDU_DATA *npdu_data); + uint8_t npdu_encode_max_seg_max_apdu(int max_segs, int max_apdu); + int npdu_encode_raw(uint8_t * npdu, + BACNET_ADDRESS * dest, + BACNET_ADDRESS * src, BACNET_NPDU_DATA * npdu_data); // encode the NPDU portion of the packet for an APDU -int npdu_encode_apdu( - uint8_t *npdu, - BACNET_ADDRESS *dest, - BACNET_ADDRESS *src, - bool data_expecting_reply, // true for confirmed messages - BACNET_MESSAGE_PRIORITY priority); + int npdu_encode_apdu(uint8_t * npdu, BACNET_ADDRESS * dest, BACNET_ADDRESS * src, bool data_expecting_reply, // true for confirmed messages + BACNET_MESSAGE_PRIORITY priority); -int npdu_decode( - uint8_t *npdu, - BACNET_ADDRESS *dest, - BACNET_ADDRESS *src, - BACNET_NPDU_DATA *npdu_data); + int npdu_decode(uint8_t * npdu, + BACNET_ADDRESS * dest, + BACNET_ADDRESS * src, BACNET_NPDU_DATA * npdu_data); -void npdu_handler( - BACNET_ADDRESS *src, // source address - uint8_t *pdu, // PDU data - uint16_t pdu_len); // length PDU + void npdu_handler(BACNET_ADDRESS * src, // source address + uint8_t * pdu, // PDU data + uint16_t pdu_len); // length PDU #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif diff --git a/bacnet-stack/rd.c b/bacnet-stack/rd.c index b11b9ef1..9746a592 100644 --- a/bacnet-stack/rd.c +++ b/bacnet-stack/rd.c @@ -38,106 +38,93 @@ #include "rd.h" /* encode service */ -int rd_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - BACNET_REINITIALIZED_STATE state, - BACNET_CHARACTER_STRING *password) +int rd_encode_apdu(uint8_t * apdu, + uint8_t invoke_id, + BACNET_REINITIALIZED_STATE state, BACNET_CHARACTER_STRING * password) { - int len = 0; /* length of each encoding */ - int apdu_len = 0; /* total length of the apdu, return value */ + int len = 0; /* length of each encoding */ + int apdu_len = 0; /* total length of the apdu, return value */ - if (apdu) - { - apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST; - apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU); - apdu[2] = invoke_id; - apdu[3] = SERVICE_CONFIRMED_REINITIALIZE_DEVICE; - apdu_len = 4; - len = encode_context_enumerated(&apdu[apdu_len], 0, - state); - apdu_len += len; - /* optional password */ - if (password) - { - /* FIXME: must be at least 1 character, limited to 20 characters */ - len = encode_context_character_string(&apdu[apdu_len], 1, - password); - apdu_len += len; + if (apdu) { + apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST; + apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU); + apdu[2] = invoke_id; + apdu[3] = SERVICE_CONFIRMED_REINITIALIZE_DEVICE; + apdu_len = 4; + len = encode_context_enumerated(&apdu[apdu_len], 0, state); + apdu_len += len; + /* optional password */ + if (password) { + /* FIXME: must be at least 1 character, limited to 20 characters */ + len = encode_context_character_string(&apdu[apdu_len], 1, + password); + apdu_len += len; + } } - } - return apdu_len; + return apdu_len; } /* decode the service request only */ -int rd_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - BACNET_REINITIALIZED_STATE *state, - BACNET_CHARACTER_STRING *password) +int rd_decode_service_request(uint8_t * apdu, + unsigned apdu_len, + BACNET_REINITIALIZED_STATE * state, BACNET_CHARACTER_STRING * password) { - unsigned len = 0; - uint8_t tag_number = 0; - uint32_t len_value_type = 0; - int value = 0; + unsigned len = 0; + uint8_t tag_number = 0; + uint32_t len_value_type = 0; + int value = 0; - /* check for value pointers */ - if (apdu_len) - { - /* Tag 0: reinitializedStateOfDevice */ - if (!decode_is_context_tag(&apdu[len], 0)) - return -1; - len += decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - len += decode_enumerated(&apdu[len], len_value_type, &value); - if (state) - *state = value; - /* Tag 1: password - optional */ - if (len < apdu_len) - { - if (!decode_is_context_tag(&apdu[len], 1)) - return -1; - len += decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - len += decode_character_string(&apdu[len], len_value_type, password); + /* check for value pointers */ + if (apdu_len) { + /* Tag 0: reinitializedStateOfDevice */ + if (!decode_is_context_tag(&apdu[len], 0)) + return -1; + len += decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + len += decode_enumerated(&apdu[len], len_value_type, &value); + if (state) + *state = value; + /* Tag 1: password - optional */ + if (len < apdu_len) { + if (!decode_is_context_tag(&apdu[len], 1)) + return -1; + len += decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + len += + decode_character_string(&apdu[len], len_value_type, + password); + } } - } - return (int)len; + return (int) len; } -int rd_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - BACNET_REINITIALIZED_STATE *state, - BACNET_CHARACTER_STRING *password) +int rd_decode_apdu(uint8_t * apdu, + unsigned apdu_len, + uint8_t * invoke_id, + BACNET_REINITIALIZED_STATE * state, BACNET_CHARACTER_STRING * password) { - int len = 0; - unsigned offset = 0; + int len = 0; + unsigned offset = 0; - if (!apdu) - return -1; - // optional checking - most likely was already done prior to this call - if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) - return -1; - // apdu[1] = encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); - *invoke_id = apdu[2]; /* invoke id - filled in by net layer */ - if (apdu[3] != SERVICE_CONFIRMED_REINITIALIZE_DEVICE) - return -1; - offset = 4; + if (!apdu) + return -1; + // optional checking - most likely was already done prior to this call + if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) + return -1; + // apdu[1] = encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); + *invoke_id = apdu[2]; /* invoke id - filled in by net layer */ + if (apdu[3] != SERVICE_CONFIRMED_REINITIALIZE_DEVICE) + return -1; + offset = 4; - if (apdu_len > offset) - { - len = rd_decode_service_request( - &apdu[offset], - apdu_len - offset, - state, - password); - } + if (apdu_len > offset) { + len = rd_decode_service_request(&apdu[offset], + apdu_len - offset, state, password); + } - return len; + return len; } #ifdef TEST @@ -147,38 +134,30 @@ int rd_decode_apdu( void test_ReinitializeDevice(Test * pTest) { - uint8_t apdu[480] = {0}; - int len = 0; - int apdu_len = 0; - uint8_t invoke_id = 128; - uint8_t test_invoke_id = 0; - BACNET_REINITIALIZED_STATE state; - BACNET_REINITIALIZED_STATE test_state; - BACNET_CHARACTER_STRING password; - BACNET_CHARACTER_STRING test_password; + uint8_t apdu[480] = { 0 }; + int len = 0; + int apdu_len = 0; + uint8_t invoke_id = 128; + uint8_t test_invoke_id = 0; + BACNET_REINITIALIZED_STATE state; + BACNET_REINITIALIZED_STATE test_state; + BACNET_CHARACTER_STRING password; + BACNET_CHARACTER_STRING test_password; - state = BACNET_REINIT_WARMSTART; - characterstring_init_ansi(&password,"John 3:16"); - len = rd_encode_apdu( - &apdu[0], - invoke_id, - state, - &password); - ct_test(pTest, len != 0); - apdu_len = len; + state = BACNET_REINIT_WARMSTART; + characterstring_init_ansi(&password, "John 3:16"); + len = rd_encode_apdu(&apdu[0], invoke_id, state, &password); + ct_test(pTest, len != 0); + apdu_len = len; - len = rd_decode_apdu( - &apdu[0], - apdu_len, - &test_invoke_id, - &test_state, - &test_password); - ct_test(pTest, len != -1); - ct_test(pTest, test_invoke_id == invoke_id); - ct_test(pTest, test_state == state); - ct_test(pTest, characterstring_same(&test_password,&password)); + len = rd_decode_apdu(&apdu[0], + apdu_len, &test_invoke_id, &test_state, &test_password); + ct_test(pTest, len != -1); + ct_test(pTest, test_invoke_id == invoke_id); + ct_test(pTest, test_state == state); + ct_test(pTest, characterstring_same(&test_password, &password)); - return; + return; } #ifdef TEST_REINITIALIZE_DEVICE diff --git a/bacnet-stack/rd.h b/bacnet-stack/rd.h index 439fe108..735937f6 100644 --- a/bacnet-stack/rd.h +++ b/bacnet-stack/rd.h @@ -39,37 +39,32 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ // encode service -int rd_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - BACNET_REINITIALIZED_STATE state, - BACNET_CHARACTER_STRING *password); + int rd_encode_apdu(uint8_t * apdu, + uint8_t invoke_id, + BACNET_REINITIALIZED_STATE state, + BACNET_CHARACTER_STRING * password); // decode the service request only -int rd_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - BACNET_REINITIALIZED_STATE *state, - BACNET_CHARACTER_STRING *password); - -int rd_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - BACNET_REINITIALIZED_STATE *state, - BACNET_CHARACTER_STRING *password); + int rd_decode_service_request(uint8_t * apdu, + unsigned apdu_len, + BACNET_REINITIALIZED_STATE * state, + BACNET_CHARACTER_STRING * password); + + int rd_decode_apdu(uint8_t * apdu, + unsigned apdu_len, + uint8_t * invoke_id, + BACNET_REINITIALIZED_STATE * state, + BACNET_CHARACTER_STRING * password); #ifdef TEST #include "ctest.h" -void test_ReinitializeDevice(Test * pTest); + void test_ReinitializeDevice(Test * pTest); #endif #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif - diff --git a/bacnet-stack/reject.c b/bacnet-stack/reject.c index a1dcd9eb..b466756a 100644 --- a/bacnet-stack/reject.c +++ b/bacnet-stack/reject.c @@ -37,71 +37,56 @@ #include "bacdef.h" // encode service -int reject_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - uint8_t reject_reason) +int reject_encode_apdu(uint8_t * apdu, + uint8_t invoke_id, uint8_t reject_reason) { - int apdu_len = 0; // total length of the apdu, return value + int apdu_len = 0; // total length of the apdu, return value - if (apdu) - { - apdu[0] = PDU_TYPE_REJECT; - apdu[1] = invoke_id; - apdu[2] = reject_reason; - apdu_len = 3; - } - - return apdu_len; + if (apdu) { + apdu[0] = PDU_TYPE_REJECT; + apdu[1] = invoke_id; + apdu[2] = reject_reason; + apdu_len = 3; + } + + return apdu_len; } // decode the service request only -int reject_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - uint8_t *reject_reason) +int reject_decode_service_request(uint8_t * apdu, + unsigned apdu_len, uint8_t * invoke_id, uint8_t * reject_reason) { - int len = 0; + int len = 0; - if (apdu_len) - { - if (invoke_id) - *invoke_id = apdu[0]; - if (reject_reason) - *reject_reason = apdu[1]; - } - - return len; + if (apdu_len) { + if (invoke_id) + *invoke_id = apdu[0]; + if (reject_reason) + *reject_reason = apdu[1]; + } + + return len; } // decode the whole APDU - mainly used for unit testing -int reject_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - uint8_t *reject_reason) +int reject_decode_apdu(uint8_t * apdu, + unsigned apdu_len, uint8_t * invoke_id, uint8_t * reject_reason) { - int len = 0; + int len = 0; - if (!apdu) - return -1; - // optional checking - most likely was already done prior to this call - if (apdu_len) - { - if (apdu[0] != PDU_TYPE_REJECT) - return -1; - if (apdu_len > 1) - { - len = reject_decode_service_request( - &apdu[1], - apdu_len - 1, - invoke_id, - reject_reason); + if (!apdu) + return -1; + // optional checking - most likely was already done prior to this call + if (apdu_len) { + if (apdu[0] != PDU_TYPE_REJECT) + return -1; + if (apdu_len > 1) { + len = reject_decode_service_request(&apdu[1], + apdu_len - 1, invoke_id, reject_reason); + } } - } - - return len; + + return len; } #ifdef TEST @@ -111,83 +96,54 @@ int reject_decode_apdu( void testReject(Test * pTest) { - uint8_t apdu[480] = {0}; - int len = 0; - int apdu_len = 0; - uint8_t invoke_id = 0; - uint8_t reject_reason = 0; - uint8_t test_invoke_id = 0; - uint8_t test_reject_reason = 0; - - len = reject_encode_apdu( - &apdu[0], - invoke_id, - reject_reason); - ct_test(pTest, len != 0); - apdu_len = len; + uint8_t apdu[480] = { 0 }; + int len = 0; + int apdu_len = 0; + uint8_t invoke_id = 0; + uint8_t reject_reason = 0; + uint8_t test_invoke_id = 0; + uint8_t test_reject_reason = 0; - len = reject_decode_apdu( - &apdu[0], - apdu_len, - &test_invoke_id, - &test_reject_reason); - ct_test(pTest, len != -1); - ct_test(pTest, test_invoke_id == invoke_id); - ct_test(pTest, test_reject_reason == reject_reason); + len = reject_encode_apdu(&apdu[0], invoke_id, reject_reason); + ct_test(pTest, len != 0); + apdu_len = len; - // change type to get negative response - apdu[0] = PDU_TYPE_ABORT; - len = reject_decode_apdu( - &apdu[0], - apdu_len, - &test_invoke_id, - &test_reject_reason); - ct_test(pTest, len == -1); + len = reject_decode_apdu(&apdu[0], + apdu_len, &test_invoke_id, &test_reject_reason); + ct_test(pTest, len != -1); + ct_test(pTest, test_invoke_id == invoke_id); + ct_test(pTest, test_reject_reason == reject_reason); - // test NULL APDU - len = reject_decode_apdu( - NULL, - apdu_len, - &test_invoke_id, - &test_reject_reason); - ct_test(pTest, len == -1); + // change type to get negative response + apdu[0] = PDU_TYPE_ABORT; + len = reject_decode_apdu(&apdu[0], + apdu_len, &test_invoke_id, &test_reject_reason); + ct_test(pTest, len == -1); - // force a zero length - len = reject_decode_apdu( - &apdu[0], - 0, - &test_invoke_id, - &test_reject_reason); - ct_test(pTest, len == 0); - - - // check them all... - for ( - invoke_id = 0; - invoke_id < 255; - invoke_id++) - { - for ( - reject_reason = 0; - reject_reason < 255; - reject_reason++) - { - len = reject_encode_apdu( - &apdu[0], - invoke_id, - reject_reason); - apdu_len = len; - ct_test(pTest, len != 0); - len = reject_decode_apdu( - &apdu[0], - apdu_len, - &test_invoke_id, - &test_reject_reason); - ct_test(pTest, len != -1); - ct_test(pTest, test_invoke_id == invoke_id); - ct_test(pTest, test_reject_reason == reject_reason); + // test NULL APDU + len = reject_decode_apdu(NULL, + apdu_len, &test_invoke_id, &test_reject_reason); + ct_test(pTest, len == -1); + + // force a zero length + len = reject_decode_apdu(&apdu[0], + 0, &test_invoke_id, &test_reject_reason); + ct_test(pTest, len == 0); + + + // check them all... + for (invoke_id = 0; invoke_id < 255; invoke_id++) { + for (reject_reason = 0; reject_reason < 255; reject_reason++) { + len = reject_encode_apdu(&apdu[0], invoke_id, reject_reason); + apdu_len = len; + ct_test(pTest, len != 0); + len = reject_decode_apdu(&apdu[0], + apdu_len, &test_invoke_id, &test_reject_reason); + ct_test(pTest, len != -1); + ct_test(pTest, test_invoke_id == invoke_id); + ct_test(pTest, test_reject_reason == reject_reason); + } } - } } #ifdef TEST_REJECT diff --git a/bacnet-stack/reject.h b/bacnet-stack/reject.h index 27b66e5b..14a73977 100644 --- a/bacnet-stack/reject.h +++ b/bacnet-stack/reject.h @@ -39,32 +39,22 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ -int reject_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - uint8_t reject_reason); + int reject_encode_apdu(uint8_t * apdu, + uint8_t invoke_id, uint8_t reject_reason); -int reject_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - uint8_t *reject_reason); - -int reject_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - uint8_t *reject_reason); + int reject_decode_service_request(uint8_t * apdu, + unsigned apdu_len, uint8_t * invoke_id, uint8_t * reject_reason); + + int reject_decode_apdu(uint8_t * apdu, + unsigned apdu_len, uint8_t * invoke_id, uint8_t * reject_reason); #ifdef TEST -void testReject(Test * pTest); + void testReject(Test * pTest); #endif #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif - diff --git a/bacnet-stack/ringbuf.c b/bacnet-stack/ringbuf.c index bf271a4c..c1b64bed 100644 --- a/bacnet-stack/ringbuf.c +++ b/bacnet-stack/ringbuf.c @@ -48,7 +48,7 @@ *****************************************************************************/ bool Ringbuf_Empty(RING_BUFFER const *b) { - return (b->count == 0); + return (b->count == 0); } /**************************************************************************** @@ -59,7 +59,7 @@ bool Ringbuf_Empty(RING_BUFFER const *b) *****************************************************************************/ char *Ringbuf_Get_Front(RING_BUFFER const *b) { - return (b->count ? &(b->data[b->head * b->element_size]) : NULL); + return (b->count ? &(b->data[b->head * b->element_size]) : NULL); } /**************************************************************************** @@ -68,20 +68,19 @@ char *Ringbuf_Get_Front(RING_BUFFER const *b) * ALGORITHM: none * NOTES: none *****************************************************************************/ -char *Ringbuf_Pop_Front(RING_BUFFER *b) +char *Ringbuf_Pop_Front(RING_BUFFER * b) { - char *data = NULL; // return value + char *data = NULL; // return value - if (b->count) - { - data = &(b->data[b->head * b->element_size]); - b->head++; - if (b->head >= b->element_count) - b->head = 0; - b->count--; - } + if (b->count) { + data = &(b->data[b->head * b->element_size]); + b->head++; + if (b->head >= b->element_count) + b->head = 0; + b->count--; + } - return data; + return data; } /**************************************************************************** @@ -90,34 +89,30 @@ char *Ringbuf_Pop_Front(RING_BUFFER *b) * ALGORITHM: none * NOTES: none *****************************************************************************/ -bool Ringbuf_Put( - RING_BUFFER *b, // ring buffer structure - char *data_element) // one element to add to the ring +bool Ringbuf_Put(RING_BUFFER * b, // ring buffer structure + char *data_element) // one element to add to the ring { - bool status = false; // return value - unsigned offset = 0; // offset into array of data - char *ring_data = NULL; // used to help point ring data - unsigned i; // loop counter + bool status = false; // return value + unsigned offset = 0; // offset into array of data + char *ring_data = NULL; // used to help point ring data + unsigned i; // loop counter - if (b && data_element) - { - // limit the amount of data that we accept - if (b->count < b->element_count) - { - offset = b->head + b->count; - if (offset >= b->element_count) - offset -= b->element_count; - ring_data = b->data + offset * b->element_size; - for(i = 0; i < b->element_size; i++) - { - ring_data[i] = data_element[i]; - } - b->count++; - status = true; + if (b && data_element) { + // limit the amount of data that we accept + if (b->count < b->element_count) { + offset = b->head + b->count; + if (offset >= b->element_count) + offset -= b->element_count; + ring_data = b->data + offset * b->element_size; + for (i = 0; i < b->element_size; i++) { + ring_data[i] = data_element[i]; + } + b->count++; + status = true; + } } - } - return status; + return status; } /**************************************************************************** @@ -126,19 +121,18 @@ bool Ringbuf_Put( * ALGORITHM: none * NOTES: none *****************************************************************************/ -void Ringbuf_Init( - RING_BUFFER *b, // ring buffer structure - char *data, // data block or array of data - unsigned element_size, // size of one element in the data block - unsigned element_count) // number of elements in the data block +void Ringbuf_Init(RING_BUFFER * b, // ring buffer structure + char *data, // data block or array of data + unsigned element_size, // size of one element in the data block + unsigned element_count) // number of elements in the data block { - b->head = 0; - b->count = 0; - b->data = data; - b->element_size = element_size; - b->element_count = element_count; + b->head = 0; + b->count = 0; + b->data = data; + b->element_size = element_size; + b->element_count = element_count; - return; + return; } #ifdef TEST @@ -150,139 +144,130 @@ void Ringbuf_Init( // test the FIFO #define RING_BUFFER_DATA_SIZE 5 #define RING_BUFFER_SIZE 16 -void testRingBuf(Test* pTest) +void testRingBuf(Test * pTest) { - RING_BUFFER test_buffer; - char data_store[RING_BUFFER_DATA_SIZE * RING_BUFFER_SIZE]; - char data[RING_BUFFER_DATA_SIZE]; - char *test_data; - unsigned index; - unsigned data_index; - unsigned count; - unsigned dummy; - bool status; + RING_BUFFER test_buffer; + char data_store[RING_BUFFER_DATA_SIZE * RING_BUFFER_SIZE]; + char data[RING_BUFFER_DATA_SIZE]; + char *test_data; + unsigned index; + unsigned data_index; + unsigned count; + unsigned dummy; + bool status; - Ringbuf_Init(&test_buffer,data_store,RING_BUFFER_DATA_SIZE,RING_BUFFER_SIZE); - ct_test(pTest,Ringbuf_Empty(&test_buffer)); + Ringbuf_Init(&test_buffer, data_store, RING_BUFFER_DATA_SIZE, + RING_BUFFER_SIZE); + ct_test(pTest, Ringbuf_Empty(&test_buffer)); - for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) - { - data[data_index] = data_index; - } - status = Ringbuf_Put(&test_buffer, data); - ct_test(pTest,status == true); - ct_test(pTest,!Ringbuf_Empty(&test_buffer)); - - test_data = Ringbuf_Get_Front(&test_buffer); - for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) - { - ct_test(pTest,test_data[data_index] == data[data_index]); - } - ct_test(pTest,!Ringbuf_Empty(&test_buffer)); - - test_data = Ringbuf_Pop_Front(&test_buffer); - for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) - { - ct_test(pTest,test_data[data_index] == data[data_index]); - } - ct_test(pTest,Ringbuf_Empty(&test_buffer)); - - // fill to max - for (index = 0; index < RING_BUFFER_SIZE; index++) - { - for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) - { - data[data_index] = index; + for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) { + data[data_index] = data_index; } status = Ringbuf_Put(&test_buffer, data); - ct_test(pTest,status == true); - ct_test(pTest,!Ringbuf_Empty(&test_buffer)); - } - // verify actions on full buffer - for (index = 0; index < RING_BUFFER_SIZE; index++) - { - for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) - { - data[data_index] = index; - } - status = Ringbuf_Put(&test_buffer, data); - ct_test(pTest,status == false); - ct_test(pTest,!Ringbuf_Empty(&test_buffer)); - } + ct_test(pTest, status == true); + ct_test(pTest, !Ringbuf_Empty(&test_buffer)); - // check buffer full - for (index = 0; index < RING_BUFFER_SIZE; index++) - { test_data = Ringbuf_Get_Front(&test_buffer); - for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) - { - ct_test(pTest,test_data[data_index] == index); + for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) { + ct_test(pTest, test_data[data_index] == data[data_index]); } + ct_test(pTest, !Ringbuf_Empty(&test_buffer)); test_data = Ringbuf_Pop_Front(&test_buffer); - for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) - { - ct_test(pTest,test_data[data_index] == index); + for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) { + ct_test(pTest, test_data[data_index] == data[data_index]); } - } - ct_test(pTest,Ringbuf_Empty(&test_buffer)); + ct_test(pTest, Ringbuf_Empty(&test_buffer)); - // test the ring around the buffer - for (index = 0; index < RING_BUFFER_SIZE; index++) - { - for (count = 1; count < 4; count++) - { - dummy = index * count; - for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) - { - data[data_index] = dummy; - } - status = Ringbuf_Put(&test_buffer, data); - ct_test(pTest,status == true); + // fill to max + for (index = 0; index < RING_BUFFER_SIZE; index++) { + for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; + data_index++) { + data[data_index] = index; + } + status = Ringbuf_Put(&test_buffer, data); + ct_test(pTest, status == true); + ct_test(pTest, !Ringbuf_Empty(&test_buffer)); + } + // verify actions on full buffer + for (index = 0; index < RING_BUFFER_SIZE; index++) { + for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; + data_index++) { + data[data_index] = index; + } + status = Ringbuf_Put(&test_buffer, data); + ct_test(pTest, status == false); + ct_test(pTest, !Ringbuf_Empty(&test_buffer)); } - for (count = 1; count < 4; count++) - { - dummy = index * count; - test_data = Ringbuf_Get_Front(&test_buffer); - for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) - { - ct_test(pTest,test_data[data_index] == dummy); - } + // check buffer full + for (index = 0; index < RING_BUFFER_SIZE; index++) { + test_data = Ringbuf_Get_Front(&test_buffer); + for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; + data_index++) { + ct_test(pTest, test_data[data_index] == index); + } - test_data = Ringbuf_Pop_Front(&test_buffer); - for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) - { - ct_test(pTest,test_data[data_index] == dummy); - } + test_data = Ringbuf_Pop_Front(&test_buffer); + for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; + data_index++) { + ct_test(pTest, test_data[data_index] == index); + } } - } - ct_test(pTest,Ringbuf_Empty(&test_buffer)); + ct_test(pTest, Ringbuf_Empty(&test_buffer)); + + // test the ring around the buffer + for (index = 0; index < RING_BUFFER_SIZE; index++) { + for (count = 1; count < 4; count++) { + dummy = index * count; + for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; + data_index++) { + data[data_index] = dummy; + } + status = Ringbuf_Put(&test_buffer, data); + ct_test(pTest, status == true); + } + + for (count = 1; count < 4; count++) { + dummy = index * count; + test_data = Ringbuf_Get_Front(&test_buffer); + for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; + data_index++) { + ct_test(pTest, test_data[data_index] == dummy); + } + + test_data = Ringbuf_Pop_Front(&test_buffer); + for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; + data_index++) { + ct_test(pTest, test_data[data_index] == dummy); + } + } + } + ct_test(pTest, Ringbuf_Empty(&test_buffer)); - return; + return; } #ifdef TEST_RINGBUF int main(void) { - Test *pTest; - bool rc; + Test *pTest; + bool rc; - pTest = ct_create("ringbuf", NULL); + pTest = ct_create("ringbuf", NULL); - /* individual tests */ - rc = ct_addTestFunction(pTest, testRingBuf); - assert(rc); + /* individual tests */ + rc = ct_addTestFunction(pTest, testRingBuf); + assert(rc); - ct_setStream(pTest, stdout); - ct_run(pTest); - (void)ct_report(pTest); + ct_setStream(pTest, stdout); + ct_run(pTest); + (void) ct_report(pTest); - ct_destroy(pTest); + ct_destroy(pTest); - return 0; + return 0; } #endif #endif - diff --git a/bacnet-stack/ringbuf.h b/bacnet-stack/ringbuf.h index 38f4cb50..7631350b 100644 --- a/bacnet-stack/ringbuf.h +++ b/bacnet-stack/ringbuf.h @@ -42,34 +42,30 @@ #include #include -struct ring_buffer_t -{ - char *data; // block of memory or array of data - unsigned element_size; // how many bytes for each chunk - unsigned element_count; // number of chunks of data - unsigned head; // first chunk of data - unsigned count; // number of chunks in use +struct ring_buffer_t { + char *data; // block of memory or array of data + unsigned element_size; // how many bytes for each chunk + unsigned element_count; // number of chunks of data + unsigned head; // first chunk of data + unsigned count; // number of chunks in use }; typedef struct ring_buffer_t RING_BUFFER; #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ -bool Ringbuf_Empty(RING_BUFFER const *b); -char *Ringbuf_Get_Front(RING_BUFFER const *b); -char *Ringbuf_Pop_Front(RING_BUFFER *b); -bool Ringbuf_Put( - RING_BUFFER *b, // ring buffer structure - char *data_element); // one element to add to the ring -void Ringbuf_Init( - RING_BUFFER *b, // ring buffer structure - char *data, // data block or array of data - unsigned element_size, // size of one element in the data block - unsigned element_count); // number of elements in the data block + bool Ringbuf_Empty(RING_BUFFER const *b); + char *Ringbuf_Get_Front(RING_BUFFER const *b); + char *Ringbuf_Pop_Front(RING_BUFFER * b); + bool Ringbuf_Put(RING_BUFFER * b, // ring buffer structure + char *data_element); // one element to add to the ring + void Ringbuf_Init(RING_BUFFER * b, // ring buffer structure + char *data, // data block or array of data + unsigned element_size, // size of one element in the data block + unsigned element_count); // number of elements in the data block #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif diff --git a/bacnet-stack/rp.c b/bacnet-stack/rp.c index e611a483..1c98d8ea 100644 --- a/bacnet-stack/rp.c +++ b/bacnet-stack/rp.c @@ -38,240 +38,203 @@ #include "rp.h" // encode service -int rp_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - BACNET_READ_PROPERTY_DATA *data) +int rp_encode_apdu(uint8_t * apdu, + uint8_t invoke_id, BACNET_READ_PROPERTY_DATA * data) { - int len = 0; // length of each encoding - int apdu_len = 0; // total length of the apdu, return value + int len = 0; // length of each encoding + int apdu_len = 0; // total length of the apdu, return value - if (apdu) - { - apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST; - apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU); - apdu[2] = invoke_id; - apdu[3] = SERVICE_CONFIRMED_READ_PROPERTY; // service choice - apdu_len = 4; - len = encode_context_object_id(&apdu[apdu_len], 0, - data->object_type, data->object_instance); - apdu_len += len; - len = encode_context_enumerated(&apdu[apdu_len], 1, - data->object_property); - apdu_len += len; - /* optional array index */ - if (data->array_index != BACNET_ARRAY_ALL) - { - len = encode_context_unsigned(&apdu[apdu_len], 2, - data->array_index); - apdu_len += len; + if (apdu) { + apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST; + apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU); + apdu[2] = invoke_id; + apdu[3] = SERVICE_CONFIRMED_READ_PROPERTY; // service choice + apdu_len = 4; + len = encode_context_object_id(&apdu[apdu_len], 0, + data->object_type, data->object_instance); + apdu_len += len; + len = encode_context_enumerated(&apdu[apdu_len], 1, + data->object_property); + apdu_len += len; + /* optional array index */ + if (data->array_index != BACNET_ARRAY_ALL) { + len = encode_context_unsigned(&apdu[apdu_len], 2, + data->array_index); + apdu_len += len; + } } - } - - return apdu_len; + + return apdu_len; } // decode the service request only -int rp_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - BACNET_READ_PROPERTY_DATA *data) +int rp_decode_service_request(uint8_t * apdu, + unsigned apdu_len, BACNET_READ_PROPERTY_DATA * data) { - unsigned len = 0; - uint8_t tag_number = 0; - uint32_t len_value_type = 0; - int type = 0; // for decoding - int property = 0; // for decoding - uint32_t array_value = 0; // for decoding + unsigned len = 0; + uint8_t tag_number = 0; + uint32_t len_value_type = 0; + int type = 0; // for decoding + int property = 0; // for decoding + uint32_t array_value = 0; // for decoding - // check for value pointers - if (apdu_len && data) - { - // Tag 0: Object ID - if (!decode_is_context_tag(&apdu[len++], 0)) - return -1; - len += decode_object_id(&apdu[len], &type, &data->object_instance); - data->object_type = type; + // check for value pointers + if (apdu_len && data) { + // Tag 0: Object ID + if (!decode_is_context_tag(&apdu[len++], 0)) + return -1; + len += decode_object_id(&apdu[len], &type, &data->object_instance); + data->object_type = type; + // Tag 1: Property ID + len += decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + if (tag_number != 1) + return -1; + len += decode_enumerated(&apdu[len], len_value_type, &property); + data->object_property = property; + // Tag 2: Optional Array Index + if (len < apdu_len) { + len += decode_tag_number_and_value(&apdu[len], &tag_number, + &len_value_type); + if (tag_number == 2) { + len += decode_unsigned(&apdu[len], len_value_type, + &array_value); + data->array_index = array_value; + } else + data->array_index = BACNET_ARRAY_ALL; + } else + data->array_index = BACNET_ARRAY_ALL; + } + + return (int) len; +} + +int rp_decode_apdu(uint8_t * apdu, + unsigned apdu_len, + uint8_t * invoke_id, BACNET_READ_PROPERTY_DATA * data) +{ + int len = 0; + unsigned offset = 0; + + if (!apdu) + return -1; + // optional checking - most likely was already done prior to this call + if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) + return -1; + // apdu[1] = encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); + *invoke_id = apdu[2]; /* invoke id - filled in by net layer */ + if (apdu[3] != SERVICE_CONFIRMED_READ_PROPERTY) + return -1; + offset = 4; + + if (apdu_len > offset) { + len = rp_decode_service_request(&apdu[offset], + apdu_len - offset, data); + } + + return len; +} + +int rp_ack_encode_apdu(uint8_t * apdu, + uint8_t invoke_id, BACNET_READ_PROPERTY_DATA * data) +{ + int len = 0; // length of each encoding + int apdu_len = 0; // total length of the apdu, return value + + if (apdu) { + apdu[0] = PDU_TYPE_COMPLEX_ACK; /* complex ACK service */ + apdu[1] = invoke_id; /* original invoke id from request */ + apdu[2] = SERVICE_CONFIRMED_READ_PROPERTY; // service choice + apdu_len = 3; + // service ack follows + apdu_len += encode_context_object_id(&apdu[apdu_len], 0, + data->object_type, data->object_instance); + apdu_len += encode_context_enumerated(&apdu[apdu_len], 1, + data->object_property); + // context 2 array index is optional + if (data->array_index != BACNET_ARRAY_ALL) { + apdu_len += encode_context_unsigned(&apdu[apdu_len], 2, + data->array_index); + } + // propertyValue + apdu_len += encode_opening_tag(&apdu[apdu_len], 3); + for (len = 0; len < data->application_data_len; len++) { + apdu[apdu_len++] = data->application_data[len]; + } + apdu_len += encode_closing_tag(&apdu[apdu_len], 3); + } + + return apdu_len; +} + +int rp_ack_decode_service_request(uint8_t * apdu, int apdu_len, // total length of the apdu + BACNET_READ_PROPERTY_DATA * data) +{ + uint8_t tag_number = 0; + uint32_t len_value_type = 0; + int tag_len = 0; // length of tag decode + int len = 0; // total length of decodes + int object = 0, property = 0; // for decoding + uint32_t array_value = 0; // for decoding + + // FIXME: check apdu_len against the len during decode + // Tag 0: Object ID + if (!decode_is_context_tag(&apdu[0], 0)) + return -1; + len = 1; + len += decode_object_id(&apdu[len], &object, &data->object_instance); + data->object_type = object; // Tag 1: Property ID len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value_type); if (tag_number != 1) - return -1; + return -1; len += decode_enumerated(&apdu[len], len_value_type, &property); data->object_property = property; // Tag 2: Optional Array Index - if (len < apdu_len) - { - len += decode_tag_number_and_value(&apdu[len],&tag_number, - &len_value_type); - if (tag_number == 2) - { - len += decode_unsigned(&apdu[len], len_value_type, - &array_value); - data->array_index = array_value; - } - else - data->array_index = BACNET_ARRAY_ALL; - } - else - data->array_index = BACNET_ARRAY_ALL; - } - - return (int)len; -} - -int rp_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - BACNET_READ_PROPERTY_DATA *data) -{ - int len = 0; - unsigned offset = 0; - - if (!apdu) - return -1; - // optional checking - most likely was already done prior to this call - if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) - return -1; - // apdu[1] = encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); - *invoke_id = apdu[2]; /* invoke id - filled in by net layer */ - if (apdu[3] != SERVICE_CONFIRMED_READ_PROPERTY) - return -1; - offset = 4; - - if (apdu_len > offset) - { - len = rp_decode_service_request( - &apdu[offset], - apdu_len - offset, - data); - } - - return len; -} - -int rp_ack_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - BACNET_READ_PROPERTY_DATA *data) -{ - int len = 0; // length of each encoding - int apdu_len = 0; // total length of the apdu, return value - - if (apdu) - { - apdu[0] = PDU_TYPE_COMPLEX_ACK; /* complex ACK service */ - apdu[1] = invoke_id; /* original invoke id from request */ - apdu[2] = SERVICE_CONFIRMED_READ_PROPERTY; // service choice - apdu_len = 3; - // service ack follows - apdu_len += encode_context_object_id(&apdu[apdu_len], 0, - data->object_type, data->object_instance); - apdu_len += encode_context_enumerated(&apdu[apdu_len], 1, - data->object_property); - // context 2 array index is optional - if (data->array_index != BACNET_ARRAY_ALL) - { - apdu_len += encode_context_unsigned(&apdu[apdu_len], 2, - data->array_index); - } - // propertyValue - apdu_len += encode_opening_tag(&apdu[apdu_len], 3); - for (len = 0; len < data->application_data_len; len++) - { - apdu[apdu_len++] = data->application_data[len]; - } - apdu_len += encode_closing_tag(&apdu[apdu_len], 3); - } - - return apdu_len; -} - -int rp_ack_decode_service_request( - uint8_t *apdu, - int apdu_len, // total length of the apdu - BACNET_READ_PROPERTY_DATA *data) -{ - uint8_t tag_number = 0; - uint32_t len_value_type = 0; - int tag_len = 0; // length of tag decode - int len = 0; // total length of decodes - int object = 0, property = 0; // for decoding - uint32_t array_value = 0; // for decoding - - // FIXME: check apdu_len against the len during decode - // Tag 0: Object ID - if (!decode_is_context_tag(&apdu[0], 0)) - return -1; - len = 1; - len += decode_object_id(&apdu[len], - &object, &data->object_instance); - data->object_type = object; - // Tag 1: Property ID - len += decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - if (tag_number != 1) - return -1; - len += decode_enumerated(&apdu[len], - len_value_type, - &property); - data->object_property = property; - // Tag 2: Optional Array Index - tag_len = decode_tag_number_and_value(&apdu[len], + tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, &len_value_type); - if (tag_number == 2) - { - len += tag_len; - len += decode_unsigned(&apdu[len], - len_value_type, &array_value); - data->array_index = array_value; - } - else - data->array_index = BACNET_ARRAY_ALL; - - // Tag 3: opening context tag */ - if (decode_is_opening_tag_number(&apdu[len], 3)) - { - // a tag number of 3 is not extended so only one octet - len++; - // don't decode the application tag number or its data here - data->application_data = &apdu[len]; - data->application_data_len = apdu_len - len - 1 /*closing tag*/; - } - else - return -1; - - return len; + if (tag_number == 2) { + len += tag_len; + len += decode_unsigned(&apdu[len], len_value_type, &array_value); + data->array_index = array_value; + } else + data->array_index = BACNET_ARRAY_ALL; + + // Tag 3: opening context tag */ + if (decode_is_opening_tag_number(&apdu[len], 3)) { + // a tag number of 3 is not extended so only one octet + len++; + // don't decode the application tag number or its data here + data->application_data = &apdu[len]; + data->application_data_len = apdu_len - len - 1 /*closing tag */ ; + } else + return -1; + + return len; } -int rp_ack_decode_apdu( - uint8_t *apdu, - int apdu_len, // total length of the apdu - uint8_t *invoke_id, - BACNET_READ_PROPERTY_DATA *data) +int rp_ack_decode_apdu(uint8_t * apdu, int apdu_len, // total length of the apdu + uint8_t * invoke_id, BACNET_READ_PROPERTY_DATA * data) { - int len = 0; - int offset = 0; + int len = 0; + int offset = 0; - if (!apdu) - return -1; - // optional checking - most likely was already done prior to this call - if (apdu[0] != PDU_TYPE_COMPLEX_ACK) - return -1; - *invoke_id = apdu[1]; - if (apdu[2] != SERVICE_CONFIRMED_READ_PROPERTY) - return -1; - offset = 3; - if (apdu_len > offset) - { - len = rp_ack_decode_service_request( - &apdu[offset], - apdu_len - offset, - data); - } - - return len; + if (!apdu) + return -1; + // optional checking - most likely was already done prior to this call + if (apdu[0] != PDU_TYPE_COMPLEX_ACK) + return -1; + *invoke_id = apdu[1]; + if (apdu[2] != SERVICE_CONFIRMED_READ_PROPERTY) + return -1; + offset = 3; + if (apdu_len > offset) { + len = rp_ack_decode_service_request(&apdu[offset], + apdu_len - offset, data); + } + + return len; } #ifdef TEST @@ -281,93 +244,78 @@ int rp_ack_decode_apdu( void testReadPropertyAck(Test * pTest) { - uint8_t apdu[480] = {0}; - uint8_t apdu2[480] = {0}; - int len = 0; - int apdu_len = 0; - uint8_t invoke_id = 1; - uint8_t test_invoke_id = 0; - BACNET_READ_PROPERTY_DATA data; - BACNET_READ_PROPERTY_DATA test_data; - BACNET_OBJECT_TYPE object_type = OBJECT_DEVICE; - uint32_t object_instance = 0; - int object = 0; + uint8_t apdu[480] = { 0 }; + uint8_t apdu2[480] = { 0 }; + int len = 0; + int apdu_len = 0; + uint8_t invoke_id = 1; + uint8_t test_invoke_id = 0; + BACNET_READ_PROPERTY_DATA data; + BACNET_READ_PROPERTY_DATA test_data; + BACNET_OBJECT_TYPE object_type = OBJECT_DEVICE; + uint32_t object_instance = 0; + int object = 0; - data.object_type = OBJECT_DEVICE; - data.object_instance = 1; - data.object_property = PROP_OBJECT_IDENTIFIER; - data.array_index = BACNET_ARRAY_ALL; + data.object_type = OBJECT_DEVICE; + data.object_instance = 1; + data.object_property = PROP_OBJECT_IDENTIFIER; + data.array_index = BACNET_ARRAY_ALL; - data.application_data_len = encode_bacnet_object_id(&apdu2[0], - data.object_type, - data.object_instance); - data.application_data = &apdu2[0]; - - len = rp_ack_encode_apdu( - &apdu[0], - invoke_id, - &data); - ct_test(pTest, len != 0); - ct_test(pTest, len != -1); - apdu_len = len; - len = rp_ack_decode_apdu( - &apdu[0], - apdu_len, // total length of the apdu - &test_invoke_id, - &test_data); - ct_test(pTest, len != -1); - ct_test(pTest, test_invoke_id == invoke_id); + data.application_data_len = encode_bacnet_object_id(&apdu2[0], + data.object_type, data.object_instance); + data.application_data = &apdu2[0]; - ct_test(pTest, test_data.object_type == data.object_type); - ct_test(pTest, test_data.object_instance == data.object_instance); - ct_test(pTest, test_data.object_property == data.object_property); - ct_test(pTest, test_data.array_index == data.array_index); - ct_test(pTest, test_data.application_data_len == data.application_data_len); + len = rp_ack_encode_apdu(&apdu[0], invoke_id, &data); + ct_test(pTest, len != 0); + ct_test(pTest, len != -1); + apdu_len = len; + len = rp_ack_decode_apdu(&apdu[0], apdu_len, // total length of the apdu + &test_invoke_id, &test_data); + ct_test(pTest, len != -1); + ct_test(pTest, test_invoke_id == invoke_id); - /* since object property == object_id, decode the application data using - the appropriate decode function */ - len = decode_object_id( - test_data.application_data, - &object, - &object_instance); - object_type = object; - ct_test(pTest, object_type == data.object_type); - ct_test(pTest, object_instance == data.object_instance); + ct_test(pTest, test_data.object_type == data.object_type); + ct_test(pTest, test_data.object_instance == data.object_instance); + ct_test(pTest, test_data.object_property == data.object_property); + ct_test(pTest, test_data.array_index == data.array_index); + ct_test(pTest, + test_data.application_data_len == data.application_data_len); + + /* since object property == object_id, decode the application data using + the appropriate decode function */ + len = decode_object_id(test_data.application_data, + &object, &object_instance); + object_type = object; + ct_test(pTest, object_type == data.object_type); + ct_test(pTest, object_instance == data.object_instance); } void testReadProperty(Test * pTest) { - uint8_t apdu[480] = {0}; - int len = 0; - int apdu_len = 0; - uint8_t invoke_id = 128; - uint8_t test_invoke_id = 0; - BACNET_READ_PROPERTY_DATA data; - BACNET_READ_PROPERTY_DATA test_data; - - data.object_type = OBJECT_DEVICE; - data.object_instance = 1; - data.object_property = PROP_OBJECT_IDENTIFIER; - data.array_index = BACNET_ARRAY_ALL; - len = rp_encode_apdu( - &apdu[0], - invoke_id, - &data); - ct_test(pTest, len != 0); - apdu_len = len; + uint8_t apdu[480] = { 0 }; + int len = 0; + int apdu_len = 0; + uint8_t invoke_id = 128; + uint8_t test_invoke_id = 0; + BACNET_READ_PROPERTY_DATA data; + BACNET_READ_PROPERTY_DATA test_data; - len = rp_decode_apdu( - &apdu[0], - apdu_len, - &test_invoke_id, - &test_data); - ct_test(pTest, len != -1); - ct_test(pTest, test_data.object_type == data.object_type); - ct_test(pTest, test_data.object_instance == data.object_instance); - ct_test(pTest, test_data.object_property == data.object_property); - ct_test(pTest, test_data.array_index == data.array_index); + data.object_type = OBJECT_DEVICE; + data.object_instance = 1; + data.object_property = PROP_OBJECT_IDENTIFIER; + data.array_index = BACNET_ARRAY_ALL; + len = rp_encode_apdu(&apdu[0], invoke_id, &data); + ct_test(pTest, len != 0); + apdu_len = len; - return; + len = rp_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, &test_data); + ct_test(pTest, len != -1); + ct_test(pTest, test_data.object_type == data.object_type); + ct_test(pTest, test_data.object_instance == data.object_instance); + ct_test(pTest, test_data.object_property == data.object_property); + ct_test(pTest, test_data.array_index == data.array_index); + + return; } #ifdef TEST_READ_PROPERTY diff --git a/bacnet-stack/rp.h b/bacnet-stack/rp.h index a52f9aa2..77cfa4d2 100644 --- a/bacnet-stack/rp.h +++ b/bacnet-stack/rp.h @@ -37,65 +37,49 @@ #include #include -typedef struct BACnet_Read_Property_Data -{ - BACNET_OBJECT_TYPE object_type; - uint32_t object_instance; - BACNET_PROPERTY_ID object_property; - int32_t array_index; - uint8_t *application_data; - int application_data_len; +typedef struct BACnet_Read_Property_Data { + BACNET_OBJECT_TYPE object_type; + uint32_t object_instance; + BACNET_PROPERTY_ID object_property; + int32_t array_index; + uint8_t *application_data; + int application_data_len; } BACNET_READ_PROPERTY_DATA; #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ // encode service -int rp_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - BACNET_READ_PROPERTY_DATA *data); + int rp_encode_apdu(uint8_t * apdu, + uint8_t invoke_id, BACNET_READ_PROPERTY_DATA * data); // decode the service request only -int rp_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - BACNET_READ_PROPERTY_DATA *data); - -int rp_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - BACNET_READ_PROPERTY_DATA *data); + int rp_decode_service_request(uint8_t * apdu, + unsigned apdu_len, BACNET_READ_PROPERTY_DATA * data); -int rp_ack_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - BACNET_READ_PROPERTY_DATA *data); + int rp_decode_apdu(uint8_t * apdu, + unsigned apdu_len, + uint8_t * invoke_id, BACNET_READ_PROPERTY_DATA * data); -int rp_ack_decode_service_request( - uint8_t *apdu, - int apdu_len, // total length of the apdu - BACNET_READ_PROPERTY_DATA *data); + int rp_ack_encode_apdu(uint8_t * apdu, + uint8_t invoke_id, BACNET_READ_PROPERTY_DATA * data); + + int rp_ack_decode_service_request(uint8_t * apdu, int apdu_len, // total length of the apdu + BACNET_READ_PROPERTY_DATA * data); + + int rp_ack_decode_apdu(uint8_t * apdu, int apdu_len, // total length of the apdu + uint8_t * invoke_id, BACNET_READ_PROPERTY_DATA * data); -int rp_ack_decode_apdu( - uint8_t *apdu, - int apdu_len, // total length of the apdu - uint8_t *invoke_id, - BACNET_READ_PROPERTY_DATA *data); - #ifdef TEST #include "ctest.h" -void test_ReadProperty(Test * pTest); -void test_ReadPropertyAck(Test * pTest); + void test_ReadProperty(Test * pTest); + void test_ReadPropertyAck(Test * pTest); #endif #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif - diff --git a/bacnet-stack/rpm.c b/bacnet-stack/rpm.c index f661f32d..502187fa 100644 --- a/bacnet-stack/rpm.c +++ b/bacnet-stack/rpm.c @@ -40,419 +40,358 @@ #include "rpm.h" /* encode the initial portion of the service */ -int rpm_encode_apdu_init( - uint8_t *apdu, - uint8_t invoke_id) +int rpm_encode_apdu_init(uint8_t * apdu, uint8_t invoke_id) { - int apdu_len = 0; /* total length of the apdu, return value */ + int apdu_len = 0; /* total length of the apdu, return value */ - if (apdu) - { - apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST; - apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU); - apdu[2] = invoke_id; - apdu[3] = SERVICE_CONFIRMED_READ_PROPERTY_MULTIPLE; /* service choice */ - apdu_len = 4; - } + if (apdu) { + apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST; + apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU); + apdu[2] = invoke_id; + apdu[3] = SERVICE_CONFIRMED_READ_PROPERTY_MULTIPLE; /* service choice */ + apdu_len = 4; + } - return apdu_len; + return apdu_len; } -int rpm_encode_apdu_object_begin( - uint8_t *apdu, - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance) +int rpm_encode_apdu_object_begin(uint8_t * apdu, + BACNET_OBJECT_TYPE object_type, uint32_t object_instance) { - int apdu_len = 0; /* total length of the apdu, return value */ - - if (apdu) - { - apdu_len = encode_context_object_id(&apdu[0], 0, - object_type, object_instance); - /* Tag 1: sequence of ReadAccessSpecification */ - apdu_len += encode_opening_tag(&apdu[apdu_len], 1); - } + int apdu_len = 0; /* total length of the apdu, return value */ - return apdu_len; + if (apdu) { + apdu_len = encode_context_object_id(&apdu[0], 0, + object_type, object_instance); + /* Tag 1: sequence of ReadAccessSpecification */ + apdu_len += encode_opening_tag(&apdu[apdu_len], 1); + } + + return apdu_len; } -int rpm_encode_apdu_object_property( - uint8_t *apdu, - BACNET_PROPERTY_ID object_property, - int32_t array_index) +int rpm_encode_apdu_object_property(uint8_t * apdu, + BACNET_PROPERTY_ID object_property, int32_t array_index) { - int apdu_len = 0; /* total length of the apdu, return value */ - - if (apdu) - { - apdu_len = encode_context_enumerated(&apdu[0], 0, - object_property); - /* optional array index */ - if (array_index != BACNET_ARRAY_ALL) - apdu_len += encode_context_unsigned(&apdu[apdu_len], 1, - array_index); - } + int apdu_len = 0; /* total length of the apdu, return value */ - return apdu_len; + if (apdu) { + apdu_len = encode_context_enumerated(&apdu[0], 0, object_property); + /* optional array index */ + if (array_index != BACNET_ARRAY_ALL) + apdu_len += encode_context_unsigned(&apdu[apdu_len], 1, + array_index); + } + + return apdu_len; } -int rpm_encode_apdu_object_end( - uint8_t *apdu) +int rpm_encode_apdu_object_end(uint8_t * apdu) { - int apdu_len = 0; /* total length of the apdu, return value */ - - if (apdu) - { - apdu_len = encode_closing_tag(&apdu[0], 1); - } + int apdu_len = 0; /* total length of the apdu, return value */ - return apdu_len; + if (apdu) { + apdu_len = encode_closing_tag(&apdu[0], 1); + } + + return apdu_len; } /* decode the object portion of the service request only */ -int rpm_decode_object_id( - uint8_t *apdu, - unsigned apdu_len, - BACNET_OBJECT_TYPE *object_type, - uint32_t *object_instance) +int rpm_decode_object_id(uint8_t * apdu, + unsigned apdu_len, + BACNET_OBJECT_TYPE * object_type, uint32_t * object_instance) { - unsigned len = 0; - int type = 0; /* for decoding */ + unsigned len = 0; + int type = 0; /* for decoding */ - /* check for value pointers */ - if (apdu && apdu_len && object_type && object_instance) - { - /* Tag 0: Object ID */ - if (!decode_is_context_tag(&apdu[len++], 0)) - return -1; - len += decode_object_id(&apdu[len], &type, object_instance); - if (object_type) - *object_type = type; - /* Tag 1: sequence of ReadAccessSpecification */ - if (!decode_is_opening_tag_number(&apdu[len], 1)) - return -1; - len++; /* opening tag is only one octet */ - } - - return (int)len; + /* check for value pointers */ + if (apdu && apdu_len && object_type && object_instance) { + /* Tag 0: Object ID */ + if (!decode_is_context_tag(&apdu[len++], 0)) + return -1; + len += decode_object_id(&apdu[len], &type, object_instance); + if (object_type) + *object_type = type; + /* Tag 1: sequence of ReadAccessSpecification */ + if (!decode_is_opening_tag_number(&apdu[len], 1)) + return -1; + len++; /* opening tag is only one octet */ + } + + return (int) len; } -int rpm_decode_object_end( - uint8_t *apdu, - unsigned apdu_len) +int rpm_decode_object_end(uint8_t * apdu, unsigned apdu_len) { - int len = 0; /* total length of the apdu, return value */ - - if (apdu && apdu_len) - { - if (decode_is_closing_tag_number(apdu,1)) - len = 1; - } + int len = 0; /* total length of the apdu, return value */ - return len; + if (apdu && apdu_len) { + if (decode_is_closing_tag_number(apdu, 1)) + len = 1; + } + + return len; } /* decode the object property portion of the service request only */ -int rpm_decode_object_property( - uint8_t *apdu, - unsigned apdu_len, - BACNET_PROPERTY_ID *object_property, - int32_t *array_index) +int rpm_decode_object_property(uint8_t * apdu, + unsigned apdu_len, + BACNET_PROPERTY_ID * object_property, int32_t * array_index) { - unsigned len = 0; - unsigned option_len = 0; - uint8_t tag_number = 0; - uint32_t len_value_type = 0; - int property = 0; /* for decoding */ - uint32_t array_value = 0; /* for decoding */ + unsigned len = 0; + unsigned option_len = 0; + uint8_t tag_number = 0; + uint32_t len_value_type = 0; + int property = 0; /* for decoding */ + uint32_t array_value = 0; /* for decoding */ - /* check for valid pointers */ - if (apdu && apdu_len && object_property && array_index) - { - /* Tag 0: propertyIdentifier */ - len += decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - if (tag_number != 0) - return -1; - len += decode_enumerated(&apdu[len], len_value_type, &property); - if (object_property) - *object_property = property; - /* Tag 1: Optional propertyArrayIndex */ - if (len < apdu_len) - { - option_len = decode_tag_number_and_value(&apdu[len],&tag_number, - &len_value_type); - if (tag_number == 2) - { - len += option_len; - len += decode_unsigned(&apdu[len], len_value_type, - &array_value); - *array_index = array_value; - } - else - *array_index = BACNET_ARRAY_ALL; + /* check for valid pointers */ + if (apdu && apdu_len && object_property && array_index) { + /* Tag 0: propertyIdentifier */ + len += decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + if (tag_number != 0) + return -1; + len += decode_enumerated(&apdu[len], len_value_type, &property); + if (object_property) + *object_property = property; + /* Tag 1: Optional propertyArrayIndex */ + if (len < apdu_len) { + option_len = + decode_tag_number_and_value(&apdu[len], &tag_number, + &len_value_type); + if (tag_number == 2) { + len += option_len; + len += decode_unsigned(&apdu[len], len_value_type, + &array_value); + *array_index = array_value; + } else + *array_index = BACNET_ARRAY_ALL; + } else + *array_index = BACNET_ARRAY_ALL; } - else - *array_index = BACNET_ARRAY_ALL; - } - return (int)len; + return (int) len; } -int rpm_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - uint8_t **service_request, - unsigned *service_request_len) +int rpm_decode_apdu(uint8_t * apdu, + unsigned apdu_len, + uint8_t * invoke_id, + uint8_t ** service_request, unsigned *service_request_len) { - unsigned offset = 0; + unsigned offset = 0; - if (!apdu) - return -1; - /* optional checking - most likely was already done prior to this call */ - if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) - return -1; - /* apdu[1] = encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); */ - *invoke_id = apdu[2]; /* invoke id - filled in by net layer */ - if (apdu[3] != SERVICE_CONFIRMED_READ_PROPERTY_MULTIPLE) - return -1; - offset = 4; + if (!apdu) + return -1; + /* optional checking - most likely was already done prior to this call */ + if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) + return -1; + /* apdu[1] = encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); */ + *invoke_id = apdu[2]; /* invoke id - filled in by net layer */ + if (apdu[3] != SERVICE_CONFIRMED_READ_PROPERTY_MULTIPLE) + return -1; + offset = 4; - if (apdu_len > offset) - { - if (service_request) - *service_request = &apdu[offset]; - if (service_request_len) - *service_request_len = apdu_len - offset; - } - - return offset; -} - -int rpm_ack_encode_apdu_init( - uint8_t *apdu, - uint8_t invoke_id) -{ - int apdu_len = 0; /* total length of the apdu, return value */ - - if (apdu) - { - apdu[0] = PDU_TYPE_COMPLEX_ACK; /* complex ACK service */ - apdu[1] = invoke_id; /* original invoke id from request */ - apdu[2] = SERVICE_CONFIRMED_READ_PROPERTY_MULTIPLE; /* service choice */ - apdu_len = 3; - } - - return apdu_len; -} - -int rpm_ack_encode_apdu_object_begin( - uint8_t *apdu, - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance) -{ - int apdu_len = 0; /* total length of the apdu, return value */ - - if (apdu) - { - /* Tag 0: objectIdentifier */ - apdu_len = encode_context_object_id(&apdu[0], 0, - object_type, object_instance); - /* Tag 1: listOfResults */ - apdu_len += encode_opening_tag(&apdu[apdu_len], 1); - } - - return apdu_len; -} - -int rpm_ack_encode_apdu_object_property( - uint8_t *apdu, - BACNET_PROPERTY_ID object_property, - int32_t array_index) -{ - int apdu_len = 0; /* total length of the apdu, return value */ - - if (apdu) - { - /* Tag 2: propertyIdentifier */ - apdu_len = encode_context_enumerated(&apdu[0], 2, - object_property); - /* Tag 3: optional propertyArrayIndex */ - if (array_index != BACNET_ARRAY_ALL) - apdu_len += encode_context_unsigned(&apdu[apdu_len], 3, - array_index); - } - - return apdu_len; -} - -int rpm_ack_encode_apdu_object_property_value( - uint8_t *apdu, - uint8_t *application_data, - unsigned application_data_len) -{ - int apdu_len = 0; /* total length of the apdu, return value */ - unsigned len = 0; - - if (apdu) - { - /* Tag 4: propertyValue */ - apdu_len += encode_opening_tag(&apdu[apdu_len], 4); - for (len = 0; len < application_data_len; len++) - { - apdu[apdu_len++] = application_data[len]; + if (apdu_len > offset) { + if (service_request) + *service_request = &apdu[offset]; + if (service_request_len) + *service_request_len = apdu_len - offset; } - apdu_len += encode_closing_tag(&apdu[apdu_len], 4); - } - return apdu_len; + return offset; } -int rpm_ack_encode_apdu_object_property_error( - uint8_t *apdu, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code) +int rpm_ack_encode_apdu_init(uint8_t * apdu, uint8_t invoke_id) { - int apdu_len = 0; /* total length of the apdu, return value */ - - if (apdu) - { - /* Tag 5: propertyAccessError */ - apdu_len += encode_opening_tag(&apdu[apdu_len], 5); - apdu_len += encode_tagged_enumerated(&apdu[apdu_len], error_class); - apdu_len += encode_tagged_enumerated(&apdu[apdu_len], error_code); - apdu_len += encode_closing_tag(&apdu[apdu_len], 5); - } + int apdu_len = 0; /* total length of the apdu, return value */ - return apdu_len; + if (apdu) { + apdu[0] = PDU_TYPE_COMPLEX_ACK; /* complex ACK service */ + apdu[1] = invoke_id; /* original invoke id from request */ + apdu[2] = SERVICE_CONFIRMED_READ_PROPERTY_MULTIPLE; /* service choice */ + apdu_len = 3; + } + + return apdu_len; } -int rpm_ack_encode_apdu_object_end( - uint8_t *apdu) +int rpm_ack_encode_apdu_object_begin(uint8_t * apdu, + BACNET_OBJECT_TYPE object_type, uint32_t object_instance) { - int apdu_len = 0; /* total length of the apdu, return value */ - - if (apdu) - { - apdu_len = encode_closing_tag(&apdu[0], 1); - } + int apdu_len = 0; /* total length of the apdu, return value */ - return apdu_len; + if (apdu) { + /* Tag 0: objectIdentifier */ + apdu_len = encode_context_object_id(&apdu[0], 0, + object_type, object_instance); + /* Tag 1: listOfResults */ + apdu_len += encode_opening_tag(&apdu[apdu_len], 1); + } + + return apdu_len; +} + +int rpm_ack_encode_apdu_object_property(uint8_t * apdu, + BACNET_PROPERTY_ID object_property, int32_t array_index) +{ + int apdu_len = 0; /* total length of the apdu, return value */ + + if (apdu) { + /* Tag 2: propertyIdentifier */ + apdu_len = encode_context_enumerated(&apdu[0], 2, object_property); + /* Tag 3: optional propertyArrayIndex */ + if (array_index != BACNET_ARRAY_ALL) + apdu_len += encode_context_unsigned(&apdu[apdu_len], 3, + array_index); + } + + return apdu_len; +} + +int rpm_ack_encode_apdu_object_property_value(uint8_t * apdu, + uint8_t * application_data, unsigned application_data_len) +{ + int apdu_len = 0; /* total length of the apdu, return value */ + unsigned len = 0; + + if (apdu) { + /* Tag 4: propertyValue */ + apdu_len += encode_opening_tag(&apdu[apdu_len], 4); + for (len = 0; len < application_data_len; len++) { + apdu[apdu_len++] = application_data[len]; + } + apdu_len += encode_closing_tag(&apdu[apdu_len], 4); + } + + return apdu_len; +} + +int rpm_ack_encode_apdu_object_property_error(uint8_t * apdu, + BACNET_ERROR_CLASS error_class, BACNET_ERROR_CODE error_code) +{ + int apdu_len = 0; /* total length of the apdu, return value */ + + if (apdu) { + /* Tag 5: propertyAccessError */ + apdu_len += encode_opening_tag(&apdu[apdu_len], 5); + apdu_len += encode_tagged_enumerated(&apdu[apdu_len], error_class); + apdu_len += encode_tagged_enumerated(&apdu[apdu_len], error_code); + apdu_len += encode_closing_tag(&apdu[apdu_len], 5); + } + + return apdu_len; +} + +int rpm_ack_encode_apdu_object_end(uint8_t * apdu) +{ + int apdu_len = 0; /* total length of the apdu, return value */ + + if (apdu) { + apdu_len = encode_closing_tag(&apdu[0], 1); + } + + return apdu_len; } /* decode the object portion of the service request only */ -int rpm_ack_decode_object_id( - uint8_t *apdu, - unsigned apdu_len, - BACNET_OBJECT_TYPE *object_type, - uint32_t *object_instance) +int rpm_ack_decode_object_id(uint8_t * apdu, + unsigned apdu_len, + BACNET_OBJECT_TYPE * object_type, uint32_t * object_instance) { - unsigned len = 0; - int type = 0; /* for decoding */ + unsigned len = 0; + int type = 0; /* for decoding */ - /* check for value pointers */ - if (apdu && apdu_len && object_type && object_instance) - { - /* Tag 0: objectIdentifier */ - if (!decode_is_context_tag(&apdu[len++], 0)) - return -1; - len += decode_object_id(&apdu[len], &type, object_instance); - if (object_type) - *object_type = type; - /* Tag 1: listOfResults */ - if (!decode_is_opening_tag_number(&apdu[len], 1)) - return -1; - len++; /* opening tag is only one octet */ - } + /* check for value pointers */ + if (apdu && apdu_len && object_type && object_instance) { + /* Tag 0: objectIdentifier */ + if (!decode_is_context_tag(&apdu[len++], 0)) + return -1; + len += decode_object_id(&apdu[len], &type, object_instance); + if (object_type) + *object_type = type; + /* Tag 1: listOfResults */ + if (!decode_is_opening_tag_number(&apdu[len], 1)) + return -1; + len++; /* opening tag is only one octet */ + } - return (int)len; + return (int) len; } /* is this the end of the list of this objects properties values? */ -int rpm_ack_decode_object_end( - uint8_t *apdu, - unsigned apdu_len) +int rpm_ack_decode_object_end(uint8_t * apdu, unsigned apdu_len) { - int len = 0; /* total length of the apdu, return value */ + int len = 0; /* total length of the apdu, return value */ - if (apdu && apdu_len) - { - if (decode_is_closing_tag_number(apdu,1)) - len = 1; - } - - return len; -} - -int rpm_ack_decode_object_property( - uint8_t *apdu, - unsigned apdu_len, - BACNET_PROPERTY_ID *object_property, - int32_t *array_index) -{ - unsigned len = 0; - unsigned tag_len = 0; - uint8_t tag_number = 0; - uint32_t len_value_type = 0; - int property = 0; /* for decoding */ - uint32_t array_value = 0; /* for decoding */ - - /* check for valid pointers */ - if (apdu && apdu_len && object_property && array_index) - { - /* Tag 2: propertyIdentifier */ - len += decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - if (tag_number != 2) - return -1; - len += decode_enumerated(&apdu[len], len_value_type, &property); - if (object_property) - *object_property = property; - /* Tag 3: Optional propertyArrayIndex */ - tag_len = decode_tag_number_and_value(&apdu[len],&tag_number, - &len_value_type); - if (tag_number == 3) - { - len += tag_len; - len += decode_unsigned(&apdu[len], len_value_type, - &array_value); - *array_index = array_value; + if (apdu && apdu_len) { + if (decode_is_closing_tag_number(apdu, 1)) + len = 1; } - else - *array_index = BACNET_ARRAY_ALL; - } - return (int)len; + return len; } -int rpm_ack_decode_apdu( - uint8_t *apdu, - int apdu_len, /* total length of the apdu */ - uint8_t *invoke_id, - uint8_t **service_request, - unsigned *service_request_len) +int rpm_ack_decode_object_property(uint8_t * apdu, + unsigned apdu_len, + BACNET_PROPERTY_ID * object_property, int32_t * array_index) { - int offset = 0; + unsigned len = 0; + unsigned tag_len = 0; + uint8_t tag_number = 0; + uint32_t len_value_type = 0; + int property = 0; /* for decoding */ + uint32_t array_value = 0; /* for decoding */ - if (!apdu) - return -1; - /* optional checking - most likely was already done prior to this call */ - if (apdu[0] != PDU_TYPE_COMPLEX_ACK) - return -1; - *invoke_id = apdu[1]; - if (apdu[2] != SERVICE_CONFIRMED_READ_PROPERTY_MULTIPLE) - return -1; - offset = 3; - if (apdu_len > offset) - { - if (service_request) - *service_request = &apdu[offset]; - if (service_request_len) - *service_request_len = apdu_len - offset; - } - - return offset; + /* check for valid pointers */ + if (apdu && apdu_len && object_property && array_index) { + /* Tag 2: propertyIdentifier */ + len += decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + if (tag_number != 2) + return -1; + len += decode_enumerated(&apdu[len], len_value_type, &property); + if (object_property) + *object_property = property; + /* Tag 3: Optional propertyArrayIndex */ + tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, + &len_value_type); + if (tag_number == 3) { + len += tag_len; + len += decode_unsigned(&apdu[len], len_value_type, + &array_value); + *array_index = array_value; + } else + *array_index = BACNET_ARRAY_ALL; + } + + return (int) len; +} + +int rpm_ack_decode_apdu(uint8_t * apdu, int apdu_len, /* total length of the apdu */ + uint8_t * invoke_id, + uint8_t ** service_request, unsigned *service_request_len) +{ + int offset = 0; + + if (!apdu) + return -1; + /* optional checking - most likely was already done prior to this call */ + if (apdu[0] != PDU_TYPE_COMPLEX_ACK) + return -1; + *invoke_id = apdu[1]; + if (apdu[2] != SERVICE_CONFIRMED_READ_PROPERTY_MULTIPLE) + return -1; + offset = 3; + if (apdu_len > offset) { + if (service_request) + *service_request = &apdu[offset]; + if (service_request_len) + *service_request_len = apdu_len - offset; + } + + return offset; } #ifdef TEST @@ -462,391 +401,322 @@ int rpm_ack_decode_apdu( void testReadPropertyMultiple(Test * pTest) { - uint8_t apdu[480] = {0}; - int len = 0; - int test_len = 0; - int apdu_len = 0; - uint8_t invoke_id = 12; - uint8_t test_invoke_id = 0; - uint8_t *service_request = NULL; - unsigned service_request_len = 0; - BACNET_OBJECT_TYPE object_type = OBJECT_DEVICE; - uint32_t object_instance = 0; - BACNET_PROPERTY_ID object_property = PROP_OBJECT_IDENTIFIER; - int32_t array_index = 0; + uint8_t apdu[480] = { 0 }; + int len = 0; + int test_len = 0; + int apdu_len = 0; + uint8_t invoke_id = 12; + uint8_t test_invoke_id = 0; + uint8_t *service_request = NULL; + unsigned service_request_len = 0; + BACNET_OBJECT_TYPE object_type = OBJECT_DEVICE; + uint32_t object_instance = 0; + BACNET_PROPERTY_ID object_property = PROP_OBJECT_IDENTIFIER; + int32_t array_index = 0; - /* build the RPM - try to make it easy for the Application Layer development */ - /* IDEA: similar construction, but pass apdu, apdu_len pointer, size of apdu to - let the called function handle the out of space problem that these get into - by returning a boolean of success/failure. - It almost needs to use the keylist library or something similar. - Also check case of storing a backoff point (i.e. save enough room for object_end) */ - apdu_len = rpm_encode_apdu_init(&apdu[0], invoke_id); - /* each object has a beginning and an end */ - apdu_len += rpm_encode_apdu_object_begin(&apdu[apdu_len], - OBJECT_DEVICE, 123); - /* then stuff as many properties into it as APDU length will allow */ - apdu_len += rpm_encode_apdu_object_property(&apdu[apdu_len], - PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL); - apdu_len += rpm_encode_apdu_object_property(&apdu[apdu_len], - PROP_OBJECT_NAME, BACNET_ARRAY_ALL); - apdu_len += rpm_encode_apdu_object_end(&apdu[apdu_len]); - /* each object has a beginning and an end */ - apdu_len += rpm_encode_apdu_object_begin(&apdu[apdu_len], - OBJECT_ANALOG_INPUT, 33); - apdu_len += rpm_encode_apdu_object_property(&apdu[apdu_len], - PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL); - apdu_len += rpm_encode_apdu_object_property(&apdu[apdu_len], - PROP_ALL, BACNET_ARRAY_ALL); - apdu_len += rpm_encode_apdu_object_end(&apdu[apdu_len]); + /* build the RPM - try to make it easy for the Application Layer development */ + /* IDEA: similar construction, but pass apdu, apdu_len pointer, size of apdu to + let the called function handle the out of space problem that these get into + by returning a boolean of success/failure. + It almost needs to use the keylist library or something similar. + Also check case of storing a backoff point (i.e. save enough room for object_end) */ + apdu_len = rpm_encode_apdu_init(&apdu[0], invoke_id); + /* each object has a beginning and an end */ + apdu_len += rpm_encode_apdu_object_begin(&apdu[apdu_len], + OBJECT_DEVICE, 123); + /* then stuff as many properties into it as APDU length will allow */ + apdu_len += rpm_encode_apdu_object_property(&apdu[apdu_len], + PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL); + apdu_len += rpm_encode_apdu_object_property(&apdu[apdu_len], + PROP_OBJECT_NAME, BACNET_ARRAY_ALL); + apdu_len += rpm_encode_apdu_object_end(&apdu[apdu_len]); + /* each object has a beginning and an end */ + apdu_len += rpm_encode_apdu_object_begin(&apdu[apdu_len], + OBJECT_ANALOG_INPUT, 33); + apdu_len += rpm_encode_apdu_object_property(&apdu[apdu_len], + PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL); + apdu_len += rpm_encode_apdu_object_property(&apdu[apdu_len], + PROP_ALL, BACNET_ARRAY_ALL); + apdu_len += rpm_encode_apdu_object_end(&apdu[apdu_len]); - ct_test(pTest, apdu_len != 0); - - test_len = rpm_decode_apdu( - &apdu[0], - apdu_len, - &test_invoke_id, - &service_request, /* will point to the service request in the apdu */ - &service_request_len); - ct_test(pTest, test_len != -1); - ct_test(pTest, test_invoke_id == invoke_id); - ct_test(pTest, service_request != NULL); - ct_test(pTest, service_request_len > 0); - - test_len = rpm_decode_object_id( - service_request, - service_request_len, - &object_type, - &object_instance); - ct_test(pTest, test_len != -1); - ct_test(pTest, object_type == OBJECT_DEVICE); - ct_test(pTest, object_instance == 123); - len = test_len; - /* decode the object property portion of the service request */ - test_len = rpm_decode_object_property( - &service_request[len], - service_request_len - len, - &object_property, - &array_index); - ct_test(pTest, test_len != -1); - ct_test(pTest, object_property == PROP_OBJECT_IDENTIFIER); - ct_test(pTest, array_index == BACNET_ARRAY_ALL); - len += test_len; - test_len = rpm_decode_object_property( - &service_request[len], - service_request_len - len, - &object_property, - &array_index); - ct_test(pTest, test_len != -1); - ct_test(pTest, object_property == PROP_OBJECT_NAME); - ct_test(pTest, array_index == BACNET_ARRAY_ALL); - len += test_len; - /* try again - we should fail */ - test_len = rpm_decode_object_property( - &service_request[len], - service_request_len - len, - &object_property, - &array_index); - ct_test(pTest, test_len == -1); - /* is it the end of this object? */ - test_len = rpm_decode_object_end( - &service_request[len], - service_request_len - len); - ct_test(pTest, test_len == 1); - len += test_len; - /* try to decode an object id */ - test_len = rpm_decode_object_id( - &service_request[len], - service_request_len - len, - &object_type, - &object_instance); - ct_test(pTest, test_len != -1); - ct_test(pTest, object_type == OBJECT_ANALOG_INPUT); - ct_test(pTest, object_instance == 33); - len += test_len; - /* decode the object property portion of the service request only */ - test_len = rpm_decode_object_property( - &service_request[len], - service_request_len - len, - &object_property, - &array_index); - ct_test(pTest, test_len != -1); - ct_test(pTest, object_property == PROP_OBJECT_IDENTIFIER); - ct_test(pTest, array_index == BACNET_ARRAY_ALL); - len += test_len; - test_len = rpm_decode_object_property( - &service_request[len], - service_request_len - len, - &object_property, - &array_index); - ct_test(pTest, test_len != -1); - ct_test(pTest, object_property == PROP_ALL); - ct_test(pTest, array_index == BACNET_ARRAY_ALL); - len += test_len; - test_len = rpm_decode_object_property( - &service_request[len], - service_request_len - len, - &object_property, - &array_index); - ct_test(pTest, test_len == -1); - /* got an error -1, is it the end of this object? */ - test_len = rpm_decode_object_end( - &service_request[len], - service_request_len - len); - ct_test(pTest, test_len == 1); - len += test_len; - ct_test(pTest, len == service_request_len); + ct_test(pTest, apdu_len != 0); + + test_len = rpm_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, &service_request, /* will point to the service request in the apdu */ + &service_request_len); + ct_test(pTest, test_len != -1); + ct_test(pTest, test_invoke_id == invoke_id); + ct_test(pTest, service_request != NULL); + ct_test(pTest, service_request_len > 0); + + test_len = rpm_decode_object_id(service_request, + service_request_len, &object_type, &object_instance); + ct_test(pTest, test_len != -1); + ct_test(pTest, object_type == OBJECT_DEVICE); + ct_test(pTest, object_instance == 123); + len = test_len; + /* decode the object property portion of the service request */ + test_len = rpm_decode_object_property(&service_request[len], + service_request_len - len, &object_property, &array_index); + ct_test(pTest, test_len != -1); + ct_test(pTest, object_property == PROP_OBJECT_IDENTIFIER); + ct_test(pTest, array_index == BACNET_ARRAY_ALL); + len += test_len; + test_len = rpm_decode_object_property(&service_request[len], + service_request_len - len, &object_property, &array_index); + ct_test(pTest, test_len != -1); + ct_test(pTest, object_property == PROP_OBJECT_NAME); + ct_test(pTest, array_index == BACNET_ARRAY_ALL); + len += test_len; + /* try again - we should fail */ + test_len = rpm_decode_object_property(&service_request[len], + service_request_len - len, &object_property, &array_index); + ct_test(pTest, test_len == -1); + /* is it the end of this object? */ + test_len = rpm_decode_object_end(&service_request[len], + service_request_len - len); + ct_test(pTest, test_len == 1); + len += test_len; + /* try to decode an object id */ + test_len = rpm_decode_object_id(&service_request[len], + service_request_len - len, &object_type, &object_instance); + ct_test(pTest, test_len != -1); + ct_test(pTest, object_type == OBJECT_ANALOG_INPUT); + ct_test(pTest, object_instance == 33); + len += test_len; + /* decode the object property portion of the service request only */ + test_len = rpm_decode_object_property(&service_request[len], + service_request_len - len, &object_property, &array_index); + ct_test(pTest, test_len != -1); + ct_test(pTest, object_property == PROP_OBJECT_IDENTIFIER); + ct_test(pTest, array_index == BACNET_ARRAY_ALL); + len += test_len; + test_len = rpm_decode_object_property(&service_request[len], + service_request_len - len, &object_property, &array_index); + ct_test(pTest, test_len != -1); + ct_test(pTest, object_property == PROP_ALL); + ct_test(pTest, array_index == BACNET_ARRAY_ALL); + len += test_len; + test_len = rpm_decode_object_property(&service_request[len], + service_request_len - len, &object_property, &array_index); + ct_test(pTest, test_len == -1); + /* got an error -1, is it the end of this object? */ + test_len = rpm_decode_object_end(&service_request[len], + service_request_len - len); + ct_test(pTest, test_len == 1); + len += test_len; + ct_test(pTest, len == service_request_len); } void testReadPropertyMultipleAck(Test * pTest) { - uint8_t apdu[480] = {0}; - int len = 0; - int test_len = 0; - int apdu_len = 0; - uint8_t invoke_id = 12; - uint8_t test_invoke_id = 0; - uint8_t *service_request = NULL; - unsigned service_request_len = 0; - BACNET_OBJECT_TYPE object_type = OBJECT_DEVICE; - uint32_t object_instance = 0; - BACNET_PROPERTY_ID object_property = PROP_OBJECT_IDENTIFIER; - int32_t array_index = 0; - BACNET_APPLICATION_DATA_VALUE application_data[4] = {{0}}; - BACNET_APPLICATION_DATA_VALUE test_application_data = {0}; - uint8_t application_data_buffer[MAX_APDU] = {0}; - int application_data_buffer_len = 0; - BACNET_ERROR_CLASS error_class; - BACNET_ERROR_CODE error_code; + uint8_t apdu[480] = { 0 }; + int len = 0; + int test_len = 0; + int apdu_len = 0; + uint8_t invoke_id = 12; + uint8_t test_invoke_id = 0; + uint8_t *service_request = NULL; + unsigned service_request_len = 0; + BACNET_OBJECT_TYPE object_type = OBJECT_DEVICE; + uint32_t object_instance = 0; + BACNET_PROPERTY_ID object_property = PROP_OBJECT_IDENTIFIER; + int32_t array_index = 0; + BACNET_APPLICATION_DATA_VALUE application_data[4] = { {0} }; + BACNET_APPLICATION_DATA_VALUE test_application_data = { 0 }; + uint8_t application_data_buffer[MAX_APDU] = { 0 }; + int application_data_buffer_len = 0; + BACNET_ERROR_CLASS error_class; + BACNET_ERROR_CODE error_code; - /* build the RPM - try to make it easy for the - Application Layer development */ - /* IDEA: similar construction, but pass apdu, apdu_len pointer, - size of apdu to let the called function handle the out of - space problem that these get into by returning a boolean - of success/failure. - It almost needs to use the keylist library or something similar. - Also check case of storing a backoff point - (i.e. save enough room for object_end) */ - apdu_len = rpm_ack_encode_apdu_init(&apdu[0], invoke_id); + /* build the RPM - try to make it easy for the + Application Layer development */ + /* IDEA: similar construction, but pass apdu, apdu_len pointer, + size of apdu to let the called function handle the out of + space problem that these get into by returning a boolean + of success/failure. + It almost needs to use the keylist library or something similar. + Also check case of storing a backoff point + (i.e. save enough room for object_end) */ + apdu_len = rpm_ack_encode_apdu_init(&apdu[0], invoke_id); - /* object beginning */ - apdu_len += rpm_ack_encode_apdu_object_begin(&apdu[apdu_len], - OBJECT_DEVICE, 123); - /* reply property */ - apdu_len += rpm_ack_encode_apdu_object_property(&apdu[apdu_len], - PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL); - /* reply value */ - application_data[0].tag = BACNET_APPLICATION_TAG_OBJECT_ID; - application_data[0].type.Object_Id.type = OBJECT_DEVICE; - application_data[0].type.Object_Id.instance = 123; - application_data_buffer_len = bacapp_encode_application_data( - &application_data_buffer[0], - &application_data[0]); - apdu_len += rpm_ack_encode_apdu_object_property_value(&apdu[apdu_len], - &application_data_buffer[0], - application_data_buffer_len); - /* reply property */ - apdu_len += rpm_ack_encode_apdu_object_property(&apdu[apdu_len], - PROP_OBJECT_TYPE, BACNET_ARRAY_ALL); - /* reply value */ - application_data[1].tag = BACNET_APPLICATION_TAG_ENUMERATED; - application_data[1].type.Enumerated = OBJECT_DEVICE; - application_data_buffer_len = bacapp_encode_application_data( - &application_data_buffer[0], - &application_data[1]); - apdu_len += rpm_ack_encode_apdu_object_property_value(&apdu[apdu_len], - &application_data_buffer[0], - application_data_buffer_len); - /* object end */ - apdu_len += rpm_ack_encode_apdu_object_end(&apdu[apdu_len]); + /* object beginning */ + apdu_len += rpm_ack_encode_apdu_object_begin(&apdu[apdu_len], + OBJECT_DEVICE, 123); + /* reply property */ + apdu_len += rpm_ack_encode_apdu_object_property(&apdu[apdu_len], + PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL); + /* reply value */ + application_data[0].tag = BACNET_APPLICATION_TAG_OBJECT_ID; + application_data[0].type.Object_Id.type = OBJECT_DEVICE; + application_data[0].type.Object_Id.instance = 123; + application_data_buffer_len = + bacapp_encode_application_data(&application_data_buffer[0], + &application_data[0]); + apdu_len += + rpm_ack_encode_apdu_object_property_value(&apdu[apdu_len], + &application_data_buffer[0], application_data_buffer_len); + /* reply property */ + apdu_len += rpm_ack_encode_apdu_object_property(&apdu[apdu_len], + PROP_OBJECT_TYPE, BACNET_ARRAY_ALL); + /* reply value */ + application_data[1].tag = BACNET_APPLICATION_TAG_ENUMERATED; + application_data[1].type.Enumerated = OBJECT_DEVICE; + application_data_buffer_len = + bacapp_encode_application_data(&application_data_buffer[0], + &application_data[1]); + apdu_len += + rpm_ack_encode_apdu_object_property_value(&apdu[apdu_len], + &application_data_buffer[0], application_data_buffer_len); + /* object end */ + apdu_len += rpm_ack_encode_apdu_object_end(&apdu[apdu_len]); - /* object beginning */ - apdu_len += rpm_ack_encode_apdu_object_begin(&apdu[apdu_len], - OBJECT_ANALOG_INPUT, 33); - /* reply property */ - apdu_len += rpm_ack_encode_apdu_object_property(&apdu[apdu_len], - PROP_PRESENT_VALUE, BACNET_ARRAY_ALL); - /* reply value */ - application_data[2].tag = BACNET_APPLICATION_TAG_REAL; - application_data[2].type.Real = 0.0; - application_data_buffer_len = bacapp_encode_application_data( - &application_data_buffer[0], - &application_data[2]); - apdu_len += rpm_ack_encode_apdu_object_property_value(&apdu[apdu_len], - &application_data_buffer[0], - application_data_buffer_len); - /* reply property */ - apdu_len += rpm_ack_encode_apdu_object_property(&apdu[apdu_len], - PROP_DEADBAND, BACNET_ARRAY_ALL); - /* reply error */ - apdu_len += rpm_ack_encode_apdu_object_property_error(&apdu[apdu_len], - ERROR_CLASS_PROPERTY, ERROR_CODE_UNKNOWN_PROPERTY); - /* object end */ - apdu_len += rpm_ack_encode_apdu_object_end(&apdu[apdu_len]); - ct_test(pTest, apdu_len != 0); + /* object beginning */ + apdu_len += rpm_ack_encode_apdu_object_begin(&apdu[apdu_len], + OBJECT_ANALOG_INPUT, 33); + /* reply property */ + apdu_len += rpm_ack_encode_apdu_object_property(&apdu[apdu_len], + PROP_PRESENT_VALUE, BACNET_ARRAY_ALL); + /* reply value */ + application_data[2].tag = BACNET_APPLICATION_TAG_REAL; + application_data[2].type.Real = 0.0; + application_data_buffer_len = + bacapp_encode_application_data(&application_data_buffer[0], + &application_data[2]); + apdu_len += + rpm_ack_encode_apdu_object_property_value(&apdu[apdu_len], + &application_data_buffer[0], application_data_buffer_len); + /* reply property */ + apdu_len += rpm_ack_encode_apdu_object_property(&apdu[apdu_len], + PROP_DEADBAND, BACNET_ARRAY_ALL); + /* reply error */ + apdu_len += rpm_ack_encode_apdu_object_property_error(&apdu[apdu_len], + ERROR_CLASS_PROPERTY, ERROR_CODE_UNKNOWN_PROPERTY); + /* object end */ + apdu_len += rpm_ack_encode_apdu_object_end(&apdu[apdu_len]); + ct_test(pTest, apdu_len != 0); /****** decode the packet ******/ - test_len = rpm_ack_decode_apdu( - &apdu[0], - apdu_len, - &test_invoke_id, - &service_request, /* will point to the service request in the apdu */ - &service_request_len); - ct_test(pTest, test_len != -1); - ct_test(pTest, test_invoke_id == invoke_id); - ct_test(pTest, service_request != NULL); - ct_test(pTest, service_request_len > 0); - /* the first part should be the first object id */ - test_len = rpm_ack_decode_object_id( - service_request, - service_request_len, - &object_type, - &object_instance); - ct_test(pTest, test_len != -1); - ct_test(pTest, object_type == OBJECT_DEVICE); - ct_test(pTest, object_instance == 123); - len = test_len; - /* extract the property */ - test_len = rpm_ack_decode_object_property( - &service_request[len], - service_request_len - len, - &object_property, - &array_index); - ct_test(pTest, object_property == PROP_OBJECT_IDENTIFIER); - ct_test(pTest, array_index == BACNET_ARRAY_ALL); - len += test_len; - /* what is the result? An error or a value? */ - ct_test(pTest,decode_is_opening_tag_number(&service_request[len], 4)); - len ++; - /* decode the object property portion of the service request */ - /* note: if this was an array, there could have been - more than one element to decode */ - test_len = bacapp_decode_application_data( - &service_request[len], - service_request_len - len, - &test_application_data); - ct_test(pTest, test_len > 0); - ct_test(pTest, bacapp_compare(&application_data[0],&test_application_data)); - len += test_len; - ct_test(pTest,decode_is_closing_tag_number(&service_request[len], 4)); - len ++; - /* see if there is another property */ - test_len = rpm_ack_decode_object_property( - &service_request[len], - service_request_len - len, - &object_property, - &array_index); - ct_test(pTest, test_len != -1); - ct_test(pTest, object_property == PROP_OBJECT_TYPE); - ct_test(pTest, array_index == BACNET_ARRAY_ALL); - len += test_len; - /* what is the result value? */ - ct_test(pTest,decode_is_opening_tag_number(&service_request[len], 4)); - len ++; - /* decode the object property portion of the service request */ - test_len = bacapp_decode_application_data( - &service_request[len], - service_request_len - len, - &test_application_data); - ct_test(pTest, test_len > 0); - ct_test(pTest, bacapp_compare(&application_data[1],&test_application_data)); - len += test_len; - ct_test(pTest,decode_is_closing_tag_number(&service_request[len], 4)); - len ++; - /* see if there is another property */ - /* this time we should fail */ - test_len = rpm_ack_decode_object_property( - &service_request[len], - service_request_len - len, - &object_property, - &array_index); - ct_test(pTest, test_len == -1); - /* see if it is the end of this object */ - test_len = rpm_ack_decode_object_end( - &service_request[len], - service_request_len - len); - ct_test(pTest, test_len == 1); - len += test_len; - /* try to decode another object id */ - test_len = rpm_ack_decode_object_id( - &service_request[len], - service_request_len - len, - &object_type, - &object_instance); - ct_test(pTest, test_len != -1); - ct_test(pTest, object_type == OBJECT_ANALOG_INPUT); - ct_test(pTest, object_instance == 33); - len += test_len; - /* decode the object property portion of the service request only */ - test_len = rpm_ack_decode_object_property( - &service_request[len], - service_request_len - len, - &object_property, - &array_index); - ct_test(pTest, test_len != -1); - ct_test(pTest, object_property == PROP_PRESENT_VALUE); - ct_test(pTest, array_index == BACNET_ARRAY_ALL); - len += test_len; - /* what is the result value? */ - ct_test(pTest,decode_is_opening_tag_number(&service_request[len], 4)); - len++; - /* decode the object property portion of the service request */ - test_len = bacapp_decode_application_data( - &service_request[len], - service_request_len - len, - &test_application_data); - ct_test(pTest, test_len > 0); - ct_test(pTest, bacapp_compare(&application_data[2],&test_application_data)); - len += test_len; - ct_test(pTest,decode_is_closing_tag_number(&service_request[len], 4)); - len++; - /* see if there is another property */ - test_len = rpm_ack_decode_object_property( - &service_request[len], - service_request_len - len, - &object_property, - &array_index); - ct_test(pTest, test_len != -1); - ct_test(pTest, object_property == PROP_DEADBAND); - ct_test(pTest, array_index == BACNET_ARRAY_ALL); - len += test_len; - /* what is the result value? */ - ct_test(pTest,decode_is_opening_tag_number(&service_request[len], 5)); - len++; - /* it was an error reply */ - test_len = bacerror_decode_error_class_and_code( - &service_request[len], - service_request_len - len, - &error_class, - &error_code); - ct_test(pTest, test_len != 0); - ct_test(pTest, error_class == ERROR_CLASS_PROPERTY); - ct_test(pTest, error_code == ERROR_CODE_UNKNOWN_PROPERTY); - len += test_len; - ct_test(pTest,decode_is_closing_tag_number(&service_request[len], 5)); - len++; - /* is there another property? */ - test_len = rpm_ack_decode_object_property( - &service_request[len], - service_request_len - len, - &object_property, - &array_index); - ct_test(pTest, test_len == -1); - /* got an error -1, is it the end of this object? */ - test_len = rpm_ack_decode_object_end( - &service_request[len], - service_request_len - len); - ct_test(pTest, test_len == 1); - len += test_len; - /* check for another object */ - test_len = rpm_ack_decode_object_id( - &service_request[len], - service_request_len - len, - &object_type, - &object_instance); - ct_test(pTest, test_len == 0); - ct_test(pTest, len == service_request_len); + test_len = rpm_ack_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, &service_request, /* will point to the service request in the apdu */ + &service_request_len); + ct_test(pTest, test_len != -1); + ct_test(pTest, test_invoke_id == invoke_id); + ct_test(pTest, service_request != NULL); + ct_test(pTest, service_request_len > 0); + /* the first part should be the first object id */ + test_len = rpm_ack_decode_object_id(service_request, + service_request_len, &object_type, &object_instance); + ct_test(pTest, test_len != -1); + ct_test(pTest, object_type == OBJECT_DEVICE); + ct_test(pTest, object_instance == 123); + len = test_len; + /* extract the property */ + test_len = rpm_ack_decode_object_property(&service_request[len], + service_request_len - len, &object_property, &array_index); + ct_test(pTest, object_property == PROP_OBJECT_IDENTIFIER); + ct_test(pTest, array_index == BACNET_ARRAY_ALL); + len += test_len; + /* what is the result? An error or a value? */ + ct_test(pTest, decode_is_opening_tag_number(&service_request[len], 4)); + len++; + /* decode the object property portion of the service request */ + /* note: if this was an array, there could have been + more than one element to decode */ + test_len = bacapp_decode_application_data(&service_request[len], + service_request_len - len, &test_application_data); + ct_test(pTest, test_len > 0); + ct_test(pTest, bacapp_compare(&application_data[0], + &test_application_data)); + len += test_len; + ct_test(pTest, decode_is_closing_tag_number(&service_request[len], 4)); + len++; + /* see if there is another property */ + test_len = rpm_ack_decode_object_property(&service_request[len], + service_request_len - len, &object_property, &array_index); + ct_test(pTest, test_len != -1); + ct_test(pTest, object_property == PROP_OBJECT_TYPE); + ct_test(pTest, array_index == BACNET_ARRAY_ALL); + len += test_len; + /* what is the result value? */ + ct_test(pTest, decode_is_opening_tag_number(&service_request[len], 4)); + len++; + /* decode the object property portion of the service request */ + test_len = bacapp_decode_application_data(&service_request[len], + service_request_len - len, &test_application_data); + ct_test(pTest, test_len > 0); + ct_test(pTest, bacapp_compare(&application_data[1], + &test_application_data)); + len += test_len; + ct_test(pTest, decode_is_closing_tag_number(&service_request[len], 4)); + len++; + /* see if there is another property */ + /* this time we should fail */ + test_len = rpm_ack_decode_object_property(&service_request[len], + service_request_len - len, &object_property, &array_index); + ct_test(pTest, test_len == -1); + /* see if it is the end of this object */ + test_len = rpm_ack_decode_object_end(&service_request[len], + service_request_len - len); + ct_test(pTest, test_len == 1); + len += test_len; + /* try to decode another object id */ + test_len = rpm_ack_decode_object_id(&service_request[len], + service_request_len - len, &object_type, &object_instance); + ct_test(pTest, test_len != -1); + ct_test(pTest, object_type == OBJECT_ANALOG_INPUT); + ct_test(pTest, object_instance == 33); + len += test_len; + /* decode the object property portion of the service request only */ + test_len = rpm_ack_decode_object_property(&service_request[len], + service_request_len - len, &object_property, &array_index); + ct_test(pTest, test_len != -1); + ct_test(pTest, object_property == PROP_PRESENT_VALUE); + ct_test(pTest, array_index == BACNET_ARRAY_ALL); + len += test_len; + /* what is the result value? */ + ct_test(pTest, decode_is_opening_tag_number(&service_request[len], 4)); + len++; + /* decode the object property portion of the service request */ + test_len = bacapp_decode_application_data(&service_request[len], + service_request_len - len, &test_application_data); + ct_test(pTest, test_len > 0); + ct_test(pTest, bacapp_compare(&application_data[2], + &test_application_data)); + len += test_len; + ct_test(pTest, decode_is_closing_tag_number(&service_request[len], 4)); + len++; + /* see if there is another property */ + test_len = rpm_ack_decode_object_property(&service_request[len], + service_request_len - len, &object_property, &array_index); + ct_test(pTest, test_len != -1); + ct_test(pTest, object_property == PROP_DEADBAND); + ct_test(pTest, array_index == BACNET_ARRAY_ALL); + len += test_len; + /* what is the result value? */ + ct_test(pTest, decode_is_opening_tag_number(&service_request[len], 5)); + len++; + /* it was an error reply */ + test_len = bacerror_decode_error_class_and_code(&service_request[len], + service_request_len - len, &error_class, &error_code); + ct_test(pTest, test_len != 0); + ct_test(pTest, error_class == ERROR_CLASS_PROPERTY); + ct_test(pTest, error_code == ERROR_CODE_UNKNOWN_PROPERTY); + len += test_len; + ct_test(pTest, decode_is_closing_tag_number(&service_request[len], 5)); + len++; + /* is there another property? */ + test_len = rpm_ack_decode_object_property(&service_request[len], + service_request_len - len, &object_property, &array_index); + ct_test(pTest, test_len == -1); + /* got an error -1, is it the end of this object? */ + test_len = rpm_ack_decode_object_end(&service_request[len], + service_request_len - len); + ct_test(pTest, test_len == 1); + len += test_len; + /* check for another object */ + test_len = rpm_ack_decode_object_id(&service_request[len], + service_request_len - len, &object_type, &object_instance); + ct_test(pTest, test_len == 0); + ct_test(pTest, len == service_request_len); } #ifdef TEST_READ_PROPERTY_MULTIPLE @@ -872,4 +742,3 @@ int main(void) #endif /* TEST_READ_PROPERTY_MULTIPLE */ #endif /* TEST */ - diff --git a/bacnet-stack/rpm.h b/bacnet-stack/rpm.h index fa2fb569..e868657d 100644 --- a/bacnet-stack/rpm.h +++ b/bacnet-stack/rpm.h @@ -42,7 +42,7 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ /* encode functions */ /* Start with the Init function, and then add an object, @@ -51,104 +51,69 @@ extern "C" { until the APDU is full.*/ /* RPM */ -int rpm_encode_apdu_init( - uint8_t *apdu, - uint8_t invoke_id); + int rpm_encode_apdu_init(uint8_t * apdu, uint8_t invoke_id); -int rpm_encode_apdu_object_begin( - uint8_t *apdu, - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance); + int rpm_encode_apdu_object_begin(uint8_t * apdu, + BACNET_OBJECT_TYPE object_type, uint32_t object_instance); -int rpm_encode_apdu_object_property( - uint8_t *apdu, - BACNET_PROPERTY_ID object_property, - int32_t array_index); + int rpm_encode_apdu_object_property(uint8_t * apdu, + BACNET_PROPERTY_ID object_property, int32_t array_index); -int rpm_encode_apdu_object_end( - uint8_t *apdu); + int rpm_encode_apdu_object_end(uint8_t * apdu); -int rpm_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - uint8_t **service_request, - unsigned *service_request_len); + int rpm_decode_apdu(uint8_t * apdu, + unsigned apdu_len, + uint8_t * invoke_id, + uint8_t ** service_request, unsigned *service_request_len); /* decode the object portion of the service request only */ -int rpm_decode_object_id( - uint8_t *apdu, - unsigned apdu_len, - BACNET_OBJECT_TYPE *object_type, - uint32_t *object_instance); + int rpm_decode_object_id(uint8_t * apdu, + unsigned apdu_len, + BACNET_OBJECT_TYPE * object_type, uint32_t * object_instance); /* is this the end of this object property list? */ -int rpm_decode_object_end( - uint8_t *apdu, - unsigned apdu_len); + int rpm_decode_object_end(uint8_t * apdu, unsigned apdu_len); /* decode the object property portion of the service request only */ -int rpm_decode_object_property( - uint8_t *apdu, - unsigned apdu_len, - BACNET_PROPERTY_ID *object_property, - int32_t *array_index); + int rpm_decode_object_property(uint8_t * apdu, + unsigned apdu_len, + BACNET_PROPERTY_ID * object_property, int32_t * array_index); /* RPM Ack */ -int rpm_ack_encode_apdu_object_begin( - uint8_t *apdu, - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance); + int rpm_ack_encode_apdu_object_begin(uint8_t * apdu, + BACNET_OBJECT_TYPE object_type, uint32_t object_instance); -int rpm_ack_encode_apdu_object_property_value( - uint8_t *apdu, - uint8_t *application_data, - unsigned application_data_len); + int rpm_ack_encode_apdu_object_property_value(uint8_t * apdu, + uint8_t * application_data, unsigned application_data_len); -int rpm_ack_encode_apdu_object_property_error( - uint8_t *apdu, - BACNET_ERROR_CLASS error_class, - BACNET_ERROR_CODE error_code); + int rpm_ack_encode_apdu_object_property_error(uint8_t * apdu, + BACNET_ERROR_CLASS error_class, BACNET_ERROR_CODE error_code); -int rpm_ack_encode_apdu_object_end( - uint8_t *apdu); + int rpm_ack_encode_apdu_object_end(uint8_t * apdu); -int rpm_ack_decode_object_id( - uint8_t *apdu, - unsigned apdu_len, - BACNET_OBJECT_TYPE *object_type, - uint32_t *object_instance); + int rpm_ack_decode_object_id(uint8_t * apdu, + unsigned apdu_len, + BACNET_OBJECT_TYPE * object_type, uint32_t * object_instance); /* is this the end of the list of this objects properties values? */ -int rpm_ack_decode_object_end( - uint8_t *apdu, - unsigned apdu_len); -int rpm_ack_decode_object_property( - uint8_t *apdu, - unsigned apdu_len, - BACNET_PROPERTY_ID *object_property, - int32_t *array_index); + int rpm_ack_decode_object_end(uint8_t * apdu, unsigned apdu_len); + int rpm_ack_decode_object_property(uint8_t * apdu, + unsigned apdu_len, + BACNET_PROPERTY_ID * object_property, int32_t * array_index); /* decode the object property value portion of the service request only */ -int rpm_ack_decode_object_property_value( - uint8_t *apdu, - unsigned apdu_len, - uint8_t **application_data, - unsigned *application_data_len); -int rpm_ack_decode_apdu( - uint8_t *apdu, - int apdu_len, /* total length of the apdu */ - uint8_t *invoke_id, - uint8_t **service_request, - unsigned *service_request_len); + int rpm_ack_decode_object_property_value(uint8_t * apdu, + unsigned apdu_len, + uint8_t ** application_data, unsigned *application_data_len); + int rpm_ack_decode_apdu(uint8_t * apdu, int apdu_len, /* total length of the apdu */ + uint8_t * invoke_id, + uint8_t ** service_request, unsigned *service_request_len); #ifdef TEST #include "ctest.h" -void testReadPropertyMultiple(Test * pTest); -void testReadPropertyMultipleAck(Test * pTest); + void testReadPropertyMultiple(Test * pTest); + void testReadPropertyMultipleAck(Test * pTest); #endif #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif - diff --git a/bacnet-stack/rs485.h b/bacnet-stack/rs485.h index 49185796..a3c0ae0b 100644 --- a/bacnet-stack/rs485.h +++ b/bacnet-stack/rs485.h @@ -41,22 +41,19 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ -void RS485_Initialize(void); + void RS485_Initialize(void); -void RS485_Send_Frame( - volatile struct mstp_port_struct_t *mstp_port, // port specific data - uint8_t *buffer, // frame to send (up to 501 bytes of data) - uint16_t nbytes); // number of bytes of data (up to 501) + void RS485_Send_Frame(volatile struct mstp_port_struct_t *mstp_port, // port specific data + uint8_t * buffer, // frame to send (up to 501 bytes of data) + uint16_t nbytes); // number of bytes of data (up to 501) -void RS485_Check_UART_Data( - volatile struct mstp_port_struct_t *mstp_port); // port specific data + void RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port); // port specific data -void RS485_Process_Tx_Message(void); + void RS485_Process_Tx_Message(void); #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif diff --git a/bacnet-stack/sbuf.c b/bacnet-stack/sbuf.c index c8ba78b4..cbb5d954 100644 --- a/bacnet-stack/sbuf.c +++ b/bacnet-stack/sbuf.c @@ -40,181 +40,170 @@ #include #include "sbuf.h" -void sbuf_init( - STATIC_BUFFER *b, /* static buffer structure */ - char *data, /* actual size, in bytes, of the data block or array of data */ - unsigned size) /* number of bytes used */ -{ - if (b) - { - b->data = data; - b->size = size; - b->count = 0; - } +void sbuf_init(STATIC_BUFFER * b, /* static buffer structure */ + char *data, /* actual size, in bytes, of the data block or array of data */ + unsigned size) +{ /* number of bytes used */ + if (b) { + b->data = data; + b->size = size; + b->count = 0; + } - return; + return; } /* returns true if count==0, false if count > 0 */ bool sbuf_empty(STATIC_BUFFER const *b) { - return (b?(b->count == 0):false); + return (b ? (b->count == 0) : false); } char *sbuf_data(STATIC_BUFFER const *b) { - return (b?b->data:NULL); + return (b ? b->data : NULL); } -unsigned sbuf_size(STATIC_BUFFER *b) +unsigned sbuf_size(STATIC_BUFFER * b) { - return (b?b->size:0); + return (b ? b->size : 0); } -unsigned sbuf_count(STATIC_BUFFER *b) +unsigned sbuf_count(STATIC_BUFFER * b) { - return (b?b->count:0); + return (b ? b->count : 0); } /* returns true if successful, false if not enough room to append data */ -bool sbuf_put( - STATIC_BUFFER *b, /* static buffer structure */ - unsigned offset, /* where to start */ - char *data, /* number of bytes used */ - unsigned data_size) /* how many to add */ -{ - bool status = false; /* return value */ +bool sbuf_put(STATIC_BUFFER * b, /* static buffer structure */ + unsigned offset, /* where to start */ + char *data, /* number of bytes used */ + unsigned data_size) +{ /* how many to add */ + bool status = false; /* return value */ - if (b && b->data) - { - if (((offset + data_size) < b->size)) - { - b->count = offset + data_size; - while (data_size) - { - b->data[offset] = *data; - offset++; - data++; - data_size--; - } - status = true; + if (b && b->data) { + if (((offset + data_size) < b->size)) { + b->count = offset + data_size; + while (data_size) { + b->data[offset] = *data; + offset++; + data++; + data_size--; + } + status = true; + } } - } - return status; + return status; } /* returns true if successful, false if not enough room to append data */ -bool sbuf_append( - STATIC_BUFFER *b, /* static buffer structure */ - char *data, /* number of bytes used */ - unsigned data_size) /* how many to add */ -{ - unsigned count = 0; - - if (b) - count = b->count; - - return sbuf_put(b, count, data, data_size); +bool sbuf_append(STATIC_BUFFER * b, /* static buffer structure */ + char *data, /* number of bytes used */ + unsigned data_size) +{ /* how many to add */ + unsigned count = 0; + + if (b) + count = b->count; + + return sbuf_put(b, count, data, data_size); } /* returns true if successful, false if not enough room to append data */ -bool sbuf_truncate( - STATIC_BUFFER *b, /* static buffer structure */ - unsigned count) /* total number of bytes in use */ -{ - bool status = false; /* return value */ +bool sbuf_truncate(STATIC_BUFFER * b, /* static buffer structure */ + unsigned count) +{ /* total number of bytes in use */ + bool status = false; /* return value */ - if (b) - { - if (count < b->size) - { - b->count = count; - status = true; + if (b) { + if (count < b->size) { + b->count = count; + status = true; + } } - } - - return status; + + return status; } - + #ifdef TEST #include #include #include "ctest.h" -void testStaticBuffer(Test* pTest) +void testStaticBuffer(Test * pTest) { - STATIC_BUFFER sbuffer; - char *data1 = "Joshua"; - char *data2 = "Anna"; - char *data3 = "Christopher"; - char *data4 = "Mary"; - char data_buffer[480] = ""; - char test_data_buffer[480] = ""; - char *data; - unsigned count; + STATIC_BUFFER sbuffer; + char *data1 = "Joshua"; + char *data2 = "Anna"; + char *data3 = "Christopher"; + char *data4 = "Mary"; + char data_buffer[480] = ""; + char test_data_buffer[480] = ""; + char *data; + unsigned count; - sbuf_init(&sbuffer,NULL,0); - ct_test(pTest,sbuf_empty(&sbuffer) == true); - ct_test(pTest,sbuf_data(&sbuffer) == NULL); - ct_test(pTest,sbuf_size(&sbuffer) == 0); - ct_test(pTest,sbuf_count(&sbuffer) == 0); - ct_test(pTest,sbuf_append(&sbuffer,data1,strlen(data1)) == false); + sbuf_init(&sbuffer, NULL, 0); + ct_test(pTest, sbuf_empty(&sbuffer) == true); + ct_test(pTest, sbuf_data(&sbuffer) == NULL); + ct_test(pTest, sbuf_size(&sbuffer) == 0); + ct_test(pTest, sbuf_count(&sbuffer) == 0); + ct_test(pTest, sbuf_append(&sbuffer, data1, strlen(data1)) == false); - sbuf_init(&sbuffer,data_buffer,sizeof(data_buffer)); - ct_test(pTest,sbuf_empty(&sbuffer) == true); - ct_test(pTest,sbuf_data(&sbuffer) == data_buffer); - ct_test(pTest,sbuf_size(&sbuffer) == sizeof(data_buffer)); - ct_test(pTest,sbuf_count(&sbuffer) == 0); - - ct_test(pTest,sbuf_append(&sbuffer,data1,strlen(data1)) == true); - ct_test(pTest,sbuf_append(&sbuffer,data2,strlen(data2)) == true); - ct_test(pTest,sbuf_append(&sbuffer,data3,strlen(data3)) == true); - ct_test(pTest,sbuf_append(&sbuffer,data4,strlen(data4)) == true); - strcat(test_data_buffer,data1); - strcat(test_data_buffer,data2); - strcat(test_data_buffer,data3); - strcat(test_data_buffer,data4); - ct_test(pTest,sbuf_count(&sbuffer) == strlen(test_data_buffer)); + sbuf_init(&sbuffer, data_buffer, sizeof(data_buffer)); + ct_test(pTest, sbuf_empty(&sbuffer) == true); + ct_test(pTest, sbuf_data(&sbuffer) == data_buffer); + ct_test(pTest, sbuf_size(&sbuffer) == sizeof(data_buffer)); + ct_test(pTest, sbuf_count(&sbuffer) == 0); - data = sbuf_data(&sbuffer); - count = sbuf_count(&sbuffer); - ct_test(pTest,memcmp(data,test_data_buffer,count) == 0); - ct_test(pTest,count == strlen(test_data_buffer)); - - ct_test(pTest,sbuf_truncate(&sbuffer,0) == true); - ct_test(pTest,sbuf_count(&sbuffer) == 0); - ct_test(pTest,sbuf_size(&sbuffer) == sizeof(data_buffer)); - ct_test(pTest,sbuf_append(&sbuffer,data4,strlen(data4)) == true); - data = sbuf_data(&sbuffer); - count = sbuf_count(&sbuffer); - ct_test(pTest,memcmp(data,data4,count) == 0); - ct_test(pTest,count == strlen(data4)); + ct_test(pTest, sbuf_append(&sbuffer, data1, strlen(data1)) == true); + ct_test(pTest, sbuf_append(&sbuffer, data2, strlen(data2)) == true); + ct_test(pTest, sbuf_append(&sbuffer, data3, strlen(data3)) == true); + ct_test(pTest, sbuf_append(&sbuffer, data4, strlen(data4)) == true); + strcat(test_data_buffer, data1); + strcat(test_data_buffer, data2); + strcat(test_data_buffer, data3); + strcat(test_data_buffer, data4); + ct_test(pTest, sbuf_count(&sbuffer) == strlen(test_data_buffer)); - return; + data = sbuf_data(&sbuffer); + count = sbuf_count(&sbuffer); + ct_test(pTest, memcmp(data, test_data_buffer, count) == 0); + ct_test(pTest, count == strlen(test_data_buffer)); + + ct_test(pTest, sbuf_truncate(&sbuffer, 0) == true); + ct_test(pTest, sbuf_count(&sbuffer) == 0); + ct_test(pTest, sbuf_size(&sbuffer) == sizeof(data_buffer)); + ct_test(pTest, sbuf_append(&sbuffer, data4, strlen(data4)) == true); + data = sbuf_data(&sbuffer); + count = sbuf_count(&sbuffer); + ct_test(pTest, memcmp(data, data4, count) == 0); + ct_test(pTest, count == strlen(data4)); + + return; } #ifdef TEST_STATIC_BUFFER int main(void) { - Test *pTest; - bool rc; + Test *pTest; + bool rc; - pTest = ct_create("static buffer", NULL); + pTest = ct_create("static buffer", NULL); - /* individual tests */ - rc = ct_addTestFunction(pTest, testStaticBuffer); - assert(rc); + /* individual tests */ + rc = ct_addTestFunction(pTest, testStaticBuffer); + assert(rc); - ct_setStream(pTest, stdout); - ct_run(pTest); - (void)ct_report(pTest); + ct_setStream(pTest, stdout); + ct_run(pTest); + (void) ct_report(pTest); - ct_destroy(pTest); + ct_destroy(pTest); - return 0; + return 0; } -#endif /* TEST_STATIC_BUFFER */ -#endif /* TEST */ - +#endif /* TEST_STATIC_BUFFER */ +#endif /* TEST */ diff --git a/bacnet-stack/sbuf.h b/bacnet-stack/sbuf.h index 111b8986..ffcad78a 100644 --- a/bacnet-stack/sbuf.h +++ b/bacnet-stack/sbuf.h @@ -42,45 +42,39 @@ #include #include -struct static_buffer_t -{ - char *data; /* block of memory or array of data */ - unsigned size; /* actual size, in bytes, of the block of data */ - unsigned count; /* number of bytes in use */ +struct static_buffer_t { + char *data; /* block of memory or array of data */ + unsigned size; /* actual size, in bytes, of the block of data */ + unsigned count; /* number of bytes in use */ }; typedef struct static_buffer_t STATIC_BUFFER; #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ -void sbuf_init( - STATIC_BUFFER *b, /* static buffer structure */ - char *data, /* actual size, in bytes, of the data block or array of data */ - unsigned size); /* number of bytes used */ + void sbuf_init(STATIC_BUFFER * b, /* static buffer structure */ + char *data, /* actual size, in bytes, of the data block or array of data */ + unsigned size); /* number of bytes used */ /* returns true if size==0, false if size > 0 */ -bool sbuf_empty(STATIC_BUFFER const *b); -char *sbuf_data(STATIC_BUFFER const *b); -unsigned sbuf_size(STATIC_BUFFER *b); -unsigned sbuf_count(STATIC_BUFFER *b); + bool sbuf_empty(STATIC_BUFFER const *b); + char *sbuf_data(STATIC_BUFFER const *b); + unsigned sbuf_size(STATIC_BUFFER * b); + unsigned sbuf_count(STATIC_BUFFER * b); /* returns true if successful, false if not enough room to append data */ -bool sbuf_put( - STATIC_BUFFER *b, /* static buffer structure */ - unsigned offset, /* where to start */ - char *data, /* number of bytes used */ - unsigned data_size); /* how many to add */ + bool sbuf_put(STATIC_BUFFER * b, /* static buffer structure */ + unsigned offset, /* where to start */ + char *data, /* number of bytes used */ + unsigned data_size); /* how many to add */ /* returns true if successful, false if not enough room to append data */ -bool sbuf_append( - STATIC_BUFFER *b, /* static buffer structure */ - char *data, /* number of bytes used */ - unsigned data_size); /* how many to add */ + bool sbuf_append(STATIC_BUFFER * b, /* static buffer structure */ + char *data, /* number of bytes used */ + unsigned data_size); /* how many to add */ /* returns true if successful, false if not enough room to append data */ -bool sbuf_truncate( - STATIC_BUFFER *b, /* static buffer structure */ - unsigned count); /* total number of bytes in use */ - + bool sbuf_truncate(STATIC_BUFFER * b, /* static buffer structure */ + unsigned count); /* total number of bytes in use */ + #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif diff --git a/bacnet-stack/tsm.c b/bacnet-stack/tsm.c index a4f3b25e..d3bbcdac 100644 --- a/bacnet-stack/tsm.c +++ b/bacnet-stack/tsm.c @@ -34,7 +34,7 @@ #include #include #include -#include // memmove() +#include // memmove() #include "bits.h" #include "apdu.h" #include "bacdef.h" @@ -57,77 +57,69 @@ // declare space for the TSM transactions, and set it up in the init. /* table rules: an Invoke ID = 0 is an unused spot in the table */ -static BACNET_TSM_DATA TSM_List[MAX_TSM_TRANSACTIONS] = {{0}}; +static BACNET_TSM_DATA TSM_List[MAX_TSM_TRANSACTIONS] = { {0} }; // returns MAX_TSM_TRANSACTIONS if not found static uint8_t tsm_find_invokeID_index(uint8_t invokeID) { - unsigned i = 0; // counter - uint8_t index = MAX_TSM_TRANSACTIONS; // return value + unsigned i = 0; // counter + uint8_t index = MAX_TSM_TRANSACTIONS; // return value - for (i = 0; i < MAX_TSM_TRANSACTIONS; i++) - { - if (TSM_List[i].InvokeID == invokeID) - { - index = i; - break; + for (i = 0; i < MAX_TSM_TRANSACTIONS; i++) { + if (TSM_List[i].InvokeID == invokeID) { + index = i; + break; + } } - } - return index; + return index; } static uint8_t tsm_find_first_free_index(void) { - unsigned i = 0; // counter - uint8_t index = MAX_TSM_TRANSACTIONS; // return value + unsigned i = 0; // counter + uint8_t index = MAX_TSM_TRANSACTIONS; // return value - for (i = 0; i < MAX_TSM_TRANSACTIONS; i++) - { - if (TSM_List[i].InvokeID == 0) - { - index = i; - break; + for (i = 0; i < MAX_TSM_TRANSACTIONS; i++) { + if (TSM_List[i].InvokeID == 0) { + index = i; + break; + } } - } - return index; + return index; } bool tsm_transaction_available(void) { - bool status = false; // return value - unsigned i = 0; // counter + bool status = false; // return value + unsigned i = 0; // counter - for (i = 0; i < MAX_TSM_TRANSACTIONS; i++) - { - if (TSM_List[i].InvokeID == 0) - { - // one is available! - status = true; - break; + for (i = 0; i < MAX_TSM_TRANSACTIONS; i++) { + if (TSM_List[i].InvokeID == 0) { + // one is available! + status = true; + break; + } } - } - return status; + return status; } uint8_t tsm_transaction_idle_count(void) { - uint8_t count = 0; // return value - unsigned i = 0; // counter + uint8_t count = 0; // return value + unsigned i = 0; // counter - for (i = 0; i < MAX_TSM_TRANSACTIONS; i++) - { - if ((TSM_List[i].InvokeID == 0) && - (TSM_List[i].state == TSM_STATE_IDLE)) - { - // one is available! - count++; + for (i = 0; i < MAX_TSM_TRANSACTIONS; i++) { + if ((TSM_List[i].InvokeID == 0) && + (TSM_List[i].state == TSM_STATE_IDLE)) { + // one is available! + count++; + } } - } - return count; + return count; } /* gets the next free invokeID, @@ -135,162 +127,138 @@ uint8_t tsm_transaction_idle_count(void) returns 0 if none are available */ uint8_t tsm_next_free_invokeID(void) { - static uint8_t current_invokeID = 1; // incremented... - uint8_t index = 0; - uint8_t invokeID = 0; - bool found = false; + static uint8_t current_invokeID = 1; // incremented... + uint8_t index = 0; + uint8_t invokeID = 0; + bool found = false; - while (!found) - { - index = tsm_find_invokeID_index(current_invokeID); - /* not found - that is good! */ - if (index == MAX_TSM_TRANSACTIONS) - { - found = true; - /* set this id into the table */ - index = tsm_find_first_free_index(); - if (index != MAX_TSM_TRANSACTIONS) - { - TSM_List[index].InvokeID = invokeID = current_invokeID; - TSM_List[index].state = TSM_STATE_IDLE; - TSM_List[index].RequestTimer = Device_APDU_Timeout(); - /* update for the next call or check */ - current_invokeID++; - // skip zero - we treat that internally as invalid or no free - if (current_invokeID == 0) - current_invokeID = 1; - } + while (!found) { + index = tsm_find_invokeID_index(current_invokeID); + /* not found - that is good! */ + if (index == MAX_TSM_TRANSACTIONS) { + found = true; + /* set this id into the table */ + index = tsm_find_first_free_index(); + if (index != MAX_TSM_TRANSACTIONS) { + TSM_List[index].InvokeID = invokeID = current_invokeID; + TSM_List[index].state = TSM_STATE_IDLE; + TSM_List[index].RequestTimer = Device_APDU_Timeout(); + /* update for the next call or check */ + current_invokeID++; + // skip zero - we treat that internally as invalid or no free + if (current_invokeID == 0) + current_invokeID = 1; + } + } } - } - return invokeID; + return invokeID; } -void tsm_set_confirmed_unsegmented_transaction( - uint8_t invokeID, - BACNET_ADDRESS *dest, - uint8_t *pdu, - uint16_t pdu_len) +void tsm_set_confirmed_unsegmented_transaction(uint8_t invokeID, + BACNET_ADDRESS * dest, uint8_t * pdu, uint16_t pdu_len) { - uint16_t j = 0; - uint8_t index; + uint16_t j = 0; + uint8_t index; - if (invokeID) - { - index = tsm_find_invokeID_index(invokeID); - if (index < MAX_TSM_TRANSACTIONS) - { - // assign the transaction - TSM_List[index].state = TSM_STATE_AWAIT_CONFIRMATION; - TSM_List[index].RetryCount = Device_Number_Of_APDU_Retries(); - // start the timer - TSM_List[index].RequestTimer = Device_APDU_Timeout(); - // copy the data - for (j = 0; j < pdu_len; j++) - { - TSM_List[index].pdu[j] = pdu[j]; - } - TSM_List[index].pdu_len = pdu_len; - address_copy(&TSM_List[index].dest,dest); + if (invokeID) { + index = tsm_find_invokeID_index(invokeID); + if (index < MAX_TSM_TRANSACTIONS) { + // assign the transaction + TSM_List[index].state = TSM_STATE_AWAIT_CONFIRMATION; + TSM_List[index].RetryCount = Device_Number_Of_APDU_Retries(); + // start the timer + TSM_List[index].RequestTimer = Device_APDU_Timeout(); + // copy the data + for (j = 0; j < pdu_len; j++) { + TSM_List[index].pdu[j] = pdu[j]; + } + TSM_List[index].pdu_len = pdu_len; + address_copy(&TSM_List[index].dest, dest); + } } - } - return; + return; } // used to retrieve the transaction payload // if we wanted to find out what we sent (i.e. when we get an ack) -bool tsm_get_transaction_pdu( - uint8_t invokeID, - BACNET_ADDRESS *dest, - uint8_t *pdu, - uint16_t *pdu_len) +bool tsm_get_transaction_pdu(uint8_t invokeID, + BACNET_ADDRESS * dest, uint8_t * pdu, uint16_t * pdu_len) { - uint16_t j = 0; - uint8_t index; - bool found = false; + uint16_t j = 0; + uint8_t index; + bool found = false; - if (invokeID) - { - index = tsm_find_invokeID_index(invokeID); - // how much checking is needed? state? dest match? just invokeID? - if (index < MAX_TSM_TRANSACTIONS) - { - // FIXME: we may want to free the transaction so it doesn't timeout - // retrieve the transaction - // FIXME: bounds check the pdu_len? - *pdu_len = TSM_List[index].pdu_len; - for (j = 0; j < *pdu_len; j++) - { - pdu[j] = TSM_List[index].pdu[j]; - } - address_copy(dest,&TSM_List[index].dest); - found = true; + if (invokeID) { + index = tsm_find_invokeID_index(invokeID); + // how much checking is needed? state? dest match? just invokeID? + if (index < MAX_TSM_TRANSACTIONS) { + // FIXME: we may want to free the transaction so it doesn't timeout + // retrieve the transaction + // FIXME: bounds check the pdu_len? + *pdu_len = TSM_List[index].pdu_len; + for (j = 0; j < *pdu_len; j++) { + pdu[j] = TSM_List[index].pdu[j]; + } + address_copy(dest, &TSM_List[index].dest); + found = true; + } } - } - return found; + return found; } /* called once a millisecond or slower */ void tsm_timer_milliseconds(uint16_t milliseconds) { - unsigned i = 0; // counter - int bytes_sent = 0; + unsigned i = 0; // counter + int bytes_sent = 0; - for (i = 0; i < MAX_TSM_TRANSACTIONS; i++) - { - if (TSM_List[i].state == TSM_STATE_AWAIT_CONFIRMATION) - { - if (TSM_List[i].RequestTimer > milliseconds) - TSM_List[i].RequestTimer -= milliseconds; - else - TSM_List[i].RequestTimer = 0; - /* timeout. retry? */ - if (TSM_List[i].RequestTimer == 0) - { - TSM_List[i].RetryCount--; - TSM_List[i].RequestTimer = Device_APDU_Timeout(); - if (TSM_List[i].RetryCount) - { - bytes_sent = datalink_send_pdu( - &TSM_List[i].dest, /* destination address */ - &TSM_List[i].pdu[0], - TSM_List[i].pdu_len); /* number of bytes of data */ + for (i = 0; i < MAX_TSM_TRANSACTIONS; i++) { + if (TSM_List[i].state == TSM_STATE_AWAIT_CONFIRMATION) { + if (TSM_List[i].RequestTimer > milliseconds) + TSM_List[i].RequestTimer -= milliseconds; + else + TSM_List[i].RequestTimer = 0; + /* timeout. retry? */ + if (TSM_List[i].RequestTimer == 0) { + TSM_List[i].RetryCount--; + TSM_List[i].RequestTimer = Device_APDU_Timeout(); + if (TSM_List[i].RetryCount) { + bytes_sent = datalink_send_pdu(&TSM_List[i].dest, /* destination address */ + &TSM_List[i].pdu[0], TSM_List[i].pdu_len); /* number of bytes of data */ + } else { + TSM_List[i].InvokeID = 0; + TSM_List[i].state = TSM_STATE_IDLE; + } + } } - else - { - TSM_List[i].InvokeID = 0; - TSM_List[i].state = TSM_STATE_IDLE; - } - } } - } } void tsm_free_invoke_id(uint8_t invokeID) { - uint8_t index; + uint8_t index; - index = tsm_find_invokeID_index(invokeID); - if (index < MAX_TSM_TRANSACTIONS) - { - TSM_List[index].state = TSM_STATE_IDLE; - TSM_List[index].InvokeID = 0; - } + index = tsm_find_invokeID_index(invokeID); + if (index < MAX_TSM_TRANSACTIONS) { + TSM_List[index].state = TSM_STATE_IDLE; + TSM_List[index].InvokeID = 0; + } } /* see if the invoke ID has been made free */ bool tsm_invoke_id_free(uint8_t invokeID) { - bool status = true; - uint8_t index; + bool status = true; + uint8_t index; - index = tsm_find_invokeID_index(invokeID); - if (index < MAX_TSM_TRANSACTIONS) - status = false; + index = tsm_find_invokeID_index(invokeID); + if (index < MAX_TSM_TRANSACTIONS) + status = false; - return status; + return status; } #ifdef TEST @@ -303,8 +271,8 @@ bool I_Am_Request = true; void testTSM(Test * pTest) { - /* FIXME: add some unit testing...*/ - return; + /* FIXME: add some unit testing... */ + return; } #ifdef TEST_TSM @@ -327,4 +295,3 @@ int main(void) } #endif /* TEST_TSM */ #endif /* TEST */ - diff --git a/bacnet-stack/tsm.h b/bacnet-stack/tsm.h index 19529196..14fa6325 100644 --- a/bacnet-stack/tsm.h +++ b/bacnet-stack/tsm.h @@ -42,81 +42,72 @@ /* note: TSM functionality is optional - only needed if we are doing client requests */ #if TSM_ENABLED -typedef enum -{ - TSM_STATE_IDLE, - TSM_STATE_AWAIT_CONFIRMATION, - TSM_STATE_AWAIT_RESPONSE, - TSM_STATE_SEGMENTED_REQUEST, - TSM_STATE_SEGMENTED_CONFIRMATION +typedef enum { + TSM_STATE_IDLE, + TSM_STATE_AWAIT_CONFIRMATION, + TSM_STATE_AWAIT_RESPONSE, + TSM_STATE_SEGMENTED_REQUEST, + TSM_STATE_SEGMENTED_CONFIRMATION } BACNET_TSM_STATE; // 5.4.1 Variables And Parameters // The following variables are defined for each instance of // Transaction State Machine: -typedef struct BACnet_TSM_Data -{ - // used to count APDU retries - uint8_t RetryCount; - // used to count segment retries - //uint8_t SegmentRetryCount; - // used to control APDU retries and the acceptance of server replies - //bool SentAllSegments; - // stores the sequence number of the last segment received in order - //uint8_t LastSequenceNumber; - // stores the sequence number of the first segment of - // a sequence of segments that fill a window - //uint8_t InitialSequenceNumber; - // stores the current window size - //uint8_t ActualWindowSize; - // stores the window size proposed by the segment sender - //uint8_t ProposedWindowSize; - // used to perform timeout on PDU segments - //uint8_t SegmentTimer; - // used to perform timeout on Confirmed Requests - // in milliseconds - uint16_t RequestTimer; - // unique id - uint8_t InvokeID; - // state that the TSM is in - BACNET_TSM_STATE state; - // the address we sent it to - BACNET_ADDRESS dest; - // copy of the PDU, should we need to send it again - uint8_t pdu[MAX_PDU]; - unsigned pdu_len; +typedef struct BACnet_TSM_Data { + // used to count APDU retries + uint8_t RetryCount; + // used to count segment retries + //uint8_t SegmentRetryCount; + // used to control APDU retries and the acceptance of server replies + //bool SentAllSegments; + // stores the sequence number of the last segment received in order + //uint8_t LastSequenceNumber; + // stores the sequence number of the first segment of + // a sequence of segments that fill a window + //uint8_t InitialSequenceNumber; + // stores the current window size + //uint8_t ActualWindowSize; + // stores the window size proposed by the segment sender + //uint8_t ProposedWindowSize; + // used to perform timeout on PDU segments + //uint8_t SegmentTimer; + // used to perform timeout on Confirmed Requests + // in milliseconds + uint16_t RequestTimer; + // unique id + uint8_t InvokeID; + // state that the TSM is in + BACNET_TSM_STATE state; + // the address we sent it to + BACNET_ADDRESS dest; + // copy of the PDU, should we need to send it again + uint8_t pdu[MAX_PDU]; + unsigned pdu_len; } BACNET_TSM_DATA; #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ -bool tsm_transaction_available(void); -uint8_t tsm_transaction_idle_count(void); -void tsm_timer_milliseconds(uint16_t milliseconds); + bool tsm_transaction_available(void); + uint8_t tsm_transaction_idle_count(void); + void tsm_timer_milliseconds(uint16_t milliseconds); // free the invoke ID when the reply comes back -void tsm_free_invoke_id(uint8_t invokeID); + void tsm_free_invoke_id(uint8_t invokeID); // use these in tandem -uint8_t tsm_next_free_invokeID(void); + uint8_t tsm_next_free_invokeID(void); // returns the same invoke ID that was given -void tsm_set_confirmed_unsegmented_transaction( - uint8_t invokeID, - BACNET_ADDRESS *dest, - uint8_t *pdu, - uint16_t pdu_len); + void tsm_set_confirmed_unsegmented_transaction(uint8_t invokeID, + BACNET_ADDRESS * dest, uint8_t * pdu, uint16_t pdu_len); // returns true if transaction is found -bool tsm_get_transaction_pdu( - uint8_t invokeID, - BACNET_ADDRESS *dest, - uint8_t *pdu, - uint16_t *pdu_len); + bool tsm_get_transaction_pdu(uint8_t invokeID, + BACNET_ADDRESS * dest, uint8_t * pdu, uint16_t * pdu_len); -bool tsm_invoke_id_free(uint8_t invokeID); + bool tsm_invoke_id_free(uint8_t invokeID); #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ /* define out any functions necessary for compile */ #else @@ -125,4 +116,3 @@ bool tsm_invoke_id_free(uint8_t invokeID); #endif #endif - diff --git a/bacnet-stack/whohas.c b/bacnet-stack/whohas.c index e9bdf204..af5b6294 100644 --- a/bacnet-stack/whohas.c +++ b/bacnet-stack/whohas.c @@ -39,137 +39,122 @@ /* encode service - use -1 for limit for unlimited */ -int whohas_encode_apdu( - uint8_t *apdu, - BACNET_WHO_HAS_DATA *data) +int whohas_encode_apdu(uint8_t * apdu, BACNET_WHO_HAS_DATA * data) { - int len = 0; // length of each encoding - int apdu_len = 0; // total length of the apdu, return value + int len = 0; // length of each encoding + int apdu_len = 0; // total length of the apdu, return value - if (apdu && data) { - apdu[0] = PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST; - apdu[1] = SERVICE_UNCONFIRMED_WHO_HAS; // service choice - apdu_len = 2; - // optional limits - must be used as a pair - if ((data->low_limit >= 0) && (data->low_limit <= BACNET_MAX_INSTANCE) && - (data->high_limit >= 0) && (data->high_limit <= BACNET_MAX_INSTANCE)) - { - len = encode_context_unsigned( - &apdu[apdu_len], - 0, - data->low_limit); - apdu_len += len; - len = encode_context_unsigned( - &apdu[apdu_len], - 1, - data->high_limit); - apdu_len += len; + if (apdu && data) { + apdu[0] = PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST; + apdu[1] = SERVICE_UNCONFIRMED_WHO_HAS; // service choice + apdu_len = 2; + // optional limits - must be used as a pair + if ((data->low_limit >= 0) + && (data->low_limit <= BACNET_MAX_INSTANCE) + && (data->high_limit >= 0) + && (data->high_limit <= BACNET_MAX_INSTANCE)) { + len = + encode_context_unsigned(&apdu[apdu_len], 0, + data->low_limit); + apdu_len += len; + len = encode_context_unsigned(&apdu[apdu_len], + 1, data->high_limit); + apdu_len += len; + } + if (data->object_name) { + len = encode_context_character_string(&apdu[apdu_len], + 3, &data->object.name); + apdu_len += len; + } else { + len = encode_context_object_id(&apdu[apdu_len], + 2, + data->object.identifier.type, + data->object.identifier.instance); + apdu_len += len; + } } - if (data->object_name) - { - len = encode_context_character_string( - &apdu[apdu_len], - 3, - &data->object.name); - apdu_len += len; - } - else - { - len = encode_context_object_id( - &apdu[apdu_len], - 2, - data->object.identifier.type, - data->object.identifier.instance); - apdu_len += len; - } - } - return apdu_len; + return apdu_len; } // decode the service request only -int whohas_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - BACNET_WHO_HAS_DATA *data) +int whohas_decode_service_request(uint8_t * apdu, + unsigned apdu_len, BACNET_WHO_HAS_DATA * data) { - int len = 0; - uint8_t tag_number = 0; - uint32_t len_value = 0; - uint32_t decoded_value = 0; /* for decoding */ - int decoded_type = 0; /* for decoding */ + int len = 0; + uint8_t tag_number = 0; + uint32_t len_value = 0; + uint32_t decoded_value = 0; /* for decoding */ + int decoded_type = 0; /* for decoding */ - if (apdu_len && data) - { - /* optional limits - must be used as a pair */ - if (decode_is_context_tag(&apdu[len], 0)) - { - len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); - len += decode_unsigned(&apdu[len], len_value, &decoded_value); - if (decoded_value <= BACNET_MAX_INSTANCE) - data->low_limit = decoded_value; - if (!decode_is_context_tag(&apdu[len], 1)) - return -1; - len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); - len += decode_unsigned(&apdu[len], - len_value, &decoded_value); - if (decoded_value <= BACNET_MAX_INSTANCE) - data->high_limit = decoded_value; + if (apdu_len && data) { + /* optional limits - must be used as a pair */ + if (decode_is_context_tag(&apdu[len], 0)) { + len += + decode_tag_number_and_value(&apdu[len], &tag_number, + &len_value); + len += decode_unsigned(&apdu[len], len_value, &decoded_value); + if (decoded_value <= BACNET_MAX_INSTANCE) + data->low_limit = decoded_value; + if (!decode_is_context_tag(&apdu[len], 1)) + return -1; + len += + decode_tag_number_and_value(&apdu[len], &tag_number, + &len_value); + len += decode_unsigned(&apdu[len], len_value, &decoded_value); + if (decoded_value <= BACNET_MAX_INSTANCE) + data->high_limit = decoded_value; + } else { + data->low_limit = -1; + data->high_limit = -1; + } + /* object id */ + if (decode_is_context_tag(&apdu[len], 2)) { + data->object_name = false; + len += + decode_tag_number_and_value(&apdu[len], &tag_number, + &len_value); + len += + decode_object_id(&apdu[len], &decoded_type, + &data->object.identifier.instance); + data->object.identifier.type = decoded_type; + } + /* object name */ + else if (decode_is_context_tag(&apdu[len], 3)) { + data->object_name = true; + len += + decode_tag_number_and_value(&apdu[len], &tag_number, + &len_value); + len += + decode_character_string(&apdu[len], len_value, + &data->object.name); + } + /* missing required parameters */ + else + return -1; } - else - { - data->low_limit = -1; - data->high_limit = -1; - } - /* object id */ - if (decode_is_context_tag(&apdu[len], 2)) - { - data->object_name = false; - len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); - len += decode_object_id(&apdu[len], &decoded_type, - &data->object.identifier.instance); - data->object.identifier.type = decoded_type; - } - /* object name */ - else if (decode_is_context_tag(&apdu[len], 3)) - { - data->object_name = true; - len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); - len += decode_character_string(&apdu[len], len_value, - &data->object.name); - } - /* missing required parameters */ - else - return -1; - } - return len; + return len; } -int whohas_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - BACNET_WHO_HAS_DATA *data) +int whohas_decode_apdu(uint8_t * apdu, + unsigned apdu_len, BACNET_WHO_HAS_DATA * data) { - int len = 0; + int len = 0; - if (!apdu) - return -1; - // optional checking - most likely was already done prior to this call - if (apdu[0] != PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST) - return -1; - if (apdu[1] != SERVICE_UNCONFIRMED_WHO_IS) - return -1; - // optional limits - must be used as a pair - if (apdu_len > 2) - { - len = whohas_decode_service_request( - &apdu[2], - apdu_len - 2, - data); - } + if (!apdu) + return -1; + // optional checking - most likely was already done prior to this call + if (apdu[0] != PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST) + return -1; + if (apdu[1] != SERVICE_UNCONFIRMED_WHO_IS) + return -1; + // optional limits - must be used as a pair + if (apdu_len > 2) { + len = whohas_decode_service_request(&apdu[2], apdu_len - 2, data); + } - return len; + return len; } #ifdef TEST @@ -177,84 +162,68 @@ int whohas_decode_apdu( #include #include "ctest.h" -void testWhoHasData(Test * pTest, BACNET_WHO_HAS_DATA *data) +void testWhoHasData(Test * pTest, BACNET_WHO_HAS_DATA * data) { - uint8_t apdu[480] = {0}; - int len = 0; - int apdu_len = 0; - BACNET_WHO_HAS_DATA test_data; + uint8_t apdu[480] = { 0 }; + int len = 0; + int apdu_len = 0; + BACNET_WHO_HAS_DATA test_data; - len = whohas_encode_apdu( - &apdu[0], - data); - ct_test(pTest, len != 0); - apdu_len = len; + len = whohas_encode_apdu(&apdu[0], data); + ct_test(pTest, len != 0); + apdu_len = len; - len = whohas_decode_apdu( - &apdu[0], - apdu_len, - &test_data); - ct_test(pTest, len != -1); - ct_test(pTest, test_data.low_limit == data->low_limit); - ct_test(pTest, test_data.high_limit == data->high_limit); - ct_test(pTest, test_data.object_name == data->object_name); - /* Object ID */ - if (data->object_name == false) - { - ct_test(pTest, test_data.object.identifier.type == - data->object.identifier.type); - ct_test(pTest, test_data.object.identifier.instance == - data->object.identifier.instance); - } - /* Object Name */ - else - { - ct_test(pTest, characterstring_same( - &test_data.object.name,&data->object.name)); - } + len = whohas_decode_apdu(&apdu[0], apdu_len, &test_data); + ct_test(pTest, len != -1); + ct_test(pTest, test_data.low_limit == data->low_limit); + ct_test(pTest, test_data.high_limit == data->high_limit); + ct_test(pTest, test_data.object_name == data->object_name); + /* Object ID */ + if (data->object_name == false) { + ct_test(pTest, test_data.object.identifier.type == + data->object.identifier.type); + ct_test(pTest, test_data.object.identifier.instance == + data->object.identifier.instance); + } + /* Object Name */ + else { + ct_test(pTest, characterstring_same(&test_data.object.name, + &data->object.name)); + } } void testWhoHas(Test * pTest) { - BACNET_WHO_HAS_DATA data; + BACNET_WHO_HAS_DATA data; - data.low_limit = -1; - data.high_limit = -1; - data.object_name = false; - data.object.identifier.type = OBJECT_ANALOG_INPUT; - data.object.identifier.instance = 1; - testWhoHasData(pTest,&data); + data.low_limit = -1; + data.high_limit = -1; + data.object_name = false; + data.object.identifier.type = OBJECT_ANALOG_INPUT; + data.object.identifier.instance = 1; + testWhoHasData(pTest, &data); - for ( - data.low_limit = 0; - data.low_limit <= BACNET_MAX_INSTANCE; - data.low_limit += (BACNET_MAX_INSTANCE/4)) - { - for ( - data.high_limit = 0; - data.high_limit <= BACNET_MAX_INSTANCE; - data.high_limit += (BACNET_MAX_INSTANCE/4)) - { - data.object_name = false; - for ( - data.object.identifier.type = OBJECT_ANALOG_INPUT; - data.object.identifier.type <= MAX_BACNET_OBJECT_TYPE; - data.object.identifier.type++) - { - for ( - data.object.identifier.instance = 1; - data.object.identifier.instance <= BACNET_MAX_INSTANCE; - data.object.identifier.instance <<= 1) - { - testWhoHasData(pTest,&data); + for (data.low_limit = 0; + data.low_limit <= BACNET_MAX_INSTANCE; + data.low_limit += (BACNET_MAX_INSTANCE / 4)) { + for (data.high_limit = 0; + data.high_limit <= BACNET_MAX_INSTANCE; + data.high_limit += (BACNET_MAX_INSTANCE / 4)) { + data.object_name = false; + for (data.object.identifier.type = OBJECT_ANALOG_INPUT; + data.object.identifier.type <= MAX_BACNET_OBJECT_TYPE; + data.object.identifier.type++) { + for (data.object.identifier.instance = 1; + data.object.identifier.instance <= BACNET_MAX_INSTANCE; + data.object.identifier.instance <<= 1) { + testWhoHasData(pTest, &data); + } + } + data.object_name = true; + characterstring_init_ansi(&data.object.name, "patricia"); + testWhoHasData(pTest, &data); } - } - data.object_name = true; - characterstring_init_ansi( - &data.object.name,"patricia"); - testWhoHasData(pTest,&data); } - } } #ifdef TEST_WHOHAS diff --git a/bacnet-stack/whohas.h b/bacnet-stack/whohas.h index 4743d135..22f81e35 100644 --- a/bacnet-stack/whohas.h +++ b/bacnet-stack/whohas.h @@ -38,45 +38,35 @@ #include #include "bacstr.h" -typedef struct BACnet_Who_Has_Data -{ - int32_t low_limit; /* deviceInstanceRange */ - int32_t high_limit; - bool object_name; /* true if a string */ - union - { - BACNET_OBJECT_ID identifier; - BACNET_CHARACTER_STRING name; - } object; +typedef struct BACnet_Who_Has_Data { + int32_t low_limit; /* deviceInstanceRange */ + int32_t high_limit; + bool object_name; /* true if a string */ + union { + BACNET_OBJECT_ID identifier; + BACNET_CHARACTER_STRING name; + } object; } BACNET_WHO_HAS_DATA; #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ // encode service - use -1 for limit if you want unlimited -int whohas_encode_apdu( - uint8_t *apdu, - BACNET_WHO_HAS_DATA *data); + int whohas_encode_apdu(uint8_t * apdu, BACNET_WHO_HAS_DATA * data); -int whohas_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - BACNET_WHO_HAS_DATA *data); + int whohas_decode_service_request(uint8_t * apdu, + unsigned apdu_len, BACNET_WHO_HAS_DATA * data); -int whohas_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - BACNET_WHO_HAS_DATA *data); + int whohas_decode_apdu(uint8_t * apdu, + unsigned apdu_len, BACNET_WHO_HAS_DATA * data); #ifdef TEST #include "ctest.h" -void testWhoHas(Test * pTest); + void testWhoHas(Test * pTest); #endif #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif - diff --git a/bacnet-stack/whois.c b/bacnet-stack/whois.c index 58537b03..9ae5ff19 100644 --- a/bacnet-stack/whois.c +++ b/bacnet-stack/whois.c @@ -37,103 +37,84 @@ #include "bacdef.h" // encode I-Am service - use -1 for limit if you want unlimited -int whois_encode_apdu( - uint8_t *apdu, - int32_t low_limit, - int32_t high_limit) +int whois_encode_apdu(uint8_t * apdu, + int32_t low_limit, int32_t high_limit) { - int len = 0; // length of each encoding - int apdu_len = 0; // total length of the apdu, return value + int len = 0; // length of each encoding + int apdu_len = 0; // total length of the apdu, return value - if (apdu) { - apdu[0] = PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST; - apdu[1] = SERVICE_UNCONFIRMED_WHO_IS; // service choice - apdu_len = 2; - // optional limits - must be used as a pair - if ((low_limit >= 0) && (low_limit <= BACNET_MAX_INSTANCE) && - (high_limit >= 0) && (high_limit <= BACNET_MAX_INSTANCE)) - { - len = encode_context_unsigned( - &apdu[apdu_len], - 0, - low_limit); - apdu_len += len; - len = encode_context_unsigned( - &apdu[apdu_len], - 1, - high_limit); - apdu_len += len; + if (apdu) { + apdu[0] = PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST; + apdu[1] = SERVICE_UNCONFIRMED_WHO_IS; // service choice + apdu_len = 2; + // optional limits - must be used as a pair + if ((low_limit >= 0) && (low_limit <= BACNET_MAX_INSTANCE) && + (high_limit >= 0) && (high_limit <= BACNET_MAX_INSTANCE)) { + len = encode_context_unsigned(&apdu[apdu_len], 0, low_limit); + apdu_len += len; + len = encode_context_unsigned(&apdu[apdu_len], 1, high_limit); + apdu_len += len; + } } - } - - return apdu_len; + + return apdu_len; } // decode the service request only -int whois_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - int32_t *pLow_limit, - int32_t *pHigh_limit) +int whois_decode_service_request(uint8_t * apdu, + unsigned apdu_len, int32_t * pLow_limit, int32_t * pHigh_limit) { - int len = 0; - uint8_t tag_number = 0; - uint32_t len_value = 0; - uint32_t decoded_value = 0; + int len = 0; + uint8_t tag_number = 0; + uint32_t len_value = 0; + uint32_t decoded_value = 0; - // optional limits - must be used as a pair - if (apdu_len) - { - len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); - if (tag_number != 0) - return -1; - len += decode_unsigned(&apdu[len], len_value, &decoded_value); - if (decoded_value <= BACNET_MAX_INSTANCE) - { - if (pLow_limit) - *pLow_limit = decoded_value; + // optional limits - must be used as a pair + if (apdu_len) { + len += + decode_tag_number_and_value(&apdu[len], &tag_number, + &len_value); + if (tag_number != 0) + return -1; + len += decode_unsigned(&apdu[len], len_value, &decoded_value); + if (decoded_value <= BACNET_MAX_INSTANCE) { + if (pLow_limit) + *pLow_limit = decoded_value; + } + len += + decode_tag_number_and_value(&apdu[len], &tag_number, + &len_value); + if (tag_number != 1) + return -1; + len += decode_unsigned(&apdu[len], len_value, &decoded_value); + if (decoded_value <= BACNET_MAX_INSTANCE) { + if (pHigh_limit) + *pHigh_limit = decoded_value; + } } - len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); - if (tag_number != 1) - return -1; - len += decode_unsigned(&apdu[len], - len_value, &decoded_value); - if (decoded_value <= BACNET_MAX_INSTANCE) - { - if (pHigh_limit) - *pHigh_limit = decoded_value; - } - } - - return len; + + return len; } -int whois_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - int32_t *pLow_limit, - int32_t *pHigh_limit) +int whois_decode_apdu(uint8_t * apdu, + unsigned apdu_len, int32_t * pLow_limit, int32_t * pHigh_limit) { - int len = 0; + int len = 0; - if (!apdu) - return -1; - // optional checking - most likely was already done prior to this call - if (apdu[0] != PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST) - return -1; - if (apdu[1] != SERVICE_UNCONFIRMED_WHO_IS) - return -1; - // optional limits - must be used as a pair - if (apdu_len > 2) - { - len = whois_decode_service_request( - &apdu[2], - apdu_len - 2, - pLow_limit, - pHigh_limit); - } - - return len; + if (!apdu) + return -1; + // optional checking - most likely was already done prior to this call + if (apdu[0] != PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST) + return -1; + if (apdu[1] != SERVICE_UNCONFIRMED_WHO_IS) + return -1; + // optional limits - must be used as a pair + if (apdu_len > 2) { + len = whois_decode_service_request(&apdu[2], + apdu_len - 2, pLow_limit, pHigh_limit); + } + + return len; } #ifdef TEST @@ -143,56 +124,40 @@ int whois_decode_apdu( void testWhoIs(Test * pTest) { - uint8_t apdu[480] = {0}; - int len = 0; - int apdu_len = 0; - int32_t low_limit = -1; - int32_t high_limit = -1; - int32_t test_low_limit = -1; - int32_t test_high_limit = -1; - - len = whois_encode_apdu( - &apdu[0], - low_limit, - high_limit); - ct_test(pTest, len != 0); - apdu_len = len; + uint8_t apdu[480] = { 0 }; + int len = 0; + int apdu_len = 0; + int32_t low_limit = -1; + int32_t high_limit = -1; + int32_t test_low_limit = -1; + int32_t test_high_limit = -1; - len = whois_decode_apdu( - &apdu[0], - apdu_len, - &test_low_limit, - &test_high_limit); - ct_test(pTest, len != -1); - ct_test(pTest, test_low_limit == low_limit); - ct_test(pTest, test_high_limit == high_limit); + len = whois_encode_apdu(&apdu[0], low_limit, high_limit); + ct_test(pTest, len != 0); + apdu_len = len; - for ( - low_limit = 0; - low_limit <= BACNET_MAX_INSTANCE; - low_limit += (BACNET_MAX_INSTANCE/4)) - { - for ( - high_limit = 0; - high_limit <= BACNET_MAX_INSTANCE; - high_limit += (BACNET_MAX_INSTANCE/4)) - { - len = whois_encode_apdu( - &apdu[0], - low_limit, - high_limit); - apdu_len = len; - ct_test(pTest, len != 0); - len = whois_decode_apdu( - &apdu[0], - apdu_len, - &test_low_limit, - &test_high_limit); - ct_test(pTest, len != -1); - ct_test(pTest, test_low_limit == low_limit); - ct_test(pTest, test_high_limit == high_limit); + len = whois_decode_apdu(&apdu[0], + apdu_len, &test_low_limit, &test_high_limit); + ct_test(pTest, len != -1); + ct_test(pTest, test_low_limit == low_limit); + ct_test(pTest, test_high_limit == high_limit); + + for (low_limit = 0; + low_limit <= BACNET_MAX_INSTANCE; + low_limit += (BACNET_MAX_INSTANCE / 4)) { + for (high_limit = 0; + high_limit <= BACNET_MAX_INSTANCE; + high_limit += (BACNET_MAX_INSTANCE / 4)) { + len = whois_encode_apdu(&apdu[0], low_limit, high_limit); + apdu_len = len; + ct_test(pTest, len != 0); + len = whois_decode_apdu(&apdu[0], + apdu_len, &test_low_limit, &test_high_limit); + ct_test(pTest, len != -1); + ct_test(pTest, test_low_limit == low_limit); + ct_test(pTest, test_high_limit == high_limit); + } } - } } #ifdef TEST_WHOIS diff --git a/bacnet-stack/whois.h b/bacnet-stack/whois.h index 97cdf584..d309d6ed 100644 --- a/bacnet-stack/whois.h +++ b/bacnet-stack/whois.h @@ -39,33 +39,23 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ // encode service - use -1 for limit if you want unlimited -int whois_encode_apdu( - uint8_t *apdu, - int32_t low_limit, - int32_t high_limit); + int whois_encode_apdu(uint8_t * apdu, + int32_t low_limit, int32_t high_limit); -int whois_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - int32_t *pLow_limit, - int32_t *pHigh_limit); - -int whois_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - int32_t *pLow_limit, - int32_t *pHigh_limit); + int whois_decode_service_request(uint8_t * apdu, + unsigned apdu_len, int32_t * pLow_limit, int32_t * pHigh_limit); + + int whois_decode_apdu(uint8_t * apdu, + unsigned apdu_len, int32_t * pLow_limit, int32_t * pHigh_limit); #ifdef TEST -void testWhoIs(Test * pTest); + void testWhoIs(Test * pTest); #endif #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif - diff --git a/bacnet-stack/wp.c b/bacnet-stack/wp.c index e5c258d8..c70ed161 100644 --- a/bacnet-stack/wp.c +++ b/bacnet-stack/wp.c @@ -39,153 +39,138 @@ #include "wp.h" // encode service -int wp_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - BACNET_WRITE_PROPERTY_DATA *data) +int wp_encode_apdu(uint8_t * apdu, + uint8_t invoke_id, BACNET_WRITE_PROPERTY_DATA * data) { - int apdu_len = 0; // total length of the apdu, return value + int apdu_len = 0; // total length of the apdu, return value - if (apdu) - { - apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST; - apdu[1] = encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); - apdu[2] = invoke_id; - apdu[3] = SERVICE_CONFIRMED_WRITE_PROPERTY; // service choice - apdu_len = 4; - apdu_len += encode_context_object_id(&apdu[apdu_len], 0, - data->object_type, data->object_instance); - apdu_len += encode_context_enumerated(&apdu[apdu_len], 1, - data->object_property); - /* optional array index; ALL is -1 which is assumed when missing */ - if (data->array_index != BACNET_ARRAY_ALL) - apdu_len += encode_context_unsigned(&apdu[apdu_len], 2, - data->array_index); - // propertyValue - apdu_len += encode_opening_tag(&apdu[apdu_len], 3); - apdu_len += bacapp_encode_application_data(&apdu[apdu_len], &data->value); - apdu_len += encode_closing_tag(&apdu[apdu_len], 3); - // optional priority - 0 if not set, 1..16 if set - if (data->priority != BACNET_NO_PRIORITY) - apdu_len += encode_context_unsigned(&apdu[apdu_len], 4, - data->priority); - } - - return apdu_len; + if (apdu) { + apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST; + apdu[1] = + encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); + apdu[2] = invoke_id; + apdu[3] = SERVICE_CONFIRMED_WRITE_PROPERTY; // service choice + apdu_len = 4; + apdu_len += encode_context_object_id(&apdu[apdu_len], 0, + data->object_type, data->object_instance); + apdu_len += encode_context_enumerated(&apdu[apdu_len], 1, + data->object_property); + /* optional array index; ALL is -1 which is assumed when missing */ + if (data->array_index != BACNET_ARRAY_ALL) + apdu_len += encode_context_unsigned(&apdu[apdu_len], 2, + data->array_index); + // propertyValue + apdu_len += encode_opening_tag(&apdu[apdu_len], 3); + apdu_len += + bacapp_encode_application_data(&apdu[apdu_len], &data->value); + apdu_len += encode_closing_tag(&apdu[apdu_len], 3); + // optional priority - 0 if not set, 1..16 if set + if (data->priority != BACNET_NO_PRIORITY) + apdu_len += encode_context_unsigned(&apdu[apdu_len], 4, + data->priority); + } + + return apdu_len; } /* decode the service request only */ /* FIXME: there could be various error messages returned using unique values less than zero */ -int wp_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - BACNET_WRITE_PROPERTY_DATA *data) +int wp_decode_service_request(uint8_t * apdu, + unsigned apdu_len, BACNET_WRITE_PROPERTY_DATA * data) { - int len = 0; - int tag_len = 0; - uint8_t tag_number = 0; - uint32_t len_value_type = 0; - int type = 0; // for decoding - int property = 0; // for decoding - uint32_t unsigned_value = 0; + int len = 0; + int tag_len = 0; + uint8_t tag_number = 0; + uint32_t len_value_type = 0; + int type = 0; // for decoding + int property = 0; // for decoding + uint32_t unsigned_value = 0; - // check for value pointers - if (apdu_len && data) - { - // Tag 0: Object ID - if (!decode_is_context_tag(&apdu[len++], 0)) - return -1; - len += decode_object_id(&apdu[len], &type, &data->object_instance); - data->object_type = type; - // Tag 1: Property ID - len += decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - if (tag_number != 1) - return -1; - len += decode_enumerated(&apdu[len], len_value_type, &property); - data->object_property = property; - // Tag 2: Optional Array Index - // note: decode without incrementing len so we can check for opening tag - tag_len = decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - if (tag_number == 2) - { - len += tag_len; - len += decode_unsigned(&apdu[len], len_value_type, - &unsigned_value); - data->array_index = unsigned_value; - } - else - data->array_index = BACNET_ARRAY_ALL; - // Tag 3: opening context tag */ - if (!decode_is_opening_tag_number(&apdu[len], 3)) - return -1; - // a tag number of 3 is not extended so only one octet - len++; - len += bacapp_decode_application_data( - &apdu[len], - apdu_len - len, - &data->value); - /* FIXME: check the return value; abort if no valid data? */ - /* FIXME: there might be more than one data element in here! */ - if (!decode_is_closing_tag_number(&apdu[len], 3)) - return -1; - // a tag number of 3 is not extended so only one octet - len++; - // Tag 4: optional Priority - assumed MAX if not explicitly set - data->priority = BACNET_MAX_PRIORITY; - if ((unsigned)len < apdu_len) - { - tag_len = decode_tag_number_and_value(&apdu[len], - &tag_number, &len_value_type); - if (tag_number == 4) - { - len += tag_len; - len = decode_unsigned(&apdu[len], len_value_type, &unsigned_value); - if ((unsigned_value >= BACNET_MIN_PRIORITY) && - (unsigned_value <= BACNET_MAX_PRIORITY)) - { - data->priority = (uint8_t)unsigned_value; + // check for value pointers + if (apdu_len && data) { + // Tag 0: Object ID + if (!decode_is_context_tag(&apdu[len++], 0)) + return -1; + len += decode_object_id(&apdu[len], &type, &data->object_instance); + data->object_type = type; + // Tag 1: Property ID + len += decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + if (tag_number != 1) + return -1; + len += decode_enumerated(&apdu[len], len_value_type, &property); + data->object_property = property; + // Tag 2: Optional Array Index + // note: decode without incrementing len so we can check for opening tag + tag_len = decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + if (tag_number == 2) { + len += tag_len; + len += decode_unsigned(&apdu[len], len_value_type, + &unsigned_value); + data->array_index = unsigned_value; + } else + data->array_index = BACNET_ARRAY_ALL; + // Tag 3: opening context tag */ + if (!decode_is_opening_tag_number(&apdu[len], 3)) + return -1; + // a tag number of 3 is not extended so only one octet + len++; + len += bacapp_decode_application_data(&apdu[len], + apdu_len - len, &data->value); + /* FIXME: check the return value; abort if no valid data? */ + /* FIXME: there might be more than one data element in here! */ + if (!decode_is_closing_tag_number(&apdu[len], 3)) + return -1; + // a tag number of 3 is not extended so only one octet + len++; + // Tag 4: optional Priority - assumed MAX if not explicitly set + data->priority = BACNET_MAX_PRIORITY; + if ((unsigned) len < apdu_len) { + tag_len = decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value_type); + if (tag_number == 4) { + len += tag_len; + len = + decode_unsigned(&apdu[len], len_value_type, + &unsigned_value); + if ((unsigned_value >= BACNET_MIN_PRIORITY) + && (unsigned_value <= BACNET_MAX_PRIORITY)) { + data->priority = (uint8_t) unsigned_value; + } else + return -1; + } } - else - return -1; - } } - } - return len; + return len; } -int wp_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - BACNET_WRITE_PROPERTY_DATA *data) +int wp_decode_apdu(uint8_t * apdu, + unsigned apdu_len, + uint8_t * invoke_id, BACNET_WRITE_PROPERTY_DATA * data) { - int len = 0; - unsigned offset = 0; + int len = 0; + unsigned offset = 0; - if (!apdu) - return -1; - // optional checking - most likely was already done prior to this call - if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) - return -1; - // apdu[1] = encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); - *invoke_id = apdu[2]; /* invoke id - filled in by net layer */ - if (apdu[3] != SERVICE_CONFIRMED_WRITE_PROPERTY) - return -1; - offset = 4; + if (!apdu) + return -1; + // optional checking - most likely was already done prior to this call + if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) + return -1; + // apdu[1] = encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); + *invoke_id = apdu[2]; /* invoke id - filled in by net layer */ + if (apdu[3] != SERVICE_CONFIRMED_WRITE_PROPERTY) + return -1; + offset = 4; - if (apdu_len > offset) - { - len = wp_decode_service_request( - &apdu[offset], - apdu_len - offset, - data); - } - - return len; + if (apdu_len > offset) { + len = wp_decode_service_request(&apdu[offset], + apdu_len - offset, data); + } + + return len; } @@ -197,169 +182,159 @@ int wp_decode_apdu( #include #include "ctest.h" -void testWritePropertyTag(Test * pTest, - BACNET_WRITE_PROPERTY_DATA *data) +void testWritePropertyTag(Test * pTest, BACNET_WRITE_PROPERTY_DATA * data) { - BACNET_WRITE_PROPERTY_DATA test_data = {0}; - uint8_t apdu[480] = {0}; - int len = 0; - int apdu_len = 0; - uint8_t invoke_id = 128; - uint8_t test_invoke_id = 0; - - len = wp_encode_apdu( - &apdu[0], - invoke_id, - data); - ct_test(pTest, len != 0); - apdu_len = len; + BACNET_WRITE_PROPERTY_DATA test_data = { 0 }; + uint8_t apdu[480] = { 0 }; + int len = 0; + int apdu_len = 0; + uint8_t invoke_id = 128; + uint8_t test_invoke_id = 0; - len = wp_decode_apdu( - &apdu[0], - apdu_len, - &test_invoke_id, - &test_data); - ct_test(pTest, len != -1); - ct_test(pTest, test_data.object_type == data->object_type); - ct_test(pTest, test_data.object_instance == data->object_instance); - ct_test(pTest, test_data.object_property == data->object_property); - ct_test(pTest, test_data.array_index == data->array_index); - ct_test(pTest, test_data.value.tag == data->value.tag); - switch (test_data.value.tag) - { + len = wp_encode_apdu(&apdu[0], invoke_id, data); + ct_test(pTest, len != 0); + apdu_len = len; + + len = wp_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, &test_data); + ct_test(pTest, len != -1); + ct_test(pTest, test_data.object_type == data->object_type); + ct_test(pTest, test_data.object_instance == data->object_instance); + ct_test(pTest, test_data.object_property == data->object_property); + ct_test(pTest, test_data.array_index == data->array_index); + ct_test(pTest, test_data.value.tag == data->value.tag); + switch (test_data.value.tag) { case BACNET_APPLICATION_TAG_NULL: - break; + break; case BACNET_APPLICATION_TAG_BOOLEAN: - ct_test(pTest, test_data.value.type.Boolean == - data->value.type.Boolean); - break; + ct_test(pTest, test_data.value.type.Boolean == + data->value.type.Boolean); + break; case BACNET_APPLICATION_TAG_UNSIGNED_INT: - ct_test(pTest, test_data.value.type.Unsigned_Int == - data->value.type.Unsigned_Int); - break; + ct_test(pTest, test_data.value.type.Unsigned_Int == + data->value.type.Unsigned_Int); + break; case BACNET_APPLICATION_TAG_SIGNED_INT: - ct_test(pTest, test_data.value.type.Signed_Int == - data->value.type.Signed_Int); - break; + ct_test(pTest, test_data.value.type.Signed_Int == + data->value.type.Signed_Int); + break; case BACNET_APPLICATION_TAG_REAL: - ct_test(pTest, test_data.value.type.Real == - data->value.type.Real); - break; + ct_test(pTest, test_data.value.type.Real == data->value.type.Real); + break; case BACNET_APPLICATION_TAG_ENUMERATED: - ct_test(pTest, test_data.value.type.Enumerated == - data->value.type.Enumerated); - break; + ct_test(pTest, test_data.value.type.Enumerated == + data->value.type.Enumerated); + break; case BACNET_APPLICATION_TAG_DATE: - ct_test(pTest, test_data.value.type.Date.year == - data->value.type.Date.year); - ct_test(pTest, test_data.value.type.Date.month == - data->value.type.Date.month); - ct_test(pTest, test_data.value.type.Date.day == - data->value.type.Date.day); - ct_test(pTest, test_data.value.type.Date.wday == - data->value.type.Date.wday); - break; + ct_test(pTest, test_data.value.type.Date.year == + data->value.type.Date.year); + ct_test(pTest, test_data.value.type.Date.month == + data->value.type.Date.month); + ct_test(pTest, test_data.value.type.Date.day == + data->value.type.Date.day); + ct_test(pTest, test_data.value.type.Date.wday == + data->value.type.Date.wday); + break; case BACNET_APPLICATION_TAG_TIME: - ct_test(pTest, test_data.value.type.Time.hour == - data->value.type.Time.hour); - ct_test(pTest, test_data.value.type.Time.min == - data->value.type.Time.min); - ct_test(pTest, test_data.value.type.Time.sec == - data->value.type.Time.sec); - ct_test(pTest, test_data.value.type.Time.hundredths == - data->value.type.Time.hundredths); - break; + ct_test(pTest, test_data.value.type.Time.hour == + data->value.type.Time.hour); + ct_test(pTest, test_data.value.type.Time.min == + data->value.type.Time.min); + ct_test(pTest, test_data.value.type.Time.sec == + data->value.type.Time.sec); + ct_test(pTest, test_data.value.type.Time.hundredths == + data->value.type.Time.hundredths); + break; case BACNET_APPLICATION_TAG_OBJECT_ID: - ct_test(pTest, test_data.value.type.Object_Id.type == - data->value.type.Object_Id.type); - ct_test(pTest, test_data.value.type.Object_Id.instance == - data->value.type.Object_Id.instance); - break; + ct_test(pTest, test_data.value.type.Object_Id.type == + data->value.type.Object_Id.type); + ct_test(pTest, test_data.value.type.Object_Id.instance == + data->value.type.Object_Id.instance); + break; default: - break; - } + break; + } } void testWriteProperty(Test * pTest) { - BACNET_WRITE_PROPERTY_DATA data = {0}; + BACNET_WRITE_PROPERTY_DATA data = { 0 }; - data.value.tag = BACNET_APPLICATION_TAG_NULL; - testWritePropertyTag(pTest, &data); + data.value.tag = BACNET_APPLICATION_TAG_NULL; + testWritePropertyTag(pTest, &data); - data.value.tag = BACNET_APPLICATION_TAG_BOOLEAN; - data.value.type.Boolean = true; - testWritePropertyTag(pTest, &data); - data.value.type.Boolean = false; - testWritePropertyTag(pTest, &data); + data.value.tag = BACNET_APPLICATION_TAG_BOOLEAN; + data.value.type.Boolean = true; + testWritePropertyTag(pTest, &data); + data.value.type.Boolean = false; + testWritePropertyTag(pTest, &data); - data.value.tag = BACNET_APPLICATION_TAG_UNSIGNED_INT; - data.value.type.Unsigned_Int = 0; - testWritePropertyTag(pTest, &data); - data.value.type.Unsigned_Int = 0xFFFF; - testWritePropertyTag(pTest, &data); - data.value.type.Unsigned_Int = 0xFFFFFFFF; - testWritePropertyTag(pTest, &data); + data.value.tag = BACNET_APPLICATION_TAG_UNSIGNED_INT; + data.value.type.Unsigned_Int = 0; + testWritePropertyTag(pTest, &data); + data.value.type.Unsigned_Int = 0xFFFF; + testWritePropertyTag(pTest, &data); + data.value.type.Unsigned_Int = 0xFFFFFFFF; + testWritePropertyTag(pTest, &data); - data.value.tag = BACNET_APPLICATION_TAG_SIGNED_INT; - data.value.type.Signed_Int = 0; - testWritePropertyTag(pTest, &data); - data.value.type.Signed_Int = -1; - testWritePropertyTag(pTest, &data); - data.value.type.Signed_Int = 32768; - testWritePropertyTag(pTest, &data); - data.value.type.Signed_Int = -32768; - testWritePropertyTag(pTest, &data); - - data.value.tag = BACNET_APPLICATION_TAG_REAL; - data.value.type.Real = 0.0; - testWritePropertyTag(pTest, &data); - data.value.type.Real = -1.0; - testWritePropertyTag(pTest, &data); - data.value.type.Real = 1.0; - testWritePropertyTag(pTest, &data); - data.value.type.Real = 3.14159; - testWritePropertyTag(pTest, &data); - data.value.type.Real = -3.14159; - testWritePropertyTag(pTest, &data); - - data.value.tag = BACNET_APPLICATION_TAG_ENUMERATED; - data.value.type.Enumerated = 0; - testWritePropertyTag(pTest, &data); - data.value.type.Enumerated = 0xFFFF; - testWritePropertyTag(pTest, &data); - data.value.type.Enumerated = 0xFFFFFFFF; - testWritePropertyTag(pTest, &data); - - data.value.tag = BACNET_APPLICATION_TAG_DATE; - data.value.type.Date.year = 2005; - data.value.type.Date.month = 5; - data.value.type.Date.day = 22; - data.value.type.Date.wday = 1; - testWritePropertyTag(pTest, &data); + data.value.tag = BACNET_APPLICATION_TAG_SIGNED_INT; + data.value.type.Signed_Int = 0; + testWritePropertyTag(pTest, &data); + data.value.type.Signed_Int = -1; + testWritePropertyTag(pTest, &data); + data.value.type.Signed_Int = 32768; + testWritePropertyTag(pTest, &data); + data.value.type.Signed_Int = -32768; + testWritePropertyTag(pTest, &data); - data.value.tag = BACNET_APPLICATION_TAG_TIME; - data.value.type.Time.hour = 23; - data.value.type.Time.min = 59; - data.value.type.Time.sec = 59; - data.value.type.Time.hundredths = 12; - testWritePropertyTag(pTest, &data); + data.value.tag = BACNET_APPLICATION_TAG_REAL; + data.value.type.Real = 0.0; + testWritePropertyTag(pTest, &data); + data.value.type.Real = -1.0; + testWritePropertyTag(pTest, &data); + data.value.type.Real = 1.0; + testWritePropertyTag(pTest, &data); + data.value.type.Real = 3.14159; + testWritePropertyTag(pTest, &data); + data.value.type.Real = -3.14159; + testWritePropertyTag(pTest, &data); - data.value.tag = BACNET_APPLICATION_TAG_OBJECT_ID; - data.value.type.Object_Id.type = OBJECT_ANALOG_INPUT; - data.value.type.Object_Id.instance = 0; - testWritePropertyTag(pTest, &data); - data.value.type.Object_Id.type = OBJECT_LIFE_SAFETY_ZONE; - data.value.type.Object_Id.instance = BACNET_MAX_INSTANCE; - testWritePropertyTag(pTest, &data); + data.value.tag = BACNET_APPLICATION_TAG_ENUMERATED; + data.value.type.Enumerated = 0; + testWritePropertyTag(pTest, &data); + data.value.type.Enumerated = 0xFFFF; + testWritePropertyTag(pTest, &data); + data.value.type.Enumerated = 0xFFFFFFFF; + testWritePropertyTag(pTest, &data); - return; + data.value.tag = BACNET_APPLICATION_TAG_DATE; + data.value.type.Date.year = 2005; + data.value.type.Date.month = 5; + data.value.type.Date.day = 22; + data.value.type.Date.wday = 1; + testWritePropertyTag(pTest, &data); + + data.value.tag = BACNET_APPLICATION_TAG_TIME; + data.value.type.Time.hour = 23; + data.value.type.Time.min = 59; + data.value.type.Time.sec = 59; + data.value.type.Time.hundredths = 12; + testWritePropertyTag(pTest, &data); + + data.value.tag = BACNET_APPLICATION_TAG_OBJECT_ID; + data.value.type.Object_Id.type = OBJECT_ANALOG_INPUT; + data.value.type.Object_Id.instance = 0; + testWritePropertyTag(pTest, &data); + data.value.type.Object_Id.type = OBJECT_LIFE_SAFETY_ZONE; + data.value.type.Object_Id.instance = BACNET_MAX_INSTANCE; + testWritePropertyTag(pTest, &data); + + return; } #ifdef TEST_WRITE_PROPERTY uint16_t Device_Max_APDU_Length_Accepted(void) { - return MAX_APDU; + return MAX_APDU; } int main(void) diff --git a/bacnet-stack/wp.h b/bacnet-stack/wp.h index 07aae862..2a30fd2f 100644 --- a/bacnet-stack/wp.h +++ b/bacnet-stack/wp.h @@ -39,49 +39,40 @@ #include "bacdcode.h" #include "bacapp.h" -typedef struct BACnet_Write_Property_Data -{ - BACNET_OBJECT_TYPE object_type; - uint32_t object_instance; - BACNET_PROPERTY_ID object_property; - int32_t array_index; // use BACNET_ARRAY_ALL when not setting - BACNET_APPLICATION_DATA_VALUE value; - uint8_t priority; // use 0 if not setting the priority +typedef struct BACnet_Write_Property_Data { + BACNET_OBJECT_TYPE object_type; + uint32_t object_instance; + BACNET_PROPERTY_ID object_property; + int32_t array_index; // use BACNET_ARRAY_ALL when not setting + BACNET_APPLICATION_DATA_VALUE value; + uint8_t priority; // use 0 if not setting the priority } BACNET_WRITE_PROPERTY_DATA; #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ // encode service -int wp_encode_apdu( - uint8_t *apdu, - uint8_t invoke_id, - BACNET_WRITE_PROPERTY_DATA *data); + int wp_encode_apdu(uint8_t * apdu, + uint8_t invoke_id, BACNET_WRITE_PROPERTY_DATA * data); // decode the service request only -int wp_decode_service_request( - uint8_t *apdu, - unsigned apdu_len, - BACNET_WRITE_PROPERTY_DATA *data); - -int wp_decode_apdu( - uint8_t *apdu, - unsigned apdu_len, - uint8_t *invoke_id, - BACNET_WRITE_PROPERTY_DATA *data); + int wp_decode_service_request(uint8_t * apdu, + unsigned apdu_len, BACNET_WRITE_PROPERTY_DATA * data); + + int wp_decode_apdu(uint8_t * apdu, + unsigned apdu_len, + uint8_t * invoke_id, BACNET_WRITE_PROPERTY_DATA * data); + - #ifdef TEST #include "ctest.h" -void test_ReadProperty(Test * pTest); -void test_ReadPropertyAck(Test * pTest); + void test_ReadProperty(Test * pTest); + void test_ReadPropertyAck(Test * pTest); #endif #ifdef __cplusplus } -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif -