From 9c88d1fab4bfba3e22a68e5490434e956ba90e36 Mon Sep 17 00:00:00 2001 From: Ron Evans Date: Fri, 21 Jun 2019 10:24:50 +0200 Subject: [PATCH] espat: add ResolveUDPAddr and ResolveTCPAddr implementations using AT command for DNS lookup Signed-off-by: Ron Evans --- espat/commands.go | 3 +++ espat/net.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ espat/tcp.go | 14 +++++++++++++- 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/espat/commands.go b/espat/commands.go index 1a01bee..24a9422 100644 --- a/espat/commands.go +++ b/espat/commands.go @@ -85,6 +85,9 @@ const ( // Establish TCP connection or register UDP port TCPConnect = "+CIPSTART" + // DNS Lookup + TCPDNSLookup = "+CIPDOMAIN" + // Send Data TCPSend = "+CIPSEND" diff --git a/espat/net.go b/espat/net.go index cb409cd..58a8274 100644 --- a/espat/net.go +++ b/espat/net.go @@ -2,6 +2,7 @@ package espat import ( "strconv" + "strings" "time" ) @@ -156,6 +157,51 @@ func (c *SerialConn) SetWriteDeadline(t time.Time) error { return nil } +// ResolveTCPAddr returns an address of TCP end point. +// +// The network must be a TCP network name. +// +func (d *Device) 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]) + if err != nil { + return nil, err + } + if len(r) > 1 { + port, e := strconv.Atoi(r[1]) + if e != nil { + return nil, e + } + return &TCPAddr{IP: ip, Port: port}, nil + } + return &TCPAddr{IP: ip}, nil +} + +// ResolveUDPAddr returns an address of UDP end point. +// +// The network must be a UDP network name. +// +func (d *Device) 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]) + if err != nil { + return nil, err + } + if len(r) > 1 { + port, e := strconv.Atoi(r[1]) + if e != nil { + return nil, e + } + return &UDPAddr{IP: ip, Port: port}, nil + } + + return &UDPAddr{IP: ip}, nil +} + // The following definitions are here to support a Golang standard package // net-compatible interface for IP until TinyGo can compile the net package. diff --git a/espat/tcp.go b/espat/tcp.go index 0007c63..084eb42 100644 --- a/espat/tcp.go +++ b/espat/tcp.go @@ -15,11 +15,23 @@ const ( TCPTransferModeUnvarnished = 1 ) +// GetDNS returns the IP address for a domain name. +func (d *Device) GetDNS(domain string) (IP, error) { + d.Set(TCPDNSLookup, "\""+domain+"\"") + time.Sleep(1000 * time.Millisecond) + r := strings.Split(string(d.Response()), ":") + if len(r) != 2 { + return nil, errors.New("Invalid domain lookup result") + } + res := strings.Split(r[1], "\r\n") + return IP(res[0]), nil +} + // ConnectTCPSocket creates a new TCP socket connection for the ESP8266/ESP32. // Currently only supports single connection mode. func (d *Device) ConnectTCPSocket(addr, port string) error { protocol := "TCP" - val := "\"" + protocol + "\",\"" + addr + "\"," + port + val := "\"" + protocol + "\",\"" + addr + "\"," + port + ",120" d.Set(TCPConnect, val) time.Sleep(1000 * time.Millisecond) r := d.Response()