Example #1
0
        /**
         * Class constructor. Instantiates a new {@code RemoteATCommandRequest}
         * object with the given parameters.
         *
         * @param frameID Frame ID.
         * @param destAddress64 64-bit address of the destination device.
         * @param destAddress16 16-bit address of the destination device.
         * @param transmitOptions Bitfield of supported transmission options.
         * @param command AT command.
         * @param parameter AT command parameter.
         *
         * @throws ArgumentException if {@code frameID < 0} or
         *                                  if {@code frameID > 255} or
         *                                  if {@code transmitOptions < 0} or
         *                                  if {@code transmitOptions > 255}.
         * @throws ArgumentNullException if {@code destAddress64 == null} or
         *                              if {@code destAddress16 == null} or
         *                              if {@code command == null}.
         *
         * @see com.digi.xbee.api.models.XBeeTransmitOptions
         * @see com.digi.xbee.api.models.XBee16BitAddress
         * @see com.digi.xbee.api.models.XBee64BitAddress
         */
        public RemoteATCommandPacket(byte frameID, XBee64BitAddress destAddress64, XBee16BitAddress destAddress16,
                                     byte transmitOptions, string command, byte[] parameter)
            : base(APIFrameType.REMOTE_AT_COMMAND_REQUEST)
        {
            if (destAddress64 == null)
            {
                throw new ArgumentNullException("64-bit destination address cannot be null.");
            }
            if (destAddress16 == null)
            {
                throw new ArgumentNullException("16-bit destination address cannot be null.");
            }
            if (command == null)
            {
                throw new ArgumentNullException("AT command cannot be null.");
            }

            this.frameID         = frameID;
            this.destAddress64   = destAddress64;
            this.destAddress16   = destAddress16;
            this.transmitOptions = transmitOptions;
            this.Command         = command;
            this.parameter       = parameter;
            this.logger          = LogManager.GetLogger <RemoteATCommandPacket>();
        }
Example #2
0
        /**
         * Creates a new remote XBee device with the provided 64-bit address,
         * 16-bit address, node identifier and the XBee device that is using this
         * data reader as the connection interface for the remote device.
         *
         * The new XBee device will be a {@code RemoteDigiMeshDevice},
         * a {@code RemoteDigiPointDevice}, a {@code RemoteRaw802Device} or a
         * {@code RemoteZigBeeDevice} depending on the protocol of the local XBee
         * device. If the protocol cannot be determined or is unknown a
         * {@code RemoteXBeeDevice} will be created instead.
         *
         * @param addr64 The 64-bit address of the new remote device. It cannot be
         *               {@code null}.
         * @param addr16 The 16-bit address of the new remote device. It may be
         *               {@code null}.
         * @param ni The node identifier of the new remote device. It may be
         *           {@code null}.
         *
         * @return a new remote XBee device with the given parameters.
         */
        private RemoteXBeeDevice createRemoteXBeeDevice(XBee64BitAddress addr64,
                                                        XBee16BitAddress addr16, String ni)
        {
            RemoteXBeeDevice device = null;

            switch (xbeeDevice.XBeeProtocol)
            {
            case XBeeProtocol.ZIGBEE:
                device = new RemoteZigBeeDevice(xbeeDevice, addr64, addr16, ni);
                break;

            case XBeeProtocol.DIGI_MESH:
                device = new RemoteDigiMeshDevice(xbeeDevice, addr64, ni);
                break;

            case XBeeProtocol.DIGI_POINT:
                device = new RemoteDigiPointDevice(xbeeDevice, addr64, ni);
                break;

            case XBeeProtocol.RAW_802_15_4:
                device = new RemoteRaw802Device(xbeeDevice, addr64, addr16, ni);
                break;

            default:
                device = new RemoteXBeeDevice(xbeeDevice, addr64, addr16, ni);
                break;
            }

            return(device);
        }
 /**
  * Class constructor. Instantiates a new {@code RemoteDigiMeshDevice} object
  * with the given local {@code XBeeDevice} which contains the connection
  * interface to be used.
  *
  * @param localXBeeDevice The local XBee device that will behave as
  *                        connection interface to communicate with this
  *                        remote DigiMesh device.
  * @param addr64 The 64-bit address to identify this remote DigiMesh device.
  * @param id The node identifier of this remote DigiMesh device. It might
  *           be {@code null}.
  *
  * @throws ArgumentException if {@code localXBeeDevice.isRemote() == true} or
  *                                  if {@code localXBeeDevice.getXBeeProtocol() != XBeeProtocol.DIGI_MESH}.
  * @throws ArgumentNullException if {@code localXBeeDevice == null} or
  *                              if {@code addr64 == null}.
  *
  * @see com.digi.xbee.api.models.XBee64BitAddress
  */
 public RemoteDigiMeshDevice(XBeeDevice localXBeeDevice, XBee64BitAddress addr64, string id)
     : base(localXBeeDevice, addr64, null, id)
 {
     // Verify the local device has DigiMesh protocol.
     if (localXBeeDevice.XBeeProtocol != Models.XBeeProtocol.DIGI_MESH)
         throw new ArgumentException("The protocol of the local XBee device is not " + XBeeProtocol.DIGI_MESH.GetDescription() + ".");
 }
Example #4
0
        /**
         * Class constructor. Instantiates a new
         * {@code RemoteATCommandResponsePacket} object with the given parameters.
         *
         * @param frameID frame ID.
         * @param sourceAddress64 64-bit address of the remote radio returning
         *                        response.
         * @param sourceAddress16 16-bit network address of the remote.
         * @param command The AT command.
         * @param status The command status.
         * @param commandValue The AT command response value.
         *
         * @throws ArgumentException if {@code frameID < 0} or
         *                                  if {@code frameID > 255}.
         * @throws ArgumentNullException if {@code sourceAddress64 == null} or
         *                              if {@code sourceAddress16 == null} or
         *                              if {@code command == null} or
         *                              if {@code status == null}.
         *
         * @see com.digi.xbee.api.models.ATCommandStatus
         * @see com.digi.xbee.api.models.XBee16BitAddress
         * @see com.digi.xbee.api.models.XBee64BitAddress
         */
        public RemoteATCommandResponsePacket(byte frameID, XBee64BitAddress sourceAddress64, XBee16BitAddress sourceAddress16,
                                             String command, ATCommandStatus status, byte[] commandValue)
            : base(APIFrameType.REMOTE_AT_COMMAND_RESPONSE)
        {
            if (sourceAddress64 == null)
            {
                throw new ArgumentNullException("64-bit source address cannot be null.");
            }
            if (sourceAddress16 == null)
            {
                throw new ArgumentNullException("16-bit source address cannot be null.");
            }
            if (command == null)
            {
                throw new ArgumentNullException("AT command cannot be null.");
            }
            if (status == null)
            {
                throw new ArgumentNullException("AT command status cannot be null.");
            }
            if (frameID < 0 || frameID > 255)
            {
                throw new ArgumentException("Frame ID must be between 0 and 255.");
            }

            this.frameID         = frameID;
            this.sourceAddress64 = sourceAddress64;
            this.sourceAddress16 = sourceAddress16;
            this.Command         = command;
            this.Status          = status;
            this.commandValue    = commandValue;
            this.logger          = LogManager.GetLogger <RemoteATCommandResponsePacket>();
        }
 /**
  * Class constructor. Instantiates a new {@code RemoteDigiPointDevice} object
  * with the given local {@code XBeeDevice} which contains the connection
  * interface to be used.
  *
  * @param localXBeeDevice The local XBee device that will behave as
  *                        connection interface to communicate with this
  *                        remote point-to-multipoint device.
  * @param addr64 The 64-bit address to identify this remote point-to-multipoint
  *               device.
  *
  * @throws ArgumentException if {@code localXBeeDevice.isRemote() == true} or
  *                                  if {@code localXBeeDevice.getXBeeProtocol() != XBeeProtocol.DIGI_POINT}.
  * @throws ArgumentNullException if {@code localXBeeDevice == null} or
  *                              if {@code addr64 == null}.
  *
  * @see com.digi.xbee.api.models.XBee64BitAddress
  */
 public RemoteDigiPointDevice(XBeeDevice localXBeeDevice, XBee64BitAddress addr64)
     : base(localXBeeDevice, addr64)
 {
     // Verify the local device has point-to-multipoint protocol.
     if (localXBeeDevice.XBeeProtocol != XBeeProtocol.DIGI_POINT)
         throw new ArgumentException("The protocol of the local XBee device is not " + XBeeProtocol.DIGI_POINT.GetDescription() + ".");
 }
        /**
         * Class constructor. Instantiates a new
         * {@code IODataSampleRxIndicatorPacket} object with the given parameters.
         *
         * @param sourceAddress64 64-bit address of the sender.
         * @param sourceAddress16 16-bit address of the sender.
         * @param receiveOptions Receive options.
         * @param rfData Received RF data.
         *
         * @throws ArgumentException if {@code receiveOptions < 0} or
         *                                  if {@code receiveOptions > 255} or
         *                                  if {@code rfData.Length < 5}.
         * @throws ArgumentNullException if {@code sourceAddress64 == null} or
         *                              if {@code sourceAddress16 == null}.
         *
         * @see com.digi.xbee.api.models.XBeeReceiveOptions
         * @see com.digi.xbee.api.models.XBee16BitAddress
         * @see com.digi.xbee.api.models.XBee64BitAddress
         */
        public IODataSampleRxIndicatorPacket(XBee64BitAddress sourceAddress64, XBee16BitAddress sourceAddress16, byte receiveOptions, byte[] rfData)
            : base(APIFrameType.IO_DATA_SAMPLE_RX_INDICATOR)
        {
            if (sourceAddress64 == null)
            {
                throw new ArgumentNullException("64-bit source address cannot be null.");
            }
            if (sourceAddress16 == null)
            {
                throw new ArgumentNullException("16-bit source address cannot be null.");
            }

            this.sourceAddress64 = sourceAddress64;
            this.sourceAddress16 = sourceAddress16;
            this.ReceiveOptions  = receiveOptions;
            this.RFData          = rfData;
            if (rfData != null)
            {
                IOSample = new IOSample(rfData);
            }
            else
            {
                IOSample = null;
            }
            this.logger = LogManager.GetLogger <IODataSampleRxIndicatorPacket>();
        }
 /**
  * Class constructor. Instantiates a new {@code RemoteZigBeeDevice} object
  * with the given local {@code XBeeDevice} which contains the connection
  * interface to be used.
  *
  * @param localXBeeDevice The local XBee device that will behave as
  *                        connection interface to communicate with this
  *                        remote ZigBee device.
  * @param addr64 The 64-bit address to identify this remote ZigBee device.
  *
  * @throws ArgumentException if {@code localXBeeDevice.isRemote() == true} or
  *                                  if {@code localXBeeDevice.getXBeeProtocol() != XBeeProtocol.ZIGBEE}.
  * @throws ArgumentNullException if {@code localXBeeDevice == null} or
  *                              if {@code addr64 == null}.
  *
  * @see com.digi.xbee.api.models.XBee64BitAddress
  */
 public RemoteZigBeeDevice(XBeeDevice localXBeeDevice, XBee64BitAddress addr64)
     : base(localXBeeDevice, addr64)
 {
     // Verify the local device has ZigBee protocol.
     if (localXBeeDevice.XBeeProtocol != XBeeProtocol.ZIGBEE)
         throw new ArgumentException("The protocol of the local XBee device is not " + XBeeProtocol.ZIGBEE.GetDescription() + ".");
 }
        /// <summary>
        /// Class constructor. Instantiates a new <see cref="ExplicitAddressingPacket"/> object with the
        /// given parameters.
        /// </summary>
        /// <param name="frameID">The frame ID.</param>
        /// <param name="destAddress64">The 64-bit address of the destination device.</param>
        /// <param name="destAddress16">The 16-bit address of the destination device.</param>
        /// <param name="sourceEndpoint">The source endpoint for the transaction.</param>
        /// <param name="destEndpoint">The destination endpoint for the transaction.</param>
        /// <param name="clusterID">The cluster ID used in the transaction.</param>
        /// <param name="profileID">The profile ID used in the transaction.</param>
        /// <param name="broadcastRadius">The maximum number of hops a broadcast transmission can traverse.
        /// Set to 0 to use the network maximum hops value.</param>
        /// <param name="transmitOptions">The bitfield of supported transmission options.</param>
        /// <param name="rfData">The RF Data that is sent to the destination device.</param>
        /// <exception cref="ArgumentException">If <c><paramref name="frameID"/> <![CDATA[<]]> 0</c>
        /// or if <c><paramref name="frameID"/> <![CDATA[>]]> 255</c>
        /// or if <c>profileID.Length != 2</c> or if <c>clusterID.Length != 2</c>.</exception>
        /// <exception cref="ArgumentNullException">If <c><paramref name="destAddress64"/> == null</c>
        /// or if <c><paramref name="destAddress16"/> == null</c>.</exception>
        /// <seealso cref="XBeeTransmitOptions"/>
        /// <seealso cref="XBee16BitAddress"/>
        /// <seealso cref="XBee64BitAddress"/>
        public ExplicitAddressingPacket(byte frameID, XBee64BitAddress destAddress64, XBee16BitAddress destAddress16,
                                        byte sourceEndpoint, byte destEndpoint, byte[] clusterID, byte[] profileID, byte broadcastRadius,
                                        byte transmitOptions, byte[] rfData)
            : base(APIFrameType.EXPLICIT_ADDRESSING_COMMAND_FRAME)
        {
            if (profileID.Length != 2)
            {
                throw new ArgumentException("Profile ID length must be 2.");
            }
            if (clusterID.Length != 2)
            {
                throw new ArgumentException("Cluster ID length must be 2.");
            }

            FrameID         = frameID;
            DestAddress64   = destAddress64 ?? throw new ArgumentNullException("64-bit destination address cannot be null.");
            DestAddress16   = destAddress16 ?? throw new ArgumentNullException("16-bit destination address cannot be null.");
            SourceEndpoint  = sourceEndpoint;
            DestEndpoint    = destEndpoint;
            ClusterID       = clusterID;
            ProfileID       = profileID;
            BroadcastRadius = broadcastRadius;
            TransmitOptions = transmitOptions;
            RFData          = rfData;
            logger          = LogManager.GetLogger <TransmitPacket>();
        }
