pvvx / ATC_MiThermometer

Custom firmware for the Xiaomi Thermometers and Telink Flasher
https://github.com/pvvx/pvvx.github.io/tree/master/ATC_MiThermometer
Other
2.93k stars 205 forks source link

Unable to pair/connect with bluetoothctl #172

Closed mvdklip closed 1 year ago

mvdklip commented 2 years ago

I'm not sure if there's something wrong with the setup of the bluetooth controller in my raspberry pi 3 so I'm seeking for confirmation here that what I'm trying to do should work with custom firmware.

Using bluetoothctl with transport set to 'le' I'm trying to do the following things:

I tried this with multiple LYWSD03MMC and CGG1-M devices and always get above results. I should be able to pair and/or connect to these devices running custom firmware, right?

The reason I'm trying to connect is because I want to send custom data to the LCD. Receiving and decoding advertisements from these devices has always worked fine but that doesn't require an active connection.

I also tried gatttool but I get Transport endpoint is not connected there. Supposedly gatttool is not supported anymore so I'm not sure if that has anything to do with my bluetoothctl issues.

pvvx commented 2 years ago

Perhaps something from what is described here will help you: https://github.com/pvvx/ATC_MiThermometer/issues/174#issuecomment-1003987084

mvdklip commented 2 years ago

Unfortunately no, it doesn't help. I tried LYWSD03MMC with PIN, LYWSD03MMC without PIN and CGG1-M without PIN. It is as if this bluetooth adapter cannot connect/pair at all. It scans fine but refuses to connect. :-(

I will see if I can pair/connect to another type of bluetooth device and/or if I can insert a second (USB) receiver in this raspberry pi.

mvdklip commented 2 years ago

Got a bit further by using btmon. It seems to create a connection successfully but then cancel it for some reason:

< HCI Command: LE Create Connection (0x08|0x000d) plen 25                                    #20 [hci0] 20:54:57.467904
        Scan interval: 60.000 msec (0x0060)
        Scan window: 60.000 msec (0x0060)
        Filter policy: White list is not used (0x00)
        Peer address type: Public (0x00)
        Peer address: 58:2D:34:**:**:** (Qingping Electronics (Suzhou) Co., Ltd)
        Own address type: Public (0x00)
        Min connection interval: 30.00 msec (0x0018)
        Max connection interval: 50.00 msec (0x0028)
        Connection latency: 0 (0x0000)
        Supervision timeout: 420 msec (0x002a)
        Min connection length: 0.000 msec (0x0000)
        Max connection length: 0.000 msec (0x0000)
> HCI Event: Command Status (0x0f) plen 4                                                    #21 [hci0] 20:54:57.468586
      LE Create Connection (0x08|0x000d) ncmd 1
        Status: Success (0x00)
< HCI Command: LE Create Connection Cancel (0x08|0x000e) plen 0                              #22 [hci0] 20:55:01.620448
> HCI Event: Command Complete (0x0e) plen 4                                                  #23 [hci0] 20:55:01.623559
      LE Create Connection Cancel (0x08|0x000e) ncmd 1
        Status: Success (0x00)

Now looking at https://www.spinics.net/lists/linux-bluetooth/msg67241.html and https://stackoverflow.com/questions/43529336/bluez-5-unknown-connection-identifier if those provide some hints on what's going wrong. Reporting it here in case some else using this firmware runs into the same problem.

Edit: lowering the advertising interval to 1s brought me one step closer. I can now successfully connect!

[bluetooth]# connect 58:2D:34:**:**:**
Attempting to connect to 58:2D:34:**:**:**
[CHG] Device 58:2D:34:**:**:** Connected: yes
Connection successful

Pairing gives another error now but I guess that's okay because the bluetooth subsystem simply doesn't know what to do with this device.

Solution: It seems that on more recent Linux kernels it's only possible to connect to these kind of BLE devices if the advertising interval is smaller than 2 seconds because of a newly added timeout in the kernel.

