Platform-agnostic bluetooth device identification mechanism - android

I'm trying to write a cross-platform abstraction over Bluetooth. When it comes to identifying devices (or peripherals, as iOS calls them), I'm a bit stumped.
iOS includes an identifier property, which is a generated ID assigned to a device the first time it connects. However, Android does not seem to have an equivalent concept. The best I seem to be able to do is to use BluetoothDevice.getAddress, which returns a MAC address. I can then turn that into a UUID by doing some byte twiddling.
Is there anything better I can do here to uniquely identify devices in an agnostic manner?

As you already noticed, you cannot use the identifier property to identify a device on iOS.
The correct way to do this is to advertise a service with a characteristic's value you can control on device A and discover this on the device B.
Depending on what you want to achieve, there are also SDKs you can use for device discovery, for example newaer, p2pkit or google nearby just to name a few.
Disclaimer: I work for Uepaa, developing p2pkit.io for Android and iOS.

Related

Differentiate between Bluetooth connection to Mac or Windows/Linux device

Is it possible to check if a connected device is manufactured by Apple / runs macOS?
I saw some info on the UUID might containing that information but I haven't found a way to extract that information from it.
https://www.bluetooth.com/specifications/assigned-numbers/
There are assigned numbers but I haven't found out if I can rely on the UUID always having that information and if it even contains a way to check.
In my case I'm developing an Android App, but I guess that and the programming language doesn't matter here. If given a UUID, how do I check if it's manufactured by apple?
So I either need a general way to figure out if a UUID is from apple, or an Android specific way of getting that information, mostly only having access to a BluetoothDevice object (without advertising or other lower level stuff because I don't access the connection directly)
To be more specific, I am using BluetoothHidDevice for the connection https://developer.android.com/reference/android/bluetooth/BluetoothHidDevice
Edit: I am provided with a device.uuids variable, that hold multiple UUIDs
Each one of them has the following methods:
What exactly can I do with the values to check if the manufacturer is apple.
The toString method generates a uuid String as expected
So to give an example, a Windows device has multiple UUIDS, one of which looks like this:
toString: 0000111f-0000-1000-8000-00805f9b34fb
leastSignificantBits: -9223371485494954757
mostSignificantBits: 18824841662464
There are around 32 UUIDs provided
I found a hackish way to do this, but the devices must have Bluetooth discovery activated, what you can do using android is to call upon the method startDiscovery() that allows you to scan nearby discoverable devices. This allows you to create a list of Bluetooth names that you can filter using regex to search whatever contains the term mac, macos, osx, macbook, etc., considering that most people don't really change their Bluetooth device name, this could be a good enough solution to your problem.
Here's a very detailed answer from another question that might help you find what you need
Find all Bluetooth devices (headsets, phones etc) nearby, without forcing the devices in discoverable mode
I don't think apple would violate the Bluetooth Specifications, so I think it is safe to assume that the company identifier in the UUID is a reliable source of information.
You can check the UUID for the Assigned Company Identifiers as provided by Bluetooth SIG. The Apple identifier is 0x004C. I don't see a way you could get hold of information regarding the operating system though. Maybe if you further described your use case, there might be a more convenient way to what you intend.
Please open this 16-bit UUID Numbers Document. Here on 3rd page you can see a table of UUID Allocation with Allocated devices. You can use 16-bit UUID for Members list to know which device is connected i.e. Apple, Samsung, Huawei etc. So we can find Apple based 16-Bit UUIDs as Apple is only platform to use IOS. All others UUIDs will relatively Android, Windows or Ubuntu etc. devices.

AltBeacon library - UUID returning 00000000-0000-0000-0000-000000000000

I am trying to create an Android app thats detect a rasperry pi by using the AltBeacon library by davidgyoung. So far I am able to get most data including distance, although the only things that I really need are dBms and the UUID of the device. Inside the rangeNotifier() function I pretty much print every piece of data to see if the UUID might come out somewhere that matches the one of the device but the only thing that resembles a UUID is given to me as "00000000-0000-0000-0000-000000000000" and is found by using the getIdentifier method. Any ideas why I can't see the actual UUID of the device? Thanks!!
If multiple Android apps say the ProximityUUID is 00000000-0000-0000-0000-000000000000, then they are probably right.
The reason iOS apps probably won't detect 00000000-0000-0000-0000-000000000000 is because unlike Android, iOS can only detect a beacon's UUID if it is pre-configured into the app (yeah, that's a chicken and egg problem I know!) and your UUID is probably not configured into those iOS apps. So it may be showing the ProximityUUID of a different beacon in the vicinity.
Also, don't confuse the Bluetooth GATT Service UUID with the iBeacon Proximity UUID. Even though these look superficially similar -- they are completely different identifiers If you are using a more general Bluetooth scanning app on iOS (and not a beacon scanning app) this may be what iOS is seeing.

Transform any devices into beacons : wifi + bluetooth (datzing like app)

I'm actually working for a startup I'm building with two other founders. On the side I would like to develop a quick prototype to be able to deepdive into a subject I can use on my project : beacons.
Here is what I want to achieve : I want to be able to use a device as an emitter (using bluetooth, BLE, or wifi) and the other one to be able to know when it enters the first one range. I need that to be able to do indoor localization (just a check in system, not to know exactly where people are in that specific location).
I'm used to code mobile application with Ionic and I'm more a Javascript developer. I saw that there is already something which fit to my needs : Dazting which transform every device mobile as "a beacon" with either bluetooth or Wifi. Problem, I want to do it on my own but to be honest I don't really now how they manage to do that with Wifi. I know that there are some libraries to emit with BLE but what about bluetooth ?
Does it mean I'll have to code it with native code ?
This is what I want to achieve :
Coding an hybrid app (will loose less time and one app for every
platform)
Transforming the mobile device into an emitter : with bluetooth or
wifi
Be able to know the distance between a device which will emit and a
one that will receive the signal
I don't want to go with beacons : I'm not going to use macro-location and buying beacons for my project at the start is not something we would like to do.
Any ideas or suggestions on how did Datzing manage to reach that goal ?
Thanks in advance.
Datzing relies on emission of Bluetooth Classic, Bluetooth LE and WiFi packets from a mobile device that is made discoverable, either programmatically or through manual selection in settings. The unique MAC address or SSID of the device can then be used to tie the detected transmission to a registered "Beacon" on the Datzing system. Basically it just registers the unique identifier associated with a Bluetooth or WiFi transmission with the Datzing servers so they can have meaning.
Using this technology to transmit on an iOS device is severely limited due to operating system restrictions. Users essentially have to manually go to settings screens to start the emissions. Android devices are much more flexible if you have a native app granted the proper permissions.
On the detection side, iOS is also much more limited than Android due to the operating system blocking access to raw MAC addresses of bluetooth devices and preventing detecting SSIDs of WiFi access points unless the network is connected. As of Android 6.0, access to the raw MAC address is also restricted, making such a system work less well with Bluetooth on newer Android devices.
On both platforms, iOS and Android, the ability to use these techniques to the extent they are allowed by the operating system are possible with native code. Doing so with Ionic or Cordova would require cobbling together a number of plugins (if they even exist) to bridge to the native features to access WiFi SSIDs and do Bluetooth discovery and scanning. This is unlikely to be a quick protoype.
Word of caution: It is always a good idea to try out a system like Datzing before trying to reproduce it yourself, as limitations often cause technologies not to live up to the claims of the marketing materials.

Can't discover desired service from bluetooth le device

I've made app that allows me to connect to bluetooth le device and lists all services and characteristics. However the only recognized service is 'Device Information Service', there is also 'Unknown Service' but it doesn't seem to pass data that im looking for. I'm sure that device is working properly because official app that was attached to the device works fine. What could be the problem? Is it possible that information that im looking for are passed in unknown service and are somehow encrypted?
Your app correctly discovers the services, the problem isn't there. The problem is that you expect the service to be a generic one but it isn't, it's a vendor specific service.
A vendor specific service (characteristic) is easily recognizable : Its UUID is 128 bits long. Also it's not resolved by generic BLE apps such as nRF Connect for the simple reason that they are specific and not generic.
When a company sells a device that implements generic services, they know that it will work with multiple applications but they also know that these applications will also work for the other devices from their competitors. By example, you can buy a heartrate belt from several companies and use them with several fitness apps on your smartphone.
When a company sells a device that implements vendor specific services, they know that it will not work with another application than their own one and that not any competitor will be able to sell a device that also works with their application.
Two different strategies, many different goals.
Basically, the company that designed the device you are playing with did not want you to be able to use another app than their own app to access the data in the device. It's that simple.
Now you still can reverse engineer their service. Use a sniffer, compare the data transferred when using their app with the data actually displayed in the app and maybe you'll find some logic, and learn the hard way how they have hidden the data in their service. However they probably have some clause stating you shall not reverse engineer this or that.
You can see the generic services here, but you won't learn anything more than what I've said : BLE GATT Services

How to talk to a BLE device using Android phone?

I'm developing an app to communicate with a BLE device (Sensor puck from Silicon labs) and get whatever it is broadcasting.
I have NO experience in developing any sort of Bluetooth application using Android.
Do I need to manually pair it to the BLE device? I downloaded Sensor puck app from Play store, it automatically started to read from the device. I don't understand how since I didn't pair it.
Do I need specific API to communicate with the device? Is it like, I connect to the device and unpack the data which the device is broadcasting?
Any other information related to BLE application development would help.
Thank you.
PS: I can't use the app from the play store as I need the data from the device for some other processing.
I have a little experience with developing BLE apps.
Do I need to manually pair it to the BLE device?
I haven't encountered use case where I needed to pair mobile device with BLE device. Basically, you can communicate with BLE devices without pairing with them. BLE devices constantly emit signals and you can read these signals. Usually, from the emitted signals, you can read name of the device (or producer name), MAC address, RSSI signal from which you can compute distance from your mobile device to BLE device. Some BLE devices emit other information like temperature read from their sensors, etc. You can read information from more than one BLE device during the single scan.
Do I need specific API to communicate with the device?
Google provides API, which you can use to communicate with BLE devices. You can read more about it at: http://developer.android.com/guide/topics/connectivity/bluetooth-le.html. You can also use some third-party libraries allowing to communicate with BLE devices. Most of them are dedicated to so called Beacons, which are simple, tiny BLE devices.
Exemplary APIs for BLE Beacons:
Estimote
Kontakt.io
AltBeacon
ReactiveBeacons - this is open-source project, which I'm currently developing, so if you have any questions regarding it, you can ask me directly
Other projects:
Android Bluetooth Demo - this is very good and simple project, which can help you to understand how to use BLE API provided in Android SDK
Other information:
To communicate with BLE devices, of course, you need to have Bluetooth enabled on your device, but regardless of this permission, you also need to have Location enabled on your device and added location permission to your app. I guess it's done due to the fact, that you can use BLE devices for creating micro-location services.
I gathered some references concerning BLE for myself. You can check them here: https://github.com/pwittchen/ReactiveBeacons#references and maybe they will be useful for you as well.
Regards,
Piotr
it might be too late, but it also might be helpful for other users. So Sensor Puck works like a simple beacon and it doesn't require any pairing. You just have to scan all bluetooth devices nerby and verify received ScanRecord object. You don't have to use any specific libs or API, Anroid sdk contain all necessary api for such case (please see BluetoothAdapter startScan, startLeScan, etc). Also you can find an example how to parse raw data in my demo project https://github.com/alexeyosminin/sensor_puck_demo

Categories

Resources