From 59aece351ab2481cb0b08401db494ee7412c1c66 Mon Sep 17 00:00:00 2001 From: Ron Evans Date: Wed, 26 Jun 2019 09:13:29 +0200 Subject: [PATCH] espat: change Response() method to use a passed-in timeout value instead of fixed pauses. Signed-off-by: Ron Evans --- espat/espat.go | 23 +++++++++-------- espat/tcp.go | 35 +++++++++----------------- espat/wifi.go | 42 ++++++++++++------------------- examples/espat/espconsole/main.go | 6 ++--- 4 files changed, 43 insertions(+), 63 deletions(-) diff --git a/espat/espat.go b/espat/espat.go index c195354..ec09d10 100644 --- a/espat/espat.go +++ b/espat/espat.go @@ -50,7 +50,7 @@ func (d *Device) Connected() bool { d.Execute(Test) // handle response here, should include "OK" - r := d.Response() + r := d.Response(100) if strings.Contains(string(r), "OK") { return true } @@ -93,7 +93,7 @@ func (d Device) Set(cmd, params string) error { // Version returns the ESP8266/ESP32 firmware version info. func (d Device) Version() []byte { d.Execute(Version) - return d.Response() + return d.Response(100) } // Echo sets the ESP8266/ESP32 echo setting. @@ -104,7 +104,7 @@ func (d Device) Echo(set bool) { d.Execute(EchoConfigOff) } // TODO: check for success - d.Response() + d.Response(100) } // Reset restarts the ESP8266/ESP32 firmware. Due to how the baud rate changes, @@ -112,13 +112,13 @@ func (d Device) Echo(set bool) { // what you are doing when you call this. func (d Device) Reset() { d.Execute(Restart) - d.Response() + d.Response(100) } // ReadSocket returns the data that has already been read in from the responses. func (d *Device) ReadSocket(b []byte) (n int, err error) { // make sure no data in buffer - d.Response() + d.Response(100) count := len(b) if len(b) >= len(d.socketdata) { @@ -137,8 +137,11 @@ func (d *Device) ReadSocket(b []byte) (n int, err error) { } // Response gets the next response bytes from the ESP8266/ESP32. -func (d *Device) Response() []byte { - var i, retries int +// The call will retry for up to timeout milliseconds before returning nothing. +func (d *Device) Response(timeout int) []byte { + var i int + pause := 10 // pause to wait for 10 ms + retries := timeout / pause header := make([]byte, 2) for { @@ -174,13 +177,13 @@ func (d *Device) Response() []byte { i++ } } - retries++ - if retries > 2 { + retries-- + if retries == 0 { break } // pause to make sure is no more data to be read - time.Sleep(10 * time.Millisecond) + time.Sleep(time.Duration(pause) * time.Millisecond) } return d.response[:i] } diff --git a/espat/tcp.go b/espat/tcp.go index 624863f..50ae75e 100644 --- a/espat/tcp.go +++ b/espat/tcp.go @@ -4,7 +4,6 @@ import ( "errors" "strconv" "strings" - "time" ) const ( @@ -18,8 +17,7 @@ const ( // 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()), ":") + r := strings.Split(string(d.Response(1000)), ":") if len(r) != 2 { return nil, errors.New("Invalid domain lookup result") } @@ -33,8 +31,7 @@ func (d *Device) ConnectTCPSocket(addr, port string) error { protocol := "TCP" val := "\"" + protocol + "\",\"" + addr + "\"," + port + ",120" d.Set(TCPConnect, val) - time.Sleep(1000 * time.Millisecond) - r := d.Response() + r := d.Response(1000) if strings.Contains(string(r), "OK") { return nil } @@ -46,8 +43,7 @@ func (d *Device) ConnectUDPSocket(addr, sendport, listenport string) error { protocol := "UDP" val := "\"" + protocol + "\",\"" + addr + "\"," + sendport + "," + listenport + ",2" d.Set(TCPConnect, val) - time.Sleep(pause * time.Millisecond) - r := d.Response() + r := d.Response(pause) if strings.Contains(string(r), "OK") { return nil } @@ -60,8 +56,8 @@ func (d *Device) ConnectSSLSocket(addr, port string) error { protocol := "SSL" val := "\"" + protocol + "\",\"" + addr + "\"," + port + ",120" d.Set(TCPConnect, val) - time.Sleep(5000 * time.Millisecond) - r := d.Response() + // this operation takes longer, so wait up to 6 seconds to complete. + r := d.Response(6000) if strings.Contains(string(r), "CONNECT") { return nil } @@ -71,8 +67,7 @@ func (d *Device) ConnectSSLSocket(addr, port string) error { // DisconnectSocket disconnects the ESP8266/ESP32 from the current TCP/UDP connection. func (d *Device) DisconnectSocket() error { d.Execute(TCPClose) - time.Sleep(pause * time.Millisecond) - d.Response() + d.Response(pause) return nil } @@ -81,15 +76,14 @@ func (d *Device) DisconnectSocket() error { func (d *Device) SetMux(mode int) error { val := strconv.Itoa(mode) d.Set(TCPMultiple, val) - time.Sleep(pause * time.Millisecond) - d.Response() + d.Response(pause) return nil } // GetMux returns the ESP8266/ESP32 current client TCP/UDP configuration for concurrent connections. func (d *Device) GetMux() ([]byte, error) { d.Query(TCPMultiple) - return d.Response(), nil + return d.Response(pause), nil } // SetTCPTransferMode sets the ESP8266/ESP32 current client TCP/UDP transfer mode. @@ -97,26 +91,24 @@ func (d *Device) GetMux() ([]byte, error) { func (d *Device) SetTCPTransferMode(mode int) error { val := strconv.Itoa(mode) d.Set(TransmissionMode, val) - time.Sleep(pause * time.Millisecond) - d.Response() + d.Response(pause) return nil } // GetTCPTransferMode returns the ESP8266/ESP32 current client TCP/UDP transfer mode. func (d *Device) GetTCPTransferMode() []byte { d.Query(TransmissionMode) - return d.Response() + return d.Response(pause) } // StartSocketSend gets the ESP8266/ESP32 ready to receive TCP/UDP socket data. func (d *Device) StartSocketSend(size int) error { val := strconv.Itoa(size) d.Set(TCPSend, val) - time.Sleep(pause * time.Millisecond) // when ">" is received, it indicates // ready to receive data - r := d.Response() + r := d.Response(pause) if strings.Contains(string(r), ">") { return nil } @@ -127,10 +119,7 @@ func (d *Device) StartSocketSend(size int) error { // and to return to command mode. This is only used in "unvarnished" raw mode. func (d *Device) EndSocketSend() error { d.Write([]byte("+++")) - time.Sleep(pause * time.Millisecond) - // TODO: wait until ">" is received, which indicates - // ready to receive data - d.Response() + d.Response(pause) return nil } diff --git a/espat/wifi.go b/espat/wifi.go index 78bf2d3..48c734b 100644 --- a/espat/wifi.go +++ b/espat/wifi.go @@ -2,7 +2,6 @@ package espat import ( "strconv" - "time" ) const ( @@ -19,15 +18,14 @@ const ( // GetWifiMode returns the ESP8266/ESP32 wifi mode. func (d *Device) GetWifiMode() []byte { d.Query(WifiMode) - return d.Response() + return d.Response(100) } // SetWifiMode sets the ESP8266/ESP32 wifi mode. func (d *Device) SetWifiMode(mode int) error { val := strconv.Itoa(mode) d.Set(WifiMode, val) - time.Sleep(pause * time.Millisecond) - d.Response() + d.Response(pause) return nil } @@ -36,7 +34,7 @@ func (d *Device) SetWifiMode(mode int) error { // GetConnectedAP returns the ESP8266/ESP32 is currently connected to as a client. func (d *Device) GetConnectedAP() []byte { d.Query(ConnectAP) - return d.Response() + return d.Response(100) } // ConnectToAP connects the ESP8266/ESP32 to an access point. @@ -44,32 +42,28 @@ func (d *Device) GetConnectedAP() []byte { func (d *Device) ConnectToAP(ssid, pwd string, ws int) error { val := "\"" + ssid + "\",\"" + pwd + "\"" d.Set(ConnectAP, val) - // TODO: a better way to wait for connect and check for up to ws seconds. - time.Sleep(time.Duration(ws) * time.Second) - d.Response() + d.Response(ws * 1000) return nil } // DisconnectFromAP disconnects the ESP8266/ESP32 from the current access point. func (d *Device) DisconnectFromAP() error { d.Execute(Disconnect) - time.Sleep(1000 * time.Millisecond) - d.Response() + d.Response(1000) return nil } // GetClientIP returns the ESP8266/ESP32 current client IP addess when connected to an Access Point. func (d *Device) GetClientIP() string { d.Query(SetStationIP) - return string(d.Response()) + return string(d.Response(100)) } // SetClientIP sets the ESP8266/ESP32 current client IP addess when connected to an Access Point. func (d *Device) SetClientIP(ipaddr string) []byte { val := "\"" + ipaddr + "\"" d.Set(ConnectAP, val) - time.Sleep(500 * time.Millisecond) - d.Response() + d.Response(500) return nil } @@ -78,7 +72,7 @@ func (d *Device) SetClientIP(ipaddr string) []byte { // GetAPConfig returns the ESP8266/ESP32 current configuration when acting as an Access Point. func (d *Device) GetAPConfig() string { d.Query(SoftAPConfigCurrent) - return string(d.Response()) + return string(d.Response(100)) } // SetAPConfig sets the ESP8266/ESP32 current configuration when acting as an Access Point. @@ -89,29 +83,27 @@ func (d *Device) SetAPConfig(ssid, pwd string, ch, security int) error { ecnval := strconv.Itoa(security) val := "\"" + ssid + "\",\"" + pwd + "\"," + chval + "," + ecnval d.Set(SoftAPConfigCurrent, val) - time.Sleep(1000 * time.Millisecond) - d.Response() + d.Response(1000) return nil } // GetAPClients returns the ESP8266/ESP32 current clients when acting as an Access Point. func (d *Device) GetAPClients() string { d.Query(ListConnectedIP) - return string(d.Response()) + return string(d.Response(100)) } // GetAPIP returns the ESP8266/ESP32 current IP addess when configured as an Access Point. func (d *Device) GetAPIP() string { d.Query(SetSoftAPIPCurrent) - return string(d.Response()) + return string(d.Response(100)) } // SetAPIP sets the ESP8266/ESP32 current IP addess when configured as an Access Point. func (d *Device) SetAPIP(ipaddr string) error { val := "\"" + ipaddr + "\"" d.Set(SetSoftAPIPCurrent, val) - time.Sleep(500 * time.Millisecond) - d.Response() + d.Response(500) return nil } @@ -119,7 +111,7 @@ func (d *Device) SetAPIP(ipaddr string) error { // from flash storage. These settings are those used after a reset. func (d *Device) GetAPConfigFlash() string { d.Query(SoftAPConfigFlash) - return string(d.Response()) + return string(d.Response(100)) } // SetAPConfigFlash sets the ESP8266/ESP32 current configuration acting as an Access Point, @@ -131,8 +123,7 @@ func (d *Device) SetAPConfigFlash(ssid, pwd string, ch, security int) error { ecnval := strconv.Itoa(security) val := "\"" + ssid + "\",\"" + pwd + "\"," + chval + "," + ecnval d.Set(SoftAPConfigFlash, val) - time.Sleep(1000 * time.Millisecond) - d.Response() + d.Response(1000) return nil } @@ -140,7 +131,7 @@ func (d *Device) SetAPConfigFlash(ssid, pwd string, ch, security int) error { // This is the IP address that will be used after a reset. func (d *Device) GetAPIPFlash() string { d.Query(SetSoftAPIPFlash) - return string(d.Response()) + return string(d.Response(100)) } // SetAPIPFlash sets the ESP8266/ESP32 current IP addess when configured as an Access Point. @@ -148,7 +139,6 @@ func (d *Device) GetAPIPFlash() string { func (d *Device) SetAPIPFlash(ipaddr string) error { val := "\"" + ipaddr + "\"" d.Set(SetSoftAPIPFlash, val) - time.Sleep(500 * time.Millisecond) - d.Response() + d.Response(500) return nil } diff --git a/examples/espat/espconsole/main.go b/examples/espat/espconsole/main.go index 5cb81ea..2e5e0bf 100644 --- a/examples/espat/espconsole/main.go +++ b/examples/espat/espconsole/main.go @@ -80,11 +80,8 @@ func main() { input[i+1] = byte('\n') adaptor.Write(input[:i+2]) - // give the ESP8266 a chance to respond. - time.Sleep(10 * time.Millisecond) - // display response - console.Write(adaptor.Response()) + console.Write(adaptor.Response(100)) // prompt prompt() @@ -118,6 +115,7 @@ func connectToAP() { // provide access point func provideAP() { + time.Sleep(500 * time.Millisecond) console.Write([]byte("Starting wifi network as access point '")) console.Write([]byte(ssid)) console.Write([]byte("'...\r\n"))