pvvx commented 2 years ago

For the BLE standard, the maximum advertising interval is 10 seconds.

mvdklip commented 2 years ago

I know. The Linux kernel people basically broke it by implenting this "auto" connection stuff with its 2s timeout. The workaround is to stay within 2s advertising interval if you want to be able to connect fron such a broken kernel.

On Tue, 4 Jan 2022, 14:15 Victor, @.***> wrote:

For the BLE standard, the maximum advertising interval is 10 seconds.

— Reply to this email directly, view it on GitHub https://github.com/pvvx/ATC_MiThermometer/issues/172#issuecomment-1004801174, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABQ47VVLPASFTNDIJD7CHDUULXILANCNFSM5LC3EC4A . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you authored the thread.Message ID: @.***>

pvvx commented 2 years ago

Core Specification 5.3 Bluetooth Core Specification Bluetooth® Specification ▪ Revision: v5.3 ▪ Revision Date: 2021-07-13 ▪ Group Prepared By: Core Specification Working Group

4.4.2.2.1 Advertising interval

The advertising interval (advInterval) shall be an integer multiple of 0.625 ms in
the range 20 ms to 10,485.759375 s.

Accessory Design Guidelines for Apple Devices Release R15: 40.5 Advertising Interval

The accessory should first use the recommended advertising interval of 20 ms for at least 30 seconds. If it is not discovered within the initial 30 seconds, Apple recommends using one of the following longer intervals to increase chances of discovery by the device: 152.5 ms 211.25 ms 318.75 ms 417.5 ms 546.25 ms 760 ms 852.5 ms 1022.5 ms 1285 ms


Someone from Apple got into Linux :) Apple previously recommended an ad interval of up to 2 seconds

pvvx commented 2 years ago

image

skgsergio commented 2 years ago

I found this thread today because I was facing issues connecting to my devices (wanted to change something) and I thought it could be related to me enabling the PIN in the past, but in the end, bringing them next to the computer helped me to connect to them using bluetoothctl (they were already paired from when I set up them).

So now I'm curious and thinking if it was not bringing them near the computer the thing that helped and was just pure luck and if I should lower the advertising time (which I guess impacts battery life)...

Solution: It seems that on more recent Linux kernels it's only possible to connect to these kind of BLE devices if the advertising interval is smaller than 2 seconds because of a newly added timeout in the kernel.

Do you have any references for this? Because I use Arch Linux and I should have a pretty fresh kernel and Bluetooth stack:

sconde@puck ~ $ uname -a 
Linux puck 5.15.12-arch1-1 #1 SMP PREEMPT Wed, 29 Dec 2021 12:04:56 +0000 x86_64 GNU/Linux
sconde@puck ~ $ bluetoothctl --version 
bluetoothctl: 5.62
mvdklip commented 2 years ago

So now I'm curious and thinking if it was not bringing them near the computer the thing that helped and was just pure luck and if I should lower the advertising time (which I guess impacts battery life)...

My advertising time was set to 5000ms and that was too high for my kernel to ever connect. It would just not work at all. I then changed to 1000ms which worked wonders ofcourse. In the end I set them to 2500ms (default value) because I was curious if I would then end up being able to connect sometimes (luck). This turned out not to be the case. Even with 2500ms I can connect reliably. With 5000ms it is totally impossible. I tried that. I didn't try all values in between.

Solution: It seems that on more recent Linux kernels it's only possible to connect to these kind of BLE devices if the advertising interval is smaller than 2 seconds because of a newly added timeout in the kernel.

Do you have any references for this? Because I use Arch Linux and I should have a pretty fresh kernel and Bluetooth stack.

Read the stackoverflow thread linked above.

skgsergio commented 2 years ago

My advertising time was set to 5000ms and that was too high for my kernel to ever connect. It would just not work at all. I then changed to 1000ms which worked wonders ofcourse. In the end I set them to 2500ms (default value) because I was curious if I would then end up being able to connect sometimes (luck). This turned out not to be the case. Even with 2500ms I can connect reliably. With 5000ms it is totally impossible. I tried that. I didn't try all values in between.

