1 /*
2  * Copyright (c) 2023 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/bluetooth/bluetooth.h>
8 #include <zephyr/bluetooth/uuid.h>
9 
10 #define SERVICE_DATA_LEN        9
11 #define SERVICE_UUID            0xfcd2      /* BTHome service UUID */
12 #define IDX_TEMPL               4           /* Index of lo byte of temp in service data*/
13 #define IDX_TEMPH               5           /* Index of hi byte of temp in service data*/
14 
15 #define ADV_PARAM BT_LE_ADV_PARAM(BT_LE_ADV_OPT_USE_IDENTITY, \
16 				  BT_GAP_ADV_SLOW_INT_MIN, \
17 				  BT_GAP_ADV_SLOW_INT_MAX, NULL)
18 
19 
20 static uint8_t service_data[SERVICE_DATA_LEN] = {
21 	BT_UUID_16_ENCODE(SERVICE_UUID),
22 	0x40,
23 	0x02,	/* Temperature */
24 	0xc4,	/* Low byte */
25 	0x00,   /* High byte */
26 	0x03,	/* Humidity */
27 	0xbf,	/* 50.55%  low byte*/
28 	0x13,   /* 50.55%  high byte*/
29 };
30 
31 static struct bt_data ad[] = {
32 	BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR),
33 	BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1),
34 	BT_DATA(BT_DATA_SVC_DATA16, service_data, ARRAY_SIZE(service_data))
35 };
36 
bt_ready(int err)37 static void bt_ready(int err)
38 {
39 	if (err) {
40 		printk("Bluetooth init failed (err %d)\n", err);
41 		return;
42 	}
43 
44 	printk("Bluetooth initialized\n");
45 
46 	/* Start advertising */
47 	err = bt_le_adv_start(ADV_PARAM, ad, ARRAY_SIZE(ad), NULL, 0);
48 	if (err) {
49 		printk("Advertising failed to start (err %d)\n", err);
50 		return;
51 	}
52 }
53 
main(void)54 int main(void)
55 {
56 	int err;
57 	int temp = 0;
58 
59 	printk("Starting BTHome sensor template\n");
60 
61 	/* Initialize the Bluetooth Subsystem */
62 	err = bt_enable(bt_ready);
63 	if (err) {
64 		printk("Bluetooth init failed (err %d)\n", err);
65 		return 0;
66 	}
67 
68 	for (;;) {
69 		/* Simulate temperature from 0C to 25C */
70 		service_data[IDX_TEMPH] = (temp * 100) >> 8;
71 		service_data[IDX_TEMPL] = (temp * 100) & 0xff;
72 		if (temp++ == 25) {
73 			temp = 0;
74 		}
75 		err = bt_le_adv_update_data(ad, ARRAY_SIZE(ad), NULL, 0);
76 		if (err) {
77 			printk("Failed to update advertising data (err %d)\n", err);
78 		}
79 		k_sleep(K_MSEC(BT_GAP_ADV_SLOW_INT_MIN));
80 	}
81 	return 0;
82 }
83