Feature/date time mstimer clock (#861)
* Added daylight savings time calculation module with unit testing. * Added datetime daylight savings time and clock API * Added basic datetime_local() clock using mstimer as basis and time-sync option. Integrated clock with ports/stm32f4xx example.
This commit is contained in:
@@ -170,6 +170,7 @@ set(BACNET_PROJECT_SOURCE
|
||||
${LIBRARY_BACNET_BASIC}/service/h_rd.c
|
||||
${LIBRARY_BACNET_BASIC}/service/h_rp.c
|
||||
${LIBRARY_BACNET_BASIC}/service/h_rpm.c
|
||||
${LIBRARY_BACNET_BASIC}/service/h_ts.c
|
||||
${LIBRARY_BACNET_BASIC}/service/h_whohas.c
|
||||
${LIBRARY_BACNET_BASIC}/service/h_whois.c
|
||||
${LIBRARY_BACNET_BASIC}/service/h_wp.c
|
||||
@@ -178,6 +179,9 @@ set(BACNET_PROJECT_SOURCE
|
||||
${LIBRARY_BACNET_BASIC}/service/s_ihave.c
|
||||
${LIBRARY_BACNET_BASIC}/tsm/tsm.c
|
||||
${LIBRARY_BACNET_BASIC}/sys/debug.c
|
||||
${LIBRARY_BACNET_BASIC}/sys/datetime_mstimer.c
|
||||
${LIBRARY_BACNET_BASIC}/sys/days.c
|
||||
${LIBRARY_BACNET_BASIC}/sys/dst.c
|
||||
${LIBRARY_BACNET_BASIC}/sys/ringbuf.c
|
||||
${LIBRARY_BACNET_BASIC}/sys/fifo.c
|
||||
${LIBRARY_BACNET_BASIC}/sys/keylist.c
|
||||
@@ -214,6 +218,7 @@ set(BACNET_PROJECT_SOURCE
|
||||
${LIBRARY_BACNET_CORE}/rp.c
|
||||
${LIBRARY_BACNET_CORE}/rpm.c
|
||||
${LIBRARY_BACNET_CORE}/timestamp.c
|
||||
${LIBRARY_BACNET_CORE}/timesync.c
|
||||
${LIBRARY_BACNET_CORE}/weeklyschedule.c
|
||||
${LIBRARY_BACNET_CORE}/dailyschedule.c
|
||||
${LIBRARY_BACNET_CORE}/calendar_entry.c
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
#+-------------------------------------------------------------------------------------------------+
|
||||
TARGET=bacnet
|
||||
|
||||
BACNET_DIR = ../..
|
||||
BACNET_DIR = $(realpath ../..)
|
||||
BACNET_SRC := $(BACNET_DIR)/src
|
||||
BACNET_CORE := $(BACNET_SRC)/bacnet
|
||||
BACNET_BASIC := $(BACNET_CORE)/basic
|
||||
BACNET_INCLUDE := $(BACNET_SRC)
|
||||
PLATFORM_DIR = .
|
||||
LIBRARY_STM32 = ./external/STM32F4xx_StdPeriph_Driver/src
|
||||
LIBRARY_STM32_INCLUDES = ./external/STM32F4xx_StdPeriph_Driver/inc
|
||||
LIBRARY_CMSIS = ./external/CMSIS
|
||||
PLATFORM_DIR = $(realpath .)
|
||||
LIBRARY_STM32 = $(realpath ./external/STM32F4xx_StdPeriph_Driver/src)
|
||||
LIBRARY_STM32_INCLUDES = $(realpath ./external/STM32F4xx_StdPeriph_Driver/inc)
|
||||
LIBRARY_CMSIS = $(realpath ./external/CMSIS)
|
||||
|
||||
CSTACK_TOOL := $(BACNET_DIR)/tools/avstack/avstack.pl
|
||||
MEMAP_TOOL := $(BACNET_DIR)/tools/memap/memap.py
|
||||
@@ -48,6 +48,7 @@ BASIC_SRC = \
|
||||
$(BACNET_BASIC)/service/h_rd.c \
|
||||
$(BACNET_BASIC)/service/h_rp.c \
|
||||
$(BACNET_BASIC)/service/h_rpm.c \
|
||||
$(BACNET_BASIC)/service/h_ts.c \
|
||||
$(BACNET_BASIC)/service/h_whohas.c \
|
||||
$(BACNET_BASIC)/service/h_whois.c \
|
||||
$(BACNET_BASIC)/service/h_wp.c \
|
||||
@@ -55,6 +56,9 @@ BASIC_SRC = \
|
||||
$(BACNET_BASIC)/service/s_iam.c \
|
||||
$(BACNET_BASIC)/service/s_ihave.c \
|
||||
$(BACNET_BASIC)/sys/debug.c \
|
||||
$(BACNET_BASIC)/sys/datetime_mstimer.c \
|
||||
$(BACNET_BASIC)/sys/days.c \
|
||||
$(BACNET_BASIC)/sys/dst.c \
|
||||
$(BACNET_BASIC)/sys/ringbuf.c \
|
||||
$(BACNET_BASIC)/sys/fifo.c \
|
||||
$(BACNET_BASIC)/sys/keylist.c \
|
||||
@@ -92,6 +96,7 @@ BACNET_SRC = \
|
||||
$(BACNET_CORE)/rpm.c \
|
||||
$(BACNET_CORE)/special_event.c \
|
||||
$(BACNET_CORE)/timestamp.c \
|
||||
$(BACNET_CORE)/timesync.c \
|
||||
$(BACNET_CORE)/weeklyschedule.c \
|
||||
$(BACNET_CORE)/whohas.c \
|
||||
$(BACNET_CORE)/whois.c \
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
#include "bacnet/datalink/datalink.h"
|
||||
#include "bacnet/npdu.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/tsm/tsm.h"
|
||||
#include "bacnet/datetime.h"
|
||||
#include "bacnet/dcc.h"
|
||||
#include "bacnet/iam.h"
|
||||
/* BACnet objects */
|
||||
@@ -116,6 +116,12 @@ void bacnet_init(void)
|
||||
SERVICE_CONFIRMED_REINITIALIZE_DEVICE, handler_reinitialize_device);
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property);
|
||||
/* local time and date */
|
||||
apdu_set_unconfirmed_handler(
|
||||
SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION,
|
||||
handler_timesync);
|
||||
handler_timesync_set_callback_set(datetime_timesync);
|
||||
datetime_init();
|
||||
/* handle communication so we can shutup when asked */
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
||||
handler_device_communication_control);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "bacnet/bacstr.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/apdu.h"
|
||||
#include "bacnet/datetime.h"
|
||||
#include "bacnet/dcc.h"
|
||||
#include "bacnet/datalink/datalink.h"
|
||||
#include "bacnet/version.h"
|
||||
@@ -49,11 +50,12 @@ static struct my_object_functions {
|
||||
read_property_function Object_Read_Property;
|
||||
write_property_function Object_Write_Property;
|
||||
rpm_property_lists_function Object_RPM_List;
|
||||
} Object_Table[] = { { OBJECT_DEVICE, NULL, /* don't init - recursive! */
|
||||
Device_Count, Device_Index_To_Instance,
|
||||
Device_Valid_Object_Instance_Number,
|
||||
Device_Object_Name, Device_Read_Property_Local,
|
||||
Device_Write_Property_Local, Device_Property_Lists },
|
||||
} Object_Table[] = { { OBJECT_DEVICE, NULL,
|
||||
/* don't init - recursive! */
|
||||
Device_Count, Device_Index_To_Instance,
|
||||
Device_Valid_Object_Instance_Number,
|
||||
Device_Object_Name, Device_Read_Property_Local,
|
||||
Device_Write_Property_Local, Device_Property_Lists },
|
||||
{ OBJECT_ANALOG_INPUT, Analog_Input_Init, Analog_Input_Count,
|
||||
Analog_Input_Index_To_Instance, Analog_Input_Valid_Instance,
|
||||
Analog_Input_Object_Name, Analog_Input_Read_Property,
|
||||
@@ -116,7 +118,9 @@ static const char *BACnet_Version = BACNET_VERSION_TEXT;
|
||||
static uint8_t Device_UUID[16];
|
||||
|
||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||
static const int Device_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
|
||||
static const int Device_Properties_Required[] = {
|
||||
/* required properties for this object */
|
||||
PROP_OBJECT_IDENTIFIER,
|
||||
PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_SYSTEM_STATUS, PROP_VENDOR_NAME,
|
||||
PROP_VENDOR_IDENTIFIER, PROP_MODEL_NAME, PROP_FIRMWARE_REVISION,
|
||||
PROP_APPLICATION_SOFTWARE_VERSION, PROP_PROTOCOL_VERSION,
|
||||
@@ -126,8 +130,17 @@ static const int Device_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
|
||||
PROP_APDU_TIMEOUT, PROP_NUMBER_OF_APDU_RETRIES, PROP_DEVICE_ADDRESS_BINDING,
|
||||
PROP_DATABASE_REVISION, -1 };
|
||||
|
||||
static const int Device_Properties_Optional[] = { PROP_DESCRIPTION,
|
||||
PROP_LOCATION, PROP_MAX_MASTER, PROP_MAX_INFO_FRAMES, PROP_DEVICE_UUID,
|
||||
static const int Device_Properties_Optional[] = {
|
||||
/* optional properties for this object */
|
||||
PROP_DESCRIPTION,
|
||||
PROP_LOCATION,
|
||||
PROP_MAX_MASTER,
|
||||
PROP_MAX_INFO_FRAMES,
|
||||
PROP_DEVICE_UUID,
|
||||
PROP_LOCAL_DATE,
|
||||
PROP_LOCAL_TIME,
|
||||
PROP_UTC_OFFSET,
|
||||
PROP_DAYLIGHT_SAVINGS_STATUS,
|
||||
-1 };
|
||||
|
||||
static const int Device_Properties_Proprietary[] = { -1 };
|
||||
@@ -686,6 +699,10 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
BACNET_BIT_STRING bit_string = { 0 };
|
||||
BACNET_CHARACTER_STRING char_string = { 0 };
|
||||
BACNET_OCTET_STRING octet_string = { 0 };
|
||||
BACNET_DATE bdate;
|
||||
BACNET_TIME btime;
|
||||
int16_t utc_offset_minutes;
|
||||
bool dst_active;
|
||||
uint32_t i = 0;
|
||||
uint32_t count = 0;
|
||||
uint8_t *apdu = NULL;
|
||||
@@ -817,6 +834,23 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
octetstring_init(&octet_string, Device_UUID, sizeof(Device_UUID));
|
||||
apdu_len = encode_application_octet_string(&apdu[0], &octet_string);
|
||||
break;
|
||||
case PROP_LOCAL_TIME:
|
||||
datetime_local(&bdate, &btime, &utc_offset_minutes, &dst_active);
|
||||
apdu_len = encode_application_time(&apdu[0], &btime);
|
||||
break;
|
||||
case PROP_LOCAL_DATE:
|
||||
datetime_local(&bdate, &btime, &utc_offset_minutes, &dst_active);
|
||||
apdu_len = encode_application_date(&apdu[0], &bdate);
|
||||
break;
|
||||
case PROP_UTC_OFFSET:
|
||||
datetime_local(&bdate, &btime, &utc_offset_minutes, &dst_active);
|
||||
apdu_len = encode_application_signed(&apdu[0], utc_offset_minutes);
|
||||
break;
|
||||
case PROP_DAYLIGHT_SAVINGS_STATUS:
|
||||
datetime_local(&bdate, &btime, &utc_offset_minutes, &dst_active);
|
||||
apdu_len =
|
||||
encode_application_boolean(&apdu[0], dst_active);
|
||||
break;
|
||||
default:
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
@@ -1060,6 +1094,39 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||
}
|
||||
break;
|
||||
case PROP_LOCAL_TIME:
|
||||
status = write_property_type_valid(
|
||||
wp_data, &value, BACNET_APPLICATION_TAG_TIME);
|
||||
if (status) {
|
||||
status = datetime_time_is_valid(&value.type.Time);
|
||||
if (status) {
|
||||
datetime_timesync(NULL, &value.type.Time, false);
|
||||
} else {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PROP_LOCAL_DATE:
|
||||
status = write_property_type_valid(
|
||||
wp_data, &value, BACNET_APPLICATION_TAG_DATE);
|
||||
if (status) {
|
||||
status = datetime_date_is_valid(&value.type.Date);
|
||||
if (status) {
|
||||
datetime_timesync(&value.type.Date, NULL, false);
|
||||
} else {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PROP_UTC_OFFSET:
|
||||
status = write_property_type_valid(
|
||||
wp_data, &value, BACNET_APPLICATION_TAG_SIGNED_INT);
|
||||
if (status) {
|
||||
datetime_utc_offset_minutes_set(value.type.Signed_Int);
|
||||
}
|
||||
break;
|
||||
case PROP_OBJECT_TYPE:
|
||||
case PROP_VENDOR_NAME:
|
||||
case PROP_VENDOR_IDENTIFIER:
|
||||
@@ -1076,6 +1143,7 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
case PROP_DEVICE_ADDRESS_BINDING:
|
||||
case PROP_ACTIVE_COV_SUBSCRIPTIONS:
|
||||
case PROP_DATABASE_REVISION:
|
||||
case PROP_DAYLIGHT_SAVINGS_STATUS:
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user