This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Reading a subset of data on a BLE server

I am definitely missing something here, but I can't figure out how to specify a subset of data to read from my peripheral.

Here's the setup: my nrf51822 device is a server, publishing a custom service with custom characteristics.

I have in memory is the nrf51822 a long (2048 bytes) list of historical data.

I want to allow a client to be able to read a specific portion of this data rather than having to transfer all 2048 bytes (which I can't anyway).

The SoftDevice handles characteristic reads automatically, but even if I could intercept them I don't see how I can pass parameters to a characteristic read operation.

What is the official BLE way to do what I'm trying to do?

  • Hi there,

    I want to allow a client to be able to read a specific portion of this data rather than having to transfer all 2048 bytes (which I can't anyway).

    There is no "official" way to read buffers from a server that are longer than 512 bytes (the maximum length of a characteristic value).

    You have several options to achieve that:

    1. Create 4x characteristics (since each characteristic can only be 512 bytes long) and use VLOC_USER to make each of those point to a quarter of your historical data. Then the client can use read long operations on all those characteristics to obtain the data

    2. Create a single characteristic, and mark it rd_auth = 1. Then every time your client asks for data you are free to provide the data you want with sd_ble_gatts_rw_auth_reply()

    Carles

  • I want this to support arbitrary lengths, so option 1 doesn't really scale well.

    I'm not sure what rd_auth does for me.

    I'm thinking what I'll do is have a separate characteristic that lets me set up the value for the next read, kind of like writing to a read pointer.

    I would still like to get notified after the read happens, so I can increment the pointer and set up the next read. Is there a way to register for read notifications?

  • I'd say that the "Bluetooth way" of doing this is using a Control Point characteristic to which the Client writes which data period or interval it's interested in, and then letting the Server send the actual data as either Notifications or Indications on a Data characteristic.

    This scheme is implemented by for example the Glucose Profile and Service, so its profile document could be a useful place to start. The profile document is here, and the service document here.

  • I'll take a look.

    In the meantime, is there a way to get an event when the server gets a read from a client?

  • In the meantime, is there a way to get an event when the server gets a read from a client?

    What you are looking for is called "Read Authorization".

    The attached MSC should help you out.

    To create a characteristic with read authorization set the following bit:

    ble_gatts_attr_md_t :: rd_auth

    when calling:

    sd_ble_gatts_characteristic_add()

    So, combining rd_auth on your side with usage of Read Long Characteristic Values (aka Read Blob) you could simply do this:

    <- Read_Blob_Req(offset = 0) -> Read_Blob_Resp(first 20 bytes of data) <- Read_Blob_req(offset = 20) -> Read_Blob_Resp(bytes 20 to 40) ...

    msc_inline_mscgraph_29.png

Related