001/**
002 * Copyright 2017, Digi International Inc.
003 *
004 * This Source Code Form is subject to the terms of the Mozilla Public
005 * License, v. 2.0. If a copy of the MPL was not distributed with this
006 * file, you can obtain one at http://mozilla.org/MPL/2.0/.
007 *
008 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 
009 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 
010 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 
011 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 
012 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
013 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
014 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
015 */
016package com.digi.xbee.api.models;
017
018import java.net.Inet4Address;
019import java.net.Inet6Address;
020
021/**
022 * This class represents an IP message containing the IP address the 
023 * message belongs to, the source and destination ports, the IP protocol,
024 * and the content (data) of the message. 
025 * 
026 * <p>This class is used within the XBee Java Library to read data sent to IP 
027 * devices.</p>
028 * 
029 * @since 1.2.0
030 */
031public class IPMessage {
032
033        // Variables.
034        private final Inet4Address ipAddress;
035        private final Inet6Address ipv6Address;
036        
037        private final byte[] data;
038        
039        private final int sourcePort;
040        private final int destPort;
041        
042        private final IPProtocol protocol;
043        
044        /**
045         * Class constructor. Instantiates a new object of type 
046         * {@code IPMessage} with the given parameters.
047         * 
048         * @param ipAddress The IP address the message comes from.
049         * @param sourcePort TCP or UDP source port of the transmission.
050         * @param destPort TCP or UDP destination port of the transmission.
051         * @param protocol IP protocol used in the transmission.
052         * @param data Byte array containing the data of the message.
053         * 
054         * @throws IllegalArgumentException if {@code sourcePort < 0} or
055         *                                  if {@code sourcePort > 65535} or
056         *                                  if {@code destPort < 0} or
057         *                                  if {@code destPort > 65535}.
058         * @throws NullPointerException if {@code ipAddress == null} or
059         *                              if {@code data == null} or
060         *                              if {@code protocol ==  null}.
061         * 
062         * @see com.digi.xbee.api.models.IPProtocol
063         * @see java.net.Inet4Address
064         */
065        public IPMessage(Inet4Address ipAddress, int sourcePort, int destPort, 
066                        IPProtocol protocol, byte[] data) {
067                this(ipAddress, null, sourcePort, destPort, protocol, data);
068        }
069        
070        /**
071         * Class constructor. Instantiates a new object of type 
072         * {@code IPMessage} with the given parameters.
073         * 
074         * @param ipv6Address The IPv6 address the message comes from.
075         * @param sourcePort TCP or UDP source port of the transmission.
076         * @param destPort TCP or UDP destination port of the transmission.
077         * @param protocol IP protocol used in the transmission.
078         * @param data Byte array containing the data of the message.
079         * 
080         * @throws IllegalArgumentException if {@code sourcePort < 0} or
081         *                                  if {@code sourcePort > 65535} or
082         *                                  if {@code destPort < 0} or
083         *                                  if {@code destPort > 65535}.
084         * @throws NullPointerException if {@code ipv6Address == null} or
085         *                              if {@code data == null} or
086         *                              if {@code protocol ==  null}.
087         * 
088         * @see com.digi.xbee.api.models.IPProtocol
089         * @see java.net.Inet6Address
090         * 
091         * @since 1.2.1
092         */
093        public IPMessage(Inet6Address ipv6Address, int sourcePort, int destPort, 
094                        IPProtocol protocol, byte[] data) {
095                this(null, ipv6Address, sourcePort, destPort, protocol, data);
096        }
097        
098        /**
099         * Class constructor. Instantiates a new object of type 
100         * {@code IPMessage} with the given parameters.
101         * 
102         * @param ipAddress The IP address the message comes from.
103         * @param ipv6Address The IPv6 address the message comes from.
104         * @param sourcePort TCP or UDP source port of the transmission.
105         * @param destPort TCP or UDP destination port of the transmission.
106         * @param protocol IP protocol used in the transmission.
107         * @param data Byte array containing the data of the message.
108         * 
109         * @throws IllegalArgumentException if {@code sourcePort < 0} or
110         *                                  if {@code sourcePort > 65535} or
111         *                                  if {@code destPort < 0} or
112         *                                  if {@code destPort > 65535} or
113         *                                  if {@code ipAddress != null} and {@code ipv6Address != null}.
114         * @throws NullPointerException if {@code ipAddress == null && ipv6Address == null} or
115         *                              if {@code data == null} or
116         *                              if {@code protocol ==  null}.
117         * 
118         * @see com.digi.xbee.api.models.IPProtocol
119         * @see java.net.Inet4Address
120         * @see java.net.Inet6Address
121         * 
122         * @since 1.2.1
123         */
124        private IPMessage(Inet4Address ipAddress, Inet6Address ipv6Address, int sourcePort, 
125                        int destPort, IPProtocol protocol, byte[] data) {
126                if (ipAddress == null && ipv6Address == null)
127                        throw new NullPointerException("IP address cannot be null.");
128                if (protocol == null)
129                        throw new NullPointerException("Protocol cannot be null.");
130                if (data == null)
131                        throw new NullPointerException("Data cannot be null.");
132                
133                if (ipAddress != null && ipv6Address != null)
134                        throw new IllegalArgumentException("There cannot be 2 types of IP addresses (IPv4 and IPv6) for one message.");
135                if (sourcePort < 0 || sourcePort > 65535)
136                        throw new IllegalArgumentException("Source port must be between 0 and 65535.");
137                if (destPort < 0 || destPort > 65535)
138                        throw new IllegalArgumentException("Destination port must be between 0 and 65535.");
139                
140                this.ipAddress = ipAddress;
141                this.ipv6Address = ipv6Address;
142                this.sourcePort = sourcePort;
143                this.destPort = destPort;
144                this.protocol = protocol;
145                this.data = data;
146        }
147        
148        /**
149         * Returns the IPv4 address this message is associated to.
150         * 
151         * @return The IPv6 address this message is associated to.
152         * 
153         * @see java.net.Inet4Address
154         */
155        public Inet4Address getIPAddress() {
156                return ipAddress;
157        }
158        
159        /**
160         * Returns the IPv6 address this message is associated to.
161         * 
162         * @return The IPv6 address this message is associated to.
163         * 
164         * @see java.net.Inet6Address
165         * 
166         * @since 1.2.1
167         */
168        public Inet6Address getIPv6Address() {
169                return ipv6Address;
170        }
171        
172        /**
173         * Returns the IPv4 or IPv6 address this message is associated to.
174         * 
175         * @return The IPv4 or IPv6 address this message is associated to.
176         * 
177         * @see java.net.Inet4Address
178         * @see java.net.Inet6Address
179         * 
180         * @since 1.2.1
181         */
182        public String getHostAddress() {
183                if (ipAddress == null)
184                        return ipv6Address.getHostAddress();
185                else
186                        return ipAddress.getHostAddress();
187        }
188        
189        /**
190         * Returns the source port of the transmission.
191         * 
192         * @return The source port of the transmission.
193         */
194        public int getSourcePort() {
195                return sourcePort;
196        }
197        
198        /**
199         * Returns the destination port of the transmission.
200         * 
201         * @return The destination port of the transmission.
202         */
203        public int getDestPort() {
204                return destPort;
205        }
206        
207        /**
208         * Returns the protocol used in the transmission.
209         * 
210         * @return The protocol used in the transmission
211         * 
212         * @see IPProtocol
213         */
214        public IPProtocol getProtocol() {
215                return protocol;
216        }
217        
218        /**
219         * Returns the byte array containing the data of the message.
220         * 
221         * @return A byte array containing the data of the message.
222         */
223        public byte[] getData() {
224                return data;
225        }
226        
227        /**
228         * Returns the data of the message in string format.
229         * 
230         * @return The data of the message in string format.
231         */
232        public String getDataString() {
233                return new String(data);
234        }
235}