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

Added ability to specify WPA2 PSK in place of WiFi password #276

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

devgs
Copy link
Contributor

@devgs devgs commented Apr 7, 2024

This is a feature that's already supported by ESP devices. However, in case of Tuya devices (at least for BK7231N) it's invaluable as it can reduce the connect time by 4 seconds or more. It's all because in order to start negotiation, each client is required to derive the PSK that is a function of SSID and Password. And it's a deterministic function: it can be calculated once, stored somewhere and used many times for the same pair of SSID and Password. Actually, looking at BDK it's obvious that native firmware does exactly that. It even has a caching system that from looks of it is capable of storing multiple records.

Saving and restoring connection parameters is a more complex feature that is not implemented by this PR. However, it can now be easily done with the fixes made in bk_wlan_start_sta_adv_fix. This PR allows user to manually pre-calculate PSK for each of hist networks and use them instead of plain passwords in YAML. Which already works with ESP32/ESP8266, but raises Passphrase too long error in LibreTiny: all due to BDK limitations that are now circumvented.

On my cb3s based door sensor, using fast_connect: true with pre-calculated PSK I have managed to achieve a boot-to-mqtt-and-sleep time that is faster than the original firmware (probably because of higher latency): around 1.25-1.40s. Using a fixed BSSID and channel can push it down 1s or less.

Additionally, this PR removes the need for two supplemental config structs in WiFiClass, STA_CFG and STA_ADV_CFG, in favor of the latter.

More info on PSK can be found here: https://jorisvr.nl/wpapsk.html

This is a feature that's already supported by ESP devices. However, in case of
Tuya devices (at least for BK7231N) it's invaluable as it can reduce the connect
time by 4 seconds or more. It's all because in order to start negotiation, each
client is required to derive the PSK that is a function of SSID and Password.
And it's a deterministic function: it can be calculated once, stored somewhere
and used many times for the same pair of SSID and Password. Actually, looking at
BDK it's obvious that native firmware does exactly that. It even has a caching
system that from looks of it is capable of storing multiple records.

Saving and restoring connection parameters is a more complex feature that is not
implemented by this PR. However, it can now be easily done with the fixes made
in `bk_wlan_start_sta_adv_fix`. This PR allows user to manually pre-calculate
PSK for each of hist networks and use them instead of plain passwords in YAML.
Which already works with ESP32/ESP8266, but raises `Passphrase too long` error
in LibreTiny: all due to BDK limitations that are now circumvented.

On my cb3s based door sensor, using `fast_connect: true` with pre-calculated PSK
I have managed to achieve a boot-to-mqtt-and-sleep time that is faster than the
original firmware (probably because of higher latency): around 1.25-1.40s. Using
a fixed BSSID and channel can push it down 1s or less.

Additionally, this PR removes the need for two supplemental config structs in
WiFiClass, STA_CFG and STA_ADV_CFG, in favor of the latter.

More info on PSK can be found here: https://jorisvr.nl/wpapsk.html
@kuba2k2 kuba2k2 added enhancement New feature or request BK7231 Beken BK72xx family labels Apr 7, 2024
@alessiocappa
Copy link

alessiocappa commented Jul 15, 2024

Hello,
I’m really interested in this PR, since I have the same device (CB3S door sensor) and I’m experiencing the same slowness in connecting after a deep sleep (it can take up to 7/8s to report the state of the sensor).

I tried to change my esphome config (I’m using the latest version - 2024.6.6) to use your branch as framework in the bk72xx section, in order to test this PR and see if I can notice any improvement.

Strangely, I can see that the device can connect really fast in some cases (around 1/2s as you stated), but it can take the same time as before in other cases after waking up from deep sleep.
It seems to be pretty random, so I’m not able to understand what is the root cause behind this different behavior; unfortunately, I don’t have a way to connect the device via serial port to monitor the logs of the WiFi connection, so I’m a bit stuck.

Can you please share your setup, so that I can try testing it as well?

Thanks

@devgs
Copy link
Contributor Author

devgs commented Jul 17, 2024

@alessiocappa Seems like an issue that was fixed by #274. Have you used them both?

@alessiocappa
Copy link

