For bigger images, the pixel index might not fit in a int16. Therefore,
int is needed during the calculation.
While fixing this bug, I've added a few tests that verify the Image
implementation by creating images, filling them with random data, and
then checking whether they still contain the same data. This test failed
before the patch.
At least one ft6336 device reports all 255 values from the first read
after reset or poweron, even after waiting the specified 300ms reset
delay.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
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()
}
rpc_wifi_connect() will return 0 on successful connection, so check for
that. Also, check that if passphrase is given, that it's the minimum 8
chars per WPA Wifi.
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
Add basis for TCP/IP stack. The stack implements Netdever interface for
the top-end, and calls into a Netlinker interface on the bottom-end.
Each TCP/IP stack instance represents a L3/L4 endpoint with an IP
address. The Netlinker is bound when creating the stack. E.g.:
spi, cs, wlreg, irq := cyw43439.PicoWSpi(0)
cyw43 := cyw43439.NewDevice(spi, cs, wlreg, irq, irq)
stack := tcpip.NewStack(cyw43)
netdev.UseNetdev(stack)
Here, the cyw43439 driver is the Netlinker for the stack. The new stack
is a Netdever, so we tell the "net" package to use the stack as the
netdev. The stack manages L3/L4 socket connections, ultimately calling
into the Netlinker to send/recv L2 Ethernet pkts.
This adds three new L2 (intermediate) drivers for bridge/bond/vlan.
Theses drivers are incomplete but illustrate how to stack L2 drivers.
Here are some examples of how these driver would stack with the cy243439
driver:
Bridge: bridge two cyw43 devices together, connecting the two LANs:
cyw43_0 := cyw43439.NewDevice(...)
cyw43_1 := cyw43439.NewDevice(...)
bridge := NewBridge([]netlink.Netlinker{cyw43_0, cyw43_1})
stack := tcpip.NewStack(bridge)
netdev.UseNetdev(stack)
Bond: bond two cyw43 devices together, creating one logical device.
The first physical device is primary, the second is backup (fail-over)
device:
cyw43_0 := cyw43439.NewDevice(...) // primary
cyw43_1 := cyw43439.NewDevice(...) // secondary (backup)
bond := NewBond([]netlink.Netlinker{cyw43_0, cyw43_1})
stack := tcpip.NewStack(bond)
netdev.UseNetdev(stack)
Vlan: add tagged VLAN ID=100 to cyw43:
cyw43 := cyw43439.NewDevice(...)
vlan100 := NewVlan(100, cyw43)
stack := tcpip.NewStack(vlan100)
netdev.UseNetdev(stack)