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;
020import java.util.LinkedList;
021
022import com.digi.xbee.api.RemoteXBeeDevice;
023import com.digi.xbee.api.packet.APIFrameType;
024import com.digi.xbee.api.packet.XBeeAPIPacket;
025import com.digi.xbee.api.packet.XBeePacket;
026import com.digi.xbee.api.packet.common.ExplicitRxIndicatorPacket;
027import com.digi.xbee.api.packet.common.ReceivePacket;
028import com.digi.xbee.api.packet.common.RemoteATCommandResponsePacket;
029import com.digi.xbee.api.packet.ip.RXIPv4Packet;
030import com.digi.xbee.api.packet.raw.RX16IOPacket;
031import com.digi.xbee.api.packet.raw.RX16Packet;
032import com.digi.xbee.api.packet.raw.RX64IOPacket;
033import com.digi.xbee.api.packet.raw.RX64Packet;
034import com.digi.xbee.api.packet.thread.RXIPv6Packet;
035
036/**
037 * This class represents a queue of XBee packets used for sequential packets 
038 * reading within the XBee Java API. 
039 * 
040 * <p>The class provides some methods to get specific packet types from 
041 * different source nodes.</p>
042 * 
043 * @see com.digi.xbee.api.packet.XBeePacket
044 */
045public class XBeePacketsQueue {
046
047        // Constants.
048        /**
049         * Default maximum number of packets to store in the queue 
050         * (value: {@value}).
051         */
052        public static final int DEFAULT_MAX_LENGTH = 50;
053        
054        // Variables.
055        private int maxLength = DEFAULT_MAX_LENGTH;
056        
057        private LinkedList<XBeePacket> packetsList;
058        
059        private Object lock = new Object();
060        
061        /**
062         * Class constructor. Instantiates a new object of type 
063         * {@code XBeePacketsQueue}.
064         */
065        public XBeePacketsQueue() {
066                this(DEFAULT_MAX_LENGTH);
067        }
068        
069        /**
070         * Class constructor. Instantiates a new object of type 
071         * {@code XBeePacketsQueue} with the given maximum length.
072         * 
073         * @param maxLength Maximum length of the queue.
074         * 
075         * @throws IllegalArgumentException if {@code maxLength < 1}.
076         */
077        public XBeePacketsQueue(int maxLength) {
078                if (maxLength < 1)
079                        throw new IllegalArgumentException("Queue length must be greater than 0.");
080                
081                this.maxLength = maxLength;
082                packetsList = new LinkedList<XBeePacket>();
083        }
084        
085        /**
086         * Adds the provided packet to the list of packets. If the queue is full 
087         * the first packet will be discarded to add the given one.
088         * 
089         * @param xbeePacket The XBee packet to be added to the list.
090         * 
091         * @see com.digi.xbee.api.packet.XBeePacket
092         */
093        public void addPacket(XBeePacket xbeePacket) {
094                synchronized (lock) {
095                        if (packetsList.size() == maxLength)
096                                packetsList.removeFirst();
097                        packetsList.add(xbeePacket);
098                }
099        }
100        
101        /**
102         * Clears the list of packets.
103         */
104        public void clearQueue() {
105                synchronized (lock) {
106                        packetsList.clear();
107                }
108        }
109        
110        /**
111         * Returns the first packet from the queue waiting up to the specified 
112         * timeout if  necessary for an XBee packet to become available. 
113         * {@code null }if the queue is empty.
114         * 
115         * @param timeout The time in milliseconds to wait for an XBee packet to 
116         *                become available. 0 to return immediately.
117         * @return The first packet from the queue, {@code null} if it is empty.
118         * 
119         * @see com.digi.xbee.api.packet.XBeePacket
120         */
121        public XBeePacket getFirstPacket(int timeout) {
122                if (timeout > 0) {
123                        XBeePacket xbeePacket = getFirstPacket(0);
124                        // Wait for a timeout or until an XBee packet is read.
125                        Long deadLine = System.currentTimeMillis() + timeout;
126                        while (xbeePacket == null && deadLine > System.currentTimeMillis()) {
127                                sleep(100);
128                                xbeePacket = getFirstPacket(0);
129                        }
130                        return xbeePacket;
131                } 
132                synchronized (lock) {
133                        if (!packetsList.isEmpty())
134                                return packetsList.pop();
135                }
136                return null;
137        }
138        
139        /**
140         * Returns the first packet from the queue whose 64-bit source address 
141         * matches the address of the provided remote XBee device.
142         * 
143         * <p>The methods waits up to the specified timeout if necessary for an 
144         * XBee packet to become available. Null if the queue is empty or there is 
145         * not any XBee packet sent by the provided remote XBee device.</p>
146         * 
147         * @param remoteXBeeDevice The remote XBee device containing the 64-bit 
148         *                         address to look for in the list of packets.
149         * @param timeout The time in milliseconds to wait for an XBee packet from 
150         *                the specified remote XBee device to become available. 
151         *                0 to return immediately.
152         * 
153         * @return The first XBee packet whose 64-bit address matches the address 
154         *         of the provided remote XBee device. {@code null} if no packets 
155         *         from the specified XBee device are found in the queue.
156         * 
157         * @see com.digi.xbee.api.RemoteXBeeDevice
158         * @see com.digi.xbee.api.packet.XBeePacket
159         */
160        public XBeePacket getFirstPacketFrom(RemoteXBeeDevice remoteXBeeDevice, int timeout) {
161                if (timeout > 0) {
162                        XBeePacket xbeePacket = getFirstPacketFrom(remoteXBeeDevice, 0);
163                        // Wait for a timeout or until an XBee packet from remoteXBeeDevice is read.
164                        Long deadLine = System.currentTimeMillis() + timeout;
165                        while (xbeePacket == null && deadLine > System.currentTimeMillis()) {
166                                sleep(100);
167                                xbeePacket = getFirstPacketFrom(remoteXBeeDevice, 0);
168                        }
169                        return xbeePacket;
170                } else {
171                        synchronized (lock) {
172                                for (int i = 0; i < packetsList.size(); i++) {
173                                        XBeePacket xbeePacket = packetsList.get(i);
174                                        if (addressesMatch(xbeePacket, remoteXBeeDevice))
175                                                return packetsList.remove(i);
176                                }
177                        }
178                }
179                return null;
180        }
181        
182        /**
183         * Returns the first data packet from the queue waiting up to the 
184         * specified timeout if necessary for an XBee data packet to become 
185         * available. {@code null} if the queue is empty or there is not any data 
186         * packet inside.
187         * 
188         * @param timeout The time in milliseconds to wait for an XBee data packet 
189         *                to become available. 0 to return immediately.
190         * 
191         * @return The first data packet from the queue, {@code null} if it is 
192         *         empty or no data packets are contained in the queue.
193         * 
194         * @see com.digi.xbee.api.packet.XBeePacket
195         */
196        public XBeePacket getFirstDataPacket(int timeout) {
197                if (timeout > 0) {
198                        XBeePacket xbeePacket = getFirstDataPacket(0);
199                        // Wait for a timeout or until a data XBee packet is read.
200                        Long deadLine = System.currentTimeMillis() + timeout;
201                        while (xbeePacket == null && deadLine > System.currentTimeMillis()) {
202                                sleep(100);
203                                xbeePacket = getFirstDataPacket(0);
204                        }
205                        return xbeePacket;
206                } else {
207                        synchronized (lock) {
208                                for (int i = 0; i < packetsList.size(); i++) {
209                                        XBeePacket xbeePacket = packetsList.get(i);
210                                        if (isDataPacket(xbeePacket))
211                                                return packetsList.remove(i);
212                                }
213                        }
214                }
215                return null;
216        }
217        
218        /**
219         * Returns the first data packet from the queue whose 64-bit source 
220         * address matches the address of the provided remote XBee device.
221         * 
222         * <p>The methods waits up to the specified timeout if necessary for an 
223         * XBee data packet to become available. {@code null} if the queue is 
224         * empty or there is not any XBee data packet sent by the provided remote 
225         * XBee device.</p>
226         * 
227         * @param remoteXBeeDevice The XBee device containing the 64-bit address 
228         *                         to look for in the list of packets.
229         * @param timeout The time in milliseconds to wait for an XBee data packet 
230         *                from the specified remote XBee device to become 
231         *                available. 0 to return immediately.
232         * 
233         * @return The first XBee data packet whose its 64-bit address matches the 
234         *         address of the provided remote XBee device. {@code null} if no 
235         *         data packets from the specified XBee device are found in the 
236         *         queue.
237         * 
238         * @see com.digi.xbee.api.RemoteXBeeDevice
239         * @see com.digi.xbee.api.packet.XBeePacket
240         */
241        public XBeePacket getFirstDataPacketFrom(RemoteXBeeDevice remoteXBeeDevice, int timeout) {
242                if (timeout > 0) {
243                        XBeePacket xbeePacket = getFirstDataPacketFrom(remoteXBeeDevice, 0);
244                        // Wait for a timeout or until an XBee packet from remoteXBeeDevice is read.
245                        Long deadLine = System.currentTimeMillis() + timeout;
246                        while (xbeePacket == null && deadLine > System.currentTimeMillis()) {
247                                sleep(100);
248                                xbeePacket = getFirstDataPacketFrom(remoteXBeeDevice, 0);
249                        }
250                        return xbeePacket;
251                } else {
252                        synchronized (lock) {
253                                for (int i = 0; i < packetsList.size(); i++) {
254                                        XBeePacket xbeePacket = packetsList.get(i);
255                                        if (isDataPacket(xbeePacket) && addressesMatch(xbeePacket, remoteXBeeDevice))
256                                                return packetsList.remove(i);
257                                }
258                        }
259                }
260                return null;
261        }
262        
263        /**
264         * Returns the first explicit data packet from the queue waiting up to the 
265         * specified timeout if necessary for an XBee explicit data packet to 
266         * become available. {@code null} if the queue is empty or there is not 
267         * any explicit data packet inside.
268         * 
269         * @param timeout The time in milliseconds to wait for an XBee explicit 
270         *                data packet to become available. 0 to return immediately.
271         * 
272         * @return The first explicit data packet from the queue, {@code null} if 
273         *         it is empty or no data packets are contained in the queue.
274         * 
275         * @see com.digi.xbee.api.packet.XBeePacket
276         * @see com.digi.xbee.api.packet.common.ExplicitRxIndicatorPacket
277         */
278        public XBeePacket getFirstExplicitDataPacket(int timeout) {
279                if (timeout > 0) {
280                        XBeePacket xbeePacket = getFirstExplicitDataPacket(0);
281                        // Wait for a timeout or until an explicit data XBee packet is read.
282                        Long deadLine = System.currentTimeMillis() + timeout;
283                        while (xbeePacket == null && deadLine > System.currentTimeMillis()) {
284                                sleep(100);
285                                xbeePacket = getFirstExplicitDataPacket(0);
286                        }
287                        return xbeePacket;
288                } else {
289                        synchronized (lock) {
290                                for (int i = 0; i < packetsList.size(); i++) {
291                                        XBeePacket xbeePacket = packetsList.get(i);
292                                        if (isExplicitDataPacket(xbeePacket))
293                                                return packetsList.remove(i);
294                                }
295                        }
296                }
297                return null;
298        }
299        
300        /**
301         * Returns the first explicit data packet from the queue whose 64-bit 
302         * source address matches the address of the provided remote XBee device.
303         * 
304         * <p>The methods waits up to the specified timeout if necessary for an 
305         * XBee explicit data packet to become available. {@code null} if the 
306         * queue is empty or there is not any XBee explicit data packet sent by 
307         * the provided remote XBee device.</p>
308         * 
309         * @param remoteXBeeDevice The XBee device containing the 64-bit address 
310         *                         to look for in the list of packets.
311         * @param timeout The time in milliseconds to wait for an XBee explicit 
312         *                data packet from the specified remote XBee device to 
313         *                become available. 0 to return immediately.
314         * 
315         * @return The first XBee explicit data packet whose its 64-bit address 
316         *         matches the address of the provided remote XBee device. 
317         *         {@code null} if no explicit data packets from the specified 
318         *         XBee device are found in the queue.
319         * 
320         * @see com.digi.xbee.api.RemoteXBeeDevice
321         * @see com.digi.xbee.api.packet.XBeePacket
322         * @see com.digi.xbee.api.packet.common.ExplicitRxIndicatorPacket
323         */
324        public XBeePacket getFirstExplicitDataPacketFrom(RemoteXBeeDevice remoteXBeeDevice, int timeout) {
325                if (timeout > 0) {
326                        XBeePacket xbeePacket = getFirstExplicitDataPacketFrom(remoteXBeeDevice, 0);
327                        // Wait for a timeout or until an XBee explicit data packet from remoteXBeeDevice is read.
328                        Long deadLine = System.currentTimeMillis() + timeout;
329                        while (xbeePacket == null && deadLine > System.currentTimeMillis()) {
330                                sleep(100);
331                                xbeePacket = getFirstExplicitDataPacketFrom(remoteXBeeDevice, 0);
332                        }
333                        return xbeePacket;
334                } else {
335                        synchronized (lock) {
336                                for (int i = 0; i < packetsList.size(); i++) {
337                                        XBeePacket xbeePacket = packetsList.get(i);
338                                        if (isExplicitDataPacket(xbeePacket) && addressesMatch(xbeePacket, remoteXBeeDevice))
339                                                return packetsList.remove(i);
340                                }
341                        }
342                }
343                return null;
344        }
345        
346        /**
347         * Returns the first IP data packet from the queue waiting up to the 
348         * specified timeout if necessary for a IP data packet to 
349         * become available. {@code null} if the queue is empty or there is not 
350         * any IP data packet inside.
351         * 
352         * @param timeout The time in milliseconds to wait for a IP data 
353         *                packet to become available. 0 to return immediately.
354         * 
355         * @return The first IP data packet from the queue, {@code null} if 
356         *         it is empty or no IP packets are contained in the queue.
357         * 
358         * @see com.digi.xbee.api.packet.XBeePacket
359         * @see com.digi.xbee.api.packet.ip.RXIPv4Packet
360         * 
361         * @since 1.2.0
362         */
363        public XBeePacket getFirstIPDataPacket(int timeout) {
364                if (timeout > 0) {
365                        XBeePacket xbeePacket = getFirstIPDataPacket(0);
366                        // Wait for a timeout or until a IP data packet is read.
367                        Long deadLine = System.currentTimeMillis() + timeout;
368                        while (xbeePacket == null && deadLine > System.currentTimeMillis()) {
369                                sleep(100);
370                                xbeePacket = getFirstIPDataPacket(0);
371                        }
372                        return xbeePacket;
373                } else {
374                        synchronized (lock) {
375                                for (int i = 0; i < packetsList.size(); i++) {
376                                        XBeePacket xbeePacket = packetsList.get(i);
377                                        if (isIPDataPacket(xbeePacket))
378                                                return packetsList.remove(i);
379                                }
380                        }
381                }
382                return null;
383        }
384        
385        /**
386         * Returns the first IPv6 data packet from the queue waiting up to the 
387         * specified timeout if necessary for a IPv6 data packet to 
388         * become available. {@code null} if the queue is empty or there is not 
389         * any IPv6 data packet inside.
390         * 
391         * @param timeout The time in milliseconds to wait for a IPv6 data 
392         *                packet to become available. 0 to return immediately.
393         * 
394         * @return The first IPv6 data packet from the queue, {@code null} if 
395         *         it is empty or no IPv6 packets are contained in the queue.
396         * 
397         * @see com.digi.xbee.api.packet.XBeePacket
398         * @see com.digi.xbee.api.packet.thread.RXIPv6Packet
399         * 
400         * @since 1.2.1
401         */
402        public XBeePacket getFirstIPv6DataPacket(int timeout) {
403                if (timeout > 0) {
404                        XBeePacket xbeePacket = getFirstIPv6DataPacket(0);
405                        // Wait for a timeout or until a IPv6 data packet is read.
406                        Long deadLine = System.currentTimeMillis() + timeout;
407                        while (xbeePacket == null && deadLine > System.currentTimeMillis()) {
408                                sleep(100);
409                                xbeePacket = getFirstIPv6DataPacket(0);
410                        }
411                        return xbeePacket;
412                } else {
413                        synchronized (lock) {
414                                for (int i = 0; i < packetsList.size(); i++) {
415                                        XBeePacket xbeePacket = packetsList.get(i);
416                                        if (isIPv6DataPacket(xbeePacket))
417                                                return packetsList.remove(i);
418                                }
419                        }
420                }
421                return null;
422        }
423        
424        /**
425         * Returns the first IP data packet from the queue whose IP address 
426         * matches the provided address.
427         * 
428         * <p>The methods waits up to the specified timeout if necessary for a 
429         * IP data packet to become available. {@code null} if the 
430         * queue is empty or there is not any IP data packet sent by 
431         * the provided IP address.</p>
432         * 
433         * @param ipAddress The IP address to look for in the list of packets.
434         * @param timeout The time in milliseconds to wait for a IP data 
435         *                packet from the specified IP address to become available.
436         *                0 to return immediately.
437         * 
438         * @return The first IP packet whose IP address matches the provided 
439         *         IP address. {@code null} if no IP data packets from the 
440         *         specified IP address are found in the queue.
441         * 
442         * @see com.digi.xbee.api.packet.XBeePacket
443         * @see com.digi.xbee.api.packet.ip.RXIPv4Packet
444         * @see java.net.Inet4Address
445         * 
446         * @since 1.2.0
447         */
448        public XBeePacket getFirstIPDataPacketFrom(Inet4Address ipAddress, int timeout) {
449                if (timeout > 0) {
450                        XBeePacket xbeePacket = getFirstIPDataPacketFrom(ipAddress, 0);
451                        // Wait for a timeout or until a IP data packet with the provided IP address is read.
452                        Long deadLine = System.currentTimeMillis() + timeout;
453                        while (xbeePacket == null && deadLine > System.currentTimeMillis()) {
454                                sleep(100);
455                                xbeePacket = getFirstIPDataPacketFrom(ipAddress, 0);
456                        }
457                        return xbeePacket;
458                } else {
459                        synchronized (lock) {
460                                for (int i = 0; i < packetsList.size(); i++) {
461                                        XBeePacket xbeePacket = packetsList.get(i);
462                                        if (isIPDataPacket(xbeePacket) && ipAddressesMatch(xbeePacket, ipAddress))
463                                                return packetsList.remove(i);
464                                }
465                        }
466                }
467                return null;
468        }
469        
470        /**
471         * Returns the first IPv6 data packet from the queue whose IPv6 address 
472         * matches the provided address.
473         * 
474         * <p>The methods waits up to the specified timeout if necessary for a 
475         * IPv6 data packet to become available. {@code null} if the 
476         * queue is empty or there is not any IPv6 data packet sent by 
477         * the provided IPv6 address.</p>
478         * 
479         * @param ipv6Address The IPv6 address to look for in the list of packets.
480         * @param timeout The time in milliseconds to wait for a IPv6 data 
481         *                packet from the specified IPv6 address to become available.
482         *                0 to return immediately.
483         * 
484         * @return The first IPv6 packet whose IPv6 address matches the provided 
485         *         IPv6 address. {@code null} if no IPv6 data packets from the 
486         *         specified IPv6 address are found in the queue.
487         * 
488         * @see com.digi.xbee.api.packet.XBeePacket
489         * @see com.digi.xbee.api.packet.thread.RXIPv6Packet
490         * @see java.net.Inet6Address
491         * 
492         * @since 1.2.1
493         */
494        public XBeePacket getFirstIPv6DataPacketFrom(Inet6Address ipv6Address, int timeout) {
495                if (timeout > 0) {
496                        XBeePacket xbeePacket = getFirstIPv6DataPacketFrom(ipv6Address, 0);
497                        // Wait for a timeout or until a IPv6 data packet with the provided IPv6 address is read.
498                        Long deadLine = System.currentTimeMillis() + timeout;
499                        while (xbeePacket == null && deadLine > System.currentTimeMillis()) {
500                                sleep(100);
501                                xbeePacket = getFirstIPv6DataPacketFrom(ipv6Address, 0);
502                        }
503                        return xbeePacket;
504                } else {
505                        synchronized (lock) {
506                                for (int i = 0; i < packetsList.size(); i++) {
507                                        XBeePacket xbeePacket = packetsList.get(i);
508                                        if (isIPv6DataPacket(xbeePacket) && ipv6AddressesMatch(xbeePacket, ipv6Address))
509                                                return packetsList.remove(i);
510                                }
511                        }
512                }
513                return null;
514        }
515        
516        /**
517         * Returns whether or not the source address of the provided XBee packet 
518         * matches the address of the given remote XBee device.
519         * 
520         * @param xbeePacket The XBee packet to compare its address with the 
521         *                   remote XBee device.
522         * @param remoteXBeeDevice The remote XBee device to compare its address 
523         *                         with the XBee packet.
524         * 
525         * @return {@code true} if the source address of the provided packet (if 
526         *         it has) matches the address of the remote XBee device.
527         * 
528         * @see com.digi.xbee.api.RemoteXBeeDevice
529         * @see com.digi.xbee.api.packet.XBeePacket
530         */
531        private boolean addressesMatch(XBeePacket xbeePacket, RemoteXBeeDevice remoteXBeeDevice) {
532                if (!(xbeePacket instanceof XBeeAPIPacket))
533                        return false;
534                APIFrameType packetType = ((XBeeAPIPacket)xbeePacket).getFrameType();
535                switch (packetType) {
536                case RECEIVE_PACKET:
537                        if (remoteXBeeDevice.get64BitAddress() != null && ((ReceivePacket)xbeePacket).get64bitSourceAddress().equals(remoteXBeeDevice.get64BitAddress()))
538                                return true;
539                        if (remoteXBeeDevice.get16BitAddress() != null && ((ReceivePacket)xbeePacket).get16bitSourceAddress().equals(remoteXBeeDevice.get16BitAddress()))
540                                return true;
541                        break;
542                case REMOTE_AT_COMMAND_RESPONSE:
543                        if (remoteXBeeDevice.get64BitAddress() != null && ((RemoteATCommandResponsePacket)xbeePacket).get64bitSourceAddress().equals(remoteXBeeDevice.get64BitAddress()))
544                                return true;
545                        if (remoteXBeeDevice.get16BitAddress() != null && ((RemoteATCommandResponsePacket)xbeePacket).get16bitSourceAddress().equals(remoteXBeeDevice.get16BitAddress()))
546                                return true;
547                        break;
548                case RX_16:
549                        if (((RX16Packet)xbeePacket).get16bitSourceAddress().equals(remoteXBeeDevice.get16BitAddress()))
550                                return true;
551                        break;
552                case RX_64:
553                        if (((RX64Packet)xbeePacket).get64bitSourceAddress().equals(remoteXBeeDevice.get64BitAddress()))
554                                return true;
555                        break;
556                case RX_IO_16:
557                        if (((RX16IOPacket)xbeePacket).get16bitSourceAddress().equals(remoteXBeeDevice.get16BitAddress()))
558                                return true;
559                        break;
560                case RX_IO_64:
561                        if (((RX64IOPacket)xbeePacket).get64bitSourceAddress().equals(remoteXBeeDevice.get64BitAddress()))
562                                return true;
563                        break;
564                case EXPLICIT_RX_INDICATOR:
565                        if (((ExplicitRxIndicatorPacket)xbeePacket).get64BitSourceAddress().equals(remoteXBeeDevice.get64BitAddress()))
566                                return true;
567                        break;
568                default:
569                        return false;
570                }
571                return false;
572        }
573        
574        /**
575         * Returns whether or not the IP address of the XBee packet matches the 
576         * provided one. 
577         * 
578         * @param xbeePacket The XBee packet to compare its IP address with the 
579         *                   provided one.
580         * @param ipAddress The IP address to be compared with the XBee packet's one.
581         * 
582         * @return {@code true} if the IP address of the XBee packet (if it has) 
583         *         matches the provided one. {@code false} otherwise.
584         * 
585         * @see com.digi.xbee.api.packet.XBeePacket
586         * @see java.net.Inet4Address
587         * 
588         * @since 1.2.0
589         */
590        private boolean ipAddressesMatch(XBeePacket xbeePacket, Inet4Address ipAddress) {
591                if (xbeePacket == null || ipAddress == null 
592                                || !(xbeePacket instanceof XBeeAPIPacket))
593                        return false;
594                APIFrameType packetType = ((XBeeAPIPacket)xbeePacket).getFrameType();
595                switch (packetType) {
596                case RX_IPV4:
597                        if (((RXIPv4Packet)xbeePacket).getSourceAddress().equals(ipAddress))
598                                return true;
599                        break;
600                default:
601                        return false;
602                }
603                return false;
604        }
605        
606        /**
607         * Returns whether the IPv6 address of the XBee packet matches the 
608         * provided one or not. 
609         * 
610         * @param xbeePacket The XBee packet to compare its IPv6 address with the 
611         *                   provided one.
612         * @param ipv6Address The IPv6 address to be compared with the XBee 
613         *                    packet's one.
614         * 
615         * @return {@code true} if the Iv6P address of the XBee packet (if it has) 
616         *         matches the provided one. {@code false} otherwise.
617         * 
618         * @see com.digi.xbee.api.packet.XBeePacket
619         * @see java.net.Inet6Address
620         * 
621         * @since 1.2.1
622         */
623        private boolean ipv6AddressesMatch(XBeePacket xbeePacket, Inet6Address ipv6Address) {
624                if (xbeePacket == null || ipv6Address == null 
625                                || !(xbeePacket instanceof XBeeAPIPacket))
626                        return false;
627                APIFrameType packetType = ((XBeeAPIPacket)xbeePacket).getFrameType();
628                switch (packetType) {
629                case RX_IPV6:
630                        if (((RXIPv6Packet)xbeePacket).getSourceAddress().equals(ipv6Address))
631                                return true;
632                        break;
633                default:
634                        return false;
635                }
636                return false;
637        }
638        
639        /**
640         * Returns whether or not the given XBee packet is a data packet.
641         * 
642         * @param xbeePacket The XBee packet to check if is data packet.
643         * 
644         * @return {@code true} if the XBee packet is a data packet, {@code false} 
645         *         otherwise.
646         * 
647         * @see com.digi.xbee.api.packet.XBeePacket
648         */
649        private boolean isDataPacket(XBeePacket xbeePacket) {
650                if (!(xbeePacket instanceof XBeeAPIPacket))
651                        return false;
652                APIFrameType packetType = ((XBeeAPIPacket)xbeePacket).getFrameType();
653                switch (packetType) {
654                        case RECEIVE_PACKET:
655                        case RX_16:
656                        case RX_64:
657                                return true;
658                        default:
659                                return false;
660                }
661        }
662        
663        /**
664         * Returns whether or not the given XBee packet is an explicit data packet.
665         * 
666         * @param xbeePacket The XBee packet to check if is an explicit data packet.
667         * 
668         * @return {@code true} if the XBee packet is an explicit data packet, 
669         *         {@code false} otherwise.
670         * 
671         * @see com.digi.xbee.api.packet.XBeePacket
672         * @see com.digi.xbee.api.packet.common.ExplicitRxIndicatorPacket
673         */
674        private boolean isExplicitDataPacket(XBeePacket xbeePacket) {
675                if (!(xbeePacket instanceof XBeeAPIPacket))
676                        return false;
677                APIFrameType packetType = ((XBeeAPIPacket)xbeePacket).getFrameType();
678                return packetType == APIFrameType.EXPLICIT_RX_INDICATOR;
679        }
680        
681        /**
682         * Returns whether or not the given XBee packet is a IP data packet.
683         * 
684         * @param xbeePacket The XBee packet to check if is a IP data packet.
685         * 
686         * @return {@code true} if the XBee packet is a IP data packet, 
687         *         {@code false} otherwise.
688         * 
689         * @see com.digi.xbee.api.packet.XBeePacket
690         * @see com.digi.xbee.api.packet.ip.RXIPv4Packet
691         * 
692         * @since 1.2.0
693         */
694        private boolean isIPDataPacket(XBeePacket xbeePacket) {
695                if (!(xbeePacket instanceof XBeeAPIPacket))
696                        return false;
697                APIFrameType packetType = ((XBeeAPIPacket)xbeePacket).getFrameType();
698                return packetType == APIFrameType.RX_IPV4;
699        }
700        
701        /**
702         * Returns whether the given XBee packet is an IPv6 data packet or not.
703         * 
704         * @param xbeePacket The XBee packet to check if is an IPv6 data packet.
705         * 
706         * @return {@code true} if the XBee packet is an IPv6 data packet, 
707         *         {@code false} otherwise.
708         * 
709         * @see com.digi.xbee.api.packet.XBeePacket
710         * @see com.digi.xbee.api.packet.thread.RXIPv6Packet
711         * 
712         * @since 1.2.1
713         */
714        private boolean isIPv6DataPacket(XBeePacket xbeePacket) {
715                if (!(xbeePacket instanceof XBeeAPIPacket))
716                        return false;
717                APIFrameType packetType = ((XBeeAPIPacket)xbeePacket).getFrameType();
718                return packetType == APIFrameType.RX_IPV6;
719        }
720        
721        /**
722         * Sleeps the thread for the given number of milliseconds.
723         * 
724         * @param milliseconds The number of milliseconds that the thread should 
725         *        be sleeping.
726         */
727        private void sleep(int milliseconds) {
728                try {
729                        Thread.sleep(milliseconds);
730                } catch (InterruptedException e) { }
731        }
732        
733        /**
734         * Returns the maximum size of the XBee packets queue.
735         * 
736         * @return The maximum size of the XBee packets queue.
737         */
738        public int getMaxSize() {
739                return maxLength;
740        }
741        
742        /**
743         * Returns the current size of the XBee packets queue.
744         * 
745         * @return The current size of the XBee packets queue.
746         */
747        public int getCurrentSize() {
748                synchronized (lock) {
749                        return packetsList.size();
750                }
751        }
752}