Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions args.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// This file is part of mdns-discovery.
//
// Copyright 2021 ARDUINO SA (http://www.arduino.cc/)
//
// This software is released under the GNU General Public License version 3,
// which covers the main part of arduino-cli.
// The terms of this license can be found at:
// https://www.gnu.org/licenses/gpl-3.0.en.html
//
// You can be released from the requirements of the above licenses by purchasing
// a commercial license. Buying such a license is mandatory if you want to modify or
// otherwise use the software for commercial activities involving the Arduino
// software without disclosing the source code of your own applications. To purchase
// a commercial license, send an email to license@arduino.cc.
//

package main

import (
"fmt"
"os"

"github.com/arduino/mdns-discovery/version"
)

func parseArgs() {
for _, arg := range os.Args[1:] {
if arg == "" {
continue
}
if arg == "-v" || arg == "--version" {
fmt.Printf("mdns-discovery %s (build timestamp: %s)\n", version.Tag, version.Timestamp)
os.Exit(0)
}
fmt.Fprintf(os.Stderr, "invalid argument: %s\n", arg)
os.Exit(1)
}
}
14 changes: 14 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module github.com/arduino/mdns-discovery

go 1.16

require (
github.com/arduino/go-paths-helper v1.6.1 // indirect
github.com/arduino/go-properties-orderedmap v1.5.0
github.com/arduino/pluggable-discovery-protocol-handler v1.1.0
github.com/brutella/dnssd v1.1.1
github.com/miekg/dns v1.1.31 // indirect
golang.org/x/crypto v0.0.0-20201002094018-c90954cbb977 // indirect
golang.org/x/net v0.0.0-20200930145003-4acb6c075d10 // indirect
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f // indirect
)
48 changes: 48 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
github.com/arduino/go-paths-helper v1.0.1/go.mod h1:HpxtKph+g238EJHq4geEPv9p+gl3v5YYu35Yb+w31Ck=
github.com/arduino/go-paths-helper v1.6.1 h1:lha+/BuuBsx0qTZ3gy6IO1kU23lObWdQ/UItkzVWQ+0=
github.com/arduino/go-paths-helper v1.6.1/go.mod h1:V82BWgAAp4IbmlybxQdk9Bpkz8M4Qyx+RAFKaG9NuvU=
github.com/arduino/go-properties-orderedmap v1.4.0/go.mod h1:DKjD2VXY/NZmlingh4lSFMEYCVubfeArCsGPGDwb2yk=
github.com/arduino/go-properties-orderedmap v1.5.0 h1:istmr13qQN3nneuU3lsqlMvI6jqB3u8QUfVU1tX/t/8=
github.com/arduino/go-properties-orderedmap v1.5.0/go.mod h1:DKjD2VXY/NZmlingh4lSFMEYCVubfeArCsGPGDwb2yk=
github.com/arduino/pluggable-discovery-protocol-handler v1.1.0 h1:/fYOQ9f6beV9+mv9rDs+kvkhNKJ1edIT0RvIRj5Jj4U=
github.com/arduino/pluggable-discovery-protocol-handler v1.1.0/go.mod h1:vQfYGJnunfcscLoUcZKqJBlEkZ/qiE28TQj+RV9UT74=
github.com/brutella/dnssd v1.1.1 h1:Ar5ytE2Z9x5DTmuNnASlMTBpcQWQLm9ceHb326s0ykg=
github.com/brutella/dnssd v1.1.1/go.mod h1:9gIcMKQSJvYlO2x+HR50cqqjghb9IWK9hvykmyveVVs=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/miekg/dns v1.1.1/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.31 h1:sJFOl9BgwbYAWOGEwr61FU28pqsBNdpRBnhGXtO06Oo=
github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002094018-c90954cbb977 h1:yH6opeNE+0SY+7pXT4gclZUoKHogXeC2EvOSHGOMGPU=
golang.org/x/crypto v0.0.0-20201002094018-c90954cbb977/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200930145003-4acb6c075d10 h1:YfxMZzv3PjGonQYNUaeU2+DhAdqOxerQ30JFB6WgAXo=
golang.org/x/net v0.0.0-20200930145003-4acb6c075d10/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20181206074257-70b957f3b65e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
191 changes: 70 additions & 121 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// This file is part of serial-discovery.
// This file is part of mdns-discovery.
//
// Copyright 2018 ARDUINO SA (http://www.arduino.cc/)
// Copyright 2018-2021 ARDUINO SA (http://www.arduino.cc/)
//
// This software is released under the GNU General Public License version 3,
// which covers the main part of arduino-cli.
Expand All @@ -18,153 +18,102 @@
package main

import (
"bufio"
"encoding/json"
"context"
"fmt"
"os"
"strconv"
"strings"
"sync"

properties "github.com/arduino/go-properties-orderedmap"
discovery "github.com/arduino/pluggable-discovery-protocol-handler"
"github.com/brutella/dnssd"
)