Example #9
0
        /// <summary>
        /// Creates a new <seealso cref="RemoteATCommandPacket"/> object from the given payload.
        /// </summary>
        /// <param name="payload">The API frame payload. It must start with the frame type corresponding
        /// to a Remote AT Command packet (<c>0x17</c>). The byte array must be in <see cref="OperatingMode.API"/>
        /// mode.</param>
        /// <returns>Parsed Remote AT Command packet.</returns>
        /// <exception cref="ArgumentException">If <c>payload[0] != APIFrameType.REMOTE_AT_COMMAND_REQUEST.GetValue()</c>
        /// or if <c>payload.Length <![CDATA[<]]> <see cref="MIN_API_PAYLOAD_LENGTH"/></c>.</exception>
        /// <exception cref="ArgumentNullException">If <c><paramref name="payload"/> == null</c>.</exception>
        public static RemoteATCommandPacket CreatePacket(byte[] payload)
        {
            if (payload == null)
            {
                throw new ArgumentNullException("Remote AT Command packet payload cannot be null.");
            }
            // 1 (Frame type) + 1 (frame ID) + 8 (64-bit address) + 2 (16-bit address) + 1 (transmit options byte) + 2 (AT command)
            if (payload.Length < MIN_API_PAYLOAD_LENGTH)
            {
                throw new ArgumentException("Incomplete Remote AT Command packet.");
            }
            if ((payload[0] & 0xFF) != APIFrameType.REMOTE_AT_COMMAND_REQUEST.GetValue())
            {
                throw new ArgumentException("Payload is not a Remote AT Command packet.");
            }

            // payload[0] is the frame type.
            int index = 1;

            // Frame ID byte.
            byte frameID = payload[index];

            index = index + 1;

            var array = new byte[8];

            Array.Copy(payload, index, array, 0, array.Length);
            // 8 bytes of 64-bit address.
            XBee64BitAddress destAddress64 = new XBee64BitAddress(array);

            index = index + 8;

            // 2 bytes of 16-bit address.
            XBee16BitAddress destAddress16 = new XBee16BitAddress(payload[index], payload[index + 1]);

            index = index + 2;

            // Options byte.
            byte transmitOptions = payload[index];

            index = index + 1;

            // 2 bytes of AT command.
            byte[] commandByte = new byte[] { payload[index], payload[index + 1] };
            string command     = Encoding.UTF8.GetString(commandByte, 0, commandByte.Length);

            index = index + 2;

            // Get data.
            byte[] parameterData = null;
            if (index < payload.Length)
            {
                parameterData = new byte[payload.Length - index];
                Array.Copy(payload, index, parameterData, 0, parameterData.Length);
            }

            return(new RemoteATCommandPacket(frameID, destAddress64, destAddress16, transmitOptions,
                                             command, parameterData));
        }
        /**
         * Removes the given remote XBee device from the network.
         *
         * <p>Notice that this operation does not remove the remote XBee device
         * from the actual XBee network; it just tells the network object that it
         * will no longer contain that device. However, next time a discovery is
         * performed, it could be added again automatically.</p>
         *
         * <p>This method will check for a device that matches the 64-bit address
         * of the provided one, if found, that device will be removed from the
         * corresponding list. In case the 64-bit address is not defined, it will
         * use the 16-bit address for DigiMesh and ZigBee devices.</p>
         *
         * @param remoteDevice The remote device to be removed from the network.
         *
         * @throws ArgumentNullException if {@code RemoteDevice == null}.
         *
         * @see #addRemoteDevice(RemoteXBeeDevice)
         * @see #clearDeviceList()
         * @see RemoteXBeeDevice
         */
        public void removeRemoteDevice(RemoteXBeeDevice remoteDevice)
        {
            if (remoteDevice == null)
            {
                throw new ArgumentNullException("Remote device cannot be null.");
            }

            RemoteXBeeDevice devInNetwork = null;

            // Look in the 64-bit map.
            XBee64BitAddress addr64 = remoteDevice.Get64BitAddress();

            if (addr64 != null && !addr64.Equals(XBee64BitAddress.UNKNOWN_ADDRESS))
            {
                if (remotesBy64BitAddr.TryRemove(addr64, out devInNetwork))
                {
                    return;
                }
            }

            // If not found, look in the 16-bit map.
            XBee16BitAddress addr16 = Get16BitAddress(remoteDevice);

            if (addr16 != null && !addr16.Equals(XBee16BitAddress.UNKNOWN_ADDRESS))
            {
                // The preference order is:
                //    1.- Look in the 64-bit map
                //    2.- Then in the 16-bit map.
                // This should be maintained in the 'getDeviceBy16BitAddress' method.

                // Look for the 16-bit address in the 64-bit map.
                ICollection <RemoteXBeeDevice> devices = remotesBy64BitAddr.Values;
                foreach (RemoteXBeeDevice d in devices)
                {
                    XBee16BitAddress a = Get16BitAddress(d);
                    if (a != null && a.Equals(addr16))
                    {
                        RemoteXBeeDevice r;
                        remotesBy64BitAddr.TryRemove(d.Get64BitAddress(), out r);
                        return;
                    }
                }

                // If not found, look for the 16-bit address in the 16-bit map.
                // Remove the device.
                if (remotesBy16BitAddr.TryRemove(addr16, out devInNetwork))
                {
                    return;
                }
            }

            // If the device does not contain a valid address log an error.
            if ((addr64 == null || addr64.Equals(XBee64BitAddress.UNKNOWN_ADDRESS)) &&
                (addr16 == null || addr16.Equals(XBee16BitAddress.UNKNOWN_ADDRESS)))
            {
                logger.ErrorFormat("{0}Remote device '{1}' cannot be removed: 64-bit and 16-bit addresses must be specified.",
                                   localDevice.ToString(), remoteDevice.ToString());
            }
        }
 /**
  * Class constructor. Instantiates a new {@code RemoteRaw802Device} object
  * with the given local {@code XBeeDevice} which contains the connection
  * interface to be used.
  *
  * @param localXBeeDevice The local XBee device that will behave as
  *                        connection interface to communicate with this
  *                        remote 802.15.4 device.
  * @param addr64 The 64-bit address to identify this remote 802.15.4 device.
  * @param addr16 The 16-bit address to identify this remote 802.15.4 device.
  *               It might be {@code null}.
  * @param id The node identifier of this remote 802.15.4 device. It might be
  *           {@code null}.
  *
  * @throws ArgumentException if {@code localXBeeDevice.isRemote() == true} or
  *                                  if {@code localXBeeDevice.getXBeeProtocol() != XBeeProtocol.RAW_802_15_4}
  * @throws ArgumentNullException if {@code localXBeeDevice == null} or
  *                              if {@code addr64 == null}.
  *
  * @see com.digi.xbee.api.models.XBee16BitAddress
  * @see com.digi.xbee.api.models.XBee64BitAddress
  */
 public RemoteRaw802Device(XBeeDevice localXBeeDevice, XBee64BitAddress addr64,
     XBee16BitAddress addr16, string id)
     : base(localXBeeDevice, addr64, addr16, id)
 {
     // Verify the local device has 802.15.4 protocol.
     if (localXBeeDevice.XBeeProtocol != XBeeProtocol.RAW_802_15_4)
         throw new ArgumentException("The protocol of the local XBee device is not " + XBeeProtocol.RAW_802_15_4.GetDescription() + ".");
 }
        /// <summary>
        /// Creates a new <see cref="TransmitPacket"/> object from the given payload.
        /// </summary>
        /// <param name="payload">The API frame payload. It must start with the frame type corresponding
        /// to a Transmit packet (<c>0x10</c>). The byte array must be in <see cref="OperatingMode.API"/>
        /// mode.</param>
        /// <returns>Parsed Transmit packet.</returns>
        /// <exception cref="ArgumentException">If <c>payload[0] != APIFrameType.TRANSMIT_REQUEST.GetValue()</c>
        /// or if <c>payload.length <![CDATA[<]]> <see cref="MIN_API_PAYLOAD_LENGTH"/></c>.</exception>
        /// <exception cref="ArgumentNullException">If <c><paramref name="payload"/> == null</c>.</exception>
        public static TransmitPacket CreatePacket(byte[] payload)
        {
            if (payload == null)
            {
                throw new ArgumentNullException("Transmit packet payload cannot be null.");
            }
            // 1 (Frame type) + 1 (frame ID) + 8 (64-bit address) + 2 (16-bit address) + 1 (broadcast radious) + 1 (options)
            if (payload.Length < MIN_API_PAYLOAD_LENGTH)
            {
                throw new ArgumentException("Incomplete Transmit packet.");
            }
            if ((payload[0] & 0xFF) != APIFrameType.TRANSMIT_REQUEST.GetValue())
            {
                throw new ArgumentException("Payload is not a Transmit packet.");
            }

            // payload[0] is the frame type.
            int index = 1;

            // Frame ID byte.
            byte frameID = payload[index];

            index = index + 1;

            var array = new byte[8];

            Array.Copy(payload, index, array, 0, array.Length);
            // 8 bytes of 64-bit address.
            XBee64BitAddress destAddress64 = new XBee64BitAddress(array);

            index = index + 8;

            // 2 bytes of 16-bit address.
            XBee16BitAddress destAddress16 = new XBee16BitAddress(payload[index], payload[index + 1]);

            index = index + 2;

            // Broadcast radious byte.
            byte broadcastRadius = payload[index];

            index = index + 1;

            // Options byte.
            byte options = payload[index];

            index = index + 1;

            // Get RF data.
            byte[] rfData = null;
            if (index < payload.Length)
            {
                rfData = new byte[payload.Length - index];
                Array.Copy(payload, index, rfData, 0, rfData.Length);
            }

            return(new TransmitPacket(frameID, destAddress64, destAddress16, broadcastRadius, options, rfData));
        }
 /// <summary>
 /// Class constructor. Instantiates a new <see cref="ReceivePacket"/> object with the
 /// given parameters.
 /// </summary>
 /// <param name="sourceAddress64">The 64-bit address of the sender device.</param>
 /// <param name="sourceAddress16">The 16-bit address of the sender device.</param>
 /// <param name="receiveOptions">The bitField of receive options.</param>
 /// <param name="rfData">The received RF data.</param>
 /// <exception cref="ArgumentException">If <c><paramref name="receiveOptions"/> <![CDATA[<]]> 0</c>
 /// or if <c><paramref name="receiveOptions"/> <![CDATA[>]]> 255</c>.</exception>
 /// <exception cref="ArgumentNullException">If <c><paramref name="sourceAddress64"/> == null</c>
 /// or if <c><paramref name="sourceAddress16"/> == null</c>.</exception>
 /// <seealso cref="XBeeReceiveOptions"/>
 /// <seealso cref="XBee16BitAddress"/>
 /// <seealso cref="XBee64BitAddress"/>
 public ReceivePacket(XBee64BitAddress sourceAddress64, XBee16BitAddress sourceAddress16, byte receiveOptions, byte[] rfData)
     : base(APIFrameType.RECEIVE_PACKET)
 {
     SourceAddress64 = sourceAddress64 ?? throw new ArgumentNullException("64-bit source address cannot be null.");
     SourceAddress16 = sourceAddress16 ?? throw new ArgumentNullException("16-bit source address cannot be null.");
     ReceiveOptions  = receiveOptions;
     RFData          = rfData;
     logger          = LogManager.GetLogger <ReceivePacket>();
 }
 /**
  * Class constructor. Instantiates a new {@code RemoteDigiMeshDevice} object
  * with the given local {@code XBeeDevice} which contains the connection
  * interface to be used.
  *
  * @param localXBeeDevice The local XBee device that will behave as
  *                        connection interface to communicate with this
  *                        remote DigiMesh device.
  * @param addr64 The 64-bit address to identify this remote DigiMesh device.
  * @param id The node identifier of this remote DigiMesh device. It might
  *           be {@code null}.
  *
  * @throws ArgumentException if {@code localXBeeDevice.isRemote() == true} or
  *                                  if {@code localXBeeDevice.getXBeeProtocol() != XBeeProtocol.DIGI_MESH}.
  * @throws ArgumentNullException if {@code localXBeeDevice == null} or
  *                              if {@code addr64 == null}.
  *
  * @see com.digi.xbee.api.models.XBee64BitAddress
  */
 public RemoteDigiMeshDevice(XBeeDevice localXBeeDevice, XBee64BitAddress addr64, string id)
     : base(localXBeeDevice, addr64, null, id)
 {
     // Verify the local device has DigiMesh protocol.
     if (localXBeeDevice.XBeeProtocol != Models.XBeeProtocol.DIGI_MESH)
     {
         throw new ArgumentException("The protocol of the local XBee device is not " + XBeeProtocol.DIGI_MESH.GetDescription() + ".");
     }
 }
 /// <summary>
 /// Class constructor. Instantiates a new <see cref="RemoteDigiPointDevice"/> object with the given
 /// local <see cref="XBeeDevice"/> which contains the connection interface to be used.
 /// </summary>
 /// <param name="localXBeeDevice">The local XBee device that will behave as connection
 /// interface to communicate with this remote point-to-multipoint device.</param>
 /// <param name="addr64">The 64-bit address to identify this remote point-to-multipoint device.</param>
 /// <param name="id">The node identifier of this remote point-to-multipoint device. It might be <c>null</c>.</param>
 /// <exception cref="ArgumentException">If <paramref name="localXBeeDevice"/> is remote
 /// or if <c><paramref name="localXBeeDevice"/> != <see cref="XBeeProtocol.DIGI_POINT"/></c>.</exception>
 /// <exception cref="ArgumentNullException">If <c><paramref name="localXBeeDevice"/> == null</c>
 /// or if <c><paramref name="addr64"/> == null</c>.</exception>
 /// /// <seealso cref="XBeeDevice"/>
 /// <seealso cref="XBee64BitAddress"/>
 public RemoteDigiPointDevice(AbstractXBeeDevice localXBeeDevice, XBee64BitAddress addr64, string id)
     : base(localXBeeDevice, addr64, null, id)
 {
     // Verify the local device has point-to-multipoint protocol.
     if (localXBeeDevice.XBeeProtocol != XBeeProtocol.DIGI_POINT)
     {
         throw new ArgumentException("The protocol of the local XBee device is not " + XBeeProtocol.DIGI_POINT.GetDescription() + ".");
     }
 }
 /**
  * Class constructor. Instantiates a new {@code RemoteZigBeeDevice} object
  * with the given local {@code XBeeDevice} which contains the connection
  * interface to be used.
  *
  * @param localXBeeDevice The local XBee device that will behave as
  *                        connection interface to communicate with this
  *                        remote ZigBee device.
  * @param addr64 The 64-bit address to identify this remote ZigBee device.
  *
  * @throws ArgumentException if {@code localXBeeDevice.isRemote() == true} or
  *                                  if {@code localXBeeDevice.getXBeeProtocol() != XBeeProtocol.ZIGBEE}.
  * @throws ArgumentNullException if {@code localXBeeDevice == null} or
  *                              if {@code addr64 == null}.
  *
  * @see com.digi.xbee.api.models.XBee64BitAddress
  */
 public RemoteZigBeeDevice(XBeeDevice localXBeeDevice, XBee64BitAddress addr64)
     : base(localXBeeDevice, addr64)
 {
     // Verify the local device has ZigBee protocol.
     if (localXBeeDevice.XBeeProtocol != XBeeProtocol.ZIGBEE)
     {
         throw new ArgumentException("The protocol of the local XBee device is not " + XBeeProtocol.ZIGBEE.GetDescription() + ".");
     }
 }