Ok, thanks for the detailed info. I'll keep them at 2500ms, I guess my issue was more related to signal strength then, I've been doing more tests and I can connect reliably to them if I put them near the computer.

Read the stackoverflow thread linked above.

Sorry I missed those links! Thanks.

skgsergio commented 2 years ago

Now looking at https://www.spinics.net/lists/linux-bluetooth/msg67241.html and https://stackoverflow.com/questions/43529336/bluez-5-unknown-connection-identifier if those provide some hints on what's going wrong. Reporting it here in case some else using this firmware runs into the same problem.

...

Solution: It seems that on more recent Linux kernels it's only possible to connect to these kind of BLE devices if the advertising interval is smaller than 2 seconds because of a newly added timeout in the kernel.

Ok after reading those references and doing some digging and if I understood correctly:

Kernel <3.17: 20 seconds timeout for BLE connections. Kernel >=3.17,<4.16: added a timeout of 2 seconds for BLE auto-connections: https://github.com/torvalds/linux/commit/09ae260ba452c2ed36ec295941a58cb75db213ed Kernel >=4.16: raised previous timeout to 4 seconds: https://github.com/torvalds/linux/commit/1f01d8be0e6a04bd682a55f6d50c14c1679e7571 (https://lists.ubuntu.com/archives/kernel-team/2017-November/088166.html)

This last change is from a later date than the SO and mailing list posts so I guess that 2500 is indeed good enough and my problem was 100% signal strength.

mvdklip commented 2 years ago

