1 /* main.c - Application main entry point */
2 
3 /*
4  * Copyright (c) 2015-2016 Intel Corporation
5  * Copyright (c) 2019 Marcio Montenegro <mtuxpe@gmail.com>
6  *
7  * SPDX-License-Identifier: Apache-2.0
8  */
9 
10 #include <zephyr/types.h>
11 #include <stddef.h>
12 #include <string.h>
13 #include <errno.h>
14 #include <zephyr/sys/printk.h>
15 #include <zephyr/sys/byteorder.h>
16 #include <zephyr/kernel.h>
17 #include <zephyr/drivers/gpio.h>
18 #include <zephyr/logging/log.h>
19 
20 #include <zephyr/bluetooth/bluetooth.h>
21 #include <zephyr/bluetooth/hci.h>
22 #include <zephyr/bluetooth/conn.h>
23 #include <zephyr/bluetooth/uuid.h>
24 #include <zephyr/bluetooth/gatt.h>
25 #include "button_svc.h"
26 #include "led_svc.h"
27 
28 LOG_MODULE_REGISTER(main);
29 
30 /* Button value. */
31 static uint16_t but_val;
32 
33 /* Prototype */
34 static ssize_t recv(struct bt_conn *conn,
35 		    const struct bt_gatt_attr *attr, const void *buf,
36 		    uint16_t len, uint16_t offset, uint8_t flags);
37 
38 /* ST Custom Service  */
39 static struct bt_uuid_128 st_service_uuid = BT_UUID_INIT_128(
40 	BT_UUID_128_ENCODE(0x0000fe40, 0xcc7a, 0x482a, 0x984a, 0x7f2ed5b3e58f));
41 
42 /* ST LED service */
43 static struct bt_uuid_128 led_char_uuid = BT_UUID_INIT_128(
44 	BT_UUID_128_ENCODE(0x0000fe41, 0x8e22, 0x4541, 0x9d4c, 0x21edae82ed19));
45 
46 /* ST Notify button service */
47 static struct bt_uuid_128 but_notif_uuid = BT_UUID_INIT_128(
48 	BT_UUID_128_ENCODE(0x0000fe42, 0x8e22, 0x4541, 0x9d4c, 0x21edae82ed19));
49 
50 #define DEVICE_NAME CONFIG_BT_DEVICE_NAME
51 #define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)
52 #define ADV_LEN 12
53 
54 /* Advertising data */
55 static uint8_t manuf_data[ADV_LEN] = {
56 	0x01 /*SKD version */,
57 	0x83 /* STM32WB - P2P Server 1 */,
58 	0x00 /* GROUP A Feature  */,
59 	0x00 /* GROUP A Feature */,
60 	0x00 /* GROUP B Feature */,
61 	0x00 /* GROUP B Feature */,
62 	0x00, /* BLE MAC start -MSB */
63 	0x00,
64 	0x00,
65 	0x00,
66 	0x00,
67 	0x00, /* BLE MAC stop */
68 };
69 
70 static const struct bt_data ad[] = {
71 	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
72 	BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
73 	BT_DATA(BT_DATA_MANUFACTURER_DATA, manuf_data, ADV_LEN)
74 };
75 
76 /* BLE connection */
77 struct bt_conn *ble_conn;
78 /* Notification state */
79 volatile bool notify_enable;
80 
mpu_ccc_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)81 static void mpu_ccc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
82 {
83 	ARG_UNUSED(attr);
84 	notify_enable = (value == BT_GATT_CCC_NOTIFY);
85 	LOG_INF("Notification %s", notify_enable ? "enabled" : "disabled");
86 }
87 
88 /* The embedded board is acting as GATT server.
89  * The ST BLE Android app is the BLE GATT client.
90  */
91 
92 /* ST BLE Sensor GATT services and characteristic */
93 
94 BT_GATT_SERVICE_DEFINE(stsensor_svc,
95 BT_GATT_PRIMARY_SERVICE(&st_service_uuid),
96 BT_GATT_CHARACTERISTIC(&led_char_uuid.uuid,
97 		       BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE_WITHOUT_RESP,
98 		       BT_GATT_PERM_WRITE, NULL, recv, (void *)1),
99 BT_GATT_CHARACTERISTIC(&but_notif_uuid.uuid, BT_GATT_CHRC_NOTIFY,
100 		       BT_GATT_PERM_READ, NULL, NULL, &but_val),
101 BT_GATT_CCC(mpu_ccc_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
102 );
103 
recv(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)104 static ssize_t recv(struct bt_conn *conn,
105 		    const struct bt_gatt_attr *attr, const void *buf,
106 		    uint16_t len, uint16_t offset, uint8_t flags)
107 {
108 	led_update();
109 
110 	return 0;
111 }
112 
button_callback(const struct device * gpiob,struct gpio_callback * cb,uint32_t pins)113 static void button_callback(const struct device *gpiob, struct gpio_callback *cb,
114 		     uint32_t pins)
115 {
116 	int err;
117 
118 	LOG_INF("Button pressed");
119 	if (ble_conn) {
120 		if (notify_enable) {
121 			err = bt_gatt_notify(NULL, &stsensor_svc.attrs[4],
122 					     &but_val, sizeof(but_val));
123 			if (err) {
124 				LOG_ERR("Notify error: %d", err);
125 			} else {
126 				LOG_INF("Send notify ok");
127 				but_val = (but_val == 0) ? 0x100 : 0;
128 			}
129 		} else {
130 			LOG_INF("Notify not enabled");
131 		}
132 	} else {
133 		LOG_INF("BLE not connected");
134 	}
135 }
136 
bt_ready(int err)137 static void bt_ready(int err)
138 {
139 	if (err) {
140 		LOG_ERR("Bluetooth init failed (err %d)", err);
141 		return;
142 	}
143 	LOG_INF("Bluetooth initialized");
144 	/* Start advertising */
145 	err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), NULL, 0);
146 	if (err) {
147 		LOG_ERR("Advertising failed to start (err %d)", err);
148 		return;
149 	}
150 
151 	LOG_INF("Configuration mode: waiting connections...");
152 }
153 
connected(struct bt_conn * connected,uint8_t err)154 static void connected(struct bt_conn *connected, uint8_t err)
155 {
156 	if (err) {
157 		LOG_ERR("Connection failed (err %u)", err);
158 	} else {
159 		LOG_INF("Connected");
160 		if (!ble_conn) {
161 			ble_conn = bt_conn_ref(connected);
162 		}
163 	}
164 }
165 
disconnected(struct bt_conn * disconn,uint8_t reason)166 static void disconnected(struct bt_conn *disconn, uint8_t reason)
167 {
168 	if (ble_conn) {
169 		bt_conn_unref(ble_conn);
170 		ble_conn = NULL;
171 	}
172 
173 	LOG_INF("Disconnected (reason %u)", reason);
174 }
175 
176 BT_CONN_CB_DEFINE(conn_callbacks) = {
177 	.connected = connected,
178 	.disconnected = disconnected,
179 };
180 
main(void)181 int main(void)
182 {
183 	int err;
184 
185 	err = button_init(button_callback);
186 	if (err) {
187 		return 0;
188 	}
189 
190 	err = led_init();
191 	if (err) {
192 		return 0;
193 	}
194 
195 	/* Initialize the Bluetooth Subsystem */
196 	err = bt_enable(bt_ready);
197 	if (err) {
198 		LOG_ERR("Bluetooth init failed (err %d)", err);
199 	}
200 	return 0;
201 }
202