Example #17
0
 /// <summary>
 /// Class constructor. Instantiates a new <see cref="TX64Packet"/> object with the
 /// given parameters.
 /// </summary>
 /// <param name="frameID">The Frame ID.</param>
 /// <param name="destAddress64">The 64-bit address of the destination device.</param>
 /// <param name="transmitOptions">The bitfield of supported transmission options.</param>
 /// <param name="rfData">The RF Data that is sent to the destination device.</param>
 /// <exception cref="ArgumentException">If <c><paramref name="frameID"/> <![CDATA[<]]> 0</c>
 /// or if <c><paramref name="frameID"/> <![CDATA[>]]> 255</c>.</exception>
 /// <exception cref="ArgumentNullException">If <c><paramref name="destAddress64"/> == null</c>.</exception>
 /// <seealso cref="XBeeTransmitOptions"/>
 /// <seealso cref="XBee64BitAddress"/>
 public TX64Packet(byte frameID, XBee64BitAddress destAddress64, byte transmitOptions, byte[] rfData)
     : base(APIFrameType.TX_64)
 {
     FrameID         = frameID;
     DestAddress64   = destAddress64 ?? throw new ArgumentNullException("64-bit destination address cannot be null.");
     TransmitOptions = transmitOptions;
     RFData          = rfData;
     logger          = LogManager.GetLogger <TX64Packet>();
 }
 /**
  * Class constructor. Instantiates a new {@code RemoteRaw802Device} object
  * with the given local {@code XBeeDevice} which contains the connection
  * interface to be used.
  *
  * @param localXBeeDevice The local XBee device that will behave as
  *                        connection interface to communicate with this
  *                        remote 802.15.4 device.
  * @param addr64 The 64-bit address to identify this remote 802.15.4 device.
  * @param addr16 The 16-bit address to identify this remote 802.15.4 device.
  *               It might be {@code null}.
  * @param id The node identifier of this remote 802.15.4 device. It might be
  *           {@code null}.
  *
  * @throws ArgumentException if {@code localXBeeDevice.isRemote() == true} or
  *                                  if {@code localXBeeDevice.getXBeeProtocol() != XBeeProtocol.RAW_802_15_4}
  * @throws ArgumentNullException if {@code localXBeeDevice == null} or
  *                              if {@code addr64 == null}.
  *
  * @see com.digi.xbee.api.models.XBee16BitAddress
  * @see com.digi.xbee.api.models.XBee64BitAddress
  */
 public RemoteRaw802Device(XBeeDevice localXBeeDevice, XBee64BitAddress addr64,
                           XBee16BitAddress addr16, string id)
     : base(localXBeeDevice, addr64, addr16, id)
 {
     // Verify the local device has 802.15.4 protocol.
     if (localXBeeDevice.XBeeProtocol != XBeeProtocol.RAW_802_15_4)
     {
         throw new ArgumentException("The protocol of the local XBee device is not " + XBeeProtocol.RAW_802_15_4.GetDescription() + ".");
     }
 }
Example #19
0
        /**
         * Class constructor. Instantiates a new {@code TX64Packet} object with
         * the given parameters.
         *
         * @param frameID Frame ID.
         * @param destAddress64 64-bit address of the destination device.
         * @param transmitOptions Bitfield of supported transmission options.
         * @param rfData RF Data that is sent to the destination device.
         *
         * @throws ArgumentException if {@code frameID < 0} or
         *                                  if {@code frameID > 255} or
         *                                  if {@code transmitOptions < 0} or
         *                                  if {@code transmitOptions > 255}.
         * @throws ArgumentNullException if {@code destAddress64 == null}.
         *
         * @see com.digi.xbee.api.models.XBeeTransmitOptions
         * @see com.digi.xbee.api.models.XBee64BitAddress
         */
        public TX64Packet(byte frameID, XBee64BitAddress destAddress64, byte transmitOptions, byte[] rfData)
            : base(APIFrameType.TX_64)
        {
            Contract.Requires <ArgumentNullException>(destAddress64 != null, "64-bit destination address cannot be null.");

            this.frameID         = frameID;
            this.destAddress64   = destAddress64;
            this.TransmitOptions = transmitOptions;
            this.RFData          = rfData;
            this.logger          = LogManager.GetLogger <TX64Packet>();
        }
Example #20
0
 public override string ToString()
 {
     if (Is64BitAddress)
     {
         return(XBee64BitAddress.ToString());
     }
     else
     {
         throw new NotImplementedException();
     }
 }
        /**
         * Class constructor. Instantiates a new {@code TX64Packet} object with
         * the given parameters.
         *
         * @param frameID Frame ID.
         * @param destAddress64 64-bit address of the destination device.
         * @param transmitOptions Bitfield of supported transmission options.
         * @param rfData RF Data that is sent to the destination device.
         *
         * @throws ArgumentException if {@code frameID < 0} or
         *                                  if {@code frameID > 255} or
         *                                  if {@code transmitOptions < 0} or
         *                                  if {@code transmitOptions > 255}.
         * @throws ArgumentNullException if {@code destAddress64 == null}.
         *
         * @see com.digi.xbee.api.models.XBeeTransmitOptions
         * @see com.digi.xbee.api.models.XBee64BitAddress
         */
        public TX64Packet(byte frameID, XBee64BitAddress destAddress64, byte transmitOptions, byte[] rfData)
            : base(APIFrameType.TX_64)
        {
            Contract.Requires<ArgumentNullException>(destAddress64 != null, "64-bit destination address cannot be null.");

            this.frameID = frameID;
            this.destAddress64 = destAddress64;
            this.TransmitOptions = transmitOptions;
            this.RFData = rfData;
            this.logger = LogManager.GetLogger<TX64Packet>();
        }
        /// <summary>
        /// Initializes a new instance of <see cref="RX64Packet"/>.
        /// </summary>
        /// <param name="sourceAddress64">64-bit address of the sender.</param>
        /// <param name="rssi">Received signal strength indicator.</param>
        /// <param name="receiveOptions">Bitfield indicating the receive options.</param>
        /// <param name="rfData">Received RF data.</param>
        /// <exception cref="ArgumentNullException">if <paramref name="sourceAddress64"/> is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException">if <paramref name="rssi"/> is greater than 100.</exception>
        /// <seealso cref="XBeeReceiveOptions"/>
        public RX64Packet(XBee64BitAddress sourceAddress64, byte rssi, byte receiveOptions, byte[] rfData)
            : base(APIFrameType.RX_64)
        {
            Contract.Requires<ArgumentNullException>(sourceAddress64 != null, "64-bit source address cannot be null.");
            Contract.Requires<ArgumentOutOfRangeException>(rssi <= 100, "RSSI value must be between 0 and 100.");

            this.SourceAddress64 = sourceAddress64;
            this.RSSI = rssi;
            this.ReceiveOptions = receiveOptions;
            this.RFData = rfData;
            this.logger = LogManager.GetLogger<RX64Packet>();
        }
 /// <summary>
 /// Class constructor. Instantiates a new <see cref="TransmitPacket"/> object with the
 /// given parameters.
 /// </summary>
 /// <param name="frameID">The Frame ID.</param>
 /// <param name="destAddress64">The 64-bit address of the destination device.</param>
 /// <param name="destAddress16">The 16-bit address of the destination device.</param>
 /// <param name="broadcastRadius">The maximum number of hops a broadcast transmission can occur.</param>
 /// <param name="transmitOptions">The bitfield of supported transmission options.</param>
 /// <param name="rfData">The RF Data that is sent to the destination device.</param>
 /// <exception cref="ArgumentException">If <c><paramref name="frameID"/> <![CDATA[<]]> 0</c>
 /// or if <c><paramref name="frameID"/> <![CDATA[>]]> 255</c>.</exception>
 /// <exception cref="ArgumentNullException">If <c><paramref name="destAddress64"/> == null</c>
 /// or if <c><paramref name="destAddress16"/> == null</c>.</exception>
 /// <seealso cref="XBeeTransmitOptions"/>
 /// <seealso cref="XBee16BitAddress"/>
 /// <seealso cref="XBee64BitAddress"/>
 public TransmitPacket(byte frameID, XBee64BitAddress destAddress64, XBee16BitAddress destAddress16,
                       byte broadcastRadius, byte transmitOptions, byte[] rfData)
     : base(APIFrameType.TRANSMIT_REQUEST)
 {
     FrameID         = frameID;
     DestAddress64   = destAddress64 ?? throw new ArgumentNullException("64-bit destination address cannot be null.");
     DestAddress16   = destAddress16 ?? throw new ArgumentNullException("16-bit destination address cannot be null.");
     BroadcastRadius = broadcastRadius;
     TransmitOptions = transmitOptions;
     RFData          = rfData;
     logger          = LogManager.GetLogger <TransmitPacket>();
 }
Example #24
0
 /// <summary>
 /// Class constructor. Instantiates a new <see cref="RemoteATCommandPacket"/> object with the
 /// given parameters.
 /// </summary>
 /// <param name="frameID">The Frame ID.</param>
 /// <param name="destAddress64">The 64-bit address of the destination device.</param>
 /// <param name="destAddress16">The 16-bit address of the destination device.</param>
 /// <param name="transmitOptions">The bitfield of supported transmission options.</param>
 /// <param name="command">The AT command.</param>
 /// <param name="parameter">The AT command parameter.</param>
 /// <exception cref="ArgumentNullException">If <c><paramref name="destAddress64"/> == null</c>
 /// or if <c><paramref name="destAddress16"/> == null</c>
 /// or if <c><paramref name="command"/> == null</c>.</exception>
 /// <seealso cref="XBeeTransmitOptions"/>
 /// <seealso cref="XBee16BitAddress"/>
 /// <seealso cref="XBee64BitAddress"/>
 public RemoteATCommandPacket(byte frameID, XBee64BitAddress destAddress64, XBee16BitAddress destAddress16,
                              byte transmitOptions, string command, byte[] parameter)
     : base(APIFrameType.REMOTE_AT_COMMAND_REQUEST)
 {
     FrameID         = frameID;
     DestAddress64   = destAddress64 ?? throw new ArgumentNullException("64-bit destination address cannot be null.");
     DestAddress16   = destAddress16 ?? throw new ArgumentNullException("16-bit destination address cannot be null.");
     TransmitOptions = transmitOptions;
     Command         = command ?? throw new ArgumentNullException("AT command cannot be null.");
     Parameter       = parameter;
     logger          = LogManager.GetLogger <RemoteATCommandPacket>();
 }
        /// <summary>
        /// Initializes a new instance of <see cref="RX64Packet"/>.
        /// </summary>
        /// <param name="sourceAddress64">64-bit address of the sender.</param>
        /// <param name="rssi">Received signal strength indicator.</param>
        /// <param name="receiveOptions">Bitfield indicating the receive options.</param>
        /// <param name="rfData">Received RF data.</param>
        /// <exception cref="ArgumentNullException">if <paramref name="sourceAddress64"/> is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException">if <paramref name="rssi"/> is greater than 100.</exception>
        /// <seealso cref="XBeeReceiveOptions"/>
        public RX64Packet(XBee64BitAddress sourceAddress64, byte rssi, byte receiveOptions, byte[] rfData)
            : base(APIFrameType.RX_64)
        {
            Contract.Requires <ArgumentNullException>(sourceAddress64 != null, "64-bit source address cannot be null.");
            Contract.Requires <ArgumentOutOfRangeException>(rssi <= 100, "RSSI value must be between 0 and 100.");

            this.SourceAddress64 = sourceAddress64;
            this.RSSI            = rssi;
            this.ReceiveOptions  = receiveOptions;
            this.RFData          = rfData;
            this.logger          = LogManager.GetLogger <RX64Packet>();
        }
