diff --git a/.github/workflows/gcc.yml b/.github/workflows/gcc.yml index 3267ebb3..943dfeaa 100644 --- a/.github/workflows/gcc.yml +++ b/.github/workflows/gcc.yml @@ -191,9 +191,9 @@ jobs: - name: ports-avr run: | avr-gcc --version - make atmega168 - make bdk-atxx4-mstp - make xplained + make LEGACY=true atmega168 + make LEGACY=true bdk-atxx4-mstp + make LEGACY=true xplained ports-lwip: runs-on: ubuntu-latest diff --git a/ports/xplained/Makefile b/ports/xplained/Makefile index 83671986..24b8e074 100644 --- a/ports/xplained/Makefile +++ b/ports/xplained/Makefile @@ -196,12 +196,12 @@ CFLAGS += -fsigned-char -std=gnu99 CFLAGS += -fno-strict-aliasing CFLAGS += -Wstrict-prototypes CFLAGS += -Wmissing-prototypes -CFLAGS += -Werror-implicit-function-declaration CFLAGS += -Wpointer-arith CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d CFLAGS += -DIOPORT_XMEGA_COMPAT # silence some warnings CFLAGS += -Wno-switch +CFLAGS += -std=gnu99 ## Assembly specific flags AFLAGS = $(SDK_FLAGS) diff --git a/src/bacnet/bacapp.c b/src/bacnet/bacapp.c index 75ede30f..ab10fce2 100644 --- a/src/bacnet/bacapp.c +++ b/src/bacnet/bacapp.c @@ -148,54 +148,70 @@ int bacapp_encode_application_data( value->type.Object_Id.type, value->type.Object_Id.instance); break; #endif -#if defined(BACAPP_TYPES_EXTRA) case BACNET_APPLICATION_TAG_EMPTYLIST: /* Empty data list */ apdu_len = 0; /* EMPTY */ break; - - break; +#if defined(BACAPP_DATETIME) case BACNET_APPLICATION_TAG_DATETIME: apdu_len = bacapp_encode_datetime(apdu, &value->type.Date_Time); break; +#endif +#if defined(BACAPP_LIGHTING_COMMAND) case BACNET_APPLICATION_TAG_LIGHTING_COMMAND: /* BACnetLightingCommand */ apdu_len = lighting_command_encode( apdu, &value->type.Lighting_Command); break; +#endif +#if defined(BACAPP_XY_COLOR) case BACNET_APPLICATION_TAG_XY_COLOR: /* BACnetxyColor */ apdu_len = xy_color_encode(apdu, &value->type.XY_Color); break; +#endif +#if defined(BACAPP_COLOR_COMMAND) case BACNET_APPLICATION_TAG_COLOR_COMMAND: /* BACnetColorCommand */ apdu_len = color_command_encode(apdu, &value->type.Color_Command); break; +#endif +#if defined(BACAPP_WEEKLY_SCHEDULE) case BACNET_APPLICATION_TAG_WEEKLY_SCHEDULE: /* BACnetWeeklySchedule */ apdu_len = bacnet_weeklyschedule_encode( apdu, &value->type.Weekly_Schedule); break; +#endif +#if defined(BACAPP_HOST_N_PORT) case BACNET_APPLICATION_TAG_HOST_N_PORT: /* BACnetHostNPort */ apdu_len = host_n_port_encode(apdu, &value->type.Host_Address); break; +#endif +#if defined(BACAPP_DEVICE_OBJECT_PROPERTY_REFERENCE) case BACNET_APPLICATION_TAG_DEVICE_OBJECT_PROPERTY_REFERENCE: /* BACnetDeviceObjectPropertyReference */ apdu_len = bacapp_encode_device_obj_property_ref( apdu, &value->type.Device_Object_Property_Reference); break; +#endif +#if defined(BACAPP_DEVICE_OBJECT_REFERENCE) case BACNET_APPLICATION_TAG_DEVICE_OBJECT_REFERENCE: /* BACnetDeviceObjectReference */ apdu_len = bacapp_encode_device_obj_ref( apdu, &value->type.Device_Object_Reference); break; +#endif +#if defined(BACAPP_OBJECT_PROPERTY_REFERENCE) case BACNET_APPLICATION_TAG_OBJECT_PROPERTY_REFERENCE: /* BACnetObjectPropertyReference */ apdu_len = bacapp_encode_obj_property_ref( apdu, &value->type.Object_Property_Reference); break; +#endif +#if defined(BACAPP_DESTINATION) case BACNET_APPLICATION_TAG_DESTINATION: /* BACnetDestination */ apdu_len = @@ -308,49 +324,73 @@ int bacapp_decode_data(uint8_t *apdu, value->type.Object_Id.instance = instance; } break; #endif -#if defined(BACAPP_TYPES_EXTRA) +#if defined(BACAPP_TIMESTAMP) + case BACNET_APPLICATION_TAG_TIMESTAMP: + len = bacnet_timestamp_decode( + apdu, len_value_type, &value->type.Time_Stamp); + break; +#endif +#if defined(BACAPP_DATETIME) case BACNET_APPLICATION_TAG_DATETIME: len = bacnet_datetime_decode( apdu, len_value_type, &value->type.Date_Time); break; +#endif +#if defined(BACAPP_LIGHTING_COMMAND) case BACNET_APPLICATION_TAG_LIGHTING_COMMAND: len = lighting_command_decode( apdu, len_value_type, &value->type.Lighting_Command); break; +#endif +#if defined(BACAPP_XY_COLOR) case BACNET_APPLICATION_TAG_XY_COLOR: /* BACnetxyColor */ len = xy_color_decode( apdu, len_value_type, &value->type.XY_Color); break; +#endif +#if defined(BACAPP_COLOR_COMMAND) case BACNET_APPLICATION_TAG_COLOR_COMMAND: /* BACnetColorCommand */ len = color_command_decode( apdu, len_value_type, NULL, &value->type.Color_Command); break; +#endif +#if defined(BACAPP_WEEKLY_SCHEDULE) case BACNET_APPLICATION_TAG_WEEKLY_SCHEDULE: len = bacnet_weeklyschedule_decode( apdu, len_value_type, &value->type.Weekly_Schedule); break; +#endif +#if defined(BACAPP_HOST_N_PORT) case BACNET_APPLICATION_TAG_HOST_N_PORT: len = host_n_port_decode( apdu, len_value_type, NULL, &value->type.Host_Address); break; +#endif +#if defined(BACAPP_DEVICE_OBJECT_PROPERTY_REFERENCE) case BACNET_APPLICATION_TAG_DEVICE_OBJECT_PROPERTY_REFERENCE: /* BACnetDeviceObjectPropertyReference */ - len = bacnet_device_object_property_reference_decode( - apdu, len_value_type, + len = bacnet_device_object_property_reference_decode(apdu, + len_value_type, &value->type.Device_Object_Property_Reference); break; +#endif +#if defined(BACAPP_DEVICE_OBJECT_REFERENCE) case BACNET_APPLICATION_TAG_DEVICE_OBJECT_REFERENCE: /* BACnetDeviceObjectReference */ len = bacapp_decode_device_obj_ref( apdu, &value->type.Device_Object_Reference); break; +#endif +#if defined(BACAPP_OBJECT_PROPERTY_REFERENCE) case BACNET_APPLICATION_TAG_OBJECT_PROPERTY_REFERENCE: /* BACnetObjectPropertyReference */ len = bacapp_decode_obj_property_ref(apdu, len_value_type, &value->type.Object_Property_Reference); break; +#endif +#if defined(BACAPP_DESTINATION) case BACNET_APPLICATION_TAG_DESTINATION: /* BACnetDestination */ len = bacnet_destination_decode( @@ -640,50 +680,74 @@ int bacapp_encode_context_data_value(uint8_t *apdu, value->type.Object_Id.type, value->type.Object_Id.instance); break; #endif -#if defined(BACAPP_TYPES_EXTRA) +#if defined(BACAPP_TIMESTAMP) + case BACNET_APPLICATION_TAG_TIMESTAMP: + apdu_len = bacapp_encode_context_timestamp( + apdu, context_tag_number, &value->type.Time_Stamp); + break; +#endif +#if defined(BACAPP_DATETIME) case BACNET_APPLICATION_TAG_DATETIME: apdu_len = bacapp_encode_context_datetime( apdu, context_tag_number, &value->type.Date_Time); break; +#endif +#if defined(BACAPP_LIGHTING_COMMAND) case BACNET_APPLICATION_TAG_LIGHTING_COMMAND: apdu_len = lighting_command_encode_context( apdu, context_tag_number, &value->type.Lighting_Command); break; +#endif +#if defined(BACAPP_XY_COLOR) case BACNET_APPLICATION_TAG_XY_COLOR: /* BACnetxyColor */ apdu_len = xy_color_context_encode( apdu, context_tag_number, &value->type.XY_Color); break; - case BACNET_APPLICATION_TAG_WEEKLY_SCHEDULE: - /* BACnetWeeklySchedule */ - apdu_len = bacnet_weeklyschedule_context_encode( - apdu, context_tag_number, &value->type.Weekly_Schedule); - break; +#endif +#if defined(BACAPP_COLOR_COMMAND) case BACNET_APPLICATION_TAG_COLOR_COMMAND: /* BACnetColorCommand */ apdu_len = color_command_context_encode( apdu, context_tag_number, &value->type.Color_Command); break; +#endif +#if defined(BACAPP_WEEKLY_SCHEDULE) + case BACNET_APPLICATION_TAG_WEEKLY_SCHEDULE: + /* BACnetWeeklySchedule */ + apdu_len = bacnet_weeklyschedule_context_encode( + apdu, context_tag_number, &value->type.Weekly_Schedule); + break; +#endif +#if defined(BACAPP_HOST_N_PORT) case BACNET_APPLICATION_TAG_HOST_N_PORT: apdu_len = host_n_port_context_encode( apdu, context_tag_number, &value->type.Host_Address); break; +#endif +#if defined(BACAPP_DEVICE_OBJECT_PROPERTY_REFERENCE) case BACNET_APPLICATION_TAG_DEVICE_OBJECT_PROPERTY_REFERENCE: /* BACnetDeviceObjectPropertyReference */ apdu_len = bacapp_encode_context_device_obj_property_ref(apdu, context_tag_number, &value->type.Device_Object_Property_Reference); break; +#endif +#if defined(BACAPP_DEVICE_OBJECT_REFERENCE) case BACNET_APPLICATION_TAG_DEVICE_OBJECT_REFERENCE: /* BACnetDeviceObjectReference */ apdu_len = bacapp_encode_context_device_obj_ref(apdu, context_tag_number, &value->type.Device_Object_Reference); break; +#endif +#if defined(BACAPP_OBJECT_PROPERTY_REFERENCE) case BACNET_APPLICATION_TAG_OBJECT_PROPERTY_REFERENCE: /* BACnetObjectPropertyReference */ apdu_len = bacapp_encode_context_obj_property_ref(apdu, context_tag_number, &value->type.Object_Property_Reference); break; +#endif +#if defined(BACAPP_DESTINATION) case BACNET_APPLICATION_TAG_DESTINATION: /* BACnetDestination */ apdu_len = bacnet_destination_context_encode( @@ -990,7 +1054,7 @@ int bacapp_decode_context_data(uint8_t *apdu, return apdu_len; } -#if defined(BACAPP_TYPES_EXTRA) +#if defined(BACAPP_COMPLEX_TYPES) /** * @brief Context or Application tagged property value decoding * @@ -1015,7 +1079,7 @@ int bacapp_decode_generic_property(uint8_t *apdu, } #endif -#if defined(BACAPP_TYPES_EXTRA) +#if defined(BACAPP_COMPLEX_TYPES) /* decode one value of a priority array */ static int decode_priority_value(uint8_t *apdu, unsigned max_apdu_len, @@ -1054,7 +1118,7 @@ static int decode_priority_value(uint8_t *apdu, } #endif -#if defined(BACAPP_TYPES_EXTRA) +#if defined(BACAPP_COMPLEX_TYPES) int bacapp_known_property_tag( BACNET_OBJECT_TYPE object_type, BACNET_PROPERTY_ID property) { @@ -1235,9 +1299,11 @@ int bacapp_decode_known_property(uint8_t *apdu, case PROP_ACCOMPANIMENT: case PROP_BELONGS_TO: case PROP_LAST_ACCESS_POINT: +#ifdef BACAPP_DEVICE_OBJECT_REFERENCE /* Properties using BACnetDeviceObjectReference */ len = bacapp_decode_device_obj_ref( apdu, &value->type.Device_Object_Reference); +#endif break; case PROP_TIME_OF_ACTIVE_TIME_RESET: @@ -1256,47 +1322,58 @@ int bacapp_decode_known_property(uint8_t *apdu, case PROP_ACTIVATION_TIME: case PROP_EXPIRATION_TIME: case PROP_LAST_USE_TIME: +#ifdef BACAPP_DATETIME /* Properties using BACnetDateTime value */ len = bacnet_datetime_decode( apdu, max_apdu_len, &value->type.Date_Time); +#endif break; case PROP_OBJECT_PROPERTY_REFERENCE: case PROP_LOG_DEVICE_OBJECT_PROPERTY: case PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES: +#ifdef BACAPP_DEVICE_OBJECT_PROPERTY_REFERENCE /* Properties using BACnetDeviceObjectPropertyReference */ - len = bacnet_device_object_property_reference_decode( - apdu, max_apdu_len, - &value->type.Device_Object_Property_Reference); + len = bacnet_device_object_property_reference_decode(apdu, + max_apdu_len, &value->type.Device_Object_Property_Reference); +#endif break; case PROP_MANIPULATED_VARIABLE_REFERENCE: case PROP_CONTROLLED_VARIABLE_REFERENCE: case PROP_INPUT_REFERENCE: +#ifdef BACAPP_OBJECT_PROPERTY_REFERENCE /* Properties using BACnetObjectPropertyReference */ len = bacapp_decode_obj_property_ref( apdu, max_apdu_len, &value->type.Object_Property_Reference); +#endif break; case PROP_EVENT_TIME_STAMPS: case PROP_LAST_RESTORE_TIME: case PROP_TIME_OF_DEVICE_RESTART: case PROP_ACCESS_EVENT_TIME: +#ifdef BACAPP_TIMESTAMP /* Properties using BACnetTimeStamp */ len = bacapp_decode_timestamp(apdu, &value->type.Time_Stamp); +#endif break; case PROP_DEFAULT_COLOR: +#ifdef BACAPP_XY_COLOR /* Properties using BACnetxyColor */ len = xy_color_decode(apdu, max_apdu_len, &value->type.XY_Color); +#endif break; case PROP_TRACKING_VALUE: case PROP_PRESENT_VALUE: if (object_type == OBJECT_COLOR) { +#ifdef BACAPP_XY_COLOR /* Properties using BACnetxyColor */ len = xy_color_decode(apdu, max_apdu_len, &value->type.XY_Color); +#endif } else { /* Decode a "classic" simple property */ len = bacapp_decode_generic_property( @@ -1305,15 +1382,19 @@ int bacapp_decode_known_property(uint8_t *apdu, break; case PROP_COLOR_COMMAND: +#ifdef BACAPP_COLOR_COMMAND /* Properties using BACnetColorCommand */ len = color_command_decode( apdu, max_apdu_len, NULL, &value->type.Color_Command); +#endif break; case PROP_LIGHTING_COMMAND: +#ifdef BACAPP_LIGHTING_COMMAND /* Properties using BACnetLightingCommand */ len = lighting_command_decode( apdu, max_apdu_len, &value->type.Lighting_Command); +#endif break; case PROP_PRIORITY_ARRAY: @@ -1322,14 +1403,18 @@ int bacapp_decode_known_property(uint8_t *apdu, break; case PROP_WEEKLY_SCHEDULE: +#ifdef BACAPP_WEEKLY_SCHEDULE /* BACnetWeeklySchedule ([7] BACnetDailySchedule*/ len = bacnet_weeklyschedule_decode( apdu, max_apdu_len, &value->type.Weekly_Schedule); +#endif break; case PROP_RECIPIENT_LIST: +#ifdef BACAPP_DESTINATION len = bacnet_destination_decode( apdu, max_apdu_len, &value->type.Destination); +#endif break; /* properties without a specific decoder - fall through to default @@ -1365,7 +1450,7 @@ int bacapp_decode_known_property(uint8_t *apdu, } #endif -#if defined(BACAPP_TYPES_EXTRA) +#if defined(BACAPP_COMPLEX_TYPES) /** * @brief Determine the BACnet Context Data number of APDU bytes consumed * @@ -1499,17 +1584,6 @@ bool bacapp_copy(BACNET_APPLICATION_DATA_VALUE *dest_value, dest_value->type.Object_Id.instance = src_value->type.Object_Id.instance; break; -#endif -#if defined(BACAPP_TYPES_EXTRA) - case BACNET_APPLICATION_TAG_LIGHTING_COMMAND: - status = - lighting_command_copy(&dest_value->type.Lighting_Command, - &src_value->type.Lighting_Command); - break; - case BACNET_APPLICATION_TAG_HOST_N_PORT: - status = host_n_port_copy(&dest_value->type.Host_Address, - &src_value->type.Host_Address); - break; #endif default: memcpy(&dest_value->type, &src_value->type, @@ -1582,7 +1656,7 @@ int bacapp_data_len( } total_len_enable = true; } else if (bacnet_is_context_specific(apdu, apdu_len_max)) { -#if defined(BACAPP_TYPES_EXTRA) +#if defined(BACAPP_COMPLEX_TYPES) /* context-specific tagged data */ len = bacapp_decode_context_data_len( apdu, apdu_len_max - apdu_len, property); @@ -1737,7 +1811,7 @@ static int bacapp_snprintf_time(char *str, size_t str_len, BACNET_TIME *btime) } #endif -#if defined(BACAPP_TYPES_EXTRA) +#if defined(BACAPP_WEEKLY_SCHEDULE) static int bacapp_snprintf_weeklyschedule(char *str, size_t str_len, BACNET_WEEKLY_SCHEDULE *ws, @@ -1897,9 +1971,6 @@ int bacapp_snprintf_value( BACNET_OBJECT_TYPE object_type = MAX_BACNET_OBJECT_TYPE; int ret_val = 0; int slen = 0; -#if defined(BACAPP_OCTET_STRING) || defined(BACAPP_TYPES_EXTRA) - uint8_t *octet_str; -#endif #if (__STDC_VERSION__ >= 199901L) && defined(__STDC_ISO_10646__) /* Wide character (decoded from multi-byte character). */ wchar_t wc; @@ -1950,19 +2021,22 @@ int bacapp_snprintf_value( #if defined(BACAPP_OCTET_STRING) case BACNET_APPLICATION_TAG_OCTET_STRING: len = octetstring_length(&value->type.Octet_String); - octet_str = octetstring_value(&value->type.Octet_String); - for (i = 0; i < len; i++) { - slen = snprintf(str, str_len, "%02X", *octet_str); - octet_str++; - if (str) { - str += slen; - if (str_len >= slen) { - str_len -= slen; - } else { - str_len = 0; + if (len > 0) { + uint8_t *octet_str; + octet_str = octetstring_value(&value->type.Octet_String); + for (i = 0; i < len; i++) { + slen = snprintf(str, str_len, "%02X", *octet_str); + octet_str++; + if (str) { + str += slen; + if (str_len >= slen) { + str_len -= slen; + } else { + str_len = 0; + } } + ret_val += slen; } - ret_val += slen; } break; #endif @@ -2160,12 +2234,12 @@ int bacapp_snprintf_value( case PROP_TRANSITION: ret_val = snprintf(str, str_len, "%s", bactext_lighting_transition( - value->type.Enumerated)); + value->type.Enumerated)); break; case PROP_IN_PROGRESS: ret_val = snprintf(str, str_len, "%s", bactext_lighting_in_progress( - value->type.Enumerated)); + value->type.Enumerated)); break; default: ret_val = snprintf(str, str_len, "%lu", @@ -2221,21 +2295,7 @@ int bacapp_snprintf_value( ret_val += slen; break; #endif -#if defined(BACAPP_TYPES_EXTRA) - case BACNET_APPLICATION_TAG_DATETIME: - slen = bacapp_snprintf_date(str, str_len, &value->type.Date); - ret_val += slen; - if (str) { - str += slen; - if (str_len >= slen) { - str_len -= slen; - } else { - str_len = 0; - } - } - slen = bacapp_snprintf_time(str, str_len, &value->type.Time); - ret_val += slen; - break; +#if defined(BACAPP_TIMESTAMP) case BACNET_APPLICATION_TAG_TIMESTAMP: /*ISO 8601 format */ slen = snprintf(str, str_len, @@ -2250,8 +2310,12 @@ int bacapp_snprintf_value( value->type.Time_Stamp.value.dateTime.time.hundredths); ret_val += slen; break; - case BACNET_APPLICATION_TAG_LIGHTING_COMMAND: - slen = snprintf(str, str_len, "("); +#endif +#if defined(BACAPP_DATETIME) + case BACNET_APPLICATION_TAG_DATETIME: + slen = bacapp_snprintf_date( + str, str_len, &value->type.Date_Time.date); + ret_val += slen; if (str) { str += slen; if (str_len >= slen) { @@ -2260,28 +2324,25 @@ int bacapp_snprintf_value( str_len = 0; } } - ret_val += slen; - slen = snprintf(str, str_len, "%s", - bactext_lighting_operation_name( - value->type.Lighting_Command.operation)); - if (str) { - str += slen; - if (str_len >= slen) { - str_len -= slen; - } else { - str_len = 0; - } - } - ret_val += slen; - /* FIXME: add the Lighting Command optional values */ - slen = snprintf(str, str_len, ")"); + slen = bacapp_snprintf_time( + str, str_len, &value->type.Date_Time.time); ret_val += slen; break; +#endif +#if defined(BACAPP_LIGHTING_COMMAND) + case BACNET_APPLICATION_TAG_LIGHTING_COMMAND: + ret_val = lighting_command_to_ascii( + &value->type.Lighting_Command, str, str_len); + break; +#endif +#if defined(BACAPP_XY_COLOR) case BACNET_APPLICATION_TAG_XY_COLOR: /* BACnetxyColor */ - ret_val = xy_color_to_ascii(&value->type.XY_Color, str, - str_len); + ret_val = + xy_color_to_ascii(&value->type.XY_Color, str, str_len); break; +#endif +#if defined(BACAPP_COLOR_COMMAND) case BACNET_APPLICATION_TAG_COLOR_COMMAND: /* BACnetColorCommand */ slen = snprintf(str, str_len, "("); @@ -2310,18 +2371,19 @@ int bacapp_snprintf_value( slen = snprintf(str, str_len, ")"); ret_val += slen; break; +#endif +#if defined(BACAPP_WEEKLY_SCHEDULE) case BACNET_APPLICATION_TAG_WEEKLY_SCHEDULE: /* BACnetWeeklySchedule */ ret_val = bacapp_snprintf_weeklyschedule(str, str_len, &value->type.Weekly_Schedule, object_value->array_index); break; - case BACNET_APPLICATION_TAG_DESTINATION: - /* BACnetWeeklySchedule */ - ret_val = bacnet_destination_to_ascii( - &value->type.Destination, str, str_len); - break; +#endif +#if defined(BACAPP_HOST_N_PORT) case BACNET_APPLICATION_TAG_HOST_N_PORT: + /* BACnetHostNPort */ if (value->type.Host_Address.host_ip_address) { + uint8_t *octet_str; octet_str = octetstring_value( &value->type.Host_Address.host.ip_address); slen = snprintf(str, str_len, "%u.%u.%u.%u:%u", @@ -2365,6 +2427,12 @@ int bacapp_snprintf_value( ret_val += slen; } break; +#endif +#if defined(BACAPP_DESTINATION) + case BACNET_APPLICATION_TAG_DESTINATION: + ret_val = bacnet_destination_to_ascii( + &value->type.Destination, str, str_len); + break; #endif default: ret_val = @@ -2457,7 +2525,7 @@ static char *trim(char *str, const char *trimmedchars) return ltrim(rtrim(str, trimmedchars), trimmedchars); } -#if defined(BACAPP_TYPES_EXTRA) +#if defined(BACAPP_WEEKLY_SCHEDULE) static bool parse_weeklyschedule( char *str, BACNET_APPLICATION_DATA_VALUE *value) { @@ -2650,9 +2718,6 @@ bool bacapp_parse_application_data(BACNET_APPLICATION_TAG tag_number, BACNET_UNSIGNED_INTEGER unsigned_long_value = 0; double double_value = 0.0; int count = 0; -#if defined(BACAPP_TYPES_EXTRA) - unsigned a[4] = { 0 }, p = 0; -#endif if (value && (tag_number != MAX_BACNET_APPLICATION_TAG)) { status = true; @@ -2797,43 +2862,42 @@ bool bacapp_parse_application_data(BACNET_APPLICATION_TAG tag_number, } break; #endif -#if defined(BACAPP_TYPES_EXTRA) - case BACNET_APPLICATION_TAG_LIGHTING_COMMAND: - /* FIXME: add parsing for lighting command */ +#if defined(BACAPP_DATETIME) + case BACNET_APPLICATION_TAG_DATETIME: + /* BACnetDateTime */ + status = datetime_init_ascii(&value->type.Date_Time, argv); break; +#endif +#if defined(BACAPP_LIGHTING_COMMAND) + case BACNET_APPLICATION_TAG_LIGHTING_COMMAND: + /* BACnetLightingCommand */ + status = lighting_command_from_ascii( + &value->type.Lighting_Command, argv); + break; +#endif +#if defined(BACAPP_XY_COLOR) case BACNET_APPLICATION_TAG_XY_COLOR: /* BACnetxyColor */ status = xy_color_from_ascii(&value->type.XY_Color, argv); break; +#endif +#if defined(BACAPP_COLOR_COMMAND) case BACNET_APPLICATION_TAG_COLOR_COMMAND: /* FIXME: add parsing for BACnetColorCommand */ break; +#endif +#if defined(BACAPP_WEEKLY_SCHEDULE) case BACNET_APPLICATION_TAG_WEEKLY_SCHEDULE: status = parse_weeklyschedule(argv, value); break; +#endif +#if defined(BACAPP_HOST_N_PORT) case BACNET_APPLICATION_TAG_HOST_N_PORT: - count = sscanf(argv, "%3u.%3u.%3u.%3u:%5u", &a[0], &a[1], &a[2], - &a[3], &p); - if ((count == 4) || (count == 5)) { - uint8_t address[4]; - value->type.Host_Address.host_ip_address = true; - value->type.Host_Address.host_name = false; - address[0] = (uint8_t)a[0]; - address[1] = (uint8_t)a[1]; - address[2] = (uint8_t)a[2]; - address[3] = (uint8_t)a[3]; - octetstring_init( - &value->type.Host_Address.host.ip_address, address, 4); - if (count == 4) { - value->type.Host_Address.port = 0xBAC0U; - } else { - value->type.Host_Address.port = (uint16_t)p; - } - status = true; - } else { - status = false; - } + status = + host_n_port_from_ascii(&value->type.Host_Address, argv); break; +#endif +#if defined(BACAPP_DESTINATION) case BACNET_APPLICATION_TAG_DESTINATION: status = bacnet_destination_from_ascii( &value->type.Destination, argv); @@ -3026,6 +3090,7 @@ int bacapp_property_value_decode( int apdu_len = 0; int tag_len = 0; uint32_t enumerated_value = 0; + uint32_t len_value_type = 0; BACNET_UNSIGNED_INTEGER unsigned_value = 0; BACNET_PROPERTY_ID property_identifier = PROP_ALL; BACNET_APPLICATION_DATA_VALUE *app_data = NULL; @@ -3044,9 +3109,10 @@ int bacapp_property_value_decode( } /* property-array-index [1] Unsigned OPTIONAL */ if (bacnet_is_context_tag_number( - &apdu[apdu_len], apdu_size - apdu_len, 1, NULL)) { - len = bacnet_unsigned_context_decode( - &apdu[apdu_len], apdu_size - apdu_len, 1, &unsigned_value); + &apdu[apdu_len], apdu_size - apdu_len, 1, &len, &len_value_type)) { + apdu_len += len; + len = bacnet_unsigned_decode(&apdu[apdu_len], apdu_size - apdu_len, + len_value_type, &unsigned_value); if (len > 0) { if (unsigned_value > UINT32_MAX) { return BACNET_STATUS_ERROR; @@ -3106,9 +3172,10 @@ int bacapp_property_value_decode( } /* priority [3] Unsigned (1..16) OPTIONAL */ if (bacnet_is_context_tag_number( - &apdu[apdu_len], apdu_size - apdu_len, 3, NULL)) { - len = bacnet_unsigned_context_decode( - &apdu[apdu_len], apdu_size - apdu_len, 3, &unsigned_value); + &apdu[apdu_len], apdu_size - apdu_len, 3, &len, &len_value_type)) { + apdu_len += len; + len = bacnet_unsigned_decode(&apdu[apdu_len], apdu_size - apdu_len, + len_value_type, &unsigned_value); if (len > 0) { if (unsigned_value > UINT8_MAX) { return BACNET_STATUS_ERROR; @@ -3241,36 +3308,79 @@ bool bacapp_same_value(BACNET_APPLICATION_DATA_VALUE *value, &value->type.Bit_String, &test_value->type.Bit_String); break; #endif -#if defined(BACAPP_TYPES_EXTRA) +#if defined(BACAPP_TIMESTAMP) + case BACNET_APPLICATION_TAG_TIMESTAMP: + status = bacapp_timestamp_same( + &value->type.Time_Stamp, &test_value->type.Time_Stamp); + break; +#endif +#if defined(BACAPP_DATETIME) case BACNET_APPLICATION_TAG_DATETIME: if (datetime_compare(&value->type.Date_Time, &test_value->type.Date_Time) == 0) { status = true; } break; +#endif +#if defined(BACAPP_LIGHTING_COMMAND) case BACNET_APPLICATION_TAG_LIGHTING_COMMAND: status = lighting_command_same(&value->type.Lighting_Command, &test_value->type.Lighting_Command); break; +#endif +#if defined(BACAPP_XY_COLOR) case BACNET_APPLICATION_TAG_XY_COLOR: /* BACnetxyColor */ status = xy_color_same( &value->type.XY_Color, &test_value->type.XY_Color); break; +#endif +#if defined(BACAPP_COLOR_COMMAND) case BACNET_APPLICATION_TAG_COLOR_COMMAND: /* BACnetColorCommand */ status = color_command_same(&value->type.Color_Command, &test_value->type.Color_Command); break; +#endif +#if defined(BACAPP_WEEKLY_SCHEDULE) case BACNET_APPLICATION_TAG_WEEKLY_SCHEDULE: /* BACnetWeeklySchedule */ status = bacnet_weeklyschedule_same(&value->type.Weekly_Schedule, &test_value->type.Weekly_Schedule); break; +#endif +#if defined(BACAPP_HOST_N_PORT) case BACNET_APPLICATION_TAG_HOST_N_PORT: status = host_n_port_same( - &value->type.Host_Address, &value->type.Host_Address); + &value->type.Host_Address, &test_value->type.Host_Address); + break; +#endif +#if defined(BACAPP_DEVICE_OBJECT_PROPERTY_REFERENCE) + case BACNET_APPLICATION_TAG_DEVICE_OBJECT_PROPERTY_REFERENCE: + status = bacnet_device_object_property_reference_same( + &value->type.Device_Object_Property_Reference, + &test_value->type.Device_Object_Property_Reference); + break; +#endif +#if defined(BACAPP_DEVICE_OBJECT_REFERENCE) + case BACNET_APPLICATION_TAG_DEVICE_OBJECT_REFERENCE: + status = bacnet_device_object_reference_same( + &value->type.Device_Object_Reference, + &test_value->type.Device_Object_Reference); + break; +#endif +#if defined(BACAPP_OBJECT_PROPERTY_REFERENCE) + case BACNET_APPLICATION_TAG_OBJECT_PROPERTY_REFERENCE: + status = bacnet_object_property_reference_same( + &value->type.Object_Property_Reference, + &test_value->type.Object_Property_Reference); + break; +#endif +#if defined(BACAPP_DESTINATION) + case BACNET_APPLICATION_TAG_DESTINATION: + status = bacnet_destination_same( + &value->type.Destination, &test_value->type.Destination); break; #endif default: diff --git a/src/bacnet/bacapp.h b/src/bacnet/bacapp.h index 60de7c61..baf16b1e 100644 --- a/src/bacnet/bacapp.h +++ b/src/bacnet/bacapp.h @@ -82,20 +82,40 @@ typedef struct BACnet_Application_Data_Value { #if defined (BACAPP_OBJECT_ID) BACNET_OBJECT_ID Object_Id; #endif -#if defined (BACAPP_TYPES_EXTRA) +#if defined (BACAPP_TIMESTAMP) BACNET_TIMESTAMP Time_Stamp; +#endif +#if defined (BACAPP_DATETIME) BACNET_DATE_TIME Date_Time; +#endif +#if defined (BACAPP_LIGHTING_COMMAND) BACNET_LIGHTING_COMMAND Lighting_Command; - BACNET_COLOR_COMMAND Color_Command; +#endif +#if defined (BACAPP_XY_COLOR) BACNET_XY_COLOR XY_Color; +#endif +#if defined (BACAPP_COLOR_COMMAND) + BACNET_COLOR_COMMAND Color_Command; +#endif +#if defined (BACAPP_WEEKLY_SCHEDULE) BACNET_WEEKLY_SCHEDULE Weekly_Schedule; +#endif +#if defined (BACAPP_HOST_N_PORT) BACNET_HOST_N_PORT Host_Address; +#endif +#if defined (BACAPP_DEVICE_OBJECT_PROPERTY_REFERENCE) BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE Device_Object_Property_Reference; +#endif +#if defined (BACAPP_DEVICE_OBJECT_REFERENCE) BACNET_DEVICE_OBJECT_REFERENCE Device_Object_Reference; +#endif +#if defined (BACAPP_OBJECT_PROPERTY_REFERENCE) BACNET_OBJECT_PROPERTY_REFERENCE Object_Property_Reference; +#endif +#if defined (BACAPP_DESTINATION) BACNET_DESTINATION Destination; #endif } type; diff --git a/src/bacnet/bacdcode.c b/src/bacnet/bacdcode.c index faf880bd..2f0c63b0 100644 --- a/src/bacnet/bacdcode.c +++ b/src/bacnet/bacdcode.c @@ -792,11 +792,14 @@ bool decode_is_context_tag_with_length( * @param tag_number Tag number, that has been decoded before. * @param tag_length Pointer to a variable, or NULL. * Returns the length of the tag in bytes if not NULL. + * @param len_value_type Pointer to a variable, or NULL. + * Returns the len_value_type of the tag in bytes if not NULL. * * @return true on a match, false otherwise. */ bool bacnet_is_context_tag_number( - uint8_t *apdu, uint32_t apdu_size, uint8_t tag_number, int *tag_length) + uint8_t *apdu, uint32_t apdu_size, uint8_t tag_number, int *tag_length, + uint32_t *len_value_type) { bool match = false; int len; @@ -808,6 +811,9 @@ bool bacnet_is_context_tag_number( if (tag_length) { *tag_length = len; } + if (len_value_type) { + *len_value_type = tag.len_value_type; + } match = true; } } diff --git a/src/bacnet/bacdcode.h b/src/bacnet/bacdcode.h index 861afd17..7319476e 100644 --- a/src/bacnet/bacdcode.h +++ b/src/bacnet/bacdcode.h @@ -86,7 +86,8 @@ bool bacnet_is_context_specific(uint8_t *apdu, uint32_t apdu_size); BACNET_STACK_EXPORT bool bacnet_is_context_tag_number( - uint8_t *apdu, uint32_t apdu_size, uint8_t tag_number, int *tag_length); + uint8_t *apdu, uint32_t apdu_size, uint8_t tag_number, int *tag_length, + uint32_t *len_value_type); BACNET_STACK_EXPORT int bacnet_tag_number_decode( uint8_t *apdu, uint32_t apdu_size, uint8_t *tag_number); diff --git a/src/bacnet/bacdevobjpropref.c b/src/bacnet/bacdevobjpropref.c index ac615478..5ce179ce 100644 --- a/src/bacnet/bacdevobjpropref.c +++ b/src/bacnet/bacdevobjpropref.c @@ -166,6 +166,7 @@ int bacnet_device_object_property_reference_decode(uint8_t *apdu, { int apdu_len = 0; int len = 0; + uint32_t len_value_type = 0; BACNET_UNSIGNED_INTEGER array_index = 0; BACNET_OBJECT_TYPE object_type = 0; uint32_t object_instance = 0; @@ -199,9 +200,10 @@ int bacnet_device_object_property_reference_decode(uint8_t *apdu, } /* property-array-index [2] Unsigned OPTIONAL */ if (bacnet_is_context_tag_number( - &apdu[apdu_len], apdu_size - apdu_len, 2, NULL)) { - len = bacnet_unsigned_context_decode( - &apdu[apdu_len], apdu_size - apdu_len, 2, &array_index); + &apdu[apdu_len], apdu_size - apdu_len, 2, &len, &len_value_type)) { + apdu_len += len; + len = bacnet_unsigned_decode(&apdu[apdu_len], apdu_size - apdu_len, + len_value_type, &array_index); if (len > 0) { apdu_len += len; if (value) { @@ -218,9 +220,10 @@ int bacnet_device_object_property_reference_decode(uint8_t *apdu, } /* device-identifier [3] BACnetObjectIdentifier OPTIONAL */ if (bacnet_is_context_tag_number( - &apdu[apdu_len], apdu_size - apdu_len, 3, NULL)) { - len = bacnet_object_id_context_decode(&apdu[apdu_len], - apdu_size - apdu_len, 3, &object_type, &object_instance); + &apdu[apdu_len], apdu_size - apdu_len, 3, &len, &len_value_type)) { + apdu_len += len; + len = bacnet_object_id_decode(&apdu[apdu_len], apdu_size - apdu_len, + len_value_type, &object_type, &object_instance); if (len > 0) { apdu_len += len; if (value) { @@ -286,6 +289,34 @@ int bacnet_device_object_property_reference_context_decode(uint8_t *apdu, return apdu_len; } +/** + * @brief Compare the complex data of value1 and value2 + * @param value1 - value 1 structure + * @param value2 - value 2 structure + * @return true if the values are the same + */ +bool bacnet_device_object_property_reference_same( + BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *value1, + BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *value2) +{ + bool status = false; + + if (value1 && value2) { + if ((value1->arrayIndex == value2->arrayIndex) && + (value1->deviceIdentifier.instance == + value2->deviceIdentifier.instance) && + (value1->deviceIdentifier.type == value2->deviceIdentifier.type) && + (value1->objectIdentifier.instance == + value2->objectIdentifier.instance) && + (value1->objectIdentifier.type == value2->objectIdentifier.type) && + (value1->propertyIdentifier == value2->propertyIdentifier)) { + status = true; + } + } + + return status; +} + /** * Decode a property reference of a device object. * @@ -433,6 +464,7 @@ int bacnet_device_object_reference_decode( { int len; int apdu_len = 0; + uint32_t len_value_type = 0; BACNET_OBJECT_TYPE object_type = 0; uint32_t object_instance = 0; @@ -441,9 +473,10 @@ int bacnet_device_object_reference_decode( } /* device-identifier [0] BACnetObjectIdentifier OPTIONAL */ if (bacnet_is_context_tag_number( - &apdu[apdu_len], apdu_size - apdu_len, 0, NULL)) { - len = bacnet_object_id_context_decode(&apdu[apdu_len], - apdu_size - apdu_len, 0, &object_type, &object_instance); + &apdu[apdu_len], apdu_size - apdu_len, 0, &len, &len_value_type)) { + apdu_len += len; + len = bacnet_object_id_decode(&apdu[apdu_len], apdu_size - apdu_len, + len_value_type, &object_type, &object_instance); if (len > 0) { apdu_len += len; if (value) { @@ -519,6 +552,31 @@ int bacnet_device_object_reference_context_decode(uint8_t *apdu, return apdu_len; } +/** + * @brief Compare the complex data of value1 and value2 + * @param value1 - value 1 structure + * @param value2 - value 2 structure + * @return true if the values are the same + */ +bool bacnet_device_object_reference_same(BACNET_DEVICE_OBJECT_REFERENCE *value1, + BACNET_DEVICE_OBJECT_REFERENCE *value2) +{ + bool status = false; + + if (value1 && value2) { + if ((value1->deviceIdentifier.instance == + value2->deviceIdentifier.instance) && + (value1->deviceIdentifier.type == value2->deviceIdentifier.type) && + (value1->objectIdentifier.instance == + value2->objectIdentifier.instance) && + (value1->objectIdentifier.type == value2->objectIdentifier.type)) { + status = true; + } + } + + return status; +} + /** * Decode the device object reference. * @@ -758,3 +816,28 @@ int bacapp_decode_context_obj_property_ref(uint8_t *apdu, return apdu_len; } + +/** + * @brief Compare the complex data of value1 and value2 + * @param value1 - value 1 structure + * @param value2 - value 2 structure + * @return true if the values are the same + */ +bool bacnet_object_property_reference_same( + BACNET_OBJECT_PROPERTY_REFERENCE *value1, + BACNET_OBJECT_PROPERTY_REFERENCE *value2) +{ + bool status = false; + + if (value1 && value2) { + if ((value1->property_identifier == value2->property_identifier) && + (value1->object_identifier.instance == + value2->object_identifier.instance) && + (value1->object_identifier.type == + value2->object_identifier.type)) { + status = true; + } + } + + return status; +} diff --git a/src/bacnet/bacdevobjpropref.h b/src/bacnet/bacdevobjpropref.h index 1ad5bc92..a3b19688 100644 --- a/src/bacnet/bacdevobjpropref.h +++ b/src/bacnet/bacdevobjpropref.h @@ -148,6 +148,20 @@ int bacnet_device_object_reference_context_decode(uint8_t *apdu, uint8_t tag_number, BACNET_DEVICE_OBJECT_REFERENCE *value); +BACNET_STACK_EXPORT +bool bacnet_device_object_property_reference_same( + BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *value1, + BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *value2); + +BACNET_STACK_EXPORT +bool bacnet_device_object_reference_same( + BACNET_DEVICE_OBJECT_REFERENCE *value1, + BACNET_DEVICE_OBJECT_REFERENCE *value2); + +BACNET_STACK_EXPORT +bool bacnet_object_property_reference_same( + BACNET_OBJECT_PROPERTY_REFERENCE *value1, + BACNET_OBJECT_PROPERTY_REFERENCE *value2); #ifdef __cplusplus } diff --git a/src/bacnet/bactext.c b/src/bacnet/bactext.c index 3c27c5ea..38394af3 100644 --- a/src/bacnet/bactext.c +++ b/src/bacnet/bactext.c @@ -1750,6 +1750,12 @@ const char *bactext_lighting_operation_name(unsigned index) } } +bool bactext_bactext_lighting_operation_strtol(const char *search_name, unsigned *found_index) +{ + return bactext_strtol_index( + bacnet_lighting_operation_names, search_name, found_index); +} + INDTEXT_DATA bacnet_color_operation_names[] = { { BACNET_COLOR_OPERATION_NONE, "none" }, { BACNET_COLOR_OPERATION_FADE_TO_COLOR, "fade-to-color" }, diff --git a/src/bacnet/bactext.h b/src/bacnet/bactext.h index 8417afee..c834a35c 100644 --- a/src/bacnet/bactext.h +++ b/src/bacnet/bactext.h @@ -200,6 +200,11 @@ extern "C" { const char *bactext_lighting_operation_name( unsigned index); + BACNET_STACK_EXPORT + bool bactext_bactext_lighting_operation_strtol( + const char *search_name, + unsigned *found_index); + BACNET_STACK_EXPORT const char *bactext_lighting_in_progress( unsigned index); diff --git a/src/bacnet/config.h b/src/bacnet/config.h index 1ec2c341..82c7e9a8 100644 --- a/src/bacnet/config.h +++ b/src/bacnet/config.h @@ -156,26 +156,26 @@ defined(BACAPP_DATE) || \ defined(BACAPP_TIME) || \ defined(BACAPP_OBJECT_ID) || \ + defined(BACAPP_DATETIME) || \ + defined(BACAPP_LIGHTING_COMMAND) || \ + defined(BACAPP_XY_COLOR) || \ + defined(BACAPP_COLOR_COMMAND) || \ + defined(BACAPP_WEEKLY_SCHEDULE) || \ + defined(BACAPP_HOST_N_PORT) || \ + defined(BACAPP_DEVICE_OBJECT_PROPERTY_REFERENCE) || \ + defined(BACAPP_DEVICE_OBJECT_REFERENCE) || \ + defined(BACAPP_OBJECT_PROPERTY_REFERENCE) || \ + defined(BACAPP_DESTINATION) || \ defined(BACAPP_TYPES_EXTRA)) #define BACAPP_ALL #endif #if defined (BACAPP_ALL) -#define BACAPP_NULL -#define BACAPP_BOOLEAN -#define BACAPP_UNSIGNED -#define BACAPP_SIGNED -#define BACAPP_REAL -#define BACAPP_DOUBLE -#define BACAPP_OCTET_STRING -#define BACAPP_CHARACTER_STRING -#define BACAPP_BIT_STRING -#define BACAPP_ENUMERATED -#define BACAPP_DATE -#define BACAPP_TIME -#define BACAPP_OBJECT_ID +#define BACAPP_MINIMAL #define BACAPP_TYPES_EXTRA -#elif defined (BACAPP_MINIMAL) +#endif + +#if defined (BACAPP_MINIMAL) #define BACAPP_NULL #define BACAPP_BOOLEAN #define BACAPP_UNSIGNED @@ -190,6 +190,35 @@ #define BACAPP_OBJECT_ID #endif +#if defined (BACAPP_TYPES_EXTRA) +#define BACAPP_DOUBLE +#define BACAPP_TIMESTAMP +#define BACAPP_DATETIME +#define BACAPP_LIGHTING_COMMAND +#define BACAPP_XY_COLOR +#define BACAPP_COLOR_COMMAND +#define BACAPP_WEEKLY_SCHEDULE +#define BACAPP_HOST_N_PORT +#define BACAPP_DEVICE_OBJECT_PROPERTY_REFERENCE +#define BACAPP_DEVICE_OBJECT_REFERENCE +#define BACAPP_OBJECT_PROPERTY_REFERENCE +#define BACAPP_DESTINATION +#endif + +#if defined(BACAPP_DOUBLE) || \ + defined(BACAPP_DATETIME) || \ + defined(BACAPP_LIGHTING_COMMAND) || \ + defined(BACAPP_XY_COLOR) || \ + defined(BACAPP_COLOR_COMMAND) || \ + defined(BACAPP_WEEKLY_SCHEDULE) || \ + defined(BACAPP_HOST_N_PORT) || \ + defined(BACAPP_DEVICE_OBJECT_PROPERTY_REFERENCE) || \ + defined(BACAPP_DEVICE_OBJECT_REFERENCE) || \ + defined(BACAPP_OBJECT_PROPERTY_REFERENCE) || \ + defined(BACAPP_DESTINATION) +#define BACAPP_COMPLEX_TYPES +#endif + /* ** Set the maximum vector type sizes */ diff --git a/src/bacnet/datetime.c b/src/bacnet/datetime.c index cf4c7908..a959ac45 100644 --- a/src/bacnet/datetime.c +++ b/src/bacnet/datetime.c @@ -1252,3 +1252,31 @@ bool datetime_time_init_ascii(BACNET_TIME *btime, const char *ascii) return status; } + +/** + * @brief Parse an ascii string for the date+time 2021/12/31 23:59:59.99 + * @param bdate - #BACNET_DATE_TIME structure + * @param argv - C string with date+time formatted 2021/12/31 23:59:59.99 + * @return true if parsed successfully + */ +bool datetime_init_ascii(BACNET_DATE_TIME *bdatetime, const char *ascii) +{ + bool status = false; + int year, month, day; + int hour = 0, min = 0, sec = 0, hundredths = 0; + int count = 0; + + count = sscanf(ascii, "%4d/%3d/%3d %3d:%3d:%3d.%3d", &year, &month, &day, + &hour, &min, &sec, &hundredths); + if (count >= 3) { + datetime_set_date( + &bdatetime->date, (uint16_t)year, (uint8_t)month, (uint8_t)day); + bdatetime->time.hour = (uint8_t)hour; + bdatetime->time.min = (uint8_t)min; + bdatetime->time.sec = (uint8_t)sec; + bdatetime->time.hundredths = (uint8_t)hundredths; + status = true; + } + + return status; +} diff --git a/src/bacnet/datetime.h b/src/bacnet/datetime.h index caa2a619..1d89aa4e 100644 --- a/src/bacnet/datetime.h +++ b/src/bacnet/datetime.h @@ -262,6 +262,8 @@ BACNET_STACK_EXPORT bool datetime_date_init_ascii(BACNET_DATE *bdate, const char *ascii); BACNET_STACK_EXPORT bool datetime_time_init_ascii(BACNET_TIME *btime, const char *ascii); +BACNET_STACK_EXPORT +bool datetime_init_ascii(BACNET_DATE_TIME *bdatetime, const char *ascii); BACNET_STACK_EXPORT int bacapp_encode_datetime(uint8_t *apdu, BACNET_DATE_TIME *value); diff --git a/src/bacnet/hostnport.c b/src/bacnet/hostnport.c index 184e5574..08dca1e7 100644 --- a/src/bacnet/hostnport.c +++ b/src/bacnet/hostnport.c @@ -303,3 +303,40 @@ bool host_n_port_same(BACNET_HOST_N_PORT *host1, BACNET_HOST_N_PORT *host2) } return status; } + +/** + * @brief Parse value from ASCII string (as entered by user) + * @param value - struct to populate with data from the ASCII string + * @param argv - ASCII string, zero terminated + * @return true on success + */ +bool host_n_port_from_ascii(BACNET_HOST_N_PORT *value, const char *argv) +{ + bool status = false; + unsigned a[4] = { 0 }, p = 0; + int count; + + count = sscanf(argv, "%3u.%3u.%3u.%3u:%5u", &a[0], &a[1], &a[2], + &a[3], &p); + if ((count == 4) || (count == 5)) { + uint8_t address[4]; + value->host_ip_address = true; + value->host_name = false; + address[0] = (uint8_t)a[0]; + address[1] = (uint8_t)a[1]; + address[2] = (uint8_t)a[2]; + address[3] = (uint8_t)a[3]; + octetstring_init( + &value->host.ip_address, address, 4); + if (count == 4) { + value->port = 0xBAC0U; + } else { + value->port = (uint16_t)p; + } + status = true; + } else { + status = false; + } + + return status; +} diff --git a/src/bacnet/hostnport.h b/src/bacnet/hostnport.h index e2175483..ea3ac74c 100644 --- a/src/bacnet/hostnport.h +++ b/src/bacnet/hostnport.h @@ -67,6 +67,10 @@ extern "C" { bool host_n_port_same( BACNET_HOST_N_PORT * dst, BACNET_HOST_N_PORT * src); + BACNET_STACK_EXPORT + bool host_n_port_from_ascii( + BACNET_HOST_N_PORT *value, + const char *argv); #ifdef __cplusplus } diff --git a/src/bacnet/lighting.c b/src/bacnet/lighting.c index ed1d23bf..657991dc 100644 --- a/src/bacnet/lighting.c +++ b/src/bacnet/lighting.c @@ -15,6 +15,7 @@ #include #include #include +#define __USE_ISOC99 #include #include "bacnet/bacdcode.h" #include "bacnet/bacreal.h" @@ -457,6 +458,276 @@ bool lighting_command_same( return status; } +/** + * @brief Convert BACnetLightingCommand to ASCII for printing + * @param value - struct to convert to ASCII + * @param buf - ASCII output buffer (or NULL for size) + * @param buf_size - ASCII output buffer capacity (or 0 for size) + * + * @return the number of characters which would be generated for the given + * input, excluding the trailing null. negative is returned if the + * capacity was not sufficient. + * + * @note buf and buf_size may be null and zero to return only the size + */ +int lighting_command_to_ascii( + const BACNET_LIGHTING_COMMAND *value, char *buf, size_t buf_size) +{ + int len = 0; + float target_level = -1.0F; + float ramp_rate = 0.0F; + float step_increment = 0.0; + uint32_t fade_time = 0; + uint8_t priority = BACNET_NO_PRIORITY; + + if (!value) { + return 0; + } + switch (value->operation) { + case BACNET_LIGHTS_NONE: + len = snprintf(buf, buf_size, "%u", (unsigned)value->operation); + break; + case BACNET_LIGHTS_FADE_TO: + if (value->use_target_level) { + target_level = value->target_level; + } + if (value->use_fade_time) { + fade_time = value->fade_time; + } + if (value->use_priority) { + priority = value->priority; + } + len = snprintf(buf, buf_size, "%u,%f,%lu,%u", value->operation, + target_level, (unsigned long)fade_time, (unsigned)priority); + break; + case BACNET_LIGHTS_RAMP_TO: + if (value->use_target_level) { + target_level = value->target_level; + } + if (value->use_ramp_rate) { + ramp_rate = value->ramp_rate; + } + if (value->use_priority) { + priority = value->priority; + } + len = snprintf(buf, buf_size, "%u,%f,%f,%u", + (unsigned)value->operation, target_level, ramp_rate, + (unsigned)priority); + break; + case BACNET_LIGHTS_STEP_UP: + case BACNET_LIGHTS_STEP_DOWN: + case BACNET_LIGHTS_STEP_ON: + case BACNET_LIGHTS_STEP_OFF: + if (value->use_step_increment) { + step_increment = value->step_increment; + } + if (value->use_priority) { + priority = value->priority; + } + len = snprintf(buf, buf_size, "%u,%f,%u", + (unsigned)value->operation, step_increment, (unsigned)priority); + break; + case BACNET_LIGHTS_WARN: + case BACNET_LIGHTS_WARN_OFF: + case BACNET_LIGHTS_WARN_RELINQUISH: + case BACNET_LIGHTS_STOP: + if (value->use_priority) { + priority = value->priority; + } + len = snprintf(buf, buf_size, "%u,%u", (unsigned)value->operation, + (unsigned)priority); + break; + default: + len = snprintf(buf, buf_size, "%u", (unsigned)value->operation); + break; + } + + return len; +} + +/** + * @brief Parse an ASCII string for a BACnetLightingCommand + * @param value [out] BACnetLightingCommand structure to store the results + * @param argv [in] nul terminated ASCII string to parse + * @return true if the address was parsed + */ +bool lighting_command_from_ascii( + BACNET_LIGHTING_COMMAND *value, const char *argv) +{ + bool status = false; + BACNET_LIGHTING_OPERATION operation = BACNET_LIGHTS_NONE; + unsigned a = 0; + float b = 0.0, c = 0.0, d = 0.0; + int count; + + if (!value) { + return false; + } + if (!argv) { + return false; + } + count = sscanf(argv, "%u,%f,%f,%f", &a, &b, &c, &d); + if (count >= 1) { + operation = a; + } else { + return false; + } + switch (operation) { + case BACNET_LIGHTS_NONE: + value->operation = operation; + value->use_target_level = false; + value->use_ramp_rate = false; + value->use_step_increment = false; + value->use_fade_time = false; + value->use_priority = false; + status = true; + break; + case BACNET_LIGHTS_FADE_TO: + value->operation = operation; + if (count >= 2) { + /* (0.0..100.0) OPTIONAL */ + if (isgreaterequal(b, 0.0) && islessequal(b, 100.0)) { + value->use_target_level = true; + value->target_level = b; + } else { + value->use_target_level = false; + } + } else { + value->use_target_level = false; + } + if (count >= 3) { + /* (100..86400000) OPTIONAL */ + if (isgreaterequal(c, 100.0) && islessequal(c, 86400000.0)) { + value->use_fade_time = true; + value->fade_time = c; + } else { + value->use_fade_time = false; + } + } else { + value->use_fade_time = false; + } + if (count >= 4) { + if (isgreaterequal(d, BACNET_MIN_PRIORITY) && + islessequal(d, BACNET_MAX_PRIORITY)) { + value->use_priority = true; + value->priority = d; + } else { + value->use_priority = false; + } + } else { + value->use_priority = false; + } + value->use_ramp_rate = false; + value->use_step_increment = false; + status = true; + break; + case BACNET_LIGHTS_RAMP_TO: + value->operation = operation; + if (count >= 2) { + /* (0.0..100.0) OPTIONAL */ + if (isgreaterequal(b, 0.0) && islessequal(b, 100.0)) { + value->use_target_level = true; + value->target_level = b; + } else { + value->use_target_level = false; + } + } else { + value->use_target_level = false; + } + if (count >= 3) { + /* (0.1..100.0) OPTIONAL */ + if (isgreaterequal(c, 0.1) && islessequal(c, 100.0)) { + value->use_ramp_rate = true; + value->ramp_rate = c; + } else { + value->use_ramp_rate = false; + } + } else { + value->use_ramp_rate = false; + } + if (count >= 4) { + if (isgreaterequal(d, BACNET_MIN_PRIORITY) && + islessequal(d, BACNET_MAX_PRIORITY)) { + value->use_priority = true; + value->priority = d; + } else { + value->use_priority = false; + } + } else { + value->use_priority = false; + } + value->use_fade_time = false; + value->use_step_increment = false; + status = true; + break; + case BACNET_LIGHTS_STEP_UP: + case BACNET_LIGHTS_STEP_DOWN: + case BACNET_LIGHTS_STEP_ON: + case BACNET_LIGHTS_STEP_OFF: + value->operation = operation; + /* (0.1..100.0) OPTIONAL */ + if (count >= 2) { + if (isgreaterequal(b, 0.1) && islessequal(b, 100.0)) { + value->use_step_increment = true; + value->ramp_rate = b; + } else { + value->step_increment = false; + } + } else { + value->step_increment = false; + } + if (count >= 3) { + if (isgreaterequal(c, BACNET_MIN_PRIORITY) && + islessequal(c, BACNET_MAX_PRIORITY)) { + value->use_priority = true; + value->priority = c; + } else { + value->use_priority = false; + } + } else { + value->use_priority = false; + } + value->use_target_level = false; + value->use_ramp_rate = false; + value->use_fade_time = false; + status = true; + break; + case BACNET_LIGHTS_WARN: + case BACNET_LIGHTS_WARN_OFF: + case BACNET_LIGHTS_WARN_RELINQUISH: + case BACNET_LIGHTS_STOP: + value->operation = operation; + if (count >= 2) { + if (isgreaterequal(b, BACNET_MIN_PRIORITY) && + islessequal(b, BACNET_MAX_PRIORITY)) { + value->use_priority = true; + value->priority = b; + } else { + value->use_priority = false; + } + } else { + value->use_priority = false; + } + value->use_target_level = false; + value->use_ramp_rate = false; + value->use_step_increment = false; + value->use_fade_time = false; + status = true; + break; + default: + value->operation = operation; + value->use_target_level = false; + value->use_ramp_rate = false; + value->use_step_increment = false; + value->use_fade_time = false; + value->use_priority = false; + status = true; + break; + } + + return status; +} + /** * @brief Encode a BACnetxyColor complex data type * @@ -670,13 +941,10 @@ bool xy_color_same(BACNET_XY_COLOR *value1, BACNET_XY_COLOR *value2) * * @note buf and buf_size may be null and zero to return only the size */ -int xy_color_to_ascii( - const BACNET_XY_COLOR *value, - char *buf, - size_t buf_size) +int xy_color_to_ascii(const BACNET_XY_COLOR *value, char *buf, size_t buf_size) { - return snprintf(buf, buf_size, "(%f,%f)", value->x_coordinate, - value->x_coordinate); + return snprintf( + buf, buf_size, "(%f,%f)", value->x_coordinate, value->x_coordinate); } /** @@ -689,7 +957,7 @@ bool xy_color_from_ascii(BACNET_XY_COLOR *value, const char *argv) { bool status = false; int count; - float x,y; + float x, y; count = sscanf(argv, "%f,%f", &x, &y); if (count == 2) { diff --git a/src/bacnet/lighting.h b/src/bacnet/lighting.h index caf3f528..518669c4 100644 --- a/src/bacnet/lighting.h +++ b/src/bacnet/lighting.h @@ -115,6 +115,16 @@ extern "C" { bool lighting_command_same( BACNET_LIGHTING_COMMAND * dst, BACNET_LIGHTING_COMMAND * src); + + BACNET_STACK_EXPORT + bool lighting_command_from_ascii( + BACNET_LIGHTING_COMMAND *value, + const char *argv); + BACNET_STACK_EXPORT + int lighting_command_to_ascii( + const BACNET_LIGHTING_COMMAND *value, + char *buf, + size_t buf_size); BACNET_STACK_EXPORT int xy_color_encode(uint8_t *apdu, diff --git a/src/bacnet/timestamp.c b/src/bacnet/timestamp.c index b6b528d3..a0be1e40 100644 --- a/src/bacnet/timestamp.c +++ b/src/bacnet/timestamp.c @@ -105,9 +105,49 @@ void bacapp_timestamp_copy(BACNET_TIMESTAMP *dest, BACNET_TIMESTAMP *src) } } -/** +/** + * @brief Compare two complex data values + * @param value1 - complex data value 1 structure + * @param value2 - complex data value 2 structure + * @return true if the two complex data values are the same + */ +bool bacapp_timestamp_same(BACNET_TIMESTAMP *value1, BACNET_TIMESTAMP *value2) +{ + bool status = false; + + if (value1 && value2) { + if (value1->tag == value2->tag) { + switch (value1->tag) { + case TIME_STAMP_TIME: + if (datetime_compare_time( + &value1->value.time, &value2->value.time) == 0) { + status = true; + } + break; + case TIME_STAMP_SEQUENCE: + if (value1->value.sequenceNum == + value2->value.sequenceNum) { + status = true; + } + break; + case TIME_STAMP_DATETIME: + if (datetime_compare(&value1->value.dateTime, + &value2->value.dateTime) == 0) { + status = true; + } + break; + default: + break; + } + } + } + + return status; +} + +/** * @brief Encode a time stamp. - * + * * BACnetTimeStamp ::= CHOICE { * time [0] Time, -- deprecated in version 1 revision 21 * sequence-number [1] Unsigned (0..65535), @@ -186,7 +226,7 @@ int bacapp_encode_context_timestamp( /** * @brief Decode a time stamp from the given buffer. - * + * * BACnetTimeStamp ::= CHOICE { * time [0] Time, -- deprecated in version 1 revision 21 * sequence-number [1] Unsigned (0..65535), @@ -224,8 +264,8 @@ int bacnet_timestamp_decode( if (value) { btime = &value->value.time; } - len = bacnet_time_context_decode(&apdu[apdu_len], - apdu_size - apdu_len, tag.number, btime); + len = bacnet_time_context_decode( + &apdu[apdu_len], apdu_size - apdu_len, tag.number, btime); if (len <= 0) { return BACNET_STATUS_ERROR; } @@ -251,8 +291,8 @@ int bacnet_timestamp_decode( if (value) { bdatetime = &value->value.dateTime; } - len = bacnet_datetime_context_decode(&apdu[apdu_len], - apdu_size - apdu_len, tag.number, bdatetime); + len = bacnet_datetime_context_decode( + &apdu[apdu_len], apdu_size - apdu_len, tag.number, bdatetime); if (len <= 0) { return BACNET_STATUS_ERROR; } @@ -278,7 +318,7 @@ int bacapp_decode_timestamp(uint8_t *apdu, BACNET_TIMESTAMP *value) return bacnet_timestamp_decode(apdu, MAX_APDU, value); } -/** +/** * @brief Decode a time stamp and check for opening and closing tags. * @param apdu Pointer to the APDU buffer. * @param apdu_size - the APDU buffer length @@ -315,7 +355,7 @@ int bacnet_timestamp_context_decode(uint8_t *apdu, return apdu_len; } -/** +/** * @brief Decode a time stamp and check for opening and closing tags. * @param apdu Pointer to the APDU buffer. * @param tag_number The tag number that shall diff --git a/src/bacnet/timestamp.h b/src/bacnet/timestamp.h index b2991eba..38a1cd0c 100644 --- a/src/bacnet/timestamp.h +++ b/src/bacnet/timestamp.h @@ -70,6 +70,11 @@ extern "C" { BACNET_TIMESTAMP * dest, BACNET_TIMESTAMP * src); + BACNET_STACK_EXPORT + bool bacapp_timestamp_same( + BACNET_TIMESTAMP *value1, + BACNET_TIMESTAMP *value2); + BACNET_STACK_EXPORT int bacapp_encode_timestamp( uint8_t * apdu, diff --git a/test/bacnet/bacapp/src/main.c b/test/bacnet/bacapp/src/main.c index 6e1a2bfe..cf1d82a8 100644 --- a/test/bacnet/bacapp/src/main.c +++ b/test/bacnet/bacapp/src/main.c @@ -355,103 +355,95 @@ static void test_bacapp_same_value(void) value.tag = test_value.tag; #if defined(BACAPP_BOOLEAN) zassert_true(bacapp_same_value(&value, &test_value), NULL); + value.type.Boolean = !test_value.type.Boolean; + zassert_false(bacapp_same_value(&value, &test_value), NULL); #else zassert_false(bacapp_same_value(&value, &test_value), NULL); #endif - value.type.Boolean = !test_value.type.Boolean; - zassert_false(bacapp_same_value(&value, &test_value), NULL); memset(&test_value, 0, sizeof(test_value)); test_value.tag = BACNET_APPLICATION_TAG_UNSIGNED_INT; value = test_value; /* Struct copy */ #if defined(BACAPP_UNSIGNED) zassert_true(bacapp_same_value(&value, &test_value), NULL); + value.type.Unsigned_Int = ~test_value.type.Unsigned_Int; + zassert_false(bacapp_same_value(&value, &test_value), NULL); #else zassert_false(bacapp_same_value(&value, &test_value), NULL); #endif - value.type.Unsigned_Int = ~test_value.type.Unsigned_Int; - zassert_false(bacapp_same_value(&value, &test_value), NULL); memset(&test_value, 0, sizeof(test_value)); test_value.tag = BACNET_APPLICATION_TAG_SIGNED_INT; value = test_value; /* Struct copy */ #if defined(BACAPP_SIGNED) zassert_true(bacapp_same_value(&value, &test_value), NULL); + value.type.Signed_Int = test_value.type.Signed_Int + 1; + zassert_false(bacapp_same_value(&value, &test_value), NULL); #else zassert_false(bacapp_same_value(&value, &test_value), NULL); #endif - value.type.Signed_Int = test_value.type.Signed_Int + 1; - zassert_false(bacapp_same_value(&value, &test_value), NULL); memset(&test_value, 0, sizeof(test_value)); test_value.tag = BACNET_APPLICATION_TAG_REAL; value = test_value; /* Struct copy */ #if defined(BACAPP_REAL) zassert_true(bacapp_same_value(&value, &test_value), NULL); + value.type.Real = test_value.type.Real + 1.0f; + zassert_false(bacapp_same_value(&value, &test_value), NULL); #else zassert_false(bacapp_same_value(&value, &test_value), NULL); #endif - value.type.Real = test_value.type.Real + 1.0f; - zassert_false(bacapp_same_value(&value, &test_value), NULL); memset(&test_value, 0, sizeof(test_value)); test_value.tag = BACNET_APPLICATION_TAG_DOUBLE; value = test_value; /* Struct copy */ #if defined(BACAPP_DOUBLE) zassert_true(bacapp_same_value(&value, &test_value), NULL); + value.type.Double = test_value.type.Double + 1.0; + zassert_false(bacapp_same_value(&value, &test_value), NULL); #else zassert_false(bacapp_same_value(&value, &test_value), NULL); #endif - value.type.Double = test_value.type.Double + 1.0; - zassert_false(bacapp_same_value(&value, &test_value), NULL); memset(&test_value, 0, sizeof(test_value)); test_value.tag = BACNET_APPLICATION_TAG_ENUMERATED; value = test_value; /* Struct copy */ #if defined(BACAPP_ENUMERATED) zassert_true(bacapp_same_value(&value, &test_value), NULL); + value.type.Enumerated = test_value.type.Enumerated + 1; + zassert_false(bacapp_same_value(&value, &test_value), NULL); #else zassert_false(bacapp_same_value(&value, &test_value), NULL); #endif - value.type.Enumerated = test_value.type.Enumerated + 1; - zassert_false(bacapp_same_value(&value, &test_value), NULL); memset(&test_value, 0, sizeof(test_value)); test_value.tag = BACNET_APPLICATION_TAG_DATE; value = test_value; /* Struct copy */ #if defined(BACAPP_DATE) zassert_true(bacapp_same_value(&value, &test_value), NULL); + value.type.Date.day = test_value.type.Date.day + 1; + zassert_false(bacapp_same_value(&value, &test_value), NULL); + value = test_value; /* Struct copy */ + value.type.Date.month = test_value.type.Date.month + 1; + zassert_false(bacapp_same_value(&value, &test_value), NULL); + value = test_value; /* Struct copy */ + value.type.Date.year = test_value.type.Date.year + 1; + zassert_false(bacapp_same_value(&value, &test_value), NULL); #else zassert_false(bacapp_same_value(&value, &test_value), NULL); #endif - value = test_value; /* Struct copy */ - value.type.Date.day = test_value.type.Date.day + 1; - zassert_false(bacapp_same_value(&value, &test_value), NULL); - #if 0 /*REVISIT: wday is not compared! */ value = test_value; /* Struct copy */ value.type.Date.wday = test_value.type.Date.wday + 1; zassert_false(bacapp_same_value(&value, &test_value), NULL); #endif - value = test_value; /* Struct copy */ - value.type.Date.month = test_value.type.Date.month + 1; - zassert_false(bacapp_same_value(&value, &test_value), NULL); - - value = test_value; /* Struct copy */ - value.type.Date.year = test_value.type.Date.year + 1; - zassert_false(bacapp_same_value(&value, &test_value), NULL); - memset(&test_value, 0, sizeof(test_value)); test_value.tag = BACNET_APPLICATION_TAG_TIME; value = test_value; /* Struct copy */ #if defined(BACAPP_TIME) zassert_true(bacapp_same_value(&value, &test_value), NULL); -#else - zassert_false(bacapp_same_value(&value, &test_value), NULL); -#endif - value = test_value; /* Struct copy */ value.type.Time.hour = test_value.type.Time.hour + 1; zassert_false(bacapp_same_value(&value, &test_value), NULL); @@ -467,16 +459,15 @@ static void test_bacapp_same_value(void) value = test_value; /* Struct copy */ value.type.Time.hundredths = test_value.type.Time.hundredths + 1; zassert_false(bacapp_same_value(&value, &test_value), NULL); +#else + zassert_false(bacapp_same_value(&value, &test_value), NULL); +#endif memset(&test_value, 0, sizeof(test_value)); test_value.tag = BACNET_APPLICATION_TAG_OBJECT_ID; value = test_value; /* Struct copy */ #if defined(BACAPP_OBJECT_ID) zassert_true(bacapp_same_value(&value, &test_value), NULL); -#else - zassert_false(bacapp_same_value(&value, &test_value), NULL); -#endif - value = test_value; /* Struct copy */ value.type.Object_Id.type = test_value.type.Object_Id.type + 1; zassert_false(bacapp_same_value(&value, &test_value), NULL); @@ -484,6 +475,9 @@ static void test_bacapp_same_value(void) value = test_value; /* Struct copy */ value.type.Object_Id.instance = test_value.type.Object_Id.instance + 1; zassert_false(bacapp_same_value(&value, &test_value), NULL); +#else + zassert_false(bacapp_same_value(&value, &test_value), NULL); +#endif memset(&test_value, 0, sizeof(test_value)); test_value.tag = BACNET_APPLICATION_TAG_CHARACTER_STRING; @@ -493,7 +487,6 @@ static void test_bacapp_same_value(void) #else zassert_false(bacapp_same_value(&value, &test_value), NULL); #endif - // TODO: Verify .type.Character_String value compared memset(&test_value, 0, sizeof(test_value)); test_value.tag = BACNET_APPLICATION_TAG_OCTET_STRING; @@ -503,7 +496,6 @@ static void test_bacapp_same_value(void) #else zassert_false(bacapp_same_value(&value, &test_value), NULL); #endif - // TODO: Verify .type.Octet_String value compared memset(&test_value, 0, sizeof(test_value)); test_value.tag = BACNET_APPLICATION_TAG_BIT_STRING; @@ -513,17 +505,15 @@ static void test_bacapp_same_value(void) #else zassert_false(bacapp_same_value(&value, &test_value), NULL); #endif - // TODO: Verify .type.Bit_String value compared memset(&test_value, 0, sizeof(test_value)); test_value.tag = BACNET_APPLICATION_TAG_LIGHTING_COMMAND; value = test_value; /* Struct copy */ -#if defined(BACAPP_TYPES_EXTRA) +#if defined(BACAPP_LIGHTING_COMMAND) zassert_true(bacapp_same_value(&value, &test_value), NULL); #else zassert_false(bacapp_same_value(&value, &test_value), NULL); #endif - // TODO: Verify .type.Lighting_Command value compared } /** diff --git a/test/bacnet/bacdcode/src/main.c b/test/bacnet/bacdcode/src/main.c index dc0c5c35..2cdfe751 100644 --- a/test/bacnet/bacdcode/src/main.c +++ b/test/bacnet/bacdcode/src/main.c @@ -49,6 +49,7 @@ static void test_bacnet_tag_codec(uint8_t tag_number, uint8_t apdu[BACNET_TAG_SIZE] = { 0 }; BACNET_TAG tag = { 0 }; int len = 0, test_len = 0, null_len = 0, tag_len = 0; + uint32_t tag_len_value_type; bool status; if (opening) { @@ -72,9 +73,10 @@ static void test_bacnet_tag_codec(uint8_t tag_number, zassert_false(tag.closing, NULL); zassert_false(tag.opening, NULL); status = bacnet_is_context_tag_number( - apdu, sizeof(apdu), tag_number, &tag_len); + apdu, sizeof(apdu), tag_number, &tag_len, &tag_len_value_type); zassert_true(status, NULL); zassert_equal(tag_len, test_len, NULL); + zassert_equal(tag_len_value_type, len_value_type, NULL); } else if (opening) { zassert_false(tag.context, NULL); zassert_false(tag.application, NULL); @@ -99,7 +101,7 @@ static void test_bacnet_tag_codec(uint8_t tag_number, zassert_false(tag.closing, NULL); zassert_false(tag.opening, NULL); status = bacnet_is_context_tag_number( - apdu, sizeof(apdu), tag_number, &tag_len); + apdu, sizeof(apdu), tag_number, &tag_len, &tag_len_value_type); zassert_false(status, NULL); } while (len) { @@ -155,7 +157,7 @@ static void testBACDCodeTags(void) uint8_t apdu[MAX_APDU] = { 0 }; uint8_t tag_number = 0, test_tag_number = 0; int len = 0, test_len = 0, tag_len = 0; - uint32_t value = 0, test_value = 0; + uint32_t value = 0, test_value = 0, tag_len_value_type = 0; unsigned i = 0, j = 0; BACNET_TAG tag = { 0 }; bool status = false; @@ -212,7 +214,7 @@ static void testBACDCodeTags(void) zassert_false(tag.context, NULL); zassert_true(tag.application, NULL); status = bacnet_is_context_tag_number( - apdu, sizeof(apdu), tag_number, &tag_len); + apdu, sizeof(apdu), tag_number, &tag_len, &tag_len_value_type); zassert_false(status, NULL); zassert_false(tag.closing, NULL); zassert_false(tag.opening, NULL); diff --git a/test/bacnet/bacdest/CMakeLists.txt b/test/bacnet/bacdest/CMakeLists.txt index 655e170d..ad8b3af2 100644 --- a/test/bacnet/bacdest/CMakeLists.txt +++ b/test/bacnet/bacdest/CMakeLists.txt @@ -23,7 +23,8 @@ set(ZTST_DIR "${TST_DIR}/ztest/src") add_compile_definitions( BIG_ENDIAN=0 CONFIG_ZTEST=1 - BACAPP_ALL + BACAPP_MINIMAL=1 + BACAPP_DESTINATION=1 ) include_directories( diff --git a/test/bacnet/bacdevobjpropref/CMakeLists.txt b/test/bacnet/bacdevobjpropref/CMakeLists.txt index 27210d11..3f27421e 100644 --- a/test/bacnet/bacdevobjpropref/CMakeLists.txt +++ b/test/bacnet/bacdevobjpropref/CMakeLists.txt @@ -24,7 +24,11 @@ add_compile_definitions( BIG_ENDIAN=0 CONFIG_ZTEST=1 MAX_APDU=50 - ) + BACAPP_MINIMAL=1 + BACAPP_DEVICE_OBJECT_PROPERTY_REFERENCE=1 + BACAPP_DEVICE_OBJECT_REFERENCE=1 + BACAPP_OBJECT_PROPERTY_REFERENCE=1 +) include_directories( ${SRC_DIR} diff --git a/test/bacnet/lighting/CMakeLists.txt b/test/bacnet/lighting/CMakeLists.txt index 2c650ed4..954db913 100644 --- a/test/bacnet/lighting/CMakeLists.txt +++ b/test/bacnet/lighting/CMakeLists.txt @@ -23,6 +23,7 @@ set(ZTST_DIR "${TST_DIR}/ztest/src") add_compile_definitions( BIG_ENDIAN=0 CONFIG_ZTEST=1 + BACAPP_PRINT_ENABLED=1 ) include_directories( diff --git a/test/bacnet/lighting/src/main.c b/test/bacnet/lighting/src/main.c index 34db9af5..4b5f0ebe 100644 --- a/test/bacnet/lighting/src/main.c +++ b/test/bacnet/lighting/src/main.c @@ -28,7 +28,9 @@ static void testBACnetLightingCommand(BACNET_LIGHTING_COMMAND *data) BACNET_LIGHTING_COMMAND test_data; int len, apdu_len; uint8_t apdu[MAX_APDU] = { 0 }; + char command_text[80] = ""; + /* copy */ status = lighting_command_copy(&test_data, NULL); zassert_false(status, NULL); status = lighting_command_copy(NULL, data); @@ -37,6 +39,7 @@ static void testBACnetLightingCommand(BACNET_LIGHTING_COMMAND *data) zassert_true(status, NULL); status = lighting_command_same(&test_data, data); zassert_true(status, NULL); + /* encode/decode */ len = lighting_command_encode(apdu, data); apdu_len = lighting_command_decode(apdu, len, &test_data); zassert_true(len > 0, "lighting-command[%s] failed to encode!", @@ -48,6 +51,26 @@ static void testBACnetLightingCommand(BACNET_LIGHTING_COMMAND *data) len--; apdu_len = lighting_command_decode(apdu, len, NULL); } + /* to/from ASCII */ + len = lighting_command_to_ascii(NULL, NULL, 0); + zassert_equal(len, 0, NULL); + len = lighting_command_to_ascii(data, NULL, 0); + zassert_true(len > 0, NULL); + len = lighting_command_to_ascii(data, command_text, 0); + zassert_true(len > 0, NULL); + len = lighting_command_to_ascii(data, command_text, sizeof(command_text)); + zassert_true(len > 0, NULL); + status = lighting_command_from_ascii(NULL, command_text); + zassert_false(status, NULL); + status = lighting_command_from_ascii(&test_data, NULL); + zassert_false(status, NULL); + status = lighting_command_from_ascii(NULL, NULL); + zassert_false(status, NULL); + status = lighting_command_from_ascii(&test_data, command_text); + zassert_true(status, NULL); + status = lighting_command_same(&test_data, data); + zassert_true(status, "lighting-command[%s] \"%s\" is different!", + bactext_lighting_operation_name(data->operation), command_text); } #if defined(CONFIG_ZTEST_NEW_API)