I am able to subscribe for differen
#if 1
/* main.c - Application main entry point */
/*
* Copyright (c) 2020 SixOctets Systems
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <stddef.h>
#include <errno.h>
#include <zephyr/zephyr.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>
static int scan_start(void);
static uint16_t CTS_read_handle =0xFFU;
static uint16_t fever_read_handle =0xFFU;
#define BT_TEMPERATURE_ADDR_LE_ANY ((bt_addr_le_t[]) { {BT_ADDR_LE_RANDOM, { { 0xEE, 0x4D, 0xAE, 0x55, 0x38, 0xE4 } } } })
//Defining the Temperature alert service UUIDs
#define BT_UUID_TEMPERATURE_ALERT_SERVICE \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x1b561960, 0xdf3c, 0x4d2a, 0xb319, 0x8f26bee36772))
#define BT_UUID_TEMPERATURE_ALERT_CHARACTER \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x00001961, 0x0000, 0x1000, 0x8000, 0x0805f9b34fb))
#define BT_UUID_TEMPERATURE_ALERT_CCC \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x00002902, 0x0000, 0x1000, 0x8000, 0x00805f9b34fb))
//Defining the Temperature battery service UUIDs
#define BT_UUID_TEMPERATURE_BATTERY_SERVICE \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x0000180F, 0x0000, 0x1000, 0x8000, 0x00805f9b34fb))
#define BT_UUID_TEMPERATURE_BATTERY_CHARACTER \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x00002A19, 0x0000, 0x1000, 0x8000, 0x00805f9b34fb))
#define BT_UUID_TEMPERATURE_BATTERY_CCC \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x00002902, 0x0000, 0x1000, 0x8000, 0x00805f9b34fb))
//Defining the Temperature Measurement UUIDs
#define BT_UUID_TEMPERATURE_MEASUREMENT_SERVICE \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x00001809, 0x0000, 0x1000, 0x8000, 0x00805f9b34fb))
#define BT_UUID_TEMPERATURE_MEASUREMENT_CHARACTER \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x00002A1C, 0x0000, 0x1000, 0x8000, 0x00805f9b34fb))
#define BT_UUID_TEMPERATURE_MEASUREMENT_CCC \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x00002902, 0x0000, 0x1000, 0x8000, 0x00805f9b34fb))
//Defining the Temperature MOVEMENT UUIDs
#define BT_UUID_TEMPERATURE_MOVEMENT_SERVICE \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0xe68f1980, 0x8e6d, 0x4254, 0x9650, 0xa4c165f927c8))
#define BT_UUID_TEMPERATURE_POSITION_CHARACTER \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x00001981, 0x0000, 0x1000, 0x8000, 0x00805f9b34fb))
#define BT_UUID_TEMPERATURE_POSITION_CCC \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x00002902, 0x0000, 0x1000, 0x8000, 0x00805f9b34fb))
//Defining the Temperature Fever and color alert UUIDs
#define BT_UUID_TEMPERATURE_COLOR_SERVICE \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0xc67b1970, 0x5a63, 0x41d4, 0x9f35, 0xf5218e4c6c83))
#define BT_UUID_TEMPERATURE_FEVER_ALERT_CHARACTER \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x00001972, 0x0000, 0x1000, 0x8000, 0x00805f9b34fb))
struct bt_conn *default_conn;
struct bt_uuid_16 uuid = BT_UUID_INIT_16(0);
struct bt_gatt_discover_params bas_discover_params;
struct bt_gatt_discover_params hts_discover_params;
struct bt_gatt_discover_params alert_discover_params;
struct bt_gatt_discover_params pos_discover_params;
struct bt_gatt_discover_params fev_cts_discover_params;
struct bt_gatt_discover_params cts_discover_params;
struct bt_gatt_subscribe_params bas_subscribe_params;
struct bt_gatt_subscribe_params hts_subscribe_params;
struct bt_gatt_subscribe_params alert_subscribe_params;
struct bt_gatt_subscribe_params pos_subscribe_params;
struct bt_gatt_read_params read_params;
struct bt_gatt_write_params CTS_write;
struct bt_gatt_write_params fever_alert_write;
struct bt_uuid_128 uuid_temp = BT_UUID_INIT_128(0);
static const uint8_t fever_temperature_limit[] = {0x00,0x0F}; //38.4 C max temperature
uint8_t value[10]={0xE6,0x07,0x0C,0x1D, 0x0C,0x01, 0x00,0x01, 0x00,0x00};
static uint8_t discover_func_temperature(struct bt_conn *conn,const struct bt_gatt_attr *attr,struct bt_gatt_discover_params *params);
static uint8_t discover_func_position(struct bt_conn *conn,const struct bt_gatt_attr *attr,struct bt_gatt_discover_params *params);
static uint8_t discover_func_alert(struct bt_conn *conn,const struct bt_gatt_attr *attr,struct bt_gatt_discover_params *params);
static uint8_t discover_func_battery(struct bt_conn *conn,const struct bt_gatt_attr *attr,struct bt_gatt_discover_params *params);
static uint8_t discover_func_fev_alert(struct bt_conn *conn,const struct bt_gatt_attr *attr,struct bt_gatt_discover_params *params);
static uint8_t discover_func_CTS(struct bt_conn *conn,const struct bt_gatt_attr *attr,struct bt_gatt_discover_params *params);
static double pow(double x, double y)
{
double result = 1;
if (y < 0) {
y = -y;
while (y--) {
result /= x;
}
} else {
while (y--) {
result *= x;
}
}
return result;
}
static uint8_t notify_func_temp(struct bt_conn *conn,
struct bt_gatt_subscribe_params *params,
const void *data, uint16_t length)
{
double temperature;
uint32_t mantissa;
int8_t exponent;
printk("Temperature notify\n");
// if (!data) {
// printk("[UNSUBSCRIBED]\n");
// params->value_handle = 0U;
// return BT_GATT_ITER_STOP;
// }
uint8_t *d = (uint8_t *)data;
for (int i =0; i < length; i++){
printk("%2x ", d[i]);
}
printk("\n");
// /* temperature value display */
// mantissa = sys_get_le24(&((uint8_t *)data)[1]);
// exponent = ((uint8_t *)data)[4];
// temperature = (double)mantissa * pow(10, exponent);
// printf("Temperature %gC.\n", temperature);
return BT_GATT_ITER_CONTINUE;
}
static uint8_t notify_func_battery(struct bt_conn *conn,
struct bt_gatt_subscribe_params *params,
const void *data, uint16_t length)
{
printk("Battery notify\n");
// if (!data) {
// printk("[UNSUBSCRIBED]\n");
// params->value_handle = 0U;
// return BT_GATT_ITER_STOP;
// }
uint8_t *d = (uint8_t *)data;
for (int i =0; i < length; i++){
printk("%2x ", d[i]);
}
printk("\n");
return BT_GATT_ITER_CONTINUE;
}
static uint8_t notify_func_position(struct bt_conn *conn,
struct bt_gatt_subscribe_params *params,
const void *data, uint16_t length)
{
printk("Position notify\n");
// if (!data) {
// printk("[UNSUBSCRIBED]\n");
// params->value_handle = 0U;
// return BT_GATT_ITER_STOP;
// }
uint8_t *d = (uint8_t *)data;
for (int i =0; i < length; i++){
printk("%2x ", d[i]);
}
printk("\n");
return BT_GATT_ITER_CONTINUE;
}
static uint8_t notify_func_alert(struct bt_conn *conn,
struct bt_gatt_subscribe_params *params,
const void *data, uint16_t length)
{
printk("Alert notify\n");
// if (!data) {
// printk("[UNSUBSCRIBED]\n");
// params->value_handle = 0U;
// return BT_GATT_ITER_STOP;
// }
uint8_t *d = (uint8_t *)data;
for (int i =0; i < length; i++){
printk("%2x ", d[i]);
}
printk("\n");
return BT_GATT_ITER_CONTINUE;
}
static uint8_t read_func_cb(struct bt_conn *conn,
uint8_t err, struct bt_gatt_read_params *params,
const void *data, uint16_t length)
{
if ((data != NULL) && (err == 0))
{
if (params->single.handle== CTS_read_handle)
{
uint8_t *d = (uint8_t *)data;
printk("length %2x \n",length);
for (int i =0; i < length; i++){
printk("%2x ", d[i]);
}
}
printk("\n");
}else{
printk("No data\n");
}
return BT_GATT_ITER_STOP;
}
static void write_cb(struct bt_conn *conn, uint8_t err, struct bt_gatt_write_params *params)
{
if (err != BT_ATT_ERR_SUCCESS) {
printk("Write failed: 0x%02X\n", err);
}else{
printk("\nafter Write CTS sucess\n");
}
}
static void write_fever_cb(struct bt_conn *conn, uint8_t err, struct bt_gatt_write_params *params)
{
if (err != BT_ATT_ERR_SUCCESS) {
printk("Write failed: 0x%02X\n", err);
}else{
printk("Write sucess \n");
}
}
static void security_changed(struct bt_conn *conn, bt_security_t level,
enum bt_security_err err)
{
printk("%s: to level %u (err %u)\n", __func__, level, err);
}
static uint8_t discover_func_temperature(struct bt_conn *conn,
const struct bt_gatt_attr *attr,
struct bt_gatt_discover_params *params)
{
int err;
if (!attr) {
printk("Discover complete\n");
(void)memset(params, 0, sizeof(*params));
return BT_GATT_ITER_STOP;
}
printk("temperature [ATTRIBUTE] handle %u\n", attr->handle);
if (!bt_uuid_cmp(hts_discover_params.uuid, BT_UUID_HTS)) {
memcpy(&uuid, BT_UUID_HTS_MEASUREMENT, sizeof(uuid));
hts_discover_params.uuid = &uuid.uuid;
hts_discover_params.start_handle = attr->handle + 1;
hts_discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
err = bt_gatt_discover(conn, &hts_discover_params);
if (err) {
printk("Discover failed 1(err %d)\n", err);
}
} else if (!bt_uuid_cmp(hts_discover_params.uuid,BT_UUID_HTS_MEASUREMENT))
{
memcpy(&uuid, BT_UUID_GATT_CCC, sizeof(uuid));
hts_discover_params.uuid = &uuid.uuid;
hts_discover_params.start_handle = attr->handle + 2;
hts_discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
hts_subscribe_params.value_handle = bt_gatt_attr_value_handle(attr);
err = bt_gatt_discover(conn, &hts_discover_params);
if (err) {
printk("Discover failed 2(err %d)\n", err);
}
} else {
hts_subscribe_params.notify = notify_func_temp;
hts_subscribe_params.value = BT_GATT_CCC_INDICATE;
hts_subscribe_params.min_security = bt_conn_get_security(conn);
hts_subscribe_params.ccc_handle = attr->handle ;
err = bt_gatt_subscribe(conn, &hts_subscribe_params);
if (err && err != -EALREADY) {
printk("Subscribe failed (err %d)\n", err);
} else {
printk("temperature measurement [SUBSCRIBED]\n");
}
memcpy(&uuid_temp, BT_UUID_TEMPERATURE_MOVEMENT_SERVICE, sizeof(uuid_temp));
pos_discover_params.uuid = &uuid_temp.uuid;
pos_discover_params.func = discover_func_position;
pos_discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
pos_discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
pos_discover_params.type = BT_GATT_DISCOVER_PRIMARY;
err = bt_gatt_discover(default_conn, &pos_discover_params);
if (err) {
printk("Discover failed(err %d)\n", err);
return;
}
return BT_GATT_ITER_STOP;
}
return BT_GATT_ITER_STOP;
}
static uint8_t discover_func_battery(struct bt_conn *conn,
const struct bt_gatt_attr *attr,
struct bt_gatt_discover_params *params)
{
int err;
if (!attr) {
printk("Discover complete\n");
(void)memset(params, 0, sizeof(*params));
return BT_GATT_ITER_STOP;
}
printk("Battery [ATTRIBUTE] handle %u\n", attr->handle);
if (!bt_uuid_cmp(bas_discover_params.uuid, BT_UUID_TEMPERATURE_BATTERY_SERVICE)) {
memcpy(&uuid_temp, BT_UUID_TEMPERATURE_BATTERY_CHARACTER, sizeof(uuid_temp));
bas_discover_params.uuid = &uuid_temp.uuid;
bas_discover_params.start_handle = attr->handle + 1;
bas_discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
err = bt_gatt_discover(conn, &bas_discover_params);
if (err) {
printk("Discover failed 3 (err %d)\n", err);
}
} else if (!bt_uuid_cmp(bas_discover_params.uuid,
BT_UUID_TEMPERATURE_BATTERY_CHARACTER)) {
memcpy(&uuid_temp, BT_UUID_GATT_CCC, sizeof(uuid_temp));
bas_discover_params.uuid = &uuid_temp.uuid;
bas_discover_params.start_handle = attr->handle + 2;
bas_discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
bas_subscribe_params.value_handle = bt_gatt_attr_value_handle(attr);
err = bt_gatt_discover(conn, &bas_discover_params);
if (err) {
printk("Discover failed 4(err %d)\n", err);
}
}
else {
bas_subscribe_params.notify= notify_func_battery;
bas_subscribe_params.value = BT_GATT_CCC_NOTIFY;
bas_subscribe_params.min_security = bt_conn_get_security(conn);
bas_subscribe_params.ccc_handle = attr->handle;
err = bt_gatt_subscribe(conn, &bas_subscribe_params);
if (err && err != -EALREADY) {
printk("Subscribe failed (err %d)\n", err);
} else {
printk("Battery characteristics [SUBSCRIBED]\n");
}
return BT_GATT_ITER_STOP;
}
return BT_GATT_ITER_STOP;
}
static uint8_t discover_func_alert(struct bt_conn *conn,
const struct bt_gatt_attr *attr,
struct bt_gatt_discover_params *params)
{
int err;
if(!attr)
{
printk("Discover complete\n");
(void)memset(params, 0, sizeof(*params));
return BT_GATT_ITER_STOP;
}
printk("alert [ATTRIBUTE] handle %u\n", attr->handle);
if (!bt_uuid_cmp(alert_discover_params.uuid, BT_UUID_TEMPERATURE_ALERT_SERVICE))
{
memcpy(&uuid_temp, BT_UUID_TEMPERATURE_ALERT_CHARACTER, sizeof(uuid_temp));
alert_discover_params.uuid = &uuid_temp.uuid;
alert_discover_params.start_handle = attr->handle + 1;
alert_discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
err = bt_gatt_discover(conn, &alert_discover_params);
if (err)
{
printk("Discover failed 5 (err %d)\n", err);
}
}
else if (!bt_uuid_cmp(alert_discover_params.uuid, BT_UUID_TEMPERATURE_ALERT_CHARACTER))
{
memcpy(&uuid_temp, BT_UUID_TEMPERATURE_ALERT_CCC, sizeof(uuid_temp));
alert_discover_params.uuid = &uuid_temp.uuid;
alert_discover_params.start_handle = attr->handle + 2;
alert_discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
alert_subscribe_params.value_handle = bt_gatt_attr_value_handle(attr);
err = bt_gatt_discover(conn, &alert_discover_params);
if (err)
{
printk("Discover failed 6(err %d)\n", err);
}
} else {
alert_subscribe_params.notify = notify_func_alert;
alert_subscribe_params.value = BT_GATT_CCC_INDICATE;
alert_subscribe_params.min_security = bt_conn_get_security(conn);
alert_subscribe_params.ccc_handle = attr->handle;
err = bt_gatt_subscribe(conn, &alert_subscribe_params);
if (err && err != -EALREADY) {
printk("Subscribe failed (err %d)\n", err);
} else {
printk("Alert characteristics [SUBSCRIBED]\n");
}
memcpy(&uuid_temp, BT_UUID_TEMPERATURE_COLOR_SERVICE, sizeof(uuid_temp));
fev_cts_discover_params.uuid = &uuid_temp.uuid;
fev_cts_discover_params.func = discover_func_fev_alert;
fev_cts_discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
fev_cts_discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
fev_cts_discover_params.type = BT_GATT_DISCOVER_PRIMARY;
err = bt_gatt_discover(default_conn, &fev_cts_discover_params);
if (err) {
printk("Discover failed(err %d)\n", err);
return;
}
return BT_GATT_ITER_STOP;
}
return BT_GATT_ITER_STOP;
}
static uint8_t discover_func_position(struct bt_conn *conn,
const struct bt_gatt_attr *attr,
struct bt_gatt_discover_params *params)
{
int err;
if (!attr)
{
printk("Discover complete\n");
(void)memset(params, 0, sizeof(*params));
return BT_GATT_ITER_STOP;
}
printk("position [ATTRIBUTE] handle %u\n", attr->handle);
if (!bt_uuid_cmp(pos_discover_params.uuid, BT_UUID_TEMPERATURE_MOVEMENT_SERVICE))
{
memcpy(&uuid_temp, BT_UUID_TEMPERATURE_POSITION_CHARACTER, sizeof(uuid_temp));
pos_discover_params.uuid = &uuid_temp.uuid;
pos_discover_params.start_handle = attr->handle + 1;
pos_discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
err = bt_gatt_discover(conn, &pos_discover_params);
if (err)
{
printk("Discover failed 7(err %d)\n", err);
}
}
else if (!bt_uuid_cmp(pos_discover_params.uuid, BT_UUID_TEMPERATURE_POSITION_CHARACTER))
{
memcpy(&uuid_temp, BT_UUID_TEMPERATURE_POSITION_CCC, sizeof(uuid_temp));
pos_discover_params.uuid = &uuid_temp.uuid;
pos_discover_params.start_handle = attr->handle + 2;
pos_discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
pos_subscribe_params.value_handle = bt_gatt_attr_value_handle(attr);
err = bt_gatt_discover(conn, &pos_discover_params);
if (err)
{
printk("Discover failed 8(err %d)\n", err);
}
} else {
pos_subscribe_params.notify = notify_func_position;
pos_subscribe_params.value = BT_GATT_CCC_INDICATE;
pos_subscribe_params.min_security = bt_conn_get_security(conn);
pos_subscribe_params.ccc_handle = attr->handle;
err = bt_gatt_subscribe(conn, &pos_subscribe_params);
if (err && err != -EALREADY) {
printk("Subscribe failed (err %d)\n", err);
} else {
printk("position characteristics [SUBSCRIBED]\n");
}
memcpy(&uuid_temp, BT_UUID_TEMPERATURE_ALERT_SERVICE, sizeof(uuid_temp));
alert_discover_params.uuid = &uuid_temp.uuid;
alert_discover_params.func = discover_func_alert;
alert_discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
alert_discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
alert_discover_params.type = BT_GATT_DISCOVER_PRIMARY;
err = bt_gatt_discover(default_conn, &alert_discover_params);
if (err) {
printk("Discover failed(err %d)\n", err);
}
return BT_GATT_ITER_STOP;
}
return BT_GATT_ITER_STOP;
}
static uint8_t discover_func_fev_alert(struct bt_conn *conn,
const struct bt_gatt_attr *attr,
struct bt_gatt_discover_params *params)
{
int err;
if (!attr)
{
printk("Discover complete\n");
(void)memset(params, 0, sizeof(*params));
return BT_GATT_ITER_STOP;
}
printk("fev alert [ATTRIBUTE] handle %u\n", attr->handle);
if (!bt_uuid_cmp(fev_cts_discover_params.uuid, BT_UUID_TEMPERATURE_COLOR_SERVICE))
{
memcpy(&uuid_temp, BT_UUID_TEMPERATURE_FEVER_ALERT_CHARACTER, sizeof(uuid_temp));
fev_cts_discover_params.uuid = &uuid_temp.uuid;
fev_cts_discover_params.start_handle = attr->handle + 1;
fev_cts_discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
err = bt_gatt_discover(conn, &fev_cts_discover_params);
if (err)
{
printk("Discover failed 9(err %d)\n", err);
}
}
else if (!bt_uuid_cmp(fev_cts_discover_params.uuid, BT_UUID_TEMPERATURE_FEVER_ALERT_CHARACTER))
{
fever_alert_write.handle = bt_gatt_attr_value_handle(attr);;
fever_alert_write.func = write_fever_cb;
fever_alert_write.offset = 0;
fever_alert_write.data = fever_temperature_limit;
fever_alert_write.length = sizeof(fever_temperature_limit);
// UNSET_FLAG(flag_write_complete);
printk("bt write start \n");
err = bt_gatt_write(conn, &fever_alert_write);
if(err){
printk("write failed (err %d)\n", err);
return BT_GATT_ITER_STOP;
}
memcpy(&uuid, BT_UUID_CTS, sizeof(uuid));
fev_cts_discover_params.uuid = &uuid.uuid;
fev_cts_discover_params.start_handle = attr->handle + 2;
fev_cts_discover_params.type = BT_GATT_DISCOVER_PRIMARY;
err = bt_gatt_discover(default_conn, &fev_cts_discover_params);
if (err) {
printk("Discover failed(err %d)\n", err);
}
memcpy(&uuid, BT_UUID_CTS, sizeof(uuid));
cts_discover_params.uuid = &uuid.uuid;
cts_discover_params.func = discover_func_CTS;
cts_discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
cts_discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
cts_discover_params.type = BT_GATT_DISCOVER_PRIMARY;
err = bt_gatt_discover(default_conn, &cts_discover_params);
if (err) {
printk("Discover failed(err %d)\n", err);
}
}
return BT_GATT_ITER_STOP;
}
static uint8_t discover_func_CTS(struct bt_conn *conn,
const struct bt_gatt_attr *attr,
struct bt_gatt_discover_params *params)
{
int err;
if (!attr)
{
printk("Discover complete\n");
(void)memset(params, 0, sizeof(*params));
return BT_GATT_ITER_STOP;
}
printk("CTS [ATTRIBUTE] handle %u\n", attr->handle);
if (!bt_uuid_cmp(cts_discover_params.uuid, BT_UUID_CTS))
{
memcpy(&uuid, BT_UUID_CTS_CURRENT_TIME, sizeof(uuid));
cts_discover_params.uuid = &uuid.uuid;
cts_discover_params.start_handle = attr->handle + 1;
cts_discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
err = bt_gatt_discover(conn, &cts_discover_params);
if (err)
{
printk("Discover failed 10(err %d)\n", err);
}
}
else if (!bt_uuid_cmp(cts_discover_params.uuid, BT_UUID_CTS_CURRENT_TIME))
{
/* Current time characteristic discovered */
CTS_read_handle = bt_gatt_attr_value_handle(attr);
printk("before write CTS \n");
/* Read Tx Power */
read_params.func = read_func_cb;
read_params.handle_count = 1;
read_params.single.handle = CTS_read_handle;
read_params.single.offset = 0;
err = bt_gatt_read(conn, &read_params);
if (err)
{
printk("GATT Read failed (err %d)\n", err);
}
CTS_read_handle =bt_gatt_attr_value_handle(attr);
CTS_write.handle = CTS_read_handle;
CTS_write.func = write_cb;
CTS_write.offset = 0;
CTS_write.data = value;
CTS_write.length = sizeof(value);
err = bt_gatt_write(conn, &CTS_write);
if(err){
printk("write failed (err %d)\n", err);
return BT_GATT_ITER_STOP;
}
/* Current time characteristic discovered */
CTS_read_handle = bt_gatt_attr_value_handle(attr);
/* Read Tx Power */
read_params.func = read_func_cb;
read_params.handle_count = 1;
read_params.single.handle = CTS_read_handle;
read_params.single.offset = 0;
err = bt_gatt_read(conn, &read_params);
if (err)
{
printk("GATT Read failed (err %d)\n", err);
}
}
return BT_GATT_ITER_STOP;
}
static void connected(struct bt_conn *conn, uint8_t conn_err)
{
char addr[BT_ADDR_LE_STR_LEN];
int err;
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
if (conn_err) {
printk("Failed to connect to %s (%u)\n", addr, conn_err);
bt_conn_unref(default_conn);
default_conn = NULL;
scan_start();
return;
}
printk("Connected: %s\n", addr);
err = bt_conn_set_security(conn, BT_SECURITY_L2);
if (err) {
printk("bt_conn_set_security failed (err %d)\n", err);
return;
}
if (conn == default_conn) {
memcpy(&uuid_temp, BT_UUID_TEMPERATURE_BATTERY_SERVICE, sizeof(uuid_temp));
bas_discover_params.uuid = &uuid_temp.uuid;
bas_discover_params.func = discover_func_battery;
bas_discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
bas_discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
bas_discover_params.type = BT_GATT_DISCOVER_PRIMARY;
err = bt_gatt_discover(default_conn, &bas_discover_params);
if (err) {
printk("Discover failed(err %d)\n", err);
//return BT_GATT_ITER_STOP;
}
memcpy(&uuid_temp, BT_UUID_TEMPERATURE_MEASUREMENT_SERVICE, sizeof(uuid_temp));
hts_discover_params.uuid = &uuid_temp.uuid;
hts_discover_params.func = discover_func_temperature;
hts_discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
hts_discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
hts_discover_params.type = BT_GATT_DISCOVER_PRIMARY;
err = bt_gatt_discover(default_conn, &hts_discover_params);
if (err) {
printk("Discover failed(err %d)\n", err);
}
}
}
static bool eir_found(struct bt_data *data, void *user_data)
{
bt_addr_le_t *addr = user_data;
int i;
printk("[AD]: %u data_len %u\n", data->type, data->data_len);
switch (data->type) {
case BT_DATA_UUID16_SOME:
case BT_DATA_UUID16_ALL:
if (data->data_len % sizeof(uint16_t) != 0U) {
printk("AD malformed\n");
return true;
}
for (i = 0; i < data->data_len; i += sizeof(uint16_t)) {
struct bt_uuid *uuid;
uint16_t u16;
int err;
memcpy(&u16, &data->data[i], sizeof(u16));
uuid = BT_UUID_DECLARE_16(sys_le16_to_cpu(u16));
if (bt_uuid_cmp(uuid, BT_UUID_HTS)) {
printk("HTS UUID matched \n");
continue;
}
err = bt_le_scan_stop();
if (err) {
printk("Stop LE scan failed (err %d)\n", err);
continue;
}
err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
BT_LE_CONN_PARAM_DEFAULT,
&default_conn);
if (err) {
printk("Create connection failed (err %d)\n",
err);
scan_start();
}
return false;
}
}
return true;
}
static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,
struct net_buf_simple *ad)
{
char dev[BT_ADDR_LE_STR_LEN];
if(bt_addr_cmp(BT_TEMPERATURE_ADDR_LE_ANY, addr) == 0){
bt_addr_le_to_str(addr, dev, sizeof(dev));
printk("[DEVICE]: %s, AD evt type %u, AD data len %u, RSSI %i\n",
dev, type, ad->len, rssi);
/* We're only interested in connectable events */
if (type == BT_HCI_ADV_IND || type == BT_HCI_ADV_DIRECT_IND) {
bt_data_parse(ad, eir_found, (void *)addr);
}
}
}
static int scan_start(void)
{
/* Use active scanning and disable duplicate filtering to handle any
* devices that might update their advertising data at runtime.
*/
struct bt_le_scan_param scan_param = {
.type = BT_LE_SCAN_TYPE_ACTIVE,
.options = BT_LE_SCAN_OPT_NONE,
.interval = BT_GAP_SCAN_FAST_INTERVAL,
.window = BT_GAP_SCAN_FAST_WINDOW,
};
return bt_le_scan_start(&scan_param, device_found);
}
static void disconnected(struct bt_conn *conn, uint8_t reason)
{
char addr[BT_ADDR_LE_STR_LEN];
int err;
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
printk("Disconnected: %s (reason 0x%02x)\n", addr, reason);
if (default_conn != conn) {
return;
}
bt_conn_unref(default_conn);
default_conn = NULL;
err = scan_start();
if (err) {
printk("Scanning failed to start (err %d)\n", err);
}
}
BT_CONN_CB_DEFINE(conn_callbacks) = {
.connected = connected,
.disconnected = disconnected,
.security_changed =security_changed,
};
void main(void)
{
int err;
printk("init main \n");
err = bt_enable(NULL);
if (err) {
printk("Bluetooth init failed (err %d)\n", err);
return;
}
printk("Bluetooth initialized\n");
err = scan_start();
if (err) {
printk("Scanning failed to start (err %d)\n", err);
return;
}
printk("Scanning successfully started\n");
}
#else
/* main.c - Application main entry point */
/*
* Copyright (c) 2015-2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/types.h>
#include <stddef.h>
#include <errno.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/sys/byteorder.h>
static void start_scan(void);
#define NAME_LEN 30
#define SPO2_NAME (char[9]){"BerryMed"}
#define BT_TEMPERATURE_ADDR_LE_ANY ((bt_addr_le_t[]) { { BT_ADDR_LE_RANDOM, { { 0xEE, 0x4D, 0xAE, 0x55, 0x38, 0xE4 } } } })
//Defining the different UUIDs for the Services of Wireless Temperature "tucky"
//Defining the Temperature alert service UUIDs
#define BT_UUID_TEMPERATURE_ALERT_SERVICE \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x1b561960, 0xdf3c, 0x4d2a, 0xb319, 0x8f26bee36772))
#define BT_UUID_TEMPERATURE_ALERT_CHARACTER \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x00001961, 0x0000, 0x1000, 0x8000, 0x0805f9b34fb))
#define BT_UUID_TEMPERATURE_ALERT_CCC \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x00002902, 0x0000, 0x1000, 0x8000, 0x00805f9b34fb))
//Defining the Temperature battery service UUIDs
#define BT_UUID_TEMPERATURE_BATTERY_SERVICE \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x0000180F, 0x0000, 0x1000, 0x8000, 0x00805f9b34fb))
#define BT_UUID_TEMPERATURE_BATTERY_CHARACTER \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x00002A19, 0x0000, 0x1000, 0x8000, 0x00805f9b34fb))
#define BT_UUID_TEMPERATURE_BATTERY_CCC \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x00002902, 0x0000, 0x1000, 0x8000, 0x00805f9b34fb))
//Defining the Temperature Measurement UUIDs
#define BT_UUID_TEMPERATURE_MEASUREMENT_SERVICE \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x00001809, 0x0000, 0x1000, 0x8000, 0x00805f9b34fb))
#define BT_UUID_TEMPERATURE_MEASUREMENT_CHARACTER \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x00002A1C, 0x0000, 0x1000, 0x8000, 0x00805f9b34fb))
#define BT_UUID_TEMPERATURE_MEASUREMENT_CCC \
BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x00002902, 0x0000, 0x1000, 0x8000, 0x00805f9b34fb))
static struct bt_conn *default_conn;
static struct bt_uuid_128 uuid = BT_UUID_INIT_128(0);
static struct bt_gatt_discover_params discover_params;
static struct bt_gatt_subscribe_params subscribe_params;
static uint8_t notify_func(struct bt_conn *conn,
struct bt_gatt_subscribe_params *params,
const void *data, uint16_t length)
{
printk("Temperature notify\n");
// if (!data) {
// printk("[UNSUBSCRIBED]\n");
// params->value_handle = 0U;
// return BT_GATT_ITER_STOP;
// }
uint8_t *d = (uint8_t *)data;
for (int i =0; i < length; i++){
printk("%2x ", d[i]);
}
printk("\n");
return BT_GATT_ITER_CONTINUE;
}
static uint8_t discover_func(struct bt_conn *conn,
const struct bt_gatt_attr *attr,
struct bt_gatt_discover_params *params){
int err;
printk("Discovering...\n");
printk("attr: %u\n", (unsigned int)attr);
if (!attr)
{
printk("Discover complete\n");
(void)memset(params, 0, sizeof(*params));
return BT_GATT_ITER_STOP;
}
printk("[ATTRIBUTE] handle %u\n", attr->handle);
if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_TEMPERATURE_ALERT_SERVICE))
{
memcpy(&uuid, BT_UUID_TEMPERATURE_ALERT_CHARACTER, sizeof(uuid));
discover_params.uuid = &uuid.uuid;
discover_params.start_handle = attr->handle + 1;
discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
err = bt_gatt_discover(conn, &discover_params);
if (err)
{
printk("Discover failed (err %d)\n", err);
}
}
else if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_TEMPERATURE_ALERT_CHARACTER))
{
memcpy(&uuid, BT_UUID_TEMPERATURE_ALERT_CCC, sizeof(uuid));
discover_params.uuid = &uuid.uuid;
discover_params.start_handle = attr->handle + 2;
discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
subscribe_params.value_handle = bt_gatt_attr_value_handle(attr);
err = bt_gatt_discover(conn, &discover_params);
if (err)
{
printk("Discover failed (err %d)\n", err);
}
}
else
{
subscribe_params.notify = notify_func;
subscribe_params.value = BT_GATT_CCC_INDICATE;
subscribe_params.ccc_handle = attr->handle;
err = bt_gatt_subscribe(conn, &subscribe_params);
if (err && err != -EALREADY)
{
printk("Subscribe failed (err %d)\n", err);
}
else
{
printk("[SUBSCRIBED]\n");
//ble_spo2_conn_sucess = true;
//blow_buzzer();
//k_msleep(500);
}
return BT_GATT_ITER_STOP;
}
return BT_GATT_ITER_STOP;
}
static uint8_t discover_func_HTS(struct bt_conn *conn,
const struct bt_gatt_attr *attr,
struct bt_gatt_discover_params *params)
{
int err;
printk("Discovering...\n");
if (!attr)
{
printk("Discover complete\n");
(void)memset(params, 0, sizeof(*params));
return BT_GATT_ITER_CONTINUE;
}
printk("[ATTRIBUTE] handle %u\n", attr->handle);
if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_TEMPERATURE_MEASUREMENT_SERVICE))
{
memcpy(&uuid, BT_UUID_TEMPERATURE_MEASUREMENT_CHARACTER, sizeof(uuid));
discover_params.uuid = &uuid.uuid;
discover_params.start_handle = attr->handle + 1;
discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
err = bt_gatt_discover(conn, &discover_params);
if (err)
{
printk("Discover failed (err %d)\n", err);
}
}
else if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_TEMPERATURE_MEASUREMENT_CHARACTER))
{
memcpy(&uuid, BT_UUID_TEMPERATURE_MEASUREMENT_CCC, sizeof(uuid));
discover_params.uuid = &uuid.uuid;
discover_params.start_handle = attr->handle + 2;
discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
subscribe_params.value_handle = bt_gatt_attr_value_handle(attr);
err = bt_gatt_discover(conn, &discover_params);
if (err)
{
printk("Discover failed (err %d)\n", err);
}
}
else
{
subscribe_params.notify = notify_func;
subscribe_params.value = BT_GATT_CCC_INDICATE;
subscribe_params.ccc_handle = attr->handle;
err = bt_gatt_subscribe(conn, &subscribe_params);
if (err && err != -EALREADY)
{
printk("Subscribe failed (err %d)\n", err);
}
else
{
printk("[SUBSCRIBED]\n");
}
return BT_GATT_ITER_STOP;
}
return BT_GATT_ITER_STOP;
}
// static bool eir_found(struct bt_data *data, void *user_data)
// {
// bt_addr_le_t *addr = user_data;
// char name[NAME_LEN];
// uint8_t len;
// int err1;
// struct bt_le_conn_param *param_spo2;
// (void)memset(name, 0, sizeof(name));
// printk("[AD]: %u data_len %u\n", data->type, data->data_len);
// switch (data->type) {
// case BT_DATA_NAME_SHORTENED:
// case BT_DATA_NAME_COMPLETE:
// len = MIN(data->data_len, NAME_LEN - 1);
// (void)memcpy(name, data->data, len);
// name[len] = '\0';
// if((memcmp(SPO2_NAME,name,sizeof(SPO2_NAME)))==0){
// err1 = bt_le_scan_stop();
// if (err1) {
// printk("Stop LE scan failed (err %d)\n", err1);
// }
// param_spo2 = BT_LE_CONN_PARAM_DEFAULT;
// err1 = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
// param_spo2, &default_conn);
// if (err1) {
// printk("Create conn failed (err %d)\n", err1);
// start_scan();
// }
// return false;
// }
// default: return true;
// }
// return true;
// }
static bool eir_found(struct bt_data *data, void *user_data)
{
bt_addr_le_t *addr = user_data;
int i;
printk("[AD]: %u data_len %u\n", data->type, data->data_len);
switch (data->type) {
case BT_DATA_UUID16_SOME:
case BT_DATA_UUID16_ALL:
if (data->data_len % sizeof(uint16_t) != 0U) {
printk("AD malformed\n");
return true;
}
for (i = 0; i < data->data_len; i += sizeof(uint16_t)) {
struct bt_uuid *uuid;
uint16_t u16;
int err;
memcpy(&u16, &data->data[i], sizeof(u16));
uuid = BT_UUID_DECLARE_16(sys_le16_to_cpu(u16));
if (bt_uuid_cmp(uuid, BT_UUID_HTS)) {
continue;
}
err = bt_le_scan_stop();
if (err) {
printk("Stop LE scan failed (err %d)\n", err);
continue;
}
err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
BT_LE_CONN_PARAM_DEFAULT,
&default_conn);
if (err) {
printk("Create connection failed (err %d)\n",
err);
scan_start();
}
return false;
}
}
return true;
}
static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,
struct net_buf_simple *ad)
{
char dev[BT_ADDR_LE_STR_LEN];
int err;
if(bt_addr_le_cmp(BT_TEMPERATURE_ADDR_LE_ANY,addr) == 0){
bt_addr_le_to_str(addr, dev, sizeof(dev));
printk("\n");
printk("[DEVICE]: %s, AD evt type %u, AD data len %u, RSSI %i\n",
dev, type, ad->len, rssi);
/* We're only interested in connectable events */
// if (type == BT_GAP_ADV_TYPE_ADV_IND ||
// type == BT_GAP_ADV_TYPE_ADV_DIRECT_IND) {
// bt_data_parse(ad, eir_found, (void *)addr);
// }
err = bt_le_scan_stop();
if (err) {
printk("Stop LE scan failed (err %d)\n", err);
}
err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
BT_LE_CONN_PARAM_DEFAULT,
&default_conn);
if (err) {
printk("Create connection failed (err %d)\n",
err);
start_scan();
}
}else{
//printk("CMP failed\n");
}
}
static void start_scan(void)
{
int err;
/* Use active scanning and disable duplicate filtering to handle any
* devices that might update their advertising data at runtime. */
struct bt_le_scan_param scan_param = {
.type = BT_LE_SCAN_TYPE_ACTIVE,
.options = BT_LE_SCAN_OPT_NONE,
.interval = BT_GAP_SCAN_FAST_INTERVAL,
.window = BT_GAP_SCAN_FAST_WINDOW,
};
err = bt_le_scan_start(&scan_param, device_found);
if (err)
{
printk("Scanning failed| Unable to load scan parameters\n");
return;
}
printk("Scanning Start Sucessfull\n");
}
static void connected(struct bt_conn *conn, uint8_t conn_err)
{
int err;
char addr[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
if (conn_err) {
printk("Failed to connect to %s (%u)\n", addr, conn_err);
bt_conn_unref(default_conn);
default_conn = NULL;
start_scan();
return;
}
printk("Connected: %s\n",addr);
if (conn == default_conn)
{
memcpy(&uuid, BT_UUID_TEMPERATURE_ALERT_SERVICE , sizeof(uuid));
discover_params.uuid = &uuid.uuid;
discover_params.func = discover_func;
discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
discover_params.type = BT_GATT_DISCOVER_PRIMARY;
err = bt_gatt_discover(default_conn, &discover_params);
if (err) {
printk("Discover failed(err %d)\n", err);
return;
}
}
}
static void disconnected(struct bt_conn *conn, uint8_t reason)
{
char addr[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
printk("Disconnected: %s (reason 0x%02x)\n", addr, reason);
if (default_conn != conn) {
return;
}
bt_conn_unref(default_conn);
default_conn = NULL;
start_scan();
}
BT_CONN_CB_DEFINE(conn_callbacks) = {
.connected = connected,
.disconnected = disconnected,
};
void main(void)
{
int err;
err = bt_enable(NULL);
if (err) {
printk("Bluetooth init failed (err %d)\n", err);
return;
}
printk("Bluetooth initialized\n");
start_scan();
}
#endif
*** Booting Zephyr OS build v3.1.99-ncs1-1 ***
init main
[Bluetooth initialized
Scanning successfully started
00:00:00.005,493] <inf> sdc_hci_driver: SoftDevice Controller build revision:
29 5c 92 f1 36 81 92 d1 b7 a9 f0 f1 99 e9 4c 19 |)\..6... ......L.
1f 23 83 4a |.#.J
[00:00:00.008,911] <inf> bt_hci_core: HW Platform: Nordic Semiconductor (0x0002)
[00:00:00.008,941] <inf> bt_hci_core: HW Variant: nRF52x (0x0002)
[00:00:00.008,972] <inf> bt_hci_core: Firmware: Standard Bluetooth controller (0x00) Version 41.37468 Build 2457941745
[00:00:00.010,314] <inf> bt_hci_core: Identity: F0:CF:29:9D:9B:96 (random)
[00:00:00.010,314] <inf> bt_hci_core: HCI: version 5.3 (0x0c) revision 0x11d8, manufacturer 0x0059
[00:00:00.010,345] <inf> bt_hci_core: LMP: version 5.3 (0x0c) subver 0x11d8
[DEVICE]: E4:38:55:AE:4D:EE (random), AD evt type 0, AD data len 26, RSSI -55
[AD]: 25 data_len 2
[AD]: 1 data_len 1
[AD]: 3 data_len 6
Connected: E4:38:55:AE:4D:EE (random)
Battery [ATTRIBUTE] handle 13
Battery characteristics [SUBSCRIBED]
temperature [ATTRIBUTE] handle 38
Battery notify
temperature [ATTRIBUTE] handle 39
temperature [ATTRIBUTE] handle 41
temperature measurement [SUBSCRIBED]
Temperature notify
position [ATTRIBUTE] handle 42
position [ATTRIBUTE] handle 43
position [ATTRIBUTE] handle 45
position characteristics [SUBSCRIBED]
Position notify
alert [ATTRIBUTE] handle 9
alert [ATTRIBUTE] handle 10
alert [ATTRIBUTE] handle 12
Alert characteristics [SUBSCRIBED]
Alert notify
fev alert [ATTRIBUTE] handle 17
fev alert [ATTRIBUTE] handle 18
bt write start
Write sucess
fev alert [ATTRIBUTE] handle 20
CTS [ATTRIBUTE] handle 20
CTS [ATTRIBUTE] handle 21
before write CTS
length a
e6 7 c 1d c 1 0 1 0 0
after Write CTS sucess
length a
e6 7 c 1d c 1 0 1 0 0
Disconnected
Disconnected
Disconnected
Disconnected
Disconnected
Disconnected
Connected via Serial Port with settings /dev/ttyACM0 115200 8n1 rtscts:off
temperature [ATTRIBUTE] handle 38
Battery notify
temperature [ATTRIBUTE] handle 39
temperature [ATTRIBUTE] handle 41
temperature measurement [SUBSCRIBED]
Temperature notify
position [ATTRIBUTE] handle 42
position [ATTRIBUTE] handle 43
position [ATTRIBUTE] handle 45
position characteristics [SUBSCRIBED]
Position notify
alert [ATTRIBUTE] handle 9
alert [ATTRIBUTE] handle 10
alert [ATTRIBUTE] handle 12
Alert characteristics [SUBSCRIBED]
Alert notify
fev alert [ATTRIBUTE] handle 17
fev alert [ATTRIBUTE] handle 18
bt write start
Write sucess
fev alert [ATTRIBUTE] handle 20
CTS [ATTRIBUTE] handle 20
CTS [ATTRIBUTE] handle 21
before write CTS
length a
e6 7 c 1f 7 d 21 1 0 0
after Write CTS sucess
length a
e6 7 c 1d c 1 0 1 0 0
*** Booting Zephyr OS build v3.1.99-ncs1-1 ***
init main
[Bluetooth initialized
Scanning successfully started
00:00:00.005,462] <inf> sdc_hci_driver: SoftDevice Controller build revision:
29 5c 92 f1 36 81 92 d1 b7 a9 f0 f1 99 e9 4c 19 |)\..6... ......L.
1f 23 83 4a |.#.J
[00:00:00.008,850] <inf> bt_hci_core: HW Platform: Nordic Semiconductor (0x0002)
[00:00:00.008,911] <inf> bt_hci_core: HW Variant: nRF52x (0x0002)
[00:00:00.008,911] <inf> bt_hci_core: Firmware: Standard Bluetooth controller (0x00) Version 41.37468 Build 2457941745
[00:00:00.010,253] <inf> bt_hci_core: Identity: F0:CF:29:9D:9B:96 (random)
[00:00:00.010,284] <inf> bt_hci_core: HCI: version 5.3 (0x0c) revision 0x11d8, manufacturer 0x0059
[00:00:00.010,314] <inf> bt_hci_core: LMP: version 5.3 (0x0c) subver 0x11d8
[DEVICE]: E4:38:55:AE:4D:EE (random), AD evt type 0, AD data len 26, RSSI -49
[AD]: 25 data_len 2
[AD]: 1 data_len 1
[AD]: 3 data_len 6
Connected: E4:38:55:AE:4D:EE (random)
Battery [ATTRIBUTE] handle 13
Battery characteristics [SUBSCRIBED]
temperature [ATTRIBUTE] handle 38
Battery notify
temperature [ATTRIBUTE] handle 39
temperature [ATTRIBUTE] handle 41
temperature measurement [SUBSCRIBED]
Temperature notify
position [ATTRIBUTE] handle 42
position [ATTRIBUTE] handle 43
position [ATTRIBUTE] handle 45
position characteristics [SUBSCRIBED]
Position notify
alert [ATTRIBUTE] handle 9
alert [ATTRIBUTE] handle 10
alert [ATTRIBUTE] handle 12
Alert characteristics [SUBSCRIBED]
Alert notify
fev alert [ATTRIBUTE] handle 17
fev alert [ATTRIBUTE] handle 18
bt write start
Write sucess
fev alert [ATTRIBUTE] handle 20
CTS [ATTRIBUTE] handle 20
CTS [ATTRIBUTE] handle 21
before write CTS
length a
e6 7 c 1d c 1 0 1 0 0
after Write CTS sucess
length a
e6 7 c 1d c 1 0 1 0 0