@alessiocappa Seems like an issue that was fixed by #274. Have you used them both?

Thanks, I didn't notice that the branch used for the PR was not up to date with the main one.
However, I tried to fork the repo, merge your PR so that the one you mentioned is included, but I'm still experiencing the same issue unfortunately.

Not sure what could be the reason behind this, I can share my esphome config if needed.
Generally speaking, I've already set a static IP address, and the fast_connect option is enabled.

@devgs
Copy link
Contributor Author

devgs commented Jul 18, 2024

You can enable debug logging and include an example output when this issue occurs.

@alessiocappa
Copy link

Thanks for the feedback, but I cannot seem to get any debug information related to WiFi using the wireless logging option. I don't think there is a way to get such information without connecting the device via serial port; I'll try to see if I can do it to better understand what's happening.

Another thing I noticed is that it seems like this problem appears only if I close/open the sensor shortly after the device goes into deep sleep; if I wait a bit more time (like a couple of minutes), it seems to connect quicker to the WiFi network.
I don't know if that might be related to the deep_sleep parameters, I tried to change the run_duration but the problem is still there.

@devgs
Copy link
Contributor Author

devgs commented Jul 19, 2024

Yes, you definitely need to connect it via serial. Also, maybe turning on the debugging of libretiny itself is going to be required.

Just an example to consider:

bk72xx:
  board: cb3s
  framework:
    version: "0.0.0"
    source: https://github.com/devgs/libretiny@test/devgs

    loglevel: debug
    debug:
      - wifi
      - ota
    sdk_silent: all
    uart_port: 1

@szupi-ipuzs
Copy link
Contributor

Thanks for the feedback, but I cannot seem to get any debug information related to WiFi using the wireless logging option. I don't think there is a way to get such information without connecting the device via serial port; I'll try to see if I can do it to better understand what's happening.

Actually there might be a chance to see this debug info without serial - see my buff_log component.

@toughvj
Copy link

toughvj commented Aug 23, 2024

any news? I have tried use this solution but my esp says that remote branch doe's not exists

@kuba2k2
Copy link
Member

kuba2k2 commented Sep 5, 2024

@devgs
I'm not sure I understand the code correctly. How does it tell if the supplied passphrase parameter is a password or a PSK?

@devgs
Copy link
Contributor Author

devgs commented Sep 5, 2024

@kuba2k2 It's a valid HEX exactly 64 bytes long.

The passphrase length is limited to 63 bytes. For exactly this reason: to be able to easily distinguish them:

A pass-phrase is a sequence of between 8 and 63 ASCII-encoded characters. The limit of 63 comes from the desire to distinguish between a pass-phrase and a PSK displayed as 64 hexadecimal characters.

@devgs
Copy link
Contributor Author

devgs commented Sep 5, 2024

Ah, I was still ambiguous. I mean it's all handled internally by the BDK or even some lower layer. What I said above is what I saw in the source code and that has motivated me to experiment with it and achieve this nice speedup.

@kuba2k2
Copy link
Member

kuba2k2 commented Sep 5, 2024

Right. But I still can't see where the actual length check is implemented Still, the code seems to call wpa_psk_request() no matter the length.

Also, the code in begin() counts the length of passphrase and copies that amount of bytes to STA_ADV_CFG.key. What if the passphrase contains 0x00 bytes?

@devgs
Copy link
Contributor Author

devgs commented Sep 5, 2024

The only difference in this fixup is the use of large enough buffer (on stack) when supplying passphrase in order to squeeze in a 0x00 byte at the end. Even before this PR this same question existed: how would wpa_psk_request() behave if someone supplies 0x00 in the middle of sub-63-byte-long passphrase.

And the reason for an explicit 0x00 is this nice piece of code that simply ignores length and would happily read past the buffer boundaries. I'm not sure whether internals behave the same, but better be safe than sorry.

@kuba2k2
Copy link
Member

kuba2k2 commented Sep 5, 2024

Oh - my bad. I assumed the actual PSK (binary data) was 64 bytes long, then a 0x00 byte inside would cause problems. But if the 64-byte long string is an ASCII hex representation - it should be fine indeed :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BK7231 Beken BK72xx family enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants