diff --git a/bmd.go b/bmd.go index 83c5b1b..4ce0049 100644 --- a/bmd.go +++ b/bmd.go @@ -10,6 +10,10 @@ import ( ) func (t *Tendrils) listenBMD(ctx context.Context, iface net.Interface) { + go t.discoverATEMs(ctx, iface) +} + +func (t *Tendrils) discoverATEMs(ctx context.Context, iface net.Interface) { addrs, err := iface.Addrs() if err != nil { return @@ -197,3 +201,70 @@ func (t *Tendrils) parseATEMCommands(data []byte, sess *atemSession) { offset += cmdLen } } + +func (t *Tendrils) probeBMDDevice(ip net.IP) { + if name := t.probeHyperDeck(ip); name != "" { + t.nodes.Update(nil, nil, []net.IP{ip}, "", name, "bmd") + return + } + if name := t.probeVideoHub(ip); name != "" { + t.nodes.Update(nil, nil, []net.IP{ip}, "", name, "bmd") + return + } +} + +func (t *Tendrils) probeHyperDeck(ip net.IP) string { + conn, err := net.DialTimeout("tcp", ip.String()+":9993", 500*time.Millisecond) + if err != nil { + return "" + } + defer conn.Close() + + conn.SetReadDeadline(time.Now().Add(1 * time.Second)) + buf := make([]byte, 1024) + n, err := conn.Read(buf) + if err != nil || n == 0 { + return "" + } + + response := string(buf[:n]) + for _, line := range strings.Split(response, "\r\n") { + if strings.HasPrefix(line, "model: ") { + model := strings.TrimPrefix(line, "model: ") + if t.DebugBMD { + log.Printf("[bmd] hyperdeck %s at %s", model, ip) + } + return model + } + } + return "" +} + +func (t *Tendrils) probeVideoHub(ip net.IP) string { + conn, err := net.DialTimeout("tcp", ip.String()+":9990", 500*time.Millisecond) + if err != nil { + return "" + } + defer conn.Close() + + conn.SetReadDeadline(time.Now().Add(1 * time.Second)) + buf := make([]byte, 1024) + n, err := conn.Read(buf) + if err != nil || n == 0 { + return "" + } + + response := string(buf[:n]) + for _, line := range strings.Split(response, "\n") { + if strings.HasPrefix(line, "Model name: ") { + model := strings.TrimSpace(strings.TrimPrefix(line, "Model name: ")) + if t.DebugBMD { + log.Printf("[bmd] videohub %s at %s", model, ip) + } + return model + } + } + return "" +} + + diff --git a/snmp.go b/snmp.go index e16609f..66dd99b 100644 --- a/snmp.go +++ b/snmp.go @@ -80,10 +80,6 @@ func (t *Tendrils) connectSNMP(ip net.IP) (*gosnmp.GoSNMP, error) { } func (t *Tendrils) pollNode(node *Node) { - if t.DisableSNMP { - return - } - t.nodes.mu.RLock() var ips []net.IP for _, iface := range node.Interfaces { @@ -93,10 +89,19 @@ func (t *Tendrils) pollNode(node *Node) { } } } + nodeName := node.Name t.nodes.mu.RUnlock() - for _, ip := range ips { - t.querySNMPDevice(node, ip) + if !t.DisableSNMP { + for _, ip := range ips { + t.querySNMPDevice(node, ip) + } + } + + if !t.DisableBMD && nodeName == "" { + for _, ip := range ips { + t.probeBMDDevice(ip) + } } }