001/**
002 * Copyright (c) 2014-2015 Digi International Inc.,
003 * All rights not expressly granted are reserved.
004 *
005 * This Source Code Form is subject to the terms of the Mozilla Public
006 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
007 * You can obtain one at http://mozilla.org/MPL/2.0/.
008 *
009 * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
010 * =======================================================================
011 */
012package com.digi.xbee.api;
013
014import com.digi.xbee.api.connection.IConnectionInterface;
015import com.digi.xbee.api.connection.serial.SerialPortParameters;
016import com.digi.xbee.api.exceptions.InterfaceNotOpenException;
017import com.digi.xbee.api.exceptions.OperationNotSupportedException;
018import com.digi.xbee.api.exceptions.TimeoutException;
019import com.digi.xbee.api.exceptions.XBeeDeviceException;
020import com.digi.xbee.api.exceptions.XBeeException;
021import com.digi.xbee.api.models.AssociationIndicationStatus;
022import com.digi.xbee.api.models.XBee16BitAddress;
023import com.digi.xbee.api.models.XBee64BitAddress;
024import com.digi.xbee.api.models.XBeeProtocol;
025import com.digi.xbee.api.models.XBeeTransmitOptions;
026import com.digi.xbee.api.packet.XBeePacket;
027import com.digi.xbee.api.packet.raw.TX16Packet;
028import com.digi.xbee.api.utils.HexUtils;
029
030/**
031 * This class represents a local 802.15.4 device.
032 * 
033 * @see XBeeDevice
034 * @see DigiMeshDevice
035 * @see DigiPointDevice
036 * @see ZigBeeDevice
037 */
038public class Raw802Device extends XBeeDevice {
039
040        /**
041         * Class constructor. Instantiates a new {@code Raw802Device} object in the 
042         * given port name and baud rate.
043         * 
044         * @param port Serial port name where 802.15.4 device is attached to.
045         * @param baudRate Serial port baud rate to communicate with the device. 
046         *                 Other connection parameters will be set as default (8 
047         *                 data bits, 1 stop bit, no parity, no flow control).
048         * 
049         * @throws IllegalArgumentException if {@code baudRate < 0}.
050         * @throws NullPointerException if {@code port == null}.
051         */
052        public Raw802Device(String port, int baudRate) {
053                this(XBee.createConnectiontionInterface(port, baudRate));
054        }
055        
056        /**
057         * Class constructor. Instantiates a new {@code Raw802Device} object in the 
058         * given serial port name and settings.
059         * 
060         * @param port Serial port name where 802.15.4 device is attached to.
061         * @param baudRate Serial port baud rate to communicate with the device.
062         * @param dataBits Serial port data bits.
063         * @param stopBits Serial port data bits.
064         * @param parity Serial port data bits.
065         * @param flowControl Serial port data bits.
066         * 
067         * @throws IllegalArgumentException if {@code baudRate < 0} or
068         *                                  if {@code dataBits < 0} or
069         *                                  if {@code stopBits < 0} or
070         *                                  if {@code parity < 0} or
071         *                                  if {@code flowControl < 0}.
072         * @throws NullPointerException if {@code port == null}.
073         */
074        public Raw802Device(String port, int baudRate, int dataBits, int stopBits, int parity, int flowControl) {
075                this(port, new SerialPortParameters(baudRate, dataBits, stopBits, parity, flowControl));
076        }
077        
078        /**
079         * Class constructor. Instantiates a new {@code Raw802Device} object in the 
080         * given serial port name and parameters.
081         * 
082         * @param port Serial port name where 802.15.4 device is attached to.
083         * @param serialPortParameters Object containing the serial port parameters.
084         * 
085         * @throws NullPointerException if {@code port == null} or
086         *                              if {@code serialPortParameters == null}.
087         * 
088         * @see SerialPortParameters
089         */
090        public Raw802Device(String port, SerialPortParameters serialPortParameters) {
091                this(XBee.createConnectiontionInterface(port, serialPortParameters));
092        }
093        
094        /**
095         * Class constructor. Instantiates a new {@code Raw802Device} object with the 
096         * given connection interface.
097         * 
098         * @param connectionInterface The connection interface with the physical 
099         *                            802.15.4 device.
100         * 
101         * @throws NullPointerException if {@code connectionInterface == null}
102         * 
103         * @see IConnectionInterface
104         */
105        public Raw802Device(IConnectionInterface connectionInterface) {
106                super(connectionInterface);
107        }
108        
109        /*
110         * (non-Javadoc)
111         * @see com.digi.xbee.api.XBeeDevice#open()
112         */
113        @Override
114        public void open() throws XBeeException {
115                super.open();
116                if (isRemote())
117                        return;
118                if (xbeeProtocol != XBeeProtocol.RAW_802_15_4)
119                        throw new XBeeDeviceException("XBee device is not a " + getXBeeProtocol().getDescription() + " device, it is a " + xbeeProtocol.getDescription() + " device.");
120        }
121        
122        /*
123         * (non-Javadoc)
124         * @see com.digi.xbee.api.XBeeDevice#getNetwork()
125         */
126        @Override
127        public XBeeNetwork getNetwork() {
128                if (!isOpen())
129                        throw new InterfaceNotOpenException();
130                
131                if (network == null)
132                        network = new Raw802Network(this);
133                return network;
134        }
135        
136        /*
137         * (non-Javadoc)
138         * @see com.digi.xbee.api.XBeeDevice#getXBeeProtocol()
139         */
140        @Override
141        public XBeeProtocol getXBeeProtocol() {
142                return XBeeProtocol.RAW_802_15_4;
143        }
144        
145        /*
146         * (non-Javadoc)
147         * @see com.digi.xbee.api.XBeeDevice#sendDataAsync(com.digi.xbee.api.models.XBee64BitAddress, byte[])
148         */
149        @Override
150        public void sendDataAsync(XBee64BitAddress address, byte[] data) throws XBeeException {
151                super.sendDataAsync(address, data);
152        }
153        
154        /**
155         * Sends the provided data to the XBee device of the network corresponding 
156         * to the given 16-bit address asynchronously.
157         * 
158         * <p>Asynchronous transmissions do not wait for answer from the remote 
159         * device or for transmit status packet</p>
160         * 
161         * @param address The 16-bit address of the XBee that will receive the data.
162         * @param data Byte array containing data to be sent.
163         * 
164         * @throws InterfaceNotOpenException if the device is not open.
165         * @throws NullPointerException if {@code address == null} or 
166         *                              if {@code data == null}.
167         * @throws XBeeException if there is any XBee related exception.
168         * 
169         * @see com.digi.xbee.api.models.XBee16BitAddress
170         * @see #sendData(RemoteXBeeDevice, byte[])
171         * @see #sendData(XBee16BitAddress, byte[])
172         * @see #sendData(XBee64BitAddress, byte[])
173         * @see #sendDataAsync(RemoteXBeeDevice, byte[])
174         * @see #sendDataAsync(XBee64BitAddress, byte[])
175         */
176        public void sendDataAsync(XBee16BitAddress address, byte[] data) throws XBeeException {
177                // Verify the parameters are not null, if they are null, throw an exception.
178                if (address == null)
179                        throw new NullPointerException("Address cannot be null");
180                if (data == null)
181                        throw new NullPointerException("Data cannot be null");
182                
183                // Check if device is remote.
184                if (isRemote())
185                        throw new OperationNotSupportedException("Cannot send data to a remote device from a remote device.");
186                
187                logger.info(toString() + "Sending data asynchronously to {} >> {}.", address, HexUtils.prettyHexString(data));
188                
189                XBeePacket xbeePacket = new TX16Packet(getNextFrameID(), address, XBeeTransmitOptions.NONE, data);
190                sendAndCheckXBeePacket(xbeePacket, true);
191        }
192        
193        /*
194         * (non-Javadoc)
195         * @see com.digi.xbee.api.XBeeDevice#sendData(com.digi.xbee.api.models.XBee64BitAddress, byte[])
196         */
197        @Override
198        public void sendData(XBee64BitAddress address, byte[] data) throws TimeoutException, XBeeException {
199                super.sendData(address, data);
200        }
201        
202        /**
203         * Sends the provided data to the XBee device of the network corresponding 
204         * to the given 16-bit address.
205         * 
206         * <p>This method blocks until a success or error response arrives or the 
207         * configured receive timeout expires.</p>
208         * 
209         * <p>The received timeout is configured using the {@code setReceiveTimeout}
210         * method and can be consulted with {@code getReceiveTimeout} method.</p>
211         * 
212         * <p>For non-blocking operations use the method 
213         * {@link #sendData(XBee16BitAddress, byte[])}.</p>
214         * 
215         * @param address The 16-bit address of the XBee that will receive the data.
216         * @param data Byte array containing data to be sent.
217         * 
218         * @throws InterfaceNotOpenException if the device is not open.
219         * @throws NullPointerException if {@code address == null} or 
220         *                              if {@code data == null}.
221         * @throws TimeoutException if there is a timeout sending the data.
222         * @throws XBeeException if there is any other XBee related exception.
223         * 
224         * @see com.digi.xbee.api.models.XBee16BitAddress
225         * @see XBeeDevice#getReceiveTimeout()
226         * @see XBeeDevice#setReceiveTimeout(int)
227         * @see #sendData(RemoteXBeeDevice, byte[])
228         * @see #sendData(XBee64BitAddress, byte[])
229         * @see #sendDataAsync(RemoteXBeeDevice, byte[])
230         * @see #sendDataAsync(XBee16BitAddress, byte[])
231         * @see #sendDataAsync(XBee64BitAddress, byte[])
232         */
233        public void sendData(XBee16BitAddress address, byte[] data) throws TimeoutException, XBeeException {
234                // Verify the parameters are not null, if they are null, throw an exception.
235                if (address == null)
236                        throw new NullPointerException("Address cannot be null");
237                if (data == null)
238                        throw new NullPointerException("Data cannot be null");
239                
240                // Check if device is remote.
241                if (isRemote())
242                        throw new OperationNotSupportedException("Cannot send data to a remote device from a remote device.");
243                
244                logger.info(toString() + "Sending data to {} >> {}.", address, HexUtils.prettyHexString(data));
245                
246                XBeePacket xbeePacket = new TX16Packet(getNextFrameID(), address, XBeeTransmitOptions.NONE, data);
247                sendAndCheckXBeePacket(xbeePacket, false);
248        }
249        
250        /*
251         * (non-Javadoc)
252         * @see com.digi.xbee.api.AbstractXBeeDevice#set16BitAddress(com.digi.xbee.api.models.XBee16BitAddress)
253         */
254        @Override
255        public void set16BitAddress(XBee16BitAddress xbee16BitAddress) throws TimeoutException, XBeeException {
256                super.set16BitAddress(xbee16BitAddress);
257        }
258        
259        /*
260         * (non-Javadoc)
261         * @see com.digi.xbee.api.AbstractXBeeDevice#getAssociationIndicationStatus()
262         */
263        @Override
264        public AssociationIndicationStatus getAssociationIndicationStatus() throws TimeoutException, XBeeException {
265                return super.getAssociationIndicationStatus();
266        }
267}