-
Notifications
You must be signed in to change notification settings - Fork 131
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
Determine over Bluetooth is micro:bit is in pairing mode #332
Comments
This will not work as well as I'd hoped. iOS doesn't allow access of any sort to the Generic Access Service like Android does so this "solution" would only help non-iOS devices. The preference then is to do something similar with the advertised name but this will definitely impact some apps. Thoughts? |
I was thinking in terms of what characteristics an app can see, but it seems iOS and macOS do reveal the GAP device name as explained here: |
Thanks @martinwork . Native developers look to be OK but some SDKs like Apache Cordova don't seem to make the GAP device name available from what I can tell (maybe it's a bug!) and reading the characteristic directly is not allowed on iOS. More to the point though, given the varying degrees to which advertising and other data is or isn't accessible on different platforms with different SDKs and frameworks, I'm wondering if something we're all confident would work anywhere and everywhere could be implemented. |
Thanks for discussing @smartyw @martinwork Firstly, why on earth would you overload the button A/B inputs for line following light sensors?? There are plenty more digital I/O pins available if your breakout the edge connector like this. :/ I'll have a friendly chat with them to see if we can avoid this in the future. I think my thoughts here are to do something with the DeviceInformationService. Currently this is an optional BLE service. We could make it compulsory when in pairing mode, and add a little metadata to one of the characteristics (e.g. "model"), to indicate whether or not the device is in pairing mode. The algo for an app to remotely determine if the micro:bit is in pairing mode would be something like: bool pairingMode = (deviceInformationServicePresent && deviceInformationService.model.endsWith('*')) Alternatively we could use one of the currently unused characteristics (marked as NULL here: https://github.com/lancaster-university/microbit-dal/blob/master/source/bluetooth/MicroBitBLEManager.cpp#L75), or add a new one (but DeviceInformation is a SIG defined interface, so this might make us incompatible). Thoughts? |
Like Yes, this is pragmatic and low risk regarding existing apps (I think!). I think I'd prefer to stick an asterisk on the end of the device name than abuse the manufacturer name, hardware or software version characteristics. It's not exactly a purist approach so I'd rather limit the "damage" to the device name. Against this argument is the fact that those other characteristics are clearly unused and so there's presumably no risk at all to existing apps. I'm open to suggestions! |
Yes, it does still feel like a bit of a hack. I guess we could align a bit more with previous approaches and put some freetext metadata in the model, as we do with the advertised name after a device is paired. e.g. model = "BBC micro:bit [pairing]" Actually, can we not simply use the fact the advertised name is different when in pairing mode? Or is this not accessible enough for BLE app framework APIs? |
doh - already discussed above... sorry guys. |
The name differs when a paired device advertises, not just when in pairing mode. The 5 char code is included when not paired regardless of whether we're in pairing mode or not. |
Can't you just stick a byte in the Manufacturer Specific Data (0xFF) in the advert? That data should be available on any framework and wouldn't corrupt the current Local Name format. |
If such data is available to apps, that would be a cleaner solution. |
The Manufacturer Data field must be prefixed by a SIG issued company ID which the foundation would need to register. |
If want to avoid using an existing field in a hacky way we could have a new custom service with a single characteristic whose presence (always with a value of 1) indicates we're in pairing mode. It would never be instantiated under other circumstances. No hack and will work everywhere I think. |
Yes, it is tempting isn't it - some sort of "Status" service... |
Yes, could have future uses... who knows. And we could call it "Utility Mode" rather than Pairing Mode. |
Is it legal to have additional characteristics in a SIG defined service? i.e. I'm pondering a new service vs. a new characteristic in DeviceInformation... |
Spec says "The Device Information Service may expose one or more of the characteristics shown in Table 3.1." so that seems like a big "NO". |
Bah. Humbug. |
@cpseager has told me that when he enquired about a company ID from the SIG, there was no charge. I'm double checking this but if that's the case, I was wrong about that and using the Manufacturer Specific Data field for this purpose would be perfect. No impact on existing apps that I can imagine and you can check for pairing mode before connecting to the device, which is definitely the right way to do it. The foundation would still need to obtain the company ID but it's just a case of filling in a form. We're using 24 octets of the advertising payload so we have space in the packet for the extra field. |
Update: Yep. Company ID is free. The foundation would need to register for the ID here: https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers |
Sorry to pop back up on an old thread. We're happy to register for an ID if free (and I think probably should anyway) but it looks like we need Adopter (also free) SIG membership as a pre-requisite too, so not sure how long it all takes. Having let the dust settle on this, is that still the right approach? Do we know for sure that on iOS and Android we can actually access the Manufacturer Specific Data in the ad packet? Does it interfere with other cool things like web-bluetooth? @martinwork might be able to tell us about the ad packet. My reading of https://stackoverflow.com/questions/22833198/get-advertisement-data-for-ble-in-ios is that we'd be good as we're not an iBeacon. FWIW I don't think any of @microbit-sam's partial flashing work will help here by default as we might well want the partial flashing service visible in both pairing (/service/utility/whatever it gets named to) mode and normal mode. We could use the new service as a Trojan horse for a new characteristic that tells you which mode you're in (excusably relevant because the app may want to trigger a reboot into 'pairing/service/utility/unicorn' mode in order to ensure that the update happens in a sane/known environment rather than alongside user code). |
@jaustin Good questions. I think you're right about iOS but unfortunately Web Bluetooth doesn't currently let filter on manufacturer data. It's in the spec but currently designated "unstable" which generally means you won't find it implemented in any browser and it's subject to change anyway. Maybe my hacky "" on the end of the advertised name is the way to go? Hacky but pragmatic? Except that... Web Bluetooth lets you filter on "name prefix" so the "" would need to prefix "BBC" in advertising packets and.... I'd want to test this... just in case there's some regular expression stuff going on in browsers that "*" might confuse! |
@jaustin regarding membership, I'm reliably informed that if all the uploaded documents are correct and the application is complete, it takes 2 business day to process. You have to upload business formation documents and sign/upload the membership agreements. I can provide support of course. |
I haven't needed to use it, but it certainly looks like the manufacturer data is available when scanning using the key CBAdvertisementDataManufacturerDataKey. The post below says this might not be available to an app running in the background. |
Yes manufacturer data works fine on android and ios. In ios you can also even get the entire advert packet if you want (when not working as a ibeacon), we have used that for debugging advert data in the past. Loads of devices allow the end user to rename the advertised name, LEGO Wedo2, LEGO Boost, SBrick etc come to mind. In those cases you can't recognise the device via the advertised name anyway, and have to use something else in the advert like a uuid or manufacturer data instead. So I wouldn't consider changing the name as hacky, it just may break existing apps that may be looking for a specific name already... |
"I wouldn't consider changing the name as hacky" :-) The asterisk isn't exactly elegant but perhaps needs must. I do think we need to think beyond iOS and Android though and I think Web Bluetooth warrants taking seriously. Probably the simpler, less sophisticated and change we make, the better. |
Background
The Bit:Bot product has a couple of line detection sensors which share pins with the two micro:bit buttons A and B. Consequently if you power it up while it is on a surface, it typically boots into pairing mode. You avoid this by lifting the Bit:Bot off the ground so that there's enough light falling onto the line sensors and then power on.
Inevitably however, users will boot into pairing mode accidentally and not realise their mistake. This leads to a poor user experience.
** Detecting Pairing Mode over Bluetooth **
There are two scenarios where it would be useful for an application to be able to determine whether or not a micro:bit was in pairing mode.
It would be useful to be able to determine from Bluetooth advertising packet content that a micro:bit is in pairing mode. This seems problematic. Adding a special character to the end of the device name in advertising packets would work, but seems to break the Samsung application (and perhaps others). Other advertising packet fields could perhaps be used (e.g. the inclusion or exclusion of the Appearance field) but not all client APIs give access to all advertising packet fields.
If we decided to implement a solution to this sub-issue, I think we'd need to use the device name advertising packet field and affected applications would need to be changed.
This is less problematic. One approach is to add a "*" to the end of the device name characteristic in the Generic Access Service. Then, after connecting, a client application can read that characteristic value, which is always guaranteed to be present, and determine whether or (perhaps) not, the micro:bit is in pairing mode.
I've submitted a PR which implements this:
#331
And here it is in use in Bitty Controller:
The text was updated successfully, but these errors were encountered: