Commit Graph

17 Commits

Author SHA1 Message Date
Daniël van de Giessen
ba8aad3d1d esp32/modnetwork: Add support for SO_BINDTODEVICE socket option.
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>
2023-09-01 19:21:20 +10:00
Glenn Moloney
dbced75b48 esp32/network_wlan: Wait for STA/AP START/STOP event in wlan.active.
This is a fix for commit bccbaa92b1:
- Should only wait for WIFI_EVENT_STA_START when invoked on the STA_IF
  interface.
- The WIFI_EVENT_STA_START event is generated every time the STA_IF
  interface is set active(True) and it was previously inactive, ie. not
  only after calling esp_wifi_start().
- Also wait for WIFI_EVENT_STA_STOP when deactivating the interface.
- Also wait for relevant AP events.

Fixes issue #11910.

Signed-off-by: Glenn Moloney <glenn.moloney@gmail.com>
Signed-off-by: Damien George <damien@micropython.org>
2023-07-13 11:49:14 +10:00
Damien George
e4650125b8 esp32: Update port to support IDF v5.0.2.
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>
2023-06-23 15:34:22 +10:00
Jim Mussared
7f5d5c7271 all: Rename mod_umodule*, ^umodule* to remove the "u" prefix.
This work was funded through GitHub Sponsors.

Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
2023-06-08 17:54:07 +10:00
Damien George
53cb073571 esp32,esp8266: Change network.WLAN from a function to a type.
When the network module was first introduced in the esp8266 port in
ee3fec3167 there was only one interface (STA)
and, to save flash, the WLAN object was aliased to the network module,
which had just static methods for WLAN operations.  This was subsequently
changed in 9e8396accb when the AP interface
was introduced, and the WLAN object became a true class.

But, network.WLAN remained a function that returned either the STA or AP
object and was never upgraded to the type itself.  This scheme was then
copied over to the esp32 port when it was first introduced.

This commit changes network.WLAN from a function to a reference to the WLAN
type.  This makes it consistent with other ports and network objects, and
allows accessing constants of network.WLAN without creating an instance.

Signed-off-by: Damien George <damien@micropython.org>
2023-05-18 14:52:28 +10:00
Glenn Moloney
7fa322afb8 esp32,esp8266: Add support for the Espressif ESP-NOW protocol.
ESP-NOW is a proprietary wireless communication protocol which supports
connectionless communication between ESP32 and ESP8266 devices, using
vendor specific WiFi frames.  This commit adds support for this protocol
through a new `espnow` module.

This commit builds on original work done by @nickzoic, @shawwwn and with
contributions from @zoland.  Features include:
- Use of (extended) ring buffers in py/ringbuf.[ch] for robust IO.
- Signal strength (RSSI) monitoring.
- Core support in `_espnow` C module, extended by `espnow.py` module.
- Asyncio support via `aioespnow.py` module (separate to this commit).
- Docs provided at `docs/library/espnow.rst`.

Methods available in espnow.ESPNow class are:
- active(True/False)
- config(): set rx buffer size, read timeout and tx rate
- recv()/irecv()/recvinto() to read incoming messages from peers
- send() to send messages to peer devices
- any() to test if a message is ready to read
- irq() to set callback for received messages
- stats() returns transfer stats:
    (tx_pkts, tx_pkt_responses, tx_failures, rx_pkts, lost_rx_pkts)
- add_peer(mac, ...) registers a peer before sending messages
- get_peer(mac) returns peer info: (mac, lmk, channel, ifidx, encrypt)
- mod_peer(mac, ...) changes peer info parameters
- get_peers() returns all peer info tuples
- peers_table supports RSSI signal monitoring for received messages:
    {peer1: [rssi, time_ms], peer2: [rssi, time_ms], ...}

ESP8266 is a pared down version of the ESP32 ESPNow support due to code
size restrictions and differences in the low-level API.  See docs for
details.

Also included is a test suite in tests/multi_espnow.  This tests basic
espnow data transfer, multiple transfers, various message sizes, encrypted
messages (pmk and lmk), and asyncio support.

