Skip to content

Commit 403eb49

Browse files
feat: enable BLE CTS service
This patch enables ZephyrWatch to communicate with a BLE client using Current Time Service GATT and update its global unix time. Please find the client implementation in the following repo: - updatetime.py in github.com/electricalgorithm/ZephyrWatchBLETools
1 parent a0fdd65 commit 403eb49

File tree

4 files changed

+60
-15
lines changed

4 files changed

+60
-15
lines changed

src/bluetooth/services/current_time_service.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <zephyr/bluetooth/gatt.h>
44
#include <string.h>
55

6+
#include "current_time_service.h"
67
#include "timeutils/timeutils.h"
78
#include "devicetwin/devicetwin.h"
89

@@ -27,22 +28,26 @@ static ssize_t m_time_write_callback(
2728
uint32_t unix_timestamp = sys_le32_to_cpu(*(uint32_t *)buf);
2829
LOG_INF("Received UNIX timestamp: %u", unix_timestamp);
2930

30-
// Convert UNIX timestamp to UTC time
31-
utc_time_t utc_time = unix_to_utc(unix_timestamp);
32-
33-
// Get the device twin instance
31+
// Get the device twin instance to get the UTC zone
3432
device_twin_t *device_twin = get_device_twin_instance();
3533
if (device_twin == NULL) {
3634
LOG_ERR("Failed to get device twin instance.");
3735
return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);
3836
}
3937

40-
// Update the device twin's current time
41-
device_twin->current_time = utc_time;
38+
// Convert UNIX timestamp to local time using the device's UTC zone
39+
utc_time_t local_time = unix_to_localtime(unix_timestamp, device_twin->utc_zone);
40+
41+
// Update the device twin's current time with local time
42+
device_twin->current_time = local_time;
4243

43-
LOG_INF("Current time updated: %04d-%02d-%02d %02d:%02d:%02d",
44-
utc_time.year, utc_time.month, utc_time.day,
45-
utc_time.hour, utc_time.minute, utc_time.second);
44+
// Update the global unix time used by the UI system
45+
update_global_unix_time(unix_timestamp);
46+
47+
LOG_INF("Current time updated to local time: %04d-%02d-%02d %02d:%02d:%02d (UTC%+d)",
48+
local_time.year, local_time.month, local_time.day,
49+
local_time.hour, local_time.minute, local_time.second,
50+
device_twin->utc_zone);
4651

4752
return len;
4853
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#ifndef CURRENT_TIME_SERVICE_H
2+
#define CURRENT_TIME_SERVICE_H
3+
4+
#ifdef __cplusplus
5+
extern "C" {
6+
#endif
7+
8+
#include <zephyr/sys/byteorder.h>
9+
#include <zephyr/logging/log.h>
10+
#include <zephyr/bluetooth/gatt.h>
11+
#include "timeutils/timeutils.h"
12+
13+
/* Function to update the global unix time - to be implemented in main.c */
14+
extern void update_global_unix_time(uint32_t unix_timestamp);
15+
16+
#ifdef __cplusplus
17+
}
18+
#endif
19+
20+
#endif // CURRENT_TIME_SERVICE_H

src/display/screens/home/home.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ uint8_t home_screen_set_date(uint16_t year, uint8_t month, uint8_t day) {
7474
// Check if the label_date is NULL.
7575
if (label_date == NULL) return 1;
7676
// Set the text of the label_date to the current date in "YYYY-MM-DD" format.
77-
lv_label_set_text_fmt(label_date, "%04u-%02d-%02d", year, month + 1, day);
77+
lv_label_set_text_fmt(label_date, "%04u-%02d-%02d", year, month, day);
7878
// Update the display.
7979
lv_disp_flush_ready(lv_disp_get_default());
8080
return 0;

src/main.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,14 @@
2525
#include "timeutils/timeutils.h"
2626
#include "devicetwin/devicetwin.h"
2727
#include "bluetooth/infrastructure.h"
28+
#include "bluetooth/services/current_time_service.h"
2829

2930
// Define the logger.
3031
LOG_MODULE_REGISTER(ZephyrWatch, LOG_LEVEL_DBG);
3132

3233
// Global values to hold time.
3334
uint32_t unix_time = 1748554674;
34-
int8_t utc_zone = +1;
35+
int8_t utc_zone = +2;
3536
const char* weekdays[] = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };
3637

3738
// Define the timer callbacks' prototypes.
@@ -161,6 +162,25 @@ void update_unix_time_callback(struct k_timer *timer) {
161162
unix_time += 1;
162163
}
163164

165+
/* UPDATE_GLOBAL_UNIX_TIME
166+
* Function to update the global unix time from external sources
167+
* (like Bluetooth CTS). This function will be called by the external
168+
* sources.
169+
*/
170+
void update_global_unix_time(uint32_t unix_timestamp) {
171+
unix_time = unix_timestamp;
172+
LOG_INF("Global UNIX time updated to: %u", unix_time);
173+
174+
// Only submit if not already pending.
175+
if (!k_work_is_pending(&clock_update_work)) {
176+
k_work_submit_to_queue(&ui_work_q, &clock_update_work);
177+
}
178+
if (!k_work_is_pending(&date_day_update_work)) {
179+
k_work_submit_to_queue(&ui_work_q, &date_day_update_work);
180+
}
181+
}
182+
183+
164184
/* CLOCK_UPDATE_WORKER
165185
* This function is called by the UI work queue to update the clock view.
166186
* It updates the current time in the device twin and then
@@ -174,7 +194,7 @@ void clock_update_worker(struct k_work *work) {
174194
utc_time_t local_time = unix_to_localtime(unix_time, device_twin->utc_zone);
175195
device_twin->current_time = local_time;
176196

177-
// Update the clock view.
197+
// Update the clock view using the device twin's current time.
178198
uint8_t ret = home_screen_set_clock(device_twin->current_time.hour, device_twin->current_time.minute);
179199
if (ret != 0) {
180200
LOG_ERR("Failed to update the clock view.");
@@ -194,12 +214,12 @@ void date_day_update_worker(struct k_work *work) {
194214
utc_time_t local_time = unix_to_localtime(unix_time, device_twin->utc_zone);
195215
device_twin->current_time = local_time;
196216

197-
// Update the date and day views.
198-
uint8_t ret = home_screen_set_date(local_time.year, local_time.month, local_time.day);
217+
// Update the date and day views using the device twin's current time.
218+
uint8_t ret = home_screen_set_date(device_twin->current_time.year, device_twin->current_time.month, device_twin->current_time.day);
199219
if (ret != 0) {
200220
LOG_ERR("Failed to update the date view.");
201221
}
202-
ret = home_screen_set_day(weekdays[local_time.weekday]);
222+
ret = home_screen_set_day(weekdays[device_twin->current_time.weekday]);
203223
if (ret != 0) {
204224
LOG_ERR("Failed to update the day view.");
205225
}

0 commit comments

Comments
 (0)