mynewt-nimble icon indicating copy to clipboard operation
mynewt-nimble copied to clipboard

`ble_gatts_clt_cfg_access(...)` odd return values casted from `BLE_HS_E...` to `BLE_ATT_ERR_...` on storage overflow

Open therealergo opened this issue 1 year ago • 1 comments

When the number of CCCD's exceeds BLE_STORE_MAX_CCCDS, ble_store_delete_cccd(...) and ble_store_write_cccd(...) will return error codes from the BLE_HS_E... range, such as BLE_HS_ENOENT, BLE_HS_ENOMEM, and BLE_HS_ENOTSUP (dependent on the code in store_status_cb).

When an attempt is made to write to the descriptor, these error codes are then directly returned from ble_gatts_clt_cfg_access(...). This causes them to be returned by the stack as the corresponding unrelated attribute errors. This causes strange unexpected attribute access errors such as BLE_ATT_ERR_INSUFFICIENT_AUTHEN, BLE_ATT_ERR_REQ_NOT_SUPPORTED, and BLE_ATT_ERR_INSUFFICIENT_AUTHOR when an overflow occurs.

These unexpected errors can cause some strange follow-up behavior: For example, returning BLE_ATT_ERR_INSUFFICIENT_AUTHEN when connected to an iOS device causes that iOS device to re-attempt pairing, regardless of whether the current connection is already bonded and encrypted.

ble_gatts_clt_cfg_access(...) should probably check for a non-zero return code and return e.g. BLE_ATT_ERR_INSUFFICIENT_RES in that case.

therealergo avatar Mar 15 '24 19:03 therealergo

Same type of casting problem with a descriptor write request returning BLE_ATT_ERR_INSUFFICIENT_AUTHEN when `BLE_STORE_MAX_CCCDS is set to 0. But in that case, not storing the descriptor is the desired outcome so returning error does not make sense to me.

The behavior of clients when receiving BLE_ATT_ERR_INSUFFICIENT_AUTHEN are very different. I have observed three kinds:

  • Some, as stated above, will reattempt pairing.
  • Some will silently retry to write the characteristic and the second time no error will be returned since the CCCD was not changed and does not need to be saved.
  • While others will stop working and refuse to read or write until disconnected and reconnected. My guess is that they do not expect to receive an insufficient authentication response when they are bonded, encrypted and authenticated.

oskla129 avatar Sep 05 '25 20:09 oskla129