Kernel <3.17: 20 seconds timeout for BLE connections. Kernel >=3.17,<4.16: added a timeout of 2 seconds for BLE auto-connections: torvalds/linux@09ae260 Kernel >=4.16: raised previous timeout to 4 seconds: torvalds/linux@1f01d8b (https://lists.ubuntu.com/archives/kernel-team/2017-November/088166.html)

Thanks for the digging! That totally explains my situation because I'm running a kernel > 4.16 so apparently the timeout is 4s in my case and that's why 2500ms works but 5000ms doesn't.

The signal strength / connection issues are more apparent in LYWSD03MMC devices because of a missing condensator. You can find more info on that elsewhere. I actually replaced one of my LYWSD03MMC devices by a CGG1-M because I want to use it as a display for external data and I need to reliably be able to connect to it.

pvvx commented 2 years ago

Thanks for the digging! That totally explains my situation because I'm running a kernel > 4.16 so apparently the timeout is 4s in my case and that's why 2500ms works but 5000ms doesn't.

The reliability of the connection cannot be at the level of 2500 ms. One lost reception and the second sending of a connection request will be in 5000..5020 ms, when the second advertisement arrives. It will work more stable if the advertising interval does not exceed 2 seconds (minus the random addition time of the interval in the BLE specification).

pvvx commented 2 years ago

Kernel <3.17: 20 seconds timeout for BLE connections. Kernel >=3.17,<4.16: added a timeout of 2 seconds for BLE auto-connections: torvalds/linux@09ae260 Kernel >=4.16: raised previous timeout to 4 seconds: torvalds/linux@1f01d8b (https://lists.ubuntu.com/archives/kernel-team/2017-November/088166.html)

This means there is no Bluetooth LE support on Linux! The standard connection time prescribed as recommended is 20 seconds. This is taking into account that the maximum advertising interval is 10 seconds.

Protoncek commented 2 years ago

The signal strength / connection issues are more apparent in LYWSD03MMC devices because of a missing condensator.

Interesting... but this capacitor can easily be added. Is that capacitor between + and - lines of battery? On this pic from another issue: image

there are C24 and C25. Which value they should be? I'm guessing that smaller is around 100nF and bigger in a micro range...?

pvvx commented 2 years ago

Desirable more than 10 μF (С24) and more 100 nF (C25). The fact is that a secure connection causes a lengthy encryption negotiation procedure and at this moment a lot of resources are used. Significantly more than conventional modes. And the old recommendations of BLE chip manufacturers do not fit. And Xiaomi generally spat on recommendations for the sake of a slight reduction in price. Only the CGG1 has all the capacitors installed.

All Qingping devices - all capacitors are installed. All Xiaomi devices - no capacitors installed :)

Bitman-GR commented 2 years ago

If these capacitors can be omitted in normal operation by Xiaomi , adding them wouldn't increase standby leakage current ?

Protoncek commented 2 years ago

pvvx: thanks for info! I have such SMD's at home, so i'll solder them. Bitman-GR: no, these SMD capacitors don't have leakage current, so don't worry.

skgsergio commented 2 years ago

This means there is no Bluetooth LE support on Linux! The standard connection time prescribed as recommended is 20 seconds. This is taking into account that the maximum advertising interval is 10 seconds.

When they first implemented it they set a 20 seconds timeout. But after some time they added the 2 seconds timeout (that later they raised it to 4) for "auto-connections".

Is not clear to me (mostly because I do not have knowledge of the BLE protocol) what they mean by auto-connections, they mention that is when a connection is established as a consequence of receiving an advertising report, but no clue what this really means.

This is the commit where they first included it:

When we establish connections as a consequence of receiving an advertising report it makes no sense to wait the normal 20 second LE connection timeout. This patch modifies the hci_connect_le function to take an extra timeout value and uses a lower 2 second timeout for the auto-connection case. This timeout is intentionally chosen to be just a bit higher than the 1.28 second timeout that High Duty Cycle Advertising uses. -- https://github.com/torvalds/linux/commit/09ae260ba452c2ed36ec295941a58cb75db213ed

pvvx commented 2 years ago

Is not clear to me (mostly because I do not have knowledge of the BLE protocol) what they mean by auto-connections, they mention that is when a connection is established as a consequence of receiving an advertising report, but no clue what this really means.

Where did "High Duty Cycle Advertising" come from?


https://devzone.nordicsemi.com/f/nordic-q-a/12425/advertisment-directed-discoverable: Directed advertising

For directed advertising with high duty cycle the timeout is 1.28 s.

For directed advertising with high duty cycle, the min/max advertising interval settings are being ignored:

"For high duty cycle directed advertising, i.e. when Advertising_Type is 0x01 (ADV_DIRECT_IND, high duty cycle), the Advertising_Interval_Min and Advertising_Interval_Max parameters are not used and shall be ignored." (Bluetooth Core Specification, Vol 2, Part E, chapter 7.8.5)

Bluetooth Core Specification, Vol 6, Part B, chapter 4.4.2.4 says the following about high and low duty cycle directed advertising:

Connectable low duty cycle directed advertising is designed for cases where reconnection with a specific device is required, but time is not of the essence or it is not known if the central device is in range or not. High duty cycle directed advertising is designed for cases in which fast Link Layer connection setup is essential (for example, a reconnection). Note that high duty cycle directed advertising is a power and bandwidth intensive advertising scheme that should only be used when fast connection setup is required.


Но термометр не передает ADV_DIRECT_IND, а передает тип рекламы ADV_IND (code: 0).

When the device is paired and does not have a keyboard or display, and the pin code is remembered, a quick connection with negotiation is performed. "quick" - in the understanding that a new PIN code is not requested and a new connection key is not required ... It is completely incomprehensible why there is "High Duty Cycle Advertising" here?

pvvx commented 2 years ago

nRF Connect, Advertiser, set option: Connectable, interval: 4000 (2500 ms): image

[bluetooth]# scan on
Discovery started
[NEW] Device 5D:26:71:A1:D7:D4 Redmi Note 7
[bluetooth]# scan off
[bluetooth]# connect 5D:26:71:A1:D7:D4
Attempting to connect to 5D:26:71:A1:D7:D4
Failed to connect: org.bluez.Error.Failed

The "[bluetooth] # connect" does not make any requests for on the BLE air. Just accepts the first advertisement, waits for a timeout 2 sec and exits "Error".

Linux is dead.

skgsergio commented 2 years ago

@pvvx I've replicated your test with the same nRF Connect parameters and with this kernel and Bluetooth stack versions:

sconde@puck ~ $ bluetoothctl --version
bluetoothctl: 5.62

sconde@puck ~ $ uname -a               
Linux puck 5.15.13-arch1-1 #1 SMP PREEMPT Wed, 05 Jan 2022 16:20:59 +0000 x86_64 GNU/Linux

I can connect with reliability using interval 4000 (2500ms), I've made several tests.

[bluetooth]# menu scan
[bluetooth]# transport le
[bluetooth]# pattern Mi9TPro
[bluetooth]# back

[bluetooth]# scan on
[NEW] Device 5F:4E:AA:CA:C4:1B Mi9TPro
[CHG] Device 5F:4E:AA:CA:C4:1B RSSI: -75

[bluetooth]# scan off
Discovery stopped
[CHG] Device 5F:4E:AA:CA:C4:1B RSSI is nil
[CHG] Controller 94:B8:6D:87:6C:A6 Discovering: no

[bluetooth]# connect 5F:4E:AA:CA:C4:1B 
Attempting to connect to 5F:4E:AA:CA:C4:1B
[CHG] Device 5F:4E:AA:CA:C4:1B Connected: yes
Connection successful
[NEW] Primary Service (Handle 0x8061)
    /org/bluez/hci0/dev_5F_4E_AA_CA_C4_1B/service0001
    00001801-0000-1000-8000-00805f9b34fb
    Generic Attribute Profile
[NEW] Characteristic (Handle 0x4ece)
    /org/bluez/hci0/dev_5F_4E_AA_CA_C4_1B/service0001/char0002
    00002a05-0000-1000-8000-00805f9b34fb
    Service Changed
[CHG] Device 5F:4E:AA:CA:C4:1B UUIDs: 00001800-0000-1000-8000-00805f9b34fb
[CHG] Device 5F:4E:AA:CA:C4:1B UUIDs: 00001801-0000-1000-8000-00805f9b34fb
[CHG] Device 5F:4E:AA:CA:C4:1B ServicesResolved: yes

[Mi9TPro]# disconnect 5F:4E:AA:CA:C4:1B 
Attempting to disconnect from 5F:4E:AA:CA:C4:1B
[CHG] Device 5F:4E:AA:CA:C4:1B ServicesResolved: no
Successful disconnected
[CHG] Device 5F:4E:AA:CA:C4:1B Connected: no

[bluetooth]# connect 5F:4E:AA:CA:C4:1B 
Attempting to connect to 5F:4E:AA:CA:C4:1B
[CHG] Device 5F:4E:AA:CA:C4:1B Connected: yes
Connection successful
[CHG] Device 5F:4E:AA:CA:C4:1B ServicesResolved: yes

[Mi9TPro]# disconnect 5F:4E:AA:CA:C4:1B 
Attempting to disconnect from 5F:4E:AA:CA:C4:1B
[CHG] Device 5F:4E:AA:CA:C4:1B ServicesResolved: no
Successful disconnected
[CHG] Device 5F:4E:AA:CA:C4:1B Connected: no

However, if I change the interval to 8000 (5000ms) it is impossible to connect!

I'll will try to recomplie the kernel changing that value and maybe is worth to write to the Kernel Bluetooth maintainers.

pvvx commented 2 years ago

I can connect with reliability using interval 4000 (2500ms), I've made several tests. However, if I change the interval to 8000 (5000ms) it is impossible to connect!

Sometimes it connects to a thermometer and a smartphone with a timing of 2.5 seconds. But more often than not, it's a mistake.

Even on NanoPi R1, OpenWrt 18.06.1:

root@FriendlyWrt:~# bluetoothctl --version
bluetoothctl: 5.49
root@FriendlyWrt:~# uname -a
Linux FriendlyWrt 4.14.111 #1 SMP Sat Dec 28 01:30:07 CST 2019 armv7l GNU/Linux

Smartphone with Android and Windows PC is always connected.

skgsergio commented 2 years ago

Sometimes it connects to a thermometer and a smartphone with a timing of 2.5 seconds. But more often than not, it's a mistake.

Even on NanoPi R1, OpenWrt 18.06.1:

root@FriendlyWrt:~# bluetoothctl --version
bluetoothctl: 5.49
root@FriendlyWrt:~# uname -a
Linux FriendlyWrt 4.14.111 #1 SMP Sat Dec 28 01:30:07 CST 2019 armv7l GNU/Linux

That kernel version has the timeout set to 2s, that's probably why.

I'll recompile the kernel with a higher limit and perform some tests, and will ask why this limit in the mailing list.

skgsergio commented 2 years ago

I recompiled my kernel version with the following patch (setting the timeout to 20 seconds) and I can connect setting nRF Connect with interval to 16000 (10000ms), it still fails sometimes. In any case, I didn't read the specification for the recommended timeout, but I guess is max interval x2 so maybe with 21s is more reliable.

With lower intervals, I tested 12000 (7500ms), and 8000 (5000ms), connected every time. So... I guess I'll be asking in the Bluetooth kernel mailing list tomorrow.

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index b80415011dcd..562c27b12d40 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -344,7 +344,7 @@ enum {
 #define HCI_AUTO_OFF_TIMEOUT   msecs_to_jiffies(2000)  /* 2 seconds */
 #define HCI_POWER_OFF_TIMEOUT  msecs_to_jiffies(5000)  /* 5 seconds */
 #define HCI_LE_CONN_TIMEOUT    msecs_to_jiffies(20000) /* 20 seconds */
-#define HCI_LE_AUTOCONN_TIMEOUT    msecs_to_jiffies(4000)  /* 4 seconds */
+#define HCI_LE_AUTOCONN_TIMEOUT    msecs_to_jiffies(20000) /* 20 seconds */

 /* HCI data types */
 #define HCI_COMMAND_PKT        0x01
pvvx commented 2 years ago

@skgsergio - Useless venture. Linux is long dead - it was killed by the Arduino generation. There are hundreds of results and conferences on the topic about the small "HCI_LE_AUTOCONN_TIMEOUT" in Google, and there will not be any fixes. Most Linux users will not be able to use Bluetooth LE due to kernel bugs. This means Linux does not support Bluetooth LE. In the new Bluetooth LE specification (from version 5), there are generally advertisements with unlimited intervals. And the solution used in Linux for connecting to the device is not suitable.

Why is the second advertising event expected after receiving the first reception of the advertising event, if it was possible to establish a connection (send a connection request) at the first reception? Why does the scan window have settings, but the period for BT connections is not? In TCP, all timeouts are user-defined ...

pvvx commented 2 years ago

Set ATC_0B5EED advertise interval to 10000 ms. Initialize NanoPi R1...

OpenWrt 18.06.1, r7258-5eb055306f
root@FriendlyWrt:~# hciattach /dev/ttyS3 bcm43xx 1500000
bcm43xx_init
Patch not found for BCM43430A1, continue anyway
Set Controller UART speed to 1500000 bit/s
Device setup complete
root@FriendlyWrt:~# hciconfig hci0 up

Test 'bluetoothctl'

root@FriendlyWrt:~# bluetoothctl
Agent registered
[bluetooth]# scan on
Discovery started
.......................
….. none A4:C1:38:0B:5E:ED ATC_0B5EED (!)
[bluetooth]# devices
Device xx:xx:xx:xx:xx:xx Qingping Motion & Light
Device xx:xx:xx:xx:xx:xx Qingping Motion & Light
Device xx:xx:xx:xx:xx:xx LYWSD02
[bluetooth]# exit

No ATC_0B5EED scan for 10 minutes! Let's see what 'hcitool' says in the scan:

root@FriendlyWrt:~# hcitool lescan
LE Scan ...
xx:xx:xx:xx:xx:xx ATC_05F8FA
xx:xx:xx:xx:xx:xx ATC_053CF7
xx:xx:xx:xx:xx:xx Qingping Motion & Light
xx:xx:xx:xx:xx:xx LYWSD02
xx:xx:xx:xx:xx:xx Qingping Motion & Light
…
A4:C1:38:0B:5E:ED ATC_0B5EED

Scan ATC_0B5EED finds at once! What's in 'bluetoothctl'?

root@FriendlyWrt:~# bluetoothctl
Agent registered
[bluetooth]# devices
Device xx:xx:xx:xx:xx:xx LYWSD02
Device xx:xx:xx:xx:xx:xx Qingping Motion & Light
Device xx:xx:xx:xx:xx:xx Qingping Motion & Light
[bluetooth]# exit

None device ATC_0B5EED ! Go 'hcitool' and connect... (you can do it right away, without any scans.)

root@FriendlyWrt:~# hcitool lecc A4:C1:38:0B:5E:ED
Connection handle 64

Connection!

Go 'bluetoothctl'...

root@FriendlyWrt:~# bluetoothctl
Agent registered
[ATC_0B5EED]# info
Device A4:C1:38:0B:5E:ED (public)
        Name: ATC_0B5EED
        Alias: ATC_0B5EED
        Paired: yes
        Trusted: no
        Blocked: no
        Connected: yes
        LegacyPairing: no
        UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
        UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
        UUID: Device Information        (0000180a-0000-1000-8000-00805f9b34fb)
        UUID: Battery Service           (0000180f-0000-1000-8000-00805f9b34fb)
        UUID: Environmental Sensing     (0000181a-0000-1000-8000-00805f9b34fb)
        UUID: Unknown                   (00001f10-0000-1000-8000-00805f9b34fb)
        UUID: Vendor specific           (00010203-0405-0607-0809-0a0b0c0d1912)
[ATC_0B5EED]#

Linux, what can I say ... :) :)

