001/**
002 * Copyright (c) 2014 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 connection.
184                if (!connectionInterface.isOpen())
185                        throw new InterfaceNotOpenException();
186                // Check if device is remote.
187                if (isRemote())
188                        throw new OperationNotSupportedException("Cannot send data to a remote device from a remote device.");
189                
190                logger.info(toString() + "Sending data asynchronously to {} >> {}.", address, HexUtils.prettyHexString(data));
191                
192                XBeePacket xbeePacket = new TX16Packet(getNextFrameID(), address, XBeeTransmitOptions.NONE, data);
193                sendAndCheckXBeePacket(xbeePacket, true);
194        }
195        
196        /*
197         * (non-Javadoc)
198         * @see com.digi.xbee.api.XBeeDevice#sendData(com.digi.xbee.api.models.XBee64BitAddress, byte[])
199         */
200        @Override
201        public void sendData(XBee64BitAddress address, byte[] data) throws TimeoutException, XBeeException {
202                super.sendData(address, data);
203        }
204        
205        /**
206         * Sends the provided data to the XBee device of the network corresponding 
207         * to the given 16-bit address.
208         * 
209         * <p>This method blocks until a success or error response arrives or the 
210         * configured receive timeout expires.</p>
211         * 
212         * <p>The received timeout is configured using the {@code setReceiveTimeout}
213         * method and can be consulted with {@code getReceiveTimeout} method.</p>
214         * 
215         * <p>For non-blocking operations use the method 
216         * {@link #sendData(XBee16BitAddress, byte[])}.</p>
217         * 
218         * @param address The 16-bit address of the XBee that will receive the data.
219         * @param data Byte array containing data to be sent.
220         * 
221         * @throws InterfaceNotOpenException if the device is not open.
222         * @throws NullPointerException if {@code address == null} or 
223         *                              if {@code data == null}.
224         * @throws TimeoutException if there is a timeout sending the data.
225         * @throws XBeeException if there is any other XBee related exception.
226         * 
227         * @see com.digi.xbee.api.models.XBee16BitAddress
228         * @see XBeeDevice#getReceiveTimeout()
229         * @see XBeeDevice#setReceiveTimeout(int)
230         * @see #sendData(RemoteXBeeDevice, byte[])
231         * @see #sendData(XBee64BitAddress, byte[])
232         * @see #sendDataAsync(RemoteXBeeDevice, byte[])
233         * @see #sendDataAsync(XBee16BitAddress, byte[])
234         * @see #sendDataAsync(XBee64BitAddress, byte[])
235         */
236        public void sendData(XBee16BitAddress address, byte[] data) throws TimeoutException, XBeeException {
237                // Verify the parameters are not null, if they are null, throw an exception.
238                if (address == null)
239                        throw new NullPointerException("Address cannot be null");
240                if (data == null)
241                        throw new NullPointerException("Data cannot be null");
242                
243                // Check connection.
244                if (!connectionInterface.isOpen())
245                        throw new InterfaceNotOpenException();
246                // Check if device is remote.
247                if (isRemote())
248                        throw new OperationNotSupportedException("Cannot send data to a remote device from a remote device.");
249                
250                logger.info(toString() + "Sending data to {} >> {}.", address, HexUtils.prettyHexString(data));
251                
252                XBeePacket xbeePacket = new TX16Packet(getNextFrameID(), address, XBeeTransmitOptions.NONE, data);
253                sendAndCheckXBeePacket(xbeePacket, false);
254        }
255        
256        /*
257         * (non-Javadoc)
258         * @see com.digi.xbee.api.AbstractXBeeDevice#set16BitAddress(com.digi.xbee.api.models.XBee16BitAddress)
259         */
260        @Override
261        public void set16BitAddress(XBee16BitAddress xbee16BitAddress) throws TimeoutException, XBeeException {
262                super.set16BitAddress(xbee16BitAddress);
263        }
264        
265        /*
266         * (non-Javadoc)
267         * @see com.digi.xbee.api.AbstractXBeeDevice#getAssociationIndicationStatus()
268         */
269        @Override
270        public AssociationIndicationStatus getAssociationIndicationStatus() throws TimeoutException, XBeeException {
271                return super.getAssociationIndicationStatus();
272        }
273}