net: updates/cleanup/docs for net, netdev, and netlink

This commit is contained in:
Scott Feldman
2023-06-11 20:34:18 -07:00
committed by Ron Evans
parent 196d1dd58d
commit 3089bf8b1b
23 changed files with 232 additions and 869 deletions
+115 -171
View File
@@ -1,12 +1,10 @@
#### Table of Contents
### Table of Contents
- ["net" Package](#net-package)
- [Using "net" Package](#using-net-package)
- [Using "net/http" Package](#using-nethttp-package)
- [Using "crypto/tls" Package](#using-cryptotls-package)
- [Using Sockets](#using-sockets)
- [Netdev and Netlink](#netdev-and-netlink)
- [Writing a New Netdev Driver](#writing-a-new-netdev-driver)
## "net" Package
@@ -14,7 +12,7 @@ TinyGo's "net" package is ported from Go. The port offers a subset of Go's
"net" package. The subset maintains Go 1 compatiblity guarantee. A Go
application that uses "net" will most-likey just work on TinyGo if the usage is
within the subset offered. (There may be external constraints such as limited
SRAM on embedded environment that may limit full functionality).
SRAM on some targets that may limit full "net" functionality).
Continue below for details on using "net" and "net/http" packages.
@@ -24,121 +22,110 @@ TinyGo's "net" package.
## Using "net" Package
Ideally, TinyGo's "net" package would be Go's "net" package and applications
using "net" would just work, as-is. TinyGo's net package is a partial port
from Go's net package, replacing OS socket syscalls with netdev socket calls.
Netdev is TinyGo's network device driver model; read more about
[Netdev](#netdev-and-netlink).
using "net" would just work, as-is. TinyGo's net package is a partial port of
Go's net package, so some things may not work because they have not been
ported.
There are a few features excluded during the porting process, in particular:
- No IPv6 support
- No DualStack support
Run ```go doc -all ./src/net``` in TinyGo repo to see full listing.
Run ```go doc -all ./src/net``` in TinyGo repo to see full listing of what has
been ported. Here is a list of things known to work. You can find examples
of these at [examples/net](examples/net/).
### What is Known to Work
(These are all IPv4 only).
- TCP client and server
- UDP client
- TLS client
- HTTP client and server
- HTTPS client
- NTP client (UDP)
- MQTT client (paho & natiu)
- WebSocket client and server
Multiple sockets can be opened in a single app. For example, the app could run
as an http server listen on port :80 and also use NTP to get the current time
or send something over MQTT. There is a practical limit to the number of
active sockets per app, around 8 or 10, so don't go crazy.
Applications using Go's net package will need a few setup steps to work with
TinyGo's net package.
TinyGo's net package. The steps are required before using "net".
### Step 1: Create the netdev for your target device.
### Step 1: Probe to Load Network Driver
The available netdev are:
- [wifinina]: ESP32 WiFi co-controller running Arduino WiFiNINA firmware
targets: pyportal arduino_nano33 nano_rp2040 metro_m4_airlift
arduino_mkrwifi1010 matrixportal_m4
- [rtl8720dn]: RealTek WiFi rtl8720dn co-controller
targets: wioterminal
- [espat]: ESP32/ESP8266 WiFi co-controller running Espressif AT firmware
targets: TBD
This example configures and creates a wifinina netdev using New().
Call Probe() to load the correct network driver for your target. Probe()
allows the app to work on multiple targets.
```go
import "tinygo.org/x/drivers/wifinina"
package main
func main() {
cfg := wifinina.Config{Ssid: "foo", Passphrase: "bar"}
netdev := wifinina.New(&cfg)
...
}
```
New() registers the netdev with the "net" package using net.useNetdev().
The Config structure is netdev-specific; consult the specific netdev package
for Config details. In this case, the WiFi credentials are passed, but other
settings are typically passed such as device configuration.
### Step 2: Connect to an IP Network
Before the net package is fully functional, connect the netdev to an underlying
IP network. For example, a WiFi netdev would connect to a WiFi access point or
become a WiFi access point; either way, once connected, the netdev has a
station IP address and is connected on the IP network. Similarly, a LTE netdev
would connect to a LTE provider, giving the device an IP address on the LTE
network.
Using the Netlinker interface, Call netdev.NetConnect() to connect the device
to an IP network. Call netdev.NetDisconnect() to disconnect. Continuing example:
```go
import (
"tinygo.org/x/drivers/wifinina"
"tinygo.org/x/drivers/netlink/probe"
)
func main() {
cfg := wifinina.Config{Ssid: "foo", Passphrase: "bar"}
netdev := wifinina.New(&cfg)
netdev.NetConnect()
// load network driver for target
link, dev := probe.Probe()
// "net" package calls here
...
}
```
netdev.NetDisconnect()
Probe() will load the driver with default configuration for the target. For
custom configuration, the app can open code Probe() for the target
requirements.
Probe() returns a [Netlinker](netlink/README.md) and a
[Netdever](netdev/README.md), interfaces implemented by the network driver.
Next, we'll use the Netlinker interface to connect the target to an IP network.
### Step 2: Connect to an IP Network
Before the net package is fully functional, we need to connect the target to an
IP network.
```go
package main
import (
"tinygo.org/x/drivers/netlink"
"tinygo.org/x/drivers/netlink/probe"
)
func main() {
// load network driver for target
link, _ := probe.Probe()
// Connect target to IP network
link.NetConnect(&netlink.ConnectParams{
Ssid: "my SSID",
Passphrase: "my passphrase",
})
// OK to use "net" from here on
...
}
```
Optionally, get notified of IP network connects and disconnects:
```go
netdev.Notify(func(e drivers.NetlinkEvent) {
link.Notify(func(e netlink.Event) {
switch e {
case drivers.NetlinkEventNetUp:
println("Network UP")
case drivers.NetlinkEventNetDown:
println("Network DOWN")
case netlink.EventNetUp: println("Network UP")
case netlink.EventNetDown: println("Network DOWN")
})
```
Here is a simple example of an http server listening on port :8080, before and
after:
Here is an example of an http server listening on port :8080:
#### Before
```go
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", HelloServer)
http.ListenAndServe(":8080", nil)
}
func HelloServer(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
}
```
#### After
```go
package main
@@ -146,21 +133,29 @@ import (
"fmt"
"net/http"
"tinygo.org/x/drivers/wifinina"
"tinygo.org/x/drivers/netlink"
"tinygo.org/x/drivers/netlink/probe"
)
func main() {
cfg := wifinina.Config{Ssid: "foo", Passphrase: "bar"}
netdev := wifinina.New(&cfg)
netdev.NetConnect()
http.HandleFunc("/", HelloServer)
http.ListenAndServe(":8080", nil)
}
func HelloServer(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
}
func main() {
// load network driver for target
link, _ := probe.Probe()
// Connect target to IP network
link.NetConnect(&netlink.ConnectParams{
Ssid: "my SSID",
Passphrase: "my passphrase",
})
// Serve it up
http.HandleFunc("/", HelloServer)
http.ListenAndServe(":8080", nil)
}
```
## Using "net/http" Package
@@ -191,17 +186,17 @@ protocol. This is different from Go's crypto/tls package which handles the TLS
protocol in software.
TinyGo's TLS support is only available for client applications. You can
http.Get() to an http:// or https:// address, but you cannot
http.ListenAndServeTLS() an https server.
http.Get() to an https:// address, but you cannot http.ListenAndServeTLS() an
https server.
The offloading hardware has pre-defined TLS certificates built-in.
## Using Sockets
A netdev implements a BSD socket-like interface so an application can make direct
socket calls, bypassing the net package.
The Netdever interface is a BSD socket-like interface so an application can make direct
socket calls, bypassing the "net" package for the lowest overhead.
Here is a simple TCP application using direct sockets:
Here is a simple TCP client application using direct sockets:
```go
package main
@@ -209,81 +204,30 @@ package main
import (
"net" // only need to parse IP address
"tinygo.org/x/drivers"
"tinygo.org/x/drivers/wifinina"
"tinygo.org/x/drivers/netdev"
"tinygo.org/x/drivers/netlink"
"tinygo.org/x/drivers/netlink/probe"
)
func main() {
cfg := wifinina.Config{Ssid: "foo", Passphrase: "bar"}
netdev := wifinina.New(&cfg)
// ignoring error handling
// load network driver for target
link, dev := probe.Probe()
netdev.NetConnect()
// Connect target to IP network
link.NetConnect(&netlink.ConnectParams{
Ssid: "my SSID",
Passphrase: "my passphrase",
})
sock, _ := netdev.Socket(drivers.AF_INET, drivers.SOCK_STREAM, drivers.IPPROTO_TCP)
// omit error handling
netdev.Connect(sock, "", net.ParseIP("10.0.0.100"), 8080)
netdev.Send(sock, []bytes("hello"), 0, 0)
sock, _ := dev.Socket(netdev.AF_INET, netdev.SOCK_STREAM, netdev.IPPROTO_TCP)
netdev.Close(sock)
dev.Connect(sock, "", net.ParseIP("10.0.0.100"), 8080)
dev.Send(sock, []bytes("hello"), 0, 0)
dev.Close(sock)
link.NetDisconnect()
}
```
## Netdev and Netlink
Netdev is TinyGo's network device driver model. Network drivers implement the
netdever interface, providing a common network I/O interface to TinyGo's "net"
package. The interface is modeled after the BSD socket interface. net.Conn
implementations (TCPConn, UDPConn, and TLSConn) use the netdev interface for
device I/O access. For example, net.DialTCP, which returns a net.TCPConn,
calls netdev.Socket() and netdev.Connect():
```go
func DialTCP(network string, laddr, raddr *TCPAddr) (*TCPConn, error) {
fd, _ := netdev.Socket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
netdev.Connect(fd, "", raddr.IP, raddr.Port)
return &TCPConn{
fd: fd,
laddr: laddr,
raddr: raddr,
}, nil
}
```
Network drivers also (optionally) implement the Netlinker interface. This
interface is not used by TinyGo's "net" package, but rather provides the TinyGo
application direct access to the network device for common settings and control
that fall outside of netdev's socket interface.
## Writing a New Netdev Driver
A new netdev driver will implement the netdever and optionally the Netlinker
interfaces. See the wifinina or rtl8720dn drivers for examples.
#### Locking
Multiple goroutines may invoke methods on a net.Conn simultaneously, and since
the net package translates net.Conn calls into netdev socket calls, it follows
that multiple goroutines may invoke socket calls, so locking is required to
keep socket calls from stepping on one another.
Don't hold a lock while Time.Sleep()ing waiting for a hardware operation to
finish. Unlocking while sleeping let's other goroutines make progress. If the
sleep period is really small, then you can get away with holding the lock.
#### Sockfd
The netdev socket interface uses a socket fd (int) to represent a socket
connection (end-point). Each net.Conn maps 1:1 to a fd. The number of fds
available is a hardware limitation. Wifinina, for example, can hand out 10
fds.
### Testing
The netdev driver should minimally run all of the example/net examples.
TODO: automate testing to catch regressions.
-7
View File
@@ -125,13 +125,6 @@ func (d *Device) NetNotify(cb func(netlink.Event)) {
// Not supported
}
func (d *Device) SendEth(pkt []byte) error {
return netlink.ErrNotSupported
}
func (d *Device) RecvEthFunc(cb func(pkt []byte) error) {
}
func (d *Device) GetHostByName(name string) (net.IP, error) {
ip, err := d.GetDNS(name)
return net.ParseIP(ip), err
-45
View File
@@ -28,11 +28,6 @@ var (
port string = ":80"
)
var (
// this is the ESP chip that has the WIFININA firmware flashed on it
adaptor *wifinina.Device
)
var led = machine.LED
func main() {
@@ -182,43 +177,3 @@ func cnt(w http.ResponseWriter, r *http.Request) {
w.Header().Set(`Content-Type`, `application/json`)
fmt.Fprintf(w, `{"cnt": %d}`, counter)
}
const retriesBeforeFailure = 3
// connect to access point
func connectToAP() {
time.Sleep(2 * time.Second)
var err error
for i := 0; i < retriesBeforeFailure; i++ {
println("Connecting to " + ssid)
err = adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second)
if err == nil {
println("Connected.")
return
}
}
// error connecting to AP
failMessage(err.Error())
}
func displayIP() {
ip, _, _, err := adaptor.GetIP()
for ; err != nil; ip, _, _, err = adaptor.GetIP() {
message(err.Error())
time.Sleep(1 * time.Second)
}
message("IP address: " + ip.String())
}
func message(msg string) {
println(msg, "\r")
}
func failMessage(msg string) {
for {
println(msg)
time.Sleep(1 * time.Second)
}
}
+78
View File
@@ -0,0 +1,78 @@
### Table of Contents
- [Netdever](#netdever)
- [Netdev Driver](#netdev-driver)
- [Netdev Driver Notes](#netdev-driver-notes)
## Netdever
TinyGo's network device driver model comprises two Go interfaces: Netdever and
Netlinker. This README covers Netdever.
The Netdever interface describes an L4/L3 network interface modeled after the
BSD sockets. A netdev is a concrete implementation of a Netdever. See
[Netlinker](../netlink/) for the L2 network interface.
A netdev can:
- Send and receive L4/L3 packets
- Resolve DNS lookups
- Get/set the device's IP address
TinyGo network drivers implement the Netdever interface, providing a BSD
sockets interface to TinyGo's "net" package. net.Conn implementations
(TCPConn, UDPConn, and TLSConn) use the netdev socket. For example,
net.DialTCP, which returns a net.TCPConn, calls netdev.Socket() and
netdev.Connect():
```go
func DialTCP(network string, laddr, raddr *TCPAddr) (*TCPConn, error) {
fd, _ := netdev.Socket(netdev.AF_INET, netdev.SOCK_STREAM, netdev.IPPROTO_TCP)
netdev.Connect(fd, "", raddr.IP, raddr.Port)
return &TCPConn{
fd: fd,
laddr: laddr,
raddr: raddr,
}, nil
}
```
## Setting Netdev
Before the app can use TinyGo's "net" package, the app must set the netdev
using UseNetdev(). This binds the "net" package to the netdev driver. For
example, setting the wifinina driver as the netdev:
```
nina := wifinina.New(&cfg)
netdev.UseNetdev(nina)
```
## Netdev Driver Notes
See the wifinina and rtl8720dn for examples of netdev drivers. Here are some
notes for netdev drivers.
#### Locking
Multiple goroutines may invoke methods on a net.Conn simultaneously, and since
the net package translates net.Conn calls into netdev socket calls, it follows
that multiple goroutines may invoke socket calls, so locking is required to
keep socket calls from stepping on one another.
Don't hold a lock while Time.Sleep()ing waiting for a long hardware operation to
finish. Unlocking while sleeping let's other goroutines make progress.
#### Sockfd
The netdev BSD socket interface uses a socket fd (int) to represent a socket
connection (end-point). Each fd maps 1:1 to a net.Conn maps. The number of fds
available is a hardware limitation. Wifinina, for example, can hand out 10
fds, representing 10 active sockets.
#### Testing
The netdev driver should minimally run all of the example/net examples.
+19
View File
@@ -0,0 +1,19 @@
### Table of Contents
- [Netlinker](#netlinker)
## Netlinker
TinyGo's network device driver model comprises two Go interfaces: Netdever and
Netlinker. This README covers Netlinker.
The Netlinker interface describes an L2 network interface. A netlink is a
concrete implementation of a Netlinker. See [Netdev](../netdev/) for
the L4/L3 network interface.
A netlink can:
- Connect/disconnect device to/from network
- Notify of network events (e.g. link UP/DOWN)
- Send and receive Ethernet packets
- Get/set device's hardware address (MAC address)
-15
View File
@@ -1,15 +0,0 @@
package netlink
// Bond aggregates links as one
type Bond struct {
*Bridge
}
func NewBond(links []Netlinker) *Bond {
return &Bond{Bridge: NewBridge(links)}
}
func (b *Bond) SendEth(pkt []byte) error {
// Send Ethernet pkt to active link(s)
return nil
}
-39
View File
@@ -1,39 +0,0 @@
package netlink
import (
"net"
)
// Bridge connects links into an Ethernet (L2) broadcast domain
type Bridge struct {
ip net.IP
links []Netlinker
recvEth func([]byte) error
}
func NewBridge(links []Netlinker) *Bridge {
return &Bridge{links: links}
}
func (b *Bridge) NetConnect(params *ConnectParams) error {
return nil
}
func (b *Bridge) NetDisconnect() {
}
func (b *Bridge) NetNotify(cb func(Event)) {
}
func (b *Bridge) GetHardwareAddr() (net.HardwareAddr, error) {
return net.HardwareAddr{}, nil
}
func (b *Bridge) SendEth(pkt []byte) error {
// L2 Forward ethernet pkt to zero of more []links
return nil
}
func (b *Bridge) RecvEthFunc(cb func(pkt []byte) error) {
b.recvEth = cb
}
+6 -8
View File
@@ -13,6 +13,7 @@ var (
ErrConnectFailed = errors.New("Connect failed")
ErrConnectTimeout = errors.New("Connect timed out")
ErrMissingSSID = errors.New("Missing WiFi SSID")
ErrAuthFailure = errors.New("Wifi authentication failure")
ErrAuthTypeNoGood = errors.New("Wifi authorization type not supported")
ErrConnectModeNoGood = errors.New("Connect mode not supported")
ErrNotSupported = errors.New("Not supported")
@@ -50,14 +51,19 @@ const (
const DefaultConnectTimeout = 10 * time.Second
type ConnectParams struct {
// Connect mode
ConnectMode
// SSID of Wifi AP
Ssid string
// Passphrase of Wifi AP
Passphrase string
// Wifi authorization type
AuthType
// Wifi country code as two-char string. E.g. "XX" for world-wide,
// "US" for USA, etc.
Country string
@@ -92,12 +98,4 @@ type Netlinker interface {
// GetHardwareAddr returns device MAC address
GetHardwareAddr() (net.HardwareAddr, error)
// SendEth sends an Ethernet packet
// TODO describe content of pkt
SendEth(pkt []byte) error
// RecvEth callback function for receiving Ethernet pkt
// TODO describe content of pkt
RecvEthFunc(cb func(pkt []byte) error)
}
-1
View File
@@ -4,7 +4,6 @@ package probe
import (
"machine"
"time"
"tinygo.org/x/drivers/netdev"
"tinygo.org/x/drivers/netlink"
-41
View File
@@ -1,41 +0,0 @@
package netlink
import (
"net"
)
// Vlan is a virtual LAN
type Vlan struct {
ip net.IP
// Vlan ID
id uint16
link Netlinker
recvEth func([]byte) error
}
func NewVlan(id uint16, link Netlinker) *Vlan {
return &Vlan{id: id, link: link}
}
func (v *Vlan) NetConnect(params *ConnectParams) error {
return nil
}
func (v *Vlan) NetDisconnect() {
}
func (v *Vlan) NetNotify(cb func(Event)) {
}
func (v *Vlan) GetHardwareAddr() (net.HardwareAddr, error) {
return net.HardwareAddr{}, nil
}
func (v *Vlan) SendEth(pkt []byte) error {
// Prepend VLAN hdr to pkt and send on link
return nil
}
func (v *Vlan) RecvEthFunc(cb func(pkt []byte) error) {
v.recvEth = cb
}
-7
View File
@@ -315,13 +315,6 @@ func (r *rtl8720dn) NetNotify(cb func(netlink.Event)) {
r.notifyCb = cb
}
func (r *rtl8720dn) SendEth(pkt []byte) error {
return netlink.ErrNotSupported
}
func (r *rtl8720dn) RecvEthFunc(cb func(pkt []byte) error) {
}
func (r *rtl8720dn) GetHostByName(name string) (net.IP, error) {
if debugging(debugNetdev) {
+14 -10
View File
@@ -24,9 +24,6 @@ tinygo build -size short -o ./build/test.hex -target=bluepill ./examples/ds1307/
tinygo build -size short -o ./build/test.hex -target=bluepill ./examples/ds1307/time/main.go
tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/ds3231/main.go
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/easystepper/main.go
tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/espat/espconsole/main.go
tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/espat/esphub/main.go
tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/espat/espstation/main.go
tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/flash/console/spi
tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/flash/console/qspi
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/gc9a01/main.go
@@ -83,10 +80,6 @@ tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/vl6
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd2in13/main.go
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd2in13x/main.go
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd4in2/main.go
tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/wifinina/ntpclient/main.go
tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/wifinina/udpstation/main.go
tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/wifinina/tcpclient/main.go
tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/wifinina/webclient/main.go
tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/ws2812
tinygo build -size short -o ./build/test.bin -target=m5stamp-c3 ./examples/ws2812
tinygo build -size short -o ./build/test.hex -target=feather-nrf52840 ./examples/is31fl3731/main.go
@@ -115,9 +108,6 @@ tinygo build -size short -o ./build/test.hex -target=pico ./examples/qmi8658c/ma
tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/ina260/main.go
tinygo build -size short -o ./build/test.hex -target=nucleo-l432kc ./examples/aht20/main.go
tinygo build -size short -o ./build/test.hex -target=feather-m4 ./examples/sdcard/console/
tinygo build -size short -o ./build/test.hex -target=wioterminal ./examples/rtl8720dn/webclient/
tinygo build -size short -o ./build/test.hex -target=wioterminal ./examples/rtl8720dn/webserver/
tinygo build -size short -o ./build/test.hex -target=wioterminal ./examples/rtl8720dn/mqttsub/
tinygo build -size short -o ./build/test.hex -target=feather-m4 ./examples/i2csoft/adt7410/
tinygo build -size short -o ./build/test.elf -target=wioterminal ./examples/axp192/m5stack-core2-blinky/
tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/xpt2046/main.go
@@ -139,3 +129,17 @@ tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ndir/ma
tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/ndir/main_ndir.go
tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/mpu9150/main.go
tinygo build -size short -o ./build/test.hex -target=macropad-rp2040 ./examples/sh1106/macropad_spi
# network examples (espat)
tinygo build -size short -o ./build/test.hex -target=challenger-rp2040 ./examples/net/ntpclient/
# network examples (wifinina)
tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/net/http-get/
tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/net/tcpclient/
tinygo build -size short -o ./build/test.hex -target=nano-rp2040 ./examples/net/websocket/dial/
tinygo build -size short -o ./build/test.hex -target=metro-m4-airlift ./examples/net/socket/
tinygo build -size short -o ./build/test.hex -target=matrixportal-m4 ./examples/net/webstatic/
tinygo build -size short -o ./build/test.hex -target=arduino-mkrwifi1010 ./examples/net/tlsclient/
tinygo build -size short -o ./build/test.hex -target=nano-rp2040 ./examples/net/mqttclient/natiu/
# network examples (rtl8720dn)
tinygo build -size short -o ./build/test.hex -target=wioterminal ./examples/net/webclient/
tinygo build -size short -o ./build/test.hex -target=wioterminal ./examples/net/webserver/
tinygo build -size short -o ./build/test.hex -target=wioterminal ./examples/net/mqttclient/paho/
-52
View File
@@ -1,52 +0,0 @@
package tcpip
import (
"net"
"time"
"tinygo.org/x/drivers/netdev"
)
func (s *Stack) GetHostByName(name string) (net.IP, error) {
return net.IP{}, netdev.ErrNotSupported
}
func (s *Stack) GetIPAddr() (net.IP, error) {
return net.IP{}, netdev.ErrNotSupported
}
func (s *Stack) Socket(domain int, stype int, protocol int) (int, error) {
return -1, netdev.ErrNotSupported
}
func (s *Stack) Bind(sockfd int, ip net.IP, port int) error {
return netdev.ErrNotSupported
}
func (s *Stack) Connect(sockfd int, host string, ip net.IP, port int) error {
return netdev.ErrNotSupported
}
func (s *Stack) Listen(sockfd int, backlog int) error {
return netdev.ErrNotSupported
}
func (s *Stack) Accept(sockfd int, ip net.IP, port int) (int, error) {
return -1, netdev.ErrNotSupported
}
func (s *Stack) Send(sockfd int, buf []byte, flags int, deadline time.Time) (int, error) {
return 0, netdev.ErrNotSupported
}
func (s *Stack) Recv(sockfd int, buf []byte, flags int, deadline time.Time) (int, error) {
return 0, netdev.ErrNotSupported
}
func (s *Stack) Close(sockfd int) error {
return netdev.ErrNotSupported
}
func (s *Stack) SetSockOpt(sockfd int, level int, opt int, value interface{}) error {
return netdev.ErrNotSupported
}
-20
View File
@@ -1,20 +0,0 @@
package tcpip
import (
"tinygo.org/x/drivers/netlink"
)
type Stack struct {
link netlink.Netlinker
}
func NewStack(link netlink.Netlinker) *Stack {
s := Stack{link: link}
s.link.RecvEthFunc(s.recvEth)
return &s
}
func (s *Stack) recvEth(pkt []byte) error {
println("recvEth", len(pkt))
return nil
}
-67
View File
@@ -1,67 +0,0 @@
package wifinina
type CommandType uint8
//go:generate stringer -type=CommandType -trimprefix=Cmd
const (
CmdStart CommandType = 0xE0
CmdEnd CommandType = 0xEE
CmdErr CommandType = 0xEF
CmdSetNet CommandType = 0x10
CmdSetPassphrase CommandType = 0x11
CmdSetKey CommandType = 0x12
CmdSetIPConfig CommandType = 0x14
CmdSetDNSConfig CommandType = 0x15
CmdSetHostname CommandType = 0x16
CmdSetPowerMode CommandType = 0x17
CmdSetAPNet CommandType = 0x18
CmdSetAPPassphrase CommandType = 0x19
CmdSetDebug CommandType = 0x1A
CmdGetTemperature CommandType = 0x1B
CmdGetReasonCode CommandType = 0x1F
// TEST_CMD = 0x13
CmdGetConnStatus CommandType = 0x20
CmdGetIPAddr CommandType = 0x21
CmdGetMACAddr CommandType = 0x22
CmdGetCurrSSID CommandType = 0x23
CmdGetCurrBSSID CommandType = 0x24
CmdGetCurrRSSI CommandType = 0x25
CmdGetCurrEncrType CommandType = 0x26
CmdScanNetworks CommandType = 0x27
CmdStartServerTCP CommandType = 0x28
CmdGetStateTCP CommandType = 0x29
CmdDataSentTCP CommandType = 0x2A
CmdAvailDataTCP CommandType = 0x2B
CmdGetDataTCP CommandType = 0x2C
CmdStartClientTCP CommandType = 0x2D
CmdStopClientTCP CommandType = 0x2E
CmdGetClientStateTCP CommandType = 0x2F
CmdDisconnect CommandType = 0x30
CmdGetIdxRSSI CommandType = 0x32
CmdGetIdxEncrType CommandType = 0x33
CmdReqHostByName CommandType = 0x34
CmdGetHostByName CommandType = 0x35
CmdStartScanNetworks CommandType = 0x36
CmdGetFwVersion CommandType = 0x37
CmdSendDataUDP CommandType = 0x39
CmdGetRemoteData CommandType = 0x3A
CmdGetTime CommandType = 0x3B
CmdGetIdxBSSID CommandType = 0x3C
CmdGetIdxChannel CommandType = 0x3D
CmdPing CommandType = 0x3E
CmdGetSocket CommandType = 0x3F
// GET_IDX_SSID_CMD = 0x31,
// GET_TEST_CMD = 0x38
// All command with DATA_FLAG 0x40 send a 16bit Len
CmdSendDataTCP CommandType = 0x44
CmdGetDatabufTCP CommandType = 0x45
CmdInsertDataBuf CommandType = 0x46
// regular format commands
CmdSetPinMode CommandType = 0x50
CmdSetDigitalWrite CommandType = 0x51
CmdSetAnalogWrite CommandType = 0x52
)
-120
View File
@@ -1,120 +0,0 @@
//go:build wifidebug
// Code generated by "stringer -type=CommandType -trimprefix=Cmd"; DO NOT EDIT.
package wifinina
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[CmdStart-224]
_ = x[CmdEnd-238]
_ = x[CmdErr-239]
_ = x[CmdSetNet-16]
_ = x[CmdSetPassphrase-17]
_ = x[CmdSetKey-18]
_ = x[CmdSetIPConfig-20]
_ = x[CmdSetDNSConfig-21]
_ = x[CmdSetHostname-22]
_ = x[CmdSetPowerMode-23]
_ = x[CmdSetAPNet-24]
_ = x[CmdSetAPPassphrase-25]
_ = x[CmdSetDebug-26]
_ = x[CmdGetTemperature-27]
_ = x[CmdGetReasonCode-31]
_ = x[CmdGetConnStatus-32]
_ = x[CmdGetIPAddr-33]
_ = x[CmdGetMACAddr-34]
_ = x[CmdGetCurrSSID-35]
_ = x[CmdGetCurrBSSID-36]
_ = x[CmdGetCurrRSSI-37]
_ = x[CmdGetCurrEncrType-38]
_ = x[CmdScanNetworks-39]
_ = x[CmdStartServerTCP-40]
_ = x[CmdGetStateTCP-41]
_ = x[CmdDataSentTCP-42]
_ = x[CmdAvailDataTCP-43]
_ = x[CmdGetDataTCP-44]
_ = x[CmdStartClientTCP-45]
_ = x[CmdStopClientTCP-46]
_ = x[CmdGetClientStateTCP-47]
_ = x[CmdDisconnect-48]
_ = x[CmdGetIdxRSSI-50]
_ = x[CmdGetIdxEncrType-51]
_ = x[CmdReqHostByName-52]
_ = x[CmdGetHostByName-53]
_ = x[CmdStartScanNetworks-54]
_ = x[CmdGetFwVersion-55]
_ = x[CmdSendDataUDP-57]
_ = x[CmdGetRemoteData-58]
_ = x[CmdGetTime-59]
_ = x[CmdGetIdxBSSID-60]
_ = x[CmdGetIdxChannel-61]
_ = x[CmdPing-62]
_ = x[CmdGetSocket-63]
_ = x[CmdSendDataTCP-68]
_ = x[CmdGetDatabufTCP-69]
_ = x[CmdInsertDataBuf-70]
_ = x[CmdSetPinMode-80]
_ = x[CmdSetDigitalWrite-81]
_ = x[CmdSetAnalogWrite-82]
}
const (
_CommandType_name_0 = "SetNetSetPassphraseSetKey"
_CommandType_name_1 = "SetIPConfigSetDNSConfigSetHostnameSetPowerModeSetAPNetSetAPPassphraseSetDebugGetTemperature"
_CommandType_name_2 = "GetReasonCodeGetConnStatusGetIPAddrGetMACAddrGetCurrSSIDGetCurrBSSIDGetCurrRSSIGetCurrEncrTypeScanNetworksStartServerTCPGetStateTCPDataSentTCPAvailDataTCPGetDataTCPStartClientTCPStopClientTCPGetClientStateTCPDisconnect"
_CommandType_name_3 = "GetIdxRSSIGetIdxEncrTypeReqHostByNameGetHostByNameStartScanNetworksGetFwVersion"
_CommandType_name_4 = "SendDataUDPGetRemoteDataGetTimeGetIdxBSSIDGetIdxChannelPingGetSocket"
_CommandType_name_5 = "SendDataTCPGetDatabufTCPInsertDataBuf"
_CommandType_name_6 = "SetPinModeSetDigitalWriteSetAnalogWrite"
_CommandType_name_7 = "Start"
_CommandType_name_8 = "EndErr"
)
var (
_CommandType_index_0 = [...]uint8{0, 6, 19, 25}
_CommandType_index_1 = [...]uint8{0, 11, 23, 34, 46, 54, 69, 77, 91}
_CommandType_index_2 = [...]uint8{0, 13, 26, 35, 45, 56, 68, 79, 94, 106, 120, 131, 142, 154, 164, 178, 191, 208, 218}
_CommandType_index_3 = [...]uint8{0, 10, 24, 37, 50, 67, 79}
_CommandType_index_4 = [...]uint8{0, 11, 24, 31, 42, 55, 59, 68}
_CommandType_index_5 = [...]uint8{0, 11, 24, 37}
_CommandType_index_6 = [...]uint8{0, 10, 25, 39}
_CommandType_index_8 = [...]uint8{0, 3, 6}
)
func (i CommandType) String() string {
switch {
case 16 <= i && i <= 18:
i -= 16
return _CommandType_name_0[_CommandType_index_0[i]:_CommandType_index_0[i+1]]
case 20 <= i && i <= 27:
i -= 20
return _CommandType_name_1[_CommandType_index_1[i]:_CommandType_index_1[i+1]]
case 31 <= i && i <= 48:
i -= 31
return _CommandType_name_2[_CommandType_index_2[i]:_CommandType_index_2[i+1]]
case 50 <= i && i <= 55:
i -= 50
return _CommandType_name_3[_CommandType_index_3[i]:_CommandType_index_3[i+1]]
case 57 <= i && i <= 63:
i -= 57
return _CommandType_name_4[_CommandType_index_4[i]:_CommandType_index_4[i+1]]
case 68 <= i && i <= 70:
i -= 68
return _CommandType_name_5[_CommandType_index_5[i]:_CommandType_index_5[i+1]]
case 80 <= i && i <= 82:
i -= 80
return _CommandType_name_6[_CommandType_index_6[i]:_CommandType_index_6[i+1]]
case i == 224:
return _CommandType_name_7
case 238 <= i && i <= 239:
i -= 238
return _CommandType_name_8[_CommandType_index_8[i]:_CommandType_index_8[i+1]]
default:
return "CommandType(" + strconv.FormatInt(int64(i), 10) + ")"
}
}
-41
View File
@@ -1,41 +0,0 @@
//go:build wifidebug
// Code generated by "stringer -type=ConnectionStatus -trimprefix=Status"; DO NOT EDIT.
package wifinina
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[StatusNoShield-255]
_ = x[StatusIdle-0]
_ = x[StatusNoSSIDAvail-1]
_ = x[StatusScanCompleted-2]
_ = x[StatusConnected-3]
_ = x[StatusConnectFailed-4]
_ = x[StatusConnectionLost-5]
_ = x[StatusDisconnected-6]
}
const (
_ConnectionStatus_name_0 = "IdleNoSSIDAvailScanCompletedConnectedConnectFailedConnectionLostDisconnected"
_ConnectionStatus_name_1 = "NoShield"
)
var (
_ConnectionStatus_index_0 = [...]uint8{0, 4, 15, 28, 37, 50, 64, 76}
)
func (i ConnectionStatus) String() string {
switch {
case i <= 6:
return _ConnectionStatus_name_0[_ConnectionStatus_index_0[i]:_ConnectionStatus_index_0[i+1]]
case i == 255:
return _ConnectionStatus_name_1
default:
return "ConnectionStatus(" + strconv.FormatInt(int64(i), 10) + ")"
}
}
-44
View File
@@ -1,44 +0,0 @@
//go:build wifidebug
// Code generated by "stringer -type=EncryptionType -trimprefix=EncType"; DO NOT EDIT.
package wifinina
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[EncTypeTKIP-2]
_ = x[EncTypeCCMP-4]
_ = x[EncTypeWEP-5]
_ = x[EncTypeNone-7]
_ = x[EncTypeAuto-8]
}
const (
_EncryptionType_name_0 = "TKIP"
_EncryptionType_name_1 = "CCMPWEP"
_EncryptionType_name_2 = "NoneAuto"
)
var (
_EncryptionType_index_1 = [...]uint8{0, 4, 7}
_EncryptionType_index_2 = [...]uint8{0, 4, 8}
)
func (i EncryptionType) String() string {
switch {
case i == 2:
return _EncryptionType_name_0
case 4 <= i && i <= 5:
i -= 4
return _EncryptionType_name_1[_EncryptionType_index_1[i]:_EncryptionType_index_1[i+1]]
case 7 <= i && i <= 8:
i -= 7
return _EncryptionType_name_2[_EncryptionType_index_2[i]:_EncryptionType_index_2[i+1]]
default:
return "EncryptionType(" + strconv.FormatInt(int64(i), 10) + ")"
}
}
-59
View File
@@ -1,59 +0,0 @@
// Code generated by "stringer -type=Error -trimprefix=Err"; DO NOT EDIT.
package wifinina
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[ErrTimeoutChipReady-1]
_ = x[ErrTimeoutChipSelect-2]
_ = x[ErrCheckStartCmd-3]
_ = x[ErrWaitRsp-4]
_ = x[ErrUnexpectedLength-224]
_ = x[ErrNoParamsReturned-225]
_ = x[ErrIncorrectSentinel-226]
_ = x[ErrCmdErrorReceived-239]
_ = x[ErrNotImplemented-240]
_ = x[ErrUnknownHost-241]
_ = x[ErrSocketAlreadySet-242]
_ = x[ErrConnectionTimeout-243]
_ = x[ErrNoData-244]
_ = x[ErrDataNotWritten-245]
_ = x[ErrCheckDataError-246]
_ = x[ErrBufferTooSmall-247]
_ = x[ErrNoSocketAvail-255]
}
const (
_Error_name_0 = "TimeoutChipReadyTimeoutChipSelectCheckStartCmdWaitRsp"
_Error_name_1 = "UnexpectedLengthNoParamsReturnedIncorrectSentinel"
_Error_name_2 = "CmdErrorReceivedNotImplementedUnknownHostSocketAlreadySetConnectionTimeoutNoDataDataNotWrittenCheckDataErrorBufferTooSmall"
_Error_name_3 = "NoSocketAvail"
)
var (
_Error_index_0 = [...]uint8{0, 16, 33, 46, 53}
_Error_index_1 = [...]uint8{0, 16, 32, 49}
_Error_index_2 = [...]uint8{0, 16, 30, 41, 57, 74, 80, 94, 108, 122}
)
func (i Error) String() string {
switch {
case 1 <= i && i <= 4:
i -= 1
return _Error_name_0[_Error_index_0[i]:_Error_index_0[i+1]]
case 224 <= i && i <= 226:
i -= 224
return _Error_name_1[_Error_index_1[i]:_Error_index_1[i+1]]
case 239 <= i && i <= 247:
i -= 239
return _Error_name_2[_Error_index_2[i]:_Error_index_2[i+1]]
case i == 255:
return _Error_name_3
default:
return "Error(" + strconv.FormatInt(int64(i), 10) + ")"
}
}
-5
View File
@@ -1,5 +0,0 @@
//go:build !wifidebug
package wifinina
var _debug = false
-75
View File
@@ -1,75 +0,0 @@
package wifinina
type ConnectionStatus uint8
//go:generate stringer -type=ConnectionStatus -trimprefix=Status
const (
StatusNoShield ConnectionStatus = 255
StatusIdle ConnectionStatus = 0
StatusNoSSIDAvail ConnectionStatus = 1
StatusScanCompleted ConnectionStatus = 2
StatusConnected ConnectionStatus = 3
StatusConnectFailed ConnectionStatus = 4
StatusConnectionLost ConnectionStatus = 5
StatusDisconnected ConnectionStatus = 6
)
// Default state value for Wifi state field
// #define NA_STATE -1
type EncryptionType uint8
//go:generate stringer -type=EncryptionType -trimprefix=EncType
const (
EncTypeTKIP EncryptionType = 2
EncTypeCCMP EncryptionType = 4
EncTypeWEP EncryptionType = 5
EncTypeNone EncryptionType = 7
EncTypeAuto EncryptionType = 8
)
type TCPState uint8
//go:generate stringer -type=TCPState -trimprefix=TCPState
const (
TCPStateClosed TCPState = 0
TCPStateListen TCPState = 1
TCPStateSynSent TCPState = 2
TCPStateSynRcvd TCPState = 3
TCPStateEstablished TCPState = 4
TCPStateFinWait1 TCPState = 5
TCPStateFinWait2 TCPState = 6
TCPStateCloseWait TCPState = 7
TCPStateClosing TCPState = 8
TCPStateLastACK TCPState = 9
TCPStateTimeWait TCPState = 10
)
type Error uint8
func (err Error) Error() string {
return "wifinina error: " + err.String()
}
//go:generate stringer -type=Error -trimprefix=Err
const (
ErrTimeoutChipReady Error = 0x01
ErrTimeoutChipSelect Error = 0x02
ErrCheckStartCmd Error = 0x03
ErrWaitRsp Error = 0x04
ErrUnexpectedLength Error = 0xE0
ErrNoParamsReturned Error = 0xE1
ErrIncorrectSentinel Error = 0xE2
ErrCmdErrorReceived Error = 0xEF
ErrNotImplemented Error = 0xF0
ErrUnknownHost Error = 0xF1
ErrSocketAlreadySet Error = 0xF2
ErrConnectionTimeout Error = 0xF3
ErrNoData Error = 0xF4
ErrDataNotWritten Error = 0xF5
ErrCheckDataError Error = 0xF6
ErrBufferTooSmall Error = 0xF7
ErrNoSocketAvail Error = 0xFF
NoSocketAvail uint8 = 0xFF
)
-35
View File
@@ -1,35 +0,0 @@
//go:build wifidebug
// Code generated by "stringer -type=TCPState -trimprefix=TCPState"; DO NOT EDIT.
package wifinina
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[TCPStateClosed-0]
_ = x[TCPStateListen-1]
_ = x[TCPStateSynSent-2]
_ = x[TCPStateSynRcvd-3]
_ = x[TCPStateEstablished-4]
_ = x[TCPStateFinWait1-5]
_ = x[TCPStateFinWait2-6]
_ = x[TCPStateCloseWait-7]
_ = x[TCPStateClosing-8]
_ = x[TCPStateLastACK-9]
_ = x[TCPStateTimeWait-10]
}
const _TCPState_name = "ClosedListenSynSentSynRcvdEstablishedFinWait1FinWait2CloseWaitClosingLastACKTimeWait"
var _TCPState_index = [...]uint8{0, 6, 12, 19, 26, 37, 45, 53, 62, 69, 76, 84}
func (i TCPState) String() string {
if i >= TCPState(len(_TCPState_index)-1) {
return "TCPState(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _TCPState_name[_TCPState_index[i]:_TCPState_index[i+1]]
}
-7
View File
@@ -498,13 +498,6 @@ func (w *wifinina) NetNotify(cb func(netlink.Event)) {
w.notifyCb = cb
}
func (w *wifinina) SendEth(pkt []byte) error {
return netlink.ErrNotSupported
}
func (w *wifinina) RecvEthFunc(cb func(pkt []byte) error) {
}
func (w *wifinina) GetHostByName(name string) (net.IP, error) {
if debugging(debugNetdev) {