add hyperdeck and videohub discovery via tcp probing
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
71
bmd.go
71
bmd.go
@@ -10,6 +10,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (t *Tendrils) listenBMD(ctx context.Context, iface net.Interface) {
|
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()
|
addrs, err := iface.Addrs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@@ -197,3 +201,70 @@ func (t *Tendrils) parseATEMCommands(data []byte, sess *atemSession) {
|
|||||||
offset += cmdLen
|
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 ""
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
13
snmp.go
13
snmp.go
@@ -80,10 +80,6 @@ func (t *Tendrils) connectSNMP(ip net.IP) (*gosnmp.GoSNMP, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Tendrils) pollNode(node *Node) {
|
func (t *Tendrils) pollNode(node *Node) {
|
||||||
if t.DisableSNMP {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
t.nodes.mu.RLock()
|
t.nodes.mu.RLock()
|
||||||
var ips []net.IP
|
var ips []net.IP
|
||||||
for _, iface := range node.Interfaces {
|
for _, iface := range node.Interfaces {
|
||||||
@@ -93,13 +89,22 @@ func (t *Tendrils) pollNode(node *Node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
nodeName := node.Name
|
||||||
t.nodes.mu.RUnlock()
|
t.nodes.mu.RUnlock()
|
||||||
|
|
||||||
|
if !t.DisableSNMP {
|
||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
t.querySNMPDevice(node, ip)
|
t.querySNMPDevice(node, ip)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !t.DisableBMD && nodeName == "" {
|
||||||
|
for _, ip := range ips {
|
||||||
|
t.probeBMDDevice(ip)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (t *Tendrils) querySNMPDevice(node *Node, ip net.IP) {
|
func (t *Tendrils) querySNMPDevice(node *Node, ip net.IP) {
|
||||||
snmp, err := t.connectSNMP(ip)
|
snmp, err := t.connectSNMP(ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user