diff --git a/src/main/java/de/ctdo/bunti/artnet/ByteUtils.java b/src/main/java/de/ctdo/bunti/artnet/ByteUtils.java index 3496ffd..78fe284 100644 --- a/src/main/java/de/ctdo/bunti/artnet/ByteUtils.java +++ b/src/main/java/de/ctdo/bunti/artnet/ByteUtils.java @@ -26,10 +26,28 @@ public class ByteUtils { this.data = data; } + public static final int byteToUint(byte b) { + return (b < 0 ? 256 + b : b); + } + + public final byte[] getBytes() { return data; } + public final int getInt16(int offset) { + return (byteToUint(data[offset]) << 8) | byteToUint(data[offset + 1]); + } + + + public final int getInt16LE(int offset) { + return (byteToUint(data[offset + 1]) << 8) | byteToUint(data[offset]); + } + + public final int getInt8(int offset) { + return byteToUint(data[offset]); + } + public final int getLength() { return data.length; } diff --git a/src/main/java/de/ctdo/bunti/artnet/SimpleArtNetSenderImpl.java b/src/main/java/de/ctdo/bunti/artnet/SimpleArtNetSenderImpl.java index ed2b514..c45eeff 100644 --- a/src/main/java/de/ctdo/bunti/artnet/SimpleArtNetSenderImpl.java +++ b/src/main/java/de/ctdo/bunti/artnet/SimpleArtNetSenderImpl.java @@ -33,7 +33,6 @@ public class SimpleArtNetSenderImpl implements SimpleArtNetSender { packet.setSequenceID(sequence++); packet.setDMX(arr, arr.length); - packet.setUniverse(0, 0); return socket.unicastPacket(packet, adr); } diff --git a/src/main/java/de/ctdo/bunti/artnet/packets/ArtDmxPacket.java b/src/main/java/de/ctdo/bunti/artnet/packets/ArtDmxPacket.java index 367e7fa..54d9fee 100644 --- a/src/main/java/de/ctdo/bunti/artnet/packets/ArtDmxPacket.java +++ b/src/main/java/de/ctdo/bunti/artnet/packets/ArtDmxPacket.java @@ -19,7 +19,17 @@ package de.ctdo.bunti.artnet.packets; +import de.ctdo.bunti.dmx.DMX; + public class ArtDmxPacket extends ArtNetPacket { + private static final int DMX_PACKET_MAX_LENGTH = 530; + private static final int DMX_PACKET_HEADER_LENGTH = 18; + private static final int OFFSET_SEQUENCE = 12; + private static final int OFFSET_PHYSICAL = 13; + private static final int OFFSET_UNIVERSE = 14; + private static final int OFFSET_DMX_LENGTH = 16; + private static final int LOWER_NIBBLE = 0x0f; + private static final int SEQUENCE_ID_MAX = 0xff; private int numChannels; private int sequenceID; @@ -27,11 +37,9 @@ public class ArtDmxPacket extends ArtNetPacket { private int universeID; public ArtDmxPacket() { - super(PacketType.ART_OUTPUT); - setData(new byte[530]); - setHeader(); - setProtocol(); - getData().setInt8(0x02, 13); + super(PacketType.ART_OUTPUT, DMX_PACKET_MAX_LENGTH); + getData().setInt8(2, OFFSET_PHYSICAL); + setUniverse(0, 0); } /** @@ -42,7 +50,7 @@ public class ArtDmxPacket extends ArtNetPacket { */ @Override public final int getLength() { - return 18 + (1 == numChannels % 2 ? numChannels + 1 : numChannels); + return DMX_PACKET_HEADER_LENGTH + (1 == numChannels % 2 ? numChannels + 1 : numChannels); } /** @@ -73,16 +81,10 @@ public class ArtDmxPacket extends ArtNetPacket { return universeID; } - @Override - public final boolean parse(byte[] raw) { - return false; - } - public final void setDMX(byte[] dmxData, int numChannels) { - this.numChannels = numChannels; - getData().setByteChunk(dmxData, 18, numChannels); - getData().setInt16((1 == numChannels % 2 ? numChannels + 1 : numChannels), - 16); + setNumChannels(numChannels); + getData().setByteChunk(dmxData, DMX_PACKET_HEADER_LENGTH, numChannels); + getData().setInt16((1 == numChannels % 2 ? numChannels + 1 : numChannels), OFFSET_DMX_LENGTH); } /** @@ -90,33 +92,36 @@ public class ArtDmxPacket extends ArtNetPacket { * the number of DMX channels to set */ public final void setNumChannels(int numChannels) { - this.numChannels = numChannels > 512 ? 512 : numChannels; + this.numChannels = numChannels > DMX.DMX_CHANNEL_INDEX_MAX ? DMX.DMX_CHANNEL_INDEX_MAX : numChannels; } public final void setSequenceID(int id) { - sequenceID = id % 0xff; - getData().setInt8(id, 12); + sequenceID = id % SEQUENCE_ID_MAX; + getData().setInt8(sequenceID, OFFSET_SEQUENCE); } /** - * @param subnetID - * the subnetID to set + * @param subnetID the subnetID to set */ public final void setSubnetID(int subnetID) { - this.subnetID = subnetID & 0x0f; - } - - public final void setUniverse(int subnetID, int universeID) { - this.subnetID = subnetID & 0x0f; - this.universeID = universeID & 0x0f; - getData().setInt16LE(subnetID << 4 | universeID, 14); + this.subnetID = subnetID & LOWER_NIBBLE; + setUniverse(this.subnetID, this.universeID); } /** - * @param universeID - * the universeID to set + * @param universeID the universeID to set */ public final void setUniverseID(int universeID) { - this.universeID = universeID & 0x0f; + this.universeID = universeID & LOWER_NIBBLE; + setUniverse(this.subnetID, this.universeID); + } + + /** + * Sets universe and subnet into data array. Needed because subnet and universe are both 4 bit and share one byte + * @param subnetID + * @param universeID + */ + private void setUniverse(int subnetID, int universeID) { + getData().setInt16LE(subnetID << 4 | universeID, OFFSET_UNIVERSE); } } \ No newline at end of file diff --git a/src/main/java/de/ctdo/bunti/artnet/packets/ArtNetPacket.java b/src/main/java/de/ctdo/bunti/artnet/packets/ArtNetPacket.java index 3696ef9..a63e753 100644 --- a/src/main/java/de/ctdo/bunti/artnet/packets/ArtNetPacket.java +++ b/src/main/java/de/ctdo/bunti/artnet/packets/ArtNetPacket.java @@ -3,21 +3,31 @@ package de.ctdo.bunti.artnet.packets; import de.ctdo.bunti.artnet.ByteUtils; public abstract class ArtNetPacket { - static final byte[] HEADER = "Art-Net\0".getBytes(); - public static final int PROTOCOL_VERSION = 14; + private static final byte[] HEADER = "Art-Net\0".getBytes(); + private static final int PROTOCOL_VERSION = 14; + private static final int OFFSET_HEADER = 0; + private static final int OFFSET_OPCODE = 8; + private static final int OFFSET_PROTOCOL_VERSION = 10; private ByteUtils data; private final PacketType type; + public ArtNetPacket(PacketType type, int length) { + this.type = type; + setData(new byte[length]); + + // Set header + data.setByteChunk(HEADER, OFFSET_HEADER, HEADER.length); + data.setInt16LE(type.getOpCode(), OFFSET_OPCODE); + + // Set protocol + data.setInt16(PROTOCOL_VERSION, OFFSET_PROTOCOL_VERSION); + } public final ByteUtils getData() { return data; } - public ArtNetPacket(PacketType type) { - this.type = type; - } - public final byte[] getRawData() { return data.getBytes(); } @@ -26,46 +36,11 @@ public abstract class ArtNetPacket { return getData().getLength(); } - public final PacketType getType() { - return type; - } - - /** - * Parses the given byte array into semantic values and populates type - * specific fields for each packet type. Implementing classes do not need to - * check the packet header anymore since this has already been done at this - * stage. - * - * @param raw - * @return true, if there were no parse errors - */ - public abstract boolean parse(byte[] raw); - - /** - * @param data - * the data to set - */ public final void setData(byte[] data) { this.data = new ByteUtils(data); } - public final void setRawData(byte[] raw, int maxLength) { - if (raw.length > maxLength) { - byte[] raw2 = new byte[maxLength]; - System.arraycopy(raw, 0, raw2, 0, maxLength); - raw = raw2; - } - setData(raw); + public final PacketType getType() { + return type; } - - protected final void setHeader() { - data.setByteChunk(HEADER, 0, 8); - data.setInt16LE(type.getOpCode(), 8); - } - - protected final void setProtocol() { - data.setInt16(PROTOCOL_VERSION, 10); - } - - }