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

Allow Access Point static IPv4 on the raspberrypi port #7976

Merged
merged 4 commits into from
May 16, 2023
Merged

Allow Access Point static IPv4 on the raspberrypi port #7976

merged 4 commits into from
May 16, 2023

Conversation

anecdata
Copy link
Member

@anecdata anecdata commented May 14, 2023

Like #7946 but for raspberrypi. The two PRs together should fully address #7931.

Draft for now... took a first stab at PicoW AP static IPv4. A couple of oddities...

  1. Unlike espressif, AP needs to be started before the IPv4 address can be set:
Adafruit CircuitPython 8.1.0-beta.2-33-gcd41fb101 on 2023-05-14; Raspberry Pi Pico W with rp2040
>>> import wifi
>>> import ipaddress
>>> 
>>> ipv4 = ipaddress.IPv4Address("192.168.251.2")
>>> netmask = ipaddress.IPv4Address("255.255.255.0")
>>> gateway = ipaddress.IPv4Address("192.168.251.1")
>>> wifi.radio.set_ipv4_address_ap(ipv4=ipv4, netmask=netmask, gateway=gateway)
>>> wifi.radio.ipv4_address_ap
>>> 
>>> wifi.radio.start_ap("Bob", "YourUncle")
>>> wifi.radio.ipv4_address_ap
192.168.4.1
>>> 
>>> wifi.radio.set_ipv4_address_ap(ipv4=ipv4, netmask=netmask, gateway=gateway)
>>> wifi.radio.ipv4_address_ap
192.168.251.2

This means that there will be an interval where something could connect to the AP with the wrong IP range, and that address could conflict with another network.

  1. The connecting station gets IP address 192.168.4.16 (expected 192.168.251.3), so something more needs to be done with the AP DHCP server.

@anecdata
Copy link
Member Author

Turns out that lwip only provides the DHCP client. The DHCP server comes from shared/netutils, and it is inited only once, deep in the cyw43 driver when wifi is inited:
https://github.com/georgerobotics/cyw43-driver/blob/05d76fe0091f3a3383d5e310b604ddc7d9556ed2/src/cyw43_lwip.c#L236
I'm not sure if or how the DHCP server can be turned off and re-started, without a lot of side effects.

@anecdata
Copy link
Member Author

Turns out that the netutils DHCP server can be turned off and back on again without obvious side effects.

AP:

Adafruit CircuitPython 8.1.0-beta.2-32-gcf124ab85 on 2023-05-14; Raspberry Pi Pico W with rp2040
>>> import wifi, ipaddress
>>> 
>>> ipv4 = ipaddress.IPv4Address("192.168.251.2")
>>> netmask = ipaddress.IPv4Address("255.255.255.0")
>>> gateway = ipaddress.IPv4Address("192.168.251.1")
>>> wifi.radio.start_ap("Bob", "YourUncle")
>>> wifi.radio.set_ipv4_address_ap(ipv4=ipv4, netmask=netmask, gateway=gateway)
>>> wifi.radio.ipv4_address_ap
192.168.251.2

Station (separate device):

>>> import wifi
>>> wifi.radio.ipv4_address
>>> 
>>> wifi.radio.connect("Bob", "YourUncle")
>>> wifi.radio.ipv4_address
192.168.251.16

Tested by connecting to the AP from another CircuitPython device and from a desktop computer. Also ran a TCP echo server on the static IPv4 PicoW AP, and sent packets to it from a TCP client on the connected CircuitPython station:

Output from TCP server on the AP...
code.py output:
Create TCP Server socket ('192.168.251.2', 5000)
Listening
Accepting connections
Accepted from ('192.168.251.16', 57117)
Received bytearray(b'Hello, world') 12 bytes
Sent bytearray(b'Hello, world') 12 bytes
# ...etc.

Output from TCP client on the station...

code.py output:
Self IP 192.168.251.16
Server ping 192.168.251.2 0.0 ms
Create TCP Client Socket
Connecting
Sent 12 bytes
Received 12 bytes bytearray(b'Hello, world')
# ...etc.

I don't know why the station IP address jumps to .16 (espressif increments connected station IPv4 adddresses by one from the AP IPv4), but it does this in the default DHCP case also (without static IPv4).

I'd appreciate careful review, this is my first dive into the depths of the PicoW internals.

@anecdata anecdata marked this pull request as ready for review May 15, 2023 01:56
@anecdata anecdata linked an issue May 15, 2023 that may be closed by this pull request
Copy link

@bill88t bill88t left a comment

Choose a reason for hiding this comment

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

I have only fumbled a little bit with lwip (back when I did AP), but looks good to me.

Copy link
Member

@tannewt tannewt left a comment

Choose a reason for hiding this comment

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

I'm fine merging as-is. I don't know a ton about the LWIP internals either but if it works, then it should be ok.

@anecdata
Copy link
Member Author

anecdata commented May 15, 2023

The changes are isolated to the affected API, so there should be minimal risk to code that is not using wifi.radio.set_ipv4_address_ap (or for some other reason trying to stop DHCP and restart it).

I realized I didn't put in the #if CYW43_NETUTILS conditional that is in the georgerobotics cyw43 driver. Not sure if that's expected to be replicated at this level. But the #if LWIP_DHCP conditional doesn't appear in our code either.

@dhalbert dhalbert requested a review from jepler May 16, 2023 01:43
@dhalbert dhalbert merged commit f2bfced into adafruit:main May 16, 2023
@anecdata anecdata deleted the ap_ipv4_picow branch May 19, 2023 21:08
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.

Wifi access point: setting subnet parameters
4 participants