Garmin watch to Pico connection issues

41 views
Skip to first unread message

Stéphane Lenclud

unread,
Apr 16, 2025, 11:16:57 AMApr 16
to btsta...@googlegroups.com
Hi,

I'm trying to connect a Garmin watch Connect IQ application to a Raspberry Pi Pico W running a GATT server based on the LE Counter example.

Connection to that GATT server works fine from nRF Connect on Android and other devices but that Garmin Forerunner 965 watch fails. It looks like it keeps trying and keeps failing until I close the watch app.

I wonder if there is something I could do to get it working. Logs attached.

Cheers,
S.
nrf-android-connect.pklg
fr965-fail.pklg

Matthias Ringwald

unread,
Apr 18, 2025, 4:04:10 PMApr 18
to btsta...@googlegroups.com
Hi Stephane

What service(s) is your Connect IQ application try to use?

In the log, the Garmin asks for available GATT Services and then disconnects. I would assume that you're not providing the correct GATT services :)

The next step could be to google it or to find a device to which it connects and then try to get access to the radio communication.
As the communication is not encrypted at this stage, a regular LE sniffer like the one from Nordic should help. You could also try a MITM approach, there's a "le_mitm.c" in our examples folder.

Best
Matthias
> --
> You received this message because you are subscribed to the Google Groups "btstack-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to btstack-dev...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/btstack-dev/CANJitvbkvWHUheRHn4pysqhvbtogAOMaxTyMjYqfQrrPBaC%2BzA%40mail.gmail.com.
> <nrf-android-connect.pklg><fr965-fail.pklg>

Stéphane Lenclud

unread,
Apr 28, 2025, 6:39:09 AMApr 28
to btstack-dev
Thanks Matthias,

Looking at the logs in Wireshark I actually came to the same conclusion. The connection is briefly established then the watch sends an ATT_FIND_INFORMATION_REQUEST before disconnecting and trying it again with the same outcome.
I was told the Connect IQ API I'm using should be working fine with generic BLE services and characteristics though it has to be the BLE central apparently.
I'm not sure how I can tell from the HCI logs if the watch is indeed the BLE central? Could you help me with that?

Cheers,
S.

Stéphane Lenclud

unread,
Apr 30, 2025, 12:39:13 PMApr 30
to btstack-dev
Here are some app level logs. It looks like the watch is trying to write some characteristic but handle 0 and size 0 does not make much sense to me.
This is how I log that line: logd("att_write_callback: %04X - Size: %d\n", att_handle, buffer_size);
att_write_callback: 0000 - Size: 0
ATT_EVENT_DISCONNECTED
HCI_EVENT_DISCONNECTION_COMPLETE
HCI_EVENT_DISCONNECTION_COMPLETE
ATT_EVENT_CONNECTED
att_write_callback: 0000 - Size: 0
ATT_EVENT_DISCONNECTED
HCI_EVENT_DISCONNECTION_COMPLETE
HCI_EVENT_DISCONNECTION_COMPLETE
ATT_EVENT_CONNECTED
att_write_callback: 0000 - Size: 0
ATT_EVENT_DISCONNECTED
HCI_EVENT_DISCONNECTION_COMPLETE
HCI_EVENT_DISCONNECTION_COMPLETE
ATT_EVENT_CONNECTED
att_write_callback: 0000 - Size: 0
ATT_EVENT_DISCONNECTED
HCI_EVENT_DISCONNECTION_COMPLETE
HCI_EVENT_DISCONNECTION_COMPLETE
ATT_EVENT_CONNECTED
att_write_callback: 0000 - Size: 0
ATT_EVENT_DISCONNECTED
HCI_EVENT_DISCONNECTION_COMPLETE
HCI_EVENT_DISCONNECTION_COMPLETE
ATT_EVENT_CONNECTED
att_write_callback: 0000 - Size: 0
ATT_EVENT_DISCONNECTED
HCI_EVENT_DISCONNECTION_COMPLETE
HCI_EVENT_DISCONNECTION_COMPLETE
ATT_EVENT_CONNECTED

Stéphane Lenclud

unread,
Apr 30, 2025, 12:40:19 PMApr 30
to btstack-dev
I have logs in the read handle too it means it is never called.

Stéphane Lenclud

unread,
Apr 30, 2025, 12:42:15 PMApr 30
to btstack-dev
Sorry, I mean read callback. I hate emails 🙄 Would be much easier to do that on github where you can edit your posts 😁

Stéphane Lenclud

unread,
Apr 30, 2025, 12:57:20 PMApr 30
to btstack-dev
Weird is also the timing. When I connect from nRF Connect on Android I get  ATT_EVENT_CONNECTED instantly.
When the watch connects it takes like 5 seconds until I get  ATT_EVENT_CONNECTED then almost immediately that strangely broken write and the disconnection.
I looks like something goes wrong during the connection process that leads to a lag and weird att write. 

Matthias Ringwald

unread,
May 9, 2025, 3:12:05 AMMay 9
to btsta...@googlegroups.com
Hi Stephane

BTstack calls att_write_callback with transaction mode = ATT_TRANSACTION_MODE_CANCEL upon disconnect - this is unrelated to your problem.

The Connect IQ API looks normal. Do you have example code that gets a list of GATT Services and Characteristics?

Best regards
 Matthias


Stéphane Lenclud

unread,
May 13, 2025, 4:33:53 AMMay 13
to btstack-dev
Turns out the issue was that I was missing the GAP_APPEARANCE characteristic.
Apparently the Bluetooth stack from Garmin watches is really strict and the appearance characteristic is mandatory as per the Bluetooth specification.
Adding the following to the .gatt file got it working:
CHARACTERISTIC, GAP_APPEARANCE, READ, 00 00
You may want to consider adding GAP_APPEARANCE to your samples where relevant since it is mandatory.
Thanks for the help.

ble-peripheral-mandatory-appearance.png

Stéphane Lenclud

unread,
May 13, 2025, 4:39:43 AMMay 13
to btstack-dev
>  Do you have example code that gets a list of GATT Services and Characteristics?

As in a Garmin watch app Connect IQ Monkey C example?

On Friday, May 9, 2025 at 9:12:05 AM UTC+2 matthias wrote:
Reply all
Reply to author
Forward
0 new messages