My app required to connect 9 Ble devices concurrently.
In this article and any other resource it write that android 4.4+ can connect only to 7 devices.
Is there anything new in M or N versions?
Thanks.
The number of connections is limited by the constants MAX_L2CAP_LINKS and GATT_MAX_PHY_CHANNEL which is currently (still) set to 7.
If you try to connect the 8th device with autoConnect = true, the stack will hang and fail to connect again until you restart Bluetooth due to a bug introduced in Android M. If you use autoConnect = false to connect an 8th device you will immediately get an onConnectionStateChange callback with newState = disconnected and no attempt to connect will be made.
I don't know why these constants are so low. Often the hardware itself can do more than 7. For example, Nexus 6P can do 15 if you compile AOSP yourself and change the constants.
Samsung seems to have noticed the issue and increased the constants on some of their devices. For example, Samsung Galaxy Tab A 10.1 can handle 15 BLE connections without modifications.
It seems that those constants are global limits, and not per app. I am linking to the source of the BT stack in Android. I wonder why those constants are as they are... seem random.
#define GATT_MAX_PHY_CHANNEL 7
https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/master/include/bt_target.h#1428
#define BTA_GATTC_CONN_MAX GATT_MAX_PHY_CHANNEL
https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/master/bta/gatt/bta_gattc_int.h#89
tBTA_GATTC_CONN conn_track[BTA_GATTC_CONN_MAX];
https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/master/bta/gatt/bta_gattc_int.h#424
NOTE
This is the official Android code. Up until Android 7.2 the vendors used to change that implementation a lot. The theory in Android 8 and above is that vendors should not modify it (not enough Android 8 devices on the field to see how this works in practice... at least at time of writing this reply).
Related
I am developing a UWP project to run on Raspberry Pi 3b that will advertise a Gatt Server. I based my program on the 3rd scenario in the windows IoT samples provided by Microsoft. I am using unpaired communication. Initially using the on-board BLE of the raspberry pi I get BSOD/restarts.
I narrowed the problem and suspected that it happens when:
client is not disconnected properly, i.e. android device is not disconnected properly
i try to notify using IAsyncOperation<IReadOnlyList> NotifyValueAsync(IBuffer value) on all devices even on devices not properly disconnected.
I did find on Microsoft documentation that it only supports low bandwidth devices so I limited my mtu/packet size, and added intervals on notification.
To fix the crash issue, I added a check for session status before sending notification to each individual subscribers. This seem to solve my issue on the crash. it hasn't happened again on my recent test. I am using 10.0.17763.1397 so maybe they also have some fix.
foreach (var client in characteristic.SubscribedClients)
{
try{
if (client.Session.SessionStatus == GattSessionStatus.Active)
{
GattClientNotificationResult result = await characteristic.NotifyValueAsync(data.AsBuffer(), client);
}
}
catch(Exception ex)
{
//if client is not disconnected properly, like
// bluetooth in client is turned off or becomes out of
//range it throws and error that on client.Session.SessionStatus
}
}
I also restart the GATT server every 60 seconds, like stopping the advertising and creating/restarting it again every 60 seconds if no client is subscribed/connected.
Now my problem is if I try to cycle scanning-connecting-reading, after some tries (6-20 tries) my client stops detecting the device. Only rebooting the device could solve the issue as I already tried restarting radio from my app and from powershell (using devcon). It didn't solve the issue.
Since I needed a perfect stable solution. I am opting to use BLE dongle with peripheral mode. I did see suggested BLE dongles from (I couldn't reply because it was already archived).
https://social.msdn.microsoft.com/Forums/SECURITY/en-US/344fc709-7e13-499a-94ee-3c935ad503bb/ble-gatt-server?forum=WindowsIoT
but I was hoping for some proof of concept before I buy them. (I did buy a bunch of CSR BLE dongles from hardware compatibility list of microsoft but none of them work)
If anyone have already tested:
BLE-USB-CR (RoHS)
BT900-US Laird
Please let me know your thoughts and how you made it work. I also saw the Bluefruit LE Friend from Adafruit but I'm not sure if it is compatible with Windows IOT.
Suggestions on my current imperfect solution are also most welcome.
I'm using Android Things 1.0.4 in a prototype where it acts as BLE peripheral device: advertising services and running a GATT server.
I encounter an issue in the BLE pairing process when trying to bond the Android Things board (Raspberry Pi 3) and a smartphone.
Since the device has no display, I set using BluetoothConfigManager:
IoCapability = BluetoothConfigManager.IO_CAPABILITY_NONE
which results in the error AUTH_FAILED every time.
Instead,
IoCapability = BluetoothConfigManager.IO_CAPABILITY_OUT
logs the pairing key and prompts the smartphone to enter it during pairing, but it results in the REMOVED error.
Questions:
Is Android Things in peripheral role capable of handling BLE pairing or not yet?
Are there more things that need to be implemented in the app's code to replicate the full-fledged Android logic?
Here's the source code of the Android Things app to test BLE pairing and bonding
The same code stripped from Android Things specific elements completes BLE pairing and bonding successfully when running on an Android phone as Peripheral (server), and an Android device or iPhone as Central (client).
Generally speaking, if you attempt to read an encrypted GATT characteristic before pairing (which triggers the pairing logic automatically), this results in GATT error 137 returned from the read request (AUTH_FAIL). This is because the device doesn't have enough time to finish setting up the bond before a response is sent by the Bluetooth stack. Retying the read request again generally succeeds.
I have not tested this with an iOS client device, but it certainly holds true with an Android client connecting to an Android (Things) peripheral. As such, I would recommend a few things:
Have the client (mobile) device explicitly initiate pairing, and Android Things should simply react to these incoming requests in the BluetoothPairingCallback. This lets the mobile device decide the pairing type based on the reported capabilities of the IoT device.
Separate the pairing flow from the GATT flow. Pair to the discovered device separately from making any attempts to read the characteristics. This tends to be the best way to avoid timing problems.
Regarding capability choices, this depends on your device. In my experience, if you choose IO_CAPABILITY_NONE this results in PAIRING_VARIANT_CONSENT inside of onPairingInitiated() and the pairing operation succeeds once finishPairing() is called. If you adjust your capabilities, you should be prepared for any number of the variants requiring you to display a PIN for the mobile device to enter. I have not not personally tested these paths.
**Overview of devices known so far:
Nexus 6,
Nexus 9,
Moto E 4G LTE,
LG G4,
Galaxy S6,
Samsung Galaxy S5 (model SM-G900M),
Nexus 5X,
Sony Xperia Z5 Compact,
Samsung Galaxy Tab S2 **
** Also see https://altbeacon.github.io/android-beacon-library/beacon-transmitter-devices.html **
One of the new features of the Android 5 release is support for Bluetooth Low Energy peripheral mode. While it is promoted to work independent of the used device, it seems to be chipset dependent (see the isMultiAdvertisementSupported() function in BluetoothAdapter.java).
It is working for the Nexus 5, but not for the Nexus 7 (called a bug in BLE peripheral support Android-L example, but it might never work because of its chipset?). Also https://code.google.com/p/android-developer-preview/issues/detail?id=589 does not give conclusive statements.
My concern is that, as many older devices are expected to get Android 5, only the newest tablets (and relatively new phones) will support BLE peripheral mode. This might be unclear to the end-user of apps relying on this new Android 5 feature.
For me it is very unclear which chipsets/devices, that will eventually get Android 5, will support the BLE peripheral mode. Anyone who can give me any insights on this? Which chipsets will support the BLE peripheral mode? More specifically, as many of our customers have a Nexus 7 (2013), will the Nexus 7 ever get supported?
Edit 19-2-2015:
Since December 2014 it is not supported anymore for the Nexus 5, only Nexus 6 and 9 seem to have support for BLE Peripheral Mode/ Advertising. Hope the number of devices supporting this will significantly increase in the near future.
More information and discussion here:
https://code.google.com/p/android-developer-preview/issues/detail?id=1570
Edit 6-3-2015: Added overview for quick reference
Edit 17-2-2016: Added some devices that I've checked myself but were not in any of the other lists
The Android 5.0.X will only allow you to use the new API for BLE. This new API comes with a new feature, which you mentioned in your question: The possibility of advertising, from your own Android device, using it in Peripheral mode. However, the disadvantaged of this new feature is that it is hardware dependent. For example, before you start any BLE you need to:
First: Check to see if the BLE is supported, which you can do by adding this line in your manifest: <uses-feature android:name="android.hardware.bluetooth_le" android:required:"true"/>
Second: You need to check if your chipset has support for it, using the following methods:
bluetoothAdapter.isMultipleAdvertisementSupported();
bluetoothAdapter.isOffloadedFilteringSupported();
bluetoothAdapter.isOffloadedScanBatchingSupported();
Also notice that for both of the above methods, the API documentation clearly states that:
"Return true if the multi advertisement is supported by the chipset"
"true if chipset supports on-chip filtering"
"true if chipset supports on-chip scan batching"
That being said, it brings us to the question:
"Which hardware devices are going to support this feature ?"
Well, the answer to that is a little bit more complicated since this is not a mandatory feature for the bluetooth hardware/protocol and it will probably vary from manufacture to manufacture. But for now, the only currently devices that officially are supporting the technology, without major issues, are the Nexus 6 and Nexus 9, since their hardware already comes with the support. The best that you can do it, is not rely solely on the technology for now and try to explore other possible solutions, if any.
I would like to control an Arduino device with a Motorola phone.
I have a Lilypad (preferred), an Uno, and a Mega Arduino board and I have two Motorola phones (a Droid Bionic and a Droid Razr Maxx) both running Android 4.1.2. According to an App called "USB Host Diagnostics" neither phone has USB Host Mode capability.
A variety of sites suggest the problem is that the phone doesn't provide enough power to the Arduino. Their solution requires cutting up and reconnecting the wires inside the cables. Others say the creation of a special "dongle" solves the problem, as long as it is in the phone when it starts to boot up but is removed before it finishes. Others suggest that it requires rooting the phone, which I'm afraid is probably beyond my comfort level and skill set. And many of these postings are several years old.
Has anyone figured out an smarter/better way to either enable or work-around the host mode capability issue of these phones? Or would it just be easier to find a used Nexus or Galaxy phone?
I have a problem with Windows CE 6 and a DIGI device with processor Freescale IMX51. I wrote an application in C # using the BSP of DIGI, to use the ARM eSPI (enhanced Serial Peripheral Interface).
Then using the functions issued by DIGI, in debug, I can active a OLED using SPI, but when I launch the application on the device, the OLED no longer works.
I have seen with an oscilloscope that when I load the application in debug mode the number of bits is correct, i.e., the clock has 8 rising edges, but when the application is launched from the device, the clock increases somewhat, that is, I see 9 bits. This also happens when I use the .exe from the debug directory.
I do not understand why this is happening. Can anyone help me solve this problem?