Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS doesn't see changes to Bluetooth services and characteristics between sketches #96

Open
don opened this issue Jan 5, 2016 · 35 comments

Comments

@don
Copy link

don commented Jan 5, 2016

iOS doesn't see changes to Bluetooth services and characteristics between sketches

To duplicate

  1. Run example CurieBle -> LED
  2. Use LightBlue from iPhone to connect to LED
  3. Run example CurieBle -> ButtonLED
  4. Use LightBlue from iPhone to connect to ButtonLED (the old LED name will be show)

Problem: The old LED characteristics are also shown

  1. Turn Bluetooth off and on on the iPhone
  2. Use LightBlue from iPhone to connect to ButtonLED

The correct service and characteristics should now be shown

Background

The original problem was that descriptors (0x2901) added to existing sketches were not showing up in LightBlue. This has not been a problem when using other libraries such as BLEPeripheral or bleno. The steps above are an easier way to duplicate the issue without adding descriptors.

Software/Hardware

Arduino 101
Arduino IDE 1.6.7 on OS 10.10.5
iOS 9.2 (13C75) on iPhone 6s

Possible solution

iOS is expecting Service Changed 0x2a05 to be implemented on the Generic Attribute Service 0x1801.

@mwms
Copy link

mwms commented Jan 5, 2016

I had the same problem. Turn off and then turn on the bluetooth on iPhone.

@kitsunami kitsunami added the bug label Feb 24, 2016
@kitsunami kitsunami added this to the Bellatrix milestone Feb 24, 2016
@kitsunami kitsunami assigned SidLeung and unassigned calvinatintel Feb 24, 2016
@kitsunami
Copy link

@noelpaz , please work with Sidney on this.

@noelpaz
Copy link
Contributor

noelpaz commented Feb 24, 2016

This could be a Light Blue issue rather than a Arduino 101 issue. For some reason the Light Blue App cache's the Peripheral address and instead of reading the local name in the Advertising packet it just remembers the old values. This even get's worse if you bond. I would suggest getting the nRF Master Controller App instead of Light Blue. Or as mention kill the app or do a rescan

@sandeepmistry
Copy link
Contributor

@kitsunami @noelpaz I've discussed this @calvinatintel.

I believe it's a caching issue with iOS in general, as @don mentioned if the Service Changed 0x2a05 characteristic is not present in the Generic Attribute Service 0x1801 iOS will cache all attributes even if the sketch changes them.

I suggest we do the following: add the 0x2a05 characteristic to the 0x1801 service by setting the services_changed property on the ble_gatts_enable_params_t parameter passed into sd_ble_enable needs to be set to true. (This might be a nRF51822 change).

@kitsunami kitsunami modified the milestones: Castor, Bellatrix Jun 10, 2016
@kitsunami kitsunami modified the milestones: Deneb, Castor Aug 22, 2016
@eriknyquist
Copy link
Contributor

@noelpaz @sandeepmistry can you guys re-test on the latest master?

@noelpaz
Copy link
Contributor

noelpaz commented Oct 11, 2016

This is still not implemented and probably will not. Any nrf FW change for us is not trivial because we do not own it.

This is a caching issue with the different BLE tools that are central devices. You get different behavior on each and I have tried many. Some cache , some don't, some allow you to store connection profiles. If you are using BlueZ central which does not cache and you see the Local Name not changing then I will agree it is a bug.

One other thing to settle this is use an analyzer.

If it really is a library or Arduino 101 issue then we need to see in the analyzer that the Local Name and Characteristic do not change when a different sketch is uploaded.

@sandeepmistry
Copy link
Contributor

To me this is a trivial change in the nRF51822 firmware (maybe 2 or 3 lines). If it's not possible to fix in the next release, I think this issue should remain open. It would make a much better experience for iOS users who are prototyping or learning BLE using the 101.

@Prof62
Copy link

Prof62 commented Oct 13, 2016

This definitely needs fixing and, in the interim, a big red warning message in the official docs. I wasted half a day trying to work out what was wrong with my sketch and then trying to "un-corrupt" my 101 before I discovered that it was actually a bug.

Luckily for me the failure was glaringly obvious but it has the potential to manifest in very subtle ways.

This may not be an simple fix but it's definitely a necessary one.

@sandeepmistry
Copy link
Contributor

@SidLeung @sgbihu @noelpaz I wonder if we can workaround this at the ARC level. We can try to automatically add a Generic Attribute service and Service Changed characteristic in the CurieBLE library when the library initializes.

