From fd0d482380b108c74e94bf9a3a9b70be3775bea4 Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Fri, 30 Jan 2026 09:14:05 -0800 Subject: [PATCH] Update for new artnet discovery API Co-Authored-By: Claude Opus 4.5 --- go.mod | 2 +- go.sum | 4 ++-- main.go | 68 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 62 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 2f54aa7..ddc7493 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.25.6 require ( github.com/BurntSushi/toml v1.6.0 - github.com/gopatchy/artnet v0.0.0-20260128203426-0a3e9b1daf66 + github.com/gopatchy/artnet v0.0.0-20260130164309-5e7400fe514e github.com/gopatchy/sacn v0.0.0-20260130055955-54a46fbfe1f0 ) diff --git a/go.sum b/go.sum index 9138efb..873f3b0 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,8 @@ github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= -github.com/gopatchy/artnet v0.0.0-20260128203426-0a3e9b1daf66 h1:QZrypvWOUbZeJsFRRx8UXf+MUbvkF/WR2KvNUynWFTM= -github.com/gopatchy/artnet v0.0.0-20260128203426-0a3e9b1daf66/go.mod h1:V/D32mh1xfK/llCKbrqI2jxw4xL4hf6Ge2yLiIrp9/4= +github.com/gopatchy/artnet v0.0.0-20260130164309-5e7400fe514e h1:KaCtixVKARhtTzqlqWyzXurNACaesAGxjFgnFd3jYT4= +github.com/gopatchy/artnet v0.0.0-20260130164309-5e7400fe514e/go.mod h1:V/D32mh1xfK/llCKbrqI2jxw4xL4hf6Ge2yLiIrp9/4= github.com/gopatchy/multicast v0.0.0-20260130055828-12d0b38af995 h1:dwu07X0JnN6Ar3oZMLa/BokX04JRa3AeM38Nz7nwKnM= github.com/gopatchy/multicast v0.0.0-20260130055828-12d0b38af995/go.mod h1:mSeh6GX+fL6SWZYqxYHTdnddvzDx4qsGSBnlGwY5ZsA= github.com/gopatchy/sacn v0.0.0-20260130055955-54a46fbfe1f0 h1:j1uxCRJSu7G8UwlTykIDacbcQY2qoUpZ9t/SBHqLET8= diff --git a/main.go b/main.go index 88f5342..de5a606 100644 --- a/main.go +++ b/main.go @@ -94,12 +94,6 @@ func main() { } } - // Convert poll targets to slice - pollTargetSlice := make([]*net.UDPAddr, 0, len(pollTargets)) - for _, addr := range pollTargets { - pollTargetSlice = append(pollTargetSlice, addr) - } - // Create ArtNet sender artSender, err := artnet.NewSender() if err != nil { @@ -129,7 +123,15 @@ func main() { for i, n := range srcNums { outputUnivs[i] = artnet.Universe(n) } - discovery := artnet.NewDiscovery(artSender, "artmap", "artmap", inputUnivs, outputUnivs, pollTargetSlice) + + // Get local interface info for discovery + var localIP, broadcastIP net.IP + var localMAC net.HardwareAddr + if len(broadcasts) > 0 { + broadcastIP = broadcasts[0].IP + localIP, localMAC = detectLocalInterface(broadcastIP) + } + discovery := artnet.NewDiscovery(artSender, localIP, broadcastIP, localMAC, "artmap", "artmap", inputUnivs, outputUnivs) // Create app app := &App{ @@ -183,8 +185,10 @@ func main() { log.Printf("[sacn] listening universes=%v", sacnUniverses) } - // Start discovery - discovery.Start() + // Start discovery only if we have ArtNet outputs + if len(destNums) > 0 || len(artTargets) > 0 { + discovery.Start() + } // Wait for interrupt sigChan := make(chan os.Signal, 1) @@ -362,6 +366,52 @@ func parseTargetAddr(s string, defaultPort int) (*net.UDPAddr, error) { return &net.UDPAddr{IP: ip, Port: port}, nil } +// detectLocalInterface returns local IP and MAC for an interface matching the broadcast address +func detectLocalInterface(broadcast net.IP) (net.IP, net.HardwareAddr) { + ifaces, err := net.Interfaces() + if err != nil { + return nil, nil + } + + for _, iface := range ifaces { + if iface.Flags&net.FlagLoopback != 0 || iface.Flags&net.FlagUp == 0 { + continue + } + + addrs, err := iface.Addrs() + if err != nil { + continue + } + + for _, addr := range addrs { + ipnet, ok := addr.(*net.IPNet) + if !ok { + continue + } + + ip4 := ipnet.IP.To4() + if ip4 == nil { + continue + } + + mask := ipnet.Mask + if len(mask) != 4 { + continue + } + + bcast := make(net.IP, 4) + for i := 0; i < 4; i++ { + bcast[i] = ip4[i] | ^mask[i] + } + + if bcast.Equal(broadcast) { + return ip4, iface.HardwareAddr + } + } + } + return nil, nil +} + // detectBroadcastAddrs returns broadcast addresses for all network interfaces func detectBroadcastAddrs() []*net.UDPAddr { var addrs []*net.UDPAddr