Custom BLE Client with 128BIT UUID

Hello,

I've needed recently to relay some results from my 52840 peripherals to the 7002dk which has the 5340 on it. I've managed to get the Central HR and Peripheral HR examples to work flawlessly however I'd like to send my custom data and respective characteristics now. I've tried variations of the below code but unfortunately no progress has been made.

Firstly, the declarations and includes: Note my UUIDs match the peripherals being tested, I've double checked this. 

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#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);
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;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Next is the discover function which I believe has no issues, it's just the same central hr sample with the service UUID and characteristic UUID swapped out for my own peripherals.

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
static uint8_t notify_func(struct bt_conn *conn,
struct bt_gatt_subscribe_params *params,
const void *data, uint16_t length)
{
if (!data)
{
printk("[UNSUBSCRIBED]\n");
params->value_handle = 0U;
return BT_GATT_ITER_STOP;
}
printk("[NOTIFICATION] data %p length %u\n", data, length);
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;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Now to the section where I think the issue really is, the eir_found callback function.

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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_UUID128_SOME:
case BT_DATA_UUID128_ALL:
if (data->data_len % 16 != 0U)
{
printk("AD malformed\n");
return true;
}
for (i = 0; i < data->data_len; i += 16)
{
struct bt_le_conn_param *param;
struct bt_uuid *uuid;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

The remaining code seems fine, I only needed to change the service UUID.

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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];
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_GAP_ADV_TYPE_ADV_IND ||
type == BT_GAP_ADV_TYPE_ADV_DIRECT_IND)
{
bt_data_parse(ad, eir_found, (void *)addr);
}
}
static void start_scan(void)
{
int err;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

I have looked around but a lot of the questions pertaining to clients seem to be utilizing the old sdk not zephyr. There was one post about this but it was more about discovery rather than connecting but I'm happy to take a look at it again if I've missed something.

Any help is appreciated.

Edit - Posted code for notification, still wont work as intended.

Regards

Doug

Parents
  • Hello Doug,

    I think it's easier to use our Scanning module with filter matching, same as we do in the central uart sample here: https://github.com/nrfconnect/sdk-nrf/blob/main/samples/bluetooth/central_uart/src/main.c#L502 

    Now to the section where I think the issue really is, the eir_found callback function.

    I guess it fails because it does not find a matching UUID? I would suggest to print the UUIDs parsed from the adv. packets to see if the expected UUID is found our not. 

    Regards,

    Vidar

  • Hello Vidar,

    After a long slog I finally have it connecting and discovering the service as well as the characteristic. The notification however won't come through, I've tried the peripheral on another device (iPad as client) and it works seamlessly. 

    I note that when I disconnect the peripheral, turn off the power, finally my notify_func gets called albeit its null.

    Any thoughts at all would be appreciated greatly.

    I've attached the relevant code based on your input to use the scanning module.

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    static struct bt_conn *default_conn;
    static uint8_t notify_func(struct bt_conn *conn,
    struct bt_gatt_subscribe_params *params,
    const void *data, uint16_t length)
    {
    printk("Notification: data %p length %u\n", data, length);
    return BT_GATT_ITER_CONTINUE;
    }
    static void discovery_complete(struct bt_gatt_dm *dm,
    void *context)
    {
    printk("Service discovery completed\n");
    bt_gatt_dm_data_print(dm);
    const struct bt_gatt_dm_attr *gatt_service_attr = bt_gatt_dm_service_get(dm);
    const struct bt_gatt_service_val *gatt_service = bt_gatt_dm_attr_service_val(gatt_service_attr);
    char uuid_str[37];
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Regards,

    DM

Reply
  • Hello Vidar,

    After a long slog I finally have it connecting and discovering the service as well as the characteristic. The notification however won't come through, I've tried the peripheral on another device (iPad as client) and it works seamlessly. 

    I note that when I disconnect the peripheral, turn off the power, finally my notify_func gets called albeit its null.

    Any thoughts at all would be appreciated greatly.

    I've attached the relevant code based on your input to use the scanning module.

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    static struct bt_conn *default_conn;
    static uint8_t notify_func(struct bt_conn *conn,
    struct bt_gatt_subscribe_params *params,
    const void *data, uint16_t length)
    {
    printk("Notification: data %p length %u\n", data, length);
    return BT_GATT_ITER_CONTINUE;
    }
    static void discovery_complete(struct bt_gatt_dm *dm,
    void *context)
    {
    printk("Service discovery completed\n");
    bt_gatt_dm_data_print(dm);
    const struct bt_gatt_dm_attr *gatt_service_attr = bt_gatt_dm_service_get(dm);
    const struct bt_gatt_service_val *gatt_service = bt_gatt_dm_attr_service_val(gatt_service_attr);
    char uuid_str[37];
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Regards,

    DM

Children