Skip to content

Commit 0693167

Browse files
feat: add bluetooth functionality
1 parent a7bce36 commit 0693167

File tree

4 files changed

+193
-0
lines changed

4 files changed

+193
-0
lines changed

src/bluetooth/bluetooth_infra.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#include <zephyr/settings/settings.h>
2+
#include <zephyr/bluetooth/gatt.h>
3+
#include <zephyr/logging/log.h>
4+
5+
6+
LOG_MODULE_REGISTER(ZephyrWatch_BluetoothInfra, LOG_LEVEL_INF);
7+
8+
9+
static const struct bt_data m_ad[] = {
10+
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
11+
BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_CTS_VAL)),
12+
};
13+
14+
static const struct bt_data m_sd[] = {
15+
BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1),
16+
};
17+
18+
static void m_connected_callback(struct bt_conn *conn, uint8_t err) {
19+
if (err) LOG_ERR("Connection failed (err %u).", err);
20+
else {
21+
char addr[BT_ADDR_LE_STR_LEN];
22+
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
23+
LOG_INF("Connection established to %s.", addr);
24+
}
25+
}
26+
27+
static void m_disconnected_callback(struct bt_conn *conn, uint8_t reason) {
28+
LOG_INF("Disconnected (reason 0x%02x).", reason);
29+
}
30+
31+
BT_CONN_CB_DEFINE(conn_callbacks) = {
32+
.connected = m_connected_callback,
33+
.disconnected = m_disconnected_callback,
34+
};
35+
36+
/* The API function to enable Bluetooth and start advertisement. */
37+
uint8_t enable_bluetooth_and_start_advertisement() {
38+
int err;
39+
40+
err = bt_enable(NULL);
41+
if (err) {
42+
LOG_ERR("Bluetooth init failed (err %d).", err);
43+
return err;
44+
}
45+
46+
LOG_INF("Bluetooth initialized.");
47+
48+
if (IS_ENABLED(CONFIG_SETTINGS)) {
49+
settings_load();
50+
}
51+
52+
err = bt_le_adv_start(BT_LE_ADV_CONN, m_ad, ARRAY_SIZE(m_ad), m_sd, ARRAY_SIZE(m_sd));
53+
if (err) {
54+
LOG_ERR("Advertising failed to start (err %d).", err);
55+
return err;
56+
}
57+
58+
LOG_INF("Advertising successfully started.");
59+
return 0;
60+
}
61+
62+
uint8_t disable_bluetooth_and_stop_advertisement() {
63+
int err;
64+
65+
err = bt_le_adv_stop();
66+
if (err) {
67+
LOG_ERR("Advertising failed to stop (err %d).", err);
68+
return err;
69+
}
70+
71+
LOG_INF("Advertising successfully stopped.");
72+
73+
err = bt_disable();
74+
if (err) {
75+
LOG_ERR("Bluetooth failed to disable (err %d).", err);
76+
return err;
77+
}
78+
79+
LOG_INF("Bluetooth disabled.");
80+
return 0;
81+
}

src/bluetooth/bluetooth_infra.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifdef __cplusplus
2+
extern "C" {
3+
#endif
4+
5+
uint8_t enable_bluetooth_and_start_advertisement();
6+
uint8_t disable_bluetooth_and_stop_advertisement();
7+
8+
#ifdef __cplusplus
9+
}
10+
#endif
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#include <zephyr/sys/byteorder.h>
2+
#include <zephyr/logging/log.h>
3+
#include <zephyr/bluetooth/gatt.h>
4+
5+
#include "current_time_service.h"
6+
7+
LOG_MODULE_REGISTER(ZephyrWatch_CurrentTimeService, LOG_LEVEL_INF);
8+
9+
10+
/* Holds current time data. */
11+
static uint8_t m_current_time_data[10] = {
12+
232U, // Year (2024) last byte
13+
7U, // Year (2024) first byte
14+
5U, // Month (May)
15+
13U, // Day (13th)
16+
23U, // Hours (23)
17+
45U, // Minutes (45)
18+
30U, // Seconds (30)
19+
2U, // Day of week (Tuesday)
20+
0U, // Fractions 256 part of 'Exact Time 256'
21+
0U, // Adjust reason
22+
};
23+
24+
/* Current Time Service Declaration */
25+
static ssize_t m_time_write_callback(
26+
struct bt_conn *conn,
27+
const struct bt_gatt_attr *attr,
28+
const void *buf,
29+
uint16_t len,
30+
uint16_t offset,
31+
uint8_t flags) {
32+
33+
// Get the value of the attribute.
34+
uint8_t *value = attr->user_data;
35+
36+
// Check if the value written is valid.
37+
if (offset + len > sizeof(m_current_time_data)) {
38+
LOG_ERR("Write request too long.");
39+
return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
40+
}
41+
42+
// Copy the new value into the m_current_time_data array (given as buffer).
43+
memcpy(value + offset, buf, len);
44+
LOG_INF("Current time updated from the Bluetooth client.");
45+
return len;
46+
}
47+
48+
/* Current Time Service Declaration */
49+
BT_GATT_SERVICE_DEFINE(cts_cvs,
50+
BT_GATT_PRIMARY_SERVICE(BT_UUID_CTS),
51+
BT_GATT_CHARACTERISTIC(
52+
BT_UUID_CTS_CURRENT_TIME,
53+
BT_GATT_CHRC_WRITE,
54+
BT_GATT_PERM_WRITE,
55+
NULL, m_time_write_callback, m_current_time_data),
56+
);
57+
58+
/* API for the Current Time Service application layer consumers.
59+
* - get_current_time: Get the current time. Returns a struct with
60+
* proper key-value pairs for year, month, hours, minutes, and seconds.
61+
* - set_current_time: Set the current time. Takes a struct with
62+
* proper key-value pairs for year, month, hours, minutes, and seconds.
63+
*/
64+
65+
struct current_time get_current_time(void) {
66+
struct current_time time;
67+
time.year = sys_le16_to_cpu(*(uint16_t *) &m_current_time_data[0]);
68+
time.month = m_current_time_data[2];
69+
time.day = m_current_time_data[3];
70+
time.hours = m_current_time_data[4];
71+
time.minutes = m_current_time_data[5];
72+
time.seconds = m_current_time_data[6];
73+
return time;
74+
}
75+
76+
void set_current_time(struct current_time time) {
77+
*(uint16_t *) &m_current_time_data[0] = sys_cpu_to_le16(time.year);
78+
m_current_time_data[2] = time.month;
79+
m_current_time_data[3] = time.day;
80+
m_current_time_data[4] = time.hours;
81+
m_current_time_data[5] = time.minutes;
82+
m_current_time_data[6] = time.seconds;
83+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ifdef __cplusplus
2+
extern "C" {
3+
#endif
4+
5+
struct current_time {
6+
uint16_t year;
7+
uint8_t month;
8+
uint8_t day;
9+
uint8_t hours;
10+
uint8_t minutes;
11+
uint8_t seconds;
12+
};
13+
14+
struct current_time get_current_time(void);
15+
void set_current_time(struct current_time time);
16+
17+
#ifdef __cplusplus
18+
}
19+
#endif

0 commit comments

Comments
 (0)