tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/espat/tcp.go (about)

     1  package espat
     2  
     3  import (
     4  	"errors"
     5  	"strconv"
     6  	"strings"
     7  )
     8  
     9  const (
    10  	TCPMuxSingle   = 0
    11  	TCPMuxMultiple = 1
    12  
    13  	TCPTransferModeNormal      = 0
    14  	TCPTransferModeUnvarnished = 1
    15  )
    16  
    17  // GetDNS returns the IP address for a domain name.
    18  func (d *Device) GetDNS(domain string) (string, error) {
    19  	d.Set(TCPDNSLookup, "\""+domain+"\"")
    20  	resp, err := d.Response(1000)
    21  	if err != nil {
    22  		return "", err
    23  	}
    24  	if !strings.Contains(string(resp), ":") {
    25  		return "", errors.New("GetDNS error:" + string(resp))
    26  	}
    27  	r := strings.Split(string(resp), ":")
    28  	if len(r) != 2 {
    29  		return "", errors.New("Invalid domain lookup result")
    30  	}
    31  	res := strings.Split(r[1], "\r\n")
    32  	return strings.Trim(res[0], `"`), nil
    33  }
    34  
    35  // ConnectTCPSocket creates a new TCP socket connection for the ESP8266/ESP32.
    36  // Currently only supports single connection mode.
    37  func (d *Device) ConnectTCPSocket(addr, port string) error {
    38  	protocol := "TCP"
    39  	val := "\"" + protocol + "\",\"" + addr + "\"," + port + ",120"
    40  	err := d.Set(TCPConnect, val)
    41  	if err != nil {
    42  		return err
    43  	}
    44  	_, e := d.Response(3000)
    45  	if e != nil {
    46  		return e
    47  	}
    48  	return nil
    49  }
    50  
    51  // ConnectUDPSocket creates a new UDP connection for the ESP8266/ESP32.
    52  func (d *Device) ConnectUDPSocket(addr, sendport, listenport string) error {
    53  	protocol := "UDP"
    54  	val := "\"" + protocol + "\",\"" + addr + "\"," + sendport + "," + listenport + ",0"
    55  	err := d.Set(TCPConnect, val)
    56  	if err != nil {
    57  		return err
    58  	}
    59  	_, e := d.Response(3000)
    60  	if e != nil {
    61  		return e
    62  	}
    63  	return nil
    64  }
    65  
    66  // ConnectSSLSocket creates a new SSL socket connection for the ESP8266/ESP32.
    67  // Currently only supports single connection mode.
    68  func (d *Device) ConnectSSLSocket(addr, port string) error {
    69  	protocol := "SSL"
    70  	val := "\"" + protocol + "\",\"" + addr + "\"," + port + ",120"
    71  	d.Set(TCPConnect, val)
    72  	// this operation takes longer, so wait up to 6 seconds to complete.
    73  	_, err := d.Response(6000)
    74  	if err != nil {
    75  		return err
    76  	}
    77  	return nil
    78  }
    79  
    80  // DisconnectSocket disconnects the ESP8266/ESP32 from the current TCP/UDP connection.
    81  func (d *Device) DisconnectSocket() error {
    82  	err := d.Execute(TCPClose)
    83  	if err != nil {
    84  		return err
    85  	}
    86  	_, e := d.Response(pause)
    87  	if e != nil {
    88  		return e
    89  	}
    90  	return nil
    91  }
    92  
    93  // SetMux sets the ESP8266/ESP32 current client TCP/UDP configuration for concurrent connections
    94  // either single TCPMuxSingle or multiple TCPMuxMultiple (up to 4).
    95  func (d *Device) SetMux(mode int) error {
    96  	val := strconv.Itoa(mode)
    97  	d.Set(TCPMultiple, val)
    98  	_, err := d.Response(pause)
    99  	return err
   100  }
   101  
   102  // GetMux returns the ESP8266/ESP32 current client TCP/UDP configuration for concurrent connections.
   103  func (d *Device) GetMux() ([]byte, error) {
   104  	d.Query(TCPMultiple)
   105  	return d.Response(pause)
   106  }
   107  
   108  // SetTCPTransferMode sets the ESP8266/ESP32 current client TCP/UDP transfer mode.
   109  // Either TCPTransferModeNormal or TCPTransferModeUnvarnished.
   110  func (d *Device) SetTCPTransferMode(mode int) error {
   111  	val := strconv.Itoa(mode)
   112  	d.Set(TransmissionMode, val)
   113  	_, err := d.Response(pause)
   114  	return err
   115  }
   116  
   117  // GetTCPTransferMode returns the ESP8266/ESP32 current client TCP/UDP transfer mode.
   118  func (d *Device) GetTCPTransferMode() ([]byte, error) {
   119  	d.Query(TransmissionMode)
   120  	return d.Response(pause)
   121  }
   122  
   123  // StartSocketSend gets the ESP8266/ESP32 ready to receive TCP/UDP socket data.
   124  func (d *Device) StartSocketSend(size int) error {
   125  	val := strconv.Itoa(size)
   126  	d.Set(TCPSend, val)
   127  
   128  	// when ">" is received, it indicates
   129  	// ready to receive data
   130  	r, err := d.Response(2000)
   131  	if err != nil {
   132  		return err
   133  	}
   134  	if strings.Contains(string(r), ">") {
   135  		return nil
   136  	}
   137  	return errors.New("StartSocketSend error:" + string(r))
   138  }
   139  
   140  // EndSocketSend tell the ESP8266/ESP32 the TCP/UDP socket data sending is complete,
   141  // and to return to command mode. This is only used in "unvarnished" raw mode.
   142  func (d *Device) EndSocketSend() error {
   143  	d.Write([]byte("+++"))
   144  
   145  	_, err := d.Response(pause)
   146  	return err
   147  }