Skip to content

Commit d34c841

Browse files
committed
Added datetime and timesync to B-LS profile sample.
1 parent 94205be commit d34c841

File tree

3 files changed

+63
-74
lines changed

3 files changed

+63
-74
lines changed

zephyr/samples/profiles/b-ls/src/main.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "bacnet/bacdef.h"
1414
/* BACnet Stack core API */
1515
#include "bacnet/version.h"
16+
#include "bacnet/datetime.h"
1617
#include "bacnet/basic/services.h"
1718
#include "bacnet/basic/sys/mstimer.h"
1819
#include "bacnet/basic/sys/linear.h"
@@ -140,6 +141,10 @@ static void BACnet_Lighting_Device_Init_Handler(void *context)
140141
/* link WriteGroup service to our channel object */
141142
Write_Group_Notification.callback = Channel_Write_Group;
142143
handler_write_group_notification_add(&Write_Group_Notification);
144+
apdu_set_unconfirmed_handler(
145+
SERVICE_UNCONFIRMED_WRITE_GROUP, handler_write_group);
146+
/* initialize timesync callback function. */
147+
handler_timesync_set_callback_set(&datetime_timesync);
143148
/* done */
144149
LOG_INF("BACnet Device ID: %u", Device_Object_Instance_Number());
145150
/* set the BACnet Basic Task device object timer for lighting output use */

zephyr/subsys/bacnet_basic/bacnet_basic.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,6 @@ void bacnet_basic_init(void)
135135
SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property);
136136
apdu_set_confirmed_handler(
137137
SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE, handler_write_property_multiple);
138-
apdu_set_unconfirmed_handler(
139-
SERVICE_UNCONFIRMED_WRITE_GROUP, handler_write_group);
140138
apdu_set_confirmed_handler(
141139
SERVICE_CONFIRMED_SUBSCRIBE_COV, handler_cov_subscribe);
142140
/* handle communication so we can shutup when asked, or restart */

zephyr/subsys/bacnet_osif/bacnet_datetime.c

Lines changed: 58 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -9,100 +9,86 @@
99
#include <stdint.h>
1010
#include <stdio.h>
1111
#include <stdlib.h>
12-
#include <time.h>
13-
#include <sys/time.h>
1412
/* BACnet Stack defines - first */
1513
#include "bacnet/bacdef.h"
14+
#include "bacnet/basic/sys/mstimer.h"
1615
/* BACnet Stack API */
1716
#include "bacnet/datetime.h"
1817

18+
/* local time */
19+
static BACNET_DATE_TIME BACnet_Date_Time;
20+
static struct mstimer Date_Timer;
1921

20-
/* HACK:
21-
* - Zephyr does not declare timezone in any header file.
22-
* - The gcc-arm-none-eabi-7-2018-q2-update/bin/arm-none-eabi/lib/thumb/v7e-m/
23-
* libc_nano.a 'time' symbol does not resolve '_gettimeofday'
24-
*
25-
* TODO: figure out how to link in the real time() and timezone;
22+
/**
23+
* @brief Synchronize the local time from the millisecond timer
2624
*/
27-
long timezone;
28-
29-
time_t time(time_t *tloc)
25+
void datetime_sync(void)
3026
{
31-
time_t time = { 0 };
27+
bacnet_time_t seconds, elapsed_seconds;
28+
unsigned long milliseconds;
3229

33-
return time;
30+
milliseconds = mstimer_elapsed(&Date_Timer);
31+
elapsed_seconds = milliseconds/1000UL;
32+
if (elapsed_seconds) {
33+
mstimer_restart(&Date_Timer);
34+
seconds = datetime_seconds_since_epoch(&BACnet_Date_Time);
35+
seconds += elapsed_seconds;
36+
datetime_since_epoch_seconds(&BACnet_Date_Time, seconds);
37+
/* generate a hundredths value */
38+
milliseconds -= (elapsed_seconds * 1000UL);
39+
BACnet_Date_Time.time.hundredths = milliseconds / 10;
40+
}
3441
}
3542

