diff --git a/cmd/tendrils/main.go b/cmd/tendrils/main.go index d3183ab..4906271 100644 --- a/cmd/tendrils/main.go +++ b/cmd/tendrils/main.go @@ -17,6 +17,7 @@ func main() { noDante := flag.Bool("no-dante", false, "disable Dante discovery") noBMD := flag.Bool("no-bmd", false, "disable Blackmagic discovery") noShure := flag.Bool("no-shure", false, "disable Shure discovery") + noYamaha := flag.Bool("no-yamaha", false, "disable Yamaha discovery") logEvents := flag.Bool("log-events", false, "log node events") logNodes := flag.Bool("log-nodes", false, "log full node details on changes") debugARP := flag.Bool("debug-arp", false, "debug ARP discovery") @@ -28,6 +29,7 @@ func main() { debugDante := flag.Bool("debug-dante", false, "debug Dante discovery") debugBMD := flag.Bool("debug-bmd", false, "debug Blackmagic discovery") debugShure := flag.Bool("debug-shure", false, "debug Shure discovery") + debugYamaha := flag.Bool("debug-yamaha", false, "debug Yamaha discovery") flag.Parse() t := tendrils.New() @@ -41,6 +43,7 @@ func main() { t.DisableDante = *noDante t.DisableBMD = *noBMD t.DisableShure = *noShure + t.DisableYamaha = *noYamaha t.LogEvents = *logEvents t.LogNodes = *logNodes t.DebugARP = *debugARP @@ -52,5 +55,6 @@ func main() { t.DebugDante = *debugDante t.DebugBMD = *debugBMD t.DebugShure = *debugShure + t.DebugYamaha = *debugYamaha t.Run() } diff --git a/snmp.go b/snmp.go index 0d52af8..bec0ee3 100644 --- a/snmp.go +++ b/snmp.go @@ -79,38 +79,6 @@ func (t *Tendrils) connectSNMP(ip net.IP) (*gosnmp.GoSNMP, error) { return snmp, nil } -func (t *Tendrils) pollNode(node *Node) { - t.nodes.mu.RLock() - var ips []net.IP - for _, iface := range node.Interfaces { - for _, ip := range iface.IPs { - if ip.To4() != nil { - ips = append(ips, ip) - } - } - } - nodeName := node.DisplayName() - t.nodes.mu.RUnlock() - - if !t.DisableSNMP { - for _, ip := range ips { - t.querySNMPDevice(node, ip) - } - } - - if !t.DisableBMD && nodeName == "" { - for _, ip := range ips { - t.probeBMDDevice(ip) - } - } - - if !t.DisableDante { - for _, ip := range ips { - t.probeDanteDevice(ip) - } - } -} - func (t *Tendrils) querySNMPDevice(node *Node, ip net.IP) { snmp, err := t.connectSNMP(ip) if err != nil { diff --git a/tendrils.go b/tendrils.go index b4a1ec4..a776166 100644 --- a/tendrils.go +++ b/tendrils.go @@ -26,6 +26,7 @@ type Tendrils struct { DisableDante bool DisableBMD bool DisableShure bool + DisableYamaha bool LogEvents bool LogNodes bool DebugARP bool @@ -37,6 +38,7 @@ type Tendrils struct { DebugDante bool DebugBMD bool DebugShure bool + DebugYamaha bool } func New() *Tendrils { @@ -213,3 +215,41 @@ func (t *Tendrils) startInterface(ctx context.Context, iface net.Interface) { go t.listenShure(ctx, iface) } } + +func (t *Tendrils) pollNode(node *Node) { + t.nodes.mu.RLock() + var ips []net.IP + for _, iface := range node.Interfaces { + for _, ip := range iface.IPs { + if ip.To4() != nil { + ips = append(ips, ip) + } + } + } + nodeName := node.DisplayName() + t.nodes.mu.RUnlock() + + if !t.DisableSNMP { + for _, ip := range ips { + t.querySNMPDevice(node, ip) + } + } + + if !t.DisableBMD && nodeName == "" { + for _, ip := range ips { + t.probeBMDDevice(ip) + } + } + + if !t.DisableYamaha && nodeName == "" { + for _, ip := range ips { + t.probeYamahaDevice(ip) + } + } + + if !t.DisableDante { + for _, ip := range ips { + t.probeDanteDevice(ip) + } + } +} diff --git a/yamaha.go b/yamaha.go new file mode 100644 index 0000000..ff24737 --- /dev/null +++ b/yamaha.go @@ -0,0 +1,36 @@ +package tendrils + +import ( + "bufio" + "log" + "net" + "regexp" + "time" +) + +var yamahaModelRegex = regexp.MustCompile(`PA-Platform:ModelId\s*=\s*0x[0-9a-fA-F]+\(([^)]+)\)`) + +func (t *Tendrils) probeYamahaDevice(ip net.IP) string { + conn, err := net.DialTimeout("tcp", net.JoinHostPort(ip.String(), "50000"), 2*time.Second) + if err != nil { + return "" + } + defer conn.Close() + + conn.SetReadDeadline(time.Now().Add(2 * time.Second)) + + scanner := bufio.NewScanner(conn) + for scanner.Scan() { + line := scanner.Text() + if match := yamahaModelRegex.FindStringSubmatch(line); match != nil { + model := match[1] + if t.DebugYamaha { + log.Printf("[yamaha] %s: found model %s", ip, model) + } + t.nodes.Update(nil, nil, []net.IP{ip}, "", model, "yamaha") + return model + } + } + + return "" +}