-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Pico W grab bag #7079
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
Pico W grab bag #7079
Conversation
Foamyguy discovered that trying to send >2920 bytes at once consistently failed. I further discovered that sometimes trying to send >1460 bytes would fail too. By "fail", I mean that it would take a very long time (around 200 * 50ms) before erroneously reporting that all bytes were written. In my testing, this change causes larger writes to successfully send either 2920 or 1460 bytes (possibly after doing some 50ms waits for a previous packet to clear). The documentation of socket.send always stated that it COULD send fewer bytes than requested, but adafruit_httpserver assumed that the number of requested bytes were always sent, so after this change alone, adafruit_httpserver will still not work properly. Closes: adafruit#7077 (albeit fixes are needed in adafruit_httpserver too)
The standard Python 'fix' for 'send()' returning prematurely is to use the 'sendall()' method instead. However, this method was not available. adafruit_httpserver will probably need to code a version of it for older versions or for Airlift, but when it's available this code works (Tested on picow sending 8192 bytes) and may be more efficient. (implementing 'sendall' in python should take care to slice a memoryview rather than the original buffer)
Weirdly we have to stop the AP too (which we never started), or cyw43_tcpip_link_status still reports that STA is connected. As long as AP mode isn't implemented, this doesn't matter and we can just do it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One q
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mDNS resolution
Using test code from 7032, all four combinations of regular DNS / mDNS, and relative domain names / FQDNs, now resolve properly.
wifi disconnection
After fresh reset, IPv4 properties populate immediately after connection, and de-populate immediately (to None
) after a disconnect is triggered by wifi.radio.stop_station()
. We should now be able to use the presence of an IPv4 address as a reliable indicator of the station being connected to an AP, consistent withespressif
behavior. But note that connections are still currently maintained across reloads, unlike espressif
.
import time
import wifi
import socketpool
from secrets import secrets
pool = socketpool.SocketPool(wifi.radio)
def ipv4_info():
return wifi.radio.ipv4_address, wifi.radio.ipv4_gateway, wifi.radio.ipv4_subnet, wifi.radio.ipv4_dns
print(f"{ipv4_info()}")
while True:
print(f"Connecting... ", end="")
wifi.radio.connect(secrets["ssid"], secrets["password"])
print(f"{ipv4_info()}")
print(f"Disconnecting... ", end="")
wifi.radio.stop_station()
print(f"{ipv4_info()}")
time.sleep(1)
yields:
(None, None, None, None) # if device was connected before a reload, it will show connected IPv4 info here
Connecting... (192.168.6.202, 192.168.4.1, 255.255.252.0, 1.1.1.2)
Disconnecting... (None, None, None, None)
# rinse, repeat
Addendum 1: I've seen one case among dozens where the IPv4 info was not cleared after disconnect. I'll add some instrumentation to see how long it takes in that case.
Addendum 2: Seems to take additional time in the range of about 10ms to some tens of milliseconds in the cases where it's not "immediate" in the CircuitPython code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
send()
requests on stream packets. Now, they will correctly send only part of the buffer. Typically, 2920 bytes (2×MSS) can be sent on an idle socket, or 1460 bytes (1×MSS) on a socket that's recently seen a transmission. This has always been according to the documentation ofsend
but previously send was expected to act like sendall by e.g., adafruit_httpserver. Closes: Pico W HTTPResponse Size Limit of 2920 bytes with No Exception Raised #7077sendall()
, compatible with CPython, to send a whole buffer with multiple underlyingsend
calls..local
MDNS names. This still doesn't enable picow to HAVE a ".local" MDNS name.wifi.Radio.stop_station
. Afterstop_station
, the ip address is None. A new connection can be made withconnect
. There's something weird about the implementation, but I commented on it for future generations / me in 2 weeks from now.