'bluetoothctl' cannot scan if there is no 'flag' in the advertisement and cannot connect with an error if the advertisement interval is more than 2 sec.

pvvx commented 2 years ago

Windows 10, Chrome and BT-USB adapters. The device has an Advertising Interval of 10 sec.

Adapter labeled 'Basseus' - scanning ok. Adapter marked "V5.0" - scanning does not find the device. With a shorter interval - approx. ...

skgsergio commented 2 years ago

I wrote to the mailing list (no response yet, but I've found later an old 2016 thread where they say what is their reason not to increase it: link to the response).

Anyway, then I found digging more in the kernel and in bluez that there is a Bluetooth management API and it allows you to change the timeout.

The downside is that is only present since kernel 5.9 and bluez 5.56:

This can be called using bluez's btmgmt tool. The command is set-sysconfig and the option needed is -v 001b:2:xxxx where xxxx is the timeout in hex little-endian.

For example, with nRF Connect setting interval to 12000 (7500ms):

sconde@puck ~/tmp/bluez $ printf "%04x\n" 20000
4e20
sconde@puck ~/tmp/bluez $ sudo btmgmt set-sysconfig -v 001b:2:204e
Set default system configuration success

sconde@puck ~/tmp/bluez $ bluetoothctl
[bluetooth]# menu scan
[bluetooth]# transport le
[bluetooth]# pattern Mi9TPro
[bluetooth]# back

[bluetooth]# scan on
Discovery started
[CHG] Controller 94:B8:6D:87:6C:A6 Discovering: yes
[NEW] Device 63:4B:74:81:8F:BB Mi9TPro

[bluetooth]# connect 63:4B:74:81:8F:BB
Attempting to connect to 63:4B:74:81:8F:BB
[CHG] Device 63:4B:74:81:8F:BB RSSI: -35
[CHG] Device 63:4B:74:81:8F:BB Connected: yes
Connection successful
[NEW] Primary Service (Handle 0x0000)
    /org/bluez/hci0/dev_63_4B_74_81_8F_BB/service0001
    00001801-0000-1000-8000-00805f9b34fb
    Generic Attribute Profile
[NEW] Characteristic (Handle 0x0000)
    /org/bluez/hci0/dev_63_4B_74_81_8F_BB/service0001/char0002
    00002a05-0000-1000-8000-00805f9b34fb
    Service Changed
[CHG] Device 63:4B:74:81:8F:BB UUIDs: 00001800-0000-1000-8000-00805f9b34fb
[CHG] Device 63:4B:74:81:8F:BB UUIDs: 00001801-0000-1000-8000-00805f9b34fb
[CHG] Device 63:4B:74:81:8F:BB ServicesResolved: yes

It is pretty hidden but it worked for me, it has the same effect and when I recompiled the kernel.

Keep in mind this option doesn't persist reboots.

skgsergio commented 2 years ago

Ok, there is a way of properly configuring it and making it persist. It requires bluez 5.55 or newer and kernel 5.9 or newer.

  1. Edit /etc/bluetooth/main.conf
  2. Add/edit the following: If bluez version is 5.55:
    [Controller]
    LEAutoconnecttimeout=10000 # ms

    If bluez version is 5.56 or greater:

    [LE]
    Autoconnecttimeout=10000 # ms

The limit seems to be 0x4000 (16384).

pvvx commented 2 years ago

I wrote to the mailing list (no response yet, but I've found later an old 2016 thread where they say what is their reason not to increase it: link to the response).

The most stupid excuse (those. complete incompetence): _the problem is that in order to send a CONNNECT_REQ, the HCI_LE_Create_Connection command needs to see connectable advertising packet one more time. So the longer time you give to HCI_LE_Create_Connection to find it, the longer everything else in the system is blocked. Since only one HCI_LE_CreateConnection can be running at the same time.

If the adapter does not allow simultaneous operation with other functions, then the connection interval is calculated by a timer. For these adapters, the connection function must be started by a timer before receiving a new advertising package (timer - 10%). And what's the difference - blocked for 4 seconds or 10 seconds? Let it be for 100 ms - this is already blocked and is not the norm. Soon TCP connection in Linux will also start blocking on TIME_WAIT after 120 seconds?

PS: Clearly Arduno crawled into Linux.

pvvx commented 2 years ago

TLSR825x (similar to Xiaomi LYWSD03MMC) automatically calculates the advertisement interval in 2 steps and then adjusts to switch synchronous advertisements and receive advertisements from the follower. Consumption chart. Average 71..75 uA: image

Reception window: image

Discrepancies, because the ad interval should contain a random additive to reduce collisions: image Reception of information later, in response in graph 14 ms. If no reception is observed, then the next timer is similar to the calculated interval. What is the difficulty? Ah, Linux!

henkiejan1 commented 2 years ago

Smartphone with Android and Windows PC is always connected.

Strange enough that it also works without problems on Android because it´s a Linux based operating system....

But on my Samsung S21 with original Android 12 from Samsung disconnect from time to time. In notice also that the battery of the sensor need to be almost new when connect. Than it will work a lot better. Also on Mint 21.

But i like your firmware very much and works really nice! Thank you. :)

pvvx commented 10 months ago

Strange enough that it also works without problems on Android because it´s a Linux based operating system....

“Based on” Linux – long ago rewritten by Google. All that's left of Linux is the name. :)

bam80 commented 10 months ago

2. If bluez version is 5.56 or greater:

        [LE]
        Autoconnecttimeout=10000 # ms

The limit seems to be 0x4000 (16384).

I didn't manage to make it work, tried values between 10000 and 16384 (I have fw advertisement interval of 10s). There is also ScanWindowAutoConnect option, does it need tweaking too?