diff --git a/README-net.md b/README-net.md new file mode 100644 index 000000000..705c23fbd --- /dev/null +++ b/README-net.md @@ -0,0 +1,233 @@ +### Table of Contents + +- ["net" Package](#net-package) +- [Using "net" Package](#using-net-package) +- [Using "net/http" Package](#using-nethttp-package) +- [Using "crypto/tls" Package](#using-cryptotls-package) +- [Using Sockets](#using-sockets) + +## "net" Package + +TinyGo's "net" package is ported from Go. The port offers a subset of Go's +"net" package. The subset maintains Go 1 compatiblity guarantee. A Go +application that uses "net" will most-likey just work on TinyGo if the usage is +within the subset offered. (There may be external constraints such as limited +SRAM on some targets that may limit full "net" functionality). + +Continue below for details on using "net" and "net/http" packages. + +See src/net/READMD.md in the TinyGo repo for more details on maintaining +TinyGo's "net" package. + +## Using "net" Package + +Ideally, TinyGo's "net" package would be Go's "net" package and applications +using "net" would just work, as-is. TinyGo's net package is a partial port of +Go's net package, so some things may not work because they have not been +ported. + +There are a few features excluded during the porting process, in particular: + +- No IPv6 support +- No DualStack support + +Run ```go doc -all ./src/net``` in TinyGo repo to see full listing of what has +been ported. Here is a list of things known to work. You can find examples +of these at [examples/net](examples/net/). + +### What is Known to Work + +(These are all IPv4 only). + +- TCP client and server +- UDP client +- TLS client +- HTTP client and server +- HTTPS client +- NTP client (UDP) +- MQTT client (paho & natiu) +- WebSocket client and server + +Multiple sockets can be opened in a single app. For example, the app could run +as an http server listen on port :80 and also use NTP to get the current time +or send something over MQTT. There is a practical limit to the number of +active sockets per app, around 8 or 10, so don't go crazy. + +Applications using Go's net package will need a few setup steps to work with +TinyGo's net package. The steps are required before using "net". + +### Step 1: Probe to Load Network Driver + +Call Probe() to load the correct network driver for your target. Probe() +allows the app to work on multiple targets. + +```go +package main + +import ( + "tinygo.org/x/drivers/netlink/probe" +) + +func main() { + + // load network driver for target + link, dev := probe.Probe() + + ... +} +``` + +Probe() will load the driver with default configuration for the target. For +custom configuration, the app can open code Probe() for the target +requirements. + +Probe() returns a [Netlinker](netlink/README.md) and a +[Netdever](netdev/README.md), interfaces implemented by the network driver. +Next, we'll use the Netlinker interface to connect the target to an IP network. + +### Step 2: Connect to an IP Network + +Before the net package is fully functional, we need to connect the target to an +IP network. + +```go +package main + +import ( + "tinygo.org/x/drivers/netlink" + "tinygo.org/x/drivers/netlink/probe" +) + +func main() { + + // load network driver for target + link, _ := probe.Probe() + + // Connect target to IP network + link.NetConnect(&netlink.ConnectParams{ + Ssid: "my SSID", + Passphrase: "my passphrase", + }) + + // OK to use "net" from here on + ... +} +``` + +Optionally, get notified of IP network connects and disconnects: + +```go + link.Notify(func(e netlink.Event) { + switch e { + case netlink.EventNetUp: println("Network UP") + case netlink.EventNetDown: println("Network DOWN") + }) +``` + +Here is an example of an http server listening on port :8080: + +```go +package main + +import ( + "fmt" + "net/http" + + "tinygo.org/x/drivers/netlink" + "tinygo.org/x/drivers/netlink/probe" +) + +func HelloServer(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:]) +} + +func main() { + + // load network driver for target + link, _ := probe.Probe() + + // Connect target to IP network + link.NetConnect(&netlink.ConnectParams{ + Ssid: "my SSID", + Passphrase: "my passphrase", + }) + + // Serve it up + http.HandleFunc("/", HelloServer) + http.ListenAndServe(":8080", nil) +} +``` + +## Using "net/http" Package + +TinyGo's net/http package is a partial port of Go's net/http package, providing +a subset of the full net/http package. There are a few features excluded +during the porting process, in particular: + +- No HTTP/2 support +- No TLS support for HTTP servers (no https servers) +- HTTP client request can't be reused + +HTTP client methods (http.Get, http.Head, http.Post, and http.PostForm) are +functional. Dial clients support both HTTP and HTTPS URLs. + +HTTP server methods and objects are mostly ported, but for HTTP only; HTTPS +servers are not supported. + +HTTP request and response handling code is mostly ported, so most the intricacy +of parsing and writing headers is handled as in the full net/http package. + +Run ```go doc -all ./src/net/http``` in TinyGo repo to see full listing. + +## Using "crypto/tls" Package + +TinyGo's TLS support (crypto/tls) relies on hardware offload of the TLS +protocol. This is different from Go's crypto/tls package which handles the TLS +protocol in software. + +TinyGo's TLS support is only available for client applications. You can +http.Get() to an https:// address, but you cannot http.ListenAndServeTLS() an +https server. + +The offloading hardware has pre-defined TLS certificates built-in. + +## Using Sockets + +The Netdever interface is a BSD socket-like interface so an application can make direct +socket calls, bypassing the "net" package for the lowest overhead. + +Here is a simple TCP client application using direct sockets: + +```go +package main + +import ( + "net" // only need to parse IP address + + "tinygo.org/x/drivers/netdev" + "tinygo.org/x/drivers/netlink" + "tinygo.org/x/drivers/netlink/probe" +) + +func main() { + + // load network driver for target + link, dev := probe.Probe() + + // Connect target to IP network + link.NetConnect(&netlink.ConnectParams{ + Ssid: "my SSID", + Passphrase: "my passphrase", + }) + + // omit error handling + + sock, _ := dev.Socket(netdev.AF_INET, netdev.SOCK_STREAM, netdev.IPPROTO_TCP) + + dev.Connect(sock, "", net.ParseIP("10.0.0.100"), 8080) + dev.Send(sock, []bytes("hello"), 0, 0) + + dev.Close(sock) + link.NetDisconnect() +} +``` diff --git a/espat/adapter.go b/espat/adapter.go deleted file mode 100644 index 3df9180e9..000000000 --- a/espat/adapter.go +++ /dev/null @@ -1,20 +0,0 @@ -package espat - -import ( - "time" - - "tinygo.org/x/drivers/net" -) - -func (d *Device) ConnectToAccessPoint(ssid, pass string, timeout time.Duration) error { - if len(ssid) == 0 { - return net.ErrWiFiMissingSSID - } - - d.SetWifiMode(WifiModeClient) - return d.ConnectToAP(ssid, pass, int(timeout.Seconds())) -} - -func (d *Device) Disconnect() error { - return d.DisconnectFromAP() -} diff --git a/espat/espat.go b/espat/espat.go index cdb97cc80..aca6d7a3e 100644 --- a/espat/espat.go +++ b/espat/espat.go @@ -15,41 +15,300 @@ // // AT command set: // https://www.espressif.com/sites/default/files/documentation/4a-esp8266_at_instruction_set_en.pdf +// +// 02/2023 sfeldma@gmail.com Heavily modified to use netdev interface + package espat // import "tinygo.org/x/drivers/espat" import ( "errors" + "fmt" + "machine" + "net" "strconv" "strings" + "sync" "time" - "tinygo.org/x/drivers" - "tinygo.org/x/drivers/net" + "tinygo.org/x/drivers/netdev" + "tinygo.org/x/drivers/netlink" ) -// Device wraps UART connection to the ESP8266/ESP32. -type Device struct { - bus drivers.UART +type Config struct { + // UART config + Uart *machine.UART + Tx machine.Pin + Rx machine.Pin +} +type socket struct { + inUse bool + protocol int + lip net.IP + lport int +} + +type Device struct { + cfg *Config + uart *machine.UART // command responses that come back from the ESP8266/ESP32 response []byte - // data received from a TCP/UDP connection forwarded by the ESP8266/ESP32 - socketdata []byte + data []byte + socket socket + mu sync.Mutex +} + +func NewDevice(cfg *Config) *Device { + return &Device{ + cfg: cfg, + response: make([]byte, 1500), + data: make([]byte, 0, 1500), + } +} + +func (d *Device) NetConnect(params *netlink.ConnectParams) error { + + if len(params.Ssid) == 0 { + return netlink.ErrMissingSSID + } + + d.uart = d.cfg.Uart + d.uart.Configure(machine.UARTConfig{TX: d.cfg.Tx, RX: d.cfg.Rx}) + + // Connect to ESP8266/ESP32 + fmt.Printf("Connecting to device...") + + for i := 0; i < 5; i++ { + if d.Connected() { + break + } + time.Sleep(1 * time.Second) + } + + if !d.Connected() { + fmt.Printf("FAILED\r\n") + return netlink.ErrConnectFailed + } + + fmt.Printf("CONNECTED\r\n") + + // Connect to Wifi AP + fmt.Printf("Connecting to Wifi SSID '%s'...", params.Ssid) + + d.SetWifiMode(WifiModeClient) + + err := d.ConnectToAP(params.Ssid, params.Passphrase, 10 /* secs */) + if err != nil { + fmt.Printf("FAILED\r\n") + return err + } + + fmt.Printf("CONNECTED\r\n") + + ip, err := d.GetIPAddr() + if err != nil { + return err + } + fmt.Printf("DHCP-assigned IP: %s\r\n", ip) + fmt.Printf("\r\n") + + return nil +} + +func (d *Device) NetDisconnect() { + d.DisconnectFromAP() + fmt.Printf("\r\nDisconnected from Wifi\r\n\r\n") +} + +func (d *Device) NetNotify(cb func(netlink.Event)) { + // Not supported +} + +func (d *Device) GetHostByName(name string) (net.IP, error) { + ip, err := d.GetDNS(name) + return net.ParseIP(ip), err +} + +func (d *Device) GetHardwareAddr() (net.HardwareAddr, error) { + return net.HardwareAddr{}, netlink.ErrNotSupported +} + +func (d *Device) GetIPAddr() (net.IP, error) { + resp, err := d.GetClientIP() + if err != nil { + return net.IP{}, err + } + prefix := "+CIPSTA:ip:" + for _, line := range strings.Split(resp, "\n") { + if ok := strings.HasPrefix(line, prefix); ok { + ip := line[len(prefix)+1 : len(line)-2] + return net.ParseIP(ip), nil + } + } + return net.IP{}, fmt.Errorf("Error getting IP address") +} + +func (d *Device) Socket(domain int, stype int, protocol int) (int, error) { + + switch domain { + case netdev.AF_INET: + default: + return -1, netdev.ErrFamilyNotSupported + } + + switch { + case protocol == netdev.IPPROTO_TCP && stype == netdev.SOCK_STREAM: + case protocol == netdev.IPPROTO_TLS && stype == netdev.SOCK_STREAM: + case protocol == netdev.IPPROTO_UDP && stype == netdev.SOCK_DGRAM: + default: + return -1, netdev.ErrProtocolNotSupported + } + + // Only supporting single connection mode, so only one socket at a time + if d.socket.inUse { + return -1, netdev.ErrNoMoreSockets + } + d.socket.inUse = true + d.socket.protocol = protocol + + return 0, nil +} + +func (d *Device) Bind(sockfd int, ip net.IP, port int) error { + d.socket.lip = ip + d.socket.lport = port + return nil +} + +func (d *Device) Connect(sockfd int, host string, ip net.IP, port int) error { + var err error + var addr = ip.String() + var rport = strconv.Itoa(port) + var lport = strconv.Itoa(d.socket.lport) + + switch d.socket.protocol { + case netdev.IPPROTO_TCP: + err = d.ConnectTCPSocket(addr, rport) + case netdev.IPPROTO_UDP: + err = d.ConnectUDPSocket(addr, rport, lport) + case netdev.IPPROTO_TLS: + err = d.ConnectSSLSocket(host, rport) + } + + if err != nil { + if host == "" { + return fmt.Errorf("Connect to %s:%d timed out", ip, port) + } else { + return fmt.Errorf("Connect to %s:%d timed out", host, port) + } + } + + return nil +} + +func (d *Device) Listen(sockfd int, backlog int) error { + switch d.socket.protocol { + case netdev.IPPROTO_UDP: + default: + return netdev.ErrProtocolNotSupported + } + return nil +} + +func (d *Device) Accept(sockfd int, ip net.IP, port int) (int, error) { + return -1, netdev.ErrNotSupported +} + +func (d *Device) sendChunk(sockfd int, buf []byte, deadline time.Time) (int, error) { + // Check if we've timed out + if !deadline.IsZero() { + if time.Now().After(deadline) { + return -1, netdev.ErrTimeout + } + } + err := d.StartSocketSend(len(buf)) + if err != nil { + return -1, err + } + n, err := d.Write(buf) + if err != nil { + return -1, err + } + _, err = d.Response(1000) + if err != nil { + return -1, err + } + return n, err +} + +func (d *Device) Send(sockfd int, buf []byte, flags int, deadline time.Time) (int, error) { + + d.mu.Lock() + defer d.mu.Unlock() + + // Break large bufs into chunks so we don't overrun the hw queue + + chunkSize := 1436 + for i := 0; i < len(buf); i += chunkSize { + end := i + chunkSize + if end > len(buf) { + end = len(buf) + } + _, err := d.sendChunk(sockfd, buf[i:end], deadline) + if err != nil { + return -1, err + } + } + + return len(buf), nil +} + +func (d *Device) Recv(sockfd int, buf []byte, flags int, deadline time.Time) (int, error) { + + d.mu.Lock() + defer d.mu.Unlock() + + var length = len(buf) + + // Limit length read size to chunk large read requests + if length > 1436 { + length = 1436 + } + + for { + // Check if we've timed out + if !deadline.IsZero() { + if time.Now().After(deadline) { + return -1, netdev.ErrTimeout + } + } + + n, err := d.ReadSocket(buf[:length]) + if err != nil { + return -1, err + } + if n == 0 { + d.mu.Unlock() + time.Sleep(100 * time.Millisecond) + d.mu.Lock() + continue + } + + return n, nil + } } -// ActiveDevice is the currently configured Device in use. There can only be one. -var ActiveDevice *Device +func (d *Device) Close(sockfd int) error { + d.mu.Lock() + defer d.mu.Unlock() -// New returns a new espat driver. Pass in a fully configured UART bus. -func New(b drivers.UART) *Device { - return &Device{bus: b, response: make([]byte, 512), socketdata: make([]byte, 0, 1024)} + d.socket.inUse = false + return d.DisconnectSocket() } -// Configure sets up the device for communication. -func (d Device) Configure() { - ActiveDevice = &d - net.ActiveDevice = ActiveDevice +func (d *Device) SetSockOpt(sockfd int, level int, opt int, value interface{}) error { + return netdev.ErrNotSupported } // Connected checks if there is communication with the ESP8266/ESP32. @@ -57,7 +316,7 @@ func (d *Device) Connected() bool { d.Execute(Test) // handle response here, should include "OK" - _, err := d.Response(100) + _, err := d.Response(1000) if err != nil { return false } @@ -66,12 +325,12 @@ func (d *Device) Connected() bool { // Write raw bytes to the UART. func (d *Device) Write(b []byte) (n int, err error) { - return d.bus.Write(b) + return d.uart.Write(b) } // Read raw bytes from the UART. func (d *Device) Read(b []byte) (n int, err error) { - return d.bus.Read(b) + return d.uart.Read(b) } // how long in milliseconds to pause after sending AT commands @@ -100,9 +359,10 @@ func (d Device) Set(cmd, params string) error { // Version returns the ESP8266/ESP32 firmware version info. func (d Device) Version() []byte { d.Execute(Version) - r, err := d.Response(100) + r, err := d.Response(2000) if err != nil { - return []byte("unknown") + //return []byte("unknown") + return []byte(err.Error()) } return r } @@ -132,16 +392,16 @@ func (d *Device) ReadSocket(b []byte) (n int, err error) { d.Response(300) count := len(b) - if len(b) >= len(d.socketdata) { + if len(b) >= len(d.data) { // copy it all, then clear socket data - count = len(d.socketdata) - copy(b, d.socketdata[:count]) - d.socketdata = d.socketdata[:0] + count = len(d.data) + copy(b, d.data[:count]) + d.data = d.data[:0] } else { // copy all we can, then keep the remaining socket data around - copy(b, d.socketdata[:count]) - copy(d.socketdata, d.socketdata[count:]) - d.socketdata = d.socketdata[:len(d.socketdata)-count] + copy(b, d.data[:count]) + copy(d.data, d.data[count:]) + d.data = d.data[:len(d.data)-count] } return count, nil @@ -157,11 +417,11 @@ func (d *Device) Response(timeout int) ([]byte, error) { retries := timeout / pause for { - size = d.bus.Buffered() + size = d.uart.Buffered() if size > 0 { end += size - d.bus.Read(d.response[start:end]) + d.uart.Read(d.response[start:end]) // if "+IPD" then read socket data if strings.Contains(string(d.response[:end]), "+IPD") { @@ -204,18 +464,19 @@ func (d *Device) parseIPD(end int) error { val := string(d.response[s+5 : e]) // TODO: verify count - _, err := strconv.Atoi(val) + v, err := strconv.Atoi(val) if err != nil { // not expected data here. what to do? return err } // load up the socket data - d.socketdata = append(d.socketdata, d.response[e+1:end]...) + //d.data = append(d.data, d.response[e+1:end]...) + d.data = append(d.data, d.response[e+1:e+1+v]...) return nil } // IsSocketDataAvailable returns of there is socket data available func (d *Device) IsSocketDataAvailable() bool { - return len(d.socketdata) > 0 || d.bus.Buffered() > 0 + return len(d.data) > 0 || d.uart.Buffered() > 0 } diff --git a/espat/tcp.go b/espat/tcp.go index b2c87e507..9c8524d9a 100644 --- a/espat/tcp.go +++ b/espat/tcp.go @@ -51,7 +51,7 @@ func (d *Device) ConnectTCPSocket(addr, port string) error { // ConnectUDPSocket creates a new UDP connection for the ESP8266/ESP32. func (d *Device) ConnectUDPSocket(addr, sendport, listenport string) error { protocol := "UDP" - val := "\"" + protocol + "\",\"" + addr + "\"," + sendport + "," + listenport + ",2" + val := "\"" + protocol + "\",\"" + addr + "\"," + sendport + "," + listenport + ",0" err := d.Set(TCPConnect, val) if err != nil { return err diff --git a/espat/wifi.go b/espat/wifi.go index ea37a8e8f..808cc0762 100644 --- a/espat/wifi.go +++ b/espat/wifi.go @@ -44,10 +44,7 @@ func (d *Device) ConnectToAP(ssid, pwd string, ws int) error { d.Set(ConnectAP, val) _, err := d.Response(ws * 1000) - if err != nil { - return err - } - return nil + return err } // DisconnectFromAP disconnects the ESP8266/ESP32 from the current access point. diff --git a/examples/espat/espconsole/main.go b/examples/espat/espconsole/main.go deleted file mode 100644 index ad550062c..000000000 --- a/examples/espat/espconsole/main.go +++ /dev/null @@ -1,145 +0,0 @@ -// This is a console to a ESP8266/ESP32 running on the device UART1. -// Allows you to type AT commands from your computer via the microcontroller. -// -// In other words: -// Your computer <--> UART0 <--> MCU <--> UART1 <--> ESP8266 <--> INTERNET -// -// More information on the Espressif AT command set at: -// https://www.espressif.com/sites/default/files/documentation/4a-esp8266_at_instruction_set_en.pdf -package main - -import ( - "machine" - "time" - - "tinygo.org/x/drivers/espat" -) - -// change actAsAP to true to act as an access point instead of connecting to one. -const actAsAP = false - -var ( - // access point info - ssid string - pass string -) - -// these are the default pins for the Arduino Nano33 IoT. -// change these to connect to a different UART or pins for the ESP8266/ESP32 -var ( - uart = machine.UART1 - tx = machine.PA22 - rx = machine.PA23 - - console = machine.Serial - - adaptor *espat.Device -) - -func main() { - uart.Configure(machine.UARTConfig{TX: tx, RX: rx}) - - // Init esp8266 - adaptor = espat.New(uart) - adaptor.Configure() - - // first check if connected - if connectToESP() { - println("Connected to wifi adaptor.") - adaptor.Echo(false) - - connectToAP() - } else { - println("") - failMessage("Unable to connect to wifi adaptor.") - return - } - - println("Type an AT command then press enter:") - prompt() - - input := make([]byte, 64) - i := 0 - for { - if console.Buffered() > 0 { - data, _ := console.ReadByte() - - switch data { - case 13: - // return key - console.Write([]byte("\r\n")) - - // send command to ESP8266 - input[i] = byte('\r') - input[i+1] = byte('\n') - adaptor.Write(input[:i+2]) - - // display response - r, _ := adaptor.Response(500) - console.Write(r) - - // prompt - prompt() - - i = 0 - continue - default: - // just echo the character - console.WriteByte(data) - input[i] = data - i++ - } - } - time.Sleep(10 * time.Millisecond) - } -} - -func prompt() { - print("ESPAT>") -} - -// connect to ESP8266/ESP32 -func connectToESP() bool { - for i := 0; i < 5; i++ { - println("Connecting to wifi adaptor...") - if adaptor.Connected() { - return true - } - time.Sleep(1 * time.Second) - } - return false -} - -// connect to access point -func connectToAP() { - println("Connecting to wifi network '" + ssid + "'") - - if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil { - failMessage(err.Error()) - } - - println("Connected.") - ip, err := adaptor.GetClientIP() - if err != nil { - failMessage(err.Error()) - } - - println(ip) -} - -// provide access point -func provideAP() { - println("Starting wifi network as access point '" + ssid + "'...") - adaptor.SetWifiMode(espat.WifiModeAP) - adaptor.SetAPConfig(ssid, pass, 7, espat.WifiAPSecurityWPA2_PSK) - println("Ready.") - ip, _ := adaptor.GetAPIP() - println(ip) -} - -func failMessage(msg string) { - for { - println(msg) - time.Sleep(1 * time.Second) - } -} diff --git a/examples/espat/esphub/main.go b/examples/espat/esphub/main.go deleted file mode 100644 index e253955ea..000000000 --- a/examples/espat/esphub/main.go +++ /dev/null @@ -1,131 +0,0 @@ -// This is a sensor hub that uses a ESP8266/ESP32 running on the device UART1. -// It creates a UDP "server" you can use to get info to/from your computer via the microcontroller. -// -// In other words: -// Your computer <--> UART0 <--> MCU <--> UART1 <--> ESP8266 <--> INTERNET -package main - -import ( - "machine" - "time" - - "tinygo.org/x/drivers/espat" - "tinygo.org/x/drivers/net" -) - -// change actAsAP to true to act as an access point instead of connecting to one. -const actAsAP = false - -var ( - // access point info - ssid string - pass string -) - -// these are the default pins for the Arduino Nano33 IoT. -// change these to connect to a different UART or pins for the ESP8266/ESP32 -var ( - uart = machine.UART1 - tx = machine.PA22 - rx = machine.PA23 - - adaptor *espat.Device -) - -func main() { - uart.Configure(machine.UARTConfig{TX: tx, RX: rx}) - - // Init esp8266 - adaptor = espat.New(uart) - adaptor.Configure() - - readyled := machine.LED - readyled.Configure(machine.PinConfig{Mode: machine.PinOutput}) - readyled.High() - - // first check if connected - if connectToESP() { - println("Connected to wifi adaptor.") - adaptor.Echo(false) - - connectToAP() - } else { - println("") - failMessage("Unable to connect to wifi adaptor.") - return - } - - // now make UDP connection - laddr := &net.UDPAddr{Port: 2222} - println("Loading UDP listener...") - conn, _ := net.ListenUDP("UDP", laddr) - - println("Waiting for data...") - data := make([]byte, 50) - blink := true - for { - n, _ := conn.Read(data) - if n > 0 { - println(string(data[:n])) - conn.Write([]byte("hello back\r\n")) - } - blink = !blink - if blink { - readyled.High() - } else { - readyled.Low() - } - time.Sleep(500 * time.Millisecond) - } - - // Right now this code is never reached. Need a way to trigger it... - println("Disconnecting UDP...") - conn.Close() - println("Done.") -} - -// connect to ESP8266/ESP32 -func connectToESP() bool { - for i := 0; i < 5; i++ { - println("Connecting to wifi adaptor...") - if adaptor.Connected() { - return true - } - time.Sleep(1 * time.Second) - } - return false -} - -// connect to access point -func connectToAP() { - println("Connecting to wifi network '" + ssid + "'") - - if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil { - failMessage(err.Error()) - } - - println("Connected.") - ip, err := adaptor.GetClientIP() - if err != nil { - failMessage(err.Error()) - } - - println(ip) -} - -// provide access point -func provideAP() { - println("Starting wifi network as access point '" + ssid + "'...") - adaptor.SetWifiMode(espat.WifiModeAP) - adaptor.SetAPConfig(ssid, pass, 7, espat.WifiAPSecurityWPA2_PSK) - println("Ready.") - ip, _ := adaptor.GetAPIP() - println(ip) -} - -func failMessage(msg string) { - for { - println(msg) - time.Sleep(1 * time.Second) - } -} diff --git a/examples/espat/espstation/main.go b/examples/espat/espstation/main.go deleted file mode 100644 index 5ae2e3d69..000000000 --- a/examples/espat/espstation/main.go +++ /dev/null @@ -1,110 +0,0 @@ -// This is a sensor station that uses a ESP8266 or ESP32 running on the device UART1. -// It creates a UDP connection you can use to get info to/from your computer via the microcontroller. -// -// In other words: -// Your computer <--> UART0 <--> MCU <--> UART1 <--> ESP8266 -package main - -import ( - "machine" - "time" - - "tinygo.org/x/drivers/espat" - "tinygo.org/x/drivers/net" -) - -var ( - // access point info - ssid string - pass string -) - -// IP address of the listener aka "hub". Replace with your own info. -const hubIP = "0.0.0.0" - -// these are the default pins for the Arduino Nano33 IoT. -// change these to connect to a different UART or pins for the ESP8266/ESP32 -var ( - uart = machine.UART1 - tx = machine.PA22 - rx = machine.PA23 - - adaptor *espat.Device -) - -func main() { - uart.Configure(machine.UARTConfig{TX: tx, RX: rx}) - - // Init esp8266/esp32 - adaptor = espat.New(uart) - adaptor.Configure() - - // first check if connected - if connectToESP() { - println("Connected to wifi adaptor.") - adaptor.Echo(false) - - connectToAP() - } else { - println("") - failMessage("Unable to connect to wifi adaptor.") - return - } - - // now make UDP connection - ip := net.ParseIP(hubIP) - raddr := &net.UDPAddr{IP: ip, Port: 2222} - laddr := &net.UDPAddr{Port: 2222} - - println("Dialing UDP connection...") - conn, _ := net.DialUDP("udp", laddr, raddr) - - for { - // send data - println("Sending data...") - conn.Write([]byte("hello\r\n")) - - time.Sleep(1000 * time.Millisecond) - } - - // Right now this code is never reached. Need a way to trigger it... - println("Disconnecting UDP...") - conn.Close() - println("Done.") -} - -// connect to ESP8266/ESP32 -func connectToESP() bool { - for i := 0; i < 5; i++ { - println("Connecting to wifi adaptor...") - if adaptor.Connected() { - return true - } - time.Sleep(1 * time.Second) - } - return false -} - -// connect to access point -func connectToAP() { - println("Connecting to wifi network '" + ssid + "'") - - if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil { - failMessage(err.Error()) - } - - println("Connected.") - ip, err := adaptor.GetClientIP() - if err != nil { - failMessage(err.Error()) - } - - println(ip) -} - -func failMessage(msg string) { - for { - println(msg) - time.Sleep(1 * time.Second) - } -} diff --git a/examples/espat/mqttclient/main.go b/examples/espat/mqttclient/main.go deleted file mode 100644 index aaa88554e..000000000 --- a/examples/espat/mqttclient/main.go +++ /dev/null @@ -1,144 +0,0 @@ -// This is a sensor station that uses a ESP8266 or ESP32 running on the device UART1. -// It creates an MQTT connection that publishes a message every second -// to an MQTT broker. -// -// In other words: -// Your computer <--> UART0 <--> MCU <--> UART1 <--> ESP8266 <--> Internet <--> MQTT broker. -// -// You must install the Paho MQTT package to build this program: -// -// go get -u github.com/eclipse/paho.mqtt.golang -package main - -import ( - "machine" - "math/rand" - "time" - - "tinygo.org/x/drivers/espat" - "tinygo.org/x/drivers/net/mqtt" -) - -var ( - // access point info - ssid string - pass string -) - -// IP address of the MQTT broker to use. Replace with your own info. -const server = "tcp://test.mosquitto.org:1883" - -//const server = "ssl://test.mosquitto.org:8883" - -// these are the default pins for the Arduino Nano33 IoT. -// change these to connect to a different UART or pins for the ESP8266/ESP32 -var ( - uart = machine.UART2 - tx = machine.PA22 - rx = machine.PA23 - - console = machine.Serial - - adaptor *espat.Device - topic = "tinygo" -) - -func main() { - time.Sleep(3000 * time.Millisecond) - - uart.Configure(machine.UARTConfig{TX: tx, RX: rx}) - rand.Seed(time.Now().UnixNano()) - - // Init esp8266/esp32 - adaptor = espat.New(uart) - adaptor.Configure() - - // first check if connected - if connectToESP() { - println("Connected to wifi adaptor.") - adaptor.Echo(false) - - connectToAP() - } else { - println("") - failMessage("Unable to connect to wifi adaptor.") - return - } - - opts := mqtt.NewClientOptions() - opts.AddBroker(server).SetClientID("tinygo-client-" + randomString(10)) - - println("Connecting to MQTT broker at", server) - cl := mqtt.NewClient(opts) - if token := cl.Connect(); token.Wait() && token.Error() != nil { - failMessage(token.Error().Error()) - } - - for { - println("Publishing MQTT message...") - data := []byte("{\"e\":[{ \"n\":\"hello\", \"v\":101 }]}") - token := cl.Publish(topic, 0, false, data) - token.Wait() - if token.Error() != nil { - println(token.Error().Error()) - } - - time.Sleep(1000 * time.Millisecond) - } - - // Right now this code is never reached. Need a way to trigger it... - println("Disconnecting MQTT...") - cl.Disconnect(100) - - println("Done.") -} - -// connect to ESP8266/ESP32 -func connectToESP() bool { - for i := 0; i < 5; i++ { - println("Connecting to wifi adaptor...") - if adaptor.Connected() { - return true - } - time.Sleep(1 * time.Second) - } - return false -} - -// connect to access point -func connectToAP() { - println("Connecting to wifi network '" + ssid + "'") - - if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil { - failMessage(err.Error()) - } - - println("Connected.") - ip, err := adaptor.GetClientIP() - if err != nil { - failMessage(err.Error()) - } - - println(ip) -} - -// Returns an int >= min, < max -func randomInt(min, max int) int { - return min + rand.Intn(max-min) -} - -// Generate a random string of A-Z chars with len = l -func randomString(len int) string { - bytes := make([]byte, len) - for i := 0; i < len; i++ { - bytes[i] = byte(randomInt(65, 90)) - } - return string(bytes) -} - -func failMessage(msg string) { - for { - println(msg) - time.Sleep(1 * time.Second) - } -} diff --git a/examples/espat/mqttsub/main.go b/examples/espat/mqttsub/main.go deleted file mode 100644 index 65753852e..000000000 --- a/examples/espat/mqttsub/main.go +++ /dev/null @@ -1,165 +0,0 @@ -// This is a sensor station that uses a ESP8266 or ESP32 running on the device UART1. -// It creates an MQTT connection that publishes a message every second -// to an MQTT broker. -// -// In other words: -// Your computer <--> UART0 <--> MCU <--> UART1 <--> ESP8266 <--> Internet <--> MQTT broker. -// -// You must also install the Paho MQTT package to build this program: -// -// go get -u github.com/eclipse/paho.mqtt.golang -package main - -import ( - "fmt" - "machine" - "math/rand" - "time" - - "tinygo.org/x/drivers/espat" - "tinygo.org/x/drivers/net/mqtt" -) - -var ( - // access point info - ssid string - pass string -) - -// IP address of the MQTT broker to use. Replace with your own info. -//const server = "tcp://test.mosquitto.org:1883" - -const server = "ssl://test.mosquitto.org:8883" - -// change these to connect to a different UART or pins for the ESP8266/ESP32 -var ( - // these are defaults for the Arduino Nano33 IoT. - uart = machine.UART1 - tx = machine.PA22 - rx = machine.PA23 - - console = machine.Serial - - adaptor *espat.Device - cl mqtt.Client - topicTx = "tinygo/tx" - topicRx = "tinygo/rx" -) - -func subHandler(client mqtt.Client, msg mqtt.Message) { - fmt.Printf("[%s] ", msg.Topic()) - fmt.Printf("%s\r\n", msg.Payload()) -} - -func main() { - time.Sleep(3000 * time.Millisecond) - - uart.Configure(machine.UARTConfig{TX: tx, RX: rx}) - rand.Seed(time.Now().UnixNano()) - - // Init esp8266/esp32 - adaptor = espat.New(uart) - adaptor.Configure() - - // first check if connected - if connectToESP() { - println("Connected to wifi adaptor.") - adaptor.Echo(false) - - connectToAP() - } else { - println("") - failMessage("Unable to connect to wifi adaptor.") - return - } - - opts := mqtt.NewClientOptions() - opts.AddBroker(server).SetClientID("tinygo-client-" + randomString(10)) - - println("Connecting to MQTT broker at", server) - cl = mqtt.NewClient(opts) - if token := cl.Connect(); token.Wait() && token.Error() != nil { - failMessage(token.Error().Error()) - } - - // subscribe - token := cl.Subscribe(topicRx, 0, subHandler) - token.Wait() - if token.Error() != nil { - failMessage(token.Error().Error()) - } - - go publishing() - - select {} - - // Right now this code is never reached. Need a way to trigger it... - println("Disconnecting MQTT...") - cl.Disconnect(100) - - println("Done.") -} - -func publishing() { - for { - println("Publishing MQTT message...") - data := []byte("{\"e\":[{ \"n\":\"hello\", \"v\":101 }]}") - token := cl.Publish(topicTx, 0, false, data) - token.Wait() - if token.Error() != nil { - println(token.Error().Error()) - } - - time.Sleep(1000 * time.Millisecond) - } -} - -// connect to ESP8266/ESP32 -func connectToESP() bool { - for i := 0; i < 5; i++ { - println("Connecting to wifi adaptor...") - if adaptor.Connected() { - return true - } - time.Sleep(1 * time.Second) - } - return false -} - -// connect to access point -func connectToAP() { - println("Connecting to wifi network '" + ssid + "'") - - if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil { - failMessage(err.Error()) - } - - println("Connected.") - ip, err := adaptor.GetClientIP() - if err != nil { - failMessage(err.Error()) - } - - println(ip) -} - -// Returns an int >= min, < max -func randomInt(min, max int) int { - return min + rand.Intn(max-min) -} - -// Generate a random string of A-Z chars with len = l -func randomString(len int) string { - bytes := make([]byte, len) - for i := 0; i < len; i++ { - bytes[i] = byte(randomInt(65, 90)) - } - return string(bytes) -} - -func failMessage(msg string) { - for { - println(msg) - time.Sleep(1 * time.Second) - } -} diff --git a/examples/espat/tcpclient/main.go b/examples/espat/tcpclient/main.go deleted file mode 100644 index db1bcb8cc..000000000 --- a/examples/espat/tcpclient/main.go +++ /dev/null @@ -1,113 +0,0 @@ -// This is a sensor station that uses a ESP8266 or ESP32 running on the device UART1. -// It creates a UDP connection you can use to get info to/from your computer via the microcontroller. -// -// In other words: -// Your computer <--> UART0 <--> MCU <--> UART1 <--> ESP8266 -package main - -import ( - "machine" - "time" - - "tinygo.org/x/drivers/espat" - "tinygo.org/x/drivers/net" -) - -var ( - // access point info - ssid string - pass string -) - -// IP address of the server aka "hub". Replace with your own info. -const serverIP = "0.0.0.0" - -// these are the default pins for the Arduino Nano33 IoT. -// change these to connect to a different UART or pins for the ESP8266/ESP32 -var ( - uart = machine.UART1 - tx = machine.PA22 - rx = machine.PA23 - - adaptor *espat.Device -) - -func main() { - uart.Configure(machine.UARTConfig{TX: tx, RX: rx}) - - // Init esp8266/esp32 - adaptor = espat.New(uart) - adaptor.Configure() - - // first check if connected - if connectToESP() { - println("Connected to wifi adaptor.") - adaptor.Echo(false) - - connectToAP() - } else { - println("") - failMessage("Unable to connect to wifi adaptor.") - return - } - - // now make TCP connection - ip := net.ParseIP(serverIP) - raddr := &net.TCPAddr{IP: ip, Port: 8080} - laddr := &net.TCPAddr{Port: 8080} - - println("Dialing TCP connection...") - conn, err := net.DialTCP("tcp", laddr, raddr) - if err != nil { - failMessage(err.Error()) - } - - for { - // send data - println("Sending data...") - conn.Write([]byte("hello\r\n")) - - time.Sleep(1000 * time.Millisecond) - } - - // Right now this code is never reached. Need a way to trigger it... - println("Disconnecting TCP...") - conn.Close() - println("Done.") -} - -// connect to ESP8266/ESP32 -func connectToESP() bool { - for i := 0; i < 5; i++ { - println("Connecting to wifi adaptor...") - if adaptor.Connected() { - return true - } - time.Sleep(1 * time.Second) - } - return false -} - -// connect to access point -func connectToAP() { - println("Connecting to wifi network '" + ssid + "'") - - if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil { - failMessage(err.Error()) - } - - println("Connected.") - ip, err := adaptor.GetClientIP() - if err != nil { - failMessage(err.Error()) - } - - println(ip) -} - -func failMessage(msg string) { - for { - println(msg) - time.Sleep(1 * time.Second) - } -} diff --git a/examples/net/http-get/main.go b/examples/net/http-get/main.go new file mode 100644 index 000000000..7f8de6757 --- /dev/null +++ b/examples/net/http-get/main.go @@ -0,0 +1,88 @@ +// This example gets an URL using http.Get(). URL scheme can be http or https. +// +// Note: It may be necessary to increase the stack size when using "net/http". +// Use the -stack-size=4KB command line option. +// +// Some targets (Arduino Nano33 IoT) don't have enough SRAM to run http.Get(). +// Use the following for those targets: +// +// examples/net/webclient (for HTTP) +// examples/net/tlsclient (for HTTPS) + +//go:build pyportal || nano_rp2040 || metro_m4_airlift || arduino_mkrwifi1010 || matrixportal_m4 || wioterminal + +package main + +import ( + "fmt" + "io" + "log" + "machine" + "net/http" + "net/url" + "strings" + "time" + + "tinygo.org/x/drivers/netlink" + "tinygo.org/x/drivers/netlink/probe" +) + +var ( + ssid string + pass string +) + +func main() { + + waitSerial() + + link, _ := probe.Probe() + + err := link.NetConnect(&netlink.ConnectParams{ + Ssid: ssid, + Passphrase: pass, + }) + if err != nil { + log.Fatal(err) + } + + name := "John Doe" + occupation := "gardener" + + params := "name=" + url.QueryEscape(name) + "&" + + "occupation=" + url.QueryEscape(occupation) + + path := fmt.Sprintf("https://httpbin.org/get?%s", params) + + cnt := 0 + for { + fmt.Printf("Getting %s\r\n\r\n", path) + resp, err := http.Get(path) + if err != nil { + fmt.Printf("%s\r\n", err.Error()) + time.Sleep(10 * time.Second) + continue + } + + fmt.Printf("%s %s\r\n", resp.Proto, resp.Status) + for k, v := range resp.Header { + fmt.Printf("%s: %s\r\n", k, strings.Join(v, " ")) + } + fmt.Printf("\r\n") + + body, err := io.ReadAll(resp.Body) + println(string(body)) + resp.Body.Close() + + cnt++ + fmt.Printf("-------- %d --------\r\n", cnt) + time.Sleep(10 * time.Second) + } +} + +// Wait for user to open serial console +func waitSerial() { + for !machine.Serial.DTR() { + time.Sleep(100 * time.Millisecond) + } +} diff --git a/examples/net/http-head/main.go b/examples/net/http-head/main.go new file mode 100644 index 000000000..07c1f4545 --- /dev/null +++ b/examples/net/http-head/main.go @@ -0,0 +1,68 @@ +// This example gets an URL using http.Head(). URL scheme can be http or https. +// +// Note: It may be necessary to increase the stack size when using "net/http". +// Use the -stack-size=4KB command line option. +// +// Some targets (Arduino Nano33 IoT) don't have enough SRAM to run http.Head(). +// Use the following for those targets: +// +// examples/net/webclient (for HTTP) +// examples/net/tlsclient (for HTTPS) + +//go:build pyportal || nano_rp2040 || metro_m4_airlift || arduino_mkrwifi1010 || matrixportal_m4 || wioterminal + +package main + +import ( + "bytes" + "fmt" + "log" + "machine" + "net/http" + "time" + + "tinygo.org/x/drivers/netlink" + "tinygo.org/x/drivers/netlink/probe" +) + +var ( + ssid string + pass string + url string = "https://httpbin.org" +) + +func main() { + + waitSerial() + + link, _ := probe.Probe() + + err := link.NetConnect(&netlink.ConnectParams{ + Ssid: ssid, + Passphrase: pass, + }) + if err != nil { + log.Fatal(err) + } + + resp, err := http.Head(url) + if err != nil { + log.Fatal(err) + } + defer resp.Body.Close() + + var buf bytes.Buffer + if err := resp.Write(&buf); err != nil { + log.Fatal(err) + } + fmt.Println(string(buf.Bytes())) + + link.NetDisconnect() +} + +// Wait for user to open serial console +func waitSerial() { + for !machine.Serial.DTR() { + time.Sleep(100 * time.Millisecond) + } +} diff --git a/examples/net/http-post/main.go b/examples/net/http-post/main.go new file mode 100644 index 000000000..d28f62da3 --- /dev/null +++ b/examples/net/http-post/main.go @@ -0,0 +1,72 @@ +// This example posts an URL using http.Post(). URL scheme can be http or https. +// +// Note: It may be necessary to increase the stack size when using "net/http". +// Use the -stack-size=4KB command line option. +// +// Some targets (Arduino Nano33 IoT) don't have enough SRAM to run http.Post(). +// Use the following for those targets: +// +// examples/net/webclient (for HTTP) +// examples/net/tlsclient (for HTTPS) + +//go:build pyportal || nano_rp2040 || metro_m4_airlift || arduino_mkrwifi1010 || matrixportal_m4 || wioterminal + +package main + +import ( + "bytes" + "fmt" + "io" + "log" + "machine" + "net/http" + "time" + + "tinygo.org/x/drivers/netlink" + "tinygo.org/x/drivers/netlink/probe" +) + +var ( + ssid string + pass string +) + +func main() { + + waitSerial() + + link, _ := probe.Probe() + + err := link.NetConnect(&netlink.ConnectParams{ + Ssid: ssid, + Passphrase: pass, + }) + if err != nil { + log.Fatal(err) + } + + path := "https://httpbin.org/post" + data := []byte("{\"name\":\"John Doe\",\"occupation\":\"gardener\"}") + + resp, err := http.Post(path, "application/json", bytes.NewBuffer(data)) + if err != nil { + log.Fatal(err) + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + log.Fatal(err) + } + + fmt.Println(string(body)) + + link.NetDisconnect() +} + +// Wait for user to open serial console +func waitSerial() { + for !machine.Serial.DTR() { + time.Sleep(100 * time.Millisecond) + } +} diff --git a/examples/net/http-postform/main.go b/examples/net/http-postform/main.go new file mode 100644 index 000000000..e72aac868 --- /dev/null +++ b/examples/net/http-postform/main.go @@ -0,0 +1,73 @@ +// This example posts an URL using http.PostForm(). URL scheme can be http or https. +// +// Note: It may be necessary to increase the stack size when using "net/http". +// Use the -stack-size=4KB command line option. +// +// Some targets (Arduino Nano33 IoT) don't have enough SRAM to run +// http.PostForm(). Use the following for those targets: +// +// examples/net/webclient (for HTTP) +// examples/net/tlsclient (for HTTPS) + +//go:build pyportal || nano_rp2040 || metro_m4_airlift || arduino_mkrwifi1010 || matrixportal_m4 || wioterminal + +package main + +import ( + "fmt" + "io" + "log" + "machine" + "net/http" + "net/url" + "time" + + "tinygo.org/x/drivers/netlink" + "tinygo.org/x/drivers/netlink/probe" +) + +var ( + ssid string + pass string +) + +func main() { + + waitSerial() + + link, _ := probe.Probe() + + err := link.NetConnect(&netlink.ConnectParams{ + Ssid: ssid, + Passphrase: pass, + }) + if err != nil { + log.Fatal(err) + } + + path := "https://httpbin.org/post" + data := url.Values{ + "name": {"John Doe"}, + "occupation": {"gardener"}, + } + + resp, err := http.PostForm(path, data) + if err != nil { + log.Fatal(err) + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + log.Fatal(err) + } + + fmt.Println(string(body)) +} + +// Wait for user to open serial console +func waitSerial() { + for !machine.Serial.DTR() { + time.Sleep(100 * time.Millisecond) + } +} diff --git a/examples/net/mqttclient/natiu/main.go b/examples/net/mqttclient/natiu/main.go new file mode 100644 index 000000000..8d82fe794 --- /dev/null +++ b/examples/net/mqttclient/natiu/main.go @@ -0,0 +1,146 @@ +// This example is an MQTT client built with the natiu-mqtt package. It sends +// machine.CPUFrequency() readings to the broker every second for 10 seconds. +// +// Note: It may be necessary to increase the stack size when using +// paho.mqtt.golang. Use the -stack-size=4KB command line option. + +//go:build pyportal || nano_rp2040 || metro_m4_airlift || arduino_mkrwifi1010 || matrixportal_m4 || wioterminal || challenger_rp2040 + +package main + +import ( + "context" + "errors" + "fmt" + "io" + "log" + "machine" + "math/rand" + "net" + "time" + + mqtt "github.com/soypat/natiu-mqtt" + "tinygo.org/x/drivers/netlink" + "tinygo.org/x/drivers/netlink/probe" +) + +var ( + ssid string + pass string + broker string = "test.mosquitto.org:1883" + topic string = "cpu/freq" +) + +func main() { + waitSerial() + + link, _ := probe.Probe() + + err := link.NetConnect(&netlink.ConnectParams{ + Ssid: ssid, + Passphrase: pass, + }) + if err != nil { + log.Fatal(err) + } + + clientId := "tinygo-client-" + randomString(10) + fmt.Printf("ClientId: %s\n", clientId) + + // Get a transport for MQTT packets + fmt.Printf("Connecting to MQTT broker at %s\n", broker) + conn, err := net.Dial("tcp", broker) + if err != nil { + log.Fatal(err) + } + defer conn.Close() + + // Create new client + client := mqtt.NewClient(mqtt.ClientConfig{ + Decoder: mqtt.DecoderNoAlloc{make([]byte, 1500)}, + OnPub: func(_ mqtt.Header, _ mqtt.VariablesPublish, r io.Reader) error { + message, _ := io.ReadAll(r) + fmt.Printf("Message %s received on topic %s\n", string(message), topic) + return nil + }, + }) + + // Connect client + var varconn mqtt.VariablesConnect + varconn.SetDefaultMQTT([]byte(clientId)) + ctx, _ := context.WithTimeout(context.Background(), 10*time.Second) + err = client.Connect(ctx, conn, &varconn) + if err != nil { + log.Fatal("failed to connect: ", err) + } + + // Subscribe to topic + ctx, _ = context.WithTimeout(context.Background(), 10*time.Second) + err = client.Subscribe(ctx, mqtt.VariablesSubscribe{ + PacketIdentifier: 23, + TopicFilters: []mqtt.SubscribeRequest{ + {TopicFilter: []byte(topic), QoS: mqtt.QoS0}, + }, + }) + if err != nil { + log.Fatal("failed to subscribe to", topic, err) + } + fmt.Printf("Subscribed to topic %s\n", topic) + + // Publish on topic + pubFlags, _ := mqtt.NewPublishFlags(mqtt.QoS0, false, false) + pubVar := mqtt.VariablesPublish{ + TopicName: []byte(topic), + } + + for i := 0; i < 10; i++ { + if !client.IsConnected() { + log.Fatal("client disconnected: ", client.Err()) + } + + freq := float32(machine.CPUFrequency()) / 1000000 + payload := fmt.Sprintf("%.02fMhz", freq) + + pubVar.PacketIdentifier++ + err = client.PublishPayload(pubFlags, pubVar, []byte(payload)) + if err != nil { + log.Fatal("error transmitting message: ", err) + } + + time.Sleep(time.Second) + + conn.SetReadDeadline(time.Now().Add(10 * time.Second)) + err = client.HandleNext() + if err != nil { + log.Fatal("handle next: ", err) + } + + } + + client.Disconnect(errors.New("disconnected gracefully")) + + for { + select {} + } +} + +// Returns an int >= min, < max +func randomInt(min, max int) int { + return min + rand.Intn(max-min) +} + +// Generate a random string of A-Z chars with len = l +func randomString(len int) string { + bytes := make([]byte, len) + for i := 0; i < len; i++ { + bytes[i] = byte(randomInt(65, 90)) + } + return string(bytes) +} + +// Wait for user to open serial console +func waitSerial() { + for !machine.Serial.DTR() { + time.Sleep(100 * time.Millisecond) + } +} diff --git a/examples/net/mqttclient/paho/main.go b/examples/net/mqttclient/paho/main.go new file mode 100644 index 000000000..293e24d15 --- /dev/null +++ b/examples/net/mqttclient/paho/main.go @@ -0,0 +1,114 @@ +// This example is an MQTT client built with the paho-mqtt package. It sends +// machine.CPUFrequency() readings to the broker every second for 10 seconds. +// +// Note: It may be necessary to increase the stack size when using +// paho.mqtt.golang. Use the -stack-size=4KB command line option. + +//go:build pyportal || nano_rp2040 || metro_m4_airlift || arduino_mkrwifi1010 || matrixportal_m4 || wioterminal || challenger_rp2040 + +package main + +import ( + "fmt" + "log" + "machine" + "math/rand" + "time" + + mqtt "github.com/eclipse/paho.mqtt.golang" + "tinygo.org/x/drivers/netlink" + "tinygo.org/x/drivers/netlink/probe" +) + +var ( + ssid string + pass string + broker string = "tcp://test.mosquitto.org:1883" +) + +var messagePubHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) { + fmt.Printf("Message %s received on topic %s\n", msg.Payload(), msg.Topic()) +} + +var connectHandler mqtt.OnConnectHandler = func(client mqtt.Client) { + fmt.Println("Connected") +} + +var connectionLostHandler mqtt.ConnectionLostHandler = func(client mqtt.Client, err error) { + fmt.Printf("Connection Lost: %s\n", err.Error()) +} + +func main() { + waitSerial() + + link, _ := probe.Probe() + + err := link.NetConnect(&netlink.ConnectParams{ + Ssid: ssid, + Passphrase: pass, + }) + if err != nil { + log.Fatal(err) + } + + clientId := "tinygo-client-" + randomString(10) + fmt.Printf("ClientId: %s\n", clientId) + + options := mqtt.NewClientOptions() + options.AddBroker(broker) + options.SetClientID(clientId) + options.SetDefaultPublishHandler(messagePubHandler) + options.OnConnect = connectHandler + options.OnConnectionLost = connectionLostHandler + + fmt.Printf("Connecting to MQTT broker at %s\n", broker) + client := mqtt.NewClient(options) + token := client.Connect() + if token.Wait() && token.Error() != nil { + panic(token.Error()) + } + + topic := "cpu/freq" + token = client.Subscribe(topic, 1, nil) + if token.Wait() && token.Error() != nil { + panic(token.Error()) + } + fmt.Printf("Subscribed to topic %s\n", topic) + + for i := 0; i < 10; i++ { + freq := float32(machine.CPUFrequency()) / 1000000 + payload := fmt.Sprintf("%.02fMhz", freq) + token = client.Publish(topic, 0, false, payload) + if token.Wait() && token.Error() != nil { + panic(token.Error()) + } + time.Sleep(time.Second) + } + + client.Disconnect(100) + + for { + select {} + } +} + +// Returns an int >= min, < max +func randomInt(min, max int) int { + return min + rand.Intn(max-min) +} + +// Generate a random string of A-Z chars with len = l +func randomString(len int) string { + bytes := make([]byte, len) + for i := 0; i < len; i++ { + bytes[i] = byte(randomInt(65, 90)) + } + return string(bytes) +} + +// Wait for user to open serial console +func waitSerial() { + for !machine.Serial.DTR() { + time.Sleep(100 * time.Millisecond) + } +} diff --git a/examples/net/ntpclient/main.go b/examples/net/ntpclient/main.go new file mode 100644 index 000000000..6c8419377 --- /dev/null +++ b/examples/net/ntpclient/main.go @@ -0,0 +1,115 @@ +// This is an example of an NTP client. +// +// It creates a UDP connection to request the current time and parse the +// response from a NTP server. The system time is set to NTP time. + +//go:build pyportal || arduino_nano33 || nano_rp2040 || metro_m4_airlift || arduino_mkrwifi1010 || matrixportal_m4 || wioterminal || challenger_rp2040 + +package main + +import ( + "fmt" + "io" + "log" + "machine" + "net" + "runtime" + "time" + + "tinygo.org/x/drivers/netlink" + "tinygo.org/x/drivers/netlink/probe" +) + +var ( + ssid string + pass string + // IP address of the server aka "hub". Replace with your own info. + ntpHost string = "0.pool.ntp.org:123" +) + +const NTP_PACKET_SIZE = 48 + +var response = make([]byte, NTP_PACKET_SIZE) + +func main() { + + waitSerial() + + link, _ := probe.Probe() + + err := link.NetConnect(&netlink.ConnectParams{ + Ssid: ssid, + Passphrase: pass, + }) + if err != nil { + log.Fatal(err) + } + + conn, err := net.Dial("udp", ntpHost) + if err != nil { + log.Fatal(err) + } + + println("Requesting NTP time...") + + t, err := getCurrentTime(conn) + if err != nil { + log.Fatal(fmt.Sprintf("Error getting current time: %v", err)) + } else { + message("NTP time: %v", t) + } + + conn.Close() + link.NetDisconnect() + + runtime.AdjustTimeOffset(-1 * int64(time.Since(t))) + + for { + message("Current time: %v", time.Now()) + time.Sleep(time.Minute) + } +} + +// Wait for user to open serial console +func waitSerial() { + for !machine.Serial.DTR() { + time.Sleep(100 * time.Millisecond) + } +} + +func getCurrentTime(conn net.Conn) (time.Time, error) { + if err := sendNTPpacket(conn); err != nil { + return time.Time{}, err + } + + n, err := conn.Read(response) + if err != nil && err != io.EOF { + return time.Time{}, err + } + if n != NTP_PACKET_SIZE { + return time.Time{}, fmt.Errorf("expected NTP packet size of %d: %d", NTP_PACKET_SIZE, n) + } + + return parseNTPpacket(response), nil +} + +func sendNTPpacket(conn net.Conn) error { + var request = [48]byte{ + 0xe3, + } + + _, err := conn.Write(request[:]) + return err +} + +func parseNTPpacket(r []byte) time.Time { + // the timestamp starts at byte 40 of the received packet and is four bytes, + // this is NTP time (seconds since Jan 1 1900): + t := uint32(r[40])<<24 | uint32(r[41])<<16 | uint32(r[42])<<8 | uint32(r[43]) + const seventyYears = 2208988800 + return time.Unix(int64(t-seventyYears), 0) +} + +func message(format string, args ...interface{}) { + println(fmt.Sprintf(format, args...), "\r") +} diff --git a/examples/net/socket/main.go b/examples/net/socket/main.go new file mode 100644 index 000000000..f17ede557 --- /dev/null +++ b/examples/net/socket/main.go @@ -0,0 +1,111 @@ +// This example opens a TCP connection and sends some data using netdev sockets. +// +// You can open a server to accept connections from this program using: +// +// nc -lk 8080 + +//go:build pyportal || arduino_nano33 || nano_rp2040 || metro_m4_airlift || arduino_mkrwifi1010 || matrixportal_m4 || wioterminal || challenger_rp2040 + +package main + +import ( + "bytes" + "fmt" + "log" + "machine" + "net" + "strconv" + "time" + + "tinygo.org/x/drivers/netdev" + "tinygo.org/x/drivers/netlink" + "tinygo.org/x/drivers/netlink/probe" +) + +var ( + ssid string + pass string + addr string = "10.0.0.100:8080" +) + +var buf = &bytes.Buffer{} +var link netlink.Netlinker +var dev netdev.Netdever + +func main() { + + waitSerial() + + link, dev = probe.Probe() + + err := link.NetConnect(&netlink.ConnectParams{ + Ssid: ssid, + Passphrase: pass, + }) + if err != nil { + log.Fatal(err) + } + + for { + sendBatch() + time.Sleep(500 * time.Millisecond) + } +} + +func sendBatch() { + + host, sport, _ := net.SplitHostPort(addr) + ip := net.ParseIP(host).To4() + port, _ := strconv.Atoi(sport) + + // make TCP connection + message("---------------\r\nDialing TCP connection") + fd, _ := dev.Socket(netdev.AF_INET, netdev.SOCK_STREAM, netdev.IPPROTO_TCP) + err := dev.Connect(fd, "", ip, port) + for ; err != nil; err = dev.Connect(fd, "", ip, port) { + message(err.Error()) + time.Sleep(5 * time.Second) + } + + n := 0 + w := 0 + start := time.Now() + + // send data + message("Sending data") + + for i := 0; i < 1000; i++ { + buf.Reset() + fmt.Fprint(buf, + "\r---------------------------- i == ", i, " ----------------------------"+ + "\r---------------------------- i == ", i, " ----------------------------") + if w, err = dev.Send(fd, buf.Bytes(), 0, time.Time{}); err != nil { + println("error:", err.Error(), "\r") + break + } + n += w + } + + buf.Reset() + ms := time.Now().Sub(start).Milliseconds() + fmt.Fprint(buf, "\nWrote ", n, " bytes in ", ms, " ms\r\n") + message(buf.String()) + + if _, err := dev.Send(fd, buf.Bytes(), 0, time.Time{}); err != nil { + println("error:", err.Error(), "\r") + } + + println("Disconnecting TCP...") + dev.Close(fd) +} + +func message(msg string) { + println(msg, "\r") +} + +// Wait for user to open serial console +func waitSerial() { + for !machine.Serial.DTR() { + time.Sleep(100 * time.Millisecond) + } +} diff --git a/examples/wifi/tcpclient/main.go b/examples/net/tcpclient/main.go similarity index 51% rename from examples/wifi/tcpclient/main.go rename to examples/net/tcpclient/main.go index 74eb1916f..10d2935da 100644 --- a/examples/wifi/tcpclient/main.go +++ b/examples/net/tcpclient/main.go @@ -1,52 +1,60 @@ -// This example opens a TCP connection and sends some data, -// for the purpose of testing speed and connectivity. +// This example opens a TCP connection and sends some data, for the purpose of +// testing speed and connectivity. // // You can open a server to accept connections from this program using: // -// nc -w 5 -lk 8080 +// nc -lk 8080 + +//go:build pyportal || arduino_nano33 || nano_rp2040 || metro_m4_airlift || arduino_mkrwifi1010 || matrixportal_m4 || wioterminal || challenger_rp2040 || pico + package main import ( "bytes" "fmt" + "log" + "machine" + "net" "time" - "tinygo.org/x/drivers/net" + "tinygo.org/x/drivers/netlink" + "tinygo.org/x/drivers/netlink/probe" ) var ( - // access point info ssid string pass string + addr string = "10.0.0.100:8080" ) -// IP address of the server aka "hub". Replace with your own info. -const serverIP = "" - var buf = &bytes.Buffer{} func main() { - initAdaptor() - connectToAP() + waitSerial() + + link, _ := probe.Probe() + + err := link.NetConnect(&netlink.ConnectParams{ + Ssid: ssid, + Passphrase: pass, + }) + if err != nil { + log.Fatal(err) + } for { sendBatch() time.Sleep(500 * time.Millisecond) } - println("Done.") } func sendBatch() { // make TCP connection - ip := net.ParseIP(serverIP) - raddr := &net.TCPAddr{IP: ip, Port: 8080} - laddr := &net.TCPAddr{Port: 8080} - message("---------------\r\nDialing TCP connection") - conn, err := net.DialTCP("tcp", laddr, raddr) - for ; err != nil; conn, err = net.DialTCP("tcp", laddr, raddr) { + conn, err := net.Dial("tcp", addr) + for ; err != nil; conn, err = net.Dial("tcp", addr) { message(err.Error()) time.Sleep(5 * time.Second) } @@ -65,7 +73,7 @@ func sendBatch() { "\r---------------------------- i == ", i, " ----------------------------") if w, err = conn.Write(buf.Bytes()); err != nil { println("error:", err.Error(), "\r") - continue + break } n += w } @@ -79,34 +87,17 @@ func sendBatch() { println("error:", err.Error(), "\r") } - // Right now this code is never reached. Need a way to trigger it... println("Disconnecting TCP...") conn.Close() } -// connect to access point -func connectToAP() { - time.Sleep(2 * time.Second) - println("Connecting to " + ssid) - err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) - if err != nil { // error connecting to AP - for { - println(err) - time.Sleep(1 * time.Second) - } - } - - println("Connected.") - - time.Sleep(2 * time.Second) - ip, err := adaptor.GetClientIP() - for ; err != nil; ip, err = adaptor.GetClientIP() { - message(err.Error()) - time.Sleep(1 * time.Second) - } - message(ip) -} - func message(msg string) { println(msg, "\r") } + +// Wait for user to open serial console +func waitSerial() { + for !machine.Serial.DTR() { + time.Sleep(100 * time.Millisecond) + } +} diff --git a/examples/net/tcpecho/main.go b/examples/net/tcpecho/main.go new file mode 100644 index 000000000..0356617ad --- /dev/null +++ b/examples/net/tcpecho/main.go @@ -0,0 +1,67 @@ +// This example listens on port :8080 for client connections. Bytes +// received from the client are echo'ed back to the client. Multiple +// clients can connect as the same time, each consuming a client socket, +// and being serviced by it's own go func. +// +// Example test using nc as client to copy file: +// +// $ nc 10.0.0.2 8080 copy ; cmp file copy + +//go:build pyportal || arduino_nano33 || nano_rp2040 || metro_m4_airlift || arduino_mkrwifi1010 || matrixportal_m4 || wioterminal + +package main + +import ( + "io" + "log" + "net" + "time" + + "tinygo.org/x/drivers/netlink" + "tinygo.org/x/drivers/netlink/probe" +) + +var ( + ssid string + pass string + port string = ":8080" +) + +var buf [1024]byte + +func echo(conn net.Conn) { + defer conn.Close() + _, err := io.CopyBuffer(conn, conn, buf[:]) + if err != nil && err != io.EOF { + log.Fatal(err.Error()) + } +} + +func main() { + + time.Sleep(time.Second) + + link, _ := probe.Probe() + + err := link.NetConnect(&netlink.ConnectParams{ + Ssid: ssid, + Passphrase: pass, + }) + if err != nil { + log.Fatal(err) + } + + l, err := net.Listen("tcp", port) + if err != nil { + log.Fatal(err.Error()) + } + defer l.Close() + + for { + conn, err := l.Accept() + if err != nil { + log.Fatal(err.Error()) + } + go echo(conn) + } +} diff --git a/examples/net/tlsclient/main.go b/examples/net/tlsclient/main.go new file mode 100644 index 000000000..186fdd587 --- /dev/null +++ b/examples/net/tlsclient/main.go @@ -0,0 +1,106 @@ +// This example uses TLS to send an HTTPS request to retrieve a webpage +// +// You shall see "strict-transport-security" header in the response, +// this confirms communication is indeed over HTTPS +// +// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security + +//go:build pyportal || nano_rp2040 || metro_m4_airlift || arduino_mkrwifi1010 || matrixportal_m4 || wioterminal + +package main + +import ( + "bufio" + "crypto/tls" + "fmt" + "io" + "log" + "machine" + "net" + "strings" + "time" + + "tinygo.org/x/drivers/netlink" + "tinygo.org/x/drivers/netlink/probe" +) + +var ( + ssid string + pass string + // HTTPS server address to hit with a GET / request + address string = "httpbin.org:443" +) + +var conn net.Conn + +// Wait for user to open serial console +func waitSerial() { + for !machine.Serial.DTR() { + time.Sleep(100 * time.Millisecond) + } +} + +func check(err error) { + if err != nil { + println("Hit an error:", err.Error()) + panic("BYE") + } +} + +func readResponse() { + r := bufio.NewReader(conn) + resp, err := io.ReadAll(r) + check(err) + println(string(resp)) +} + +func closeConnection() { + conn.Close() +} + +func dialConnection() { + var err error + + println("\r\n---------------\r\nDialing TLS connection") + conn, err = tls.Dial("tcp", address, nil) + for ; err != nil; conn, err = tls.Dial("tcp", address, nil) { + println("Connection failed:", err.Error()) + time.Sleep(5 * time.Second) + } + println("Connected!\r") +} + +func makeRequest() { + print("Sending HTTPS request...") + w := bufio.NewWriter(conn) + fmt.Fprintln(w, "GET /get HTTP/1.1") + fmt.Fprintln(w, "Host:", strings.Split(address, ":")[0]) + fmt.Fprintln(w, "User-Agent: TinyGo") + fmt.Fprintln(w, "Connection: close") + fmt.Fprintln(w) + check(w.Flush()) + println("Sent!\r\n\r") +} + +func main() { + waitSerial() + + link, _ := probe.Probe() + + err := link.NetConnect(&netlink.ConnectParams{ + Ssid: ssid, + Passphrase: pass, + }) + if err != nil { + log.Fatal(err) + } + + for i := 0; ; i++ { + dialConnection() + makeRequest() + readResponse() + closeConnection() + println("--------", i, "--------\r\n") + time.Sleep(10 * time.Second) + } +} diff --git a/examples/net/webclient-tinyterm/main.go b/examples/net/webclient-tinyterm/main.go new file mode 100644 index 000000000..9720aaae9 --- /dev/null +++ b/examples/net/webclient-tinyterm/main.go @@ -0,0 +1,120 @@ +// This example runs on wioterminal. It gets an URL using http.Get() and +// displays the output on the wioterminal LCD screen. +// +// Note: It may be necessary to increase the stack size when using "net/http". +// Use the -stack-size=4KB command line option. + +//go:build wioterminal + +package main + +import ( + "fmt" + "image/color" + "io" + "log" + "machine" + "net/http" + "net/url" + "strings" + "time" + + "tinygo.org/x/drivers/ili9341" + "tinygo.org/x/drivers/netlink" + "tinygo.org/x/drivers/netlink/probe" + "tinygo.org/x/tinyfont/proggy" + "tinygo.org/x/tinyterm" +) + +var ( + ssid string + pass string +) + +var ( + display = ili9341.NewSPI( + machine.SPI3, + machine.LCD_DC, + machine.LCD_SS_PIN, + machine.LCD_RESET, + ) + + backlight = machine.LCD_BACKLIGHT + + terminal = tinyterm.NewTerminal(display) + + black = color.RGBA{0, 0, 0, 255} + white = color.RGBA{255, 255, 255, 255} + red = color.RGBA{255, 0, 0, 255} + blue = color.RGBA{0, 0, 255, 255} + green = color.RGBA{0, 255, 0, 255} + + font = &proggy.TinySZ8pt7b +) + +func main() { + + machine.SPI3.Configure(machine.SPIConfig{ + SCK: machine.LCD_SCK_PIN, + SDO: machine.LCD_SDO_PIN, + SDI: machine.LCD_SDI_PIN, + Frequency: 40000000, + }) + + display.Configure(ili9341.Config{}) + display.FillScreen(black) + + backlight.Configure(machine.PinConfig{machine.PinOutput}) + backlight.High() + + terminal.Configure(&tinyterm.Config{ + Font: font, + FontHeight: 10, + FontOffset: 6, + }) + + fmt.Fprintf(terminal, "Connecting to %s...\r\n", ssid) + + link, _ := probe.Probe() + + err := link.NetConnect(&netlink.ConnectParams{ + Ssid: ssid, + Passphrase: pass, + }) + if err != nil { + log.Fatal(err) + } + + name := "John Doe" + occupation := "gardener" + + params := "name=" + url.QueryEscape(name) + "&" + + "occupation=" + url.QueryEscape(occupation) + + path := fmt.Sprintf("https://httpbin.org/get?%s", params) + + cnt := 0 + for { + fmt.Fprintf(terminal, "Getting %s\r\n\r\n", path) + resp, err := http.Get(path) + if err != nil { + fmt.Fprintf(terminal, "%s\r\n", err.Error()) + time.Sleep(10 * time.Second) + continue + } + + fmt.Fprintf(terminal, "%s %s\r\n", resp.Proto, resp.Status) + for k, v := range resp.Header { + fmt.Fprintf(terminal, "%s: %s\r\n", k, strings.Join(v, " ")) + } + fmt.Fprintf(terminal, "\r\n") + + body, err := io.ReadAll(resp.Body) + fmt.Fprintf(terminal, string(body)) + resp.Body.Close() + + cnt++ + fmt.Fprintf(terminal, "-------- %d --------\r\n", cnt) + time.Sleep(10 * time.Second) + } +} diff --git a/examples/net/webclient/main.go b/examples/net/webclient/main.go new file mode 100644 index 000000000..bb2fe9d5d --- /dev/null +++ b/examples/net/webclient/main.go @@ -0,0 +1,117 @@ +// This example uses TCP to send an HTTP request to retrieve a webpage. The +// HTTP request is hand-rolled to avoid the overhead of using http.Get() from +// the "net/http" package. See example/net/http-get for the full http.Get() +// functionality. +// +// Example HTTP server: +// --------------------------------------------------------------------------- +// package main +// +// import "net/http" +// +// func main() { +// http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { +// w.Write([]byte("hello")) +// }) +// http.ListenAndServe(":8080", nil) +// } +// --------------------------------------------------------------------------- + +//go:build pyportal || arduino_nano33 || nano_rp2040 || metro_m4_airlift || arduino_mkrwifi1010 || matrixportal_m4 || wioterminal + +package main + +import ( + "bufio" + "fmt" + "io" + "log" + "machine" + "net" + "strings" + "time" + + "tinygo.org/x/drivers/netlink" + "tinygo.org/x/drivers/netlink/probe" +) + +var ( + ssid string + pass string + // HTTP server address to hit with a GET / request + address string = "10.0.0.100:8080" +) + +var conn net.Conn + +// Wait for user to open serial console +func waitSerial() { + for !machine.Serial.DTR() { + time.Sleep(100 * time.Millisecond) + } +} + +func dialConnection() { + var err error + + println("\r\n---------------\r\nDialing TCP connection") + conn, err = net.Dial("tcp", address) + for ; err != nil; conn, err = net.Dial("tcp", address) { + println("Connection failed:", err.Error()) + time.Sleep(5 * time.Second) + } + println("Connected!\r") +} + +func check(err error) { + if err != nil { + println("Hit an error:", err.Error()) + panic("BYE") + } +} + +func makeRequest() { + println("Sending HTTP request...") + w := bufio.NewWriter(conn) + fmt.Fprintln(w, "GET / HTTP/1.1") + fmt.Fprintln(w, "Host:", strings.Split(address, ":")[0]) + fmt.Fprintln(w, "User-Agent: TinyGo") + fmt.Fprintln(w, "Connection: close") + fmt.Fprintln(w) + check(w.Flush()) + println("Sent!\r\n\r") +} + +func readResponse() { + r := bufio.NewReader(conn) + resp, err := io.ReadAll(r) + check(err) + println(string(resp)) +} + +func closeConnection() { + conn.Close() +} + +func main() { + waitSerial() + + link, _ := probe.Probe() + + err := link.NetConnect(&netlink.ConnectParams{ + Ssid: ssid, + Passphrase: pass, + }) + if err != nil { + log.Fatal(err) + } + + for i := 0; ; i++ { + dialConnection() + makeRequest() + readResponse() + closeConnection() + println("--------", i, "--------\r\n") + time.Sleep(10 * time.Second) + } +} diff --git a/examples/rtl8720dn/webserver/main.go b/examples/net/webserver/main.go similarity index 75% rename from examples/rtl8720dn/webserver/main.go rename to examples/net/webserver/main.go index 6ae17c712..84f0fb4d4 100644 --- a/examples/rtl8720dn/webserver/main.go +++ b/examples/net/webserver/main.go @@ -1,61 +1,51 @@ +// This example listens on port :80 serving a web page. Multiple clients +// may connect and be serviced at the same time. IPv4 only. HTTP only. +// +// $ curl http://10.0.0.2 +// +// Note: It may be necessary to increase the stack size when using "net/http". +// Use the -stack-size=4KB command line option. + +//go:build pyportal || nano_rp2040 || metro_m4_airlift || arduino_mkrwifi1010 || matrixportal_m4 || wioterminal + package main import ( "fmt" + "log" "machine" + "net/http" "strconv" "time" - "tinygo.org/x/drivers/net/http" - "tinygo.org/x/drivers/rtl8720dn" + "tinygo.org/x/drivers/netlink" + "tinygo.org/x/drivers/netlink/probe" ) -// You can override the setting with the init() in another source code. -// func init() { -// ssid = "your-ssid" -// pass = "your-password" -// debug = true -// } - var ( - ssid string - pass string - debug = false + ssid string + pass string + port string = ":80" ) var led = machine.LED -var backlight = machine.LCD_BACKLIGHT func main() { - led.Configure(machine.PinConfig{Mode: machine.PinOutput}) - backlight.Configure(machine.PinConfig{Mode: machine.PinOutput}) - - err := run() - for err != nil { - fmt.Printf("error: %s\r\n", err.Error()) - time.Sleep(5 * time.Second) - } -} -func run() error { - adaptor := rtl8720dn.New(machine.UART3, machine.PB24, machine.PC24, machine.RTL8720D_CHIP_PU) - adaptor.Debug(debug) - adaptor.Configure() + // wait a bit for serial + time.Sleep(2 * time.Second) - http.UseDriver(adaptor) + led.Configure(machine.PinConfig{Mode: machine.PinOutput}) - err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) - if err != nil { - return err - } + link, _ := probe.Probe() - ip, subnet, gateway, err := adaptor.GetIP() + err := link.NetConnect(&netlink.ConnectParams{ + Ssid: ssid, + Passphrase: pass, + }) if err != nil { - return err + log.Fatal(err) } - fmt.Printf("IP Address : %s\r\n", ip) - fmt.Printf("Mask : %s\r\n", subnet) - fmt.Printf("Gateway : %s\r\n", gateway) http.HandleFunc("/", root) http.HandleFunc("/hello", hello) @@ -63,10 +53,12 @@ func run() error { http.HandleFunc("/6", sixlines) http.HandleFunc("/off", LED_OFF) http.HandleFunc("/on", LED_ON) - if err := http.ListenAndServe(":80", nil); err != nil { - message(err.Error()) + + err = http.ListenAndServe(port, nil) + for err != nil { + fmt.Printf("error: %s\r\n", err.Error()) + time.Sleep(5 * time.Second) } - return nil } func root(w http.ResponseWriter, r *http.Request) { @@ -101,8 +93,8 @@ func root(w http.ResponseWriter, r *http.Request) { TinyGo HTTP Server - - -
TinyGo HTTP Server
- -

- access: %d -

- - /hello
- /6
- -

- LED
- /on
- /off
-

- - -

- /cnt
- cnt:
- incrCnt()
-

- - -
-

- - - `, access) -} - -func sixlines(w http.ResponseWriter, r *http.Request) { - // https://fukuno.jig.jp/3267 - fmt.Fprint(w, ``) -} - -func LED_ON(w http.ResponseWriter, r *http.Request) { - led.High() - w.Header().Set(`Content-Type`, `text/plain; charset=UTF-8`) - fmt.Fprintf(w, "led.High()") -} - -func LED_OFF(w http.ResponseWriter, r *http.Request) { - led.Low() - w.Header().Set(`Content-Type`, `text/plain; charset=UTF-8`) - fmt.Fprintf(w, "led.Low()") -} - -func hello(w http.ResponseWriter, r *http.Request) { - w.Header().Set(`Content-Type`, `text/plain; charset=UTF-8`) - fmt.Fprintf(w, "hello") -} - -var counter int - -func cnt(w http.ResponseWriter, r *http.Request) { - r.ParseForm() - if r.Method == "POST" { - c := r.Form.Get("cnt") - if c != "" { - i64, _ := strconv.ParseInt(c, 0, 0) - counter = int(i64) - } - } - - w.Header().Set(`Content-Type`, `application/json`) - fmt.Fprintf(w, `{"cnt": %d}`, counter) -} - -const retriesBeforeFailure = 3 - -// connect to access point -func connectToAP() { - time.Sleep(2 * time.Second) - var err error - for i := 0; i < retriesBeforeFailure; i++ { - println("Connecting to " + ssid) - err = adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second) - if err == nil { - println("Connected.") - - return - } - } - - // error connecting to AP - failMessage(err.Error()) -} - -func displayIP() { - ip, _, _, err := adaptor.GetIP() - for ; err != nil; ip, _, _, err = adaptor.GetIP() { - message(err.Error()) - time.Sleep(1 * time.Second) - } - message("IP address: " + ip.String()) -} - -func message(msg string) { - println(msg, "\r") -} - -func failMessage(msg string) { - for { - println(msg) - time.Sleep(1 * time.Second) - } -} diff --git a/net/adapter.go b/net/adapter.go deleted file mode 100644 index 501def85d..000000000 --- a/net/adapter.go +++ /dev/null @@ -1,44 +0,0 @@ -package net - -import ( - "errors" - "time" -) - -var ( - ErrWiFiMissingSSID = errors.New("missing SSID") - ErrWiFiConnectTimeout = errors.New("WiFi connect timeout") -) - -// Adapter interface is used to communicate with the network adapter. -type Adapter interface { - // functions used to connect/disconnect to/from an access point - ConnectToAccessPoint(ssid, pass string, timeout time.Duration) error - Disconnect() error - GetClientIP() (string, error) - - // these functions are used once the adapter is connected to the network - 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 Adapter - -func UseDriver(a Adapter) { - // TODO: rethink and refactor this - if ActiveDevice != nil { - panic("net.ActiveDevice is already set") - } - ActiveDevice = a -} diff --git a/net/http/client.go b/net/http/client.go deleted file mode 100644 index ab1d81dfe..000000000 --- a/net/http/client.go +++ /dev/null @@ -1,253 +0,0 @@ -package http - -import ( - "io" - "net/url" - "strings" - "time" -) - -// A Client is an HTTP client. Its zero value (DefaultClient) is a -// usable client that uses DefaultTransport. -// -// The Client's Transport typically has internal state (cached TCP -// connections), so Clients should be reused instead of created as -// needed. Clients are safe for concurrent use by multiple goroutines. -// -// A Client is higher-level than a RoundTripper (such as Transport) -// and additionally handles HTTP details such as cookies and -// redirects. -// -// When following redirects, the Client will forward all headers set on the -// initial Request except: -// -// • when forwarding sensitive headers like "Authorization", -// "WWW-Authenticate", and "Cookie" to untrusted targets. -// These headers will be ignored when following a redirect to a domain -// that is not a subdomain match or exact match of the initial domain. -// For example, a redirect from "foo.com" to either "foo.com" or "sub.foo.com" -// will forward the sensitive headers, but a redirect to "bar.com" will not. -// -// • when forwarding the "Cookie" header with a non-nil cookie Jar. -// Since each redirect may mutate the state of the cookie jar, -// a redirect may possibly alter a cookie set in the initial request. -// When forwarding the "Cookie" header, any mutated cookies will be omitted, -// with the expectation that the Jar will insert those mutated cookies -// with the updated values (assuming the origin matches). -// If Jar is nil, the initial cookies are forwarded without change. -type Client struct { - // Transport specifies the mechanism by which individual - // HTTP requests are made. - // If nil, DefaultTransport is used. - Transport RoundTripper - - // CheckRedirect specifies the policy for handling redirects. - // If CheckRedirect is not nil, the client calls it before - // following an HTTP redirect. The arguments req and via are - // the upcoming request and the requests made already, oldest - // first. If CheckRedirect returns an error, the Client's Get - // method returns both the previous Response (with its Body - // closed) and CheckRedirect's error (wrapped in a url.Error) - // instead of issuing the Request req. - // As a special case, if CheckRedirect returns ErrUseLastResponse, - // then the most recent response is returned with its body - // unclosed, along with a nil error. - // - // If CheckRedirect is nil, the Client uses its default policy, - // which is to stop after 10 consecutive requests. - CheckRedirect func(req *Request, via []*Request) error - - // Jar specifies the cookie jar. - // - // The Jar is used to insert relevant cookies into every - // outbound Request and is updated with the cookie values - // of every inbound Response. The Jar is consulted for every - // redirect that the Client follows. - // - // If Jar is nil, cookies are only sent if they are explicitly - // set on the Request. - Jar CookieJar - - // Timeout specifies a time limit for requests made by this - // Client. The timeout includes connection time, any - // redirects, and reading the response body. The timer remains - // running after Get, Head, Post, or Do return and will - // interrupt reading of the Response.Body. - // - // A Timeout of zero means no timeout. - // - // The Client cancels requests to the underlying Transport - // as if the Request's Context ended. - // - // For compatibility, the Client will also use the deprecated - // CancelRequest method on Transport if found. New - // RoundTripper implementations should use the Request's Context - // for cancellation instead of implementing CancelRequest. - Timeout time.Duration -} - -// DefaultClient is the default Client and is used by Get, Head, and Post. -var DefaultClient = &Client{} - -// RoundTripper is an interface representing the ability to execute a -// single HTTP transaction, obtaining the Response for a given Request. -// -// A RoundTripper must be safe for concurrent use by multiple -// goroutines. -type RoundTripper interface { - // RoundTrip executes a single HTTP transaction, returning - // a Response for the provided Request. - // - // RoundTrip should not attempt to interpret the response. In - // particular, RoundTrip must return err == nil if it obtained - // a response, regardless of the response's HTTP status code. - // A non-nil err should be reserved for failure to obtain a - // response. Similarly, RoundTrip should not attempt to - // handle higher-level protocol details such as redirects, - // authentication, or cookies. - // - // RoundTrip should not modify the request, except for - // consuming and closing the Request's Body. RoundTrip may - // read fields of the request in a separate goroutine. Callers - // should not mutate or reuse the request until the Response's - // Body has been closed. - // - // RoundTrip must always close the body, including on errors, - // but depending on the implementation may do so in a separate - // goroutine even after RoundTrip returns. This means that - // callers wanting to reuse the body for subsequent requests - // must arrange to wait for the Close call before doing so. - // - // The Request's URL and Header fields must be initialized. - RoundTrip(*Request) (*Response, error) -} - -// Get issues a GET to the specified URL. If the response is one of -// the following redirect codes, Get follows the redirect, up to a -// maximum of 10 redirects: -// -// 301 (Moved Permanently) -// 302 (Found) -// 303 (See Other) -// 307 (Temporary Redirect) -// 308 (Permanent Redirect) -// -// An error is returned if there were too many redirects or if there -// was an HTTP protocol error. A non-2xx response doesn't cause an -// error. Any returned error will be of type *url.Error. The url.Error -// value's Timeout method will report true if request timed out or was -// canceled. -// -// When err is nil, resp always contains a non-nil resp.Body. -// Caller should close resp.Body when done reading from it. -// -// Get is a wrapper around DefaultClient.Get. -// -// To make a request with custom headers, use NewRequest and -// DefaultClient.Do. -func Get(url string) (resp *Response, err error) { - return DefaultClient.Get(url) -} - -// Get issues a GET to the specified URL. If the response is one of the -// following redirect codes, Get follows the redirect after calling the -// Client's CheckRedirect function: -// -// 301 (Moved Permanently) -// 302 (Found) -// 303 (See Other) -// 307 (Temporary Redirect) -// 308 (Permanent Redirect) -// -// An error is returned if the Client's CheckRedirect function fails -// or if there was an HTTP protocol error. A non-2xx response doesn't -// cause an error. Any returned error will be of type *url.Error. The -// url.Error value's Timeout method will report true if the request -// timed out. -// -// When err is nil, resp always contains a non-nil resp.Body. -// Caller should close resp.Body when done reading from it. -// -// To make a request with custom headers, use NewRequest and Client.Do. -func (c *Client) Get(url string) (resp *Response, err error) { - req, err := NewRequest("GET", url, nil) - if err != nil { - return nil, err - } - return c.Do(req) -} - -// Post issues a POST to the specified URL. -// -// Caller should close resp.Body when done reading from it. -// -// If the provided body is an io.Closer, it is closed after the -// request. -// -// Post is a wrapper around DefaultClient.Post. -// -// To set custom headers, use NewRequest and DefaultClient.Do. -// -// See the Client.Do method documentation for details on how redirects -// are handled. -func Post(url, contentType string, body io.Reader) (resp *Response, err error) { - return DefaultClient.Post(url, contentType, body) -} - -// Post issues a POST to the specified URL. -// -// Caller should close resp.Body when done reading from it. -// -// If the provided body is an io.Closer, it is closed after the -// request. -// -// To set custom headers, use NewRequest and Client.Do. -// -// See the Client.Do method documentation for details on how redirects -// are handled. -func (c *Client) Post(url, contentType string, body io.Reader) (resp *Response, err error) { - req, err := NewRequest("POST", url, body) - if err != nil { - return nil, err - } - req.Header.Set("Content-Type", contentType) - return c.Do(req) -} - -// PostForm issues a POST to the specified URL, with data's keys and -// values URL-encoded as the request body. -// -// The Content-Type header is set to application/x-www-form-urlencoded. -// To set other headers, use NewRequest and DefaultClient.Do. -// -// When err is nil, resp always contains a non-nil resp.Body. -// Caller should close resp.Body when done reading from it. -// -// PostForm is a wrapper around DefaultClient.PostForm. -// -// See the Client.Do method documentation for details on how redirects -// are handled. -// -// To make a request with a specified context.Context, use NewRequestWithContext -// and DefaultClient.Do. -func PostForm(url string, data url.Values) (resp *Response, err error) { - return DefaultClient.PostForm(url, data) -} - -// PostForm issues a POST to the specified URL, -// with data's keys and values URL-encoded as the request body. -// -// The Content-Type header is set to application/x-www-form-urlencoded. -// To set other headers, use NewRequest and Client.Do. -// -// When err is nil, resp always contains a non-nil resp.Body. -// Caller should close resp.Body when done reading from it. -// -// See the Client.Do method documentation for details on how redirects -// are handled. -// -// To make a request with a specified context.Context, use NewRequestWithContext -// and Client.Do. -func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error) { - return c.Post(url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode())) -} diff --git a/net/http/cookie.go b/net/http/cookie.go deleted file mode 100644 index 2155289b7..000000000 --- a/net/http/cookie.go +++ /dev/null @@ -1,435 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -import ( - "log" - "net" - "net/textproto" - "strconv" - "strings" - "time" -) - -// A Cookie represents an HTTP cookie as sent in the Set-Cookie header of an -// HTTP response or the Cookie header of an HTTP request. -// -// See https://tools.ietf.org/html/rfc6265 for details. -type Cookie struct { - Name string - Value string - - Path string // optional - Domain string // optional - Expires time.Time // optional - RawExpires string // for reading cookies only - - // MaxAge=0 means no 'Max-Age' attribute specified. - // MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0' - // MaxAge>0 means Max-Age attribute present and given in seconds - MaxAge int - Secure bool - HttpOnly bool - SameSite SameSite - Raw string - Unparsed []string // Raw text of unparsed attribute-value pairs -} - -// SameSite allows a server to define a cookie attribute making it impossible for -// the browser to send this cookie along with cross-site requests. The main -// goal is to mitigate the risk of cross-origin information leakage, and provide -// some protection against cross-site request forgery attacks. -// -// See https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00 for details. -type SameSite int - -const ( - SameSiteDefaultMode SameSite = iota + 1 - SameSiteLaxMode - SameSiteStrictMode - SameSiteNoneMode -) - -// readSetCookies parses all "Set-Cookie" values from -// the header h and returns the successfully parsed Cookies. -func readSetCookies(h Header) []*Cookie { - cookieCount := len(h["Set-Cookie"]) - if cookieCount == 0 { - return []*Cookie{} - } - cookies := make([]*Cookie, 0, cookieCount) - for _, line := range h["Set-Cookie"] { - parts := strings.Split(textproto.TrimString(line), ";") - if len(parts) == 1 && parts[0] == "" { - continue - } - parts[0] = textproto.TrimString(parts[0]) - j := strings.Index(parts[0], "=") - if j < 0 { - continue - } - name, value := parts[0][:j], parts[0][j+1:] - if !isCookieNameValid(name) { - continue - } - value, ok := parseCookieValue(value, true) - if !ok { - continue - } - c := &Cookie{ - Name: name, - Value: value, - Raw: line, - } - for i := 1; i < len(parts); i++ { - parts[i] = textproto.TrimString(parts[i]) - if len(parts[i]) == 0 { - continue - } - - attr, val := parts[i], "" - if j := strings.Index(attr, "="); j >= 0 { - attr, val = attr[:j], attr[j+1:] - } - lowerAttr := strings.ToLower(attr) - val, ok = parseCookieValue(val, false) - if !ok { - c.Unparsed = append(c.Unparsed, parts[i]) - continue - } - switch lowerAttr { - case "samesite": - lowerVal := strings.ToLower(val) - switch lowerVal { - case "lax": - c.SameSite = SameSiteLaxMode - case "strict": - c.SameSite = SameSiteStrictMode - case "none": - c.SameSite = SameSiteNoneMode - default: - c.SameSite = SameSiteDefaultMode - } - continue - case "secure": - c.Secure = true - continue - case "httponly": - c.HttpOnly = true - continue - case "domain": - c.Domain = val - continue - case "max-age": - secs, err := strconv.Atoi(val) - if err != nil || secs != 0 && val[0] == '0' { - break - } - if secs <= 0 { - secs = -1 - } - c.MaxAge = secs - continue - case "expires": - c.RawExpires = val - exptime, err := time.Parse(time.RFC1123, val) - if err != nil { - exptime, err = time.Parse("Mon, 02-Jan-2006 15:04:05 MST", val) - if err != nil { - c.Expires = time.Time{} - break - } - } - c.Expires = exptime.UTC() - continue - case "path": - c.Path = val - continue - } - c.Unparsed = append(c.Unparsed, parts[i]) - } - cookies = append(cookies, c) - } - return cookies -} - -// SetCookie adds a Set-Cookie header to the provided ResponseWriter's headers. -// The provided cookie must have a valid Name. Invalid cookies may be -// silently dropped. -func SetCookie(w ResponseWriter, cookie *Cookie) { - if v := cookie.String(); v != "" { - w.Header().Add("Set-Cookie", v) - } -} - -// String returns the serialization of the cookie for use in a Cookie -// header (if only Name and Value are set) or a Set-Cookie response -// header (if other fields are set). -// If c is nil or c.Name is invalid, the empty string is returned. -func (c *Cookie) String() string { - if c == nil || !isCookieNameValid(c.Name) { - return "" - } - // extraCookieLength derived from typical length of cookie attributes - // see RFC 6265 Sec 4.1. - const extraCookieLength = 110 - var b strings.Builder - b.Grow(len(c.Name) + len(c.Value) + len(c.Domain) + len(c.Path) + extraCookieLength) - b.WriteString(c.Name) - b.WriteRune('=') - b.WriteString(sanitizeCookieValue(c.Value)) - - if len(c.Path) > 0 { - b.WriteString("; Path=") - b.WriteString(sanitizeCookiePath(c.Path)) - } - if len(c.Domain) > 0 { - if validCookieDomain(c.Domain) { - // A c.Domain containing illegal characters is not - // sanitized but simply dropped which turns the cookie - // into a host-only cookie. A leading dot is okay - // but won't be sent. - d := c.Domain - if d[0] == '.' { - d = d[1:] - } - b.WriteString("; Domain=") - b.WriteString(d) - } else { - log.Printf("net/http: invalid Cookie.Domain %q; dropping domain attribute", c.Domain) - } - } - var buf [len(TimeFormat)]byte - if validCookieExpires(c.Expires) { - b.WriteString("; Expires=") - b.Write(c.Expires.UTC().AppendFormat(buf[:0], TimeFormat)) - } - if c.MaxAge > 0 { - b.WriteString("; Max-Age=") - b.Write(strconv.AppendInt(buf[:0], int64(c.MaxAge), 10)) - } else if c.MaxAge < 0 { - b.WriteString("; Max-Age=0") - } - if c.HttpOnly { - b.WriteString("; HttpOnly") - } - if c.Secure { - b.WriteString("; Secure") - } - switch c.SameSite { - case SameSiteDefaultMode: - // Skip, default mode is obtained by not emitting the attribute. - case SameSiteNoneMode: - b.WriteString("; SameSite=None") - case SameSiteLaxMode: - b.WriteString("; SameSite=Lax") - case SameSiteStrictMode: - b.WriteString("; SameSite=Strict") - } - return b.String() -} - -// readCookies parses all "Cookie" values from the header h and -// returns the successfully parsed Cookies. -// -// if filter isn't empty, only cookies of that name are returned -func readCookies(h Header, filter string) []*Cookie { - lines := h["Cookie"] - if len(lines) == 0 { - return []*Cookie{} - } - - cookies := make([]*Cookie, 0, len(lines)+strings.Count(lines[0], ";")) - for _, line := range lines { - line = textproto.TrimString(line) - - var part string - for len(line) > 0 { // continue since we have rest - if splitIndex := strings.Index(line, ";"); splitIndex > 0 { - part, line = line[:splitIndex], line[splitIndex+1:] - } else { - part, line = line, "" - } - part = textproto.TrimString(part) - if len(part) == 0 { - continue - } - name, val := part, "" - if j := strings.Index(part, "="); j >= 0 { - name, val = name[:j], name[j+1:] - } - if !isCookieNameValid(name) { - continue - } - if filter != "" && filter != name { - continue - } - val, ok := parseCookieValue(val, true) - if !ok { - continue - } - cookies = append(cookies, &Cookie{Name: name, Value: val}) - } - } - return cookies -} - -// validCookieDomain reports whether v is a valid cookie domain-value. -func validCookieDomain(v string) bool { - if isCookieDomainName(v) { - return true - } - if net.ParseIP(v) != nil && !strings.Contains(v, ":") { - return true - } - return false -} - -// validCookieExpires reports whether v is a valid cookie expires-value. -func validCookieExpires(t time.Time) bool { - // IETF RFC 6265 Section 5.1.1.5, the year must not be less than 1601 - return t.Year() >= 1601 -} - -// isCookieDomainName reports whether s is a valid domain name or a valid -// domain name with a leading dot '.'. It is almost a direct copy of -// package net's isDomainName. -func isCookieDomainName(s string) bool { - if len(s) == 0 { - return false - } - if len(s) > 255 { - return false - } - - if s[0] == '.' { - // A cookie a domain attribute may start with a leading dot. - s = s[1:] - } - last := byte('.') - ok := false // Ok once we've seen a letter. - partlen := 0 - for i := 0; i < len(s); i++ { - c := s[i] - switch { - default: - return false - case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z': - // No '_' allowed here (in contrast to package net). - ok = true - partlen++ - case '0' <= c && c <= '9': - // fine - partlen++ - case c == '-': - // Byte before dash cannot be dot. - if last == '.' { - return false - } - partlen++ - case c == '.': - // Byte before dot cannot be dot, dash. - if last == '.' || last == '-' { - return false - } - if partlen > 63 || partlen == 0 { - return false - } - partlen = 0 - } - last = c - } - if last == '-' || partlen > 63 { - return false - } - - return ok -} - -var cookieNameSanitizer = strings.NewReplacer("\n", "-", "\r", "-") - -func sanitizeCookieName(n string) string { - return cookieNameSanitizer.Replace(n) -} - -// sanitizeCookieValue produces a suitable cookie-value from v. -// https://tools.ietf.org/html/rfc6265#section-4.1.1 -// cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) -// cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E -// -// ; US-ASCII characters excluding CTLs, -// ; whitespace DQUOTE, comma, semicolon, -// ; and backslash -// -// We loosen this as spaces and commas are common in cookie values -// but we produce a quoted cookie-value if and only if v contains -// commas or spaces. -// See https://golang.org/issue/7243 for the discussion. -func sanitizeCookieValue(v string) string { - v = sanitizeOrWarn("Cookie.Value", validCookieValueByte, v) - if len(v) == 0 { - return v - } - if strings.IndexByte(v, ' ') >= 0 || strings.IndexByte(v, ',') >= 0 { - return `"` + v + `"` - } - return v -} - -func validCookieValueByte(b byte) bool { - return 0x20 <= b && b < 0x7f && b != '"' && b != ';' && b != '\\' -} - -// path-av = "Path=" path-value -// path-value = -func sanitizeCookiePath(v string) string { - return sanitizeOrWarn("Cookie.Path", validCookiePathByte, v) -} - -func validCookiePathByte(b byte) bool { - return 0x20 <= b && b < 0x7f && b != ';' -} - -func sanitizeOrWarn(fieldName string, valid func(byte) bool, v string) string { - ok := true - for i := 0; i < len(v); i++ { - if valid(v[i]) { - continue - } - log.Printf("net/http: invalid byte %q in %s; dropping invalid bytes", v[i], fieldName) - ok = false - break - } - if ok { - return v - } - buf := make([]byte, 0, len(v)) - for i := 0; i < len(v); i++ { - if b := v[i]; valid(b) { - buf = append(buf, b) - } - } - return string(buf) -} - -func parseCookieValue(raw string, allowDoubleQuote bool) (string, bool) { - // Strip the quotes, if present. - if allowDoubleQuote && len(raw) > 1 && raw[0] == '"' && raw[len(raw)-1] == '"' { - raw = raw[1 : len(raw)-1] - } - for i := 0; i < len(raw); i++ { - if !validCookieValueByte(raw[i]) { - return "", false - } - } - return raw, true -} - -func isCookieNameValid(raw string) bool { - if raw == "" { - return false - } - return strings.IndexFunc(raw, isNotToken) < 0 -} diff --git a/net/http/cookiejar/jar.go b/net/http/cookiejar/jar.go deleted file mode 100644 index 9a773f8a7..000000000 --- a/net/http/cookiejar/jar.go +++ /dev/null @@ -1,504 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package cookiejar implements an in-memory RFC 6265-compliant http.CookieJar. -package cookiejar - -import ( - "errors" - "fmt" - "net/url" - "sort" - "strings" - "sync" - "time" - - "tinygo.org/x/drivers/net" - "tinygo.org/x/drivers/net/http" -) - -// PublicSuffixList provides the public suffix of a domain. For example: -// - the public suffix of "example.com" is "com", -// - the public suffix of "foo1.foo2.foo3.co.uk" is "co.uk", and -// - the public suffix of "bar.pvt.k12.ma.us" is "pvt.k12.ma.us". -// -// Implementations of PublicSuffixList must be safe for concurrent use by -// multiple goroutines. -// -// An implementation that always returns "" is valid and may be useful for -// testing but it is not secure: it means that the HTTP server for foo.com can -// set a cookie for bar.com. -// -// A public suffix list implementation is in the package -// golang.org/x/net/publicsuffix. -type PublicSuffixList interface { - // PublicSuffix returns the public suffix of domain. - // - // TODO: specify which of the caller and callee is responsible for IP - // addresses, for leading and trailing dots, for case sensitivity, and - // for IDN/Punycode. - PublicSuffix(domain string) string - - // String returns a description of the source of this public suffix - // list. The description will typically contain something like a time - // stamp or version number. - String() string -} - -// Options are the options for creating a new Jar. -type Options struct { - // PublicSuffixList is the public suffix list that determines whether - // an HTTP server can set a cookie for a domain. - // - // A nil value is valid and may be useful for testing but it is not - // secure: it means that the HTTP server for foo.co.uk can set a cookie - // for bar.co.uk. - PublicSuffixList PublicSuffixList -} - -// Jar implements the http.CookieJar interface from the net/http package. -type Jar struct { - psList PublicSuffixList - - // mu locks the remaining fields. - mu sync.Mutex - - // entries is a set of entries, keyed by their eTLD+1 and subkeyed by - // their name/domain/path. - entries map[string]map[string]entry - - // nextSeqNum is the next sequence number assigned to a new cookie - // created SetCookies. - nextSeqNum uint64 -} - -// New returns a new cookie jar. A nil *Options is equivalent to a zero -// Options. -func New(o *Options) (*Jar, error) { - jar := &Jar{ - entries: make(map[string]map[string]entry), - } - if o != nil { - jar.psList = o.PublicSuffixList - } - return jar, nil -} - -// entry is the internal representation of a cookie. -// -// This struct type is not used outside of this package per se, but the exported -// fields are those of RFC 6265. -type entry struct { - Name string - Value string - Domain string - Path string - SameSite string - Secure bool - HttpOnly bool - Persistent bool - HostOnly bool - Expires time.Time - Creation time.Time - LastAccess time.Time - - // seqNum is a sequence number so that Cookies returns cookies in a - // deterministic order, even for cookies that have equal Path length and - // equal Creation time. This simplifies testing. - seqNum uint64 -} - -// id returns the domain;path;name triple of e as an id. -func (e *entry) id() string { - return fmt.Sprintf("%s;%s;%s", e.Domain, e.Path, e.Name) -} - -// shouldSend determines whether e's cookie qualifies to be included in a -// request to host/path. It is the caller's responsibility to check if the -// cookie is expired. -func (e *entry) shouldSend(https bool, host, path string) bool { - return e.domainMatch(host) && e.pathMatch(path) && (https || !e.Secure) -} - -// domainMatch implements "domain-match" of RFC 6265 section 5.1.3. -func (e *entry) domainMatch(host string) bool { - if e.Domain == host { - return true - } - return !e.HostOnly && hasDotSuffix(host, e.Domain) -} - -// pathMatch implements "path-match" according to RFC 6265 section 5.1.4. -func (e *entry) pathMatch(requestPath string) bool { - if requestPath == e.Path { - return true - } - if strings.HasPrefix(requestPath, e.Path) { - if e.Path[len(e.Path)-1] == '/' { - return true // The "/any/" matches "/any/path" case. - } else if requestPath[len(e.Path)] == '/' { - return true // The "/any" matches "/any/path" case. - } - } - return false -} - -// hasDotSuffix reports whether s ends in "."+suffix. -func hasDotSuffix(s, suffix string) bool { - return len(s) > len(suffix) && s[len(s)-len(suffix)-1] == '.' && s[len(s)-len(suffix):] == suffix -} - -// Cookies implements the Cookies method of the http.CookieJar interface. -// -// It returns an empty slice if the URL's scheme is not HTTP or HTTPS. -func (j *Jar) Cookies(u *url.URL) (cookies []*http.Cookie) { - return j.cookies(u, time.Now()) -} - -// cookies is like Cookies but takes the current time as a parameter. -func (j *Jar) cookies(u *url.URL, now time.Time) (cookies []*http.Cookie) { - if u.Scheme != "http" && u.Scheme != "https" { - return cookies - } - host, err := canonicalHost(u.Host) - if err != nil { - return cookies - } - key := jarKey(host, j.psList) - - j.mu.Lock() - defer j.mu.Unlock() - - submap := j.entries[key] - if submap == nil { - return cookies - } - - https := u.Scheme == "https" - path := u.Path - if path == "" { - path = "/" - } - - modified := false - var selected []entry - for id, e := range submap { - if e.Persistent && !e.Expires.After(now) { - delete(submap, id) - modified = true - continue - } - if !e.shouldSend(https, host, path) { - continue - } - e.LastAccess = now - submap[id] = e - selected = append(selected, e) - modified = true - } - if modified { - if len(submap) == 0 { - delete(j.entries, key) - } else { - j.entries[key] = submap - } - } - - // sort according to RFC 6265 section 5.4 point 2: by longest - // path and then by earliest creation time. - sort.Slice(selected, func(i, j int) bool { - s := selected - if len(s[i].Path) != len(s[j].Path) { - return len(s[i].Path) > len(s[j].Path) - } - if !s[i].Creation.Equal(s[j].Creation) { - return s[i].Creation.Before(s[j].Creation) - } - return s[i].seqNum < s[j].seqNum - }) - for _, e := range selected { - cookies = append(cookies, &http.Cookie{Name: e.Name, Value: e.Value}) - } - - return cookies -} - -// SetCookies implements the SetCookies method of the http.CookieJar interface. -// -// It does nothing if the URL's scheme is not HTTP or HTTPS. -func (j *Jar) SetCookies(u *url.URL, cookies []*http.Cookie) { - j.setCookies(u, cookies, time.Now()) -} - -// setCookies is like SetCookies but takes the current time as parameter. -func (j *Jar) setCookies(u *url.URL, cookies []*http.Cookie, now time.Time) { - if len(cookies) == 0 { - return - } - if u.Scheme != "http" && u.Scheme != "https" { - return - } - host, err := canonicalHost(u.Host) - if err != nil { - return - } - key := jarKey(host, j.psList) - defPath := defaultPath(u.Path) - - j.mu.Lock() - defer j.mu.Unlock() - - submap := j.entries[key] - - modified := false - for _, cookie := range cookies { - e, remove, err := j.newEntry(cookie, now, defPath, host) - if err != nil { - continue - } - id := e.id() - if remove { - if submap != nil { - if _, ok := submap[id]; ok { - delete(submap, id) - modified = true - } - } - continue - } - if submap == nil { - submap = make(map[string]entry) - } - - if old, ok := submap[id]; ok { - e.Creation = old.Creation - e.seqNum = old.seqNum - } else { - e.Creation = now - e.seqNum = j.nextSeqNum - j.nextSeqNum++ - } - e.LastAccess = now - submap[id] = e - modified = true - } - - if modified { - if len(submap) == 0 { - delete(j.entries, key) - } else { - j.entries[key] = submap - } - } -} - -// canonicalHost strips port from host if present and returns the canonicalized -// host name. -func canonicalHost(host string) (string, error) { - var err error - host = strings.ToLower(host) - if hasPort(host) { - host, _, err = net.SplitHostPort(host) - if err != nil { - return "", err - } - } - if strings.HasSuffix(host, ".") { - // Strip trailing dot from fully qualified domain names. - host = host[:len(host)-1] - } - return toASCII(host) -} - -// hasPort reports whether host contains a port number. host may be a host -// name, an IPv4 or an IPv6 address. -func hasPort(host string) bool { - colons := strings.Count(host, ":") - if colons == 0 { - return false - } - if colons == 1 { - return true - } - return host[0] == '[' && strings.Contains(host, "]:") -} - -// jarKey returns the key to use for a jar. -func jarKey(host string, psl PublicSuffixList) string { - if isIP(host) { - return host - } - - var i int - if psl == nil { - i = strings.LastIndex(host, ".") - if i <= 0 { - return host - } - } else { - suffix := psl.PublicSuffix(host) - if suffix == host { - return host - } - i = len(host) - len(suffix) - if i <= 0 || host[i-1] != '.' { - // The provided public suffix list psl is broken. - // Storing cookies under host is a safe stopgap. - return host - } - // Only len(suffix) is used to determine the jar key from - // here on, so it is okay if psl.PublicSuffix("www.buggy.psl") - // returns "com" as the jar key is generated from host. - } - prevDot := strings.LastIndex(host[:i-1], ".") - return host[prevDot+1:] -} - -// isIP reports whether host is an IP address. -func isIP(host string) bool { - return net.ParseIP(host) != nil -} - -// defaultPath returns the directory part of an URL's path according to -// RFC 6265 section 5.1.4. -func defaultPath(path string) string { - if len(path) == 0 || path[0] != '/' { - return "/" // Path is empty or malformed. - } - - i := strings.LastIndex(path, "/") // Path starts with "/", so i != -1. - if i == 0 { - return "/" // Path has the form "/abc". - } - return path[:i] // Path is either of form "/abc/xyz" or "/abc/xyz/". -} - -// newEntry creates an entry from a http.Cookie c. now is the current time and -// is compared to c.Expires to determine deletion of c. defPath and host are the -// default-path and the canonical host name of the URL c was received from. -// -// remove records whether the jar should delete this cookie, as it has already -// expired with respect to now. In this case, e may be incomplete, but it will -// be valid to call e.id (which depends on e's Name, Domain and Path). -// -// A malformed c.Domain will result in an error. -func (j *Jar) newEntry(c *http.Cookie, now time.Time, defPath, host string) (e entry, remove bool, err error) { - e.Name = c.Name - - if c.Path == "" || c.Path[0] != '/' { - e.Path = defPath - } else { - e.Path = c.Path - } - - e.Domain, e.HostOnly, err = j.domainAndType(host, c.Domain) - if err != nil { - return e, false, err - } - - // MaxAge takes precedence over Expires. - if c.MaxAge < 0 { - return e, true, nil - } else if c.MaxAge > 0 { - e.Expires = now.Add(time.Duration(c.MaxAge) * time.Second) - e.Persistent = true - } else { - if c.Expires.IsZero() { - e.Expires = endOfTime - e.Persistent = false - } else { - if !c.Expires.After(now) { - return e, true, nil - } - e.Expires = c.Expires - e.Persistent = true - } - } - - e.Value = c.Value - e.Secure = c.Secure - e.HttpOnly = c.HttpOnly - - switch c.SameSite { - case http.SameSiteDefaultMode: - e.SameSite = "SameSite" - case http.SameSiteStrictMode: - e.SameSite = "SameSite=Strict" - case http.SameSiteLaxMode: - e.SameSite = "SameSite=Lax" - } - - return e, false, nil -} - -var ( - errIllegalDomain = errors.New("cookiejar: illegal cookie domain attribute") - errMalformedDomain = errors.New("cookiejar: malformed cookie domain attribute") - errNoHostname = errors.New("cookiejar: no host name available (IP only)") -) - -// endOfTime is the time when session (non-persistent) cookies expire. -// This instant is representable in most date/time formats (not just -// Go's time.Time) and should be far enough in the future. -var endOfTime = time.Date(9999, 12, 31, 23, 59, 59, 0, time.UTC) - -// domainAndType determines the cookie's domain and hostOnly attribute. -func (j *Jar) domainAndType(host, domain string) (string, bool, error) { - if domain == "" { - // No domain attribute in the SetCookie header indicates a - // host cookie. - return host, true, nil - } - - if isIP(host) { - // According to RFC 6265 domain-matching includes not being - // an IP address. - // TODO: This might be relaxed as in common browsers. - return "", false, errNoHostname - } - - // From here on: If the cookie is valid, it is a domain cookie (with - // the one exception of a public suffix below). - // See RFC 6265 section 5.2.3. - if domain[0] == '.' { - domain = domain[1:] - } - - if len(domain) == 0 || domain[0] == '.' { - // Received either "Domain=." or "Domain=..some.thing", - // both are illegal. - return "", false, errMalformedDomain - } - domain = strings.ToLower(domain) - - if domain[len(domain)-1] == '.' { - // We received stuff like "Domain=www.example.com.". - // Browsers do handle such stuff (actually differently) but - // RFC 6265 seems to be clear here (e.g. section 4.1.2.3) in - // requiring a reject. 4.1.2.3 is not normative, but - // "Domain Matching" (5.1.3) and "Canonicalized Host Names" - // (5.1.2) are. - return "", false, errMalformedDomain - } - - // See RFC 6265 section 5.3 #5. - if j.psList != nil { - if ps := j.psList.PublicSuffix(domain); ps != "" && !hasDotSuffix(domain, ps) { - if host == domain { - // This is the one exception in which a cookie - // with a domain attribute is a host cookie. - return host, true, nil - } - return "", false, errIllegalDomain - } - } - - // The domain must domain-match host: www.mycompany.com cannot - // set cookies for .ourcompetitors.com. - if host != domain && !hasDotSuffix(host, domain) { - return "", false, errIllegalDomain - } - - return domain, false, nil -} diff --git a/net/http/cookiejar/punycode.go b/net/http/cookiejar/punycode.go deleted file mode 100644 index a9cc666e8..000000000 --- a/net/http/cookiejar/punycode.go +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cookiejar - -// This file implements the Punycode algorithm from RFC 3492. - -import ( - "fmt" - "strings" - "unicode/utf8" -) - -// These parameter values are specified in section 5. -// -// All computation is done with int32s, so that overflow behavior is identical -// regardless of whether int is 32-bit or 64-bit. -const ( - base int32 = 36 - damp int32 = 700 - initialBias int32 = 72 - initialN int32 = 128 - skew int32 = 38 - tmax int32 = 26 - tmin int32 = 1 -) - -// encode encodes a string as specified in section 6.3 and prepends prefix to -// the result. -// -// The "while h < length(input)" line in the specification becomes "for -// remaining != 0" in the Go code, because len(s) in Go is in bytes, not runes. -func encode(prefix, s string) (string, error) { - output := make([]byte, len(prefix), len(prefix)+1+2*len(s)) - copy(output, prefix) - delta, n, bias := int32(0), initialN, initialBias - b, remaining := int32(0), int32(0) - for _, r := range s { - if r < utf8.RuneSelf { - b++ - output = append(output, byte(r)) - } else { - remaining++ - } - } - h := b - if b > 0 { - output = append(output, '-') - } - for remaining != 0 { - m := int32(0x7fffffff) - for _, r := range s { - if m > r && r >= n { - m = r - } - } - delta += (m - n) * (h + 1) - if delta < 0 { - return "", fmt.Errorf("cookiejar: invalid label %q", s) - } - n = m - for _, r := range s { - if r < n { - delta++ - if delta < 0 { - return "", fmt.Errorf("cookiejar: invalid label %q", s) - } - continue - } - if r > n { - continue - } - q := delta - for k := base; ; k += base { - t := k - bias - if t < tmin { - t = tmin - } else if t > tmax { - t = tmax - } - if q < t { - break - } - output = append(output, encodeDigit(t+(q-t)%(base-t))) - q = (q - t) / (base - t) - } - output = append(output, encodeDigit(q)) - bias = adapt(delta, h+1, h == b) - delta = 0 - h++ - remaining-- - } - delta++ - n++ - } - return string(output), nil -} - -func encodeDigit(digit int32) byte { - switch { - case 0 <= digit && digit < 26: - return byte(digit + 'a') - case 26 <= digit && digit < 36: - return byte(digit + ('0' - 26)) - } - panic("cookiejar: internal error in punycode encoding") -} - -// adapt is the bias adaptation function specified in section 6.1. -func adapt(delta, numPoints int32, firstTime bool) int32 { - if firstTime { - delta /= damp - } else { - delta /= 2 - } - delta += delta / numPoints - k := int32(0) - for delta > ((base-tmin)*tmax)/2 { - delta /= base - tmin - k += base - } - return k + (base-tmin+1)*delta/(delta+skew) -} - -// Strictly speaking, the remaining code below deals with IDNA (RFC 5890 and -// friends) and not Punycode (RFC 3492) per se. - -// acePrefix is the ASCII Compatible Encoding prefix. -const acePrefix = "xn--" - -// toASCII converts a domain or domain label to its ASCII form. For example, -// toASCII("bücher.example.com") is "xn--bcher-kva.example.com", and -// toASCII("golang") is "golang". -func toASCII(s string) (string, error) { - if ascii(s) { - return s, nil - } - labels := strings.Split(s, ".") - for i, label := range labels { - if !ascii(label) { - a, err := encode(acePrefix, label) - if err != nil { - return "", err - } - labels[i] = a - } - } - return strings.Join(labels, "."), nil -} - -func ascii(s string) bool { - for i := 0; i < len(s); i++ { - if s[i] >= utf8.RuneSelf { - return false - } - } - return true -} diff --git a/net/http/driver.go b/net/http/driver.go deleted file mode 100644 index d12593985..000000000 --- a/net/http/driver.go +++ /dev/null @@ -1,15 +0,0 @@ -package http - -type DeviceDriver interface { - ListenAndServe(addr string, handler Handler) 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/net/http/header.go b/net/http/header.go deleted file mode 100644 index 0cc0e556c..000000000 --- a/net/http/header.go +++ /dev/null @@ -1,259 +0,0 @@ -package http - -import ( - "io" - "net/http/httptrace" - "net/textproto" - "sort" - "strings" - "sync" - "time" -) - -// A Header represents the key-value pairs in an HTTP header. -// -// The keys should be in canonical form, as returned by -// CanonicalHeaderKey. -type Header map[string][]string - -// Add adds the key, value pair to the header. -// It appends to any existing values associated with key. -// The key is case insensitive; it is canonicalized by -// CanonicalHeaderKey. -func (h Header) Add(key, value string) { - textproto.MIMEHeader(h).Add(key, value) -} - -// Set sets the header entries associated with key to the -// single element value. It replaces any existing values -// associated with key. The key is case insensitive; it is -// canonicalized by textproto.CanonicalMIMEHeaderKey. -// To use non-canonical keys, assign to the map directly. -func (h Header) Set(key, value string) { - textproto.MIMEHeader(h).Set(key, value) -} - -// Get gets the first value associated with the given key. If -// there are no values associated with the key, Get returns "". -// It is case insensitive; textproto.CanonicalMIMEHeaderKey is -// used to canonicalize the provided key. To use non-canonical keys, -// access the map directly. -func (h Header) Get(key string) string { - return textproto.MIMEHeader(h).Get(key) -} - -// Values returns all values associated with the given key. -// It is case insensitive; textproto.CanonicalMIMEHeaderKey is -// used to canonicalize the provided key. To use non-canonical -// keys, access the map directly. -// The returned slice is not a copy. -func (h Header) Values(key string) []string { - return textproto.MIMEHeader(h).Values(key) -} - -// get is like Get, but key must already be in CanonicalHeaderKey form. -func (h Header) get(key string) string { - if v := h[key]; len(v) > 0 { - return v[0] - } - return "" -} - -// has reports whether h has the provided key defined, even if it's -// set to 0-length slice. -func (h Header) has(key string) bool { - _, ok := h[key] - return ok -} - -// Del deletes the values associated with key. -// The key is case insensitive; it is canonicalized by -// CanonicalHeaderKey. -func (h Header) Del(key string) { - textproto.MIMEHeader(h).Del(key) -} - -// Write writes a header in wire format. -func (h Header) Write(w io.Writer) error { - return h.write(w, nil) -} - -func (h Header) write(w io.Writer, trace *httptrace.ClientTrace) error { - return h.writeSubset(w, nil, trace) -} - -// Clone returns a copy of h or nil if h is nil. -func (h Header) Clone() Header { - if h == nil { - return nil - } - - // Find total number of values. - nv := 0 - for _, vv := range h { - nv += len(vv) - } - sv := make([]string, nv) // shared backing array for headers' values - h2 := make(Header, len(h)) - for k, vv := range h { - n := copy(sv, vv) - h2[k] = sv[:n:n] - sv = sv[n:] - } - return h2 -} - -var timeFormats = []string{ - TimeFormat, - time.RFC850, - time.ANSIC, -} - -// ParseTime parses a time header (such as the Date: header), -// trying each of the three formats allowed by HTTP/1.1: -// TimeFormat, time.RFC850, and time.ANSIC. -func ParseTime(text string) (t time.Time, err error) { - for _, layout := range timeFormats { - t, err = time.Parse(layout, text) - if err == nil { - return - } - } - return -} - -var headerNewlineToSpace = strings.NewReplacer("\n", " ", "\r", " ") - -// stringWriter implements WriteString on a Writer. -type stringWriter struct { - w io.Writer -} - -func (w stringWriter) WriteString(s string) (n int, err error) { - return w.w.Write([]byte(s)) -} - -type keyValues struct { - key string - values []string -} - -// A headerSorter implements sort.Interface by sorting a []keyValues -// by key. It's used as a pointer, so it can fit in a sort.Interface -// interface value without allocation. -type headerSorter struct { - kvs []keyValues -} - -func (s *headerSorter) Len() int { return len(s.kvs) } -func (s *headerSorter) Swap(i, j int) { s.kvs[i], s.kvs[j] = s.kvs[j], s.kvs[i] } -func (s *headerSorter) Less(i, j int) bool { return s.kvs[i].key < s.kvs[j].key } - -var headerSorterPool = sync.Pool{ - New: func() interface{} { return new(headerSorter) }, -} - -// sortedKeyValues returns h's keys sorted in the returned kvs -// slice. The headerSorter used to sort is also returned, for possible -// return to headerSorterCache. -func (h Header) sortedKeyValues(exclude map[string]bool) (kvs []keyValues, hs *headerSorter) { - hs = headerSorterPool.Get().(*headerSorter) - if cap(hs.kvs) < len(h) { - hs.kvs = make([]keyValues, 0, len(h)) - } - kvs = hs.kvs[:0] - for k, vv := range h { - if !exclude[k] { - kvs = append(kvs, keyValues{k, vv}) - } - } - hs.kvs = kvs - sort.Sort(hs) - return kvs, hs -} - -// WriteSubset writes a header in wire format. -// If exclude is not nil, keys where exclude[key] == true are not written. -// Keys are not canonicalized before checking the exclude map. -func (h Header) WriteSubset(w io.Writer, exclude map[string]bool) error { - return h.writeSubset(w, exclude, nil) -} - -func (h Header) writeSubset(w io.Writer, exclude map[string]bool, trace *httptrace.ClientTrace) error { - ws, ok := w.(io.StringWriter) - if !ok { - ws = stringWriter{w} - } - kvs, sorter := h.sortedKeyValues(exclude) - var formattedVals []string - for _, kv := range kvs { - for _, v := range kv.values { - v = headerNewlineToSpace.Replace(v) - v = textproto.TrimString(v) - for _, s := range []string{kv.key, ": ", v, "\r\n"} { - if _, err := ws.WriteString(s); err != nil { - headerSorterPool.Put(sorter) - return err - } - } - if trace != nil && trace.WroteHeaderField != nil { - formattedVals = append(formattedVals, v) - } - } - if trace != nil && trace.WroteHeaderField != nil { - trace.WroteHeaderField(kv.key, formattedVals) - formattedVals = nil - } - } - headerSorterPool.Put(sorter) - return nil -} - -// CanonicalHeaderKey returns the canonical format of the -// header key s. The canonicalization converts the first -// letter and any letter following a hyphen to upper case; -// the rest are converted to lowercase. For example, the -// canonical key for "accept-encoding" is "Accept-Encoding". -// If s contains a space or invalid header field bytes, it is -// returned without modifications. -func CanonicalHeaderKey(s string) string { return textproto.CanonicalMIMEHeaderKey(s) } - -// hasToken reports whether token appears with v, ASCII -// case-insensitive, with space or comma boundaries. -// token must be all lowercase. -// v may contain mixed cased. -func hasToken(v, token string) bool { - if len(token) > len(v) || token == "" { - return false - } - if v == token { - return true - } - for sp := 0; sp <= len(v)-len(token); sp++ { - // Check that first character is good. - // The token is ASCII, so checking only a single byte - // is sufficient. We skip this potential starting - // position if both the first byte and its potential - // ASCII uppercase equivalent (b|0x20) don't match. - // False positives ('^' => '~') are caught by EqualFold. - if b := v[sp]; b != token[0] && b|0x20 != token[0] { - continue - } - // Check that start pos is on a valid token boundary. - if sp > 0 && !isTokenBoundary(v[sp-1]) { - continue - } - // Check that end pos is on a valid token boundary. - if endPos := sp + len(token); endPos != len(v) && !isTokenBoundary(v[endPos]) { - continue - } - if strings.EqualFold(v[sp:sp+len(token)], token) { - return true - } - } - return false -} - -func isTokenBoundary(b byte) bool { - return b == ' ' || b == ',' || b == '\t' -} diff --git a/net/http/http.go b/net/http/http.go deleted file mode 100644 index 926869870..000000000 --- a/net/http/http.go +++ /dev/null @@ -1,162 +0,0 @@ -package http - -import ( - "io" - "strconv" - "strings" - "time" - "unicode/utf8" - - "golang.org/x/net/http/httpguts" -) - -// incomparable is a zero-width, non-comparable type. Adding it to a struct -// makes that struct also non-comparable, and generally doesn't add -// any size (as long as it's first). -type incomparable [0]func() - -// maxInt64 is the effective "infinite" value for the Server and -// Transport's byte-limiting readers. -const maxInt64 = 1<<63 - 1 - -// aLongTimeAgo is a non-zero time, far in the past, used for -// immediate cancellation of network operations. -var aLongTimeAgo = time.Unix(1, 0) - -// omitBundledHTTP2 is set by omithttp2.go when the nethttpomithttp2 -// build tag is set. That means h2_bundle.go isn't compiled in and we -// shouldn't try to use it. -var omitBundledHTTP2 bool - -// TODO(bradfitz): move common stuff here. The other files have accumulated -// generic http stuff in random places. - -// contextKey is a value for use with context.WithValue. It's used as -// a pointer so it fits in an interface{} without allocation. -type contextKey struct { - name string -} - -func (k *contextKey) String() string { return "net/http context value " + k.name } - -// Given a string of the form "host", "host:port", or "[ipv6::address]:port", -// return true if the string includes a port. -func hasPort(s string) bool { return strings.LastIndex(s, ":") > strings.LastIndex(s, "]") } - -// removeEmptyPort strips the empty port in ":port" to "" -// as mandated by RFC 3986 Section 6.2.3. -func removeEmptyPort(host string) string { - if hasPort(host) { - return strings.TrimSuffix(host, ":") - } - return host -} - -func isNotToken(r rune) bool { - return !httpguts.IsTokenRune(r) -} - -func isASCII(s string) bool { - for i := 0; i < len(s); i++ { - if s[i] >= utf8.RuneSelf { - return false - } - } - return true -} - -// stringContainsCTLByte reports whether s contains any ASCII control character. -func stringContainsCTLByte(s string) bool { - for i := 0; i < len(s); i++ { - b := s[i] - if b < ' ' || b == 0x7f { - return true - } - } - return false -} - -func hexEscapeNonASCII(s string) string { - newLen := 0 - for i := 0; i < len(s); i++ { - if s[i] >= utf8.RuneSelf { - newLen += 3 - } else { - newLen++ - } - } - if newLen == len(s) { - return s - } - b := make([]byte, 0, newLen) - for i := 0; i < len(s); i++ { - if s[i] >= utf8.RuneSelf { - b = append(b, '%') - b = strconv.AppendInt(b, int64(s[i]), 16) - } else { - b = append(b, s[i]) - } - } - return string(b) -} - -// NoBody is an io.ReadCloser with no bytes. Read always returns EOF -// and Close always returns nil. It can be used in an outgoing client -// request to explicitly signal that a request has zero bytes. -// An alternative, however, is to simply set Request.Body to nil. -var NoBody = noBody{} - -type noBody struct{} - -func (noBody) Read([]byte) (int, error) { return 0, io.EOF } -func (noBody) Close() error { return nil } -func (noBody) WriteTo(io.Writer) (int64, error) { return 0, nil } - -var ( - // verify that an io.Copy from NoBody won't require a buffer: - _ io.WriterTo = NoBody - _ io.ReadCloser = NoBody -) - -// PushOptions describes options for Pusher.Push. -type PushOptions struct { - // Method specifies the HTTP method for the promised request. - // If set, it must be "GET" or "HEAD". Empty means "GET". - Method string - - // Header specifies additional promised request headers. This cannot - // include HTTP/2 pseudo header fields like ":path" and ":scheme", - // which will be added automatically. - Header Header -} - -// Pusher is the interface implemented by ResponseWriters that support -// HTTP/2 server push. For more background, see -// https://tools.ietf.org/html/rfc7540#section-8.2. -type Pusher interface { - // Push initiates an HTTP/2 server push. This constructs a synthetic - // request using the given target and options, serializes that request - // into a PUSH_PROMISE frame, then dispatches that request using the - // server's request handler. If opts is nil, default options are used. - // - // The target must either be an absolute path (like "/path") or an absolute - // URL that contains a valid host and the same scheme as the parent request. - // If the target is a path, it will inherit the scheme and host of the - // parent request. - // - // The HTTP/2 spec disallows recursive pushes and cross-authority pushes. - // Push may or may not detect these invalid pushes; however, invalid - // pushes will be detected and canceled by conforming clients. - // - // Handlers that wish to push URL X should call Push before sending any - // data that may trigger a request for URL X. This avoids a race where the - // client issues requests for X before receiving the PUSH_PROMISE for X. - // - // Push will run in a separate goroutine making the order of arrival - // non-deterministic. Any required synchronization needs to be implemented - // by the caller. - // - // Push returns ErrNotSupported if the client has disabled push or if push - // is not supported on the underlying connection. - Push(target string, opts *PushOptions) error -} diff --git a/net/http/jar.go b/net/http/jar.go deleted file mode 100644 index 5c3de0dad..000000000 --- a/net/http/jar.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -import ( - "net/url" -) - -// A CookieJar manages storage and use of cookies in HTTP requests. -// -// Implementations of CookieJar must be safe for concurrent use by multiple -// goroutines. -// -// The net/http/cookiejar package provides a CookieJar implementation. -type CookieJar interface { - // SetCookies handles the receipt of the cookies in a reply for the - // given URL. It may or may not choose to save the cookies, depending - // on the jar's policy and implementation. - SetCookies(u *url.URL, cookies []*Cookie) - - // Cookies returns the cookies to send in a request for the given URL. - // It is up to the implementation to honor the standard cookie use - // restrictions such as in RFC 6265. - Cookies(u *url.URL) []*Cookie -} diff --git a/net/http/request.go b/net/http/request.go deleted file mode 100644 index ac67be2b3..000000000 --- a/net/http/request.go +++ /dev/null @@ -1,769 +0,0 @@ -package http - -import ( - "bufio" - "bytes" - "context" - "crypto/tls" - "errors" - "fmt" - "io" - "mime" - "mime/multipart" - "net/textproto" - "net/url" - urlpkg "net/url" - "strconv" - "strings" - "sync" -) - -func badStringError(what, val string) error { return fmt.Errorf("%s %q", what, val) } - -type Request struct { - // Method specifies the HTTP method (GET, POST, PUT, etc.). - // For client requests, an empty string means GET. - // - // Go's HTTP client does not support sending a request with - // the CONNECT method. See the documentation on Transport for - // details. - Method string - - // URL specifies either the URI being requested (for server - // requests) or the URL to access (for client requests). - // - // For server requests, the URL is parsed from the URI - // supplied on the Request-Line as stored in RequestURI. For - // most requests, fields other than Path and RawQuery will be - // empty. (See RFC 7230, Section 5.3) - // - // For client requests, the URL's Host specifies the server to - // connect to, while the Request's Host field optionally - // specifies the Host header value to send in the HTTP - // request. - URL *url.URL - - // The protocol version for incoming server requests. - // - // For client requests, these fields are ignored. The HTTP - // client code always uses either HTTP/1.1 or HTTP/2. - // See the docs on Transport for details. - Proto string // "HTTP/1.0" - ProtoMajor int // 1 - ProtoMinor int // 0 - - // Header contains the request header fields either received - // by the server or to be sent by the client. - // - // If a server received a request with header lines, - // - // Host: example.com - // accept-encoding: gzip, deflate - // Accept-Language: en-us - // fOO: Bar - // foo: two - // - // then - // - // Header = map[string][]string{ - // "Accept-Encoding": {"gzip, deflate"}, - // "Accept-Language": {"en-us"}, - // "Foo": {"Bar", "two"}, - // } - // - // For incoming requests, the Host header is promoted to the - // Request.Host field and removed from the Header map. - // - // HTTP defines that header names are case-insensitive. The - // request parser implements this by using CanonicalHeaderKey, - // making the first character and any characters following a - // hyphen uppercase and the rest lowercase. - // - // For client requests, certain headers such as Content-Length - // and Connection are automatically written when needed and - // values in Header may be ignored. See the documentation - // for the Request.Write method. - Header Header - - // Body is the request's body. - // - // For client requests, a nil body means the request has no - // body, such as a GET request. The HTTP Client's Transport - // is responsible for calling the Close method. - // - // For server requests, the Request Body is always non-nil - // but will return EOF immediately when no body is present. - // The Server will close the request body. The ServeHTTP - // Handler does not need to. - // - // Body must allow Read to be called concurrently with Close. - // In particular, calling Close should unblock a Read waiting - // for input. - Body io.ReadCloser - - // GetBody defines an optional func to return a new copy of - // Body. It is used for client requests when a redirect requires - // reading the body more than once. Use of GetBody still - // requires setting Body. - // - // For server requests, it is unused. - GetBody func() (io.ReadCloser, error) - - // ContentLength records the length of the associated content. - // The value -1 indicates that the length is unknown. - // Values >= 0 indicate that the given number of bytes may - // be read from Body. - // - // For client requests, a value of 0 with a non-nil Body is - // also treated as unknown. - ContentLength int64 - - // TransferEncoding lists the transfer encodings from outermost to - // innermost. An empty list denotes the "identity" encoding. - // TransferEncoding can usually be ignored; chunked encoding is - // automatically added and removed as necessary when sending and - // receiving requests. - TransferEncoding []string - - // Close indicates whether to close the connection after - // replying to this request (for servers) or after sending this - // request and reading its response (for clients). - // - // For server requests, the HTTP server handles this automatically - // and this field is not needed by Handlers. - // - // For client requests, setting this field prevents re-use of - // TCP connections between requests to the same hosts, as if - // Transport.DisableKeepAlives were set. - Close bool - - // For server requests, Host specifies the host on which the - // URL is sought. For HTTP/1 (per RFC 7230, section 5.4), this - // is either the value of the "Host" header or the host name - // given in the URL itself. For HTTP/2, it is the value of the - // ":authority" pseudo-header field. - // It may be of the form "host:port". For international domain - // names, Host may be in Punycode or Unicode form. Use - // golang.org/x/net/idna to convert it to either format if - // needed. - // To prevent DNS rebinding attacks, server Handlers should - // validate that the Host header has a value for which the - // Handler considers itself authoritative. The included - // ServeMux supports patterns registered to particular host - // names and thus protects its registered Handlers. - // - // For client requests, Host optionally overrides the Host - // header to send. If empty, the Request.Write method uses - // the value of URL.Host. Host may contain an international - // domain name. - Host string - - // Form contains the parsed form data, including both the URL - // field's query parameters and the PATCH, POST, or PUT form data. - // This field is only available after ParseForm is called. - // The HTTP client ignores Form and uses Body instead. - Form url.Values - - // PostForm contains the parsed form data from PATCH, POST - // or PUT body parameters. - // - // This field is only available after ParseForm is called. - // The HTTP client ignores PostForm and uses Body instead. - PostForm url.Values - - // MultipartForm is the parsed multipart form, including file uploads. - // This field is only available after ParseMultipartForm is called. - // The HTTP client ignores MultipartForm and uses Body instead. - MultipartForm *multipart.Form - - // Trailer specifies additional headers that are sent after the request - // body. - // - // For server requests, the Trailer map initially contains only the - // trailer keys, with nil values. (The client declares which trailers it - // will later send.) While the handler is reading from Body, it must - // not reference Trailer. After reading from Body returns EOF, Trailer - // can be read again and will contain non-nil values, if they were sent - // by the client. - // - // For client requests, Trailer must be initialized to a map containing - // the trailer keys to later send. The values may be nil or their final - // values. The ContentLength must be 0 or -1, to send a chunked request. - // After the HTTP request is sent the map values can be updated while - // the request body is read. Once the body returns EOF, the caller must - // not mutate Trailer. - // - // Few HTTP clients, servers, or proxies support HTTP trailers. - Trailer Header - - // RemoteAddr allows HTTP servers and other software to record - // the network address that sent the request, usually for - // logging. This field is not filled in by ReadRequest and - // has no defined format. The HTTP server in this package - // sets RemoteAddr to an "IP:port" address before invoking a - // handler. - // This field is ignored by the HTTP client. - RemoteAddr string - - // RequestURI is the unmodified request-target of the - // Request-Line (RFC 7230, Section 3.1.1) as sent by the client - // to a server. Usually the URL field should be used instead. - // It is an error to set this field in an HTTP client request. - RequestURI string - - // TLS allows HTTP servers and other software to record - // information about the TLS connection on which the request - // was received. This field is not filled in by ReadRequest. - // The HTTP server in this package sets the field for - // TLS-enabled connections before invoking a handler; - // otherwise it leaves the field nil. - // This field is ignored by the HTTP client. - TLS *tls.ConnectionState - - // Cancel is an optional channel whose closure indicates that the client - // request should be regarded as canceled. Not all implementations of - // RoundTripper may support Cancel. - // - // For server requests, this field is not applicable. - // - // Deprecated: Set the Request's context with NewRequestWithContext - // instead. If a Request's Cancel field and context are both - // set, it is undefined whether Cancel is respected. - Cancel <-chan struct{} - - // Response is the redirect response which caused this request - // to be created. This field is only populated during client - // redirects. - Response *Response - - // ctx is either the client or server context. It should only - // be modified via copying the whole Request using WithContext. - // It is unexported to prevent people from using Context wrong - // and mutating the contexts held by callers of the same request. - ctx context.Context -} - -// ProtoAtLeast reports whether the HTTP protocol used -// in the request is at least major.minor. -func (r *Request) ProtoAtLeast(major, minor int) bool { - return r.ProtoMajor > major || - r.ProtoMajor == major && r.ProtoMinor >= minor -} - -// UserAgent returns the client's User-Agent, if sent in the request. -func (r *Request) UserAgent() string { - return r.Header.Get("User-Agent") -} - -// Cookies parses and returns the HTTP cookies sent with the request. -func (r *Request) Cookies() []*Cookie { - return readCookies(r.Header, "") -} - -// ErrNoCookie is returned by Request's Cookie method when a cookie is not found. -var ErrNoCookie = errors.New("http: named cookie not present") - -// Cookie returns the named cookie provided in the request or -// ErrNoCookie if not found. -// If multiple cookies match the given name, only one cookie will -// be returned. -func (r *Request) Cookie(name string) (*Cookie, error) { - for _, c := range readCookies(r.Header, name) { - return c, nil - } - return nil, ErrNoCookie -} - -// AddCookie adds a cookie to the request. Per RFC 6265 section 5.4, -// AddCookie does not attach more than one Cookie header field. That -// means all cookies, if any, are written into the same line, -// separated by semicolon. -// AddCookie only sanitizes c's name and value, and does not sanitize -// a Cookie header already present in the request. -func (r *Request) AddCookie(c *Cookie) { - s := fmt.Sprintf("%s=%s", sanitizeCookieName(c.Name), sanitizeCookieValue(c.Value)) - if c := r.Header.Get("Cookie"); c != "" { - r.Header.Set("Cookie", c+"; "+s) - } else { - r.Header.Set("Cookie", s) - } -} - -// Referer returns the referring URL, if sent in the request. -// -// Referer is misspelled as in the request itself, a mistake from the -// earliest days of HTTP. This value can also be fetched from the -// Header map as Header["Referer"]; the benefit of making it available -// as a method is that the compiler can diagnose programs that use the -// alternate (correct English) spelling req.Referrer() but cannot -// diagnose programs that use Header["Referrer"]. -func (r *Request) Referer() string { - return r.Header.Get("Referer") -} - -// isH2Upgrade reports whether r represents the http2 "client preface" -// magic string. -func (r *Request) isH2Upgrade() bool { - return r.Method == "PRI" && len(r.Header) == 0 && r.URL.Path == "*" && r.Proto == "HTTP/2.0" -} - -// ParseHTTPVersion parses an HTTP version string. -// "HTTP/1.0" returns (1, 0, true). -func ParseHTTPVersion(vers string) (major, minor int, ok bool) { - const Big = 1000000 // arbitrary upper bound - switch vers { - case "HTTP/1.1": - return 1, 1, true - case "HTTP/1.0": - return 1, 0, true - } - if !strings.HasPrefix(vers, "HTTP/") { - return 0, 0, false - } - dot := strings.Index(vers, ".") - if dot < 0 { - return 0, 0, false - } - major, err := strconv.Atoi(vers[5:dot]) - if err != nil || major < 0 || major > Big { - return 0, 0, false - } - minor, err = strconv.Atoi(vers[dot+1:]) - if err != nil || minor < 0 || minor > Big { - return 0, 0, false - } - return major, minor, true -} - -func validMethod(method string) bool { - /* - Method = "OPTIONS" ; Section 9.2 - | "GET" ; Section 9.3 - | "HEAD" ; Section 9.4 - | "POST" ; Section 9.5 - | "PUT" ; Section 9.6 - | "DELETE" ; Section 9.7 - | "TRACE" ; Section 9.8 - | "CONNECT" ; Section 9.9 - | extension-method - extension-method = token - token = 1* - */ - return len(method) > 0 && strings.IndexFunc(method, isNotToken) == -1 -} - -// NewRequest wraps NewRequestWithContext using the background context. -func NewRequest(method, url string, body io.Reader) (*Request, error) { - return NewRequestWithContext(context.Background(), method, url, body) -} - -// NewRequestWithContext returns a new Request given a method, URL, and -// optional body. -// -// If the provided body is also an io.Closer, the returned -// Request.Body is set to body and will be closed by the Client -// methods Do, Post, and PostForm, and Transport.RoundTrip. -// -// NewRequestWithContext returns a Request suitable for use with -// Client.Do or Transport.RoundTrip. To create a request for use with -// testing a Server Handler, either use the NewRequest function in the -// net/http/httptest package, use ReadRequest, or manually update the -// Request fields. For an outgoing client request, the context -// controls the entire lifetime of a request and its response: -// obtaining a connection, sending the request, and reading the -// response headers and body. See the Request type's documentation for -// the difference between inbound and outbound request fields. -// -// If body is of type *bytes.Buffer, *bytes.Reader, or -// *strings.Reader, the returned request's ContentLength is set to its -// exact value (instead of -1), GetBody is populated (so 307 and 308 -// redirects can replay the body), and Body is set to NoBody if the -// ContentLength is 0. -func NewRequestWithContext(ctx context.Context, method, url string, body io.Reader) (*Request, error) { - if method == "" { - // We document that "" means "GET" for Request.Method, and people have - // relied on that from NewRequest, so keep that working. - // We still enforce validMethod for non-empty methods. - method = "GET" - } - if !validMethod(method) { - return nil, fmt.Errorf("net/http: invalid method %q", method) - } - if ctx == nil { - return nil, errors.New("net/http: nil Context") - } - u, err := urlpkg.Parse(url) - if err != nil { - return nil, err - } - rc, ok := body.(io.ReadCloser) - if !ok && body != nil { - rc = io.NopCloser(body) - } - // The host's colon:port should be normalized. See Issue 14836. - u.Host = removeEmptyPort(u.Host) - req := &Request{ - ctx: ctx, - Method: method, - URL: u, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Header: make(Header), - Body: rc, - Host: u.Host, - } - if body != nil { - switch v := body.(type) { - case *bytes.Buffer: - req.ContentLength = int64(v.Len()) - buf := v.Bytes() - req.GetBody = func() (io.ReadCloser, error) { - r := bytes.NewReader(buf) - return io.NopCloser(r), nil - } - case *bytes.Reader: - req.ContentLength = int64(v.Len()) - snapshot := *v - req.GetBody = func() (io.ReadCloser, error) { - r := snapshot - return io.NopCloser(&r), nil - } - case *strings.Reader: - req.ContentLength = int64(v.Len()) - snapshot := *v - req.GetBody = func() (io.ReadCloser, error) { - r := snapshot - return io.NopCloser(&r), nil - } - default: - // This is where we'd set it to -1 (at least - // if body != NoBody) to mean unknown, but - // that broke people during the Go 1.8 testing - // period. People depend on it being 0 I - // guess. Maybe retry later. See Issue 18117. - } - // For client requests, Request.ContentLength of 0 - // means either actually 0, or unknown. The only way - // to explicitly say that the ContentLength is zero is - // to set the Body to nil. But turns out too much code - // depends on NewRequest returning a non-nil Body, - // so we use a well-known ReadCloser variable instead - // and have the http package also treat that sentinel - // variable to mean explicitly zero. - if req.GetBody != nil && req.ContentLength == 0 { - req.Body = NoBody - req.GetBody = func() (io.ReadCloser, error) { return NoBody, nil } - } - } - - return req, nil -} - -// parseRequestLine parses "GET /foo HTTP/1.1" into its three parts. -func parseRequestLine(line string) (method, requestURI, proto string, ok bool) { - s1 := strings.Index(line, " ") - s2 := strings.Index(line[s1+1:], " ") - if s1 < 0 || s2 < 0 { - return - } - s2 += s1 + 1 - return line[:s1], line[s1+1 : s2], line[s2+1:], true -} - -var textprotoReaderPool sync.Pool - -func newTextprotoReader(br *bufio.Reader) *textproto.Reader { - if v := textprotoReaderPool.Get(); v != nil { - tr := v.(*textproto.Reader) - tr.R = br - return tr - } - return textproto.NewReader(br) -} - -func putTextprotoReader(r *textproto.Reader) { - r.R = nil - textprotoReaderPool.Put(r) -} - -// ReadRequest reads and parses an incoming request from b. -// -// ReadRequest is a low-level function and should only be used for -// specialized applications; most code should use the Server to read -// requests and handle them via the Handler interface. ReadRequest -// only supports HTTP/1.x requests. For HTTP/2, use golang.org/x/net/http2. -func ReadRequest(b *bufio.Reader) (*Request, error) { - return readRequest(b, deleteHostHeader) -} - -// Constants for readRequest's deleteHostHeader parameter. -const ( - deleteHostHeader = true - keepHostHeader = false -) - -func readRequest(b *bufio.Reader, deleteHostHeader bool) (req *Request, err error) { - tp := newTextprotoReader(b) - req = new(Request) - - // First line: GET /index.html HTTP/1.0 - var s string - if s, err = tp.ReadLine(); err != nil { - return nil, err - } - defer func() { - putTextprotoReader(tp) - if err == io.EOF { - err = io.ErrUnexpectedEOF - } - }() - - var ok bool - req.Method, req.RequestURI, req.Proto, ok = parseRequestLine(s) - if !ok { - return nil, badStringError("malformed HTTP request", s) - } - if !validMethod(req.Method) { - return nil, badStringError("invalid method", req.Method) - } - rawurl := req.RequestURI - if req.ProtoMajor, req.ProtoMinor, ok = ParseHTTPVersion(req.Proto); !ok { - return nil, badStringError("malformed HTTP version", req.Proto) - } - - // CONNECT requests are used two different ways, and neither uses a full URL: - // The standard use is to tunnel HTTPS through an HTTP proxy. - // It looks like "CONNECT www.google.com:443 HTTP/1.1", and the parameter is - // just the authority section of a URL. This information should go in req.URL.Host. - // - // The net/rpc package also uses CONNECT, but there the parameter is a path - // that starts with a slash. It can be parsed with the regular URL parser, - // and the path will end up in req.URL.Path, where it needs to be in order for - // RPC to work. - justAuthority := req.Method == "CONNECT" && !strings.HasPrefix(rawurl, "/") - if justAuthority { - rawurl = "http://" + rawurl - } - - if req.URL, err = url.ParseRequestURI(rawurl); err != nil { - return nil, err - } - - if justAuthority { - // Strip the bogus "http://" back off. - req.URL.Scheme = "" - } - - // Subsequent lines: Key: value. - mimeHeader, err := tp.ReadMIMEHeader() - if err != nil { - return nil, err - } - req.Header = Header(mimeHeader) - - // RFC 7230, section 5.3: Must treat - // GET /index.html HTTP/1.1 - // Host: www.google.com - // and - // GET http://www.google.com/index.html HTTP/1.1 - // Host: doesntmatter - // the same. In the second case, any Host line is ignored. - req.Host = req.URL.Host - if req.Host == "" { - req.Host = req.Header.get("Host") - } - if deleteHostHeader { - delete(req.Header, "Host") - } - - fixPragmaCacheControl(req.Header) - - req.Close = shouldClose(req.ProtoMajor, req.ProtoMinor, req.Header, false) - - err = readTransfer(req, b) - if err != nil { - return nil, err - } - - if req.isH2Upgrade() { - // Because it's neither chunked, nor declared: - req.ContentLength = -1 - - // We want to give handlers a chance to hijack the - // connection, but we need to prevent the Server from - // dealing with the connection further if it's not - // hijacked. Set Close to ensure that: - req.Close = true - } - return req, nil -} - -// MaxBytesReader is similar to io.LimitReader but is intended for -// limiting the size of incoming request bodies. In contrast to -// io.LimitReader, MaxBytesReader's result is a ReadCloser, returns a -// non-EOF error for a Read beyond the limit, and closes the -// underlying reader when its Close method is called. -// -// MaxBytesReader prevents clients from accidentally or maliciously -// sending a large request and wasting server resources. -func MaxBytesReader(w ResponseWriter, r io.ReadCloser, n int64) io.ReadCloser { - return &maxBytesReader{w: w, r: r, n: n} -} - -type maxBytesReader struct { - w ResponseWriter - r io.ReadCloser // underlying reader - n int64 // max bytes remaining - err error // sticky error -} - -func (l *maxBytesReader) Read(p []byte) (n int, err error) { - if l.err != nil { - return 0, l.err - } - if len(p) == 0 { - return 0, nil - } - // If they asked for a 32KB byte read but only 5 bytes are - // remaining, no need to read 32KB. 6 bytes will answer the - // question of the whether we hit the limit or go past it. - if int64(len(p)) > l.n+1 { - p = p[:l.n+1] - } - n, err = l.r.Read(p) - - if int64(n) <= l.n { - l.n -= int64(n) - l.err = err - return n, err - } - - n = int(l.n) - l.n = 0 - - // The server code and client code both use - // maxBytesReader. This "requestTooLarge" check is - // only used by the server code. To prevent binaries - // which only using the HTTP Client code (such as - // cmd/go) from also linking in the HTTP server, don't - // use a static type assertion to the server - // "*response" type. Check this interface instead: - type requestTooLarger interface { - requestTooLarge() - } - if res, ok := l.w.(requestTooLarger); ok { - res.requestTooLarge() - } - l.err = errors.New("http: request body too large") - return n, l.err -} - -func (l *maxBytesReader) Close() error { - return l.r.Close() -} - -func copyValues(dst, src url.Values) { - for k, vs := range src { - dst[k] = append(dst[k], vs...) - } -} - -func parsePostForm(r *Request) (vs url.Values, err error) { - if r.Body == nil { - err = errors.New("missing form body") - return - } - ct := r.Header.Get("Content-Type") - // RFC 7231, section 3.1.1.5 - empty type - // MAY be treated as application/octet-stream - if ct == "" { - ct = "application/octet-stream" - } - ct, _, err = mime.ParseMediaType(ct) - switch { - case ct == "application/x-www-form-urlencoded": - var reader io.Reader = r.Body - maxFormSize := int64(1<<63 - 1) - if _, ok := r.Body.(*maxBytesReader); !ok { - maxFormSize = int64(10 << 20) // 10 MB is a lot of text. - reader = io.LimitReader(r.Body, maxFormSize+1) - } - b, e := io.ReadAll(reader) - if e != nil { - if err == nil { - err = e - } - break - } - if int64(len(b)) > maxFormSize { - err = errors.New("http: POST too large") - return - } - vs, e = url.ParseQuery(string(b)) - if err == nil { - err = e - } - case ct == "multipart/form-data": - // handled by ParseMultipartForm (which is calling us, or should be) - // TODO(bradfitz): there are too many possible - // orders to call too many functions here. - // Clean this up and write more tests. - // request_test.go contains the start of this, - // in TestParseMultipartFormOrder and others. - } - return -} - -// ParseForm populates r.Form and r.PostForm. -// -// For all requests, ParseForm parses the raw query from the URL and updates -// r.Form. -// -// For POST, PUT, and PATCH requests, it also reads the request body, parses it -// as a form and puts the results into both r.PostForm and r.Form. Request body -// parameters take precedence over URL query string values in r.Form. -// -// If the request Body's size has not already been limited by MaxBytesReader, -// the size is capped at 10MB. -// -// For other HTTP methods, or when the Content-Type is not -// application/x-www-form-urlencoded, the request Body is not read, and -// r.PostForm is initialized to a non-nil, empty value. -// -// ParseMultipartForm calls ParseForm automatically. -// ParseForm is idempotent. -func (r *Request) ParseForm() error { - var err error - if r.PostForm == nil { - if r.Method == "POST" || r.Method == "PUT" || r.Method == "PATCH" { - r.PostForm, err = parsePostForm(r) - } - if r.PostForm == nil { - r.PostForm = make(url.Values) - } - } - if r.Form == nil { - if len(r.PostForm) > 0 { - r.Form = make(url.Values) - copyValues(r.Form, r.PostForm) - } - var newValues url.Values - if r.URL != nil { - var e error - newValues, e = url.ParseQuery(r.URL.RawQuery) - if err == nil { - err = e - } - } - if newValues == nil { - newValues = make(url.Values) - } - if r.Form == nil { - r.Form = newValues - } else { - copyValues(r.Form, newValues) - } - } - return err -} diff --git a/net/http/response.go b/net/http/response.go deleted file mode 100644 index 3015e5270..000000000 --- a/net/http/response.go +++ /dev/null @@ -1,120 +0,0 @@ -package http - -import ( - "crypto/tls" - "io" -) - -// Response represents the response from an HTTP request. -// -// The Client and Transport return Responses from servers once -// the response headers have been received. The response body -// is streamed on demand as the Body field is read. -type Response struct { - Status string // e.g. "200 OK" - StatusCode int // e.g. 200 - Proto string // e.g. "HTTP/1.0" - ProtoMajor int // e.g. 1 - ProtoMinor int // e.g. 0 - - // Header maps header keys to values. If the response had multiple - // headers with the same key, they may be concatenated, with comma - // delimiters. (RFC 7230, section 3.2.2 requires that multiple headers - // be semantically equivalent to a comma-delimited sequence.) When - // Header values are duplicated by other fields in this struct (e.g., - // ContentLength, TransferEncoding, Trailer), the field values are - // authoritative. - // - // Keys in the map are canonicalized (see CanonicalHeaderKey). - Header Header - - // Body represents the response body. - // - // The response body is streamed on demand as the Body field - // is read. If the network connection fails or the server - // terminates the response, Body.Read calls return an error. - // - // The http Client and Transport guarantee that Body is always - // non-nil, even on responses without a body or responses with - // a zero-length body. It is the caller's responsibility to - // close Body. The default HTTP client's Transport may not - // reuse HTTP/1.x "keep-alive" TCP connections if the Body is - // not read to completion and closed. - // - // The Body is automatically dechunked if the server replied - // with a "chunked" Transfer-Encoding. - // - // As of Go 1.12, the Body will also implement io.Writer - // on a successful "101 Switching Protocols" response, - // as used by WebSockets and HTTP/2's "h2c" mode. - Body io.ReadCloser - - // ContentLength records the length of the associated content. The - // value -1 indicates that the length is unknown. Unless Request.Method - // is "HEAD", values >= 0 indicate that the given number of bytes may - // be read from Body. - ContentLength int64 - - // Contains transfer encodings from outer-most to inner-most. Value is - // nil, means that "identity" encoding is used. - TransferEncoding []string - - // Close records whether the header directed that the connection be - // closed after reading Body. The value is advice for clients: neither - // ReadResponse nor Response.Write ever closes a connection. - Close bool - - // Uncompressed reports whether the response was sent compressed but - // was decompressed by the http package. When true, reading from - // Body yields the uncompressed content instead of the compressed - // content actually set from the server, ContentLength is set to -1, - // and the "Content-Length" and "Content-Encoding" fields are deleted - // from the responseHeader. To get the original response from - // the server, set Transport.DisableCompression to true. - Uncompressed bool - - // Trailer maps trailer keys to values in the same - // format as Header. - // - // The Trailer initially contains only nil values, one for - // each key specified in the server's "Trailer" header - // value. Those values are not added to Header. - // - // Trailer must not be accessed concurrently with Read calls - // on the Body. - // - // After Body.Read has returned io.EOF, Trailer will contain - // any trailer values sent by the server. - Trailer Header - - // Request is the request that was sent to obtain this Response. - // Request's Body is nil (having already been consumed). - // This is only populated for Client requests. - Request *Request - - // TLS contains information about the TLS connection on which the - // response was received. It is nil for unencrypted responses. - // The pointer is shared between responses and should not be - // modified. - TLS *tls.ConnectionState -} - -// Cookies parses and returns the cookies set in the Set-Cookie headers. -func (r *Response) Cookies() []*Cookie { - return readSetCookies(r.Header) -} - -// RFC 7234, section 5.4: Should treat -// -// Pragma: no-cache -// -// like -// -// Cache-Control: no-cache -func fixPragmaCacheControl(header Header) { - if hp, ok := header["Pragma"]; ok && len(hp) > 0 && hp[0] == "no-cache" { - if _, presentcc := header["Cache-Control"]; !presentcc { - header["Cache-Control"] = []string{"no-cache"} - } - } -} diff --git a/net/http/server.go b/net/http/server.go deleted file mode 100644 index 383d4f2ac..000000000 --- a/net/http/server.go +++ /dev/null @@ -1,581 +0,0 @@ -package http - -import ( - "fmt" - "net" - "net/url" - urlpkg "net/url" - "path" - "sort" - "strings" - "sync" -) - -// A Handler responds to an HTTP request. -// -// ServeHTTP should write reply headers and data to the ResponseWriter -// and then return. Returning signals that the request is finished; it -// is not valid to use the ResponseWriter or read from the -// Request.Body after or concurrently with the completion of the -// ServeHTTP call. -// -// Depending on the HTTP client software, HTTP protocol version, and -// any intermediaries between the client and the Go server, it may not -// be possible to read from the Request.Body after writing to the -// ResponseWriter. Cautious handlers should read the Request.Body -// first, and then reply. -// -// Except for reading the body, handlers should not modify the -// provided Request. -// -// If ServeHTTP panics, the server (the caller of ServeHTTP) assumes -// that the effect of the panic was isolated to the active request. -// It recovers the panic, logs a stack trace to the server error log, -// and either closes the network connection or sends an HTTP/2 -// RST_STREAM, depending on the HTTP protocol. To abort a handler so -// the client sees an interrupted response but the server doesn't log -// an error, panic with the value ErrAbortHandler. -type Handler interface { - ServeHTTP(ResponseWriter, *Request) -} - -// A ResponseWriter interface is used by an HTTP handler to -// construct an HTTP response. -// -// A ResponseWriter may not be used after the Handler.ServeHTTP method -// has returned. -type ResponseWriter interface { - // Header returns the header map that will be sent by - // WriteHeader. The Header map also is the mechanism with which - // Handlers can set HTTP trailers. - // - // Changing the header map after a call to WriteHeader (or - // Write) has no effect unless the modified headers are - // trailers. - // - // There are two ways to set Trailers. The preferred way is to - // predeclare in the headers which trailers you will later - // send by setting the "Trailer" header to the names of the - // trailer keys which will come later. In this case, those - // keys of the Header map are treated as if they were - // trailers. See the example. The second way, for trailer - // keys not known to the Handler until after the first Write, - // is to prefix the Header map keys with the TrailerPrefix - // constant value. See TrailerPrefix. - // - // To suppress automatic response headers (such as "Date"), set - // their value to nil. - Header() Header - - // Write writes the data to the connection as part of an HTTP reply. - // - // If WriteHeader has not yet been called, Write calls - // WriteHeader(http.StatusOK) before writing the data. If the Header - // does not contain a Content-Type line, Write adds a Content-Type set - // to the result of passing the initial 512 bytes of written data to - // DetectContentType. Additionally, if the total size of all written - // data is under a few KB and there are no Flush calls, the - // Content-Length header is added automatically. - // - // Depending on the HTTP protocol version and the client, calling - // Write or WriteHeader may prevent future reads on the - // Request.Body. For HTTP/1.x requests, handlers should read any - // needed request body data before writing the response. Once the - // headers have been flushed (due to either an explicit Flusher.Flush - // call or writing enough data to trigger a flush), the request body - // may be unavailable. For HTTP/2 requests, the Go HTTP server permits - // handlers to continue to read the request body while concurrently - // writing the response. However, such behavior may not be supported - // by all HTTP/2 clients. Handlers should read before writing if - // possible to maximize compatibility. - Write([]byte) (int, error) - - // WriteHeader sends an HTTP response header with the provided - // status code. - // - // If WriteHeader is not called explicitly, the first call to Write - // will trigger an implicit WriteHeader(http.StatusOK). - // Thus explicit calls to WriteHeader are mainly used to - // send error codes. - // - // The provided code must be a valid HTTP 1xx-5xx status code. - // Only one header may be written. Go does not currently - // support sending user-defined 1xx informational headers, - // with the exception of 100-continue response header that the - // Server sends automatically when the Request.Body is read. - WriteHeader(statusCode int) -} - -// TimeFormat is the time format to use when generating times in HTTP -// headers. It is like time.RFC1123 but hard-codes GMT as the time -// zone. The time being formatted must be in UTC for Format to -// generate the correct format. -// -// For parsing this time format, see ParseTime. -const TimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT" - -// The HandlerFunc type is an adapter to allow the use of -// ordinary functions as HTTP handlers. If f is a function -// with the appropriate signature, HandlerFunc(f) is a -// Handler that calls f. -type HandlerFunc func(ResponseWriter, *Request) - -// ServeHTTP calls f(w, r). -func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) { - f(w, r) -} - -// Helper handlers - -// Error replies to the request with the specified error message and HTTP code. -// It does not otherwise end the request; the caller should ensure no further -// writes are done to w. -// The error message should be plain text. -func Error(w ResponseWriter, error string, code int) { - w.Header().Set("Content-Type", "text/plain; charset=utf-8") - w.Header().Set("X-Content-Type-Options", "nosniff") - w.WriteHeader(code) - fmt.Fprintln(w, error) -} - -// NotFound replies to the request with an HTTP 404 not found error. -func NotFound(w ResponseWriter, r *Request) { Error(w, "404 page not found", StatusNotFound) } - -// NotFoundHandler returns a simple request handler -// that replies to each request with a “404 page not found” reply. -func NotFoundHandler() Handler { return HandlerFunc(NotFound) } - -// StripPrefix returns a handler that serves HTTP requests by removing the -// given prefix from the request URL's Path (and RawPath if set) and invoking -// the handler h. StripPrefix handles a request for a path that doesn't begin -// with prefix by replying with an HTTP 404 not found error. The prefix must -// match exactly: if the prefix in the request contains escaped characters -// the reply is also an HTTP 404 not found error. -func StripPrefix(prefix string, h Handler) Handler { - if prefix == "" { - return h - } - return HandlerFunc(func(w ResponseWriter, r *Request) { - p := strings.TrimPrefix(r.URL.Path, prefix) - rp := strings.TrimPrefix(r.URL.RawPath, prefix) - if len(p) < len(r.URL.Path) && (r.URL.RawPath == "" || len(rp) < len(r.URL.RawPath)) { - r2 := new(Request) - *r2 = *r - r2.URL = new(url.URL) - *r2.URL = *r.URL - r2.URL.Path = p - r2.URL.RawPath = rp - h.ServeHTTP(w, r2) - } else { - NotFound(w, r) - } - }) -} - -// Redirect replies to the request with a redirect to url, -// which may be a path relative to the request path. -// -// The provided code should be in the 3xx range and is usually -// StatusMovedPermanently, StatusFound or StatusSeeOther. -// -// If the Content-Type header has not been set, Redirect sets it -// to "text/html; charset=utf-8" and writes a small HTML body. -// Setting the Content-Type header to any value, including nil, -// disables that behavior. -func Redirect(w ResponseWriter, r *Request, url string, code int) { - if u, err := urlpkg.Parse(url); err == nil { - // If url was relative, make its path absolute by - // combining with request path. - // The client would probably do this for us, - // but doing it ourselves is more reliable. - // See RFC 7231, section 7.1.2 - if u.Scheme == "" && u.Host == "" { - oldpath := r.URL.Path - if oldpath == "" { // should not happen, but avoid a crash if it does - oldpath = "/" - } - - // no leading http://server - if url == "" || url[0] != '/' { - // make relative path absolute - olddir, _ := path.Split(oldpath) - url = olddir + url - } - - var query string - if i := strings.Index(url, "?"); i != -1 { - url, query = url[:i], url[i:] - } - - // clean up but preserve trailing slash - trailing := strings.HasSuffix(url, "/") - url = path.Clean(url) - if trailing && !strings.HasSuffix(url, "/") { - url += "/" - } - url += query - } - } - - h := w.Header() - - // RFC 7231 notes that a short HTML body is usually included in - // the response because older user agents may not understand 301/307. - // Do it only if the request didn't already have a Content-Type header. - _, hadCT := h["Content-Type"] - - h.Set("Location", hexEscapeNonASCII(url)) - if !hadCT && (r.Method == "GET" || r.Method == "HEAD") { - h.Set("Content-Type", "text/html; charset=utf-8") - } - w.WriteHeader(code) - - // Shouldn't send the body for POST or HEAD; that leaves GET. - if !hadCT && r.Method == "GET" { - body := "" + statusText[code] + ".\n" - fmt.Fprintln(w, body) - } -} - -var htmlReplacer = strings.NewReplacer( - "&", "&", - "<", "<", - ">", ">", - // """ is shorter than """. - `"`, """, - // "'" is shorter than "'" and apos was not in HTML until HTML5. - "'", "'", -) - -func htmlEscape(s string) string { - return htmlReplacer.Replace(s) -} - -// Redirect to a fixed URL -type redirectHandler struct { - url string - code int -} - -func (rh *redirectHandler) ServeHTTP(w ResponseWriter, r *Request) { - Redirect(w, r, rh.url, rh.code) -} - -// RedirectHandler returns a request handler that redirects -// each request it receives to the given url using the given -// status code. -// -// The provided code should be in the 3xx range and is usually -// StatusMovedPermanently, StatusFound or StatusSeeOther. -func RedirectHandler(url string, code int) Handler { - return &redirectHandler{url, code} -} - -// ServeMux is an HTTP request multiplexer. -// It matches the URL of each incoming request against a list of registered -// patterns and calls the handler for the pattern that -// most closely matches the URL. -// -// Patterns name fixed, rooted paths, like "/favicon.ico", -// or rooted subtrees, like "/images/" (note the trailing slash). -// Longer patterns take precedence over shorter ones, so that -// if there are handlers registered for both "/images/" -// and "/images/thumbnails/", the latter handler will be -// called for paths beginning "/images/thumbnails/" and the -// former will receive requests for any other paths in the -// "/images/" subtree. -// -// Note that since a pattern ending in a slash names a rooted subtree, -// the pattern "/" matches all paths not matched by other registered -// patterns, not just the URL with Path == "/". -// -// If a subtree has been registered and a request is received naming the -// subtree root without its trailing slash, ServeMux redirects that -// request to the subtree root (adding the trailing slash). This behavior can -// be overridden with a separate registration for the path without -// the trailing slash. For example, registering "/images/" causes ServeMux -// to redirect a request for "/images" to "/images/", unless "/images" has -// been registered separately. -// -// Patterns may optionally begin with a host name, restricting matches to -// URLs on that host only. Host-specific patterns take precedence over -// general patterns, so that a handler might register for the two patterns -// "/codesearch" and "codesearch.google.com/" without also taking over -// requests for "http://www.google.com/". -// -// ServeMux also takes care of sanitizing the URL request path and the Host -// header, stripping the port number and redirecting any request containing . or -// .. elements or repeated slashes to an equivalent, cleaner URL. -type ServeMux struct { - mu sync.RWMutex - m map[string]muxEntry - es []muxEntry // slice of entries sorted from longest to shortest. - hosts bool // whether any patterns contain hostnames -} - -type muxEntry struct { - h Handler - pattern string -} - -// NewServeMux allocates and returns a new ServeMux. -func NewServeMux() *ServeMux { return new(ServeMux) } - -// DefaultServeMux is the default ServeMux used by Serve. -var DefaultServeMux = &defaultServeMux - -var defaultServeMux ServeMux - -// cleanPath returns the canonical path for p, eliminating . and .. elements. -func cleanPath(p string) string { - if p == "" { - return "/" - } - if p[0] != '/' { - p = "/" + p - } - np := path.Clean(p) - // path.Clean removes trailing slash except for root; - // put the trailing slash back if necessary. - if p[len(p)-1] == '/' && np != "/" { - // Fast path for common case of p being the string we want: - if len(p) == len(np)+1 && strings.HasPrefix(p, np) { - np = p - } else { - np += "/" - } - } - return np -} - -// stripHostPort returns h without any trailing ":". -func stripHostPort(h string) string { - // If no port on host, return unchanged - if strings.IndexByte(h, ':') == -1 { - return h - } - host, _, err := net.SplitHostPort(h) - if err != nil { - return h // on error, return unchanged - } - return host -} - -// Find a handler on a handler map given a path string. -// Most-specific (longest) pattern wins. -func (mux *ServeMux) match(path string) (h Handler, pattern string) { - // Check for exact match first. - v, ok := mux.m[path] - if ok { - return v.h, v.pattern - } - - // Check for longest valid match. mux.es contains all patterns - // that end in / sorted from longest to shortest. - for _, e := range mux.es { - if strings.HasPrefix(path, e.pattern) { - return e.h, e.pattern - } - } - return nil, "" -} - -// redirectToPathSlash determines if the given path needs appending "/" to it. -// This occurs when a handler for path + "/" was already registered, but -// not for path itself. If the path needs appending to, it creates a new -// URL, setting the path to u.Path + "/" and returning true to indicate so. -func (mux *ServeMux) redirectToPathSlash(host, path string, u *url.URL) (*url.URL, bool) { - mux.mu.RLock() - shouldRedirect := mux.shouldRedirectRLocked(host, path) - mux.mu.RUnlock() - if !shouldRedirect { - return u, false - } - path = path + "/" - u = &url.URL{Path: path, RawQuery: u.RawQuery} - return u, true -} - -// shouldRedirectRLocked reports whether the given path and host should be redirected to -// path+"/". This should happen if a handler is registered for path+"/" but -// not path -- see comments at ServeMux. -func (mux *ServeMux) shouldRedirectRLocked(host, path string) bool { - p := []string{path, host + path} - - for _, c := range p { - if _, exist := mux.m[c]; exist { - return false - } - } - - n := len(path) - if n == 0 { - return false - } - for _, c := range p { - if _, exist := mux.m[c+"/"]; exist { - return path[n-1] != '/' - } - } - - return false -} - -// Handler returns the handler to use for the given request, -// consulting r.Method, r.Host, and r.URL.Path. It always returns -// a non-nil handler. If the path is not in its canonical form, the -// handler will be an internally-generated handler that redirects -// to the canonical path. If the host contains a port, it is ignored -// when matching handlers. -// -// The path and host are used unchanged for CONNECT requests. -// -// Handler also returns the registered pattern that matches the -// request or, in the case of internally-generated redirects, -// the pattern that will match after following the redirect. -// -// If there is no registered handler that applies to the request, -// Handler returns a “page not found” handler and an empty pattern. -func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) { - - // CONNECT requests are not canonicalized. - if r.Method == "CONNECT" { - // If r.URL.Path is /tree and its handler is not registered, - // the /tree -> /tree/ redirect applies to CONNECT requests - // but the path canonicalization does not. - if u, ok := mux.redirectToPathSlash(r.URL.Host, r.URL.Path, r.URL); ok { - return RedirectHandler(u.String(), StatusMovedPermanently), u.Path - } - - return mux.handler(r.Host, r.URL.Path) - } - - // All other requests have any port stripped and path cleaned - // before passing to mux.handler. - host := stripHostPort(r.Host) - path := cleanPath(r.URL.Path) - - // If the given path is /tree and its handler is not registered, - // redirect for /tree/. - if u, ok := mux.redirectToPathSlash(host, path, r.URL); ok { - return RedirectHandler(u.String(), StatusMovedPermanently), u.Path - } - - if path != r.URL.Path { - _, pattern = mux.handler(host, path) - url := *r.URL - url.Path = path - return RedirectHandler(url.String(), StatusMovedPermanently), pattern - } - - return mux.handler(host, r.URL.Path) -} - -// handler is the main implementation of Handler. -// The path is known to be in canonical form, except for CONNECT methods. -func (mux *ServeMux) handler(host, path string) (h Handler, pattern string) { - mux.mu.RLock() - defer mux.mu.RUnlock() - - // Host-specific pattern takes precedence over generic ones - if mux.hosts { - h, pattern = mux.match(host + path) - } - if h == nil { - h, pattern = mux.match(path) - } - if h == nil { - h, pattern = NotFoundHandler(), "" - } - return -} - -// ServeHTTP dispatches the request to the handler whose -// pattern most closely matches the request URL. -func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) { - if r.RequestURI == "*" { - if r.ProtoAtLeast(1, 1) { - w.Header().Set("Connection", "close") - } - w.WriteHeader(StatusBadRequest) - return - } - h, _ := mux.Handler(r) - h.ServeHTTP(w, r) -} - -// Handle registers the handler for the given pattern. -// If a handler already exists for pattern, Handle panics. -func (mux *ServeMux) Handle(pattern string, handler Handler) { - mux.mu.Lock() - defer mux.mu.Unlock() - - if pattern == "" { - panic("http: invalid pattern") - } - if handler == nil { - panic("http: nil handler") - } - if _, exist := mux.m[pattern]; exist { - panic("http: multiple registrations for " + pattern) - } - - if mux.m == nil { - mux.m = make(map[string]muxEntry) - } - e := muxEntry{h: handler, pattern: pattern} - mux.m[pattern] = e - if pattern[len(pattern)-1] == '/' { - mux.es = appendSorted(mux.es, e) - } - - if pattern[0] != '/' { - mux.hosts = true - } -} - -func appendSorted(es []muxEntry, e muxEntry) []muxEntry { - n := len(es) - i := sort.Search(n, func(i int) bool { - return len(es[i].pattern) < len(e.pattern) - }) - if i == n { - return append(es, e) - } - // we now know that i points at where we want to insert - es = append(es, muxEntry{}) // try to grow the slice in place, any entry works. - copy(es[i+1:], es[i:]) // Move shorter entries down - es[i] = e - return es -} - -// HandleFunc registers the handler function for the given pattern. -func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) { - if handler == nil { - panic("http: nil handler") - } - mux.Handle(pattern, HandlerFunc(handler)) -} - -// Handle registers the handler for the given pattern -// in the DefaultServeMux. -// The documentation for ServeMux explains how patterns are matched. -func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) } - -// HandleFunc registers the handler function for the given pattern -// in the DefaultServeMux. -// The documentation for ServeMux explains how patterns are matched. -func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) { - DefaultServeMux.HandleFunc(pattern, handler) -} - -// ListenAndServe listens on the TCP network address addr and then calls -// Serve with handler to handle requests on incoming connections. -// Accepted connections are configured to enable TCP keep-alives. -// -// The handler is typically nil, in which case the DefaultServeMux is used. -// -// ListenAndServe always returns a non-nil error. -func ListenAndServe(addr string, handler Handler) error { - return ActiveDevice.ListenAndServe(addr, handler) -} diff --git a/net/http/status.go b/net/http/status.go deleted file mode 100644 index 286315f63..000000000 --- a/net/http/status.go +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -// HTTP status codes as registered with IANA. -// See: https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml -const ( - StatusContinue = 100 // RFC 7231, 6.2.1 - StatusSwitchingProtocols = 101 // RFC 7231, 6.2.2 - StatusProcessing = 102 // RFC 2518, 10.1 - StatusEarlyHints = 103 // RFC 8297 - - StatusOK = 200 // RFC 7231, 6.3.1 - StatusCreated = 201 // RFC 7231, 6.3.2 - StatusAccepted = 202 // RFC 7231, 6.3.3 - StatusNonAuthoritativeInfo = 203 // RFC 7231, 6.3.4 - StatusNoContent = 204 // RFC 7231, 6.3.5 - StatusResetContent = 205 // RFC 7231, 6.3.6 - StatusPartialContent = 206 // RFC 7233, 4.1 - StatusMultiStatus = 207 // RFC 4918, 11.1 - StatusAlreadyReported = 208 // RFC 5842, 7.1 - StatusIMUsed = 226 // RFC 3229, 10.4.1 - - StatusMultipleChoices = 300 // RFC 7231, 6.4.1 - StatusMovedPermanently = 301 // RFC 7231, 6.4.2 - StatusFound = 302 // RFC 7231, 6.4.3 - StatusSeeOther = 303 // RFC 7231, 6.4.4 - StatusNotModified = 304 // RFC 7232, 4.1 - StatusUseProxy = 305 // RFC 7231, 6.4.5 - _ = 306 // RFC 7231, 6.4.6 (Unused) - StatusTemporaryRedirect = 307 // RFC 7231, 6.4.7 - StatusPermanentRedirect = 308 // RFC 7538, 3 - - StatusBadRequest = 400 // RFC 7231, 6.5.1 - StatusUnauthorized = 401 // RFC 7235, 3.1 - StatusPaymentRequired = 402 // RFC 7231, 6.5.2 - StatusForbidden = 403 // RFC 7231, 6.5.3 - StatusNotFound = 404 // RFC 7231, 6.5.4 - StatusMethodNotAllowed = 405 // RFC 7231, 6.5.5 - StatusNotAcceptable = 406 // RFC 7231, 6.5.6 - StatusProxyAuthRequired = 407 // RFC 7235, 3.2 - StatusRequestTimeout = 408 // RFC 7231, 6.5.7 - StatusConflict = 409 // RFC 7231, 6.5.8 - StatusGone = 410 // RFC 7231, 6.5.9 - StatusLengthRequired = 411 // RFC 7231, 6.5.10 - StatusPreconditionFailed = 412 // RFC 7232, 4.2 - StatusRequestEntityTooLarge = 413 // RFC 7231, 6.5.11 - StatusRequestURITooLong = 414 // RFC 7231, 6.5.12 - StatusUnsupportedMediaType = 415 // RFC 7231, 6.5.13 - StatusRequestedRangeNotSatisfiable = 416 // RFC 7233, 4.4 - StatusExpectationFailed = 417 // RFC 7231, 6.5.14 - StatusTeapot = 418 // RFC 7168, 2.3.3 - StatusMisdirectedRequest = 421 // RFC 7540, 9.1.2 - StatusUnprocessableEntity = 422 // RFC 4918, 11.2 - StatusLocked = 423 // RFC 4918, 11.3 - StatusFailedDependency = 424 // RFC 4918, 11.4 - StatusTooEarly = 425 // RFC 8470, 5.2. - StatusUpgradeRequired = 426 // RFC 7231, 6.5.15 - StatusPreconditionRequired = 428 // RFC 6585, 3 - StatusTooManyRequests = 429 // RFC 6585, 4 - StatusRequestHeaderFieldsTooLarge = 431 // RFC 6585, 5 - StatusUnavailableForLegalReasons = 451 // RFC 7725, 3 - - StatusInternalServerError = 500 // RFC 7231, 6.6.1 - StatusNotImplemented = 501 // RFC 7231, 6.6.2 - StatusBadGateway = 502 // RFC 7231, 6.6.3 - StatusServiceUnavailable = 503 // RFC 7231, 6.6.4 - StatusGatewayTimeout = 504 // RFC 7231, 6.6.5 - StatusHTTPVersionNotSupported = 505 // RFC 7231, 6.6.6 - StatusVariantAlsoNegotiates = 506 // RFC 2295, 8.1 - StatusInsufficientStorage = 507 // RFC 4918, 11.5 - StatusLoopDetected = 508 // RFC 5842, 7.2 - StatusNotExtended = 510 // RFC 2774, 7 - StatusNetworkAuthenticationRequired = 511 // RFC 6585, 6 -) - -var statusText = map[int]string{ - StatusContinue: "Continue", - StatusSwitchingProtocols: "Switching Protocols", - StatusProcessing: "Processing", - StatusEarlyHints: "Early Hints", - - StatusOK: "OK", - StatusCreated: "Created", - StatusAccepted: "Accepted", - StatusNonAuthoritativeInfo: "Non-Authoritative Information", - StatusNoContent: "No Content", - StatusResetContent: "Reset Content", - StatusPartialContent: "Partial Content", - StatusMultiStatus: "Multi-Status", - StatusAlreadyReported: "Already Reported", - StatusIMUsed: "IM Used", - - StatusMultipleChoices: "Multiple Choices", - StatusMovedPermanently: "Moved Permanently", - StatusFound: "Found", - StatusSeeOther: "See Other", - StatusNotModified: "Not Modified", - StatusUseProxy: "Use Proxy", - StatusTemporaryRedirect: "Temporary Redirect", - StatusPermanentRedirect: "Permanent Redirect", - - StatusBadRequest: "Bad Request", - StatusUnauthorized: "Unauthorized", - StatusPaymentRequired: "Payment Required", - StatusForbidden: "Forbidden", - StatusNotFound: "Not Found", - StatusMethodNotAllowed: "Method Not Allowed", - StatusNotAcceptable: "Not Acceptable", - StatusProxyAuthRequired: "Proxy Authentication Required", - StatusRequestTimeout: "Request Timeout", - StatusConflict: "Conflict", - StatusGone: "Gone", - StatusLengthRequired: "Length Required", - StatusPreconditionFailed: "Precondition Failed", - StatusRequestEntityTooLarge: "Request Entity Too Large", - StatusRequestURITooLong: "Request URI Too Long", - StatusUnsupportedMediaType: "Unsupported Media Type", - StatusRequestedRangeNotSatisfiable: "Requested Range Not Satisfiable", - StatusExpectationFailed: "Expectation Failed", - StatusTeapot: "I'm a teapot", - StatusMisdirectedRequest: "Misdirected Request", - StatusUnprocessableEntity: "Unprocessable Entity", - StatusLocked: "Locked", - StatusFailedDependency: "Failed Dependency", - StatusTooEarly: "Too Early", - StatusUpgradeRequired: "Upgrade Required", - StatusPreconditionRequired: "Precondition Required", - StatusTooManyRequests: "Too Many Requests", - StatusRequestHeaderFieldsTooLarge: "Request Header Fields Too Large", - StatusUnavailableForLegalReasons: "Unavailable For Legal Reasons", - - StatusInternalServerError: "Internal Server Error", - StatusNotImplemented: "Not Implemented", - StatusBadGateway: "Bad Gateway", - StatusServiceUnavailable: "Service Unavailable", - StatusGatewayTimeout: "Gateway Timeout", - StatusHTTPVersionNotSupported: "HTTP Version Not Supported", - StatusVariantAlsoNegotiates: "Variant Also Negotiates", - StatusInsufficientStorage: "Insufficient Storage", - StatusLoopDetected: "Loop Detected", - StatusNotExtended: "Not Extended", - StatusNetworkAuthenticationRequired: "Network Authentication Required", -} - -// StatusText returns a text for the HTTP status code. It returns the empty -// string if the code is unknown. -func StatusText(code int) string { - return statusText[code] -} diff --git a/net/http/tinygo.go b/net/http/tinygo.go deleted file mode 100644 index 6ac34495a..000000000 --- a/net/http/tinygo.go +++ /dev/null @@ -1,308 +0,0 @@ -package http - -import ( - "bufio" - "bytes" - "fmt" - "io" - "strconv" - "strings" - "time" - - "tinygo.org/x/drivers/net" - "tinygo.org/x/drivers/net/tls" -) - -var buf []byte - -func SetBuf(b []byte) { - buf = b -} - -func (c *Client) Do(req *Request) (*Response, error) { - if c.Jar != nil { - for _, cookie := range c.Jar.Cookies(req.URL) { - req.AddCookie(cookie) - } - } - switch req.URL.Scheme { - case "http": - return c.doHTTP(req) - case "https": - return c.doHTTPS(req) - default: - return nil, fmt.Errorf("invalid schemer : %s", req.URL.Scheme) - } -} - -func (c *Client) doHTTP(req *Request) (*Response, error) { - // make TCP connection - ip := net.ParseIP(req.URL.Hostname()) - port := 80 - if req.URL.Port() != "" { - p, err := strconv.ParseUint(req.URL.Port(), 0, 64) - if err != nil { - return nil, err - } - port = int(p) - } - raddr := &net.TCPAddr{IP: ip, Port: port} - laddr := &net.TCPAddr{Port: 8080} - - conn, err := net.DialTCP("tcp", laddr, raddr) - retry := 0 - for ; err != nil; conn, err = net.DialTCP("tcp", laddr, raddr) { - retry++ - if retry > 10 { - return nil, fmt.Errorf("Connection failed: %s", err.Error()) - } - time.Sleep(1 * time.Second) - } - - p := req.URL.Path - if p == "" { - p = "/" - } - if req.URL.RawQuery != "" { - p += "?" + req.URL.RawQuery - } - fmt.Fprintln(conn, req.Method+" "+p+" HTTP/1.1") - fmt.Fprintln(conn, "Host:", req.URL.Host) - - if req.Header.get(`User-Agent`) == "" { - fmt.Fprintln(conn, "User-Agent: TinyGo") - } - - for k, v := range req.Header { - if v == nil || len(v) == 0 { - return nil, fmt.Errorf("req.Header error: %s", k) - } - fmt.Fprintln(conn, k+": "+v[0]) - } - - if req.Header.get(`Connection`) == "" { - fmt.Fprintln(conn, "Connection: close") - } - - if req.ContentLength > 0 { - fmt.Fprintf(conn, "Content-Length: %d\n", req.ContentLength) - } - - fmt.Fprintln(conn) - - if req.ContentLength > 0 { - b, err := req.GetBody() - if err != nil { - return nil, err - } - - n, err := b.Read(buf) - if err != nil { - return nil, err - } - conn.Write(buf[:n]) - - b.Close() - - } - - return c.doResp(conn, req) -} - -func (c *Client) doHTTPS(req *Request) (*Response, error) { - conn, err := tls.Dial("tcp", req.URL.Host, nil) - retry := 0 - for ; err != nil; conn, err = tls.Dial("tcp", req.URL.Host, nil) { - retry++ - if retry > 10 { - return nil, fmt.Errorf("Connection failed: %s", err.Error()) - } - time.Sleep(1 * time.Second) - } - - p := req.URL.Path - if p == "" { - p = "/" - } - if req.URL.RawQuery != "" { - p += "?" + req.URL.RawQuery - } - fmt.Fprintln(conn, req.Method+" "+p+" HTTP/1.1") - fmt.Fprintln(conn, "Host:", req.URL.Host) - - if req.Header.get(`User-Agent`) == "" { - fmt.Fprintln(conn, "User-Agent: TinyGo") - } - - for k, v := range req.Header { - if v == nil || len(v) == 0 { - return nil, fmt.Errorf("req.Header error: %s", k) - } - fmt.Fprintln(conn, k+": "+v[0]) - } - - if req.Header.get(`Connection`) == "" { - fmt.Fprintln(conn, "Connection: close") - } - - if req.ContentLength > 0 { - fmt.Fprintf(conn, "Content-Length: %d\n", req.ContentLength) - } - - fmt.Fprintln(conn) - - if req.ContentLength > 0 { - b, err := req.GetBody() - if err != nil { - return nil, err - } - - n, err := b.Read(buf) - if err != nil { - return nil, err - } - conn.Write(buf[:n]) - - b.Close() - - } - - return c.doResp(conn, req) -} - -func (c *Client) doResp(conn net.Conn, req *Request) (*Response, error) { - resp := &Response{ - Header: map[string][]string{}, - } - - // Header - var scanner *bufio.Scanner - cont := true - ofs := 0 - remain := int64(0) - for cont { - for n, err := conn.Read(buf[ofs:]); n > 0; n, err = conn.Read(buf[ofs:]) { - if err != nil { - println("Read error: " + err.Error()) - } else { - // Take care of the case where "\r\n\r\n" is on the boundary of a buffer - start := ofs - if start > 3 { - start -= 3 - } - idx := bytes.Index(buf[start:ofs+n], []byte("\r\n\r\n")) - if idx == -1 { - ofs += n - continue - } - idx += start + 4 - - scanner = bufio.NewScanner(bytes.NewReader(buf[0 : ofs+n])) - if resp.Status == "" && scanner.Scan() { - status := strings.SplitN(scanner.Text(), " ", 2) - if len(status) != 2 { - conn.Close() - return nil, fmt.Errorf("invalid status : %q", scanner.Text()) - } - resp.Proto = status[0] - fmt.Sscanf(status[0], "HTTP/%d.%d", &resp.ProtoMajor, &resp.ProtoMinor) - - resp.Status = status[1] - fmt.Sscanf(status[1], "%d", &resp.StatusCode) - } - - for scanner.Scan() { - text := scanner.Text() - if text == "" { - // end of header - if idx < n+ofs { - ofs = ofs + n - idx - for i := 0; i < ofs; i++ { - buf[i] = buf[i+idx] - } - } else { - ofs = 0 - } - break - } else { - header := strings.SplitN(text, ": ", 2) - if len(header) != 2 { - conn.Close() - return nil, fmt.Errorf("invalid header : %q", text) - } - if resp.Header.Get(header[0]) == "" { - resp.Header.Set(header[0], header[1]) - } else { - resp.Header.Add(header[0], header[1]) - } - - if strings.ToLower(header[0]) == "content-length" { - resp.ContentLength, err = strconv.ParseInt(header[1], 10, 64) - if err != nil { - conn.Close() - return nil, err - } - remain = resp.ContentLength - } - } - } - cont = false - break - } - } - } - - // Body - remain -= int64(ofs) - if remain <= 0 { - resp.Body = io.NopCloser(bytes.NewReader(buf[:ofs])) - if c.Jar != nil { - if rc := resp.Cookies(); len(rc) > 0 { - c.Jar.SetCookies(req.URL, rc) - } - } - return resp, conn.Close() - } - - cont = true - lastRequestTime := time.Now() - for cont { - for { - end := ofs + 0x400 - if len(buf) < end { - return nil, fmt.Errorf("slice out of range : use http.SetBuf() to change the allocation to %d bytes or more", end) - } - n, err := conn.Read(buf[ofs : ofs+0x400]) - if err != nil { - return nil, err - } - if n == 0 { - continue - } - if err != nil { - conn.Close() - return nil, err - } else { - ofs += n - remain -= int64(n) - if remain <= 0 { - resp.Body = io.NopCloser(bytes.NewReader(buf[:ofs])) - cont = false - break - } - if time.Now().Sub(lastRequestTime).Milliseconds() >= 1000 { - conn.Close() - return nil, fmt.Errorf("time out") - } - } - } - } - - if c.Jar != nil { - if rc := resp.Cookies(); len(rc) > 0 { - c.Jar.SetCookies(req.URL, rc) - } - } - - return resp, conn.Close() -} diff --git a/net/http/transefer.go b/net/http/transefer.go deleted file mode 100644 index d9a440621..000000000 --- a/net/http/transefer.go +++ /dev/null @@ -1,34 +0,0 @@ -package http - -import ( - "bufio" - - "golang.org/x/net/http/httpguts" -) - -// msg is *Request or *Response. -func readTransfer(msg *Request, r *bufio.Reader) (err error) { - // TODO: - return nil -} - -// Determine whether to hang up after sending a request and body, or -// receiving a response and body -// 'header' is the request headers -func shouldClose(major, minor int, header Header, removeCloseHeader bool) bool { - if major < 1 { - return true - } - - conv := header["Connection"] - hasClose := httpguts.HeaderValuesContainsToken(conv, "close") - if major == 1 && minor == 0 { - return hasClose || !httpguts.HeaderValuesContainsToken(conv, "keep-alive") - } - - if hasClose && removeCloseHeader { - header.Del("Connection") - } - - return hasClose -} diff --git a/net/ipsocki.go b/net/ipsocki.go deleted file mode 100644 index dfc30c9b2..000000000 --- a/net/ipsocki.go +++ /dev/null @@ -1,26 +0,0 @@ -package net - -import "strings" - -// SplitHostPort splits a network address of the form "host:port", -// "host%zone:port", "[host]:port" or "[host%zone]:port" into host or -// host%zone and port. -// -// A literal IPv6 address in hostport must be enclosed in square -// brackets, as in "[::1]:80", "[::1%lo0]:80". -// -// See func Dial for a description of the hostport parameter, and host -// and port results. -func SplitHostPort(hostport string) (host, port string, err error) { - - if strings.Contains(hostport, ":") { - spl := strings.Split(hostport, ":") - host = spl[0] - port = spl[1] - } else { - host = hostport - port = "80" - } - - return host, port, nil -} diff --git a/net/mqtt/mqtt.go b/net/mqtt/mqtt.go deleted file mode 100644 index c18641ba9..000000000 --- a/net/mqtt/mqtt.go +++ /dev/null @@ -1,396 +0,0 @@ -// Package mqtt is intended to provide compatible interfaces with the -// Paho mqtt library. -package mqtt - -import ( - "errors" - "strings" - "sync" - "time" - - "github.com/eclipse/paho.mqtt.golang/packets" - "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 -// in the provided ClientOptions. The client must have the Connect method called -// on it before it may be used. This is to make sure resources (such as a net -// connection) are created before the application is actually ready. -func NewClient(o *ClientOptions) Client { - c := &mqttclient{opts: o, adaptor: o.Adaptor} - c.msgRouter, c.stopRouter = newRouter() - - c.inboundPacketChan = make(chan packets.ControlPacket, 10) - c.stopInbound = make(chan struct{}) - c.incomingPubChan = make(chan *packets.PublishPacket, 10) - // this launches a goroutine, so only call once per client: - c.msgRouter.matchAndDispatch(c.incomingPubChan, c.opts.Order, c) - return c -} - -type mqttclient struct { - adaptor net.Adapter - conn net.Conn - connected bool - opts *ClientOptions - mid uint16 - inboundPacketChan chan packets.ControlPacket - stopInbound chan struct{} - msgRouter *router - stopRouter chan bool - incomingPubChan chan *packets.PublishPacket - // stats for keepalive - lastReceive time.Time - lastSend time.Time - // keep track of routines and signal a shutdown - workers sync.WaitGroup - shutdown bool -} - -// AddRoute allows you to add a handler for messages on a specific topic -// without making a subscription. For example having a different handler -// for parts of a wildcard subscription -func (c *mqttclient) AddRoute(topic string, callback MessageHandler) { - return -} - -// IsConnected returns a bool signifying whether -// the client is connected or not. -func (c *mqttclient) IsConnected() bool { - return c.connected -} - -// IsConnectionOpen return a bool signifying whether the client has an active -// connection to mqtt broker, i.e not in disconnected or reconnect mode -func (c *mqttclient) IsConnectionOpen() bool { - return c.connected -} - -// Connect will create a connection to the message broker. -func (c *mqttclient) Connect() Token { - if c.IsConnected() { - return &mqtttoken{} - } - var err error - - // make connection - if strings.Contains(c.opts.Servers, "ssl://") { - url := strings.TrimPrefix(c.opts.Servers, "ssl://") - 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 = net.Dial("tcp", url) - if err != nil { - return &mqtttoken{err: err} - } - } else { - // invalid protocol - return &mqtttoken{err: errors.New("invalid protocol")} - } - - c.mid = 1 - - // send the MQTT connect message - connectPkt := packets.NewControlPacket(packets.Connect).(*packets.ConnectPacket) - connectPkt.Qos = 0 - if c.opts.Username != "" { - connectPkt.Username = c.opts.Username - connectPkt.UsernameFlag = true - } - - if c.opts.Password != "" { - connectPkt.Password = []byte(c.opts.Password) - connectPkt.PasswordFlag = true - } - - connectPkt.ClientIdentifier = c.opts.ClientID - connectPkt.ProtocolVersion = byte(c.opts.ProtocolVersion) - connectPkt.ProtocolName = "MQTT" - connectPkt.Keepalive = uint16(c.opts.KeepAlive) - - connectPkt.WillFlag = c.opts.WillEnabled - connectPkt.WillTopic = c.opts.WillTopic - connectPkt.WillMessage = c.opts.WillPayload - connectPkt.WillQos = c.opts.WillQos - connectPkt.WillRetain = c.opts.WillRetained - - err = connectPkt.Write(c.conn) - if err != nil { - return &mqtttoken{err: err} - } - c.lastSend = time.Now() - - // TODO: handle timeout as ReadPacket blocks until it gets a packet. - // CONNECT response. - packet, err := packets.ReadPacket(c.conn) - if err != nil { - return &mqtttoken{err: err} - } - if packet != nil { - ack, ok := packet.(*packets.ConnackPacket) - if ok { - if ack.ReturnCode != 0 { - return &mqtttoken{err: errors.New(packet.String())} - } - c.connected = true - } - } - - go processInbound(c) - go readMessages(c) - go keepAlive(c) - - return &mqtttoken{} -} - -// Disconnect will end the connection with the server, but not before waiting -// the specified number of milliseconds to wait for existing work to be -// completed. Blocks until disconnected. -func (c *mqttclient) Disconnect(quiesce uint) { - c.shutdownRoutines() - // block until all done - for c.connected { - time.Sleep(time.Millisecond * 10) - } - return -} - -// shutdownRoutines will disconnect and shut down all processes. If you want to trigger a -// disconnect internally, make sure you call this instead of Disconnect() to avoid deadlocks -func (c *mqttclient) shutdownRoutines() { - if c.shutdown { - return - } - c.shutdown = true - c.conn.Close() - c.stopInbound <- struct{}{} -} - -// Publish will publish a message with the specified QoS and content -// to the specified topic. -// Returns a token to track delivery of the message to the broker -func (c *mqttclient) Publish(topic string, qos byte, retained bool, payload interface{}) Token { - if !c.IsConnected() { - return &mqtttoken{err: errors.New("MQTT client not connected")} - } - - pub := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket) - pub.Qos = qos - pub.TopicName = topic - pub.Retain = retained - - switch payload.(type) { - case string: - pub.Payload = []byte(payload.(string)) - case []byte: - pub.Payload = payload.([]byte) - default: - return &mqtttoken{err: errors.New("Unknown payload type")} - } - pub.MessageID = c.mid - c.mid++ - - err := pub.Write(c.conn) - if err != nil { - return &mqtttoken{err: err} - } - // update this for every control message that is sent successfully, for keepalive - c.lastSend = time.Now() - - return &mqtttoken{} -} - -// Subscribe starts a new subscription. Provide a MessageHandler to be executed when -// a message is published on the topic provided. -func (c *mqttclient) Subscribe(topic string, qos byte, callback MessageHandler) Token { - if !c.IsConnected() { - return &mqtttoken{err: errors.New("MQTT client not connected")} - } - - sub := packets.NewControlPacket(packets.Subscribe).(*packets.SubscribePacket) - sub.Topics = append(sub.Topics, topic) - sub.Qoss = append(sub.Qoss, qos) - - if callback != nil { - c.msgRouter.addRoute(topic, callback) - } - - sub.MessageID = c.mid - c.mid++ - - // drop in the channel to send - err := sub.Write(c.conn) - if err != nil { - return &mqtttoken{err: err} - } - c.lastSend = time.Now() - - return &mqtttoken{} -} - -// SubscribeMultiple starts a new subscription for multiple topics. Provide a MessageHandler to -// be executed when a message is published on one of the topics provided. -func (c *mqttclient) SubscribeMultiple(filters map[string]byte, callback MessageHandler) Token { - return &mqtttoken{} -} - -// Unsubscribe will end the subscription from each of the topics provided. -// Messages published to those topics from other clients will no longer be -// received. -func (c *mqttclient) Unsubscribe(topics ...string) Token { - return &mqtttoken{} -} - -// OptionsReader returns a ClientOptionsReader which is a copy of the clientoptions -// in use by the client. -func (c *mqttclient) OptionsReader() ClientOptionsReader { - r := ClientOptionsReader{} - return r -} - -func processInbound(c *mqttclient) { -PROCESS: - for { - select { - case msg := <-c.inboundPacketChan: - switch m := msg.(type) { - case *packets.PingrespPacket: - // println("pong") - case *packets.SubackPacket: - // TODO: handle this - case *packets.UnsubackPacket: - // TODO: handle this - case *packets.PublishPacket: - // TODO: handle Qos - c.incomingPubChan <- m - case *packets.PubackPacket: - // TODO: handle this - case *packets.PubrecPacket: - // TODO: handle this - case *packets.PubrelPacket: - // TODO: handle this - case *packets.PubcompPacket: - // TODO: handle this - } - case <-c.stopInbound: - break PROCESS - } - } - - // as this routine could be the last to finish (if a lot of messages are queued in the - // channel), it is the last to turn out the lights - - c.workers.Wait() - c.connected = false - c.shutdown = false -} - -// readMessages reads incoming messages off the wire. -// incoming messages are then send into inbound buffered channel. -func readMessages(c *mqttclient) { - c.workers.Add(1) - defer c.workers.Done() - - var err error - var cp packets.ControlPacket - - for !c.shutdown { - if cp, err = c.ReadPacket(); err != nil { - c.shutdownRoutines() - return - } - if cp != nil { - c.inboundPacketChan <- cp - // notify keepalive logic that we recently received a packet - c.lastReceive = time.Now() - } - - time.Sleep(100 * time.Millisecond) - } -} - -// keepAlive is a goroutine to handle sending ping requests according to the MQTT spec. If the keepalive time has -// been reached with no messages being sent, we will send a ping request and check back to see if we've -// had any activity by the timeout. If not, disconnect. -func keepAlive(c *mqttclient) { - c.workers.Add(1) - defer c.workers.Done() - - var err error - var ping *packets.PingreqPacket - var timeout, pingsent time.Time - - for !c.shutdown { - // As long as we haven't reached the keepalive value... - if time.Since(c.lastSend) < time.Duration(c.opts.KeepAlive)*time.Second { - // ...sleep and check shutdown status again - time.Sleep(time.Millisecond * 100) - continue - } - - // value has been reached, so send a ping request - ping = packets.NewControlPacket(packets.Pingreq).(*packets.PingreqPacket) - if err = ping.Write(c.conn); err != nil { - // if connection is lost, report disconnect - c.shutdownRoutines() - return - } - // println("ping") - - c.lastSend = time.Now() - pingsent = time.Now() - timeout = pingsent.Add(c.opts.PingTimeout) - - // as long as we are still connected and haven't received anything after the ping... - for !c.shutdown && c.lastReceive.Before(pingsent) { - // if the timeout has passed, disconnect - if time.Now().After(timeout) { - c.shutdownRoutines() - return - } - time.Sleep(time.Millisecond * 100) - } - } -} - -func (c *mqttclient) ackFunc(packet *packets.PublishPacket) func() { - return func() { - switch packet.Qos { - case 2: - // pr := packets.NewControlPacket(packets.Pubrec).(*packets.PubrecPacket) - // pr.MessageID = packet.MessageID - // DEBUG.Println(NET, "putting pubrec msg on obound") - // select { - // case c.oboundP <- &PacketAndToken{p: pr, t: nil}: - // case <-c.stop: - // } - // DEBUG.Println(NET, "done putting pubrec msg on obound") - case 1: - // pa := packets.NewControlPacket(packets.Puback).(*packets.PubackPacket) - // pa.MessageID = packet.MessageID - // DEBUG.Println(NET, "putting puback msg on obound") - // persistOutbound(c.persist, pa) - // select { - // case c.oboundP <- &PacketAndToken{p: pa, t: nil}: - // case <-c.stop: - // } - // DEBUG.Println(NET, "done putting puback msg on obound") - case 0: - // do nothing, since there is no need to send an ack packet back - } - } -} - -// ReadPacket tries to read the next incoming packet from the MQTT broker. -// 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 net.ActiveDevice.IsSocketDataAvailable() { - return packets.ReadPacket(c.conn) - } - return nil, nil -} diff --git a/net/mqtt/paho.go b/net/mqtt/paho.go deleted file mode 100644 index ff9c7af52..000000000 --- a/net/mqtt/paho.go +++ /dev/null @@ -1,299 +0,0 @@ -// The following code is a slightly modified version of code taken from the Paho MQTT library. -// It is here until TinyGo can compile the "net" package from the standard library, at which time -// it can be removed. - -/* - * Copyright (c) 2013 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Seth Hoenig - * Allan Stockdill-Mander - * Mike Robertson - */ - -// Portions copyright © 2018 TIBCO Software Inc. - -package mqtt - -import ( - "strings" - "time" - - "github.com/eclipse/paho.mqtt.golang/packets" - "tinygo.org/x/drivers/net" -) - -const ( - disconnected uint32 = iota - connecting - reconnecting - connected -) - -// Client is the interface definition for a Client as used by this -// library, the interface is primarily to allow mocking tests. -// -// It is an MQTT v3.1.1 client for communicating -// with an MQTT server using non-blocking methods that allow work -// to be done in the background. -// An application may connect to an MQTT server using: -// -// A plain TCP socket -// A secure SSL/TLS socket -// A websocket -// -// To enable ensured message delivery at Quality of Service (QoS) levels -// described in the MQTT spec, a message persistence mechanism must be -// used. This is done by providing a type which implements the Store -// interface. For convenience, FileStore and MemoryStore are provided -// implementations that should be sufficient for most use cases. More -// information can be found in their respective documentation. -// Numerous connection options may be specified by configuring a -// and then supplying a ClientOptions type. -type Client interface { - // IsConnected returns a bool signifying whether - // the client is connected or not. - IsConnected() bool - // IsConnectionOpen return a bool signifying wether the client has an active - // connection to mqtt broker, i.e not in disconnected or reconnect mode - IsConnectionOpen() bool - // Connect will create a connection to the message broker, by default - // it will attempt to connect at v3.1.1 and auto retry at v3.1 if that - // fails - Connect() Token - // Disconnect will end the connection with the server, but not before waiting - // the specified number of milliseconds to wait for existing work to be - // completed. - Disconnect(quiesce uint) - // Publish will publish a message with the specified QoS and content - // to the specified topic. - // Returns a token to track delivery of the message to the broker - Publish(topic string, qos byte, retained bool, payload interface{}) Token - // Subscribe starts a new subscription. Provide a MessageHandler to be executed when - // a message is published on the topic provided, or nil for the default handler - Subscribe(topic string, qos byte, callback MessageHandler) Token - // SubscribeMultiple starts a new subscription for multiple topics. Provide a MessageHandler to - // be executed when a message is published on one of the topics provided, or nil for the - // default handler - SubscribeMultiple(filters map[string]byte, callback MessageHandler) Token - // Unsubscribe will end the subscription from each of the topics provided. - // Messages published to those topics from other clients will no longer be - // received. - Unsubscribe(topics ...string) Token - // AddRoute allows you to add a handler for messages on a specific topic - // without making a subscription. For example having a different handler - // for parts of a wildcard subscription - AddRoute(topic string, callback MessageHandler) - // OptionsReader returns a ClientOptionsReader which is a copy of the clientoptions - // in use by the client. - OptionsReader() ClientOptionsReader -} - -// Token defines the interface for the tokens used to indicate when -// actions have completed. -type Token interface { - Wait() bool - WaitTimeout(time.Duration) bool - Error() error -} - -// MessageHandler is a callback type which can be set to be -// executed upon the arrival of messages published to topics -// to which the client is subscribed. -type MessageHandler func(Client, Message) - -// Message defines the externals that a message implementation must support -// these are received messages that are passed to the callbacks, not internal -// messages -type Message interface { - Duplicate() bool - Qos() byte - Retained() bool - Topic() string - MessageID() uint16 - Payload() []byte - Ack() -} - -type message struct { - duplicate bool - qos byte - retained bool - topic string - messageID uint16 - payload []byte - ack func() -} - -func (m *message) Duplicate() bool { - return m.duplicate -} - -func (m *message) Qos() byte { - return m.qos -} - -func (m *message) Retained() bool { - return m.retained -} - -func (m *message) Topic() string { - return m.topic -} - -func (m *message) MessageID() uint16 { - return m.messageID -} - -func (m *message) Payload() []byte { - return m.payload -} - -func (m *message) Ack() { - return -} - -func messageFromPublish(p *packets.PublishPacket, ack func()) Message { - return &message{ - duplicate: p.Dup, - qos: p.Qos, - retained: p.Retain, - topic: p.TopicName, - messageID: p.MessageID, - payload: p.Payload, - ack: ack, - } -} - -// ClientOptionsReader provides an interface for reading ClientOptions after the client has been initialized. -type ClientOptionsReader struct { - options *ClientOptions -} - -// ClientOptions contains configurable options for an MQTT Client. -type ClientOptions struct { - Adaptor net.Adapter - - //Servers []*url.URL - Servers string - ClientID string - Username string - Password string - //CredentialsProvider CredentialsProvider - CleanSession bool - Order bool - WillEnabled bool - WillTopic string - WillPayload []byte - WillQos byte - WillRetained bool - ProtocolVersion uint - protocolVersionExplicit bool - //TLSConfig *tls.Config - KeepAlive int64 - PingTimeout time.Duration - ConnectTimeout time.Duration - MaxReconnectInterval time.Duration - AutoReconnect bool - //Store Store - //DefaultPublishHandler MessageHandler - //OnConnect OnConnectHandler - //OnConnectionLost ConnectionLostHandler - WriteTimeout time.Duration - MessageChannelDepth uint - ResumeSubs bool - //HTTPHeaders http.Header -} - -// NewClientOptions returns a new ClientOptions struct. -func NewClientOptions() *ClientOptions { - return &ClientOptions{Adaptor: net.ActiveDevice, ProtocolVersion: 4, KeepAlive: 60, PingTimeout: time.Second * 10} -} - -// AddBroker adds a broker URI to the list of brokers to be used. The format should be -// scheme://host:port -// Where "scheme" is one of "tcp", "ssl", or "ws", "host" is the ip-address (or hostname) -// and "port" is the port on which the broker is accepting connections. -// -// Default values for hostname is "127.0.0.1", for schema is "tcp://". -// -// An example broker URI would look like: tcp://foobar.com:1883 -func (o *ClientOptions) AddBroker(server string) *ClientOptions { - if len(server) > 0 && server[0] == ':' { - server = "127.0.0.1" + server - } - if !strings.Contains(server, "://") { - server = "tcp://" + server - } - - o.Servers = server - return o -} - -// SetClientID will set the client id to be used by this client when -// connecting to the MQTT broker. According to the MQTT v3.1 specification, -// a client id mus be no longer than 23 characters. -func (o *ClientOptions) SetClientID(id string) *ClientOptions { - o.ClientID = id - return o -} - -// SetUsername will set the username to be used by this client when connecting -// to the MQTT broker. Note: without the use of SSL/TLS, this information will -// be sent in plaintext accross the wire. -func (o *ClientOptions) SetUsername(u string) *ClientOptions { - o.Username = u - return o -} - -// SetPassword will set the password to be used by this client when connecting -// to the MQTT broker. Note: without the use of SSL/TLS, this information will -// be sent in plaintext accross the wire. -func (o *ClientOptions) SetPassword(p string) *ClientOptions { - o.Password = p - return o -} - -// SetKeepAlive will set the amount of time (in seconds) that the client -// should wait before sending a PING request to the broker. This will -// allow the client to know that a connection has not been lost with the -// server. -func (o *ClientOptions) SetKeepAlive(k time.Duration) *ClientOptions { - o.KeepAlive = int64(k / time.Second) - return o -} - -// SetPingTimeout will set the amount of time (in seconds) that the client -// will wait after sending a PING request to the broker, before deciding -// that the connection has been lost. Default is 10 seconds. -func (o *ClientOptions) SetPingTimeout(k time.Duration) *ClientOptions { - o.PingTimeout = k - 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/net/mqtt/router.go b/net/mqtt/router.go deleted file mode 100644 index 7d9b930f1..000000000 --- a/net/mqtt/router.go +++ /dev/null @@ -1,178 +0,0 @@ -// The following code is a slightly modified version of code taken from the Paho MQTT library. -// It is here until TinyGo can compile the "net" package from the standard library, at which time -// it can be removed. - -/* - * Copyright (c) 2013 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Seth Hoenig - * Allan Stockdill-Mander - * Mike Robertson - */ - -package mqtt - -import ( - "container/list" - "strings" - - "github.com/eclipse/paho.mqtt.golang/packets" -) - -// route is a type which associates MQTT Topic strings with a -// callback to be executed upon the arrival of a message associated -// with a subscription to that topic. -type route struct { - topic string - callback MessageHandler -} - -// match takes a slice of strings which represent the route being tested having been split on '/' -// separators, and a slice of strings representing the topic string in the published message, similarly -// split. -// The function determines if the topic string matches the route according to the MQTT topic rules -// and returns a boolean of the outcome -func match(route []string, topic []string) bool { - if len(route) == 0 { - if len(topic) == 0 { - return true - } - return false - } - - if len(topic) == 0 { - if route[0] == "#" { - return true - } - return false - } - - if route[0] == "#" { - return true - } - - if (route[0] == "+") || (route[0] == topic[0]) { - return match(route[1:], topic[1:]) - } - return false -} - -func routeIncludesTopic(route, topic string) bool { - return match(routeSplit(route), strings.Split(topic, "/")) -} - -// removes $share and sharename when splitting the route to allow -// shared subscription routes to correctly match the topic -func routeSplit(route string) []string { - var result []string - if strings.HasPrefix(route, "$share") { - result = strings.Split(route, "/")[2:] - } else { - result = strings.Split(route, "/") - } - return result -} - -// match takes the topic string of the published message and does a basic compare to the -// string of the current Route, if they match it returns true -func (r *route) match(topic string) bool { - return r.topic == topic || routeIncludesTopic(r.topic, topic) -} - -type router struct { - //sync.RWMutex - routes *list.List - defaultHandler MessageHandler - messages chan *packets.PublishPacket - stop chan bool -} - -// newRouter returns a new instance of a Router and channel which can be used to tell the Router -// to stop -func newRouter() (*router, chan bool) { - router := &router{routes: list.New(), messages: make(chan *packets.PublishPacket), stop: make(chan bool)} - stop := router.stop - return router, stop -} - -// addRoute takes a topic string and MessageHandler callback. It looks in the current list of -// routes to see if there is already a matching Route. If there is it replaces the current -// callback with the new one. If not it add a new entry to the list of Routes. -func (r *router) addRoute(topic string, callback MessageHandler) { - for e := r.routes.Front(); e != nil; e = e.Next() { - if e.Value.(*route).match(topic) { - r := e.Value.(*route) - r.callback = callback - return - } - } - r.routes.PushBack(&route{topic: topic, callback: callback}) -} - -// deleteRoute takes a route string, looks for a matching Route in the list of Routes. If -// found it removes the Route from the list. -func (r *router) deleteRoute(topic string) { - for e := r.routes.Front(); e != nil; e = e.Next() { - if e.Value.(*route).match(topic) { - r.routes.Remove(e) - return - } - } -} - -// setDefaultHandler assigns a default callback that will be called if no matching Route -// is found for an incoming Publish. -func (r *router) setDefaultHandler(handler MessageHandler) { - r.defaultHandler = handler -} - -// matchAndDispatch takes a channel of Message pointers as input and starts a go routine that -// takes messages off the channel, matches them against the internal route list and calls the -// associated callback (or the defaultHandler, if one exists and no other route matched). If -// anything is sent down the stop channel the function will end. -func (r *router) matchAndDispatch(messages <-chan *packets.PublishPacket, order bool, client *mqttclient) { - go func() { - for { - select { - case message := <-messages: - sent := false - m := messageFromPublish(message, client.ackFunc(message)) - handlers := []MessageHandler{} - for e := r.routes.Front(); e != nil; e = e.Next() { - if e.Value.(*route).match(message.TopicName) { - if order { - handlers = append(handlers, e.Value.(*route).callback) - } else { - hd := e.Value.(*route).callback - hd(client, m) - //TODO: m.Ack() - } - sent = true - } - } - if !sent && r.defaultHandler != nil { - if order { - handlers = append(handlers, r.defaultHandler) - } else { - r.defaultHandler(client, m) - //TODO: m.Ack() - } - } - for _, handler := range handlers { - func() { - handler(client, m) - //TODO: m.Ack() - }() - } - case <-r.stop: - return - } - } - }() -} diff --git a/net/mqtt/token.go b/net/mqtt/token.go deleted file mode 100644 index f4225ffce..000000000 --- a/net/mqtt/token.go +++ /dev/null @@ -1,19 +0,0 @@ -package mqtt - -import "time" - -type mqtttoken struct { - err error -} - -func (t *mqtttoken) Wait() bool { - return true -} - -func (t *mqtttoken) WaitTimeout(time.Duration) bool { - return true -} - -func (t *mqtttoken) Error() error { - return t.err -} diff --git a/net/net.go b/net/net.go deleted file mode 100644 index 8654820a1..000000000 --- a/net/net.go +++ /dev/null @@ -1,420 +0,0 @@ -// package net is intended to provide compatible interfaces with the -// Go standard library's net package. -package net - -import ( - "errors" - "strconv" - "strings" - "time" -) - -// 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 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 - ActiveDevice.DisconnectSocket() - - // connect new socket - err := ActiveDevice.ConnectUDPSocket(addr, sendport, listenport) - if err != nil { - return nil, err - } - - return &UDPSerialConn{SerialConn: SerialConn{Adaptor: ActiveDevice}, laddr: laddr, raddr: raddr}, nil -} - -// ListenUDP listens for UDP connections on the port listed in laddr. -func ListenUDP(network string, laddr *UDPAddr) (*UDPSerialConn, error) { - addr := "0" - sendport := "0" - listenport := strconv.Itoa(laddr.Port) - - // disconnect any old socket - ActiveDevice.DisconnectSocket() - - // connect new socket - err := ActiveDevice.ConnectUDPSocket(addr, sendport, listenport) - if err != nil { - return nil, err - } - - return &UDPSerialConn{SerialConn: SerialConn{Adaptor: 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 DialTCP(network string, laddr, raddr *TCPAddr) (*TCPSerialConn, error) { - addr := raddr.IP.String() - sendport := strconv.Itoa(raddr.Port) - - // disconnect any old socket? - //ActiveDevice.DisconnectSocket() - - // connect new socket - err := ActiveDevice.ConnectTCPSocket(addr, sendport) - if err != nil { - return nil, err - } - - return &TCPSerialConn{SerialConn: SerialConn{Adaptor: 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 Dial(network, address string) (Conn, error) { - switch network { - case "tcp": - raddr, err := ResolveTCPAddr(network, address) - if err != nil { - return nil, err - } - - c, e := DialTCP(network, &TCPAddr{}, raddr) - return c.opConn(), e - case "udp": - raddr, err := ResolveUDPAddr(network, address) - if err != nil { - return nil, err - } - - c, e := DialUDP(network, &UDPAddr{}, raddr) - return c.opConn(), e - default: - return nil, errors.New("invalid network for dial") - } -} - -// SerialConn is a loosely net.Conn compatible implementation -type SerialConn struct { - Adaptor Adapter -} - -// UDPSerialConn is a loosely net.Conn compatible intended to support -// UDP over serial. -type UDPSerialConn struct { - SerialConn - laddr *UDPAddr - 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 { - SerialConn - laddr *TCPAddr - 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 -// after a fixed time limit; see SetDeadline and SetReadDeadline. -func (c *SerialConn) Read(b []byte) (n int, err error) { - // read only the data that has been received via "+IPD" socket - return c.Adaptor.ReadSocket(b) -} - -// Write writes data to the connection. -// TODO: implement the full method functionality for timeouts. -// Write can be made to time out and return an Error with Timeout() == true -// after a fixed time limit; see SetDeadline and SetWriteDeadline. -func (c *SerialConn) Write(b []byte) (n int, err error) { - // specify that is a data transfer to the - // currently open socket, not commands to the ESP8266/ESP32. - err = c.Adaptor.StartSocketSend(len(b)) - if err != nil { - return - } - n, err = c.Adaptor.Write(b) - 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 - } - return n, err -} - -// Close closes the connection. -// Currently only supports a single Read or Write operations without blocking. -func (c *SerialConn) Close() error { - c.Adaptor.DisconnectSocket() - return nil -} - -// LocalAddr returns the local network address. -func (c *UDPSerialConn) LocalAddr() Addr { - return c.laddr.opAddr() -} - -// RemoteAddr returns the remote network address. -func (c *UDPSerialConn) RemoteAddr() Addr { - return c.raddr.opAddr() -} - -func (c *UDPSerialConn) opConn() Conn { - if c == nil { - return nil - } - return c -} - -// LocalAddr returns the local network address. -func (c *TCPSerialConn) LocalAddr() Addr { - return c.laddr.opAddr() -} - -// RemoteAddr returns the remote network address. -func (c *TCPSerialConn) RemoteAddr() Addr { - return c.raddr.opAddr() -} - -func (c *TCPSerialConn) opConn() Conn { - if c == nil { - return nil - } - return c -} - -// SetDeadline sets the read and write deadlines associated -// with the connection. It is equivalent to calling both -// SetReadDeadline and SetWriteDeadline. -// -// A deadline is an absolute time after which I/O operations -// fail with a timeout (see type Error) instead of -// blocking. The deadline applies to all future and pending -// I/O, not just the immediately following call to Read or -// Write. After a deadline has been exceeded, the connection -// can be refreshed by setting a deadline in the future. -// -// An idle timeout can be implemented by repeatedly extending -// the deadline after successful Read or Write calls. -// -// A zero value for t means I/O operations will not time out. -func (c *SerialConn) SetDeadline(t time.Time) error { - return nil -} - -// SetReadDeadline sets the deadline for future Read calls -// and any currently-blocked Read call. -// A zero value for t means Read will not time out. -func (c *SerialConn) SetReadDeadline(t time.Time) error { - return nil -} - -// SetWriteDeadline sets the deadline for future Write calls -// and any currently-blocked Write call. -// Even if write times out, it may return n > 0, indicating that -// some of the data was successfully written. -// A zero value for t means Write will not time out. -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 ResolveTCPAddr(network, address string) (*TCPAddr, error) { - // TODO: make sure network is 'tcp' - // separate domain from port, if any - r := strings.Split(address, ":") - addr, err := 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 { - 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 ResolveUDPAddr(network, address string) (*UDPAddr, error) { - // TODO: make sure network is 'udp' - // separate domain from port, if any - r := strings.Split(address, ":") - addr, err := 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 { - 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. - -// IP is an IP address. Unlike the standard implementation, it is only -// a buffer of bytes that contains the string form of the IP address, not the -// full byte format used by the Go standard . -type IP []byte - -// UDPAddr here to serve as compatible type. until TinyGo can compile the net package. -type UDPAddr struct { - IP IP - Port int - Zone string // IPv6 scoped addressing zone; added in Go 1.1 -} - -// Network returns the address's network name, "udp". -func (a *UDPAddr) Network() string { return "udp" } - -func (a *UDPAddr) String() string { - if a == nil { - return "" - } - if a.Port != 0 { - return a.IP.String() + ":" + strconv.Itoa(a.Port) - } - return a.IP.String() -} - -func (a *UDPAddr) opAddr() Addr { - if a == nil { - return nil - } - return a -} - -// TCPAddr here to serve as compatible type. until TinyGo can compile the net package. -type TCPAddr struct { - IP IP - Port int - Zone string // IPv6 scoped addressing zone -} - -// Network returns the address's network name, "tcp". -func (a *TCPAddr) Network() string { return "tcp" } - -func (a *TCPAddr) String() string { - if a == nil { - return "" - } - if a.Port != 0 { - return a.IP.String() + ":" + strconv.Itoa(a.Port) - } - return a.IP.String() -} - -func (a *TCPAddr) opAddr() Addr { - if a == nil { - return nil - } - return a -} - -// ParseIP parses s as an IP address, returning the result. -func ParseIP(s string) IP { - b := strings.Split(s, ".") - if len(b) == 4 { - ip := make([]byte, 4) - - for i := range ip { - x, _ := strconv.ParseUint(b[i], 10, 8) - ip[i] = byte(x) - } - - return IP(ip) - } - - return IP([]byte(s)) -} - -// String returns the string form of the IP address ip. -func (ip IP) String() string { - return string(ip) -} - -// Conn is a generic stream-oriented network connection. -// This interface is from the Go standard library. -type Conn interface { - // Read reads data from the connection. - // Read can be made to time out and return an Error with Timeout() == true - // after a fixed time limit; see SetDeadline and SetReadDeadline. - Read(b []byte) (n int, err error) - - // Write writes data to the connection. - // Write can be made to time out and return an Error with Timeout() == true - // after a fixed time limit; see SetDeadline and SetWriteDeadline. - Write(b []byte) (n int, err error) - - // Close closes the connection. - // Any blocked Read or Write operations will be unblocked and return errors. - Close() error - - // LocalAddr returns the local network address. - LocalAddr() Addr - - // RemoteAddr returns the remote network address. - RemoteAddr() Addr - - // SetDeadline sets the read and write deadlines associated - // with the connection. It is equivalent to calling both - // SetReadDeadline and SetWriteDeadline. - // - // A deadline is an absolute time after which I/O operations - // fail with a timeout (see type Error) instead of - // blocking. The deadline applies to all future and pending - // I/O, not just the immediately following call to Read or - // Write. After a deadline has been exceeded, the connection - // can be refreshed by setting a deadline in the future. - // - // An idle timeout can be implemented by repeatedly extending - // the deadline after successful Read or Write calls. - // - // A zero value for t means I/O operations will not time out. - SetDeadline(t time.Time) error - - // SetReadDeadline sets the deadline for future Read calls - // and any currently-blocked Read call. - // A zero value for t means Read will not time out. - SetReadDeadline(t time.Time) error - - // SetWriteDeadline sets the deadline for future Write calls - // and any currently-blocked Write call. - // Even if write times out, it may return n > 0, indicating that - // some of the data was successfully written. - // A zero value for t means Write will not time out. - SetWriteDeadline(t time.Time) error -} - -// Addr represents a network end point address. -type Addr interface { - Network() string // name of the network (for example, "tcp", "udp") - String() string // string form of address (for example, "192.0.2.1:25", "[2001:db8::1]:80") -} diff --git a/net/tls/tls.go b/net/tls/tls.go deleted file mode 100644 index 12ba037ea..000000000 --- a/net/tls/tls.go +++ /dev/null @@ -1,42 +0,0 @@ -// Package tls is intended to provide a minimal set of compatible interfaces with the -// Go standard library's tls package. -package tls - -import ( - "strconv" - "strings" - - "tinygo.org/x/drivers/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 - } - - hostname := strings.Split(address, ":")[0] - sendport := strconv.Itoa(raddr.Port) - if sendport == "0" { - sendport = "443" - } - - // disconnect any old socket - net.ActiveDevice.DisconnectSocket() - - // connect new socket - err = net.ActiveDevice.ConnectSSLSocket(hostname, sendport) - if err != nil { - return nil, err - } - - return net.NewTCPSerialConn(net.SerialConn{Adaptor: net.ActiveDevice}, nil, raddr), nil -} - -// Config is a placeholder for future compatibility with -// tls.Config. -type Config struct { -} diff --git a/netdev/README.md b/netdev/README.md new file mode 100644 index 000000000..96ce8515a --- /dev/null +++ b/netdev/README.md @@ -0,0 +1,78 @@ +### Table of Contents + +- [Netdever](#netdever) +- [Netdev Driver](#netdev-driver) +- [Netdev Driver Notes](#netdev-driver-notes) + +## Netdever + +TinyGo's network device driver model comprises two Go interfaces: Netdever and +Netlinker. This README covers Netdever. + +The Netdever interface describes an L4/L3 network interface modeled after the +BSD sockets. A netdev is a concrete implementation of a Netdever. See +[Netlinker](../netlink/) for the L2 network interface. + +A netdev can: + +- Send and receive L4/L3 packets +- Resolve DNS lookups +- Get/set the device's IP address + +TinyGo network drivers implement the Netdever interface, providing a BSD +sockets interface to TinyGo's "net" package. net.Conn implementations +(TCPConn, UDPConn, and TLSConn) use the netdev socket. For example, +net.DialTCP, which returns a net.TCPConn, calls netdev.Socket() and +netdev.Connect(): + +```go +func DialTCP(network string, laddr, raddr *TCPAddr) (*TCPConn, error) { + + fd, _ := netdev.Socket(netdev.AF_INET, netdev.SOCK_STREAM, netdev.IPPROTO_TCP) + + netdev.Connect(fd, "", raddr.IP, raddr.Port) + + return &TCPConn{ + fd: fd, + laddr: laddr, + raddr: raddr, + }, nil +} +``` + +## Setting Netdev + +Before the app can use TinyGo's "net" package, the app must set the netdev +using UseNetdev(). This binds the "net" package to the netdev driver. For +example, setting the wifinina driver as the netdev: + +``` + nina := wifinina.New(&cfg) + netdev.UseNetdev(nina) +``` + +## Netdev Driver Notes + +See the wifinina and rtl8720dn for examples of netdev drivers. Here are some +notes for netdev drivers. + +#### Locking + +Multiple goroutines may invoke methods on a net.Conn simultaneously, and since +the net package translates net.Conn calls into netdev socket calls, it follows +that multiple goroutines may invoke socket calls, so locking is required to +keep socket calls from stepping on one another. + +Don't hold a lock while Time.Sleep()ing waiting for a long hardware operation to +finish. Unlocking while sleeping let's other goroutines make progress. + +#### Sockfd + +The netdev BSD socket interface uses a socket fd (int) to represent a socket +connection (end-point). Each fd maps 1:1 to a net.Conn maps. The number of fds +available is a hardware limitation. Wifinina, for example, can hand out 10 +fds, representing 10 active sockets. + +#### Testing + +The netdev driver should minimally run all of the example/net examples. diff --git a/netdev/netdev.go b/netdev/netdev.go new file mode 100644 index 000000000..cf07c07d4 --- /dev/null +++ b/netdev/netdev.go @@ -0,0 +1,89 @@ +// L3/L4 network/transport layer + +package netdev + +import ( + "errors" + "net" + "time" + _ "unsafe" // to use go:linkname +) + +const ( + AF_INET = 0x2 + SOCK_STREAM = 0x1 + SOCK_DGRAM = 0x2 + SOL_SOCKET = 0x1 + SO_KEEPALIVE = 0x9 + SOL_TCP = 0x6 + TCP_KEEPINTVL = 0x5 + IPPROTO_TCP = 0x6 + IPPROTO_UDP = 0x11 + // Made up, not a real IP protocol number. This is used to create a + // TLS socket on the device, assuming the device supports mbed TLS. + IPPROTO_TLS = 0xFE + F_SETFL = 0x4 +) + +// GethostByName() errors +var ( + ErrHostUnknown = errors.New("Host unknown") +) + +// Socket errors +var ( + ErrFamilyNotSupported = errors.New("Address family not supported") + ErrProtocolNotSupported = errors.New("Socket protocol/type not supported") + ErrStartingDHCPClient = errors.New("Error starting DHPC client") + ErrNoMoreSockets = errors.New("No more sockets") + ErrClosingSocket = errors.New("Error closing socket") + ErrNotSupported = errors.New("Not supported") +) + +// Duplicate of non-exported net.errTimeout +var ErrTimeout error = &timeoutError{} + +type timeoutError struct{} + +func (e *timeoutError) Error() string { return "i/o timeout" } +func (e *timeoutError) Timeout() bool { return true } +func (e *timeoutError) Temporary() bool { return true } + +//go:linkname UseNetdev net.useNetdev +func UseNetdev(dev Netdever) + +// Netdever is TinyGo's OSI L3/L4 network/transport layer interface. Network +// drivers implement the Netdever interface, providing a common network L3/L4 +// interface to TinyGo's "net" package. net.Conn implementations (TCPConn, +// UDPConn, and TLSConn) use the Netdever interface for device I/O access. +// +// A Netdever is passed to the "net" package using UseNetdev(). +// +// Just like a net.Conn, multiple goroutines may invoke methods on a Netdever +// simultaneously. +// +// NOTE: The Netdever interface is mirrored in tinygo/src/net/netdev.go. +// NOTE: If making changes to this interface, mirror the changes in +// NOTE: tinygo/src/net/netdev.go, and vice-versa. + +type Netdever interface { + + // GetHostByName returns the IP address of either a hostname or IPv4 + // address in standard dot notation + GetHostByName(name string) (net.IP, error) + + // GetIPAddr returns IP address assigned to the interface, either by + // DHCP or statically + GetIPAddr() (net.IP, error) + + // Berkely Sockets-like interface, Go-ified. See man page for socket(2), etc. + Socket(domain int, stype int, protocol int) (int, error) + Bind(sockfd int, ip net.IP, port int) error + Connect(sockfd int, host string, ip net.IP, port int) error + Listen(sockfd int, backlog int) error + Accept(sockfd int, ip net.IP, port int) (int, error) + Send(sockfd int, buf []byte, flags int, deadline time.Time) (int, error) + Recv(sockfd int, buf []byte, flags int, deadline time.Time) (int, error) + Close(sockfd int) error + SetSockOpt(sockfd int, level int, opt int, value interface{}) error +} diff --git a/netlink/README.md b/netlink/README.md new file mode 100644 index 000000000..cfe57f0ac --- /dev/null +++ b/netlink/README.md @@ -0,0 +1,19 @@ +### Table of Contents + +- [Netlinker](#netlinker) + +## Netlinker + +TinyGo's network device driver model comprises two Go interfaces: Netdever and +Netlinker. This README covers Netlinker. + +The Netlinker interface describes an L2 network interface. A netlink is a +concrete implementation of a Netlinker. See [Netdev](../netdev/) for +the L4/L3 network interface. + +A netlink can: + +- Connect/disconnect device to/from network +- Notify of network events (e.g. link UP/DOWN) +- Send and receive Ethernet packets +- Get/set device's hardware address (MAC address) diff --git a/netlink/netlink.go b/netlink/netlink.go new file mode 100644 index 000000000..9cb0ee55b --- /dev/null +++ b/netlink/netlink.go @@ -0,0 +1,101 @@ +// L2 data link layer + +package netlink + +import ( + "errors" + "net" + "time" +) + +var ( + ErrConnected = errors.New("Already connected") + ErrConnectFailed = errors.New("Connect failed") + ErrConnectTimeout = errors.New("Connect timed out") + ErrMissingSSID = errors.New("Missing WiFi SSID") + ErrAuthFailure = errors.New("Wifi authentication failure") + ErrAuthTypeNoGood = errors.New("Wifi authorization type not supported") + ErrConnectModeNoGood = errors.New("Connect mode not supported") + ErrNotSupported = errors.New("Not supported") +) + +type Event int + +// Network events +const ( + // The device's network connection is now UP + EventNetUp Event = iota + // The device's network connection is now DOWN + EventNetDown +) + +type ConnectMode int + +// Connect modes +const ( + ConnectModeSTA = iota // Connect as Wifi station (default) + ConnectModeAP // Connect as Wifi Access Point +) + +type AuthType int + +// Wifi authorization types. Used when setting up an access point, or +// connecting to an access point +const ( + AuthTypeWPA2 = iota // WPA2 authorization (default) + AuthTypeOpen // No authorization required (open) + AuthTypeWPA // WPA authorization + AuthTypeWPA2Mixed // WPA2/WPA mixed authorization +) + +const DefaultConnectTimeout = 10 * time.Second + +type ConnectParams struct { + + // Connect mode + ConnectMode + + // SSID of Wifi AP + Ssid string + + // Passphrase of Wifi AP + Passphrase string + + // Wifi authorization type + AuthType + + // Wifi country code as two-char string. E.g. "XX" for world-wide, + // "US" for USA, etc. + Country string + + // Retries is how many attempts to connect before returning with a + // "Connect failed" error. Zero means infinite retries. + Retries int + + // Timeout duration for each connection attempt. The default zero + // value means 10sec. + ConnectTimeout time.Duration + + // Watchdog ticker duration. On tick, the watchdog will check for + // downed connection or hardware fault and try to recover the + // connection. Set to zero to disable watchodog. + WatchdogTimeout time.Duration +} + +// Netlinker is TinyGo's OSI L2 data link layer interface. Network device +// drivers implement Netlinker to expose the device's L2 functionality. + +type Netlinker interface { + + // Connect device to network + NetConnect(params *ConnectParams) error + + // Disconnect device from network + NetDisconnect() + + // Notify to register callback for network events + NetNotify(cb func(Event)) + + // GetHardwareAddr returns device MAC address + GetHardwareAddr() (net.HardwareAddr, error) +} diff --git a/netlink/probe/espat.go b/netlink/probe/espat.go new file mode 100644 index 000000000..ead122a60 --- /dev/null +++ b/netlink/probe/espat.go @@ -0,0 +1,26 @@ +//go:build challenger_rp2040 + +package probe + +import ( + "machine" + + "tinygo.org/x/drivers/espat" + "tinygo.org/x/drivers/netdev" + "tinygo.org/x/drivers/netlink" +) + +func Probe() (netlink.Netlinker, netdev.Netdever) { + + cfg := espat.Config{ + // UART + Uart: machine.UART1, + Tx: machine.UART1_TX_PIN, + Rx: machine.UART1_RX_PIN, + } + + esp := espat.NewDevice(&cfg) + netdev.UseNetdev(esp) + + return esp, esp +} diff --git a/netlink/probe/mrkwifi1010.go b/netlink/probe/mrkwifi1010.go new file mode 100644 index 000000000..e33e3d1ae --- /dev/null +++ b/netlink/probe/mrkwifi1010.go @@ -0,0 +1,35 @@ +//go:build arduino_mkrwifi1010 + +package probe + +import ( + "machine" + + "tinygo.org/x/drivers/netdev" + "tinygo.org/x/drivers/netlink" + "tinygo.org/x/drivers/wifinina" +) + +func Probe() (netlink.Netlinker, netdev.Netdever) { + + cfg := wifinina.Config{ + // Configure SPI for 8Mhz, Mode 0, MSB First + Spi: machine.NINA_SPI, + Freq: 8 * 1e6, + Sdo: machine.NINA_SDO, + Sdi: machine.NINA_SDI, + Sck: machine.NINA_SCK, + // Device pins + Cs: machine.NINA_CS, + Ack: machine.NINA_ACK, + Gpio0: machine.NINA_GPIO0, + Resetn: machine.NINA_RESETN, + // mMKR 1010 resets High + ResetIsHigh: true, + } + + nina := wifinina.New(&cfg) + netdev.UseNetdev(nina) + + return nina, nina +} diff --git a/netlink/probe/rtl8720dn.go b/netlink/probe/rtl8720dn.go new file mode 100644 index 000000000..09e5ce9d6 --- /dev/null +++ b/netlink/probe/rtl8720dn.go @@ -0,0 +1,29 @@ +//go:build wioterminal + +package probe + +import ( + "machine" + + "tinygo.org/x/drivers/netdev" + "tinygo.org/x/drivers/netlink" + "tinygo.org/x/drivers/rtl8720dn" +) + +func Probe() (netlink.Netlinker, netdev.Netdever) { + + cfg := rtl8720dn.Config{ + // Device + En: machine.RTL8720D_CHIP_PU, + // UART + Uart: machine.UART3, + Tx: machine.PB24, + Rx: machine.PC24, + Baudrate: 614400, + } + + rtl := rtl8720dn.New(&cfg) + netdev.UseNetdev(rtl) + + return rtl, rtl +} diff --git a/netlink/probe/wifinina.go b/netlink/probe/wifinina.go new file mode 100644 index 000000000..bae964767 --- /dev/null +++ b/netlink/probe/wifinina.go @@ -0,0 +1,33 @@ +//go:build pyportal || arduino_nano33 || nano_rp2040 || metro_m4_airlift || matrixportal_m4 + +package probe + +import ( + "machine" + + "tinygo.org/x/drivers/netdev" + "tinygo.org/x/drivers/netlink" + "tinygo.org/x/drivers/wifinina" +) + +func Probe() (netlink.Netlinker, netdev.Netdever) { + + cfg := wifinina.Config{ + // Configure SPI for 8Mhz, Mode 0, MSB First + Spi: machine.NINA_SPI, + Freq: 8 * 1e6, + Sdo: machine.NINA_SDO, + Sdi: machine.NINA_SDI, + Sck: machine.NINA_SCK, + // Device pins + Cs: machine.NINA_CS, + Ack: machine.NINA_ACK, + Gpio0: machine.NINA_GPIO0, + Resetn: machine.NINA_RESETN, + } + + nina := wifinina.New(&cfg) + netdev.UseNetdev(nina) + + return nina, nina +} diff --git a/rtl8720dn/README.md b/rtl8720dn/README.md index c5bf991b0..bfd67825d 100644 --- a/rtl8720dn/README.md +++ b/rtl8720dn/README.md @@ -1,7 +1,6 @@ # RTL8720DN Driver This package provides a driver to use a separate connected WiFi processor `RTL8720DN` for TCP/UDP communication. -At this time, only part of TCP is supported. ## Using th RTL8720DN Driver @@ -9,8 +8,8 @@ For now, it is only available for the `RTL8720DN` on `Wio Terminal`. You can try the following command. ``` -$ tinygo flash --target wioterminal --size short ./examples/rtl8720dn/webclient/ -$ tinygo flash --target wioterminal --size short ./examples/rtl8720dn/tlsclient/ +$ tinygo flash --target wioterminal --size short ./examples/net/webclient/ +$ tinygo flash --target wioterminal --size short ./examples/net/tlsclient/ ``` ## RTL8720DN Firmware @@ -18,4 +17,4 @@ $ tinygo flash --target wioterminal --size short ./examples/rtl8720dn/tlsclient/ Follow the steps below to update. The firmware must be version 2.1.2 or later. -https://wiki.seeedstudio.com/Wio-Terminal-Network-Overview/ \ No newline at end of file +https://wiki.seeedstudio.com/Wio-Terminal-Network-Overview/ diff --git a/rtl8720dn/adapter.go b/rtl8720dn/adapter.go deleted file mode 100644 index f60179b9a..000000000 --- a/rtl8720dn/adapter.go +++ /dev/null @@ -1,57 +0,0 @@ -package rtl8720dn - -import ( - "machine" - "time" - - "tinygo.org/x/drivers/net" -) - -type Driver struct { - *RTL8720DN -} - -// New returns a new RTL8720DN driver. The UART that is passed in -// will be reconfigured at the baud rate required by the device. -func New(uart *machine.UART, tx, rx, en machine.Pin) *Driver { - enable(en) - uart.Configure(machine.UARTConfig{TX: tx, RX: rx, BaudRate: 614400}) - - return &Driver{ - RTL8720DN: &RTL8720DN{ - port: &UARTx{UART: uart}, - seq: 1, - sema: make(chan bool, 1), - debug: false, - }, - } -} - -func (d *Driver) Configure() error { - net.UseDriver(d) - - _, err := d.Rpc_tcpip_adapter_init() - if err != nil { - return err - } - - return nil -} - -func (d *Driver) ConnectToAccessPoint(ssid, pass string, timeout time.Duration) error { - if len(ssid) == 0 { - return net.ErrWiFiMissingSSID - } - - return d.ConnectToAP(ssid, pass) -} - -func (d *Driver) Disconnect() error { - _, err := d.Rpc_wifi_disconnect() - return err -} - -func (d *Driver) GetClientIP() (string, error) { - ip, _, _, err := d.GetIP() - return ip.String(), err -} diff --git a/rtl8720dn/debug.go b/rtl8720dn/debug.go new file mode 100644 index 000000000..f04e5b34a --- /dev/null +++ b/rtl8720dn/debug.go @@ -0,0 +1,16 @@ +package rtl8720dn + +type debug uint8 + +const ( + debugBasic debug = 1 << iota // show fw version, mac addr, etc + debugNetdev // show netdev entry points + debugRpc // show rtl8720dn cmds + + debugOff = 0 + debugAll = debugBasic | debugNetdev | debugRpc +) + +func debugging(want debug) bool { + return (_debug & want) != 0 +} diff --git a/rtl8720dn/http.go b/rtl8720dn/http.go deleted file mode 100644 index 921ee9dc7..000000000 --- a/rtl8720dn/http.go +++ /dev/null @@ -1,236 +0,0 @@ -package rtl8720dn - -import ( - "bufio" - "bytes" - "fmt" - "io" - "time" - - "tinygo.org/x/drivers/net/http" -) - -func (rtl *RTL8720DN) setupHTTPServer() error { - _, err := rtl.Rpc_lwip_close(-1) - if err != nil { - return err - } - - _, err = rtl.Rpc_lwip_socket(0x00000002, 0x00000001, 0x00000000) - if err != nil { - return err - } - - name := []byte{0x00, 0x02, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0xA5, 0x42, 0x00, 0x00, 0xC7, 0x61, 0x01, 0x00} - _, err = rtl.Rpc_lwip_bind(0, name, uint32(len(name))) - if err != nil { - return err - } - - _, err = rtl.Rpc_lwip_listen(0, 4) - if err != nil { - return err - } - - _, err = rtl.Rpc_lwip_fcntl(0, 4, 1) - if err != nil { - return err - } - - return nil -} - -func (rtl *RTL8720DN) accept() (bool, error) { - addr := []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0xD7, 0x00, 0x20, 0x00, 0xD8, 0x00, 0x20} - length := uint32(len(addr)) - ret, err := rtl.Rpc_lwip_accept(0, addr, &length) - if err != nil { - return false, err - } - - return ret == 1, nil -} - -func (rtl *RTL8720DN) handleHTTP() error { - socket := int32(1) - optval := []byte{0x01, 0x00, 0x00, 0x00} - _, err := rtl.Rpc_lwip_setsockopt(socket, 0x00000FFF, 8, optval, uint32(len(optval))) - if err != nil { - return nil - } - - _, err = rtl.Rpc_lwip_setsockopt(socket, 6, 1, optval, uint32(len(optval))) - if err != nil { - return nil - } - - buf := make([]byte, 4096) - for { - _, err = rtl.Rpc_lwip_recv(socket, &buf, uint32(len(buf)), 8, 0) - if err != nil { - return nil - } - if len(buf) > 0 { - break - } - - _, err = rtl.Rpc_lwip_errno() - if err != nil { - return nil - } - - time.Sleep(100 * time.Millisecond) - } - - buf2 := make([]byte, 4096) - result, err := rtl.Rpc_lwip_recv(socket, &buf2, uint32(len(buf2)), 8, 0) - if err != nil { - return nil - } - if result != -1 && result != 0 { - return fmt.Errorf("Rpc_lwip_recv error") - } - - result, err = rtl.Rpc_lwip_errno() - if err != nil { - return nil - } - if result != 11 { - return fmt.Errorf("Rpc_lwip_errno error") - } - - b := bufio.NewReader(bytes.NewReader(buf)) - req, err := http.ReadRequest(b) - if err != nil { - return err - } - if rtl.debug { - fmt.Printf("%s %s %s\r\n", req.Method, req.RequestURI, req.Proto) - } - - pos := bytes.Index(buf, []byte("\r\n\r\n")) - if pos > 0 { - body := bytes.NewReader(buf[pos+4:]) - req.Body = io.NopCloser(body) - } - - handler, _ := http.DefaultServeMux.Handler(req) - rwx := responseWriter{ - header: http.Header{}, - statusCode: 200, - } - rwx.header.Add(`Content-Type`, `text/html; charset=UTF-8`) - rwx.header.Add(`Connection`, `close`) - handler.ServeHTTP(&rwx, req) - rwx.header.Add(`Content-Length`, fmt.Sprintf("%d", len(rwx.Buf))) - - optval = []byte{0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA5, 0xA5, 0xA5, 0xA5} - _, err = rtl.Rpc_lwip_setsockopt(socket, 0x00000FFF, 0x1006, optval, uint32(len(optval))) - if err != nil { - return nil - } - - optval = []byte{0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA5, 0xA5, 0xA5, 0xA5} - _, err = rtl.Rpc_lwip_setsockopt(socket, 0x00000FFF, 0x1005, optval, uint32(len(optval))) - if err != nil { - return nil - } - - maxfdp1 := int32(2) - writeset := []byte{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} - timeout := []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x42, 0x0F, 0x00, 0x0A, 0x00, 0x00, 0x00} - _, err = rtl.Rpc_lwip_select(maxfdp1, []byte{}, writeset, []byte{}, timeout) - if err != nil { - return nil - } - - msg := rwx.Buf - hb := bytes.Buffer{} - err = rwx.header.Write(&hb) - if err != nil { - return err - } - - data := []byte(fmt.Sprintf("HTTP/1.1 %d OK\n", rwx.statusCode)) - data = append(data, hb.Bytes()...) - data = append(data, byte('\n')) - - _, err = rtl.Rpc_lwip_send(socket, data, 8) - if err != nil { - return nil - } - - if len(msg) > 0 { - timeout = []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x42, 0x0F, 0x00, 0x54, 0x00, 0x00, 0x00} - _, err = rtl.Rpc_lwip_select(maxfdp1, []byte{}, writeset, []byte{}, timeout) - if err != nil { - return nil - } - - _, err = rtl.Rpc_lwip_send(socket, msg, 8) - if err != nil { - return nil - } - } - - for i := 0; i < 4; i++ { - buf := make([]byte, 4096) - _, err = rtl.Rpc_lwip_recv(socket, &buf, uint32(len(buf)), 8, 0) - if err != nil { - return nil - } - - _, err = rtl.Rpc_lwip_errno() - if err != nil { - return nil - } - } - - _, err = rtl.Rpc_lwip_close(socket) - if err != nil { - return nil - } - return nil -} - -func (rtl *RTL8720DN) ListenAndServe(addr string, handler http.Handler) error { - err := rtl.setupHTTPServer() - if err != nil { - return err - } - - for { - connected, err := rtl.accept() - if err != nil { - return err - } - - if connected { - err := rtl.handleHTTP() - if err != nil { - return err - } - } - - time.Sleep(100 * time.Millisecond) - } -} - -type responseWriter struct { - Buf []byte - header http.Header - statusCode int -} - -func (r *responseWriter) Header() http.Header { - return r.header -} - -func (r *responseWriter) Write(b []byte) (int, error) { - r.Buf = append(r.Buf, b...) - return len(b), nil -} - -func (r *responseWriter) WriteHeader(statusCode int) { - r.statusCode = statusCode -} diff --git a/rtl8720dn/netdriver.go b/rtl8720dn/netdriver.go deleted file mode 100644 index 73e6cc43b..000000000 --- a/rtl8720dn/netdriver.go +++ /dev/null @@ -1,377 +0,0 @@ -package rtl8720dn - -import ( - "fmt" - "strconv" -) - -// Here is the implementation of tinygo-org/x/drivers/net.DeviceDriver. - -func (d *Driver) GetDNS(domain string) (string, error) { - if d.debug { - fmt.Printf("GetDNS(%q)\r\n", domain) - } - - ipaddr := make([]byte, 4) - _, err := d.Rpc_netconn_gethostbyname(domain, &ipaddr) - if err != nil { - return "", err - } - - ret, err := fmt.Sprintf("%d.%d.%d.%d", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]), nil - if d.debug { - fmt.Printf("-> %s\r\n", ret) - fmt.Printf("-> %02X.%02X.%02X.%02X\r\n", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]) - } - return ret, err -} - -func (d *Driver) ConnectTCPSocket(addr, port string) error { - if d.debug { - fmt.Printf("ConnectTCPSocket(%q, %q)\r\n", addr, port) - } - - ipaddr := make([]byte, 4) - if len(addr) == 4 { - copy(ipaddr, addr) - } else { - _, err := d.Rpc_netconn_gethostbyname(addr, &ipaddr) - if err != nil { - return err - } - } - - portNum, err := strconv.ParseUint(port, 0, 0) - if err != nil { - return err - } - - socket, err := d.Rpc_lwip_socket(0x02, 0x01, 0x00) - if err != nil { - return err - } - d.socket = socket - d.connectionType = ConnectionTypeTCP - - _, err = d.Rpc_lwip_fcntl(socket, 0x00000003, 0x00000000) - if err != nil { - return err - } - - _, err = d.Rpc_lwip_fcntl(socket, 0x00000004, 0x00000001) - if err != nil { - return err - } - - name := []byte{0x00, 0x02, 0x00, 0x50, 0xC0, 0xA8, 0x01, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} - name[2] = byte(portNum >> 8) - name[3] = byte(portNum) - name[4] = byte(ipaddr[0]) - name[5] = byte(ipaddr[1]) - name[6] = byte(ipaddr[2]) - name[7] = byte(ipaddr[3]) - - _, err = d.Rpc_lwip_connect(socket, name, uint32(len(name))) - if err != nil { - return err - } - - readset := []byte{} - writeset := []byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} - exceptset := []byte{} - timeout := []byte{} - _, err = d.Rpc_lwip_select(0x01, readset, writeset, exceptset, timeout) - if err != nil { - return err - } - - optval := make([]byte, 4) - optlen := uint32(len(optval)) - _, err = d.Rpc_lwip_getsockopt(socket, 0x00000FFF, 0x00001007, []byte{0xA5, 0xA5, 0xA5, 0xA5}, &optval, &optlen) - if err != nil { - return err - } - - _, err = d.Rpc_lwip_fcntl(socket, 0x00000003, 0x00000000) - if err != nil { - return err - } - - _, err = d.Rpc_lwip_fcntl(socket, 0x00000004, 0x00000000) - if err != nil { - return err - } - - readset = []byte{} - writeset = []byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} - exceptset = []byte{} - timeout = []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x42, 0x0F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF} - _, err = d.Rpc_lwip_select(0x01, readset, writeset, exceptset, timeout) - if err != nil { - return err - } - - return nil -} - -func (d *Driver) ConnectSSLSocket(addr, port string) error { - if d.debug { - fmt.Printf("ConnectSSLSocket(%q, %q)\r\n", addr, port) - } - if d.root_ca == nil { - return fmt.Errorf("root_ca is not set") - } - - client, err := d.Rpc_wifi_ssl_client_create() - if err != nil { - return err - } - d.client = client - d.connectionType = ConnectionTypeTLS - - err = d.Rpc_wifi_ssl_init(client) - if err != nil { - return err - } - - err = d.Rpc_wifi_ssl_set_timeout(client, 0x0001D4C0) - if err != nil { - return err - } - - _, err = d.Rpc_wifi_ssl_set_rootCA(client, *d.root_ca) - if err != nil { - return err - } - - // TODO: use port - _, err = d.Rpc_wifi_start_ssl_client(client, addr, 443, 0x0001D4C0) - if err != nil { - return err - } - - _, err = d.Rpc_wifi_ssl_get_socket(client) - if err != nil { - return err - } - return nil -} - -func (d *Driver) ConnectUDPSocket(addr, sendport, listenport string) error { - if d.debug { - fmt.Printf("ConnectUDPSocket(\"%d.%d.%d.%d\", %q, %q)\r\n", byte(addr[0]), byte(addr[1]), byte(addr[2]), byte(addr[3]), sendport, listenport) - } - - socket, err := d.Rpc_lwip_socket(0x02, 0x02, 0x00) - if err != nil { - return err - } - d.socket = socket - d.connectionType = ConnectionTypeUDP - - optval := []byte{0x01, 0x00, 0x00, 0x00} - _, err = d.Rpc_lwip_setsockopt(socket, 0x00000FFF, 0x00000004, optval, uint32(len(optval))) - if err != nil { - return err - } - - port, err := strconv.ParseUint(sendport, 10, 0) - if err != nil { - return err - } - - ip := []byte(addr) - - // remote info - d.udpInfo[0] = byte(port >> 8) - d.udpInfo[1] = byte(port) - d.udpInfo[2] = ip[0] - d.udpInfo[3] = ip[1] - d.udpInfo[4] = ip[2] - d.udpInfo[5] = ip[3] - - port, err = strconv.ParseUint(listenport, 10, 0) - if err != nil { - return err - } - - ip_info := make([]byte, 12) - _, err = d.Rpc_tcpip_adapter_get_ip_info(0, &ip_info) - if err != nil { - return err - } - - name := []byte{0x00, 0x02, 0x0D, 0x05, 0xC0, 0xA8, 0x01, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} - name[2] = byte(port >> 8) - name[3] = byte(port) - name[4] = ip_info[0] - name[5] = ip_info[1] - name[6] = ip_info[2] - name[7] = ip_info[3] - - _, err = d.Rpc_lwip_bind(socket, name, uint32(len(name))) - if err != nil { - return err - } - - _, err = d.Rpc_lwip_fcntl(socket, 0x00000004, 0x00000000) - if err != nil { - return err - } - - return nil -} - -func (d *Driver) DisconnectSocket() error { - if d.debug { - fmt.Printf("DisconnectSocket()\r\n") - } - switch d.connectionType { - case ConnectionTypeTCP, ConnectionTypeUDP: - _, err := d.Rpc_lwip_close(d.socket) - if err != nil { - return err - } - case ConnectionTypeTLS: - err := d.Rpc_wifi_stop_ssl_socket(d.client) - if err != nil { - return err - } - - err = d.Rpc_wifi_ssl_client_destroy(d.client) - if err != nil { - return err - } - default: - } - d.connectionType = ConnectionTypeNone - return nil -} - -func (d *Driver) StartSocketSend(size int) error { - if d.debug { - fmt.Printf("StartSocketSend(%d)\r\n", size) - } - // No implementation required - return nil -} - -func (d *Driver) Write(b []byte) (n int, err error) { - if d.debug { - fmt.Printf("Write(%#v)\r\n", b) - } - - switch d.connectionType { - case ConnectionTypeTCP: - sn, err := d.Rpc_lwip_send(d.socket, b, 0x00000008) - if err != nil { - return 0, err - } - n = int(sn) - case ConnectionTypeUDP: - to := []byte{0x00, 0x02, 0x0D, 0x05, 0xC0, 0xA8, 0x01, 0x76, 0xEB, 0x43, 0x00, 0x00, 0xD5, 0x27, 0x01, 0x00} - copy(to[2:], d.udpInfo[:]) - sn, err := d.Rpc_lwip_sendto(d.socket, b, 0x00000000, to, uint32(len(to))) - if err != nil { - return 0, err - } - n = int(sn) - case ConnectionTypeTLS: - sn, err := d.Rpc_wifi_send_ssl_data(d.client, b, uint16(len(b))) - if err != nil { - return 0, err - } - n = int(sn) - default: - return 0, nil - } - return n, nil -} - -func (d *Driver) ReadSocket(b []byte) (n int, err error) { - if d.debug { - //fmt.Printf("ReadSocket(b)\r\n") - } - if d.connectionType == ConnectionTypeNone { - return 0, nil - } - - switch d.connectionType { - case ConnectionTypeTCP: - length := len(b) - if length > maxUartRecvSize-16 { - length = maxUartRecvSize - 16 - } - buf := b[:length] - nn, err := d.Rpc_lwip_recv(d.socket, &buf, uint32(length), 0x00000008, 0x00002800) - if err != nil { - return 0, err - } - - if nn == -1 { - return 0, nil - } else if nn == 0 { - return 0, d.DisconnectSocket() - } - n = int(nn) - case ConnectionTypeUDP: - length := len(b) - if length > maxUartRecvSize-32 { - length = maxUartRecvSize - 32 - } - buf := b[:length] - from := make([]byte, 16) - fromLen := uint32(len(from)) - nn, err := d.Rpc_lwip_recvfrom(d.socket, &buf, uint32(length), 0x00000008, &from, &fromLen, 10000) - if err != nil { - return 0, err - } - - if nn == -1 { - return 0, nil - } - n = int(nn) - case ConnectionTypeTLS: - length := len(b) - if length > maxUartRecvSize-16 { - length = maxUartRecvSize - 16 - } - buf := b[:length] - nn, err := d.Rpc_wifi_get_ssl_receive(d.client, &buf, int32(length)) - if err != nil { - return 0, err - } - if nn < 0 { - return 0, fmt.Errorf("error %d", n) - } else if nn == 0 || nn == -30848 { - return 0, d.DisconnectSocket() - } - n = int(nn) - default: - } - - return n, nil -} - -func (d *Driver) IsSocketDataAvailable() bool { - if d.debug { - fmt.Printf("IsSocketDataAvailable()\r\n") - } - ret, err := d.Rpc_lwip_available(d.socket) - if err != nil { - fmt.Printf("error: %s\r\n", err.Error()) - return false - } - if ret == 1 { - return true - } - return false -} - -func (d *Driver) Response(timeout int) ([]byte, error) { - if d.debug { - fmt.Printf("Response(%d))\r\n", timeout) - } - // No implementation required - return nil, nil -} diff --git a/rtl8720dn/rpc.go b/rtl8720dn/rpc.go index 50498aef2..b554e8b0f 100644 --- a/rtl8720dn/rpc.go +++ b/rtl8720dn/rpc.go @@ -8,21 +8,13 @@ import ( "fmt" ) -func (r *RTL8720DN) Rpc_system_version() (string, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_system_version() string { if r.debug { fmt.Printf("rpc_system_version()\r\n") } msg := startWriteMessage(0x00, 0x01, 0x01, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return "", err - } + r.performRequest(msg) r.read() widx := 8 @@ -32,15 +24,10 @@ func (r *RTL8720DN) Rpc_system_version() (string, error) { result = string(payload[widx : widx+int(result_length)]) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_system_ack(c uint8) (uint8, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_system_ack(c uint8) uint8 { if r.debug { fmt.Printf("rpc_system_ack()\r\n") } @@ -49,10 +36,7 @@ func (r *RTL8720DN) Rpc_system_ack(c uint8) (uint8, error) { // c : in uint8 msg = append(msg, byte(c>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -61,24 +45,16 @@ func (r *RTL8720DN) Rpc_system_ack(c uint8) (uint8, error) { result = uint8(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_ble_init() (bool, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_ble_init() bool { if r.debug { fmt.Printf("rpc_ble_init()\r\n") } msg := startWriteMessage(0x00, 0x02, 0x01, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return false, err - } + r.performRequest(msg) r.read() widx := 8 @@ -86,59 +62,38 @@ func (r *RTL8720DN) Rpc_ble_init() (bool, error) { result = binary.LittleEndian.Uint32(payload[widx:]) == 1 r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_ble_start() error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_ble_start() { if r.debug { fmt.Printf("rpc_ble_start()\r\n") } msg := startWriteMessage(0x00, 0x02, 0x02, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_ble_deinit() error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_ble_deinit() { if r.debug { fmt.Printf("rpc_ble_deinit()\r\n") } msg := startWriteMessage(0x00, 0x02, 0x03, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_gap_set_param(param RPC_T_GAP_PARAM_TYPE, value []byte) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_gap_set_param(param RPC_T_GAP_PARAM_TYPE, value []byte) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_gap_set_param()\r\n") } @@ -153,10 +108,7 @@ func (r *RTL8720DN) Rpc_gap_set_param(param RPC_T_GAP_PARAM_TYPE, value []byte) msg = append(msg, byte(len(value)), byte(len(value)>>8), byte(len(value)>>16), byte(len(value)>>24)) msg = append(msg, []byte(value)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -165,15 +117,10 @@ func (r *RTL8720DN) Rpc_gap_set_param(param RPC_T_GAP_PARAM_TYPE, value []byte) result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_gap_get_param(param RPC_T_GAP_PARAM_TYPE, value *[]byte) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_gap_get_param(param RPC_T_GAP_PARAM_TYPE, value []byte) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_gap_get_param()\r\n") } @@ -185,10 +132,7 @@ func (r *RTL8720DN) Rpc_gap_get_param(param RPC_T_GAP_PARAM_TYPE, value *[]byte) msg = append(msg, byte(param>>16)) msg = append(msg, byte(param>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -196,33 +140,24 @@ func (r *RTL8720DN) Rpc_gap_get_param(param RPC_T_GAP_PARAM_TYPE, value *[]byte) value_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if value_length > 0 { - copy(*value, payload[widx:widx+int(value_length)]) + copy(value, payload[widx:widx+int(value_length)]) widx += int(value_length) } - *value = (*value)[:value_length] var result RPC_T_GAP_CAUSE result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_gap_set_pairable_mode() (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_gap_set_pairable_mode() RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_gap_set_pairable_mode()\r\n") } msg := startWriteMessage(0x00, 0x03, 0x03, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -230,15 +165,10 @@ func (r *RTL8720DN) Rpc_gap_set_pairable_mode() (RPC_T_GAP_CAUSE, error) { result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_bond_set_param(param RPC_T_LE_BOND_PARAM_TYPE, value []byte) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_bond_set_param(param RPC_T_LE_BOND_PARAM_TYPE, value []byte) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_bond_set_param()\r\n") } @@ -253,10 +183,7 @@ func (r *RTL8720DN) Rpc_le_bond_set_param(param RPC_T_LE_BOND_PARAM_TYPE, value msg = append(msg, byte(len(value)), byte(len(value)>>8), byte(len(value)>>16), byte(len(value)>>24)) msg = append(msg, []byte(value)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -265,15 +192,10 @@ func (r *RTL8720DN) Rpc_le_bond_set_param(param RPC_T_LE_BOND_PARAM_TYPE, value result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_bond_get_param(param RPC_T_LE_BOND_PARAM_TYPE, value *[]byte) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_bond_get_param(param RPC_T_LE_BOND_PARAM_TYPE, value []byte) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_bond_get_param()\r\n") } @@ -285,10 +207,7 @@ func (r *RTL8720DN) Rpc_le_bond_get_param(param RPC_T_LE_BOND_PARAM_TYPE, value msg = append(msg, byte(param>>16)) msg = append(msg, byte(param>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -296,24 +215,18 @@ func (r *RTL8720DN) Rpc_le_bond_get_param(param RPC_T_LE_BOND_PARAM_TYPE, value value_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if value_length > 0 { - copy(*value, payload[widx:widx+int(value_length)]) + copy(value, payload[widx:widx+int(value_length)]) widx += int(value_length) } - *value = (*value)[:value_length] var result RPC_T_GAP_CAUSE result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_bond_pair(conn_id uint8) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_bond_pair(conn_id uint8) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_bond_pair()\r\n") } @@ -322,10 +235,7 @@ func (r *RTL8720DN) Rpc_le_bond_pair(conn_id uint8) (RPC_T_GAP_CAUSE, error) { // conn_id : in uint8 msg = append(msg, byte(conn_id>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -334,15 +244,10 @@ func (r *RTL8720DN) Rpc_le_bond_pair(conn_id uint8) (RPC_T_GAP_CAUSE, error) { result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_bond_get_display_key(conn_id uint8, key *uint32) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_bond_get_display_key(conn_id uint8, key *uint32) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_bond_get_display_key()\r\n") } @@ -351,10 +256,7 @@ func (r *RTL8720DN) Rpc_le_bond_get_display_key(conn_id uint8, key *uint32) (RPC // conn_id : in uint8 msg = append(msg, byte(conn_id>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -366,15 +268,10 @@ func (r *RTL8720DN) Rpc_le_bond_get_display_key(conn_id uint8, key *uint32) (RPC result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_bond_passkey_input_confirm(conn_id uint8, passcode uint32, cause RPC_T_GAP_CFM_CAUSE) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_bond_passkey_input_confirm(conn_id uint8, passcode uint32, cause RPC_T_GAP_CFM_CAUSE) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_bond_passkey_input_confirm()\r\n") } @@ -393,10 +290,7 @@ func (r *RTL8720DN) Rpc_le_bond_passkey_input_confirm(conn_id uint8, passcode ui msg = append(msg, byte(cause>>16)) msg = append(msg, byte(cause>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -405,15 +299,10 @@ func (r *RTL8720DN) Rpc_le_bond_passkey_input_confirm(conn_id uint8, passcode ui result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_bond_oob_input_confirm(conn_id uint8, cause RPC_T_GAP_CFM_CAUSE) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_bond_oob_input_confirm(conn_id uint8, cause RPC_T_GAP_CFM_CAUSE) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_bond_oob_input_confirm()\r\n") } @@ -427,10 +316,7 @@ func (r *RTL8720DN) Rpc_le_bond_oob_input_confirm(conn_id uint8, cause RPC_T_GAP msg = append(msg, byte(cause>>16)) msg = append(msg, byte(cause>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -439,15 +325,10 @@ func (r *RTL8720DN) Rpc_le_bond_oob_input_confirm(conn_id uint8, cause RPC_T_GAP result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_bond_just_work_confirm(conn_id uint8, cause RPC_T_GAP_CFM_CAUSE) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_bond_just_work_confirm(conn_id uint8, cause RPC_T_GAP_CFM_CAUSE) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_bond_just_work_confirm()\r\n") } @@ -461,10 +342,7 @@ func (r *RTL8720DN) Rpc_le_bond_just_work_confirm(conn_id uint8, cause RPC_T_GAP msg = append(msg, byte(cause>>16)) msg = append(msg, byte(cause>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -473,15 +351,10 @@ func (r *RTL8720DN) Rpc_le_bond_just_work_confirm(conn_id uint8, cause RPC_T_GAP result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_bond_passkey_display_confirm(conn_id uint8, cause RPC_T_GAP_CFM_CAUSE) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_bond_passkey_display_confirm(conn_id uint8, cause RPC_T_GAP_CFM_CAUSE) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_bond_passkey_display_confirm()\r\n") } @@ -495,10 +368,7 @@ func (r *RTL8720DN) Rpc_le_bond_passkey_display_confirm(conn_id uint8, cause RPC msg = append(msg, byte(cause>>16)) msg = append(msg, byte(cause>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -507,15 +377,10 @@ func (r *RTL8720DN) Rpc_le_bond_passkey_display_confirm(conn_id uint8, cause RPC result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_bond_user_confirm(conn_id uint8, cause RPC_T_GAP_CFM_CAUSE) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_bond_user_confirm(conn_id uint8, cause RPC_T_GAP_CFM_CAUSE) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_bond_user_confirm()\r\n") } @@ -529,10 +394,7 @@ func (r *RTL8720DN) Rpc_le_bond_user_confirm(conn_id uint8, cause RPC_T_GAP_CFM_ msg = append(msg, byte(cause>>16)) msg = append(msg, byte(cause>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -541,15 +403,10 @@ func (r *RTL8720DN) Rpc_le_bond_user_confirm(conn_id uint8, cause RPC_T_GAP_CFM_ result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_bond_cfg_local_key_distribute(init_dist uint8, rsp_dist uint8) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_bond_cfg_local_key_distribute(init_dist uint8, rsp_dist uint8) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_bond_cfg_local_key_distribute()\r\n") } @@ -560,10 +417,7 @@ func (r *RTL8720DN) Rpc_le_bond_cfg_local_key_distribute(init_dist uint8, rsp_di // rsp_dist : in uint8 msg = append(msg, byte(rsp_dist>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -572,37 +426,24 @@ func (r *RTL8720DN) Rpc_le_bond_cfg_local_key_distribute(init_dist uint8, rsp_di result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_bond_clear_all_keys() error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_bond_clear_all_keys() { if r.debug { fmt.Printf("rpc_le_bond_clear_all_keys()\r\n") } msg := startWriteMessage(0x00, 0x04, 0x0B, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_le_bond_delete_by_idx(idx uint8) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_bond_delete_by_idx(idx uint8) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_bond_delete_by_idx()\r\n") } @@ -611,10 +452,7 @@ func (r *RTL8720DN) Rpc_le_bond_delete_by_idx(idx uint8) (RPC_T_GAP_CAUSE, error // idx : in uint8 msg = append(msg, byte(idx>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -623,32 +461,24 @@ func (r *RTL8720DN) Rpc_le_bond_delete_by_idx(idx uint8) (RPC_T_GAP_CAUSE, error result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_bond_delete_by_bd(bd_addr uint8, bd_type RPC_T_GAP_REMOTE_ADDR_TYPE) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_bond_delete_by_bd(bd_addr []uint8, bd_type RPC_T_GAP_REMOTE_ADDR_TYPE) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_bond_delete_by_bd()\r\n") } msg := startWriteMessage(0x00, 0x04, 0x0D, uint32(r.seq)) - // bd_addr : in uint8 - msg = append(msg, byte(bd_addr>>0)) + // bd_addr : in []uint8 (6) + msg = append(msg, bd_addr...) // bd_type : in RPC_T_GAP_REMOTE_ADDR_TYPE msg = append(msg, byte(bd_type>>0)) msg = append(msg, byte(bd_type>>8)) msg = append(msg, byte(bd_type>>16)) msg = append(msg, byte(bd_type>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -657,15 +487,10 @@ func (r *RTL8720DN) Rpc_le_bond_delete_by_bd(bd_addr uint8, bd_type RPC_T_GAP_RE result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_bond_get_sec_level(conn_id uint8, sec_type RPC_T_GAP_SEC_LEVEL) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_bond_get_sec_level(conn_id uint8, sec_type RPC_T_GAP_SEC_LEVEL) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_bond_get_sec_level()\r\n") } @@ -674,10 +499,7 @@ func (r *RTL8720DN) Rpc_le_bond_get_sec_level(conn_id uint8, sec_type RPC_T_GAP_ // conn_id : in uint8 msg = append(msg, byte(conn_id>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -688,15 +510,10 @@ func (r *RTL8720DN) Rpc_le_bond_get_sec_level(conn_id uint8, sec_type RPC_T_GAP_ result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_gap_init(link_num uint8) (bool, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_gap_init(link_num uint8) bool { if r.debug { fmt.Printf("rpc_le_gap_init()\r\n") } @@ -705,10 +522,7 @@ func (r *RTL8720DN) Rpc_le_gap_init(link_num uint8) (bool, error) { // link_num : in uint8 msg = append(msg, byte(link_num>>0)) - err := r.performRequest(msg) - if err != nil { - return false, err - } + r.performRequest(msg) r.read() widx := 8 @@ -717,15 +531,10 @@ func (r *RTL8720DN) Rpc_le_gap_init(link_num uint8) (bool, error) { result = binary.LittleEndian.Uint32(payload[widx:]) == 1 r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_gap_msg_info_way(use_msg bool) error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_gap_msg_info_way(use_msg bool) { if r.debug { fmt.Printf("rpc_le_gap_msg_info_way()\r\n") } @@ -738,32 +547,21 @@ func (r *RTL8720DN) Rpc_le_gap_msg_info_way(use_msg bool) error { msg = append(msg, 0) } - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_le_get_max_link_num() (uint8, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_get_max_link_num() uint8 { if r.debug { fmt.Printf("rpc_le_get_max_link_num()\r\n") } msg := startWriteMessage(0x00, 0x05, 0x03, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -771,15 +569,10 @@ func (r *RTL8720DN) Rpc_le_get_max_link_num() (uint8, error) { result = uint8(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_set_gap_param(param RPC_T_GAP_LE_PARAM_TYPE, value []byte) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_set_gap_param(param RPC_T_GAP_LE_PARAM_TYPE, value []byte) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_set_gap_param()\r\n") } @@ -794,10 +587,7 @@ func (r *RTL8720DN) Rpc_le_set_gap_param(param RPC_T_GAP_LE_PARAM_TYPE, value [] msg = append(msg, byte(len(value)), byte(len(value)>>8), byte(len(value)>>16), byte(len(value)>>24)) msg = append(msg, []byte(value)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -806,15 +596,10 @@ func (r *RTL8720DN) Rpc_le_set_gap_param(param RPC_T_GAP_LE_PARAM_TYPE, value [] result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_get_gap_param(param RPC_T_GAP_LE_PARAM_TYPE, value *[]byte) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_get_gap_param(param RPC_T_GAP_LE_PARAM_TYPE, value []byte) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_get_gap_param()\r\n") } @@ -826,10 +611,7 @@ func (r *RTL8720DN) Rpc_le_get_gap_param(param RPC_T_GAP_LE_PARAM_TYPE, value *[ msg = append(msg, byte(param>>16)) msg = append(msg, byte(param>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -837,24 +619,18 @@ func (r *RTL8720DN) Rpc_le_get_gap_param(param RPC_T_GAP_LE_PARAM_TYPE, value *[ value_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if value_length > 0 { - copy(*value, payload[widx:widx+int(value_length)]) + copy(value, payload[widx:widx+int(value_length)]) widx += int(value_length) } - *value = (*value)[:value_length] var result RPC_T_GAP_CAUSE result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_modify_white_list(operation RPC_T_GAP_WHITE_LIST_OP, bd_addr uint8, bd_type RPC_T_GAP_REMOTE_ADDR_TYPE) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_modify_white_list(operation RPC_T_GAP_WHITE_LIST_OP, bd_addr []uint8, bd_type RPC_T_GAP_REMOTE_ADDR_TYPE) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_modify_white_list()\r\n") } @@ -865,18 +641,15 @@ func (r *RTL8720DN) Rpc_le_modify_white_list(operation RPC_T_GAP_WHITE_LIST_OP, msg = append(msg, byte(operation>>8)) msg = append(msg, byte(operation>>16)) msg = append(msg, byte(operation>>24)) - // bd_addr : in uint8 - msg = append(msg, byte(bd_addr>>0)) + // bd_addr : in []uint8 (6) + msg = append(msg, bd_addr...) // bd_type : in RPC_T_GAP_REMOTE_ADDR_TYPE msg = append(msg, byte(bd_type>>0)) msg = append(msg, byte(bd_type>>8)) msg = append(msg, byte(bd_type>>16)) msg = append(msg, byte(bd_type>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -885,15 +658,10 @@ func (r *RTL8720DN) Rpc_le_modify_white_list(operation RPC_T_GAP_WHITE_LIST_OP, result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_gen_rand_addr(rand_addr_type RPC_T_GAP_RAND_ADDR_TYPE, random_bd *uint8) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_gen_rand_addr(rand_addr_type RPC_T_GAP_RAND_ADDR_TYPE, random_bd []uint8) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_gen_rand_addr()\r\n") } @@ -905,42 +673,31 @@ func (r *RTL8720DN) Rpc_le_gen_rand_addr(rand_addr_type RPC_T_GAP_RAND_ADDR_TYPE msg = append(msg, byte(rand_addr_type>>16)) msg = append(msg, byte(rand_addr_type>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 - // random_bd : out uint8 - *random_bd = payload[widx] - widx += 1 + // random_bd : out []uint8 (6) + copy(random_bd, payload[widx:widx+6]) + widx += 6 var result RPC_T_GAP_CAUSE result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_set_rand_addr(random_bd uint8) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_set_rand_addr(random_bd []uint8) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_set_rand_addr()\r\n") } msg := startWriteMessage(0x00, 0x05, 0x08, uint32(r.seq)) - // random_bd : in uint8 - msg = append(msg, byte(random_bd>>0)) + // random_bd : in []uint8 (6) + msg = append(msg, random_bd...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -949,32 +706,24 @@ func (r *RTL8720DN) Rpc_le_set_rand_addr(random_bd uint8) (RPC_T_GAP_CAUSE, erro result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_cfg_local_identity_address(addr uint8, ident_addr_type RPC_T_GAP_IDENT_ADDR_TYPE) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_cfg_local_identity_address(addr []uint8, ident_addr_type RPC_T_GAP_IDENT_ADDR_TYPE) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_cfg_local_identity_address()\r\n") } msg := startWriteMessage(0x00, 0x05, 0x09, uint32(r.seq)) - // addr : in uint8 - msg = append(msg, byte(addr>>0)) + // addr : in []uint8 (6) + msg = append(msg, addr...) // ident_addr_type : in RPC_T_GAP_IDENT_ADDR_TYPE msg = append(msg, byte(ident_addr_type>>0)) msg = append(msg, byte(ident_addr_type>>8)) msg = append(msg, byte(ident_addr_type>>16)) msg = append(msg, byte(ident_addr_type>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -983,15 +732,10 @@ func (r *RTL8720DN) Rpc_le_cfg_local_identity_address(addr uint8, ident_addr_typ result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_set_host_chann_classif(p_channel_map uint8) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_set_host_chann_classif(p_channel_map uint8) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_set_host_chann_classif()\r\n") } @@ -1000,10 +744,7 @@ func (r *RTL8720DN) Rpc_le_set_host_chann_classif(p_channel_map uint8) (RPC_T_GA // p_channel_map : in uint8 msg = append(msg, byte(p_channel_map>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1012,15 +753,10 @@ func (r *RTL8720DN) Rpc_le_set_host_chann_classif(p_channel_map uint8) (RPC_T_GA result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_write_default_data_len(tx_octets uint16, tx_time uint16) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_write_default_data_len(tx_octets uint16, tx_time uint16) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_write_default_data_len()\r\n") } @@ -1033,10 +769,7 @@ func (r *RTL8720DN) Rpc_le_write_default_data_len(tx_octets uint16, tx_time uint msg = append(msg, byte(tx_time>>0)) msg = append(msg, byte(tx_time>>8)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1045,15 +778,10 @@ func (r *RTL8720DN) Rpc_le_write_default_data_len(tx_octets uint16, tx_time uint result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_gap_config_cccd_not_check(cccd_not_check_flag RPC_T_GAP_CONFIG_GATT_CCCD_NOT_CHECK) error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_gap_config_cccd_not_check(cccd_not_check_flag RPC_T_GAP_CONFIG_GATT_CCCD_NOT_CHECK) { if r.debug { fmt.Printf("rpc_gap_config_cccd_not_check()\r\n") } @@ -1065,23 +793,15 @@ func (r *RTL8720DN) Rpc_gap_config_cccd_not_check(cccd_not_check_flag RPC_T_GAP_ msg = append(msg, byte(cccd_not_check_flag>>16)) msg = append(msg, byte(cccd_not_check_flag>>24)) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_gap_config_ccc_bits_count(gatt_server_ccc_bits_count uint8, gatt_storage_ccc_bits_count uint8) error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_gap_config_ccc_bits_count(gatt_server_ccc_bits_count uint8, gatt_storage_ccc_bits_count uint8) { if r.debug { fmt.Printf("rpc_gap_config_ccc_bits_count()\r\n") } @@ -1092,23 +812,15 @@ func (r *RTL8720DN) Rpc_gap_config_ccc_bits_count(gatt_server_ccc_bits_count uin // gatt_storage_ccc_bits_count : in uint8 msg = append(msg, byte(gatt_storage_ccc_bits_count>>0)) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_gap_config_max_attribute_table_count(gatt_max_attribute_table_count uint8) error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_gap_config_max_attribute_table_count(gatt_max_attribute_table_count uint8) { if r.debug { fmt.Printf("rpc_gap_config_max_attribute_table_count()\r\n") } @@ -1117,23 +829,15 @@ func (r *RTL8720DN) Rpc_gap_config_max_attribute_table_count(gatt_max_attribute_ // gatt_max_attribute_table_count : in uint8 msg = append(msg, byte(gatt_max_attribute_table_count>>0)) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_gap_config_max_mtu_size(att_max_mtu_size uint16) error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_gap_config_max_mtu_size(att_max_mtu_size uint16) { if r.debug { fmt.Printf("rpc_gap_config_max_mtu_size()\r\n") } @@ -1143,23 +847,15 @@ func (r *RTL8720DN) Rpc_gap_config_max_mtu_size(att_max_mtu_size uint16) error { msg = append(msg, byte(att_max_mtu_size>>0)) msg = append(msg, byte(att_max_mtu_size>>8)) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_gap_config_bte_pool_size(bte_pool_size uint8) error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_gap_config_bte_pool_size(bte_pool_size uint8) { if r.debug { fmt.Printf("rpc_gap_config_bte_pool_size()\r\n") } @@ -1168,23 +864,15 @@ func (r *RTL8720DN) Rpc_gap_config_bte_pool_size(bte_pool_size uint8) error { // bte_pool_size : in uint8 msg = append(msg, byte(bte_pool_size>>0)) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_gap_config_bt_report_buf_num(bt_report_buf_num uint8) error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_gap_config_bt_report_buf_num(bt_report_buf_num uint8) { if r.debug { fmt.Printf("rpc_gap_config_bt_report_buf_num()\r\n") } @@ -1193,23 +881,15 @@ func (r *RTL8720DN) Rpc_gap_config_bt_report_buf_num(bt_report_buf_num uint8) er // bt_report_buf_num : in uint8 msg = append(msg, byte(bt_report_buf_num>>0)) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_gap_config_le_key_storage_flag(le_key_storage_flag uint16) error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_gap_config_le_key_storage_flag(le_key_storage_flag uint16) { if r.debug { fmt.Printf("rpc_gap_config_le_key_storage_flag()\r\n") } @@ -1219,23 +899,15 @@ func (r *RTL8720DN) Rpc_gap_config_le_key_storage_flag(le_key_storage_flag uint1 msg = append(msg, byte(le_key_storage_flag>>0)) msg = append(msg, byte(le_key_storage_flag>>8)) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_gap_config_max_le_paired_device(max_le_paired_device uint8) error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_gap_config_max_le_paired_device(max_le_paired_device uint8) { if r.debug { fmt.Printf("rpc_gap_config_max_le_paired_device()\r\n") } @@ -1244,23 +916,15 @@ func (r *RTL8720DN) Rpc_gap_config_max_le_paired_device(max_le_paired_device uin // max_le_paired_device : in uint8 msg = append(msg, byte(max_le_paired_device>>0)) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_gap_config_max_le_link_num(le_link_num uint8) error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_gap_config_max_le_link_num(le_link_num uint8) { if r.debug { fmt.Printf("rpc_gap_config_max_le_link_num()\r\n") } @@ -1269,23 +933,15 @@ func (r *RTL8720DN) Rpc_gap_config_max_le_link_num(le_link_num uint8) error { // le_link_num : in uint8 msg = append(msg, byte(le_link_num>>0)) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_le_adv_set_param(param RPC_T_LE_ADV_PARAM_TYPE, value []byte) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_adv_set_param(param RPC_T_LE_ADV_PARAM_TYPE, value []byte) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_adv_set_param()\r\n") } @@ -1300,10 +956,7 @@ func (r *RTL8720DN) Rpc_le_adv_set_param(param RPC_T_LE_ADV_PARAM_TYPE, value [] msg = append(msg, byte(len(value)), byte(len(value)>>8), byte(len(value)>>16), byte(len(value)>>24)) msg = append(msg, []byte(value)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1312,15 +965,10 @@ func (r *RTL8720DN) Rpc_le_adv_set_param(param RPC_T_LE_ADV_PARAM_TYPE, value [] result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_adv_get_param(param RPC_T_LE_ADV_PARAM_TYPE, value *[]byte) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_adv_get_param(param RPC_T_LE_ADV_PARAM_TYPE, value []byte) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_adv_get_param()\r\n") } @@ -1332,10 +980,7 @@ func (r *RTL8720DN) Rpc_le_adv_get_param(param RPC_T_LE_ADV_PARAM_TYPE, value *[ msg = append(msg, byte(param>>16)) msg = append(msg, byte(param>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1343,33 +988,24 @@ func (r *RTL8720DN) Rpc_le_adv_get_param(param RPC_T_LE_ADV_PARAM_TYPE, value *[ value_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if value_length > 0 { - copy(*value, payload[widx:widx+int(value_length)]) + copy(value, payload[widx:widx+int(value_length)]) widx += int(value_length) } - *value = (*value)[:value_length] var result RPC_T_GAP_CAUSE result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_adv_start() (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_adv_start() RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_adv_start()\r\n") } msg := startWriteMessage(0x00, 0x07, 0x03, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1377,24 +1013,16 @@ func (r *RTL8720DN) Rpc_le_adv_start() (RPC_T_GAP_CAUSE, error) { result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_adv_stop() (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_adv_stop() RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_adv_stop()\r\n") } msg := startWriteMessage(0x00, 0x07, 0x04, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1402,24 +1030,16 @@ func (r *RTL8720DN) Rpc_le_adv_stop() (RPC_T_GAP_CAUSE, error) { result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_adv_update_param() (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_adv_update_param() RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_adv_update_param()\r\n") } msg := startWriteMessage(0x00, 0x07, 0x05, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1427,15 +1047,10 @@ func (r *RTL8720DN) Rpc_le_adv_update_param() (RPC_T_GAP_CAUSE, error) { result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_scan_set_param(param RPC_T_LE_SCAN_PARAM_TYPE, value []byte) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_scan_set_param(param RPC_T_LE_SCAN_PARAM_TYPE, value []byte) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_scan_set_param()\r\n") } @@ -1450,10 +1065,7 @@ func (r *RTL8720DN) Rpc_le_scan_set_param(param RPC_T_LE_SCAN_PARAM_TYPE, value msg = append(msg, byte(len(value)), byte(len(value)>>8), byte(len(value)>>16), byte(len(value)>>24)) msg = append(msg, []byte(value)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1462,15 +1074,10 @@ func (r *RTL8720DN) Rpc_le_scan_set_param(param RPC_T_LE_SCAN_PARAM_TYPE, value result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_scan_get_param(param RPC_T_LE_SCAN_PARAM_TYPE, value *[]byte) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_scan_get_param(param RPC_T_LE_SCAN_PARAM_TYPE, value []byte) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_scan_get_param()\r\n") } @@ -1482,10 +1089,7 @@ func (r *RTL8720DN) Rpc_le_scan_get_param(param RPC_T_LE_SCAN_PARAM_TYPE, value msg = append(msg, byte(param>>16)) msg = append(msg, byte(param>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1493,33 +1097,24 @@ func (r *RTL8720DN) Rpc_le_scan_get_param(param RPC_T_LE_SCAN_PARAM_TYPE, value value_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if value_length > 0 { - copy(*value, payload[widx:widx+int(value_length)]) + copy(value, payload[widx:widx+int(value_length)]) widx += int(value_length) } - *value = (*value)[:value_length] var result RPC_T_GAP_CAUSE result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_scan_start() (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_scan_start() RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_scan_start()\r\n") } msg := startWriteMessage(0x00, 0x08, 0x03, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1527,15 +1122,10 @@ func (r *RTL8720DN) Rpc_le_scan_start() (RPC_T_GAP_CAUSE, error) { result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_scan_timer_start(tick uint32) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_scan_timer_start(tick uint32) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_scan_timer_start()\r\n") } @@ -1547,10 +1137,7 @@ func (r *RTL8720DN) Rpc_le_scan_timer_start(tick uint32) (RPC_T_GAP_CAUSE, error msg = append(msg, byte(tick>>16)) msg = append(msg, byte(tick>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1559,24 +1146,16 @@ func (r *RTL8720DN) Rpc_le_scan_timer_start(tick uint32) (RPC_T_GAP_CAUSE, error result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_scan_stop() (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_scan_stop() RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_scan_stop()\r\n") } msg := startWriteMessage(0x00, 0x08, 0x05, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1584,15 +1163,10 @@ func (r *RTL8720DN) Rpc_le_scan_stop() (RPC_T_GAP_CAUSE, error) { result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_scan_info_filter(enable bool, offset uint8, length uint8, p_filter uint8) (bool, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_scan_info_filter(enable bool, offset uint8, length uint8, p_filter []uint8) bool { if r.debug { fmt.Printf("rpc_le_scan_info_filter()\r\n") } @@ -1608,13 +1182,10 @@ func (r *RTL8720DN) Rpc_le_scan_info_filter(enable bool, offset uint8, length ui msg = append(msg, byte(offset>>0)) // length : in uint8 msg = append(msg, byte(length>>0)) - // p_filter : in uint8 - msg = append(msg, byte(p_filter>>0)) + // p_filter : in []uint8 (31) + msg = append(msg, p_filter...) - err := r.performRequest(msg) - if err != nil { - return false, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1623,15 +1194,10 @@ func (r *RTL8720DN) Rpc_le_scan_info_filter(enable bool, offset uint8, length ui result = binary.LittleEndian.Uint32(payload[widx:]) == 1 r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_get_conn_param(param RPC_T_LE_CONN_PARAM_TYPE, value *[]byte, conn_id uint8) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_get_conn_param(param RPC_T_LE_CONN_PARAM_TYPE, value []byte, conn_id uint8) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_get_conn_param()\r\n") } @@ -1645,10 +1211,7 @@ func (r *RTL8720DN) Rpc_le_get_conn_param(param RPC_T_LE_CONN_PARAM_TYPE, value // conn_id : in uint8 msg = append(msg, byte(conn_id>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1656,24 +1219,18 @@ func (r *RTL8720DN) Rpc_le_get_conn_param(param RPC_T_LE_CONN_PARAM_TYPE, value value_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if value_length > 0 { - copy(*value, payload[widx:widx+int(value_length)]) + copy(value, payload[widx:widx+int(value_length)]) widx += int(value_length) } - *value = (*value)[:value_length] var result RPC_T_GAP_CAUSE result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_get_conn_info(conn_id uint8, p_conn_info RPC_T_GAP_CONN_INFO) (bool, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_get_conn_info(conn_id uint8, p_conn_info RPC_T_GAP_CONN_INFO) bool { if r.debug { fmt.Printf("rpc_le_get_conn_info()\r\n") } @@ -1682,10 +1239,7 @@ func (r *RTL8720DN) Rpc_le_get_conn_info(conn_id uint8, p_conn_info RPC_T_GAP_CO // conn_id : in uint8 msg = append(msg, byte(conn_id>>0)) - err := r.performRequest(msg) - if err != nil { - return false, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1696,15 +1250,10 @@ func (r *RTL8720DN) Rpc_le_get_conn_info(conn_id uint8, p_conn_info RPC_T_GAP_CO result = binary.LittleEndian.Uint32(payload[widx:]) == 1 r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_get_conn_addr(conn_id uint8, bd_addr *uint8, bd_type *uint8) (bool, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_get_conn_addr(conn_id uint8, bd_addr []uint8, bd_type *uint8) bool { if r.debug { fmt.Printf("rpc_le_get_conn_addr()\r\n") } @@ -1713,16 +1262,13 @@ func (r *RTL8720DN) Rpc_le_get_conn_addr(conn_id uint8, bd_addr *uint8, bd_type // conn_id : in uint8 msg = append(msg, byte(conn_id>>0)) - err := r.performRequest(msg) - if err != nil { - return false, err - } + r.performRequest(msg) r.read() widx := 8 - // bd_addr : out uint8 - *bd_addr = payload[widx] - widx += 1 + // bd_addr : out []uint8 (6) + copy(bd_addr, payload[widx:widx+6]) + widx += 6 // bd_type : out uint8 *bd_type = payload[widx] widx += 1 @@ -1731,29 +1277,21 @@ func (r *RTL8720DN) Rpc_le_get_conn_addr(conn_id uint8, bd_addr *uint8, bd_type result = binary.LittleEndian.Uint32(payload[widx:]) == 1 r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_get_conn_id(bd_addr uint8, bd_type uint8, p_conn_id *uint8) (bool, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_get_conn_id(bd_addr []uint8, bd_type uint8, p_conn_id *uint8) bool { if r.debug { fmt.Printf("rpc_le_get_conn_id()\r\n") } msg := startWriteMessage(0x00, 0x09, 0x04, uint32(r.seq)) - // bd_addr : in uint8 - msg = append(msg, byte(bd_addr>>0)) + // bd_addr : in []uint8 (6) + msg = append(msg, bd_addr...) // bd_type : in uint8 msg = append(msg, byte(bd_type>>0)) - err := r.performRequest(msg) - if err != nil { - return false, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1765,24 +1303,16 @@ func (r *RTL8720DN) Rpc_le_get_conn_id(bd_addr uint8, bd_type uint8, p_conn_id * result = binary.LittleEndian.Uint32(payload[widx:]) == 1 r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_get_active_link_num() (uint8, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_get_active_link_num() uint8 { if r.debug { fmt.Printf("rpc_le_get_active_link_num()\r\n") } msg := startWriteMessage(0x00, 0x09, 0x05, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1790,24 +1320,16 @@ func (r *RTL8720DN) Rpc_le_get_active_link_num() (uint8, error) { result = uint8(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_get_idle_link_num() (uint8, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_get_idle_link_num() uint8 { if r.debug { fmt.Printf("rpc_le_get_idle_link_num()\r\n") } msg := startWriteMessage(0x00, 0x09, 0x06, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1815,15 +1337,10 @@ func (r *RTL8720DN) Rpc_le_get_idle_link_num() (uint8, error) { result = uint8(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_disconnect(conn_id uint8) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_disconnect(conn_id uint8) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_disconnect()\r\n") } @@ -1832,10 +1349,7 @@ func (r *RTL8720DN) Rpc_le_disconnect(conn_id uint8) (RPC_T_GAP_CAUSE, error) { // conn_id : in uint8 msg = append(msg, byte(conn_id>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1844,15 +1358,10 @@ func (r *RTL8720DN) Rpc_le_disconnect(conn_id uint8) (RPC_T_GAP_CAUSE, error) { result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_read_rssi(conn_id uint8) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_read_rssi(conn_id uint8) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_read_rssi()\r\n") } @@ -1861,10 +1370,7 @@ func (r *RTL8720DN) Rpc_le_read_rssi(conn_id uint8) (RPC_T_GAP_CAUSE, error) { // conn_id : in uint8 msg = append(msg, byte(conn_id>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1873,15 +1379,10 @@ func (r *RTL8720DN) Rpc_le_read_rssi(conn_id uint8) (RPC_T_GAP_CAUSE, error) { result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_set_data_len(conn_id uint8, tx_octets uint16, tx_time uint16) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_set_data_len(conn_id uint8, tx_octets uint16, tx_time uint16) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_set_data_len()\r\n") } @@ -1896,10 +1397,7 @@ func (r *RTL8720DN) Rpc_le_set_data_len(conn_id uint8, tx_octets uint16, tx_time msg = append(msg, byte(tx_time>>0)) msg = append(msg, byte(tx_time>>8)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1908,15 +1406,10 @@ func (r *RTL8720DN) Rpc_le_set_data_len(conn_id uint8, tx_octets uint16, tx_time result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_set_phy(conn_id uint8, all_phys uint8, tx_phys uint8, rx_phys uint8, phy_options RPC_T_GAP_PHYS_OPTIONS) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_set_phy(conn_id uint8, all_phys uint8, tx_phys uint8, rx_phys uint8, phy_options RPC_T_GAP_PHYS_OPTIONS) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_set_phy()\r\n") } @@ -1936,10 +1429,7 @@ func (r *RTL8720DN) Rpc_le_set_phy(conn_id uint8, all_phys uint8, tx_phys uint8, msg = append(msg, byte(phy_options>>16)) msg = append(msg, byte(phy_options>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1948,15 +1438,10 @@ func (r *RTL8720DN) Rpc_le_set_phy(conn_id uint8, all_phys uint8, tx_phys uint8, result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_set_conn_param(conn_type RPC_T_GAP_CONN_PARAM_TYPE, p_conn_param RPC_T_GAP_LE_CONN_REQ_PARAM) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_set_conn_param(conn_type RPC_T_GAP_CONN_PARAM_TYPE, p_conn_param RPC_T_GAP_LE_CONN_REQ_PARAM) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_set_conn_param()\r\n") } @@ -1973,10 +1458,7 @@ func (r *RTL8720DN) Rpc_le_set_conn_param(conn_type RPC_T_GAP_CONN_PARAM_TYPE, p msg = append(msg, byte(p_conn_param>>16)) msg = append(msg, byte(p_conn_param>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -1985,15 +1467,10 @@ func (r *RTL8720DN) Rpc_le_set_conn_param(conn_type RPC_T_GAP_CONN_PARAM_TYPE, p result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_connect(init_phys uint8, remote_bd uint8, remote_bd_type RPC_T_GAP_REMOTE_ADDR_TYPE, local_bd_type RPC_T_GAP_LOCAL_ADDR_TYPE, scan_timeout uint16) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_connect(init_phys uint8, remote_bd []uint8, remote_bd_type RPC_T_GAP_REMOTE_ADDR_TYPE, local_bd_type RPC_T_GAP_LOCAL_ADDR_TYPE, scan_timeout uint16) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_connect()\r\n") } @@ -2001,8 +1478,8 @@ func (r *RTL8720DN) Rpc_le_connect(init_phys uint8, remote_bd uint8, remote_bd_t // init_phys : in uint8 msg = append(msg, byte(init_phys>>0)) - // remote_bd : in uint8 - msg = append(msg, byte(remote_bd>>0)) + // remote_bd : in []uint8 (6) + msg = append(msg, remote_bd...) // remote_bd_type : in RPC_T_GAP_REMOTE_ADDR_TYPE msg = append(msg, byte(remote_bd_type>>0)) msg = append(msg, byte(remote_bd_type>>8)) @@ -2017,10 +1494,7 @@ func (r *RTL8720DN) Rpc_le_connect(init_phys uint8, remote_bd uint8, remote_bd_t msg = append(msg, byte(scan_timeout>>0)) msg = append(msg, byte(scan_timeout>>8)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2029,15 +1503,10 @@ func (r *RTL8720DN) Rpc_le_connect(init_phys uint8, remote_bd uint8, remote_bd_t result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_update_conn_param(conn_id uint8, conn_interval_min uint16, conn_interval_max uint16, conn_latency uint16, supervision_timeout uint16, ce_length_min uint16, ce_length_max uint16) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_update_conn_param(conn_id uint8, conn_interval_min uint16, conn_interval_max uint16, conn_latency uint16, supervision_timeout uint16, ce_length_min uint16, ce_length_max uint16) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_le_update_conn_param()\r\n") } @@ -2064,10 +1533,7 @@ func (r *RTL8720DN) Rpc_le_update_conn_param(conn_id uint8, conn_interval_min ui msg = append(msg, byte(ce_length_max>>0)) msg = append(msg, byte(ce_length_max>>8)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2076,15 +1542,10 @@ func (r *RTL8720DN) Rpc_le_update_conn_param(conn_id uint8, conn_interval_min ui result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_flash_save_local_name(p_data RPC_T_LOCAL_NAME) (uint32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_flash_save_local_name(p_data RPC_T_LOCAL_NAME) uint32 { if r.debug { fmt.Printf("rpc_flash_save_local_name()\r\n") } @@ -2096,10 +1557,7 @@ func (r *RTL8720DN) Rpc_flash_save_local_name(p_data RPC_T_LOCAL_NAME) (uint32, msg = append(msg, byte(p_data>>16)) msg = append(msg, byte(p_data>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2108,24 +1566,16 @@ func (r *RTL8720DN) Rpc_flash_save_local_name(p_data RPC_T_LOCAL_NAME) (uint32, result = uint32(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_flash_load_local_name(p_data RPC_T_LOCAL_NAME) (uint32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_flash_load_local_name(p_data RPC_T_LOCAL_NAME) uint32 { if r.debug { fmt.Printf("rpc_flash_load_local_name()\r\n") } msg := startWriteMessage(0x00, 0x0A, 0x02, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2136,15 +1586,10 @@ func (r *RTL8720DN) Rpc_flash_load_local_name(p_data RPC_T_LOCAL_NAME) (uint32, result = uint32(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_flash_save_local_appearance(p_data RPC_T_LOCAL_APPEARANCE) (uint32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_flash_save_local_appearance(p_data RPC_T_LOCAL_APPEARANCE) uint32 { if r.debug { fmt.Printf("rpc_flash_save_local_appearance()\r\n") } @@ -2156,10 +1601,7 @@ func (r *RTL8720DN) Rpc_flash_save_local_appearance(p_data RPC_T_LOCAL_APPEARANC msg = append(msg, byte(p_data>>16)) msg = append(msg, byte(p_data>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2168,24 +1610,16 @@ func (r *RTL8720DN) Rpc_flash_save_local_appearance(p_data RPC_T_LOCAL_APPEARANC result = uint32(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_flash_load_local_appearance(p_data RPC_T_LOCAL_APPEARANCE) (uint32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_flash_load_local_appearance(p_data RPC_T_LOCAL_APPEARANCE) uint32 { if r.debug { fmt.Printf("rpc_flash_load_local_appearance()\r\n") } msg := startWriteMessage(0x00, 0x0A, 0x04, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2196,32 +1630,24 @@ func (r *RTL8720DN) Rpc_flash_load_local_appearance(p_data RPC_T_LOCAL_APPEARANC result = uint32(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_find_key_entry(bd_addr uint8, bd_type RPC_T_GAP_REMOTE_ADDR_TYPE) (RPC_T_LE_KEY_ENTRY, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_find_key_entry(bd_addr []uint8, bd_type RPC_T_GAP_REMOTE_ADDR_TYPE) RPC_T_LE_KEY_ENTRY { if r.debug { fmt.Printf("rpc_le_find_key_entry()\r\n") } msg := startWriteMessage(0x00, 0x0A, 0x05, uint32(r.seq)) - // bd_addr : in uint8 - msg = append(msg, byte(bd_addr>>0)) + // bd_addr : in []uint8 (6) + msg = append(msg, bd_addr...) // bd_type : in RPC_T_GAP_REMOTE_ADDR_TYPE msg = append(msg, byte(bd_type>>0)) msg = append(msg, byte(bd_type>>8)) msg = append(msg, byte(bd_type>>16)) msg = append(msg, byte(bd_type>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2230,15 +1656,10 @@ func (r *RTL8720DN) Rpc_le_find_key_entry(bd_addr uint8, bd_type RPC_T_GAP_REMOT result = RPC_T_LE_KEY_ENTRY(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_find_key_entry_by_idx(idx uint8) (RPC_T_LE_KEY_ENTRY, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_find_key_entry_by_idx(idx uint8) RPC_T_LE_KEY_ENTRY { if r.debug { fmt.Printf("rpc_le_find_key_entry_by_idx()\r\n") } @@ -2247,10 +1668,7 @@ func (r *RTL8720DN) Rpc_le_find_key_entry_by_idx(idx uint8) (RPC_T_LE_KEY_ENTRY, // idx : in uint8 msg = append(msg, byte(idx>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2259,24 +1677,16 @@ func (r *RTL8720DN) Rpc_le_find_key_entry_by_idx(idx uint8) (RPC_T_LE_KEY_ENTRY, result = RPC_T_LE_KEY_ENTRY(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_get_bond_dev_num() (uint8, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_get_bond_dev_num() uint8 { if r.debug { fmt.Printf("rpc_le_get_bond_dev_num()\r\n") } msg := startWriteMessage(0x00, 0x0A, 0x07, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2284,24 +1694,16 @@ func (r *RTL8720DN) Rpc_le_get_bond_dev_num() (uint8, error) { result = uint8(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_get_low_priority_bond() (RPC_T_LE_KEY_ENTRY, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_get_low_priority_bond() RPC_T_LE_KEY_ENTRY { if r.debug { fmt.Printf("rpc_le_get_low_priority_bond()\r\n") } msg := startWriteMessage(0x00, 0x0A, 0x08, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2309,24 +1711,16 @@ func (r *RTL8720DN) Rpc_le_get_low_priority_bond() (RPC_T_LE_KEY_ENTRY, error) { result = RPC_T_LE_KEY_ENTRY(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_get_high_priority_bond() (RPC_T_LE_KEY_ENTRY, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_get_high_priority_bond() RPC_T_LE_KEY_ENTRY { if r.debug { fmt.Printf("rpc_le_get_high_priority_bond()\r\n") } msg := startWriteMessage(0x00, 0x0A, 0x09, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2334,32 +1728,24 @@ func (r *RTL8720DN) Rpc_le_get_high_priority_bond() (RPC_T_LE_KEY_ENTRY, error) result = RPC_T_LE_KEY_ENTRY(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_set_high_priority_bond(bd_addr uint8, bd_type RPC_T_GAP_REMOTE_ADDR_TYPE) (bool, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_set_high_priority_bond(bd_addr []uint8, bd_type RPC_T_GAP_REMOTE_ADDR_TYPE) bool { if r.debug { fmt.Printf("rpc_le_set_high_priority_bond()\r\n") } msg := startWriteMessage(0x00, 0x0A, 0x0A, uint32(r.seq)) - // bd_addr : in uint8 - msg = append(msg, byte(bd_addr>>0)) + // bd_addr : in []uint8 (6) + msg = append(msg, bd_addr...) // bd_type : in RPC_T_GAP_REMOTE_ADDR_TYPE msg = append(msg, byte(bd_type>>0)) msg = append(msg, byte(bd_type>>8)) msg = append(msg, byte(bd_type>>16)) msg = append(msg, byte(bd_type>>24)) - err := r.performRequest(msg) - if err != nil { - return false, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2368,40 +1754,32 @@ func (r *RTL8720DN) Rpc_le_set_high_priority_bond(bd_addr uint8, bd_type RPC_T_G result = binary.LittleEndian.Uint32(payload[widx:]) == 1 r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_resolve_random_address(unresolved_addr uint8, resolved_addr *uint8, resolved_addr_type RPC_T_GAP_IDENT_ADDR_TYPE) (bool, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_resolve_random_address(unresolved_addr []uint8, resolved_addr []uint8, resolved_addr_type RPC_T_GAP_IDENT_ADDR_TYPE) bool { if r.debug { fmt.Printf("rpc_le_resolve_random_address()\r\n") } msg := startWriteMessage(0x00, 0x0A, 0x0B, uint32(r.seq)) - // unresolved_addr : in uint8 - msg = append(msg, byte(unresolved_addr>>0)) - // resolved_addr : inout uint8 - msg = append(msg, byte(*resolved_addr>>0)) + // unresolved_addr : in []uint8 (6) + msg = append(msg, unresolved_addr...) + // resolved_addr : inout []uint8 (6) + msg = append(msg, resolved_addr...) // resolved_addr_type : inout RPC_T_GAP_IDENT_ADDR_TYPE msg = append(msg, byte(resolved_addr_type>>0)) msg = append(msg, byte(resolved_addr_type>>8)) msg = append(msg, byte(resolved_addr_type>>16)) msg = append(msg, byte(resolved_addr_type>>24)) - err := r.performRequest(msg) - if err != nil { - return false, err - } + r.performRequest(msg) r.read() widx := 8 - // resolved_addr : inout uint8 - *resolved_addr = payload[widx] - widx += 1 + // resolved_addr : inout []uint8 (6) + copy(resolved_addr, payload[widx:widx+6]) + widx += 6 // resolved_addr_type : inout RPC_T_GAP_IDENT_ADDR_TYPE // not impl (a.Size() > 0) @@ -2409,15 +1787,10 @@ func (r *RTL8720DN) Rpc_le_resolve_random_address(unresolved_addr uint8, resolve result = binary.LittleEndian.Uint32(payload[widx:]) == 1 r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_get_cccd_data(p_entry RPC_T_LE_KEY_ENTRY, p_data RPC_T_LE_CCCD) (bool, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_get_cccd_data(p_entry RPC_T_LE_KEY_ENTRY, p_data RPC_T_LE_CCCD) bool { if r.debug { fmt.Printf("rpc_le_get_cccd_data()\r\n") } @@ -2429,10 +1802,7 @@ func (r *RTL8720DN) Rpc_le_get_cccd_data(p_entry RPC_T_LE_KEY_ENTRY, p_data RPC_ msg = append(msg, byte(p_entry>>16)) msg = append(msg, byte(p_entry>>24)) - err := r.performRequest(msg) - if err != nil { - return false, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2443,22 +1813,17 @@ func (r *RTL8720DN) Rpc_le_get_cccd_data(p_entry RPC_T_LE_KEY_ENTRY, p_data RPC_ result = binary.LittleEndian.Uint32(payload[widx:]) == 1 r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_gen_bond_dev(bd_addr uint8, bd_type RPC_T_GAP_REMOTE_ADDR_TYPE, local_bd_type RPC_T_GAP_LOCAL_ADDR_TYPE, local_ltk []byte, key_type RPC_T_LE_KEY_TYPE, p_cccd RPC_T_LE_CCCD) (bool, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_gen_bond_dev(bd_addr []uint8, bd_type RPC_T_GAP_REMOTE_ADDR_TYPE, local_bd_type RPC_T_GAP_LOCAL_ADDR_TYPE, local_ltk []byte, key_type RPC_T_LE_KEY_TYPE, p_cccd RPC_T_LE_CCCD) bool { if r.debug { fmt.Printf("rpc_le_gen_bond_dev()\r\n") } msg := startWriteMessage(0x00, 0x0A, 0x0D, uint32(r.seq)) - // bd_addr : in uint8 - msg = append(msg, byte(bd_addr>>0)) + // bd_addr : in []uint8 (6) + msg = append(msg, bd_addr...) // bd_type : in RPC_T_GAP_REMOTE_ADDR_TYPE msg = append(msg, byte(bd_type>>0)) msg = append(msg, byte(bd_type>>8)) @@ -2483,10 +1848,7 @@ func (r *RTL8720DN) Rpc_le_gen_bond_dev(bd_addr uint8, bd_type RPC_T_GAP_REMOTE_ msg = append(msg, byte(p_cccd>>16)) msg = append(msg, byte(p_cccd>>24)) - err := r.performRequest(msg) - if err != nil { - return false, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2495,24 +1857,16 @@ func (r *RTL8720DN) Rpc_le_gen_bond_dev(bd_addr uint8, bd_type RPC_T_GAP_REMOTE_ result = binary.LittleEndian.Uint32(payload[widx:]) == 1 r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_get_dev_bond_info_len() (uint16, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_get_dev_bond_info_len() uint16 { if r.debug { fmt.Printf("rpc_le_get_dev_bond_info_len()\r\n") } msg := startWriteMessage(0x00, 0x0A, 0x0E, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2520,15 +1874,10 @@ func (r *RTL8720DN) Rpc_le_get_dev_bond_info_len() (uint16, error) { result = uint16(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_set_dev_bond_info(p_data []byte, exist *bool) (RPC_T_LE_KEY_ENTRY, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_set_dev_bond_info(p_data []byte, exist *bool) RPC_T_LE_KEY_ENTRY { if r.debug { fmt.Printf("rpc_le_set_dev_bond_info()\r\n") } @@ -2538,10 +1887,7 @@ func (r *RTL8720DN) Rpc_le_set_dev_bond_info(p_data []byte, exist *bool) (RPC_T_ msg = append(msg, byte(len(p_data)), byte(len(p_data)>>8), byte(len(p_data)>>16), byte(len(p_data)>>24)) msg = append(msg, []byte(p_data)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2553,15 +1899,10 @@ func (r *RTL8720DN) Rpc_le_set_dev_bond_info(p_data []byte, exist *bool) (RPC_T_ result = RPC_T_LE_KEY_ENTRY(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_le_get_dev_bond_info(p_entry RPC_T_LE_KEY_ENTRY, p_data *[]byte) (bool, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_le_get_dev_bond_info(p_entry RPC_T_LE_KEY_ENTRY, p_data []byte) bool { if r.debug { fmt.Printf("rpc_le_get_dev_bond_info()\r\n") } @@ -2573,10 +1914,7 @@ func (r *RTL8720DN) Rpc_le_get_dev_bond_info(p_entry RPC_T_LE_KEY_ENTRY, p_data msg = append(msg, byte(p_entry>>16)) msg = append(msg, byte(p_entry>>24)) - err := r.performRequest(msg) - if err != nil { - return false, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2584,24 +1922,18 @@ func (r *RTL8720DN) Rpc_le_get_dev_bond_info(p_entry RPC_T_LE_KEY_ENTRY, p_data p_data_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if p_data_length > 0 { - copy(*p_data, payload[widx:widx+int(p_data_length)]) + copy(p_data, payload[widx:widx+int(p_data_length)]) widx += int(p_data_length) } - *p_data = (*p_data)[:p_data_length] var result bool result = binary.LittleEndian.Uint32(payload[widx:]) == 1 r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_ble_client_init(num uint8) (bool, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_ble_client_init(num uint8) bool { if r.debug { fmt.Printf("rpc_ble_client_init()\r\n") } @@ -2610,10 +1942,7 @@ func (r *RTL8720DN) Rpc_ble_client_init(num uint8) (bool, error) { // num : in uint8 msg = append(msg, byte(num>>0)) - err := r.performRequest(msg) - if err != nil { - return false, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2622,15 +1951,10 @@ func (r *RTL8720DN) Rpc_ble_client_init(num uint8) (bool, error) { result = binary.LittleEndian.Uint32(payload[widx:]) == 1 r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_ble_add_client(app_id uint8, link_num uint8) (uint8, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_ble_add_client(app_id uint8, link_num uint8) uint8 { if r.debug { fmt.Printf("rpc_ble_add_client()\r\n") } @@ -2641,10 +1965,7 @@ func (r *RTL8720DN) Rpc_ble_add_client(app_id uint8, link_num uint8) (uint8, err // link_num : in uint8 msg = append(msg, byte(link_num>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2653,15 +1974,10 @@ func (r *RTL8720DN) Rpc_ble_add_client(app_id uint8, link_num uint8) (uint8, err result = uint8(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_client_init(client_num uint8) error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_client_init(client_num uint8) { if r.debug { fmt.Printf("rpc_client_init()\r\n") } @@ -2670,23 +1986,15 @@ func (r *RTL8720DN) Rpc_client_init(client_num uint8) error { // client_num : in uint8 msg = append(msg, byte(client_num>>0)) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_client_all_primary_srv_discovery(conn_id uint8, client_id uint8) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_client_all_primary_srv_discovery(conn_id uint8, client_id uint8) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_client_all_primary_srv_discovery()\r\n") } @@ -2697,10 +2005,7 @@ func (r *RTL8720DN) Rpc_client_all_primary_srv_discovery(conn_id uint8, client_i // client_id : in uint8 msg = append(msg, byte(client_id>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2709,15 +2014,10 @@ func (r *RTL8720DN) Rpc_client_all_primary_srv_discovery(conn_id uint8, client_i result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_client_by_uuid_srv_discovery(conn_id uint8, client_id uint8, uuid16 uint16) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_client_by_uuid_srv_discovery(conn_id uint8, client_id uint8, uuid16 uint16) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_client_by_uuid_srv_discovery()\r\n") } @@ -2731,10 +2031,7 @@ func (r *RTL8720DN) Rpc_client_by_uuid_srv_discovery(conn_id uint8, client_id ui msg = append(msg, byte(uuid16>>0)) msg = append(msg, byte(uuid16>>8)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2743,15 +2040,10 @@ func (r *RTL8720DN) Rpc_client_by_uuid_srv_discovery(conn_id uint8, client_id ui result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_client_by_uuid128_srv_discovery(conn_id uint8, client_id uint8, p_uuid128 uint8) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_client_by_uuid128_srv_discovery(conn_id uint8, client_id uint8, p_uuid128 []uint8) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_client_by_uuid128_srv_discovery()\r\n") } @@ -2761,13 +2053,10 @@ func (r *RTL8720DN) Rpc_client_by_uuid128_srv_discovery(conn_id uint8, client_id msg = append(msg, byte(conn_id>>0)) // client_id : in uint8 msg = append(msg, byte(client_id>>0)) - // p_uuid128 : in uint8 - msg = append(msg, byte(p_uuid128>>0)) + // p_uuid128 : in []uint8 (16) + msg = append(msg, p_uuid128...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2776,15 +2065,10 @@ func (r *RTL8720DN) Rpc_client_by_uuid128_srv_discovery(conn_id uint8, client_id result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_client_relationship_discovery(conn_id uint8, client_id uint8, start_handle uint16, end_handle uint16) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_client_relationship_discovery(conn_id uint8, client_id uint8, start_handle uint16, end_handle uint16) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_client_relationship_discovery()\r\n") } @@ -2801,10 +2085,7 @@ func (r *RTL8720DN) Rpc_client_relationship_discovery(conn_id uint8, client_id u msg = append(msg, byte(end_handle>>0)) msg = append(msg, byte(end_handle>>8)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2813,15 +2094,10 @@ func (r *RTL8720DN) Rpc_client_relationship_discovery(conn_id uint8, client_id u result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_client_all_char_discovery(conn_id uint8, client_id uint8, start_handle uint16, end_handle uint16) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_client_all_char_discovery(conn_id uint8, client_id uint8, start_handle uint16, end_handle uint16) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_client_all_char_discovery()\r\n") } @@ -2838,10 +2114,7 @@ func (r *RTL8720DN) Rpc_client_all_char_discovery(conn_id uint8, client_id uint8 msg = append(msg, byte(end_handle>>0)) msg = append(msg, byte(end_handle>>8)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2850,15 +2123,10 @@ func (r *RTL8720DN) Rpc_client_all_char_discovery(conn_id uint8, client_id uint8 result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_client_by_uuid_char_discovery(conn_id uint8, client_id uint8, start_handle uint16, end_handle uint16, uuid16 uint16) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_client_by_uuid_char_discovery(conn_id uint8, client_id uint8, start_handle uint16, end_handle uint16, uuid16 uint16) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_client_by_uuid_char_discovery()\r\n") } @@ -2878,10 +2146,7 @@ func (r *RTL8720DN) Rpc_client_by_uuid_char_discovery(conn_id uint8, client_id u msg = append(msg, byte(uuid16>>0)) msg = append(msg, byte(uuid16>>8)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2890,15 +2155,10 @@ func (r *RTL8720DN) Rpc_client_by_uuid_char_discovery(conn_id uint8, client_id u result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_client_by_uuid128_char_discovery(conn_id uint8, client_id uint8, start_handle uint16, end_handle uint16, p_uuid128 uint8) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_client_by_uuid128_char_discovery(conn_id uint8, client_id uint8, start_handle uint16, end_handle uint16, p_uuid128 []uint8) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_client_by_uuid128_char_discovery()\r\n") } @@ -2914,13 +2174,10 @@ func (r *RTL8720DN) Rpc_client_by_uuid128_char_discovery(conn_id uint8, client_i // end_handle : in uint16 msg = append(msg, byte(end_handle>>0)) msg = append(msg, byte(end_handle>>8)) - // p_uuid128 : in uint8 - msg = append(msg, byte(p_uuid128>>0)) + // p_uuid128 : in []uint8 (16) + msg = append(msg, p_uuid128...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2929,15 +2186,10 @@ func (r *RTL8720DN) Rpc_client_by_uuid128_char_discovery(conn_id uint8, client_i result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_client_all_char_descriptor_discovery(conn_id uint8, client_id uint8, start_handle uint16, end_handle uint16) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_client_all_char_descriptor_discovery(conn_id uint8, client_id uint8, start_handle uint16, end_handle uint16) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_client_all_char_descriptor_discovery()\r\n") } @@ -2954,10 +2206,7 @@ func (r *RTL8720DN) Rpc_client_all_char_descriptor_discovery(conn_id uint8, clie msg = append(msg, byte(end_handle>>0)) msg = append(msg, byte(end_handle>>8)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -2966,15 +2215,10 @@ func (r *RTL8720DN) Rpc_client_all_char_descriptor_discovery(conn_id uint8, clie result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_client_attr_read(conn_id uint8, client_id uint8, handle uint16) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_client_attr_read(conn_id uint8, client_id uint8, handle uint16) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_client_attr_read()\r\n") } @@ -2988,10 +2232,7 @@ func (r *RTL8720DN) Rpc_client_attr_read(conn_id uint8, client_id uint8, handle msg = append(msg, byte(handle>>0)) msg = append(msg, byte(handle>>8)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -3000,15 +2241,10 @@ func (r *RTL8720DN) Rpc_client_attr_read(conn_id uint8, client_id uint8, handle result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_client_attr_read_using_uuid(conn_id uint8, client_id uint8, start_handle uint16, end_handle uint16, uuid16 uint16, p_uuid128 uint8) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_client_attr_read_using_uuid(conn_id uint8, client_id uint8, start_handle uint16, end_handle uint16, uuid16 uint16, p_uuid128 []uint8) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_client_attr_read_using_uuid()\r\n") } @@ -3027,13 +2263,10 @@ func (r *RTL8720DN) Rpc_client_attr_read_using_uuid(conn_id uint8, client_id uin // uuid16 : in uint16 msg = append(msg, byte(uuid16>>0)) msg = append(msg, byte(uuid16>>8)) - // p_uuid128 : in uint8 - msg = append(msg, byte(p_uuid128>>0)) + // p_uuid128 : in []uint8 (16) + msg = append(msg, p_uuid128...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -3042,15 +2275,10 @@ func (r *RTL8720DN) Rpc_client_attr_read_using_uuid(conn_id uint8, client_id uin result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_client_attr_write(conn_id uint8, client_id uint8, write_type RPC_T_GATT_WRITE_TYPE, handle uint16, data []byte) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_client_attr_write(conn_id uint8, client_id uint8, write_type RPC_T_GATT_WRITE_TYPE, handle uint16, data []byte) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_client_attr_write()\r\n") } @@ -3072,10 +2300,7 @@ func (r *RTL8720DN) Rpc_client_attr_write(conn_id uint8, client_id uint8, write_ msg = append(msg, byte(len(data)), byte(len(data)>>8), byte(len(data)>>16), byte(len(data)>>24)) msg = append(msg, []byte(data)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -3084,15 +2309,10 @@ func (r *RTL8720DN) Rpc_client_attr_write(conn_id uint8, client_id uint8, write_ result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_client_attr_ind_confirm(conn_id uint8) (RPC_T_GAP_CAUSE, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_client_attr_ind_confirm(conn_id uint8) RPC_T_GAP_CAUSE { if r.debug { fmt.Printf("rpc_client_attr_ind_confirm()\r\n") } @@ -3101,10 +2321,7 @@ func (r *RTL8720DN) Rpc_client_attr_ind_confirm(conn_id uint8) (RPC_T_GAP_CAUSE, // conn_id : in uint8 msg = append(msg, byte(conn_id>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -3113,15 +2330,10 @@ func (r *RTL8720DN) Rpc_client_attr_ind_confirm(conn_id uint8) (RPC_T_GAP_CAUSE, result = RPC_T_GAP_CAUSE(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_ble_server_init(num uint8) (bool, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_ble_server_init(num uint8) bool { if r.debug { fmt.Printf("rpc_ble_server_init()\r\n") } @@ -3130,10 +2342,7 @@ func (r *RTL8720DN) Rpc_ble_server_init(num uint8) (bool, error) { // num : in uint8 msg = append(msg, byte(num>>0)) - err := r.performRequest(msg) - if err != nil { - return false, err - } + r.performRequest(msg) r.read() widx := 8 @@ -3142,22 +2351,17 @@ func (r *RTL8720DN) Rpc_ble_server_init(num uint8) (bool, error) { result = binary.LittleEndian.Uint32(payload[widx:]) == 1 r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_ble_create_service(uuid uint8, uuid_length uint8, is_primary bool) (uint8, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_ble_create_service(uuid []uint8, uuid_length uint8, is_primary bool) uint8 { if r.debug { fmt.Printf("rpc_ble_create_service()\r\n") } msg := startWriteMessage(0x00, 0x0C, 0x02, uint32(r.seq)) - // uuid : in uint8 - msg = append(msg, byte(uuid>>0)) + // uuid : in []uint8 (16) + msg = append(msg, uuid...) // uuid_length : in uint8 msg = append(msg, byte(uuid_length>>0)) // is_primary : in bool @@ -3167,10 +2371,7 @@ func (r *RTL8720DN) Rpc_ble_create_service(uuid uint8, uuid_length uint8, is_pri msg = append(msg, 0) } - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -3179,15 +2380,10 @@ func (r *RTL8720DN) Rpc_ble_create_service(uuid uint8, uuid_length uint8, is_pri result = uint8(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_ble_delete_service(app_id uint8) (bool, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_ble_delete_service(app_id uint8) bool { if r.debug { fmt.Printf("rpc_ble_delete_service()\r\n") } @@ -3196,10 +2392,7 @@ func (r *RTL8720DN) Rpc_ble_delete_service(app_id uint8) (bool, error) { // app_id : in uint8 msg = append(msg, byte(app_id>>0)) - err := r.performRequest(msg) - if err != nil { - return false, err - } + r.performRequest(msg) r.read() widx := 8 @@ -3208,15 +2401,10 @@ func (r *RTL8720DN) Rpc_ble_delete_service(app_id uint8) (bool, error) { result = binary.LittleEndian.Uint32(payload[widx:]) == 1 r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_ble_service_start(app_id uint8) (uint8, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_ble_service_start(app_id uint8) uint8 { if r.debug { fmt.Printf("rpc_ble_service_start()\r\n") } @@ -3225,10 +2413,7 @@ func (r *RTL8720DN) Rpc_ble_service_start(app_id uint8) (uint8, error) { // app_id : in uint8 msg = append(msg, byte(app_id>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -3237,15 +2422,10 @@ func (r *RTL8720DN) Rpc_ble_service_start(app_id uint8) (uint8, error) { result = uint8(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_ble_get_servie_handle(app_id uint8) (uint8, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_ble_get_servie_handle(app_id uint8) uint8 { if r.debug { fmt.Printf("rpc_ble_get_servie_handle()\r\n") } @@ -3254,10 +2434,7 @@ func (r *RTL8720DN) Rpc_ble_get_servie_handle(app_id uint8) (uint8, error) { // app_id : in uint8 msg = append(msg, byte(app_id>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -3266,15 +2443,10 @@ func (r *RTL8720DN) Rpc_ble_get_servie_handle(app_id uint8) (uint8, error) { result = uint8(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_ble_create_char(app_id uint8, uuid uint8, uuid_length uint8, properties uint8, permissions uint32) (uint16, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_ble_create_char(app_id uint8, uuid []uint8, uuid_length uint8, properties uint8, permissions uint32) uint16 { if r.debug { fmt.Printf("rpc_ble_create_char()\r\n") } @@ -3282,8 +2454,8 @@ func (r *RTL8720DN) Rpc_ble_create_char(app_id uint8, uuid uint8, uuid_length ui // app_id : in uint8 msg = append(msg, byte(app_id>>0)) - // uuid : in uint8 - msg = append(msg, byte(uuid>>0)) + // uuid : in []uint8 (16) + msg = append(msg, uuid...) // uuid_length : in uint8 msg = append(msg, byte(uuid_length>>0)) // properties : in uint8 @@ -3294,10 +2466,7 @@ func (r *RTL8720DN) Rpc_ble_create_char(app_id uint8, uuid uint8, uuid_length ui msg = append(msg, byte(permissions>>16)) msg = append(msg, byte(permissions>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -3306,15 +2475,10 @@ func (r *RTL8720DN) Rpc_ble_create_char(app_id uint8, uuid uint8, uuid_length ui result = uint16(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_ble_create_desc(app_id uint8, char_handle uint16, uuid uint8, uuid_length uint8, flags uint8, permissions uint32, value_length uint16, p_value []byte) (uint16, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_ble_create_desc(app_id uint8, char_handle uint16, uuid []uint8, uuid_length uint8, flags uint8, permissions uint32, value_length uint16, p_value []byte) uint16 { if r.debug { fmt.Printf("rpc_ble_create_desc()\r\n") } @@ -3325,8 +2489,8 @@ func (r *RTL8720DN) Rpc_ble_create_desc(app_id uint8, char_handle uint16, uuid u // char_handle : in uint16 msg = append(msg, byte(char_handle>>0)) msg = append(msg, byte(char_handle>>8)) - // uuid : in uint8 - msg = append(msg, byte(uuid>>0)) + // uuid : in []uint8 (16) + msg = append(msg, uuid...) // uuid_length : in uint8 msg = append(msg, byte(uuid_length>>0)) // flags : in uint8 @@ -3348,10 +2512,7 @@ func (r *RTL8720DN) Rpc_ble_create_desc(app_id uint8, char_handle uint16, uuid u msg = append(msg, []byte(p_value)...) } - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -3360,15 +2521,10 @@ func (r *RTL8720DN) Rpc_ble_create_desc(app_id uint8, char_handle uint16, uuid u result = uint16(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_server_send_data(conn_id uint8, service_id uint8, attrib_index uint16, data []byte, pdu_type RPC_T_GATT_PDU_TYPE) (bool, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_server_send_data(conn_id uint8, service_id uint8, attrib_index uint16, data []byte, pdu_type RPC_T_GATT_PDU_TYPE) bool { if r.debug { fmt.Printf("rpc_server_send_data()\r\n") } @@ -3390,10 +2546,7 @@ func (r *RTL8720DN) Rpc_server_send_data(conn_id uint8, service_id uint8, attrib msg = append(msg, byte(pdu_type>>16)) msg = append(msg, byte(pdu_type>>24)) - err := r.performRequest(msg) - if err != nil { - return false, err - } + r.performRequest(msg) r.read() widx := 8 @@ -3402,15 +2555,10 @@ func (r *RTL8720DN) Rpc_server_send_data(conn_id uint8, service_id uint8, attrib result = binary.LittleEndian.Uint32(payload[widx:]) == 1 r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_ble_server_get_attr_value(app_id uint8, attr_handle uint16) ([]byte, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_ble_server_get_attr_value(app_id uint8, attr_handle uint16) []byte { if r.debug { fmt.Printf("rpc_ble_server_get_attr_value()\r\n") } @@ -3422,10 +2570,7 @@ func (r *RTL8720DN) Rpc_ble_server_get_attr_value(app_id uint8, attr_handle uint msg = append(msg, byte(attr_handle>>0)) msg = append(msg, byte(attr_handle>>8)) - err := r.performRequest(msg) - if err != nil { - return nil, err - } + r.performRequest(msg) r.read() widx := 8 @@ -3436,15 +2581,10 @@ func (r *RTL8720DN) Rpc_ble_server_get_attr_value(app_id uint8, attr_handle uint copy(result, payload[widx:result_length]) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_server_exec_write_confirm(conn_id uint8, cause uint16, handle uint16) (bool, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_server_exec_write_confirm(conn_id uint8, cause uint16, handle uint16) bool { if r.debug { fmt.Printf("rpc_server_exec_write_confirm()\r\n") } @@ -3459,10 +2599,7 @@ func (r *RTL8720DN) Rpc_server_exec_write_confirm(conn_id uint8, cause uint16, h msg = append(msg, byte(handle>>0)) msg = append(msg, byte(handle>>8)) - err := r.performRequest(msg) - if err != nil { - return false, err - } + r.performRequest(msg) r.read() widx := 8 @@ -3471,15 +2608,10 @@ func (r *RTL8720DN) Rpc_server_exec_write_confirm(conn_id uint8, cause uint16, h result = binary.LittleEndian.Uint32(payload[widx:]) == 1 r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_server_attr_write_confirm(conn_id uint8, service_id uint8, attrib_index uint16, cause RPC_T_APP_RESULT) (bool, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_server_attr_write_confirm(conn_id uint8, service_id uint8, attrib_index uint16, cause RPC_T_APP_RESULT) bool { if r.debug { fmt.Printf("rpc_server_attr_write_confirm()\r\n") } @@ -3498,10 +2630,7 @@ func (r *RTL8720DN) Rpc_server_attr_write_confirm(conn_id uint8, service_id uint msg = append(msg, byte(cause>>16)) msg = append(msg, byte(cause>>24)) - err := r.performRequest(msg) - if err != nil { - return false, err - } + r.performRequest(msg) r.read() widx := 8 @@ -3510,15 +2639,10 @@ func (r *RTL8720DN) Rpc_server_attr_write_confirm(conn_id uint8, service_id uint result = binary.LittleEndian.Uint32(payload[widx:]) == 1 r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_server_attr_read_confirm(conn_id uint8, service_id uint8, attrib_index uint16, data []byte, cause RPC_T_APP_RESULT) (bool, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_server_attr_read_confirm(conn_id uint8, service_id uint8, attrib_index uint16, data []byte, cause RPC_T_APP_RESULT) bool { if r.debug { fmt.Printf("rpc_server_attr_read_confirm()\r\n") } @@ -3540,10 +2664,7 @@ func (r *RTL8720DN) Rpc_server_attr_read_confirm(conn_id uint8, service_id uint8 msg = append(msg, byte(cause>>16)) msg = append(msg, byte(cause>>24)) - err := r.performRequest(msg) - if err != nil { - return false, err - } + r.performRequest(msg) r.read() widx := 8 @@ -3552,15 +2673,10 @@ func (r *RTL8720DN) Rpc_server_attr_read_confirm(conn_id uint8, service_id uint8 result = binary.LittleEndian.Uint32(payload[widx:]) == 1 r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_ble_handle_gap_msg(gap_msg []byte) (RPC_T_APP_RESULT, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_ble_handle_gap_msg(gap_msg []byte) RPC_T_APP_RESULT { if r.debug { fmt.Printf("rpc_ble_handle_gap_msg()\r\n") } @@ -3570,10 +2686,7 @@ func (r *RTL8720DN) Rpc_ble_handle_gap_msg(gap_msg []byte) (RPC_T_APP_RESULT, er msg = append(msg, byte(len(gap_msg)), byte(len(gap_msg)>>8), byte(len(gap_msg)>>16), byte(len(gap_msg)>>24)) msg = append(msg, []byte(gap_msg)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -3582,15 +2695,10 @@ func (r *RTL8720DN) Rpc_ble_handle_gap_msg(gap_msg []byte) (RPC_T_APP_RESULT, er result = RPC_T_APP_RESULT(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_ble_gap_callback(cb_type uint8, cb_data []byte) (RPC_T_APP_RESULT, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_ble_gap_callback(cb_type uint8, cb_data []byte) RPC_T_APP_RESULT { if r.debug { fmt.Printf("rpc_ble_gap_callback()\r\n") } @@ -3602,10 +2710,7 @@ func (r *RTL8720DN) Rpc_ble_gap_callback(cb_type uint8, cb_data []byte) (RPC_T_A msg = append(msg, byte(len(cb_data)), byte(len(cb_data)>>8), byte(len(cb_data)>>16), byte(len(cb_data)>>24)) msg = append(msg, []byte(cb_data)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -3614,15 +2719,10 @@ func (r *RTL8720DN) Rpc_ble_gap_callback(cb_type uint8, cb_data []byte) (RPC_T_A result = RPC_T_APP_RESULT(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_ble_gattc_callback(gatt_if uint8, conn_id uint8, cb_data []byte, extra_data []byte) (RPC_T_APP_RESULT, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_ble_gattc_callback(gatt_if uint8, conn_id uint8, cb_data []byte, extra_data []byte) RPC_T_APP_RESULT { if r.debug { fmt.Printf("rpc_ble_gattc_callback()\r\n") } @@ -3639,10 +2739,7 @@ func (r *RTL8720DN) Rpc_ble_gattc_callback(gatt_if uint8, conn_id uint8, cb_data msg = append(msg, byte(len(extra_data)), byte(len(extra_data)>>8), byte(len(extra_data)>>16), byte(len(extra_data)>>24)) msg = append(msg, []byte(extra_data)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -3651,15 +2748,10 @@ func (r *RTL8720DN) Rpc_ble_gattc_callback(gatt_if uint8, conn_id uint8, cb_data result = RPC_T_APP_RESULT(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_ble_gatts_callback(gatt_if uint8, conn_id uint8, attrib_index uint16, event RPC_T_SERVICE_CALLBACK_TYPE, property uint16, read_cb_data *[]byte, write_cb_data []byte, app_cb_data []byte) (RPC_T_APP_RESULT, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_ble_gatts_callback(gatt_if uint8, conn_id uint8, attrib_index uint16, event RPC_T_SERVICE_CALLBACK_TYPE, property uint16, read_cb_data []byte, write_cb_data []byte, app_cb_data []byte) RPC_T_APP_RESULT { if r.debug { fmt.Printf("rpc_ble_gatts_callback()\r\n") } @@ -3697,10 +2789,7 @@ func (r *RTL8720DN) Rpc_ble_gatts_callback(gatt_if uint8, conn_id uint8, attrib_ msg = append(msg, []byte(app_cb_data)...) } - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -3712,24 +2801,18 @@ func (r *RTL8720DN) Rpc_ble_gatts_callback(gatt_if uint8, conn_id uint8, attrib_ widx += 4 } if read_cb_data_length > 0 { - copy(*read_cb_data, payload[widx:widx+int(read_cb_data_length)]) + copy(read_cb_data, payload[widx:widx+int(read_cb_data_length)]) widx += int(read_cb_data_length) } - *read_cb_data = (*read_cb_data)[:read_cb_data_length] var result RPC_T_APP_RESULT result = RPC_T_APP_RESULT(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_connect(ssid string, password string, security_type uint32, key_id int32, semaphore uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_connect(ssid string, password string, security_type uint32, key_id int32, semaphore uint32) int32 { if r.debug { fmt.Printf("rpc_wifi_connect()\r\n") } @@ -3762,33 +2845,20 @@ func (r *RTL8720DN) Rpc_wifi_connect(ssid string, password string, security_type msg = append(msg, byte(semaphore>>16)) msg = append(msg, byte(semaphore>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_connect_bssid(bssid []byte, ssid string, password string, security_type uint32, key_id int32, semaphore uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_connect_bssid(bssid []byte, ssid string, password string, security_type uint32, key_id int32, semaphore uint32) int32 { if r.debug { fmt.Printf("rpc_wifi_connect_bssid()\r\n") } @@ -3824,95 +2894,56 @@ func (r *RTL8720DN) Rpc_wifi_connect_bssid(bssid []byte, ssid string, password s msg = append(msg, byte(semaphore>>16)) msg = append(msg, byte(semaphore>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_disconnect() (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_disconnect() int32 { if r.debug { fmt.Printf("rpc_wifi_disconnect()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x03, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_is_connected_to_ap() (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_is_connected_to_ap() int32 { if r.debug { fmt.Printf("rpc_wifi_is_connected_to_ap()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x04, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_is_up(itf uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_is_up(itf uint32) int32 { if r.debug { fmt.Printf("rpc_wifi_is_up()\r\n") } @@ -3924,33 +2955,20 @@ func (r *RTL8720DN) Rpc_wifi_is_up(itf uint32) (int32, error) { msg = append(msg, byte(itf>>16)) msg = append(msg, byte(itf>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_is_ready_to_transceive(itf uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_is_ready_to_transceive(itf uint32) int32 { if r.debug { fmt.Printf("rpc_wifi_is_ready_to_transceive()\r\n") } @@ -3962,33 +2980,20 @@ func (r *RTL8720DN) Rpc_wifi_is_ready_to_transceive(itf uint32) (int32, error) { msg = append(msg, byte(itf>>16)) msg = append(msg, byte(itf>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_set_mac_address(mac []byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_set_mac_address(mac []byte) int32 { if r.debug { fmt.Printf("rpc_wifi_set_mac_address()\r\n") } @@ -3998,205 +3003,124 @@ func (r *RTL8720DN) Rpc_wifi_set_mac_address(mac []byte) (int32, error) { msg = append(msg, byte(len(mac)), byte(len(mac)>>8), byte(len(mac)>>16), byte(len(mac)>>24)) msg = append(msg, []byte(mac)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_get_mac_address(mac *uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_get_mac_address(mac []uint8) int32 { if r.debug { fmt.Printf("rpc_wifi_get_mac_address()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x08, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 - // mac : out uint8 - *mac = payload[widx] - widx += 1 + // mac : out []uint8 (18) + copy(mac, payload[widx:widx+18]) + widx += 18 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_enable_powersave() (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_enable_powersave() int32 { if r.debug { fmt.Printf("rpc_wifi_enable_powersave()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x09, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_resume_powersave() (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_resume_powersave() int32 { if r.debug { fmt.Printf("rpc_wifi_resume_powersave()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x0A, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_disable_powersave() (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_disable_powersave() int32 { if r.debug { fmt.Printf("rpc_wifi_disable_powersave()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x0B, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_btcoex_set_bt_on() error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_btcoex_set_bt_on() { if r.debug { fmt.Printf("rpc_wifi_btcoex_set_bt_on()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x0C, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_wifi_btcoex_set_bt_off() error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_btcoex_set_bt_off() { if r.debug { fmt.Printf("rpc_wifi_btcoex_set_bt_off()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x0D, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_wifi_get_associated_client_list(client_list_buffer *[]byte, buffer_length uint16) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_get_associated_client_list(client_list_buffer []byte, buffer_length uint16) int32 { if r.debug { fmt.Printf("rpc_wifi_get_associated_client_list()\r\n") } @@ -4206,10 +3130,7 @@ func (r *RTL8720DN) Rpc_wifi_get_associated_client_list(client_list_buffer *[]by msg = append(msg, byte(buffer_length>>0)) msg = append(msg, byte(buffer_length>>8)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -4217,74 +3138,47 @@ func (r *RTL8720DN) Rpc_wifi_get_associated_client_list(client_list_buffer *[]by client_list_buffer_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if client_list_buffer_length > 0 { - copy(*client_list_buffer, payload[widx:widx+int(client_list_buffer_length)]) + copy(client_list_buffer, payload[widx:widx+int(client_list_buffer_length)]) widx += int(client_list_buffer_length) } - *client_list_buffer = (*client_list_buffer)[:client_list_buffer_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_get_ap_bssid(bssid *uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_get_ap_bssid(bssid []uint8) int32 { if r.debug { fmt.Printf("rpc_wifi_get_ap_bssid()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x0F, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 - // bssid : out uint8 - *bssid = payload[widx] - widx += 1 + // bssid : out []uint8 (6) + copy(bssid, payload[widx:widx+6]) + widx += 6 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_get_ap_info(ap_info *[]byte, security *uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_get_ap_info(ap_info []byte, security *uint32) int32 { if r.debug { fmt.Printf("rpc_wifi_get_ap_info()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x10, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -4292,33 +3186,22 @@ func (r *RTL8720DN) Rpc_wifi_get_ap_info(ap_info *[]byte, security *uint32) (int ap_info_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if ap_info_length > 0 { - copy(*ap_info, payload[widx:widx+int(ap_info_length)]) + copy(ap_info, payload[widx:widx+int(ap_info_length)]) widx += int(ap_info_length) } - *ap_info = (*ap_info)[:ap_info_length] // security : out uint32 *security = binary.LittleEndian.Uint32(payload[widx:]) widx += 4 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_set_country(country_code uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_set_country(country_code uint32) int32 { if r.debug { fmt.Printf("rpc_wifi_set_country()\r\n") } @@ -4330,42 +3213,26 @@ func (r *RTL8720DN) Rpc_wifi_set_country(country_code uint32) (int32, error) { msg = append(msg, byte(country_code>>16)) msg = append(msg, byte(country_code>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_get_sta_max_data_rate(inidata_rate *uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_get_sta_max_data_rate(inidata_rate *uint8) int32 { if r.debug { fmt.Printf("rpc_wifi_get_sta_max_data_rate()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x12, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -4375,32 +3242,19 @@ func (r *RTL8720DN) Rpc_wifi_get_sta_max_data_rate(inidata_rate *uint8) (int32, var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_get_rssi(pRSSI *int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_get_rssi(pRSSI *int32) int32 { if r.debug { fmt.Printf("rpc_wifi_get_rssi()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x13, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -4410,23 +3264,13 @@ func (r *RTL8720DN) Rpc_wifi_get_rssi(pRSSI *int32) (int32, error) { var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_set_channel(channel int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_set_channel(channel int32) int32 { if r.debug { fmt.Printf("rpc_wifi_set_channel()\r\n") } @@ -4438,42 +3282,26 @@ func (r *RTL8720DN) Rpc_wifi_set_channel(channel int32) (int32, error) { msg = append(msg, byte(channel>>16)) msg = append(msg, byte(channel>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_get_channel(channel *int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_get_channel(channel *int32) int32 { if r.debug { fmt.Printf("rpc_wifi_get_channel()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x15, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -4483,23 +3311,13 @@ func (r *RTL8720DN) Rpc_wifi_get_channel(channel *int32) (int32, error) { var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_change_channel_plan(channel_plan uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_change_channel_plan(channel_plan uint8) int32 { if r.debug { fmt.Printf("rpc_wifi_change_channel_plan()\r\n") } @@ -4508,165 +3326,100 @@ func (r *RTL8720DN) Rpc_wifi_change_channel_plan(channel_plan uint8) (int32, err // channel_plan : in uint8 msg = append(msg, byte(channel_plan>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_register_multicast_address(mac uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_register_multicast_address(mac []uint8) int32 { if r.debug { fmt.Printf("rpc_wifi_register_multicast_address()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x17, uint32(r.seq)) - // mac : in uint8 - msg = append(msg, byte(mac>>0)) + // mac : in []uint8 (6) + msg = append(msg, mac...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_unregister_multicast_address(mac uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_unregister_multicast_address(mac []uint8) int32 { if r.debug { fmt.Printf("rpc_wifi_unregister_multicast_address()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x18, uint32(r.seq)) - // mac : in uint8 - msg = append(msg, byte(mac>>0)) + // mac : in []uint8 (6) + msg = append(msg, mac...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_rf_on() (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_rf_on() int32 { if r.debug { fmt.Printf("rpc_wifi_rf_on()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x19, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_rf_off() (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_rf_off() int32 { if r.debug { fmt.Printf("rpc_wifi_rf_off()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x1A, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_on(mode uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_on(mode uint32) int32 { if r.debug { fmt.Printf("rpc_wifi_on()\r\n") } @@ -4678,64 +3431,38 @@ func (r *RTL8720DN) Rpc_wifi_on(mode uint32) (int32, error) { msg = append(msg, byte(mode>>16)) msg = append(msg, byte(mode>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_off() (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_off() int32 { if r.debug { fmt.Printf("rpc_wifi_off()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x1C, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_set_mode(mode uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_set_mode(mode uint32) int32 { if r.debug { fmt.Printf("rpc_wifi_set_mode()\r\n") } @@ -4747,64 +3474,38 @@ func (r *RTL8720DN) Rpc_wifi_set_mode(mode uint32) (int32, error) { msg = append(msg, byte(mode>>16)) msg = append(msg, byte(mode>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_off_fastly() (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_off_fastly() int32 { if r.debug { fmt.Printf("rpc_wifi_off_fastly()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x1E, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_set_power_mode(ips_mode uint8, lps_mode uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_set_power_mode(ips_mode uint8, lps_mode uint8) int32 { if r.debug { fmt.Printf("rpc_wifi_set_power_mode()\r\n") } @@ -4815,33 +3516,20 @@ func (r *RTL8720DN) Rpc_wifi_set_power_mode(ips_mode uint8, lps_mode uint8) (int // lps_mode : in uint8 msg = append(msg, byte(lps_mode>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_set_tdma_param(slot_period uint8, rfon_period_len_1 uint8, rfon_period_len_2 uint8, rfon_period_len_3 uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_set_tdma_param(slot_period uint8, rfon_period_len_1 uint8, rfon_period_len_2 uint8, rfon_period_len_3 uint8) int32 { if r.debug { fmt.Printf("rpc_wifi_set_tdma_param()\r\n") } @@ -4856,33 +3544,20 @@ func (r *RTL8720DN) Rpc_wifi_set_tdma_param(slot_period uint8, rfon_period_len_1 // rfon_period_len_3 : in uint8 msg = append(msg, byte(rfon_period_len_3>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_set_lps_dtim(dtim uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_set_lps_dtim(dtim uint8) int32 { if r.debug { fmt.Printf("rpc_wifi_set_lps_dtim()\r\n") } @@ -4891,42 +3566,26 @@ func (r *RTL8720DN) Rpc_wifi_set_lps_dtim(dtim uint8) (int32, error) { // dtim : in uint8 msg = append(msg, byte(dtim>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_get_lps_dtim(dtim *uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_get_lps_dtim(dtim *uint8) int32 { if r.debug { fmt.Printf("rpc_wifi_get_lps_dtim()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x22, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -4936,23 +3595,13 @@ func (r *RTL8720DN) Rpc_wifi_get_lps_dtim(dtim *uint8) (int32, error) { var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_set_lps_thresh(mode uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_set_lps_thresh(mode uint8) int32 { if r.debug { fmt.Printf("rpc_wifi_set_lps_thresh()\r\n") } @@ -4961,33 +3610,20 @@ func (r *RTL8720DN) Rpc_wifi_set_lps_thresh(mode uint8) (int32, error) { // mode : in uint8 msg = append(msg, byte(mode>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_set_lps_level(lps_level uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_set_lps_level(lps_level uint8) int32 { if r.debug { fmt.Printf("rpc_wifi_set_lps_level()\r\n") } @@ -4996,33 +3632,20 @@ func (r *RTL8720DN) Rpc_wifi_set_lps_level(lps_level uint8) (int32, error) { // lps_level : in uint8 msg = append(msg, byte(lps_level>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_set_mfp_support(value uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_set_mfp_support(value uint8) int32 { if r.debug { fmt.Printf("rpc_wifi_set_mfp_support()\r\n") } @@ -5031,33 +3654,20 @@ func (r *RTL8720DN) Rpc_wifi_set_mfp_support(value uint8) (int32, error) { // value : in uint8 msg = append(msg, byte(value>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_start_ap(ssid string, password string, security_type uint32, channel int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_start_ap(ssid string, password string, security_type uint32, channel int32) int32 { if r.debug { fmt.Printf("rpc_wifi_start_ap()\r\n") } @@ -5085,33 +3695,20 @@ func (r *RTL8720DN) Rpc_wifi_start_ap(ssid string, password string, security_typ msg = append(msg, byte(channel>>16)) msg = append(msg, byte(channel>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_start_ap_with_hidden_ssid(ssid string, password string, security_type uint32, channel int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_start_ap_with_hidden_ssid(ssid string, password string, security_type uint32, channel int32) int32 { if r.debug { fmt.Printf("rpc_wifi_start_ap_with_hidden_ssid()\r\n") } @@ -5139,33 +3736,20 @@ func (r *RTL8720DN) Rpc_wifi_start_ap_with_hidden_ssid(ssid string, password str msg = append(msg, byte(channel>>16)) msg = append(msg, byte(channel>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_set_pscan_chan(channel_list []byte, pscan_config uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_set_pscan_chan(channel_list []byte, pscan_config uint8) int32 { if r.debug { fmt.Printf("rpc_wifi_set_pscan_chan()\r\n") } @@ -5177,33 +3761,20 @@ func (r *RTL8720DN) Rpc_wifi_set_pscan_chan(channel_list []byte, pscan_config ui // pscan_config : in uint8 msg = append(msg, byte(pscan_config>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_get_setting(ifname string, pSetting *[]byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_get_setting(ifname string, pSetting []byte) int32 { if r.debug { fmt.Printf("rpc_wifi_get_setting()\r\n") } @@ -5213,10 +3784,7 @@ func (r *RTL8720DN) Rpc_wifi_get_setting(ifname string, pSetting *[]byte) (int32 msg = append(msg, byte(len(ifname)), byte(len(ifname)>>8), byte(len(ifname)>>16), byte(len(ifname)>>24)) msg = append(msg, []byte(ifname)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -5224,30 +3792,19 @@ func (r *RTL8720DN) Rpc_wifi_get_setting(ifname string, pSetting *[]byte) (int32 pSetting_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if pSetting_length > 0 { - copy(*pSetting, payload[widx:widx+int(pSetting_length)]) + copy(pSetting, payload[widx:widx+int(pSetting_length)]) widx += int(pSetting_length) } - *pSetting = (*pSetting)[:pSetting_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_set_network_mode(mode uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_set_network_mode(mode uint32) int32 { if r.debug { fmt.Printf("rpc_wifi_set_network_mode()\r\n") } @@ -5259,42 +3816,26 @@ func (r *RTL8720DN) Rpc_wifi_set_network_mode(mode uint32) (int32, error) { msg = append(msg, byte(mode>>16)) msg = append(msg, byte(mode>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_get_network_mode(pmode *uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_get_network_mode(pmode *uint32) int32 { if r.debug { fmt.Printf("rpc_wifi_get_network_mode()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x2B, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -5304,23 +3845,13 @@ func (r *RTL8720DN) Rpc_wifi_get_network_mode(pmode *uint32) (int32, error) { var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_set_wps_phase(is_trigger_wps uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_set_wps_phase(is_trigger_wps uint8) int32 { if r.debug { fmt.Printf("rpc_wifi_set_wps_phase()\r\n") } @@ -5329,33 +3860,20 @@ func (r *RTL8720DN) Rpc_wifi_set_wps_phase(is_trigger_wps uint8) (int32, error) // is_trigger_wps : in uint8 msg = append(msg, byte(is_trigger_wps>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_restart_ap(ssid []byte, password []byte, security_type uint32, channel int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_restart_ap(ssid []byte, password []byte, security_type uint32, channel int32) int32 { if r.debug { fmt.Printf("rpc_wifi_restart_ap()\r\n") } @@ -5378,33 +3896,20 @@ func (r *RTL8720DN) Rpc_wifi_restart_ap(ssid []byte, password []byte, security_t msg = append(msg, byte(channel>>16)) msg = append(msg, byte(channel>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_config_autoreconnect(mode uint8, retry_times uint8, timeout uint16) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_config_autoreconnect(mode uint8, retry_times uint8, timeout uint16) int32 { if r.debug { fmt.Printf("rpc_wifi_config_autoreconnect()\r\n") } @@ -5418,33 +3923,20 @@ func (r *RTL8720DN) Rpc_wifi_config_autoreconnect(mode uint8, retry_times uint8, msg = append(msg, byte(timeout>>0)) msg = append(msg, byte(timeout>>8)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_set_autoreconnect(mode uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_set_autoreconnect(mode uint8) int32 { if r.debug { fmt.Printf("rpc_wifi_set_autoreconnect()\r\n") } @@ -5453,42 +3945,26 @@ func (r *RTL8720DN) Rpc_wifi_set_autoreconnect(mode uint8) (int32, error) { // mode : in uint8 msg = append(msg, byte(mode>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_get_autoreconnect(mode *uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_get_autoreconnect(mode *uint8) int32 { if r.debug { fmt.Printf("rpc_wifi_get_autoreconnect()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x30, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -5498,54 +3974,31 @@ func (r *RTL8720DN) Rpc_wifi_get_autoreconnect(mode *uint8) (int32, error) { var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_get_last_error() (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_get_last_error() int32 { if r.debug { fmt.Printf("rpc_wifi_get_last_error()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x31, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_add_custom_ie(cus_ie []byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_add_custom_ie(cus_ie []byte) int32 { if r.debug { fmt.Printf("rpc_wifi_add_custom_ie()\r\n") } @@ -5555,33 +4008,20 @@ func (r *RTL8720DN) Rpc_wifi_add_custom_ie(cus_ie []byte) (int32, error) { msg = append(msg, byte(len(cus_ie)), byte(len(cus_ie)>>8), byte(len(cus_ie)>>16), byte(len(cus_ie)>>24)) msg = append(msg, []byte(cus_ie)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_update_custom_ie(cus_ie []byte, ie_index int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_update_custom_ie(cus_ie []byte, ie_index int32) int32 { if r.debug { fmt.Printf("rpc_wifi_update_custom_ie()\r\n") } @@ -5596,64 +4036,38 @@ func (r *RTL8720DN) Rpc_wifi_update_custom_ie(cus_ie []byte, ie_index int32) (in msg = append(msg, byte(ie_index>>16)) msg = append(msg, byte(ie_index>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_del_custom_ie() (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_del_custom_ie() int32 { if r.debug { fmt.Printf("rpc_wifi_del_custom_ie()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x34, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_set_indicate_mgnt(enable int32) error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_set_indicate_mgnt(enable int32) { if r.debug { fmt.Printf("rpc_wifi_set_indicate_mgnt()\r\n") } @@ -5665,32 +4079,21 @@ func (r *RTL8720DN) Rpc_wifi_set_indicate_mgnt(enable int32) error { msg = append(msg, byte(enable>>16)) msg = append(msg, byte(enable>>24)) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_wifi_get_drv_ability(ability *uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_get_drv_ability(ability *uint32) int32 { if r.debug { fmt.Printf("rpc_wifi_get_drv_ability()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x36, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -5700,23 +4103,13 @@ func (r *RTL8720DN) Rpc_wifi_get_drv_ability(ability *uint32) (int32, error) { var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_set_channel_plan(channel_plan uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_set_channel_plan(channel_plan uint8) int32 { if r.debug { fmt.Printf("rpc_wifi_set_channel_plan()\r\n") } @@ -5725,42 +4118,26 @@ func (r *RTL8720DN) Rpc_wifi_set_channel_plan(channel_plan uint8) (int32, error) // channel_plan : in uint8 msg = append(msg, byte(channel_plan>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_get_channel_plan(channel_plan *uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_get_channel_plan(channel_plan *uint8) int32 { if r.debug { fmt.Printf("rpc_wifi_get_channel_plan()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x38, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -5770,85 +4147,49 @@ func (r *RTL8720DN) Rpc_wifi_get_channel_plan(channel_plan *uint8) (int32, error var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_enable_forwarding() (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_enable_forwarding() int32 { if r.debug { fmt.Printf("rpc_wifi_enable_forwarding()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x39, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_disable_forwarding() (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_disable_forwarding() int32 { if r.debug { fmt.Printf("rpc_wifi_disable_forwarding()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x3A, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_set_ch_deauth(enable uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_set_ch_deauth(enable uint8) int32 { if r.debug { fmt.Printf("rpc_wifi_set_ch_deauth()\r\n") } @@ -5857,42 +4198,26 @@ func (r *RTL8720DN) Rpc_wifi_set_ch_deauth(enable uint8) (int32, error) { // enable : in uint8 msg = append(msg, byte(enable>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_get_band_type() (uint8, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_get_band_type() uint8 { if r.debug { fmt.Printf("rpc_wifi_get_band_type()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x3C, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -5900,15 +4225,10 @@ func (r *RTL8720DN) Rpc_wifi_get_band_type() (uint8, error) { result = uint8(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_set_tx_pause_data(NewState uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_set_tx_pause_data(NewState uint32) int32 { if r.debug { fmt.Printf("rpc_wifi_set_tx_pause_data()\r\n") } @@ -5920,42 +4240,26 @@ func (r *RTL8720DN) Rpc_wifi_set_tx_pause_data(NewState uint32) (int32, error) { msg = append(msg, byte(NewState>>16)) msg = append(msg, byte(NewState>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_get_reconnect_data(wifi_info *[]byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_get_reconnect_data(wifi_info []byte) int32 { if r.debug { fmt.Printf("rpc_wifi_get_reconnect_data()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x3E, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -5963,101 +4267,61 @@ func (r *RTL8720DN) Rpc_wifi_get_reconnect_data(wifi_info *[]byte) (int32, error wifi_info_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if wifi_info_length > 0 { - copy(*wifi_info, payload[widx:widx+int(wifi_info_length)]) + copy(wifi_info, payload[widx:widx+int(wifi_info_length)]) widx += int(wifi_info_length) } - *wifi_info = (*wifi_info)[:wifi_info_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_clear_reconnect_data() (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_clear_reconnect_data() int32 { if r.debug { fmt.Printf("rpc_wifi_clear_reconnect_data()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x3F, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_scan_start() (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_scan_start() int32 { if r.debug { fmt.Printf("rpc_wifi_scan_start()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x40, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_is_scaning() (bool, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_is_scaning() bool { if r.debug { fmt.Printf("rpc_wifi_is_scaning()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x41, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return false, err - } + r.performRequest(msg) r.read() widx := 8 @@ -6065,15 +4329,10 @@ func (r *RTL8720DN) Rpc_wifi_is_scaning() (bool, error) { result = binary.LittleEndian.Uint32(payload[widx:]) == 1 r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_scan_get_ap_records(number uint16, _scanResult *[]byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_scan_get_ap_records(number uint16, _scanResult []byte) int32 { if r.debug { fmt.Printf("rpc_wifi_scan_get_ap_records()\r\n") } @@ -6083,10 +4342,7 @@ func (r *RTL8720DN) Rpc_wifi_scan_get_ap_records(number uint16, _scanResult *[]b msg = append(msg, byte(number>>0)) msg = append(msg, byte(number>>8)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -6094,39 +4350,25 @@ func (r *RTL8720DN) Rpc_wifi_scan_get_ap_records(number uint16, _scanResult *[]b _scanResult_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if _scanResult_length > 0 { - copy(*_scanResult, payload[widx:widx+int(_scanResult_length)]) + copy(_scanResult, payload[widx:widx+int(_scanResult_length)]) widx += int(_scanResult_length) } - *_scanResult = (*_scanResult)[:_scanResult_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_scan_get_ap_num() (uint16, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_scan_get_ap_num() uint16 { if r.debug { fmt.Printf("rpc_wifi_scan_get_ap_num()\r\n") } msg := startWriteMessage(0x00, 0x0E, 0x43, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -6134,46 +4376,28 @@ func (r *RTL8720DN) Rpc_wifi_scan_get_ap_num() (uint16, error) { result = uint16(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcpip_adapter_init() (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcpip_adapter_init() int32 { if r.debug { fmt.Printf("rpc_tcpip_adapter_init()\r\n") } msg := startWriteMessage(0x00, 0x0F, 0x01, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcpip_adapter_sta_start(mac []byte, ip_info []byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcpip_adapter_sta_start(mac []byte, ip_info []byte) int32 { if r.debug { fmt.Printf("rpc_tcpip_adapter_sta_start()\r\n") } @@ -6186,33 +4410,20 @@ func (r *RTL8720DN) Rpc_tcpip_adapter_sta_start(mac []byte, ip_info []byte) (int msg = append(msg, byte(len(ip_info)), byte(len(ip_info)>>8), byte(len(ip_info)>>16), byte(len(ip_info)>>24)) msg = append(msg, []byte(ip_info)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcpip_adapter_ap_start(mac []byte, ip_info []byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcpip_adapter_ap_start(mac []byte, ip_info []byte) int32 { if r.debug { fmt.Printf("rpc_tcpip_adapter_ap_start()\r\n") } @@ -6225,33 +4436,20 @@ func (r *RTL8720DN) Rpc_tcpip_adapter_ap_start(mac []byte, ip_info []byte) (int3 msg = append(msg, byte(len(ip_info)), byte(len(ip_info)>>8), byte(len(ip_info)>>16), byte(len(ip_info)>>24)) msg = append(msg, []byte(ip_info)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcpip_adapter_stop(tcpip_if uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcpip_adapter_stop(tcpip_if uint32) int32 { if r.debug { fmt.Printf("rpc_tcpip_adapter_stop()\r\n") } @@ -6263,33 +4461,20 @@ func (r *RTL8720DN) Rpc_tcpip_adapter_stop(tcpip_if uint32) (int32, error) { msg = append(msg, byte(tcpip_if>>16)) msg = append(msg, byte(tcpip_if>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcpip_adapter_up(tcpip_if uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcpip_adapter_up(tcpip_if uint32) int32 { if r.debug { fmt.Printf("rpc_tcpip_adapter_up()\r\n") } @@ -6301,33 +4486,20 @@ func (r *RTL8720DN) Rpc_tcpip_adapter_up(tcpip_if uint32) (int32, error) { msg = append(msg, byte(tcpip_if>>16)) msg = append(msg, byte(tcpip_if>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcpip_adapter_down(tcpip_if uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcpip_adapter_down(tcpip_if uint32) int32 { if r.debug { fmt.Printf("rpc_tcpip_adapter_down()\r\n") } @@ -6339,33 +4511,20 @@ func (r *RTL8720DN) Rpc_tcpip_adapter_down(tcpip_if uint32) (int32, error) { msg = append(msg, byte(tcpip_if>>16)) msg = append(msg, byte(tcpip_if>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcpip_adapter_get_ip_info(tcpip_if uint32, ip_info *[]byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcpip_adapter_get_ip_info(tcpip_if uint32, ip_info []byte) int32 { if r.debug { fmt.Printf("rpc_tcpip_adapter_get_ip_info()\r\n") } @@ -6377,10 +4536,7 @@ func (r *RTL8720DN) Rpc_tcpip_adapter_get_ip_info(tcpip_if uint32, ip_info *[]by msg = append(msg, byte(tcpip_if>>16)) msg = append(msg, byte(tcpip_if>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -6388,30 +4544,19 @@ func (r *RTL8720DN) Rpc_tcpip_adapter_get_ip_info(tcpip_if uint32, ip_info *[]by ip_info_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if ip_info_length > 0 { - copy(*ip_info, payload[widx:widx+int(ip_info_length)]) + copy(ip_info, payload[widx:widx+int(ip_info_length)]) widx += int(ip_info_length) } - *ip_info = (*ip_info)[:ip_info_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcpip_adapter_set_ip_info(tcpip_if uint32, ip_info []byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcpip_adapter_set_ip_info(tcpip_if uint32, ip_info []byte) int32 { if r.debug { fmt.Printf("rpc_tcpip_adapter_set_ip_info()\r\n") } @@ -6426,33 +4571,20 @@ func (r *RTL8720DN) Rpc_tcpip_adapter_set_ip_info(tcpip_if uint32, ip_info []byt msg = append(msg, byte(len(ip_info)), byte(len(ip_info)>>8), byte(len(ip_info)>>16), byte(len(ip_info)>>24)) msg = append(msg, []byte(ip_info)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcpip_adapter_set_dns_info(tcpip_if uint32, dns_type uint32, dns []byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcpip_adapter_set_dns_info(tcpip_if uint32, dns_type uint32, dns []byte) int32 { if r.debug { fmt.Printf("rpc_tcpip_adapter_set_dns_info()\r\n") } @@ -6472,33 +4604,20 @@ func (r *RTL8720DN) Rpc_tcpip_adapter_set_dns_info(tcpip_if uint32, dns_type uin msg = append(msg, byte(len(dns)), byte(len(dns)>>8), byte(len(dns)>>16), byte(len(dns)>>24)) msg = append(msg, []byte(dns)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcpip_adapter_get_dns_info(tcpip_if uint32, dns_type uint32, dns *[]byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcpip_adapter_get_dns_info(tcpip_if uint32, dns_type uint32, dns []byte) int32 { if r.debug { fmt.Printf("rpc_tcpip_adapter_get_dns_info()\r\n") } @@ -6515,10 +4634,7 @@ func (r *RTL8720DN) Rpc_tcpip_adapter_get_dns_info(tcpip_if uint32, dns_type uin msg = append(msg, byte(dns_type>>16)) msg = append(msg, byte(dns_type>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -6526,30 +4642,19 @@ func (r *RTL8720DN) Rpc_tcpip_adapter_get_dns_info(tcpip_if uint32, dns_type uin dns_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if dns_length > 0 { - copy(*dns, payload[widx:widx+int(dns_length)]) + copy(dns, payload[widx:widx+int(dns_length)]) widx += int(dns_length) } - *dns = (*dns)[:dns_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcpip_adapter_dhcps_start(tcpip_if uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcpip_adapter_dhcps_start(tcpip_if uint32) int32 { if r.debug { fmt.Printf("rpc_tcpip_adapter_dhcps_start()\r\n") } @@ -6561,33 +4666,20 @@ func (r *RTL8720DN) Rpc_tcpip_adapter_dhcps_start(tcpip_if uint32) (int32, error msg = append(msg, byte(tcpip_if>>16)) msg = append(msg, byte(tcpip_if>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcpip_adapter_dhcps_stop(tcpip_if uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcpip_adapter_dhcps_stop(tcpip_if uint32) int32 { if r.debug { fmt.Printf("rpc_tcpip_adapter_dhcps_stop()\r\n") } @@ -6599,33 +4691,20 @@ func (r *RTL8720DN) Rpc_tcpip_adapter_dhcps_stop(tcpip_if uint32) (int32, error) msg = append(msg, byte(tcpip_if>>16)) msg = append(msg, byte(tcpip_if>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcpip_adapter_dhcpc_start(tcpip_if uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcpip_adapter_dhcpc_start(tcpip_if uint32) int32 { if r.debug { fmt.Printf("rpc_tcpip_adapter_dhcpc_start()\r\n") } @@ -6637,33 +4716,20 @@ func (r *RTL8720DN) Rpc_tcpip_adapter_dhcpc_start(tcpip_if uint32) (int32, error msg = append(msg, byte(tcpip_if>>16)) msg = append(msg, byte(tcpip_if>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcpip_adapter_dhcpc_stop(tcpip_if uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcpip_adapter_dhcpc_stop(tcpip_if uint32) int32 { if r.debug { fmt.Printf("rpc_tcpip_adapter_dhcpc_stop()\r\n") } @@ -6675,33 +4741,20 @@ func (r *RTL8720DN) Rpc_tcpip_adapter_dhcpc_stop(tcpip_if uint32) (int32, error) msg = append(msg, byte(tcpip_if>>16)) msg = append(msg, byte(tcpip_if>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcpip_adapter_set_hostname(tcpip_if uint32, hostname string) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcpip_adapter_set_hostname(tcpip_if uint32, hostname string) int32 { if r.debug { fmt.Printf("rpc_tcpip_adapter_set_hostname()\r\n") } @@ -6716,33 +4769,20 @@ func (r *RTL8720DN) Rpc_tcpip_adapter_set_hostname(tcpip_if uint32, hostname str msg = append(msg, byte(len(hostname)), byte(len(hostname)>>8), byte(len(hostname)>>16), byte(len(hostname)>>24)) msg = append(msg, []byte(hostname)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcpip_adapter_get_hostname(tcpip_if uint32, hostname string) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcpip_adapter_get_hostname(tcpip_if uint32, hostname string) int32 { if r.debug { fmt.Printf("rpc_tcpip_adapter_get_hostname()\r\n") } @@ -6754,10 +4794,7 @@ func (r *RTL8720DN) Rpc_tcpip_adapter_get_hostname(tcpip_if uint32, hostname str msg = append(msg, byte(tcpip_if>>16)) msg = append(msg, byte(tcpip_if>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -6768,27 +4805,16 @@ func (r *RTL8720DN) Rpc_tcpip_adapter_get_hostname(tcpip_if uint32, hostname str hostname = string(payload[widx : widx+int(hostname_length)]) widx += int(hostname_length) } - hostname = (hostname)[:hostname_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcpip_adapter_get_mac(tcpip_if uint32, mac *[]byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcpip_adapter_get_mac(tcpip_if uint32, mac []byte) int32 { if r.debug { fmt.Printf("rpc_tcpip_adapter_get_mac()\r\n") } @@ -6800,10 +4826,7 @@ func (r *RTL8720DN) Rpc_tcpip_adapter_get_mac(tcpip_if uint32, mac *[]byte) (int msg = append(msg, byte(tcpip_if>>16)) msg = append(msg, byte(tcpip_if>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -6811,30 +4834,19 @@ func (r *RTL8720DN) Rpc_tcpip_adapter_get_mac(tcpip_if uint32, mac *[]byte) (int mac_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if mac_length > 0 { - copy(*mac, payload[widx:widx+int(mac_length)]) + copy(mac, payload[widx:widx+int(mac_length)]) widx += int(mac_length) } - *mac = (*mac)[:mac_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcpip_adapter_set_mac(tcpip_if uint32, mac []byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcpip_adapter_set_mac(tcpip_if uint32, mac []byte) int32 { if r.debug { fmt.Printf("rpc_tcpip_adapter_set_mac()\r\n") } @@ -6849,33 +4861,20 @@ func (r *RTL8720DN) Rpc_tcpip_adapter_set_mac(tcpip_if uint32, mac []byte) (int3 msg = append(msg, byte(len(mac)), byte(len(mac)>>8), byte(len(mac)>>16), byte(len(mac)>>24)) msg = append(msg, []byte(mac)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcpip_api_call(fn []byte, call []byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcpip_api_call(fn []byte, call []byte) int32 { if r.debug { fmt.Printf("rpc_tcpip_api_call()\r\n") } @@ -6888,33 +4887,20 @@ func (r *RTL8720DN) Rpc_tcpip_api_call(fn []byte, call []byte) (int32, error) { msg = append(msg, byte(len(call)), byte(len(call)>>8), byte(len(call)>>16), byte(len(call)>>24)) msg = append(msg, []byte(call)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcp_connect(pcb_in []byte, pcb_out *[]byte, ipaddr []byte, port uint16, connected []byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcp_connect(pcb_in []byte, pcb_out []byte, ipaddr []byte, port uint16, connected []byte) int32 { if r.debug { fmt.Printf("rpc_tcp_connect()\r\n") } @@ -6933,10 +4919,7 @@ func (r *RTL8720DN) Rpc_tcp_connect(pcb_in []byte, pcb_out *[]byte, ipaddr []byt msg = append(msg, byte(len(connected)), byte(len(connected)>>8), byte(len(connected)>>16), byte(len(connected)>>24)) msg = append(msg, []byte(connected)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -6944,30 +4927,19 @@ func (r *RTL8720DN) Rpc_tcp_connect(pcb_in []byte, pcb_out *[]byte, ipaddr []byt pcb_out_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if pcb_out_length > 0 { - copy(*pcb_out, payload[widx:widx+int(pcb_out_length)]) + copy(pcb_out, payload[widx:widx+int(pcb_out_length)]) widx += int(pcb_out_length) } - *pcb_out = (*pcb_out)[:pcb_out_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcp_recved(pcb_in []byte, pcb_out *[]byte, length uint16) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcp_recved(pcb_in []byte, pcb_out []byte, length uint16) int32 { if r.debug { fmt.Printf("rpc_tcp_recved()\r\n") } @@ -6980,10 +4952,7 @@ func (r *RTL8720DN) Rpc_tcp_recved(pcb_in []byte, pcb_out *[]byte, length uint16 msg = append(msg, byte(length>>0)) msg = append(msg, byte(length>>8)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -6991,30 +4960,19 @@ func (r *RTL8720DN) Rpc_tcp_recved(pcb_in []byte, pcb_out *[]byte, length uint16 pcb_out_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if pcb_out_length > 0 { - copy(*pcb_out, payload[widx:widx+int(pcb_out_length)]) + copy(pcb_out, payload[widx:widx+int(pcb_out_length)]) widx += int(pcb_out_length) } - *pcb_out = (*pcb_out)[:pcb_out_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcp_abort(pcb_in []byte, pcb_out *[]byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcp_abort(pcb_in []byte, pcb_out []byte) int32 { if r.debug { fmt.Printf("rpc_tcp_abort()\r\n") } @@ -7024,10 +4982,7 @@ func (r *RTL8720DN) Rpc_tcp_abort(pcb_in []byte, pcb_out *[]byte) (int32, error) msg = append(msg, byte(len(pcb_in)), byte(len(pcb_in)>>8), byte(len(pcb_in)>>16), byte(len(pcb_in)>>24)) msg = append(msg, []byte(pcb_in)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -7035,30 +4990,19 @@ func (r *RTL8720DN) Rpc_tcp_abort(pcb_in []byte, pcb_out *[]byte) (int32, error) pcb_out_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if pcb_out_length > 0 { - copy(*pcb_out, payload[widx:widx+int(pcb_out_length)]) + copy(pcb_out, payload[widx:widx+int(pcb_out_length)]) widx += int(pcb_out_length) } - *pcb_out = (*pcb_out)[:pcb_out_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcp_write(pcb_in []byte, pcb_out *[]byte, data []byte, apiflags uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcp_write(pcb_in []byte, pcb_out []byte, data []byte, apiflags uint8) int32 { if r.debug { fmt.Printf("rpc_tcp_write()\r\n") } @@ -7073,10 +5017,7 @@ func (r *RTL8720DN) Rpc_tcp_write(pcb_in []byte, pcb_out *[]byte, data []byte, a // apiflags : in uint8 msg = append(msg, byte(apiflags>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -7084,30 +5025,19 @@ func (r *RTL8720DN) Rpc_tcp_write(pcb_in []byte, pcb_out *[]byte, data []byte, a pcb_out_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if pcb_out_length > 0 { - copy(*pcb_out, payload[widx:widx+int(pcb_out_length)]) + copy(pcb_out, payload[widx:widx+int(pcb_out_length)]) widx += int(pcb_out_length) } - *pcb_out = (*pcb_out)[:pcb_out_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcp_output(pcb_in []byte, pcb_out *[]byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcp_output(pcb_in []byte, pcb_out []byte) int32 { if r.debug { fmt.Printf("rpc_tcp_output()\r\n") } @@ -7117,10 +5047,7 @@ func (r *RTL8720DN) Rpc_tcp_output(pcb_in []byte, pcb_out *[]byte) (int32, error msg = append(msg, byte(len(pcb_in)), byte(len(pcb_in)>>8), byte(len(pcb_in)>>16), byte(len(pcb_in)>>24)) msg = append(msg, []byte(pcb_in)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -7128,30 +5055,19 @@ func (r *RTL8720DN) Rpc_tcp_output(pcb_in []byte, pcb_out *[]byte) (int32, error pcb_out_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if pcb_out_length > 0 { - copy(*pcb_out, payload[widx:widx+int(pcb_out_length)]) + copy(pcb_out, payload[widx:widx+int(pcb_out_length)]) widx += int(pcb_out_length) } - *pcb_out = (*pcb_out)[:pcb_out_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcp_close(pcb_in []byte, pcb_out *[]byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcp_close(pcb_in []byte, pcb_out []byte) int32 { if r.debug { fmt.Printf("rpc_tcp_close()\r\n") } @@ -7161,10 +5077,7 @@ func (r *RTL8720DN) Rpc_tcp_close(pcb_in []byte, pcb_out *[]byte) (int32, error) msg = append(msg, byte(len(pcb_in)), byte(len(pcb_in)>>8), byte(len(pcb_in)>>16), byte(len(pcb_in)>>24)) msg = append(msg, []byte(pcb_in)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -7172,30 +5085,19 @@ func (r *RTL8720DN) Rpc_tcp_close(pcb_in []byte, pcb_out *[]byte) (int32, error) pcb_out_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if pcb_out_length > 0 { - copy(*pcb_out, payload[widx:widx+int(pcb_out_length)]) + copy(pcb_out, payload[widx:widx+int(pcb_out_length)]) widx += int(pcb_out_length) } - *pcb_out = (*pcb_out)[:pcb_out_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcp_bind(pcb_in []byte, pcb_out *[]byte, ipaddr []byte, port uint16) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcp_bind(pcb_in []byte, pcb_out []byte, ipaddr []byte, port uint16) int32 { if r.debug { fmt.Printf("rpc_tcp_bind()\r\n") } @@ -7211,10 +5113,7 @@ func (r *RTL8720DN) Rpc_tcp_bind(pcb_in []byte, pcb_out *[]byte, ipaddr []byte, msg = append(msg, byte(port>>0)) msg = append(msg, byte(port>>8)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -7222,30 +5121,19 @@ func (r *RTL8720DN) Rpc_tcp_bind(pcb_in []byte, pcb_out *[]byte, ipaddr []byte, pcb_out_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if pcb_out_length > 0 { - copy(*pcb_out, payload[widx:widx+int(pcb_out_length)]) + copy(pcb_out, payload[widx:widx+int(pcb_out_length)]) widx += int(pcb_out_length) } - *pcb_out = (*pcb_out)[:pcb_out_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcp_new_ip_type(ip_type uint8, pcb_out *[]byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcp_new_ip_type(ip_type uint8, pcb_out []byte) int32 { if r.debug { fmt.Printf("rpc_tcp_new_ip_type()\r\n") } @@ -7254,10 +5142,7 @@ func (r *RTL8720DN) Rpc_tcp_new_ip_type(ip_type uint8, pcb_out *[]byte) (int32, // ip_type : in uint8 msg = append(msg, byte(ip_type>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -7265,30 +5150,19 @@ func (r *RTL8720DN) Rpc_tcp_new_ip_type(ip_type uint8, pcb_out *[]byte) (int32, pcb_out_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if pcb_out_length > 0 { - copy(*pcb_out, payload[widx:widx+int(pcb_out_length)]) + copy(pcb_out, payload[widx:widx+int(pcb_out_length)]) widx += int(pcb_out_length) } - *pcb_out = (*pcb_out)[:pcb_out_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcp_arg(pcb_in []byte, pcb_out *[]byte, func_arg []byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcp_arg(pcb_in []byte, pcb_out []byte, func_arg []byte) int32 { if r.debug { fmt.Printf("rpc_tcp_arg()\r\n") } @@ -7301,10 +5175,7 @@ func (r *RTL8720DN) Rpc_tcp_arg(pcb_in []byte, pcb_out *[]byte, func_arg []byte) msg = append(msg, byte(len(func_arg)), byte(len(func_arg)>>8), byte(len(func_arg)>>16), byte(len(func_arg)>>24)) msg = append(msg, []byte(func_arg)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -7312,30 +5183,19 @@ func (r *RTL8720DN) Rpc_tcp_arg(pcb_in []byte, pcb_out *[]byte, func_arg []byte) pcb_out_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if pcb_out_length > 0 { - copy(*pcb_out, payload[widx:widx+int(pcb_out_length)]) + copy(pcb_out, payload[widx:widx+int(pcb_out_length)]) widx += int(pcb_out_length) } - *pcb_out = (*pcb_out)[:pcb_out_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcp_err(pcb_in []byte, pcb_out *[]byte, func_err []byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcp_err(pcb_in []byte, pcb_out []byte, func_err []byte) int32 { if r.debug { fmt.Printf("rpc_tcp_err()\r\n") } @@ -7348,10 +5208,7 @@ func (r *RTL8720DN) Rpc_tcp_err(pcb_in []byte, pcb_out *[]byte, func_err []byte) msg = append(msg, byte(len(func_err)), byte(len(func_err)>>8), byte(len(func_err)>>16), byte(len(func_err)>>24)) msg = append(msg, []byte(func_err)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -7359,30 +5216,19 @@ func (r *RTL8720DN) Rpc_tcp_err(pcb_in []byte, pcb_out *[]byte, func_err []byte) pcb_out_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if pcb_out_length > 0 { - copy(*pcb_out, payload[widx:widx+int(pcb_out_length)]) + copy(pcb_out, payload[widx:widx+int(pcb_out_length)]) widx += int(pcb_out_length) } - *pcb_out = (*pcb_out)[:pcb_out_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcp_recv(pcb_in []byte, pcb_out *[]byte, func_recv []byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcp_recv(pcb_in []byte, pcb_out []byte, func_recv []byte) int32 { if r.debug { fmt.Printf("rpc_tcp_recv()\r\n") } @@ -7395,10 +5241,7 @@ func (r *RTL8720DN) Rpc_tcp_recv(pcb_in []byte, pcb_out *[]byte, func_recv []byt msg = append(msg, byte(len(func_recv)), byte(len(func_recv)>>8), byte(len(func_recv)>>16), byte(len(func_recv)>>24)) msg = append(msg, []byte(func_recv)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -7406,30 +5249,19 @@ func (r *RTL8720DN) Rpc_tcp_recv(pcb_in []byte, pcb_out *[]byte, func_recv []byt pcb_out_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if pcb_out_length > 0 { - copy(*pcb_out, payload[widx:widx+int(pcb_out_length)]) + copy(pcb_out, payload[widx:widx+int(pcb_out_length)]) widx += int(pcb_out_length) } - *pcb_out = (*pcb_out)[:pcb_out_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcp_sent(pcb_in []byte, pcb_out *[]byte, func_sent []byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcp_sent(pcb_in []byte, pcb_out []byte, func_sent []byte) int32 { if r.debug { fmt.Printf("rpc_tcp_sent()\r\n") } @@ -7442,10 +5274,7 @@ func (r *RTL8720DN) Rpc_tcp_sent(pcb_in []byte, pcb_out *[]byte, func_sent []byt msg = append(msg, byte(len(func_sent)), byte(len(func_sent)>>8), byte(len(func_sent)>>16), byte(len(func_sent)>>24)) msg = append(msg, []byte(func_sent)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -7453,30 +5282,19 @@ func (r *RTL8720DN) Rpc_tcp_sent(pcb_in []byte, pcb_out *[]byte, func_sent []byt pcb_out_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if pcb_out_length > 0 { - copy(*pcb_out, payload[widx:widx+int(pcb_out_length)]) + copy(pcb_out, payload[widx:widx+int(pcb_out_length)]) widx += int(pcb_out_length) } - *pcb_out = (*pcb_out)[:pcb_out_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcp_accept(pcb_in []byte, pcb_out *[]byte, func_accept []byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcp_accept(pcb_in []byte, pcb_out []byte, func_accept []byte) int32 { if r.debug { fmt.Printf("rpc_tcp_accept()\r\n") } @@ -7489,10 +5307,7 @@ func (r *RTL8720DN) Rpc_tcp_accept(pcb_in []byte, pcb_out *[]byte, func_accept [ msg = append(msg, byte(len(func_accept)), byte(len(func_accept)>>8), byte(len(func_accept)>>16), byte(len(func_accept)>>24)) msg = append(msg, []byte(func_accept)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -7500,30 +5315,19 @@ func (r *RTL8720DN) Rpc_tcp_accept(pcb_in []byte, pcb_out *[]byte, func_accept [ pcb_out_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if pcb_out_length > 0 { - copy(*pcb_out, payload[widx:widx+int(pcb_out_length)]) + copy(pcb_out, payload[widx:widx+int(pcb_out_length)]) widx += int(pcb_out_length) } - *pcb_out = (*pcb_out)[:pcb_out_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcp_poll(pcb_in []byte, pcb_out *[]byte, func_poll []byte, interval uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcp_poll(pcb_in []byte, pcb_out []byte, func_poll []byte, interval uint8) int32 { if r.debug { fmt.Printf("rpc_tcp_poll()\r\n") } @@ -7538,10 +5342,7 @@ func (r *RTL8720DN) Rpc_tcp_poll(pcb_in []byte, pcb_out *[]byte, func_poll []byt // interval : in uint8 msg = append(msg, byte(interval>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -7549,30 +5350,19 @@ func (r *RTL8720DN) Rpc_tcp_poll(pcb_in []byte, pcb_out *[]byte, func_poll []byt pcb_out_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if pcb_out_length > 0 { - copy(*pcb_out, payload[widx:widx+int(pcb_out_length)]) + copy(pcb_out, payload[widx:widx+int(pcb_out_length)]) widx += int(pcb_out_length) } - *pcb_out = (*pcb_out)[:pcb_out_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcp_listen_with_backlog(pcb_in []byte, pcb_out *[]byte, backlog uint8) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcp_listen_with_backlog(pcb_in []byte, pcb_out []byte, backlog uint8) int32 { if r.debug { fmt.Printf("rpc_tcp_listen_with_backlog()\r\n") } @@ -7584,10 +5374,7 @@ func (r *RTL8720DN) Rpc_tcp_listen_with_backlog(pcb_in []byte, pcb_out *[]byte, // backlog : in uint8 msg = append(msg, byte(backlog>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -7595,30 +5382,19 @@ func (r *RTL8720DN) Rpc_tcp_listen_with_backlog(pcb_in []byte, pcb_out *[]byte, pcb_out_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if pcb_out_length > 0 { - copy(*pcb_out, payload[widx:widx+int(pcb_out_length)]) + copy(pcb_out, payload[widx:widx+int(pcb_out_length)]) widx += int(pcb_out_length) } - *pcb_out = (*pcb_out)[:pcb_out_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_pbuf_free(p []byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_pbuf_free(p []byte) int32 { if r.debug { fmt.Printf("rpc_pbuf_free()\r\n") } @@ -7628,33 +5404,20 @@ func (r *RTL8720DN) Rpc_pbuf_free(p []byte) (int32, error) { msg = append(msg, byte(len(p)), byte(len(p)>>8), byte(len(p)>>16), byte(len(p)>>24)) msg = append(msg, []byte(p)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_ip4addr_ntoa(ip4_addr_in []byte) (string, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_ip4addr_ntoa(ip4_addr_in []byte) string { if r.debug { fmt.Printf("rpc_ip4addr_ntoa()\r\n") } @@ -7664,10 +5427,7 @@ func (r *RTL8720DN) Rpc_ip4addr_ntoa(ip4_addr_in []byte) (string, error) { msg = append(msg, byte(len(ip4_addr_in)), byte(len(ip4_addr_in)>>8), byte(len(ip4_addr_in)>>16), byte(len(ip4_addr_in)>>24)) msg = append(msg, []byte(ip4_addr_in)...) - err := r.performRequest(msg) - if err != nil { - return "", err - } + r.performRequest(msg) r.read() widx := 8 @@ -7678,15 +5438,10 @@ func (r *RTL8720DN) Rpc_ip4addr_ntoa(ip4_addr_in []byte) (string, error) { result = string(payload[widx : widx+int(result_length)]) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_inet_chksum(dataptr_in []byte) (uint16, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_inet_chksum(dataptr_in []byte) uint16 { if r.debug { fmt.Printf("rpc_inet_chksum()\r\n") } @@ -7696,10 +5451,7 @@ func (r *RTL8720DN) Rpc_inet_chksum(dataptr_in []byte) (uint16, error) { msg = append(msg, byte(len(dataptr_in)), byte(len(dataptr_in)>>8), byte(len(dataptr_in)>>16), byte(len(dataptr_in)>>24)) msg = append(msg, []byte(dataptr_in)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -7708,15 +5460,10 @@ func (r *RTL8720DN) Rpc_inet_chksum(dataptr_in []byte) (uint16, error) { result = uint16(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_accept(s int32, addr []byte, addrlen *uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_accept(s int32, addr []byte, addrlen *uint32) int32 { if r.debug { fmt.Printf("rpc_lwip_accept()\r\n") } @@ -7736,10 +5483,7 @@ func (r *RTL8720DN) Rpc_lwip_accept(s int32, addr []byte, addrlen *uint32) (int3 msg = append(msg, byte(*addrlen>>16)) msg = append(msg, byte(*addrlen>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -7749,23 +5493,13 @@ func (r *RTL8720DN) Rpc_lwip_accept(s int32, addr []byte, addrlen *uint32) (int3 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_bind(s int32, name []byte, namelen uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_bind(s int32, name []byte, namelen uint32) int32 { if r.debug { fmt.Printf("rpc_lwip_bind()\r\n") } @@ -7785,33 +5519,20 @@ func (r *RTL8720DN) Rpc_lwip_bind(s int32, name []byte, namelen uint32) (int32, msg = append(msg, byte(namelen>>16)) msg = append(msg, byte(namelen>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_shutdown(s int32, how int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_shutdown(s int32, how int32) int32 { if r.debug { fmt.Printf("rpc_lwip_shutdown()\r\n") } @@ -7828,33 +5549,20 @@ func (r *RTL8720DN) Rpc_lwip_shutdown(s int32, how int32) (int32, error) { msg = append(msg, byte(how>>16)) msg = append(msg, byte(how>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_getpeername(s int32, name *[]byte, namelen *uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_getpeername(s int32, name []byte, namelen *uint32) int32 { if r.debug { fmt.Printf("rpc_lwip_getpeername()\r\n") } @@ -7871,10 +5579,7 @@ func (r *RTL8720DN) Rpc_lwip_getpeername(s int32, name *[]byte, namelen *uint32) msg = append(msg, byte(*namelen>>16)) msg = append(msg, byte(*namelen>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -7882,33 +5587,22 @@ func (r *RTL8720DN) Rpc_lwip_getpeername(s int32, name *[]byte, namelen *uint32) name_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if name_length > 0 { - copy(*name, payload[widx:widx+int(name_length)]) + copy(name, payload[widx:widx+int(name_length)]) widx += int(name_length) } - *name = (*name)[:name_length] // namelen : inout uint32 *namelen = binary.LittleEndian.Uint32(payload[widx:]) widx += 4 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_getsockname(s int32, name *[]byte, namelen *uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_getsockname(s int32, name []byte, namelen *uint32) int32 { if r.debug { fmt.Printf("rpc_lwip_getsockname()\r\n") } @@ -7925,10 +5619,7 @@ func (r *RTL8720DN) Rpc_lwip_getsockname(s int32, name *[]byte, namelen *uint32) msg = append(msg, byte(*namelen>>16)) msg = append(msg, byte(*namelen>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -7936,33 +5627,22 @@ func (r *RTL8720DN) Rpc_lwip_getsockname(s int32, name *[]byte, namelen *uint32) name_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if name_length > 0 { - copy(*name, payload[widx:widx+int(name_length)]) + copy(name, payload[widx:widx+int(name_length)]) widx += int(name_length) } - *name = (*name)[:name_length] // namelen : inout uint32 *namelen = binary.LittleEndian.Uint32(payload[widx:]) widx += 4 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_getsockopt(s int32, level int32, optname int32, in_optval []byte, out_optval *[]byte, optlen *uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_getsockopt(s int32, level int32, optname int32, in_optval []byte, out_optval []byte, optlen *uint32) int32 { if r.debug { fmt.Printf("rpc_lwip_getsockopt()\r\n") } @@ -7992,10 +5672,7 @@ func (r *RTL8720DN) Rpc_lwip_getsockopt(s int32, level int32, optname int32, in_ msg = append(msg, byte(*optlen>>16)) msg = append(msg, byte(*optlen>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -8003,33 +5680,22 @@ func (r *RTL8720DN) Rpc_lwip_getsockopt(s int32, level int32, optname int32, in_ out_optval_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if out_optval_length > 0 { - copy(*out_optval, payload[widx:widx+int(out_optval_length)]) + copy(out_optval, payload[widx:widx+int(out_optval_length)]) widx += int(out_optval_length) } - *out_optval = (*out_optval)[:out_optval_length] // optlen : inout uint32 *optlen = binary.LittleEndian.Uint32(payload[widx:]) widx += 4 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_setsockopt(s int32, level int32, optname int32, optval []byte, optlen uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_setsockopt(s int32, level int32, optname int32, optval []byte, optlen uint32) int32 { if r.debug { fmt.Printf("rpc_lwip_setsockopt()\r\n") } @@ -8059,33 +5725,20 @@ func (r *RTL8720DN) Rpc_lwip_setsockopt(s int32, level int32, optname int32, opt msg = append(msg, byte(optlen>>16)) msg = append(msg, byte(optlen>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_close(s int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_close(s int32) int32 { if r.debug { fmt.Printf("rpc_lwip_close()\r\n") } @@ -8097,33 +5750,20 @@ func (r *RTL8720DN) Rpc_lwip_close(s int32) (int32, error) { msg = append(msg, byte(s>>16)) msg = append(msg, byte(s>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_connect(s int32, name []byte, namelen uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_connect(s int32, name []byte, namelen uint32) int32 { if r.debug { fmt.Printf("rpc_lwip_connect()\r\n") } @@ -8143,33 +5783,20 @@ func (r *RTL8720DN) Rpc_lwip_connect(s int32, name []byte, namelen uint32) (int3 msg = append(msg, byte(namelen>>16)) msg = append(msg, byte(namelen>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_listen(s int32, backlog int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_listen(s int32, backlog int32) int32 { if r.debug { fmt.Printf("rpc_lwip_listen()\r\n") } @@ -8186,33 +5813,20 @@ func (r *RTL8720DN) Rpc_lwip_listen(s int32, backlog int32) (int32, error) { msg = append(msg, byte(backlog>>16)) msg = append(msg, byte(backlog>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_available(s int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_available(s int32) int32 { if r.debug { fmt.Printf("rpc_lwip_available()\r\n") } @@ -8224,33 +5838,20 @@ func (r *RTL8720DN) Rpc_lwip_available(s int32) (int32, error) { msg = append(msg, byte(s>>16)) msg = append(msg, byte(s>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_recv(s int32, mem *[]byte, length uint32, flags int32, timeout uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_recv(s int32, mem []byte, length uint32, flags int32, timeout uint32) int32 { if r.debug { fmt.Printf("rpc_lwip_recv()\r\n") } @@ -8277,10 +5878,7 @@ func (r *RTL8720DN) Rpc_lwip_recv(s int32, mem *[]byte, length uint32, flags int msg = append(msg, byte(timeout>>16)) msg = append(msg, byte(timeout>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -8288,30 +5886,19 @@ func (r *RTL8720DN) Rpc_lwip_recv(s int32, mem *[]byte, length uint32, flags int mem_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if mem_length > 0 { - copy(*mem, payload[widx:widx+int(mem_length)]) + copy(mem, payload[widx:widx+int(mem_length)]) widx += int(mem_length) } - *mem = (*mem)[:mem_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_read(s int32, mem *[]byte, length uint32, timeout uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_read(s int32, mem []byte, length uint32, timeout uint32) int32 { if r.debug { fmt.Printf("rpc_lwip_read()\r\n") } @@ -8333,10 +5920,7 @@ func (r *RTL8720DN) Rpc_lwip_read(s int32, mem *[]byte, length uint32, timeout u msg = append(msg, byte(timeout>>16)) msg = append(msg, byte(timeout>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -8344,30 +5928,19 @@ func (r *RTL8720DN) Rpc_lwip_read(s int32, mem *[]byte, length uint32, timeout u mem_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if mem_length > 0 { - copy(*mem, payload[widx:widx+int(mem_length)]) + copy(mem, payload[widx:widx+int(mem_length)]) widx += int(mem_length) } - *mem = (*mem)[:mem_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_recvfrom(s int32, mem *[]byte, length uint32, flags int32, from *[]byte, fromlen *uint32, timeout uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_recvfrom(s int32, mem []byte, length uint32, flags int32, from []byte, fromlen *uint32, timeout uint32) int32 { if r.debug { fmt.Printf("rpc_lwip_recvfrom()\r\n") } @@ -8399,10 +5972,7 @@ func (r *RTL8720DN) Rpc_lwip_recvfrom(s int32, mem *[]byte, length uint32, flags msg = append(msg, byte(timeout>>16)) msg = append(msg, byte(timeout>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -8410,41 +5980,29 @@ func (r *RTL8720DN) Rpc_lwip_recvfrom(s int32, mem *[]byte, length uint32, flags mem_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if mem_length > 0 { - copy(*mem, payload[widx:widx+int(mem_length)]) + copy(mem, payload[widx:widx+int(mem_length)]) widx += int(mem_length) } - *mem = (*mem)[:mem_length] // from : out []byte from_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if from_length > 0 { - copy(*from, payload[widx:widx+int(from_length)]) + copy(from, payload[widx:widx+int(from_length)]) widx += int(from_length) } - *from = (*from)[:from_length] // fromlen : inout uint32 *fromlen = binary.LittleEndian.Uint32(payload[widx:]) widx += 4 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_send(s int32, dataptr []byte, flags int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_send(s int32, dataptr []byte, flags int32) int32 { if r.debug { fmt.Printf("rpc_lwip_send()\r\n") } @@ -8464,33 +6022,20 @@ func (r *RTL8720DN) Rpc_lwip_send(s int32, dataptr []byte, flags int32) (int32, msg = append(msg, byte(flags>>16)) msg = append(msg, byte(flags>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_sendmsg(s int32, msg_name []byte, msg_iov []byte, msg_control []byte, msg_flags int32, flags int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_sendmsg(s int32, msg_name []byte, msg_iov []byte, msg_control []byte, msg_flags int32, flags int32) int32 { if r.debug { fmt.Printf("rpc_lwip_sendmsg()\r\n") } @@ -8521,33 +6066,20 @@ func (r *RTL8720DN) Rpc_lwip_sendmsg(s int32, msg_name []byte, msg_iov []byte, m msg = append(msg, byte(flags>>16)) msg = append(msg, byte(flags>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_sendto(s int32, dataptr []byte, flags int32, to []byte, tolen uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_sendto(s int32, dataptr []byte, flags int32, to []byte, tolen uint32) int32 { if r.debug { fmt.Printf("rpc_lwip_sendto()\r\n") } @@ -8575,33 +6107,20 @@ func (r *RTL8720DN) Rpc_lwip_sendto(s int32, dataptr []byte, flags int32, to []b msg = append(msg, byte(tolen>>16)) msg = append(msg, byte(tolen>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_socket(domain int32, l_type int32, protocol int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_socket(domain int32, l_type int32, protocol int32) int32 { if r.debug { fmt.Printf("rpc_lwip_socket()\r\n") } @@ -8623,33 +6142,20 @@ func (r *RTL8720DN) Rpc_lwip_socket(domain int32, l_type int32, protocol int32) msg = append(msg, byte(protocol>>16)) msg = append(msg, byte(protocol>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_write(s int32, dataptr []byte, size uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_write(s int32, dataptr []byte, size uint32) int32 { if r.debug { fmt.Printf("rpc_lwip_write()\r\n") } @@ -8669,33 +6175,20 @@ func (r *RTL8720DN) Rpc_lwip_write(s int32, dataptr []byte, size uint32) (int32, msg = append(msg, byte(size>>16)) msg = append(msg, byte(size>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_writev(s int32, iov []byte, iovcnt int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_writev(s int32, iov []byte, iovcnt int32) int32 { if r.debug { fmt.Printf("rpc_lwip_writev()\r\n") } @@ -8715,33 +6208,20 @@ func (r *RTL8720DN) Rpc_lwip_writev(s int32, iov []byte, iovcnt int32) (int32, e msg = append(msg, byte(iovcnt>>16)) msg = append(msg, byte(iovcnt>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_select(maxfdp1 int32, readset []byte, writeset []byte, exceptset []byte, timeout []byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_select(maxfdp1 int32, readset []byte, writeset []byte, exceptset []byte, timeout []byte) int32 { if r.debug { fmt.Printf("rpc_lwip_select()\r\n") } @@ -8785,33 +6265,20 @@ func (r *RTL8720DN) Rpc_lwip_select(maxfdp1 int32, readset []byte, writeset []by msg = append(msg, []byte(timeout)...) } - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_ioctl(s int32, cmd uint32, in_argp []byte, out_argp *[]byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_ioctl(s int32, cmd uint32, in_argp []byte, out_argp []byte) int32 { if r.debug { fmt.Printf("rpc_lwip_ioctl()\r\n") } @@ -8831,10 +6298,7 @@ func (r *RTL8720DN) Rpc_lwip_ioctl(s int32, cmd uint32, in_argp []byte, out_argp msg = append(msg, byte(len(in_argp)), byte(len(in_argp)>>8), byte(len(in_argp)>>16), byte(len(in_argp)>>24)) msg = append(msg, []byte(in_argp)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -8842,30 +6306,19 @@ func (r *RTL8720DN) Rpc_lwip_ioctl(s int32, cmd uint32, in_argp []byte, out_argp out_argp_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if out_argp_length > 0 { - copy(*out_argp, payload[widx:widx+int(out_argp_length)]) + copy(out_argp, payload[widx:widx+int(out_argp_length)]) widx += int(out_argp_length) } - *out_argp = (*out_argp)[:out_argp_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_fcntl(s int32, cmd int32, val int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_fcntl(s int32, cmd int32, val int32) int32 { if r.debug { fmt.Printf("rpc_lwip_fcntl()\r\n") } @@ -8887,64 +6340,38 @@ func (r *RTL8720DN) Rpc_lwip_fcntl(s int32, cmd int32, val int32) (int32, error) msg = append(msg, byte(val>>16)) msg = append(msg, byte(val>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_lwip_errno() (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_lwip_errno() int32 { if r.debug { fmt.Printf("rpc_lwip_errno()\r\n") } msg := startWriteMessage(0x00, 0x10, 0x18, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_netconn_gethostbyname(name string, addr *[]byte) (int8, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_netconn_gethostbyname(name string, addr []byte) int8 { if r.debug { fmt.Printf("rpc_netconn_gethostbyname()\r\n") } @@ -8954,10 +6381,7 @@ func (r *RTL8720DN) Rpc_netconn_gethostbyname(name string, addr *[]byte) (int8, msg = append(msg, byte(len(name)), byte(len(name)>>8), byte(len(name)>>16), byte(len(name)>>24)) msg = append(msg, []byte(name)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -8965,30 +6389,19 @@ func (r *RTL8720DN) Rpc_netconn_gethostbyname(name string, addr *[]byte) (int8, addr_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if addr_length > 0 { - copy(*addr, payload[widx:widx+int(addr_length)]) + copy(addr, payload[widx:widx+int(addr_length)]) widx += int(addr_length) } - *addr = (*addr)[:addr_length] var result int8 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80 { - result = int8(int(x) * -1) - } else { - result = int8(int(x)) - } result = int8(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_dns_gethostbyname_addrtype(hostname string, addr *[]byte, found uint32, callback_arg []byte, dns_addrtype uint8) (int8, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_dns_gethostbyname_addrtype(hostname string, addr []byte, found uint32, callback_arg []byte, dns_addrtype uint8) int8 { if r.debug { fmt.Printf("rpc_dns_gethostbyname_addrtype()\r\n") } @@ -9013,10 +6426,7 @@ func (r *RTL8720DN) Rpc_dns_gethostbyname_addrtype(hostname string, addr *[]byte // dns_addrtype : in uint8 msg = append(msg, byte(dns_addrtype>>0)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -9024,39 +6434,25 @@ func (r *RTL8720DN) Rpc_dns_gethostbyname_addrtype(hostname string, addr *[]byte addr_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if addr_length > 0 { - copy(*addr, payload[widx:widx+int(addr_length)]) + copy(addr, payload[widx:widx+int(addr_length)]) widx += int(addr_length) } - *addr = (*addr)[:addr_length] var result int8 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80 { - result = int8(int(x) * -1) - } else { - result = int8(int(x)) - } result = int8(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_ssl_client_create() (uint32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_ssl_client_create() uint32 { if r.debug { fmt.Printf("rpc_wifi_ssl_client_create()\r\n") } msg := startWriteMessage(0x00, 0x11, 0x01, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -9064,15 +6460,10 @@ func (r *RTL8720DN) Rpc_wifi_ssl_client_create() (uint32, error) { result = uint32(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_ssl_client_destroy(ssl_client uint32) error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_ssl_client_destroy(ssl_client uint32) { if r.debug { fmt.Printf("rpc_wifi_ssl_client_destroy()\r\n") } @@ -9084,23 +6475,15 @@ func (r *RTL8720DN) Rpc_wifi_ssl_client_destroy(ssl_client uint32) error { msg = append(msg, byte(ssl_client>>16)) msg = append(msg, byte(ssl_client>>24)) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_wifi_ssl_init(ssl_client uint32) error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_ssl_init(ssl_client uint32) { if r.debug { fmt.Printf("rpc_wifi_ssl_init()\r\n") } @@ -9112,23 +6495,15 @@ func (r *RTL8720DN) Rpc_wifi_ssl_init(ssl_client uint32) error { msg = append(msg, byte(ssl_client>>16)) msg = append(msg, byte(ssl_client>>24)) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_wifi_ssl_set_socket(ssl_client uint32, socket int32) error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_ssl_set_socket(ssl_client uint32, socket int32) { if r.debug { fmt.Printf("rpc_wifi_ssl_set_socket()\r\n") } @@ -9145,23 +6520,15 @@ func (r *RTL8720DN) Rpc_wifi_ssl_set_socket(ssl_client uint32, socket int32) err msg = append(msg, byte(socket>>16)) msg = append(msg, byte(socket>>24)) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_wifi_ssl_set_timeout(ssl_client uint32, timeout uint32) error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_ssl_set_timeout(ssl_client uint32, timeout uint32) { if r.debug { fmt.Printf("rpc_wifi_ssl_set_timeout()\r\n") } @@ -9178,23 +6545,15 @@ func (r *RTL8720DN) Rpc_wifi_ssl_set_timeout(ssl_client uint32, timeout uint32) msg = append(msg, byte(timeout>>16)) msg = append(msg, byte(timeout>>24)) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_wifi_ssl_get_socket(ssl_client uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_ssl_get_socket(ssl_client uint32) int32 { if r.debug { fmt.Printf("rpc_wifi_ssl_get_socket()\r\n") } @@ -9206,33 +6565,20 @@ func (r *RTL8720DN) Rpc_wifi_ssl_get_socket(ssl_client uint32) (int32, error) { msg = append(msg, byte(ssl_client>>16)) msg = append(msg, byte(ssl_client>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_ssl_get_timeout(ssl_client uint32) (uint32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_ssl_get_timeout(ssl_client uint32) uint32 { if r.debug { fmt.Printf("rpc_wifi_ssl_get_timeout()\r\n") } @@ -9244,10 +6590,7 @@ func (r *RTL8720DN) Rpc_wifi_ssl_get_timeout(ssl_client uint32) (uint32, error) msg = append(msg, byte(ssl_client>>16)) msg = append(msg, byte(ssl_client>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -9256,15 +6599,10 @@ func (r *RTL8720DN) Rpc_wifi_ssl_get_timeout(ssl_client uint32) (uint32, error) result = uint32(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_ssl_set_rootCA(ssl_client uint32, rootCABuff string) (uint32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_ssl_set_rootCA(ssl_client uint32, rootCABuff string) uint32 { if r.debug { fmt.Printf("rpc_wifi_ssl_set_rootCA()\r\n") } @@ -9279,10 +6617,7 @@ func (r *RTL8720DN) Rpc_wifi_ssl_set_rootCA(ssl_client uint32, rootCABuff string msg = append(msg, byte(len(rootCABuff)), byte(len(rootCABuff)>>8), byte(len(rootCABuff)>>16), byte(len(rootCABuff)>>24)) msg = append(msg, []byte(rootCABuff)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -9291,15 +6626,10 @@ func (r *RTL8720DN) Rpc_wifi_ssl_set_rootCA(ssl_client uint32, rootCABuff string result = uint32(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_ssl_get_rootCA(ssl_client uint32, rootCABuff string) (uint32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_ssl_get_rootCA(ssl_client uint32, rootCABuff string) uint32 { if r.debug { fmt.Printf("rpc_wifi_ssl_get_rootCA()\r\n") } @@ -9311,10 +6641,7 @@ func (r *RTL8720DN) Rpc_wifi_ssl_get_rootCA(ssl_client uint32, rootCABuff string msg = append(msg, byte(ssl_client>>16)) msg = append(msg, byte(ssl_client>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -9329,21 +6656,15 @@ func (r *RTL8720DN) Rpc_wifi_ssl_get_rootCA(ssl_client uint32, rootCABuff string rootCABuff = string(payload[widx : widx+int(rootCABuff_length)]) widx += int(rootCABuff_length) } - rootCABuff = (rootCABuff)[:rootCABuff_length] var result uint32 result = uint32(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_ssl_set_cliCert(ssl_client uint32, cli_cert string) (uint32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_ssl_set_cliCert(ssl_client uint32, cli_cert string) uint32 { if r.debug { fmt.Printf("rpc_wifi_ssl_set_cliCert()\r\n") } @@ -9358,10 +6679,7 @@ func (r *RTL8720DN) Rpc_wifi_ssl_set_cliCert(ssl_client uint32, cli_cert string) msg = append(msg, byte(len(cli_cert)), byte(len(cli_cert)>>8), byte(len(cli_cert)>>16), byte(len(cli_cert)>>24)) msg = append(msg, []byte(cli_cert)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -9370,15 +6688,10 @@ func (r *RTL8720DN) Rpc_wifi_ssl_set_cliCert(ssl_client uint32, cli_cert string) result = uint32(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_ssl_get_cliCert(ssl_client uint32, cli_cert string) (uint32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_ssl_get_cliCert(ssl_client uint32, cli_cert string) uint32 { if r.debug { fmt.Printf("rpc_wifi_ssl_get_cliCert()\r\n") } @@ -9398,10 +6711,7 @@ func (r *RTL8720DN) Rpc_wifi_ssl_get_cliCert(ssl_client uint32, cli_cert string) msg = append(msg, []byte(cli_cert)...) } - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -9410,15 +6720,10 @@ func (r *RTL8720DN) Rpc_wifi_ssl_get_cliCert(ssl_client uint32, cli_cert string) result = uint32(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_ssl_set_cliKey(ssl_client uint32, cli_key string) (uint32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_ssl_set_cliKey(ssl_client uint32, cli_key string) uint32 { if r.debug { fmt.Printf("rpc_wifi_ssl_set_cliKey()\r\n") } @@ -9433,10 +6738,7 @@ func (r *RTL8720DN) Rpc_wifi_ssl_set_cliKey(ssl_client uint32, cli_key string) ( msg = append(msg, byte(len(cli_key)), byte(len(cli_key)>>8), byte(len(cli_key)>>16), byte(len(cli_key)>>24)) msg = append(msg, []byte(cli_key)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -9445,15 +6747,10 @@ func (r *RTL8720DN) Rpc_wifi_ssl_set_cliKey(ssl_client uint32, cli_key string) ( result = uint32(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_ssl_get_cliKey(ssl_client uint32, cli_key string) (uint32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_ssl_get_cliKey(ssl_client uint32, cli_key string) uint32 { if r.debug { fmt.Printf("rpc_wifi_ssl_get_cliKey()\r\n") } @@ -9473,10 +6770,7 @@ func (r *RTL8720DN) Rpc_wifi_ssl_get_cliKey(ssl_client uint32, cli_key string) ( msg = append(msg, []byte(cli_key)...) } - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -9485,15 +6779,10 @@ func (r *RTL8720DN) Rpc_wifi_ssl_get_cliKey(ssl_client uint32, cli_key string) ( result = uint32(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_ssl_set_pskIdent(ssl_client uint32, pskIdent string) (uint32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_ssl_set_pskIdent(ssl_client uint32, pskIdent string) uint32 { if r.debug { fmt.Printf("rpc_wifi_ssl_set_pskIdent()\r\n") } @@ -9508,10 +6797,7 @@ func (r *RTL8720DN) Rpc_wifi_ssl_set_pskIdent(ssl_client uint32, pskIdent string msg = append(msg, byte(len(pskIdent)), byte(len(pskIdent)>>8), byte(len(pskIdent)>>16), byte(len(pskIdent)>>24)) msg = append(msg, []byte(pskIdent)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -9520,15 +6806,10 @@ func (r *RTL8720DN) Rpc_wifi_ssl_set_pskIdent(ssl_client uint32, pskIdent string result = uint32(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_ssl_get_pskIdent(ssl_client uint32, pskIdent string) (uint32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_ssl_get_pskIdent(ssl_client uint32, pskIdent string) uint32 { if r.debug { fmt.Printf("rpc_wifi_ssl_get_pskIdent()\r\n") } @@ -9548,10 +6829,7 @@ func (r *RTL8720DN) Rpc_wifi_ssl_get_pskIdent(ssl_client uint32, pskIdent string msg = append(msg, []byte(pskIdent)...) } - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -9560,15 +6838,10 @@ func (r *RTL8720DN) Rpc_wifi_ssl_get_pskIdent(ssl_client uint32, pskIdent string result = uint32(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_ssl_set_psKey(ssl_client uint32, psKey string) (uint32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_ssl_set_psKey(ssl_client uint32, psKey string) uint32 { if r.debug { fmt.Printf("rpc_wifi_ssl_set_psKey()\r\n") } @@ -9583,10 +6856,7 @@ func (r *RTL8720DN) Rpc_wifi_ssl_set_psKey(ssl_client uint32, psKey string) (uin msg = append(msg, byte(len(psKey)), byte(len(psKey)>>8), byte(len(psKey)>>16), byte(len(psKey)>>24)) msg = append(msg, []byte(psKey)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -9595,15 +6865,10 @@ func (r *RTL8720DN) Rpc_wifi_ssl_set_psKey(ssl_client uint32, psKey string) (uin result = uint32(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_ssl_get_psKey(ssl_client uint32, psKey string) (uint32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_ssl_get_psKey(ssl_client uint32, psKey string) uint32 { if r.debug { fmt.Printf("rpc_wifi_ssl_get_psKey()\r\n") } @@ -9623,10 +6888,7 @@ func (r *RTL8720DN) Rpc_wifi_ssl_get_psKey(ssl_client uint32, psKey string) (uin msg = append(msg, []byte(psKey)...) } - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -9635,15 +6897,10 @@ func (r *RTL8720DN) Rpc_wifi_ssl_get_psKey(ssl_client uint32, psKey string) (uin result = uint32(binary.LittleEndian.Uint32(payload[widx:])) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_start_ssl_client(ssl_client uint32, host string, port uint32, timeout int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_start_ssl_client(ssl_client uint32, host string, port uint32, timeout int32) int32 { if r.debug { fmt.Printf("rpc_wifi_start_ssl_client()\r\n") } @@ -9673,33 +6930,20 @@ func (r *RTL8720DN) Rpc_wifi_start_ssl_client(ssl_client uint32, host string, po msg = append(msg, byte(timeout>>16)) msg = append(msg, byte(timeout>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_stop_ssl_socket(ssl_client uint32) error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_stop_ssl_socket(ssl_client uint32) { if r.debug { fmt.Printf("rpc_wifi_stop_ssl_socket()\r\n") } @@ -9711,23 +6955,15 @@ func (r *RTL8720DN) Rpc_wifi_stop_ssl_socket(ssl_client uint32) error { msg = append(msg, byte(ssl_client>>16)) msg = append(msg, byte(ssl_client>>24)) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_wifi_data_to_read(ssl_client uint32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_data_to_read(ssl_client uint32) int32 { if r.debug { fmt.Printf("rpc_wifi_data_to_read()\r\n") } @@ -9739,33 +6975,20 @@ func (r *RTL8720DN) Rpc_wifi_data_to_read(ssl_client uint32) (int32, error) { msg = append(msg, byte(ssl_client>>16)) msg = append(msg, byte(ssl_client>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_send_ssl_data(ssl_client uint32, data []byte, length uint16) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_send_ssl_data(ssl_client uint32, data []byte, length uint16) int32 { if r.debug { fmt.Printf("rpc_wifi_send_ssl_data()\r\n") } @@ -9783,33 +7006,20 @@ func (r *RTL8720DN) Rpc_wifi_send_ssl_data(ssl_client uint32, data []byte, lengt msg = append(msg, byte(length>>0)) msg = append(msg, byte(length>>8)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_get_ssl_receive(ssl_client uint32, data *[]byte, length int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_get_ssl_receive(ssl_client uint32, data []byte, length int32) int32 { if r.debug { fmt.Printf("rpc_wifi_get_ssl_receive()\r\n") } @@ -9826,10 +7036,7 @@ func (r *RTL8720DN) Rpc_wifi_get_ssl_receive(ssl_client uint32, data *[]byte, le msg = append(msg, byte(length>>16)) msg = append(msg, byte(length>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -9837,30 +7044,19 @@ func (r *RTL8720DN) Rpc_wifi_get_ssl_receive(ssl_client uint32, data *[]byte, le data_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if data_length > 0 { - copy(*data, payload[widx:widx+int(data_length)]) + copy(data, payload[widx:widx+int(data_length)]) widx += int(data_length) } - *data = (*data)[:data_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_verify_ssl_fingerprint(ssl_client uint32, fp string, domain_name string) (bool, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_verify_ssl_fingerprint(ssl_client uint32, fp string, domain_name string) bool { if r.debug { fmt.Printf("rpc_wifi_verify_ssl_fingerprint()\r\n") } @@ -9878,10 +7074,7 @@ func (r *RTL8720DN) Rpc_wifi_verify_ssl_fingerprint(ssl_client uint32, fp string msg = append(msg, byte(len(domain_name)), byte(len(domain_name)>>8), byte(len(domain_name)>>16), byte(len(domain_name)>>24)) msg = append(msg, []byte(domain_name)...) - err := r.performRequest(msg) - if err != nil { - return false, err - } + r.performRequest(msg) r.read() widx := 8 @@ -9890,15 +7083,10 @@ func (r *RTL8720DN) Rpc_wifi_verify_ssl_fingerprint(ssl_client uint32, fp string result = binary.LittleEndian.Uint32(payload[widx:]) == 1 r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_verify_ssl_dn(ssl_client uint32, domain_name string) (bool, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_verify_ssl_dn(ssl_client uint32, domain_name string) bool { if r.debug { fmt.Printf("rpc_wifi_verify_ssl_dn()\r\n") } @@ -9913,10 +7101,7 @@ func (r *RTL8720DN) Rpc_wifi_verify_ssl_dn(ssl_client uint32, domain_name string msg = append(msg, byte(len(domain_name)), byte(len(domain_name)>>8), byte(len(domain_name)>>16), byte(len(domain_name)>>24)) msg = append(msg, []byte(domain_name)...) - err := r.performRequest(msg) - if err != nil { - return false, err - } + r.performRequest(msg) r.read() widx := 8 @@ -9925,15 +7110,10 @@ func (r *RTL8720DN) Rpc_wifi_verify_ssl_dn(ssl_client uint32, domain_name string result = binary.LittleEndian.Uint32(payload[widx:]) == 1 r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_ssl_strerror(errnum int32, buffer *[]byte, buflen uint32) error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_ssl_strerror(errnum int32, buffer []byte, buflen uint32) { if r.debug { fmt.Printf("rpc_wifi_ssl_strerror()\r\n") } @@ -9950,10 +7130,7 @@ func (r *RTL8720DN) Rpc_wifi_ssl_strerror(errnum int32, buffer *[]byte, buflen u msg = append(msg, byte(buflen>>16)) msg = append(msg, byte(buflen>>24)) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() widx := 8 @@ -9961,83 +7138,51 @@ func (r *RTL8720DN) Rpc_wifi_ssl_strerror(errnum int32, buffer *[]byte, buflen u buffer_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if buffer_length > 0 { - copy(*buffer, payload[widx:widx+int(buffer_length)]) + copy(buffer, payload[widx:widx+int(buffer_length)]) widx += int(buffer_length) } - *buffer = (*buffer)[:buffer_length] r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_mdns_init() (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_mdns_init() int32 { if r.debug { fmt.Printf("rpc_mdns_init()\r\n") } msg := startWriteMessage(0x00, 0x12, 0x01, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_mdns_free() (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_mdns_free() int32 { if r.debug { fmt.Printf("rpc_mdns_free()\r\n") } msg := startWriteMessage(0x00, 0x12, 0x02, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_mdns_service_add(instance_name string, service_type string, proto string, port uint16) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_mdns_service_add(instance_name string, service_type string, proto string, port uint16) int32 { if r.debug { fmt.Printf("rpc_mdns_service_add()\r\n") } @@ -10056,33 +7201,20 @@ func (r *RTL8720DN) Rpc_mdns_service_add(instance_name string, service_type stri msg = append(msg, byte(port>>0)) msg = append(msg, byte(port>>8)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_mdns_service_remove(service_type string, proto string) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_mdns_service_remove(service_type string, proto string) int32 { if r.debug { fmt.Printf("rpc_mdns_service_remove()\r\n") } @@ -10095,33 +7227,20 @@ func (r *RTL8720DN) Rpc_mdns_service_remove(service_type string, proto string) ( msg = append(msg, byte(len(proto)), byte(len(proto)>>8), byte(len(proto)>>16), byte(len(proto)>>24)) msg = append(msg, []byte(proto)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_mdns_service_txt_item_set(service_type string, proto string, key string, value string) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_mdns_service_txt_item_set(service_type string, proto string, key string, value string) int32 { if r.debug { fmt.Printf("rpc_mdns_service_txt_item_set()\r\n") } @@ -10140,33 +7259,20 @@ func (r *RTL8720DN) Rpc_mdns_service_txt_item_set(service_type string, proto str msg = append(msg, byte(len(value)), byte(len(value)>>8), byte(len(value)>>16), byte(len(value)>>24)) msg = append(msg, []byte(value)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_mdns_service_instance_name_set(service string, proto string, instance string) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_mdns_service_instance_name_set(service string, proto string, instance string) int32 { if r.debug { fmt.Printf("rpc_mdns_service_instance_name_set()\r\n") } @@ -10182,33 +7288,20 @@ func (r *RTL8720DN) Rpc_mdns_service_instance_name_set(service string, proto str msg = append(msg, byte(len(instance)), byte(len(instance)>>8), byte(len(instance)>>16), byte(len(instance)>>24)) msg = append(msg, []byte(instance)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_mdns_instance_name_set(instance_name string) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_mdns_instance_name_set(instance_name string) int32 { if r.debug { fmt.Printf("rpc_mdns_instance_name_set()\r\n") } @@ -10218,33 +7311,20 @@ func (r *RTL8720DN) Rpc_mdns_instance_name_set(instance_name string) (int32, err msg = append(msg, byte(len(instance_name)), byte(len(instance_name)>>8), byte(len(instance_name)>>16), byte(len(instance_name)>>24)) msg = append(msg, []byte(instance_name)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_mdns_hostname_set(hostname string) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_mdns_hostname_set(hostname string) int32 { if r.debug { fmt.Printf("rpc_mdns_hostname_set()\r\n") } @@ -10254,33 +7334,20 @@ func (r *RTL8720DN) Rpc_mdns_hostname_set(hostname string) (int32, error) { msg = append(msg, byte(len(hostname)), byte(len(hostname)>>8), byte(len(hostname)>>16), byte(len(hostname)>>24)) msg = append(msg, []byte(hostname)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_mdns_query_a(host_name string, timeout uint32, addr *[]byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_mdns_query_a(host_name string, timeout uint32, addr []byte) int32 { if r.debug { fmt.Printf("rpc_mdns_query_a()\r\n") } @@ -10295,10 +7362,7 @@ func (r *RTL8720DN) Rpc_mdns_query_a(host_name string, timeout uint32, addr *[]b msg = append(msg, byte(timeout>>16)) msg = append(msg, byte(timeout>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -10306,30 +7370,19 @@ func (r *RTL8720DN) Rpc_mdns_query_a(host_name string, timeout uint32, addr *[]b addr_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if addr_length > 0 { - copy(*addr, payload[widx:widx+int(addr_length)]) + copy(addr, payload[widx:widx+int(addr_length)]) widx += int(addr_length) } - *addr = (*addr)[:addr_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_mdns_query_ptr(service_type string, proto string, timeout uint32, max_results int32, result_total *int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_mdns_query_ptr(service_type string, proto string, timeout uint32, max_results int32, result_total *int32) int32 { if r.debug { fmt.Printf("rpc_mdns_query_ptr()\r\n") } @@ -10352,10 +7405,7 @@ func (r *RTL8720DN) Rpc_mdns_query_ptr(service_type string, proto string, timeou msg = append(msg, byte(max_results>>16)) msg = append(msg, byte(max_results>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -10365,23 +7415,13 @@ func (r *RTL8720DN) Rpc_mdns_query_ptr(service_type string, proto string, timeou var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_mdns_query_ptr_result_basic(result_target int32, scan_result *[]byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_mdns_query_ptr_result_basic(result_target int32, scan_result []byte) int32 { if r.debug { fmt.Printf("rpc_mdns_query_ptr_result_basic()\r\n") } @@ -10393,10 +7433,7 @@ func (r *RTL8720DN) Rpc_mdns_query_ptr_result_basic(result_target int32, scan_re msg = append(msg, byte(result_target>>16)) msg = append(msg, byte(result_target>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -10404,30 +7441,19 @@ func (r *RTL8720DN) Rpc_mdns_query_ptr_result_basic(result_target int32, scan_re scan_result_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if scan_result_length > 0 { - copy(*scan_result, payload[widx:widx+int(scan_result_length)]) + copy(scan_result, payload[widx:widx+int(scan_result_length)]) widx += int(scan_result_length) } - *scan_result = (*scan_result)[:scan_result_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_mdns_query_ptr_result_txt(result_target int32, txt_target int32, txt *[]byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_mdns_query_ptr_result_txt(result_target int32, txt_target int32, txt []byte) int32 { if r.debug { fmt.Printf("rpc_mdns_query_ptr_result_txt()\r\n") } @@ -10444,10 +7470,7 @@ func (r *RTL8720DN) Rpc_mdns_query_ptr_result_txt(result_target int32, txt_targe msg = append(msg, byte(txt_target>>16)) msg = append(msg, byte(txt_target>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -10455,30 +7478,19 @@ func (r *RTL8720DN) Rpc_mdns_query_ptr_result_txt(result_target int32, txt_targe txt_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if txt_length > 0 { - copy(*txt, payload[widx:widx+int(txt_length)]) + copy(txt, payload[widx:widx+int(txt_length)]) widx += int(txt_length) } - *txt = (*txt)[:txt_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_mdns_query_ptr_result_addr(result_target int32, addr_target int32, addr *[]byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_mdns_query_ptr_result_addr(result_target int32, addr_target int32, addr []byte) int32 { if r.debug { fmt.Printf("rpc_mdns_query_ptr_result_addr()\r\n") } @@ -10495,10 +7507,7 @@ func (r *RTL8720DN) Rpc_mdns_query_ptr_result_addr(result_target int32, addr_tar msg = append(msg, byte(addr_target>>16)) msg = append(msg, byte(addr_target>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 @@ -10506,61 +7515,37 @@ func (r *RTL8720DN) Rpc_mdns_query_ptr_result_addr(result_target int32, addr_tar addr_length := binary.LittleEndian.Uint32(payload[widx:]) widx += 4 if addr_length > 0 { - copy(*addr, payload[widx:widx+int(addr_length)]) + copy(addr, payload[widx:widx+int(addr_length)]) widx += int(addr_length) } - *addr = (*addr)[:addr_length] var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_mdns_query_results_free() (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_mdns_query_results_free() int32 { if r.debug { fmt.Printf("rpc_mdns_query_results_free()\r\n") } msg := startWriteMessage(0x00, 0x12, 0x0E, uint32(r.seq)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_wifi_event_callback(event []byte) error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_event_callback(event []byte) { if r.debug { fmt.Printf("rpc_wifi_event_callback()\r\n") } @@ -10570,23 +7555,15 @@ func (r *RTL8720DN) Rpc_wifi_event_callback(event []byte) error { msg = append(msg, byte(len(event)), byte(len(event)>>8), byte(len(event)>>16), byte(len(event)>>24)) msg = append(msg, []byte(event)...) - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_wifi_dns_found(hostname string, ipaddr []byte, arg []byte) error { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_wifi_dns_found(hostname string, ipaddr []byte, arg []byte) { if r.debug { fmt.Printf("rpc_wifi_dns_found()\r\n") } @@ -10607,23 +7584,15 @@ func (r *RTL8720DN) Rpc_wifi_dns_found(hostname string, ipaddr []byte, arg []byt msg = append(msg, []byte(arg)...) } - err := r.performRequest(msg) - if err != nil { - return err - } + r.performRequest(msg) r.read() r.seq++ - return err + return } -func (r *RTL8720DN) Rpc_tcpip_api_call_fn(fn uint32, call []byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcpip_api_call_fn(fn uint32, call []byte) int32 { if r.debug { fmt.Printf("rpc_tcpip_api_call_fn()\r\n") } @@ -10638,33 +7607,20 @@ func (r *RTL8720DN) Rpc_tcpip_api_call_fn(fn uint32, call []byte) (int32, error) msg = append(msg, byte(len(call)), byte(len(call)>>8), byte(len(call)>>16), byte(len(call)>>24)) msg = append(msg, []byte(call)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcp_connected_fn(fn uint32, arg []byte, tpcb []byte, err_val int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcp_connected_fn(fn uint32, arg []byte, tpcb []byte, err_val int32) int32 { if r.debug { fmt.Printf("rpc_tcp_connected_fn()\r\n") } @@ -10687,33 +7643,20 @@ func (r *RTL8720DN) Rpc_tcp_connected_fn(fn uint32, arg []byte, tpcb []byte, err msg = append(msg, byte(err_val>>16)) msg = append(msg, byte(err_val>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcp_recv_fn(fn uint32, arg []byte, tpcb []byte, p_data []byte, p_addr []byte, err_val int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcp_recv_fn(fn uint32, arg []byte, tpcb []byte, p_data []byte, p_addr []byte, err_val int32) int32 { if r.debug { fmt.Printf("rpc_tcp_recv_fn()\r\n") } @@ -10742,33 +7685,20 @@ func (r *RTL8720DN) Rpc_tcp_recv_fn(fn uint32, arg []byte, tpcb []byte, p_data [ msg = append(msg, byte(err_val>>16)) msg = append(msg, byte(err_val>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcp_accept_fn(fn uint32, arg []byte, newpcb []byte, err_val int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcp_accept_fn(fn uint32, arg []byte, newpcb []byte, err_val int32) int32 { if r.debug { fmt.Printf("rpc_tcp_accept_fn()\r\n") } @@ -10791,33 +7721,20 @@ func (r *RTL8720DN) Rpc_tcp_accept_fn(fn uint32, arg []byte, newpcb []byte, err_ msg = append(msg, byte(err_val>>16)) msg = append(msg, byte(err_val>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcp_err_fn(fn uint32, arg []byte, err_val int32) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcp_err_fn(fn uint32, arg []byte, err_val int32) int32 { if r.debug { fmt.Printf("rpc_tcp_err_fn()\r\n") } @@ -10837,33 +7754,20 @@ func (r *RTL8720DN) Rpc_tcp_err_fn(fn uint32, arg []byte, err_val int32) (int32, msg = append(msg, byte(err_val>>16)) msg = append(msg, byte(err_val>>24)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcp_sent_fn(fn uint32, arg []byte, tpcb []byte, length uint16) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcp_sent_fn(fn uint32, arg []byte, tpcb []byte, length uint16) int32 { if r.debug { fmt.Printf("rpc_tcp_sent_fn()\r\n") } @@ -10884,33 +7788,20 @@ func (r *RTL8720DN) Rpc_tcp_sent_fn(fn uint32, arg []byte, tpcb []byte, length u msg = append(msg, byte(length>>0)) msg = append(msg, byte(length>>8)) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } -func (r *RTL8720DN) Rpc_tcp_poll_fn(fn uint32, arg []byte, tpcb []byte) (int32, error) { - r.sema <- true - defer func() { - <-r.sema - }() - +func (r *rtl8720dn) rpc_tcp_poll_fn(fn uint32, arg []byte, tpcb []byte) int32 { if r.debug { fmt.Printf("rpc_tcp_poll_fn()\r\n") } @@ -10928,23 +7819,15 @@ func (r *RTL8720DN) Rpc_tcp_poll_fn(fn uint32, arg []byte, tpcb []byte) (int32, msg = append(msg, byte(len(tpcb)), byte(len(tpcb)>>8), byte(len(tpcb)>>16), byte(len(tpcb)>>24)) msg = append(msg, []byte(tpcb)...) - err := r.performRequest(msg) - if err != nil { - return 0, err - } + r.performRequest(msg) r.read() widx := 8 var result int32 x := binary.LittleEndian.Uint32(payload[widx:]) - if x >= 0x80000000 { - result = int32(int(x) * -1) - } else { - result = int32(int(x)) - } result = int32(x) r.seq++ - return result, err + return result } diff --git a/rtl8720dn/rpc_util.go b/rtl8720dn/rpc_util.go index ee894224a..68efebbe0 100644 --- a/rtl8720dn/rpc_util.go +++ b/rtl8720dn/rpc_util.go @@ -9,7 +9,7 @@ var ( headerBuf [4]byte readBuf [4]byte startWriteMessageBuf [1024]byte - payload [1024 + 256]byte + payload [2048]byte ) const ( @@ -30,7 +30,7 @@ func startWriteMessage(msgType, service, requestNumber, sequence uint32) []byte return startWriteMessageBuf[:8] } -func (r *RTL8720DN) performRequest(msg []byte) error { +func (r *rtl8720dn) performRequest(msg []byte) { crc := computeCRC16(msg) headerBuf[0] = byte(len(msg)) headerBuf[1] = byte(len(msg) >> 8) @@ -43,16 +43,14 @@ func (r *RTL8720DN) performRequest(msg []byte) error { fmt.Printf("\r\n") } - r.port.Write(headerBuf[:]) + r.uart.Write(headerBuf[:]) if r.debug { fmt.Printf("tx : %2d : ", len(msg)) dumpHex(msg) fmt.Printf("\r\n") } - r.port.Write(msg) - - return nil + r.uart.Write(msg) } func dumpHex(b []byte) { @@ -65,9 +63,9 @@ func dumpHex(b []byte) { } } -func (r *RTL8720DN) read() { +func (r *rtl8720dn) read() { for { - n, _ := io.ReadFull(r.port, readBuf[:4]) + n, _ := io.ReadFull(r.uart, readBuf[:4]) if n == 0 { continue } @@ -81,7 +79,7 @@ func (r *RTL8720DN) read() { length := uint16(readBuf[0]) + uint16(readBuf[1])<<8 crc := uint16(readBuf[2]) + uint16(readBuf[3])<<8 - n, _ = io.ReadFull(r.port, payload[:length]) + n, _ = io.ReadFull(r.uart, payload[:length]) if r.debug { fmt.Printf("rx : %2d : ", length) dumpHex(payload[0:n]) diff --git a/rtl8720dn/rtl8720dn.go b/rtl8720dn/rtl8720dn.go index 8a21bde97..fa0f38447 100644 --- a/rtl8720dn/rtl8720dn.go +++ b/rtl8720dn/rtl8720dn.go @@ -1,69 +1,776 @@ -package rtl8720dn +// Package rtl8720dn implements TCP wireless communication over UART +// talking to a RealTek rtl8720dn module. +// +// 01/2023 sfeldma@gmail.com Heavily modified to use netdev interface -import ( - "machine" +package rtl8720dn // import "tinygo.org/x/drivers/rtl8720dn" +import ( + "encoding/hex" + "errors" + "fmt" "io" + "machine" + "net" + "strings" + "sync" "time" + + "tinygo.org/x/drivers/netdev" + "tinygo.org/x/drivers/netlink" ) -const maxUartRecvSize = 128 +var _debug debug = debugBasic + +//var _debug debug = debugBasic | debugNetdev +//var _debug debug = debugBasic | debugNetdev | debugRpc + +var ( + version = "0.0.1" + driverName = "Realtek rtl8720dn Wifi network device driver (rtl8720dn)" +) + +const ( + O_NONBLOCK = 1 // note: different value than syscall.O_NONBLOCK (0x800) + RTW_MODE_STA = 0x00000001 +) + +type sock int32 + +type socket struct { + protocol int + inuse bool +} + +type Config struct { + // Enable + En machine.Pin + + // UART config + Uart *machine.UART + Tx machine.Pin + Rx machine.Pin + Baudrate uint32 +} + +type rtl8720dn struct { + cfg *Config + notifyCb func(netlink.Event) + mu sync.Mutex + + uart *machine.UART + seq uint64 -type RTL8720DN struct { - port io.ReadWriter - seq uint64 - sema chan bool debug bool - connectionType ConnectionType - socket int32 - client uint32 - length int - root_ca *string - udpInfo [6]byte // Port: [2]byte + IP: [4]byte + params *netlink.ConnectParams + + netConnected bool + driverShown bool + deviceShown bool + + killWatchdog chan bool + + // keyed by sock as returned by rpc_lwip_socket() + sockets map[sock]*socket } -type ConnectionType int +func newSocket(protocol int) *socket { + return &socket{protocol: protocol, inuse: true} +} -const ( - ConnectionTypeNone ConnectionType = iota - ConnectionTypeTCP - ConnectionTypeUDP - ConnectionTypeTLS -) +func New(cfg *Config) *rtl8720dn { + return &rtl8720dn{ + debug: (_debug & debugRpc) != 0, + cfg: cfg, + sockets: make(map[sock]*socket), + killWatchdog: make(chan bool), + } +} + +func (r *rtl8720dn) startDhcpc() error { + if result := r.rpc_tcpip_adapter_dhcpc_start(0); result == -1 { + return netdev.ErrStartingDHCPClient + } + return nil +} -func (d *Driver) SetSeq(s uint64) { - d.seq = s +func (r *rtl8720dn) connectToAP() error { + + if len(r.params.Ssid) == 0 { + return netlink.ErrMissingSSID + } + + if debugging(debugBasic) { + fmt.Printf("Connecting to Wifi SSID '%s'...", r.params.Ssid) + } + + // Start the connection process + securityType := uint32(0x00400004) + result := r.rpc_wifi_connect(r.params.Ssid, r.params.Passphrase, securityType, -1, 0) + if result == -1 { + if debugging(debugBasic) { + fmt.Printf("FAILED\r\n") + } + return netlink.ErrConnectFailed + } + + if debugging(debugBasic) { + fmt.Printf("CONNECTED\r\n") + } + + if r.notifyCb != nil { + r.notifyCb(netlink.EventNetUp) + } + + return r.startDhcpc() } -func (d *Driver) Debug(b bool) { - d.debug = b +func (r *rtl8720dn) showDriver() { + if r.driverShown { + return + } + if debugging(debugBasic) { + fmt.Printf("\r\n") + fmt.Printf("%s\r\n\r\n", driverName) + fmt.Printf("Driver version : %s\r\n", version) + } + r.driverShown = true } -func (d *Driver) SetRootCA(s *string) { - d.root_ca = s +func (r *rtl8720dn) initWifi() error { + if result := r.rpc_tcpip_adapter_init(); result == -1 { + return fmt.Errorf("TCP/IP adapter init failed") + } + if result := r.rpc_wifi_off(); result == -1 { + return errors.New("Error turning off WiFi") + } + if result := r.rpc_wifi_on(RTW_MODE_STA); result == -1 { + return errors.New("Error turning on WiFi") + } + if result := r.rpc_wifi_disconnect(); result == -1 { + return errors.New("Error disconnecting WiFi") + } + return nil } -func (d *Driver) Version() (string, error) { - return d.Rpc_system_version() +func (r *rtl8720dn) setupUART() { + r.uart = r.cfg.Uart + r.uart.Configure(machine.UARTConfig{TX: r.cfg.Tx, + RX: r.cfg.Rx, BaudRate: r.cfg.Baudrate}) } -func enable(en machine.Pin) { +func (r *rtl8720dn) start() error { + en := r.cfg.En + if en == 0 { + return fmt.Errorf("Must set Config.En") + } en.Configure(machine.PinConfig{Mode: machine.PinOutput}) en.Low() time.Sleep(100 * time.Millisecond) en.High() time.Sleep(1000 * time.Millisecond) + r.setupUART() + return r.initWifi() +} + +func (r *rtl8720dn) stop() { + r.rpc_tcpip_adapter_stop(0) + r.cfg.En.Low() +} + +func (r *rtl8720dn) showDevice() { + if r.deviceShown { + return + } + if debugging(debugBasic) { + fmt.Printf("RTL8720 firmware version : %s\r\n", r.getFwVersion()) + fmt.Printf("MAC address : %s\r\n", r.getMACAddr()) + fmt.Printf("\r\n") + } + r.deviceShown = true +} + +func (r *rtl8720dn) showIP() { + if debugging(debugBasic) { + ip, subnet, gateway, _ := r.getIP() + fmt.Printf("\r\n") + fmt.Printf("DHCP-assigned IP : %s\r\n", ip.String()) + fmt.Printf("DHCP-assigned subnet : %s\r\n", subnet.String()) + fmt.Printf("DHCP-assigned gateway : %s\r\n", gateway.String()) + fmt.Printf("\r\n") + } +} + +func (r *rtl8720dn) networkDown() bool { + result := r.rpc_wifi_is_connected_to_ap() + return result != 0 +} + +func (r *rtl8720dn) watchdog() { + ticker := time.NewTicker(r.params.WatchdogTimeout) + for { + select { + case <-r.killWatchdog: + return + case <-ticker.C: + r.mu.Lock() + if r.networkDown() { + if debugging(debugBasic) { + fmt.Printf("Watchdog: Wifi NOT CONNECTED, trying again...\r\n") + } + if r.notifyCb != nil { + r.notifyCb(netlink.EventNetDown) + } + r.netConnect(false) + } + r.mu.Unlock() + } + } +} + +func (r *rtl8720dn) netConnect(reset bool) error { + if reset { + if err := r.start(); err != nil { + return err + } + } + r.showDevice() + + for i := 0; r.params.Retries == 0 || i < r.params.Retries; i++ { + if err := r.connectToAP(); err != nil { + if err == netlink.ErrConnectFailed { + continue + } + return err + } + break + } + + if r.networkDown() { + return netlink.ErrConnectFailed + } + + r.showIP() + return nil +} + +func (r *rtl8720dn) NetConnect(params *netlink.ConnectParams) error { + + r.mu.Lock() + defer r.mu.Unlock() + + if r.netConnected { + return netlink.ErrConnected + } + + r.params = params + + r.showDriver() + + if err := r.netConnect(true); err != nil { + return err + } + + r.netConnected = true + + if r.params.WatchdogTimeout != 0 { + go r.watchdog() + } + + return nil +} + +func (r *rtl8720dn) netDisconnect() { + r.disconnect() +} + +func (r *rtl8720dn) NetDisconnect() { + + r.mu.Lock() + defer r.mu.Unlock() + + if !r.netConnected { + return + } + + if r.params.WatchdogTimeout != 0 { + r.killWatchdog <- true + } + r.netDisconnect() + r.stop() + + r.netConnected = false + + if debugging(debugBasic) { + fmt.Printf("\r\nDisconnected from Wifi SSID '%s'\r\n\r\n", r.params.Ssid) + } + + if r.notifyCb != nil { + r.notifyCb(netlink.EventNetDown) + } +} + +func (r *rtl8720dn) NetNotify(cb func(netlink.Event)) { + r.notifyCb = cb +} + +func (r *rtl8720dn) GetHostByName(name string) (net.IP, error) { + + if debugging(debugNetdev) { + fmt.Printf("[GetHostByName] name: %s\r\n", name) + } + + r.mu.Lock() + defer r.mu.Unlock() + + var ip [4]byte + result := r.rpc_netconn_gethostbyname(name, ip[:]) + if result == -1 { + return net.IP{}, netdev.ErrHostUnknown + } + + return net.IP(ip[:]), nil +} + +func (r *rtl8720dn) GetHardwareAddr() (net.HardwareAddr, error) { + + if debugging(debugNetdev) { + fmt.Printf("[GetHardwareAddr]\r\n") + } + + r.mu.Lock() + defer r.mu.Unlock() + + mac := strings.ReplaceAll(r.getMACAddr(), ":", "") + addr, err := hex.DecodeString(mac) + + return net.HardwareAddr(addr), err +} + +func (r *rtl8720dn) GetIPAddr() (net.IP, error) { + + if debugging(debugNetdev) { + fmt.Printf("[GetIPAddr]\r\n") + } + + r.mu.Lock() + defer r.mu.Unlock() + + ip, _, _, err := r.getIP() + + return net.IP(ip), err +} + +func (r *rtl8720dn) clientTLS() uint32 { + client := r.rpc_wifi_ssl_client_create() + r.rpc_wifi_ssl_init(client) + r.rpc_wifi_ssl_set_timeout(client, 120*1000 /* usec? */) + return client +} + +// See man socket(2) for standard Berkely sockets for Socket, Bind, etc. +// The driver strives to meet the function and semantics of socket(2). + +func (r *rtl8720dn) Socket(domain int, stype int, protocol int) (int, error) { + + if debugging(debugNetdev) { + fmt.Printf("[Socket] domain: %d, type: %d, protocol: %d\r\n", + domain, stype, protocol) + } + + switch domain { + case netdev.AF_INET: + default: + return -1, netdev.ErrFamilyNotSupported + } + + var newSock int32 + + r.mu.Lock() + defer r.mu.Unlock() + + switch { + case protocol == netdev.IPPROTO_TCP && stype == netdev.SOCK_STREAM: + newSock = r.rpc_lwip_socket(netdev.AF_INET, netdev.SOCK_STREAM, + netdev.IPPROTO_TCP) + case protocol == netdev.IPPROTO_TLS && stype == netdev.SOCK_STREAM: + // TODO Investigate: using client number as socket number; + // TODO this may cause a problem if mixing TLS and non-TLS sockets? + newSock = int32(r.clientTLS()) + case protocol == netdev.IPPROTO_UDP && stype == netdev.SOCK_DGRAM: + newSock = r.rpc_lwip_socket(netdev.AF_INET, netdev.SOCK_DGRAM, + netdev.IPPROTO_UDP) + default: + return -1, netdev.ErrProtocolNotSupported + } + + if newSock == -1 { + return -1, netdev.ErrNoMoreSockets + } + + socket := newSocket(protocol) + r.sockets[sock(newSock)] = socket + + return int(newSock), nil +} + +func addrToName(ip net.IP, port int) []byte { + name := make([]byte, 16) + name[0] = 0x00 + name[1] = netdev.AF_INET + name[2] = byte(port >> 8) + name[3] = byte(port) + if len(ip) == 4 { + name[4] = byte(ip[0]) + name[5] = byte(ip[1]) + name[6] = byte(ip[2]) + name[7] = byte(ip[3]) + } + + return name +} + +func (r *rtl8720dn) Bind(sockfd int, ip net.IP, port int) error { + + if debugging(debugNetdev) { + fmt.Printf("[Bind] sockfd: %d, addr: %s:%d\r\n", sockfd, ip, port) + } + + r.mu.Lock() + defer r.mu.Unlock() + + var sock = sock(sockfd) + var socket = r.sockets[sock] + var name = addrToName(ip, port) + + switch socket.protocol { + case netdev.IPPROTO_TCP, netdev.IPPROTO_UDP: + result := r.rpc_lwip_bind(int32(sock), name, uint32(len(name))) + if result == -1 { + return fmt.Errorf("Bind to %s:%d failed", ip, port) + } + default: + return netdev.ErrProtocolNotSupported + } + + return nil +} + +func (r *rtl8720dn) Connect(sockfd int, host string, ip net.IP, port int) error { + + if debugging(debugNetdev) { + if host == "" { + fmt.Printf("[Connect] sockfd: %d, addr: %s:%d\r\n", sockfd, ip, port) + } else { + fmt.Printf("[Connect] sockfd: %d, host: %s:%d\r\n", sockfd, host, port) + } + } + + r.mu.Lock() + defer r.mu.Unlock() + + var sock = sock(sockfd) + var socket = r.sockets[sock] + var name = addrToName(ip, port) + + // Start the connection + switch socket.protocol { + case netdev.IPPROTO_TCP, netdev.IPPROTO_UDP: + result := r.rpc_lwip_connect(int32(sock), name, uint32(len(name))) + if result == -1 { + return fmt.Errorf("Connect to %s:%d failed", ip, port) + } + case netdev.IPPROTO_TLS: + result := r.rpc_wifi_start_ssl_client(uint32(sock), + host, uint32(port), 0) + if result == -1 { + return fmt.Errorf("Connect to %s:%d failed", host, port) + } + } + + return nil +} + +func (r *rtl8720dn) Listen(sockfd int, backlog int) error { + + if debugging(debugNetdev) { + fmt.Printf("[Listen] sockfd: %d\r\n", sockfd) + } + + r.mu.Lock() + defer r.mu.Unlock() + + var sock = sock(sockfd) + var socket = r.sockets[sock] + + switch socket.protocol { + case netdev.IPPROTO_TCP: + result := r.rpc_lwip_listen(int32(sock), int32(backlog)) + if result == -1 { + return fmt.Errorf("Listen failed") + } + result = r.rpc_lwip_fcntl(int32(sock), netdev.F_SETFL, O_NONBLOCK) + if result == -1 { + return fmt.Errorf("Fcntl failed") + } + case netdev.IPPROTO_UDP: + result := r.rpc_lwip_listen(int32(sock), int32(backlog)) + if result == -1 { + return fmt.Errorf("Listen failed") + } + default: + return netdev.ErrProtocolNotSupported + } + + return nil +} + +func (r *rtl8720dn) Accept(sockfd int, ip net.IP, port int) (int, error) { + + if debugging(debugNetdev) { + fmt.Printf("[Accept] sockfd: %d, peer: %s:%d\r\n", sockfd, ip, port) + } + + r.mu.Lock() + defer r.mu.Unlock() + + var newSock int32 + var lsock = sock(sockfd) + var socket = r.sockets[lsock] + var addr = addrToName(ip, port) + + switch socket.protocol { + case netdev.IPPROTO_TCP: + default: + return -1, netdev.ErrProtocolNotSupported + } + + for { + // Accept() will be sleeping most of the time, checking for a + // new clients every 1/10 sec. + r.mu.Unlock() + time.Sleep(100 * time.Millisecond) + r.mu.Lock() + + // Check if a client connected. O_NONBLOCK is set on lsock. + addrlen := uint32(len(addr)) + newSock = r.rpc_lwip_accept(int32(lsock), addr, &addrlen) + if newSock == -1 { + // No new client + time.Sleep(100 * time.Millisecond) + continue + } + + // If we've already seen this socket, we can re-use + // the socket and return it. But, only if the socket + // is closed. If it's not closed, we'll just come back + // later to reuse it. + + clientSocket, ok := r.sockets[sock(newSock)] + if ok { + // Wait for client to Close + if clientSocket.inuse { + continue + } + // Reuse client socket + return int(newSock), nil + } + + // Create new socket for client and return fd + r.sockets[sock(newSock)] = newSocket(socket.protocol) + return int(newSock), nil + } +} + +func (r *rtl8720dn) sendChunk(sockfd int, buf []byte, deadline time.Time) (int, error) { + var sock = sock(sockfd) + var socket = r.sockets[sock] + + // Check if we've timed out + if !deadline.IsZero() { + if time.Now().After(deadline) { + return -1, netdev.ErrTimeout + } + } + + switch socket.protocol { + case netdev.IPPROTO_TCP, netdev.IPPROTO_UDP: + result := r.rpc_lwip_send(int32(sock), buf, 0x00000008) + if result == -1 { + return -1, fmt.Errorf("Send error") + } + return int(result), nil + case netdev.IPPROTO_TLS: + result := r.rpc_wifi_send_ssl_data(uint32(sock), buf, uint16(len(buf))) + if result == -1 { + return -1, fmt.Errorf("TLS Send error") + } + return int(result), nil + } + + return -1, netdev.ErrProtocolNotSupported +} + +func (r *rtl8720dn) Send(sockfd int, buf []byte, flags int, + deadline time.Time) (int, error) { + + if debugging(debugNetdev) { + fmt.Printf("[Send] sockfd: %d, len(buf): %d, flags: %d\r\n", + sockfd, len(buf), flags) + } + + r.mu.Lock() + defer r.mu.Unlock() + + // Break large bufs into chunks + + chunkSize := 1436 + for i := 0; i < len(buf); i += chunkSize { + end := i + chunkSize + if end > len(buf) { + end = len(buf) + } + _, err := r.sendChunk(sockfd, buf[i:end], deadline) + if err != nil { + return -1, err + } + } + + return len(buf), nil +} + +func (r *rtl8720dn) Recv(sockfd int, buf []byte, flags int, + deadline time.Time) (int, error) { + + if debugging(debugNetdev) { + fmt.Printf("[Recv] sockfd: %d, len(buf): %d, flags: %d\r\n", + sockfd, len(buf), flags) + } + + r.mu.Lock() + defer r.mu.Unlock() + + var sock = sock(sockfd) + var socket = r.sockets[sock] + var length = len(buf) + var n int32 + + // Limit length read size to chunk large read requests + if length > 1436 { + length = 1436 + } + + for { + // Check if we've timed out + if !deadline.IsZero() { + if time.Now().After(deadline) { + return -1, netdev.ErrTimeout + } + } + + switch socket.protocol { + case netdev.IPPROTO_TCP, netdev.IPPROTO_UDP: + n = r.rpc_lwip_recv(int32(sock), buf[:length], + uint32(length), 0x00000008, 0) + case netdev.IPPROTO_TLS: + n = r.rpc_wifi_get_ssl_receive(uint32(sock), + buf[:length], int32(length)) + } + + if n < 0 { + r.mu.Unlock() + time.Sleep(100 * time.Millisecond) + r.mu.Lock() + continue + } else if n == 0 { + if debugging(debugNetdev) { + fmt.Printf("[<--Recv] sockfd: %d, n: %d EOF\r\n", + sock, n) + } + return -1, io.EOF + } + + if debugging(debugNetdev) { + fmt.Printf("[<--Recv] sockfd: %d, n: %d\r\n", + sock, n) + } + + return int(n), nil + } +} + +func (r *rtl8720dn) Close(sockfd int) error { + + if debugging(debugNetdev) { + fmt.Printf("[Close] sockfd: %d\r\n", sockfd) + } + + r.mu.Lock() + defer r.mu.Unlock() + + var sock = sock(sockfd) + var socket = r.sockets[sock] + var result int32 + + if !socket.inuse { + return nil + } + + switch socket.protocol { + case netdev.IPPROTO_TCP, netdev.IPPROTO_UDP: + result = r.rpc_lwip_close(int32(sock)) + case netdev.IPPROTO_TLS: + r.rpc_wifi_stop_ssl_socket(uint32(sock)) + r.rpc_wifi_ssl_client_destroy(uint32(sock)) + } + + if result == -1 { + return netdev.ErrClosingSocket + } + + socket.inuse = false + + return nil +} + +func (r *rtl8720dn) SetSockOpt(sockfd int, level int, opt int, value interface{}) error { + + if debugging(debugNetdev) { + fmt.Printf("[SetSockOpt] sockfd: %d\r\n", sockfd) + } + + return netdev.ErrNotSupported +} + +func (r *rtl8720dn) disconnect() error { + result := r.rpc_wifi_disconnect() + if result == -1 { + return fmt.Errorf("Error disconnecting Wifi") + } + return nil +} + +func (r *rtl8720dn) getFwVersion() string { + return r.rpc_system_version() } -type UARTx struct { - *machine.UART +func (r *rtl8720dn) getMACAddr() string { + var mac [18]uint8 + r.rpc_wifi_get_mac_address(mac[:]) + return string(mac[:]) } -func (u *UARTx) Read(p []byte) (n int, err error) { - if u.Buffered() == 0 { - time.Sleep(1 * time.Millisecond) - return 0, nil +func (r *rtl8720dn) getIP() (ip, subnet, gateway net.IP, err error) { + var ip_info [12]byte + result := r.rpc_tcpip_adapter_get_ip_info(0, ip_info[:]) + if result == -1 { + err = fmt.Errorf("Get IP info failed") + return } - return u.UART.Read(p) + ip, subnet, gateway = make([]byte, 4), make([]byte, 4), make([]byte, 4) + copy(ip[:], ip_info[0:4]) + copy(subnet[:], ip_info[4:8]) + copy(gateway[:], ip_info[8:12]) + return } diff --git a/rtl8720dn/util.go b/rtl8720dn/util.go deleted file mode 100644 index 588106c5c..000000000 --- a/rtl8720dn/util.go +++ /dev/null @@ -1,51 +0,0 @@ -package rtl8720dn - -import ( - "bytes" - "encoding/binary" - "fmt" - "strconv" - "strings" -) - -type httpHeader []byte - -func (h httpHeader) ContentLength() int { - contentLength := -1 - idx := bytes.Index(h, []byte("Content-Length: ")) - if 0 <= idx { - _, err := fmt.Sscanf(string(h[idx+16:]), "%d", &contentLength) - if err != nil { - return -1 - } - } - return contentLength -} - -// TODO: IPAddress implementation should be moved under drivers/net -// The same implementation exists in wifinina. -type IPAddress []byte - -func (addr IPAddress) String() string { - if len(addr) < 4 { - return "" - } - return strconv.Itoa(int(addr[0])) + "." + strconv.Itoa(int(addr[1])) + "." + strconv.Itoa(int(addr[2])) + "." + strconv.Itoa(int(addr[3])) -} - -func ParseIPv4(s string) (IPAddress, error) { - v := strings.Split(s, ".") - v0, _ := strconv.Atoi(v[0]) - v1, _ := strconv.Atoi(v[1]) - v2, _ := strconv.Atoi(v[2]) - v3, _ := strconv.Atoi(v[3]) - return IPAddress([]byte{byte(v0), byte(v1), byte(v2), byte(v3)}), nil -} - -func (addr IPAddress) AsUint32() uint32 { - if len(addr) < 4 { - return 0 - } - b := []byte(string(addr)) - return binary.BigEndian.Uint32(b[0:4]) -} diff --git a/rtl8720dn/wifi.go b/rtl8720dn/wifi.go deleted file mode 100644 index 08764210c..000000000 --- a/rtl8720dn/wifi.go +++ /dev/null @@ -1,72 +0,0 @@ -package rtl8720dn - -import ( - "fmt" - "time" -) - -func (d *Driver) ConnectToAP(ssid string, password string) error { - if len(ssid) == 0 || len(password) == 0 { - return fmt.Errorf("connection failed: either ssid or password not set") - } - - _, err := d.Rpc_wifi_off() - if err != nil { - return err - } - _, err = d.Rpc_wifi_on(0x00000001) - if err != nil { - return err - } - - _, err = d.Rpc_wifi_disconnect() - if err != nil { - return err - } - - numTry := 5 - securityType := uint32(0x00400004) - for i := 0; i < numTry; i++ { - ret, err := d.Rpc_wifi_connect(ssid, password, securityType, -1, 0) - if err != nil { - return err - } - if ret != 0 { - if i == numTry-1 { - return fmt.Errorf("connection failed: rpc_wifi_connect failed") - } - time.Sleep(100 * time.Millisecond) - } else { - break - } - } - - _, err = d.Rpc_tcpip_adapter_dhcpc_start(0) - if err != nil { - return err - } - - for i := 0; i < 3; i++ { - _, err = d.Rpc_wifi_is_connected_to_ap() - if err != nil { - return err - } - time.Sleep(1 * time.Second) - } - - return nil -} - -func (d *Driver) GetIP() (ip, subnet, gateway IPAddress, err error) { - ip_info := make([]byte, 12) - _, err = d.Rpc_tcpip_adapter_get_ip_info(0, &ip_info) - if err != nil { - return nil, nil, nil, err - } - - ip = IPAddress(ip_info[0:4]) - subnet = IPAddress(ip_info[4:8]) - gateway = IPAddress(ip_info[8:12]) - - return ip, subnet, gateway, nil -} diff --git a/smoketest.sh b/smoketest.sh index 777401ef3..a3b6d3593 100755 --- a/smoketest.sh +++ b/smoketest.sh @@ -24,9 +24,6 @@ tinygo build -size short -o ./build/test.hex -target=bluepill ./examples/ds1307/ tinygo build -size short -o ./build/test.hex -target=bluepill ./examples/ds1307/time/main.go tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/ds3231/main.go tinygo build -size short -o ./build/test.hex -target=microbit ./examples/easystepper/main.go -tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/espat/espconsole/main.go -tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/espat/esphub/main.go -tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/espat/espstation/main.go tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/flash/console/spi tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/flash/console/qspi tinygo build -size short -o ./build/test.hex -target=microbit ./examples/gc9a01/main.go @@ -81,10 +78,6 @@ tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/vl6 tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd2in13/main.go tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd2in13x/main.go tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd4in2/main.go -tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/wifinina/ntpclient/main.go -tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/wifinina/udpstation/main.go -tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/wifinina/tcpclient/main.go -tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/wifinina/webclient/main.go tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/ws2812 tinygo build -size short -o ./build/test.bin -target=m5stamp-c3 ./examples/ws2812 tinygo build -size short -o ./build/test.hex -target=feather-nrf52840 ./examples/is31fl3731/main.go @@ -113,9 +106,6 @@ tinygo build -size short -o ./build/test.hex -target=pico ./examples/qmi8658c/ma tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/ina260/main.go tinygo build -size short -o ./build/test.hex -target=nucleo-l432kc ./examples/aht20/main.go tinygo build -size short -o ./build/test.hex -target=feather-m4 ./examples/sdcard/console/ -tinygo build -size short -o ./build/test.hex -target=wioterminal ./examples/rtl8720dn/webclient/ -tinygo build -size short -o ./build/test.hex -target=wioterminal ./examples/rtl8720dn/webserver/ -tinygo build -size short -o ./build/test.hex -target=wioterminal ./examples/rtl8720dn/mqttsub/ tinygo build -size short -o ./build/test.hex -target=feather-m4 ./examples/i2csoft/adt7410/ tinygo build -size short -o ./build/test.elf -target=wioterminal ./examples/axp192/m5stack-core2-blinky/ tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/xpt2046/main.go @@ -137,3 +127,17 @@ tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ndir/ma tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/ndir/main_ndir.go tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/mpu9150/main.go tinygo build -size short -o ./build/test.hex -target=macropad-rp2040 ./examples/sh1106/macropad_spi +# network examples (espat) +tinygo build -size short -o ./build/test.hex -target=challenger-rp2040 ./examples/net/ntpclient/ +# network examples (wifinina) +tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/net/http-get/ +tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/net/tcpclient/ +tinygo build -size short -o ./build/test.hex -target=nano-rp2040 ./examples/net/websocket/dial/ +tinygo build -size short -o ./build/test.hex -target=metro-m4-airlift ./examples/net/socket/ +tinygo build -size short -o ./build/test.hex -target=matrixportal-m4 ./examples/net/webstatic/ +tinygo build -size short -o ./build/test.hex -target=arduino-mkrwifi1010 ./examples/net/tlsclient/ +tinygo build -size short -o ./build/test.hex -target=nano-rp2040 ./examples/net/mqttclient/natiu/ +# network examples (rtl8720dn) +tinygo build -size short -o ./build/test.hex -target=wioterminal ./examples/net/webclient/ +tinygo build -size short -o ./build/test.hex -target=wioterminal ./examples/net/webserver/ +tinygo build -size short -o ./build/test.hex -target=wioterminal ./examples/net/mqttclient/paho/ diff --git a/wifinina/README.md b/wifinina/README.md index 868e07f3f..daebbb906 100644 --- a/wifinina/README.md +++ b/wifinina/README.md @@ -6,7 +6,7 @@ The way this driver works is by using the SPI interface of your microcontroller ## Using the WiFiNINA Driver -For information on how to use this driver, please take a look at the examples located in the [examples/wifinina](../examples/wifinina) directory. +For information on how to use this driver, please take a look at the examples located in the [examples/net](../examples/net) directory. ## Firmware diff --git a/wifinina/adapter.go b/wifinina/adapter.go deleted file mode 100644 index 063ca0771..000000000 --- a/wifinina/adapter.go +++ /dev/null @@ -1,31 +0,0 @@ -package wifinina - -import ( - "time" - - "tinygo.org/x/drivers/net" -) - -func (d *Device) ConnectToAccessPoint(ssid, pass string, timeout time.Duration) error { - if len(ssid) == 0 { - return net.ErrWiFiMissingSSID - } - - start := time.Now() - d.SetPassphrase(ssid, pass) - - for time.Since(start) < timeout { - st, _ := d.GetConnectionStatus() - if st == StatusConnected { - return nil - } - time.Sleep(100 * time.Millisecond) - } - - return net.ErrWiFiConnectTimeout -} - -func (d *Device) GetClientIP() (string, error) { - ip, _, _, err := d.GetIP() - return ip.String(), err -} diff --git a/wifinina/commands.go b/wifinina/commands.go deleted file mode 100644 index c43c1dc2d..000000000 --- a/wifinina/commands.go +++ /dev/null @@ -1,67 +0,0 @@ -package wifinina - -type CommandType uint8 - -//go:generate stringer -type=CommandType -trimprefix=Cmd -const ( - CmdStart CommandType = 0xE0 - CmdEnd CommandType = 0xEE - CmdErr CommandType = 0xEF - - CmdSetNet CommandType = 0x10 - CmdSetPassphrase CommandType = 0x11 - CmdSetKey CommandType = 0x12 - CmdSetIPConfig CommandType = 0x14 - CmdSetDNSConfig CommandType = 0x15 - CmdSetHostname CommandType = 0x16 - CmdSetPowerMode CommandType = 0x17 - CmdSetAPNet CommandType = 0x18 - CmdSetAPPassphrase CommandType = 0x19 - CmdSetDebug CommandType = 0x1A - CmdGetTemperature CommandType = 0x1B - CmdGetReasonCode CommandType = 0x1F - // TEST_CMD = 0x13 - - CmdGetConnStatus CommandType = 0x20 - CmdGetIPAddr CommandType = 0x21 - CmdGetMACAddr CommandType = 0x22 - CmdGetCurrSSID CommandType = 0x23 - CmdGetCurrBSSID CommandType = 0x24 - CmdGetCurrRSSI CommandType = 0x25 - CmdGetCurrEncrType CommandType = 0x26 - CmdScanNetworks CommandType = 0x27 - CmdStartServerTCP CommandType = 0x28 - CmdGetStateTCP CommandType = 0x29 - CmdDataSentTCP CommandType = 0x2A - CmdAvailDataTCP CommandType = 0x2B - CmdGetDataTCP CommandType = 0x2C - CmdStartClientTCP CommandType = 0x2D - CmdStopClientTCP CommandType = 0x2E - CmdGetClientStateTCP CommandType = 0x2F - CmdDisconnect CommandType = 0x30 - CmdGetIdxRSSI CommandType = 0x32 - CmdGetIdxEncrType CommandType = 0x33 - CmdReqHostByName CommandType = 0x34 - CmdGetHostByName CommandType = 0x35 - CmdStartScanNetworks CommandType = 0x36 - CmdGetFwVersion CommandType = 0x37 - CmdSendDataUDP CommandType = 0x39 - CmdGetRemoteData CommandType = 0x3A - CmdGetTime CommandType = 0x3B - CmdGetIdxBSSID CommandType = 0x3C - CmdGetIdxChannel CommandType = 0x3D - CmdPing CommandType = 0x3E - CmdGetSocket CommandType = 0x3F - // GET_IDX_SSID_CMD = 0x31, - // GET_TEST_CMD = 0x38 - - // All command with DATA_FLAG 0x40 send a 16bit Len - CmdSendDataTCP CommandType = 0x44 - CmdGetDatabufTCP CommandType = 0x45 - CmdInsertDataBuf CommandType = 0x46 - - // regular format commands - CmdSetPinMode CommandType = 0x50 - CmdSetDigitalWrite CommandType = 0x51 - CmdSetAnalogWrite CommandType = 0x52 -) diff --git a/wifinina/commandtype_string.go b/wifinina/commandtype_string.go deleted file mode 100644 index 09860476f..000000000 --- a/wifinina/commandtype_string.go +++ /dev/null @@ -1,120 +0,0 @@ -//go:build wifidebug - -// Code generated by "stringer -type=CommandType -trimprefix=Cmd"; DO NOT EDIT. - -package wifinina - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[CmdStart-224] - _ = x[CmdEnd-238] - _ = x[CmdErr-239] - _ = x[CmdSetNet-16] - _ = x[CmdSetPassphrase-17] - _ = x[CmdSetKey-18] - _ = x[CmdSetIPConfig-20] - _ = x[CmdSetDNSConfig-21] - _ = x[CmdSetHostname-22] - _ = x[CmdSetPowerMode-23] - _ = x[CmdSetAPNet-24] - _ = x[CmdSetAPPassphrase-25] - _ = x[CmdSetDebug-26] - _ = x[CmdGetTemperature-27] - _ = x[CmdGetReasonCode-31] - _ = x[CmdGetConnStatus-32] - _ = x[CmdGetIPAddr-33] - _ = x[CmdGetMACAddr-34] - _ = x[CmdGetCurrSSID-35] - _ = x[CmdGetCurrBSSID-36] - _ = x[CmdGetCurrRSSI-37] - _ = x[CmdGetCurrEncrType-38] - _ = x[CmdScanNetworks-39] - _ = x[CmdStartServerTCP-40] - _ = x[CmdGetStateTCP-41] - _ = x[CmdDataSentTCP-42] - _ = x[CmdAvailDataTCP-43] - _ = x[CmdGetDataTCP-44] - _ = x[CmdStartClientTCP-45] - _ = x[CmdStopClientTCP-46] - _ = x[CmdGetClientStateTCP-47] - _ = x[CmdDisconnect-48] - _ = x[CmdGetIdxRSSI-50] - _ = x[CmdGetIdxEncrType-51] - _ = x[CmdReqHostByName-52] - _ = x[CmdGetHostByName-53] - _ = x[CmdStartScanNetworks-54] - _ = x[CmdGetFwVersion-55] - _ = x[CmdSendDataUDP-57] - _ = x[CmdGetRemoteData-58] - _ = x[CmdGetTime-59] - _ = x[CmdGetIdxBSSID-60] - _ = x[CmdGetIdxChannel-61] - _ = x[CmdPing-62] - _ = x[CmdGetSocket-63] - _ = x[CmdSendDataTCP-68] - _ = x[CmdGetDatabufTCP-69] - _ = x[CmdInsertDataBuf-70] - _ = x[CmdSetPinMode-80] - _ = x[CmdSetDigitalWrite-81] - _ = x[CmdSetAnalogWrite-82] -} - -const ( - _CommandType_name_0 = "SetNetSetPassphraseSetKey" - _CommandType_name_1 = "SetIPConfigSetDNSConfigSetHostnameSetPowerModeSetAPNetSetAPPassphraseSetDebugGetTemperature" - _CommandType_name_2 = "GetReasonCodeGetConnStatusGetIPAddrGetMACAddrGetCurrSSIDGetCurrBSSIDGetCurrRSSIGetCurrEncrTypeScanNetworksStartServerTCPGetStateTCPDataSentTCPAvailDataTCPGetDataTCPStartClientTCPStopClientTCPGetClientStateTCPDisconnect" - _CommandType_name_3 = "GetIdxRSSIGetIdxEncrTypeReqHostByNameGetHostByNameStartScanNetworksGetFwVersion" - _CommandType_name_4 = "SendDataUDPGetRemoteDataGetTimeGetIdxBSSIDGetIdxChannelPingGetSocket" - _CommandType_name_5 = "SendDataTCPGetDatabufTCPInsertDataBuf" - _CommandType_name_6 = "SetPinModeSetDigitalWriteSetAnalogWrite" - _CommandType_name_7 = "Start" - _CommandType_name_8 = "EndErr" -) - -var ( - _CommandType_index_0 = [...]uint8{0, 6, 19, 25} - _CommandType_index_1 = [...]uint8{0, 11, 23, 34, 46, 54, 69, 77, 91} - _CommandType_index_2 = [...]uint8{0, 13, 26, 35, 45, 56, 68, 79, 94, 106, 120, 131, 142, 154, 164, 178, 191, 208, 218} - _CommandType_index_3 = [...]uint8{0, 10, 24, 37, 50, 67, 79} - _CommandType_index_4 = [...]uint8{0, 11, 24, 31, 42, 55, 59, 68} - _CommandType_index_5 = [...]uint8{0, 11, 24, 37} - _CommandType_index_6 = [...]uint8{0, 10, 25, 39} - _CommandType_index_8 = [...]uint8{0, 3, 6} -) - -func (i CommandType) String() string { - switch { - case 16 <= i && i <= 18: - i -= 16 - return _CommandType_name_0[_CommandType_index_0[i]:_CommandType_index_0[i+1]] - case 20 <= i && i <= 27: - i -= 20 - return _CommandType_name_1[_CommandType_index_1[i]:_CommandType_index_1[i+1]] - case 31 <= i && i <= 48: - i -= 31 - return _CommandType_name_2[_CommandType_index_2[i]:_CommandType_index_2[i+1]] - case 50 <= i && i <= 55: - i -= 50 - return _CommandType_name_3[_CommandType_index_3[i]:_CommandType_index_3[i+1]] - case 57 <= i && i <= 63: - i -= 57 - return _CommandType_name_4[_CommandType_index_4[i]:_CommandType_index_4[i+1]] - case 68 <= i && i <= 70: - i -= 68 - return _CommandType_name_5[_CommandType_index_5[i]:_CommandType_index_5[i+1]] - case 80 <= i && i <= 82: - i -= 80 - return _CommandType_name_6[_CommandType_index_6[i]:_CommandType_index_6[i+1]] - case i == 224: - return _CommandType_name_7 - case 238 <= i && i <= 239: - i -= 238 - return _CommandType_name_8[_CommandType_index_8[i]:_CommandType_index_8[i+1]] - default: - return "CommandType(" + strconv.FormatInt(int64(i), 10) + ")" - } -} diff --git a/wifinina/connectionstatus_string.go b/wifinina/connectionstatus_string.go deleted file mode 100644 index 7e7f513af..000000000 --- a/wifinina/connectionstatus_string.go +++ /dev/null @@ -1,41 +0,0 @@ -//go:build wifidebug - -// Code generated by "stringer -type=ConnectionStatus -trimprefix=Status"; DO NOT EDIT. - -package wifinina - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[StatusNoShield-255] - _ = x[StatusIdle-0] - _ = x[StatusNoSSIDAvail-1] - _ = x[StatusScanCompleted-2] - _ = x[StatusConnected-3] - _ = x[StatusConnectFailed-4] - _ = x[StatusConnectionLost-5] - _ = x[StatusDisconnected-6] -} - -const ( - _ConnectionStatus_name_0 = "IdleNoSSIDAvailScanCompletedConnectedConnectFailedConnectionLostDisconnected" - _ConnectionStatus_name_1 = "NoShield" -) - -var ( - _ConnectionStatus_index_0 = [...]uint8{0, 4, 15, 28, 37, 50, 64, 76} -) - -func (i ConnectionStatus) String() string { - switch { - case i <= 6: - return _ConnectionStatus_name_0[_ConnectionStatus_index_0[i]:_ConnectionStatus_index_0[i+1]] - case i == 255: - return _ConnectionStatus_name_1 - default: - return "ConnectionStatus(" + strconv.FormatInt(int64(i), 10) + ")" - } -} diff --git a/wifinina/debug.go b/wifinina/debug.go index e4088c5c6..0def23f57 100644 --- a/wifinina/debug.go +++ b/wifinina/debug.go @@ -1,5 +1,17 @@ -//go:build wifidebug - package wifinina -var _debug = true +type debug uint8 + +const ( + debugBasic debug = 1 << iota // show fw version, mac addr, etc + debugNetdev // show netdev entry points + debugCmd // show non-chatty wifinina cmds + debugDetail // show chatty wifinina cmds + + debugOff = 0 + debugAll = debugBasic | debugNetdev | debugCmd | debugDetail +) + +func debugging(want debug) bool { + return (_debug & want) != 0 +} diff --git a/wifinina/encryptiontype_string.go b/wifinina/encryptiontype_string.go deleted file mode 100644 index bb3e733f8..000000000 --- a/wifinina/encryptiontype_string.go +++ /dev/null @@ -1,44 +0,0 @@ -//go:build wifidebug - -// Code generated by "stringer -type=EncryptionType -trimprefix=EncType"; DO NOT EDIT. - -package wifinina - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[EncTypeTKIP-2] - _ = x[EncTypeCCMP-4] - _ = x[EncTypeWEP-5] - _ = x[EncTypeNone-7] - _ = x[EncTypeAuto-8] -} - -const ( - _EncryptionType_name_0 = "TKIP" - _EncryptionType_name_1 = "CCMPWEP" - _EncryptionType_name_2 = "NoneAuto" -) - -var ( - _EncryptionType_index_1 = [...]uint8{0, 4, 7} - _EncryptionType_index_2 = [...]uint8{0, 4, 8} -) - -func (i EncryptionType) String() string { - switch { - case i == 2: - return _EncryptionType_name_0 - case 4 <= i && i <= 5: - i -= 4 - return _EncryptionType_name_1[_EncryptionType_index_1[i]:_EncryptionType_index_1[i+1]] - case 7 <= i && i <= 8: - i -= 7 - return _EncryptionType_name_2[_EncryptionType_index_2[i]:_EncryptionType_index_2[i+1]] - default: - return "EncryptionType(" + strconv.FormatInt(int64(i), 10) + ")" - } -} diff --git a/wifinina/error_string.go b/wifinina/error_string.go deleted file mode 100644 index 51a001715..000000000 --- a/wifinina/error_string.go +++ /dev/null @@ -1,59 +0,0 @@ -// Code generated by "stringer -type=Error -trimprefix=Err"; DO NOT EDIT. - -package wifinina - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[ErrTimeoutChipReady-1] - _ = x[ErrTimeoutChipSelect-2] - _ = x[ErrCheckStartCmd-3] - _ = x[ErrWaitRsp-4] - _ = x[ErrUnexpectedLength-224] - _ = x[ErrNoParamsReturned-225] - _ = x[ErrIncorrectSentinel-226] - _ = x[ErrCmdErrorReceived-239] - _ = x[ErrNotImplemented-240] - _ = x[ErrUnknownHost-241] - _ = x[ErrSocketAlreadySet-242] - _ = x[ErrConnectionTimeout-243] - _ = x[ErrNoData-244] - _ = x[ErrDataNotWritten-245] - _ = x[ErrCheckDataError-246] - _ = x[ErrBufferTooSmall-247] - _ = x[ErrNoSocketAvail-255] -} - -const ( - _Error_name_0 = "TimeoutChipReadyTimeoutChipSelectCheckStartCmdWaitRsp" - _Error_name_1 = "UnexpectedLengthNoParamsReturnedIncorrectSentinel" - _Error_name_2 = "CmdErrorReceivedNotImplementedUnknownHostSocketAlreadySetConnectionTimeoutNoDataDataNotWrittenCheckDataErrorBufferTooSmall" - _Error_name_3 = "NoSocketAvail" -) - -var ( - _Error_index_0 = [...]uint8{0, 16, 33, 46, 53} - _Error_index_1 = [...]uint8{0, 16, 32, 49} - _Error_index_2 = [...]uint8{0, 16, 30, 41, 57, 74, 80, 94, 108, 122} -) - -func (i Error) String() string { - switch { - case 1 <= i && i <= 4: - i -= 1 - return _Error_name_0[_Error_index_0[i]:_Error_index_0[i+1]] - case 224 <= i && i <= 226: - i -= 224 - return _Error_name_1[_Error_index_1[i]:_Error_index_1[i+1]] - case 239 <= i && i <= 247: - i -= 239 - return _Error_name_2[_Error_index_2[i]:_Error_index_2[i+1]] - case i == 255: - return _Error_name_3 - default: - return "Error(" + strconv.FormatInt(int64(i), 10) + ")" - } -} diff --git a/wifinina/http.go b/wifinina/http.go deleted file mode 100644 index 4f73d8333..000000000 --- a/wifinina/http.go +++ /dev/null @@ -1,323 +0,0 @@ -package wifinina - -import ( - "bufio" - "bytes" - "fmt" - "io" - "strconv" - "strings" - "time" - - "tinygo.org/x/drivers/net/http" -) - -func (d *Device) ListenAndServe(addr string, handler http.Handler) error { - - if handler == nil { - handler = http.DefaultServeMux - } - - server := newServer(d, handler) - - if err := server.listen(addr); err != nil { - return err - } - - for { - client, err := server.accept() - if err != nil { - return err - } - - if err := client.handleHTTP(); err != nil { - return err - } - - if err = client.stop(); err != nil { - return err - } - } - - return nil -} - -// Server stuff - -type server struct { - device *Device - handler http.Handler - sock uint8 - clients map[uint8]*client // keyed by client sock -} - -func newServer(device *Device, handler http.Handler) *server { - return &server{ - device: device, - handler: handler, - sock: NoSocketAvail, - clients: make(map[uint8]*client), - } -} - -func portFromAddr(addr string) (uint16, error) { - // ignore anything before ':' in address - i := strings.LastIndex(addr, ":") - if i < 0 { - return 0, fmt.Errorf("Missing ':' in address") - } - v, err := strconv.ParseUint(addr[i+1:], 10, 16) - if err != nil { - return 0, fmt.Errorf("Parsing address err: %s", err) - } - return uint16(v), nil -} - -func (s *server) listen(addr string) error { - port, err := portFromAddr(addr) - if err != nil { - return fmt.Errorf("Getting port err: %s", err) - } - - s.sock, err = s.device.GetSocket() - if err != nil { - return fmt.Errorf("Getting socket err: %s", err) - } - if s.sock == NoSocketAvail { - return fmt.Errorf("No socket available") - } - - return s.device.StartServer(port, s.sock, ProtoModeTCP) -} - -func (s *server) availServer(sock uint8) (uint8, error) { - d := s.device - - d.mu.Lock() - defer d.mu.Unlock() - - if err := d.waitForChipSelect(); err != nil { - d.spiChipDeselect() - return NoSocketAvail, fmt.Errorf("Wait for CS: %s", err) - } - - l := d.sendCmd(CmdAvailDataTCP, 1) - l += d.sendParam8(sock, true) - d.addPadding(l) - d.spiChipDeselect() - _, err := d.waitRspCmd1(CmdAvailDataTCP) - if err != nil { - return NoSocketAvail, fmt.Errorf("Wait for Rsp: %s", err) - } - newsock, err := d.getUint16(2, err) - if err != nil { - return NoSocketAvail, fmt.Errorf("getUint16: %s", err) - } - return uint8(newsock >> 8), nil -} - -func (s *server) accept() (*client, error) { - - for { - sock, err := s.availServer(s.sock) - if err != nil { - return nil, fmt.Errorf("accept: %w", err) - } - - if sock == NoSocketAvail { - continue - } - - if client, ok := s.clients[sock]; ok { - return client, nil - } - - client := newClient(s, sock) - s.clients[sock] = client - - return client, nil - } -} - -// client stuff - -type client struct { - server *server - device *Device - sock uint8 - - // HTTP request - req *http.Request - reqBuf bytes.Buffer - readBuf [256]byte - - // HTTP response - res bytes.Buffer - resHdr http.Header - resBuf bytes.Buffer - statusCode int -} - -func newClient(server *server, sock uint8) *client { - return &client{ - server: server, - device: server.device, - sock: sock, - } -} - -// client implements http.ResponseWriter interface - -func (c *client) Header() http.Header { - return c.resHdr -} - -func (c *client) Write(b []byte) (int, error) { - return c.resBuf.Write(b) -} - -func (c *client) WriteHeader(statusCode int) { - c.statusCode = statusCode -} - -func (c *client) status() uint8 { - d := c.device - - d.mu.Lock() - defer d.mu.Unlock() - - if err := d.waitForChipSelect(); err != nil { - d.spiChipDeselect() - return 0 - } - - l := d.sendCmd(CmdGetClientStateTCP, 1) - l += d.sendParam8(c.sock, true) - d.addPadding(l) - d.spiChipDeselect() - _, err := d.waitRspCmd1(CmdGetClientStateTCP) - if err != nil { - return 0 - } - status, err := d.getUint8(1, err) - if err != nil { - return 0 - } - return status -} - -func (c *client) stop() error { - if err := c.device.StopClient(c.sock); err != nil { - return err - } - - // Wait max 5 secs for the connection to close - for i := 0; i < 50 && c.status() != uint8(TCPStateClosed); i++ { - time.Sleep(100 * time.Millisecond) - } - - if c.status() != uint8(TCPStateClosed) { - return fmt.Errorf("stop failed, client status %x", c.status()) - } - - return nil -} - -func (c *client) handleHTTP() error { - - c.reqBuf.Reset() - end := -1 - - // read the request - - start := time.Now() - for { - - // TODO use Server.ReadTimeout - if time.Since(start) > 1*time.Second { - return fmt.Errorf("ReadTimeout") - } - - n, err := c.device.GetDataBuf(c.sock, c.readBuf[:]) - if err != nil { - return fmt.Errorf("GetDataBuf: %s", err) - } - if n == 0 { - time.Sleep(1 * time.Millisecond) - continue - } - - c.reqBuf.Write(c.readBuf[:n]) - bytesSoFar := c.reqBuf.Bytes() - - if end == -1 { - - // search for blank line marking end-of-header - end = bytes.Index(bytesSoFar, []byte("\r\n\r\n")) - if end == -1 { - continue - } - - // found end-of-header; parse header - end += len([]byte("\r\n\r\n")) - bufio := bufio.NewReader(bytes.NewReader(bytesSoFar[:end])) - c.req, err = http.ReadRequest(bufio) - if err != nil { - return err - } - } - - v := c.req.Header.Get("Content-Length") - if v == "" { - // no body; we're done reading request - break - } - - length, _ := strconv.Atoi(v) - if end+length == len(bytesSoFar) { - // got the whole body - body := bytes.NewReader(bytesSoFar[end:]) - c.req.Body = io.NopCloser(body) - break - } - - // continue reading request... - } - - // build the response - - c.statusCode = 200 - - c.resHdr = http.Header{} - c.resHdr.Add(`Content-Type`, `text/html; charset=UTF-8`) - c.resHdr.Add(`Connection`, `close`) - - c.resBuf.Reset() - c.server.handler.ServeHTTP(c, c.req) - - c.resHdr.Add(`Content-Length`, fmt.Sprintf("%d", c.resBuf.Len())) - - c.res.Reset() - fmt.Fprintf(&c.res, "HTTP/1.1 %d %s\r\n", c.statusCode, - http.StatusText(c.statusCode)) - if err := c.resHdr.Write(&c.res); err != nil { - return err - } - c.res.WriteByte(byte('\n')) - c.res.Write(c.resBuf.Bytes()) - - // send the response - - written, err := c.device.SendData(c.res.Bytes(), c.sock) - if err != nil { - return err - } - if written == 0 { - return ErrDataNotWritten - } - if sent, _ := c.device.CheckDataSent(c.sock); !sent { - return ErrCheckDataError - } - - return nil -} diff --git a/wifinina/nodebug.go b/wifinina/nodebug.go deleted file mode 100644 index 78cd24310..000000000 --- a/wifinina/nodebug.go +++ /dev/null @@ -1,5 +0,0 @@ -//go:build !wifidebug - -package wifinina - -var _debug = false diff --git a/wifinina/pins.go b/wifinina/pins.go index a1afbcbde..5d7ca2b4f 100644 --- a/wifinina/pins.go +++ b/wifinina/pins.go @@ -32,17 +32,18 @@ var ( ErrPinNoDevice = errors.New("wifinina pin: device not set") ) -var pinDevice *Device +var pinDevice *wifinina -func pinUseDevice(d *Device) { - pinDevice = d +func pinUseDevice(w *wifinina) { + pinDevice = w } func (p Pin) Configure(config PinConfig) error { if pinDevice == nil { return ErrPinNoDevice } - return pinDevice.PinMode(uint8(p), uint8(config.Mode)) + pinDevice.PinMode(uint8(p), uint8(config.Mode)) + return nil } func (p Pin) Set(high bool) error { @@ -53,7 +54,8 @@ func (p Pin) Set(high bool) error { if high { value = PinHigh } - return pinDevice.DigitalWrite(uint8(p), value) + pinDevice.DigitalWrite(uint8(p), value) + return nil } func (p Pin) High() error { diff --git a/wifinina/protocol/readme.md b/wifinina/protocol/readme.md deleted file mode 100644 index 0f2a5e395..000000000 --- a/wifinina/protocol/readme.md +++ /dev/null @@ -1,3 +0,0 @@ -WiFiNINA protocol -================= - diff --git a/wifinina/status.go b/wifinina/status.go deleted file mode 100644 index fc2e3bf83..000000000 --- a/wifinina/status.go +++ /dev/null @@ -1,75 +0,0 @@ -package wifinina - -type ConnectionStatus uint8 - -//go:generate stringer -type=ConnectionStatus -trimprefix=Status -const ( - StatusNoShield ConnectionStatus = 255 - StatusIdle ConnectionStatus = 0 - StatusNoSSIDAvail ConnectionStatus = 1 - StatusScanCompleted ConnectionStatus = 2 - StatusConnected ConnectionStatus = 3 - StatusConnectFailed ConnectionStatus = 4 - StatusConnectionLost ConnectionStatus = 5 - StatusDisconnected ConnectionStatus = 6 -) - -// Default state value for Wifi state field -// #define NA_STATE -1 - -type EncryptionType uint8 - -//go:generate stringer -type=EncryptionType -trimprefix=EncType -const ( - EncTypeTKIP EncryptionType = 2 - EncTypeCCMP EncryptionType = 4 - EncTypeWEP EncryptionType = 5 - EncTypeNone EncryptionType = 7 - EncTypeAuto EncryptionType = 8 -) - -type TCPState uint8 - -//go:generate stringer -type=TCPState -trimprefix=TCPState -const ( - TCPStateClosed TCPState = 0 - TCPStateListen TCPState = 1 - TCPStateSynSent TCPState = 2 - TCPStateSynRcvd TCPState = 3 - TCPStateEstablished TCPState = 4 - TCPStateFinWait1 TCPState = 5 - TCPStateFinWait2 TCPState = 6 - TCPStateCloseWait TCPState = 7 - TCPStateClosing TCPState = 8 - TCPStateLastACK TCPState = 9 - TCPStateTimeWait TCPState = 10 -) - -type Error uint8 - -func (err Error) Error() string { - return "wifinina error: " + err.String() -} - -//go:generate stringer -type=Error -trimprefix=Err -const ( - ErrTimeoutChipReady Error = 0x01 - ErrTimeoutChipSelect Error = 0x02 - ErrCheckStartCmd Error = 0x03 - ErrWaitRsp Error = 0x04 - ErrUnexpectedLength Error = 0xE0 - ErrNoParamsReturned Error = 0xE1 - ErrIncorrectSentinel Error = 0xE2 - ErrCmdErrorReceived Error = 0xEF - ErrNotImplemented Error = 0xF0 - ErrUnknownHost Error = 0xF1 - ErrSocketAlreadySet Error = 0xF2 - ErrConnectionTimeout Error = 0xF3 - ErrNoData Error = 0xF4 - ErrDataNotWritten Error = 0xF5 - ErrCheckDataError Error = 0xF6 - ErrBufferTooSmall Error = 0xF7 - ErrNoSocketAvail Error = 0xFF - - NoSocketAvail uint8 = 0xFF -) diff --git a/wifinina/tcp.go b/wifinina/tcp.go deleted file mode 100644 index e27b78842..000000000 --- a/wifinina/tcp.go +++ /dev/null @@ -1,270 +0,0 @@ -package wifinina - -import ( - "errors" - "strconv" - "time" -) - -const ( - ReadBufferSize = 128 -) - -type readBuffer struct { - data [ReadBufferSize]byte - head int - size int -} - -func (d *Device) GetDNS(domain string) (string, error) { - ipAddr, err := d.GetHostByName(domain) - return ipAddr.String(), err -} - -func (d *Device) ConnectTCPSocket(addr, portStr string) error { - return d.connectSocket(addr, portStr, ProtoModeTCP) -} - -func (d *Device) ConnectSSLSocket(addr, portStr string) error { - return d.connectSocket(addr, portStr, ProtoModeTLS) -} - -func (d *Device) connectSocket(addr, portStr string, mode uint8) error { - - d.proto, d.ip, d.port = mode, 0, 0 - - // convert port to uint16 - port, err := convertPort(portStr) - if err != nil { - return err - } - - hostname := addr - ip := uint32(0) - - if mode != ProtoModeTLS { - // look up the hostname if necessary; if an IP address was specified, the - // same will be returned. Otherwise, an IPv4 for the hostname is returned. - ipAddr, err := d.GetHostByName(addr) - if err != nil { - return err - } - hostname = "" - ip = ipAddr.AsUint32() - } - - // check to see if socket is already set; if so, stop it - if d.sock != NoSocketAvail { - if err := d.stop(); err != nil { - return err - } - } - - // get a socket from the device - if d.sock, err = d.GetSocket(); err != nil { - return err - } - - // attempt to start the client - if err := d.StartClient(hostname, ip, port, d.sock, mode); err != nil { - return err - } - - // FIXME: this 4 second timeout is simply mimicking the Arduino driver - start := time.Now() - for time.Since(start) < 4*time.Second { - connected, err := d.IsConnected() - if err != nil { - return err - } - if connected { - return nil - } - time.Sleep(1 * time.Millisecond) - } - - return ErrConnectionTimeout -} - -func convertPort(portStr string) (uint16, error) { - p64, err := strconv.ParseUint(portStr, 10, 16) - if err != nil { - return 0, errors.New("could not convert port to uint16: " + err.Error()) - } - return uint16(p64), nil -} - -func (d *Device) ConnectUDPSocket(addr, portStr, lportStr string) (err error) { - - d.proto, d.ip, d.port = ProtoModeUDP, 0, 0 - - // convert remote port to uint16 - if d.port, err = convertPort(portStr); err != nil { - return err - } - - // convert local port to uint16 - var lport uint16 - if lport, err = convertPort(lportStr); err != nil { - return err - } - - // look up the hostname if necessary; if an IP address was specified, the - // same will be returned. Otherwise, an IPv4 for the hostname is returned. - ipAddr, err := d.GetHostByName(addr) - if err != nil { - return err - } - d.ip = ipAddr.AsUint32() - - // check to see if socket is already set; if so, stop it - // TODO: we can probably have more than one socket at once right? - if d.sock != NoSocketAvail { - if err := d.stop(); err != nil { - return err - } - } - - // get a socket from the device - if d.sock, err = d.GetSocket(); err != nil { - return err - } - - // start listening for UDP packets on the local port - if err := d.StartServer(lport, d.sock, d.proto); err != nil { - return err - } - - return nil -} - -func (d *Device) DisconnectSocket() error { - return d.stop() -} - -func (d *Device) StartSocketSend(size int) error { - // not needed for WiFiNINA??? - return nil -} - -func (d *Device) Response(timeout int) ([]byte, error) { - return nil, nil -} - -func (d *Device) Write(b []byte) (n int, err error) { - if d.sock == NoSocketAvail { - return 0, ErrNoSocketAvail - } - if len(b) == 0 { - return 0, ErrNoData - } - if d.proto == ProtoModeUDP { - if err := d.StartClient("", d.ip, d.port, d.sock, d.proto); err != nil { - return 0, errors.New("error in startClient: " + err.Error()) - } - if _, err := d.InsertDataBuf(b, d.sock); err != nil { - return 0, errors.New("error in insertDataBuf: " + err.Error()) - } - if _, err := d.SendUDPData(d.sock); err != nil { - return 0, errors.New("error in sendUDPData: " + err.Error()) - } - return len(b), nil - } else { - written, err := d.SendData(b, d.sock) - if err != nil { - return 0, err - } - if written == 0 { - return 0, ErrDataNotWritten - } - if sent, _ := d.CheckDataSent(d.sock); !sent { - return 0, ErrCheckDataError - } - return len(b), nil - } - - return len(b), nil -} - -func (d *Device) ReadSocket(b []byte) (n int, err error) { - avail, err := d.available() - if err != nil { - println("ReadSocket error: " + err.Error()) - return 0, err - } - if avail == 0 { - return 0, nil - } - length := len(b) - if avail < length { - length = avail - } - copy(b, d.readBuf.data[d.readBuf.head:d.readBuf.head+length]) - d.readBuf.head += length - d.readBuf.size -= length - return length, nil -} - -// IsSocketDataAvailable returns of there is socket data available -func (d *Device) IsSocketDataAvailable() bool { - n, err := d.available() - return err == nil && n > 0 -} - -func (d *Device) available() (int, error) { - if d.readBuf.size == 0 { - n, err := d.GetDataBuf(d.sock, d.readBuf.data[:]) - if n > 0 { - d.readBuf.head = 0 - d.readBuf.size = n - } - if err != nil { - return int(n), err - } - } - return d.readBuf.size, nil -} - -func (d *Device) IsConnected() (bool, error) { - if d.sock == NoSocketAvail { - return false, nil - } - s, err := d.status() - if err != nil { - return false, err - } - isConnected := !(s == uint8(TCPStateListen) || s == uint8(TCPStateClosed) || - s == uint8(TCPStateFinWait1) || s == uint8(TCPStateFinWait2) || s == uint8(TCPStateTimeWait) || - s == uint8(TCPStateSynSent) || s == uint8(TCPStateSynRcvd) || s == uint8(TCPStateCloseWait)) - // TODO: investigate if the below is necessary (as per Arduino driver) - //if !isConnected { - // //close socket buffer? - // WiFiSocketBuffer.close(_sock); - // _sock = 255; - //} - return isConnected, nil -} - -func (d *Device) status() (uint8, error) { - if d.sock == NoSocketAvail { - return uint8(TCPStateClosed), nil - } - return d.GetClientState(d.sock) -} - -func (d *Device) stop() error { - if d.sock == NoSocketAvail { - return nil - } - d.StopClient(d.sock) - start := time.Now() - for time.Since(start) < 5*time.Second { - st, _ := d.status() - if st == uint8(TCPStateClosed) { - break - } - time.Sleep(1 * time.Millisecond) - } - d.sock = NoSocketAvail - return nil -} diff --git a/wifinina/tcpstate_string.go b/wifinina/tcpstate_string.go deleted file mode 100644 index 52b6fc18e..000000000 --- a/wifinina/tcpstate_string.go +++ /dev/null @@ -1,35 +0,0 @@ -//go:build wifidebug - -// Code generated by "stringer -type=TCPState -trimprefix=TCPState"; DO NOT EDIT. - -package wifinina - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[TCPStateClosed-0] - _ = x[TCPStateListen-1] - _ = x[TCPStateSynSent-2] - _ = x[TCPStateSynRcvd-3] - _ = x[TCPStateEstablished-4] - _ = x[TCPStateFinWait1-5] - _ = x[TCPStateFinWait2-6] - _ = x[TCPStateCloseWait-7] - _ = x[TCPStateClosing-8] - _ = x[TCPStateLastACK-9] - _ = x[TCPStateTimeWait-10] -} - -const _TCPState_name = "ClosedListenSynSentSynRcvdEstablishedFinWait1FinWait2CloseWaitClosingLastACKTimeWait" - -var _TCPState_index = [...]uint8{0, 6, 12, 19, 26, 37, 45, 53, 62, 69, 76, 84} - -func (i TCPState) String() string { - if i >= TCPState(len(_TCPState_index)-1) { - return "TCPState(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _TCPState_name[_TCPState_index[i]:_TCPState_index[i+1]] -} diff --git a/wifinina/wifinina.go b/wifinina/wifinina.go index 9e2d6c81c..efcc765cd 100644 --- a/wifinina/wifinina.go +++ b/wifinina/wifinina.go @@ -1,1094 +1,1897 @@ -// Package wifinina implements TCP wireless communication over SPI -// with an attached separate ESP32 board using the Arduino WiFiNINA protocol. +// Package wifinina implements TCP wireless communication over SPI with an +// attached separate ESP32 SoC using the Arduino WiFiNINA protocol. // -// In order to use this driver, the ESP32 must be flashed with specific firmware from Arduino. -// For more information: https://github.com/arduino/nina-fw +// In order to use this driver, the ESP32 must be flashed with specific +// firmware from Arduino. For more information: +// https://github.com/arduino/nina-fw +// +// 12/2022 sfeldma@gmail.com Heavily modified to use netdev interface + package wifinina // import "tinygo.org/x/drivers/wifinina" import ( "encoding/binary" "encoding/hex" - "fmt" // used only in debug printouts and is optimized out when debugging is disabled - "strconv" - "strings" + "fmt" + "io" + "machine" + "math/bits" + "net" "sync" "time" - "machine" - "tinygo.org/x/drivers" - "tinygo.org/x/drivers/net" + "tinygo.org/x/drivers/netdev" + "tinygo.org/x/drivers/netlink" ) -const ( - MaxSockets = 4 - MaxNetworks = 10 - MaxAttempts = 10 - - MaxLengthSSID = 32 - MaxLengthWPAKey = 63 - MaxLengthWEPKey = 13 +var _debug debug = debugBasic - LengthMacAddress = 6 - LengthIPV4 = 4 +//var _debug debug = debugBasic | debugNetdev +//var _debug debug = debugBasic | debugNetdev | debugCmd +//var _debug debug = debugBasic | debugNetdev | debugCmd | debugDetail - WlFailure = -1 - WlSuccess = 1 +var ( + version = "0.0.1" + driverName = "Tinygo ESP32 Wifi network device driver (WiFiNINA)" ) const ( - FlagCmd = 0 - FlagReply = 1 << 7 - FlagData = 0x40 - - NinaCmdPos = 1 - NinaParamLenPos = 2 + maxNetworks = 10 + + statusNoShield connectionStatus = 255 + statusIdle connectionStatus = 0 + statusNoSSIDAvail connectionStatus = 1 + statusScanCompleted connectionStatus = 2 + statusConnected connectionStatus = 3 + statusConnectFailed connectionStatus = 4 + statusConnectionLost connectionStatus = 5 + statusDisconnected connectionStatus = 6 + + encTypeTKIP encryptionType = 2 + encTypeCCMP encryptionType = 4 + encTypeWEP encryptionType = 5 + encTypeNone encryptionType = 7 + encTypeAuto encryptionType = 8 + + tcpStateClosed = 0 + tcpStateListen = 1 + tcpStateSynSent = 2 + tcpStateSynRcvd = 3 + tcpStateEstablished = 4 + tcpStateFinWait1 = 5 + tcpStateFinWait2 = 6 + tcpStateCloseWait = 7 + tcpStateClosing = 8 + tcpStateLastACK = 9 + tcpStateTimeWait = 10 + + flagCmd = 0 + flagReply = 1 << 7 + flagData = 0x40 + + cmdStart = 0xE0 + cmdEnd = 0xEE + cmdErr = 0xEF dummyData = 0xFF + + cmdSetNet = 0x10 + cmdSetPassphrase = 0x11 + cmdSetKey = 0x12 + cmdSetIPConfig = 0x14 + cmdSetDNSConfig = 0x15 + cmdSetHostname = 0x16 + cmdSetPowerMode = 0x17 + cmdSetAPNet = 0x18 + cmdSetAPPassphrase = 0x19 + cmdSetDebug = 0x1A + cmdGetTemperature = 0x1B + cmdGetReasonCode = 0x1F + cmdGetConnStatus = 0x20 + cmdGetIPAddr = 0x21 + cmdGetMACAddr = 0x22 + cmdGetCurrSSID = 0x23 + cmdGetCurrBSSID = 0x24 + cmdGetCurrRSSI = 0x25 + cmdGetCurrEncrType = 0x26 + cmdScanNetworks = 0x27 + cmdStartServerTCP = 0x28 + cmdGetStateTCP = 0x29 + cmdDataSentTCP = 0x2A + cmdAvailDataTCP = 0x2B + cmdGetDataTCP = 0x2C + cmdStartClientTCP = 0x2D + cmdStopClientTCP = 0x2E + cmdGetClientStateTCP = 0x2F + cmdDisconnect = 0x30 + cmdGetIdxRSSI = 0x32 + cmdGetIdxEncrType = 0x33 + cmdReqHostByName = 0x34 + cmdGetHostByName = 0x35 + cmdStartScanNetworks = 0x36 + cmdGetFwVersion = 0x37 + cmdSendDataUDP = 0x39 + cmdGetRemoteData = 0x3A + cmdGetTime = 0x3B + cmdGetIdxBSSID = 0x3C + cmdGetIdxChannel = 0x3D + cmdPing = 0x3E + cmdGetSocket = 0x3F + + // All commands with DATA_FLAG 0x4x send a 16bit Len + cmdSendDataTCP = 0x44 + cmdGetDatabufTCP = 0x45 + cmdInsertDataBuf = 0x46 + + // Regular format commands + cmdSetPinMode = 0x50 + cmdSetDigitalWrite = 0x51 + cmdSetAnalogWrite = 0x52 + + errTimeoutChipReady hwerr = 0x01 + errTimeoutChipSelect hwerr = 0x02 + errCheckStartCmd hwerr = 0x03 + errWaitRsp hwerr = 0x04 + errUnexpectedLength hwerr = 0xE0 + errNoParamsReturned hwerr = 0xE1 + errIncorrectSentinel hwerr = 0xE2 + errCmdErrorReceived hwerr = 0xEF + errNotImplemented hwerr = 0xF0 + errUnknownHost hwerr = 0xF1 + errSocketAlreadySet hwerr = 0xF2 + errConnectionTimeout hwerr = 0xF3 + errNoData hwerr = 0xF4 + errDataNotWritten hwerr = 0xF5 + errCheckDataError hwerr = 0xF6 + errBufferTooSmall hwerr = 0xF7 + errNoSocketAvail hwerr = 0xFF + + noSocketAvail sock = 0xFF ) const ( - ProtoModeTCP = iota - ProtoModeUDP - ProtoModeTLS - ProtoModeMul + protoModeTCP = iota + protoModeUDP + protoModeTLS + protoModeMul ) -type IPAddress string // TODO: does WiFiNINA support ipv6??? +type connectionStatus uint8 +type encryptionType uint8 +type sock uint8 +type hwerr uint8 + +type socket struct { + protocol int + ip net.IP + port int + inuse bool +} + +type Config struct { + // SPI config + Spi drivers.SPI + Freq uint32 + Sdo machine.Pin + Sdi machine.Pin + Sck machine.Pin + + // Device config + Cs machine.Pin + Ack machine.Pin + Gpio0 machine.Pin + Resetn machine.Pin + // ResetIsHigh controls if the RESET signal to the processor should be + // High or Low (the default). Set this to true for boards such as the + // Arduino MKR 1010, where the reset signal needs to go high instead of + // low. + ResetIsHigh bool +} -func (addr IPAddress) String() string { - if len(addr) < 4 { - return "" +type wifinina struct { + cfg *Config + notifyCb func(netlink.Event) + mu sync.Mutex + + spi drivers.SPI + cs machine.Pin + ack machine.Pin + gpio0 machine.Pin + resetn machine.Pin + + buf [64]byte + ssids [maxNetworks]string + + params *netlink.ConnectParams + + netConnected bool + driverShown bool + deviceShown bool + spiSetup bool + + killWatchdog chan bool + fault error + + sockets map[sock]*socket // keyed by sock as returned by getSocket() +} + +func newSocket(protocol int) *socket { + return &socket{protocol: protocol, inuse: true} +} + +func New(cfg *Config) *wifinina { + w := wifinina{ + cfg: cfg, + sockets: make(map[sock]*socket), + killWatchdog: make(chan bool), + cs: cfg.Cs, + ack: cfg.Ack, + gpio0: cfg.Gpio0, + resetn: cfg.Resetn, } - return strconv.Itoa(int(addr[0])) + "." + strconv.Itoa(int(addr[1])) + "." + strconv.Itoa(int(addr[2])) + "." + strconv.Itoa(int(addr[3])) + + return &w } -func ParseIPv4(s string) (IPAddress, error) { - v := strings.Split(s, ".") - v0, _ := strconv.Atoi(v[0]) - v1, _ := strconv.Atoi(v[1]) - v2, _ := strconv.Atoi(v[2]) - v3, _ := strconv.Atoi(v[3]) - return IPAddress([]byte{byte(v0), byte(v1), byte(v2), byte(v3)}), nil +func (err hwerr) Error() string { + return "[wifinina] error: 0x" + hex.EncodeToString([]byte{uint8(err)}) } -func (addr IPAddress) AsUint32() uint32 { - if len(addr) < 4 { - return 0 +func (w *wifinina) reason() string { + reason := w.getReasonCode() + switch reason { + case 0: + return "unknown failure" + case 201: + return "no AP found" + case 202: + return "auth failed" } - b := []byte(string(addr)) - return binary.BigEndian.Uint32(b[0:4]) + return fmt.Sprintf("%d", reason) } -type MACAddress uint64 +func (w *wifinina) connectToAP() error { + + timeout := w.params.ConnectTimeout + if timeout == 0 { + timeout = netlink.DefaultConnectTimeout + } + + if len(w.params.Ssid) == 0 { + return netlink.ErrMissingSSID + } + + if debugging(debugBasic) { + fmt.Printf("Connecting to Wifi SSID '%s'...", w.params.Ssid) + } + + start := time.Now() + + // Start the connection process + w.setPassphrase(w.params.Ssid, w.params.Passphrase) -func (addr MACAddress) String() string { - b := make([]byte, 8) - binary.BigEndian.PutUint64(b, uint64(addr)) - encoded := hex.EncodeToString(b) - result := "" - for i := 2; i < 8; i++ { - result += encoded[i*2 : i*2+2] - if i < 7 { - result += ":" + // Check if we connected + for { + status := w.getConnectionStatus() + switch status { + case statusConnected: + if debugging(debugBasic) { + fmt.Printf("CONNECTED\r\n") + } + if w.notifyCb != nil { + w.notifyCb(netlink.EventNetUp) + } + return nil + case statusConnectFailed: + if debugging(debugBasic) { + fmt.Printf("FAILED (%s)\r\n", w.reason()) + } + return netlink.ErrConnectFailed + } + if time.Since(start) > timeout { + break } + time.Sleep(1 * time.Second) + } + + if debugging(debugBasic) { + fmt.Printf("FAILED (timed out)\r\n") } - return result + + return netlink.ErrConnectTimeout } -// Cmd Struct Message */ -// ._______________________________________________________________________. -// | START CMD | C/R | CMD | N.PARAM | PARAM LEN | PARAM | .. | END CMD | -// |___________|______|______|_________|___________|________|____|_________| -// | 8 bit | 1bit | 7bit | 8bit | 8bit | nbytes | .. | 8bit | -// |___________|______|______|_________|___________|________|____|_________| -type command struct { - cmd uint8 - reply bool - params []int - paramData []byte +func (w *wifinina) netDisconnect() { + w.disconnect() +} + +func (w *wifinina) showDriver() { + if w.driverShown { + return + } + if debugging(debugBasic) { + fmt.Printf("\r\n") + fmt.Printf("%s\r\n\r\n", driverName) + fmt.Printf("Driver version : %s\r\n", version) + } + w.driverShown = true } -type Device struct { - SPI drivers.SPI - CS machine.Pin - ACK machine.Pin - GPIO0 machine.Pin - RESET machine.Pin +func (w *wifinina) setupSPI() { + if w.spiSetup { + return + } + spi := machine.NINA_SPI + spi.Configure(machine.SPIConfig{ + Frequency: w.cfg.Freq, + SDO: w.cfg.Sdo, + SDI: w.cfg.Sdi, + SCK: w.cfg.Sck, + }) + w.spi = spi + w.spiSetup = true +} - buf [64]byte - ssids [10]string +func (w *wifinina) start() { - sock uint8 - readBuf readBuffer + pinUseDevice(w) - proto uint8 - ip uint32 - port uint16 - mu sync.Mutex + w.cs.Configure(machine.PinConfig{Mode: machine.PinOutput}) + w.ack.Configure(machine.PinConfig{Mode: machine.PinInput}) + w.resetn.Configure(machine.PinConfig{Mode: machine.PinOutput}) + w.gpio0.Configure(machine.PinConfig{Mode: machine.PinOutput}) - // ResetIsHigh controls if the RESET signal to the processor - // should be High or Low (the default). Set this to true - // before calling Configure() for boards such as the Arduino MKR 1010, - // where the reset signal needs to go high instead of low. - ResetIsHigh bool + w.gpio0.High() + w.cs.High() + w.resetn.Set(w.cfg.ResetIsHigh) + time.Sleep(10 * time.Millisecond) + w.resetn.Set(!w.cfg.ResetIsHigh) + time.Sleep(750 * time.Millisecond) + + w.gpio0.Low() + w.gpio0.Configure(machine.PinConfig{Mode: machine.PinInput}) +} + +func (w *wifinina) stop() { + w.resetn.Low() + w.cs.Configure(machine.PinConfig{Mode: machine.PinInput}) } -// New returns a new Wifinina device. -func New(bus drivers.SPI, csPin, ackPin, gpio0Pin, resetPin machine.Pin) *Device { - return &Device{ - SPI: bus, - CS: csPin, - ACK: ackPin, - GPIO0: gpio0Pin, - RESET: resetPin, +func (w *wifinina) showDevice() { + if w.deviceShown { + return + } + if debugging(debugBasic) { + fmt.Printf("ESP32 firmware version : %s\r\n", w.getFwVersion()) + mac := w.getMACAddr() + fmt.Printf("MAC address : %s\r\n", mac.String()) + fmt.Printf("\r\n") + } + w.deviceShown = true +} + +func (w *wifinina) showIP() { + if debugging(debugBasic) { + ip, subnet, gateway := w.getIP() + fmt.Printf("\r\n") + fmt.Printf("DHCP-assigned IP : %s\r\n", ip.String()) + fmt.Printf("DHCP-assigned subnet : %s\r\n", subnet.String()) + fmt.Printf("DHCP-assigned gateway : %s\r\n", gateway.String()) + fmt.Printf("\r\n") + } +} + +func (w *wifinina) networkDown() bool { + return w.getConnectionStatus() != statusConnected +} + +func (w *wifinina) watchdog() { + ticker := time.NewTicker(w.params.WatchdogTimeout) + for { + select { + case <-w.killWatchdog: + return + case <-ticker.C: + w.mu.Lock() + if w.fault != nil { + if debugging(debugBasic) { + fmt.Printf("Watchdog: FAULT: %s\r\n", w.fault) + } + w.netDisconnect() + w.netConnect(true) + w.fault = nil + } else if w.networkDown() { + if debugging(debugBasic) { + fmt.Printf("Watchdog: Wifi NOT CONNECTED, trying again...\r\n") + } + if w.notifyCb != nil { + w.notifyCb(netlink.EventNetDown) + } + w.netConnect(false) + } + w.mu.Unlock() + } } } -// Configure sets the needed pin settings and performs a reset -// of the WiFi device. -func (d *Device) Configure() { - net.UseDriver(d) - pinUseDevice(d) +func (w *wifinina) netConnect(reset bool) error { + if reset { + w.start() + } + w.showDevice() - d.CS.Configure(machine.PinConfig{Mode: machine.PinOutput}) - d.ACK.Configure(machine.PinConfig{Mode: machine.PinInput}) - d.RESET.Configure(machine.PinConfig{Mode: machine.PinOutput}) - d.GPIO0.Configure(machine.PinConfig{Mode: machine.PinOutput}) + for i := 0; w.params.Retries == 0 || i < w.params.Retries; i++ { + if err := w.connectToAP(); err != nil { + switch err { + case netlink.ErrConnectTimeout, netlink.ErrConnectFailed: + continue + } + return err + } + break + } - d.GPIO0.High() - d.CS.High() + if w.networkDown() { + return netlink.ErrConnectFailed + } - d.RESET.Set(d.ResetIsHigh) - time.Sleep(10 * time.Millisecond) + w.showIP() + return nil +} - d.RESET.Set(!d.ResetIsHigh) - time.Sleep(750 * time.Millisecond) +func (w *wifinina) NetConnect(params *netlink.ConnectParams) error { + + w.mu.Lock() + defer w.mu.Unlock() + + if w.netConnected { + return netlink.ErrConnected + } + + w.params = params + + w.showDriver() + w.setupSPI() + + if err := w.netConnect(true); err != nil { + return err + } + + w.netConnected = true + + if w.params.WatchdogTimeout != 0 { + go w.watchdog() + } - d.GPIO0.Low() - d.GPIO0.Configure(machine.PinConfig{Mode: machine.PinInputPullup}) + return nil } -// ----------- client methods (should this be a separate struct?) ------------ +func (w *wifinina) NetDisconnect() { + + w.mu.Lock() + defer w.mu.Unlock() -func (d *Device) StartClient(hostname string, addr uint32, port uint16, sock uint8, mode uint8) error { - if _debug { - fmt.Printf("[StartClient] hostname: %s addr: %02X, port: %d, sock: %d\r\n", hostname, addr, port, sock) + if !w.netConnected { + return } - if err := d.waitForChipSelect(); err != nil { - d.spiChipDeselect() - return err + + if w.params.WatchdogTimeout != 0 { + w.killWatchdog <- true } - if len(hostname) > 0 { - d.sendCmd(CmdStartClientTCP, 5) - d.sendParamStr(hostname, false) - } else { - d.sendCmd(CmdStartClientTCP, 4) + w.netDisconnect() + w.stop() + + w.netConnected = false + + if debugging(debugBasic) { + fmt.Printf("\r\nDisconnected from Wifi SSID '%s'\r\n\r\n", w.params.Ssid) } - d.sendParam32(addr, false) - d.sendParam16(port, false) - d.sendParam8(sock, false) - d.sendParam8(mode, true) - if len(hostname) > 0 { - d.padTo4(17 + len(hostname)) + if w.notifyCb != nil { + w.notifyCb(netlink.EventNetDown) + } +} + +func (w *wifinina) NetNotify(cb func(netlink.Event)) { + w.notifyCb = cb +} + +func (w *wifinina) GetHostByName(name string) (net.IP, error) { + + if debugging(debugNetdev) { + fmt.Printf("[GetHostByName] name: %s\r\n", name) } - d.spiChipDeselect() + w.mu.Lock() + defer w.mu.Unlock() + + ip := w.getHostByName(name) + if ip == "" { + return net.IP{}, netdev.ErrHostUnknown + } - _, err := d.waitRspCmd1(CmdStartClientTCP) - return err + return net.IP([]byte(ip)), nil } -func (d *Device) GetSocket() (uint8, error) { - return d.getUint8(d.req0(CmdGetSocket)) +func (w *wifinina) GetHardwareAddr() (net.HardwareAddr, error) { + + if debugging(debugNetdev) { + fmt.Printf("[GetHardwareAddr]\r\n") + } + + w.mu.Lock() + defer w.mu.Unlock() + + return w.getMACAddr(), nil } -func (d *Device) GetClientState(sock uint8) (uint8, error) { - return d.getUint8(d.reqUint8(CmdGetClientStateTCP, sock)) +func (w *wifinina) GetIPAddr() (net.IP, error) { + + if debugging(debugNetdev) { + fmt.Printf("[GetIPAddr]\r\n") + } + + w.mu.Lock() + defer w.mu.Unlock() + + ip, _, _ := w.getIP() + + return net.IP(ip), nil } -func (d *Device) SendData(buf []byte, sock uint8) (uint16, error) { - d.mu.Lock() - defer d.mu.Unlock() +// See man socket(2) for standard Berkely sockets for Socket, Bind, etc. +// The driver strives to meet the function and semantics of socket(2). + +func (w *wifinina) Socket(domain int, stype int, protocol int) (int, error) { - if err := d.waitForChipSelect(); err != nil { - d.spiChipDeselect() - return 0, err + if debugging(debugNetdev) { + fmt.Printf("[Socket] domain: %d, type: %d, protocol: %d\r\n", + domain, stype, protocol) } - l := d.sendCmd(CmdSendDataTCP, 2) - l += d.sendParamBuf([]byte{sock}, false) - l += d.sendParamBuf(buf, true) - d.addPadding(l) - d.spiChipDeselect() - return d.getUint16(d.waitRspCmd1(CmdSendDataTCP)) + + switch domain { + case netdev.AF_INET: + default: + return -1, netdev.ErrFamilyNotSupported + } + + switch { + case protocol == netdev.IPPROTO_TCP && stype == netdev.SOCK_STREAM: + case protocol == netdev.IPPROTO_TLS && stype == netdev.SOCK_STREAM: + case protocol == netdev.IPPROTO_UDP && stype == netdev.SOCK_DGRAM: + default: + return -1, netdev.ErrProtocolNotSupported + } + + w.mu.Lock() + defer w.mu.Unlock() + + sock := w.getSocket() + if sock == noSocketAvail { + return -1, netdev.ErrNoMoreSockets + } + + socket := newSocket(protocol) + w.sockets[sock] = socket + + return int(sock), nil } -func (d *Device) CheckDataSent(sock uint8) (bool, error) { - d.mu.Lock() - defer d.mu.Unlock() +func (w *wifinina) Bind(sockfd int, ip net.IP, port int) error { - var lastErr error - for timeout := 0; timeout < 10; timeout++ { - sent, err := d.getUint8(d.reqUint8(CmdDataSentTCP, sock)) - if err != nil { - lastErr = err - } - if sent > 0 { - return true, nil + if debugging(debugNetdev) { + fmt.Printf("[Bind] sockfd: %d, addr: %s:%d\r\n", sockfd, ip, port) + } + + w.mu.Lock() + defer w.mu.Unlock() + + var sock = sock(sockfd) + var socket = w.sockets[sock] + + switch socket.protocol { + case netdev.IPPROTO_TCP: + case netdev.IPPROTO_TLS: + case netdev.IPPROTO_UDP: + w.startServer(sock, uint16(port), protoModeUDP) + } + + socket.ip, socket.port = ip, port + + return nil +} + +func toUint32(ip net.IP) uint32 { + ip = ip.To4() + return uint32(ip[0])<<24 | + uint32(ip[1])<<16 | + uint32(ip[2])<<8 | + uint32(ip[3]) +} + +func (w *wifinina) Connect(sockfd int, host string, ip net.IP, port int) error { + + if debugging(debugNetdev) { + if host == "" { + fmt.Printf("[Connect] sockfd: %d, addr: %s:%d\r\n", sockfd, ip, port) + } else { + fmt.Printf("[Connect] sockfd: %d, host: %s:%d\r\n", sockfd, host, port) } - time.Sleep(100 * time.Microsecond) } - return false, lastErr + + w.mu.Lock() + defer w.mu.Unlock() + + var sock = sock(sockfd) + var socket = w.sockets[sock] + + // Start the connection + switch socket.protocol { + case netdev.IPPROTO_TCP: + w.startClient(sock, "", toUint32(ip), uint16(port), protoModeTCP) + case netdev.IPPROTO_TLS: + w.startClient(sock, host, 0, uint16(port), protoModeTLS) + case netdev.IPPROTO_UDP: + w.startClient(sock, "", toUint32(ip), uint16(port), protoModeUDP) + return nil + } + + if w.getClientState(sock) == tcpStateEstablished { + return nil + } + + if host == "" { + return fmt.Errorf("Connect to %s:%d failed", ip, port) + } else { + return fmt.Errorf("Connect to %s:%d failed", host, port) + } } -func (d *Device) GetDataBuf(sock uint8, buf []byte) (int, error) { - d.mu.Lock() - defer d.mu.Unlock() +func (w *wifinina) Listen(sockfd int, backlog int) error { - if err := d.waitForChipSelect(); err != nil { - d.spiChipDeselect() - return 0, err + if debugging(debugNetdev) { + fmt.Printf("[Listen] sockfd: %d\r\n", sockfd) } - p := uint16(len(buf)) - l := d.sendCmd(CmdGetDatabufTCP, 2) - l += d.sendParamBuf([]byte{sock}, false) - l += d.sendParamBuf([]byte{uint8(p & 0x00FF), uint8((p) >> 8)}, true) - d.addPadding(l) - d.spiChipDeselect() - if err := d.waitForChipSelect(); err != nil { - d.spiChipDeselect() - return 0, err + + w.mu.Lock() + defer w.mu.Unlock() + + var sock = sock(sockfd) + var socket = w.sockets[sock] + + switch socket.protocol { + case netdev.IPPROTO_TCP: + w.startServer(sock, uint16(socket.port), protoModeTCP) + case netdev.IPPROTO_UDP: + default: + return netdev.ErrProtocolNotSupported } - n, err := d.waitRspBuf16(CmdGetDatabufTCP, buf) - d.spiChipDeselect() - return int(n), err + + return nil } -func (d *Device) StopClient(sock uint8) error { - d.mu.Lock() - defer d.mu.Unlock() +func (w *wifinina) Accept(sockfd int, ip net.IP, port int) (int, error) { + + if debugging(debugNetdev) { + fmt.Printf("[Accept] sockfd: %d, peer: %s:%d\r\n", sockfd, ip, port) + } + + w.mu.Lock() + defer w.mu.Unlock() + + var client sock + var sock = sock(sockfd) + var socket = w.sockets[sock] + + switch socket.protocol { + case netdev.IPPROTO_TCP: + default: + return -1, netdev.ErrProtocolNotSupported + } + + for { + // Accept() will be sleeping most of the time, checking for a + // new clients every 1/10 sec. + w.mu.Unlock() + time.Sleep(100 * time.Millisecond) + w.mu.Lock() + + // Check if we've faulted + if w.fault != nil { + return -1, w.fault + } + + // TODO: BUG: Currently, a sock that is 100% busy will always be + // TODO: returned by w.accept(sock), starving other socks + // TODO: from begin serviced. Need to figure out how to + // TODO: service socks fairly (round-robin?) so no one sock + // TODO: can dominate. + + // Check if a client has data + client = w.accept(sock) + if client == noSocketAvail { + // None ready + continue + } + + // If we've already seen this socket, we can reuse + // the socket and return it. But, only if the socket + // is closed. If it's not closed, we'll just come back + // later to reuse it. + + clientSocket, ok := w.sockets[client] + if ok { + // Wait for client to Close + if clientSocket.inuse { + continue + } + // Reuse client socket + return int(client), nil + } + + // Create new socket for client and return fd + w.sockets[client] = newSocket(socket.protocol) + return int(client), nil + } +} - if _debug { - println("[StopClient] called StopClient()\r") +func (w *wifinina) sockDown(sock sock) bool { + var socket = w.sockets[sock] + if socket.protocol == netdev.IPPROTO_UDP { + return false } - _, err := d.getUint8(d.reqUint8(CmdStopClientTCP, sock)) - return err + return w.getClientState(sock) != tcpStateEstablished } -func (d *Device) StartServer(port uint16, sock uint8, mode uint8) error { - d.mu.Lock() - defer d.mu.Unlock() +func (w *wifinina) sendTCP(sock sock, buf []byte, deadline time.Time) (int, error) { - if err := d.waitForChipSelect(); err != nil { - d.spiChipDeselect() - return err + var timeoutDataSent = 25 + + // Send it + n := int(w.sendData(sock, buf)) + if n == 0 { + return -1, io.EOF } - l := d.sendCmd(CmdStartServerTCP, 3) - l += d.sendParam16(port, false) - l += d.sendParam8(sock, false) - l += d.sendParam8(mode, true) - d.addPadding(l) - d.spiChipDeselect() - _, err := d.waitRspCmd1(CmdStartClientTCP) - return err + + // Check if data was sent + for i := 0; i < timeoutDataSent; i++ { + sent := w.checkDataSent(sock) + if sent { + return n, nil + } + + // Check if we've timed out + if !deadline.IsZero() { + if time.Now().After(deadline) { + return -1, netdev.ErrTimeout + } + } + + // Check if socket went down + if w.sockDown(sock) { + return -1, io.EOF + } + + // Check if we've faulted + if w.fault != nil { + return -1, w.fault + } + + // Unlock while we sleep, so others can make progress + w.mu.Unlock() + time.Sleep(100 * time.Millisecond) + w.mu.Lock() + } + + return -1, netdev.ErrTimeout } -// InsertDataBuf adds data to the buffer used for sending UDP data -func (d *Device) InsertDataBuf(buf []byte, sock uint8) (bool, error) { - d.mu.Lock() - defer d.mu.Unlock() +func (w *wifinina) sendUDP(sock sock, buf []byte, deadline time.Time) (int, error) { - if err := d.waitForChipSelect(); err != nil { - d.spiChipDeselect() - return false, err + // Queue it + ok := w.insertDataBuf(sock, buf) + if !ok { + return -1, fmt.Errorf("Insert UDP data failed, len(buf)=%d", len(buf)) } - l := d.sendCmd(CmdInsertDataBuf, 2) - l += d.sendParamBuf([]byte{sock}, false) - l += d.sendParamBuf(buf, true) - d.addPadding(l) - d.spiChipDeselect() - n, err := d.getUint8(d.waitRspCmd1(CmdInsertDataBuf)) - return n == 1, err + + // Send it + ok = w.sendUDPData(sock) + if !ok { + return -1, fmt.Errorf("Send UDP data failed, len(buf)=%d", len(buf)) + } + + return len(buf), nil } -// SendUDPData sends the data previously added to the UDP buffer -func (d *Device) SendUDPData(sock uint8) (bool, error) { - d.mu.Lock() - defer d.mu.Unlock() +func (w *wifinina) sendChunk(sockfd int, buf []byte, deadline time.Time) (int, error) { + var sock = sock(sockfd) + var socket = w.sockets[sock] - if err := d.waitForChipSelect(); err != nil { - d.spiChipDeselect() - return false, err + // Check if we've timed out + if !deadline.IsZero() { + if time.Now().After(deadline) { + return -1, netdev.ErrTimeout + } } - l := d.sendCmd(CmdSendDataUDP, 1) - l += d.sendParam8(sock, true) - d.addPadding(l) - d.spiChipDeselect() - n, err := d.getUint8(d.waitRspCmd1(CmdSendDataUDP)) - return n == 1, err + + switch socket.protocol { + case netdev.IPPROTO_TCP, netdev.IPPROTO_TLS: + return w.sendTCP(sock, buf, deadline) + case netdev.IPPROTO_UDP: + return w.sendUDP(sock, buf, deadline) + } + + return -1, netdev.ErrProtocolNotSupported } -// ---------- /client methods (should this be a separate struct?) ------------ +func (w *wifinina) Send(sockfd int, buf []byte, flags int, + deadline time.Time) (int, error) { -/* - static bool startServer(uint16_t port, uint8_t sock); - static uint8_t getServerState(uint8_t sock); - static bool getData(uint8_t connId, uint8_t *data, bool peek, bool* connClose); - static int getDataBuf(uint8_t connId, uint8_t *buf, uint16_t bufSize); - static bool sendData(uint8_t sock, const uint8_t *data, uint16_t len); - static bool sendDataUdp(uint8_t sock, const char* host, uint16_t port, const uint8_t *data, uint16_t len); - static uint16_t availData(uint8_t connId); + if debugging(debugNetdev) { + fmt.Printf("[Send] sockfd: %d, len(buf): %d, flags: %d\r\n", + sockfd, len(buf), flags) + } + w.mu.Lock() + defer w.mu.Unlock() - static bool ping(const char *host); - static void reset(); + // Break large bufs into chunks so we don't overrun the hw queue - static void getRemoteIpAddress(IPAddress& ip); - static uint16_t getRemotePort(); -*/ + chunkSize := 1436 + for i := 0; i < len(buf); i += chunkSize { + end := i + chunkSize + if end > len(buf) { + end = len(buf) + } + _, err := w.sendChunk(sockfd, buf[i:end], deadline) + if err != nil { + return -1, err + } + } -func (d *Device) Disconnect() error { - _, err := d.req1(CmdDisconnect) - return err + return len(buf), nil } -func (d *Device) GetFwVersion() (string, error) { - return d.getString(d.req0(CmdGetFwVersion)) +func (w *wifinina) Recv(sockfd int, buf []byte, flags int, + deadline time.Time) (int, error) { + + if debugging(debugNetdev) { + fmt.Printf("[Recv] sockfd: %d, len(buf): %d, flags: %d\r\n", + sockfd, len(buf), flags) + } + + w.mu.Lock() + defer w.mu.Unlock() + + var sock = sock(sockfd) + + // Limit max read size to chunk large read requests + var max = len(buf) + if max > 1436 { + max = 1436 + } + + for { + // Check if we've timed out + if !deadline.IsZero() { + if time.Now().After(deadline) { + return -1, netdev.ErrTimeout + } + } + + // Receive into buf, if any data available. It's ok if no data + // is available, we'll just sleep a bit and recheck. Recv() + // doesn't return unless there is data, even a single byte, or + // on error such as timeout or EOF. + + n := int(w.getDataBuf(sock, buf[:max])) + if n > 0 { + if debugging(debugNetdev) { + fmt.Printf("[<--Recv] sockfd: %d, n: %d\r\n", + sock, n) + } + return n, nil + } + + // Check if socket went down + if w.sockDown(sock) { + // Get any last bytes + n = int(w.getDataBuf(sock, buf[:max])) + if debugging(debugNetdev) { + fmt.Printf("[<--Recv] sockfd: %d, n: %d, EOF\r\n", + sock, n) + } + if n > 0 { + return n, io.EOF + } + return -1, io.EOF + } + + // Check if we've faulted + if w.fault != nil { + return -1, w.fault + } + + // Unlock while we sleep, so others can make progress + w.mu.Unlock() + time.Sleep(100 * time.Millisecond) + w.mu.Lock() + } } -func (d *Device) GetConnectionStatus() (ConnectionStatus, error) { - status, err := d.getUint8(d.req0(CmdGetConnStatus)) - return ConnectionStatus(status), err +func (w *wifinina) Close(sockfd int) error { + + if debugging(debugNetdev) { + fmt.Printf("[Close] sockfd: %d\r\n", sockfd) + } + + w.mu.Lock() + defer w.mu.Unlock() + + var sock = sock(sockfd) + var socket = w.sockets[sock] + + if !socket.inuse { + return nil + } + + w.stopClient(sock) + + if socket.protocol == netdev.IPPROTO_UDP { + socket.inuse = false + return nil + } + + start := time.Now() + for time.Since(start) < 5*time.Second { + + if w.getClientState(sock) == tcpStateClosed { + socket.inuse = false + return nil + } + + w.mu.Unlock() + time.Sleep(100 * time.Millisecond) + w.mu.Lock() + } + + return netdev.ErrClosingSocket } -func (d *Device) GetCurrentEncryptionType() (EncryptionType, error) { - enctype, err := d.getUint8(d.req1(CmdGetCurrEncrType)) - return EncryptionType(enctype), err +func (w *wifinina) SetSockOpt(sockfd int, level int, opt int, value interface{}) error { + + if debugging(debugNetdev) { + fmt.Printf("[SetSockOpt] sockfd: %d\r\n", sockfd) + } + + return netdev.ErrNotSupported } -func (d *Device) GetCurrentBSSID() (MACAddress, error) { - return d.getMACAddress(d.req1(CmdGetCurrBSSID)) +func (w *wifinina) startClient(sock sock, hostname string, addr uint32, port uint16, mode uint8) { + if debugging(debugCmd) { + fmt.Printf(" [cmdStartClientTCP] sock: %d, hostname: \"%s\", addr: % 02X, port: %d, mode: %d\r\n", + sock, hostname, addr, port, mode) + } + + w.waitForChipReady() + w.spiChipSelect() + + if len(hostname) > 0 { + w.sendCmd(cmdStartClientTCP, 5) + w.sendParamStr(hostname, false) + } else { + w.sendCmd(cmdStartClientTCP, 4) + } + + w.sendParam32(addr, false) + w.sendParam16(port, false) + w.sendParam8(uint8(sock), false) + w.sendParam8(mode, true) + + if len(hostname) > 0 { + w.padTo4(17 + len(hostname)) + } + + w.spiChipDeselect() + w.waitRspCmd1(cmdStartClientTCP) } -func (d *Device) GetCurrentRSSI() (int32, error) { - return d.getInt32(d.req1(CmdGetCurrRSSI)) +func (w *wifinina) getSocket() sock { + if debugging(debugCmd) { + fmt.Printf(" [cmdGetSocket]\r\n") + } + return sock(w.getUint8(w.req0(cmdGetSocket))) } -func (d *Device) GetCurrentSSID() (string, error) { - return d.getString(d.req1(CmdGetCurrSSID)) +func (w *wifinina) getClientState(sock sock) uint8 { + if debugging(debugCmd) { + fmt.Printf(" [cmdGetClientStateTCP] sock: %d\r\n", sock) + } + return w.getUint8(w.reqUint8(cmdGetClientStateTCP, uint8(sock))) } -func (d *Device) GetMACAddress() (MACAddress, error) { - return d.getMACAddress(d.req1(CmdGetMACAddr)) +func (w *wifinina) sendData(sock sock, buf []byte) uint16 { + if debugging(debugCmd) { + fmt.Printf(" [cmdSendDataTCP] sock: %d, len(buf): %d\r\n", + sock, len(buf)) + } + + w.waitForChipReady() + w.spiChipSelect() + l := w.sendCmd(cmdSendDataTCP, 2) + l += w.sendParamBuf([]byte{uint8(sock)}, false) + l += w.sendParamBuf(buf, true) + w.addPadding(l) + w.spiChipDeselect() + + sent := w.getUint16(w.waitRspCmd1(cmdSendDataTCP)) + return bits.RotateLeft16(sent, 8) } -func (d *Device) GetIP() (ip, subnet, gateway IPAddress, err error) { - sl := make([]string, 3) - if l, err := d.reqRspStr1(CmdGetIPAddr, dummyData, sl); err != nil { - return "", "", "", err - } else if l != 3 { - return "", "", "", ErrUnexpectedLength +func (w *wifinina) checkDataSent(sock sock) bool { + if debugging(debugCmd) { + fmt.Printf(" [cmdDataSentTCP] sock: %d\r\n", sock) } - return IPAddress(sl[0]), IPAddress(sl[1]), IPAddress(sl[2]), err + sent := w.getUint8(w.reqUint8(cmdDataSentTCP, uint8(sock))) + return sent > 0 } -func (d *Device) GetHostByName(hostname string) (IPAddress, error) { - ok, err := d.getUint8(d.reqStr(CmdReqHostByName, hostname)) - if err != nil { - return "", err +func (w *wifinina) getDataBuf(sock sock, buf []byte) uint16 { + if debugging(debugCmd) { + fmt.Printf(" [cmdGetDatabufTCP] sock: %d, len(buf): %d\r\n", + sock, len(buf)) } - if ok != 1 { - return "", ErrUnknownHost + + w.waitForChipReady() + w.spiChipSelect() + p := uint16(len(buf)) + l := w.sendCmd(cmdGetDatabufTCP, 2) + l += w.sendParamBuf([]byte{uint8(sock)}, false) + l += w.sendParamBuf([]byte{uint8(p & 0x00FF), uint8((p) >> 8)}, true) + w.addPadding(l) + w.spiChipDeselect() + + w.waitForChipReady() + w.spiChipSelect() + n := w.waitRspBuf16(cmdGetDatabufTCP, buf) + w.spiChipDeselect() + + if n > 0 { + if debugging(debugCmd) { + fmt.Printf(" [<--cmdGetDatabufTCP] sock: %d, got n: %d\r\n", + sock, n) + } } - ip, err := d.getString(d.req0(CmdGetHostByName)) - return IPAddress(ip), err + + return n } -func (d *Device) GetNetworkBSSID(idx int) (MACAddress, error) { - if idx < 0 || idx >= MaxNetworks { - return 0, nil +func (w *wifinina) stopClient(sock sock) { + if debugging(debugCmd) { + fmt.Printf(" [cmdStopClientTCP] sock: %d\r\n", sock) } - return d.getMACAddress(d.reqUint8(CmdGetIdxBSSID, uint8(idx))) + w.getUint8(w.reqUint8(cmdStopClientTCP, uint8(sock))) } -func (d *Device) GetNetworkChannel(idx int) (uint8, error) { - if idx < 0 || idx >= MaxNetworks { - return 0, nil +func (w *wifinina) startServer(sock sock, port uint16, mode uint8) { + if debugging(debugCmd) { + fmt.Printf(" [cmdStartServerTCP] sock: %d, port: %d, mode: %d\r\n", + sock, port, mode) } - return d.getUint8(d.reqUint8(CmdGetIdxChannel, uint8(idx))) + + w.waitForChipReady() + w.spiChipSelect() + l := w.sendCmd(cmdStartServerTCP, 3) + l += w.sendParam16(port, false) + l += w.sendParam8(uint8(sock), false) + l += w.sendParam8(mode, true) + w.addPadding(l) + w.spiChipDeselect() + + w.waitRspCmd1(cmdStartServerTCP) } -func (d *Device) GetNetworkEncrType(idx int) (EncryptionType, error) { - if idx < 0 || idx >= MaxNetworks { - return 0, nil +func (w *wifinina) accept(s sock) sock { + + if debugging(debugCmd) { + fmt.Printf(" [cmdAvailDataTCP] sock: %d\r\n", s) } - enctype, err := d.getUint8(d.reqUint8(CmdGetIdxEncrType, uint8(idx))) - return EncryptionType(enctype), err + + w.waitForChipReady() + w.spiChipSelect() + l := w.sendCmd(cmdAvailDataTCP, 1) + l += w.sendParam8(uint8(s), true) + w.addPadding(l) + w.spiChipDeselect() + + newsock16 := w.getUint16(w.waitRspCmd1(cmdAvailDataTCP)) + newsock := sock(uint8(bits.RotateLeft16(newsock16, 8))) + + if newsock != noSocketAvail { + if debugging(debugCmd) { + fmt.Printf(" [cmdAvailDataTCP-->] sock: %d, got sock: %d\r\n", + s, newsock) + } + } + + return newsock } -func (d *Device) GetNetworkRSSI(idx int) (int32, error) { - if idx < 0 || idx >= MaxNetworks { - return 0, nil +// insertDataBuf adds data to the buffer used for sending UDP data +func (w *wifinina) insertDataBuf(sock sock, buf []byte) bool { + + if debugging(debugCmd) { + fmt.Printf(" [cmdInsertDataBuf] sock: %d, len(buf): %d\r\n", + sock, len(buf)) } - return d.getInt32(d.reqUint8(CmdGetIdxRSSI, uint8(idx))) + + w.waitForChipReady() + w.spiChipSelect() + l := w.sendCmd(cmdInsertDataBuf, 2) + l += w.sendParamBuf([]byte{uint8(sock)}, false) + l += w.sendParamBuf(buf, true) + w.addPadding(l) + w.spiChipDeselect() + + n := w.getUint8(w.waitRspCmd1(cmdInsertDataBuf)) + return n == 1 } -func (d *Device) GetNetworkSSID(idx int) string { - if idx < 0 || idx >= MaxNetworks { - return "" +// sendUDPData sends the data previously added to the UDP buffer +func (w *wifinina) sendUDPData(sock sock) bool { + + if debugging(debugCmd) { + fmt.Printf(" [cmdSendDataUDP] sock: %d\r\n", sock) } - return d.ssids[idx] + + w.waitForChipReady() + w.spiChipSelect() + l := w.sendCmd(cmdSendDataUDP, 1) + l += w.sendParam8(uint8(sock), true) + w.addPadding(l) + w.spiChipDeselect() + + n := w.getUint8(w.waitRspCmd1(cmdSendDataUDP)) + return n == 1 } -func (d *Device) GetReasonCode() (uint8, error) { - return d.getUint8(d.req0(CmdGetReasonCode)) +func (w *wifinina) disconnect() { + if debugging(debugCmd) { + fmt.Printf(" [cmdDisconnect]\r\n") + } + w.req1(cmdDisconnect) } -// GetTime is the time as a Unix timestamp -func (d *Device) GetTime() (uint32, error) { - return d.getUint32(d.req0(CmdGetTime)) +func (w *wifinina) getFwVersion() string { + if debugging(debugCmd) { + fmt.Printf(" [cmdGetFwVersion]\r\n") + } + return w.getString(w.req0(cmdGetFwVersion)) } -func (d *Device) GetTemperature() (float32, error) { - return d.getFloat32(d.req0(CmdGetTemperature)) +func (w *wifinina) getConnectionStatus() connectionStatus { + if debugging(debugCmd) { + fmt.Printf(" [cmdGetConnStatus]\r\n") + } + status := w.getUint8(w.req0(cmdGetConnStatus)) + return connectionStatus(status) } -func (d *Device) Ping(ip IPAddress, ttl uint8) int16 { - return 0 +func (w *wifinina) getCurrentencryptionType() encryptionType { + enctype := w.getUint8(w.req1(cmdGetCurrEncrType)) + return encryptionType(enctype) } -func (d *Device) SetDebug(on bool) error { - var v uint8 - if on { - v = 1 - } - _, err := d.reqUint8(CmdSetDebug, v) - return err +func (w *wifinina) getCurrentBSSID() net.HardwareAddr { + return w.getMACAddress(w.req1(cmdGetCurrBSSID)) } -func (d *Device) SetNetwork(ssid string) error { - _, err := d.reqStr(CmdSetNet, ssid) - return err +func (w *wifinina) getCurrentRSSI() int32 { + return w.getInt32(w.req1(cmdGetCurrRSSI)) } -func (d *Device) SetPassphrase(ssid string, passphrase string) error { - _, err := d.reqStr2(CmdSetPassphrase, ssid, passphrase) - return err +func (w *wifinina) getCurrentSSID() string { + return w.getString(w.req1(cmdGetCurrSSID)) } -func (d *Device) SetKey(ssid string, index uint8, key string) error { - defer d.spiChipDeselect() - if err := d.waitForChipSelect(); err != nil { - return err +func (w *wifinina) getMACAddr() net.HardwareAddr { + if debugging(debugCmd) { + fmt.Printf(" [cmdGetMACAddr]\r\n") } + return w.getMACAddress(w.req1(cmdGetMACAddr)) +} - d.sendCmd(CmdSetKey, 3) - d.sendParamStr(ssid, false) - d.sendParam8(index, false) - d.sendParamStr(key, true) +func (w *wifinina) faultf(f string, args ...any) { + // Only record the first fault + if w.fault == nil { + w.fault = fmt.Errorf(f, args...) + } +} - d.padTo4(8 + len(ssid) + len(key)) +func (w *wifinina) getIP() (ip, subnet, gateway net.IP) { + if debugging(debugCmd) { + fmt.Printf(" [cmdGetIPAddr]\r\n") + } + sl := make([]string, 3) + l := w.reqRspStr1(cmdGetIPAddr, dummyData, sl) + if l != 3 { + w.faultf("getIP wanted l=3, got l=%d", l) + return + } + ip, subnet, gateway = make([]byte, 4), make([]byte, 4), make([]byte, 4) + copy(ip[:], sl[0]) + copy(subnet[:], sl[1]) + copy(gateway[:], sl[2]) + return +} - _, err := d.waitRspCmd1(CmdSetKey) - if err != nil { - return err +func (w *wifinina) getHostByName(name string) string { + if debugging(debugCmd) { + fmt.Printf(" [cmdGetHostByName]\r\n") + } + ok := w.getUint8(w.reqStr(cmdReqHostByName, name)) + if ok != 1 { + return "" } + return w.getString(w.req0(cmdGetHostByName)) +} - return nil +func (w *wifinina) getNetworkBSSID(idx int) net.HardwareAddr { + if idx < 0 || idx >= maxNetworks { + return net.HardwareAddr{} + } + return w.getMACAddress(w.reqUint8(cmdGetIdxBSSID, uint8(idx))) } -func (d *Device) SetNetworkForAP(ssid string) error { - _, err := d.reqStr(CmdSetAPNet, ssid) - return err +func (w *wifinina) getNetworkChannel(idx int) uint8 { + if idx < 0 || idx >= maxNetworks { + return 0 + } + return w.getUint8(w.reqUint8(cmdGetIdxChannel, uint8(idx))) } -func (d *Device) SetPassphraseForAP(ssid string, passphrase string) error { - _, err := d.reqStr2(CmdSetAPPassphrase, ssid, passphrase) - return err +func (w *wifinina) getNetworkEncrType(idx int) encryptionType { + if idx < 0 || idx >= maxNetworks { + return 0 + } + enctype := w.getUint8(w.reqUint8(cmdGetIdxEncrType, uint8(idx))) + return encryptionType(enctype) } -func (d *Device) SetIP(which uint8, ip uint32, gw uint32, subnet uint32) error { - return ErrNotImplemented +func (w *wifinina) getNetworkRSSI(idx int) int32 { + if idx < 0 || idx >= maxNetworks { + return 0 + } + return w.getInt32(w.reqUint8(cmdGetIdxRSSI, uint8(idx))) } -func (d *Device) SetDNS(which uint8, dns1 uint32, dns2 uint32) error { - defer d.spiChipDeselect() - if err := d.waitForChipSelect(); err != nil { - return err +func (w *wifinina) getNetworkSSID(idx int) string { + if idx < 0 || idx >= maxNetworks { + return "" } + return w.ssids[idx] +} - d.sendCmd(CmdSetDNSConfig, 3) - d.sendParam8(which, false) - d.sendParam32(dns1, false) - d.sendParam32(dns2, true) +func (w *wifinina) getReasonCode() uint8 { + return w.getUint8(w.req0(cmdGetReasonCode)) +} - _, err := d.waitRspCmd1(CmdSetDNSConfig) - if err != nil { - return err - } +// getTime is the time as a Unix timestamp +func (w *wifinina) getTime() uint32 { + return w.getUint32(w.req0(cmdGetTime)) +} - return nil +func (w *wifinina) getTemperature() float32 { + return w.getFloat32(w.req0(cmdGetTemperature)) } -func (d *Device) SetHostname(hostname string) error { - defer d.spiChipDeselect() - if err := d.waitForChipSelect(); err != nil { - return err +func (w *wifinina) setDebug(on bool) { + var v uint8 + if on { + v = 1 } + w.reqUint8(cmdSetDebug, v) +} - d.sendCmd(CmdSetHostname, 3) - d.sendParamStr(hostname, true) +func (w *wifinina) setNetwork(ssid string) { + w.reqStr(cmdSetNet, ssid) +} - d.padTo4(5 + len(hostname)) +func (w *wifinina) setPassphrase(ssid string, passphrase string) { - _, err := d.waitRspCmd1(CmdSetHostname) - if err != nil { - return err + if debugging(debugCmd) { + fmt.Printf(" [cmdSetPassphrase] ssid: %s, passphrase: ******\r\n", + ssid) } - return nil + // Dont' show passphrase in debug output + saveDebug := _debug + _debug = _debug & ^debugDetail + w.reqStr2(cmdSetPassphrase, ssid, passphrase) + _debug = saveDebug +} + +func (w *wifinina) setKey(ssid string, index uint8, key string) { + + w.waitForChipReady() + w.spiChipSelect() + w.sendCmd(cmdSetKey, 3) + w.sendParamStr(ssid, false) + w.sendParam8(index, false) + w.sendParamStr(key, true) + w.padTo4(8 + len(ssid) + len(key)) + w.spiChipDeselect() + + w.waitRspCmd1(cmdSetKey) } -func (d *Device) SetPowerMode(mode uint8) error { - _, err := d.reqUint8(CmdSetPowerMode, mode) - return err +func (w *wifinina) setNetworkForAP(ssid string) { + w.reqStr(cmdSetAPNet, ssid) } -func (d *Device) ScanNetworks() (uint8, error) { - return d.reqRspStr0(CmdScanNetworks, d.ssids[:]) +func (w *wifinina) setPassphraseForAP(ssid string, passphrase string) { + w.reqStr2(cmdSetAPPassphrase, ssid, passphrase) } -func (d *Device) StartScanNetworks() (uint8, error) { - return d.getUint8(d.req0(CmdStartScanNetworks)) +func (w *wifinina) setDNS(which uint8, dns1 uint32, dns2 uint32) { + w.waitForChipReady() + w.spiChipSelect() + w.sendCmd(cmdSetDNSConfig, 3) + w.sendParam8(which, false) + w.sendParam32(dns1, false) + w.sendParam32(dns2, true) + //pad?? + w.spiChipDeselect() + + w.waitRspCmd1(cmdSetDNSConfig) } -func (d *Device) PinMode(pin uint8, mode uint8) error { - _, err := d.req2Uint8(CmdSetPinMode, pin, mode) - return err +func (w *wifinina) setHostname(hostname string) { + w.waitForChipReady() + w.spiChipSelect() + w.sendCmd(cmdSetHostname, 3) + w.sendParamStr(hostname, true) + w.padTo4(5 + len(hostname)) + w.spiChipDeselect() + + w.waitRspCmd1(cmdSetHostname) } -func (d *Device) DigitalWrite(pin uint8, value uint8) error { - _, err := d.req2Uint8(CmdSetDigitalWrite, pin, value) - return err +func (w *wifinina) setPowerMode(mode uint8) { + w.reqUint8(cmdSetPowerMode, mode) } -func (d *Device) AnalogWrite(pin uint8, value uint8) error { - _, err := d.req2Uint8(CmdSetAnalogWrite, pin, value) - return err +func (w *wifinina) scanNetworks() uint8 { + return w.reqRspStr0(cmdScanNetworks, w.ssids[:]) } -// ------------- End of public device interface ---------------------------- +func (w *wifinina) startScanNetworks() uint8 { + return w.getUint8(w.req0(cmdStartScanNetworks)) +} -func (d *Device) getString(l uint8, err error) (string, error) { - if err != nil { - return "", err +func (w *wifinina) PinMode(pin uint8, mode uint8) { + if debugging(debugCmd) { + fmt.Printf(" [cmdSetPinMode] pin: %d, mode: %d\r\n", pin, mode) } - return string(d.buf[0:l]), err + w.req2Uint8(cmdSetPinMode, pin, mode) } -func (d *Device) getUint8(l uint8, err error) (uint8, error) { - if err != nil { - return 0, err - } - if l != 1 { - if _debug { - println("expected length 1, was actually", l, "\r") - } - return 0, ErrUnexpectedLength +func (w *wifinina) DigitalWrite(pin uint8, value uint8) { + if debugging(debugCmd) { + fmt.Printf(" [cmdSetDigitialWrite] pin: %d, value: %d\r\n", pin, value) } - return d.buf[0], err + w.req2Uint8(cmdSetDigitalWrite, pin, value) } -func (d *Device) getUint16(l uint8, err error) (uint16, error) { - if err != nil { - return 0, err - } - if l != 2 { - if _debug { - println("expected length 2, was actually", l, "\r") - } - return 0, ErrUnexpectedLength +func (w *wifinina) AnalogWrite(pin uint8, value uint8) { + w.req2Uint8(cmdSetAnalogWrite, pin, value) +} + +func (w *wifinina) getString(l uint8) string { + return string(w.buf[0:l]) +} + +func (w *wifinina) getUint8(l uint8) uint8 { + if l == 1 { + return w.buf[0] } - return binary.BigEndian.Uint16(d.buf[0:2]), err + w.faultf("expected length 1, was actually %d", l) + return 0 } -func (d *Device) getUint32(l uint8, err error) (uint32, error) { - if err != nil { - return 0, err +func (w *wifinina) getUint16(l uint8) uint16 { + if l == 2 { + return binary.BigEndian.Uint16(w.buf[0:2]) } - if l != 4 { - return 0, ErrUnexpectedLength + w.faultf("expected length 2, was actually %d", l) + return 0 +} + +func (w *wifinina) getUint32(l uint8) uint32 { + if l == 4 { + return binary.BigEndian.Uint32(w.buf[0:4]) } - return binary.LittleEndian.Uint32(d.buf[0:4]), err + w.faultf("expected length 4, was actually %d", l) + return 0 } -func (d *Device) getInt32(l uint8, err error) (int32, error) { - i, err := d.getUint32(l, err) - return int32(i), err +func (w *wifinina) getInt32(l uint8) int32 { + return int32(w.getUint32(l)) } -func (d *Device) getFloat32(l uint8, err error) (float32, error) { - i, err := d.getUint32(l, err) - return float32(i), err +func (w *wifinina) getFloat32(l uint8) float32 { + return float32(w.getUint32(l)) } -func (d *Device) getMACAddress(l uint8, err error) (MACAddress, error) { - if err != nil { - return 0, err +func (w *wifinina) getMACAddress(l uint8) net.HardwareAddr { + if l == 6 { + mac := w.buf[0:6] + // Reverse the bytes + for i, j := 0, len(mac)-1; i < j; i, j = i+1, j-1 { + mac[i], mac[j] = mac[j], mac[i] + } + return mac } - if l != 6 { - return 0, ErrUnexpectedLength + w.faultf("expected length 6, was actually %d", l) + return net.HardwareAddr{} +} + +func (w *wifinina) transfer(b byte) byte { + v, err := w.spi.Transfer(b) + if err != nil { + w.faultf("SPI.Transfer") + return 0 } - return MACAddress(binary.LittleEndian.Uint64(d.buf[0:8]) & 0xFFFFFFFFFFFF), err + return v } +// Cmd Struct Message */ +// ._______________________________________________________________________. +// | START CMD | C/R | CMD | N.PARAM | PARAM LEN | PARAM | .. | END CMD | +// |___________|______|______|_________|___________|________|____|_________| +// | 8 bit | 1bit | 7bit | 8bit | 8bit | nbytes | .. | 8bit | +// |___________|______|______|_________|___________|________|____|_________| + // req0 sends a command to the device with no request parameters -func (d *Device) req0(cmd CommandType) (l uint8, err error) { - if err := d.sendCmd0(cmd); err != nil { - return 0, err - } - return d.waitRspCmd1(cmd) +func (w *wifinina) req0(cmd uint8) uint8 { + w.sendCmd0(cmd) + return w.waitRspCmd1(cmd) } // req1 sends a command to the device with a single dummy parameters of 0xFF -func (d *Device) req1(cmd CommandType) (l uint8, err error) { - return d.reqUint8(cmd, dummyData) +func (w *wifinina) req1(cmd uint8) uint8 { + return w.reqUint8(cmd, dummyData) } // reqUint8 sends a command to the device with a single uint8 parameter -func (d *Device) reqUint8(cmd CommandType, data uint8) (l uint8, err error) { - if err := d.sendCmdPadded1(cmd, data); err != nil { - return 0, err - } - return d.waitRspCmd1(cmd) +func (w *wifinina) reqUint8(cmd uint8, data uint8) uint8 { + w.sendCmdPadded1(cmd, data) + return w.waitRspCmd1(cmd) } // req2Uint8 sends a command to the device with two uint8 parameters -func (d *Device) req2Uint8(cmd CommandType, p1, p2 uint8) (l uint8, err error) { - if err := d.sendCmdPadded2(cmd, p1, p2); err != nil { - return 0, err - } - return d.waitRspCmd1(cmd) +func (w *wifinina) req2Uint8(cmd, p1, p2 uint8) uint8 { + w.sendCmdPadded2(cmd, p1, p2) + return w.waitRspCmd1(cmd) } // reqStr sends a command to the device with a single string parameter -func (d *Device) reqStr(cmd CommandType, p1 string) (uint8, error) { - if err := d.sendCmdStr(cmd, p1); err != nil { - return 0, err - } - return d.waitRspCmd1(cmd) +func (w *wifinina) reqStr(cmd uint8, p1 string) uint8 { + w.sendCmdStr(cmd, p1) + return w.waitRspCmd1(cmd) } -// reqStr sends a command to the device with 2 string parameters -func (d *Device) reqStr2(cmd CommandType, p1 string, p2 string) (uint8, error) { - if err := d.sendCmdStr2(cmd, p1, p2); err != nil { - return 0, err - } - return d.waitRspCmd1(cmd) +// reqStr2 sends a command to the device with 2 string parameters +func (w *wifinina) reqStr2(cmd uint8, p1 string, p2 string) { + w.sendCmdStr2(cmd, p1, p2) + w.waitRspCmd1(cmd) } // reqStrRsp0 sends a command passing a string slice for the response -func (d *Device) reqRspStr0(cmd CommandType, sl []string) (l uint8, err error) { - if err := d.sendCmd0(cmd); err != nil { - return 0, err - } - defer d.spiChipDeselect() - if err = d.waitForChipSelect(); err != nil { - return - } - return d.waitRspStr(cmd, sl) +func (w *wifinina) reqRspStr0(cmd uint8, sl []string) (l uint8) { + w.sendCmd0(cmd) + w.waitForChipReady() + w.spiChipSelect() + l = w.waitRspStr(cmd, sl) + w.spiChipDeselect() + return } // reqStrRsp1 sends a command with a uint8 param and a string slice for the response -func (d *Device) reqRspStr1(cmd CommandType, data uint8, sl []string) (uint8, error) { - if err := d.sendCmdPadded1(cmd, data); err != nil { - return 0, err - } - defer d.spiChipDeselect() - if err := d.waitForChipSelect(); err != nil { - return 0, err - } - return d.waitRspStr(cmd, sl) -} - -func (d *Device) sendCmd0(cmd CommandType) error { - defer d.spiChipDeselect() - if err := d.waitForChipSelect(); err != nil { - return err - } - d.sendCmd(cmd, 0) - return nil +func (w *wifinina) reqRspStr1(cmd uint8, data uint8, sl []string) uint8 { + w.sendCmdPadded1(cmd, data) + w.waitForChipReady() + w.spiChipSelect() + l := w.waitRspStr(cmd, sl) + w.spiChipDeselect() + return l +} + +func (w *wifinina) sendCmd0(cmd uint8) { + w.waitForChipReady() + w.spiChipSelect() + w.sendCmd(cmd, 0) + w.spiChipDeselect() +} + +func (w *wifinina) sendCmdPadded1(cmd uint8, data uint8) { + w.waitForChipReady() + w.spiChipSelect() + w.sendCmd(cmd, 1) + w.sendParam8(data, true) + w.transfer(dummyData) + w.transfer(dummyData) + w.spiChipDeselect() + return } -func (d *Device) sendCmdPadded1(cmd CommandType, data uint8) error { - defer d.spiChipDeselect() - if err := d.waitForChipSelect(); err != nil { - return err - } - d.sendCmd(cmd, 1) - d.sendParam8(data, true) - d.SPI.Transfer(dummyData) - d.SPI.Transfer(dummyData) - return nil +func (w *wifinina) sendCmdPadded2(cmd, data1, data2 uint8) { + w.waitForChipReady() + w.spiChipSelect() + w.sendCmd(cmd, 1) + w.sendParam8(data1, false) + w.sendParam8(data2, true) + w.transfer(dummyData) + w.spiChipDeselect() } -func (d *Device) sendCmdPadded2(cmd CommandType, data1, data2 uint8) error { - defer d.spiChipDeselect() - if err := d.waitForChipSelect(); err != nil { - return err - } - l := d.sendCmd(cmd, 1) - l += d.sendParam8(data1, false) - l += d.sendParam8(data2, true) - d.SPI.Transfer(dummyData) - return nil +func (w *wifinina) sendCmdStr(cmd uint8, p1 string) { + w.waitForChipReady() + w.spiChipSelect() + w.sendCmd(cmd, 1) + w.sendParamStr(p1, true) + w.padTo4(5 + len(p1)) + w.spiChipDeselect() } -func (d *Device) sendCmdStr(cmd CommandType, p1 string) (err error) { - defer d.spiChipDeselect() - if err := d.waitForChipSelect(); err != nil { - return err - } - l := d.sendCmd(cmd, 1) - l += d.sendParamStr(p1, true) - d.padTo4(5 + len(p1)) - return nil +func (w *wifinina) sendCmdStr2(cmd uint8, p1 string, p2 string) { + w.waitForChipReady() + w.spiChipSelect() + w.sendCmd(cmd, 2) + w.sendParamStr(p1, false) + w.sendParamStr(p2, true) + w.padTo4(6 + len(p1) + len(p2)) + w.spiChipDeselect() } -func (d *Device) sendCmdStr2(cmd CommandType, p1 string, p2 string) (err error) { - defer d.spiChipDeselect() - if err := d.waitForChipSelect(); err != nil { - return err - } - d.sendCmd(cmd, 2) - d.sendParamStr(p1, false) - d.sendParamStr(p2, true) - d.padTo4(6 + len(p1) + len(p2)) - return nil +func (w *wifinina) waitRspCmd1(cmd uint8) uint8 { + w.waitForChipReady() + w.spiChipSelect() + l := w.waitRspCmd(cmd, 1) + w.spiChipDeselect() + return l } -func (d *Device) waitRspCmd1(cmd CommandType) (l uint8, err error) { - defer d.spiChipDeselect() - if err = d.waitForChipSelect(); err != nil { - return +func (w *wifinina) sendCmd(cmd uint8, numParam uint8) (l int) { + if debugging(debugDetail) { + fmt.Printf(" sendCmd: %02X %02X %02X", + cmdStart, cmd & ^(uint8(flagReply)), numParam) } - return d.waitRspCmd(cmd, 1) -} -func (d *Device) sendCmd(cmd CommandType, numParam uint8) (l int) { - if _debug { - fmt.Printf( - "sendCmd: %s %s(%02X) %02X", - CmdStart, cmd, uint8(cmd) & ^(uint8(FlagReply)), numParam) - } l = 3 - d.SPI.Transfer(byte(CmdStart)) - d.SPI.Transfer(uint8(cmd) & ^(uint8(FlagReply))) - d.SPI.Transfer(numParam) + w.transfer(cmdStart) + w.transfer(cmd & ^(uint8(flagReply))) + w.transfer(numParam) if numParam == 0 { - d.SPI.Transfer(byte(CmdEnd)) + w.transfer(cmdEnd) l += 1 - if _debug { - fmt.Printf(" %s", CmdEnd) + if debugging(debugDetail) { + fmt.Printf(" %02X", cmdEnd) } } - if _debug { + + if debugging(debugDetail) { fmt.Printf(" (%d)\r\n", l) } return } -func (d *Device) sendParamLen16(p uint16) (l int) { - d.SPI.Transfer(uint8(p >> 8)) - d.SPI.Transfer(uint8(p & 0xFF)) - if _debug { - fmt.Printf(" %02X %02X", uint8(p>>8), uint8(p&0xFF)) +func (w *wifinina) sendParamLen16(p uint16) (l int) { + w.transfer(uint8(p >> 8)) + w.transfer(uint8(p & 0xFF)) + if debugging(debugDetail) { + fmt.Printf(" %02X %02X", uint8(p>>8), uint8(p&0xFF)) } return 2 } -func (d *Device) sendParamBuf(p []byte, isLastParam bool) (l int) { - if _debug { - println("sendParamBuf:") +func (w *wifinina) sendParamBuf(p []byte, isLastParam bool) (l int) { + if debugging(debugDetail) { + fmt.Printf(" sendParamBuf:") } - l += d.sendParamLen16(uint16(len(p))) + l += w.sendParamLen16(uint16(len(p))) for _, b := range p { - if _debug { + if debugging(debugDetail) { fmt.Printf(" %02X", b) } - d.SPI.Transfer(b) + w.transfer(b) l += 1 } if isLastParam { - if _debug { - fmt.Printf(" %s", CmdEnd) + if debugging(debugDetail) { + fmt.Printf(" %02X", cmdEnd) } - d.SPI.Transfer(byte(CmdEnd)) + w.transfer(cmdEnd) l += 1 } - if _debug { + if debugging(debugDetail) { fmt.Printf(" (%d) \r\n", l) } return } -func (d *Device) sendParamStr(p string, isLastParam bool) (l int) { +func (w *wifinina) sendParamStr(p string, isLastParam bool) (l int) { + if debugging(debugDetail) { + fmt.Printf(" sendParamStr: p: %s, lastParam: %t\r\n", p, isLastParam) + } l = len(p) - d.SPI.Transfer(uint8(l)) + w.transfer(uint8(l)) if l > 0 { - d.SPI.Tx([]byte(p), nil) + w.spi.Tx([]byte(p), nil) } if isLastParam { - d.SPI.Transfer(byte(CmdEnd)) + w.transfer(cmdEnd) l += 1 } return } -func (d *Device) sendParam8(p uint8, isLastParam bool) (l int) { - if _debug { - println("sendParam8:", p, "lastParam:", isLastParam, "\r") +func (w *wifinina) sendParam8(p uint8, isLastParam bool) (l int) { + if debugging(debugDetail) { + fmt.Printf(" sendParam8: p: %d, lastParam: %t\r\n", p, isLastParam) } l = 2 - d.SPI.Transfer(1) - d.SPI.Transfer(p) + w.transfer(1) + w.transfer(p) if isLastParam { - d.SPI.Transfer(byte(CmdEnd)) + w.transfer(cmdEnd) l += 1 } return } -func (d *Device) sendParam16(p uint16, isLastParam bool) (l int) { +func (w *wifinina) sendParam16(p uint16, isLastParam bool) (l int) { + if debugging(debugDetail) { + fmt.Printf(" sendParam16: p: %d, lastParam: %t\r\n", p, isLastParam) + } l = 3 - d.SPI.Transfer(2) - d.SPI.Transfer(uint8(p >> 8)) - d.SPI.Transfer(uint8(p & 0xFF)) + w.transfer(2) + w.transfer(uint8(p >> 8)) + w.transfer(uint8(p & 0xFF)) if isLastParam { - d.SPI.Transfer(byte(CmdEnd)) + w.transfer(cmdEnd) l += 1 } return } -func (d *Device) sendParam32(p uint32, isLastParam bool) (l int) { +func (w *wifinina) sendParam32(p uint32, isLastParam bool) (l int) { + if debugging(debugDetail) { + fmt.Printf(" sendParam32: p: %d, lastParam: %t\r\n", p, isLastParam) + } l = 5 - d.SPI.Transfer(4) - d.SPI.Transfer(uint8(p >> 24)) - d.SPI.Transfer(uint8(p >> 16)) - d.SPI.Transfer(uint8(p >> 8)) - d.SPI.Transfer(uint8(p & 0xFF)) + w.transfer(4) + w.transfer(uint8(p >> 24)) + w.transfer(uint8(p >> 16)) + w.transfer(uint8(p >> 8)) + w.transfer(uint8(p & 0xFF)) if isLastParam { - d.SPI.Transfer(byte(CmdEnd)) + w.transfer(cmdEnd) l += 1 } return } -func (d *Device) checkStartCmd() (bool, error) { - check, err := d.waitSpiChar(byte(CmdStart)) - if err != nil { - return false, err - } - if !check { - return false, ErrCheckStartCmd - } - return true, nil -} - -func (d *Device) waitForChipSelect() (err error) { - if err = d.waitForChipReady(); err == nil { - err = d.spiChipSelect() +func (w *wifinina) waitForChipReady() { + if debugging(debugDetail) { + fmt.Printf(" waitForChipReady\r\n") } - return -} -func (d *Device) waitForChipReady() error { - if _debug { - println("waitForChipReady()\r") - } - start := time.Now() - for time.Since(start) < 10*time.Second { - if !d.ACK.Get() { - return nil - } + for i := 0; w.ack.Get(); i++ { time.Sleep(1 * time.Millisecond) + if i == 10000 { + w.faultf("hung in waitForChipReady") + return + } } - return ErrTimeoutChipReady } -func (d *Device) spiChipSelect() error { - if _debug { - println("spiChipSelect()\r") +func (w *wifinina) spiChipSelect() { + if debugging(debugDetail) { + fmt.Printf(" spiChipSelect\r\n") } - d.CS.Low() + w.cs.Low() start := time.Now() - for time.Since(start) < 5*time.Millisecond { - if d.ACK.Get() { - return nil + for time.Since(start) < 10*time.Millisecond { + if w.ack.Get() { + return } time.Sleep(100 * time.Microsecond) } - return ErrTimeoutChipSelect + w.faultf("hung in spiChipSelect") } -func (d *Device) spiChipDeselect() { - if _debug { - println("spiChipDeselect\r") +func (w *wifinina) spiChipDeselect() { + if debugging(debugDetail) { + fmt.Printf(" spiChipDeselect\r\n") } - d.CS.High() + w.cs.High() } -func (d *Device) waitSpiChar(wait byte) (bool, error) { - var timeout = 1000 +func (w *wifinina) waitSpiChar(desired byte) { + + if debugging(debugDetail) { + fmt.Printf(" waitSpiChar: desired: %02X\r\n", desired) + } + var read byte - for first := true; first || (timeout > 0 && read != wait); timeout-- { - first = false - d.readParam(&read) - if read == byte(CmdErr) { - return false, ErrCmdErrorReceived + + for i := 0; i < 10; i++ { + w.readParam(&read) + switch read { + case cmdErr: + w.faultf("cmdErr received, waiting for %d", desired) + return + case desired: + return } + time.Sleep(10 * time.Millisecond) } - if _debug && read != wait { - fmt.Printf("read: %02X, wait: %02X\r\n", read, wait) - } - return read == wait, nil + + w.faultf("timeout waiting for SPI char %02X\r\n", desired) } -func (d *Device) waitRspCmd(cmd CommandType, np uint8) (l uint8, err error) { - if _debug { - println("waitRspCmd") +func (w *wifinina) waitRspCmd(cmd uint8, np uint8) (l uint8) { + + if debugging(debugDetail) { + fmt.Printf(" waitRspCmd: cmd: %02X, np: %d\r\n", cmd, np) } - var check bool + var data byte - if check, err = d.checkStartCmd(); !check { - return - } - if check = d.readAndCheckByte(byte(cmd)|FlagReply, &data); !check { + + w.waitSpiChar(cmdStart) + + if !w.readAndCheckByte(cmd|flagReply, &data) { + w.faultf("expected cmd %02X, read %02X", cmd, data) return } - if check = d.readAndCheckByte(np, &data); check { - d.readParam(&l) + + if w.readAndCheckByte(np, &data) { + w.readParam(&l) for i := uint8(0); i < l; i++ { - d.readParam(&d.buf[i]) + w.readParam(&w.buf[i]) + } + if !w.readAndCheckByte(cmdEnd, &data) { + w.faultf("expected cmdEnd, read %02X", data) } } - if !d.readAndCheckByte(byte(CmdEnd), &data) { - err = ErrIncorrectSentinel - } + return } -func (d *Device) waitRspBuf16(cmd CommandType, buf []byte) (l uint16, err error) { - if _debug { - println("waitRspBuf16") +func (w *wifinina) waitRspBuf16(cmd uint8, buf []byte) (l uint16) { + + if debugging(debugDetail) { + fmt.Printf(" waitRspBuf16: cmd: %02X, len(buf): %d\r\n", cmd, len(buf)) } - var check bool + var data byte - if check, err = d.checkStartCmd(); !check { - return - } - if check = d.readAndCheckByte(byte(cmd)|FlagReply, &data); !check { + + w.waitSpiChar(cmdStart) + + if !w.readAndCheckByte(cmd|flagReply, &data) { + w.faultf("expected cmd %02X, read %02X", cmd, data) return } - if check = d.readAndCheckByte(1, &data); check { - l, _ = d.readParamLen16() + + if w.readAndCheckByte(1, &data) { + l = w.readParamLen16() for i := uint16(0); i < l; i++ { - d.readParam(&buf[i]) + w.readParam(&buf[i]) + } + if !w.readAndCheckByte(cmdEnd, &data) { + w.faultf("expected cmdEnd, read %02X", data) } } - if !d.readAndCheckByte(byte(CmdEnd), &data) { - err = ErrIncorrectSentinel - } + return } -func (d *Device) waitRspStr(cmd CommandType, sl []string) (numRead uint8, err error) { - if _debug { - println("waitRspStr") +func (w *wifinina) waitRspStr(cmd uint8, sl []string) (numRead uint8) { + + if debugging(debugDetail) { + fmt.Printf(" waitRspStr: cmd: %02X, len(sl): %d\r\n", cmd, len(sl)) } - var check bool + var data byte - if check, err = d.checkStartCmd(); !check { - return - } - if check = d.readAndCheckByte(byte(cmd)|FlagReply, &data); !check { + + w.waitSpiChar(cmdStart) + + if !w.readAndCheckByte(cmd|flagReply, &data) { + w.faultf("expected cmd %02X, read %02X", cmd, data) return } - numRead, _ = d.SPI.Transfer(dummyData) + + numRead = w.transfer(dummyData) if numRead == 0 { - return 0, ErrNoParamsReturned + w.faultf("waitRspStr numRead == 0") + return } + maxNumRead := uint8(len(sl)) for j, l := uint8(0), uint8(0); j < numRead; j++ { - d.readParam(&l) + w.readParam(&l) for i := uint8(0); i < l; i++ { - d.readParam(&d.buf[i]) + w.readParam(&w.buf[i]) } if j < maxNumRead { - sl[j] = string(d.buf[0:l]) - if _debug { - fmt.Printf("str %d (%d) - %08X\r\n", j, l, []byte(sl[j])) + sl[j] = string(w.buf[0:l]) + if debugging(debugDetail) { + fmt.Printf(" str: %d (%d) - %08X\r\n", j, l, []byte(sl[j])) } } } + for j := numRead; j < maxNumRead; j++ { - if _debug { - println("str", j, "\"\"\r") + if debugging(debugDetail) { + fmt.Printf(" str: ", j, "\"\"\r") } sl[j] = "" } - if !d.readAndCheckByte(byte(CmdEnd), &data) { - err = ErrIncorrectSentinel + + if !w.readAndCheckByte(cmdEnd, &data) { + w.faultf("expected cmdEnd, read %02X", data) + return } + if numRead > maxNumRead { numRead = maxNumRead } return } -func (d *Device) readAndCheckByte(check byte, read *byte) bool { - d.readParam(read) - return (*read == check) +func (w *wifinina) readAndCheckByte(check byte, read *byte) bool { + w.readParam(read) + return *read == check } // readParamLen16 reads 2 bytes from the SPI bus (MSB first), returning uint16 -func (d *Device) readParamLen16() (v uint16, err error) { - if b, err := d.SPI.Transfer(0xFF); err == nil { - v |= uint16(b) << 8 - if b, err = d.SPI.Transfer(0xFF); err == nil { - v |= uint16(b) - } - } +func (w *wifinina) readParamLen16() (v uint16) { + b := w.transfer(0xFF) + v = uint16(b) << 8 + b = w.transfer(0xFF) + v |= uint16(b) return } -func (d *Device) readParam(b *byte) (err error) { - *b, err = d.SPI.Transfer(0xFF) - return +func (w *wifinina) readParam(b *byte) { + *b = w.transfer(0xFF) } -func (d *Device) addPadding(l int) { - if _debug { - println("addPadding", l, "\r") +func (w *wifinina) addPadding(l int) { + if debugging(debugDetail) { + fmt.Printf(" addPadding: l: %d\r\n", l) } for i := (4 - (l % 4)) & 3; i > 0; i-- { - if _debug { - println("padding\r") + if debugging(debugDetail) { + fmt.Printf(" padding\r\n") } - d.SPI.Transfer(dummyData) + w.transfer(dummyData) } } -func (d *Device) padTo4(l int) { - if _debug { - println("padTo4", l, "\r") +func (w *wifinina) padTo4(l int) { + if debugging(debugDetail) { + fmt.Printf(" padTo4: l: %d\r\n", l) } for l%4 != 0 { - d.SPI.Transfer(dummyData) + if debugging(debugDetail) { + fmt.Printf(" padding\r\n") + } + w.transfer(dummyData) l++ } }