diff --git a/espat/wifidriver.go b/espat/adapter.go similarity index 74% rename from espat/wifidriver.go rename to espat/adapter.go index ee485fe..2af80bf 100644 --- a/espat/wifidriver.go +++ b/espat/adapter.go @@ -3,14 +3,15 @@ package espat import ( "time" - "tinygo.org/x/drivers" + "tinygo.org/x/drivers/net" ) func (d *Device) ConnectToAccessPoint(ssid, pass string, timeout time.Duration) error { if len(ssid) == 0 { - return drivers.ErrWiFiMissingSSID + return net.ErrWiFiMissingSSID } + d.SetWifiMode(WifiModeClient) return d.ConnectToAP(ssid, pass, 10) } diff --git a/examples/espat/espconsole/main.go b/examples/espat/espconsole/main.go index dc554d4..d4b7f57 100644 --- a/examples/espat/espconsole/main.go +++ b/examples/espat/espconsole/main.go @@ -113,7 +113,6 @@ func connectToESP() bool { func connectToAP() { println("Connecting to wifi network '" + ssid + "'") - adaptor.SetWifiMode(espat.WifiModeClient) if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil { failMessage(err.Error()) } diff --git a/examples/espat/esphub/main.go b/examples/espat/esphub/main.go index 6f9015d..ba9fff2 100644 --- a/examples/espat/esphub/main.go +++ b/examples/espat/esphub/main.go @@ -99,7 +99,6 @@ func connectToESP() bool { func connectToAP() { println("Connecting to wifi network '" + ssid + "'") - adaptor.SetWifiMode(espat.WifiModeClient) if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil { failMessage(err.Error()) } diff --git a/examples/espat/espstation/main.go b/examples/espat/espstation/main.go index 3a9b7ba..fb08f92 100644 --- a/examples/espat/espstation/main.go +++ b/examples/espat/espstation/main.go @@ -88,7 +88,6 @@ func connectToESP() bool { func connectToAP() { println("Connecting to wifi network '" + ssid + "'") - adaptor.SetWifiMode(espat.WifiModeClient) if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil { failMessage(err.Error()) } diff --git a/examples/espat/mqttclient/main.go b/examples/espat/mqttclient/main.go index 701c91c..3c6bd23 100644 --- a/examples/espat/mqttclient/main.go +++ b/examples/espat/mqttclient/main.go @@ -108,7 +108,6 @@ func connectToESP() bool { func connectToAP() { println("Connecting to wifi network '" + ssid + "'") - adaptor.SetWifiMode(espat.WifiModeClient) if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil { failMessage(err.Error()) } diff --git a/examples/espat/mqttsub/main.go b/examples/espat/mqttsub/main.go index 450703e..a4547cb 100644 --- a/examples/espat/mqttsub/main.go +++ b/examples/espat/mqttsub/main.go @@ -129,7 +129,6 @@ func connectToESP() bool { func connectToAP() { println("Connecting to wifi network '" + ssid + "'") - adaptor.SetWifiMode(espat.WifiModeClient) if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil { failMessage(err.Error()) } diff --git a/examples/espat/tcpclient/main.go b/examples/espat/tcpclient/main.go index 51d3d11..ee5c024 100644 --- a/examples/espat/tcpclient/main.go +++ b/examples/espat/tcpclient/main.go @@ -91,7 +91,6 @@ func connectToESP() bool { func connectToAP() { println("Connecting to wifi network '" + ssid + "'") - adaptor.SetWifiMode(espat.WifiModeClient) if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil { failMessage(err.Error()) } diff --git a/net/driver.go b/net/adapter.go similarity index 51% rename from net/driver.go rename to net/adapter.go index 0880687..501def8 100644 --- a/net/driver.go +++ b/net/adapter.go @@ -1,6 +1,23 @@ 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) ConnectTCPSocket(addr, port string) error ConnectSSLSocket(addr, port string) error @@ -16,12 +33,12 @@ type DeviceDriver interface { Response(timeout int) ([]byte, error) } -var ActiveDevice DeviceDriver +var ActiveDevice Adapter -func UseDriver(driver DeviceDriver) { +func UseDriver(a Adapter) { // TODO: rethink and refactor this if ActiveDevice != nil { panic("net.ActiveDevice is already set") } - ActiveDevice = driver + ActiveDevice = a } diff --git a/net/mqtt/mqtt.go b/net/mqtt/mqtt.go index bcc0d56..bfbbb5f 100644 --- a/net/mqtt/mqtt.go +++ b/net/mqtt/mqtt.go @@ -23,7 +23,7 @@ func NewClient(o *ClientOptions) Client { } type mqttclient struct { - adaptor net.DeviceDriver + adaptor net.Adapter conn net.Conn connected bool opts *ClientOptions diff --git a/net/mqtt/paho.go b/net/mqtt/paho.go index b853455..8490363 100644 --- a/net/mqtt/paho.go +++ b/net/mqtt/paho.go @@ -175,7 +175,7 @@ type ClientOptionsReader struct { // ClientOptions contains configurable options for an MQTT Client. type ClientOptions struct { - Adaptor net.DeviceDriver + Adaptor net.Adapter //Servers []*url.URL Servers string diff --git a/net/net.go b/net/net.go index b4eb349..5c10613 100644 --- a/net/net.go +++ b/net/net.go @@ -94,7 +94,7 @@ func Dial(network, address string) (Conn, error) { // SerialConn is a loosely net.Conn compatible implementation type SerialConn struct { - Adaptor DeviceDriver + Adaptor Adapter } // UDPSerialConn is a loosely net.Conn compatible intended to support diff --git a/rtl8720dn/wifidriver.go b/rtl8720dn/adapter.go similarity index 62% rename from rtl8720dn/wifidriver.go rename to rtl8720dn/adapter.go index 24de7e0..db0d1ce 100644 --- a/rtl8720dn/wifidriver.go +++ b/rtl8720dn/adapter.go @@ -3,12 +3,12 @@ package rtl8720dn import ( "time" - "tinygo.org/x/drivers" + "tinygo.org/x/drivers/net" ) func (r *RTL8720DN) ConnectToAccessPoint(ssid, pass string, timeout time.Duration) error { if len(ssid) == 0 { - return drivers.ErrWiFiMissingSSID + return net.ErrWiFiMissingSSID } return r.ConnectToAP(ssid, pass) @@ -18,3 +18,8 @@ func (r *RTL8720DN) Disconnect() error { _, err := r.Rpc_wifi_disconnect() return err } + +func (r *RTL8720DN) GetClientIP() (string, error) { + ip, _, _, err := r.GetIP() + return ip.String(), err +} diff --git a/wifi.go b/wifi.go deleted file mode 100644 index 2e4df71..0000000 --- a/wifi.go +++ /dev/null @@ -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 -} diff --git a/wifinina/wifidriver.go b/wifinina/adapter.go similarity index 64% rename from wifinina/wifidriver.go rename to wifinina/adapter.go index 7898fd4..063ca07 100644 --- a/wifinina/wifidriver.go +++ b/wifinina/adapter.go @@ -3,12 +3,12 @@ package wifinina import ( "time" - "tinygo.org/x/drivers" + "tinygo.org/x/drivers/net" ) func (d *Device) ConnectToAccessPoint(ssid, pass string, timeout time.Duration) error { if len(ssid) == 0 { - return drivers.ErrWiFiMissingSSID + return net.ErrWiFiMissingSSID } start := time.Now() @@ -22,5 +22,10 @@ func (d *Device) ConnectToAccessPoint(ssid, pass string, timeout time.Duration) 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 } diff --git a/wifinina/tcp.go b/wifinina/tcp.go index fb747e4..ba5f41a 100644 --- a/wifinina/tcp.go +++ b/wifinina/tcp.go @@ -4,50 +4,34 @@ import ( "errors" "strconv" "time" - - "tinygo.org/x/drivers/net" ) const ( 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 { data [ReadBufferSize]byte head int size int } -func (drv *Driver) GetDNS(domain string) (string, error) { - ipAddr, err := drv.dev.GetHostByName(domain) +func (d *Device) GetDNS(domain string) (string, error) { + ipAddr, err := d.GetHostByName(domain) return ipAddr.String(), err } -func (drv *Driver) ConnectTCPSocket(addr, portStr string) error { - return drv.connectSocket(addr, portStr, ProtoModeTCP) +func (d *Device) ConnectTCPSocket(addr, portStr string) error { + return d.connectSocket(addr, portStr, ProtoModeTCP) } -func (drv *Driver) ConnectSSLSocket(addr, portStr string) error { - return drv.connectSocket(addr, portStr, ProtoModeTLS) +func (d *Device) ConnectSSLSocket(addr, portStr string) error { + 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 port, err := convertPort(portStr) @@ -61,7 +45,7 @@ func (drv *Driver) connectSocket(addr, portStr string, mode uint8) error { if mode != ProtoModeTLS { // 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. - ipAddr, err := drv.dev.GetHostByName(addr) + ipAddr, err := d.GetHostByName(addr) if err != nil { 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 - if drv.sock != NoSocketAvail { - if err := drv.stop(); err != nil { + if d.sock != NoSocketAvail { + if err := d.stop(); err != nil { return err } } // 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 } // 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 } // FIXME: this 4 second timeout is simply mimicking the Arduino driver start := time.Now() for time.Since(start) < 4*time.Second { - connected, err := drv.IsConnected() + connected, err := d.IsConnected() if err != nil { return err } @@ -110,12 +94,12 @@ func convertPort(portStr string) (uint16, error) { 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 - if drv.port, err = convertPort(portStr); err != nil { + if d.port, err = convertPort(portStr); err != nil { 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 // 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 { return err } - drv.ip = ipAddr.AsUint32() + d.ip = ipAddr.AsUint32() // check to see if socket is already set; if so, stop it // TODO: we can probably have more than one socket at once right? - if drv.sock != NoSocketAvail { - if err := drv.stop(); err != nil { + if d.sock != NoSocketAvail { + if err := d.stop(); err != nil { return err } } // 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 } // 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 nil } -func (drv *Driver) DisconnectSocket() error { - return drv.stop() +func (d *Device) DisconnectSocket() error { + return d.stop() } -func (drv *Driver) StartSocketSend(size int) error { +func (d *Device) StartSocketSend(size int) error { // not needed for WiFiNINA??? return nil } -func (drv *Driver) Response(timeout int) ([]byte, error) { +func (d *Device) Response(timeout int) ([]byte, error) { return nil, nil } -func (drv *Driver) Write(b []byte) (n int, err error) { - if drv.sock == NoSocketAvail { +func (d *Device) Write(b []byte) (n int, err error) { + if d.sock == NoSocketAvail { return 0, ErrNoSocketAvail } if len(b) == 0 { return 0, ErrNoData } - if drv.proto == ProtoModeUDP { - if err := drv.dev.StartClient("", drv.ip, drv.port, drv.sock, drv.proto); err != nil { + if d.proto == ProtoModeUDP { + if err := d.StartClient("", d.ip, d.port, d.sock, d.proto); err != nil { 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()) } - 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 len(b), nil } else { - written, err := drv.dev.SendData(b, drv.sock) + written, err := d.SendData(b, d.sock) if err != nil { return 0, err } if written == 0 { return 0, ErrDataNotWritten } - if sent, _ := drv.dev.CheckDataSent(drv.sock); !sent { + if sent, _ := d.CheckDataSent(d.sock); !sent { return 0, ErrCheckDataError } return len(b), nil @@ -202,8 +186,8 @@ func (drv *Driver) Write(b []byte) (n int, err error) { return len(b), nil } -func (drv *Driver) ReadSocket(b []byte) (n int, err error) { - avail, err := drv.available() +func (d *Device) ReadSocket(b []byte) (n int, err error) { + avail, err := d.available() if err != nil { println("ReadSocket error: " + err.Error()) return 0, err @@ -215,37 +199,37 @@ func (drv *Driver) ReadSocket(b []byte) (n int, err error) { if avail < length { length = avail } - copy(b, drv.readBuf.data[drv.readBuf.head:drv.readBuf.head+length]) - drv.readBuf.head += length - drv.readBuf.size -= length + copy(b, d.readBuf.data[d.readBuf.head:d.readBuf.head+length]) + d.readBuf.head += length + d.readBuf.size -= length return length, nil } // IsSocketDataAvailable returns of there is socket data available -func (drv *Driver) IsSocketDataAvailable() bool { - n, err := drv.available() +func (d *Device) IsSocketDataAvailable() bool { + n, err := d.available() return err == nil && n > 0 } -func (drv *Driver) available() (int, error) { - if drv.readBuf.size == 0 { - n, err := drv.dev.GetDataBuf(drv.sock, drv.readBuf.data[:]) +func (d *Device) available() (int, error) { + if d.readBuf.size == 0 { + n, err := d.GetDataBuf(d.sock, d.readBuf.data[:]) if n > 0 { - drv.readBuf.head = 0 - drv.readBuf.size = n + d.readBuf.head = 0 + d.readBuf.size = n } if err != nil { return int(n), err } } - return drv.readBuf.size, nil + return d.readBuf.size, nil } -func (drv *Driver) IsConnected() (bool, error) { - if drv.sock == NoSocketAvail { +func (d *Device) IsConnected() (bool, error) { + if d.sock == NoSocketAvail { return false, nil } - s, err := drv.status() + s, err := d.status() if err != nil { return false, err } @@ -261,26 +245,26 @@ func (drv *Driver) IsConnected() (bool, error) { return isConnected, nil } -func (drv *Driver) status() (uint8, error) { - if drv.sock == NoSocketAvail { +func (d *Device) status() (uint8, error) { + if d.sock == NoSocketAvail { return TCPStateClosed, nil } - return drv.dev.GetClientState(drv.sock) + return d.GetClientState(d.sock) } -func (drv *Driver) stop() error { - if drv.sock == NoSocketAvail { +func (d *Device) stop() error { + if d.sock == NoSocketAvail { return nil } - drv.dev.StopClient(drv.sock) + d.StopClient(d.sock) start := time.Now() for time.Since(start) < 5*time.Second { - st, _ := drv.status() + st, _ := d.status() if st == TCPStateClosed { break } time.Sleep(1 * time.Millisecond) } - drv.sock = NoSocketAvail + d.sock = NoSocketAvail return nil } diff --git a/wifinina/wifinina.go b/wifinina/wifinina.go index 6875629..13907a9 100644 --- a/wifinina/wifinina.go +++ b/wifinina/wifinina.go @@ -281,9 +281,16 @@ type Device struct { buf [64]byte 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 { return &Device{ SPI: bus, @@ -295,8 +302,7 @@ func New(bus drivers.SPI, csPin, ackPin, gpio0Pin, resetPin machine.Pin) *Device } func (d *Device) Configure() { - - net.UseDriver(d.NewDriver()) + net.UseDriver(d) pinUseDevice(d) d.CS.Configure(machine.PinConfig{Mode: machine.PinOutput})