-
Notifications
You must be signed in to change notification settings - Fork 107
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
Bluetooth LE (BLE / Bluetooth Smart) TNC #124
Comments
Principally, yes. However, Bluetooth LE does not provide a "serial" profile comparable to Bluetooth SPP, so a specific profile would be needed. I have created a proof-of-concept for APRS-IS-over-BLE here: https://github.com/ge0rg/bluetoothle-tnc Something similar needs to be created for exchanging KISS packets over BLE, and then implemented both on the IC and on the Android side. Such a protocol could even be deployed on iOS. I'd gladly volunteer to write out the specification of the protocol and do the Android side implementation, provided somebody creates an according BLE TNC (or at least a BLE-to-serial adapter of some sort). |
I am working on new TNC prototypes right now so, what the heck, I might at well do a version that has a dual-mode BT module on it. I'm not convinced that BLE is a good fit for a general purpose TNC, but I do like to see hams experimenting with this stuff. If I can get hardware into peoples hands and something good comes of it, that would be great. The TNC will also have a working USB CDC and BT SPP. I will try to get one out to you in the next month or so. The firmware will be very alpha quality. And I will have little time to work on the BLE code. Now I just need to find my HM-12 modules... |
@mobilinkd I think that BLE is the only reasonable way to attach a TNC to an iPhone, so that would be the main reason. Besides of that, it has sufficient capacity for 1200bd APRS, so it might be an interesting low-power alternative for Android as well, provided the AFSK codec doesn't eat too much in comparison to BT. Ping me up some weeks before you start your work, and I'll sketch out the KISS-over-BLE protocol. |
I too would be interested in this. I have a Joying Android head unit for my car. It will not connect to my mobilinkd via blue tooth. I believe it does not support SPP profile. It sees the mobilinked as a phone. So i am willing to try out any beta code and provide feedback. |
Are there any news on BLE hardware? |
@ge0rg I received my first packets over BLE today. |
@ge0rg First packet TX happened this evening. |
Hey @rriggs, that's some awesome news. From your twitter feed I implied that you are running a HM-10 module of some sort, but I wasn't yet able to find its BLE serial protocol spec. If it's as simple as "read/write strings from certain characteristic", it shouldn't be too hard to add to APRSdroid. Maybe you can contact me off-list with some more details? :) |
Even though this thread has not had activity for some time, I'll venture to add my input as well. I'd argue that it makes more sense to simply run the communications over a generic UART profile, than creating a more specific KISS-over-BLE profile. KISS has always encapsulated in "raw" UART anyways, and several adapters already support a generic UART profile. Either way, I'd be interested to think what you all think. |
It looks like this is exactly what's happening in the TNC3. I didn't have the time to implement the BLE protocol yet, but I assume the battery savings will be meager compared to the GPS usage on the phone. OTOH, maybe the TNC battery will last significantly longer in LE mode? @rriggs, do you happen to have numbers on BLE vs SPP battery life time expectations? |
Surprisingly, EDR uses somewhat less power than BLE when connected. I can
tune the parameters to make BLE consume slightly less, but then it becomes
painfully sluggish in the config app.
I would like to see support for BLE in APRSdroid. Because then I can
release a BLE only device. I have a couple BLE-only prototypes on my desk
that I am experimenting with.
…On Tue, Jan 29, 2019, 09:33 Georg Lukas ***@***.*** wrote:
It looks like this is exactly what's happening in the TNC3. I didn't have
the time to implement the BLE protocol yet, but I assume the battery
savings will be meager compared to the GPS usage on the phone. OTOH, maybe
the TNC battery will last significantly longer in LE mode?
@rriggs <https://github.com/rriggs>, do you happen to have numbers on BLE
vs SPP battery life time expectations?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#124 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AEfuDBmb0CER69la0qNIGQMrzZIyoxeMks5vIGnfgaJpZM4Hpya8>
.
|
I should also say that I agree with you. Just use transparent data
transfer. Easy to implement, works well, lots of existing modules support
it.
I would like to see amateur equipment standardize on the service and
characteristic uuids. I just more or less used the ones from your BLE node
POC.
…On Tue, Jan 29, 2019, 14:02 Mobilinkd LLC ***@***.*** wrote:
Surprisingly, EDR uses somewhat less power than BLE when connected. I can
tune the parameters to make BLE consume slightly less, but then it becomes
painfully sluggish in the config app.
I would like to see support for BLE in APRSdroid. Because then I can
release a BLE only device. I have a couple BLE-only prototypes on my desk
that I am experimenting with.
On Tue, Jan 29, 2019, 09:33 Georg Lukas ***@***.*** wrote:
> It looks like this is exactly what's happening in the TNC3. I didn't have
> the time to implement the BLE protocol yet, but I assume the battery
> savings will be meager compared to the GPS usage on the phone. OTOH,
maybe
> the TNC battery will last significantly longer in LE mode?
>
> @rriggs <https://github.com/rriggs>, do you happen to have numbers on
BLE
> vs SPP battery life time expectations?
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <#124 (comment)>,
> or mute the thread
> <
https://github.com/notifications/unsubscribe-auth/AEfuDBmb0CER69la0qNIGQMrzZIyoxeMks5vIGnfgaJpZM4Hpya8
>
> .
>
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#124 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABBj3WvLylMhnNKF4fklMhL-2csJ8vdFks5vIKjVgaJpZM4Hpya8>
.
|
In my upcoming TNC I ended up going for BLE instead of SPP, even though there is not much application support at the moment, but I think it makes more sense from a platform standpoint to support BLE in the long run. It's currently working with a generic UART over BLE profile, where it uses the KISS protocol transparently over UART, same as serial and USB serial. I'd be happy to test any experimental builds of APRS droid on the hardware, or supply you with a prototype if that could help out. |
Hi Mark, when you say "generic UART over BLE", is there a new standard
service UUID for this? When I last looked, every BLE vendor was doing
their own implementation -- service and characteristic UUIDs. Some worked
better than others. A few were not 8-bit clean, apparently designed for
text-only use. IIRC, the NUS example code from Nordic worked pretty well.
What I would hope to see is that the ham community adopt a standard set of
service and characteristic UUIDs for this. That's why I used the ones
@ge0rg initially came up with rather than create my own. This
standardization will help avoid fragmentation of support in ham radio
software for these devices. It is easier and faster to scan for a
well-known service than for all nearby devices.
KTS_SERVICE_UUID = '00000001-ba2a-46c9-ae49-01b0961f68bb'
KTS_RX_CHAR_UUID = '00000003-ba2a-46c9-ae49-01b0961f68bb' # Notify
KTS_TX_CHAR_UUID = '00000002-ba2a-46c9-ae49-01b0961f68bb' # Write (with and
without response)
…On Wed, Jan 30, 2019 at 4:49 AM Mark Qvist ***@***.***> wrote:
In my upcoming TNC I ended up going for BLE instead of SPP, even though
there is not much application support at the moment, but I think it makes
more sense from a platform standpoint to support BLE in the long run. It's
currently working with a generic UART over BLE profile, where it uses the
KISS protocol transparently over UART, same as serial and USB serial. I'd
be happy to test any experimental builds of APRS droid on the hardware, or
supply you with a prototype if that could help out.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#124 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AEfuDIwiU53kGdCjrCASHgtSFIoqXS1Nks5vIXjVgaJpZM4Hpya8>
.
|
I was referring to the example UART GATT service from Nordic, with UUID 6E400001-B5A3-F393-E0A9-E50E24DCCA9E. In my (admittedly still rather limited) testing, it seems to work as intended. But I had assumed this service profile was used as a reference and was thus relatively standard, which apparently I was wrong in assuming. What are your thoughts, do you think we should "stick" with just running everything over a generic UART profile (whatever profile that turns out to be), or would you rather see a specific profiles for different protocols, say a profile for KISS endpoints, a profile for CAT control and so on? I just read through @ge0rg's specifications, and it looks soild enough, although I think there's a bit of an issue if the specification only talks about AX.25 frames, as opposed to KISS frames. It might just be me being pedantic here, but I think it's worth chiseling out clearly in the spec, if this is to be a standard we all converge on. The data frame command is only one command out of a potential 256 KISS commands (or 16 if using the high nibble as HDLC port number). To be honest I don't see much added benefit to using the custom profile over a generic profile just advertising UART capability though, apart from the discoverability aspect, which might very well be worth it anyhow. The additional features from ge0rg's spec like audio volume and other diagnostics messages can just be implemented in KISS frames, and seems to me like a more elegant solution, than having to side-channel them into a separate characteristic. |
Hi @markqvist , Every module manufacturer uses a different service UUID for transparent data transfer. We have a product on the market using those UUIDs, and @hessu supports those UUIDs in the aprs.fi iOS app. Using those existing UUIDs will allow you and others to build on existing infrastructure. In the end, as you aptly note, it is just doing KISS over a transparent data connection [1]. The primary reason to use a custom service UUID is that we are not just providing a transparent data service -- we are providing a very specific service that sends and receives KISS packets over a BLE endpoint. An entire KISS TNC firmware can be implemented inside a BLE module, without a single UART on the module enabled. Things like rig control belong under a separate service UUID. Rig control should not be tied to a TNC service. The idea behind BLE is that its services implement the purest form of a microservice. I need to publish the current implementation with input from @hessu and @ge0rg. It is pretty straight-forward, but there are a few things to clarify. For example, we support packing multiple KISS packets into a single MTU transfer. That impacts things like setting of KISS parameters (0x01-0x05) and hardware parameters (0x06). And a single KISS packets can span multiple MTU transfers. I agree that using KISS hardware parameters (0x06) to update things like volume levels is the way to go. That is how we configure our TNCs. The Mobilinkd iOS config app is an open reference implementation of the BLE client side code in Swift. If you look at the SLIP and KISS code, there is nothing at all surprising in there. The Mobilinkd TNC3 use a Microchip BM78 module. I have a number of prototypes using various BLE-only modules, including various Nordic nRF51 & nRF52 modules. At last count there were 7 or 8 different modules in various stages of testing on my bench. The nRF52 modules are certainly the way to go for a BLE-only product.
|
@mobilinkd, you are right, it's the correct way to go about it. A KISS service should be advertised as that over BLE, not a UART service, which as you mention is even quite a misnomer here, since there is no serial parameters involved. If a more formal specification is worked out, I will support that in my upcoming products as well. Having an agreed upon standard is the way to go here. |
I guess nobody wrote the updated formal spec yet? @mobilinkd ? I was just thinking I might do it if nobody else did. It'd be good to have it out there before someone makes yet another protocol which is different, and then we have to start reimplementing clients. |
I know you probably also have a ton of other things to work on, but I really like the idea of you being the author of it @hessu. It seems more fitting than if it originates from one of us “hardware implementers”. We can all help out, of course. But you being the main author, I think would be very suitable. And I agree completely, it would be very good to have it formalised sooner than later. |
Hessu, if you have time to do it, please do. I will certainly review and
can provide additional details where required.
I think it's important that we leave BLE-specific implementation details
such as MTU size open. As long as the spec is clear that it is a KISS
protocol and that a KISS packet can span multiple BLE transfers, we should
be OK. The first BLE module I worked with had a fixed MTU of 27.
I would like to provide guidance to anyone considering extending the spec.
I would like to specify that any extensions to the protocol should be
done using additional attributes. I use vendor-specific KISS hardware
records to configure and control the TNC3, but anything that is meant to be
open should be done as a GATT attribute. This will limit what I can do
with the TNC3 because of the BLE module used, but I think it is best for
the standard.
As an example, an extension to the protocol such as SMACK should be done on
a separate pair of attributes. Same for command mode. The reason for this
is that it advertises this additional capability to the BLE client.
Another example, one I think you requested, is audio level information.
Beyond that, I think we just need to specify the service GUID and KISS R/W
attribute GUIDs.
Kind Regards,
Rob Riggs WX9O
Mobilinkd LLC
…On Fri, May 15, 2020 at 4:03 PM Mark Qvist ***@***.***> wrote:
I know you probably also have a ton of other things to work on, but I
really like the idea of you being the author of it @hessu
<https://github.com/hessu>. It seems more fitting than if it originates
from one of us “hardware implementers”. We can all help out, of course. But
you being the main author, I think would be very suitable.
And I agree completely, it would be very good to have it formalised sooner
than later.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#124 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABD64DBM5MYDA6FSUVXDIULRRWU3BANCNFSM4B5HE26A>
.
|
Here goes, initial proposal: https://github.com/hessu/aprsfi/blob/kiss-ble/AX25-KISS-BLE.md Please review and provide feedback. I was very tired so there may be something silly in there. Maybe Georg does not mind if we hijack this aprsdroid ticket for the discussion since we've been here so long already. :) |
Great work. That is clear, concise and easy to follow for implementation, and I don’t think it leaves anything up to the imagination. Thanks a lot for the effort. I’d like to discuss whether it’s beneficial to tie it exclusively to AX.25. I know that in practice, AX.25 is almost all that is ever encapsulated in KISS, but that’s not a limitation of KISS, since it can encapsulate and transport frames for anything to and from a TNC. It would also be “free” specification-wise to state it more as just “KISS over BLE”, since it would not pose any restrictions for the current primary use-case of AX.25 over KISS over BLE. Personally I have several uses of KISS TNCs that do not involve AX.25, but use other link layers. I think the primary focus should still be on AX.25, and that the frame and buffer size calculations and rationales you present should be based on AX.25, but opening it up a little will make it come across as more generic, which I think is good in this case. If you’re interested I can submit an edit proposal as a pull request, and you can look it over and incorporate what you find useful, if you find that my points are sensible at all, that is. |
It looks like someone else is a fan of RFC 2119. :-) One change I believe needs to be made is with regards to the vendor extensions section. One cannot just pick a random UUID for an attribute. The BLE spec is written to say that, but Nordic software is written such that the service and attribute UUIDs must share a base, and you get 16 bits for the attribute UUIDs. This is why I changed the UUIDs used by @ge0rg's original implementation. The way it is done with Nordic (and I think I have seen others do the same) is to create a UUID, then zero out the third and fourth octet. Set it to 1 for the service UUID and then increment from there for the service attributes. Maybe the right thing to do is ask people to pick a 13-bit number for their vendor code and use the bottom 3-bits for their own 8 unique attributes? Additionally, you are welcome to refer to the Mobilinkd iOS Config App as well. This is written in Swift and released under the Apache license. https://github.com/mobilinkd/iosTncConfig It implements part of the spec for configuring the TNC using SetHardware codes. Should this be added as a reference for the KISS protocol? http://www.ax25.net/kiss.aspx |
Thanks, good points. @markqvist I think the application should be made aware of whether the KISS device can accept AX.25 or something else. For example, my application can only do AX.25 at the moment, and it might cause issues if it would send AX.25 to a non-AX.25 KISS device. Should there be a different service UUID for non-AX.25 KISS-over-BLE device, so that they wouldn't even show up in my app? |
In practice, most TNCs will happily (and should) transmit whatever is encapsulated in its KISS data frame, whether that be AX.25 or not. That was part of the point with KISS, to leave only the physical layer processing to the TNC, and actual data link-layer protocols to the host. A KISS-device is per definition network- and link-layer protocol agnostic, so there is not really a concept of "AX.25 vs non-AX.25" KISS device. You could go as far as saying that all KISS devices are essentially non-AX.25 devices. Even the Frame Check Sequence, which is sometimes taken as a part of AX.25 is technically part of the physical layer HDLC-like framing. My argument is that any KISS device should in theory adhere to the following operating principle:
Conversely, a receiving KISS device should transparently pass any received frames with a valid Frame Check Sequence to the host device encapsulated as a KISS frame, without making any judgements on the content. |
I agree with Mark. KISS is agnostic as to the contents of the payload. I have used the TNC3 to receive satellite telemetry data which are not in AX.25 format, but which are embedded in HDLC frames. The spec should probably make it clear that it is up to the client application to determine whether the data it receives from the TNC is properly formatted. |
Please find an updated version here: https://github.com/hessu/aprs-specs/blob/master/BLE-KISS-API.md diff: I tried to implement all of your suggestions, and give a fairly precise method to allocate extension UUIDs. Did I miss something? |
Here's the full log for startup. Appears to only start once. Then 2 seconds later it throws an error. In this attempt it actually allowed data to be sent followed by the same errors 2 seconds after writing. A follow up disconnect and reconnect provides the exact same results, but data is not sent to the device. 2024-12-16 19:14:54.704 8581-8581 APRSdroid.Service pid-8581 D onStartCommand: Intent { act=org.aprsdroid.app.SERVICE cmp=org.aprsdroid.app/.AprsService }, 0, 1 |
I think I will pick up on this tomorrow, as I can't focus on this enough without missing details. But what I provided is the most I can provide at this time. Unless you have other info that would help. This is on a Moto G Stylus 2023, Android 13, and a BTech UV-PRO. |
There's the smoking gun:
2024-12-16 19:14:55.948 8581-10635 APRSdroid.BluetoothLE pid-8581 D MTU
changed to 155 bytes
...
2024-12-16 19:14:58.163 8581-9072 APRSdroid.BluetoothLE pid-8581 D MTU
changed to 155 bytes
The MTU change was initiated under the hood, immediately after the
connection was established.
…On Mon, Dec 16, 2024 at 7:19 PM Mike ***@***.***> wrote:
Here's the full log for startup. Appears to only start once. Then 2
seconds later it throws an error. In this attempt it actually allowed data
to be sent followed by the same errors 2 seconds after writing. A follow up
disconnect and reconnect provides the exact same results, but data is not
sent to the device.
2024-12-16 19:14:54.704 8581-8581 APRSdroid.Service pid-8581 D
onStartCommand: Intent { act=org.aprsdroid.app.SERVICE cmp=
org.aprsdroid.app/.AprsService }, 0, 1
2024-12-16 19:14:54.711 8581-8581 APRSdroid.Service pid-8581 D addPost:
null - APRS Service started: Manual Position, TNC (KISS), Bluetooth Low
Energy.
2024-12-16 19:14:54.713 8581-8581 APRSdroid.BluetoothLE pid-8581 D
BluetoothTncBle.createConnection: 38:D2:00:00:F3:56
2024-12-16 19:14:55.947 8581-10635 APRSdroid.BluetoothLE pid-8581 D
Connected to GATT server
2024-12-16 19:14:55.948 8581-10635 APRSdroid.BluetoothLE pid-8581 D MTU
changed to 155 bytes
2024-12-16 19:14:55.949 8581-10635 APRSdroid.KissProto pid-8581 D Backend
Name1: TNC (KISS), Bluetooth Low Energy
2024-12-16 19:14:55.949 8581-17372 APRSdroid....eiveThread pid-8581 D
BLEReceiveThread.run()
2024-12-16 19:14:55.971 8581-8581 APRSdroid.Service pid-8581 D
onPosterStarted
2024-12-16 19:14:55.973 8581-8581 APRSdroid.FixedPosition pid-8581 D
start: periodic=false single=false
2024-12-16 19:14:57.954 8581-9072 APRSdroid.BluetoothLE pid-8581 D
Services discovered and characteristics set
2024-12-16 19:14:58.074 8581-9072 APRSdroid.BluetoothLE pid-8581 D
Notification enabled
2024-12-16 19:14:58.163 8581-9072 APRSdroid.BluetoothLE pid-8581 D MTU
changed to 155 bytes
2024-12-16 19:14:58.168 8581-9072 BluetoothGatt pid-8581 W Unhandled
exception in callback
java.lang.IllegalThreadStateException
at java.lang.Thread.start(Thread.java:960)
at
org.aprsdroid.app.BluetoothLETnc$$anon$1.onMtuChanged(BluetoothLETnc.scala:136)
at android.bluetooth.BluetoothGatt$1$13.run(BluetoothGatt.java:770)
at
android.bluetooth.BluetoothGatt.runOrQueueCallback(BluetoothGatt.java:948)
at android.bluetooth.BluetoothGatt.-$$Nest$mrunOrQueueCallback(Unknown
Source:0)
at android.bluetooth.BluetoothGatt$1.onConfigureMTU(BluetoothGatt.java:765)
at
android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:353)
at android.os.Binder.execTransactInternal(Binder.java:1299)
at android.os.Binder.execTransact(Binder.java:1253)
—
Reply to this email directly, view it on GitHub
<#124 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABD64DDWJN7AXUGILV675F32F6J2RAVCNFSM6AAAAABQJ7ZX2OVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKNBXGQZDANBZGQ>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
I can fix this. The MTU change has to be done earlier, before the
descriptor change. The thread will start in onDescriptorWrite. That way,
duplicate MTU requests won't be an issue.
So the sequence will look like this:
Service Discovery
MTU Change
Enable Notification
…On Mon, Dec 16, 2024 at 7:22 PM Mike ***@***.***> wrote:
I think I will pick up on this tomorrow, as I can't focus on this enough
without missing details. But what I provided is the most I can provide at
this time. Unless you have other info that would help. This is on a Moto G
Stylus 2023, Android 13, and a BTech UV-PRO.
—
Reply to this email directly, view it on GitHub
<#124 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABD64DHPGKOLKTPCWDXJFDD2F6KF5AVCNFSM6AAAAABQJ7ZX2OVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKNBXGQZDGNBVHE>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Well I attempted a change in that order. No error!! ..... but sending data still doesn't seem to make it to the radio on 13. Sometimes it works, 95% of the time it doesn't. Making progress though. I figure what you have might be even better. Still working on understanding things. 2024-12-16 20:24:02.983 28737-28737 APRSdroid.Service pid-28737 D onStartCommand: Intent { act=org.aprsdroid.app.SERVICE cmp=org.aprsdroid.app/.AprsService }, 0, 1 |
Attempted to fix this differently in
https://github.com/mobilinkd/aprsdroid/releases/tag/MOBILINKD_BLE_3
Ensure service discovery is complete before starting the thread.
Kind Regards,
Rob Riggs WX9O
Mobilinkd LLC
…On Mon, Dec 16, 2024 at 7:31 PM Mobilinkd LLC ***@***.***> wrote:
I can fix this. The MTU change has to be done earlier, before the
descriptor change. The thread will start in onDescriptorWrite. That way,
duplicate MTU requests won't be an issue.
So the sequence will look like this:
Service Discovery
MTU Change
Enable Notification
On Mon, Dec 16, 2024 at 7:22 PM Mike ***@***.***> wrote:
> I think I will pick up on this tomorrow, as I can't focus on this enough
> without missing details. But what I provided is the most I can provide at
> this time. Unless you have other info that would help. This is on a Moto G
> Stylus 2023, Android 13, and a BTech UV-PRO.
>
> —
> Reply to this email directly, view it on GitHub
> <#124 (comment)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/ABD64DHPGKOLKTPCWDXJFDD2F6KF5AVCNFSM6AAAAABQJ7ZX2OVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKNBXGQZDGNBVHE>
> .
> You are receiving this because you were mentioned.Message ID:
> ***@***.***>
>
|
So like mine, no error. But same issues on sending data to the radio. As well as the unmentioned disconnect of the gatt server after sending. 2024-12-16 20:38:05.708 9575-9575 APRSdroid.Service pid-9575 D onStartCommand: Intent { act=org.aprsdroid.app.SERVICE cmp=org.aprsdroid.app/.AprsService }, 0, 1 |
Just a quick update for those following along. NA7Q and I have been working offline on getting a few issues worked out. He is having an issue with his Android 13 device (Moto G Stylus) that I have not been able to replicate on my Android 13 device (Samsung Tab S7). The issue is that on BLE write for TX, the Moto disconnects with status 22 (GATT_CONN_TERMINATE_LOCAL_HOST). Current issue list:
The 2 other Android BLE apps I have are a BLE Config App and an M17 voice app. Both work well but the apps manage the connection lifecycle a little differently. The config app has a rather complicated BLE connection state machine due to the need to disconnect on Stop and reconnect on Start. One thing I still need to test is the behavior when two apps attempt to connect to the device at the same time. Unlike SPP, GATT will allow it. |
Are there instructions on testing the BLE build? I'd like to test it with my BLE KISS board. |
@mumrah Not yet. You can try one of my APKs (links above), select connection type "Bluetooth Low Energy", select a paired BLE device in the TNC Bluetooth Device dialog, then "Start Tracking". |
Feel free to try my build. It's feature packed, so beware of all the extra settings. Just added new stuff in the last hour here. |
I finally am moved into the new workshop and found all of my older Android devices on which to test. It seems that for the most part we have a working BLE implementation. I am running into an issue with Android 6.0. The first time it attempts to enable notification, it invariably fails to invoke the Disconnecting/closing the connection then re-establishing the connection seems to work, although I have seen a spurious "CONNECTION TERMINATED DUE TO MIC FAILURE" (status 61) on 6.0 as well. This may be due to a corrupted write caused by an internal race conditions in the older Android BLE stack. I think we have a couple of options here. The simplest is to just not support BLE connections until API level 26 (Android 8.0) in APRSdroid. Otherwise we could add a timer to the requests in the BLE service to detect the missing callback and retry. My concern here is that 6.0 is known to have race conditions, so we may need to add a timer and retry logic to every GATT call. I have tested on:
I have only done preliminary testing with the tablets, but they seem fine. If you have tested on another Android version, please document the version and device here. Any thoughts on how we want to handle the issue on Android 6.0? My preference is to only offer BLE as a connection option on Android 8.0 and greater. |
I fully agree that supporting Android 8+ would be the best approach. As realistically most users at this point will be at this OS version or higher. If you're using a BLE device, I'd suspect you're using a newer device anyway. |
I agree as well, just ignore the older devices. There is a limit on how much effort should be put into supporting obsolete versions. I would personally not care much about versions which no longer get security updates from the upstream (I believe Android 11 and lower, currently). But this is not my project, of course. |
Recap of the above issue list:
Additional changes:
The above logging change has resulted in 2 new string values which may benefit from translations since they are visible to the user. To Do:
https://github.com/mobilinkd/aprsdroid/releases/tag/MOBILINKD_BLE_4 There's a signed APK file with that release which uses my maps API key, so google maps should work in this one. You will need to uninstall APRSdroid before installing that package. The only thing that has not yet been done is limiting BLE to Android 8.0 and greater. The simple option here is to change |
For anyone interested, there is an Android BLE Config App for Mobilinkd TNCs available for testing here: https://github.com/mobilinkd/BLEConfig/releases/tag/v1.0.0 Version 1.1.0 will be coming soon, but this works well enough that people can test it out. Please report any problems with this app at https://github.com/mobilinkd/BLEConfig/issues rather than here. |
This is the first real "release candidate" build. All known BLE issues in APRSdroid are addressed. https://github.com/mobilinkd/aprsdroid/releases/tag/MOBILINKD_BLE_5 I have been working with @na7q offline. He alerted me to an RX issue. This release addresses two issues:
There is a signed APK with Google Maps support like the previous release. @mumrah please test if you can. Install the APK available from the link above. Pair the TNC to the Android device. In Preferences:
In Log view:
You should see the connection established and a packet transmitted. |
@mobilinkd it seems to be working. I did have to "pair" to my device using the SPP advert, which seems incorrect. There could very well be something awry with my advertisements, though it does work reliably on iOS with aprs.fi. Edit: I wonder if there's some caching within Android regarding device hardware IDs and the adverts. I'll see if I can try a fresh Pico W without the SPP code enabled and see what happens. Here are the logs from my BLE device with some commentary: I tried connecting to the "NinoBLE" device, which is from the GAP advertisement.
This did not work. The Android device never completed the connection. When I select the SPP advertised device "SPP KISS 00:00:00:00..." it is able to connect as before.
Once I selected "Start Tracking" I see the ATT connection, MTU exchange and the test message received from the device. This message is displayed in APRSDroid
I then pushed the button on the NinoTNC to simulate a packet and I get this
Next I sent position from APRSDroid. It is received by my device
|
I have a "scanner" version that you can attempt to connect to a device that isn't "SPP paired", whether it works correctly or not, I'm not sure. I can only test using a UV-PRO with BLE. And it does seem to work, but with the radio in "pairing mode". Not sure how that works on a Pico or others. |
@mumrah Please let me know what device model(s) and Android version(s) you are testing with. Android does cache service information. There are a couple of ways to flush the cache, but the most reliable I have found is to disable/enable Bluetooth on the Android device. Android does have a few issues with dual-mode devices. It seems the preferred way to deal with this on the device is to have different MAC addresses for BLE (KISS) and BT Classic (SPP). Alas that's not possible on the module used in the TNC3/TNC4. I deal with this in the BLE Config app by asking the user to disable/enable Bluetooth. That seems to always address the issue. You can try replicating the issue with the following steps:
Discovery should fail most of the time at step 6. Repeating just step 2 will allow the connection to proceed. The same issue also affect SPP connections. However, after connecting via BLE, you won't be able to connect until doing step 1 & 3 (unpair/pair device). Frustratingly, this behavior really depends on the device and Android version. Step 6 does not fail on my Nexus 5X (Android 8.1). It will always successfully connect via BLE. The behavior appears to have changed on my Pixel 8 after it was upgraded from Android 14 to Android 15. |
My test phone is a Pixel 2 XL running Android 11. With my SPP code removed, I cannot pair to the Pico W of BLE. I tried disabling/enabling bluetooth as well as restarting the phone. No joy. Here is the unsuccessful pairing:
Here is a successful "pairing" from iOS
So it seems that Android is not completing the ATT connection when attempting to pair through the bluetooth settings. Is it possible for APRSDroid to scan for BLE devices which advertise the correct service UUID? |
Another quirk I have noticed with SPP is that it often re-prompts the user to pair (i.e., asks the user to confirm the PIN). I suspect this is because I am not using a persistent address and am letting BTStack create a random hardware address
With this BLE version, it seems that it no longer asks me to repair the device. |
It is possible to scan for devices in one of my builds. It'll display any BLE device detected. You can select it from the list and see what happens. I'm still no expert of BLE, so this implementation could be worthless. |
It can be done, but it makes the code quite a bit more complicated. The code would need to initiate the bonding when selecting an unbonded device. For dual mode devices, the bond state may change when connecting via BLE, which requires a state machine to track the bond state. I may need to resurrect my nRF dev board with a BLE-only KISS service to test this. In the meantime, can you Edit: I should be more explicit. I don't recall seeing any notable pairing/connection issues with the device running in BT 4.0 (LE only) mode. |
I have modified the configuration of the BM78 (a dual mode device) to completely disable the BT Classic side of things so that it only supports BLE. The device with this configuration does not have any issues pairing on Android or connecting with APRSdroid. Something to note that I discovered in developing the BLE TNC config app: scanning interferes with the BLE connection and service discovery process on Android. Stopping scanning is an async operation with no callback. Because APRSdroid does not do any scanning, it was much more reliable at making BLE connections than my BLE TNC config app until I discovered this. |
After trying again today, the BLE "pairing" seems to be working. When I select the device from the Bluetooth settings, it doesn't seem to really do anything, but then the device appears under "previously connected devices" and APRSDroid can find it. Edit: well I spoke too soon. I tried to unpair and repeat the whole process. Now, I cannot get the Android to pair with the BLE device. However, APRSDroid is still able to send data! I guess someone remembers the last device it used? Under "TNC Bluetooth Device" nothing is present. |
@na7q is your "scanner" fork on github? |
Yes, I put it here. |
@mumrah I have been doing a bit more testing with my BLE-only device. One thing that is occurring on Android 15 is that as soon as the device is paired using Android's Bluetooth Settings, the device is left in a "connected" state in the Bluetooth Settings. On my device, when connected, advertising is disabled so it cannot be seen by any scanner. This is not a problem with the way APRSdroid currently works because it does not need to scan for the BLE devices. It just pulls the list of paired devices and lets the user choose. As soon as a new connection is open/closed, the device shows "saved" rather than "connected". But with my TNC config app, it is a problem. It cannot see the BLE device at all after pairing. Either the device needs to be reset or Bluetooth needs to be recycled on Android to release the connection and resume advertising. This does not happen with my dual-mode devices. It shows "connected" momentarily after pairing, then shows "saved" and is always visible. Just dropping this here in case it helps anyone with connection issues. This is the first time I have spent much time testing BLE-only devices, so this is really helpful. |
Is it possible to add Bluetooth LE support in aprsdroid?
e.g. HM-10 module
Thanks
Stephan
The text was updated successfully, but these errors were encountered: