Skip to content

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

Merged
merged 7 commits into from
Oct 19, 2022
Merged

Pico W grab bag #7079

merged 7 commits into from
Oct 19, 2022

Conversation

jepler
Copy link

@jepler jepler commented Oct 18, 2022

  • Fix large 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 of send 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 #7077
  • Add sendall(), compatible with CPython, to send a whole buffer with multiple underlying send calls.
  • When lwip debugging is enabled, 16-bit values weren't formatted correctly, because "hu" was not a good string format for mp_printf
  • enabled resolution of .local MDNS names. This still doesn't enable picow to HAVE a ".local" MDNS name.
  • Implemented wifi.Radio.stop_station. After stop_station, the ip address is None. A new connection can be made with connect. There's something weird about the implementation, but I commented on it for future generations / me in 2 weeks from now.

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.
Copy link
Collaborator

@dhalbert dhalbert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One q

Copy link
Member

@anecdata anecdata left a 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.

Copy link
Collaborator

@dhalbert dhalbert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@dhalbert dhalbert merged commit 08e1cdb into adafruit:main Oct 19, 2022
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

Successfully merging this pull request may close these issues.

Pico W HTTPResponse Size Limit of 2920 bytes with No Exception Raised
3 participants