ge0rg / aprsdroid

APRSdroid - Geo-Location for Radio Amateurs
https://aprsdroid.org/
GNU General Public License v2.0
503 stars 96 forks source link

Using ESP32 as TNC ( BT classic Works and BLE not) #370

Open richonguzman opened 4 months ago

richonguzman commented 4 months ago

Hi!

CA2RXU here (I develop code for LoRa APRS)

I achieved to connect:

Android over BT Classic to ESP32 to use this as TNC and works awesome!

APPLE over BLE with another aprs app over BLE and works also

But trying to connect to Aprsdroid in Android over BLE get the "valid connection" to ESP32 as TNC, but soon gets disconnected or dropped connection.

Checking BT Serial Terminal on Android all the data is flowing between both.

What should I do in configurations or maybe code to achieve the Android+APRSdroid over BLE as TNC?

penguin359 commented 4 months ago

APRSdroid only supports using Bluetooth with the Serial Port Profile which, as of it's latest revision 1.2, only supports BR/EDR (Classic) Bluetooth. It has not been specified for Bluetooth Low Energy. I am not aware of any standardized support to emulate a serial port over BLE. Are you trying to implement BLE support in the app? If not, there are general-purpose Bluetooth to Serial Port adapters that you can get which should be able to be connected to the UART on an ESP32 as an alternative to BLE.

richonguzman commented 4 months ago

the adapters was a good idea but the LoRa boards (ESP32 and ESP32S3) do work fin as they are... even as TNC over BT or Wifi...

so its seems I have to pray that APRSDROID updates to be used with BLE as ESP32S3 (and all new esp32 are coming with BLE "only")

penguin359 commented 4 months ago

The problem is that there is no standard as of yet for how to implement a serial port over Bluetooth Low Energy. For the Bluetooth Serial Port Profile that works over Bluetooth Classic, that is defined by the Bluetooth SIG and implemented by the Android operating system. APRSdroid merely uses the support that is already present in Android to connect to it. For BLE, there are APIs to talk to it, but it's a completely different interface to use and there is no mapping for how that interface would map to a TNC which is designed to work over a serial port. Someone would need to create a standard for how that works with a TNC. You are free to do that if you want to see it implemented and submit a Pull Request to APRSdroid with the changes needed for us to review, but in the absence of a specific protocol to talk over BLE, there's nothing for us to work on.

If you are developing a BLE application for ESP32, feel free to propose an interface and submit code to support it, but we need something to base support on.

Mane76 commented 4 months ago

Is there a possibility to allow aprsdroid to make BLE connections like 3rd party serial bluetooth apps (e.g. Serial Bluetooth Terminal) ? With this Terminal I can connect from my Samsung S23 to Ricardos Code using BLE, and by typing the LORA-String I can send via the Tracker. Also RX works, you need to be able to read the String of course.

penguin359 commented 4 months ago

First of all, it is completely possible for APRSdroid to talk to a BLE-based TNC as long as there is a well-defined interface to it and someone takes the time to implement the support for it in APRSdroid. The problem is that we don't have a well-defined interface to discuss yet. The current support in APRSdroid using something called the Serial Port Profile which is a standard defined by the Bluetooth SIG. It works on top of a layer called RFCOMM. Both of these layers are well-defined by these standard and have native support in the Android operating system. They've existed for nearly the entire history of Bluetooth, but they have only ever been defined for Bluetooth Classic. Because of this, the Android API to use them only works with Bluetooth Classic devices.

BLE uses a completely different interface to talk to them based on an attribute protocol. Essentially, a BLE device can present one or more characteristics which can be read and/or written. These work in a way more akin to packets rather than a stream of bytes like a serial port. Working with characteristics is a lower-level interface and requires more supporting code to utilize. Normally, you would have a set of characteristics defined together as a service and one or more services can be specified by a high-level profile like a heart-rate sensor or audio device. There are a number of profiles defined for BLE including the two I just mentioned, but Serial Port Profile (SPP) is not one of them. This is problematic because it means that the Android OS doesn't include support and any support for one specific device BLE device might work differently from another BLE device. The beauty of SPP is that any device that implements it talks in the same way making them interoperable, but there isn't a single, clear way to just map that to BLE without a specification.

As for how that Android App is presenting a serial port over BLE, it's cheating a little bit. It's likely just writing each line of text to whatever the first writable characteristic it finds on the device (or whatever UUID you set in the preferences). In fact, since BLE characteristics are written as packets, effectively, you could actually create an interface that just takes the APRS contents itself without any other framing needed as writes in BLE have their own framing unlike serial ports that just work as streams of bytes. The TNC-2 and KISS Bluetooth modes represent two different ways to frame an APRS packet into the stream of bytes used by the Serial Port Profile, but a BLE TNC could be designed to just work without either of those modes needed.

All this to say, it's difficult to decide how this should even be implemented without the context of a specific BLE-enabled TNC device that is already designed and working to test it against. Even if there was one, it might operate differently than another BLE TNC. I am experimenting with some form of BLE support, but I can't say if it will be completed or what hardware it would even work with. It just needs to be well-defined and written down to make any real decisions.

penguin359 commented 4 months ago

I looked into that app a little more and discovered that he does provide the source code for it to examine. It turns out, his BLE terminal is a little less ad-hoc than I expected, but still very vendor-specific. He actually implements the interface for several custom profiles from different vendors and tries to detect which profile the device has:

https://github.com/kai-morich/SimpleBluetoothLeTerminal/blob/6ab96d5cc8283b44c384cba76709bad2a5e80c39/app/src/main/java/de/kai_morich/simple_bluetooth_le_terminal/SerialSocket.java#L225

These are specific profiles developed by Microchip, Nordic, Telic, and TI of which each one is a little different. Also, all of these are focused on implementing a serial port, but I think if a BLE TNC device was developed, it would be nicer if it took advantage of the nature of BLE and used each Read/Write as a self contained packet and avoiding the need to deal with framing it as KISS or TNC-3 packets as there are already inherent boundaries provided by BLE.

In any case, this issue should probably be merged with #124.

richonguzman commented 4 months ago

I looked into that app a little more and discovered that he does provide the source code for it to examine. It turns out, his BLE terminal is a little less ad-hoc than I expected, but still very vendor-specific. He actually implements the interface for several custom profiles from different vendors and tries to detect which profile the device has:

https://github.com/kai-morich/SimpleBluetoothLeTerminal/blob/6ab96d5cc8283b44c384cba76709bad2a5e80c39/app/src/main/java/de/kai_morich/simple_bluetooth_le_terminal/SerialSocket.java#L225

These are specific profiles developed by Microchip, Nordic, Telic, and TI of which each one is a little different. Also, all of these are focused on implementing a serial port, but I think if a BLE TNC device was developed, it would be nicer if it took advantage of the nature of BLE and used each Read/Write as a self contained packet and avoiding the need to deal with framing it as KISS or TNC-3 packets as there are already inherent boundaries provided by BLE.

In any case, this issue should probably be merged with #124.

so you say there is a way?

penguin359 commented 4 months ago

so you say there is a way?

I say that I will be happy to review any pull request you want to submit adding support for it to APRSdroid. ;-)

In the long run, I might be able to add some support myself, but it will likely be specific to certain BLE devices as they all talk a little differently. I have not yet seen anyone actually produce a TNC that uses BLE by itself so it's hard to gauge what way to go.