@SidLeung
Copy link
Contributor

Understood that it would be nice to have the peripheral to cause the Central to flush its cache of stale info. The above suggestion should be implemented on a customized bases, not a generic function. For example, if you plug a new device onto an Ethernet, it device will not perform extra activities to cause all the switches and routers on the net to flush and refresh their cache. It is not within its scope of duty. In addition, resource constraints should be considered here, namely, memory and power consumption. For 101 which is usually not powered by battery, it is acceptable to have a high level of BLE activities. For a wearable platform, BLE activities should be kept to the minimal. In other words, it cannot afford nice features.

@noelpaz
Copy link
Contributor

noelpaz commented Oct 13, 2016

@sandeepmistry Not sure if we can do this just by making changes in the library and framework source code The 1801 Generic Attribute Service is already added by default but it is empty, so it looks like we are using the default that usually come with Nordic FW. I experimented on adding that Characteristic and it just caused BLE to not start.

I did some experiments with nrfController on Android 6.0 and even though it has cached data before connect, I can always get the changes once I connect and I do not have to even ask it to refresh, so even without the 2A05 Service Changed Characteristic it seems to behave as desired using this version of the OS and this app. I know it still does not solved the issues with iOS users.

@noelpaz
Copy link
Contributor

noelpaz commented Oct 13, 2016

In addition to what @SidLeung said, one thing to remember about sketches on Arduino 101 is that even though it may not seem like it, every time you upload a sketch and make changes you are in fact pushing a new FW unto the board not just an app. And anyone who has updated the FW on their router or BT headset etc, knows that you have to start fresh to re-configure the settings as well. Restarting Bluetooth, asking your central app to refresh or restarting it or maybe even restarting the devices are inconvenient/unavoidable activities that are part of development.

I agree that in addition to the current documentation, we can document these caching issues and provide guidance to the end user on workarounds until a fix or if a fix will be implemented.

@sandeepmistry
Copy link
Contributor

Hi @noelpaz,

Thanks for trying out my suggestion, I forgot that the Nordic stack includes an empty Generic Attribute service.

Please note, this is the behaviour of the iOS CoreBluetooth stack, so it impacts all iOS apps, just not LightBlue. iOS treats non-presence of the Service Changed Characteristic as a flag to turn on caching. When the Service Changed Characteristic is present it disables caching entirely, as far as I know other BLE stacks such as Android and OS X don't cache at all.

@SidLeung please remember Arduino is an "open-source electronic prototyping platform". When prototyping BLE using a 101 board, the services and characteristics may change quite frequently, especially during the out of box experience when the user changes tries out number example sketches.

This issue has come up numerous times on the forum, and making it the default behaviour will save 101 customers using an iOS device lots of headaches and time. In the interim we can add warnings in both the example sketches and documentation to prevent these. However, fixing this behaviour should still be scheduled in the roadmap. For advanced users who would like iOS to cache, we can add a API to not include the Service Changed Characteristic.

@don
Copy link
Author

don commented Oct 14, 2016

@SidLeung Since this is Arduino I think it's really important that the library does the "right thing" and makes the user's life easier by setting the Service Changed Characteristic. It should be easy for users to create and modify Bluetooth services.

Forcing users to restart Bluetooth on their phone or a custom implementation of Service Changed Characteristic won't be the best experience. I agree with @sandeepmistry that advanced users should be able to override the Service Changed Characteristic if they want iOS to cache.

@SidLeung
Copy link
Contributor

@sandeepmistry Please provide a BLE Peripheral device that has Service Change Characteristic so that @noelpaz can verify the caching disabling feature on iOS before we should proceed further.

@sandeepmistry
Copy link
Contributor

The easiest for you might be to use bleno on an Intel Edison, if you have one handy.

@rexstjohn has a nice configuration guide: http://rexstjohn.com/configure-intel-edison-for-bluetooth-le-smart-development/

@SidLeung
Copy link
Contributor

@sandeepmistry Please provide a BLE Peripheral device that is other than a Maker product that has the Service Change Characteristic feature. Thanks.

@sandeepmistry
Copy link
Contributor

TI SensorTag

You might be able to change the services via downgrading or upgrading the firmware.

@SidLeung
Copy link
Contributor

@noelpaz Please proceed with the verification.

@kitsunami kitsunami modified the milestones: Elnath, Deneb Feb 6, 2017
@don
Copy link
Author

don commented Feb 7, 2017

@SidLeung Anything I can do to help move this along?

I ran into this issue again last week during a class where the students were using the Arduino 101. We incrementally build services so there are a lot of changes. It a students forget to turn Bluetooth off and on on their iPhones between sketches, they get old cached results. It adds a lot more confusion while they're trying to learn.

@SidLeung
Copy link
Contributor

SidLeung commented Feb 7, 2017

Did an initial investigation into the BLE stack with the team, could not find a definitive answer whether this feature is supported. It could be a build option for the construction of the stack itself. Will need to schedule resources for further investigation. Will keep you posted with progress.

@tigoe
Copy link
Member

tigoe commented Feb 7, 2017

I'd definitely like to see it pushed up in the priority stack. I agree with Don, it matters a lot when working with students, and since we intend the 101 to be a learning board, they are the primary audience. When it doesn't work as expected, they turn to simpler BLE boards.

I've run into it several times on OSX, and never found a good solution. My guess is because the service name doesn't get stored, and because the radio's starting the advertising before the RTOS starts the sketch, so the default name gets used. I end up explaining it away to students, but they always walk away confused and grumpy.

Maybe the simple solution is to hold the BLE radio in reset until the RTOS can startup and give it the current name and stats, etc.

@SidLeung
Copy link
Contributor

SidLeung commented Feb 7, 2017

We had a meeting with Sandeep this morning and he gave us some pointers to check out. It may be part of the BLE stack initialization process that we missed. Will look into this.

@sandeepmistry
Copy link
Contributor

Here's a related blog post as discussed: https://punchthrough.com/blog/posts/attribute-caching-in-ble-advantages-and-pitfalls

@tigoe
Copy link
Member

tigoe commented Feb 21, 2017

Thanks, that was helpful to understand the problem better.

@sandeepmistry
Copy link
Contributor

@SidLeung do you have any updates on this?

@SidLeung
Copy link
Contributor

SidLeung commented Mar 7, 2017

This feature will not be in the upcoming release, Deneb. It is being considered for the CoreLibs release after the x86 firmware upgrade.

@Programmer-Nikhil
Copy link

Hi guys,
I am also running through the same issue. I have also added the possible solution mentioned by @don in questions.

below is the image of services discovery which is clearly showing the addition of service change characteristic in GATT profile.

services_beam

After implementing above change still, I am getting the cache data. Is anyone has any other findings?

@SidLeung
Copy link
Contributor

A Jira ticket was created to track this issue, Jira-484.

@russmcinnis
Copy link
Contributor

russmcinnis commented May 1, 2017

BLE 4.2. Using LightBlue on a mac book, the local name as well as service and characteristics show the changes to button LED values so if this is a good test it appears the issue is resolved. @SidLeung

@tigoe
Copy link
Member

tigoe commented May 1, 2017

Agreed, it seems to be working properly now. Strangely enough, the BLE change didn't take effect until I did "burn bootloader" to Zephyr twice. The first time adjusted the serial problem, but the BLE problem persisted. Then when I saw @russmcinnis' note I tried burning bootloader again, and that made the BLE problem go away. It seems like the first "burn bootload" changed the RTOS, and the second changed the BLE firmware, is that accurate? If so, let's make sure it's noted in the documentation.

@sandeepmistry
Copy link
Contributor

@russmcinnis macOS doesn't cache like iOS does. Would you be able to re-test with iOS?

@russmcinnis
Copy link
Contributor

Thanks Sandeep. I tested with an iPad and it was updating local name to BtnLED and the proper characteristics.

@sandeepmistry
Copy link
Contributor

@russmcinnis I'm still seeing the issue with my iPhone running iOS 10.3.1 and 2.0.2 of the 101 core.

Steps I ran:

  1. Load Battery monitor peripheral example.
  2. Connect with LightBlue iOS app, battery service and characteristic shown.
  3. Disconnect LightBlue
  4. Load LED peripheral example sketch.
  5. Connect with LightBlue iOS app, battery service and characteristic still shown. I would expect the LED service and characteristic here.

After step 5, if I toggle BT off and on again and re-connect (to clear the cache), I see the right LED service and characteristic.

@sandeepmistry
Copy link
Contributor

There was a misunderstanding here, @russmcinnis was testing with PR #534 in his recent comments above. I was testing with the 2.0.2 release.

@kitsunami kitsunami removed this from the Elnath milestone Aug 30, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests