ble
ble copied to clipboard
add API to enable notifications
refer to https://developer.mbed.org/forum/team-63-Bluetooth-Low-Energy-community/topic/16517/?page=1#comment-38845
It could be that what's needed here is a simple API like: DiscoveredCharacteristic::enableNotification(), but then that would allow manipulation of only the CCCD. There may be other writable descriptors, which would then require a more generic API.
There's an API meant to discover descriptors for a Characteristic. https://github.com/mbedmicro/BLE_API/blob/master/ble/DiscoveredCharacteristic.h#L117 Unfortunately, we haven't implemented this for the nRF51 yet. The default implementation remains in effect: https://github.com/mbedmicro/BLE_API/blob/master/source/DiscoveredCharacteristic.cpp#L63
My thinking is that launching descriptor discovery should result in callbacks passing the DiscoveredDescriptors (which is a datatype which needs to be added to BLE_API). I'm not sure how best to handle the discovered descriptors following the callback. Perhaps they should be contained within the owning characteristic, or perhaps the user would issue reads/writes directly upon the discovered descriptors.
It would be lovely if the community comes together and proposes a solution (or even a pull request).
Just for the record I have been using this extension to DiscoveredCharacteristics, which is very similar to your proposed DiscoveredCharacteristic::enableNotification():
ble_error_t
DiscoveredCharacteristic::requestHVX(HVXType_t type) const
{
if (!props.write()) {
return BLE_ERROR_OPERATION_NOT_PERMITTED;
}
if (!props.notify()) {
return BLE_ERROR_OPERATION_NOT_PERMITTED;
}
if (!gattc) {
return BLE_ERROR_INVALID_STATE;
}
/* Cargo Culted from: https://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_ButtonSense/file/2dec89c76f68/main.cpp */
/* HACK. We're assuming that CCCD descriptor immediately follows the value attribute. */
/* TODO actually discover the handle for the CCCD descriptor */
uint16_t value = (uint16_t)type;
return gattc->write(GattClient::GATT_OP_WRITE_REQ, connHandle, valueHandle + 1, sizeof(value), (const uint8_t*)(&value));
}
I know it doesn't solve the real problem of descriptor discovery, but it does hide away the hack to somewhere that they can be worked on without effecting user code.
And, of course, having posted that I see that the second test in not correct for indications, that have their own property. But you get the idea.
Update, this is what I'm currently using:
DiscoveredCharacteristic::requestHVX(HVXType_t type) const
{
if (type == BLE_HVX_NOTIFICATION && !props.notify()) {
return BLE_ERROR_OPERATION_NOT_PERMITTED;
}
if (type == BLE_HVX_INDICATION && !props.indicate()) {
return BLE_ERROR_OPERATION_NOT_PERMITTED;
}
if (!gattc) {
return BLE_ERROR_INVALID_STATE;
}
/* Cargo Culted from: https://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_ButtonSense/file/2dec89c76f68/main.cpp */
/* HACK. We're assuming that CCCD descriptor immediately follows the value attribute. */
/* TODO actually discover the handle for the CCCD descriptor */
uint16_t value = (uint16_t)type;
return gattc->write(GattClient::GATT_OP_WRITE_REQ, connHandle, valueHandle + 1, sizeof(value), (const uint8_t*)(&value));
}
ARM Internal Ref: IOTSFW-1033