Example #26
0
        protected SerializableXBeeAddress(SerializationInfo info, StreamingContext context)
        {
            Is64BitAddress = info.GetBoolean(nameof(Is64BitAddress));

            if (Is64BitAddress)
            {
                XBee64BitAddress = new XBee64BitAddress((byte[])info.GetValue(ValueName, typeof(byte[])));
            }
            else
            {
                throw new NotImplementedException();
            }
        }
        /**
         * Creates a new {@code ReceivePacket} object from the given payload.
         *
         * @param payload The API frame payload. It must start with the frame type
         *                corresponding to a Receive packet ({@code 0x90}).
         *                The byte array must be in {@code OperatingMode.API} mode.
         *
         * @return Parsed ZigBee Receive packet.
         *
         * @throws ArgumentException if {@code payload[0] != APIFrameType.RECEIVE_PACKET.getValue()} or
         *                                  if {@code payload.Length < {@value #MIN_API_PAYLOAD_LENGTH}} or
         *                                  if {@code receiveOptions < 0} or
         *                                  if {@code receiveOptions > 255}.
         * @throws ArgumentNullException if {@code payload == null}.
         */
        public static ReceivePacket createPacket(byte[] payload)
        {
            if (payload == null)
            {
                throw new ArgumentNullException("Receive packet payload cannot be null.");
            }

            // 1 (Frame type) + 8 (32-bit address) + 2 (16-bit address) + 1 (receive options)
            if (payload.Length < MIN_API_PAYLOAD_LENGTH)
            {
                throw new ArgumentException("Incomplete Receive packet.");
            }

            if ((payload[0] & 0xFF) != APIFrameType.RECEIVE_PACKET.GetValue())
            {
                throw new ArgumentException("Payload is not a Receive packet.");
            }

            // payload[0] is the frame type.
            int index = 1;

            var array = new byte[8];

            Array.Copy(payload, index, array, 0, array.Length);
            // 2 bytes of 16-bit address.
            XBee64BitAddress sourceAddress64 = new XBee64BitAddress(array);

            index = index + 8;

            // 2 bytes of 16-bit address.
            XBee16BitAddress sourceAddress16 = new XBee16BitAddress(payload[index], payload[index + 1]);

            index = index + 2;

            // Receive options
            byte receiveOptions = payload[index];

            index = index + 1;

            // Get data.
            byte[] data = null;
            if (index < payload.Length)
            {
                data = new byte[payload.Length - index];
                Array.Copy(payload, index, data, 0, data.Length);
                //data = Arrays.copyOfRange(payload, index, payload.Length);
            }

            return(new ReceivePacket(sourceAddress64, sourceAddress16, receiveOptions, data));
        }
        /**
         * Class constructor. Instantiates a new {@code ReceivePacket} object
         * with the given parameters.
         *
         * @param sourceAddress64 64-bit address of the sender.
         * @param sourceAddress16 16-bit address of the sender.
         * @param receiveOptions Bitfield indicating the receive options.
         * @param rfData Received RF data.
         *
         * @throws ArgumentException if {@code receiveOptions < 0} or
         *                                  if {@code receiveOptions > 255}.
         * @throws ArgumentNullException if {@code sourceAddress64 == null} or
         *                              if {@code sourceAddress16 == null}.
         *
         * @see com.digi.xbee.api.models.XBeeReceiveOptions
         * @see com.digi.xbee.api.models.XBee16BitAddress
         * @see com.digi.xbee.api.models.XBee64BitAddress
         */
        public ReceivePacket(XBee64BitAddress sourceAddress64, XBee16BitAddress sourceAddress16, byte receiveOptions, byte[] rfData)
            : base(APIFrameType.RECEIVE_PACKET)
        {
            if (sourceAddress64 == null)
                throw new ArgumentNullException("64-bit source address cannot be null.");
            if (sourceAddress16 == null)
                throw new ArgumentNullException("16-bit source address cannot be null.");

            this.sourceAddress64 = sourceAddress64;
            this.sourceAddress16 = sourceAddress16;
            this.ReceiveOptions = receiveOptions;
            this.RFData = rfData;
            this.logger = LogManager.GetLogger<ReceivePacket>();
        }
Example #29
0
        /// <summary>
        /// Class constructor. Instantiates a new <see cref="RX64Packet"/> object with the
        /// given parameters.
        /// </summary>
        /// <param name="sourceAddress64">The 64-bit address of the sender.</param>
        /// <param name="rssi">The received signal strength indicator.</param>
        /// <param name="receiveOptions">The bitfield indicating the receive options.</param>
        /// <param name="rfData">The received RF data.</param>
        /// <exception cref="ArgumentOutOfRangeException">If <c><paramref name="rssi"/> <![CDATA[<]]> 0</c>
        /// or if <c><paramref name="rssi"/> <![CDATA[>]]> 255</c>.</exception>
        /// <exception cref="ArgumentNullException">If <c><paramref name="sourceAddress64"/> == null</c>.</exception>
        /// <seealso cref="XBeeReceiveOptions"/>
        /// <seealso cref="XBee64BitAddress"/>
        public RX64Packet(XBee64BitAddress sourceAddress64, byte rssi, byte receiveOptions, byte[] rfData)
            : base(APIFrameType.RX_64)
        {
            if (rssi < 0 || rssi > 255)
            {
                throw new ArgumentOutOfRangeException("RSSI value must be between 0 and 255.");
            }

            SourceAddress64 = sourceAddress64 ?? throw new ArgumentNullException("64-bit source address cannot be null.");
            RSSI            = rssi;
            ReceiveOptions  = receiveOptions;
            RFData          = rfData;
            logger          = LogManager.GetLogger <RX64Packet>();
        }
        /// <summary>
        /// Creates a new <see cref="RX64IOPacket"/> object from the given payload.
        /// </summary>
        /// <param name="payload">The API frame payload. It must start with the frame type corresponding
        /// to an RX64 Address IO packet (<c>0x82</c>). The byte array must be in <see cref="OperatingMode.API"/>
        /// mode.</param>
        /// <returns>Parsed RX64 Address IO packet.</returns>
        /// <exception cref="ArgumentException">If <c>payload[0] != APIFrameType.RX_IO_64.GetValue()</c>
        /// or if <c>payload.length <![CDATA[<]]> <see cref="MIN_API_PAYLOAD_LENGTH"/></c>.</exception>
        /// <exception cref="ArgumentNullException">If <c><paramref name="payload"/> == null</c>.</exception>
        public static RX64IOPacket CreatePacket(byte[] payload)
        {
            if (payload == null)
            {
                throw new ArgumentNullException("RX64 Address IO packet payload cannot be null.");
            }
            // 1 (Frame type) + 8 (64-bit address) + 1 (RSSI) + 1 (receive options)
            if (payload.Length < MIN_API_PAYLOAD_LENGTH)
            {
                throw new ArgumentException("Incomplete RX64 Address IO packet.");
            }
            if ((payload[0] & 0xFF) != APIFrameType.RX_IO_64.GetValue())
            {
                throw new ArgumentException("Payload is not a RX64 Address IO packet.");
            }

            // payload[0] is the frame type.
            int index = 1;

            // 8 bytes of 64-bit address.
            var address = new byte[8];

            Array.Copy(payload, index, address, 0, address.Length);

            XBee64BitAddress sourceAddress64 = new XBee64BitAddress(address);

            index = index + 8;

            // Received Signal Strength Indicator byte.
            byte rssi = (byte)(payload[index] & 0xFF);

            index = index + 1;

            // Received Options byte.
            byte receiveOptions = (byte)(payload[index] & 0xFF);

            index = index + 1;

            // Get data.
            byte[] data = null;
            if (index < payload.Length)
            {
                data = new byte[payload.Length - index];
                Array.Copy(payload, index, data, 0, data.Length);
            }

            return(new RX64IOPacket(sourceAddress64, rssi, receiveOptions, data));
        }
        /**
         * Class constructor. Instantiates a new {@code RX64IOPacket} object with
         * the given parameters.
         *
         * @param sourceAddress64 64-bit address of the sender.
         * @param rssi Received signal strength indicator.
         * @param receiveOptions Bitfield indicating the receive options.
         * @param rfData Received RF data.
         *
         * @throws ArgumentException if {@code rssi < 0} or
         *                                  if {@code rssi > 100} or
         *                                  if {@code receiveOptions < 0} or
         *                                  if {@code receiveOptions > 255} or
         *                                  if {@code rfData.Length < 5}.
         * @throws ArgumentNullException if {@code sourceAddress64 == null}.
         *
         * @see com.digi.xbee.api.models.XBeeReceiveOptions
         * @see com.digi.xbee.api.models.XBee64BitAddress
         */
        public RX64IOPacket(XBee64BitAddress sourceAddress64, byte rssi, byte receiveOptions, byte[] rfData)
            : base(APIFrameType.RX_IO_64)
        {
            Contract.Requires<ArgumentNullException>(sourceAddress64 != null, "64-bit source address cannot be null.");
            Contract.Requires<ArgumentOutOfRangeException>(rssi >= 0 && rssi <= 100);

            this.SourceAddress64 = sourceAddress64;
            this.RSSI = rssi;
            this.ReceiveOptions = receiveOptions;
            this.RFData = rfData;
            if (rfData != null)
                ioSample = new IOSample(rfData);
            else
                ioSample = null;
            this.logger = LogManager.GetLogger<RX64IOPacket>();
        }
Example #32
0
        /// <summary>
        /// Returns the 64bit and 16bit addresses of a packet.
        /// </summary>
        /// <remarks>
        /// Note this has different functionality than python, as it can accept any of 7 packets.
        /// The original python API only accepts 4 kinds.
        /// It is also somewhat redundant to Devices.XBeeNetwork.GetDataForRemote, although that takes a raw byte array instead of a packet
        /// </remarks>
        /// <param name="packet">The API packet to scrape addresses from</param>
        /// <returns>A pair of 64bit and 16bit addresses</returns>
        protected static Tuple <XBee64BitAddress, XBee16BitAddress> GetRemoteDeviceDataFromPacket(XBeeAPIPacket packet)
        {
            XBee64BitAddress x64bitAddr = null;
            XBee16BitAddress x16bitAddr = null;

            if (((Dictionary <DictKeys, object>)packet.GetFrameSpecDataDict()[DictKeys.API_DATA]).ContainsKey(DictKeys.X64BIT_ADDR))
            {
                x64bitAddr = (XBee64BitAddress)((Dictionary <DictKeys, object>)packet.GetFrameSpecDataDict()[DictKeys.API_DATA])[DictKeys.X64BIT_ADDR];
            }
            if (((Dictionary <DictKeys, object>)packet.GetFrameSpecDataDict()[DictKeys.API_DATA]).ContainsKey(DictKeys.X16BIT_ADDR))
            {
                x16bitAddr = (XBee16BitAddress)((Dictionary <DictKeys, object>)packet.GetFrameSpecDataDict()[DictKeys.API_DATA])[DictKeys.X16BIT_ADDR];
            }

            return(new Tuple <XBee64BitAddress, XBee16BitAddress>(x64bitAddr, x16bitAddr));
        }
Example #33
0
        /// <summary>
        /// Creates a new <see cref="TX64Packet"/> object from the given payload.
        /// </summary>
        /// <param name="payload">The API frame payload. It must start with the frame type corresponding
        /// to a TX64 Request packet (<c>0x00</c>). The byte array must be in <see cref="OperatingMode.API"/>
        /// mode.</param>
        /// <returns>Parsed TX64 Request packet.</returns>
        /// <exception cref="ArgumentException">If <c>payload[0] != APIFrameType.TX_64.GetValue()</c>
        /// or if <c>payload.length <![CDATA[<]]> <see cref="MIN_API_PAYLOAD_LENGTH"/></c>.</exception>
        /// <exception cref="ArgumentNullException">If <c><paramref name="payload"/> == null</c>.</exception>
        public static TX64Packet CreatePacket(byte[] payload)
        {
            if (payload == null)
            {
                throw new ArgumentNullException("TX64 Request packet payload cannot be null.");
            }
            // 1 (Frame type) + 1 (frame ID) + 8 (address) + 1 (transmit options)
            if (payload.Length < MIN_API_PAYLOAD_LENGTH)
            {
                throw new ArgumentException("Incomplete TX64 Request packet.");
            }
            if ((payload[0] & 0xFF) != APIFrameType.TX_64.GetValue())
            {
                throw new ArgumentException("Payload is not a TX64 Request packet.");
            }

            // payload[0] is the frame type.
            int index = 1;

            // Frame ID byte.
            byte frameID = payload[index];

            index = index + 1;

            var array = new byte[8];

            Array.Copy(payload, index, array, 0, array.Length);
            // 8 bytes of address, starting at 2nd byte.
            XBee64BitAddress destAddress64 = new XBee64BitAddress(array);

            index = index + 8;

            // Transmit options byte.
            byte transmitOptions = payload[index];

            index = index + 1;

            // Get data.
            byte[] data = null;
            if (index < payload.Length)
            {
                data = new byte[payload.Length - index];
                Array.Copy(payload, index, data, 0, data.Length);
            }

            return(new TX64Packet(frameID, destAddress64, transmitOptions, data));
        }
