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

Sending data before pairing

I have a timer that sends BLE data to a central every 5 seconds. The timers starts immediately out of reset. Until I actually pair the devices, the nRF51822 outputs an error message NRF_ERROR_INVALID_STATE when it tries to send the data. I understand that it is because I'm trying to send data before the two are paired, but how do I test if that pairing has been done?

  • I should have been more clear. I am using Master Control Panel. When I click on "Service Discovery" this generates the BLE_GAP_EVT_CONNECTED event. That is where I currently start my timers to send data to MCP. Then I get the NRF_ERROR_INVALID_STATE error for each characteristic that I send. Once I click "Enable Services" in MCP, those messages stop. I put a break point in the on_ble_evt(ble_evt_t * p_ble_evt) function. Clicking "Enable Services" seems to create a BLE_GATTS_EVT_WRITE event. This is a very generic write event.

    What I want to do is not try sending data until services are enabled so the NRF_ERROR_INVALID_STATE is not generated. How do I do this? Is this error a non-issue? Is there an event that I should be checking for that I am missing?

  • Hi there,

    What are you using to send the data?

    If it's sd_ble_gatts_hvx() then you'll have to wait until the remote peer has written into the corresponding CCCD.

    Are you able to send once the BLE_GATTS_EVT_WRITE comes?

    Carles

  • What are you using to send the data?

    sd_ble_gatts_hvx().

    If it's sd_ble_gatts_hvx() then you'll have to wait until the remote peer has written into the corresponding CCCD.

    Can you elaborate on how to do this?

    Are you able to send once the BLE_GATTS_EVT_WRITE comes?

    Yes. The errors stop and data is sent successfully.

  • Hi there,

    You can use the Quotes widget on the top bar to quote.

    sd_ble_gatts_hvx().

    If it's sd_ble_gatts_hvx() then you'll have to wait until the remote peer has written into the corresponding CCCD.

    Can you elaborate on how to do this?

    It depends on whether you are using the bond manager or not. If you are not, then you will have to wait for a BLE_GATTS_EVT_WRITE writing to the CCCD (Client Characteristic Configuration Descriptor) that is included in the characteristic you want to notify or indicate. You can detect whether a BLE_GATTS_EVT_WRITE targets a CCCD by looking at the attribute context inside the event. By using handles (if you have stored them during the population of the attribute table) or UUIDs you can find that out.

    This is how notifications and indications (sd_ble_gatts_hvx()) work:

    • Each characteristic that you want to notify and indicate contains a CCCD (Client Characteristic Configuration Descriptor). This descriptor is added automatically by the stack when you populate the characteristic using sd_ble_gatts_characteristic_add()

    • The GATT client (in this case the MCP) needs to enable notifications and/or indications by writing into that CCCD

    • The CCCD is reset every time you disconnect and reconnect, except if you are bonded with the device.

    • If you are bonded then it is your (or the bond manager's if you use it) responsibility to store the values of the different CCCDs and then restore them later when you reconnect to a bonded device. This is done through the sys_attr family of API calls

    So, if you are not going to bond to the remote device (in this case the MCP) you will have to wait every time for the MCP to "Enable Services" (that means writing to the all the CCCDs) before you can actually use sd_ble_gatts_hvx(). Before that you will get an INVALID_STATE error because you are not allowed to send notifications or indications before that CCCD is enabled.

    These MSCs are relevant to this discussion:

    devzone.nordicsemi.com/.../a00867.html

    devzone.nordicsemi.com/.../a00868.html

    devzone.nordicsemi.com/.../a00869.html

    Carles

Related