func main() {
syncStarted := false
var syncCloseChan chan<- bool

reader := bufio.NewReader(os.Stdin)
for {
cmd, err := reader.ReadString('\n')
if err != nil {
outputError(err)
os.Exit(1)
}
cmd = strings.ToUpper(strings.TrimSpace(cmd))
switch cmd {
case "START":
outputMessage("start", "OK")
case "STOP":
if syncStarted {
syncCloseChan <- true
syncStarted = false
}
outputMessage("stop", "OK")
case "LIST":
outputList()
case "QUIT":
outputMessage("quit", "OK")
os.Exit(0)
case "START_SYNC":
if syncStarted {
outputMessage("startSync", "OK")
} else if close, err := startSync(); err != nil {
outputError(err)
} else {
syncCloseChan = close
syncStarted = true
}
default:
outputError(fmt.Errorf("Command %s not supported", cmd))
}
parseArgs()
mdnsDiscovery := &MDNSDiscovery{}
disc := discovery.NewDiscoveryServer(mdnsDiscovery)
if err := disc.Run(os.Stdin, os.Stdout); err != nil {
fmt.Fprintf(os.Stderr, "Error: %s\n", err.Error())
os.Exit(1)
}

}

type boardPortJSON struct {
Address string `json:"address"`
Label string `json:"label,omitempty"`
Prefs *properties.Map `json:"prefs,omitempty"`
IdentificationPrefs *properties.Map `json:"identificationPrefs,omitempty"`
Protocol string `json:"protocol,omitempty"`
ProtocolLabel string `json:"protocolLabel,omitempty"`
const mdnsServiceName = "_arduino._tcp.local."

type MDNSDiscovery struct {
cancelFunc func()
}

type listOutputJSON struct {
EventType string `json:"eventType"`
Ports []*boardPortJSON `json:"ports"`
// Hello handles the pluggable-discovery HELLO command
func (d *MDNSDiscovery) Hello(userAgent string, protocolVersion int) error {
return nil
}

func outputList() {
/*
list, err := enumerator.GetDetailedPortsList()
if err != nil {
outputError(err)
return
}
portsJSON := []*boardPortJSON{}
for _, port := range list {
portJSON := newBoardPortJSON(port)
portsJSON = append(portsJSON, portJSON)
}
d, err := json.MarshalIndent(&listOutputJSON{
EventType: "list",
Ports: portsJSON,
}, "", " ")
if err != nil {
outputError(err)
return
}
syncronizedPrintLn(string(d))
*/
// Start handles the pluggable-discovery START command
func (d *MDNSDiscovery) Start() error {
return nil
}

func newBoardPortJSON(port *dnssd.Service) *boardPortJSON {
prefs := properties.NewMap()
identificationPrefs := properties.NewMap()
// Stop handles the pluggable-discovery STOP command
func (d *MDNSDiscovery) Stop() error {
if d.cancelFunc != nil {
d.cancelFunc()
d.cancelFunc = nil
}
return nil
}

ip := "127.0.0.1"
// Quit handles the pluggable-discovery QUIT command
func (d *MDNSDiscovery) Quit() {
}

// List handles the pluggable-discovery LIST command
func (d *MDNSDiscovery) List() ([]*discovery.Port, error) {
return []*discovery.Port{}, nil
}

// StartSync handles the pluggable-discovery START_SYNC command
func (d *MDNSDiscovery) StartSync(eventCB discovery.EventCallback, errorCB discovery.ErrorCallback) error {
addFn := func(srv dnssd.Service) {
eventCB("add", newBoardPortJSON(&srv))
}
remFn := func(srv dnssd.Service) {
eventCB("remove", newBoardPortJSON(&srv))
}
ctx, cancel := context.WithCancel(context.Background())

go func() {
if err := dnssd.LookupType(ctx, mdnsServiceName, addFn, remFn); err != nil {
errorCB("mdns lookup error: " + err.Error())
}
}()
d.cancelFunc = cancel
return nil
}

func newBoardPortJSON(port *dnssd.Service) *discovery.Port {
ip := "127.0.0.1"
if len(port.IPs) > 0 {
ip = port.IPs[0].String()
}

portJSON := &boardPortJSON{
Address: ip,
Label: port.Name + " at " + ip,
Protocol: "network",
ProtocolLabel: "Network Port",
Prefs: prefs,
IdentificationPrefs: identificationPrefs,
}
portJSON.Prefs.Set("ttl", port.Ttl.String())
portJSON.Prefs.Set("hostname", port.Hostname())
portJSON.Prefs.Set("port", strconv.Itoa(port.Port))
props := properties.NewMap()
props.Set("ttl", strconv.Itoa(int(port.TTL.Seconds())))
props.Set("hostname", port.Hostname())
props.Set("port", strconv.Itoa(port.Port))
for key, value := range port.Text {
portJSON.Prefs.Set(key, value)
props.Set(key, value)
if key == "board" {
// duplicate for backwards compatibility
identificationPrefs.Set(".", value)
props.Set(".", value)
}
}
return portJSON
}

type messageOutputJSON struct {
EventType string `json:"eventType"`
Message string `json:"message"`
}

func outputMessage(eventType, message string) {
d, err := json.MarshalIndent(&messageOutputJSON{
EventType: eventType,
Message: message,
}, "", " ")
if err != nil {
outputError(err)
} else {
syncronizedPrintLn(string(d))
return &discovery.Port{
Address: ip,
AddressLabel: port.Name + " at " + ip,
Protocol: "network",
ProtocolLabel: "Network Port",
Properties: props,
}
}

func outputError(err error) {
outputMessage("error", err.Error())
}

var stdoutMutext sync.Mutex

func syncronizedPrintLn(a ...interface{}) {
stdoutMutext.Lock()
fmt.Println(a...)
stdoutMutext.Unlock()
}
Loading