Trying to connect an Android phone to a somewhat unusual, nonstandard BLE device (a blood pressure monitor). Data points:
My program connects and reads other BLE devices fine.
My program sees the device in a BLE scan, but won't connect. Instead I get an immediate "Disconnected" status with a generic GATT_ERROR (status code 0x85).
Nordic's Android BLE scanner app will connect and read/write the device.
The device uses an unknown Service (FFF0) with one characteristic (FFF1) for notifications from the device and another (FFF2) to write commands to it.
The TI BLE packet sniffer software seems to indicate that no connection request is ever sent to the device.
Here's what I've observed with the Nordic scanner app:
When you turn the device on, it advertises and the app can connect to it. If you then enable Notifications on FFF1, you receive a byte 0xA5; this is per the device spec, which says it sends this byte every 500 ms. The (rather rudimentary) docs say this is "waiting for the connection" but obviously it is already connected.
If you then write the specified "start" command string to FFF2, it starts taking a reading and appears to perform correctly.
The Nordic app can connect; why can't mine?
Update: have verified that the Nordic app works on the same Android phone that is running my program.
Related
I have a setup with two Android devices: an android phone and a custom hardware running Android 10. The latter acts as a BLE Server, which is discoverable always with the same static MAC address. Also when that custom HW is paired with the phone it has access to phone's contacts and calls history. That HW can also play media (sound) streamed from the phone.
I use RxAndroidBle 1.11.0 library for BLE communication. As soon as I exchange some data via BLE Characteristic I unsubscribe from the RX observable so the library effectively calls: bluetoothGatt.disconnect() then blutetoohGatt.close()
(all those inside the DisconnectOperation class).
My problem is the fact that based on my observations, calling blutetoohGatt.disconnect() disconnects the classic BT profile (PBAP) as well.
Is it an expected behaviour?
I have investigated the code of generic Android P framework and it looks that calling bluetoothGatt.disconnect() -> bluetoothGatt.close() completely disconnects the device described by the given MAC Address:
BluteoothGatt#disconnect()
BlutetoothGatt#close()
BlutetoothGatt#unregisterApp()
I would risk a statement that I have quite unusual BLE use-case scenario where the phone (Central/Client) and the peripheral (custom Android HW/Server) are connected simultaneously via Classic BT profile and via BLE.
I suspect that disconnecting/closing device using its BT MAC address disconnect both profiles, hence the contacts sharing stops working.
Is it possible to disconnect BLE connection only, but not affect the classic BT (SPP/PBAP) connections between the two devices?
After further investigation described on that Github issue
I realised that my custom hardware is equipped with dual-mode BT adapter so it supports classic BT (BR/EDR) and the BLE one.
As soon as I pair an Android phone with the custom hardware via System Settings, classic BT profiles are bonded, but also my GATT Server advertises relevant services using the same MAC address which is used by the BR/EDR. Disconnecting BLE client connection disconnect BD/EDR as well.
What helps in my case is to not start pairing via System Settings, but let the GATT server advertise and let my BLE client app to connect (and trigger pairing) first. As a result I have a BLE connection with server available under "AA:AA:AA:AA:xx", while the classic BT profiles are connected to "BB:BB:BB:BB:yy" interface on the custom hardware.
Now, disconnecting BLE profile does not disconnect the classic one.
I am looking for a solution which would allow my GATT Server to be advertised with BLE only, but no luck so far.
Here are some interesting links I have found:
connectGatt creates connection over BT Classic instead of BLE
how to force BLE "just works" pairing in Android
BLE Dual-Mode
The pairing process on Windows 10 will not result in establishing a successful connection on Android when Android device plays the peripheral role. The pairing process which is directly handled by the OSs on both sides (regardless of which services you are advertising) is being failed during updating the connection parameters such as Interval, Latency, and Timeout.
It seems both sides are looking for different settings on the connection. We recently tried to simulate another peripheral device using the NRFconnect android app by advertising a battery service for example. The connection will be dropped immediately after failing on compromising on the connection parameter settings. See the attached log files for the NRFConnect words, announcing why the connection is being terminated when it works with Windows. Just for the record, there is no problem when we change the central with another Android device.
I have a Bluetooth device which is connected to Android smartphone over Bluetooth SPP profile.
Once connection is successful, device opens the rfcomm device
handle = open("/dev/rfcomm0", O_RDWR | O_NOCTTY | O_SYNC);
After successful connection smartphone sends data to device.
It sends 3 consecutive messages of few bytes to device. This is verified after looking at snoop log of Bluetooth device.
However the blocking read at Bluetooth device side is never able to read initial 2 messages, after that it reads all other messages.
Same experiment is tried by writing a standalone script which starts reading data on rfcomm device as soon as SPP connection is successful, but here also outcome is same.
Please guide what might go wrong.
More or less it was a timing issue.
The app on device requests Bluetooth stack to create SPP connection with Android phone. On successful SPP connection /dev/rfcomm0 device is created by Bluetooth stack.
As soon as rfcomm channel is created, Android phone sends data to device but by this time application on device was not updated with the creation of rfcomm device. As there are no readers for rfcomm, Bluetooth stack flushes all data it received from Android phone.
Performed this experiment multiple times, once it worked.
I'm developing 2 Android BLE applications. One app will serve as the peripheral role and the other app will serve as the central role. On the peripheral app, there is one encrypted characteristic with PROPERTY_WRITE and PERMISSION_WRITE_ENCRYPTED.
The central app is able to connect to the peripheral and discover its services. The first time that central attempts to write to the encrypted characteristic, the system begins the bonding process and a dialog for entering the PIN appears. After the PIN is entered correctly, the characteristic can be written to successfully. If the central disconnects from the peripheral and then attempts to reconnect, a connection is briefly established but then disconnected. The onConnectionStateChange callback is received on the peripheral with a status of STATE_CONNECTED and then immediately called again with a status of STATE_DISCONNECTED.
Unless I manually unpair the devices (from the Bluetooth settings) and then start the connection process again, the central is unable to connect to the peripheral.
I've tried this solution but it did not work for me.
BLE Device Bonding Remove Automatically in Android
Both apps are running on devices with Android 5.
This issue seems to be resolved in Android 5.1.1. Originally, I was running the peripheral app on a Samsung Galaxy Tab A with Android 5.0.2. I switched to a Nexus 9 running 5.1.1 and 6.0.1 and did not encounter the issue described above.
I am implementing Bluetooth Low Energy's HID over GATT (HOGP) profile on Android Lollipop. My target is to use the phone as a keyboard/mouse, which can just plug and play with the default BLE (HID) drivers in Windows 8.1 laptop. The Android phone is supposed to act as BLE peripheral and the laptop should be in BLE central role.
Currently, I am able to establish a very short connection with the laptop. But just right after I enter the passkeys, and bonded successfully with the laptop, the BLE connection will be lost. Have anyone faced this kind of problems before? Or have any solutions on it?
Also, I failed to add generic access service to the gatt server in Android. I am curious if GAP service is included in Android BLE communication by nature? The reason I want to include this service is for defining the "device name", "appearance", and the "peripheral connection parameter update" characteristics. How I can do so?
Did you get your system fixed, I am seeing something kind of similar, where after bonding, my device will go to paired list, then about 20 sec later, the bluetooth on /off button will automatically switch to off position, wait 10 sec, then back
to on position, and my device is gone..