This implements support for SO_BINDTODEVICE, which allows telling a socket
to use a specific interface instead of lwIP automatically selecting one.
This allows devices that have multiple connections (for example cellular
over PPP in addition to WLAN) to explicitly choose which data is send over
which connection, which may have different reliability and or (mobile data)
costs associated with using them.
The used lwIP network stack already has support for this, so all that was
needed was to expose this functionality in MicroPython. This commit
exposes a new constant SO_BINDTODEVICE which can be set as an socket
option. As a value it expects the name of the interface to bind to. These
names can be retrieved using `.config('ifname')` implemented on each
interface type (including adding in this commit a `.config()` method to
PPP, which it didn't have before), which returns a string with the
interface name:
>>> import machine
>>> import network
>>> network.WLAN(network.AP_IF).config('ifname')
'lo0'
>>> wlan = network.WLAN(network.AP_IF)
>>> wlan.active(True) and wlan.config('ifname')
'ap1'
>>> wlan = network.WLAN(network.STA_IF)
>>> wlan.active(True) and wlan.config('ifname')
'st1'
>>> ppp = network.PPP(machine.UART(0))
>>> ppp.active(True) and ppp.config('ifname')
'pp1'
>>> ppp = network.PPP(machine.UART(0))
>>> ppp.active(True) and ppp.config('ifname')
'pp2'
>>> ppp = network.PPP(machine.UART(0))
>>> ppp.active(True) and ppp.config('ifname')
'pp3'
Note that lo0 seems to be returned by lwIP if the interface is not yet
active. The method can also return None in the case of PPP where the
entire lwIP interface doesn't yet exist before being activated. Currently
no effort is made to unify those cases; it is expected that whatever we
receive from lwIP is valid.
When the socket option is set, this forces using a specific device:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BINDTODEVICE, 'st1')
setsockopt will throw (OSError: [Errno 19] ENODEV) if the specified
interface does not exist.
Tested with LAN, WLAN, and PPP; can specify which interface should be used
and when testing with, for example, HTTP requests to ifconfig.co the
returned IP address confirms a specific interface was used.
Signed-off-by: Daniël van de Giessen <daniel@dvdgiessen.nl>
This commit updates the esp32 port to work exclusively with ESP-IDF v5.
IDF v5 is needed for some of the newer ESP32 SoCs to work, and it also
cleans up a lot of the inconsistencies between existing SoCs (eg S2, S3,
and C3).
Support for IDF v4 is dropped because it's a lot of effort to maintain both
versions at the same time.
The following components have been verified to work on the various SoCs:
ESP32 ESP32-S2 ESP32-S3 ESP32-C3
build pass pass pass pass
SPIRAM pass pass pass N/A
REPL (UART) pass pass pass pass
REPL (USB) N/A pass pass N/A
filesystem pass pass pass pass
GPIO pass pass pass pass
SPI pass pass pass pass
I2C pass pass pass pass
PWM pass pass pass pass
ADC pass pass pass pass
WiFi STA pass pass pass pass
WiFi AP pass pass pass pass
BLE pass N/A pass pass
ETH pass -- -- --
PPP pass pass pass --
sockets pass pass pass pass
SSL pass ENOMEM pass pass
RMT pass pass pass pass
NeoPixel pass pass pass pass
I2S pass pass pass N/A
ESPNow pass pass pass pass
ULP-FSM pass pass pass N/A
SDCard pass N/A N/A pass
WDT pass pass pass pass
Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
Rather than duplicating the implementation of `network`, this allows ESP32
to use the shared one in extmod. In particular this gains access to
network.hostname and network.country.
Set default hostnames for various ESP32 boards.
Other than adding these two methods and the change to the default hostname,
there is no other user-visible change.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>