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

nRFToobox on Android not recognizing changes in application type running on Nordic pcb

Today nRF Toolbox App on my Android 5.0 phone is only recognizing HRM code running on my nRF5182-mkit, not other examples.

  • Today nRFToobox and nRFUART2.0 Apps both report "The Device Does not have the required services" when I try anything other than HRM code yesterday and today.

  • Two days ago it was allowing me to easily switch between code on the mkit, but then something changed. It was about same time as the latest nRFToolbox update on playstore. Funnily enough it was just after the previous Nordic updates on playstore that this all started working, as two weeks ago it wasn't working with similar issue. Did a fix get undone?

  • nRF-MCP App is shows changes in Device Name when I run other sample code on my mkit (Thermometer, UART Loopback, HRM, etc.)

  • I tried wiping the cache in the Android 5.0 phone, no effect

  • I can capture with nRF-MCP or Sniffer if that will help (just tell me what you need, I'm not very familiar with either of those)

Any help appreciated! Paul

  • Possibly:

    • If not properly disconnect then App data in Android may be confused.
    • This may be a bug in latest nRF-MCP/nRF-ToolBox for Android (Released ~20141209?)

    Try:

    • Open nRF-MCP in Android, select device, connect, disconnect (Ensure disconnect happens)

    Note:

    • UART device doesn't seem to offer disconnect (nRF51 sample code may need tweak)
    • May need to load a 3rd sample, disconnect from that, then try new sample.

    Still testing. This method of using nRF-MCP to disconnect between sample type changes (HTM, HTM, UART) does appear to be working, consider it a "work around" for now.

  • Hi,

    There are 4 ways to clear the attribute cache on Android:

    1. Using Service Changed characteristic - the proper solution:

    a) when not bonded - android should never cache services if such characteristic is present in Generic Attribute service. However it always does - this is the Android bug, reported here: code.google.com/.../detail

    b) when bonded - a device may enable CCCD indications on Service Changed char. Whenever Android receives this indication it will perform service rediscovery automatically. When writing Android code make sure that you give ~2 sec after you get onConnectionStateChange(Connected) event before calling gatt.discoverServices() when you expect that the indication may be received. If you call it immediately, inside the onConnStateCh callback, you'll get old services as this callback is called immediately when you connect but before the bond has been re-established and the indication was sent.


    When you don't use bonding or you don't want to use Service Changed indications, or when you are flashing your board with different firmwares you may find useful this:

    1. Using Android hack - there is a hidden method refresh() on the Android API. It works since Android 4.3 but it may be removed in any new release. I'm calling it when you disconnect from the DFU in nRF Toolbox and whenever you disconnect from the device in MCP. In the upcomming version MCP 2.1 (release tomorrow(?)) there will be an option to change in MCP settings (connectivity): refresh always (after disconnection), refresh only when not bonded (also only after diconnnecting), refresh never (actually it will refresh when an error occur)

    2. Use different device address when services are different. When you design a firmware that has different modes with different services consider using different device address in every of them. In that case the cache will not be a problem.

    3. On older versions of Android (f.e. 4.3) restarting Bluetooth adapter was also clearing the cache. As we can observe now this no longer works which is OK (cache shouldn't be cleared unless services are changed). This no longer works.


    So.. if you want to use different firmware on the same device use the trick with the nRF MCP. As I've written before it refreshes the cache every time it disconnects from the device. If you check the log on DEBUG level you will see the gatt.refresh() method being called.

  • I have been able to reproduce this on Android 4.4.4, and did some investigating.

    This is actually a Android bug, not a nRF Toolbox/nRF Master Control Panel bug.

    On Android 4.3 the cache was cleared if you restarted Bluetooth, but this does not happen in 4.4 (and 5). I think this modification was on purpose.

    Attribute catching is explained in Vol 3, Part G, Section 2.5.2 in the Bluetooth Core Specification 4.2.

    If GATT based services on the server cannot be changed during the usable lifetime of the device, the Service Changed characteristic shall not exist on the server and the client does not need to ever perform service discovery after the initial service discovery for that server.

    This means that if the Service Changed characteristic doesn't exist, Android can cache the attributes.

    For clients that have a trusted relationship (i.e. bond) with the server, the attribute cache is valid across connections. For clients with a trusted relationship and not in a connection when a service change occurs, the server shall send an indication when the client reconnects to the server.

    This means that if the devices are bonded Android can cache the attributes.

    For clients that do not have a trusted relationship with the server, the attribute cache is valid only during the connection. Clients without a trusted relationship shall receive an indication when the service change occurs only during the current connection.

    This means that if the devices are not bonded, Android can cache the attributes, but they must be cleared between every connection. Android do not do this.

    When you disconnect from Master Control Panel the cache is manually cleared. But this is not done in nRF Toolbox.

    This should only be a problem in development because the DFU procedure also manually clears the cache.

    The workaround is to do a disconnect in Master Control Panel if you change apps.

    The service changed characteristic is included in the SDK examples by setting IS_SRVC_CHANGED_CHARACT_PRESENT to 1.

  • I'm sorry but still new to this...

    Exactly where in an example would I add/change: IS_SRVC_CHANGED_CHARACT_PRESENT 1?

    I searched through SDK6.1 examples but couldn't ind this.

    I can't download SDK7 examples as my Nordic demos are older nRF51822-DK and nRF51822-EK whick only go to SDK6.1 on downloads.

    Most of my nRF work is in mbed, that is where I really would like to try this.

  • Np :) For example in ble_app_hrs in SDK 6.1.0 it is in main.c on line 54. You can also search for it, CTRL+F->Find in Files tab.

Related