Files
artnet/sender.go
Ian Gulliver af1a9bceb1 Remove ArtRDM TOD discovery support
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 10:55:44 -08:00

96 lines
2.0 KiB
Go

package artnet
import (
"context"
"net"
"sync"
"syscall"
)
type Sender struct {
conn *net.UDPConn
sequences map[Universe]uint8
seqMu sync.Mutex
}
func NewSender() (*Sender, error) {
conn, err := net.ListenUDP("udp4", &net.UDPAddr{IP: net.IPv4zero, Port: 0})
if err != nil {
return nil, err
}
return &Sender{
conn: conn,
sequences: map[Universe]uint8{},
}, nil
}
func NewSenderFromConn(conn *net.UDPConn) *Sender {
return &Sender{
conn: conn,
sequences: map[Universe]uint8{},
}
}
func NewInterfaceSender(ifaceName string) (*Sender, error) {
lc := net.ListenConfig{
Control: func(network, address string, c syscall.RawConn) error {
var err error
c.Control(func(fd uintptr) {
err = syscall.SetsockoptString(int(fd), syscall.SOL_SOCKET, syscall.SO_BINDTODEVICE, ifaceName)
})
return err
},
}
conn, err := lc.ListenPacket(context.Background(), "udp4", ":0")
if err != nil {
return nil, err
}
return &Sender{
conn: conn.(*net.UDPConn),
sequences: map[Universe]uint8{},
}, nil
}
func (s *Sender) SendDMX(addr *net.UDPAddr, universe Universe, data []byte) error {
s.seqMu.Lock()
seq := s.sequences[universe]
seq++
if seq == 0 {
seq = 1
}
s.sequences[universe] = seq
s.seqMu.Unlock()
pkt := BuildDMXPacket(universe, seq, data)
_, err := s.conn.WriteToUDP(pkt, addr)
return err
}
func (s *Sender) SendPoll(addr *net.UDPAddr) error {
pkt := BuildPollPacket()
_, err := s.conn.WriteToUDP(pkt, addr)
return err
}
func (s *Sender) SendPollReply(addr *net.UDPAddr, localIP [4]byte, localMAC [6]byte, shortName, longName string, universes []Universe, isInput bool) error {
pkt := BuildPollReplyPacket(localIP, localMAC, shortName, longName, universes, isInput)
_, err := s.conn.WriteToUDP(pkt, addr)
return err
}
func (s *Sender) SendRaw(addr *net.UDPAddr, data []byte) error {
_, err := s.conn.WriteToUDP(data, addr)
return err
}
func (s *Sender) Close() error {
return s.conn.Close()
}
func (s *Sender) LocalAddr() net.Addr {
return s.conn.LocalAddr()
}