Skip to content
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

GATT server receiving data from Android devices but no iOS devices #479

Closed
greymfm opened this issue May 1, 2024 · 6 comments
Closed

GATT server receiving data from Android devices but no iOS devices #479

greymfm opened this issue May 1, 2024 · 6 comments

Comments

@greymfm
Copy link

greymfm commented May 1, 2024

For kids educaton (https://github.com/owlRobotics-GmbH/owlRobotPlatform) we are using an existing App ('Dabble') to control our robots with a virtual joystick.
image

iOS: https://apps.apple.com/ch/app/dabble-bluetooth-controller/id1472734455
Android: https://play.google.com/store/apps/details?id=io.dabbleapp&hl=gsw&gl=US

The Dabble App works fine using attached Python example code and transfers joystick data between a Linux computer and Android devices. However it does not transfer joystick data (or any data) between the Linux computer and any iOS devices.

Python BLE GATT server <---- Dabble App sending data (joystick press etc.)
run below example with: python dabble.py

dabble.zip

This is how it looks with Android (connecting and receiving data):
Screenshot from 2024-05-01 10-08-13
Full debug log file:
android_log.txt

And this is how it looks with iOS (connecting, but not receiving any data - at the end we manually disconnected from within the App):
Screenshot from 2024-05-01 10-09-32
Full debug log file:
ios_log.txt

Further investigations show:

  1. It is not related to the Dabble App - We can use the Ardumower Sunray Website (http://grauonline.de/am/) in a BLE-enabled browser, and again data is received with Android devices (https://play.google.com/store/apps/details?id=com.evothings.evothingsviewer) but no data is received with iOS devices (https://apps.apple.com/de/app/cgtek-viewer/id1135118284).
  2. We can try something like GATTBrowser App on both Android and iOS, and with it we can receive data from iOS devices as well. So in principle the receiving works, but only using the GATTBrowser App.

What might be the issue here? :-)

@greymfm greymfm changed the title GATT server transferring data between Android devices but no iOS devices GATT server transferring data from Android devices but no iOS devices May 1, 2024
@greymfm greymfm changed the title GATT server transferring data from Android devices but no iOS devices GATT server receiving data from Android devices but no iOS devices May 1, 2024
@barbibulle
Copy link
Collaborator

There's nothing obviously wrong at first sight. It looks like iOS does connect and discover the GATT services and characteristics just fine. We even see a write to CCDs for subscriptions. But no other operation is seen. It's not clear whether the app didn't find something it was looking for, or if the iOS BT stack didn't like something.
I'll download the mobile apps and try a few things, to see if I can figure out what's going on. This is puzzling.

@greymfm
Copy link
Author

greymfm commented May 1, 2024

Thanks. I'm pretty sure it's 'the iOS BT stack didn't like something' because I have the same issue with another App (Ardumower Sunray Website in iOS CGTek Viewer) that I developed (and that does not expect something but instead just writes something) and I get the same issue there as well (no receiving at Linux from iOS and Android works just fine as well)...

@greymfm
Copy link
Author

greymfm commented May 2, 2024

As a side note, we are using the iOS Dabble App in another project as well (this time using some C code version of the BLE stack), and in this project the C code is correctly receiving joystick commands...
https://github.com/Ardumower/Sunray/blob/master/alfred/src/BleUartServer.cpp
https://github.com/Ardumower/Sunray/blob/master/python/test.py
https://github.com/Ardumower/Sunray/blob/master/python/dabble/DabbleESP32.cpp
... looks like the Python version of the BLE stack is doing something differently :-)

@barbibulle
Copy link
Collaborator

I installed the iOS app, and ran your example app.
What I saw in the iOS logs is:
WARNING: Characteristic <private> does not specify the "Write Without Response" property - ignoring response-less write
Which makes sense, since in the dabble.py app, the TX characteristic is declared as WRITE only. Presumably (I don't have the source code) the iOS app tries a write-without-response call (writeValue(data, for characteristic: xyz, type: CBCharacteristicWriteType.withoutResponse)).

But... I updated dabble.py, specifying WRITE_WITHOUT_RESPONSE in the TX characteristic properties (I tried with both WRITE and WRITE_WITHOUT_RESPONSE), and I still see the error in the iOS app logs. Using the nrfConnect app or the GATTBrowser app, I do see that the characteristic has the right properties (the GATTBrowser app shows two buttons, one for Write, one for WriteWithoutResponse, which trigger a WRITE_REQUEST and WRITE_COMMAND respectively), but somehow the Dabble app still fails to write, and the warning still shows up in the logs.
NOTE: the reason why the Android app still works even without WRITE_WITHOUT_RESPONSE is that Android will automatically fall back to WRITE without complaining.

I need to do some more digging to understand why nrfConnect and GATTBrowser see something different from what the Dabble app sees.

@barbibulle
Copy link
Collaborator

Followup: I was able to get the iOS Dabble app to write.
Looking at the BleUartServer.cpp I noticed that for some reason the RX characteristic was set up as BT_ATT_PERM_READ | BT_ATT_PERM_WRITE, BT_GATT_CHRC_PROP_WRITE | BT_GATT_CHRC_PROP_NOTIFY, which is definitely odd. But after I make the dabble.py app do the same, then I can receive the WRITE_REQUEST from iOS (on the RX characteristic). It seems that the iOS app uses the same characteristic for sending and receiving, writing and subscribing to 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, whereas the Android app writes to 6E400002-B5A3-F393-E0A9-E50E24DCCA9E and subscribes to 6E400003-B5A3-F393-E0A9-E50E24DCCA9E.
It doesn't make much sense for the iOS app to write to the RX characteristic, especially given that this characteristic is part of the "standard" Nordic UART service, which clearly documents that TX is the for writing data from the central to the peripheral, and RX is for receiving data from the peripheral to the central, as notifications! But that's definitely what the iOS app does... It might be worth letting the Dabble app authors know about this if you have contacts there.

@greymfm
Copy link
Author

greymfm commented May 5, 2024

Brilliant! Unfortuneately, I missed that little detail (what characteristics the iOS app actually uses)- Great that you found it out. I'll try to inform the Dabble app authors. In the end this is so simple :-) (for me it was really puzzling and I had no clue...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants