Added set time callback with optional offset for BACnet TimeSynchronization services (#691)
This commit is contained in:
@@ -47,6 +47,7 @@
|
|||||||
#include "bacnet/basic/tsm/tsm.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "bacnet/datalink/datalink.h"
|
#include "bacnet/datalink/datalink.h"
|
||||||
#include "bacnet/datalink/dlenv.h"
|
#include "bacnet/datalink/dlenv.h"
|
||||||
|
#include "bacnet/datetime.h"
|
||||||
/* include the device object */
|
/* include the device object */
|
||||||
#include "bacnet/basic/object/device.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
/* objects that have tasks inside them */
|
/* objects that have tasks inside them */
|
||||||
@@ -369,6 +370,9 @@ int main(int argc, char *argv[])
|
|||||||
in our device bindings list */
|
in our device bindings list */
|
||||||
address_init();
|
address_init();
|
||||||
Init_Service_Handlers();
|
Init_Service_Handlers();
|
||||||
|
/* initialize timesync callback function. */
|
||||||
|
handler_timesync_set_callback_set(&datetime_timesync);
|
||||||
|
|
||||||
#if defined(BAC_UCI)
|
#if defined(BAC_UCI)
|
||||||
const char *uciname;
|
const char *uciname;
|
||||||
ctx = ucix_init("bacnet_dev");
|
ctx = ucix_init("bacnet_dev");
|
||||||
|
|||||||
@@ -15,9 +15,24 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include "bacnet/basic/service/h_ts.h"
|
||||||
#include "bacport.h"
|
#include "bacport.h"
|
||||||
#include "bacnet/datetime.h"
|
#include "bacnet/datetime.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set offset from the system clock.
|
||||||
|
* @param bdate BACnet Date structure to hold local time
|
||||||
|
* @param btime BACnet Time structure to hold local time
|
||||||
|
* @param utc - True for UTC sync, False for Local time
|
||||||
|
* @return True if time is set
|
||||||
|
*/
|
||||||
|
void datetime_timesync(
|
||||||
|
BACNET_DATE *bdate, BACNET_TIME *btime, bool utc)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the date, time, timezone, and UTC offset from system
|
* @brief Get the date, time, timezone, and UTC offset from system
|
||||||
* @param utc_time - the BACnet Date and Time structure to hold UTC time
|
* @param utc_time - the BACnet Date and Time structure to hold UTC time
|
||||||
|
|||||||
@@ -15,9 +15,54 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include "bacnet/basic/service/h_ts.h"
|
||||||
#include "bacport.h"
|
#include "bacport.h"
|
||||||
#include "bacnet/datetime.h"
|
#include "bacnet/datetime.h"
|
||||||
|
|
||||||
|
|
||||||
|
static int32_t timedifference(struct timeval t0, struct timeval t1)
|
||||||
|
{
|
||||||
|
return (t0.tv_sec - t1.tv_sec)*1000 + (t0.tv_usec - t1.tv_usec) / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set offset from the system clock.
|
||||||
|
* @param bdate BACnet Date structure to hold local time
|
||||||
|
* @param btime BACnet Time structure to hold local time
|
||||||
|
* @param utc - True for UTC sync, False for Local time
|
||||||
|
* @return True if time is set
|
||||||
|
*/
|
||||||
|
void datetime_timesync(
|
||||||
|
BACNET_DATE *bdate, BACNET_TIME *btime, bool utc)
|
||||||
|
{
|
||||||
|
struct timeval tv_inp, tv_sys;
|
||||||
|
struct tm *timeinfo;
|
||||||
|
time_t rawtime;
|
||||||
|
time( &rawtime);
|
||||||
|
timeinfo = localtime(&rawtime);
|
||||||
|
/* fixme: only set the time if off by some amount */
|
||||||
|
timeinfo->tm_year = bdate->year-1900;
|
||||||
|
timeinfo->tm_mon = bdate->month-1;
|
||||||
|
timeinfo->tm_mday = bdate->day;
|
||||||
|
timeinfo->tm_hour = btime->hour;
|
||||||
|
timeinfo->tm_min = btime->min;
|
||||||
|
timeinfo->tm_sec = btime->sec;
|
||||||
|
tv_inp.tv_sec = mktime(timeinfo);
|
||||||
|
tv_inp.tv_usec = btime->hundredths*10000;
|
||||||
|
if (gettimeofday(&tv_sys, NULL) == 0) {
|
||||||
|
if (utc) {
|
||||||
|
handler_timesync_offset_set(timedifference(tv_inp, tv_sys) - (timezone - timeinfo->tm_isdst*3600)*1000);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
handler_timesync_offset_set(timedifference(tv_inp, tv_sys));
|
||||||
|
}
|
||||||
|
#if PRINT_ENABLED
|
||||||
|
printf("Time offset = %d\n",handler_timesync_offset());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the date, time, timezone, and UTC offset from system
|
* @brief Get the date, time, timezone, and UTC offset from system
|
||||||
* @param utc_time - the BACnet Date and Time structure to hold UTC time
|
* @param utc_time - the BACnet Date and Time structure to hold UTC time
|
||||||
@@ -35,8 +80,12 @@ bool datetime_local(BACNET_DATE *bdate,
|
|||||||
bool status = false;
|
bool status = false;
|
||||||
struct tm *tblock = NULL;
|
struct tm *tblock = NULL;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
int32_t to;
|
||||||
|
|
||||||
if (gettimeofday(&tv, NULL) == 0) {
|
if (gettimeofday(&tv, NULL) == 0) {
|
||||||
|
to = handler_timesync_offset();
|
||||||
|
tv.tv_sec += (int) to/1000;
|
||||||
|
tv.tv_usec += (to%1000)*1000;
|
||||||
tblock = (struct tm *)localtime((const time_t *)&tv.tv_sec);
|
tblock = (struct tm *)localtime((const time_t *)&tv.tv_sec);
|
||||||
}
|
}
|
||||||
if (tblock) {
|
if (tblock) {
|
||||||
|
|||||||
@@ -94,6 +94,19 @@ int gettimeofday(struct timeval *tp, void *tzp)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set offset from the system clock.
|
||||||
|
* @param bdate BACnet Date structure to hold local time
|
||||||
|
* @param btime BACnet Time structure to hold local time
|
||||||
|
* @param utc - True for UTC sync, False for Local time
|
||||||
|
* @return True if time is set
|
||||||
|
*/
|
||||||
|
void datetime_timesync(
|
||||||
|
BACNET_DATE *bdate, BACNET_TIME *btime, bool utc)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the date, time, timezone, and UTC offset from system
|
* @brief Get the date, time, timezone, and UTC offset from system
|
||||||
* @param utc_time - the BACnet Date and Time structure to hold UTC time
|
* @param utc_time - the BACnet Date and Time structure to hold UTC time
|
||||||
|
|||||||
@@ -66,6 +66,21 @@ static void show_bacnet_date_time(BACNET_DATE *bdate, BACNET_TIME *btime)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Callback for timesync set */
|
||||||
|
static handler_timesync_set_callback_t handler_timesync_set_callback;
|
||||||
|
|
||||||
|
static int32_t Time_Offset; /* Time offset in ms */
|
||||||
|
|
||||||
|
int32_t handler_timesync_offset(void)
|
||||||
|
{
|
||||||
|
return Time_Offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handler_timesync_offset_set(int32_t offset)
|
||||||
|
{
|
||||||
|
Time_Offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
void handler_timesync(
|
void handler_timesync(
|
||||||
uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src)
|
uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src)
|
||||||
{
|
{
|
||||||
@@ -80,12 +95,12 @@ void handler_timesync(
|
|||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
if (datetime_is_valid(&bdate, &btime)) {
|
if (datetime_is_valid(&bdate, &btime)) {
|
||||||
/* fixme: only set the time if off by some amount */
|
/* fixme: only set the time if off by some amount */
|
||||||
|
if (handler_timesync_set_callback) {
|
||||||
|
handler_timesync_set_callback(&bdate, &btime, false);
|
||||||
|
}
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "Received TimeSyncronization Request\r\n");
|
fprintf(stderr, "Received Local TimeSyncronization Request\r\n");
|
||||||
show_bacnet_date_time(&bdate, &btime);
|
show_bacnet_date_time(&bdate, &btime);
|
||||||
#else
|
|
||||||
/* FIXME: set the time?
|
|
||||||
Maybe only set the time if off by some amount */
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,12 +121,13 @@ void handler_timesync_utc(
|
|||||||
service_request, service_len, &bdate, &btime);
|
service_request, service_len, &bdate, &btime);
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
if (datetime_is_valid(&bdate, &btime)) {
|
if (datetime_is_valid(&bdate, &btime)) {
|
||||||
|
if (handler_timesync_set_callback) {
|
||||||
|
handler_timesync_set_callback(&bdate, &btime, true);
|
||||||
|
}
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "Received TimeSyncronization Request\r\n");
|
fprintf(stderr, "Received UTC TimeSyncronization Request\r\n");
|
||||||
show_bacnet_date_time(&bdate, &btime);
|
show_bacnet_date_time(&bdate, &btime);
|
||||||
#endif
|
#endif
|
||||||
/* FIXME: set the time?
|
|
||||||
only set the time if off by some amount */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,3 +292,14 @@ void handler_timesync_init(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures and enables a timesync callback function
|
||||||
|
*
|
||||||
|
* @param cb - pointer to #handler_timesync_set_callback_t
|
||||||
|
*/
|
||||||
|
void handler_timesync_set_callback_set(
|
||||||
|
handler_timesync_set_callback_t cb)
|
||||||
|
{
|
||||||
|
handler_timesync_set_callback = cb;
|
||||||
|
}
|
||||||
|
|||||||
@@ -39,10 +39,19 @@
|
|||||||
#include "bacnet/datetime.h"
|
#include "bacnet/datetime.h"
|
||||||
#include "bacnet/wp.h"
|
#include "bacnet/wp.h"
|
||||||
|
|
||||||
|
typedef void (*handler_timesync_set_callback_t)(
|
||||||
|
BACNET_DATE *bdate,
|
||||||
|
BACNET_TIME *btime,
|
||||||
|
bool utc);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
int32_t handler_timesync_offset(void);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
void handler_timesync_offset_set(int32_t offset);
|
||||||
/* time synchronization handlers */
|
/* time synchronization handlers */
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
void handler_timesync(
|
void handler_timesync(
|
||||||
@@ -81,7 +90,9 @@ extern "C" {
|
|||||||
bool handler_timesync_recipient_address_set(
|
bool handler_timesync_recipient_address_set(
|
||||||
unsigned index,
|
unsigned index,
|
||||||
BACNET_ADDRESS * address);
|
BACNET_ADDRESS * address);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
void handler_timesync_set_callback_set(
|
||||||
|
handler_timesync_set_callback_t cb);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|||||||
@@ -304,6 +304,11 @@ bool datetime_local(BACNET_DATE *bdate,
|
|||||||
BACNET_TIME *btime,
|
BACNET_TIME *btime,
|
||||||
int16_t *utc_offset_minutes,
|
int16_t *utc_offset_minutes,
|
||||||
bool *dst_active);
|
bool *dst_active);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
void datetime_timesync(
|
||||||
|
BACNET_DATE *bdate, BACNET_TIME *btime, bool utc);
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
void datetime_init(void);
|
void datetime_init(void);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user