wifi/espat, rtl8720dn, wifinina, net: modify to use Adapter interface

Signed-off-by: deadprogram <ron@hybridgroup.com>
This commit is contained in:
deadprogram
2022-01-23 17:10:37 +01:00
committed by Ron Evans
parent d8c813d515
commit 941c1c9057
16 changed files with 110 additions and 114 deletions
+3 -2
View File
@@ -3,14 +3,15 @@ package espat
import ( import (
"time" "time"
"tinygo.org/x/drivers" "tinygo.org/x/drivers/net"
) )
func (d *Device) ConnectToAccessPoint(ssid, pass string, timeout time.Duration) error { func (d *Device) ConnectToAccessPoint(ssid, pass string, timeout time.Duration) error {
if len(ssid) == 0 { if len(ssid) == 0 {
return drivers.ErrWiFiMissingSSID return net.ErrWiFiMissingSSID
} }
d.SetWifiMode(WifiModeClient)
return d.ConnectToAP(ssid, pass, 10) return d.ConnectToAP(ssid, pass, 10)
} }
-1
View File
@@ -113,7 +113,6 @@ func connectToESP() bool {
func connectToAP() { func connectToAP() {
println("Connecting to wifi network '" + ssid + "'") println("Connecting to wifi network '" + ssid + "'")
adaptor.SetWifiMode(espat.WifiModeClient)
if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil { if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil {
failMessage(err.Error()) failMessage(err.Error())
} }
-1
View File
@@ -99,7 +99,6 @@ func connectToESP() bool {
func connectToAP() { func connectToAP() {
println("Connecting to wifi network '" + ssid + "'") println("Connecting to wifi network '" + ssid + "'")
adaptor.SetWifiMode(espat.WifiModeClient)
if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil { if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil {
failMessage(err.Error()) failMessage(err.Error())
} }
-1
View File
@@ -88,7 +88,6 @@ func connectToESP() bool {
func connectToAP() { func connectToAP() {
println("Connecting to wifi network '" + ssid + "'") println("Connecting to wifi network '" + ssid + "'")
adaptor.SetWifiMode(espat.WifiModeClient)
if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil { if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil {
failMessage(err.Error()) failMessage(err.Error())
} }
-1
View File
@@ -108,7 +108,6 @@ func connectToESP() bool {
func connectToAP() { func connectToAP() {
println("Connecting to wifi network '" + ssid + "'") println("Connecting to wifi network '" + ssid + "'")
adaptor.SetWifiMode(espat.WifiModeClient)
if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil { if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil {
failMessage(err.Error()) failMessage(err.Error())
} }
-1
View File
@@ -129,7 +129,6 @@ func connectToESP() bool {
func connectToAP() { func connectToAP() {
println("Connecting to wifi network '" + ssid + "'") println("Connecting to wifi network '" + ssid + "'")
adaptor.SetWifiMode(espat.WifiModeClient)
if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil { if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil {
failMessage(err.Error()) failMessage(err.Error())
} }
-1
View File
@@ -91,7 +91,6 @@ func connectToESP() bool {
func connectToAP() { func connectToAP() {
println("Connecting to wifi network '" + ssid + "'") println("Connecting to wifi network '" + ssid + "'")
adaptor.SetWifiMode(espat.WifiModeClient)
if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil { if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil {
failMessage(err.Error()) failMessage(err.Error())
} }
+21 -4
View File
@@ -1,6 +1,23 @@
package net package net
type DeviceDriver interface { import (
"errors"
"time"
)
var (
ErrWiFiMissingSSID = errors.New("missing SSID")
ErrWiFiConnectTimeout = errors.New("WiFi connect timeout")
)
// Adapter interface is used to communicate with the network adapter.
type Adapter interface {
// functions used to connect/disconnect to/from an access point
ConnectToAccessPoint(ssid, pass string, timeout time.Duration) error
Disconnect() error
GetClientIP() (string, error)
// these functions are used once the adapter is connected to the network
GetDNS(domain string) (string, error) GetDNS(domain string) (string, error)
ConnectTCPSocket(addr, port string) error ConnectTCPSocket(addr, port string) error
ConnectSSLSocket(addr, port string) error ConnectSSLSocket(addr, port string) error
@@ -16,12 +33,12 @@ type DeviceDriver interface {
Response(timeout int) ([]byte, error) Response(timeout int) ([]byte, error)
} }
var ActiveDevice DeviceDriver var ActiveDevice Adapter
func UseDriver(driver DeviceDriver) { func UseDriver(a Adapter) {
// TODO: rethink and refactor this // TODO: rethink and refactor this
if ActiveDevice != nil { if ActiveDevice != nil {
panic("net.ActiveDevice is already set") panic("net.ActiveDevice is already set")
} }
ActiveDevice = driver ActiveDevice = a
} }
+1 -1
View File
@@ -23,7 +23,7 @@ func NewClient(o *ClientOptions) Client {
} }
type mqttclient struct { type mqttclient struct {
adaptor net.DeviceDriver adaptor net.Adapter
conn net.Conn conn net.Conn
connected bool connected bool
opts *ClientOptions opts *ClientOptions
+1 -1
View File
@@ -175,7 +175,7 @@ type ClientOptionsReader struct {
// ClientOptions contains configurable options for an MQTT Client. // ClientOptions contains configurable options for an MQTT Client.
type ClientOptions struct { type ClientOptions struct {
Adaptor net.DeviceDriver Adaptor net.Adapter
//Servers []*url.URL //Servers []*url.URL
Servers string Servers string
+1 -1
View File
@@ -94,7 +94,7 @@ func Dial(network, address string) (Conn, error) {
// SerialConn is a loosely net.Conn compatible implementation // SerialConn is a loosely net.Conn compatible implementation
type SerialConn struct { type SerialConn struct {
Adaptor DeviceDriver Adaptor Adapter
} }
// UDPSerialConn is a loosely net.Conn compatible intended to support // UDPSerialConn is a loosely net.Conn compatible intended to support
@@ -3,12 +3,12 @@ package rtl8720dn
import ( import (
"time" "time"
"tinygo.org/x/drivers" "tinygo.org/x/drivers/net"
) )
func (r *RTL8720DN) ConnectToAccessPoint(ssid, pass string, timeout time.Duration) error { func (r *RTL8720DN) ConnectToAccessPoint(ssid, pass string, timeout time.Duration) error {
if len(ssid) == 0 { if len(ssid) == 0 {
return drivers.ErrWiFiMissingSSID return net.ErrWiFiMissingSSID
} }
return r.ConnectToAP(ssid, pass) return r.ConnectToAP(ssid, pass)
@@ -18,3 +18,8 @@ func (r *RTL8720DN) Disconnect() error {
_, err := r.Rpc_wifi_disconnect() _, err := r.Rpc_wifi_disconnect()
return err return err
} }
func (r *RTL8720DN) GetClientIP() (string, error) {
ip, _, _, err := r.GetIP()
return ip.String(), err
}
-16
View File
@@ -1,16 +0,0 @@
package drivers
import (
"errors"
"time"
)
var (
ErrWiFiMissingSSID = errors.New("missing SSID")
ErrWiFiConnectTimeout = errors.New("WiFi connect timeout")
)
type WiFiDriver interface {
ConnectToAccessPoint(ssid, pass string, timeout time.Duration) error
Disconnect() error
}
@@ -3,12 +3,12 @@ package wifinina
import ( import (
"time" "time"
"tinygo.org/x/drivers" "tinygo.org/x/drivers/net"
) )
func (d *Device) ConnectToAccessPoint(ssid, pass string, timeout time.Duration) error { func (d *Device) ConnectToAccessPoint(ssid, pass string, timeout time.Duration) error {
if len(ssid) == 0 { if len(ssid) == 0 {
return drivers.ErrWiFiMissingSSID return net.ErrWiFiMissingSSID
} }
start := time.Now() start := time.Now()
@@ -22,5 +22,10 @@ func (d *Device) ConnectToAccessPoint(ssid, pass string, timeout time.Duration)
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
} }
return drivers.ErrWiFiConnectTimeout return net.ErrWiFiConnectTimeout
}
func (d *Device) GetClientIP() (string, error) {
ip, _, _, err := d.GetIP()
return ip.String(), err
} }
+59 -75
View File
@@ -4,50 +4,34 @@ import (
"errors" "errors"
"strconv" "strconv"
"time" "time"
"tinygo.org/x/drivers/net"
) )
const ( const (
ReadBufferSize = 128 ReadBufferSize = 128
) )
func (d *Device) NewDriver() net.DeviceDriver {
return &Driver{dev: d, sock: NoSocketAvail}
}
type Driver struct {
dev *Device
sock uint8
readBuf readBuffer
proto uint8
ip uint32
port uint16
}
type readBuffer struct { type readBuffer struct {
data [ReadBufferSize]byte data [ReadBufferSize]byte
head int head int
size int size int
} }
func (drv *Driver) GetDNS(domain string) (string, error) { func (d *Device) GetDNS(domain string) (string, error) {
ipAddr, err := drv.dev.GetHostByName(domain) ipAddr, err := d.GetHostByName(domain)
return ipAddr.String(), err return ipAddr.String(), err
} }
func (drv *Driver) ConnectTCPSocket(addr, portStr string) error { func (d *Device) ConnectTCPSocket(addr, portStr string) error {
return drv.connectSocket(addr, portStr, ProtoModeTCP) return d.connectSocket(addr, portStr, ProtoModeTCP)
} }
func (drv *Driver) ConnectSSLSocket(addr, portStr string) error { func (d *Device) ConnectSSLSocket(addr, portStr string) error {
return drv.connectSocket(addr, portStr, ProtoModeTLS) return d.connectSocket(addr, portStr, ProtoModeTLS)
} }
func (drv *Driver) connectSocket(addr, portStr string, mode uint8) error { func (d *Device) connectSocket(addr, portStr string, mode uint8) error {
drv.proto, drv.ip, drv.port = mode, 0, 0 d.proto, d.ip, d.port = mode, 0, 0
// convert port to uint16 // convert port to uint16
port, err := convertPort(portStr) port, err := convertPort(portStr)
@@ -61,7 +45,7 @@ func (drv *Driver) connectSocket(addr, portStr string, mode uint8) error {
if mode != ProtoModeTLS { if mode != ProtoModeTLS {
// look up the hostname if necessary; if an IP address was specified, the // look up the hostname if necessary; if an IP address was specified, the
// same will be returned. Otherwise, an IPv4 for the hostname is returned. // same will be returned. Otherwise, an IPv4 for the hostname is returned.
ipAddr, err := drv.dev.GetHostByName(addr) ipAddr, err := d.GetHostByName(addr)
if err != nil { if err != nil {
return err return err
} }
@@ -70,26 +54,26 @@ func (drv *Driver) connectSocket(addr, portStr string, mode uint8) error {
} }
// check to see if socket is already set; if so, stop it // check to see if socket is already set; if so, stop it
if drv.sock != NoSocketAvail { if d.sock != NoSocketAvail {
if err := drv.stop(); err != nil { if err := d.stop(); err != nil {
return err return err
} }
} }
// get a socket from the device // get a socket from the device
if drv.sock, err = drv.dev.GetSocket(); err != nil { if d.sock, err = d.GetSocket(); err != nil {
return err return err
} }
// attempt to start the client // attempt to start the client
if err := drv.dev.StartClient(hostname, ip, port, drv.sock, mode); err != nil { if err := d.StartClient(hostname, ip, port, d.sock, mode); err != nil {
return err return err
} }
// FIXME: this 4 second timeout is simply mimicking the Arduino driver // FIXME: this 4 second timeout is simply mimicking the Arduino driver
start := time.Now() start := time.Now()
for time.Since(start) < 4*time.Second { for time.Since(start) < 4*time.Second {
connected, err := drv.IsConnected() connected, err := d.IsConnected()
if err != nil { if err != nil {
return err return err
} }
@@ -110,12 +94,12 @@ func convertPort(portStr string) (uint16, error) {
return uint16(p64), nil return uint16(p64), nil
} }
func (drv *Driver) ConnectUDPSocket(addr, portStr, lportStr string) (err error) { func (d *Device) ConnectUDPSocket(addr, portStr, lportStr string) (err error) {
drv.proto, drv.ip, drv.port = ProtoModeUDP, 0, 0 d.proto, d.ip, d.port = ProtoModeUDP, 0, 0
// convert remote port to uint16 // convert remote port to uint16
if drv.port, err = convertPort(portStr); err != nil { if d.port, err = convertPort(portStr); err != nil {
return err return err
} }
@@ -127,73 +111,73 @@ func (drv *Driver) ConnectUDPSocket(addr, portStr, lportStr string) (err error)
// look up the hostname if necessary; if an IP address was specified, the // look up the hostname if necessary; if an IP address was specified, the
// same will be returned. Otherwise, an IPv4 for the hostname is returned. // same will be returned. Otherwise, an IPv4 for the hostname is returned.
ipAddr, err := drv.dev.GetHostByName(addr) ipAddr, err := d.GetHostByName(addr)
if err != nil { if err != nil {
return err return err
} }
drv.ip = ipAddr.AsUint32() d.ip = ipAddr.AsUint32()
// check to see if socket is already set; if so, stop it // check to see if socket is already set; if so, stop it
// TODO: we can probably have more than one socket at once right? // TODO: we can probably have more than one socket at once right?
if drv.sock != NoSocketAvail { if d.sock != NoSocketAvail {
if err := drv.stop(); err != nil { if err := d.stop(); err != nil {
return err return err
} }
} }
// get a socket from the device // get a socket from the device
if drv.sock, err = drv.dev.GetSocket(); err != nil { if d.sock, err = d.GetSocket(); err != nil {
return err return err
} }
// start listening for UDP packets on the local port // start listening for UDP packets on the local port
if err := drv.dev.StartServer(lport, drv.sock, drv.proto); err != nil { if err := d.StartServer(lport, d.sock, d.proto); err != nil {
return err return err
} }
return nil return nil
} }
func (drv *Driver) DisconnectSocket() error { func (d *Device) DisconnectSocket() error {
return drv.stop() return d.stop()
} }
func (drv *Driver) StartSocketSend(size int) error { func (d *Device) StartSocketSend(size int) error {
// not needed for WiFiNINA??? // not needed for WiFiNINA???
return nil return nil
} }
func (drv *Driver) Response(timeout int) ([]byte, error) { func (d *Device) Response(timeout int) ([]byte, error) {
return nil, nil return nil, nil
} }
func (drv *Driver) Write(b []byte) (n int, err error) { func (d *Device) Write(b []byte) (n int, err error) {
if drv.sock == NoSocketAvail { if d.sock == NoSocketAvail {
return 0, ErrNoSocketAvail return 0, ErrNoSocketAvail
} }
if len(b) == 0 { if len(b) == 0 {
return 0, ErrNoData return 0, ErrNoData
} }
if drv.proto == ProtoModeUDP { if d.proto == ProtoModeUDP {
if err := drv.dev.StartClient("", drv.ip, drv.port, drv.sock, drv.proto); err != nil { if err := d.StartClient("", d.ip, d.port, d.sock, d.proto); err != nil {
return 0, errors.New("error in startClient: " + err.Error()) return 0, errors.New("error in startClient: " + err.Error())
} }
if _, err := drv.dev.InsertDataBuf(b, drv.sock); err != nil { if _, err := d.InsertDataBuf(b, d.sock); err != nil {
return 0, errors.New("error in insertDataBuf: " + err.Error()) return 0, errors.New("error in insertDataBuf: " + err.Error())
} }
if _, err := drv.dev.SendUDPData(drv.sock); err != nil { if _, err := d.SendUDPData(d.sock); err != nil {
return 0, errors.New("error in sendUDPData: " + err.Error()) return 0, errors.New("error in sendUDPData: " + err.Error())
} }
return len(b), nil return len(b), nil
} else { } else {
written, err := drv.dev.SendData(b, drv.sock) written, err := d.SendData(b, d.sock)
if err != nil { if err != nil {
return 0, err return 0, err
} }
if written == 0 { if written == 0 {
return 0, ErrDataNotWritten return 0, ErrDataNotWritten
} }
if sent, _ := drv.dev.CheckDataSent(drv.sock); !sent { if sent, _ := d.CheckDataSent(d.sock); !sent {
return 0, ErrCheckDataError return 0, ErrCheckDataError
} }
return len(b), nil return len(b), nil
@@ -202,8 +186,8 @@ func (drv *Driver) Write(b []byte) (n int, err error) {
return len(b), nil return len(b), nil
} }
func (drv *Driver) ReadSocket(b []byte) (n int, err error) { func (d *Device) ReadSocket(b []byte) (n int, err error) {
avail, err := drv.available() avail, err := d.available()
if err != nil { if err != nil {
println("ReadSocket error: " + err.Error()) println("ReadSocket error: " + err.Error())
return 0, err return 0, err
@@ -215,37 +199,37 @@ func (drv *Driver) ReadSocket(b []byte) (n int, err error) {
if avail < length { if avail < length {
length = avail length = avail
} }
copy(b, drv.readBuf.data[drv.readBuf.head:drv.readBuf.head+length]) copy(b, d.readBuf.data[d.readBuf.head:d.readBuf.head+length])
drv.readBuf.head += length d.readBuf.head += length
drv.readBuf.size -= length d.readBuf.size -= length
return length, nil return length, nil
} }
// IsSocketDataAvailable returns of there is socket data available // IsSocketDataAvailable returns of there is socket data available
func (drv *Driver) IsSocketDataAvailable() bool { func (d *Device) IsSocketDataAvailable() bool {
n, err := drv.available() n, err := d.available()
return err == nil && n > 0 return err == nil && n > 0
} }
func (drv *Driver) available() (int, error) { func (d *Device) available() (int, error) {
if drv.readBuf.size == 0 { if d.readBuf.size == 0 {
n, err := drv.dev.GetDataBuf(drv.sock, drv.readBuf.data[:]) n, err := d.GetDataBuf(d.sock, d.readBuf.data[:])
if n > 0 { if n > 0 {
drv.readBuf.head = 0 d.readBuf.head = 0
drv.readBuf.size = n d.readBuf.size = n
} }
if err != nil { if err != nil {
return int(n), err return int(n), err
} }
} }
return drv.readBuf.size, nil return d.readBuf.size, nil
} }
func (drv *Driver) IsConnected() (bool, error) { func (d *Device) IsConnected() (bool, error) {
if drv.sock == NoSocketAvail { if d.sock == NoSocketAvail {
return false, nil return false, nil
} }
s, err := drv.status() s, err := d.status()
if err != nil { if err != nil {
return false, err return false, err
} }
@@ -261,26 +245,26 @@ func (drv *Driver) IsConnected() (bool, error) {
return isConnected, nil return isConnected, nil
} }
func (drv *Driver) status() (uint8, error) { func (d *Device) status() (uint8, error) {
if drv.sock == NoSocketAvail { if d.sock == NoSocketAvail {
return TCPStateClosed, nil return TCPStateClosed, nil
} }
return drv.dev.GetClientState(drv.sock) return d.GetClientState(d.sock)
} }
func (drv *Driver) stop() error { func (d *Device) stop() error {
if drv.sock == NoSocketAvail { if d.sock == NoSocketAvail {
return nil return nil
} }
drv.dev.StopClient(drv.sock) d.StopClient(d.sock)
start := time.Now() start := time.Now()
for time.Since(start) < 5*time.Second { for time.Since(start) < 5*time.Second {
st, _ := drv.status() st, _ := d.status()
if st == TCPStateClosed { if st == TCPStateClosed {
break break
} }
time.Sleep(1 * time.Millisecond) time.Sleep(1 * time.Millisecond)
} }
drv.sock = NoSocketAvail d.sock = NoSocketAvail
return nil return nil
} }
+9 -3
View File
@@ -281,9 +281,16 @@ type Device struct {
buf [64]byte buf [64]byte
ssids [10]string ssids [10]string
sock uint8
readBuf readBuffer
proto uint8
ip uint32
port uint16
} }
// New returns a new Wifinina driver. // New returns a new Wifinina device.
func New(bus drivers.SPI, csPin, ackPin, gpio0Pin, resetPin machine.Pin) *Device { func New(bus drivers.SPI, csPin, ackPin, gpio0Pin, resetPin machine.Pin) *Device {
return &Device{ return &Device{
SPI: bus, SPI: bus,
@@ -295,8 +302,7 @@ func New(bus drivers.SPI, csPin, ackPin, gpio0Pin, resetPin machine.Pin) *Device
} }
func (d *Device) Configure() { func (d *Device) Configure() {
net.UseDriver(d)
net.UseDriver(d.NewDriver())
pinUseDevice(d) pinUseDevice(d)
d.CS.Configure(machine.PinConfig{Mode: machine.PinOutput}) d.CS.Configure(machine.PinConfig{Mode: machine.PinOutput})