From 7506448bd9afe2d2236d0823772a54aafdce8a64 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Fri, 5 Jun 2026 09:37:26 +0200 Subject: [PATCH] all: update to latest lneto This updates the espradio package to use the latest lneto which has required changes to restore full functionality with the espradio netlink package. Signed-off-by: deadprogram --- README.md | 2 +- espstack.go | 3 +-- examples/ap/main-ap.go | 7 ++++--- examples/connect-and-dhcp/main-dhcp.go | 9 ++++++++- examples/http-app/main-http.go | 14 ++++++++++---- examples/http-static/main-httpstatic.go | 12 +++++++++--- go.mod | 2 +- go.sum | 4 ++-- netlink/errors.go | 8 ++++++++ netlink/netlink.go | 14 +++++++++----- radio_esp32c3.go | 4 ++-- 11 files changed, 55 insertions(+), 24 deletions(-) create mode 100644 netlink/errors.go diff --git a/README.md b/README.md index 02c42c9..05bd703 100644 --- a/README.md +++ b/README.md @@ -305,7 +305,7 @@ listening on http://192.168.1.46:80 Minimal HTTP server that serves a static webpage using the low-level lneto interface. ``` -$ tinygo flash -target xiao-esp32c3 -ldflags="-X main.ssid=yourssid -X main.password=YourPasswordHere" -monitor 8kb ./examples/http-static/ +$ tinygo flash -target xiao-esp32c3 -ldflags="-X main.ssid=yourssid -X main.password=YourPasswordHere" -monitor ./examples/http-static/ Connected to ESP32-C3 Flashing: 627504/627504 bytes (100%) Connected to /dev/ttyACM0. Press Ctrl-C to exit. diff --git a/espstack.go b/espstack.go index 93becc1..11a5af3 100644 --- a/espstack.go +++ b/espstack.go @@ -48,7 +48,6 @@ func NewStack(dev *NetDev, cfg StackConfig) (*Stack, error) { stack := &Stack{dev: dev} const MTU = MaxFrameSize - ethernet.MaxOverheadSize + 4 // CRC not included:+4 err = stack.s.Reset(xnet.StackConfig{ - StaticAddress: cfg.StaticAddress, DNSServer: cfg.DNSServer, NTPServer: cfg.NTPServer, Hostname: cfg.Hostname, @@ -131,6 +130,6 @@ func (stack *Stack) SetupWithDHCP(cfg DHCPConfig) (*xnet.DHCPResults, error) { if err != nil { return dhcpResults, err } - lstack.SetGateway6(gatewayHW) + lstack.SetGatewayHardwareAddr(gatewayHW) return dhcpResults, nil } diff --git a/examples/ap/main-ap.go b/examples/ap/main-ap.go index 30df6c1..e58c4b7 100644 --- a/examples/ap/main-ap.go +++ b/examples/ap/main-ap.go @@ -7,7 +7,8 @@ import ( "net/netip" "time" - "github.com/soypat/lneto/dhcpv4" + "github.com/soypat/lneto/dhcp/dhcpv4" + "github.com/soypat/lneto/ipv4" "tinygo.org/x/espradio" ) @@ -61,13 +62,13 @@ func main() { err = dhcpServer.Configure(dhcpv4.ServerConfig{ ServerAddr: addr.As4(), Gateway: addr.As4(), - Subnet: subnet, + Subnet: ipv4.PrefixFromNetip(subnet), }) if err != nil { failure("ap: dhcp server configure err: " + err.Error()) } - err = stack.LnetoStack().RegisterUDP(&dhcpServer, nil, dhcpv4.DefaultClientPort) + err = stack.LnetoStack().RegisterUDP4(&dhcpServer, addr.As4(), dhcpv4.DefaultClientPort) if err != nil { failure("ap: dhcp server register err: " + err.Error()) } diff --git a/examples/connect-and-dhcp/main-dhcp.go b/examples/connect-and-dhcp/main-dhcp.go index f0ebd65..c8b634f 100644 --- a/examples/connect-and-dhcp/main-dhcp.go +++ b/examples/connect-and-dhcp/main-dhcp.go @@ -3,6 +3,7 @@ package main import ( + "net/netip" "time" "tinygo.org/x/espradio" @@ -65,7 +66,13 @@ func main() { if err != nil { failure("DHCP failed: " + err.Error()) } - println("got IP:", dhcp.AssignedAddr.String()) + + addr, ok := netip.AddrFromSlice(dhcp.AssignedAddr4[:]) + if !ok { + failure("invalid IP address") + } + + println("got IP:", addr.String()) println("gateway:", dhcp.Router.String()) if len(dhcp.DNSServers) > 0 { println("DNS:", dhcp.DNSServers[0].String()) diff --git a/examples/http-app/main-http.go b/examples/http-app/main-http.go index 81251ce..346bacc 100644 --- a/examples/http-app/main-http.go +++ b/examples/http-app/main-http.go @@ -98,7 +98,13 @@ func main() { if err != nil { failure("DHCP failed: " + err.Error()) } - println("got IP:", dhcp.AssignedAddr.String()) + + addr, ok := netip.AddrFromSlice(dhcp.AssignedAddr4[:]) + if !ok { + failure("invalid IP address") + } + + println("got IP:", addr.String()) lstack := espstack.LnetoStack() rstack := lstack.StackRetrying(lneto.BackoffStrategy(func(_ uint) time.Duration { @@ -108,7 +114,7 @@ func main() { if err != nil { failure("ARP resolve failed: " + err.Error()) } - lstack.SetGateway6(gatewayHW) + lstack.SetGatewayHardwareAddr(gatewayHW) // DNS lookup for NTP server and calculate time. If this fails just ignore. println("resolving ntp host:", ntpHost) @@ -138,13 +144,13 @@ func main() { failure("tcppool create: " + err.Error()) } - listenAddr := netip.AddrPortFrom(dhcp.AssignedAddr, listenPort) + listenAddr := netip.AddrPortFrom(addr, listenPort) var listener tcp.Listener err = listener.Reset(listenPort, tcpPool) if err != nil { failure("listener reset: " + err.Error()) } - err = lstack.RegisterListener(&listener) + err = lstack.RegisterListenerTCP(&listener) if err != nil { failure("listener register: " + err.Error()) } diff --git a/examples/http-static/main-httpstatic.go b/examples/http-static/main-httpstatic.go index 9557478..4771cab 100644 --- a/examples/http-static/main-httpstatic.go +++ b/examples/http-static/main-httpstatic.go @@ -88,7 +88,7 @@ func main() { // VERY IMPORTANT TO START BEFORE USING STACK! go loopForeverStack(espstack) - dhcpResults, err := espstack.SetupWithDHCP(espradio.DHCPConfig{}) + dhcp, err := espstack.SetupWithDHCP(espradio.DHCPConfig{}) if err != nil { failure("DHCP failed: " + err.Error()) } @@ -111,7 +111,13 @@ func main() { } lstack := espstack.LnetoStack() - listenAddr := netip.AddrPortFrom(dhcpResults.AssignedAddr, listenPort) + addr, ok := netip.AddrFromSlice(dhcp.AssignedAddr4[:]) + if !ok { + failure("invalid IP address") + } + + println("got IP:", addr.String()) + listenAddr := netip.AddrPortFrom(addr, listenPort) // Create and register TCP listener. var listener tcp.Listener @@ -119,7 +125,7 @@ func main() { if err != nil { failure("listener reset: " + err.Error()) } - err = lstack.RegisterListener(&listener) + err = lstack.RegisterListenerTCP(&listener) if err != nil { failure("listener register: " + err.Error()) } diff --git a/go.mod b/go.mod index e85f203..6b5f585 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module tinygo.org/x/espradio go 1.24.4 require ( - github.com/soypat/lneto v0.1.1-0.20260425023453-aa77403a2b32 + github.com/soypat/lneto v0.1.1-0.20260527165357-24d5d303bcb8 tinygo.org/x/drivers v0.35.0 ) diff --git a/go.sum b/go.sum index 4063f69..94aa8d9 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/soypat/lneto v0.1.1-0.20260425023453-aa77403a2b32 h1:4fNa4mcNPVTMJ3Kzn+cS/LqmpXhKM9SiZ9Vgu/Ucq3c= -github.com/soypat/lneto v0.1.1-0.20260425023453-aa77403a2b32/go.mod h1:Be5PjwoYukvHFiUXxpYi8+ppH2F/gw/vjGBvFdv+Ti8= +github.com/soypat/lneto v0.1.1-0.20260527165357-24d5d303bcb8 h1:w0XI6cvLwkR+7FQa3zKiziBpRq+yrtBGCYbdThy8H5A= +github.com/soypat/lneto v0.1.1-0.20260527165357-24d5d303bcb8/go.mod h1:Be5PjwoYukvHFiUXxpYi8+ppH2F/gw/vjGBvFdv+Ti8= github.com/soypat/natiu-mqtt v0.6.0 h1:ddrem9iAqFYtQOx2C7AhCizhPXXmGZs1T5fkvLroPO4= github.com/soypat/natiu-mqtt v0.6.0/go.mod h1:xEta+cwop9izVCW7xOx2W+ct9PRMqr0gNVkvBPnQTc4= tinygo.org/x/drivers v0.35.0 h1:cTK36tsI/S4Mg3hCPH0MBjV/ta7XKQ+wpvch4mVqgsE= diff --git a/netlink/errors.go b/netlink/errors.go new file mode 100644 index 0000000..9f72759 --- /dev/null +++ b/netlink/errors.go @@ -0,0 +1,8 @@ +package netlink + +import "errors" + +var ( + errInvalidIPAddress = errors.New("invalid IP address") + errEmptyHostname = errors.New("empty hostname") +) diff --git a/netlink/netlink.go b/netlink/netlink.go index 67c616e..694d020 100644 --- a/netlink/netlink.go +++ b/netlink/netlink.go @@ -1,7 +1,6 @@ package netlink import ( - "errors" "net" "net/netip" "sync" @@ -98,7 +97,7 @@ func (n *Esplink) NetConnect(params *nl.ConnectParams) error { Hostname: params.Ssid, MaxUDPPorts: 2, MaxTCPPorts: 1, - PassivePeers: 3, + PassivePeers: 255, }) if err != nil { if debug { @@ -168,7 +167,7 @@ func (n *Esplink) GetHardwareAddr() (net.HardwareAddr, error) { if debug { println("GetHardwareAddr") } - hw := n.netstack.LnetoStack().HardwareAddress() + hw := n.netstack.LnetoStack().HardwareAddr() return hw[:], nil } @@ -182,7 +181,7 @@ func (n *Esplink) GetHostByName(name string) (netip.Addr, error) { if debug { println("GetHostByName: empty name") } - return netip.Addr{}, errors.New("empty name") + return netip.Addr{}, errEmptyHostname } else if name[0] >= '0' && name[0] <= '9' { // Special case to try for IPv4 addresses. addr, err := netip.ParseAddr(name) @@ -209,7 +208,12 @@ func (n *Esplink) Addr() (netip.Addr, error) { if debug { println("Addr") } - return n.netstack.LnetoStack().Addr(), nil + addr4 := n.netstack.LnetoStack().Addr4() + addr, ok := netip.AddrFromSlice(addr4[:]) + if !ok { + return netip.Addr{}, errInvalidIPAddress + } + return addr, nil } // Berkely Sockets-like interface, Go-ified. See man page for socket(2), etc. diff --git a/radio_esp32c3.go b/radio_esp32c3.go index 4cd8d7f..98135f4 100644 --- a/radio_esp32c3.go +++ b/radio_esp32c3.go @@ -63,8 +63,8 @@ func initHardware() error { // https://github.com/esp-rs/esp-wifi/blob/v0.2.0/esp-wifi/src/timer/riscv.rs#L28 const ticksPerSecond = 16_000_000 -// C3 has only 321KB DRAM total; keep the arena pool small. -const arenaPoolSize = 32 * 1024 +// C3 has only 321KB DRAM total, however 48KB is required for the arena pool for netlink. +const arenaPoolSize = 48 * 1024 // ESP32-C3 (RISC-V): call the blob's WiFi ISR directly from the // hardware interrupt handler. On RISC-V the interrupt context can