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

Service Changed Characteristic not enabled on iOS

Hi,

My current project make use of pairing/bonding and at certain times I change the attribute table. To notify the central device about this change I have added the Service Changed Characteristic. It works good on Android after enabling notifications from the characteristic. However on iOS I cannot see the Service Changed Characteristic (iOS filter these out according to their guidelines), and I always receive error: NRF_ERROR_INVALID_STATE when I try to send I notification to an iOS device. I  seems like iOS is not enabling notifications on the Service Changed characteristic.

Is there something more to be done in order to make iOS enable notification for the Service Changed Characteristic?

I send the notification from the BLE_GAP_EVT_CONN_SEC_UPDATE event:

Edit:

After pairing I can send a Service Changed Notification. When the device eventually get disconnected after pairing/bonding I reconnect and after that the nRF52832 can no longer send Service Changed Notifications (NRF_ERROR_INVALID_STATE). Do I need to restore the CCCDs or what is happening here?

Parents
  • Hi,

    I think I have found the issue. After pairing/bonding another CPU resets the nRF52832, but before that happens I can see that the application can send one notification. When the nRF52832 boots up again and I reconnect I receive error NRF_ERROR_INVALID_STATE. It seems like the CCCDs are not saved on Central side it seems like.

  • Further investigation shows that it happens regardless of reset or not.

    I pair / bond using my iPhone 6s running iOS 12.4, after pairing/bonding is complete my application running on the nRF52832 sends one notification successfully. Then the iPhone gets disconnected regardless, when I reconnect I receive NRF_ERROR_INVALID_STATE when trying to send Service Changed notifications

  • You may get INVALID_STATE if you try to issue a SC indication while there is an ongoing MTU exchange. Could this maybe explain why it's not sent in your case? You can try to send the indication at a later time and see if you still get the error to confirm this. 

    My iPhone 7 w iOS 12.4 enables SC indication after the bond is established. 

    Edit: this thread may be relevant as well: https://devzone.nordicsemi.com/f/nordic-q-a/46633/peer-manager-silently-drop-service-changed-indications-if-an-att-mtu-exchange-was-happening/204968#204968. You can use the PM API to manage SC indications to bonded peers.  

  • Hi Vidar,

    It seems like that the case, I moved the call sd_ble_gatts_service_changed from the event BLE_GAP_EVT_CONN_SEC_UPDATE to BLE_GAP_EVT_CONN_PARAM_UPDATE which comes after roughly 20 seconds after connection. Then it works without issues.

    Any advice how to handle this? Putting the call in BLE_GAP_EVT_CONN_PARAM_UPDATE seems abit strange.

    Edit:

    You can use the PM API to manage SC indications to bonded peers.

    When you say PM API to manage SC indications, do you mean pm_local_database_has_changed()?

    Also I'm using SDK v15.0

  • AntonHellbe said:
    When you say PM API to manage SC indications, do you mean pm_local_database_has_changed()?

    Yes, that's what I meant. But you need to fix the implementation as I proposed in the other thread to ensure SC indications aren't dropped. Are you on an older SDK version? 

Reply
  • AntonHellbe said:
    When you say PM API to manage SC indications, do you mean pm_local_database_has_changed()?

    Yes, that's what I meant. But you need to fix the implementation as I proposed in the other thread to ensure SC indications aren't dropped. Are you on an older SDK version? 

Children
  • Yes SDK V15.0, is the fix you suggested in the other question valid for SDK v15.0?

    I have checked and service_changed_cccd function does not exist in SDK v15.0

  • I think the changes shown in the *.diff file from my last comment will be valid for v15.0.0 as well. But haven't verified it here.  

  • Hi Vidar,

    I checked the source files for SDK v15.0 (gatt_cache_manager.c) and I cannot find the function service_changed_cccd function that you mention in the other thread.

  • That is correct, the function was added in SDK 15.3.0 and is used to check whether the SC indication is enabled or if it even exists. You need to add this function in the NRF_ERROR_INVALID_STATE case to determine if is "invalid state" because of an ongoing MTU exchange or simply because the indication is not enabled.

  • I see, I was a bit unsure about that part. Thanks for clarifying!