Can any one describe what is wrong with this code. It didn't search devices, and it showed some paired devices.
Project hosted here in Github.
think of the UUID as one identifier for a particular kind of service your device is advertising or accepting. It could have many such identifiers for many different services it can offer or use. It's not an identifier for the actual device.
The UUID you are quoting is the same one I found here and use too. it seems to be the UUID for generic bluetooth SPP service. (but haven't found much actual proof like an official published document quot8ing this number, just posts on here with no refrence) This UUID will allow your android device to connect to things like bluetooth serial port adapters, or anything expecting a generic serial port device... so it's a good one to start with.
If you plan to create a special service that's not the same as bluetooth SPP or has a different reason to exist, like android chat does, then it's a good idea to create your own UUID. Of course all devices to connect your service will have to understand this same special number.
Related
I am working on a mobile application, written in Kotlin, which, among other things, retrieves information about nearby Bluetooth devices. One of the requirements is to obtain information about the Bluetooth profiles supported by the scanned device.
You can find a complete list of Bluetooth profiles on Wikipedia. The requirement is to scan for each of these profiles.
So far, I have been able to obtain information about the services on a given BLE device:
As far as I know, each profile uses multiple services. I haven't found a way to deduce from such a list what profiles are used. But that may be a dead end.
I also know that the BluetoothProfile class contains constants representing A2DP, GATT, HSP/HFP, HID, HDP and SAP profiles, but I don't know how to implement their detection. I think, this is most promising lead, so I would appreciate any help, regarding
I don't think you can "reliably" determine the profiles of discovered devices until an RFCOMM socket is established (i.e. the peripheral is connected). It looks like you are using the BluetoothLeScanner? This will not find all profiles, for example A2DP. Use the BluetoothAdapter to discover devices. From its results, you will get a BluetoothDevice, on which you can get "rough" data about the class of each device from its bluetoothClass property. From there, you can try to call BluetoothClass.doesClassMatch(Int) which makes educated guesses about profiles, and errs on the side of false positives. This may be good enough for the purposes of your use case, but it isn't 100% reliable until a connection is established:
BluetoothClass is useful as a hint to roughly describe a device (for
example to show an icon in the UI), but does not reliably describe
which Bluetooth profiles or services are actually supported by a
device. Accurate service discovery is done through SDP requests, which
are automatically performed when creating an RFCOMM socket with
BluetoothDevice.createRfcommSocketToServiceRecord(UUID) and
BluetoothAdapter.listenUsingRfcommWithServiceRecord(String, UUID)
Use BluetoothDevice#getBluetoothClass to retrieve the class for a
remote 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.
I knew how to get the mac address of a BLE device in Android by calling address from BleDevice
bleDevice.address
But I didn't find a way to get the UUID of the device
On the other hand in iOS I can get the UUID of a device by calling identifier from CBPeripheral peripheral.identifier
But I didn't find a way to get the mac address.
Note that the mac address is not advertised in the advertisement data in iOS those are only the fields in advertisement data
kCBAdvDataIsConnectable
kCBAdvDataServiceUUIDs
kCBAdvDataTxPowerLevel
kCBAdvDataRxPrimaryPHY
kCBAdvDataLocalName
kCBAdvDataRxSecondaryPHY
kCBAdvDataTimestamp
My problem is I need an identifier that I can use in both Android and iOS to identify my ble device
In Android, BLE devices are distinguished by their hardware address. CBPeripheral.identifier property seems to be for iOS only and how their peripheral manager identifies and assigns the devices. Probably your implementation should use String as common denominator, for iOS should return identifier and for Android bleDevice.address.
Indeed the iOS MAC-> UUID Issue is a long standing one (and with search you'll see a number of threads on the issue).
Unfortunately there's no simple good news for a solution, and only some potential solutions... here's a summary and hope one of the paths may work for you:
iOS hides the MAC address and randomly generates a UUID for you. You can store the UUID on the phone, but it will be unique to that phone. If we both have iPhones and scan the same peripheral, we'll see different UUIDs. iOS generates the UUID on the device and hides the MAC address.
Indeed the iOS MAC-> UUID Issue is a long standing one (and with search you'll see a number of threads on the issue).
To make life easier, some devices add the some or all of the MAC address in their secondary advertising packet or in a unique device identifier in the Manufacturer data of the device and read this from the advertisement in iOS.... If you're in control of the devices firmware then I'd add this... of course if this is another party's device then you're at the mercy of their implementation.
Another possible route is using the GATT Device Information Service (Service UUID: 0x180a). Under this service there is a Serial Number String (Assigned UUID: 0x2A25) characteristic which can hold a serial number specific to the Bluetooth low energy device. But note, This is optional though and not all BLE profiles will have it, and you have to connect to the device first to retrieve this information which may not fit your usage pattern.
There may be other unique proprietary identifers for a specific device that are exposed either in advertising data or characteristics
If you're talking about an iBeacon then the advertised ibeacon guid and bluetooth address are effectively the same value.
In cases where I'm implementing the firmware for a custom BLE device I always add the 6 byte MAC address to the advertising manufacturer data. Some devices do this (or some other identifier that's not as unique like "Thermometer1020" with the 1020 hopefully being unique). But again you're at the mercy of what the device is advertising.
If you're looking for a solution that works across a wide variety of BLE devices and vendors, then unfortunatly Apple has made life difficult, if not impossible for you in their quest for security, privacy and limiting use cases of connected device applications.
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.
I created an App that connects to an HC-06 bluetooth module. This app is gonna be used in multiple devices to connect to different modules (they are all gonna be HC-06). Do I need to create a special UUID for every single phone? or can I hard code one that will work fine in every phone??
UUID in bluetooth in most cases refers to id of service that bluetooth devices offers.
Here are examples of UUIDs: https://www.bluetooth.org/en-us/specification/assigned-numbers/service-discovery
So to answer your questions you can hardcoded it, it won't change as long as device that you connect to is serving the same service.