diff --git a/.licenses/arduino-create-agent/go/go.bug.st/serial.dep.yml b/.licenses/arduino-create-agent/go/go.bug.st/serial.dep.yml index a3ba42c32..c55d351d0 100644 --- a/.licenses/arduino-create-agent/go/go.bug.st/serial.dep.yml +++ b/.licenses/arduino-create-agent/go/go.bug.st/serial.dep.yml @@ -1,6 +1,6 @@ --- name: go.bug.st/serial -version: v1.4.1 +version: v1.6.1 type: go summary: Package serial is a cross-platform serial library for the go language. homepage: https://pkg.go.dev/go.bug.st/serial @@ -9,7 +9,7 @@ licenses: - sources: LICENSE text: |2+ - Copyright (c) 2014-2021, Cristian Maglie. + Copyright (c) 2014-2023, Cristian Maglie. All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/.licenses/arduino-create-agent/go/go.bug.st/serial/enumerator.dep.yml b/.licenses/arduino-create-agent/go/go.bug.st/serial/enumerator.dep.yml index 0078a4a60..7743f09d9 100644 --- a/.licenses/arduino-create-agent/go/go.bug.st/serial/enumerator.dep.yml +++ b/.licenses/arduino-create-agent/go/go.bug.st/serial/enumerator.dep.yml @@ -1,16 +1,16 @@ --- name: go.bug.st/serial/enumerator -version: v1.4.1 +version: v1.6.1 type: go summary: Package enumerator is a golang cross-platform library for USB serial port discovery. homepage: https://pkg.go.dev/go.bug.st/serial/enumerator license: bsd-3-clause licenses: -- sources: serial@v1.4.1/LICENSE +- sources: serial@v1.6.1/LICENSE text: |2+ - Copyright (c) 2014-2021, Cristian Maglie. + Copyright (c) 2014-2023, Cristian Maglie. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -42,7 +42,7 @@ licenses: ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- sources: serial@v1.4.1/README.md +- sources: serial@v1.6.1/README.md text: |- The software is release under a [BSD 3-clause license] diff --git a/.licenses/arduino-create-agent/go/go.bug.st/serial/unixutils.dep.yml b/.licenses/arduino-create-agent/go/go.bug.st/serial/unixutils.dep.yml index ad23c8bc3..b744d2524 100644 --- a/.licenses/arduino-create-agent/go/go.bug.st/serial/unixutils.dep.yml +++ b/.licenses/arduino-create-agent/go/go.bug.st/serial/unixutils.dep.yml @@ -1,15 +1,15 @@ --- name: go.bug.st/serial/unixutils -version: v1.4.1 +version: v1.6.1 type: go summary: homepage: https://pkg.go.dev/go.bug.st/serial/unixutils license: bsd-3-clause licenses: -- sources: serial@v1.4.1/LICENSE +- sources: serial@v1.6.1/LICENSE text: |2+ - Copyright (c) 2014-2021, Cristian Maglie. + Copyright (c) 2014-2023, Cristian Maglie. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -41,7 +41,7 @@ licenses: ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- sources: serial@v1.4.1/README.md +- sources: serial@v1.6.1/README.md text: |- The software is release under a [BSD 3-clause license] diff --git a/discovery.go b/discovery.go index 48d9ed83f..1856ea9b5 100644 --- a/discovery.go +++ b/discovery.go @@ -42,10 +42,10 @@ const timeoutConst = 2 // SavedNetworkPorts contains the ports which we know are already connected var SavedNetworkPorts []OsSerialPort -// GetNetworkList returns a list of Network Ports +// enumerateNetworkPorts returns a list of Network Ports // The research of network ports is articulated in two phases. First we add new ports coming from // the bonjour module, then we prune the boards who don't respond to a ping -func GetNetworkList() ([]OsSerialPort, error) { +func enumerateNetworkPorts() ([]OsSerialPort, error) { newPorts, err := getPorts() if err != nil { return nil, err diff --git a/go.mod b/go.mod index 5fbf2a7a2..a60f5bb12 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/stretchr/testify v1.8.4 github.com/xrash/smetrics v0.0.0-20170218160415-a3153f7040e9 go.bug.st/downloader/v2 v2.1.1 - go.bug.st/serial v1.4.1 + go.bug.st/serial v1.6.1 goa.design/goa/v3 v3.12.4 golang.org/x/crypto v0.12.0 golang.org/x/sys v0.11.0 diff --git a/go.sum b/go.sum index 3e93edd5f..fa2f7ee27 100644 --- a/go.sum +++ b/go.sum @@ -165,8 +165,8 @@ github.com/xrash/smetrics v0.0.0-20170218160415-a3153f7040e9 h1:w8V9v0qVympSF6Gj github.com/xrash/smetrics v0.0.0-20170218160415-a3153f7040e9/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= go.bug.st/downloader/v2 v2.1.1 h1:nyqbUizo3E2IxCCm4YFac4FtSqqFpqWP+Aae5GCMuw4= go.bug.st/downloader/v2 v2.1.1/go.mod h1:VZW2V1iGKV8rJL2ZEGIDzzBeKowYv34AedJz13RzVII= -go.bug.st/serial v1.4.1 h1:AwYUNixVf90XymNeJaUkMrPp+GZQe3RMFQmpVdHIUK8= -go.bug.st/serial v1.4.1/go.mod h1:z8CesKorE90Qr/oRSJiEuvzYRKol9r/anJZEb5kt304= +go.bug.st/serial v1.6.1 h1:VSSWmUxlj1T/YlRo2J104Zv3wJFrjHIl/T3NeruWAHY= +go.bug.st/serial v1.6.1/go.mod h1:UABfsluHAiaNI+La2iESysd9Vetq7VRdpxvjx7CmmOE= goa.design/goa/v3 v3.12.4 h1:g3G8yHLk+jyUDNRL2sNg+ZcoQ62zY83rpgagAQ5VmTA= goa.design/goa/v3 v3.12.4/go.mod h1:h1vjyGQ+rqWK+VvnqN8oLcpqaHrKIyuY1Vx+jhKodpg= golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU= diff --git a/main.go b/main.go index 9f021af27..0d564d920 100755 --- a/main.go +++ b/main.go @@ -22,6 +22,7 @@ import ( _ "embed" "encoding/json" "flag" + "io" "os" "os/exec" "runtime" @@ -99,10 +100,6 @@ var ( Systray systray.Systray ) -type nullWriter int - -func (nullWriter) Write([]byte) (int, error) { return 0, nil } - type logWriter struct{} func (u *logWriter) Write(p []byte) (n int, err error) { @@ -310,7 +307,7 @@ func loop() { } // list serial ports - portList, _ := GetList(false) + portList, _ := enumerateSerialPorts() log.Println("Your serial ports:") if len(portList) == 0 { log.Println("\tThere are no serial ports to list.") @@ -322,7 +319,7 @@ func loop() { if !*verbose { log.Println("You can enter verbose mode to see all logging by starting with the -v command line switch.") - log.SetOutput(new(nullWriter)) //route all logging to nullwriter + log.SetOutput(io.Discard) } // save crashreport to file diff --git a/serial.go b/serial.go index 77c9c69f6..e1270c7c6 100755 --- a/serial.go +++ b/serial.go @@ -71,11 +71,11 @@ type SpPortItem struct { ProductID string } -// SerialPorts contains the ports attached to the machine -var SerialPorts SpPortList +// serialPorts contains the ports attached to the machine +var serialPorts SpPortList -// NetworkPorts contains the ports on the network -var NetworkPorts SpPortList +// networkPorts contains the ports on the network +var networkPorts SpPortList var sh = serialhub{ //write: make(chan *serport, chan []byte), @@ -130,13 +130,13 @@ func spList(network bool) { var ls []byte var err error if network { - NetworkPorts.Mu.Lock() - ls, err = json.MarshalIndent(&NetworkPorts, "", "\t") - NetworkPorts.Mu.Unlock() + networkPorts.Mu.Lock() + ls, err = json.MarshalIndent(&networkPorts, "", "\t") + networkPorts.Mu.Unlock() } else { - SerialPorts.Mu.Lock() - ls, err = json.MarshalIndent(&SerialPorts, "", "\t") - SerialPorts.Mu.Unlock() + serialPorts.Mu.Lock() + ls, err = json.MarshalIndent(&serialPorts, "", "\t") + serialPorts.Mu.Unlock() } if err != nil { //log.Println(err) @@ -149,81 +149,73 @@ func spList(network bool) { // discoverLoop periodically update the list of ports found func discoverLoop() { - SerialPorts.Mu.Lock() - SerialPorts.Network = false - SerialPorts.Ports = make([]SpPortItem, 0) - SerialPorts.Mu.Unlock() - NetworkPorts.Mu.Lock() - NetworkPorts.Network = true - NetworkPorts.Ports = make([]SpPortItem, 0) - NetworkPorts.Mu.Unlock() + serialPorts.Mu.Lock() + serialPorts.Network = false + serialPorts.Ports = make([]SpPortItem, 0) + serialPorts.Mu.Unlock() + networkPorts.Mu.Lock() + networkPorts.Network = true + networkPorts.Ports = make([]SpPortItem, 0) + networkPorts.Mu.Unlock() go func() { for { if !upload.Busy { - spListDual(false) + updateSerialPortList() } time.Sleep(2 * time.Second) } }() go func() { for { - spListDual(true) + updateNetworkPortList() time.Sleep(2 * time.Second) } }() } -func spListDual(network bool) { +var serialEnumeratorLock sync.Mutex - // call our os specific implementation of getting the serial list - list, err := GetList(network) +func updateSerialPortList() { + if !serialEnumeratorLock.TryLock() { + return + } + defer serialEnumeratorLock.Unlock() + ports, err := enumerateSerialPorts() + if err != nil { + // TODO: report error? - //log.Println(list) - //log.Println(err) + // Empty port list if they can not be detected + ports = []OsSerialPort{} + } + list := spListDual(ports) + serialPorts.Mu.Lock() + serialPorts.Ports = list + serialPorts.Mu.Unlock() +} +func updateNetworkPortList() { + ports, err := enumerateNetworkPorts() if err != nil { - // avoid reporting dummy data if an error occurred - return - } + // TODO: report error? - // do a quick loop to see if any of our open ports - // did not end up in the list port list. this can - // happen on windows in a fallback scenario where an - // open port can't be identified because it is locked, - // so just solve that by manually inserting - // if network { - // for port := range sh.ports { - - // isFound := false - // for _, item := range list { - // if strings.ToLower(port.portConf.Name) == strings.ToLower(item.Name) { - // isFound = true - // } - // } - - // if !isFound { - // // artificially push to front of port list - // log.Println(fmt.Sprintf("Did not find an open port in the serial port list. We are going to artificially push it onto the list. port:%v", port.portConf.Name)) - // var ossp OsSerialPort - // ossp.Name = port.portConf.Name - // ossp.FriendlyName = port.portConf.Name - // list = append([]OsSerialPort{ossp}, list...) - // } - // } - // } + // Empty port list if they can not be detected + ports = []OsSerialPort{} + } + list := spListDual(ports) + networkPorts.Mu.Lock() + networkPorts.Ports = list + networkPorts.Mu.Unlock() +} +func spListDual(list []OsSerialPort) []SpPortItem { // we have a full clean list of ports now. iterate thru them // to append the open/close state, baud rates, etc to make // a super clean nice list to send back to browser - n := len(list) - spl := make([]SpPortItem, n) - - ctr := 0 + spl := []SpPortItem{} for _, item := range list { - - spl[ctr] = SpPortItem{ + port := SpPortItem{ Name: item.Name, SerialNumber: item.ISerial, DeviceClass: item.DeviceClass, @@ -238,26 +230,15 @@ func spListDual(network bool) { } // figure out if port is open - myport, isFound := findPortByName(item.Name) - - if isFound { - // we found our port - spl[ctr].IsOpen = true - spl[ctr].Baud = myport.portConf.Baud - spl[ctr].BufferAlgorithm = myport.BufferType + if myport, isFound := findPortByName(item.Name); isFound { + // and update data with the open port parameters + port.IsOpen = true + port.Baud = myport.portConf.Baud + port.BufferAlgorithm = myport.BufferType } - ctr++ - } - - if network { - NetworkPorts.Mu.Lock() - NetworkPorts.Ports = spl - NetworkPorts.Mu.Unlock() - } else { - SerialPorts.Mu.Lock() - SerialPorts.Ports = spl - SerialPorts.Mu.Unlock() + spl = append(spl, port) } + return spl } func spErr(err string) { diff --git a/seriallist.go b/seriallist.go index d24c5554b..8e86ec08f 100755 --- a/seriallist.go +++ b/seriallist.go @@ -38,14 +38,8 @@ type OsSerialPort struct { NetworkPort bool } -// GetList will return the OS serial port -func GetList(network bool) ([]OsSerialPort, error) { - - if network { - netportList, err := GetNetworkList() - return netportList, err - } - +// enumerateSerialPorts will return the OS serial port +func enumerateSerialPorts() ([]OsSerialPort, error) { // will timeout in 2 seconds arrPorts := []OsSerialPort{} ports, err := enumerator.GetDetailedPortsList() diff --git a/serialport.go b/serialport.go index b965782b8..41e2c1819 100755 --- a/serialport.go +++ b/serialport.go @@ -232,7 +232,7 @@ func (p *serport) writerNoBuf() { log.Println(msgstr) h.broadcastSys <- []byte(msgstr) p.portIo.Close() - spListDual(false) + updateSerialPortList() spList(false) } @@ -300,7 +300,13 @@ func spHandlerOpen(portname string, baud int, buftype string) { log.Print("Opened port successfully") //p := &serport{send: make(chan []byte, 256), portConf: conf, portIo: sp} // we can go up to 256,000 lines of gcode in the buffer - p := &serport{sendBuffered: make(chan string, 256000), sendNoBuf: make(chan []byte), sendRaw: make(chan string), portConf: conf, portIo: sp, BufferType: buftype} + p := &serport{ + sendBuffered: make(chan string, 256000), + sendNoBuf: make(chan []byte), + sendRaw: make(chan string), + portConf: conf, + portIo: sp, + BufferType: buftype} var bw Bufferflow @@ -321,7 +327,7 @@ func spHandlerOpen(portname string, baud int, buftype string) { sh.register <- p defer func() { sh.unregister <- p }() - spListDual(false) + updateSerialPortList() spList(false) // this is internally buffered thread to not send to serial port if blocked @@ -333,7 +339,7 @@ func spHandlerOpen(portname string, baud int, buftype string) { p.reader(buftype) - spListDual(false) + updateSerialPortList() spList(false) } @@ -346,6 +352,6 @@ func spHandlerClose(p *serport) { func spCloseReal(p *serport) { p.bufferwatcher.Close() p.portIo.Close() - spListDual(false) + updateSerialPortList() spList(false) }