3643
/**
37-
* @brief Get the date, time, timezone, and UTC offset from system
38-
* @param utc_time - the BACnet Date and Time structure to hold UTC time
39-
* @param local_time - the BACnet Date and Time structure to hold local time
40-
* @param utc_offset_minutes - number of minutes offset from UTC
41-
* For example, -6*60 represents 6.00 hours behind UTC/GMT
42-
* @param true if DST is enabled and active
43-
* @return true if local time was retrieved
44+
* @brief Get the local date and time
45+
* @param bdate [out] The date to get
46+
* @param btime [out] The time to get
47+
* @param utc_offset_minutes [out] The UTC offset in minutes
48+
* @param dst_active [out] The DST flag
49+
* @return true if successful, false on error
4450
*/
4551
bool datetime_local(
46-
BACNET_DATE * bdate,
47-
BACNET_TIME * btime,
48-
int16_t * utc_offset_minutes,
49-
bool * dst_active)
52+
BACNET_DATE *bdate,
53+
BACNET_TIME *btime,
54+
int16_t *utc_offset_minutes,
55+
bool *dst_active)
5056
{
51-
bool status = false;
52-
struct tm tblock_st = { 0 };
53-
struct tm *tblock = &tblock_st;
54-
struct timeval tv;
55-
56-
if (gettimeofday(&tv, NULL) == 0)
57-
{
58-
tblock = (struct tm *)localtime((const time_t *)&tv.tv_sec);
57+
datetime_sync();
58+
if (bdate) {
59+
datetime_copy_date(bdate, &BACnet_Date_Time.date);
5960
}
60-
if (tblock) {
61-
status = true;
62-
/** struct tm
63-
* int tm_sec Seconds [0,60].
64-
* int tm_min Minutes [0,59].
65-
* int tm_hour Hour [0,23].
66-
* int tm_mday Day of month [1,31].
67-
* int tm_mon Month of year [0,11].
68-
* int tm_year Years since 1900.
69-
* int tm_wday Day of week [0,6] (Sunday =0).
70-
* int tm_yday Day of year [0,365].
71-
* int tm_isdst Daylight Savings flag.
72-
*/
73-
datetime_set_date(bdate, (uint16_t)tblock->tm_year + 1900,
74-
(uint8_t)tblock->tm_mon + 1,
75-
(uint8_t)tblock->tm_mday);
76-
datetime_set_time(btime, (uint8_t)tblock->tm_hour,
77-
(uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec,
78-
(uint8_t)(tv.tv_usec / 10000));
79-
if (dst_active) {
80-
/* The value of tm_isdst is:
81-
- positive if Daylight Saving Time is in effect,
82-
- 0 if Daylight Saving Time is not in effect, and
83-
- negative if the information is not available. */
84-
if (tblock->tm_isdst > 0) {
85-
*dst_active = true;
86-
} else {
87-
*dst_active = false;
88-
}
89-
}
90-
/* note: timezone is declared in <time.h> stdlib. */
91-
if (utc_offset_minutes) {
92-
/* timezone is set to the difference, in seconds,
93-
between Coordinated Universal Time (UTC) and
94-
local standard time */
95-
*utc_offset_minutes = timezone / 60;
96-
}
61+
if (btime) {
62+
datetime_copy_time(btime, &BACnet_Date_Time.time);
9763
}
64+
(void)utc_offset_minutes;
65+
(void)dst_active;
66+
67+
return true;
68+
}
9869

99-
return status;
70+
/**
71+
* @brief Set the local date and time from a BACnet TimeSynchronization request
72+
* @param bdate [in] The date to set
73+
* @param btime [in] The time to set
74+
* @param utc [in] true if originating from an UTCTimeSynchronization request
75+
*/
76+
void datetime_timesync(BACNET_DATE *bdate, BACNET_TIME *btime, bool utc)
77+
{
78+
if (bdate) {
79+
datetime_copy_date(&BACnet_Date_Time.date, bdate);
80+
}
81+
if (btime) {
82+
datetime_copy_time(&BACnet_Date_Time.time, btime);
83+
}
84+
mstimer_restart(&Date_Timer);
85+
(void)utc;
10086
}
10187

10288
/**
103-
* initialize the date time
89+
* @brief Initialize the local date and time timer
10490
*/
10591
void datetime_init(void)
10692
{
107-
/* nothing to do */
93+
mstimer_set(&Date_Timer, 0);
10894
}

0 commit comments

Comments
 (0)