clj-artnet.impl.protocol.rdm.transport
ArtRdm and ArtRdmSub transport validation and helpers per Art-Net 4 spec.
Art-Net 4 §ArtRdm: - Transport all non-discovery RDM messages - Unicast only (broadcast no longer allowed in Art-Net 4) - Command field 0x00 = ArProcess (process RDM packet) - Validate command class in RDM payload (byte 20)
Art-Net 4 §ArtRdmSub: - Compressed sub-device data transfer - Get (0x20): 0 data bytes - Set (0x30): SubCount * 2 data bytes - GetResponse (0x21): SubCount * 2 data bytes - SetResponse (0x31): 0 data bytes
This module provides pure functions for: - RDM command class validation - ArtRdmSub packet validation - Sub-device range and entry helpers - Payload normalization for outbound commands
build-artrdm-packet
(build-artrdm-packet {:keys [target rdm-packet rdm-version fifo-available fifo-max address], :as command-msg})Construct an ArtRdm packet and the associated send action. Handles packet normalization, validation, and packet field population. Throws an exception if validation fails. Returns action map.
expected-data-length
(expected-data-length {:keys [command-class sub-count]})Calculate the expected data array size for ArtRdmSub based on CommandClass. Per spec: - Get (0x20): Array Size 0 - Set (0x30): Array Size SubCount * 2 bytes - GetResponse (0x21): Array Size SubCount * 2 bytes - SetResponse (0x31): Array Size 0
Returns nil for unknown command class.
normalize-payload-buffer
(normalize-payload-buffer payload)Convert payload to read-only ByteBuffer for transmission.
normalize-payload-bytes
(normalize-payload-bytes payload)Convert payload to a byte array for transmission. Accepts ByteBuffer, byte[], or seq of integers.
normalize-target
(normalize-target target)Normalize RDM target address for unicast transmission. ArtRdm requires unicast in Art-Net 4. Returns {:host h :port p} or throws if the host is missing.
payload-command-class
(payload-command-class payload)Extract command class byte from the RDM payload. The command class is at byte offset 20 in the RDM packet. Returns nil if the payload is too short or invalid type.
request?
(request? command-class)Check if the command class is a request (Get=0x20 or Set=0x30).
response-command-classes
Command classes representing responses (GetResponse/SetResponse).
response?
(response? command-class)Check if the command class is a response (GetResponse=0x21 or SetResponse=0x31).
sub-device-entries
(sub-device-entries {:keys [values], :as packet})Parse ArtRdmSub into indexed entries with a sub-device and optional value. Returns {:index 0 :sub-device n :value v} ….
sub-device-range
(sub-device-range {:keys [sub-device sub-count]})Extract sub-device range from ArtRdmSub packet. Returns {:first
sub-devices
(sub-devices {:keys [sub-device sub-count]})Generate a vector of sub-device addresses from ArtRdmSub packet. Handles 16-bit wrap-around.
valid-command-class?
(valid-command-class? command-class)Check if command class is valid for ArtRdm/ArtRdmSub.
valid-command-classes
Valid RDM command classes that ArtRdm/ArtRdmSub accept. 0x20 = GET_COMMAND 0x21 = GET_COMMAND_RESPONSE 0x30 = SET_COMMAND 0x31 = SET_COMMAND_RESPONSE
valid-rdmsub-packet?
(valid-rdmsub-packet? {:keys [command-class payload-length sub-count], :as packet})Validate ArtRdmSub packet structure per spec. Checks: - SubCount > 0 (zero is illegal per spec) - CommandClass is valid - PayloadLength matches expected for CommandClass - PayloadLength is even (16-bit values)
validate-payload-length
(validate-payload-length payload-length)Validate RDM payload length is within spec bounds. Throws ex-info if invalid. Returns the payload length if valid.