mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-15 12:23:41 +00:00
espat: refactor net and tls interface compatible code into separate sub-packages
Signed-off-by: Ron Evans <ron@hybridgroup.com>
This commit is contained in:
@@ -36,6 +36,9 @@ type Device struct {
|
||||
socketdata []byte
|
||||
}
|
||||
|
||||
// ActiveDevice is the currently configured Device in use. There can only be one.
|
||||
var ActiveDevice *Device
|
||||
|
||||
// New returns a new espat driver. Pass in a fully configured UART bus.
|
||||
func New(b machine.UART) *Device {
|
||||
return &Device{bus: b, response: make([]byte, 512), socketdata: make([]byte, 0, 1024)}
|
||||
@@ -43,6 +46,7 @@ func New(b machine.UART) *Device {
|
||||
|
||||
// Configure sets up the device for communication.
|
||||
func (d Device) Configure() {
|
||||
ActiveDevice = &d
|
||||
}
|
||||
|
||||
// Connected checks if there is communication with the ESP8266/ESP32.
|
||||
|
||||
+5
-3
@@ -7,6 +7,8 @@ import (
|
||||
|
||||
"github.com/eclipse/paho.mqtt.golang/packets"
|
||||
"tinygo.org/x/drivers/espat"
|
||||
"tinygo.org/x/drivers/espat/net"
|
||||
"tinygo.org/x/drivers/espat/tls"
|
||||
)
|
||||
|
||||
// NewClient will create an MQTT v3.1.1 client with all of the options specified
|
||||
@@ -20,7 +22,7 @@ func NewClient(o *ClientOptions) Client {
|
||||
|
||||
type mqttclient struct {
|
||||
adaptor *espat.Device
|
||||
conn espat.Conn
|
||||
conn net.Conn
|
||||
connected bool
|
||||
opts *ClientOptions
|
||||
mid uint16
|
||||
@@ -52,13 +54,13 @@ func (c *mqttclient) Connect() Token {
|
||||
// make connection
|
||||
if strings.Contains(c.opts.Servers, "ssl://") {
|
||||
url := strings.TrimPrefix(c.opts.Servers, "ssl://")
|
||||
c.conn, err = c.adaptor.DialTLS("tcp", url, nil)
|
||||
c.conn, err = tls.Dial("tcp", url, nil)
|
||||
if err != nil {
|
||||
return &mqtttoken{err: err}
|
||||
}
|
||||
} else if strings.Contains(c.opts.Servers, "tcp://") {
|
||||
url := strings.TrimPrefix(c.opts.Servers, "tcp://")
|
||||
c.conn, err = c.adaptor.Dial("tcp", url)
|
||||
c.conn, err = net.Dial("tcp", url)
|
||||
if err != nil {
|
||||
return &mqtttoken{err: err}
|
||||
}
|
||||
|
||||
@@ -1,113 +1,93 @@
|
||||
package espat
|
||||
// package net is intended to provide compatible interfaces with the
|
||||
// Go standard library's net package.
|
||||
package net
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"tinygo.org/x/drivers/espat"
|
||||
)
|
||||
|
||||
// DialUDP makes a UDP network connection. raadr is the port that the messages will
|
||||
// be sent to, and laddr is the port that will be listened to in order to
|
||||
// receive incoming messages.
|
||||
func (d *Device) DialUDP(network string, laddr, raddr *UDPAddr) (*UDPSerialConn, error) {
|
||||
func DialUDP(network string, laddr, raddr *UDPAddr) (*UDPSerialConn, error) {
|
||||
addr := raddr.IP.String()
|
||||
sendport := strconv.Itoa(raddr.Port)
|
||||
listenport := strconv.Itoa(laddr.Port)
|
||||
|
||||
// disconnect any old socket
|
||||
d.DisconnectSocket()
|
||||
espat.ActiveDevice.DisconnectSocket()
|
||||
|
||||
// connect new socket
|
||||
d.ConnectUDPSocket(addr, sendport, listenport)
|
||||
espat.ActiveDevice.ConnectUDPSocket(addr, sendport, listenport)
|
||||
|
||||
return &UDPSerialConn{SerialConn: SerialConn{Adaptor: d}, laddr: laddr, raddr: raddr}, nil
|
||||
return &UDPSerialConn{SerialConn: SerialConn{Adaptor: espat.ActiveDevice}, laddr: laddr, raddr: raddr}, nil
|
||||
}
|
||||
|
||||
// ListenUDP listens for UDP connections on the port listed in laddr.
|
||||
func (d *Device) ListenUDP(network string, laddr *UDPAddr) (*UDPSerialConn, error) {
|
||||
func ListenUDP(network string, laddr *UDPAddr) (*UDPSerialConn, error) {
|
||||
addr := "0"
|
||||
sendport := "0"
|
||||
listenport := strconv.Itoa(laddr.Port)
|
||||
|
||||
// disconnect any old socket
|
||||
d.DisconnectSocket()
|
||||
espat.ActiveDevice.DisconnectSocket()
|
||||
|
||||
// connect new socket
|
||||
d.ConnectUDPSocket(addr, sendport, listenport)
|
||||
espat.ActiveDevice.ConnectUDPSocket(addr, sendport, listenport)
|
||||
|
||||
return &UDPSerialConn{SerialConn: SerialConn{Adaptor: d}, laddr: laddr}, nil
|
||||
return &UDPSerialConn{SerialConn: SerialConn{Adaptor: espat.ActiveDevice}, laddr: laddr}, nil
|
||||
}
|
||||
|
||||
// DialTCP makes a TCP network connection. raadr is the port that the messages will
|
||||
// be sent to, and laddr is the port that will be listened to in order to
|
||||
// receive incoming messages.
|
||||
func (d *Device) DialTCP(network string, laddr, raddr *TCPAddr) (*TCPSerialConn, error) {
|
||||
func DialTCP(network string, laddr, raddr *TCPAddr) (*TCPSerialConn, error) {
|
||||
addr := raddr.IP.String()
|
||||
sendport := strconv.Itoa(raddr.Port)
|
||||
|
||||
// disconnect any old socket
|
||||
d.DisconnectSocket()
|
||||
espat.ActiveDevice.DisconnectSocket()
|
||||
|
||||
// connect new socket
|
||||
d.ConnectTCPSocket(addr, sendport)
|
||||
espat.ActiveDevice.ConnectTCPSocket(addr, sendport)
|
||||
|
||||
return &TCPSerialConn{SerialConn: SerialConn{Adaptor: d}, laddr: laddr, raddr: raddr}, nil
|
||||
return &TCPSerialConn{SerialConn: SerialConn{Adaptor: espat.ActiveDevice}, laddr: laddr, raddr: raddr}, nil
|
||||
}
|
||||
|
||||
// Dial connects to the address on the named network.
|
||||
// It tries to provide a mostly compatible interface
|
||||
// to net.Dial().
|
||||
func (d *Device) Dial(network, address string) (Conn, error) {
|
||||
func Dial(network, address string) (Conn, error) {
|
||||
switch network {
|
||||
case "tcp":
|
||||
raddr, err := d.ResolveTCPAddr(network, address)
|
||||
raddr, err := ResolveTCPAddr(network, address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c, e := d.DialTCP(network, &TCPAddr{}, raddr)
|
||||
c, e := DialTCP(network, &TCPAddr{}, raddr)
|
||||
return c.opConn(), e
|
||||
case "udp":
|
||||
raddr, err := d.ResolveUDPAddr(network, address)
|
||||
raddr, err := ResolveUDPAddr(network, address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c, e := d.DialUDP(network, &UDPAddr{}, raddr)
|
||||
c, e := DialUDP(network, &UDPAddr{}, raddr)
|
||||
return c.opConn(), e
|
||||
default:
|
||||
return nil, errors.New("invalid network for dial")
|
||||
}
|
||||
}
|
||||
|
||||
// DialTLS makes a TLS network connection. It tries to provide a mostly compatible interface
|
||||
// to tls.Dial().
|
||||
// DialTLS connects to the given network address.
|
||||
func (d *Device) DialTLS(network, address string, config *TLSConfig) (*TCPSerialConn, error) {
|
||||
raddr, err := d.ResolveTCPAddr(network, address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addr := raddr.IP.String()
|
||||
sendport := strconv.Itoa(raddr.Port)
|
||||
|
||||
// disconnect any old socket
|
||||
d.DisconnectSocket()
|
||||
|
||||
// connect new socket
|
||||
err = d.ConnectSSLSocket(addr, sendport)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &TCPSerialConn{SerialConn: SerialConn{Adaptor: d}, raddr: raddr}, nil
|
||||
}
|
||||
|
||||
// SerialConn is a loosely net.Conn compatible implementation
|
||||
type SerialConn struct {
|
||||
Adaptor *Device
|
||||
Adaptor *espat.Device
|
||||
}
|
||||
|
||||
// UDPSerialConn is a loosely net.Conn compatible intended to support
|
||||
@@ -118,6 +98,11 @@ type UDPSerialConn struct {
|
||||
raddr *UDPAddr
|
||||
}
|
||||
|
||||
// NewUDPSerialConn returns a new UDPSerialConn/
|
||||
func NewUDPSerialConn(c SerialConn, laddr, raddr *UDPAddr) *UDPSerialConn {
|
||||
return &UDPSerialConn{SerialConn: c, raddr: raddr}
|
||||
}
|
||||
|
||||
// TCPSerialConn is a loosely net.Conn compatible intended to support
|
||||
// TCP over serial.
|
||||
type TCPSerialConn struct {
|
||||
@@ -126,6 +111,11 @@ type TCPSerialConn struct {
|
||||
raddr *TCPAddr
|
||||
}
|
||||
|
||||
// NewTCPSerialConn returns a new TCPSerialConn/
|
||||
func NewTCPSerialConn(c SerialConn, laddr, raddr *TCPAddr) *TCPSerialConn {
|
||||
return &TCPSerialConn{SerialConn: c, raddr: raddr}
|
||||
}
|
||||
|
||||
// Read reads data from the connection.
|
||||
// TODO: implement the full method functionality:
|
||||
// Read can be made to time out and return an Error with Timeout() == true
|
||||
@@ -226,14 +216,15 @@ func (c *SerialConn) SetWriteDeadline(t time.Time) error {
|
||||
//
|
||||
// The network must be a TCP network name.
|
||||
//
|
||||
func (d *Device) ResolveTCPAddr(network, address string) (*TCPAddr, error) {
|
||||
func ResolveTCPAddr(network, address string) (*TCPAddr, error) {
|
||||
// TODO: make sure network is 'tcp'
|
||||
// separate domain from port, if any
|
||||
r := strings.Split(address, ":")
|
||||
ip, err := d.GetDNS(r[0])
|
||||
addr, err := espat.ActiveDevice.GetDNS(r[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ip := IP(addr)
|
||||
if len(r) > 1 {
|
||||
port, e := strconv.Atoi(r[1])
|
||||
if e != nil {
|
||||
@@ -248,14 +239,15 @@ func (d *Device) ResolveTCPAddr(network, address string) (*TCPAddr, error) {
|
||||
//
|
||||
// The network must be a UDP network name.
|
||||
//
|
||||
func (d *Device) ResolveUDPAddr(network, address string) (*UDPAddr, error) {
|
||||
func ResolveUDPAddr(network, address string) (*UDPAddr, error) {
|
||||
// TODO: make sure network is 'udp'
|
||||
// separate domain from port, if any
|
||||
r := strings.Split(address, ":")
|
||||
ip, err := d.GetDNS(r[0])
|
||||
addr, err := espat.ActiveDevice.GetDNS(r[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ip := IP(addr)
|
||||
if len(r) > 1 {
|
||||
port, e := strconv.Atoi(r[1])
|
||||
if e != nil {
|
||||
@@ -339,11 +331,6 @@ func (ip IP) String() string {
|
||||
return string(ip)
|
||||
}
|
||||
|
||||
// TLSConfig is a placeholder for future compatibility with
|
||||
// tls.Config.
|
||||
type TLSConfig struct {
|
||||
}
|
||||
|
||||
// Conn is a generic stream-oriented network connection.
|
||||
// This interface is from the Go standard library.
|
||||
type Conn interface {
|
||||
+3
-3
@@ -15,14 +15,14 @@ const (
|
||||
)
|
||||
|
||||
// GetDNS returns the IP address for a domain name.
|
||||
func (d *Device) GetDNS(domain string) (IP, error) {
|
||||
func (d *Device) GetDNS(domain string) (string, error) {
|
||||
d.Set(TCPDNSLookup, "\""+domain+"\"")
|
||||
r := strings.Split(string(d.Response(1000)), ":")
|
||||
if len(r) != 2 {
|
||||
return nil, errors.New("Invalid domain lookup result")
|
||||
return "", errors.New("Invalid domain lookup result")
|
||||
}
|
||||
res := strings.Split(r[1], "\r\n")
|
||||
return IP(res[0]), nil
|
||||
return res[0], nil
|
||||
}
|
||||
|
||||
// ConnectTCPSocket creates a new TCP socket connection for the ESP8266/ESP32.
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// Package tls is intended to provide a minimal set of compatible interfaces with the
|
||||
// Go standard library's tls package.
|
||||
package tls
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"tinygo.org/x/drivers/espat"
|
||||
"tinygo.org/x/drivers/espat/net"
|
||||
)
|
||||
|
||||
// Dial makes a TLS network connection. It tries to provide a mostly compatible interface
|
||||
// to tls.Dial().
|
||||
// Dial connects to the given network address.
|
||||
func Dial(network, address string, config *Config) (*net.TCPSerialConn, error) {
|
||||
raddr, err := net.ResolveTCPAddr(network, address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addr := raddr.IP.String()
|
||||
sendport := strconv.Itoa(raddr.Port)
|
||||
|
||||
// disconnect any old socket
|
||||
espat.ActiveDevice.DisconnectSocket()
|
||||
|
||||
// connect new socket
|
||||
err = espat.ActiveDevice.ConnectSSLSocket(addr, sendport)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return net.NewTCPSerialConn(net.SerialConn{Adaptor: espat.ActiveDevice}, nil, raddr), nil
|
||||
}
|
||||
|
||||
// Config is a placeholder for future compatibility with
|
||||
// tls.Config.
|
||||
type Config struct {
|
||||
}
|
||||
Reference in New Issue
Block a user