Hi.
There is MainThread and MeasureThread.
There are also two events that MainThread sends - BIT(0), BIT(1). These are Start and Stop.
In MeasureThread, we first wait for the Start event K_FOREVER, after which we get into another loop where we wait for Stop K_NO_WAIT.
The idea is to send a Start event when a Client connects via BE, which will wake up the thread.
This Thread will start sending notify via BE until it receives a Stop event when the client disconnects.
My problem is that when I sent the Stop event, it does not arrive, although Start did. What could this be related to?
I do not see the line "WT> Receive WT_STOP_EVENT"
#include <zephyr/types.h>
#include <zephyr/kernel.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/sys/printk.h>
static uint8_t weight_value = 0;
static struct bt_conn *connection_;
#define WT_EXEC_EVENT BIT(0)
#define WT_STOP_EVENT BIT(1)
K_EVENT_DEFINE(measure_thread_event_);
#define WT_STACK_SIZE 4096
K_THREAD_STACK_DEFINE(wt_stack, WT_STACK_SIZE);
extern void wt_thread(void *, void *, void *);
struct k_thread wt_data;
static struct bt_uuid_128 service_uuid = BT_UUID_INIT_128(
BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef0));
static struct bt_uuid_128 weight_char_uuid = BT_UUID_INIT_128(
BT_UUID_128_ENCODE(0x87654321, 0x4321, 0x8765, 0x4321, 0xfedcba987654));
static ssize_t read_weight(struct bt_conn *conn, const struct bt_gatt_attr *attr,
void *buf, uint16_t len, uint16_t offset)
{
const uint8_t *value = attr->user_data;
return bt_gatt_attr_read(conn, attr, buf, len, offset, value, sizeof(weight_value));
}
static void bt_read_weight_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
{
bool notif_enabled = (value == BT_GATT_CCC_NOTIFY);
printk("BT> Notifications %s\n", notif_enabled ? "enabled" : "disabled");
}
BT_GATT_SERVICE_DEFINE(service,
BT_GATT_PRIMARY_SERVICE(&service_uuid),
BT_GATT_CHARACTERISTIC(&weight_char_uuid.uuid, BT_GATT_CHRC_NOTIFY | BT_GATT_CHRC_READ,
BT_GATT_PERM_READ, read_weight, NULL, &weight_value),
BT_GATT_CCC(bt_read_weight_cfg_changed,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE), );
static void connected(struct bt_conn *conn, uint8_t err)
{
if (err)
{
printk("BT> Connection failed (err %u)\n", err);
return;
}
if (connection_)
{
printk("BT> Only one connection is allowed at a time.\n");
return;
}
printk("BT> Connected\n");
connection_ = bt_conn_ref(conn);
printk("BT> Send WT_EXEC_EVENT\n");
k_event_set(&measure_thread_event_, WT_EXEC_EVENT);
}
static void disconnected(struct bt_conn *conn, uint8_t reason)
{
printk("BT> Disconnected (reason %u)\n", reason);
if (!connection_)
{
printk("BT> No active connection\n");
}
else
{
printk("BT> Send WT_STOP_EVENT\n");
k_event_set(&measure_thread_event_, WT_STOP_EVENT);
}
}
BT_CONN_CB_DEFINE(conn_callbacks) = {
.connected = connected,
.disconnected = disconnected,
};
int main(void)
{
printk("BT> Starting Bluetooth Peripheral\n");
int error;
error = bt_enable(NULL);
if (error)
{
printk("BT> Bluetooth init failed (err %d)\n", error);
return -1;
}
printk("BT> Bluetooth initialized\n");
k_tid_t my_tid = k_thread_create(&wt_data, wt_stack,
K_THREAD_STACK_SIZEOF(wt_stack),
wt_thread,
NULL, NULL, NULL,
/*lowPrio=*/7, /*options=*/0, K_NO_WAIT);
error = bt_le_adv_start(BT_LE_ADV_CONN, NULL, 0, NULL, 0);
if (error)
{
printk("BT> Advertising failed to start (err %d)\n", error);
return -1;
}
printk("BT> Advertising successfully started\n");
k_thread_suspend(k_current_get());
return 0;
}
void wt_thread(void *, void *, void *)
{
while (1)
{
uint32_t events = k_event_wait(&measure_thread_event_, WT_EXEC_EVENT, true, K_FOREVER);
if (events & WT_EXEC_EVENT)
{
printk("WT> Received WT_EXEC_EVENT\n");
if (!connection_)
{
printk("WT> No active connection\n");
return;
}
exec();
printk("WT> Completed\n");
bt_conn_unref(connection_);
connection_ = NULL;
}
}
}
void exec()
{
while (1)
{
uint32_t events = k_event_wait(&measure_thread_event_, WT_STOP_EVENT, false, K_NO_WAIT);
if (events & WT_STOP_EVENT)
{
printk("WT> Receive WT_STOP_EVENT\n");
return;
}
weight_value++;
printk("WT> Notify %d\n", weight_value);
//bt_gatt_notify(NULL, &service.attrs[1], &weight_value, sizeof(weight_value));
k_sleep(K_MSEC(500));
}
}