5 years, 10 months ago.

Cannot get neither onDataRead() nor setReadAuthorizationCallback() to work with nrf52832

I need a callback function to execute when a data read is performed from the Client via nrf Connect on Android. I have tried two methods:

1. using the onDataRead() function in a manner similar to onDataWritten(). The function onDataWritten() works fine. I have attempted to set a callback function for onDataRead with: ble.gattServer().onDataRead(onDataRead) in the bleInitComplete function:

include the mbed library with this snippet

#include "mbed.h"

void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
{

    ble.gattServer().onDataRead(onDataRead);

....

The callback looks like:

include the mbed library with this snippet

#include "mbed.h"

void onDataRead(const GattReadCallbackParams *params) {
    if (params->handle == BLEServicePtr->readBatteryLevelCharacteristicHandle())
    {
    	BLEServicePtr->updateBatteryLevel(0x08);

    }
    BLEServicePtr->updateBatteryLevel(0x08);
    printf("onDataRead works \r\n");
}

The callback is never called.

2. I have attemped using the setReadAuthorizationCallback(). The first item is in the initializer of my service class and the second in the .cpp:

include the mbed library with this snippet

#include "mbed.h"

readBatteryLevelCharacteristic.setReadAuthorizationCallback(this, &BleService::onDataRead_2);

void BleService::onDataRead_2(GattReadAuthCallbackParams* event)
{
	BLEServicePtr->updateBatteryLevel(0x08);


}

I am working with mbed 5.9.1 in Eclipse on an nrf52832. Any insight into the use of the onDataRead and/or setReadAuthorizationCallback functions would be appreciated.

Thank you

Did you find a solution? I am getting stuck at the same problem. PUSH

posted by Wenzel Reichmuth 25 Jan 2019

2 Answers

5 years, 2 months ago.

I've got setReadAuthorizationCallback() to work with nrf52. You have to set it before adding the Characteristic to GattService.

5 years, 2 months ago.

I am also trying to figure out why this feature is not working. Here is what I've discovered so far. Here is an implementation of onDataRead() in the GattServer.h file in mbed-os:

OnDataRead

  /**
     * Set an event handler that monitors attribute reads from connected clients.
     *
     * @param[in] objPtr Pointer to the instance that is used to invoke the
     * event handler (@p memberPtr).
     * @param[in] memberPtr Event handler being registered. It is a member
     * function.
     */
    template <typename T>
    ble_error_t onDataRead(
        T *objPtr,
        void (T::*memberPtr)(const GattReadCallbackParams *context)
    ) {
        if (!isOnDataReadAvailable()) {
            return BLE_ERROR_NOT_IMPLEMENTED;
        }

        dataReadCallChain.add(objPtr, memberPtr);
        return BLE_ERROR_NONE;
    }

but the problem is that the function inOnDataReadAvailable() is set to false unless it is over ridden somewhere. Still trying to figure out what to do from here.

isOnDataReadAvailable

    /**
     * Indicate if the underlying stack emit events when an attribute is read by
     * a client.
     *
     * @attention This function should be overridden to return true if
     * applicable.
     *
     * @return true if onDataRead is supported; false otherwise.
     */
    virtual bool isOnDataReadAvailable() const
    {
        /* Requesting action from porters: override this API if this capability
           is supported. */
        return false;
    }

Looks like the IsOnDataRead() needs to be overrided to return true somewhere.

Hi Peter,

What BLE stack are you using? I recommend using Cordio stack because it's the mainly supported BLE stack of Mbed OS. I believe Cordio has overriden isOnDataReadAvailable() so onDataRead() should be called correctly.

posted by Desmond Chen 22 Feb 2019