add ip programming packet types

This commit is contained in:
Joel Wetzell
2026-05-26 07:27:07 -05:00
parent 76189580db
commit 9546018fb7
3 changed files with 275 additions and 0 deletions
+20
View File
@@ -65,6 +65,26 @@ func Decode(bytes []byte) (ArtNetPacket, error) {
}
return &artPoll, nil
case OpIpProg:
artIpProg := ArtIpProg{}
err := artIpProg.UnmarshalBinary(bytes)
if err != nil {
return nil, err
}
return &artIpProg, nil
case OpIpProgReply:
artIpProgReply := ArtIpProgReply{}
err := artIpProgReply.UnmarshalBinary(bytes)
if err != nil {
return nil, err
}
return &artIpProgReply, nil
case OpDmx:
artDmx := ArtDmx{}
+127
View File
@@ -0,0 +1,127 @@
package artnet
import (
"encoding/binary"
"errors"
"slices"
)
type ArtIpProg struct {
ID [8]uint8
OpCode uint16
ProtVerHi uint8
ProtVerLo uint8
filler1 uint8
filler2 uint8
Command uint8
filler4 uint8
ProgIpHi uint8
ProgIp2 uint8
ProgIp1 uint8
ProgIpLo uint8
ProgSmHi uint8
ProgSm2 uint8
ProgSm1 uint8
ProgSmLo uint8
ProgPortHi uint8
ProgPortLo uint8
ProgDgHi uint8
ProgDg2 uint8
ProgDg1 uint8
ProgDgLo uint8
spare4 uint8
spare5 uint8
spare6 uint8
spare7 uint8
}
func (ad *ArtIpProg) GetOpCode() uint16 {
return ad.OpCode
}
func (ad *ArtIpProg) GetProtVer() uint16 {
return uint16(ad.ProtVerHi)<<8 + uint16(ad.ProtVerLo)
}
func (ad *ArtIpProg) GetID() [8]uint8 {
return ad.ID
}
func (ad *ArtIpProg) UnmarshalBinary(data []byte) error {
if len(data) < 34 {
return errors.New("ArtIpProg packet must be at least 18 bytes long")
}
copy(ad.ID[:], data[0:8])
if !slices.Equal(ArtNetID[:], ad.ID[:]) {
return errors.New("ID does not match Art-Net ID")
}
ad.OpCode = binary.LittleEndian.Uint16(data[8:10])
ad.ProtVerHi = data[10]
ad.ProtVerLo = data[11]
offset := 12
ad.filler1 = data[offset]
ad.filler2 = data[offset+1]
ad.Command = data[offset+2]
ad.filler4 = data[offset+3]
ad.ProgIpHi = data[offset+4]
ad.ProgIp2 = data[offset+5]
ad.ProgIp1 = data[offset+6]
ad.ProgIpLo = data[offset+7]
ad.ProgSmHi = data[offset+8]
ad.ProgSm2 = data[offset+9]
ad.ProgSm1 = data[offset+10]
ad.ProgSmLo = data[offset+11]
ad.ProgPortHi = data[offset+12]
ad.ProgPortLo = data[offset+13]
ad.ProgDgHi = data[offset+14]
ad.ProgDg2 = data[offset+15]
ad.ProgDg1 = data[offset+16]
ad.ProgDgLo = data[offset+17]
ad.spare4 = data[offset+18]
ad.spare5 = data[offset+19]
ad.spare6 = data[offset+20]
ad.spare7 = data[offset+21]
return nil
}
func (ad *ArtIpProg) MarshalBinary() ([]byte, error) {
data := make([]byte, 8+26)
copy(data[0:8], ad.ID[:])
binary.LittleEndian.PutUint16(data[8:10], ad.OpCode)
data[10] = ad.ProtVerHi
data[11] = ad.ProtVerLo
data[12] = ad.filler1
data[13] = ad.filler2
data[14] = ad.Command
data[15] = ad.filler4
data[16] = ad.ProgIpHi
data[17] = ad.ProgIp2
data[18] = ad.ProgIp1
data[19] = ad.ProgIpLo
data[20] = ad.ProgSmHi
data[21] = ad.ProgSm2
data[22] = ad.ProgSm1
data[23] = ad.ProgSmLo
data[24] = ad.ProgPortHi
data[25] = ad.ProgPortLo
data[26] = ad.ProgDgHi
data[27] = ad.ProgDg2
data[28] = ad.ProgDg1
data[29] = ad.ProgDgLo
data[30] = ad.spare4
data[31] = ad.spare5
data[32] = ad.spare6
data[33] = ad.spare7
return data, nil
}
+128
View File
@@ -0,0 +1,128 @@
package artnet
import (
"encoding/binary"
"errors"
"slices"
)
type ArtIpProgReply struct {
ID [8]uint8
OpCode uint16
ProtVerHi uint8
ProtVerLo uint8
filler1 uint8
filler2 uint8
filler3 uint8
filler4 uint8
ProgIpHi uint8
ProgIp2 uint8
ProgIp1 uint8
ProgIpLo uint8
ProgSmHi uint8
ProgSm2 uint8
ProgSm1 uint8
ProgSmLo uint8
ProgPortHi uint8
ProgPortLo uint8
Status uint8
spare2 uint8
ProgDgHi uint8
ProgDg2 uint8
ProgDg1 uint8
ProgDgLo uint8
spare7 uint8
spare8 uint8
}
func (ad *ArtIpProgReply) GetOpCode() uint16 {
return ad.OpCode
}
func (ad *ArtIpProgReply) GetProtVer() uint16 {
return uint16(ad.ProtVerHi)<<8 + uint16(ad.ProtVerLo)
}
func (ad *ArtIpProgReply) GetID() [8]uint8 {
return ad.ID
}
func (ad *ArtIpProgReply) UnmarshalBinary(data []byte) error {
if len(data) < 34 {
return errors.New("ArtIpProgReply packet must be at least 18 bytes long")
}
copy(ad.ID[:], data[0:8])
if !slices.Equal(ArtNetID[:], ad.ID[:]) {
return errors.New("ID does not match Art-Net ID")
}
ad.OpCode = binary.LittleEndian.Uint16(data[8:10])
ad.ProtVerHi = data[10]
ad.ProtVerLo = data[11]
offset := 12
ad.filler1 = data[offset]
ad.filler2 = data[offset+1]
ad.filler3 = data[offset+2]
ad.filler4 = data[offset+3]
ad.ProgIpHi = data[offset+4]
ad.ProgIp2 = data[offset+5]
ad.ProgIp1 = data[offset+6]
ad.ProgIpLo = data[offset+7]
ad.ProgSmHi = data[offset+8]
ad.ProgSm2 = data[offset+9]
ad.ProgSm1 = data[offset+10]
ad.ProgSmLo = data[offset+11]
ad.ProgPortHi = data[offset+12]
ad.ProgPortLo = data[offset+13]
ad.Status = data[offset+14]
ad.spare2 = data[offset+15]
ad.ProgDgHi = data[offset+16]
ad.ProgDg2 = data[offset+17]
ad.ProgDg1 = data[offset+18]
ad.ProgDgLo = data[offset+19]
ad.spare7 = data[offset+20]
ad.spare8 = data[offset+21]
return nil
}
func (ad *ArtIpProgReply) MarshalBinary() ([]byte, error) {
data := make([]byte, 8+26)
copy(data[0:8], ad.ID[:])
binary.LittleEndian.PutUint16(data[8:10], ad.OpCode)
data[10] = ad.ProtVerHi
data[11] = ad.ProtVerLo
data[12] = ad.filler1
data[13] = ad.filler2
data[14] = ad.filler3
data[15] = ad.filler4
data[16] = ad.ProgIpHi
data[17] = ad.ProgIp2
data[18] = ad.ProgIp1
data[19] = ad.ProgIpLo
data[20] = ad.ProgSmHi
data[21] = ad.ProgSm2
data[22] = ad.ProgSm1
data[23] = ad.ProgSmLo
data[24] = ad.ProgPortHi
data[25] = ad.ProgPortLo
data[26] = ad.Status
data[27] = ad.spare2
data[28] = ad.ProgDgHi
data[29] = ad.ProgDg2
data[30] = ad.ProgDg1
data[31] = ad.ProgDgLo
data[32] = ad.spare7
data[33] = ad.spare8
return data, nil
}