Example #34
0
        /// <summary>
        /// Creates a
        /// </summary>
        /// <param name="packet"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException">Thrown if device uses 802.15.4 protocol, since that functionality isn't implemented</exception>
        protected XBeeAPIPacket ExplToNoExpl(ExplicitRXIndicatorPacket packet)
        {
            XBee64BitAddress x64addr = packet.X64BitAddress;
            XBee16BitAddress x16addr = packet.X16BitAddress;
            XBeeAPIPacket    newPacket;

            if (xbeeDevice.Protocol == XBeeProtocol.Byte.RAW_802_15_4)
            {
                throw new NotImplementedException("This method does not support 802.15.4 protocol yet");
            }
            else
            {
                newPacket = new ReceivePacket(packet.X64BitAddress, packet.X16BitAddress, packet.ReceiveOptions, packet.RfData);
            }

            return(newPacket);
        }
Example #35
0
        /// <summary>
        /// Returns the remote device already contained in the network whose 64-bit address matches
        /// the given one.
        /// </summary>
        /// <remarks>Note that this method does not perform a discovery, only returns the device that
        /// has been previously discovered.</remarks>
        /// <param name="address">The 64-bit address of the device to be retrieved.</param>
        /// <returns>The remote device in the network or <c>null</c> if it is not found.</returns>
        /// <exception cref="ArgumentException">If <paramref name="address"/> is
        /// <see cref="XBee64BitAddress.UNKNOWN_ADDRESS"/>.</exception>
        /// <exception cref="ArgumentNullException">If <c><paramref name="address"/> == null</c>.</exception>
        public RemoteXBeeDevice GetDevice(XBee64BitAddress address)
        {
            if (address == null)
            {
                throw new ArgumentNullException("64-bit address cannot be null.");
            }
            if (address.Equals(XBee64BitAddress.UNKNOWN_ADDRESS))
            {
                throw new ArgumentException("64-bit address cannot be unknown.");
            }

            logger.DebugFormat("{0}Getting device '{1}' from network.", localDevice.ToString(), address);

            remotesBy64BitAddr.TryGetValue(address, out RemoteXBeeDevice result);

            return(result);
        }
        /// <summary>
        /// Creates a new <seealso cref="IODataSampleRxIndicatorPacket"/> object from the given payload.
        /// </summary>
        /// <param name="payload">The API frame payload. It must start with the frame type corresponding
        /// to an IO Data Sample RX Indicator packet (<c>0x92</c>). The byte array must be in
        /// <see cref="OperatingMode.API"/> mode.</param>
        /// <returns>Parsed IO Data Sample RX Indicator packet.</returns>
        /// <exception cref="ArgumentException">If <c>payload[0] != APIFrameType.IO_DATA_SAMPLE_RX_INDICATOR.GetValue()</c>
        /// or if <c>payload.Length <![CDATA[<]]> <see cref="MIN_API_PAYLOAD_LENGTH"/></c>.</exception>
        /// <exception cref="ArgumentNullException">If <c><paramref name="payload"/> == null</c>.</exception>
        public static IODataSampleRxIndicatorPacket CreatePacket(byte[] payload)
        {
            if (payload == null)
            {
                throw new ArgumentNullException("IO Data Sample RX Indicator packet payload cannot be null.");
            }
            // 1 (Frame type) + 8 (32-bit address) + 2 (16-bit address) + 1 (receive options)
            if (payload.Length < MIN_API_PAYLOAD_LENGTH)
            {
                throw new ArgumentException("Incomplete IO Data Sample RX Indicator packet.");
            }
            if ((payload[0] & 0xFF) != APIFrameType.IO_DATA_SAMPLE_RX_INDICATOR.GetValue())
            {
                throw new ArgumentException("Payload is not a IO Data Sample RX Indicator packet.");
            }

            // payload[0] is the frame type.
            int index = 1;

            var addr = new byte[8];

            Array.Copy(payload, index, addr, 0, addr.Length);
            // 8 bytes of 64-bit address.
            XBee64BitAddress sourceAddress64 = new XBee64BitAddress(addr);

            index = index + 8;

            // 2 bytes of 16-bit address.
            XBee16BitAddress sourceAddress16 = new XBee16BitAddress(payload[index], payload[index + 1]);

            index = index + 2;

            // Receive options
            byte receiveOptions = payload[index];

            index = index + 1;

            // Get data.
            byte[] data = null;
            if (index < payload.Length)
            {
                data = new byte[payload.Length - index];
                Array.Copy(payload, index, data, 0, data.Length);
            }
            return(new IODataSampleRxIndicatorPacket(sourceAddress64, sourceAddress16, receiveOptions, data));
        }
        /**
         * Class constructor. Instantiates a new
         * {@code IODataSampleRxIndicatorPacket} object with the given parameters.
         *
         * @param sourceAddress64 64-bit address of the sender.
         * @param sourceAddress16 16-bit address of the sender.
         * @param receiveOptions Receive options.
         * @param rfData Received RF data.
         *
         * @throws ArgumentException if {@code receiveOptions < 0} or
         *                                  if {@code receiveOptions > 255} or
         *                                  if {@code rfData.Length < 5}.
         * @throws ArgumentNullException if {@code sourceAddress64 == null} or
         *                              if {@code sourceAddress16 == null}.
         *
         * @see com.digi.xbee.api.models.XBeeReceiveOptions
         * @see com.digi.xbee.api.models.XBee16BitAddress
         * @see com.digi.xbee.api.models.XBee64BitAddress
         */
        public IODataSampleRxIndicatorPacket(XBee64BitAddress sourceAddress64, XBee16BitAddress sourceAddress16, byte receiveOptions, byte[] rfData)
            : base(APIFrameType.IO_DATA_SAMPLE_RX_INDICATOR)
        {
            if (sourceAddress64 == null)
                throw new ArgumentNullException("64-bit source address cannot be null.");
            if (sourceAddress16 == null)
                throw new ArgumentNullException("16-bit source address cannot be null.");

            this.sourceAddress64 = sourceAddress64;
            this.sourceAddress16 = sourceAddress16;
            this.ReceiveOptions = receiveOptions;
            this.RFData = rfData;
            if (rfData != null)
                IOSample = new IOSample(rfData);
            else
                IOSample = null;
            this.logger = LogManager.GetLogger<IODataSampleRxIndicatorPacket>();
        }
 /// <summary>
 /// Class constructor. Instantiates a <see cref="IODataSampleRxIndicatorPacket"/> with the given parameters.
 /// </summary>
 /// <param name="sourceAddress64">The 64-bit address of the sender.</param>
 /// <param name="sourceAddress16">The 16-bit address of the sender.</param>
 /// <param name="receiveOptions">The receive options.</param>
 /// <param name="rfData">The received RF data.</param>
 /// <exception cref="ArgumentException">If <c><paramref name="receiveOptions"/> <![CDATA[<]]> 0</c>
 /// or if <c><paramref name="receiveOptions"/> <![CDATA[>]]> 255</c>.</exception>
 /// <exception cref="ArgumentNullException">If <paramref name="sourceAddress64"/> is <c>null</c>
 /// or if <paramref name="sourceAddress16"/> is <c>null</c>.</exception>
 /// <seealso cref="XBeeReceiveOptions"/>
 /// <seealso cref="XBee16BitAddress"/>
 /// <seealso cref="XBee64BitAddress"/>
 public IODataSampleRxIndicatorPacket(XBee64BitAddress sourceAddress64, XBee16BitAddress sourceAddress16,
                                      byte receiveOptions, byte[] rfData)
     : base(APIFrameType.IO_DATA_SAMPLE_RX_INDICATOR)
 {
     SourceAddress64 = sourceAddress64 ?? throw new ArgumentNullException("64-bit source address cannot be null.");
     SourceAddress16 = sourceAddress16 ?? throw new ArgumentNullException("16-bit source address cannot be null.");
     ReceiveOptions  = receiveOptions;
     RFData          = rfData;
     if (rfData != null && rfData.Length >= 5)
     {
         IOSample = new IOSample(rfData);
     }
     else
     {
         // TODO: Should we throw an exception here?
         IOSample = null;
     }
     logger = LogManager.GetLogger <IODataSampleRxIndicatorPacket>();
 }
        /**
         * Class constructor. Instantiates a new {@code RX64IOPacket} object with
         * the given parameters.
         *
         * @param sourceAddress64 64-bit address of the sender.
         * @param rssi Received signal strength indicator.
         * @param receiveOptions Bitfield indicating the receive options.
         * @param rfData Received RF data.
         *
         * @throws ArgumentException if {@code rssi < 0} or
         *                                  if {@code rssi > 100} or
         *                                  if {@code receiveOptions < 0} or
         *                                  if {@code receiveOptions > 255} or
         *                                  if {@code rfData.Length < 5}.
         * @throws ArgumentNullException if {@code sourceAddress64 == null}.
         *
         * @see com.digi.xbee.api.models.XBeeReceiveOptions
         * @see com.digi.xbee.api.models.XBee64BitAddress
         */
        public RX64IOPacket(XBee64BitAddress sourceAddress64, byte rssi, byte receiveOptions, byte[] rfData)
            : base(APIFrameType.RX_IO_64)
        {
            Contract.Requires <ArgumentNullException>(sourceAddress64 != null, "64-bit source address cannot be null.");
            Contract.Requires <ArgumentOutOfRangeException>(rssi >= 0 && rssi <= 100);

            this.SourceAddress64 = sourceAddress64;
            this.RSSI            = rssi;
            this.ReceiveOptions  = receiveOptions;
            this.RFData          = rfData;
            if (rfData != null)
            {
                ioSample = new IOSample(rfData);
            }
            else
            {
                ioSample = null;
            }
            this.logger = LogManager.GetLogger <RX64IOPacket>();
        }
        /**
         * Class constructor. Instantiates a new {@code RemoteATCommandRequest}
         * object with the given parameters.
         *
         * @param frameID The Frame ID.
         * @param destAddress64 64-bit address of the destination device.
         * @param destAddress16 16-bit address of the destination device.
         * @param transmitOptions Bitfield of supported transmission options.
         * @param command AT command.
         * @param parameter AT command parameter as String.
         *
         * @throws ArgumentException if {@code frameID < 0} or
         *                                  if {@code frameID > 255} or
         *                                  if {@code transmitOptions < 0} or
         *                                  if {@code transmitOptions > 255}.
         * @throws ArgumentNullException if {@code destAddress64 == null} or
         *                              if {@code destAddress16 == null} or
         *                              if {@code command == null}.
         *
         * @see com.digi.xbee.api.models.XBeeTransmitOptions
         * @see com.digi.xbee.api.models.XBee16BitAddress
         * @see com.digi.xbee.api.models.XBee64BitAddress
         */
        public RemoteATCommandPacket(byte frameID, XBee64BitAddress destAddress64, XBee16BitAddress destAddress16,
            byte transmitOptions, String command, string parameter)
            : base(APIFrameType.REMOTE_AT_COMMAND_REQUEST)
        {
            ;

            if (destAddress64 == null)
                throw new ArgumentNullException("64-bit destination address cannot be null.");
            if (destAddress16 == null)
                throw new ArgumentNullException("16-bit destination address cannot be null.");
            if (command == null)
                throw new ArgumentNullException("AT command cannot be null.");

            this.frameID = frameID;
            this.destAddress64 = destAddress64;
            this.destAddress16 = destAddress16;
            this.transmitOptions = transmitOptions;
            this.Command = command;
            if (parameter != null)
                this.parameter = Encoding.UTF8.GetBytes(parameter);
            this.logger = LogManager.GetLogger<RemoteATCommandPacket>();
        }
        /**
         * Class constructor. Instantiates a new
         * {@code RemoteATCommandResponsePacket} object with the given parameters.
         *
         * @param frameID frame ID.
         * @param sourceAddress64 64-bit address of the remote radio returning
         *                        response.
         * @param sourceAddress16 16-bit network address of the remote.
         * @param command The AT command.
         * @param status The command status.
         * @param commandValue The AT command response value.
         *
         * @throws ArgumentException if {@code frameID < 0} or
         *                                  if {@code frameID > 255}.
         * @throws ArgumentNullException if {@code sourceAddress64 == null} or
         *                              if {@code sourceAddress16 == null} or
         *                              if {@code command == null} or
         *                              if {@code status == null}.
         *
         * @see com.digi.xbee.api.models.ATCommandStatus
         * @see com.digi.xbee.api.models.XBee16BitAddress
         * @see com.digi.xbee.api.models.XBee64BitAddress
         */
        public RemoteATCommandResponsePacket(byte frameID, XBee64BitAddress sourceAddress64, XBee16BitAddress sourceAddress16,
            String command, ATCommandStatus status, byte[] commandValue)
            : base(APIFrameType.REMOTE_AT_COMMAND_RESPONSE)
        {
            if (sourceAddress64 == null)
                throw new ArgumentNullException("64-bit source address cannot be null.");
            if (sourceAddress16 == null)
                throw new ArgumentNullException("16-bit source address cannot be null.");
            if (command == null)
                throw new ArgumentNullException("AT command cannot be null.");
            if (status == null)
                throw new ArgumentNullException("AT command status cannot be null.");
            if (frameID < 0 || frameID > 255)
                throw new ArgumentException("Frame ID must be between 0 and 255.");

            this.frameID = frameID;
            this.sourceAddress64 = sourceAddress64;
            this.sourceAddress16 = sourceAddress16;
            this.Command = command;
            this.Status = status;
            this.commandValue = commandValue;
            this.logger = LogManager.GetLogger<RemoteATCommandResponsePacket>();
        }
        /*throws TimeoutException, XBeeException */
        /**
         * Sends the provided data to the XBee device of the network corresponding
         * to the given 64-bit address.
         *
         * <p>This method blocks till a success or error response arrives or the
         * configured receive timeout expires.</p>
         *
         * <p>The received timeout is configured using the {@code setReceiveTimeout}
         * method and can be consulted with {@code getReceiveTimeout} method.</p>
         *
         * <p>For non-blocking operations use the method
         * {@link #sendData(XBee64BitAddress, byte[])}.</p>
         *
         * @param address The 64-bit address of the XBee that will receive the data.
         * @param data Byte array containing the data to be sent.
         *
         * @throws InterfaceNotOpenException if this device connection is not open.
         * @throws ArgumentNullException if {@code address == null} or
         *                              if {@code data == null}.
         * @throws TimeoutException if there is a timeout sending the data.
         * @throws XBeeException if there is any other XBee related exception.
         *
         * @see #getReceiveTimeout()
         * @see #setReceiveTimeout(int)
         * @see #sendData(RemoteXBeeDevice, byte[])
         * @see #sendData(XBee64BitAddress, XBee16BitAddress, byte[])
         * @see #sendDataAsync(RemoteXBeeDevice, byte[])
         * @see #sendDataAsync(XBee64BitAddress, byte[])
         * @see #sendDataAsync(XBee64BitAddress, XBee16BitAddress, byte[])
         * @see com.digi.xbee.api.models.XBee64BitAddress
         */
        protected void SendData(XBee64BitAddress address, byte[] data)
        {
            // Verify the parameters are not null, if they are null, throw an exception.
            if (address == null)
                throw new ArgumentNullException("Address cannot be null");
            if (data == null)
                throw new ArgumentNullException("Data cannot be null");

            // Check connection.
            if (!connectionInterface.SerialPort.IsOpen)
                throw new InterfaceNotOpenException();
            // Check if device is remote.
            if (IsRemote)
                throw new OperationNotSupportedException("Cannot send data to a remote device from a remote device.");

            logger.DebugFormat(ToString() + "Sending data to {0} >> {1}.", address, HexUtils.PrettyHexString(data));

            XBeePacket xbeePacket;
            switch (XBeeProtocol)
            {
                case XBeeProtocol.RAW_802_15_4:
                    xbeePacket = new TX64Packet(GetNextFrameID(), address, (byte)XBeeTransmitOptions.NONE, data);
                    break;
                default:
                    xbeePacket = new TransmitPacket(GetNextFrameID(), address, XBee16BitAddress.UNKNOWN_ADDRESS, 0, (byte)XBeeTransmitOptions.NONE, data);
                    break;
            }
            SendAndCheckXBeePacket(xbeePacket, false);
        }
        /**
         * Creates an new {@code RemoteATCommandResponsePacket} object from the
         * given payload.
         *
         * @param payload The API frame payload. It must start with the frame type
         *                corresponding to a Remote AT Command Response packet ({@code 0x97}).
         *                The byte array must be in {@code OperatingMode.API} mode.
         *
         * @return Parsed Remote AT Command Response packet.
         *
         * @throws ArgumentException if {@code payload[0] != APIFrameType.REMOTE_AT_COMMAND_RESPONSE.getValue()} or
         *                                  if {@code payload.Length < }{@value #MIN_API_PAYLOAD_LENGTH} or
         *                                  if {@code frameID < 0} or
         *                                  if {@code frameID > 255}.
         * @throws ArgumentNullException if {@code payload == null}.
         */
        public static RemoteATCommandResponsePacket createPacket(byte[] payload)
        {
            if (payload == null)
                throw new ArgumentNullException("Remote AT Command Response packet payload cannot be null.");

            // 1 (Frame type) + 1 (frame ID) + 8 (32-bit address) + 2 (16-bit address) + 2 (AT command) + 1 (status)
            if (payload.Length < MIN_API_PAYLOAD_LENGTH)
                throw new ArgumentException("Incomplete Remote AT Command Response packet.");

            if ((payload[0] & 0xFF) != APIFrameType.REMOTE_AT_COMMAND_RESPONSE.GetValue())
                throw new ArgumentException("Payload is not a Remote AT Command Response packet.");

            // payload[0] is the frame type.
            int index = 1;

            // Frame ID byte.
            byte frameID = payload[index];
            index = index + 1;

            var addr = new byte[8];
            Array.Copy(payload, index, addr, 0, addr.Length);
            // 8 bytes of 64-bit address.
            XBee64BitAddress sourceAddress64 = new XBee64BitAddress(addr);
            index = index + 8;

            // 2 bytes of 16-bit address.
            XBee16BitAddress sourceAddress16 = new XBee16BitAddress(payload[index], payload[index + 1]);
            index = index + 2;

            // 2 bytes of AT command.
            string command = Encoding.UTF8.GetString(new byte[] { payload[index], payload[index + 1] });
            index = index + 2;

            // Status byte.
            byte status = payload[index];
            index = index + 1;

            // Get data.
            byte[] commandData = null;
            if (index < payload.Length)
            {
                commandData = new byte[payload.Length - index];
                Array.Copy(payload, index, commandData, 0, commandData.Length);
                //commandData = Arrays.copyOfRange(payload, index, payload.Length);
            }

            // TODO if ATCommandStatus is unknown????
            return new RemoteATCommandResponsePacket(frameID, sourceAddress64,
                    sourceAddress16, command, ATCommandStatus.UNKNOWN.Get(status), commandData);
        }
 /**
  * Class constructor. Instantiates a new {@code RemoteZigBeeDevice} object
  * with the given local {@code ZigBeeDevice} which contains the connection
  * interface to be used.
  *
  * @param localXBeeDevice The local ZigBee device that will behave as
  *                        connection interface to communicate with this
  *                        remote ZigBee device.
  * @param addr64 The 64-bit address to identify this remote ZigBee device.
  *
  * @throws ArgumentException if {@code localXBeeDevice.isRemote() == true}.
  * @throws ArgumentNullException if {@code localXBeeDevice == null} or
  *                              if {@code addr64 == null}.
  *
  * @see com.digi.xbee.api.models.XBee64BitAddress
  */
 public RemoteZigBeeDevice(ZigBeeDevice localXBeeDevice, XBee64BitAddress addr64)
     : base(localXBeeDevice, addr64)
 {
 }
		/**
		 * Sets the 64-bit destination extended address of this XBee device.
		 * 
		 * <p>{@link XBee64BitAddress#BROADCAST_ADDRESS} is the broadcast address 
		 * for the PAN. {@link XBee64BitAddress#COORDINATOR_ADDRESS} can be used to 
		 * address the Pan Coordinator.</p>
		 * 
		 * @param xbee64BitAddress 64-bit destination address to be configured.
		 * 
		 * @throws InterfaceNotOpenException if this device connection is not open.
		 * @throws ArgumentNullException if {@code xbee64BitAddress == null}.
		 * @throws TimeoutException if there is a timeout sending the set 
		 *                          destination address command.
		 * @throws XBeeException if there is any other XBee related exception.
		 * 
		 * @see #getDestinationAddress()
		 * @see com.digi.xbee.api.models.XBee64BitAddress
		 */
		public void setDestinationAddress(XBee64BitAddress xbee64BitAddress)/*throws TimeoutException, XBeeException */{
			if (xbee64BitAddress == null)
				throw new ArgumentNullException("Address cannot be null.");

			// This method needs to apply changes after modifying the destination 
			// address, but only if the destination address could be set successfully.
			bool applyChanges = IsApplyConfigurationChangesEnabled();
			if (applyChanges)
				EnableApplyConfigurationChanges(false);

			byte[] address = xbee64BitAddress.Value;
			try
			{
				var dh = new byte[4];
				var dl = new byte[4];
				Array.Copy(address, 0, dh, 0, 4);
				Array.Copy(address, 4, dl, 0, 4);
				SetParameter("DH", dh);
				SetParameter("DL", dl);
				this.ApplyChanges();
			}
			finally
			{
				// Always restore the old value of the AC.
				EnableApplyConfigurationChanges(applyChanges);
			}
		}
 /**
  * Class constructor. Instantiates a new {@code RemoteXBeeDevice} object
  * with the given local {@code XBeeDevice} which contains the connection
  * interface to be used.
  *
  * @param localXBeeDevice The local XBee device that will behave as
  *                        connection interface to communicate with this
  *                        remote XBee device.
  * @param addr64 The 64-bit address to identify this remote XBee device.
  * @param addr16 The 16-bit address to identify this remote XBee device. It
  *               might be {@code null}.
  * @param ni The node identifier of this remote XBee device. It might be
  *           {@code null}.
  *
  * @throws ArgumentException if {@code localXBeeDevice.isRemote() == true}.
  * @throws ArgumentNullException if {@code localXBeeDevice == null} or
  *                              if {@code addr64 == null}.
  *
  * @see com.digi.xbee.api.models.XBee16BitAddress
  * @see com.digi.xbee.api.models.XBee64BitAddress
  */
 public RemoteXBeeDevice(XBeeDevice localXBeeDevice, XBee64BitAddress addr64,
     XBee16BitAddress addr16, string ni)
     : base(localXBeeDevice, addr64, addr16, ni)
 {
 }
        /**
         * Creates a new {@code TX64Packet} object from the given payload.
         *
         * @param payload The API frame payload. It must start with the frame type
         *                corresponding to a TX64 Request packet ({@code 0x00}).
         *                The byte array must be in {@code OperatingMode.API} mode.
         *
         * @return Parsed TX (transmit) 64 Request packet.
         *
         * @throws ArgumentException if {@code payload[0] != APIFrameType.TX_64.getValue()} or
         *                                  if {@code payload.Length < }{@value #MIN_API_PAYLOAD_LENGTH} or
         *                                  if {@code frameID < 0} or
         *                                  if {@code frameID > 255} or
         *                                  if {@code transmitOptions < 0} or
         *                                  if {@code transmitOptions > 255}.
         * @throws ArgumentNullException if {@code payload == null}.
         */
        public static TX64Packet CreatePacket(byte[] payload)
        {
            Contract.Requires<ArgumentNullException>(payload != null, "TX64 Request packet payload cannot be null.");
            // 1 (Frame type) + 1 (frame ID) + 8 (address) + 1 (transmit options)
            Contract.Requires<ArgumentException>(payload.Length >= MIN_API_PAYLOAD_LENGTH, "Incomplete TX64 Request packet.");
            Contract.Requires<ArgumentException>((payload[0] & 0xFF) == APIFrameType.TX_64.GetValue(), "Payload is not a TX64 Request packet.");

            // payload[0] is the frame type.
            int index = 1;

            // Frame ID byte.
            byte frameID = payload[index];
            index = index + 1;

            var array = new byte[8];
            Array.Copy(payload, index, array, 0, array.Length);
            // 8 bytes of address, starting at 2nd byte.
            XBee64BitAddress destAddress64 = new XBee64BitAddress(array);
            index = index + 8;

            // Transmit options byte.
            byte transmitOptions = payload[index];
            index = index + 1;

            // Get data.
            byte[] data = null;
            if (index < payload.Length)
            {
                data = new byte[payload.Length - index];
                Array.Copy(payload, index, data, 0, data.Length);
                //data = Arrays.copyOfRange(payload, index, payload.Length);
            }

            return new TX64Packet(frameID, destAddress64, transmitOptions, data);
        }
        /*throws TimeoutException, XBeeException */
        /**
         * Sends the provided data to the XBee device of the network corresponding
         * to the given 64-bit/16-bit address.
         *
         * <p>This method blocks till a success or error response arrives or the
         * configured receive timeout expires.</p>
         *
         * <p>The received timeout is configured using the {@code setReceiveTimeout}
         * method and can be consulted with {@code getReceiveTimeout} method.</p>
         *
         * <p>For non-blocking operations use the method
         * {@link #sendDataAsync(XBee64BitAddress, XBee16BitAddress, byte[])}.</p>
         *
         * @param address64Bit The 64-bit address of the XBee that will receive the
         *                     data.
         * @param address16bit The 16-bit address of the XBee that will receive the
         *                     data. If it is unknown the
         *                     {@code XBee16BitAddress.UNKNOWN_ADDRESS} must be
         *                     used.
         * @param data Byte array containing the data to be sent.
         *
         * @throws InterfaceNotOpenException if this device connection is not open.
         * @throws ArgumentNullException if {@code address64Bit == null} or
         *                              if {@code address16bit == null} or
         *                              if {@code data == null}.
         * @throws TimeoutException if there is a timeout sending the data.
         * @throws XBeeException if a remote device is trying to send data or
         *                       if there is any other XBee related exception.
         *
         * @see #getReceiveTimeout()
         * @see #setReceiveTimeout(int)
         * @see #sendData(RemoteXBeeDevice, byte[])
         * @see #sendData(XBee64BitAddress, byte[])
         * @see #sendDataAsync(RemoteXBeeDevice, byte[])
         * @see #sendDataAsync(XBee64BitAddress, byte[])
         * @see #sendDataAsync(XBee64BitAddress, XBee16BitAddress, byte[])
         * @see com.digi.xbee.api.models.XBee16BitAddress
         * @see com.digi.xbee.api.models.XBee64BitAddress
         */
        protected void SendData(XBee64BitAddress address64Bit, XBee16BitAddress address16bit, byte[] data)
        {
            // Verify the parameters are not null, if they are null, throw an exception.
            if (address64Bit == null)
                throw new ArgumentNullException("64-bit address cannot be null");
            if (address16bit == null)
                throw new ArgumentNullException("16-bit address cannot be null");
            if (data == null)
                throw new ArgumentNullException("Data cannot be null");

            // Check connection.
            if (!connectionInterface.SerialPort.IsOpen)
                throw new InterfaceNotOpenException();
            // Check if device is remote.
            if (IsRemote)
                throw new OperationNotSupportedException("Cannot send data to a remote device from a remote device.");

            logger.DebugFormat(ToString() + "Sending data to {0}[{1}] >> {2}.",
                    address64Bit, address16bit, HexUtils.PrettyHexString(data));

            XBeePacket xbeePacket = new TransmitPacket(GetNextFrameID(), address64Bit, address16bit, 0, (byte)XBeeTransmitOptions.NONE, data);
            SendAndCheckXBeePacket(xbeePacket, false);
        }
		/**
		 * Class constructor. Instantiates a new {@code RemoteXBeeDevice} object 
		 * with the given local {@code XBeeDevice} which contains the connection 
		 * interface to be used.
		 * 
		 * @param localXBeeDevice The local XBee device that will behave as 
		 *                        connection interface to communicate with this 
		 *                        remote XBee device.
		 * @param addr64 The 64-bit address to identify this XBee device.
		 * 
		 * @throws ArgumentException If {@code localXBeeDevice.isRemote() == true}.
		 * @throws ArgumentNullException if {@code localXBeeDevice == null} or
		 *                              if {@code addr64 == null}.
		 * 
		 * @see #AbstractXBeeDevice(IConnectionInterface)
		 * @see #AbstractXBeeDevice(String, int)
		 * @see #AbstractXBeeDevice(String, SerialPortParameters)
		 * @see #AbstractXBeeDevice(XBeeDevice, XBee64BitAddress, XBee16BitAddress, String)
		 * @see #AbstractXBeeDevice(String, int, int, int, int, int)
		 * @see com.digi.xbee.api.models.XBee16BitAddress
		 */
		public AbstractXBeeDevice(XBeeDevice localXBeeDevice, XBee64BitAddress addr64)
			: this(localXBeeDevice, addr64, null, null)
		{
		}
		/**
		 * Class constructor. Instantiates a new {@code RemoteXBeeDevice} object 
		 * with the given local {@code XBeeDevice} which contains the connection 
		 * interface to be used.
		 * 
		 * @param localXBeeDevice The local XBee device that will behave as 
		 *                        connection interface to communicate with this 
		 *                        remote XBee device.
		 * @param addr64 The 64-bit address to identify this XBee device.
		 * @param addr16 The 16-bit address to identify this XBee device. It might 
		 *               be {@code null}.
		 * @param id The node identifier of this XBee device. It might be 
		 *           {@code null}.
		 * 
		 * @throws ArgumentException If {@code localXBeeDevice.isRemote() == true}.
		 * @throws ArgumentNullException If {@code localXBeeDevice == null} or
		 *                              if {@code addr64 == null}.
		 * 
		 * @see #AbstractXBeeDevice(IConnectionInterface)
		 * @see #AbstractXBeeDevice(String, int)
		 * @see #AbstractXBeeDevice(String, SerialPortParameters)
		 * @see #AbstractXBeeDevice(XBeeDevice, XBee64BitAddress)
		 * @see #AbstractXBeeDevice(String, int, int, int, int, int)
		 * @see com.digi.xbee.api.models.XBee16BitAddress
		 * @see com.digi.xbee.api.models.XBee64BitAddress
		 */
		public AbstractXBeeDevice(XBeeDevice localXBeeDevice, XBee64BitAddress addr64,
				XBee16BitAddress addr16, String id)
		{
			if (localXBeeDevice == null)
				throw new ArgumentNullException("Local XBee device cannot be null.");
			if (addr64 == null)
				throw new ArgumentNullException("XBee 64-bit address of the device cannot be null.");
			if (localXBeeDevice.IsRemote)
				throw new ArgumentException("The given local XBee device is remote.");

			XBeeProtocol = XBeeProtocol.UNKNOWN;
			this.localXBeeDevice = localXBeeDevice;
			this.connectionInterface = localXBeeDevice.GetConnectionInterface();
			this.xbee64BitAddress = addr64;
			this.xbee16BitAddress = addr16;
			if (addr16 == null)
				xbee16BitAddress = XBee16BitAddress.UNKNOWN_ADDRESS;
			this.nodeID = id;
			this.logger = LogManager.GetLogger(this.GetType());
			logger.DebugFormat(ToString() + "Using the connection interface {0}.",
					connectionInterface.GetType().Name);
			this.IOPacketReceiveListener = new CustomPacketReceiveListener(this);
		}
		/**
		 * Reads some parameters from this device and obtains its protocol.
		 * 
		 * <p>This method refresh the values of:</p>
		 * <ul>
		 * <li>64-bit address only if it is not initialized.</li>
		 * <li>Node Identifier.</li>
		 * <li>Hardware version if it is not initialized.</li>
		 * <li>Firmware version.</li>
		 * <li>XBee device protocol.</li>
		 * <li>16-bit address (not for DigiMesh modules).</li>
		 * </ul>
		 * 
		 * @throws InterfaceNotOpenException if this device connection is not open.
		 * @throws TimeoutException if there is a timeout reading the parameters.
		 * @throws XBeeException if there is any other XBee related exception.
		 * 
		 * @see #get16BitAddress()
		 * @see #get64BitAddress()
		 * @see #getHardwareVersion()
		 * @see #getNodeID()
		 * @see #getFirmwareVersion()
		 * @see #getXBeeProtocol()
		 * @see #setNodeID(String)
		 */
		public void readDeviceInfo() /*throws TimeoutException, XBeeException*/ {
			byte[] response = null;
			// Get the 64-bit address.
			if (xbee64BitAddress == null || xbee64BitAddress == XBee64BitAddress.UNKNOWN_ADDRESS)
			{
				String addressHigh;
				String addressLow;

				response = GetParameter("SH");
				addressHigh = HexUtils.ByteArrayToHexString(response);

				response = GetParameter("SL");
				addressLow = HexUtils.ByteArrayToHexString(response);

				while (addressLow.Length < 8)
					addressLow = "0" + addressLow;

				xbee64BitAddress = new XBee64BitAddress(addressHigh + addressLow);
			}
			// Get the Node ID.
			response = GetParameter("NI");
			nodeID = Encoding.UTF8.GetString(response);

			// Get the hardware version.
			if (hardwareVersion == null)
			{
				response = GetParameter("HV");
				hardwareVersion = HardwareVersion.Get(response[0]);
			}
			// Get the firmware version.
			response = GetParameter("VR");
			firmwareVersion = HexUtils.ByteArrayToHexString(response);

			// Obtain the device protocol.
			XBeeProtocol = XBeeProtocol.UNKNOWN.DetermineProtocol(hardwareVersion, firmwareVersion);

			// Get the 16-bit address. This must be done after obtaining the protocol because 
			// DigiMesh and Point-to-Multipoint protocols don't have 16-bit addresses.
			if (XBeeProtocol != XBeeProtocol.DIGI_MESH
					&& XBeeProtocol != XBeeProtocol.DIGI_POINT)
			{
				response = GetParameter("MY");
				xbee16BitAddress = new XBee16BitAddress(response);
			}
		}
        /**
         * Creates a new {@code TransmitPacket} object from the given payload.
         *
         * @param payload The API frame payload. It must start with the frame type
         *                corresponding to a Transmit packet ({@code 0x10}).
         *                The byte array must be in {@code OperatingMode.API} mode.
         *
         * @return Parsed Transmit Request packet.
         *
         * @throws ArgumentException if {@code payload[0] != APIFrameType.TRANSMIT_REQUEST.getValue()} or
         *                                  if {@code payload.Length < }{@value #MIN_API_PAYLOAD_LENGTH} or
         *                                  if {@code frameID < 0} or
         *                                  if {@code frameID > 255} or
         *                                  if {@code broadcastRadius < 0} or
         *                                  if {@code broadcastRadius > 255} or
         *                                  if {@code transmitOptions < 0} or
         *                                  if {@code transmitOptions > 255}.
         * @throws ArgumentNullException if {@code payload == null}.
         */
        public static TransmitPacket createPacket(byte[] payload)
        {
            Contract.Requires<ArgumentNullException>(payload != null, "Transmit packet payload cannot be null.");
            // 1 (Frame type) + 1 (frame ID) + 8 (64-bit address) + 2 (16-bit address) + 1 (broadcast radious) + 1 (options)
            Contract.Requires<ArgumentException>(payload.Length >= MIN_API_PAYLOAD_LENGTH, "Incomplete Transmit packet.");
            Contract.Requires<ArgumentException>((payload[0] & 0xFF) != APIFrameType.TRANSMIT_REQUEST.GetValue(), "Payload is not a Transmit packet.");

            // payload[0] is the frame type.
            int index = 1;

            // Frame ID byte.
            byte frameID = payload[index];
            index = index + 1;

            var array = new byte[8];
            Array.Copy(payload, index, array, 0, array.Length);
            // 8 bytes of 64-bit address.
            XBee64BitAddress destAddress64 = new XBee64BitAddress(array);
            index = index + 8;

            // 2 bytes of 16-bit address.
            XBee16BitAddress destAddress16 = new XBee16BitAddress(payload[index], payload[index + 1]);
            index = index + 2;

            // Broadcast radious byte.
            byte broadcastRadius = payload[index];
            index = index + 1;

            // Options byte.
            byte options = payload[index];
            index = index + 1;

            // Get RF data.
            byte[] rfData = null;
            if (index < payload.Length)
            {
                rfData = new byte[payload.Length - index];
                Array.Copy(payload, index, rfData, 0, rfData.Length);
                //rfData = Arrays.copyOfRange(payload, index, payload.Length);
            }

            return new TransmitPacket(frameID, destAddress64, destAddress16, broadcastRadius, options, rfData);
        }
        /**
         * Creates a new remote XBee device with the provided 64-bit address,
         * 16-bit address, node identifier and the XBee device that is using this
         * data reader as the connection interface for the remote device.
         *
         * The new XBee device will be a {@code RemoteDigiMeshDevice},
         * a {@code RemoteDigiPointDevice}, a {@code RemoteRaw802Device} or a
         * {@code RemoteZigBeeDevice} depending on the protocol of the local XBee
         * device. If the protocol cannot be determined or is unknown a
         * {@code RemoteXBeeDevice} will be created instead.
         *
         * @param addr64 The 64-bit address of the new remote device. It cannot be
         *               {@code null}.
         * @param addr16 The 16-bit address of the new remote device. It may be
         *               {@code null}.
         * @param ni The node identifier of the new remote device. It may be
         *           {@code null}.
         *
         * @return a new remote XBee device with the given parameters.
         */
        private RemoteXBeeDevice createRemoteXBeeDevice(XBee64BitAddress addr64,
            XBee16BitAddress addr16, String ni)
        {
            RemoteXBeeDevice device = null;

            switch (xbeeDevice.XBeeProtocol)
            {
                case XBeeProtocol.ZIGBEE:
                    device = new RemoteZigBeeDevice(xbeeDevice, addr64, addr16, ni);
                    break;
                case XBeeProtocol.DIGI_MESH:
                    device = new RemoteDigiMeshDevice(xbeeDevice, addr64, ni);
                    break;
                case XBeeProtocol.DIGI_POINT:
                    device = new RemoteDigiPointDevice(xbeeDevice, addr64, ni);
                    break;
                case XBeeProtocol.RAW_802_15_4:
                    device = new RemoteRaw802Device(xbeeDevice, addr64, addr16, ni);
                    break;
                default:
                    device = new RemoteXBeeDevice(xbeeDevice, addr64, addr16, ni);
                    break;
            }

            return device;
        }
		/**
		 * Parses the given node discovery API data to create and return a remote 
		 * XBee Device.
		 * 
		 * @param data Byte array with the data to parse.
		 * @param localDevice The local device that received the remote XBee data.
		 * 
		 * @return Discovered XBee device.
		 */
		private async Task<RemoteXBeeDevice> ParseDiscoveryAPIData(byte[] data, XBeeDevice localDevice)
		{
			if (data == null)
				return null;

			RemoteXBeeDevice device = null;
			XBee16BitAddress addr16 = null;
			XBee64BitAddress addr64 = null;
			String id = null;
			// TODO role of the device: coordinator, router, end device or unknown.
			//XBeeDeviceType role = XBeeDeviceType.UNKNOWN;
			int signalStrength = 0;
			byte[] profileID = null;
			byte[] manufacturerID = null;

			using (var inputStream = new MemoryStream(data))
			{
				// Read 16 bit address.
				addr16 = new XBee16BitAddress(await ByteUtils.ReadBytes(2, inputStream));
				// Read 64 bit address.
				addr64 = new XBee64BitAddress(await ByteUtils.ReadBytes(8, inputStream));


				switch (localDevice.XBeeProtocol)
				{
					case XBeeProtocol.ZIGBEE:
					case XBeeProtocol.DIGI_MESH:
					case XBeeProtocol.ZNET:
					case XBeeProtocol.DIGI_POINT:
					case XBeeProtocol.XLR:
					// TODO [XLR_DM] The next version of the XLR will add DigiMesh support.
					// For the moment only point-to-multipoint is supported in this kind of devices.
					case XBeeProtocol.XLR_DM:
						// Read node identifier.
						id = ByteUtils.ReadString(inputStream);
						// Read parent address.
						XBee16BitAddress parentAddress = new XBee16BitAddress(await ByteUtils.ReadBytes(2, inputStream));
						// TODO Read device type.
						//role = XBeeDeviceType.get(inputStream.read());
						// Consume status byte, it is not used yet.
						await ByteUtils.ReadBytes(1, inputStream);
						// Read profile ID.
						profileID = await ByteUtils.ReadBytes(2, inputStream);
						// Read manufacturer ID.
						manufacturerID = await ByteUtils.ReadBytes(2, inputStream);

						logger.DebugFormat("{0}Discovered {1} device: 16-bit[{2}], 64-bit[{3}], id[{4}], parent[{5}], profile[{6}], manufacturer[{7}].",
								xbeeDevice.ToString(), localDevice.XBeeProtocol.GetDescription(), addr16,
								addr64, id, parentAddress, HexUtils.ByteArrayToHexString(profileID),
								HexUtils.ByteArrayToHexString(manufacturerID));

						break;
					case XBeeProtocol.RAW_802_15_4:
						// Read strength signal byte.
						signalStrength = inputStream.ReadByte();
						// Read node identifier.
						id = ByteUtils.ReadString(inputStream);

						logger.DebugFormat("{0}Discovered {1} device: 16-bit[{2}], 64-bit[{3}], id[{4}], rssi[{5}].",
								xbeeDevice.ToString(), localDevice.XBeeProtocol.GetDescription(), addr16, addr64, id, signalStrength);

						break;
					case XBeeProtocol.UNKNOWN:
					default:
						logger.DebugFormat("{0}Discovered {1} device: 16-bit[{2}], 64-bit[{3}].",
								xbeeDevice.ToString(), localDevice.XBeeProtocol.GetDescription(), addr16, addr64);
						break;
				}

				// Create device and fill with parameters.
				switch (localDevice.XBeeProtocol)
				{
					case XBeeProtocol.ZIGBEE:
						device = new RemoteZigBeeDevice(localDevice, addr64, addr16, id/*, role*/);
						// TODO profileID and manufacturerID
						break;
					case XBeeProtocol.DIGI_MESH:
						device = new RemoteDigiMeshDevice(localDevice, addr64, id/*, role*/);
						// TODO profileID and manufacturerID
						break;
					case XBeeProtocol.DIGI_POINT:
						device = new RemoteDigiPointDevice(localDevice, addr64, id/*, role*/);
						// TODO profileID and manufacturerID
						break;
					case XBeeProtocol.RAW_802_15_4:
						device = new RemoteRaw802Device(localDevice, addr64, addr16, id/*, role*/);
						// TODO signalStrength
						break;
					default:
						device = new RemoteXBeeDevice(localDevice, addr64, addr16, id/*, role*/);
						break;
				}
			}

			return device;
		}
 /**
  * Class constructor. Instantiates a new {@code RemoteDigiPointDevice} object
  * with the given local {@code DigiPointDevice} which contains the connection
  * interface to be used.
  *
  * @param localXBeeDevice The local point-to-multipoint device that will behave as
  *                        connection interface to communicate with this
  *                        remote point-to-multipoint device.
  * @param addr64 The 64-bit address to identify this remote point-to-multipoint
  *               device.
  *
  * @throws ArgumentException if {@code localXBeeDevice.isRemote() == true}.
  * @throws ArgumentNullException if {@code localXBeeDevice == null} or
  *                              if {@code addr64 == null}.
  *
  * @see com.digi.xbee.api.models.XBee64BitAddress
  */
 public RemoteDigiPointDevice(DigiPointDevice localXBeeDevice, XBee64BitAddress addr64)
     : base(localXBeeDevice, addr64)
 {
 }
        /**
         * Creates a new {@code RemoteATCommandPacket} object from the given
         * payload.
         *
         * @param payload The API frame payload. It must start with the frame type
         *                corresponding to a Remote AT Command packet ({@code 0x17}).
         *                The byte array must be in {@code OperatingMode.API} mode.
         *
         * @return Parsed Remote AT Command Request packet.
         *
         * @throws ArgumentException if {@code payload[0] != APIFrameType.REMOTE_AT_COMMAND_REQUEST.getValue()} or
         *                                  if {@code payload.Length < }{@value #MIN_API_PAYLOAD_LENGTH} or
         *                                  if {@code frameID < 0} or
         *                                  if {@code frameID > 255} or
         *                                  if {@code transmitOptions < 0} or
         *                                  if {@code transmitOptions > 255}.
         * @throws ArgumentNullException if {@code payload == null}.
         */
        public static RemoteATCommandPacket createPacket(byte[] payload)
        {
            Contract.Requires<ArgumentNullException>(payload != null, "Remote AT Command packet payload cannot be null.");
            // 1 (Frame type) + 1 (frame ID) + 8 (64-bit address) + 2 (16-bit address) + 1 (transmit options byte) + 2 (AT command)
            Contract.Requires<ArgumentException>(payload.Length >= MIN_API_PAYLOAD_LENGTH, "Incomplete Remote AT Command packet.");
            Contract.Requires<ArgumentException>((payload[0] & 0xFF) == APIFrameType.REMOTE_AT_COMMAND_REQUEST.GetValue(), "Payload is not a Remote AT Command packet.");

            // payload[0] is the frame type.
            int index = 1;

            // Frame ID byte.
            byte frameID = payload[index];
            index = index + 1;

            var array = new byte[8];
            Array.Copy(payload, index, array, 0, array.Length);
            // 8 bytes of 64-bit address.
            XBee64BitAddress destAddress64 = new XBee64BitAddress(array);
            index = index + 8;

            // 2 bytes of 16-bit address.
            XBee16BitAddress destAddress16 = new XBee16BitAddress(payload[index], payload[index + 1]);
            index = index + 2;

            // Options byte.
            byte transmitOptions = payload[index];
            index = index + 1;

            // 2 bytes of AT command.
            string command = Encoding.UTF8.GetString(new byte[] { payload[index], payload[index + 1] });
            index = index + 2;

            // Get data.
            byte[] parameterData = null;
            if (index < payload.Length)
            {
                parameterData = new byte[payload.Length - index];
                Array.Copy(payload, index, parameterData, 0, parameterData.Length);
                //parameterData = Arrays.copyOfRange(payload, index, payload.Length);
            }

            return new RemoteATCommandPacket(frameID, destAddress64, destAddress16, transmitOptions,
                    command, parameterData);
        }
        /**
         * Creates a new {@code IODataSampleRxIndicatorPacket} object from the
         * given payload.
         *
         * @param payload The API frame payload. It must start with the frame type
         *                corresponding to a IO Data Sample RX Indicator packet ({@code 0x92}).
         *                The byte array must be in {@code OperatingMode.API} mode.
         *
         * @return Parsed ZigBee Receive packet.
         *
         * @throws ArgumentException if {@code payload[0] != APIFrameType.IO_DATA_SAMPLE_RX_INDICATOR.getValue()} or
         *                                  if {@code payload.Length < }{@value #MIN_API_PAYLOAD_LENGTH} or
         *                                  if {@code receiveOptions < 0} or
         *                                  if {@code receiveOptions > 255} or
         *                                  if {@code rfData.Length < 5}.
         * @throws ArgumentNullException if {@code payload == null}.
         */
        public static IODataSampleRxIndicatorPacket CreatePacket(byte[] payload)
        {
            Contract.Requires<ArgumentNullException>(payload != null, "IO Data Sample RX Indicator packet payload cannot be null.");
            // 1 (Frame type) + 8 (32-bit address) + 2 (16-bit address) + 1 (receive options)
            Contract.Requires<ArgumentException>(payload.Length >= MIN_API_PAYLOAD_LENGTH, "Incomplete IO Data Sample RX Indicator packet.");
            Contract.Requires<ArgumentException>((payload[0] & 0xFF) == APIFrameType.IO_DATA_SAMPLE_RX_INDICATOR.GetValue(), "Payload is not a IO Data Sample RX Indicator packet.");

            // payload[0] is the frame type.
            int index = 1;

            var addr = new byte[8];
            Array.Copy(payload, index, addr, 0, addr.Length);
            // 2 bytes of 16-bit address.
            XBee64BitAddress sourceAddress64 = new XBee64BitAddress(addr);
            index = index + 8;

            // 2 bytes of 16-bit address.
            XBee16BitAddress sourceAddress16 = new XBee16BitAddress(payload[index], payload[index + 1]);
            index = index + 2;

            // Receive options
            byte receiveOptions = payload[index];
            index = index + 1;

            // Get data.
            byte[] data = null;
            if (index < payload.Length)
            {
                data = new byte[payload.Length - index];
                Array.Copy(payload, index, data, 0, data.Length);
                //data = Arrays.copyOfRange(payload, index, payload.Length);
            }
            return new IODataSampleRxIndicatorPacket(sourceAddress64, sourceAddress16, receiveOptions, data);
        }
		/**
		 * Updates the current device reference with the data provided for the 
		 * given device.
		 * 
		 * <p><b>This is only for internal use.</b></p>
		 * 
		 * @param device The XBee Device to get the data from.
		 */
		public void UpdateDeviceDataFrom(AbstractXBeeDevice device)
		{
			// TODO Should the devices have the same protocol??
			// TODO Should be allow to update a local from a remote or viceversa?? Maybe 
			// this must be in the Local/Remote device class(es) and not here... 

			// Only update the Node Identifier if the provided is not null.
			if (device.NodeID != null)
				this.nodeID = device.NodeID;

			// Only update the 64-bit address if the original is null or unknown.
			XBee64BitAddress addr64 = device.Get64BitAddress();
			if (addr64 != null && addr64 != XBee64BitAddress.UNKNOWN_ADDRESS
					&& !addr64.Equals(xbee64BitAddress)
					&& (xbee64BitAddress == null
						|| xbee64BitAddress.Equals(XBee64BitAddress.UNKNOWN_ADDRESS)))
			{
				xbee64BitAddress = addr64;
			}

			// TODO Change here the 16-bit address or maybe in ZigBee and 802.15.4?
			// TODO Should the 16-bit address be always updated? Or following the same rule as the 64-bit address.
			XBee16BitAddress addr16 = device.Get16BitAddress();
			if (addr16 != null && !addr16.Equals(xbee16BitAddress))
			{
				xbee16BitAddress = addr16;
			}

			//this.deviceType = device.deviceType; // This is not yet done.

			// The operating mode: only API/API2. Do we need this for a remote device?
			// The protocol of the device should be the same.
			// The hardware version should be the same.
			// The firmware version can change...
		}
        /**
         * Creates an new {@code RX64IOPacket} object from the given payload.
         *
         * @param payload The API frame payload. It must start with the frame type
         *                corresponding to a RX64 Address IO packet ({@code 0x82}).
         *                The byte array must be in {@code OperatingMode.API} mode.
         *
         * @return Parsed RX64 Address IO packet.
         *
         * @throws ArgumentException if {@code payload[0] != APIFrameType.RX_64.getValue()} or
         *                                  if {@code payload.Length < }{@value #MIN_API_PAYLOAD_LENGTH} or
         *                                  if {@code rssi < 0} or
         *                                  if {@code rssi > 100} or
         *                                  if {@code receiveOptions < 0} or
         *                                  if {@code receiveOptions > 255} or
         *                                  if {@code rfData.Length < 5}.
         * @throws ArgumentNullException if {@code payload == null}.
         */
        public static RX64IOPacket CreatePacket(byte[] payload)
        {
            Contract.Requires<ArgumentNullException>(payload != null, "RX64 Address IO packet payload cannot be null.");
            // 1 (Frame type) + 8 (64-bit address) + 1 (RSSI) + 1 (receive options)
            Contract.Requires<ArgumentException>(payload.Length >= MIN_API_PAYLOAD_LENGTH, "Incomplete RX64 Address IO packet.");
            Contract.Requires<ArgumentException>((payload[0] & 0xFF) != APIFrameType.RX_IO_64.GetValue(), "Payload is not a RX64 Address IO packet.");

            // payload[0] is the frame type.
            int index = 1;

            // 8 bytes of 64-bit address.
            var address = new byte[8];
            Array.Copy(payload, index, address, 0, address.Length);
            //XBee64BitAddress sourceAddress64 = new XBee64BitAddress(Arrays.copyOfRange(payload, index, index + 8));
            XBee64BitAddress sourceAddress64 = new XBee64BitAddress(address);
            index = index + 8;

            // Received Signal Strength Indicator byte.
            byte rssi = (byte)(payload[index] & 0xFF);
            index = index + 1;

            // Received Options byte.
            byte receiveOptions = (byte)(payload[index] & 0xFF);
            index = index + 1;

            // Get data.
            byte[] data = null;
            if (index < payload.Length)
            {
                data = new byte[payload.Length - index];
                Array.Copy(payload, index, data, 0, data.Length);
                //data = Arrays.copyOfRange(payload, index, payload.Length);
            }

            return new RX64IOPacket(sourceAddress64, rssi, receiveOptions, data);
        }
        /**
         * Class constructor. Instantiates a new {@code TransmitPacket} object
         * with the given parameters.
         *
         * @param frameID Frame ID.
         * @param destAddress64 64-bit address of the destination device.
         * @param destAddress16 16-bit address of the destination device.
         * @param broadcastRadius maximum number of hops a broadcast transmission
         *                        can occur.
         * @param transmitOptions Bitfield of supported transmission options.
         * @param rfData RF Data that is sent to the destination device.
         *
         * @throws ArgumentException if {@code frameID < 0} or
         *                                  if {@code frameID > 255} or
         *                                  if {@code broadcastRadius < 0} or
         *                                  if {@code broadcastRadius > 255} or
         *                                  if {@code transmitOptions < 0} or
         *                                  if {@code transmitOptions > 255}.
         * @throws ArgumentNullException if {@code destAddress64 == null} or
         *                              if {@code destAddress16 == null}.
         *
         * @see com.digi.xbee.api.models.XBeeTransmitOptions
         * @see com.digi.xbee.api.models.XBee16BitAddress
         * @see com.digi.xbee.api.models.XBee64BitAddress
         */
        public TransmitPacket(byte frameID, XBee64BitAddress destAddress64, XBee16BitAddress destAddress16,
            byte broadcastRadius, byte transmitOptions, byte[] rfData)
            : base(APIFrameType.TRANSMIT_REQUEST)
        {
            if (destAddress64 == null)
                throw new ArgumentNullException("64-bit destination address cannot be null.");
            if (destAddress16 == null)
                throw new ArgumentNullException("16-bit destination address cannot be null.");

            this.frameID = frameID;
            this.destAddress64 = destAddress64;
            this.destAddress16 = destAddress16;
            this.broadcastRadius = broadcastRadius;
            this.transmitOptions = transmitOptions;
            this.RFData = rfData;
            this.logger = LogManager.GetLogger<TransmitPacket>();
        }