Initial work is from https://github.com/micropython/micropython/pull/4115.
Initial import of code is from:
https://github.com/nickzoic/micropython/tree/espnow-4115.
2023-05-01 16:47:21 +10:00
Jim Mussared
eb51ca4a11 esp32: Use extmod/modnetwork.c instead of port-specific version.
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>
2023-03-01 01:26:54 +11:00
ma-lalonde
30db33d1e0 esp32/network_lan: Add support for Ethernet PHY KSZ8081.
This is available since ESP-IDF v4.4.

Signed-off-by: Damien George <damien@micropython.org>
2023-01-19 22:50:41 +11:00
Damien Tournoud
e982c1d8de esp32/network_lan: Add support for SPI-based ethernet chips.
Add support for various SPI-based ethernet chips (W5500, KSZ8851SNL,
DM9051) to the ESP32 port.  This leverages the existing support in ESP-IDF
for these chips -- which configures these chips in "MAC raw" mode -- and
the existing support for network.LAN in the ESP32 port.  In particular,
this doesn't leverage the wiznet5k support that is used on the rp2 and
stm32 ports (because that's for native use of lwIP).

Tested on the POE Featherwing (with the SJIRQ solder jumper bridged) and a
ESP32-S3 feather.

A note about the interrupt pin: The W5500 implementation within ESP-IDF
relies on hardware interrupt, and requires the interrupt pin from the W5500
to be wired to a GPIO.  This is not the case by default on the Adafruit
Ethernet FeatherWing, which makes it not directly compatible with this
implementation.
2023-01-18 11:16:09 +11:00
robert-hh
efb4bd3555 esp32/network_lan: Add support for LAN8710 PHY.
LAN8710 uses the same drivers as LAN8720, so this commit just adds the
names.  Alternatively, both could be summarised under LAN87xx, like the
esp-idf does.
2023-01-18 10:04:31 +11:00
Damien George
ea186de4c5 esp32: Split out WLAN code from modnetwork.c to network_wlan.c.
To match network_lan.c and network_ppp.c, and make it clear what code is
specifically for WLAN support.

Also provide a configuration option MICROPY_PY_NETWORK_WLAN which can be
used to fully disable network.WLAN (it's enabled by default).

Signed-off-by: Damien George <damien@micropython.org>
2021-09-24 12:41:35 +10:00
Tobias Eydam
48437cec45 esp32/network_lan: Add Ethernet support for IDF v4.1 and above.
Ethernet-PHYs from ESP-IDF (LAN8720, IP101, RTL8201, DP83848) are now
supported in IDF v4.1 and above.  PHY_KSZ8041 is only for ESP-IDF 4.3 and
above.  ESP32S2 is not supported.

Signed-off-by: Tobias Eydam <eydam-prototyping@outlook.com>
2021-06-17 15:36:14 +10:00
Kenneth Ryerson
76fefad18b esp32/network_lan: Add support for IP101 PHY.
Signed-off-by: Kenneth Ryerson <kenneth.ryerson@gmail.com>
2020-07-21 00:59:47 +10:00
Eric Poulsen
5635b96461 esp32: Add 'config' function to network.LAN, reusing network.WLAN. 2019-08-28 13:11:48 +10:00
Eric Poulsen
3c6f639aa5 esp32/network_ppp: Add PPPoS functionality.
This commit adds network.PPP(stream) which allows to create a TCP/IP
network interface over a stream object (eg a UART).
2018-10-19 23:32:02 +11:00
Damien George
999c8b9711 esp32/modsocket: Add support for registering socket event callbacks.
The esp8266 uses modlwip.c for its usocket implementation, which allows to
easily support callbacks on socket events (like when a socket becomes ready
for reading).  This is not as easy to do for the esp32 which uses the
ESP-IDF-provided lwIP POSIX socket API.  Socket events are needed to get
WebREPL working, and this patch provides a way for such events to work by
explicitly polling registered sockets for readability, and then calling the
associated callback if the socket is readable.
2018-04-27 23:57:26 +10:00
Eric Poulsen
29dd6a7678 esp32: Implement wired Ethernet via network.LAN().
Updates to Makefile, modnetwork.c, and addition of network_lan.c to
implement `network.LAN()` object for wired PHY objects.
2017-12-13 14:48:53 +11:00