Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

Attempting to print out device name data with "device_found()" in "central_hrs"

Hi,

I am trying to modify the Zephyr central_hrs module so that it will print out the name of any peripheral it discovers and eventually store them in some 2D array. The problem is that I can't get it to work properly. I found this post:  How to read advertising BLE devices' name? which does let you print out device names. The issue is that they are using the generic "central" example and bt_data_parse() eats the pointer to the advertisement data you give it so it can't be reused. In "central_hr" you already have an essential call to bt_data_parse() in order to establish a connection. The obvious solution to this is to create "struct net_buf_simple ad_temp" and copy the advertisement data structure into it but all attempts to do so have failed. Everything I have tried has either given me a memory fault or or just given me garbled characters. I also tried modifying the existing bt_data_parse() callback function in "central_hr" but to little success. I don't know if this is more a zephyr or a straight up C fundamentals question but any help copying the advertisement data into a temporary net_buf_simple struct would be greatly appreciated. I will post the relevant code I have below: 

This is the central_code. In this state it the code seems to memory fault and I am not sure why:

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 Actual Data: %u\n", data->type, data->data_len, data->data);

    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_le_conn_param *param;
            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_HRS)) {
                continue;
            }

            err = bt_le_scan_stop();
            if (err) {
                printk("Stop LE scan failed (err %d)\n", err);
                continue;
            }

            param = BT_LE_CONN_PARAM_DEFAULT;
            err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
                        param, &default_conn);
            if (err) {
                printk("Create conn failed (err %d)\n", err);
                start_scan();
            }

            return false;
        }
    }

    return true;
}

static bool data_cb2(struct bt_data *data, void *user_data){

    char *name = user_data;

    switch(data->type){
        case BT_DATA_NAME_SHORTENED:
        case BT_DATA_NAME_COMPLETE:
            memcpy(name, data->data, MIN(data->data_len, NAME_LEN - 1));
            return false;
        default:
            return false;
    }
}

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];
    char name[30];
    struct net_buf_simple ad_temp;
   
    memcpy(&ad_temp, ad->data, net_buf_simple_max_len(ad->len));

    bt_addr_le_to_str(&addr, dev, sizeof(dev));

    bt_data_parse(&ad_temp, data_cb2, name);
    printk("Device found: %s \n", *name);

    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);
    }
}

And then here is the relevant stuff on the peripheral code:

static const struct bt_data ad[] = {
    BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
    BT_DATA_BYTES(BT_DATA_UUID16_ALL,
              BT_UUID_16_ENCODE(BT_UUID_HRS_VAL),
              BT_UUID_16_ENCODE(BT_UUID_BAS_VAL),
              BT_UUID_16_ENCODE(BT_UUID_DIS_VAL))
};
static void bt_ready(void)
{
    int err;

    printk("Bluetooth initialized\n");

    err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0);
    if (err) {
        printk("Advertising failed to start (err %d)\n", err);
        return;
    }

    printk("Advertising successfully started\n");
}
Parents Reply Children
No Data
Related