wifinina driver was not handling concurrent socket connections
correctly. When trying to make multiple socket connections, the sockfd
returned by the first Socket() call would be the same sockfd returned by
subsequent Socket() calls. The problem is the sockfd returned by
Socket() isn't used until Connect() (or Appect()). This would result in
Connect() trying to use the same sockfd for multiple connections,
causing wifinina fw to lock up.
The solution in this PR is to create a new sockfd space managed by the
driver that gives the app a unique, safe sockfd for each connection.
The real underlying sock fd returned by fw is set on Connect() (or
Accept()), and mapped back to the apps sockfd using a map:
sockets map[int]*Socket // keyed by sockfd
Where Socket has a reference to the fw sock:
type Socket struct {
protocol int
clientConnected bool
laddr netip.AddrPort // Set in Bind()
raddr netip.AddrPort // Set in Connect()
sock // Device socket, as returned from w.getSocket()
}
Fix an error I introduced in porting wifinina to netdev. The driver was
starting a client on the socket once, during Connect. The first UDP
send on the socket would succeed, any subsequent sends would fail. The
fix is to start the client on the socket for each UDP send.
I think I see the logic in this design, so the fix makes sense. If the
device was sending to many UDP clients, it could use a single socket,
but change the dst addr for each send. The pkt data would be queued to
hw just once, and then sent from hw to each client dst addr. This would
be a real efficient way to multicast to many clients.
According to man page accept(2), accept returns new client sockfd and
remote peer ip:port. This patch corrects the Accept() prototype in the
netdever interface to not take in an ip:port arg, but rather return an
ip:port for remote peer.
Tested with examples/net/tcpecho on wioterminal and nano-rp2040. Here's
a run with wioterminal:
SERVER
============
sfeldma@nuc:~/work/drivers$ tinygo flash -monitor -target wioterminal -size short -stack-size=8kb ./examples/net/tcpecho
code data bss | flash ram
110876 2552 11212 | 113428 13764
Connected to /dev/ttyACM2. Press Ctrl-C to exit.
Realtek rtl8720dn Wifi network device driver (rtl8720dn)
Driver version : 0.0.1
RTL8720 firmware version : 2.1.2
MAC address : 2c:f7:f1:1c:9b:2f
Connecting to Wifi SSID 'test'...CONNECTED
DHCP-assigned IP : 10.0.0.140
DHCP-assigned subnet : 255.255.255.0
DHCP-assigned gateway : 10.0.0.1
Starting TCP server listening on :8080
Client 10.0.0.190:50000 connected
Client 10.0.0.190:50000 closed
CLIENT
=============
nc -p 50000 10.0.0.140 8080
This moves the netdev/netlink namespace out of drivers and into their
own packages. Also, defines netdev and netlink as L3/L4 and L2 OSI
layers, respectively. Move some L3 functionality from netlink to
netdev (GetIPAddr).
For netlink, add ConnectParams for NetConnect to pass in L2 connection
parameters (ssid, pass, auth_type, etc). Also adds connection mode
(STA, AP, etc).
For netlink, add SendEth and RecvEthFunc funcs to handle L2 send/recv of
Ethernet pkts.
* wifinina: add support for http server
This adds http.ListenAndServe() implementation for wifinina. Included
is an example webserver, basically copied from the rtl8720dn/webserver.
Tested on Arduino Nano RP2040 Connect. Also tried testing on Arduino
Nano33 IoT but test panics with "out of memory". There's only 32K of
SRAM on the Nano33, vs 264K on the rp2040 Connect.
* wifinina: implementation of WiFiNINA driver, including:
- TCP client example is working
- reading sockets and mqtt working
- switched over to common net package also used by espat package
- smoke tests and updated README for wifinina