├── .gitignore ├── README.md ├── build.gradle ├── misc ├── cs └── logo.al8 ├── pom.xml └── src ├── main ├── AndroidManifest.xml └── java │ └── fr │ └── azelart │ └── artnetstack │ ├── constants │ ├── Constants.java │ ├── MagicNumbers.java │ ├── OpCodeConstants.java │ └── StyleConstants.java │ ├── domain │ ├── artaddress │ │ └── ArtAddress.java │ ├── artdmx │ │ └── ArtDMX.java │ ├── artnet │ │ └── ArtNetObject.java │ ├── artpoll │ │ └── ArtPoll.java │ ├── artpollreply │ │ ├── ArtPollReply.java │ │ ├── ArtPollReplyOutputPortStatus.java │ │ ├── ArtPollReplyStatus.java │ │ └── ArtPollReplyStyle.java │ ├── arttimecode │ │ ├── ArtTimeCode.java │ │ └── ArtTimeCodeType.java │ ├── controller │ │ ├── Controller.java │ │ ├── ControllerGoodInput.java │ │ ├── ControllerGoodOutput.java │ │ └── ControllerPortType.java │ └── enums │ │ ├── ArtPollReplyStrategyEnum.java │ │ ├── DiagnosticMessageEnum.java │ │ ├── DiagnosticMessageEnumAvailable.java │ │ ├── IndicatorStateEnum.java │ │ ├── NetworkCommunicationTypeEnum.java │ │ ├── PortInputOutputEnum.java │ │ ├── PortTypeEnum.java │ │ ├── PriorityCodesEnum.java │ │ └── UniverseAddressProgrammingAuthorityEnum.java │ ├── listeners │ ├── ArtNetPacketListener.java │ └── ServerListener.java │ ├── runners │ └── ExampleServer.java │ ├── server │ └── ArtNetServer.java │ └── utils │ ├── ArtNetPacketDecoder.java │ ├── ArtNetPacketEncoder.java │ ├── ByteUtils.java │ └── ByteUtilsArt.java └── test └── java └── fr └── azelart └── artnetstack └── utils └── ByteUtilsArtTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | .project 2 | .classpath 3 | .settings 4 | .checkstyle 5 | target 6 | *.class 7 | .idea 8 | 9 | # Package Files # 10 | *.jar 11 | *.war 12 | *.ear 13 | atlassian-ide-plugin.xml 14 | build 15 | *.iml 16 | .*/ 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ArtNetStack 2 | =========== 3 | 4 | Art-Net by Artistic Licence allows for broadcasting DMX data via IP/UDP. 5 | This library is implementing the basic protocol for Java applications. 6 | 7 | http://www.artisticlicence.com/WebSiteMaster/User%20Guides/art-net.pdf 8 | 9 | Currently supported core features are: 10 | * **ArtPoll** Encode and Decode ArtPoll Packet 11 | * **ArtPollReply** Encode ArtPollReply 12 | * **ArtTimeCode** Encode and Decode ArtTimeCode 13 | * **ArtDMX** Encode and Decode ArtDMX 14 | 15 | Currently supported events features are: 16 | * **Art** ArtNet packet event catch 17 | * **ArtPoll** ArtPoll event catch 18 | * **ArtPollReply** ArtPollReply event catch 19 | * **ArtTimeCode** ArtTimeCode event catch 20 | * **ArtDMX** ArtDMX event catch 21 | 22 | * **onTerminate** Server is die and disconnected 23 | * **onConnect** Server has binding address 24 | 25 | Currently supported protocols are: 26 | * **Broadcast** Broadcast protocol (100%) 27 | * **Unicast** Unicast protocol (0%) -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 24 5 | defaultConfig { 6 | minSdkVersion 15 7 | targetSdkVersion 24 8 | versionCode 18 9 | versionName '2.0.1' 10 | } 11 | } 12 | 13 | dependencies { 14 | testImplementation 'junit:junit:4.12' 15 | } 16 | -------------------------------------------------------------------------------- /misc/cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /misc/logo.al8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corentin59/ArtNetStack/ca941fc2c662ee0669bc976c3e726aaa0291ca54/misc/logo.al8 -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | fr.azelart.artnetstack 5 | stack 6 | 1.0.0-SNAPSHOT 7 | ArtNetStack 8 | 9 | 10 | 11 | junit 12 | junit 13 | 4.13.1 14 | test 15 | 16 | 17 | 18 | 19 | iso8859-15 20 | 21 | 22 | 23 | 24 | 25 | org.apache.maven.plugins 26 | maven-compiler-plugin 27 | 28 | iso8859-15 29 | 1.6 30 | 1.6 31 | true 32 | true 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/constants/Constants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.constants; 17 | 18 | /** 19 | * Constants file. 20 | * @author Corentin Azelart 21 | * 22 | */ 23 | public final class Constants { 24 | 25 | /** 26 | * Private constructor. 27 | */ 28 | private Constants() { 29 | super(); 30 | } 31 | 32 | /** Server port. */ 33 | public static final short DEFAULT_ART_NET_UDP_PORT = 6454; 34 | 35 | /** Version 14. */ 36 | public static final int ART_NET_VERSION = 14; 37 | 38 | /** General Id. */ 39 | public static final String ID = "Art-Net"; 40 | 41 | /** Major version. */ 42 | public static final int VERSION_LIB_HIGHT = 1; 43 | 44 | /** Minor version. */ 45 | public static final int VERSION_LIB_LOW = 0; 46 | 47 | /** Short Name. */ 48 | public static final String SHORT_NAME = "ArtNetStack 0.001"; 49 | 50 | /** Long Name. */ 51 | public static final String LONG_NAME = "ArtNetStack 1.001"; 52 | 53 | /** Max Ports (4 in protocol specification). */ 54 | public static final int MAX_PORT = 4; 55 | 56 | /** Size of DMX data area. */ 57 | public static final int DMX_512_SIZE = 512; 58 | 59 | /** Integer escape. */ 60 | public static final int INT_ESCAP = 0xff; 61 | 62 | /** Max length for short name. */ 63 | public static final int MAX_LENGTH_SHORT_NAME = 18; 64 | 65 | /** Max length for long name. */ 66 | public static final int MAX_LENGTH_LONG_NAME = 64; 67 | 68 | /** Max length for node report. */ 69 | public static final int MAX_LENGTH_NODE_REPORT = 64; 70 | 71 | /** DMX Data value : 512. */ 72 | public static final int DMX_DATA_LENGTH = 512; 73 | 74 | /** Buffer of datagramm trames. */ 75 | public static final int SERVER_BUFFER_INPUT = 1024; 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/constants/MagicNumbers.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.constants; 17 | 18 | /** 19 | * Magic numbers file. 20 | * @author Corentin Azelart. 21 | */ 22 | public final class MagicNumbers { 23 | 24 | /** 25 | * Private constructor. 26 | */ 27 | private MagicNumbers() { 28 | super(); 29 | } 30 | 31 | /** We work in 8 bits. */ 32 | public static final int MAGIC_NUMBER_BITSET = 8; 33 | 34 | /** Bit 0. */ 35 | public static final int MAGIC_NUMBER_BIT_0 = 0; 36 | 37 | /** Bit 1. */ 38 | public static final int MAGIC_NUMBER_BIT_1 = 1; 39 | 40 | /** Bit 2. */ 41 | public static final int MAGIC_NUMBER_BIT_2 = 2; 42 | 43 | /** Bit 3. */ 44 | public static final int MAGIC_NUMBER_BIT_3 = 3; 45 | 46 | /** Bit 4. */ 47 | public static final int MAGIC_NUMBER_BIT_4 = 4; 48 | 49 | /** Bit 5. */ 50 | public static final int MAGIC_NUMBER_BIT_5 = 5; 51 | 52 | /** Bit 6. */ 53 | public static final int MAGIC_NUMBER_BIT_6 = 6; 54 | 55 | /** Bit 7. */ 56 | public static final int MAGIC_NUMBER_BIT_7 = 7; 57 | 58 | /** Magic number 0. */ 59 | public static final int MAGIC_NUMBER_ZERO = 0; 60 | 61 | /** Magic number 3. */ 62 | public static final int MAGIC_NUMBER_3 = 3; 63 | 64 | /** Magic number 4. */ 65 | public static final int MAGIC_NUMBER_4 = 4; 66 | 67 | /** Magic number 5. */ 68 | public static final int MAGIC_NUMBER_5 = 5; 69 | 70 | /** Magic number 6. */ 71 | public static final int MAGIC_NUMBER_6 = 6; 72 | 73 | /** Magic number 7. */ 74 | public static final int MAGIC_NUMBER_7 = 7; 75 | 76 | /** Magic number 9. */ 77 | public static final byte MAGIC_NUMBER_9 = 9; 78 | 79 | /** Magic number 10. */ 80 | public static final int MAGIC_NUMBER_10 = 10; 81 | 82 | /** Magic number 11. */ 83 | public static final int MAGIC_NUMBER_11 = 11; 84 | 85 | /** Magic number 12. */ 86 | public static final int MAGIC_NUMBER_12 = 12; 87 | 88 | /** Magic number 13. */ 89 | public static final int MAGIC_NUMBER_13 = 13; 90 | 91 | /** Magic number 14. */ 92 | public static final int MAGIC_NUMBER_14 = 14; 93 | 94 | /** Magic number 15. */ 95 | public static final int MAGIC_NUMBER_15 = 15; 96 | 97 | /** Magic number 16. */ 98 | public static final int MAGIC_NUMBER_16 = 16; 99 | 100 | /** Magic number 17. */ 101 | public static final int MAGIC_NUMBER_17 = 17; 102 | 103 | /** Magic number 18. */ 104 | public static final int MAGIC_NUMBER_18 = 18; 105 | 106 | /** Magic number 19. */ 107 | public static final int MAGIC_NUMBER_19 = 19; 108 | 109 | /** Magic number 20. */ 110 | public static final int MAGIC_NUMBER_20 = 20; 111 | 112 | /** Magic number 20. */ 113 | public static final int MAGIC_NUMBER_21 = 21; 114 | 115 | /** Magic number 22. */ 116 | public static final int MAGIC_NUMBER_22 = 22; 117 | 118 | /** Magic number 23. */ 119 | public static final int MAGIC_NUMBER_23 = 23; 120 | 121 | /** Magic number 24. */ 122 | public static final int MAGIC_NUMBER_24 = 24; 123 | 124 | /** Magic number 26. */ 125 | public static final int MAGIC_NUMBER_26 = 26; 126 | 127 | /** Magic number 32. */ 128 | public static final int MAGIC_NUMBER_32 = 32; 129 | 130 | /** Magic number 33. */ 131 | public static final int MAGIC_NUMBER_33 = 33; 132 | 133 | /** Magic number 33. */ 134 | public static final int MAGIC_NUMBER_199 = 199; 135 | 136 | /** Magic number 44. */ 137 | public static final int MAGIC_NUMBER_44 = 44; 138 | 139 | /** Magic number 64. */ 140 | public static final int MAGIC_NUMBER_64 = 64; 141 | 142 | public static final int OUTPUT_SUBSWITCH_PORT_1 = 190; 143 | public static final int OUTPUT_SUBSWITCH_PORT_2 = 191; 144 | public static final int OUTPUT_SUBSWITCH_PORT_3 = 192; 145 | public static final int OUTPUT_SUBSWITCH_PORT_4 = 193; 146 | 147 | public static final int OUTPUT_PORT_STATUS_1 = 182; 148 | public static final int OUTPUT_PORT_STATUS_2 = 183; 149 | public static final int OUTPUT_PORT_STATUS_3 = 184; 150 | public static final int OUTPUT_PORT_STATUS_4 = 185; 151 | 152 | } 153 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/constants/OpCodeConstants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.constants; 17 | 18 | /** 19 | * OpCodes file. 20 | * @author Corentin Azelart. 21 | */ 22 | public final class OpCodeConstants { 23 | 24 | /** 25 | * Private constructor. 26 | */ 27 | private OpCodeConstants() { 28 | super(); 29 | } 30 | 31 | /** 32 | * This is an ArtPoll packet, 33 | * no other data is contained in this UDP packet. 34 | */ 35 | public static final int OPPOLL = 2000; 36 | 37 | /** 38 | * This is an ArtPollReply packet,. 39 | */ 40 | public static final int OPPOLLREPLY = 2100; 41 | 42 | /** 43 | * This is an ArtTimeCode packet. 44 | * It is used to transport time code over the network. 45 | */ 46 | public static final int OPTIMECODE = 9700; 47 | 48 | /** 49 | * This is an ArtDMX packet. 50 | * It is used to transport DMX over the network. 51 | */ 52 | public static final int OPOUTPUT = 5000; 53 | 54 | /** 55 | * This is an ArtAddress packet. 56 | * It contains remote programming information for a Node. 57 | */ 58 | public static final int ARTADDRESS = 6000; 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/constants/StyleConstants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.constants; 17 | 18 | /** 19 | * Styles contants. 20 | * @author Corentin Azelart 21 | */ 22 | public final class StyleConstants { 23 | 24 | /** 25 | * Private constructor. 26 | */ 27 | private StyleConstants() { 28 | super(); 29 | } 30 | 31 | /** A DMX to / from Art-Net device. */ 32 | public static final int ST_NODE = 0; 33 | 34 | /** A lighting console. */ 35 | public static final int ST_CONTROLLER = 1; 36 | 37 | /** A Media Server. */ 38 | public static final int ST_MEDIA = 2; 39 | 40 | /** A network routing device. */ 41 | public static final int ST_ROUTE = 3; 42 | 43 | /** A backup device. */ 44 | public static final int ST_BACKUP = 4; 45 | 46 | /** A configuration or diagnostic tool. */ 47 | public static final int ST_CONFIG = 5; 48 | 49 | /** A visualiser. */ 50 | public static final int ST_VISUAL = 6; 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/artaddress/ArtAddress.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.artaddress; 17 | 18 | import fr.azelart.artnetstack.domain.artnet.ArtNetObject; 19 | 20 | 21 | /** 22 | * This is an ArtAddress packet. 23 | * @author Corentin Azelart 24 | * 25 | */ 26 | public class ArtAddress extends ArtNetObject { 27 | 28 | /** 29 | * Short name to program. 30 | */ 31 | private String shortName; 32 | 33 | /** 34 | * Long name to program. 35 | */ 36 | private String longName; 37 | 38 | /** 39 | * @return the shortName 40 | */ 41 | public final String getShortName() { 42 | return shortName; 43 | } 44 | 45 | /** 46 | * @param shortName the shortName to set 47 | */ 48 | public final void setShortName(String shortName) { 49 | this.shortName = shortName; 50 | } 51 | 52 | /** 53 | * @return the longName 54 | */ 55 | public final String getLongName() { 56 | return longName; 57 | } 58 | 59 | /** 60 | * @param longName the longName to set 61 | */ 62 | public final void setLongName(String longName) { 63 | this.longName = longName; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/artdmx/ArtDMX.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.artdmx; 17 | 18 | import fr.azelart.artnetstack.constants.Constants; 19 | import fr.azelart.artnetstack.domain.artnet.ArtNetObject; 20 | 21 | /** 22 | * This is an ArtDMX packet. 23 | * @author Corentin Azelart 24 | * 25 | */ 26 | public class ArtDMX extends ArtNetObject { 27 | 28 | /** 29 | * The sequence number is used to ensure that ArtDmx 30 | * packets are used in the correct order. When Art-Net is 31 | * carried over a medium such as the Internet, it is 32 | * possible that ArtDmx packets will reach the receiver 33 | * out of order. 34 | */ 35 | private int sequence; 36 | 37 | /** 38 | * The Sequence field is set to 0x00 to disable this feature. 39 | */ 40 | private boolean sequenceEnabled; 41 | 42 | /** 43 | * The physical input port from which DMX512 data was 44 | * input. This field is for information only. Use Universe 45 | * for data routing. 46 | */ 47 | private int physicalPort; 48 | 49 | /** Network. */ 50 | private String subNet; 51 | 52 | /** Adress in network. */ 53 | private String subSwitch; 54 | 55 | /** 56 | * The length of the DMX512 data array. This value 57 | * should be an even number in the range 2 - 512. 58 | * It represents the number of DMX512 channels encoded 59 | * in packet. NB: Products which convert Art-Net to 60 | * DMX512 may opt to always send 512 channels. 61 | * High Byte 62 | */ 63 | private int lengthHi; 64 | 65 | /** 66 | * Low Byte of above. 67 | */ 68 | private int length; 69 | 70 | /** 71 | * An variable length array of DMX512 lighting data. 72 | */ 73 | private int[] data; 74 | 75 | /** 76 | * Construct an Art DMX packet. 77 | */ 78 | public ArtDMX() { 79 | super(); 80 | } 81 | 82 | /** 83 | * ToString method. 84 | * @return a textual representation 85 | */ 86 | @Override 87 | public final String toString() { 88 | final StringBuilder vSb = new StringBuilder(); 89 | vSb.append("ArtDMX[sequence="); 90 | vSb.append(sequence); 91 | vSb.append(",port="); 92 | vSb.append(physicalPort); 93 | vSb.append(",length="); 94 | vSb.append(lengthHi); 95 | if (data.length >= 1) { 96 | vSb.append(",C0="); 97 | vSb.append(data[0]); 98 | } 99 | if (data.length >= Constants.DMX_512_SIZE) { 100 | vSb.append(",C512="); 101 | vSb.append(data[Constants.DMX_512_SIZE - 1]); 102 | } 103 | vSb.append("]"); 104 | return vSb.toString(); 105 | } 106 | 107 | /** 108 | * @return the sequence 109 | */ 110 | public final int getSequence() { 111 | return sequence; 112 | } 113 | 114 | /** 115 | * @param pSequence the sequence to set 116 | */ 117 | public final void setSequence(final int pSequence) { 118 | this.sequence = pSequence; 119 | } 120 | 121 | /** 122 | * @return the sequenceEnabled 123 | */ 124 | public final boolean isSequenceEnabled() { 125 | return sequenceEnabled; 126 | } 127 | 128 | /** 129 | * @param pSequenceEnabled the sequenceEnabled to set 130 | */ 131 | public final void setSequenceEnabled(final boolean pSequenceEnabled) { 132 | this.sequenceEnabled = pSequenceEnabled; 133 | } 134 | 135 | /** 136 | * @return the physicalPort 137 | */ 138 | public final int getPhysicalPort() { 139 | return physicalPort; 140 | } 141 | 142 | /** 143 | * @param pPhysicalPort the physicalPort to set 144 | */ 145 | public final void setPhysicalPort(final int pPhysicalPort) { 146 | this.physicalPort = pPhysicalPort; 147 | } 148 | 149 | /** 150 | * @return the subNet 151 | */ 152 | public final String getSubNet() { 153 | return subNet; 154 | } 155 | 156 | /** 157 | * @param pSubNet the subNet to set 158 | */ 159 | public final void setSubNet(final String pSubNet) { 160 | this.subNet = pSubNet; 161 | } 162 | 163 | /** 164 | * @return the subSwitch 165 | */ 166 | public final String getSubSwitch() { 167 | return subSwitch; 168 | } 169 | 170 | /** 171 | * @param pSubSwitch the pSubSwitch to set 172 | */ 173 | public final void setSubSwitch(final String pSubSwitch) { 174 | this.subSwitch = pSubSwitch; 175 | } 176 | 177 | /** 178 | * @return the lengthHi 179 | */ 180 | public final int getLengthHi() { 181 | return lengthHi; 182 | } 183 | 184 | /** 185 | * @param pLengthHi the lengthHi to set 186 | */ 187 | public final void setLengthHi(final int pLengthHi) { 188 | this.lengthHi = pLengthHi; 189 | } 190 | 191 | /** 192 | * @return the length 193 | */ 194 | public final int getLength() { 195 | return length; 196 | } 197 | 198 | /** 199 | * @param pLength the length to set. 200 | */ 201 | public final void setLength(final int pLength) { 202 | this.length = pLength; 203 | } 204 | 205 | /** 206 | * @return the data 207 | */ 208 | public final int[] getData() { 209 | return data; 210 | } 211 | 212 | /** 213 | * @param pData the data to set. 214 | */ 215 | public final void setData(final int[] pData) { 216 | this.data = pData; 217 | } 218 | } 219 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/artnet/ArtNetObject.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.artnet; 17 | 18 | /** 19 | * This is a general ArtNet object. 20 | * @author Corentin Azelart. 21 | * 22 | */ 23 | public class ArtNetObject { 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/artpoll/ArtPoll.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.artpoll; 17 | 18 | import fr.azelart.artnetstack.domain.artnet.ArtNetObject; 19 | import fr.azelart.artnetstack.domain.enums.NetworkCommunicationTypeEnum; 20 | import fr.azelart.artnetstack.domain.enums.PriorityCodesEnum; 21 | 22 | /** 23 | * This is an ArtPoll. 24 | * @author Corentin Azelart. 25 | * 26 | */ 27 | public class ArtPoll extends ArtNetObject { 28 | 29 | /** 30 | * Send ArtPollReply whenever Node conditions 31 | * change. This selection allows the Controller to be 32 | * informed of changes without the need to continuously poll. 33 | * If false : 34 | * Only send ArtPollReply in response to an ArtPoll or ArtAddress. 35 | */ 36 | private Boolean artPollReplyWhenConditionsChanges; 37 | 38 | /** 39 | * Send me diagnostics messages. 40 | */ 41 | private Boolean sendMeDiagnosticsMessage; 42 | 43 | /** 44 | * Diagnostics messages are broadcast or unicast. 45 | */ 46 | private NetworkCommunicationTypeEnum networkCommunicationTypeDiagnosticsMessages; 47 | 48 | /** 49 | * Prority codes. 50 | */ 51 | private PriorityCodesEnum priorityCodes; 52 | 53 | 54 | /** 55 | * Constructor. 56 | */ 57 | public ArtPoll() { 58 | super(); 59 | } 60 | 61 | 62 | /** 63 | * @return the artPollReplyWhenConditionsChanges 64 | */ 65 | public final Boolean getArtPollReplyWhenConditionsChanges() { 66 | return artPollReplyWhenConditionsChanges; 67 | } 68 | 69 | 70 | /** 71 | * @param artPollReplyWhenConditionsChanges the artPollReplyWhenConditionsChanges to set 72 | */ 73 | public final void setArtPollReplyWhenConditionsChanges( 74 | final Boolean artPollReplyWhenConditionsChanges) { 75 | this.artPollReplyWhenConditionsChanges = artPollReplyWhenConditionsChanges; 76 | } 77 | 78 | 79 | /** 80 | * @return the sendMeDiagnosticsMessage 81 | */ 82 | public final Boolean getSendMeDiagnosticsMessage() { 83 | return sendMeDiagnosticsMessage; 84 | } 85 | 86 | 87 | /** 88 | * @param sendMeDiagnosticsMessage the sendMeDiagnosticsMessage to set 89 | */ 90 | public final void setSendMeDiagnosticsMessage(final Boolean sendMeDiagnosticsMessage) { 91 | this.sendMeDiagnosticsMessage = sendMeDiagnosticsMessage; 92 | } 93 | 94 | 95 | /** 96 | * @return the networkCommunicationTypeDiagnosticsMessages 97 | */ 98 | public final NetworkCommunicationTypeEnum getNetworkCommunicationTypeDiagnosticsMessages() { 99 | return networkCommunicationTypeDiagnosticsMessages; 100 | } 101 | 102 | 103 | /** 104 | * @param networkCommunicationTypeDiagnosticsMessages the networkCommunicationTypeDiagnosticsMessages to set 105 | */ 106 | public final void setNetworkCommunicationTypeDiagnosticsMessages( 107 | final NetworkCommunicationTypeEnum networkCommunicationTypeDiagnosticsMessages) { 108 | this.networkCommunicationTypeDiagnosticsMessages = networkCommunicationTypeDiagnosticsMessages; 109 | } 110 | 111 | 112 | /** 113 | * @return the priorityCodes 114 | */ 115 | public final PriorityCodesEnum getPriorityCodes() { 116 | return priorityCodes; 117 | } 118 | 119 | 120 | /** 121 | * @param priorityCodes the priorityCodes to set 122 | */ 123 | public final void setPriorityCodes(final PriorityCodesEnum priorityCodes) { 124 | this.priorityCodes = priorityCodes; 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/artpollreply/ArtPollReply.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.artpollreply; 17 | 18 | import fr.azelart.artnetstack.domain.artnet.ArtNetObject; 19 | 20 | /** 21 | * This is an ArtPollReply object. 22 | * @author Corentin Azelart 23 | * 24 | */ 25 | public class ArtPollReply extends ArtNetObject { 26 | 27 | /** Adress IP. */ 28 | private String ip; 29 | 30 | /** Port. */ 31 | private int port; 32 | 33 | /** Version High. */ 34 | private int versionH; 35 | 36 | /** Version Low. */ 37 | private int versionL; 38 | 39 | /** Hexa Oem. */ 40 | private String oemHexa; 41 | 42 | /** UBEA Version. */ 43 | private int ubeaVersion; 44 | 45 | /** ArtPollReply status. */ 46 | private ArtPollReplyStatus artPollReplyStatus; 47 | 48 | /** Network. */ 49 | private String subNet; 50 | 51 | /** Adress in network. */ 52 | private String subSwitch; 53 | 54 | /** Real ip address. */ 55 | private String physicalIp; 56 | 57 | /** The ESTA manufacturer code. These codes are used to 58 | * represent equipment manufacturer. They are assigned 59 | * by ESTA. This field can be interpreted as two ASCII 60 | * bytes representing the manufacturer initials. 61 | */ 62 | private String esta; 63 | 64 | /** 65 | * The array represents a null terminated short name for 66 | * the Node. The Controller uses the ArtAddress packet 67 | * to program this string. Max length is 17 characters 68 | * plus the null. This is a fixed length field, although the 69 | * string it contains can be shorter than the field. 70 | */ 71 | private String shortName; 72 | 73 | /** 74 | * The array represents a null terminated long name for 75 | * the Node. The Controller uses the ArtAddress packet 76 | * to program this string. Max length is 63 characters 77 | * plus the null. This is a fixed length field, although the 78 | * string it contains can be shorter than the field. 79 | */ 80 | private String longName; 81 | 82 | /** 83 | * The Style code defines the equipment style of the 84 | * device. See Table 4 for current Style codes. 85 | */ 86 | private ArtPollReplyStyle artPollReplyStyle; 87 | 88 | /** 89 | * Array of the four output subswitch ports 90 | * on the artnet node. 91 | */ 92 | private int[] outputSubswitch = new int[4]; 93 | 94 | /** 95 | * Array of the four output statuses 96 | */ 97 | private ArtPollReplyOutputPortStatus[] outputStatus = new ArtPollReplyOutputPortStatus[4]; 98 | 99 | @Override 100 | public String toString() { 101 | return "ArtPollReply{" + 102 | "ip='" + ip + '\'' + 103 | ", port=" + port + 104 | ", versionH=" + versionH + 105 | ", versionL=" + versionL + 106 | ", oemHexa='" + oemHexa + '\'' + 107 | ", ubeaVersion=" + ubeaVersion + 108 | ", artPollReplyStatus=" + artPollReplyStatus + 109 | ", subNet='" + subNet + '\'' + 110 | ", subSwitch='" + subSwitch + '\'' + 111 | ", physicalIp='" + physicalIp + '\'' + 112 | ", esta='" + esta + '\'' + 113 | ", shortName='" + shortName + '\'' + 114 | ", longName='" + longName + '\'' + 115 | ", artPollReplyStyle=" + artPollReplyStyle + 116 | '}'; 117 | } 118 | 119 | /** 120 | * @return the artPollReplyStyle 121 | */ 122 | public final ArtPollReplyStyle getArtPollReplyStyle() { 123 | return artPollReplyStyle; 124 | } 125 | 126 | /** 127 | * @param artPollReplyStyle the artPollReplyStyle to set 128 | */ 129 | public final void setArtPollReplyStyle(final ArtPollReplyStyle artPollReplyStyle) { 130 | this.artPollReplyStyle = artPollReplyStyle; 131 | } 132 | 133 | /** 134 | * @return the ip 135 | */ 136 | public final String getIp() { 137 | return ip; 138 | } 139 | 140 | /** 141 | * @param ip the ip to set 142 | */ 143 | public final void setIp(final String ip) { 144 | this.ip = ip; 145 | } 146 | 147 | /** 148 | * @return the port 149 | */ 150 | public final int getPort() { 151 | return port; 152 | } 153 | 154 | /** 155 | * @param port the port to set 156 | */ 157 | public final void setPort(final int port) { 158 | this.port = port; 159 | } 160 | 161 | /** 162 | * @return the versionH 163 | */ 164 | public final int getVersionH() { 165 | return versionH; 166 | } 167 | 168 | /** 169 | * @param versionH the versionH to set 170 | */ 171 | public final void setVersionH(final int versionH) { 172 | this.versionH = versionH; 173 | } 174 | 175 | /** 176 | * @return the versionL 177 | */ 178 | public final int getVersionL() { 179 | return versionL; 180 | } 181 | 182 | /** 183 | * @param versionL the versionL to set 184 | */ 185 | public final void setVersionL(final int versionL) { 186 | this.versionL = versionL; 187 | } 188 | 189 | /** 190 | * @return the oemHexa 191 | */ 192 | public final String getOemHexa() { 193 | return oemHexa; 194 | } 195 | 196 | /** 197 | * @param oemHexa the oemHexa to set 198 | */ 199 | public final void setOemHexa(final String oemHexa) { 200 | this.oemHexa = oemHexa; 201 | } 202 | 203 | /** 204 | * @return the ubeaVersion 205 | */ 206 | public final int getUbeaVersion() { 207 | return ubeaVersion; 208 | } 209 | 210 | /** 211 | * @param ubeaVersion the ubeaVersion to set 212 | */ 213 | public final void setUbeaVersion(final int ubeaVersion) { 214 | this.ubeaVersion = ubeaVersion; 215 | } 216 | 217 | public final ArtPollReplyStatus getArtPollReplyStatus() { 218 | return artPollReplyStatus; 219 | } 220 | 221 | public final void setArtPollReplyStatus(final ArtPollReplyStatus artPollReplyStatus) { 222 | this.artPollReplyStatus = artPollReplyStatus; 223 | } 224 | 225 | /** 226 | * @return the subNet 227 | */ 228 | public final String getSubNet() { 229 | return subNet; 230 | } 231 | 232 | /** 233 | * @param subNet the subNet to set 234 | */ 235 | public final void setSubNet(final String subNet) { 236 | this.subNet = subNet; 237 | } 238 | 239 | /** 240 | * @return the subSwitch 241 | */ 242 | public final String getSubSwitch() { 243 | return subSwitch; 244 | } 245 | 246 | /** 247 | * @param subSwitch the subSwitch to set 248 | */ 249 | public final void setSubSwitch(final String subSwitch) { 250 | this.subSwitch = subSwitch; 251 | } 252 | 253 | /** 254 | * @return the shortName 255 | */ 256 | public final String getShortName() { 257 | return shortName; 258 | } 259 | 260 | /** 261 | * @param shortName the shortName to set 262 | */ 263 | public final void setShortName(final String shortName) { 264 | this.shortName = shortName; 265 | } 266 | 267 | /** 268 | * @return the longName 269 | */ 270 | public final String getLongName() { 271 | return longName; 272 | } 273 | 274 | /** 275 | * @param longName the longName to set 276 | */ 277 | public final void setLongName(final String longName) { 278 | this.longName = longName; 279 | } 280 | 281 | /** 282 | * @return the esta 283 | */ 284 | public final String getEsta() { 285 | return esta; 286 | } 287 | 288 | /** 289 | * @param esta the esta to set 290 | */ 291 | public final void setEsta(final String esta) { 292 | this.esta = esta; 293 | } 294 | 295 | 296 | /** 297 | * @return the physicalIp 298 | */ 299 | public final String getPhysicalIp() { 300 | return physicalIp; 301 | } 302 | 303 | /** 304 | * @param physicalIp the physicalIp to set 305 | */ 306 | public final void setPhysicalIp(final String physicalIp) { 307 | this.physicalIp = physicalIp; 308 | } 309 | 310 | public int[] getOutputSubswitch() { 311 | return outputSubswitch; 312 | } 313 | 314 | public void setOutputSubswitch(int[] outputSubswitch) { 315 | this.outputSubswitch = outputSubswitch; 316 | } 317 | 318 | public ArtPollReplyOutputPortStatus[] getOutputStatus() { 319 | return outputStatus; 320 | } 321 | 322 | public void setOutputStatus(ArtPollReplyOutputPortStatus[] outputStatus) { 323 | this.outputStatus = outputStatus; 324 | } 325 | } 326 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/artpollreply/ArtPollReplyOutputPortStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Dan Fredell. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.artpollreply; 17 | 18 | /** 19 | * ArtPolLReply port status. 20 | * Fields 22 of ArtPollReply in the ArtNet specs 21 | * 22 | * @author Dan Fredell 23 | * @see art-net.pdf 24 | */ 25 | public class ArtPollReplyOutputPortStatus { 26 | 27 | /** 28 | * true if you can send ArtNet data to this port 29 | * and the node will transmit it to DMX 30 | */ 31 | public boolean dataTransmitted; 32 | public boolean testPacket, 33 | sip, 34 | texPacket, 35 | mergingData, 36 | outputShort, 37 | ltp, 38 | unused; 39 | 40 | public ArtPollReplyOutputPortStatus(byte inputByte) { 41 | this.dataTransmitted = (inputByte & 0x80) != 0; 42 | this.testPacket = (inputByte & 0x40) != 0; 43 | this.sip = (inputByte & 0x20) != 0; 44 | this.texPacket = (inputByte & 0x10) != 0; 45 | this.mergingData = (inputByte & 0x08) != 0; 46 | this.outputShort = (inputByte & 0x04) != 0; 47 | this.ltp = (inputByte & 0x02) != 0; 48 | this.unused = (inputByte & 0x01) != 0; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/artpollreply/ArtPollReplyStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.artpollreply; 17 | 18 | import fr.azelart.artnetstack.domain.enums.IndicatorStateEnum; 19 | import fr.azelart.artnetstack.domain.enums.UniverseAddressProgrammingAuthorityEnum; 20 | 21 | /** 22 | * ArtPolLReply status. 23 | * @author Corentin Azelart. 24 | */ 25 | public class ArtPollReplyStatus { 26 | 27 | /** UBEA is present. */ 28 | private Boolean ubeaPresent; 29 | 30 | /** RDM Available. */ 31 | private Boolean rdmCapable; 32 | 33 | /** Device is booted from ROM. */ 34 | private Boolean bootRom; 35 | 36 | /** Programming authority. */ 37 | private UniverseAddressProgrammingAuthorityEnum programmingAuthority; 38 | 39 | /** Indicator state. */ 40 | private IndicatorStateEnum indicatorState; 41 | 42 | /** 43 | * Constructor. 44 | */ 45 | public ArtPollReplyStatus() { 46 | super(); 47 | } 48 | 49 | /** 50 | * @return the ubeaPresent 51 | */ 52 | public final Boolean getUbeaPresent() { 53 | return ubeaPresent; 54 | } 55 | 56 | /** 57 | * @param ubeaPresent the ubeaPresent to set 58 | */ 59 | public final void setUbeaPresent(final Boolean ubeaPresent) { 60 | this.ubeaPresent = ubeaPresent; 61 | } 62 | 63 | /** 64 | * @return the rdmCapable 65 | */ 66 | public final Boolean getRdmCapable() { 67 | return rdmCapable; 68 | } 69 | 70 | /** 71 | * @param rdmCapable the rdmCapable to set 72 | */ 73 | public final void setRdmCapable(final Boolean rdmCapable) { 74 | this.rdmCapable = rdmCapable; 75 | } 76 | 77 | /** 78 | * @return the bootRom 79 | */ 80 | public final Boolean getBootRom() { 81 | return bootRom; 82 | } 83 | 84 | /** 85 | * @param bootRom the bootRom to set 86 | */ 87 | public final void setBootRom(final Boolean bootRom) { 88 | this.bootRom = bootRom; 89 | } 90 | 91 | /** 92 | * @return the programmingAuthority 93 | */ 94 | public final UniverseAddressProgrammingAuthorityEnum getProgrammingAuthority() { 95 | return programmingAuthority; 96 | } 97 | 98 | /** 99 | * @param programmingAuthority the programmingAuthority to set 100 | */ 101 | public final void setProgrammingAuthority( 102 | final UniverseAddressProgrammingAuthorityEnum programmingAuthority) { 103 | this.programmingAuthority = programmingAuthority; 104 | } 105 | 106 | /** 107 | * @return the indicatorState 108 | */ 109 | public final IndicatorStateEnum getIndicatorState() { 110 | return indicatorState; 111 | } 112 | 113 | /** 114 | * @param indicatorState the indicatorState to set 115 | */ 116 | public final void setIndicatorState(final IndicatorStateEnum indicatorState) { 117 | this.indicatorState = indicatorState; 118 | } 119 | 120 | @Override 121 | public String toString() { 122 | return "ArtPollReplyStatus{" + 123 | "ubeaPresent=" + ubeaPresent + 124 | ", rdmCapable=" + rdmCapable + 125 | ", bootRom=" + bootRom + 126 | ", programmingAuthority=" + programmingAuthority + 127 | ", indicatorState=" + indicatorState + 128 | '}'; 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/artpollreply/ArtPollReplyStyle.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.artpollreply; 17 | 18 | /** 19 | * Style enumeration. 20 | * @author Corentin Azelart. 21 | * 22 | */ 23 | public enum ArtPollReplyStyle { 24 | 25 | /** A DMX to / from Art-Net device. */ 26 | ST_NODE, 27 | 28 | /** A lighting console. */ 29 | ST_CONTROLLER, 30 | 31 | /** A Media Server. */ 32 | ST_MEDIA, 33 | 34 | /** A network routing device. */ 35 | ST_ROUTE, 36 | 37 | /** A backup device. */ 38 | ST_BACKUP, 39 | 40 | /** A configuration or diagnostic tool. */ 41 | ST_CONFIG, 42 | 43 | /** A visualiser. */ 44 | ST_VISUAL 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/arttimecode/ArtTimeCode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.arttimecode; 17 | 18 | import fr.azelart.artnetstack.domain.artnet.ArtNetObject; 19 | 20 | /** 21 | * ArtTimeCode. 22 | * @author Corentin Azelart. 23 | * 24 | */ 25 | public class ArtTimeCode extends ArtNetObject { 26 | 27 | /** Frames time. 0 - 29 depending on mode. */ 28 | private int frameTime; 29 | 30 | /** Seconds. 0 - 59. */ 31 | private int seconds; 32 | 33 | /** Minutes. 0 - 59. */ 34 | private int minutes; 35 | 36 | /** Hours. 0 - 23. */ 37 | private int hours; 38 | 39 | /** Type of ArtTimeCode. */ 40 | private ArtTimeCodeType artTimeCodeType; 41 | 42 | /** 43 | * Constructor. 44 | */ 45 | public ArtTimeCode() { 46 | super(); 47 | } 48 | 49 | /** 50 | * @return the frameTime 51 | */ 52 | public final int getFrameTime() { 53 | return frameTime; 54 | } 55 | 56 | /** 57 | * @param frameTimecode the frameTime to set 58 | */ 59 | public final void setFrameTime(final int frameTimecode) { 60 | this.frameTime = frameTimecode; 61 | } 62 | 63 | /** 64 | * @return the seconds 65 | */ 66 | public final int getSeconds() { 67 | return seconds; 68 | } 69 | 70 | /** 71 | * @param secondsTimecode the seconds to set 72 | */ 73 | public final void setSeconds(final int secondsTimecode) { 74 | this.seconds = secondsTimecode; 75 | } 76 | 77 | /** 78 | * @return the minutes 79 | */ 80 | public final int getMinutes() { 81 | return minutes; 82 | } 83 | 84 | /** 85 | * @param minutesTimecode the minutes to set 86 | */ 87 | public final void setMinutes(final int minutesTimecode) { 88 | this.minutes = minutesTimecode; 89 | } 90 | 91 | /** 92 | * @return the hours 93 | */ 94 | public final int getHours() { 95 | return hours; 96 | } 97 | 98 | /** 99 | * @param hoursTimecode the hours to set 100 | */ 101 | public final void setHours(final int hoursTimecode) { 102 | this.hours = hoursTimecode; 103 | } 104 | 105 | /** 106 | * @return the artTimeCodeType 107 | */ 108 | public final ArtTimeCodeType getArtTimeCodeType() { 109 | return artTimeCodeType; 110 | } 111 | 112 | /** 113 | * @param timeCodeType the artTimeCodeType to set 114 | */ 115 | public final void setArtTimeCodeType(final ArtTimeCodeType timeCodeType) { 116 | this.artTimeCodeType = timeCodeType; 117 | } 118 | 119 | /** 120 | * ToString. 121 | * @return A Human String of current timecode 122 | */ 123 | public final String toString() { 124 | final StringBuffer sb = new StringBuffer(); 125 | sb.append("f(").append(frameTime).append(") "). 126 | append("s(").append(seconds).append(") "). 127 | append("m(").append(minutes).append(") "). 128 | append("h(").append(hours).append(")"); 129 | return sb.toString(); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/arttimecode/ArtTimeCodeType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.arttimecode; 17 | 18 | /** 19 | * Types of ArtTimeCode. 20 | * @author Corentin Azelart 21 | * 22 | */ 23 | public enum ArtTimeCodeType { 24 | 25 | /** FILM. */ 26 | FILM, 27 | 28 | /** EBU. */ 29 | EBU, 30 | 31 | /** DF. */ 32 | DF, 33 | 34 | /** SMTPE. */ 35 | SMPTE, 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/controller/Controller.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.controller; 17 | 18 | import fr.azelart.artnetstack.domain.artnet.ArtNetObject; 19 | 20 | import java.util.Map; 21 | 22 | /** 23 | * General controler. 24 | * @author Corentin Azelart. 25 | */ 26 | public class Controller extends ArtNetObject { 27 | 28 | /** Port mapping. */ 29 | private Map portTypeMap; 30 | 31 | /** GoodInput mapping. */ 32 | private Map goodInputMapping; 33 | 34 | /** GoodOutput mapping. */ 35 | private Map goodOutputMapping; 36 | 37 | /** 38 | * Set to false when video display is showing local data. 39 | * Set to true when video is showing ethernet data. 40 | */ 41 | private Boolean screen; 42 | 43 | /** 44 | * Network identifier, 0-255. 45 | */ 46 | private int network = 0x00; 47 | 48 | /** 49 | * Subnetwork identifier, 0-255. 50 | */ 51 | private int subNetwork = 0x0D; 52 | 53 | /** 54 | * @return the goodInputMapping 55 | */ 56 | public final Map getGoodInputMapping() { 57 | return goodInputMapping; 58 | } 59 | 60 | /** 61 | * @param goodInputMapping the goodInputMapping to set 62 | */ 63 | public final void setGoodInputMapping(final Map goodInputMapping) { 64 | this.goodInputMapping = goodInputMapping; 65 | } 66 | 67 | /** 68 | * Controler. 69 | */ 70 | public Controller() { 71 | super(); 72 | } 73 | 74 | /** 75 | * @return the portTypeMap 76 | */ 77 | public final Map getPortTypeMap() { 78 | return portTypeMap; 79 | } 80 | 81 | /** 82 | * @param portTypeMap the portTypeMap to set 83 | */ 84 | public final void setPortTypeMap(final Map portTypeMap) { 85 | this.portTypeMap = portTypeMap; 86 | } 87 | 88 | /** 89 | * @return the goodOutputMapping 90 | */ 91 | public final Map getGoodOutputMapping() { 92 | return goodOutputMapping; 93 | } 94 | 95 | /** 96 | * @param goodOutputMapping the goodOutputMapping to set 97 | */ 98 | public final void setGoodOutputMapping(final Map goodOutputMapping) { 99 | this.goodOutputMapping = goodOutputMapping; 100 | } 101 | 102 | /** 103 | * @return the screen 104 | */ 105 | public final Boolean getScreen() { 106 | return screen; 107 | } 108 | 109 | /** 110 | * Set to false when video display is showing local data. 111 | * Set to true when video is showing ethernet data. 112 | * @param screen the screen to set 113 | */ 114 | public final void setScreen(final Boolean screen) { 115 | this.screen = screen; 116 | } 117 | 118 | /** 119 | * @return the network 120 | */ 121 | public int getNetwork() { 122 | return network; 123 | } 124 | 125 | /** 126 | * @param network the network to set 127 | */ 128 | public void setNetwork(final int network) { 129 | this.network = network; 130 | } 131 | 132 | /** 133 | * @return the subNetwork 134 | */ 135 | public int getSubNetwork() { 136 | return subNetwork; 137 | } 138 | 139 | /** 140 | * @param subNetwork the subNetwork to set 141 | */ 142 | public void setSubNetwork(final int subNetwork) { 143 | this.subNetwork = subNetwork; 144 | } 145 | } -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/controller/ControllerGoodInput.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.controller; 17 | 18 | /** 19 | * Good input. 20 | * @author Corentin Azelart. 21 | * 22 | */ 23 | public class ControllerGoodInput { 24 | 25 | /** Input receive data in error. */ 26 | private Boolean receivedDataError; 27 | 28 | /** Input is disabled. */ 29 | private Boolean disabled; 30 | 31 | /** This input accept DMX Text packets. */ 32 | private Boolean includeDMXTextPackets; 33 | 34 | /** This input accept DMX SIPs packets. */ 35 | private Boolean includeDMXSIPsPackets; 36 | 37 | /** This input accept DMX test packets. */ 38 | private Boolean includeDMXTestPackets; 39 | 40 | /** This input receive data. */ 41 | private Boolean dataReceived; 42 | 43 | /** 44 | * Constructor. 45 | */ 46 | public ControllerGoodInput() { 47 | super(); 48 | } 49 | 50 | /** 51 | * @return the receivedDataError 52 | */ 53 | public final Boolean getReceivedDataError() { 54 | return receivedDataError; 55 | } 56 | 57 | /** 58 | * @param receivedDataError the receivedDataError to set 59 | */ 60 | public final void setReceivedDataError(final Boolean receivedDataError) { 61 | this.receivedDataError = receivedDataError; 62 | } 63 | 64 | /** 65 | * @return the disabled 66 | */ 67 | public final Boolean getDisabled() { 68 | return disabled; 69 | } 70 | 71 | /** 72 | * @param disabled the disabled to set 73 | */ 74 | public void setDisabled(final Boolean disabled) { 75 | this.disabled = disabled; 76 | } 77 | 78 | /** 79 | * @return the includeDMXTextPackets 80 | */ 81 | public final Boolean getIncludeDMXTextPackets() { 82 | return includeDMXTextPackets; 83 | } 84 | 85 | /** 86 | * @param includeDMXTextPackets the includeDMXTextPackets to set 87 | */ 88 | public final void setIncludeDMXTextPackets(Boolean includeDMXTextPackets) { 89 | this.includeDMXTextPackets = includeDMXTextPackets; 90 | } 91 | 92 | /** 93 | * @return the includeDMXSIPsPackets 94 | */ 95 | public final Boolean getIncludeDMXSIPsPackets() { 96 | return includeDMXSIPsPackets; 97 | } 98 | 99 | /** 100 | * @param includeDMXSIPsPackets the includeDMXSIPsPackets to set 101 | */ 102 | public final void setIncludeDMXSIPsPackets(Boolean includeDMXSIPsPackets) { 103 | this.includeDMXSIPsPackets = includeDMXSIPsPackets; 104 | } 105 | 106 | /** 107 | * @return the includeDMXTestPackets 108 | */ 109 | public final Boolean getIncludeDMXTestPackets() { 110 | return includeDMXTestPackets; 111 | } 112 | 113 | /** 114 | * @param includeDMXTestPackets the includeDMXTestPackets to set 115 | */ 116 | public final void setIncludeDMXTestPackets(Boolean includeDMXTestPackets) { 117 | this.includeDMXTestPackets = includeDMXTestPackets; 118 | } 119 | 120 | /** 121 | * @return the dataReceived 122 | */ 123 | public final Boolean getDataReceived() { 124 | return dataReceived; 125 | } 126 | 127 | /** 128 | * @param dataReceived the dataReceived to set 129 | */ 130 | public final void setDataReceived(final Boolean dataReceived) { 131 | this.dataReceived = dataReceived; 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/controller/ControllerGoodOutput.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.controller; 17 | 18 | /** 19 | * Controler Input Good. 20 | * @author Corentin Azelart. 21 | * 22 | */ 23 | public class ControllerGoodOutput { 24 | 25 | /** The merge mode is LTP. */ 26 | private Boolean mergeLTP; 27 | 28 | /** DMX output short detected on power up. */ 29 | private Boolean outputPowerOn; 30 | 31 | /** Output is merging ArtNet data. */ 32 | private Boolean outputmergeArtNet; 33 | 34 | /** This output accept DMX Text packets. */ 35 | private Boolean includeDMXTextPackets; 36 | 37 | /** This output accept DMX SIPs packets. */ 38 | private Boolean includeDMXSIPsPackets; 39 | 40 | /** This output accept DMX test packets. */ 41 | private Boolean includeDMXTestPackets; 42 | 43 | /** This output transmit data. */ 44 | private Boolean dataTransmited; 45 | 46 | /** 47 | * Constructor. 48 | */ 49 | public ControllerGoodOutput() { 50 | super(); 51 | } 52 | 53 | /** 54 | * @return the mergeLTP 55 | */ 56 | public final Boolean getMergeLTP() { 57 | return mergeLTP; 58 | } 59 | 60 | /** 61 | * @param mergeLTP the mergeLTP to set 62 | */ 63 | public final void setMergeLTP(Boolean mergeLTP) { 64 | this.mergeLTP = mergeLTP; 65 | } 66 | 67 | /** 68 | * @return the outputPowerOn 69 | */ 70 | public final Boolean getOutputPowerOn() { 71 | return outputPowerOn; 72 | } 73 | 74 | /** 75 | * @param outputPowerOn the outputPowerOn to set 76 | */ 77 | public final void setOutputPowerOn(Boolean outputPowerOn) { 78 | this.outputPowerOn = outputPowerOn; 79 | } 80 | 81 | /** 82 | * @return the outputmergeArtNet 83 | */ 84 | public final Boolean getOutputmergeArtNet() { 85 | return outputmergeArtNet; 86 | } 87 | 88 | /** 89 | * @param outputmergeArtNet the outputmergeArtNet to set 90 | */ 91 | public final void setOutputMergeArtNet(final Boolean outputmergeArtNet) { 92 | this.outputmergeArtNet = outputmergeArtNet; 93 | } 94 | 95 | /** 96 | * @return the includeDMXTextPackets 97 | */ 98 | public final Boolean getIncludeDMXTextPackets() { 99 | return includeDMXTextPackets; 100 | } 101 | 102 | /** 103 | * @param includeDMXTextPackets the includeDMXTextPackets to set 104 | */ 105 | public final void setIncludeDMXTextPackets(final Boolean includeDMXTextPackets) { 106 | this.includeDMXTextPackets = includeDMXTextPackets; 107 | } 108 | 109 | /** 110 | * @return the includeDMXSIPsPackets 111 | */ 112 | public final Boolean getIncludeDMXSIPsPackets() { 113 | return includeDMXSIPsPackets; 114 | } 115 | 116 | /** 117 | * @param includeDMXSIPsPackets the includeDMXSIPsPackets to set 118 | */ 119 | public final void setIncludeDMXSIPsPackets(Boolean includeDMXSIPsPackets) { 120 | this.includeDMXSIPsPackets = includeDMXSIPsPackets; 121 | } 122 | 123 | /** 124 | * @return the includeDMXTestPackets 125 | */ 126 | public final Boolean getIncludeDMXTestPackets() { 127 | return includeDMXTestPackets; 128 | } 129 | 130 | /** 131 | * @param includeDMXTestPackets the includeDMXTestPackets to set 132 | */ 133 | public final void setIncludeDMXTestPackets(final Boolean includeDMXTestPackets) { 134 | this.includeDMXTestPackets = includeDMXTestPackets; 135 | } 136 | 137 | /** 138 | * @return the dataTransmited 139 | */ 140 | public final Boolean getDataTransmited() { 141 | return dataTransmited; 142 | } 143 | 144 | /** 145 | * @param dataTransmited the dataTransmited to set 146 | */ 147 | public final void setDataTransmited(final Boolean dataTransmited) { 148 | this.dataTransmited = dataTransmited; 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/controller/ControllerPortType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.controller; 17 | 18 | import fr.azelart.artnetstack.domain.enums.PortInputOutputEnum; 19 | import fr.azelart.artnetstack.domain.enums.PortTypeEnum; 20 | 21 | /** 22 | * Controler Port Type. 23 | * @author Corentin Azelart. 24 | * 25 | */ 26 | public class ControllerPortType { 27 | 28 | /** Port Number. */ 29 | private int port; 30 | 31 | /** Port type. */ 32 | private PortTypeEnum type; 33 | 34 | /** Direction. */ 35 | private PortInputOutputEnum direction; 36 | 37 | /** 38 | * @return the direction 39 | */ 40 | public final PortInputOutputEnum getDirection() { 41 | return direction; 42 | } 43 | 44 | /** 45 | * @param direction the direction to set 46 | */ 47 | public final void setDirection(final PortInputOutputEnum direction) { 48 | this.direction = direction; 49 | } 50 | 51 | /** Specify if we can input communicate. */ 52 | private boolean inputArtNet; 53 | 54 | /** Specify if we can output communicate. */ 55 | private boolean outputArtNet; 56 | 57 | /** 58 | * @return the port 59 | */ 60 | public final int getPort() { 61 | return port; 62 | } 63 | 64 | /** 65 | * @param port the port to set 66 | */ 67 | public final void setPort(final int port) { 68 | this.port = port; 69 | } 70 | 71 | /** 72 | * @return the type 73 | */ 74 | public final PortTypeEnum getType() { 75 | return type; 76 | } 77 | 78 | /** 79 | * @param type the type to set 80 | */ 81 | public final void setType(final PortTypeEnum type) { 82 | this.type = type; 83 | } 84 | 85 | /** 86 | * @return the inputArtNet 87 | */ 88 | public final boolean isInputArtNet() { 89 | return inputArtNet; 90 | } 91 | 92 | /** 93 | * @param inputArtNet the inputArtNet to set 94 | */ 95 | public final void setInputArtNet(final boolean inputArtNet) { 96 | this.inputArtNet = inputArtNet; 97 | } 98 | 99 | /** 100 | * @return the outputArtNet 101 | */ 102 | public final boolean isOutputArtNet() { 103 | return outputArtNet; 104 | } 105 | 106 | /** 107 | * @param outputArtNet the outputArtNet to set 108 | */ 109 | public final void setOutputArtNet(final boolean outputArtNet) { 110 | this.outputArtNet = outputArtNet; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/enums/ArtPollReplyStrategyEnum.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.enums; 17 | 18 | /** 19 | * Diagnostic messages enumeration. 20 | * @author Corentin Azelart. 21 | * 22 | */ 23 | public enum ArtPollReplyStrategyEnum { 24 | 25 | /** 26 | * 0 = Only send ArtPollReply in 27 | * response to an ArtPoll or ArtAddress. 28 | */ 29 | ALWAYS, 30 | 31 | /** 32 | * 1 = Send ArtPollReply whenever Node conditions change. 33 | * This selection allows the Controller to be informed 34 | * of changes without the need to continuously poll. 35 | */ 36 | ONLYCHANGE 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/enums/DiagnosticMessageEnum.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.enums; 17 | 18 | /** 19 | * Diagnostic messages enumeration. 20 | * @author Corentin Azelart. 21 | * 22 | */ 23 | public enum DiagnosticMessageEnum { 24 | 25 | /** 0 = Diagnostics messages are broadcast. (if bit 2). */ 26 | BROADCAST, 27 | 28 | /** 1 = Diagnostics messages are unicast. (if bit 2). */ 29 | UNICAST 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/enums/DiagnosticMessageEnumAvailable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.enums; 17 | 18 | /** 19 | * Diagnostic messages enumeration. 20 | * @author Corentin Azelart. 21 | * 22 | */ 23 | public enum DiagnosticMessageEnumAvailable { 24 | 25 | /** 26 | * 0 = Do not send me diagnostics messages. 27 | */ 28 | NOSEND, 29 | 30 | /** 31 | * 1 = Send me diagnostics messages. 32 | */ 33 | SEND 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/enums/IndicatorStateEnum.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.enums; 17 | 18 | /** 19 | * Indicator state. 20 | * @author Corentin Azelart. 21 | * 22 | */ 23 | public enum IndicatorStateEnum { 24 | 25 | /** Unknow. */ 26 | UNKNOW, 27 | 28 | /** Locate mode. */ 29 | LOCATE_MODE, 30 | 31 | /** Mute mode. */ 32 | MUTE_MODE, 33 | 34 | /** Normal mode. */ 35 | NORMAL_MODE, 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/enums/NetworkCommunicationTypeEnum.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.enums; 17 | 18 | /** 19 | * Communication Type Enumeration. 20 | * @author Corentin Azelart. 21 | * 22 | */ 23 | public enum NetworkCommunicationTypeEnum { 24 | 25 | /** BROADCAST. */ 26 | BROADCAST, 27 | 28 | /** UNICAST. */ 29 | UNICAST, 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/enums/PortInputOutputEnum.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.enums; 17 | 18 | /** 19 | * A port can input, output or both. 20 | * @author Corentin Azelart. 21 | * 22 | */ 23 | public enum PortInputOutputEnum { 24 | 25 | /** Input port. */ 26 | INPUT, 27 | 28 | /** Output port. */ 29 | OUTPUT, 30 | 31 | /** Both. */ 32 | BOTH 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/enums/PortTypeEnum.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.enums; 17 | 18 | /** 19 | * Port Type Enumeration. 20 | * @author Corentin Azelart. 21 | * 22 | */ 23 | public enum PortTypeEnum { 24 | 25 | /** DMX512 Protocol. */ 26 | DMX512, 27 | 28 | /** MIDI Protocol. */ 29 | MIDI, 30 | 31 | /** AVAB Protocol. */ 32 | AVAB, 33 | 34 | /** COLORTRANCMX Protocol. */ 35 | COLORTRANCMX, 36 | 37 | /** ADB Protocol. */ 38 | ADB, 39 | 40 | /** ARTNET Protocol. */ 41 | ARTNET 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/enums/PriorityCodesEnum.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.enums; 17 | 18 | /** 19 | * Priority code (table 5). 20 | * @author Corentin Azelart. 21 | * 22 | */ 23 | public enum PriorityCodesEnum { 24 | 25 | /** Low. */ 26 | DP_LOW, 27 | 28 | /** Medium. */ 29 | DP_MEDIUM, 30 | 31 | /** High. */ 32 | DP_HIGH, 33 | 34 | /** Critical. */ 35 | DP_CRITICAL, 36 | 37 | /** Volatile (just displayed on one line). */ 38 | DP_VOLATILE, 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/domain/enums/UniverseAddressProgrammingAuthorityEnum.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.domain.enums; 17 | 18 | /** 19 | * Universe Address Programming Authority. 20 | * @author Corentin Azelart. 21 | * 22 | */ 23 | public enum UniverseAddressProgrammingAuthorityEnum { 24 | 25 | /** Universe Programming Authority unknown. */ 26 | UNKNOW, 27 | 28 | /** Set by Front panel. */ 29 | FRONT_PANEL, 30 | 31 | /** Set by network. */ 32 | NETWORK, 33 | 34 | /** Not in use. */ 35 | NOT_USED, 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/listeners/ArtNetPacketListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.listeners; 17 | 18 | import java.util.EventListener; 19 | 20 | import fr.azelart.artnetstack.domain.artaddress.ArtAddress; 21 | import fr.azelart.artnetstack.domain.artdmx.ArtDMX; 22 | import fr.azelart.artnetstack.domain.artnet.ArtNetObject; 23 | import fr.azelart.artnetstack.domain.artpoll.ArtPoll; 24 | import fr.azelart.artnetstack.domain.artpollreply.ArtPollReply; 25 | import fr.azelart.artnetstack.domain.arttimecode.ArtTimeCode; 26 | 27 | /** 28 | * The list of availables methods on recept ArtNetPacket. 29 | * @author Corentin Azelart. 30 | */ 31 | public interface ArtNetPacketListener extends EventListener { 32 | 33 | /** 34 | * We have receive an ArtNet object (this is a ArtNet packet). 35 | * @param artNetObject is the artNet object 36 | */ 37 | void onArt(ArtNetObject artNetObject); 38 | 39 | /** 40 | * We have receive an ArtPoll packet. 41 | * @param artPoll is the object 42 | */ 43 | void onArtPoll(ArtPoll artPoll); 44 | 45 | /** 46 | * We have receive an ArtPolLReply packet. 47 | * @param artPollReply is the artPollReply object 48 | */ 49 | void onArtPollReply(ArtPollReply artPollReply); 50 | 51 | /** 52 | * We have receive an ArtTimeCode packet. 53 | * @param artTimeCode is the artTimeCode object 54 | */ 55 | void onArtTimeCode(ArtTimeCode artTimeCode); 56 | 57 | /** 58 | * We have receive an ArtDMX packet. 59 | * @param artDMX is the artDMX packet 60 | */ 61 | void onArtDMX(ArtDMX artDMX); 62 | 63 | /** 64 | * We have receive an ArtAddress packet. 65 | * @param artAddress is the ArtAddress packet 66 | */ 67 | void onArtAddress(ArtAddress artAddress); 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/listeners/ServerListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.listeners; 17 | 18 | /** 19 | * Server listeners. 20 | * @author Corentin Azelart. 21 | * 22 | */ 23 | public interface ServerListener { 24 | 25 | /** Server is connected. */ 26 | void onConnect(); 27 | 28 | /** Server is disconnected and is off (thread is die). */ 29 | void onTerminate(); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/runners/ExampleServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.runners; 17 | 18 | import fr.azelart.artnetstack.constants.Constants; 19 | import fr.azelart.artnetstack.domain.artaddress.ArtAddress; 20 | import fr.azelart.artnetstack.domain.artdmx.ArtDMX; 21 | import fr.azelart.artnetstack.domain.artnet.ArtNetObject; 22 | import fr.azelart.artnetstack.domain.artpoll.ArtPoll; 23 | import fr.azelart.artnetstack.domain.artpollreply.ArtPollReply; 24 | import fr.azelart.artnetstack.domain.arttimecode.ArtTimeCode; 25 | import fr.azelart.artnetstack.domain.controller.Controller; 26 | import fr.azelart.artnetstack.domain.controller.ControllerGoodInput; 27 | import fr.azelart.artnetstack.domain.controller.ControllerGoodOutput; 28 | import fr.azelart.artnetstack.domain.controller.ControllerPortType; 29 | import fr.azelart.artnetstack.domain.enums.PortInputOutputEnum; 30 | import fr.azelart.artnetstack.domain.enums.PortTypeEnum; 31 | import fr.azelart.artnetstack.listeners.ArtNetPacketListener; 32 | import fr.azelart.artnetstack.listeners.ServerListener; 33 | import fr.azelart.artnetstack.server.ArtNetServer; 34 | 35 | import java.io.IOException; 36 | import java.net.InetAddress; 37 | import java.net.SocketException; 38 | import java.net.UnknownHostException; 39 | import java.util.HashMap; 40 | import java.util.Map; 41 | 42 | /** 43 | * Server Runner. 44 | * @author Corentin Azelart 45 | * 46 | */ 47 | public class ExampleServer { 48 | private static Controller thisControler; 49 | 50 | private static void createControler() { 51 | thisControler = new Controller(); 52 | 53 | // Create one port 54 | final Map vPorts = new HashMap(); 55 | ControllerPortType vPort1 = new ControllerPortType(); 56 | vPort1.setInputArtNet( true ); 57 | vPort1.setOutputArtNet( true ); 58 | vPort1.setPort( 0 ); 59 | vPort1.setType( PortTypeEnum.DMX512 ); 60 | vPort1.setDirection( PortInputOutputEnum.BOTH ); 61 | vPorts.put(0, vPort1); 62 | 63 | // Set status port1 input 64 | final Map vGoodInputsMap = new HashMap(); 65 | ControllerGoodInput vGoodInput1 = new ControllerGoodInput(); 66 | vGoodInput1.setDisabled( false ); 67 | vGoodInput1.setDataReceived( true ); 68 | vGoodInput1.setIncludeDMXSIPsPackets( true ); 69 | vGoodInput1.setIncludeDMXTestPackets( true ); 70 | vGoodInput1.setIncludeDMXTextPackets( true ); 71 | vGoodInput1.setReceivedDataError( false ); 72 | vGoodInputsMap.put(0, vGoodInput1); 73 | 74 | // Set status port1 output 75 | final Map vGoodOutputsMap = new HashMap(); 76 | ControllerGoodOutput vGoodOutput1 = new ControllerGoodOutput(); 77 | vGoodOutput1.setDataTransmited( true ); 78 | vGoodOutput1.setOutputPowerOn( true ); 79 | vGoodOutput1.setOutputMergeArtNet( false ); 80 | vGoodOutput1.setMergeLTP( false ); 81 | vGoodOutput1.setIncludeDMXTextPackets( false ); 82 | vGoodOutput1.setIncludeDMXTestPackets( false ); 83 | vGoodOutput1.setIncludeDMXSIPsPackets( false ); 84 | vGoodOutputsMap.put(0, vGoodOutput1); 85 | 86 | // Display 87 | thisControler.setScreen( false ); 88 | 89 | thisControler.setGoodOutputMapping( vGoodOutputsMap ); 90 | thisControler.setGoodInputMapping(vGoodInputsMap); 91 | thisControler.setPortTypeMap(vPorts); 92 | 93 | // Network 94 | thisControler.setNetwork(0x00); 95 | thisControler.setSubNetwork(0x0D); 96 | } 97 | 98 | /** 99 | * Start program method. 100 | * @param args 101 | */ 102 | public static void main(String[] args) throws IOException { 103 | final ArtNetServer artNetServer; 104 | createControler(); 105 | 106 | 107 | try { 108 | artNetServer = new ArtNetServer( 109 | InetAddress.getLocalHost(), 110 | InetAddress.getLocalHost(), 111 | Constants.DEFAULT_ART_NET_UDP_PORT 112 | ); 113 | 114 | // Server listener 115 | artNetServer.addListenerServer( new ServerListener() { 116 | public void onConnect() { 117 | System.out.println("Connected"); 118 | } 119 | 120 | public void onTerminate() { 121 | System.out.println("Disconnected"); 122 | } 123 | } ); 124 | 125 | // Packet Listener 126 | artNetServer.addListenerPacket( new ArtNetPacketListener() { 127 | 128 | 129 | /** 130 | * We receive an ArtPoll packet. 131 | */ 132 | public void onArtPoll(ArtPoll artPoll) { 133 | System.out.println(artPoll); 134 | } 135 | 136 | /** 137 | * We receive an ArtTimeCode packet. 138 | */ 139 | @Override 140 | public void onArtTimeCode(ArtTimeCode artTimeCode) { 141 | System.out.println(artTimeCode); 142 | } 143 | 144 | @Override 145 | public void onArtPollReply(ArtPollReply artPollReply) { 146 | System.out.println(artPollReply); 147 | } 148 | 149 | @Override 150 | public void onArt(ArtNetObject artNetObject) { 151 | System.out.println( artNetObject ); 152 | } 153 | 154 | @Override 155 | public void onArtDMX(ArtDMX artDMX) { 156 | System.out.println( artDMX ); 157 | } 158 | 159 | @Override 160 | public void onArtAddress(ArtAddress artAddress) { 161 | System.out.println( artAddress ); 162 | } 163 | } ); 164 | 165 | artNetServer.start(); 166 | 167 | /** 168 | * Configure a time code for example. 169 | */ 170 | /* 171 | final Timer timer = new Timer(); 172 | timer.scheduleAtFixedRate(new TimeCodeTask(artNetServer, ArtTimeCodeType.SMPTE), 0, 1000); 173 | */ 174 | 175 | 176 | } catch (SocketException e) { 177 | e.printStackTrace(); 178 | } catch (UnknownHostException e) { 179 | e.printStackTrace(); 180 | } 181 | 182 | 183 | } 184 | 185 | } 186 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/server/ArtNetServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.server; 17 | 18 | import fr.azelart.artnetstack.constants.Constants; 19 | import fr.azelart.artnetstack.domain.artaddress.ArtAddress; 20 | import fr.azelart.artnetstack.domain.artdmx.ArtDMX; 21 | import fr.azelart.artnetstack.domain.artnet.ArtNetObject; 22 | import fr.azelart.artnetstack.domain.artpoll.ArtPoll; 23 | import fr.azelart.artnetstack.domain.artpollreply.ArtPollReply; 24 | import fr.azelart.artnetstack.domain.arttimecode.ArtTimeCode; 25 | import fr.azelart.artnetstack.listeners.ArtNetPacketListener; 26 | import fr.azelart.artnetstack.listeners.ServerListener; 27 | import fr.azelart.artnetstack.utils.ArtNetPacketDecoder; 28 | 29 | import java.io.IOException; 30 | import java.net.DatagramPacket; 31 | import java.net.DatagramSocket; 32 | import java.net.InetAddress; 33 | import java.net.InterfaceAddress; 34 | import java.net.MulticastSocket; 35 | import java.net.NetworkInterface; 36 | import java.net.SocketException; 37 | import java.net.UnknownHostException; 38 | import java.util.ArrayList; 39 | import java.util.Enumeration; 40 | import java.util.List; 41 | 42 | /** 43 | * A Thread for the server. 44 | * @author Corentin Azelart. 45 | * 46 | */ 47 | public class ArtNetServer extends Thread implements Runnable { 48 | 49 | /** 50 | * Socket communication. 51 | */ 52 | private final DatagramSocket datagramSocket; 53 | 54 | /** 55 | * Listeners for packets. 56 | */ 57 | private final List listenersListPacket; 58 | 59 | /** 60 | * Listeners for server. 61 | */ 62 | private final List listenersListServer; 63 | 64 | /** 65 | * Broadcast IP. 66 | */ 67 | private InetAddress listenAddress; 68 | 69 | /** 70 | * Broadcast IP. 71 | */ 72 | private InetAddress broadcastAddress; 73 | 74 | /** 75 | * Port. 76 | */ 77 | private final int port; 78 | 79 | /** 80 | * Running. 81 | */ 82 | private boolean running = false; 83 | 84 | /** 85 | * Creates an ArtNet server for the given addresses. 86 | * 87 | * @param listenAddress The address to bind the receiving socket to. {@code null} will bind to the local wildcard 88 | * address (0.0.0.0). 89 | * 90 | * @param broadcastAddress The address to send ArtNet packets to, either a specific IP or the broadcast address 91 | * for the interface connected to other nodes. Use {@link #broadcastAddressFor(java.net.InetAddress)} 92 | * to determine the broadcast address associated with a local ip. 93 | * 94 | * @param port The UDP port to send packets to. The default ArtNet port is {@value Constants#DEFAULT_ART_NET_UDP_PORT}. 95 | * 96 | * @throws SocketException 97 | * @throws UnknownHostException 98 | */ 99 | public ArtNetServer( 100 | final InetAddress listenAddress, 101 | final InetAddress broadcastAddress, 102 | final int port 103 | ) throws IOException { 104 | this.port = port; 105 | this.listenAddress = listenAddress; 106 | this.broadcastAddress = broadcastAddress; 107 | 108 | listenersListPacket = new ArrayList(); 109 | listenersListServer = new ArrayList(); 110 | 111 | datagramSocket = new MulticastSocket(port); 112 | } 113 | 114 | /** 115 | * Server execution. 116 | */ 117 | @Override 118 | public final void run() { 119 | // Define inputDatagramPacket 120 | DatagramPacket inputDatagramPacket = null; 121 | 122 | // Define input byte buffer 123 | final byte[] inputBuffer = new byte[Constants.SERVER_BUFFER_INPUT]; 124 | 125 | // We inform than server is ready 126 | running = true; 127 | fireServerConnect(); 128 | 129 | // ArtNet object 130 | ArtNetObject vArtNetObject = null; 131 | 132 | while (running) { 133 | inputDatagramPacket = new DatagramPacket(inputBuffer, inputBuffer.length); 134 | try { 135 | datagramSocket.receive(inputDatagramPacket); 136 | vArtNetObject = ArtNetPacketDecoder.decodeArtNetPacket(inputDatagramPacket.getData(), inputDatagramPacket.getAddress()); 137 | 138 | // It's realy an artnet packet. 139 | if (vArtNetObject != null) { 140 | fireArtNet(vArtNetObject); 141 | if (vArtNetObject instanceof ArtPoll) { 142 | // ArtPollPacket 143 | fireArtPoll((ArtPoll) vArtNetObject); 144 | } else if (vArtNetObject instanceof ArtTimeCode) { 145 | // ArtTimeCodePacket 146 | fireArtTimeCode((ArtTimeCode) vArtNetObject); 147 | } else if (vArtNetObject instanceof ArtPollReply) { 148 | // ArtPollReply 149 | fireArtPollReply((ArtPollReply) vArtNetObject); 150 | } else if (vArtNetObject instanceof ArtDMX) { 151 | // ArtDMX 152 | fireArtDMXReply((ArtDMX) vArtNetObject); 153 | } else if (vArtNetObject instanceof ArtAddress) { 154 | // ArtAddress 155 | fireArtAddressReply((ArtAddress) vArtNetObject); 156 | } 157 | } 158 | } catch (final Exception e) { 159 | e.getMessage(); 160 | e.printStackTrace(); 161 | } 162 | } 163 | } 164 | 165 | /** 166 | * Determines the broadcast address used by the interface which owns the given ip address. The given IP must 167 | * be one representing the local machine. 168 | * 169 | * @param inetAddress The address 170 | * @return The broadcast address for the interface owning the given address 171 | * @throws SocketException 172 | */ 173 | public static InetAddress broadcastAddressFor(final InetAddress inetAddress) throws SocketException { 174 | final Enumeration allInterfaces = NetworkInterface.getNetworkInterfaces(); 175 | 176 | while (allInterfaces.hasMoreElements()) { 177 | final NetworkInterface networkInterface = allInterfaces.nextElement(); 178 | 179 | for (final InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) { 180 | if (interfaceAddress.getAddress().getHostAddress().equals(inetAddress.getHostAddress())) { 181 | 182 | if (interfaceAddress.getBroadcast() == null) { 183 | throw new IllegalArgumentException( 184 | "Broadcast address for " + networkInterface + ", which owns " + inetAddress + " is null. " + 185 | "Try a different interface." 186 | ); 187 | } 188 | 189 | return interfaceAddress.getBroadcast(); 190 | } 191 | } 192 | } 193 | 194 | throw new IllegalArgumentException("No interface has address " + inetAddress); 195 | } 196 | 197 | /** 198 | * Stop server. 199 | */ 200 | public final void stopServer() { 201 | running = false; 202 | datagramSocket.disconnect(); 203 | datagramSocket.close(); 204 | fireServerTerminate(); 205 | } 206 | 207 | /** 208 | * Check if server is running. 209 | * @return yes if he run 210 | */ 211 | public final boolean isRunning() { 212 | return running; 213 | } 214 | 215 | /** 216 | * Send a packet. 217 | * @param bytes is the packet data 218 | * @throws IOException if we can't send packet 219 | */ 220 | public final void sendPacket( byte[] bytes ) throws IOException { 221 | if(datagramSocket!=null) { 222 | final DatagramPacket packet = new DatagramPacket( 223 | bytes, 224 | bytes.length, 225 | broadcastAddress, 226 | port 227 | ); 228 | datagramSocket.send( packet ); 229 | } 230 | } 231 | 232 | /** 233 | * We add an listener. 234 | * @param serverListener is a server listener 235 | */ 236 | public final void addListenerServer(final ServerListener serverListener) { 237 | this.listenersListServer.add(serverListener); 238 | } 239 | 240 | /** 241 | * Server is connected. 242 | */ 243 | public final void fireServerConnect() { 244 | for (final ServerListener listener : this.listenersListServer) { 245 | listener.onConnect(); 246 | } 247 | } 248 | 249 | /** 250 | * Server is die. 251 | */ 252 | public final void fireServerTerminate() { 253 | for (final ServerListener listener : this.listenersListServer) { 254 | listener.onTerminate(); 255 | } 256 | } 257 | 258 | /** 259 | * We add a listener. 260 | * @param artNetPacketListener is the artnet packet. 261 | */ 262 | public final void addListenerPacket(final ArtNetPacketListener artNetPacketListener) { 263 | this.listenersListPacket.add(artNetPacketListener); 264 | } 265 | 266 | /** 267 | * A new ArtNetObject incoming. 268 | * @param artNetObject is the artPollPacket 269 | */ 270 | private void fireArtNet(final ArtNetObject artNetObject) { 271 | for (final ArtNetPacketListener listener : this.listenersListPacket) { 272 | listener.onArt(artNetObject); 273 | } 274 | } 275 | 276 | /** 277 | * A new ArtPollPacket incoming. 278 | * @param artPoll is the artPollPacket 279 | */ 280 | public final void fireArtPoll(final ArtPoll artPoll) { 281 | for (final ArtNetPacketListener listener : this.listenersListPacket) { 282 | listener.onArtPoll(artPoll); 283 | } 284 | } 285 | 286 | /** 287 | * A new ArtTimeCode incoming. 288 | * @param artTimeCode is the instance of the artTimeCodePacket 289 | */ 290 | public final void fireArtTimeCode(final ArtTimeCode artTimeCode) { 291 | for (final ArtNetPacketListener listener : this.listenersListPacket) { 292 | listener.onArtTimeCode(artTimeCode); 293 | } 294 | } 295 | 296 | /** 297 | * A new ArtPollReply incoming. 298 | * @param artPollReply is the instance of the artPollReplyPacket 299 | */ 300 | public final void fireArtPollReply(final ArtPollReply artPollReply) { 301 | for (final ArtNetPacketListener listener : this.listenersListPacket) { 302 | listener.onArtPollReply(artPollReply); 303 | } 304 | } 305 | 306 | /** 307 | * A new ArtDMX incoming. 308 | * @param artDMX is the instance of the artDMX pakcet 309 | */ 310 | public final void fireArtDMXReply(final ArtDMX artDMX) { 311 | for (final ArtNetPacketListener listener : this.listenersListPacket) { 312 | listener.onArtDMX(artDMX); 313 | } 314 | } 315 | 316 | /** 317 | * A new ArtAddress incoming. 318 | * @param artAddress is the instance of the artAddress pakcet 319 | */ 320 | public final void fireArtAddressReply(final ArtAddress artAddress) { 321 | for (final ArtNetPacketListener listener : this.listenersListPacket) { 322 | listener.onArtAddress(artAddress); 323 | } 324 | } 325 | 326 | /** 327 | * @return the port 328 | */ 329 | public final int getPort() { 330 | return port; 331 | } 332 | } 333 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/utils/ArtNetPacketDecoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.utils; 17 | 18 | import java.net.InetAddress; 19 | import java.net.UnknownHostException; 20 | 21 | import fr.azelart.artnetstack.constants.Constants; 22 | import fr.azelart.artnetstack.constants.MagicNumbers; 23 | import fr.azelart.artnetstack.constants.OpCodeConstants; 24 | import fr.azelart.artnetstack.domain.artaddress.ArtAddress; 25 | import fr.azelart.artnetstack.domain.artdmx.ArtDMX; 26 | import fr.azelart.artnetstack.domain.artnet.ArtNetObject; 27 | import fr.azelart.artnetstack.domain.artpoll.ArtPoll; 28 | import fr.azelart.artnetstack.domain.artpollreply.ArtPollReply; 29 | import fr.azelart.artnetstack.domain.artpollreply.ArtPollReplyOutputPortStatus; 30 | import fr.azelart.artnetstack.domain.artpollreply.ArtPollReplyStatus; 31 | import fr.azelart.artnetstack.domain.arttimecode.ArtTimeCode; 32 | import fr.azelart.artnetstack.domain.arttimecode.ArtTimeCodeType; 33 | import fr.azelart.artnetstack.domain.enums.IndicatorStateEnum; 34 | import fr.azelart.artnetstack.domain.enums.NetworkCommunicationTypeEnum; 35 | import fr.azelart.artnetstack.domain.enums.UniverseAddressProgrammingAuthorityEnum; 36 | 37 | /** 38 | * ArtNetPacket decoder. 39 | * @author Corentin Azelart. 40 | */ 41 | public class ArtNetPacketDecoder { 42 | 43 | /** 44 | * Private constructor. 45 | */ 46 | private ArtNetPacketDecoder() { 47 | super(); 48 | } 49 | 50 | /** 51 | * Decode an ArtNet packet. 52 | * @param packet is the packet. 53 | * @param ip is the ip of source. 54 | * @return a ArtNetObject than be cast in correct format 55 | */ 56 | public static ArtNetObject decodeArtNetPacket(final byte[] packet, final InetAddress ip) { 57 | 58 | // The ArtNetPacket. 59 | final ArtNetObject artNetObject = null; 60 | 61 | // Set generals infos 62 | final String hexaBrut = byteArrayToHex(packet); 63 | final String id = new String(packet, 0, 7); 64 | 65 | // Extract OpCode 66 | int opCode = ((packet[9] & 0xFF) << 8) | (packet[8] & 0xFF); 67 | opCode = Integer.parseInt(Integer.toHexString(opCode)); 68 | 69 | // Yes, it's a ArtNetPacket 70 | if (!"Art-Net".equals(id)) { 71 | return null; 72 | } 73 | 74 | /* 75 | * Dicover the type of the packet. 76 | * Please refer to OpcodeTable. 77 | */ 78 | if (OpCodeConstants.OPPOLL == opCode) { 79 | /* 80 | * ArtPollPacket : This is an ArtPoll packet, 81 | * no other data is contained in this UDP packet 82 | */ 83 | if (!checkVersion(packet, hexaBrut)) { 84 | return null; 85 | } 86 | return decodeArtPollPacket(packet, hexaBrut); 87 | } else if (OpCodeConstants.OPTIMECODE == opCode) { 88 | /* 89 | * ArtTimePacket : OpTimeCode 90 | * This is an ArtTimeCode packet. 91 | * It is used to transport time code over the network. 92 | */ 93 | if (!checkVersion(packet, hexaBrut)) { 94 | return null; 95 | } 96 | return decodeArtTimeCodePacket(packet, hexaBrut); 97 | } else if (OpCodeConstants.OPPOLLREPLY == opCode) { 98 | // ArtPollReply : This is a ArtPollReply packet. 99 | return decodeArtPollReplyPacket(packet, hexaBrut, ip); 100 | } else if (OpCodeConstants.OPOUTPUT == opCode) { 101 | // ArtDMX 102 | return decodeArtDMXPacket(packet, hexaBrut); 103 | } else if (OpCodeConstants.ARTADDRESS == opCode) { 104 | // ArtAddress 105 | return decodeArtAddressPacket(packet, hexaBrut); 106 | } 107 | 108 | return artNetObject; 109 | } 110 | 111 | /** 112 | * Decode an artPollReplyPacket. 113 | * @param bytes is the packet data 114 | * @param hexaBrut is the text data 115 | * @param ip is the address ip 116 | * @return ArtPollReply 117 | */ 118 | private static ArtPollReply decodeArtPollReplyPacket(final byte[] bytes, final String hexaBrut, final InetAddress ip) { 119 | final ArtPollReply artPollReply = new ArtPollReply(); 120 | 121 | // IP Adress (4*8) 122 | final byte[] address = new byte[MagicNumbers.MAGIC_NUMBER_4]; 123 | System.arraycopy(bytes, MagicNumbers.MAGIC_NUMBER_10, address, MagicNumbers.MAGIC_NUMBER_ZERO, MagicNumbers.MAGIC_NUMBER_4); 124 | try { 125 | final InetAddress inetAdress = InetAddress.getByAddress(address); 126 | artPollReply.setIp(inetAdress.getHostAddress()); 127 | } catch (final UnknownHostException e) { 128 | artPollReply.setIp(null); 129 | } 130 | 131 | // Port (2*8) 132 | artPollReply.setPort(ByteUtilsArt.byte2toIn(bytes, MagicNumbers.MAGIC_NUMBER_14)); 133 | 134 | // Version High (1*8) 135 | artPollReply.setVersionH(bytes[MagicNumbers.MAGIC_NUMBER_16]); 136 | 137 | // Version Low (1*8) 138 | artPollReply.setVersionL(bytes[MagicNumbers.MAGIC_NUMBER_15]); 139 | 140 | // Subnet (1*8) and subswtich (1*8) 141 | artPollReply.setSubNet(String.format("%02X", bytes[MagicNumbers.MAGIC_NUMBER_18])); 142 | artPollReply.setSubSwitch(String.format("%02X", bytes[MagicNumbers.MAGIC_NUMBER_19])); 143 | 144 | // Oem Hi (1*8) + Oem (1*8) 145 | artPollReply.setOemHexa(String.format("%02X", bytes[MagicNumbers.MAGIC_NUMBER_20]) + String.format("%02X", bytes[MagicNumbers.MAGIC_NUMBER_21])); 146 | 147 | // UBEA Version (1*8) / 0 if not programmed 148 | artPollReply.setUbeaVersion(bytes[MagicNumbers.MAGIC_NUMBER_22]); 149 | 150 | // Status area 151 | final ArtPollReplyStatus artPollReplyStatus = new ArtPollReplyStatus(); 152 | artPollReplyStatus.setUbeaPresent(ByteUtilsArt.bitIsSet(bytes[MagicNumbers.MAGIC_NUMBER_23] , 0)); 153 | artPollReplyStatus.setRdmCapable(ByteUtilsArt.bitIsSet(bytes[MagicNumbers.MAGIC_NUMBER_23] , 1)); 154 | artPollReplyStatus.setBootRom(ByteUtilsArt.bitIsSet(bytes[MagicNumbers.MAGIC_NUMBER_23] , 2)); 155 | 156 | if (ByteUtilsArt.bitIsSet(bytes[MagicNumbers.MAGIC_NUMBER_23] , MagicNumbers.MAGIC_NUMBER_5) && ByteUtilsArt.bitIsSet(bytes[MagicNumbers.MAGIC_NUMBER_23] , MagicNumbers.MAGIC_NUMBER_4)) { 157 | artPollReplyStatus.setProgrammingAuthority(UniverseAddressProgrammingAuthorityEnum.NOT_USED); 158 | } else if (!ByteUtilsArt.bitIsSet(bytes[MagicNumbers.MAGIC_NUMBER_23] , MagicNumbers.MAGIC_NUMBER_5) && ByteUtilsArt.bitIsSet(bytes[MagicNumbers.MAGIC_NUMBER_23] , MagicNumbers.MAGIC_NUMBER_4)) { 159 | artPollReplyStatus.setProgrammingAuthority(UniverseAddressProgrammingAuthorityEnum.FRONT_PANEL); 160 | } else if (ByteUtilsArt.bitIsSet(bytes[MagicNumbers.MAGIC_NUMBER_23] , MagicNumbers.MAGIC_NUMBER_5) && !ByteUtilsArt.bitIsSet(bytes[MagicNumbers.MAGIC_NUMBER_23] , MagicNumbers.MAGIC_NUMBER_4)) { 161 | artPollReplyStatus.setProgrammingAuthority(UniverseAddressProgrammingAuthorityEnum.NETWORK); 162 | } else if (!ByteUtilsArt.bitIsSet(bytes[MagicNumbers.MAGIC_NUMBER_23] , MagicNumbers.MAGIC_NUMBER_5) && !ByteUtilsArt.bitIsSet(bytes[MagicNumbers.MAGIC_NUMBER_23] , MagicNumbers.MAGIC_NUMBER_4)) { 163 | artPollReplyStatus.setProgrammingAuthority(UniverseAddressProgrammingAuthorityEnum.UNKNOW); 164 | } 165 | 166 | if (ByteUtilsArt.bitIsSet(bytes[MagicNumbers.MAGIC_NUMBER_23] , MagicNumbers.MAGIC_NUMBER_7) && ByteUtilsArt.bitIsSet(bytes[MagicNumbers.MAGIC_NUMBER_23] , MagicNumbers.MAGIC_NUMBER_6)) { 167 | artPollReplyStatus.setIndicatorState(IndicatorStateEnum.NORMAL_MODE); 168 | } else if (!ByteUtilsArt.bitIsSet(bytes[MagicNumbers.MAGIC_NUMBER_23] , MagicNumbers.MAGIC_NUMBER_7) && ByteUtilsArt.bitIsSet(bytes[MagicNumbers.MAGIC_NUMBER_23] , MagicNumbers.MAGIC_NUMBER_6)) { 169 | artPollReplyStatus.setIndicatorState(IndicatorStateEnum.LOCATE_MODE); 170 | } else if (ByteUtilsArt.bitIsSet(bytes[MagicNumbers.MAGIC_NUMBER_23] , MagicNumbers.MAGIC_NUMBER_7) && !ByteUtilsArt.bitIsSet(bytes[MagicNumbers.MAGIC_NUMBER_23] , MagicNumbers.MAGIC_NUMBER_6)) { 171 | artPollReplyStatus.setIndicatorState(IndicatorStateEnum.MUTE_MODE); 172 | } else if (!ByteUtilsArt.bitIsSet(bytes[MagicNumbers.MAGIC_NUMBER_23] , MagicNumbers.MAGIC_NUMBER_7) && !ByteUtilsArt.bitIsSet(bytes[MagicNumbers.MAGIC_NUMBER_23] , MagicNumbers.MAGIC_NUMBER_6)) { 173 | artPollReplyStatus.setIndicatorState(IndicatorStateEnum.UNKNOW); 174 | } 175 | 176 | artPollReply.setArtPollReplyStatus(artPollReplyStatus); 177 | 178 | // EstaManHi (1*8) + EstaManLow (1*8) 179 | artPollReply.setEsta(new String(bytes, MagicNumbers.MAGIC_NUMBER_24, 2)); 180 | 181 | // Short Name 182 | artPollReply.setShortName(new String(bytes, MagicNumbers.MAGIC_NUMBER_26, MagicNumbers.MAGIC_NUMBER_18)); 183 | 184 | // Long Name 185 | artPollReply.setLongName(new String(bytes, MagicNumbers.MAGIC_NUMBER_44, MagicNumbers.MAGIC_NUMBER_64)); 186 | 187 | // Port Output Subswitchs 188 | artPollReply.setOutputSubswitch(new int[]{ 189 | bytes[MagicNumbers.OUTPUT_SUBSWITCH_PORT_1], 190 | bytes[MagicNumbers.OUTPUT_SUBSWITCH_PORT_2], 191 | bytes[MagicNumbers.OUTPUT_SUBSWITCH_PORT_3], 192 | bytes[MagicNumbers.OUTPUT_SUBSWITCH_PORT_4]}); 193 | 194 | // Port Output Subswitchs 195 | artPollReply.setOutputStatus(new ArtPollReplyOutputPortStatus[]{ 196 | new ArtPollReplyOutputPortStatus(bytes[MagicNumbers.OUTPUT_PORT_STATUS_1]), 197 | new ArtPollReplyOutputPortStatus(bytes[MagicNumbers.OUTPUT_PORT_STATUS_2]), 198 | new ArtPollReplyOutputPortStatus(bytes[MagicNumbers.OUTPUT_PORT_STATUS_3]), 199 | new ArtPollReplyOutputPortStatus(bytes[MagicNumbers.OUTPUT_PORT_STATUS_4])}); 200 | 201 | // Real ip 202 | artPollReply.setPhysicalIp(ip.getHostAddress()); 203 | 204 | return artPollReply; 205 | } 206 | 207 | /** 208 | * Decode an artTimeCodePacket. 209 | * @param bytes is the packet data 210 | * @param hexaBrut is the text packet 211 | * @return the ArtPollPacketObject 212 | */ 213 | private static ArtTimeCode decodeArtTimeCodePacket(final byte[] bytes, final String hexaBrut) { 214 | final ArtTimeCode artTimeCode = new ArtTimeCode(); 215 | artTimeCode.setFrameTime(bytes[MagicNumbers.MAGIC_NUMBER_14]); 216 | artTimeCode.setSeconds(bytes[MagicNumbers.MAGIC_NUMBER_15]); 217 | artTimeCode.setMinutes(bytes[MagicNumbers.MAGIC_NUMBER_16]); 218 | artTimeCode.setHours(bytes[MagicNumbers.MAGIC_NUMBER_17]); 219 | final int typeTimecode = bytes[MagicNumbers.MAGIC_NUMBER_18]; 220 | 221 | if (typeTimecode == 0) { 222 | artTimeCode.setArtTimeCodeType(ArtTimeCodeType.FILM); 223 | } else if (typeTimecode == 1) { 224 | artTimeCode.setArtTimeCodeType(ArtTimeCodeType.EBU); 225 | } else if (typeTimecode == 2) { 226 | artTimeCode.setArtTimeCodeType(ArtTimeCodeType.DF); 227 | } else if (typeTimecode == MagicNumbers.MAGIC_NUMBER_3) { 228 | artTimeCode.setArtTimeCodeType(ArtTimeCodeType.SMPTE); 229 | } 230 | return artTimeCode; 231 | } 232 | 233 | /** 234 | * Decode an artPollPacket. 235 | * @param bytes is the packet data 236 | * @param hexaBrut is the text packet 237 | * @return the ArtPollPacketObject 238 | */ 239 | private static ArtPoll decodeArtPollPacket(final byte[] bytes, final String hexaBrut) { 240 | final ArtPoll artPoll = new ArtPoll(); 241 | 242 | artPoll.setArtPollReplyWhenConditionsChanges(ByteUtilsArt.bitIsSet(bytes[MagicNumbers.MAGIC_NUMBER_12], 1)); 243 | artPoll.setSendMeDiagnosticsMessage(ByteUtilsArt.bitIsSet(bytes[MagicNumbers.MAGIC_NUMBER_12], 2)); 244 | 245 | if (ByteUtilsArt.bitIsSet(bytes[MagicNumbers.MAGIC_NUMBER_12], MagicNumbers.MAGIC_NUMBER_3)) { 246 | artPoll.setNetworkCommunicationTypeDiagnosticsMessages(NetworkCommunicationTypeEnum.UNICAST); 247 | } else { 248 | artPoll.setNetworkCommunicationTypeDiagnosticsMessages(NetworkCommunicationTypeEnum.BROADCAST); 249 | } 250 | 251 | return artPoll; 252 | } 253 | 254 | /** 255 | * Decode an artDMX packet. 256 | * @param bytes is the packet data 257 | * @param hexaBrut is hexa packet 258 | * @return an ArtDMX packet. 259 | */ 260 | private static ArtDMX decodeArtDMXPacket(final byte[] bytes, final String hexaBrut) { 261 | final ArtDMX artDMX = new ArtDMX(); 262 | 263 | // Sequence (1*8) 264 | artDMX.setSequence(bytes[MagicNumbers.MAGIC_NUMBER_12] & Constants.INT_ESCAP); 265 | 266 | // Physical (1*8) 267 | artDMX.setPhysicalPort(bytes[MagicNumbers.MAGIC_NUMBER_13] & Constants.INT_ESCAP); 268 | 269 | // Subnet (1*8) and subswtich (1*8) 270 | artDMX.setSubNet(String.format("%02X", bytes[MagicNumbers.MAGIC_NUMBER_14])); 271 | artDMX.setSubSwitch(String.format("%02X", bytes[MagicNumbers.MAGIC_NUMBER_15])); 272 | 273 | // Length of DMX data (1*8) 274 | artDMX.setLengthHi(bytes[MagicNumbers.MAGIC_NUMBER_16] & Constants.INT_ESCAP); 275 | 276 | // Low Byte of above. (1*8) 277 | artDMX.setLength(bytes[MagicNumbers.MAGIC_NUMBER_17] & Constants.INT_ESCAP); 278 | 279 | // An variable length array of DMX512 lighting data 280 | final byte[] dmx = new byte[Constants.DMX_512_SIZE]; 281 | System.arraycopy(bytes, MagicNumbers.MAGIC_NUMBER_18, dmx, 0, Constants.DMX_512_SIZE); 282 | artDMX.setData(byteArrayToIntArray(dmx)); 283 | 284 | return artDMX; 285 | } 286 | 287 | /** 288 | * Decode an ArtAddress packet, we can only set : 289 | * - Short name 290 | * - Long name 291 | * @param bytes is the packet. 292 | * @param hexaBrut is the packet on hexa format. 293 | * @return an ArtAddress 294 | */ 295 | private static ArtAddress decodeArtAddressPacket(final byte[] bytes, final String hexaBrut) { 296 | final ArtAddress artAddress = new ArtAddress(); 297 | 298 | 299 | 300 | return artAddress; 301 | } 302 | 303 | 304 | /** 305 | * Check the version of artnet. 306 | * @param packet is the packet 307 | * @param hexaBrut is the text packet 308 | * @return true if the is the correct version of ArtNet protocol 309 | */ 310 | private static boolean checkVersion(final byte[] packet, final String hexaBrut) { 311 | final int version = packet[MagicNumbers.MAGIC_NUMBER_11]; 312 | return (version >= Constants.ART_NET_VERSION); 313 | } 314 | 315 | /** 316 | * Convert byte to hexa. 317 | * @param barray is the byte array. 318 | * @return the String in hexa value 319 | */ 320 | private static String byteArrayToHex(final byte[] barray) { 321 | final char[] c = new char[barray.length * 2]; 322 | byte b; 323 | for (int i = 0; i < barray.length; ++i) { 324 | b = ((byte) (barray[i] >> MagicNumbers.MAGIC_NUMBER_4)); 325 | c[i * 2] = (char) (b > MagicNumbers.MAGIC_NUMBER_9 ? b + 0x37 : b + 0x30); 326 | b = ((byte) (barray[i] & 0xF)); 327 | c[i * 2 + 1] = (char) (b > 9 ? b + 0x37 : b + 0x30); 328 | } 329 | 330 | return new String(c); 331 | } 332 | 333 | /** 334 | * Transform a byte array to int array. 335 | * @param in a array in bytes 336 | * @return a array in int 337 | */ 338 | private static int[] byteArrayToIntArray(final byte[] in) { 339 | final int[] output = new int[in.length]; 340 | for (int i = 0; i != in.length; i++) { 341 | output[i] = in[i] & Constants.INT_ESCAP; 342 | } 343 | return output; 344 | } 345 | } 346 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/utils/ArtNetPacketEncoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.utils; 17 | 18 | import fr.azelart.artnetstack.constants.Constants; 19 | import fr.azelart.artnetstack.constants.MagicNumbers; 20 | import fr.azelart.artnetstack.domain.arttimecode.ArtTimeCode; 21 | import fr.azelart.artnetstack.domain.controller.Controller; 22 | import fr.azelart.artnetstack.domain.controller.ControllerGoodInput; 23 | import fr.azelart.artnetstack.domain.controller.ControllerGoodOutput; 24 | import fr.azelart.artnetstack.domain.controller.ControllerPortType; 25 | import fr.azelart.artnetstack.domain.enums.PortInputOutputEnum; 26 | import fr.azelart.artnetstack.domain.enums.PortTypeEnum; 27 | 28 | import java.io.ByteArrayOutputStream; 29 | import java.io.IOException; 30 | import java.net.InetAddress; 31 | import java.util.BitSet; 32 | import java.util.Map; 33 | 34 | /** 35 | * Encoder for ArtNet Packets. 36 | * 37 | * @author Corentin Azelart 38 | */ 39 | public final class ArtNetPacketEncoder { 40 | 41 | /** 42 | * ArtPollCounter. 43 | */ 44 | private static volatile int artPollCounter = 1; 45 | 46 | /** 47 | * ArtDmxCounter. 48 | */ 49 | private static volatile int artDmxCounter = 1; 50 | 51 | /** 52 | * Private constructor to respect checkstyle and protect class. 53 | */ 54 | private ArtNetPacketEncoder() { 55 | super(); 56 | } 57 | 58 | /** 59 | * Encode an ArtPoll packet. 60 | * 61 | * @param controller is the controller 62 | * @return the ArtPollPacket in array 63 | * @throws IOException is the OutputStream have problem 64 | */ 65 | public static byte[] encodeArtPollPacket(final Controller controller) throws IOException { 66 | final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 67 | byteArrayOutputStream.write(ByteUtils.toByta(Constants.ID)); 68 | byteArrayOutputStream.write(MagicNumbers.MAGIC_NUMBER_ZERO); 69 | byteArrayOutputStream.write(MagicNumbers.MAGIC_NUMBER_ZERO); 70 | byteArrayOutputStream.write(MagicNumbers.MAGIC_NUMBER_32); 71 | byteArrayOutputStream.write(MagicNumbers.MAGIC_NUMBER_ZERO); 72 | byteArrayOutputStream.write(new Integer(Constants.ART_NET_VERSION).byteValue()); 73 | byteArrayOutputStream.write(MagicNumbers.MAGIC_NUMBER_6); // TalkToMe 74 | byteArrayOutputStream.write(MagicNumbers.MAGIC_NUMBER_ZERO); // Filler 75 | return byteArrayOutputStream.toByteArray(); 76 | } 77 | 78 | /** 79 | * Encode an ArtTimeCode packet. 80 | * 81 | * @param artTimeCode is timecode informations 82 | * @return the ArtTimeCode in array 83 | * @throws IOException in error with byte array 84 | */ 85 | public static byte[] encodeArtTimeCodePacket(final ArtTimeCode artTimeCode) throws IOException { 86 | final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 87 | 88 | // ID. 89 | byteArrayOutputStream.write(ByteUtils.toByta(Constants.ID)); 90 | byteArrayOutputStream.write(MagicNumbers.MAGIC_NUMBER_ZERO); 91 | 92 | // OpTimeCode 93 | byteArrayOutputStream.write(ByteUtilsArt.in16toByte(38656)); 94 | 95 | // Version 96 | byteArrayOutputStream.write(MagicNumbers.MAGIC_NUMBER_ZERO); 97 | byteArrayOutputStream.write(new Integer(Constants.ART_NET_VERSION).byteValue()); 98 | 99 | // Filler 1 and 2 100 | byteArrayOutputStream.write(MagicNumbers.MAGIC_NUMBER_ZERO); 101 | byteArrayOutputStream.write(MagicNumbers.MAGIC_NUMBER_ZERO); 102 | 103 | // Frame 104 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(artTimeCode.getFrameTime())); 105 | 106 | // Seconds 107 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(artTimeCode.getSeconds())); 108 | 109 | // Minutes 110 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(artTimeCode.getMinutes())); 111 | 112 | // Hours 113 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(artTimeCode.getHours())); 114 | 115 | // Type 116 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(artTimeCode.getArtTimeCodeType().ordinal())); 117 | 118 | return byteArrayOutputStream.toByteArray(); 119 | } 120 | 121 | /** 122 | * Encode a ArtDMX packet. 123 | * 124 | * @param universe is the universe 125 | * @param network is the network 126 | * @param dmx is the 512 DMX parameters 127 | * @return the ArtDmxCode in array 128 | * @throws IOException in error with byte array 129 | */ 130 | public static byte[] encodeArtDmxPacket( 131 | final int universe, 132 | final int network, 133 | final int dmx[] 134 | ) throws IOException { 135 | final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 136 | 137 | // Prepare next frame 138 | artDmxCounter++; 139 | 140 | // ID. 141 | byteArrayOutputStream.write(ByteUtils.toByta(Constants.ID)); 142 | byteArrayOutputStream.write(MagicNumbers.MAGIC_NUMBER_ZERO); 143 | 144 | // OpOutput 145 | byteArrayOutputStream.write(ByteUtilsArt.in16toByte(20480)); 146 | 147 | // Version 148 | byteArrayOutputStream.write(ByteUtilsArt.in16toBit(Constants.ART_NET_VERSION)); 149 | 150 | // Sequence 151 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(artDmxCounter)); 152 | 153 | // Physical 154 | byteArrayOutputStream.write(MagicNumbers.MAGIC_NUMBER_ZERO); 155 | 156 | // Net Switch 157 | byteArrayOutputStream.write(universe); 158 | byteArrayOutputStream.write(network); 159 | 160 | // DMX data Length 161 | byteArrayOutputStream.write(ByteUtilsArt.in16toBit(dmx.length)); 162 | 163 | byte bdmx; 164 | for (int i = 0; i != Constants.DMX_512_SIZE; i++) { 165 | if (dmx.length > i) { 166 | bdmx = (byte) dmx[i]; 167 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(bdmx)); 168 | } else { 169 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_ZERO)); 170 | } 171 | } 172 | 173 | return byteArrayOutputStream.toByteArray(); 174 | } 175 | 176 | /** 177 | * Encode an ArtPollReply packet. 178 | * 179 | * @param controller is the controller 180 | * @param inetAdress is the address informations 181 | * @param port is the port information 182 | * @return the ArtTimeCode in array 183 | * @throws IOException in error with byte array 184 | */ 185 | public static byte[] encodeArtPollReplyPacket( 186 | final Controller controller, 187 | final InetAddress inetAdress, 188 | final int port 189 | ) throws IOException { 190 | final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 191 | 192 | // Prepare newt trame 193 | artPollCounter++; 194 | 195 | // ID. 196 | byteArrayOutputStream.write(ByteUtils.toByta(Constants.ID)); 197 | byteArrayOutputStream.write(MagicNumbers.MAGIC_NUMBER_ZERO); 198 | 199 | // ArtPollReply 200 | byteArrayOutputStream.write(MagicNumbers.MAGIC_NUMBER_ZERO); 201 | byteArrayOutputStream.write(MagicNumbers.MAGIC_NUMBER_33); 202 | 203 | // IP 204 | byteArrayOutputStream.write(inetAdress.getAddress()); 205 | 206 | // Port 207 | byteArrayOutputStream.write(ByteUtilsArt.in16toByte(port)); 208 | 209 | // Version Hight 210 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(Constants.VERSION_LIB_HIGHT)); 211 | 212 | // Version Low 213 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(Constants.VERSION_LIB_LOW)); 214 | 215 | // Net Switch 216 | byteArrayOutputStream.write(controller.getNetwork()); 217 | byteArrayOutputStream.write(controller.getSubNetwork()); 218 | 219 | // Oem and UBEA 220 | byteArrayOutputStream.write(ByteUtilsArt.hexStringToByteArray(("0x00ff"))); 221 | 222 | // Status1 223 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_199)); 224 | 225 | // Manufactor code 226 | byteArrayOutputStream.write(ByteUtils.toByta("CZ")); 227 | 228 | // ShotName 229 | byteArrayOutputStream.write( 230 | ByteUtils.toByta( 231 | encodeString( 232 | Constants.SHORT_NAME, 233 | Constants.MAX_LENGTH_SHORT_NAME 234 | ) 235 | ) 236 | ); 237 | 238 | // LongName 239 | byteArrayOutputStream.write( 240 | ByteUtils.toByta( 241 | encodeString( 242 | Constants.LONG_NAME, 243 | Constants.MAX_LENGTH_LONG_NAME 244 | ) 245 | ) 246 | ); 247 | 248 | //Node report 249 | final int vArtPollCounter = artPollCounter + 1; 250 | final StringBuffer nodeReport = new StringBuffer(); 251 | nodeReport.append("#").append("0x0000"); // Debug mode, see table 3 252 | nodeReport.append("[").append(vArtPollCounter).append("]"); 253 | nodeReport.append("ok"); 254 | byteArrayOutputStream.write( 255 | ByteUtils.toByta( 256 | encodeString( 257 | nodeReport.toString(), 258 | Constants.MAX_LENGTH_NODE_REPORT 259 | ) 260 | ) 261 | ); 262 | 263 | // NumPortHi (0, future evolution of ArtNet protocol) 264 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_ZERO)); 265 | 266 | // NumPortLo (Between 0 and 4, max is 4) 267 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_4)); 268 | 269 | // Port Type 270 | final Map portsTypesMap = controller.getPortTypeMap(); 271 | ControllerPortType controlerPortType = null; 272 | BitSet bitSet = null; 273 | for (int i = 0; i != Constants.MAX_PORT; i++) { 274 | controlerPortType = portsTypesMap.get(i); 275 | // No port 276 | if (controlerPortType == null) { 277 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_ZERO)); 278 | } else { 279 | bitSet = new BitSet(MagicNumbers.MAGIC_NUMBER_BITSET); 280 | // First 4 bits (PROCOTOL) 281 | if (controlerPortType.getType().equals(PortTypeEnum.DMX512)) { 282 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_0, MagicNumbers.MAGIC_NUMBER_BIT_4, false); // DMX 283 | } else if (controlerPortType.getType().equals(PortTypeEnum.MIDI)) { 284 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_0, MagicNumbers.MAGIC_NUMBER_BIT_3, false); // MIDI 285 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_4, true); // MIDI 286 | } else if (controlerPortType.getType().equals(PortTypeEnum.AVAB)) { 287 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_0, MagicNumbers.MAGIC_NUMBER_BIT_2, false); // AVAB 288 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_3, true); // AVAB 289 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_4, false); // AVAB 290 | } else if (controlerPortType.getType().equals(PortTypeEnum.COLORTRANCMX)) { 291 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_0, MagicNumbers.MAGIC_NUMBER_BIT_2, false); // COLORTRAN 292 | bitSet.set( 293 | MagicNumbers.MAGIC_NUMBER_BIT_3, 294 | MagicNumbers.MAGIC_NUMBER_BIT_4, 295 | true 296 | ); // COLORTRAN 297 | } else if (controlerPortType.getType().equals(PortTypeEnum.ADB)) { 298 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_0, MagicNumbers.MAGIC_NUMBER_BIT_1, false); // ADB 299 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_2, true); // ADB 300 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_3, MagicNumbers.MAGIC_NUMBER_BIT_4, false); // ADB 301 | } else if (controlerPortType.getType().equals(PortTypeEnum.ARTNET)) { 302 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_0, MagicNumbers.MAGIC_NUMBER_BIT_1, false); // ARTNET 303 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_2, true); // ARTNET 304 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_3, false); // ARTNET 305 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_4, true); // ARTNET 306 | } 307 | // Set if this channel can input onto the Art-NetNetwork 308 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_5, controlerPortType.isInputArtNet()); 309 | // Set is this channel can output data from the Art-Net Network 310 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_6, controlerPortType.isOutputArtNet()); 311 | byteArrayOutputStream.write(toByteArray(bitSet)); 312 | } 313 | } 314 | 315 | // Good Input 316 | final Map portsGoodInputsMap = controller.getGoodInputMapping(); 317 | ControllerGoodInput controlerGoodInput = null; 318 | for (int i = 0; i != Constants.MAX_PORT; i++) { 319 | controlerGoodInput = portsGoodInputsMap.get(i); 320 | // No port 321 | if (controlerGoodInput == null) { 322 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_ZERO)); 323 | } else { 324 | bitSet = new BitSet(MagicNumbers.MAGIC_NUMBER_BITSET); 325 | bitSet.set( 326 | MagicNumbers.MAGIC_NUMBER_BIT_0, 327 | MagicNumbers.MAGIC_NUMBER_BIT_1, 328 | false 329 | ); // Unused and transmitted as zero 330 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_2, controlerGoodInput.getReceivedDataError()); 331 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_3, controlerGoodInput.getDisabled()); 332 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_4, controlerGoodInput.getIncludeDMXTextPackets()); 333 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_5, controlerGoodInput.getIncludeDMXSIPsPackets()); 334 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_6, controlerGoodInput.getIncludeDMXTestPackets()); 335 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_7, controlerGoodInput.getDataReceived()); 336 | byteArrayOutputStream.write(toByteArray(bitSet)); 337 | } 338 | } 339 | 340 | // Good Ouput 341 | final Map portsGoodOutputsMap = controller.getGoodOutputMapping(); 342 | ControllerGoodOutput controlerGoodOutput = null; 343 | for (int i = 0; i != Constants.MAX_PORT; i++) { 344 | controlerGoodOutput = portsGoodOutputsMap.get(i); 345 | // No port 346 | if (controlerGoodOutput == null) { 347 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_ZERO)); 348 | } else { 349 | bitSet = new BitSet(MagicNumbers.MAGIC_NUMBER_BITSET); 350 | bitSet.set( 351 | MagicNumbers.MAGIC_NUMBER_BIT_0, 352 | MagicNumbers.MAGIC_NUMBER_BIT_1, 353 | false 354 | ); // Unused and transmitted as zero 355 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_1, controlerGoodOutput.getMergeLTP()); 356 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_2, controlerGoodOutput.getOutputPowerOn()); 357 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_3, controlerGoodOutput.getOutputmergeArtNet()); 358 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_4, controlerGoodOutput.getIncludeDMXTextPackets()); 359 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_5, controlerGoodOutput.getIncludeDMXSIPsPackets()); 360 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_6, controlerGoodOutput.getIncludeDMXTestPackets()); 361 | bitSet.set(MagicNumbers.MAGIC_NUMBER_BIT_7, controlerGoodOutput.getDataTransmited()); 362 | byteArrayOutputStream.write(toByteArray(bitSet)); 363 | } 364 | } 365 | 366 | // Directions 367 | BitSet bitSetIn; 368 | BitSet bitSetOut; 369 | final ByteArrayOutputStream byteArrayInTempOutputStream = new ByteArrayOutputStream(); 370 | final ByteArrayOutputStream byteArrayOutTempOutputStream = new ByteArrayOutputStream(); 371 | for (int i = 0; i != Constants.MAX_PORT; i++) { 372 | controlerPortType = portsTypesMap.get(i); 373 | bitSetIn = new BitSet(MagicNumbers.MAGIC_NUMBER_BITSET); 374 | bitSetOut = new BitSet(MagicNumbers.MAGIC_NUMBER_BITSET); 375 | 376 | // No port 377 | if (controlerPortType == null || controlerPortType.getDirection() == null) { 378 | bitSetIn.set(i, false); 379 | bitSetOut.set(i, false); 380 | } else if (controlerPortType.getDirection().equals(PortInputOutputEnum.INPUT)) { 381 | bitSetIn.set(i, true); 382 | } else if (controlerPortType.getDirection().equals(PortInputOutputEnum.OUTPUT)) { 383 | bitSetOut.set(i, true); 384 | } else if (controlerPortType.getDirection().equals(PortInputOutputEnum.BOTH)) { 385 | bitSetIn.set(i, true); 386 | bitSetOut.set(i, true); 387 | } else { 388 | bitSetIn.set(i, false); 389 | bitSetOut.set(i, false); 390 | } 391 | 392 | 393 | if (bitSetIn.isEmpty()) { 394 | byteArrayInTempOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_ZERO)); 395 | } else { 396 | byteArrayInTempOutputStream.write(toByteArray(bitSetIn)); 397 | } 398 | 399 | if (bitSetOut.isEmpty()) { 400 | byteArrayOutTempOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_ZERO)); 401 | } else { 402 | byteArrayOutTempOutputStream.write(toByteArray(bitSetOut)); 403 | } 404 | } 405 | byteArrayOutputStream.write(byteArrayInTempOutputStream.toByteArray()); 406 | byteArrayOutputStream.write(byteArrayOutTempOutputStream.toByteArray()); 407 | 408 | // Screen 409 | bitSet = new BitSet(MagicNumbers.MAGIC_NUMBER_BITSET); 410 | if (controller.getScreen()) { 411 | // Ethernet data display 412 | bitSet.set(1, true); 413 | byteArrayOutputStream.write(toByteArray(bitSet)); 414 | 415 | } else { 416 | // Local data display 417 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_ZERO)); 418 | } 419 | 420 | // SwMacro (not implemented) 421 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_ZERO)); 422 | 423 | // SwRemote (not implemented) 424 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_ZERO)); 425 | 426 | // Spare (1+2+3), Not used, set to zero 427 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_ZERO)); 428 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_ZERO)); 429 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_ZERO)); 430 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_ZERO)); 431 | 432 | // Style 433 | // TODO 434 | 435 | // MAC 436 | // TODO : Implement it. 437 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_ZERO)); 438 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_ZERO)); 439 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_ZERO)); 440 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_ZERO)); 441 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_ZERO)); 442 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_ZERO)); 443 | byteArrayOutputStream.write(ByteUtilsArt.in8toByte(MagicNumbers.MAGIC_NUMBER_ZERO)); 444 | 445 | return byteArrayOutputStream.toByteArray(); 446 | } 447 | 448 | /** 449 | * Encode string with finals white spaces. 450 | * 451 | * @param text is text 452 | * @param size is max size 453 | * @return the string 454 | */ 455 | private static String encodeString(final String text, final int size) { 456 | final StringBuffer sb = new StringBuffer(); 457 | sb.append(text); 458 | for (int i = text.length(); i != size; i++) { 459 | sb.append(" "); 460 | } 461 | return sb.toString(); 462 | } 463 | 464 | private static byte[] toByteArray(BitSet bits) { 465 | byte[] bytes = new byte[(bits.length() + 7) / 8]; 466 | for (int i = 0; i < bits.length(); i++) { 467 | if (bits.get(i)) { 468 | bytes[bytes.length - i / 8 - 1] |= 1 << (i % 8); 469 | } 470 | } 471 | return bytes; 472 | } 473 | } 474 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/utils/ByteUtils.java: -------------------------------------------------------------------------------- 1 | package fr.azelart.artnetstack.utils; 2 | 3 | public class ByteUtils { 4 | 5 | /* ========================= */ 6 | /* "primitive type --> byte[] data" Methods */ 7 | /* ========================= */ 8 | public static byte[] toByta(byte data) { 9 | return new byte[]{data}; 10 | } 11 | public static byte[] toByta(byte[] data) { 12 | return data; 13 | } 14 | /* ========================= */ 15 | public static byte[] toByta(short data) { 16 | return new byte[] { 17 | (byte)((data >> 8) & 0xff), 18 | (byte)((data >> 0) & 0xff), 19 | }; 20 | } 21 | public static byte[] toByta(short[] data) { 22 | if (data == null) return null; 23 | // ---------- 24 | byte[] byts = new byte[data.length * 2]; 25 | for (int i = 0; i < data.length; i++) 26 | System.arraycopy(toByta(data[i]), 0, byts, i * 2, 2); 27 | return byts; 28 | } 29 | /* ========================= */ 30 | public static byte[] toByta(char data) { 31 | return new byte[] { 32 | (byte)((data >> 8) & 0xff), 33 | (byte)((data >> 0) & 0xff), 34 | }; 35 | } 36 | public static byte[] toByta(char[] data) { 37 | if (data == null) return null; 38 | // ---------- 39 | byte[] byts = new byte[data.length * 2]; 40 | for (int i = 0; i < data.length; i++) 41 | System.arraycopy(toByta(data[i]), 0, byts, i * 2, 2); 42 | return byts; 43 | } 44 | /* ========================= */ 45 | public static byte[] toByta(int data) { 46 | return new byte[] { 47 | (byte)((data >> 24) & 0xff), 48 | (byte)((data >> 16) & 0xff), 49 | (byte)((data >> 8) & 0xff), 50 | (byte)((data >> 0) & 0xff), 51 | }; 52 | } 53 | public static byte[] toByta(int[] data) { 54 | if (data == null) return null; 55 | // ---------- 56 | byte[] byts = new byte[data.length * 4]; 57 | for (int i = 0; i < data.length; i++) 58 | System.arraycopy(toByta(data[i]), 0, byts, i * 4, 4); 59 | return byts; 60 | } 61 | /* ========================= */ 62 | public static byte[] toByta(long data) { 63 | return new byte[] { 64 | (byte)((data >> 56) & 0xff), 65 | (byte)((data >> 48) & 0xff), 66 | (byte)((data >> 40) & 0xff), 67 | (byte)((data >> 32) & 0xff), 68 | (byte)((data >> 24) & 0xff), 69 | (byte)((data >> 16) & 0xff), 70 | (byte)((data >> 8) & 0xff), 71 | (byte)((data >> 0) & 0xff), 72 | }; 73 | } 74 | public static byte[] toByta(long[] data) { 75 | if (data == null) return null; 76 | // ---------- 77 | byte[] byts = new byte[data.length * 8]; 78 | for (int i = 0; i < data.length; i++) 79 | System.arraycopy(toByta(data[i]), 0, byts, i * 8, 8); 80 | return byts; 81 | } 82 | /* ========================= */ 83 | public static byte[] toByta(float data) { 84 | return toByta(Float.floatToRawIntBits(data)); 85 | } 86 | public static byte[] toByta(float[] data) { 87 | if (data == null) return null; 88 | // ---------- 89 | byte[] byts = new byte[data.length * 4]; 90 | for (int i = 0; i < data.length; i++) 91 | System.arraycopy(toByta(data[i]), 0, byts, i * 4, 4); 92 | return byts; 93 | } 94 | /* ========================= */ 95 | public static byte[] toByta(double data) { 96 | return toByta(Double.doubleToRawLongBits(data)); 97 | } 98 | public static byte[] toByta(double[] data) { 99 | if (data == null) return null; 100 | // ---------- 101 | byte[] byts = new byte[data.length * 8]; 102 | for (int i = 0; i < data.length; i++) 103 | System.arraycopy(toByta(data[i]), 0, byts, i * 8, 8); 104 | return byts; 105 | } 106 | /* ========================= */ 107 | public static byte[] toByta(boolean data) { 108 | return new byte[]{(byte)(data ? 0x01 : 0x00)}; // bool -> {1 byte} 109 | } 110 | public static byte[] toByta(boolean[] data) { 111 | // Advanced Technique: The byte array containts information 112 | // about how many boolean values are involved, so the exact 113 | // array is returned when later decoded. 114 | // ---------- 115 | if (data == null) return null; 116 | // ---------- 117 | int len = data.length; 118 | byte[] lena = toByta(len); // int conversion; length array = lena 119 | byte[] byts = new byte[lena.length + (len / 8) + (len % 8 != 0 ? 1 : 0)]; 120 | // (Above) length-array-length + sets-of-8-booleans +? byte-for-remainder 121 | System.arraycopy(lena, 0, byts, 0, lena.length); 122 | // ---------- 123 | // (Below) algorithm by Matthew Cudmore: boolean[] -> bits -> byte[] 124 | for (int i = 0, j = lena.length, k = 7; i < data.length; i++) { 125 | byts[j] |= (data[i] ? 1 : 0) << k--; 126 | if (k < 0) { j++; k = 7; } 127 | } 128 | // ---------- 129 | return byts; 130 | } 131 | /* ========================= */ 132 | public static byte[] toByta(String data) { 133 | return (data == null) ? null : data.getBytes(); 134 | } 135 | public static byte[] toByta(String[] data) { 136 | // Advanced Technique: Generates an indexed byte array 137 | // which contains the array of Strings. The byte array 138 | // contains information about the number of Strings and 139 | // the length of each String. 140 | // ---------- 141 | if (data == null) return null; 142 | // ---------- flags: 143 | int totalLength = 0; // Measure length of final byte array 144 | int bytesPos = 0; // Used later 145 | // ----- arrays: 146 | byte[] dLen = toByta(data.length); // byte array of data length 147 | totalLength += dLen.length; 148 | int[] sLens = new int[data.length]; // String lengths = sLens 149 | totalLength += (sLens.length * 4); 150 | byte[][] strs = new byte[data.length][]; // array of String bytes 151 | // ----- pack strs: 152 | for (int i = 0; i < data.length; i++) { 153 | if (data[i] != null) { 154 | strs[i] = toByta(data[i]); 155 | sLens[i] = strs[i].length; 156 | totalLength += strs[i].length; 157 | } else { 158 | sLens[i] = 0; 159 | strs[i] = new byte[0]; // prevent null entries 160 | } 161 | } 162 | // ---------- 163 | byte[] bytes = new byte[totalLength]; // final array 164 | System.arraycopy(dLen, 0, bytes, 0, 4); 165 | byte[] bsLens = toByta(sLens); // byte version of String sLens 166 | System.arraycopy(bsLens, 0, bytes, 4, bsLens.length); 167 | // ----- 168 | bytesPos += 4 + bsLens.length; // mark position 169 | // ----- 170 | for (byte[] sba : strs) { 171 | System.arraycopy(sba, 0, bytes, bytesPos, sba.length); 172 | bytesPos += sba.length; 173 | } 174 | // ---------- 175 | return bytes; 176 | } 177 | /* ========================= */ 178 | /* "byte[] data --> primitive type" Methods */ 179 | /* ========================= */ 180 | public static byte toByte(byte[] data) { 181 | return (data == null || data.length == 0) ? 0x0 : data[0]; 182 | } 183 | public static byte[] toByteA(byte[] data) { 184 | return data; 185 | } 186 | /* ========================= */ 187 | public static short toShort(byte[] data) { 188 | if (data == null || data.length != 2) return 0x0; 189 | // ---------- 190 | return (short)( 191 | (0xff & data[0]) << 8 | 192 | (0xff & data[1]) << 0 193 | ); 194 | } 195 | public static short[] toShortA(byte[] data) { 196 | if (data == null || data.length % 2 != 0) return null; 197 | // ---------- 198 | short[] shts = new short[data.length / 2]; 199 | for (int i = 0; i < shts.length; i++) { 200 | shts[i] = toShort( new byte[] { 201 | data[(i*2)], 202 | data[(i*2)+1] 203 | } ); 204 | } 205 | return shts; 206 | } 207 | /* ========================= */ 208 | public static char toChar(byte[] data) { 209 | if (data == null || data.length != 2) return 0x0; 210 | // ---------- 211 | return (char)( 212 | (0xff & data[0]) << 8 | 213 | (0xff & data[1]) << 0 214 | ); 215 | } 216 | public static char[] toCharA(byte[] data) { 217 | if (data == null || data.length % 2 != 0) return null; 218 | // ---------- 219 | char[] chrs = new char[data.length / 2]; 220 | for (int i = 0; i < chrs.length; i++) { 221 | chrs[i] = toChar( new byte[] { 222 | data[(i*2)], 223 | data[(i*2)+1], 224 | } ); 225 | } 226 | return chrs; 227 | } 228 | /* ========================= */ 229 | public static int toInt(byte[] data) { 230 | if (data == null || data.length != 4) return 0x0; 231 | // ---------- 232 | return (int)( // NOTE: type cast not necessary for int 233 | (0xff & data[0]) << 24 | 234 | (0xff & data[1]) << 16 | 235 | (0xff & data[2]) << 8 | 236 | (0xff & data[3]) << 0 237 | ); 238 | } 239 | public static int[] toIntA(byte[] data) { 240 | if (data == null || data.length % 4 != 0) return null; 241 | // ---------- 242 | int[] ints = new int[data.length / 4]; 243 | for (int i = 0; i < ints.length; i++) 244 | ints[i] = toInt( new byte[] { 245 | data[(i*4)], 246 | data[(i*4)+1], 247 | data[(i*4)+2], 248 | data[(i*4)+3], 249 | } ); 250 | return ints; 251 | } 252 | /* ========================= */ 253 | public static long toLong(byte[] data) { 254 | if (data == null || data.length != 8) return 0x0; 255 | // ---------- 256 | return (long)( 257 | // (Below) convert to longs before shift because digits 258 | // are lost with ints beyond the 32-bit limit 259 | (long)(0xff & data[0]) << 56 | 260 | (long)(0xff & data[1]) << 48 | 261 | (long)(0xff & data[2]) << 40 | 262 | (long)(0xff & data[3]) << 32 | 263 | (long)(0xff & data[4]) << 24 | 264 | (long)(0xff & data[5]) << 16 | 265 | (long)(0xff & data[6]) << 8 | 266 | (long)(0xff & data[7]) << 0 267 | ); 268 | } 269 | public static long[] toLongA(byte[] data) { 270 | if (data == null || data.length % 8 != 0) return null; 271 | // ---------- 272 | long[] lngs = new long[data.length / 8]; 273 | for (int i = 0; i < lngs.length; i++) { 274 | lngs[i] = toLong( new byte[] { 275 | data[(i*8)], 276 | data[(i*8)+1], 277 | data[(i*8)+2], 278 | data[(i*8)+3], 279 | data[(i*8)+4], 280 | data[(i*8)+5], 281 | data[(i*8)+6], 282 | data[(i*8)+7], 283 | } ); 284 | } 285 | return lngs; 286 | } 287 | /* ========================= */ 288 | public static float toFloat(byte[] data) { 289 | if (data == null || data.length != 4) return 0x0; 290 | // ---------- simple: 291 | return Float.intBitsToFloat(toInt(data)); 292 | } 293 | public static float[] toFloatA(byte[] data) { 294 | if (data == null || data.length % 4 != 0) return null; 295 | // ---------- 296 | float[] flts = new float[data.length / 4]; 297 | for (int i = 0; i < flts.length; i++) { 298 | flts[i] = toFloat( new byte[] { 299 | data[(i*4)], 300 | data[(i*4)+1], 301 | data[(i*4)+2], 302 | data[(i*4)+3], 303 | } ); 304 | } 305 | return flts; 306 | } 307 | /* ========================= */ 308 | public static double toDouble(byte[] data) { 309 | if (data == null || data.length != 8) return 0x0; 310 | // ---------- simple: 311 | return Double.longBitsToDouble(toLong(data)); 312 | } 313 | public static double[] toDoubleA(byte[] data) { 314 | if (data == null) return null; 315 | // ---------- 316 | if (data.length % 8 != 0) return null; 317 | double[] dbls = new double[data.length / 8]; 318 | for (int i = 0; i < dbls.length; i++) { 319 | dbls[i] = toDouble( new byte[] { 320 | data[(i*8)], 321 | data[(i*8)+1], 322 | data[(i*8)+2], 323 | data[(i*8)+3], 324 | data[(i*8)+4], 325 | data[(i*8)+5], 326 | data[(i*8)+6], 327 | data[(i*8)+7], 328 | } ); 329 | } 330 | return dbls; 331 | } 332 | /* ========================= */ 333 | public static boolean toBoolean(byte[] data) { 334 | return (data == null || data.length == 0) ? false : data[0] != 0x00; 335 | } 336 | public static boolean[] toBooleanA(byte[] data) { 337 | // Advanced Technique: Extract the boolean array's length 338 | // from the first four bytes in the char array, and then 339 | // read the boolean array. 340 | // ---------- 341 | if (data == null || data.length < 4) return null; 342 | // ---------- 343 | int len = toInt(new byte[]{data[0], data[1], data[2], data[3]}); 344 | boolean[] bools = new boolean[len]; 345 | // ----- pack bools: 346 | for (int i = 0, j = 4, k = 7; i < bools.length; i++) { 347 | bools[i] = ((data[j] >> k--) & 0x01) == 1; 348 | if (k < 0) { j++; k = 7; } 349 | } 350 | // ---------- 351 | return bools; 352 | } 353 | /* ========================= */ 354 | public static String toString(byte[] data) { 355 | return (data == null) ? null : new String(data); 356 | } 357 | public static String[] toStringA(byte[] data) { 358 | // Advanced Technique: Extract the String array's length 359 | // from the first four bytes in the char array, and then 360 | // read the int array denoting the String lengths, and 361 | // then read the Strings. 362 | // ---------- 363 | if (data == null || data.length < 4) return null; 364 | // ---------- 365 | byte[] bBuff = new byte[4]; // Buffer 366 | // ----- 367 | System.arraycopy(data, 0, bBuff, 0, 4); 368 | int saLen = toInt(bBuff); 369 | if (data.length < (4 + (saLen * 4))) return null; 370 | // ----- 371 | bBuff = new byte[saLen * 4]; 372 | System.arraycopy(data, 4, bBuff, 0, bBuff.length); 373 | int[] sLens = toIntA(bBuff); 374 | if (sLens == null) return null; 375 | // ---------- 376 | String[] strs = new String[saLen]; 377 | for (int i = 0, dataPos = 4 + (saLen * 4); i < saLen; i++) { 378 | if (sLens[i] > 0) { 379 | if (data.length >= (dataPos + sLens[i])) { 380 | bBuff = new byte[sLens[i]]; 381 | System.arraycopy(data, dataPos, bBuff, 0, sLens[i]); 382 | dataPos += sLens[i]; 383 | strs[i] = toString(bBuff); 384 | } else return null; 385 | } 386 | } 387 | // ---------- 388 | return strs; 389 | } 390 | 391 | } 392 | -------------------------------------------------------------------------------- /src/main/java/fr/azelart/artnetstack/utils/ByteUtilsArt.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Corentin Azelart. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package fr.azelart.artnetstack.utils; 17 | 18 | public final class ByteUtilsArt { 19 | 20 | public static int byte2toIn( byte[] b, int offset ) { 21 | return (b[offset+1]&0xff)<<8 | (b[offset] & 0xff); 22 | //return b[3]<<24 | b[2]<<16 | b[1]<<8 | b[0]; 23 | } 24 | 25 | public static int byte4toIn( byte[] b, int offset ) { 26 | return (b[offset+3]&0xff)<<8 | (b[offset+2]&0xff)<<8 | (b[offset+1]&0xff)<<8 | (b[offset] & 0xff); 27 | } 28 | 29 | 30 | public static boolean bitIsSet( int i, int offset ) { 31 | return (i & (1 << offset)) != 0; 32 | } 33 | 34 | public static byte[] in8toByte( int i ) { 35 | return new byte[] {(byte)((i >> 0) & 0xff)}; 36 | } 37 | 38 | public static byte[] in16toByte( int data ) { 39 | return new byte[] {(byte)((data >> 0) & 0xff),(byte)((data >> 8) & 0xff)}; 40 | } 41 | 42 | /** 43 | * New method to convert integer to 2*8 bit. 44 | * @param data is number. 45 | * @return the byte array. 46 | */ 47 | public static byte[] in16toBit( int data ) { 48 | return new byte[] {(byte)(data >>> 8),(byte)data}; 49 | } 50 | 51 | public static byte[] hexStringToByteArray(String s) { 52 | int len = s.length(); 53 | byte[] data = new byte[len / 2]; 54 | for (int i = 0; i < len; i += 2) { 55 | data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) 56 | + Character.digit(s.charAt(i+1), 16)); 57 | } 58 | return data; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/test/java/fr/azelart/artnetstack/utils/ByteUtilsArtTest.java: -------------------------------------------------------------------------------- 1 | package fr.azelart.artnetstack.utils; 2 | 3 | import junit.framework.Assert; 4 | 5 | import org.junit.Test; 6 | 7 | import java.util.Arrays; 8 | 9 | /** 10 | * Created with IntelliJ IDEA. 11 | * User: matthias 12 | * Date: 06.08.12 13 | * Time: 22:49 14 | * To change this template use File | Settings | File Templates. 15 | */ 16 | public class ByteUtilsArtTest { 17 | @Test 18 | public void testByte2toIn() throws Exception { 19 | byte[][] test_data = new byte[][]{ 20 | new byte[]{0x00, 0x00}, 21 | new byte[]{(byte) 0xff, 0x00}, 22 | new byte[]{0x00, (byte) 0xff}, 23 | new byte[]{(byte) 0xff, (byte) 0xff}}; 24 | int[] results = new int[]{ 25 | 0x0000, 26 | 0x00ff, 27 | 0xff00, 28 | 0xffff}; 29 | for (int i = 0; i < test_data.length; i++) { 30 | Assert.assertEquals(Arrays.toString(test_data[i]) + " should be converted to " + results[i], results[i], ByteUtilsArt.byte2toIn(test_data[i], 0)); 31 | } 32 | } 33 | } 34 | --------------------------------------------------------------------------------