From cc5ecafacf79b2d369748b7bd8a91b817d685785 Mon Sep 17 00:00:00 2001 From: BCG Date: Sun, 15 Dec 2019 11:50:21 -0500 Subject: [PATCH] Decoupled net package from espat --- espat/espat.go | 3 +++ examples/espat/esphub/main.go | 2 +- examples/espat/espstation/main.go | 2 +- examples/espat/mqttclient/main.go | 4 ++-- examples/espat/mqttsub/main.go | 4 ++-- examples/espat/tcpclient/main.go | 2 +- net/driver.go | 27 +++++++++++++++++++++++++++ {espat => net}/mqtt/mqtt.go | 9 ++++----- {espat => net}/mqtt/paho.go | 30 ++++++++++++++++++++++++++---- {espat => net}/mqtt/router.go | 0 {espat => net}/mqtt/token.go | 0 {espat/net => net}/net.go | 27 +++++++++++++-------------- {espat => net}/tls/tls.go | 9 ++++----- 13 files changed, 84 insertions(+), 35 deletions(-) create mode 100644 net/driver.go rename {espat => net}/mqtt/mqtt.go (97%) rename {espat => net}/mqtt/paho.go (88%) rename {espat => net}/mqtt/router.go (100%) rename {espat => net}/mqtt/token.go (100%) rename {espat/net => net}/net.go (93%) rename {espat => net}/tls/tls.go (74%) diff --git a/espat/espat.go b/espat/espat.go index 3a5ff39..9abe785 100644 --- a/espat/espat.go +++ b/espat/espat.go @@ -24,6 +24,8 @@ import ( "strconv" "strings" "time" + + "tinygo.org/x/drivers/net" ) // Device wraps UART connection to the ESP8266/ESP32. @@ -48,6 +50,7 @@ func New(b machine.UART) *Device { // Configure sets up the device for communication. func (d Device) Configure() { ActiveDevice = &d + net.ActiveDevice = ActiveDevice } // Connected checks if there is communication with the ESP8266/ESP32. diff --git a/examples/espat/esphub/main.go b/examples/espat/esphub/main.go index bba6427..fdc3301 100644 --- a/examples/espat/esphub/main.go +++ b/examples/espat/esphub/main.go @@ -11,7 +11,7 @@ import ( "time" "tinygo.org/x/drivers/espat" - "tinygo.org/x/drivers/espat/net" + "tinygo.org/x/drivers/net" ) // change actAsAP to true to act as an access point instead of connecting to one. diff --git a/examples/espat/espstation/main.go b/examples/espat/espstation/main.go index 2cdb380..f6b7dc8 100644 --- a/examples/espat/espstation/main.go +++ b/examples/espat/espstation/main.go @@ -11,7 +11,7 @@ import ( "time" "tinygo.org/x/drivers/espat" - "tinygo.org/x/drivers/espat/net" + "tinygo.org/x/drivers/net" ) // access point info diff --git a/examples/espat/mqttclient/main.go b/examples/espat/mqttclient/main.go index acbe829..aede3a0 100644 --- a/examples/espat/mqttclient/main.go +++ b/examples/espat/mqttclient/main.go @@ -17,7 +17,7 @@ import ( "time" "tinygo.org/x/drivers/espat" - "tinygo.org/x/drivers/espat/mqtt" + "tinygo.org/x/drivers/net/mqtt" ) // access point info @@ -64,7 +64,7 @@ func main() { return } - opts := mqtt.NewClientOptions(adaptor) + opts := mqtt.NewClientOptions() opts.AddBroker(server).SetClientID("tinygo-client-" + randomString(10)) println("Connecting to MQTT broker at", server) diff --git a/examples/espat/mqttsub/main.go b/examples/espat/mqttsub/main.go index 1a429f5..bf9544c 100644 --- a/examples/espat/mqttsub/main.go +++ b/examples/espat/mqttsub/main.go @@ -18,7 +18,7 @@ import ( "time" "tinygo.org/x/drivers/espat" - "tinygo.org/x/drivers/espat/mqtt" + "tinygo.org/x/drivers/net/mqtt" ) // access point info @@ -72,7 +72,7 @@ func main() { return } - opts := mqtt.NewClientOptions(adaptor) + opts := mqtt.NewClientOptions() opts.AddBroker(server).SetClientID("tinygo-client-" + randomString(10)) println("Connecting to MQTT broker at", server) diff --git a/examples/espat/tcpclient/main.go b/examples/espat/tcpclient/main.go index f85a62d..a52ca44 100644 --- a/examples/espat/tcpclient/main.go +++ b/examples/espat/tcpclient/main.go @@ -11,7 +11,7 @@ import ( "time" "tinygo.org/x/drivers/espat" - "tinygo.org/x/drivers/espat/net" + "tinygo.org/x/drivers/net" ) // access point info diff --git a/net/driver.go b/net/driver.go new file mode 100644 index 0000000..0880687 --- /dev/null +++ b/net/driver.go @@ -0,0 +1,27 @@ +package net + +type DeviceDriver interface { + GetDNS(domain string) (string, error) + ConnectTCPSocket(addr, port string) error + ConnectSSLSocket(addr, port string) error + ConnectUDPSocket(addr, sendport, listenport string) error + DisconnectSocket() error + StartSocketSend(size int) error + Write(b []byte) (n int, err error) + ReadSocket(b []byte) (n int, err error) + IsSocketDataAvailable() bool + + // FIXME: this is really specific to espat, and maybe shouldn't be part + // of the driver interface + Response(timeout int) ([]byte, error) +} + +var ActiveDevice DeviceDriver + +func UseDriver(driver DeviceDriver) { + // TODO: rethink and refactor this + if ActiveDevice != nil { + panic("net.ActiveDevice is already set") + } + ActiveDevice = driver +} diff --git a/espat/mqtt/mqtt.go b/net/mqtt/mqtt.go similarity index 97% rename from espat/mqtt/mqtt.go rename to net/mqtt/mqtt.go index 65d9edd..e3b51ce 100644 --- a/espat/mqtt/mqtt.go +++ b/net/mqtt/mqtt.go @@ -8,9 +8,8 @@ import ( "time" "github.com/eclipse/paho.mqtt.golang/packets" - "tinygo.org/x/drivers/espat" - "tinygo.org/x/drivers/espat/net" - "tinygo.org/x/drivers/espat/tls" + "tinygo.org/x/drivers/net" + "tinygo.org/x/drivers/net/tls" ) // NewClient will create an MQTT v3.1.1 client with all of the options specified @@ -24,7 +23,7 @@ func NewClient(o *ClientOptions) Client { } type mqttclient struct { - adaptor *espat.Device + adaptor net.DeviceDriver conn net.Conn connected bool opts *ClientOptions @@ -297,7 +296,7 @@ func (c *mqttclient) ackFunc(packet *packets.PublishPacket) func() { // If there is no data yet but also is no error, it returns nil for both values. func (c *mqttclient) ReadPacket() (packets.ControlPacket, error) { // check for data first... - if espat.ActiveDevice.IsSocketDataAvailable() { + if net.ActiveDevice.IsSocketDataAvailable() { return packets.ReadPacket(c.conn) } return nil, nil diff --git a/espat/mqtt/paho.go b/net/mqtt/paho.go similarity index 88% rename from espat/mqtt/paho.go rename to net/mqtt/paho.go index 4a9eaf3..b853455 100644 --- a/espat/mqtt/paho.go +++ b/net/mqtt/paho.go @@ -25,7 +25,7 @@ import ( "time" "github.com/eclipse/paho.mqtt.golang/packets" - "tinygo.org/x/drivers/espat" + "tinygo.org/x/drivers/net" ) const ( @@ -175,7 +175,7 @@ type ClientOptionsReader struct { // ClientOptions contains configurable options for an MQTT Client. type ClientOptions struct { - Adaptor *espat.Device + Adaptor net.DeviceDriver //Servers []*url.URL Servers string @@ -209,8 +209,8 @@ type ClientOptions struct { } // NewClientOptions returns a new ClientOptions struct. -func NewClientOptions(adaptor *espat.Device) *ClientOptions { - return &ClientOptions{Adaptor: adaptor, ProtocolVersion: 4} +func NewClientOptions() *ClientOptions { + return &ClientOptions{Adaptor: net.ActiveDevice, ProtocolVersion: 4} } // AddBroker adds a broker URI to the list of brokers to be used. The format should be @@ -256,3 +256,25 @@ func (o *ClientOptions) SetPassword(p string) *ClientOptions { o.Password = p return o } + +// SetWill accepts a string will message to be set. When the client connects, +// it will give this will message to the broker, which will then publish the +// provided payload (the will) to any clients that are subscribed to the provided +// topic. +func (o *ClientOptions) SetWill(topic string, payload string, qos byte, retained bool) *ClientOptions { + o.SetBinaryWill(topic, []byte(payload), qos, retained) + return o +} + +// SetBinaryWill accepts a []byte will message to be set. When the client connects, +// it will give this will message to the broker, which will then publish the +// provided payload (the will) to any clients that are subscribed to the provided +// topic. +func (o *ClientOptions) SetBinaryWill(topic string, payload []byte, qos byte, retained bool) *ClientOptions { + o.WillEnabled = true + o.WillTopic = topic + o.WillPayload = payload + o.WillQos = qos + o.WillRetained = retained + return o +} diff --git a/espat/mqtt/router.go b/net/mqtt/router.go similarity index 100% rename from espat/mqtt/router.go rename to net/mqtt/router.go diff --git a/espat/mqtt/token.go b/net/mqtt/token.go similarity index 100% rename from espat/mqtt/token.go rename to net/mqtt/token.go diff --git a/espat/net/net.go b/net/net.go similarity index 93% rename from espat/net/net.go rename to net/net.go index 4ed784c..05a35df 100644 --- a/espat/net/net.go +++ b/net/net.go @@ -7,8 +7,6 @@ import ( "strconv" "strings" "time" - - "tinygo.org/x/drivers/espat" ) // DialUDP makes a UDP network connection. raadr is the port that the messages will @@ -20,15 +18,15 @@ func DialUDP(network string, laddr, raddr *UDPAddr) (*UDPSerialConn, error) { listenport := strconv.Itoa(laddr.Port) // disconnect any old socket - espat.ActiveDevice.DisconnectSocket() + ActiveDevice.DisconnectSocket() // connect new socket - err := espat.ActiveDevice.ConnectUDPSocket(addr, sendport, listenport) + err := ActiveDevice.ConnectUDPSocket(addr, sendport, listenport) if err != nil { return nil, err } - return &UDPSerialConn{SerialConn: SerialConn{Adaptor: espat.ActiveDevice}, laddr: laddr, raddr: raddr}, nil + return &UDPSerialConn{SerialConn: SerialConn{Adaptor: ActiveDevice}, laddr: laddr, raddr: raddr}, nil } // ListenUDP listens for UDP connections on the port listed in laddr. @@ -38,15 +36,15 @@ func ListenUDP(network string, laddr *UDPAddr) (*UDPSerialConn, error) { listenport := strconv.Itoa(laddr.Port) // disconnect any old socket - espat.ActiveDevice.DisconnectSocket() + ActiveDevice.DisconnectSocket() // connect new socket - err := espat.ActiveDevice.ConnectUDPSocket(addr, sendport, listenport) + err := ActiveDevice.ConnectUDPSocket(addr, sendport, listenport) if err != nil { return nil, err } - return &UDPSerialConn{SerialConn: SerialConn{Adaptor: espat.ActiveDevice}, laddr: laddr}, nil + return &UDPSerialConn{SerialConn: SerialConn{Adaptor: ActiveDevice}, laddr: laddr}, nil } // DialTCP makes a TCP network connection. raadr is the port that the messages will @@ -57,15 +55,15 @@ func DialTCP(network string, laddr, raddr *TCPAddr) (*TCPSerialConn, error) { sendport := strconv.Itoa(raddr.Port) // disconnect any old socket? - //espat.ActiveDevice.DisconnectSocket() + //ActiveDevice.DisconnectSocket() // connect new socket - err := espat.ActiveDevice.ConnectTCPSocket(addr, sendport) + err := ActiveDevice.ConnectTCPSocket(addr, sendport) if err != nil { return nil, err } - return &TCPSerialConn{SerialConn: SerialConn{Adaptor: espat.ActiveDevice}, laddr: laddr, raddr: raddr}, nil + return &TCPSerialConn{SerialConn: SerialConn{Adaptor: ActiveDevice}, laddr: laddr, raddr: raddr}, nil } // Dial connects to the address on the named network. @@ -96,7 +94,7 @@ func Dial(network, address string) (Conn, error) { // SerialConn is a loosely net.Conn compatible implementation type SerialConn struct { - Adaptor *espat.Device + Adaptor DeviceDriver } // UDPSerialConn is a loosely net.Conn compatible intended to support @@ -149,6 +147,7 @@ func (c *SerialConn) Write(b []byte) (n int, err error) { if err != nil { return n, err } + /* TODO(bcg): this is kind of specific to espat, should maybe refactor */ _, err = c.Adaptor.Response(1000) if err != nil { return n, err @@ -240,7 +239,7 @@ func ResolveTCPAddr(network, address string) (*TCPAddr, error) { // TODO: make sure network is 'tcp' // separate domain from port, if any r := strings.Split(address, ":") - addr, err := espat.ActiveDevice.GetDNS(r[0]) + addr, err := ActiveDevice.GetDNS(r[0]) if err != nil { return nil, err } @@ -263,7 +262,7 @@ func ResolveUDPAddr(network, address string) (*UDPAddr, error) { // TODO: make sure network is 'udp' // separate domain from port, if any r := strings.Split(address, ":") - addr, err := espat.ActiveDevice.GetDNS(r[0]) + addr, err := ActiveDevice.GetDNS(r[0]) if err != nil { return nil, err } diff --git a/espat/tls/tls.go b/net/tls/tls.go similarity index 74% rename from espat/tls/tls.go rename to net/tls/tls.go index 3abd27f..5e5460c 100644 --- a/espat/tls/tls.go +++ b/net/tls/tls.go @@ -5,8 +5,7 @@ package tls import ( "strconv" - "tinygo.org/x/drivers/espat" - "tinygo.org/x/drivers/espat/net" + "tinygo.org/x/drivers/net" ) // Dial makes a TLS network connection. It tries to provide a mostly compatible interface @@ -22,15 +21,15 @@ func Dial(network, address string, config *Config) (*net.TCPSerialConn, error) { sendport := strconv.Itoa(raddr.Port) // disconnect any old socket - espat.ActiveDevice.DisconnectSocket() + net.ActiveDevice.DisconnectSocket() // connect new socket - err = espat.ActiveDevice.ConnectSSLSocket(addr, sendport) + err = net.ActiveDevice.ConnectSSLSocket(addr, sendport) if err != nil { return nil, err } - return net.NewTCPSerialConn(net.SerialConn{Adaptor: espat.ActiveDevice}, nil, raddr), nil + return net.NewTCPSerialConn(net.SerialConn{Adaptor: net.ActiveDevice}, nil, raddr), nil } // Config is a placeholder for future compatibility with