diff --git a/CMakeLists.txt b/CMakeLists.txt index 10648a9f..a5bf9c1a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,11 @@ option( "compile with ipv6 support" OFF) +option( + BACDL_NONE + "compile without datalink" + OFF) + set(BACNET_PROTOCOL_REVISION 19) message(STATUS "BACNET: using cmake ${CMAKE_VERSION}") @@ -68,6 +73,7 @@ message(STATUS "BACNET: BACDL_BIP \"${BACDL_BIP}\"") message(STATUS "BACNET: BACDL_ARCNET \"${BACDL_ARCNET}\"") message(STATUS "BACNET: BACDL_MSTP \"${BACDL_MSTP}\"") message(STATUS "BACNET: BACDL_ETHERNET \"${BACDL_ETHERNET}\"") +message(STATUS "BACNET: BACDL_NONE \"${BACDL_NONE}\"") # # sources @@ -141,6 +147,7 @@ set(BACNETSTACK_SRCS src/bacnet/basic/object/access_user.h src/bacnet/basic/object/access_zone.c src/bacnet/basic/object/access_zone.h + src/bacnet/basic/object/acc.c src/bacnet/basic/object/ai.c src/bacnet/basic/object/ai.h src/bacnet/basic/object/ao.c @@ -456,9 +463,7 @@ if(WIN32) $<$:ports/win32/ethernet.c> ports/win32/mstimer-init.c $<$:ports/win32/rs485.c> - $<$:ports/win32/rs485.h> - ports/win32/stdbool.h - ports/win32/stdint.h) + $<$:ports/win32/rs485.h>) endif() if(APPLE) @@ -498,6 +503,7 @@ target_compile_definitions( $<$:BACDL_ARCNET> $<$:BACDL_MSTP> $<$:BACDL_ETHERNET> + $<$:BACDL_NONE> $<$:BACNET_PROPERTY_LISTS> PRIVATE -DPRINT_ENABLED=1) diff --git a/apps/gateway/Makefile b/apps/gateway/Makefile index 0592ce73..d1f09704 100644 --- a/apps/gateway/Makefile +++ b/apps/gateway/Makefile @@ -12,6 +12,7 @@ TARGET_BIN = ${TARGET}$(TARGET_EXT) BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object SRC = main.c \ $(BACNET_OBJECT_DIR)/gateway/gw_device.c \ + $(BACNET_OBJECT_DIR)/acc.c \ $(BACNET_OBJECT_DIR)/ai.c \ $(BACNET_OBJECT_DIR)/ao.c \ $(BACNET_OBJECT_DIR)/av.c \ diff --git a/apps/server/Makefile b/apps/server/Makefile index aa63741a..795c8fb4 100644 --- a/apps/server/Makefile +++ b/apps/server/Makefile @@ -34,6 +34,7 @@ SRC = main.c \ $(BACNET_OBJECT_DIR)/access_user.c \ $(BACNET_OBJECT_DIR)/access_zone.c \ $(BACNET_OBJECT_DIR)/credential_data_input.c \ + $(BACNET_OBJECT_DIR)/acc.c \ $(BACNET_OBJECT_DIR)/bacfile.c BACNET_BASIC_SRC += \ diff --git a/ports/arduino_uno/stdint.h b/ports/arduino_uno/stdint.h index 874f309d..afc7867f 100644 --- a/ports/arduino_uno/stdint.h +++ b/ports/arduino_uno/stdint.h @@ -12,4 +12,16 @@ typedef signed short int16_t; /* 2 bytes -32767 to 32767 */ typedef unsigned long uint32_t; /* 4 bytes 0 to 4294967295 */ typedef signed long int32_t; /* 4 bytes -2147483647 to 2147483647 */ +#define INT8_MIN (-128) +#define INT16_MIN (-32768) +#define INT32_MIN (-2147483647 - 1) + +#define INT8_MAX 127 +#define INT16_MAX 32767 +#define INT32_MAX 2147483647 + +#define UINT8_MAX 0xff /* 255U */ +#define UINT16_MAX 0xffff /* 65535U */ +#define UINT32_MAX 0xffffffff /* 4294967295U */ + #endif /* STDINT_H */ diff --git a/ports/atmega168/stdbool.h b/ports/atmega168/stdbool.h deleted file mode 100644 index 39c1c286..00000000 --- a/ports/atmega168/stdbool.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef STDBOOL_H -#define STDBOOL_H - -/* C99 Boolean types for compilers without C99 support */ - -#ifndef __cplusplus -/* typedef char _Bool; */ -#ifndef bool -#define bool _Bool -#endif -#ifndef true -#define true 1 -#endif -#ifndef false -#define false 0 -#endif -#define __bool_true_false_are_defined 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#endif diff --git a/ports/atmega168/stdint.h b/ports/atmega168/stdint.h deleted file mode 100644 index 874f309d..00000000 --- a/ports/atmega168/stdint.h +++ /dev/null @@ -1,15 +0,0 @@ -/* Defines the standard integer types that are used in code */ - -#ifndef STDINT_H -#define STDINT_H 1 - -#include - -typedef unsigned char uint8_t; /* 1 byte 0 to 255 */ -typedef signed char int8_t; /* 1 byte -127 to 127 */ -typedef unsigned short uint16_t; /* 2 bytes 0 to 65535 */ -typedef signed short int16_t; /* 2 bytes -32767 to 32767 */ -typedef unsigned long uint32_t; /* 4 bytes 0 to 4294967295 */ -typedef signed long int32_t; /* 4 bytes -2147483647 to 2147483647 */ - -#endif /* STDINT_H */ diff --git a/ports/pic18f6720/stdint.h b/ports/pic18f6720/stdint.h index c6426c17..84e6d12f 100644 --- a/ports/pic18f6720/stdint.h +++ b/ports/pic18f6720/stdint.h @@ -15,4 +15,16 @@ typedef signed long int32_t; /* 4 bytes -2147483647 to 2147483647 */ /* typedef signed long long int64_t; */ /* typedef unsigned long long uint64_t; */ +#define INT8_MIN (-128) +#define INT16_MIN (-32768) +#define INT32_MIN (-2147483647 - 1) + +#define INT8_MAX 127 +#define INT16_MAX 32767 +#define INT32_MAX 2147483647 + +#define UINT8_MAX 0xff /* 255U */ +#define UINT16_MAX 0xffff /* 65535U */ +#define UINT32_MAX 0xffffffff /* 4294967295U */ + #endif /* STDINT_H */ diff --git a/ports/pic18f97j60/stdint.h b/ports/pic18f97j60/stdint.h index c6426c17..84e6d12f 100644 --- a/ports/pic18f97j60/stdint.h +++ b/ports/pic18f97j60/stdint.h @@ -15,4 +15,16 @@ typedef signed long int32_t; /* 4 bytes -2147483647 to 2147483647 */ /* typedef signed long long int64_t; */ /* typedef unsigned long long uint64_t; */ +#define INT8_MIN (-128) +#define INT16_MIN (-32768) +#define INT32_MIN (-2147483647 - 1) + +#define INT8_MAX 127 +#define INT16_MAX 32767 +#define INT32_MAX 2147483647 + +#define UINT8_MAX 0xff /* 255U */ +#define UINT16_MAX 0xffff /* 65535U */ +#define UINT32_MAX 0xffffffff /* 4294967295U */ + #endif /* STDINT_H */ diff --git a/ports/win32/stdbool.h b/ports/win32/stdbool.h deleted file mode 100644 index f7bccff5..00000000 --- a/ports/win32/stdbool.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _STDBOOL_H -#define _STDBOOL_H - -#include - -/* C99 Boolean types for compilers without C99 support */ -/* http://www.opengroup.org/onlinepubs/009695399/basedefs/stdbool.h.html */ - -#if !defined(__cplusplus) - -#if !defined(__GNUC__) -/* _Bool builtin type is included in GCC */ -/* ISO C Standard: 5.2.5 An object declared as - type _Bool is large enough to store - the values 0 and 1. */ -/* We choose 8 bit to match C++ */ -/* It must also promote to integer */ -#if _MSC_VER < 1600 -typedef int8_t _Bool; -#endif /* _MSC_VER < 1600 VS 2010 and earlier */ -#endif - -/* ISO C Standard: 7.16 Boolean type */ -#define bool _Bool -#define true 1 -#define false 0 -#define __bool_true_false_are_defined 1 - -#endif - -#endif diff --git a/ports/win32/stdint.h b/ports/win32/stdint.h deleted file mode 100644 index face7314..00000000 --- a/ports/win32/stdint.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Defines the standard integer types that are used in code */ -/* for the x86 processor and Borland Compiler */ - -#ifndef _STDINT_H -#define _STDINT_H - -#include - -typedef unsigned char uint8_t; /* 1 byte 0 to 255 */ -typedef signed char int8_t; /* 1 byte -127 to 127 */ -typedef unsigned short uint16_t; /* 2 bytes 0 to 65535 */ -typedef signed short int16_t; /* 2 bytes -32767 to 32767 */ -/*typedef unsigned short long uint24_t; // 3 bytes 0 to 16777215 */ -typedef unsigned uint32_t; /* 4 bytes 0 to 4294967295 */ -typedef int int32_t; /* 4 bytes -2147483647 to 2147483647 */ -/* typedef signed long long int64_t; */ -/* typedef unsigned long long uint64_t; */ - -#define INT8_MIN (-128) -#define INT16_MIN (-32768) -#define INT32_MIN (-2147483647 - 1) - -#define INT8_MAX 127 -#define INT16_MAX 32767 -#define INT32_MAX 2147483647 - -#define UINT8_MAX 0xff /* 255U */ -#define UINT16_MAX 0xffff /* 65535U */ -#define UINT32_MAX 0xffffffff /* 4294967295U */ - -#endif /* STDINT_H */ diff --git a/src/bacnet/alarm_ack.c b/src/bacnet/alarm_ack.c index 70c24857..d8281b10 100644 --- a/src/bacnet/alarm_ack.c +++ b/src/bacnet/alarm_ack.c @@ -111,50 +111,51 @@ int alarm_ack_decode_service_request( uint8_t *apdu, unsigned apdu_len, BACNET_ALARM_ACK_DATA *data) { int len = 0; - int section_len; - uint32_t enumValue; + int section_len = 0; + uint32_t enum_value = 0; + BACNET_UNSIGNED_INTEGER unsigned_value = 0; (void)apdu_len; - if (-1 == - (section_len = decode_context_unsigned( - &apdu[len], 0, &data->ackProcessIdentifier))) { - return -1; + section_len = decode_context_unsigned(&apdu[len], 0, &unsigned_value); + if (section_len == BACNET_STATUS_ERROR) { + return BACNET_STATUS_ERROR; + } + data->ackProcessIdentifier = (uint32_t)unsigned_value; + len += section_len; + + section_len = decode_context_object_id(&apdu[len], 1, + &data->eventObjectIdentifier.type, + &data->eventObjectIdentifier.instance); + if (section_len == BACNET_STATUS_ERROR) { + return BACNET_STATUS_ERROR; } len += section_len; - if (-1 == - (section_len = decode_context_object_id(&apdu[len], 1, - &data->eventObjectIdentifier.type, - &data->eventObjectIdentifier.instance))) { - return -1; + section_len = decode_context_enumerated(&apdu[len], 2, &enum_value); + if (section_len == BACNET_STATUS_ERROR) { + return BACNET_STATUS_ERROR; + } + data->eventStateAcked = (BACNET_EVENT_STATE)enum_value; + len += section_len; + + section_len = + bacapp_decode_context_timestamp(&apdu[len], 3, &data->eventTimeStamp); + if (section_len == BACNET_STATUS_ERROR) { + return BACNET_STATUS_ERROR; } len += section_len; - if (-1 == - (section_len = decode_context_enumerated(&apdu[len], 2, &enumValue))) { - return -1; - } - data->eventStateAcked = (BACNET_EVENT_STATE)enumValue; - len += section_len; - - if (-1 == - (section_len = bacapp_decode_context_timestamp( - &apdu[len], 3, &data->eventTimeStamp))) { - return -1; + section_len = + decode_context_character_string(&apdu[len], 4, &data->ackSource); + if (section_len == BACNET_STATUS_ERROR) { + return BACNET_STATUS_ERROR; } len += section_len; - if (-1 == - (section_len = decode_context_character_string( - &apdu[len], 4, &data->ackSource))) { - return -1; - } - len += section_len; - - if (-1 == - (section_len = bacapp_decode_context_timestamp( - &apdu[len], 5, &data->ackTimeStamp))) { - return -1; + section_len = + bacapp_decode_context_timestamp(&apdu[len], 5, &data->ackTimeStamp); + if (section_len == BACNET_STATUS_ERROR) { + return BACNET_STATUS_ERROR; } len += section_len; diff --git a/src/bacnet/arf.h b/src/bacnet/arf.h index ce32040e..4dbee028 100644 --- a/src/bacnet/arf.h +++ b/src/bacnet/arf.h @@ -41,12 +41,12 @@ typedef struct BACnet_Atomic_Read_File_Data { union { struct { int32_t fileStartPosition; - uint32_t requestedOctetCount; + BACNET_UNSIGNED_INTEGER requestedOctetCount; } stream; struct { int32_t fileStartRecord; /* requested or returned record count */ - uint32_t RecordCount; + BACNET_UNSIGNED_INTEGER RecordCount; } record; } type; BACNET_OCTET_STRING fileData[BACNET_READ_FILE_RECORD_COUNT]; diff --git a/src/bacnet/authentication_factor.c b/src/bacnet/authentication_factor.c index a1687190..921b87c3 100644 --- a/src/bacnet/authentication_factor.c +++ b/src/bacnet/authentication_factor.c @@ -80,6 +80,7 @@ int bacapp_decode_authentication_factor( int len; int apdu_len = 0; uint32_t format_type = af->format_type; + BACNET_UNSIGNED_INTEGER unsigned_value = 0; if (decode_is_context_tag(&apdu[apdu_len], 0)) { len = decode_context_enumerated(&apdu[apdu_len], 0, &format_type); @@ -97,10 +98,11 @@ int bacapp_decode_authentication_factor( } if (decode_is_context_tag(&apdu[apdu_len], 1)) { - len = decode_context_unsigned(&apdu[apdu_len], 1, &af->format_class); + len = decode_context_unsigned(&apdu[apdu_len], 1, &unsigned_value); if (len < 0) { return -1; } else { + af->format_class = unsigned_value; apdu_len += len; } } else { diff --git a/src/bacnet/authentication_factor_format.c b/src/bacnet/authentication_factor_format.c index af296df1..b8afae93 100644 --- a/src/bacnet/authentication_factor_format.c +++ b/src/bacnet/authentication_factor_format.c @@ -81,6 +81,7 @@ int bacapp_decode_authentication_factor_format( int len; int apdu_len = 0; uint32_t format_type = aff->format_type; + BACNET_UNSIGNED_INTEGER unsigned_value = 0; if (decode_is_context_tag(&apdu[apdu_len], 0)) { len = decode_context_enumerated(&apdu[apdu_len], 0, &format_type); @@ -98,10 +99,11 @@ int bacapp_decode_authentication_factor_format( } if (decode_is_context_tag(&apdu[apdu_len], 1)) { - len = decode_context_unsigned(&apdu[apdu_len], 1, &aff->vendor_id); + len = decode_context_unsigned(&apdu[apdu_len], 1, &unsigned_value); if (len < 0) { return -1; } else { + aff->vendor_id = unsigned_value; apdu_len += len; } if ((aff->format_type != AUTHENTICATION_FACTOR_CUSTOM) && @@ -111,10 +113,11 @@ int bacapp_decode_authentication_factor_format( } if (decode_is_context_tag(&apdu[apdu_len], 2)) { - len = decode_context_unsigned(&apdu[apdu_len], 2, &aff->vendor_format); + len = decode_context_unsigned(&apdu[apdu_len], 2, &unsigned_value); if (len < 0) { return -1; } else { + aff->vendor_format = unsigned_value; apdu_len += len; } if ((aff->format_type != AUTHENTICATION_FACTOR_CUSTOM) && diff --git a/src/bacnet/awf.c b/src/bacnet/awf.c index 3fdd2eaa..9cb908d1 100644 --- a/src/bacnet/awf.c +++ b/src/bacnet/awf.c @@ -91,6 +91,7 @@ int awf_decode_service_request( int apdu_len = BACNET_STATUS_ERROR; BACNET_OBJECT_TYPE object_type = OBJECT_NONE; uint32_t object_instance = 0; + BACNET_UNSIGNED_INTEGER unsigned_value = 0; uint32_t i = 0; /* check for value pointers */ @@ -158,10 +159,11 @@ int awf_decode_service_request( return BACNET_STATUS_ERROR; } len = bacnet_unsigned_application_decode(&apdu[apdu_len], - apdu_len_max, &data->type.record.returnedRecordCount); + apdu_len_max, &unsigned_value); if (len <= 0) { return BACNET_STATUS_ERROR; } + data->type.record.returnedRecordCount = unsigned_value; apdu_len += len; if (apdu_len >= apdu_len_max) { return BACNET_STATUS_ERROR; diff --git a/src/bacnet/bacapp.h b/src/bacnet/bacapp.h index 5052789b..db230c00 100644 --- a/src/bacnet/bacapp.h +++ b/src/bacnet/bacapp.h @@ -28,6 +28,7 @@ #include #include #include "bacnet/bacdef.h" +#include "bacnet/bacint.h" #include "bacnet/bacstr.h" #include "bacnet/datetime.h" #if defined (BACAPP_LIGHTING_COMMAND) @@ -49,7 +50,7 @@ typedef struct BACnet_Application_Data_Value { bool Boolean; #endif #if defined (BACAPP_UNSIGNED) - uint32_t Unsigned_Int; + BACNET_UNSIGNED_INTEGER Unsigned_Int; #endif #if defined (BACAPP_SIGNED) int32_t Signed_Int; @@ -102,7 +103,8 @@ typedef struct BACnet_Access_Error { struct BACnet_Property_Reference; typedef struct BACnet_Property_Reference { BACNET_PROPERTY_ID propertyIdentifier; - uint32_t propertyArrayIndex; /* optional */ + /* optional array index */ + BACNET_ARRAY_INDEX propertyArrayIndex; /* either value or error, but not both. Use NULL value to indicate error */ BACNET_APPLICATION_DATA_VALUE *value; @@ -114,7 +116,7 @@ typedef struct BACnet_Property_Reference { struct BACnet_Property_Value; typedef struct BACnet_Property_Value { BACNET_PROPERTY_ID propertyIdentifier; - uint32_t propertyArrayIndex; + BACNET_ARRAY_INDEX propertyArrayIndex; BACNET_APPLICATION_DATA_VALUE value; uint8_t priority; /* simple linked list */ @@ -127,7 +129,7 @@ typedef struct BACnet_Object_Property_Value { BACNET_OBJECT_TYPE object_type; uint32_t object_instance; BACNET_PROPERTY_ID object_property; - uint32_t array_index; + BACNET_ARRAY_INDEX array_index; BACNET_APPLICATION_DATA_VALUE *value; } BACNET_OBJECT_PROPERTY_VALUE; diff --git a/src/bacnet/bacdcode.c b/src/bacnet/bacdcode.c index cbc3c44e..a690ea26 100644 --- a/src/bacnet/bacdcode.c +++ b/src/bacnet/bacdcode.c @@ -1314,10 +1314,14 @@ int decode_context_character_string( * @return number of bytes decoded, or zero if errors occur */ int bacnet_unsigned_decode( - uint8_t *apdu, uint16_t apdu_len_max, uint32_t len_value, uint32_t *value) + uint8_t *apdu, uint16_t apdu_len_max, uint32_t len_value, BACNET_UNSIGNED_INTEGER *value) { int len = 0; uint16_t unsigned16_value = 0; + uint32_t unsigned32_value = 0; +#ifdef UINT64_MAX + uint64_t unsigned64_value = 0; +#endif if (value && (len_value <= apdu_len_max)) { switch (len_value) { @@ -1331,13 +1335,37 @@ int bacnet_unsigned_decode( len = (int)len_value; break; case 3: - decode_unsigned24(&apdu[0], value); + decode_unsigned24(&apdu[0], &unsigned32_value); + *value = unsigned32_value; len = (int)len_value; break; case 4: - decode_unsigned32(&apdu[0], value); + decode_unsigned32(&apdu[0], &unsigned32_value); + *value = unsigned32_value; len = (int)len_value; break; +#ifdef UINT64_MAX + case 5: + decode_unsigned40(&apdu[0], &unsigned64_value); + *value = unsigned64_value; + len = (int)len_value; + break; + case 6: + decode_unsigned48(&apdu[0], &unsigned64_value); + *value = unsigned64_value; + len = (int)len_value; + break; + case 7: + decode_unsigned56(&apdu[0], &unsigned64_value); + *value = unsigned64_value; + len = (int)len_value; + break; + case 8: + decode_unsigned64(&apdu[0], &unsigned64_value); + *value = unsigned64_value; + len = (int)len_value; + break; +#endif default: *value = 0; break; @@ -1361,7 +1389,7 @@ int bacnet_unsigned_decode( * or error (-1) if malformed */ int bacnet_unsigned_context_decode( - uint8_t *apdu, uint16_t apdu_len_max, uint8_t tag_value, uint32_t *value) + uint8_t *apdu, uint16_t apdu_len_max, uint8_t tag_value, BACNET_UNSIGNED_INTEGER *value) { int apdu_len = 0; unsigned len = 0; @@ -1407,7 +1435,7 @@ int bacnet_unsigned_context_decode( * @return the number of apdu bytes consumed, or #BACNET_STATUS_ERROR (-1) */ int bacnet_unsigned_application_decode( - uint8_t *apdu, uint16_t apdu_len_max, uint32_t *value) + uint8_t *apdu, uint16_t apdu_len_max, BACNET_UNSIGNED_INTEGER *value) { int len = 0; int apdu_len = BACNET_STATUS_ERROR; @@ -1445,9 +1473,13 @@ int bacnet_unsigned_application_decode( * * @return number of bytes decoded, or zero if errors occur */ -int decode_unsigned(uint8_t *apdu, uint32_t len_value, uint32_t *value) +int decode_unsigned(uint8_t *apdu, uint32_t len_value, BACNET_UNSIGNED_INTEGER *value) { +#ifdef UINT64_MAX + const uint16_t apdu_len_max = 8; +#else const uint16_t apdu_len_max = 4; +#endif return bacnet_unsigned_decode(apdu, apdu_len_max, len_value, value); } @@ -1464,9 +1496,14 @@ int decode_unsigned(uint8_t *apdu, uint32_t len_value, uint32_t *value) * @return number of bytes decoded, #BACNET_STATUS_ERROR (-1) if * wrong tag number, or error (-1) if malformed */ -int decode_context_unsigned(uint8_t *apdu, uint8_t tag_value, uint32_t *value) +int decode_context_unsigned(uint8_t *apdu, uint8_t tag_value, + BACNET_UNSIGNED_INTEGER *value) { - const uint16_t apdu_len_max = 6; +#ifdef UINT64_MAX + const uint16_t apdu_len_max = 3+8; +#else + const uint16_t apdu_len_max = 2+4; +#endif int len = 0; len = bacnet_unsigned_context_decode(apdu, apdu_len_max, tag_value, value); @@ -1480,19 +1517,33 @@ int decode_context_unsigned(uint8_t *apdu, uint8_t tag_value, uint32_t *value) /* from clause 20.2.4 Encoding of an Unsigned Integer Value */ /* and 20.2.1 General Rules for Encoding BACnet Tags */ /* returns the number of apdu bytes consumed */ -int encode_bacnet_unsigned(uint8_t *apdu, uint32_t value) +int encode_bacnet_unsigned(uint8_t *apdu, BACNET_UNSIGNED_INTEGER value) { int len = 0; /* return value */ - if (value < 0x100) { + len = bacnet_unsigned_length(value); + if (len == 1) { apdu[0] = (uint8_t)value; - len = 1; - } else if (value < 0x10000) { - len = encode_unsigned16(&apdu[0], (uint16_t)value); - } else if (value < 0x1000000) { - len = encode_unsigned24(&apdu[0], value); + } else if (len == 2) { + (void)encode_unsigned16(&apdu[0], (uint16_t)value); + } else if (len == 3) { + (void)encode_unsigned24(&apdu[0], (uint32_t)value); } else { +#ifdef UINT64_MAX + if (len == 4) { + (void)encode_unsigned32(&apdu[0], (uint32_t)value); + } else if (len == 5) { + (void)encode_unsigned40(&apdu[0], value); + } else if (len == 6) { + (void)encode_unsigned48(&apdu[0], value); + } else if (len == 7) { + (void)encode_unsigned56(&apdu[0], value); + } else { + len = encode_unsigned64(&apdu[0], value); + } +#else len = encode_unsigned32(&apdu[0], value); +#endif } return len; @@ -1501,21 +1552,12 @@ int encode_bacnet_unsigned(uint8_t *apdu, uint32_t value) /* from clause 20.2.4 Encoding of an Unsigned Integer Value */ /* and 20.2.1 General Rules for Encoding BACnet Tags */ /* returns the number of apdu bytes consumed */ -int encode_context_unsigned(uint8_t *apdu, uint8_t tag_number, uint32_t value) +int encode_context_unsigned(uint8_t *apdu, uint8_t tag_number, BACNET_UNSIGNED_INTEGER value) { int len = 0; /* length of unsigned is variable, as per 20.2.4 */ - if (value < 0x100) { - len = 1; - } else if (value < 0x10000) { - len = 2; - } else if (value < 0x1000000) { - len = 3; - } else { - len = 4; - } - + len = bacnet_unsigned_length(value); len = encode_tag(&apdu[0], tag_number, true, (uint32_t)len); len += encode_bacnet_unsigned(&apdu[len], value); @@ -1525,13 +1567,14 @@ int encode_context_unsigned(uint8_t *apdu, uint8_t tag_number, uint32_t value) /* from clause 20.2.4 Encoding of an Unsigned Integer Value */ /* and 20.2.1 General Rules for Encoding BACnet Tags */ /* returns the number of apdu bytes consumed */ -int encode_application_unsigned(uint8_t *apdu, uint32_t value) +int encode_application_unsigned(uint8_t *apdu, BACNET_UNSIGNED_INTEGER value) { int len = 0; - len = encode_bacnet_unsigned(&apdu[1], value); - len += encode_tag( + len = bacnet_unsigned_length(value); + len = encode_tag( &apdu[0], BACNET_APPLICATION_TAG_UNSIGNED_INT, false, (uint32_t)len); + len += encode_bacnet_unsigned(&apdu[len], value); return len; } @@ -1551,7 +1594,15 @@ int encode_application_unsigned(uint8_t *apdu, uint32_t value) int bacnet_enumerated_decode( uint8_t *apdu, uint16_t apdu_len_max, uint32_t len_value, uint32_t *value) { - return bacnet_unsigned_decode(apdu, apdu_len_max, len_value, value); + BACNET_UNSIGNED_INTEGER unsigned_value = 0; + int len; + + len = bacnet_unsigned_decode(apdu, apdu_len_max, len_value, &unsigned_value); + if (len > 0) { + *value = unsigned_value; + } + + return len; } /** @@ -2339,7 +2390,7 @@ int decode_bacnet_address(uint8_t *apdu, BACNET_ADDRESS *destination) int tag_len = 0; uint32_t len_value_type = 0; uint8_t i = 0; - uint32_t data_unsigned = 0; + BACNET_UNSIGNED_INTEGER data_unsigned = 0; uint8_t tag_number = 0; BACNET_OCTET_STRING mac_addr = { 0 }; @@ -2351,7 +2402,7 @@ int decode_bacnet_address(uint8_t *apdu, BACNET_ADDRESS *destination) return BACNET_STATUS_ERROR; } len += decode_unsigned(&apdu[len], len_value_type, &data_unsigned); - destination->net = data_unsigned; + destination->net = (uint16_t)data_unsigned; /* encode mac address as an octet-string */ tag_len = decode_tag_number_and_value(&apdu[len], &tag_number, &len_value_type); @@ -2644,11 +2695,11 @@ static void testBACDCodeDouble(Test *pTest) return; } -static void testBACDCodeUnsignedValue(Test *pTest, uint32_t value) +static void testBACDCodeUnsignedValue(Test *pTest, BACNET_UNSIGNED_INTEGER value) { uint8_t array[5] = { 0 }; uint8_t encoded_array[5] = { 0 }; - uint32_t decoded_value = 0; + BACNET_UNSIGNED_INTEGER decoded_value = 0; int len; uint8_t apdu[MAX_APDU] = { 0 }; uint8_t tag_number = 0; @@ -2677,14 +2728,19 @@ static void testBACDCodeUnsignedValue(Test *pTest, uint32_t value) static void testBACDCodeUnsigned(Test *pTest) { +#ifdef UINT64_MAX + const unsigned max_bits = 64; +#else + const unsigned max_bits = 32; +#endif uint32_t value = 1; int i; - for (i = 0; i < 32; i++) { + for (i = 0; i < max_bits; i++) { testBACDCodeUnsignedValue(pTest, value - 1); testBACDCodeUnsignedValue(pTest, value); testBACDCodeUnsignedValue(pTest, value + 1); - value = value << 1; + value |= (value << 1); } return; @@ -2693,16 +2749,15 @@ static void testBACDCodeUnsigned(Test *pTest) static void testBACnetUnsigned(Test *pTest) { uint8_t apdu[32] = { 0 }; - uint32_t value = 0, test_value = 0; + BACNET_UNSIGNED_INTEGER value = 0, test_value = 0; int len = 0, test_len = 0; - for (value = 0;; value += 0xFF) { + for (value = 0; value == BACNET_UNSIGNED_INTEGER_MAX; + value = (value << 8) | 0xff) { len = encode_bacnet_unsigned(&apdu[0], value); test_len = decode_unsigned(&apdu[0], len, &test_value); ct_test(pTest, len == test_len); ct_test(pTest, value == test_value); - if (value == 0xFFFFFFFF) - break; } } @@ -3026,18 +3081,37 @@ static void testBACDCodeBitString(Test *pTest) static void testUnsignedContextDecodes(Test *pTest) { - uint8_t apdu[MAX_APDU]; - int inLen; - int outLen; - int outLen2; + uint8_t apdu[MAX_APDU] = { 0 }; + int inLen = 0; + int outLen = 0; + int outLen2 = 0; uint8_t large_context_tag = 0xfe; + BACNET_UNSIGNED_INTEGER in = 0xdeadbeef; + BACNET_UNSIGNED_INTEGER out = 0; - /* 32 bit number */ - uint32_t in = 0xdeadbeef; - uint32_t out; - + /* error, stack-overflow check */ outLen2 = decode_context_unsigned(apdu, 9, &out); +#ifdef UINT64_MAX + /* 64 bit number */ + in = 0xdeadbeefdeadbeef; + inLen = encode_context_unsigned(apdu, 10, in); + outLen = decode_context_unsigned(apdu, 10, &out); + + ct_test(pTest, inLen == outLen); + ct_test(pTest, in == out); + ct_test(pTest, outLen2 == BACNET_STATUS_ERROR); + + inLen = encode_context_unsigned(apdu, large_context_tag, in); + outLen = decode_context_unsigned(apdu, large_context_tag, &out); + outLen2 = decode_context_unsigned(apdu, large_context_tag - 1, &out); + + ct_test(pTest, inLen == outLen); + ct_test(pTest, in == out); + ct_test(pTest, outLen2 == BACNET_STATUS_ERROR); +#endif + + /* 32 bit number */ in = 0xdeadbeef; inLen = encode_context_unsigned(apdu, 10, in); outLen = decode_context_unsigned(apdu, 10, &out); diff --git a/src/bacnet/bacdcode.h b/src/bacnet/bacdcode.h index 374cbd73..f61c086e 100644 --- a/src/bacnet/bacdcode.h +++ b/src/bacnet/bacdcode.h @@ -288,37 +288,37 @@ extern "C" { /* returns the number of apdu bytes consumed */ int encode_bacnet_unsigned( uint8_t * apdu, - uint32_t value); + BACNET_UNSIGNED_INTEGER value); int encode_context_unsigned( uint8_t * apdu, uint8_t tag_number, - uint32_t value); + BACNET_UNSIGNED_INTEGER value); int encode_application_unsigned( uint8_t * apdu, - uint32_t value); + BACNET_UNSIGNED_INTEGER value); int decode_unsigned( uint8_t * apdu, uint32_t len_value, - uint32_t * value); + BACNET_UNSIGNED_INTEGER * value); int decode_context_unsigned( uint8_t * apdu, uint8_t tag_number, - uint32_t * value); + BACNET_UNSIGNED_INTEGER * value); int bacnet_unsigned_decode( uint8_t * apdu, uint16_t apdu_max_len, uint32_t len_value, - uint32_t * value); + BACNET_UNSIGNED_INTEGER * value); int bacnet_unsigned_application_decode( uint8_t * apdu, uint16_t apdu_len_max, - uint32_t * value); + BACNET_UNSIGNED_INTEGER * value); int bacnet_unsigned_context_decode( uint8_t * apdu, uint16_t apdu_len_max, uint8_t tag_number, - uint32_t * value); + BACNET_UNSIGNED_INTEGER * value); /* from clause 20.2.5 Encoding of a Signed Integer Value */ /* and 20.2.1 General Rules for Encoding BACnet Tags */ diff --git a/src/bacnet/bacdef.h b/src/bacnet/bacdef.h index 53ab29a1..bc355e9b 100644 --- a/src/bacnet/bacdef.h +++ b/src/bacnet/bacdef.h @@ -27,6 +27,7 @@ #include #include #include "bacnet/bacenum.h" +#include "bacnet/bacint.h" #include "bacnet/config.h" #if defined(_MSC_VER) @@ -122,8 +123,8 @@ /* large BACnet Object Type */ #define BACNET_MAX_OBJECT (0x3FF) /* Array index 0=size of array, n=array element n, MAX=all array elements */ -/* 32-bit MAX, to use with uint32_t */ -#define BACNET_ARRAY_ALL 0xFFFFFFFFU +#define BACNET_ARRAY_ALL UINT32_MAX +typedef uint32_t BACNET_ARRAY_INDEX; /* For device object property references with no device id defined */ #define BACNET_NO_DEV_ID 0xFFFFFFFFu #define BACNET_NO_DEV_TYPE OBJECT_NONE diff --git a/src/bacnet/bacdevobjpropref.h b/src/bacnet/bacdevobjpropref.h index ef81d474..f6c78a9f 100644 --- a/src/bacnet/bacdevobjpropref.h +++ b/src/bacnet/bacdevobjpropref.h @@ -28,11 +28,12 @@ #include #include #include "bacnet/bacdef.h" +#include "bacnet/bacint.h" #include "bacnet/bacenum.h" typedef struct BACnetDeviceObjectPropertyReference { /* number type first to avoid enum cast warning on = { 0 } */ - uint32_t arrayIndex; + BACNET_UNSIGNED_INTEGER arrayIndex; BACNET_OBJECT_ID objectIdentifier; BACNET_PROPERTY_ID propertyIdentifier; BACNET_OBJECT_ID deviceIdentifier; diff --git a/src/bacnet/bacint.c b/src/bacnet/bacint.c index cbd31ba6..8a2d030b 100644 --- a/src/bacnet/bacint.c +++ b/src/bacnet/bacint.c @@ -102,6 +102,135 @@ int decode_unsigned32(uint8_t *apdu, uint32_t *value) } #ifdef UINT64_MAX +/** + * @brief Encode a 40-bit unsigned value into buffer + * @param buffer - pointer to bytes for storing encoding + * @param value - 40-bit value to encode + * @return Returns the number of bytes encoded + */ +int encode_unsigned40(uint8_t *buffer, uint64_t value) +{ + buffer[0] = (uint8_t)((value & 0x000000ff00000000) >> 32); + buffer[1] = (uint8_t)((value & 0x00000000ff000000) >> 24); + buffer[2] = (uint8_t)((value & 0x0000000000ff0000) >> 16); + buffer[3] = (uint8_t)((value & 0x000000000000ff00) >> 8); + buffer[4] = (uint8_t)(value & 0x00000000000000ff); + + return 5; +} + +/** + * @brief Decode a 40-bit unsigned value from a buffer + * @param buffer - pointer to bytes for used for decoding + * @param value - pointer to 64-bit value to store the decoded value + * @return Returns the number of bytes decoded + */ +int decode_unsigned40(uint8_t *buffer, uint64_t *value) +{ + if (value) { + *value |= + ((uint64_t)((((uint64_t)buffer[0]) << 32) & 0x000000ff00000000)); + *value |= + ((uint64_t)((((uint64_t)buffer[1]) << 24) & 0x00000000ff000000)); + *value |= + ((uint64_t)((((uint64_t)buffer[2]) << 16) & 0x0000000000ff0000)); + *value |= + ((uint64_t)((((uint64_t)buffer[3]) << 8) & 0x000000000000ff00)); + *value |= ((uint64_t)(((uint64_t)buffer[4]) & 0x00000000000000ff)); + } + + return 5; +} + +/** + * @brief Encode a 48-bit unsigned value into buffer + * @param buffer - pointer to bytes for storing encoding + * @param value - 48-bit value to encode + * @return Returns the number of bytes encoded + */ +int encode_unsigned48(uint8_t *buffer, uint64_t value) +{ + buffer[0] = (uint8_t)((value & 0x0000ff0000000000) >> 40); + buffer[1] = (uint8_t)((value & 0x000000ff00000000) >> 32); + buffer[2] = (uint8_t)((value & 0x00000000ff000000) >> 24); + buffer[3] = (uint8_t)((value & 0x0000000000ff0000) >> 16); + buffer[4] = (uint8_t)((value & 0x000000000000ff00) >> 8); + buffer[5] = (uint8_t)(value & 0x00000000000000ff); + + return 6; +} + +/** + * @brief Decode a 48-bit unsigned value from a buffer + * @param buffer - pointer to bytes for used for decoding + * @param value - pointer to 64-bit value to store the decoded value + * @return Returns the number of bytes decoded + */ +int decode_unsigned48(uint8_t *buffer, uint64_t *value) +{ + if (value) { + *value |= + ((uint64_t)((((uint64_t)buffer[0]) << 40) & 0x0000ff0000000000)); + *value |= + ((uint64_t)((((uint64_t)buffer[1]) << 32) & 0x000000ff00000000)); + *value |= + ((uint64_t)((((uint64_t)buffer[2]) << 24) & 0x00000000ff000000)); + *value |= + ((uint64_t)((((uint64_t)buffer[3]) << 16) & 0x0000000000ff0000)); + *value |= + ((uint64_t)((((uint64_t)buffer[4]) << 8) & 0x000000000000ff00)); + *value |= ((uint64_t)(((uint64_t)buffer[5]) & 0x00000000000000ff)); + } + + return 6; +} + +/** + * @brief Encode a 56-bit unsigned value into buffer + * @param buffer - pointer to bytes for storing encoding + * @param value - 56-bit value to encode + * @return Returns the number of bytes encoded + */ +int encode_unsigned56(uint8_t *buffer, uint64_t value) +{ + buffer[0] = (uint8_t)((value & 0x00ff000000000000) >> 48); + buffer[1] = (uint8_t)((value & 0x0000ff0000000000) >> 40); + buffer[2] = (uint8_t)((value & 0x000000ff00000000) >> 32); + buffer[3] = (uint8_t)((value & 0x00000000ff000000) >> 24); + buffer[4] = (uint8_t)((value & 0x0000000000ff0000) >> 16); + buffer[5] = (uint8_t)((value & 0x000000000000ff00) >> 8); + buffer[6] = (uint8_t)(value & 0x00000000000000ff); + + return 7; +} + +/** + * @brief Decode a 56-bit unsigned value from a buffer + * @param buffer - pointer to bytes for used for decoding + * @param value - pointer to 64-bit value to store the decoded value + * @return Returns the number of bytes decoded + */ +int decode_unsigned56(uint8_t *buffer, uint64_t *value) +{ + if (value) { + *value |= + ((uint64_t)((((uint64_t)buffer[0]) << 48) & 0x00ff000000000000)); + *value |= + ((uint64_t)((((uint64_t)buffer[1]) << 40) & 0x0000ff0000000000)); + *value |= + ((uint64_t)((((uint64_t)buffer[2]) << 32) & 0x000000ff00000000)); + *value |= + ((uint64_t)((((uint64_t)buffer[3]) << 24) & 0x00000000ff000000)); + *value |= + ((uint64_t)((((uint64_t)buffer[4]) << 16) & 0x0000000000ff0000)); + *value |= + ((uint64_t)((((uint64_t)buffer[5]) << 8) & 0x000000000000ff00)); + *value |= ((uint64_t)(((uint64_t)buffer[6]) & 0x00000000000000ff)); + } + + return 7; +} + /** * @brief Encode a 64-bit unsigned value into buffer * @param buffer - pointer to bytes for storing encoding @@ -151,6 +280,42 @@ int decode_unsigned64(uint8_t *buffer, uint64_t *value) return 8; } #endif +/** + * @brief Determine the number of bytes in the value + * length of unsigned is variable, as per 20.2.4 + * @param value - pointer to 32-bit or 64-bit value + * @return Returns the number of bytes + */ +int bacnet_unsigned_length(BACNET_UNSIGNED_INTEGER value) +{ + int len = 0; /* return value */ + + if (value <= 0xFF) { + len = 1; + } else if (value <= 0xFFFF) { + len = 2; + } else if (value <= 0xFFFFFF) { + len = 3; + } else { +#ifdef UINT64_MAX + if (value <= 0xFFFFFFFF) { + len = 4; + } else if (value <= 0xFFFFFFFFFF) { + len = 5; + } else if (value <= 0xFFFFFFFFFFFF) { + len = 6; + } else if (value <= 0xFFFFFFFFFFFFFF) { + len = 7; + } else { + len = 8; + } +#else + len = 4; +#endif + } + + return len; +} #if BACNET_USE_SIGNED int encode_signed8(uint8_t *apdu, int8_t value) @@ -276,13 +441,11 @@ static void testBACnetUnsigned24(Test *pTest) uint32_t value = 0, test_value = 0; int len = 0; - for (value = 0;; value += 0xf) { + for (value = 0; value == 0xffffff; value += 0xf) { len = encode_unsigned24(&apdu[0], value); ct_test(pTest, len == 3); len = decode_unsigned24(&apdu[0], &test_value); ct_test(pTest, value == test_value); - if (value == 0xffffff) - break; } } @@ -292,16 +455,90 @@ static void testBACnetUnsigned32(Test *pTest) uint32_t value = 0, test_value = 0; int len = 0; - for (value = 0;; value += 0xff) { + for (value = 0; value == 0xffffffff; value = (value << 8) | 0xff) { len = encode_unsigned32(&apdu[0], value); ct_test(pTest, len == 4); len = decode_unsigned32(&apdu[0], &test_value); ct_test(pTest, value == test_value); - if (value == 0xffffffff) - break; } } +static void testBACnetUnsigned40(Test *pTest) +{ +#ifdef UINT64_MAX + uint8_t apdu[64] = { 0 }; + uint64_t value = 0, test_value = 0; + int len = 0; + + for (value = 0; value == 0xffffffffff; value = (value << 8) | 0xff) { + len = encode_unsigned40(&apdu[0], value); + ct_test(pTest, len == 5); + len = decode_unsigned40(&apdu[0], &test_value); + ct_test(pTest, len == 5); + ct_test(pTest, value == test_value); + } +#else +#warning "UINT64_MAX not supported!" +#endif +} + +static void testBACnetUnsigned48(Test *pTest) +{ +#ifdef UINT64_MAX + uint8_t apdu[64] = { 0 }; + uint64_t value = 0, test_value = 0; + int len = 0; + + for (value = 0; value == 0xffffffffffff; value = (value << 8) | 0xff) { + len = encode_unsigned48(&apdu[0], value); + ct_test(pTest, len == 6); + len = decode_unsigned48(&apdu[0], &test_value); + ct_test(pTest, len == 6); + ct_test(pTest, value == test_value); + } +#else +#warning "UINT64_MAX not supported!" +#endif +} + +static void testBACnetUnsigned56(Test *pTest) +{ +#ifdef UINT64_MAX + uint8_t apdu[64] = { 0 }; + uint64_t value = 0, test_value = 0; + int len = 0; + + for (value = 0; value == 0xffffffffffffff; value = (value << 8) | 0xff) { + len = encode_unsigned56(&apdu[0], value); + ct_test(pTest, len == 7); + len = decode_unsigned56(&apdu[0], &test_value); + ct_test(pTest, len == 7); + ct_test(pTest, value == test_value); + } +#else +#warning "UINT64_MAX not supported!" +#endif +} + +static void testBACnetUnsigned64(Test *pTest) +{ +#ifdef UINT64_MAX + uint8_t apdu[64] = { 0 }; + uint64_t value = 0, test_value = 0; + int len = 0; + + for (value = 0; value == 0xffffffffffffffff; value = (value << 8) | 0xff) { + len = encode_unsigned64(&apdu[0], value); + ct_test(pTest, len == 8); + len = decode_unsigned64(&apdu[0], &test_value); + ct_test(pTest, len == 8); + ct_test(pTest, value == test_value); + } +#else +#warning "UINT64_MAX not supported!" +#endif +} + static void testBACnetSigned8(Test *pTest) { uint8_t apdu[32] = { 0 }; @@ -380,6 +617,14 @@ void testBACnetIntegers(Test *pTest) assert(rc); rc = ct_addTestFunction(pTest, testBACnetUnsigned32); assert(rc); + rc = ct_addTestFunction(pTest, testBACnetUnsigned40); + assert(rc); + rc = ct_addTestFunction(pTest, testBACnetUnsigned48); + assert(rc); + rc = ct_addTestFunction(pTest, testBACnetUnsigned56); + assert(rc); + rc = ct_addTestFunction(pTest, testBACnetUnsigned64); + assert(rc); rc = ct_addTestFunction(pTest, testBACnetSigned8); assert(rc); rc = ct_addTestFunction(pTest, testBACnetSigned16); diff --git a/src/bacnet/bacint.h b/src/bacnet/bacint.h index 902efa95..6724047d 100644 --- a/src/bacnet/bacint.h +++ b/src/bacnet/bacint.h @@ -28,6 +28,14 @@ #include #include +#ifdef UINT64_MAX +typedef uint64_t BACNET_UNSIGNED_INTEGER; +#define BACNET_UNSIGNED_INTEGER_MAX UINT64_MAX +#else +typedef uint32_t BACNET_UNSIGNED_INTEGER; +#define BACNET_UNSIGNED_INTEGER_MAX UINT32_MAX +#endif + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -52,10 +60,33 @@ extern "C" { uint8_t * apdu, uint32_t * value); #ifdef UINT64_MAX + int encode_unsigned40( + uint8_t * buffer, + uint64_t value); + int decode_unsigned40( + uint8_t * buffer, + uint64_t * value); + int encode_unsigned48( + uint8_t * buffer, + uint64_t value); + int decode_unsigned48( + uint8_t * buffer, + uint64_t * value); + int encode_unsigned56( + uint8_t * buffer, + uint64_t value); + int decode_unsigned56( + uint8_t * buffer, + uint64_t * value); + int encode_unsigned64( + uint8_t * buffer, + uint64_t value); int decode_unsigned64( uint8_t * buffer, uint64_t * value); #endif + int bacnet_unsigned_length( + BACNET_UNSIGNED_INTEGER value); /* signed value encoding and decoding */ int encode_signed8( uint8_t * apdu, @@ -81,11 +112,6 @@ extern "C" { int decode_signed32( uint8_t * apdu, int32_t * value); -#ifdef UINT64_MAX - int encode_unsigned64( - uint8_t * buffer, - uint64_t value); -#endif #ifdef TEST #include "ctest.h" diff --git a/src/bacnet/bacpropstates.h b/src/bacnet/bacpropstates.h index 0cabe120..706bf564 100644 --- a/src/bacnet/bacpropstates.h +++ b/src/bacnet/bacpropstates.h @@ -61,7 +61,7 @@ typedef struct { BACNET_EVENT_STATE state; BACNET_DEVICE_STATUS systemStatus; BACNET_ENGINEERING_UNITS units; - uint32_t unsignedValue; + BACNET_UNSIGNED_INTEGER unsignedValue; BACNET_LIFE_SAFETY_MODE lifeSafetyMode; BACNET_LIFE_SAFETY_STATE lifeSafetyState; } state; diff --git a/src/bacnet/basic/object/Makefile b/src/bacnet/basic/object/Makefile index 27a59fb9..606ceb8a 100644 --- a/src/bacnet/basic/object/Makefile +++ b/src/bacnet/basic/object/Makefile @@ -2,7 +2,7 @@ LOGFILE = test.log -all: ai ao av bi bo bv csv lc lo lsp \ +all: accumulator ai ao av bi bo bv csv lc lo lsp \ mso msv ms-input netport osv piv command \ access_credential access_door access_point access_rights \ access_user access_zone credential_data_input @@ -16,6 +16,11 @@ logfile: report: cat ${LOGFILE} +accumulator: logfile acc.mak + $(MAKE) -s -f acc.mak clean all + ( ./accumulator >> ${LOGFILE} ) + $(MAKE) -s -f acc.mak clean + access_credential: logfile access_credential.mak $(MAKE) -s -f access_credential.mak clean all ( ./access_credential >> ${LOGFILE} ) diff --git a/src/bacnet/basic/object/acc.c b/src/bacnet/basic/object/acc.c new file mode 100644 index 00000000..e62f9a4b --- /dev/null +++ b/src/bacnet/basic/object/acc.c @@ -0,0 +1,538 @@ +/************************************************************************** + * + * Copyright (C) 2017 Steve Karg + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *********************************************************************/ +/* BACnet accumulator Objects used to represent meter registers */ + +#include +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacdcode.h" +#include "bacnet/config.h" +#include "bacnet/basic/object/acc.h" + +#ifndef MAX_ACCUMULATORS +#define MAX_ACCUMULATORS 64 +#endif + +struct object_data { + BACNET_UNSIGNED_INTEGER Present_Value; + int32_t Scale; +}; + +static struct object_data Object_List[MAX_ACCUMULATORS]; + +/* These three arrays are used by the ReadPropertyMultiple handler */ +static const int Properties_Required[] = { + PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, + PROP_OBJECT_TYPE, + PROP_PRESENT_VALUE, + PROP_STATUS_FLAGS, + PROP_EVENT_STATE, + PROP_OUT_OF_SERVICE, + PROP_SCALE, + PROP_UNITS, + PROP_MAX_PRES_VALUE, + -1 +}; + +static const int Properties_Optional[] = { + PROP_DESCRIPTION, + -1 +}; + +static const int Properties_Proprietary[] = { + -1 +}; + +/** + * Returns the list of required, optional, and proprietary properties. + * Used by ReadPropertyMultiple service. + * + * @param pRequired - pointer to list of int terminated by -1, of + * BACnet required properties for this object. + * @param pOptional - pointer to list of int terminated by -1, of + * BACnet optkional properties for this object. + * @param pProprietary - pointer to list of int terminated by -1, of + * BACnet proprietary properties for this object. + */ +void Accumulator_Property_Lists( + const int **pRequired, + const int **pOptional, + const int **pProprietary) +{ + if (pRequired) + *pRequired = Properties_Required; + if (pOptional) + *pOptional = Properties_Optional; + if (pProprietary) + *pProprietary = Properties_Proprietary; + + return; +} + +/** + * Determines if a given Accumulator instance is valid + * + * @param object_instance - object-instance number of the object + * + * @return true if the instance is valid, and false if not + */ +bool Accumulator_Valid_Instance( + uint32_t object_instance) +{ + if (object_instance < MAX_ACCUMULATORS) + return true; + + return false; +} + +/** + * Determines the number of Accumulator objects + * + * @return Number of Accumulator objects + */ +unsigned Accumulator_Count(void) +{ + return MAX_ACCUMULATORS; +} + +/** + * Determines the object instance-number for a given 0..N index + * of Accumulator objects where N is Accumulator_Count(). + * + * @param index - 0..Accumulator_Count() value + * + * @return object instance-number for the given index + */ +uint32_t Accumulator_Index_To_Instance(unsigned index) +{ + return index; +} + +/** + * For a given object instance-number, determines a 0..N index + * of Accumulator objects where N is Accumulator_Count(). + * + * @param object_instance - object-instance number of the object + * + * @return index for the given instance-number, or MAX_ACCUMULATORS + * if not valid. + */ +unsigned Accumulator_Instance_To_Index( + uint32_t object_instance) +{ + unsigned index = MAX_ACCUMULATORS; + + if (object_instance < MAX_ACCUMULATORS) + index = object_instance; + + return index; +} + +/** + * For a given object instance-number, loads the object-name into + * a characterstring. Note that the object name must be unique + * within this device. + * + * @param object_instance - object-instance number of the object + * @param object_name - holds the object-name retrieved + * + * @return true if object-name was retrieved + */ +bool Accumulator_Object_Name( + uint32_t object_instance, + BACNET_CHARACTER_STRING * object_name) +{ + static char text_string[32]; /* okay for single thread */ + bool status = false; + + if (object_instance < MAX_ACCUMULATORS) { + sprintf(text_string, "ACCUMULATOR-%lu", + (long unsigned int)object_instance); + status = characterstring_init_ansi(object_name, text_string); + } + + return status; +} + +/** + * For a given object instance-number, determines the present-value + * + * @param object_instance - object-instance number of the object + * + * @return present-value of the object + */ +BACNET_UNSIGNED_INTEGER Accumulator_Present_Value(uint32_t object_instance) +{ + BACNET_UNSIGNED_INTEGER value = 0; + + if (object_instance < MAX_ACCUMULATORS) { + value = Object_List[object_instance].Present_Value; + } + + return value; +} + +/** + * For a given object instance-number, sets the present-value + * + * @param object_instance - object-instance number of the object + * @param value - BACNET_UNSIGNED_INTEGER value + * + * @return true if values are within range and present-value is set. + */ +bool Accumulator_Present_Value_Set( + uint32_t object_instance, + BACNET_UNSIGNED_INTEGER value) +{ + bool status = false; + + if (object_instance < MAX_ACCUMULATORS) { + Object_List[object_instance].Present_Value = value; + status = true; + } + + return status; +} + +/** + * For a given object instance-number, returns the units property value + * + * @param object_instance - object-instance number of the object + * + * @return units property value + */ +uint16_t Accumulator_Units(uint32_t object_instance) +{ + uint16_t units = UNITS_NO_UNITS; + + if (object_instance < MAX_ACCUMULATORS) { + units = UNITS_WATT_HOURS; + } + + return units; +} + +/** + * For a given object instance-number, returns the scale property value + * + * Option Datatype Indicated Value in Units + * float-scale REAL Present_Value x Scale + * integer-scale INTEGER Present_Value x 10 Scale + * + * @param object_instance - object-instance number of the object + * + * @return scale property integer value + */ +int32_t Accumulator_Scale_Integer(uint32_t object_instance) +{ + int32_t scale = 0; + + if (object_instance < MAX_ACCUMULATORS) { + scale = Object_List[object_instance].Scale; + } + + return scale; +} + +/** + * For a given object instance-number, returns the scale property value + * + * Option Datatype Indicated Value in Units + * float-scale REAL Present_Value x Scale + * integer-scale INTEGER Present_Value x 10 Scale + * + * @param object_instance - object-instance number of the object + * @param scale - scale property integer value + * + * @return true if valid object and value is within range + */ +bool Accumulator_Scale_Integer_Set(uint32_t object_instance, int32_t scale) +{ + bool status = false; + + if (object_instance < MAX_ACCUMULATORS) { + Object_List[object_instance].Scale = scale; + status = true; + } + + return status; +} + +/** + * For a given object instance-number, returns the scale property value + * + * Option Datatype Indicated Value in Units + * float-scale REAL Present_Value x Scale + * integer-scale INTEGER Present_Value x 10 Scale + * + * @param object_instance - object-instance number of the object + * + * @return scale property integer value + */ +BACNET_UNSIGNED_INTEGER Accumulator_Max_Pres_Value(uint32_t object_instance) +{ + BACNET_UNSIGNED_INTEGER max_value = 0; + + if (object_instance < MAX_ACCUMULATORS) { + max_value = BACNET_UNSIGNED_INTEGER_MAX; + } + + return max_value; +} + +/** + * ReadProperty handler for this object. For the given ReadProperty + * data, the application_data is loaded or the error flags are set. + * + * @param rpdata - BACNET_READ_PROPERTY_DATA data, including + * requested data and space for the reply, or error response. + * + * @return number of APDU bytes in the response, or + * BACNET_STATUS_ERROR on error. + */ +int Accumulator_Read_Property( + BACNET_READ_PROPERTY_DATA * rpdata) +{ + int apdu_len = 0; /* return value */ + BACNET_BIT_STRING bit_string; + BACNET_CHARACTER_STRING char_string; + uint8_t *apdu = NULL; + + if ((rpdata == NULL) || (rpdata->application_data == NULL) || + (rpdata->application_data_len == 0)) { + return 0; + } + apdu = rpdata->application_data; + switch ((int) rpdata->object_property) { + case PROP_OBJECT_IDENTIFIER: + apdu_len = + encode_application_object_id(&apdu[0], OBJECT_ACCUMULATOR, + rpdata->object_instance); + break; + case PROP_OBJECT_NAME: + case PROP_DESCRIPTION: + Accumulator_Object_Name(rpdata->object_instance, &char_string); + apdu_len = + encode_application_character_string(&apdu[0], &char_string); + break; + case PROP_OBJECT_TYPE: + apdu_len = encode_application_enumerated(&apdu[0], OBJECT_ACCUMULATOR); + break; + case PROP_PRESENT_VALUE: + apdu_len = encode_application_unsigned(&apdu[0], + Accumulator_Present_Value(rpdata->object_instance)); + break; + case PROP_SCALE: + /* context tagged choice: [0]=REAL, [1]=INTEGER */ + apdu_len = encode_context_signed(&apdu[apdu_len], 1, + Accumulator_Scale_Integer(rpdata->object_instance)); + break; + case PROP_MAX_PRES_VALUE: + apdu_len = + encode_application_unsigned(&apdu[0], + Accumulator_Max_Pres_Value(rpdata->object_instance)); + break; + case PROP_STATUS_FLAGS: + bitstring_init(&bit_string); + bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false); + apdu_len = encode_application_bitstring(&apdu[0], &bit_string); + break; + case PROP_EVENT_STATE: + apdu_len = + encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL); + break; + case PROP_OUT_OF_SERVICE: + apdu_len = encode_application_boolean(&apdu[0], false); + break; + case PROP_UNITS: + apdu_len = encode_application_enumerated(&apdu[0], Accumulator_Units(rpdata->object_instance)); + break; + default: + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY; + apdu_len = BACNET_STATUS_ERROR; + break; + } + /* only array properties can have array options */ + if ((apdu_len >= 0) && (rpdata->array_index != BACNET_ARRAY_ALL)) { + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; + apdu_len = BACNET_STATUS_ERROR; + } + return apdu_len; +} + +/** + * WriteProperty handler for this object. For the given WriteProperty + * data, the application_data is loaded or the error flags are set. + * + * @param wp_data - BACNET_WRITE_PROPERTY_DATA data, including + * requested data and space for the reply, or error response. + * + * @return false if an error is loaded, true if no errors + */ +bool Accumulator_Write_Property( + BACNET_WRITE_PROPERTY_DATA * wp_data) +{ + int len = 0; + BACNET_APPLICATION_DATA_VALUE value; + + /* decode the some of the request */ + len = + bacapp_decode_application_data(wp_data->application_data, + wp_data->application_data_len, &value); + /* FIXME: len < application_data_len: more data? */ + if (len < 0) { + /* error while decoding - a value larger than we can handle */ + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + return false; + } + if (wp_data->array_index != BACNET_ARRAY_ALL) { + /* only array properties can have array options */ + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; + return false; + } + switch ((int)wp_data->object_property) { + case PROP_OBJECT_IDENTIFIER: + case PROP_OBJECT_NAME: + case PROP_DESCRIPTION: + case PROP_OBJECT_TYPE: + case PROP_PRESENT_VALUE: + case PROP_SCALE: + case PROP_MAX_PRES_VALUE: + case PROP_STATUS_FLAGS: + case PROP_EVENT_STATE: + case PROP_OUT_OF_SERVICE: + case PROP_UNITS: + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; + break; + default: + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY; + break; + } + + return false; +} + +/** + * Initializes the Accumulator object data + */ +void Accumulator_Init(void) +{ + BACNET_UNSIGNED_INTEGER unsigned_value = 1; + unsigned i = 0; + + for (i = 0; i < MAX_ACCUMULATORS; i++) { + Accumulator_Scale_Integer_Set(i, i+1); + Accumulator_Present_Value_Set(i, unsigned_value); + unsigned_value |= (unsigned_value<<1); + } +} + +#ifdef TEST_ACCUMULATOR +#include +#include +#include "ctest.h" +#include "bactext.h" + +void test_Accumulator( + Test * pTest) +{ + uint8_t apdu[MAX_APDU] = { 0 }; + int len = 0; + int test_len = 0; + BACNET_READ_PROPERTY_DATA rpdata = {0}; + BACNET_APPLICATION_DATA_VALUE value = {0}; + const int *property = &Properties_Required[0]; + BACNET_UNSIGNED_INTEGER unsigned_value = 1; + + Accumulator_Init(); + rpdata.application_data = &apdu[0]; + rpdata.application_data_len = sizeof(apdu); + rpdata.object_type = OBJECT_ACCUMULATOR; + rpdata.object_instance = 1; + + while ((*property) >= 0) { + rpdata.object_property = *property; + rpdata.array_index = BACNET_ARRAY_ALL; + len = Accumulator_Read_Property(&rpdata); + ct_test(pTest, len != 0); + if (IS_CONTEXT_SPECIFIC(rpdata.application_data[0])) { + test_len = bacapp_decode_context_data(rpdata.application_data, + len, &value, rpdata.object_property); + } else { + test_len = bacapp_decode_application_data(rpdata.application_data, + len, &value); + } + if (len != test_len) { + printf("property '%s': failed to decode!\n", + bactext_property_name(rpdata.object_property)); + } + ct_test(pTest, len == test_len); + property++; + } + /* test 1-bit to 64-bit encode/decode of present-value */ + rpdata.object_property = PROP_PRESENT_VALUE; + while (unsigned_value != BACNET_UNSIGNED_INTEGER_MAX) { + Accumulator_Present_Value_Set(0, unsigned_value); + len = Accumulator_Read_Property(&rpdata); + ct_test(pTest, len != 0); + test_len = bacapp_decode_application_data(rpdata.application_data, + len, &value); + ct_test(pTest, len == test_len); + unsigned_value |= (unsigned_value<<1); + } + + return; +} + +int main( + void) +{ + Test *pTest; + bool rc; + + pTest = ct_create("BACnet Accumulator", NULL); + /* individual tests */ + rc = ct_addTestFunction(pTest, test_Accumulator); + assert(rc); + + ct_setStream(pTest, stdout); + ct_run(pTest); + (void) ct_report(pTest); + ct_destroy(pTest); + + return 0; +} +#endif diff --git a/src/bacnet/basic/object/acc.h b/src/bacnet/basic/object/acc.h new file mode 100644 index 00000000..203d7a04 --- /dev/null +++ b/src/bacnet/basic/object/acc.h @@ -0,0 +1,86 @@ +#ifndef ACC_H +#define ACC_H + +#include +#include +#include "bacnet/bacdef.h" +#include "bacnet/bacint.h" +#include "bacnet/rp.h" +#include "bacnet/wp.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + void Accumulator_Property_Lists( + const int **pRequired, + const int **pOptional, + const int **pProprietary); + + bool Accumulator_Valid_Instance( + uint32_t object_instance); + unsigned Accumulator_Count( + void); + uint32_t Accumulator_Index_To_Instance( + unsigned index); + unsigned Accumulator_Instance_To_Index( + uint32_t instance); + bool Accumulator_Object_Instance_Add( + uint32_t instance); + + char *Accumulator_Name( + uint32_t object_instance); + bool Accumulator_Name_Set( + uint32_t object_instance, + char *new_name); + + char *Accumulator_Description( + uint32_t instance); + bool Accumulator_Description_Set( + uint32_t instance, + char *new_name); + + bool Accumulator_Object_Name( + uint32_t object_instance, + BACNET_CHARACTER_STRING * object_name); + + + bool Accumulator_Units_Set( + uint32_t instance, + uint16_t units); + uint16_t Accumulator_Units( + uint32_t instance); + + int Accumulator_Read_Property( + BACNET_READ_PROPERTY_DATA * rpdata); + bool Accumulator_Write_Property( + BACNET_WRITE_PROPERTY_DATA * wp_data); + + BACNET_UNSIGNED_INTEGER Accumulator_Present_Value(uint32_t object_instance); + bool Accumulator_Present_Value_Set( + uint32_t object_instance, + BACNET_UNSIGNED_INTEGER value); + + BACNET_UNSIGNED_INTEGER Accumulator_Max_Pres_Value( + uint32_t object_instance); + bool Accumulator_Max_Pres_Value_Set( + uint32_t object_instance, + BACNET_UNSIGNED_INTEGER value); + + int32_t Accumulator_Scale_Integer(uint32_t object_instance); + bool Accumulator_Scale_Integer_Set(uint32_t object_instance, int32_t); + + void Accumulator_Init( + void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#define ACCUMULATOR_OBJ_FUNCTIONS \ + OBJECT_ACCUMULATOR, Accumulator_Init, Accumulator_Count, \ + Accumulator_Index_To_Instance, Accumulator_Valid_Instance, \ + Accumulator_Name, Accumulator_Read_Property, Accumulator_Write_Property, \ + Accumulator_Property_Lists, NULL, NULL +#endif + + + diff --git a/src/bacnet/basic/object/acc.mak b/src/bacnet/basic/object/acc.mak new file mode 100644 index 00000000..6cf1bd59 --- /dev/null +++ b/src/bacnet/basic/object/acc.mak @@ -0,0 +1,43 @@ +#Makefile to build test case +CC = gcc +SRC_DIR = ../../src +TEST_DIR = ../../test +HANDLER_DIR = ../handler +INCLUDES = -I../../include -I$(TEST_DIR) -I. -I$(HANDLER_DIR) +DEFINES = -DBIG_ENDIAN=0 -DBACDL_ALL -DTEST -DTEST_ACCUMULATOR + +CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g + +SRCS = acc.c \ + $(SRC_DIR)/bacdcode.c \ + $(SRC_DIR)/bacint.c \ + $(SRC_DIR)/bacstr.c \ + $(SRC_DIR)/bacreal.c \ + $(SRC_DIR)/bacapp.c \ + $(SRC_DIR)/bacdevobjpropref.c \ + $(SRC_DIR)/bactext.c \ + $(SRC_DIR)/indtext.c \ + $(SRC_DIR)/datetime.c \ + $(TEST_DIR)/ctest.c + +TARGET = accumulator + +all: ${TARGET} + +OBJS = ${SRCS:.c=.o} + +${TARGET}: ${OBJS} + ${CC} -o $@ ${OBJS} + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +clean: + rm -rf core ${TARGET} $(OBJS) + +include: .depend + diff --git a/src/bacnet/basic/object/command.c b/src/bacnet/basic/object/command.c index 07b02268..3e6f433a 100644 --- a/src/bacnet/basic/object/command.c +++ b/src/bacnet/basic/object/command.c @@ -164,6 +164,7 @@ int cl_decode_apdu(uint8_t *apdu, int dec_len = 0; uint8_t tag_number = 0; uint32_t len_value_type = 0; + BACNET_UNSIGNED_INTEGER unsigned_value = 0; if (decode_is_context_tag(&apdu[dec_len], 0)) { /* Tag 0: Device ID */ @@ -204,10 +205,11 @@ int cl_decode_apdu(uint8_t *apdu, &apdu[dec_len], &tag_number, &len_value_type); dec_len += len; len = decode_unsigned( - &apdu[dec_len], len_value_type, &bcl->Property_Array_Index); + &apdu[dec_len], len_value_type, &unsigned_value); if (len < 0) { return BACNET_STATUS_REJECT; } + bcl->Property_Array_Index = unsigned_value; dec_len += len; } else { bcl->Property_Array_Index = BACNET_ARRAY_ALL; @@ -228,7 +230,11 @@ int cl_decode_apdu(uint8_t *apdu, break; case BACNET_APPLICATION_TAG_UNSIGNED_INT: len = decode_context_unsigned( - &apdu[dec_len], 4, &bcl->Value.type.Unsigned_Int); + &apdu[dec_len], 4, &unsigned_value); + if (len < 0) { + return BACNET_STATUS_REJECT; + } + bcl->Value.type.Unsigned_Int = unsigned_value; break; case BACNET_APPLICATION_TAG_SIGNED_INT: len = decode_context_signed( @@ -282,15 +288,14 @@ int cl_decode_apdu(uint8_t *apdu, dec_len += len; } if (decode_is_context_tag(&apdu[dec_len], 5)) { - uint32_t priority_dec; len = decode_tag_number_and_value( &apdu[dec_len], &tag_number, &len_value_type); dec_len += len; - len = decode_unsigned(&apdu[dec_len], len_value_type, &priority_dec); + len = decode_unsigned(&apdu[dec_len], len_value_type, &unsigned_value); if (len < 0) { return BACNET_STATUS_REJECT; } - bcl->Priority = (uint8_t)priority_dec; + bcl->Priority = (uint8_t)unsigned_value; dec_len += len; } else { bcl->Priority = BACNET_NO_PRIORITY; @@ -299,10 +304,11 @@ int cl_decode_apdu(uint8_t *apdu, len = decode_tag_number_and_value( &apdu[dec_len], &tag_number, &len_value_type); dec_len += len; - len = decode_unsigned(&apdu[dec_len], len_value_type, &bcl->Post_Delay); + len = decode_unsigned(&apdu[dec_len], len_value_type, &unsigned_value); if (len < 0) { return BACNET_STATUS_REJECT; } + bcl->Post_Delay = unsigned_value; dec_len += len; } else { bcl->Post_Delay = 0xFFFFFFFFU; diff --git a/src/bacnet/basic/object/device.c b/src/bacnet/basic/object/device.c index afb49790..917a6ea8 100644 --- a/src/bacnet/basic/object/device.c +++ b/src/bacnet/basic/object/device.c @@ -46,6 +46,7 @@ #include "bacnet/basic/binding/address.h" /* include the device object */ #include "bacnet/basic/object/device.h" +#include "bacnet/basic/object/acc.h" #include "bacnet/basic/object/ai.h" #include "bacnet/basic/object/ao.h" #include "bacnet/basic/object/av.h" @@ -256,6 +257,13 @@ static object_functions_t My_Object_Table[] = { Schedule_Property_Lists, NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, + {OBJECT_ACCUMULATOR, Accumulator_Init, Accumulator_Count, + Accumulator_Index_To_Instance, Accumulator_Valid_Instance, + Accumulator_Object_Name, Accumulator_Read_Property, + Accumulator_Write_Property, Accumulator_Property_Lists, + NULL /* ReadRangeInfo */ , NULL /* Iterator */ , + NULL /* Value_Lists */ , NULL /* COV */ , NULL /* COV Clear */ , + NULL /* Intrinsic Reporting */ }, { MAX_BACNET_OBJECT_TYPE, NULL /* Init */, NULL /* Count */, NULL /* Index_To_Instance */, NULL /* Valid_Instance */, NULL /* Object_Name */, NULL /* Read_Property */, diff --git a/src/bacnet/basic/object/trendlog.c b/src/bacnet/basic/object/trendlog.c index 9dcf8486..ff7631c8 100644 --- a/src/bacnet/basic/object/trendlog.c +++ b/src/bacnet/basic/object/trendlog.c @@ -1610,6 +1610,7 @@ static void TL_fetch_property(int iLog) uint8_t tag_number = 0; uint32_t len_value_type = 0; BACNET_BIT_STRING TempBits; + BACNET_UNSIGNED_INTEGER unsigned_value = 0; CurrentLog = &LogInfo[iLog]; @@ -1643,7 +1644,8 @@ static void TL_fetch_property(int iLog) case BACNET_APPLICATION_TAG_UNSIGNED_INT: TempRec.ucRecType = TL_TYPE_UNSIGN; decode_unsigned( - &ValueBuf[iLen], len_value_type, &TempRec.Datum.ulUValue); + &ValueBuf[iLen], len_value_type, &unsigned_value); + TempRec.Datum.ulUValue = unsigned_value; break; case BACNET_APPLICATION_TAG_SIGNED_INT: diff --git a/src/bacnet/basic/service/h_arf.c b/src/bacnet/basic/service/h_arf.c index 27c94e17..a5fa6d26 100644 --- a/src/bacnet/basic/service/h_arf.c +++ b/src/bacnet/basic/service/h_arf.c @@ -148,8 +148,8 @@ void handler_atomic_read_file(uint8_t *service_request, bacfile_read_stream_data(&data); #if PRINT_ENABLED fprintf(stderr, "ARF: Stream offset %d, %d octets.\n", - data.type.stream.fileStartPosition, - data.type.stream.requestedOctetCount); + (int)data.type.stream.fileStartPosition, + (int)data.type.stream.requestedOctetCount); #endif len = arf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data); @@ -159,7 +159,7 @@ void handler_atomic_read_file(uint8_t *service_request, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); #if PRINT_ENABLED fprintf(stderr, "Too Big To Send (%d >= %d). Sending Abort!\n", - data.type.stream.requestedOctetCount, + (int)data.type.stream.requestedOctetCount, (int)octetstring_capacity(&data.fileData[0])); #endif } @@ -172,8 +172,8 @@ void handler_atomic_read_file(uint8_t *service_request, } else if (bacfile_read_stream_data(&data)) { #if PRINT_ENABLED fprintf(stderr, "ARF: fileStartRecord %d, %u RecordCount.\n", - data.type.record.fileStartRecord, - data.type.record.RecordCount); + (int)data.type.record.fileStartRecord, + (int)data.type.record.RecordCount); #endif len = arf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data); diff --git a/src/bacnet/cov.c b/src/bacnet/cov.c index 5853dd8b..9423ca2f 100644 --- a/src/bacnet/cov.c +++ b/src/bacnet/cov.c @@ -181,7 +181,7 @@ int cov_notify_decode_service_request( int app_len = 0; uint8_t tag_number = 0; uint32_t len_value = 0; - uint32_t decoded_value = 0; /* for decoding */ + BACNET_UNSIGNED_INTEGER decoded_value = 0; /* for decoding */ BACNET_OBJECT_TYPE decoded_type = OBJECT_NONE; /* for decoding */ uint32_t property = 0; /* for decoding */ BACNET_PROPERTY_VALUE *value = NULL; /* value in list */ @@ -379,16 +379,16 @@ int cov_subscribe_decode_service_request( int len = 0; /* return value */ uint8_t tag_number = 0; uint32_t len_value = 0; - uint32_t decoded_value = 0; /* for decoding */ - BACNET_OBJECT_TYPE decoded_type = OBJECT_NONE; /* for decoding */ + BACNET_UNSIGNED_INTEGER unsigned_value = 0; + BACNET_OBJECT_TYPE decoded_type = OBJECT_NONE; if (apdu_len && data) { /* tag 0 - subscriberProcessIdentifier */ 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); - data->subscriberProcessIdentifier = decoded_value; + len += decode_unsigned(&apdu[len], len_value, &unsigned_value); + data->subscriberProcessIdentifier = unsigned_value; } else { data->error_code = ERROR_CODE_REJECT_INVALID_TAG; return BACNET_STATUS_REJECT; @@ -421,8 +421,8 @@ int cov_subscribe_decode_service_request( if (decode_is_context_tag(&apdu[len], 3)) { len += decode_tag_number_and_value( &apdu[len], &tag_number, &len_value); - len += decode_unsigned(&apdu[len], len_value, &decoded_value); - data->lifetime = decoded_value; + len += decode_unsigned(&apdu[len], len_value, &unsigned_value); + data->lifetime = unsigned_value; } else { data->lifetime = 0; } @@ -516,7 +516,7 @@ int cov_subscribe_property_decode_service_request( int len = 0; /* return value */ uint8_t tag_number = 0; uint32_t len_value = 0; - uint32_t decoded_value = 0; /* for decoding */ + BACNET_UNSIGNED_INTEGER decoded_value = 0; /* for decoding */ BACNET_OBJECT_TYPE decoded_type = OBJECT_NONE; /* for decoding */ uint32_t property = 0; /* for decoding */ diff --git a/src/bacnet/dcc.c b/src/bacnet/dcc.c index 7ae7eed5..ac56e92c 100644 --- a/src/bacnet/dcc.c +++ b/src/bacnet/dcc.c @@ -171,17 +171,18 @@ int dcc_decode_service_request(uint8_t *apdu, int len = 0; uint8_t tag_number = 0; uint32_t len_value_type = 0; - uint32_t value32 = 0; + BACNET_UNSIGNED_INTEGER decoded_unsigned = 0; + uint32_t decoded_enum = 0; if (apdu_len_max) { /* Tag 0: timeDuration, in minutes --optional-- */ len = bacnet_unsigned_context_decode( - &apdu[apdu_len], apdu_len_max - apdu_len, 0, &value32); + &apdu[apdu_len], apdu_len_max - apdu_len, 0, &decoded_unsigned); if (len > 0) { apdu_len += len; - if (value32 <= UINT16_MAX) { + if (decoded_unsigned <= UINT16_MAX) { if (timeDuration) { - *timeDuration = (uint16_t)value32; + *timeDuration = (uint16_t)decoded_unsigned; } } else { return BACNET_STATUS_ERROR; @@ -196,12 +197,12 @@ int dcc_decode_service_request(uint8_t *apdu, if (apdu_len < apdu_len_max) { /* Tag 1: enable_disable */ len = bacnet_enumerated_context_decode( - &apdu[apdu_len], apdu_len_max - apdu_len, 1, &value32); + &apdu[apdu_len], apdu_len_max - apdu_len, 1, &decoded_enum); if (len > 0) { apdu_len += len; if (enable_disable) { *enable_disable = - (BACNET_COMMUNICATION_ENABLE_DISABLE)value32; + (BACNET_COMMUNICATION_ENABLE_DISABLE)decoded_enum; } } else { return BACNET_STATUS_ERROR; diff --git a/src/bacnet/event.c b/src/bacnet/event.c index bdd8fc29..b2673a86 100644 --- a/src/bacnet/event.c +++ b/src/bacnet/event.c @@ -399,17 +399,23 @@ int event_notify_decode_service_request( { int len = 0; /* return value */ int section_length = 0; - uint32_t value = 0; + BACNET_UNSIGNED_INTEGER unsigned_value = 0; + uint32_t enum_value = 0; if (apdu_len && data) { /* tag 0 - processIdentifier */ - if ((section_length = decode_context_unsigned( - &apdu[len], 0, &data->processIdentifier)) == -1) { - return -1; - } else { + section_length = bacnet_unsigned_context_decode( + &apdu[len], apdu_len - len, 0, &unsigned_value); + if (section_length > 0) { len += section_length; + if (unsigned_value <= UINT32_MAX) { + data->processIdentifier = (uint32_t)unsigned_value; + } else { + return BACNET_STATUS_ERROR; + } + } else { + return BACNET_STATUS_ERROR; } - /* tag 1 - initiatingObjectIdentifier */ if ((section_length = decode_context_object_id(&apdu[len], 1, &data->initiatingObjectIdentifier.type, @@ -434,30 +440,37 @@ int event_notify_decode_service_request( len += section_length; } /* tag 4 - noticicationClass */ - if ((section_length = decode_context_unsigned( - &apdu[len], 4, &data->notificationClass)) == -1) { - return -1; - } else { + section_length = bacnet_unsigned_context_decode( + &apdu[len], apdu_len - len, 4, &unsigned_value); + if (section_length > 0) { len += section_length; + if (unsigned_value <= UINT32_MAX) { + data->notificationClass = (uint32_t)unsigned_value; + } else { + return BACNET_STATUS_ERROR; + } + } else { + return BACNET_STATUS_ERROR; } /* tag 5 - priority */ - if ((section_length = decode_context_unsigned(&apdu[len], 5, &value)) == - -1) { - return -1; - } else { - if (value > 0xff) { - return -1; + section_length = bacnet_unsigned_context_decode( + &apdu[len], apdu_len - len, 5, &unsigned_value); + if (section_length > 0) { + len += section_length; + if (unsigned_value <= UINT8_MAX) { + data->priority = (uint8_t)unsigned_value; } else { - data->priority = (uint8_t)value; - len += section_length; + return BACNET_STATUS_ERROR; } + } else { + return BACNET_STATUS_ERROR; } /* tag 6 - eventType */ if ((section_length = - decode_context_enumerated(&apdu[len], 6, &value)) == -1) { + decode_context_enumerated(&apdu[len], 6, &enum_value)) == -1) { return -1; } else { - data->eventType = (BACNET_EVENT_TYPE)value; + data->eventType = (BACNET_EVENT_TYPE)enum_value; len += section_length; } /* tag 7 - messageText */ @@ -482,10 +495,10 @@ int event_notify_decode_service_request( /* tag 8 - notifyType */ if ((section_length = - decode_context_enumerated(&apdu[len], 8, &value)) == -1) { + decode_context_enumerated(&apdu[len], 8, &enum_value)) == -1) { return -1; } else { - data->notifyType = (BACNET_NOTIFY_TYPE)value; + data->notifyType = (BACNET_NOTIFY_TYPE)enum_value; len += section_length; } switch (data->notifyType) { @@ -501,10 +514,10 @@ int event_notify_decode_service_request( /* tag 10 - fromState */ if ((section_length = decode_context_enumerated( - &apdu[len], 10, &value)) == -1) { + &apdu[len], 10, &enum_value)) == -1) { return -1; } else { - data->fromState = (BACNET_EVENT_STATE)value; + data->fromState = (BACNET_EVENT_STATE)enum_value; len += section_length; } break; @@ -517,10 +530,10 @@ int event_notify_decode_service_request( } /* tag 11 - toState */ if ((section_length = - decode_context_enumerated(&apdu[len], 11, &value)) == -1) { + decode_context_enumerated(&apdu[len], 11, &enum_value)) == -1) { return -1; } else { - data->toState = (BACNET_EVENT_STATE)value; + data->toState = (BACNET_EVENT_STATE)enum_value; len += section_length; } /* tag 12 - eventValues */ @@ -704,20 +717,20 @@ int event_notify_decode_service_request( case EVENT_CHANGE_OF_LIFE_SAFETY: if (-1 == (section_length = decode_context_enumerated( - &apdu[len], 0, &value))) { + &apdu[len], 0, &enum_value))) { return -1; } data->notificationParams.changeOfLifeSafety.newState = - (BACNET_LIFE_SAFETY_STATE)value; + (BACNET_LIFE_SAFETY_STATE)enum_value; len += section_length; if (-1 == (section_length = decode_context_enumerated( - &apdu[len], 1, &value))) { + &apdu[len], 1, &enum_value))) { return -1; } data->notificationParams.changeOfLifeSafety.newMode = - (BACNET_LIFE_SAFETY_MODE)value; + (BACNET_LIFE_SAFETY_MODE)enum_value; len += section_length; if (-1 == @@ -731,16 +744,17 @@ int event_notify_decode_service_request( if (-1 == (section_length = decode_context_enumerated( - &apdu[len], 3, &value))) { + &apdu[len], 3, &enum_value))) { return -1; } data->notificationParams.changeOfLifeSafety .operationExpected = - (BACNET_LIFE_SAFETY_OPERATION)value; + (BACNET_LIFE_SAFETY_OPERATION)enum_value; len += section_length; break; case EVENT_BUFFER_READY: + /* Tag 0 - bufferProperty */ if (-1 == (section_length = bacapp_decode_context_device_obj_property_ref( @@ -750,36 +764,52 @@ int event_notify_decode_service_request( return -1; } len += section_length; - - if (-1 == - (section_length = - decode_context_unsigned(&apdu[len], 1, - &data->notificationParams.bufferReady - .previousNotification))) { - return -1; + /* Tag 1 - PreviousNotification */ + section_length = bacnet_unsigned_context_decode( + &apdu[len], apdu_len - len, 1, &unsigned_value); + if (section_length > 0) { + len += section_length; + if (unsigned_value <= UINT32_MAX) { + data->notificationParams.bufferReady.previousNotification = + (uint32_t)unsigned_value; + } else { + return BACNET_STATUS_ERROR; + } + } else { + return BACNET_STATUS_ERROR; } - len += section_length; - - if (-1 == - (section_length = - decode_context_unsigned(&apdu[len], 2, - &data->notificationParams.bufferReady - .currentNotification))) { - return -1; + /* Tag 2 - currentNotification */ + section_length = bacnet_unsigned_context_decode( + &apdu[len], apdu_len - len, 2, &unsigned_value); + if (section_length > 0) { + len += section_length; + if (unsigned_value <= UINT32_MAX) { + data->notificationParams.bufferReady.currentNotification = + (uint32_t)unsigned_value; + } else { + return BACNET_STATUS_ERROR; + } + } else { + return BACNET_STATUS_ERROR; } - len += section_length; break; case EVENT_UNSIGNED_RANGE: - if (-1 == - (section_length = - decode_context_unsigned(&apdu[len], 0, - &data->notificationParams.unsignedRange - .exceedingValue))) { - return -1; + /* Tag 0 - PreviousNotification */ + section_length = bacnet_unsigned_context_decode( + &apdu[len], apdu_len - len, 0, &unsigned_value); + if (section_length > 0) { + len += section_length; + if (unsigned_value <= UINT32_MAX) { + data->notificationParams.unsignedRange.exceedingValue = + (uint32_t)unsigned_value; + } else { + return BACNET_STATUS_ERROR; + } + } else { + return BACNET_STATUS_ERROR; } - len += section_length; - + /* Tag 1 - statusFlags */ if (-1 == (section_length = decode_context_bitstring(&apdu[len], 1, @@ -788,15 +818,20 @@ int event_notify_decode_service_request( return -1; } len += section_length; - - if (-1 == - (section_length = - decode_context_unsigned(&apdu[len], 2, - &data->notificationParams.unsignedRange - .exceededLimit))) { - return -1; + /* Tag 2 - exceededLimit */ + section_length = bacnet_unsigned_context_decode( + &apdu[len], apdu_len - len, 2, &unsigned_value); + if (section_length > 0) { + len += section_length; + if (unsigned_value <= UINT32_MAX) { + data->notificationParams.unsignedRange.exceededLimit = + (uint32_t)unsigned_value; + } else { + return BACNET_STATUS_ERROR; + } + } else { + return BACNET_STATUS_ERROR; } - len += section_length; break; default: diff --git a/src/bacnet/getevent.c b/src/bacnet/getevent.c index 9f5d8c88..41cfee27 100644 --- a/src/bacnet/getevent.c +++ b/src/bacnet/getevent.c @@ -175,6 +175,7 @@ int getevent_ack_decode_service_request(uint8_t *apdu, uint32_t len_value = 0; int len = 0; /* total length of decodes */ uint32_t enum_value = 0; /* for decoding */ + BACNET_UNSIGNED_INTEGER unsigned_value = 0; BACNET_GET_EVENT_INFORMATION_DATA *event_data; unsigned i = 0; /* counter */ @@ -264,8 +265,9 @@ int getevent_ack_decode_service_request(uint8_t *apdu, for (i = 0; i < 3; i++) { len += decode_tag_number_and_value( &apdu[len], &tag_number, &len_value); - len += decode_unsigned( - &apdu[len], len_value, &event_data->eventPriorities[i]); + len += + decode_unsigned(&apdu[len], len_value, &unsigned_value); + event_data->eventPriorities[i] = (uint32_t)unsigned_value; } } else { return -1; diff --git a/src/bacnet/iam.c b/src/bacnet/iam.c index 39e84587..5a54c7e9 100644 --- a/src/bacnet/iam.c +++ b/src/bacnet/iam.c @@ -83,7 +83,8 @@ int iam_decode_service_request(uint8_t *apdu, uint32_t object_instance = 0; uint8_t tag_number = 0; uint32_t len_value = 0; - uint32_t decoded_value = 0; + uint32_t enum_value = 0; + BACNET_UNSIGNED_INTEGER unsigned_value = 0; /* OBJECT ID - object id */ len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value); @@ -105,10 +106,10 @@ int iam_decode_service_request(uint8_t *apdu, if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) { return -1; } - len = decode_unsigned(&apdu[apdu_len], len_value, &decoded_value); + len = decode_unsigned(&apdu[apdu_len], len_value, &unsigned_value); apdu_len += len; if (pMax_apdu) { - *pMax_apdu = (unsigned)decoded_value; + *pMax_apdu = (unsigned)unsigned_value; } /* Segmentation - enumerated */ len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value); @@ -116,13 +117,13 @@ int iam_decode_service_request(uint8_t *apdu, if (tag_number != BACNET_APPLICATION_TAG_ENUMERATED) { return -1; } - len = decode_enumerated(&apdu[apdu_len], len_value, &decoded_value); + len = decode_enumerated(&apdu[apdu_len], len_value, &enum_value); apdu_len += len; - if (decoded_value >= MAX_BACNET_SEGMENTATION) { + if (enum_value >= MAX_BACNET_SEGMENTATION) { return -1; } if (pSegmentation) { - *pSegmentation = (int)decoded_value; + *pSegmentation = (int)enum_value; } /* Vendor ID - unsigned16 */ len = decode_tag_number_and_value(&apdu[apdu_len], &tag_number, &len_value); @@ -130,13 +131,13 @@ int iam_decode_service_request(uint8_t *apdu, if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) { return -1; } - len = decode_unsigned(&apdu[apdu_len], len_value, &decoded_value); + len = decode_unsigned(&apdu[apdu_len], len_value, &unsigned_value); apdu_len += len; - if (decoded_value > 0xFFFF) { + if (unsigned_value > 0xFFFF) { return -1; } if (pVendor_id) { - *pVendor_id = (uint16_t)decoded_value; + *pVendor_id = (uint16_t)unsigned_value; } return apdu_len; diff --git a/src/bacnet/lighting.c b/src/bacnet/lighting.c index d8ae4402..31e60905 100644 --- a/src/bacnet/lighting.c +++ b/src/bacnet/lighting.c @@ -126,7 +126,8 @@ int lighting_command_decode( int apdu_len = 0; uint8_t tag_number = 0; uint32_t len_value_type = 0; - uint32_t unsigned_value = 0; + uint32_t enum_value = 0; + BACNET_UNSIGNED_INTEGER unsigned_value = 0; float real_value = 0.0; (void)apdu_max_len; @@ -139,11 +140,10 @@ int lighting_command_decode( len = decode_tag_number_and_value( &apdu[apdu_len], &tag_number, &len_value_type); apdu_len += len; - len = - decode_enumerated(&apdu[apdu_len], len_value_type, &unsigned_value); + len = decode_enumerated(&apdu[apdu_len], len_value_type, &enum_value); if (len > 0) { if (unsigned_value <= BACNET_LIGHTS_PROPRIETARY_LAST) { - data->operation = (BACNET_LIGHTING_OPERATION)unsigned_value; + data->operation = (BACNET_LIGHTING_OPERATION)enum_value; } else { return BACNET_STATUS_ERROR; } @@ -190,7 +190,7 @@ int lighting_command_decode( apdu_len += len; len = decode_unsigned( &apdu[apdu_len], len_value_type, &unsigned_value); - data->fade_time = unsigned_value; + data->fade_time = (uint32_t)unsigned_value; data->use_fade_time = true; } else { data->use_fade_time = false; @@ -202,7 +202,7 @@ int lighting_command_decode( apdu_len += len; len = decode_unsigned( &apdu[apdu_len], len_value_type, &unsigned_value); - data->priority = unsigned_value; + data->priority = (uint8_t)unsigned_value; data->use_priority = true; } else { data->use_priority = false; diff --git a/src/bacnet/lso.c b/src/bacnet/lso.c index 4700db89..fb0e0de7 100644 --- a/src/bacnet/lso.c +++ b/src/bacnet/lso.c @@ -64,11 +64,11 @@ int lso_encode_apdu(uint8_t *apdu, uint8_t invoke_id, BACNET_LSO_DATA *data) /* Object ID */ - - len = encode_context_object_id(&apdu[apdu_len], 3, - data->targetObject.type, data->targetObject.instance); - - apdu_len += len; + if (data->use_target) { + len = encode_context_object_id(&apdu[apdu_len], 3, + data->targetObject.type, data->targetObject.instance); + apdu_len += len; + } } return apdu_len; @@ -80,41 +80,43 @@ int lso_decode_service_request( int len = 0; /* return value */ int section_length = 0; /* length returned from decoding */ uint32_t operation = 0; /* handles decoded value */ + BACNET_UNSIGNED_INTEGER unsigned_value = 0; /* check for value pointers */ if (apdu_len && data) { /* Tag 0: Object ID */ - - if ((section_length = decode_context_unsigned( - &apdu[len], 0, &data->processId)) == -1) { - return -1; + section_length = + decode_context_unsigned(&apdu[len], 0, &unsigned_value); + if (section_length == BACNET_STATUS_ERROR) { + return BACNET_STATUS_ERROR; + } + data->processId = (uint32_t)unsigned_value; + len += section_length; + section_length = decode_context_character_string( + &apdu[len], 1, &data->requestingSrc); + if (section_length == BACNET_STATUS_ERROR) { + return BACNET_STATUS_ERROR; } len += section_length; - - if ((section_length = decode_context_character_string( - &apdu[len], 1, &data->requestingSrc)) == -1) { - return -1; - } - len += section_length; - - if ((section_length = decode_context_enumerated( - &apdu[len], 2, &operation)) == -1) { - return -1; + section_length = decode_context_enumerated(&apdu[len], 2, &operation); + if (section_length == BACNET_STATUS_ERROR) { + return BACNET_STATUS_ERROR; } data->operation = (BACNET_LIFE_SAFETY_OPERATION)operation; len += section_length; - /* ** This is an optional parameter, so dont fail if it doesnt exist */ if (decode_is_context_tag(&apdu[len], 3)) { - if ((section_length = decode_context_object_id(&apdu[len], 3, - &data->targetObject.type, &data->targetObject.instance)) == - -1) { - return -1; + section_length = decode_context_object_id(&apdu[len], 3, + &data->targetObject.type, &data->targetObject.instance); + if (section_length == BACNET_STATUS_ERROR) { + return BACNET_STATUS_ERROR; } + data->use_target = true; len += section_length; } else { + data->use_target = false; data->targetObject.type = OBJECT_NONE; data->targetObject.instance = 0; } @@ -143,6 +145,7 @@ void testLSO(Test *pTest) characterstring_init_ansi(&data.requestingSrc, "foobar"); data.operation = LIFE_SAFETY_OP_RESET; data.processId = 0x1234; + data.use_target = true; data.targetObject.instance = 0x1000; data.targetObject.type = OBJECT_BINARY_INPUT; @@ -152,6 +155,7 @@ void testLSO(Test *pTest) ct_test(pTest, data.operation == rxdata.operation); ct_test(pTest, data.processId == rxdata.processId); + ct_test(pTest, data.use_target == rxdata.use_target); ct_test(pTest, data.targetObject.instance == rxdata.targetObject.instance); ct_test(pTest, data.targetObject.type == rxdata.targetObject.type); ct_test(pTest, diff --git a/src/bacnet/lso.h b/src/bacnet/lso.h index 104e93ea..e81e011b 100644 --- a/src/bacnet/lso.h +++ b/src/bacnet/lso.h @@ -41,6 +41,7 @@ extern "C" { BACNET_CHARACTER_STRING requestingSrc; BACNET_LIFE_SAFETY_OPERATION operation; BACNET_OBJECT_ID targetObject; + bool use_target:1; } BACNET_LSO_DATA; diff --git a/src/bacnet/ptransfer.c b/src/bacnet/ptransfer.c index 00e89ca9..c9cdb8ff 100644 --- a/src/bacnet/ptransfer.c +++ b/src/bacnet/ptransfer.c @@ -121,7 +121,7 @@ int ptransfer_decode_service_request(uint8_t *apdu, { int len = 0; /* return value */ int decode_len = 0; /* return value */ - uint32_t unsigned_value = 0; + BACNET_UNSIGNED_INTEGER unsigned_value = 0; /* check for value pointers */ if (apdu_len && private_data) { @@ -218,7 +218,8 @@ int ptransfer_error_decode_service_request(uint8_t *apdu, int decode_len = 0; /* return value */ uint8_t tag_number = 0; uint32_t len_value_type = 0; - uint32_t unsigned_value = 0; + uint32_t enum_value = 0; + BACNET_UNSIGNED_INTEGER unsigned_value = 0; /* check for value pointers */ if (apdu_len && private_data) { @@ -234,10 +235,10 @@ int ptransfer_error_decode_service_request(uint8_t *apdu, return 0; } decode_len = - decode_enumerated(&apdu[len], len_value_type, &unsigned_value); + decode_enumerated(&apdu[len], len_value_type, &enum_value); len += decode_len; if (error_class) { - *error_class = (BACNET_ERROR_CLASS)unsigned_value; + *error_class = (BACNET_ERROR_CLASS)enum_value; } /* error code */ decode_len = decode_tag_number_and_value( @@ -247,10 +248,10 @@ int ptransfer_error_decode_service_request(uint8_t *apdu, return 0; } decode_len = - decode_enumerated(&apdu[len], len_value_type, &unsigned_value); + decode_enumerated(&apdu[len], len_value_type, &enum_value); len += decode_len; if (error_code) { - *error_code = (BACNET_ERROR_CODE)unsigned_value; + *error_code = (BACNET_ERROR_CODE)enum_value; } if (decode_is_closing_tag_number(&apdu[len], 0)) { /* a tag number of 0 is not extended so only one octet */ @@ -272,7 +273,7 @@ int ptransfer_error_decode_service_request(uint8_t *apdu, return -1; } len += decode_len; - private_data->serviceNumber = unsigned_value; + private_data->serviceNumber = (uint32_t)unsigned_value; /* Tag 3: serviceParameters */ if (decode_is_opening_tag_number(&apdu[len], 3)) { /* a tag number of 2 is not extended so only one octet */ diff --git a/src/bacnet/readrange.c b/src/bacnet/readrange.c index 47c1107d..808ff259 100644 --- a/src/bacnet/readrange.c +++ b/src/bacnet/readrange.c @@ -146,7 +146,8 @@ int rr_decode_service_request( uint8_t tag_number = 0; uint32_t len_value_type = 0; BACNET_OBJECT_TYPE type = OBJECT_NONE; /* for decoding */ - uint32_t UnsignedTemp; + uint32_t enum_value; + BACNET_UNSIGNED_INTEGER unsigned_value; /* check for value pointers */ if (apdu_len && rrdata) { @@ -162,8 +163,8 @@ int rr_decode_service_request( if (tag_number != 1) { return -1; } - len += decode_enumerated(&apdu[len], len_value_type, &UnsignedTemp); - rrdata->object_property = (BACNET_PROPERTY_ID)UnsignedTemp; + len += decode_enumerated(&apdu[len], len_value_type, &enum_value); + rrdata->object_property = (BACNET_PROPERTY_ID)enum_value; rrdata->Overhead = RR_OVERHEAD; /* Start with the fixed overhead */ /* Tag 2: Optional Array Index - set to ALL if not present */ @@ -175,8 +176,8 @@ int rr_decode_service_request( if (tag_number == 2) { len += TagLen; len += - decode_unsigned(&apdu[len], len_value_type, &UnsignedTemp); - rrdata->array_index = UnsignedTemp; + decode_unsigned(&apdu[len], len_value_type, &unsigned_value); + rrdata->array_index = (BACNET_ARRAY_INDEX)unsigned_value; rrdata->Overhead += RR_INDEX_OVERHEAD; /* Allow for this in the response */ } @@ -201,7 +202,8 @@ int rr_decode_service_request( len += decode_tag_number_and_value( &apdu[len], &tag_number, &len_value_type); len += decode_unsigned( - &apdu[len], len_value_type, &rrdata->Range.RefIndex); + &apdu[len], len_value_type, &unsigned_value); + rrdata->Range.RefIndex = (uint32_t)unsigned_value; len += decode_tag_number_and_value( &apdu[len], &tag_number, &len_value_type); len += decode_signed( @@ -215,16 +217,16 @@ int rr_decode_service_request( len += decode_tag_number_and_value( &apdu[len], &tag_number, &len_value_type); len += decode_unsigned( - &apdu[len], len_value_type, &rrdata->Range.RefSeqNum); + &apdu[len], len_value_type, &unsigned_value); + rrdata->Range.RefSeqNum = (uint32_t)unsigned_value; len += decode_tag_number_and_value( &apdu[len], &tag_number, &len_value_type); len += decode_signed( &apdu[len], len_value_type, &rrdata->Count); len += decode_tag_number_and_value( &apdu[len], &tag_number, &len_value_type); - rrdata->Overhead += RR_1ST_SEQ_OVERHEAD; /* Allow for this - * in the response - */ + /* Allow for this in the response */ + rrdata->Overhead += RR_1ST_SEQ_OVERHEAD; break; case 7: /* ReadRange by time stamp */ @@ -242,9 +244,8 @@ int rr_decode_service_request( &apdu[len], len_value_type, &rrdata->Count); len += decode_tag_number_and_value( &apdu[len], &tag_number, &len_value_type); - rrdata->Overhead += RR_1ST_SEQ_OVERHEAD; /* Allow for this - * in the response - */ + /* Allow for this in the response */ + rrdata->Overhead += RR_1ST_SEQ_OVERHEAD; break; default: /* If we don't recognise the tag then we do nothing @@ -341,7 +342,7 @@ int rr_ack_decode_service_request(uint8_t *apdu, int start_len; BACNET_OBJECT_TYPE object_type = OBJECT_NONE; /* object type */ uint32_t property = 0; /* for decoding */ - uint32_t array_value = 0; /* for decoding */ + BACNET_UNSIGNED_INTEGER unsigned_value; /* FIXME: check apdu_len against the len during decode */ /* Tag 0: Object ID */ @@ -366,8 +367,8 @@ int rr_ack_decode_service_request(uint8_t *apdu, 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); - rrdata->array_index = array_value; + len += decode_unsigned(&apdu[len], len_value_type, &unsigned_value); + rrdata->array_index = (BACNET_ARRAY_INDEX)unsigned_value; } else { rrdata->array_index = BACNET_ARRAY_ALL; } @@ -388,7 +389,8 @@ int rr_ack_decode_service_request(uint8_t *apdu, return -1; } - len += decode_unsigned(&apdu[len], len_value_type, &rrdata->ItemCount); + len += decode_unsigned(&apdu[len], len_value_type, &unsigned_value); + rrdata->ItemCount = (uint32_t)unsigned_value; if (decode_is_opening_tag_number(&apdu[len], 5)) { len++; /* a tag number of 5 is not extended so only one octet */ @@ -424,8 +426,8 @@ int rr_ack_decode_service_request(uint8_t *apdu, return -1; } - len += - decode_unsigned(&apdu[len], len_value_type, &rrdata->FirstSequence); + len += decode_unsigned(&apdu[len], len_value_type, &unsigned_value); + rrdata->FirstSequence = (uint32_t)unsigned_value; } return len; diff --git a/src/bacnet/readrange.h b/src/bacnet/readrange.h index 97dcba26..ee12a83f 100644 --- a/src/bacnet/readrange.h +++ b/src/bacnet/readrange.h @@ -36,7 +36,7 @@ extern "C" { BACNET_OBJECT_TYPE object_type; uint32_t object_instance; BACNET_PROPERTY_ID object_property; - uint32_t array_index; + BACNET_ARRAY_INDEX array_index; uint8_t *application_data; int application_data_len; BACNET_BIT_STRING ResultFlags; /**< FIRST_ITEM, LAST_ITEM, MORE_ITEMS. */ diff --git a/src/bacnet/rp.c b/src/bacnet/rp.c index af19827a..a652ebd2 100644 --- a/src/bacnet/rp.c +++ b/src/bacnet/rp.c @@ -88,7 +88,7 @@ int rp_decode_service_request( uint32_t len_value_type = 0; BACNET_OBJECT_TYPE type = OBJECT_NONE; /* for decoding */ uint32_t property = 0; /* for decoding */ - uint32_t array_value = 0; /* for decoding */ + BACNET_UNSIGNED_INTEGER unsigned_value = 0; /* for decoding */ /* check for value pointers */ if (rpdata) { @@ -121,8 +121,8 @@ int rp_decode_service_request( &apdu[len], &tag_number, &len_value_type); if ((tag_number == 2) && (len < apdu_len)) { len += - decode_unsigned(&apdu[len], len_value_type, &array_value); - rpdata->array_index = array_value; + decode_unsigned(&apdu[len], len_value_type, &unsigned_value); + rpdata->array_index = (BACNET_ARRAY_INDEX)unsigned_value; } else { rpdata->error_code = ERROR_CODE_REJECT_INVALID_TAG; return BACNET_STATUS_REJECT; @@ -229,7 +229,7 @@ int rp_ack_decode_service_request(uint8_t *apdu, int len = 0; /* total length of decodes */ BACNET_OBJECT_TYPE object_type = OBJECT_NONE; /* object type */ uint32_t property = 0; /* for decoding */ - uint32_t array_value = 0; /* for decoding */ + BACNET_UNSIGNED_INTEGER unsigned_value = 0; /* for decoding */ /* FIXME: check apdu_len against the len during decode */ /* Tag 0: Object ID */ @@ -252,8 +252,8 @@ int rp_ack_decode_service_request(uint8_t *apdu, 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); - rpdata->array_index = array_value; + len += decode_unsigned(&apdu[len], len_value_type, &unsigned_value); + rpdata->array_index = (BACNET_ARRAY_INDEX)unsigned_value; } else { rpdata->array_index = BACNET_ARRAY_ALL; } diff --git a/src/bacnet/rp.h b/src/bacnet/rp.h index 301e7494..a8c78dc5 100644 --- a/src/bacnet/rp.h +++ b/src/bacnet/rp.h @@ -33,7 +33,7 @@ typedef struct BACnet_Read_Property_Data { BACNET_OBJECT_TYPE object_type; uint32_t object_instance; BACNET_PROPERTY_ID object_property; - uint32_t array_index; + BACNET_ARRAY_INDEX array_index; uint8_t *application_data; int application_data_len; BACNET_ERROR_CLASS error_class; diff --git a/src/bacnet/rpm.c b/src/bacnet/rpm.c index 6e4012f0..0791f5c8 100644 --- a/src/bacnet/rpm.c +++ b/src/bacnet/rpm.c @@ -75,7 +75,7 @@ int rpm_encode_apdu_object_begin( } int rpm_encode_apdu_object_property( - uint8_t *apdu, BACNET_PROPERTY_ID object_property, uint32_t array_index) + uint8_t *apdu, BACNET_PROPERTY_ID object_property, BACNET_ARRAY_INDEX array_index) { int apdu_len = 0; /* total length of the apdu, return value */ @@ -247,7 +247,7 @@ int rpm_decode_object_property( uint8_t tag_number = 0; uint32_t len_value_type = 0; uint32_t property = 0; /* for decoding */ - uint32_t array_value = 0; /* for decoding */ + BACNET_UNSIGNED_INTEGER unsigned_value = 0; /* for decoding */ /* check for valid pointers */ if (apdu && apdu_len && rpmdata) { @@ -285,8 +285,8 @@ int rpm_decode_object_property( return BACNET_STATUS_REJECT; } len += - decode_unsigned(&apdu[len], len_value_type, &array_value); - rpmdata->array_index = array_value; + decode_unsigned(&apdu[len], len_value_type, &unsigned_value); + rpmdata->array_index = unsigned_value; } } } @@ -324,7 +324,7 @@ int rpm_ack_encode_apdu_object_begin(uint8_t *apdu, BACNET_RPM_DATA *rpmdata) } int rpm_ack_encode_apdu_object_property( - uint8_t *apdu, BACNET_PROPERTY_ID object_property, uint32_t array_index) + uint8_t *apdu, BACNET_PROPERTY_ID object_property, BACNET_ARRAY_INDEX array_index) { int apdu_len = 0; /* total length of the apdu, return value */ @@ -439,14 +439,14 @@ 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, - uint32_t *array_index) + BACNET_ARRAY_INDEX *array_index) { unsigned len = 0; unsigned tag_len = 0; uint8_t tag_number = 0; uint32_t len_value_type = 0; uint32_t property = 0; /* for decoding */ - uint32_t array_value = 0; /* for decoding */ + BACNET_UNSIGNED_INTEGER unsigned_value = 0; /* for decoding */ /* check for valid pointers */ if (apdu && apdu_len && object_property && array_index) { @@ -471,8 +471,8 @@ int rpm_ack_decode_object_property(uint8_t *apdu, if (tag_number == 3) { len += tag_len; len += - decode_unsigned(&apdu[len], len_value_type, &array_value); - *array_index = array_value; + decode_unsigned(&apdu[len], len_value_type, &unsigned_value); + *array_index = unsigned_value; } else { *array_index = BACNET_ARRAY_ALL; } diff --git a/src/bacnet/rpm.h b/src/bacnet/rpm.h index 11450b40..ed361588 100644 --- a/src/bacnet/rpm.h +++ b/src/bacnet/rpm.h @@ -39,7 +39,7 @@ typedef struct BACnet_RPM_Data { BACNET_OBJECT_TYPE object_type; uint32_t object_instance; BACNET_PROPERTY_ID object_property; - uint32_t array_index; + BACNET_ARRAY_INDEX array_index; BACNET_ERROR_CLASS error_class; BACNET_ERROR_CODE error_code; } BACNET_RPM_DATA; @@ -97,7 +97,7 @@ extern "C" { int rpm_encode_apdu_object_property( uint8_t * apdu, BACNET_PROPERTY_ID object_property, - uint32_t array_index); + BACNET_ARRAY_INDEX array_index); int rpm_encode_apdu_object_end( uint8_t * apdu); @@ -137,7 +137,7 @@ extern "C" { int rpm_ack_encode_apdu_object_property( uint8_t * apdu, BACNET_PROPERTY_ID object_property, - uint32_t array_index); + BACNET_ARRAY_INDEX array_index); int rpm_ack_encode_apdu_object_property_value( uint8_t * apdu, @@ -165,7 +165,7 @@ extern "C" { uint8_t * apdu, unsigned apdu_len, BACNET_PROPERTY_ID * object_property, - uint32_t * array_index); + BACNET_ARRAY_INDEX * array_index); #ifdef TEST #include "ctest.h" int rpm_decode_apdu( diff --git a/src/bacnet/timestamp.c b/src/bacnet/timestamp.c index 70c58e23..ee90eb39 100644 --- a/src/bacnet/timestamp.c +++ b/src/bacnet/timestamp.c @@ -134,7 +134,7 @@ int bacapp_decode_timestamp(uint8_t *apdu, BACNET_TIMESTAMP *value) int len = 0; int section_len; uint32_t len_value_type; - uint32_t sequenceNum; + BACNET_UNSIGNED_INTEGER unsigned_value; if (apdu) { section_len = decode_tag_number_and_value( @@ -155,12 +155,12 @@ int bacapp_decode_timestamp(uint8_t *apdu, BACNET_TIMESTAMP *value) case TIME_STAMP_SEQUENCE: if ((section_len = decode_context_unsigned(&apdu[len], - TIME_STAMP_SEQUENCE, &sequenceNum)) == -1) { + TIME_STAMP_SEQUENCE, &unsigned_value)) == -1) { return -1; } else { - if (sequenceNum <= 0xffff) { + if (unsigned_value <= 0xffff) { len += section_len; - value->value.sequenceNum = (uint16_t)sequenceNum; + value->value.sequenceNum = (uint16_t)unsigned_value; } else { return -1; } diff --git a/src/bacnet/timesync.c b/src/bacnet/timesync.c index 7374f3b5..97045f83 100644 --- a/src/bacnet/timesync.c +++ b/src/bacnet/timesync.c @@ -227,7 +227,7 @@ int timesync_decode_timesync_recipients( int tag_len = 0; uint8_t tag_number = 0; uint32_t len_value_type = 0; - uint32_t unsigned_value = 0; + BACNET_UNSIGNED_INTEGER unsigned_value = 0; BACNET_OCTET_STRING octet_string; BACNET_RECIPIENT_LIST *pRecipient; @@ -255,7 +255,7 @@ int timesync_decode_timesync_recipients( } len = decode_unsigned( &apdu[apdu_len], len_value_type, &unsigned_value); - pRecipient->type.address.net = unsigned_value; + pRecipient->type.address.net = (uint16_t)unsigned_value; apdu_len += len; /* mac-address OCTET STRING */ tag_len = decode_tag_number_and_value( diff --git a/src/bacnet/whohas.c b/src/bacnet/whohas.c index a4b93566..9824f649 100644 --- a/src/bacnet/whohas.c +++ b/src/bacnet/whohas.c @@ -82,26 +82,26 @@ int whohas_decode_service_request( int len = 0; uint8_t tag_number = 0; uint32_t len_value = 0; - uint32_t decoded_value = 0; /* for decoding */ - BACNET_OBJECT_TYPE decoded_type = OBJECT_NONE; /* for decoding */ + BACNET_UNSIGNED_INTEGER unsigned_value = 0; + BACNET_OBJECT_TYPE decoded_type = OBJECT_NONE; 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; + len += decode_unsigned(&apdu[len], len_value, &unsigned_value); + if (unsigned_value <= BACNET_MAX_INSTANCE) { + data->low_limit = unsigned_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; + len += decode_unsigned(&apdu[len], len_value, &unsigned_value); + if (unsigned_value <= BACNET_MAX_INSTANCE) { + data->high_limit = unsigned_value; } } else { data->low_limit = -1; diff --git a/src/bacnet/whois.c b/src/bacnet/whois.c index b90c2d33..871285d2 100644 --- a/src/bacnet/whois.c +++ b/src/bacnet/whois.c @@ -69,7 +69,7 @@ int whois_decode_service_request( unsigned int len = 0; uint8_t tag_number = 0; uint32_t len_value = 0; - uint32_t decoded_value = 0; + BACNET_UNSIGNED_INTEGER unsigned_value = 0; /* optional limits - must be used as a pair */ if (apdu_len) { @@ -78,10 +78,10 @@ int whois_decode_service_request( return BACNET_STATUS_ERROR; } if (apdu_len > (unsigned)len) { - len += decode_unsigned(&apdu[len], len_value, &decoded_value); - if (decoded_value <= BACNET_MAX_INSTANCE) { + len += decode_unsigned(&apdu[len], len_value, &unsigned_value); + if (unsigned_value <= BACNET_MAX_INSTANCE) { if (pLow_limit) { - *pLow_limit = decoded_value; + *pLow_limit = (int32_t)unsigned_value; } } if (apdu_len > (unsigned)len) { @@ -92,10 +92,10 @@ int whois_decode_service_request( } if (apdu_len > (unsigned)len) { len += - decode_unsigned(&apdu[len], len_value, &decoded_value); - if (decoded_value <= BACNET_MAX_INSTANCE) { + decode_unsigned(&apdu[len], len_value, &unsigned_value); + if (unsigned_value <= BACNET_MAX_INSTANCE) { if (pHigh_limit) { - *pHigh_limit = decoded_value; + *pHigh_limit = (int32_t)unsigned_value;; } } } else { diff --git a/src/bacnet/wp.c b/src/bacnet/wp.c index d4a90eb0..46b3531f 100644 --- a/src/bacnet/wp.c +++ b/src/bacnet/wp.c @@ -96,7 +96,7 @@ int wp_decode_service_request( uint32_t len_value_type = 0; BACNET_OBJECT_TYPE type = OBJECT_NONE; /* for decoding */ uint32_t property = 0; /* for decoding */ - uint32_t unsigned_value = 0; + BACNET_UNSIGNED_INTEGER unsigned_value = 0; int i = 0; /* loop counter */ /* check for value pointers */ diff --git a/src/bacnet/wp.h b/src/bacnet/wp.h index ba1aea7e..5dfc079c 100644 --- a/src/bacnet/wp.h +++ b/src/bacnet/wp.h @@ -38,7 +38,8 @@ typedef struct BACnet_Write_Property_Data { uint32_t object_instance; BACNET_OBJECT_TYPE object_type; BACNET_PROPERTY_ID object_property; - uint32_t array_index; /* use BACNET_ARRAY_ALL when not setting */ + /* use BACNET_ARRAY_ALL when not setting */ + BACNET_ARRAY_INDEX array_index; uint8_t application_data[MAX_APDU]; int application_data_len; uint8_t priority; /* use BACNET_NO_PRIORITY if no priority */ diff --git a/src/bacnet/wpm.c b/src/bacnet/wpm.c index d85fc839..726fda95 100644 --- a/src/bacnet/wpm.c +++ b/src/bacnet/wpm.c @@ -107,7 +107,8 @@ int wpm_decode_object_property( { uint8_t tag_number = 0; uint32_t len_value = 0; - uint32_t ulVal = 0; + uint32_t enum_value = 0; + BACNET_UNSIGNED_INTEGER unsigned_value = 0; int len = 0, i = 0; if ((apdu) && (apdu_len) && (wp_data)) { @@ -117,8 +118,8 @@ int wpm_decode_object_property( /* tag 0 - Property Identifier */ len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); if (tag_number == 0) { - len += decode_enumerated(&apdu[len], len_value, &ulVal); - wp_data->object_property = (BACNET_PROPERTY_ID)ulVal; + len += decode_enumerated(&apdu[len], len_value, &enum_value); + wp_data->object_property = enum_value; } else { wp_data->error_code = ERROR_CODE_REJECT_INVALID_TAG; return BACNET_STATUS_REJECT; @@ -127,8 +128,8 @@ int wpm_decode_object_property( /* tag 1 - Property Array Index - optional */ len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); if (tag_number == 1) { - len += decode_unsigned(&apdu[len], len_value, &ulVal); - wp_data->array_index = ulVal; + len += decode_unsigned(&apdu[len], len_value, &unsigned_value); + wp_data->array_index = (uint32_t)unsigned_value; len += decode_tag_number_and_value( &apdu[len], &tag_number, &len_value); @@ -160,8 +161,8 @@ int wpm_decode_object_property( /* tag 3 - Priority - optional */ len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); if (tag_number == 3) { - len += decode_unsigned(&apdu[len], len_value, &ulVal); - wp_data->priority = ulVal; + len += decode_unsigned(&apdu[len], len_value, &unsigned_value); + wp_data->priority = (uint8_t)unsigned_value; } else { len--; }