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

Weird connection/disconnection behaviour #433

Closed
fullmetalfelix opened this issue Oct 4, 2022 · 14 comments
Closed

Weird connection/disconnection behaviour #433

fullmetalfelix opened this issue Oct 4, 2022 · 14 comments

Comments

@fullmetalfelix
Copy link

I have a raspberry pi zero acting as HID joystick using a program running the btstack (modified HID mouse example), and a windows 10 computer that the pi has to connect to.
I start the program on the pi, btstack goes online, and the computer can find the HID device and connect to it without trouble. The pi is correctly seen as a joystick, and it sends correct HID reports to the computer.

Eventually I kill the program on the pi, but windows 10 still shows the HID device as connected. Even when pi is completely off, cut from the power supply, windows still thinks it is connected. It even appears in the list of USB joysticks, although it does not show any sign of life.

When I start the pi and the program again, it shows the message that btstack is online, but it does not connect to the computer. In order to connect it again, I have to manually disconnect the device from the windows bluetooth control panel, then search for it again, at which point it connects and works as expected.

I would have expected windows to realize the HID joystick was disconnected but paired, and automatically reconnect when the btstack program starts on the pi.
Did I miss something or did something wrong?

Thanks for your help.

@mringwal
Copy link
Member

mringwal commented Oct 4, 2022

Hi. BTstack stores the bonding information on Linux systems in /tmp, which gets deleted on a power cycle.
Could you either move it to persistent storage (check TLV_DB_PATH_PREFIX in main.c) or instead of quitting the app and shutting down, just disconnect the connection to Windows by calling gap_disconnect with the connection handle from HID_SUBEVENT_CONNECTION_OPENED.

@fullmetalfelix
Copy link
Author

Hi,
thanks a lot for the swift response. I moved the bonding info to a persistent path. Now when the program on the pi is terminated, windows displays it as "Paired" as I would expect.
However, when the program is restarted and the BTstack goes online, it does not automatically connect.
I tried calling hid_device_connect(addr, &hid_cid) using the address of the pi itself, but fails to connect with status 0xf.
How would I get it to automatically reconnect on start?

@mringwal
Copy link
Member

mringwal commented Oct 4, 2022

if you want to connect in a BTstack app running on the Raspi to the Windows PC, you need to specify the Bluetooth Address (BD_ADDR) of the PC in the hid_device_connect call.

Also, please have a look at /tmp/hci_dump.pklg with Wireshark. It is often helpful to just follow the HCI Commands and check the responses.

@fullmetalfelix
Copy link
Author

That is what I would have expected, but how can I get the host address? My guess would be to read it from some packet of some type during the connection procedure, save it in a file, and then try to reconnect to previously seen hosts until one responds.

@mringwal
Copy link
Member

mringwal commented Oct 4, 2022

You can get it during connection from HID_SUBEVENT_CONNECTION_OPENED with hid_subevent_connection_opened_get_bd_addr. For a first test, you can write it down and hard-code it.

In practice, you could store the address in BTstack's persistent store via btstack_tlv.h.

@fullmetalfelix
Copy link
Author

fullmetalfelix commented Oct 4, 2022

I managed to get the server address from the connection_openened event, and it corresponds to the one found in the hci_dump.
This was saved to a file, and loaded when the program restarted.
I setup a separate pthread that periodically checks if the app_status is not connected, and calls hid_device_connect with the server address, but nothing happens.

HCI dump can be found here:
https://www.dropbox.com/s/rjx1yn2h89m1b7a/hci_dump.pklg?dl=0

Any suggestions?

@mringwal
Copy link
Member

mringwal commented Oct 5, 2022

BTstack is not thread-safe. You can use BTstack's timer sources, see led_counter.c, to trigger periodic action.
(You could also schedule a callback from the BTstack thread to your code).
You could try to re-connect on startup, and set a timer when it fails, or if you get disconencted.
Please send another log if it doesn't work with the BTstack time.

@fullmetalfelix
Copy link
Author

I implemented it like in the led_counter example but still not working.
Now the btstack_main sets up the heartbeat with 10s timeout, and the heartbeat handler calls hid_device_connect if the app_status is not connected. Before finishing heartbeat handler resets and adds the timer to the main loop (30s delay this time).

hci dump log here: https://www.dropbox.com/s/2sdkx0hdcq2gszr/hci_dump_heartbeat.pklg?dl=0

As expected, after 10s I see the connection attempt and after another 15s it prints "Connection failed, status 0x4"

@mringwal
Copy link
Member

mringwal commented Oct 5, 2022

Looks good. if you get statux 0x04, that's a page timeout. Usually, the BD_ADDR is not correct or the device is not in range. Please double check the BD_ADDR. Your code tries to connected to 08:78:A7:B6:08:78.

@fullmetalfelix
Copy link
Author

OK, sorry to have bothered you!
For some reason the address of the bluetooth dongle on the windows computer changed since yesterday. Obviously, the stored address was not good. Now calling hid_device_connect does indeed reconnect the pi to the computer.

Thanks a lot for your help.

@mringwal
Copy link
Member

mringwal commented Oct 5, 2022

Glad you got it working

@mringwal mringwal closed this as completed Oct 5, 2022
@fullmetalfelix
Copy link
Author

Perhaps one last question. Currently the heartbeat calls the connect and resets itself. Is there a way to wait until the connection attempt fails before starting the next countdown?

@mringwal
Copy link
Member

mringwal commented Oct 5, 2022

well. what about setting the timer on the connection failure?

@fullmetalfelix
Copy link
Author

Ah yes, event HID_SUBEVENT_CONNECTION_OPENED fires also when it fails. Thanks.

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