Fixed Send_TimeSyncUTC().
Fixes bug https://sourceforge.net/p/bacnet/bugs/28/ Added functions in s_ts.c that reference Device object Local_Time, UTC_Offset, and Daylight_Savings_Time properties. Implements feature request https://sourceforge.net/p/bacnet/bugs/27/
This commit is contained in:
@@ -65,7 +65,6 @@ void Send_TimeSync_Remote(
|
|||||||
pdu_len =
|
pdu_len =
|
||||||
npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
|
npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
|
||||||
&npdu_data);
|
&npdu_data);
|
||||||
|
|
||||||
/* encode the APDU portion of the packet */
|
/* encode the APDU portion of the packet */
|
||||||
len =
|
len =
|
||||||
timesync_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bdate, btime);
|
timesync_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bdate, btime);
|
||||||
@@ -112,10 +111,9 @@ void Send_TimeSyncUTC(
|
|||||||
pdu_len =
|
pdu_len =
|
||||||
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
|
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
|
||||||
&npdu_data);
|
&npdu_data);
|
||||||
|
|
||||||
/* encode the APDU portion of the packet */
|
/* encode the APDU portion of the packet */
|
||||||
pdu_len =
|
pdu_len =
|
||||||
timesync_utc_encode_apdu(&Handler_Transmit_Buffer[0], bdate, btime);
|
timesync_utc_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bdate, btime);
|
||||||
bytes_sent =
|
bytes_sent =
|
||||||
datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0],
|
datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0],
|
||||||
pdu_len);
|
pdu_len);
|
||||||
@@ -126,3 +124,35 @@ void Send_TimeSyncUTC(
|
|||||||
strerror(errno));
|
strerror(errno));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a UTC TimeSync message using the local time from the device.
|
||||||
|
*/
|
||||||
|
void Send_TimeSyncUTC_Device(void)
|
||||||
|
{
|
||||||
|
int32_t utc_offset_minutes = 0;
|
||||||
|
bool dst = false;
|
||||||
|
BACNET_DATE_TIME local_time;
|
||||||
|
BACNET_DATE_TIME utc_time;
|
||||||
|
|
||||||
|
Device_getCurrentDateTime(&local_time);
|
||||||
|
dst = Device_Daylight_Savings_Status();
|
||||||
|
utc_offset_minutes = Device_UTC_Offset();
|
||||||
|
datetime_copy(&utc_time, &local_time);
|
||||||
|
datetime_add_minutes(&utc_time, utc_offset_minutes);
|
||||||
|
if (dst) {
|
||||||
|
datetime_add_minutes(&utc_time, -60);
|
||||||
|
}
|
||||||
|
Send_TimeSyncUTC(&utc_time.date, &utc_time.time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a TimeSync message using the local time from the device.
|
||||||
|
*/
|
||||||
|
void Send_TimeSync_Device(void)
|
||||||
|
{
|
||||||
|
BACNET_DATE_TIME local_time;
|
||||||
|
|
||||||
|
Device_getCurrentDateTime(&local_time);
|
||||||
|
Send_TimeSync(&local_time.date, &local_time.time);
|
||||||
|
}
|
||||||
|
|||||||
@@ -32,6 +32,10 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h> /* for memmove */
|
#include <string.h> /* for memmove */
|
||||||
#include <time.h> /* for timezone, localtime */
|
#include <time.h> /* for timezone, localtime */
|
||||||
|
/* OS specific include*/
|
||||||
|
#include "net.h"
|
||||||
|
#include "timer.h"
|
||||||
|
/* BACnet includes */
|
||||||
#include "bacdef.h"
|
#include "bacdef.h"
|
||||||
#include "bacdcode.h"
|
#include "bacdcode.h"
|
||||||
#include "bacenum.h"
|
#include "bacenum.h"
|
||||||
@@ -69,14 +73,14 @@ static char *Description = "command line client";
|
|||||||
/* static uint8_t Max_Segments_Accepted = 0; */
|
/* static uint8_t Max_Segments_Accepted = 0; */
|
||||||
/* VT_Classes_Supported */
|
/* VT_Classes_Supported */
|
||||||
/* Active_VT_Sessions */
|
/* Active_VT_Sessions */
|
||||||
/* static BACNET_TIME Local_Time; rely on OS, if there is one */
|
static BACNET_TIME Local_Time; /* rely on OS, if there is one */
|
||||||
/* static BACNET_DATE Local_Date; rely on OS, if there is one */
|
static BACNET_DATE Local_Date; /* rely on OS, if there is one */
|
||||||
/* NOTE: BACnet UTC Offset is inverse of common practice.
|
/* NOTE: BACnet UTC Offset is inverse of common practice.
|
||||||
If your UTC offset is -5hours of GMT,
|
If your UTC offset is -5hours of GMT,
|
||||||
then BACnet UTC offset is +5hours.
|
then BACnet UTC offset is +5hours.
|
||||||
BACnet UTC offset is expressed in minutes. */
|
BACnet UTC offset is expressed in minutes. */
|
||||||
/* static int32_t UTC_Offset = 5 * 60; */
|
static int32_t UTC_Offset = 5 * 60;
|
||||||
/* static bool Daylight_Savings_Status = false; rely on OS */
|
static bool Daylight_Savings_Status = false; /* rely on OS */
|
||||||
/* List_Of_Session_Keys */
|
/* List_Of_Session_Keys */
|
||||||
/* Time_Synchronization_Recipients */
|
/* Time_Synchronization_Recipients */
|
||||||
/* Max_Master - rely on MS/TP subsystem, if there is one */
|
/* Max_Master - rely on MS/TP subsystem, if there is one */
|
||||||
@@ -633,6 +637,83 @@ bool Device_Object_Name_Copy(
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Update_Current_Time(
|
||||||
|
void)
|
||||||
|
{
|
||||||
|
struct tm *tblock = NULL;
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
time_t tTemp;
|
||||||
|
#else
|
||||||
|
struct timeval tv;
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
struct tm
|
||||||
|
|
||||||
|
int tm_sec Seconds [0,60].
|
||||||
|
int tm_min Minutes [0,59].
|
||||||
|
int tm_hour Hour [0,23].
|
||||||
|
int tm_mday Day of month [1,31].
|
||||||
|
int tm_mon Month of year [0,11].
|
||||||
|
int tm_year Years since 1900.
|
||||||
|
int tm_wday Day of week [0,6] (Sunday =0).
|
||||||
|
int tm_yday Day of year [0,365].
|
||||||
|
int tm_isdst Daylight Savings flag.
|
||||||
|
*/
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
time(&tTemp);
|
||||||
|
tblock = (struct tm *)localtime(&tTemp);
|
||||||
|
#else
|
||||||
|
if (gettimeofday(&tv, NULL) == 0) {
|
||||||
|
tblock = (struct tm *)localtime((const time_t *)&tv.tv_sec);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (tblock) {
|
||||||
|
datetime_set_date(&Local_Date, (uint16_t) tblock->tm_year + 1900,
|
||||||
|
(uint8_t) tblock->tm_mon + 1, (uint8_t) tblock->tm_mday);
|
||||||
|
#if !defined(_MSC_VER)
|
||||||
|
datetime_set_time(&Local_Time, (uint8_t) tblock->tm_hour,
|
||||||
|
(uint8_t) tblock->tm_min, (uint8_t) tblock->tm_sec,
|
||||||
|
(uint8_t) (tv.tv_usec / 10000));
|
||||||
|
#else
|
||||||
|
datetime_set_time(&Local_Time, (uint8_t) tblock->tm_hour,
|
||||||
|
(uint8_t) tblock->tm_min, (uint8_t) tblock->tm_sec, 0);
|
||||||
|
#endif
|
||||||
|
if (tblock->tm_isdst) {
|
||||||
|
Daylight_Savings_Status = true;
|
||||||
|
} else {
|
||||||
|
Daylight_Savings_Status = false;
|
||||||
|
}
|
||||||
|
/* note: timezone is declared in <time.h> stdlib. */
|
||||||
|
UTC_Offset = timezone / 60;
|
||||||
|
} else {
|
||||||
|
datetime_date_wildcard_set(&Local_Date);
|
||||||
|
datetime_time_wildcard_set(&Local_Time);
|
||||||
|
Daylight_Savings_Status = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Device_getCurrentDateTime(
|
||||||
|
BACNET_DATE_TIME * DateTime)
|
||||||
|
{
|
||||||
|
Update_Current_Time();
|
||||||
|
|
||||||
|
DateTime->date = Local_Date;
|
||||||
|
DateTime->time = Local_Time;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t Device_UTC_Offset(void)
|
||||||
|
{
|
||||||
|
Update_Current_Time();
|
||||||
|
|
||||||
|
return UTC_Offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Device_Daylight_Savings_Status(void)
|
||||||
|
{
|
||||||
|
return Daylight_Savings_Status;
|
||||||
|
}
|
||||||
|
|
||||||
/* return the length of the apdu encoded or BACNET_STATUS_ERROR for error or
|
/* return the length of the apdu encoded or BACNET_STATUS_ERROR for error or
|
||||||
BACNET_STATUS_ABORT for abort message */
|
BACNET_STATUS_ABORT for abort message */
|
||||||
int Device_Read_Property_Local(
|
int Device_Read_Property_Local(
|
||||||
|
|||||||
@@ -1169,6 +1169,18 @@ void Device_getCurrentDateTime(
|
|||||||
DateTime->time = Local_Time;
|
DateTime->time = Local_Time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t Device_UTC_Offset(void)
|
||||||
|
{
|
||||||
|
Update_Current_Time();
|
||||||
|
|
||||||
|
return UTC_Offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Device_Daylight_Savings_Status(void)
|
||||||
|
{
|
||||||
|
return Daylight_Savings_Status;
|
||||||
|
}
|
||||||
|
|
||||||
/* return the length of the apdu encoded or BACNET_STATUS_ERROR for error or
|
/* return the length of the apdu encoded or BACNET_STATUS_ERROR for error or
|
||||||
BACNET_STATUS_ABORT for abort message */
|
BACNET_STATUS_ABORT for abort message */
|
||||||
int Device_Read_Property_Local(
|
int Device_Read_Property_Local(
|
||||||
|
|||||||
@@ -235,6 +235,8 @@ extern "C" {
|
|||||||
|
|
||||||
void Device_getCurrentDateTime(
|
void Device_getCurrentDateTime(
|
||||||
BACNET_DATE_TIME * DateTime);
|
BACNET_DATE_TIME * DateTime);
|
||||||
|
int32_t Device_UTC_Offset(void);
|
||||||
|
bool Device_Daylight_Savings_Status(void);
|
||||||
|
|
||||||
void Device_Property_Lists(
|
void Device_Property_Lists(
|
||||||
const int **pRequired,
|
const int **pRequired,
|
||||||
|
|||||||
@@ -179,6 +179,8 @@ extern "C" {
|
|||||||
void Send_TimeSyncUTC(
|
void Send_TimeSyncUTC(
|
||||||
BACNET_DATE * bdate,
|
BACNET_DATE * bdate,
|
||||||
BACNET_TIME * btime);
|
BACNET_TIME * btime);
|
||||||
|
void Send_TimeSyncUTC_Device(void);
|
||||||
|
void Send_TimeSync_Device(void);
|
||||||
|
|
||||||
uint8_t Send_Atomic_Read_File_Stream(
|
uint8_t Send_Atomic_Read_File_Stream(
|
||||||
uint32_t device_id,
|
uint32_t device_id,
|
||||||
|
|||||||
Reference in New Issue
Block a user