/**
         * 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 RX16IOPacket} object with
         * the given parameters.
         *
         * @param sourceAddress16 16-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 sourceAddress16 == null}.
         *
         * @see com.digi.xbee.api.models.XBeeReceiveOptions
         * @see com.digi.xbee.api.models.XBee16BitAddress
         */
        public RX16IOPacket(XBee16BitAddress sourceAddress16, byte rssi, byte receiveOptions, byte[] rfData)
            : base(APIFrameType.RX_IO_16)
        {
            Contract.Requires<ArgumentNullException>(sourceAddress16 != null, "16-bit source address cannot be null.");
            Contract.Requires<ArgumentOutOfRangeException>(rssi >= 0 && rssi <= 100, "RSSI value must be between 0 and 100.");

            this.sourceAddress16 = sourceAddress16;
            this.RSSI = rssi;
            this.ReceiveOptions = receiveOptions;
            this.RFData = rfData;
            if (rfData != null)
                IOSample = new IOSample(rfData);
            else
                IOSample = null;
            this.logger = LogManager.GetLogger<RX16IOPacket>();
        }
        /**
         * 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>();
        }
 public IOSampleReceivedEventArgs(RemoteXBeeDevice remoteDevice, IOSample ioSample)
 {
     RemoteDevice = remoteDevice;
     IOSample = ioSample;
 }
		/**
		 * Returns an IO sample from this XBee device containing the value of all
		 * enabled digital IO and analog input channels.
		 * 
		 * @return An IO sample containing the value of all enabled digital IO and
		 *         analog input channels.
		 * 
		 * @throws InterfaceNotOpenException if this device connection is not open.
		 * @throws TimeoutException if there is a timeout getting the IO sample.
		 * @throws XBeeException if there is any other XBee related exception.
		 * 
		 * @see com.digi.xbee.api.io.IOSample
		 */
		public IOSample readIOSample()/*throws TimeoutException, XBeeException */{
			// Check connection.
			if (!connectionInterface.SerialPort.IsOpen)
				throw new InterfaceNotOpenException();

			// Try to build an IO Sample from the sample payload.
			byte[] samplePayload = null;
			IOSample ioSample;

			// The response to the IS command in local 802.15.4 devices is empty, 
			// so we have to create a packet listener to receive the IO sample.
			if (!IsRemote && XBeeProtocol == XBeeProtocol.RAW_802_15_4)
			{
				ExecuteParameter("IS");
				samplePayload = receiveRaw802IOPacket();
				if (samplePayload == null)
					throw new Kveer.XBeeApi.Exceptions.TimeoutException("Timeout waiting for the IO response packet.");
			}
			else
				samplePayload = GetParameter("IS");

			try
			{
				ioSample = new IOSample(samplePayload);
			}
			catch (ArgumentException e)
			{
				throw new XBeeException("Couldn't create the IO sample.", e);
			}
			return ioSample;
		}
        /**
         * Notifies subscribed IO sample listeners that a new IO sample packet has
         * been received.
         *
         * @param ioSample The received IO sample.
         * @param remoteDevice The remote XBee device that sent the sample.
         *
         * @see com.digi.xbee.api.RemoteXBeeDevice
         * @see com.digi.xbee.api.io.IOSample
         */
        private void NotifyIOSampleReceived(RemoteXBeeDevice remoteDevice, IOSample ioSample)
        {
            logger.Debug(connectionInterface.ToString() + "IO sample received.");

            try
            {
                lock (IOSampleReceived)
                {
                    var handler = IOSampleReceived;
                    if (handler != null)
                    {
                        var args = new IOSampleReceivedEventArgs(remoteDevice, ioSample);

                        handler.GetInvocationList().AsParallel().ForAll((action) =>
                        {
                            action.DynamicInvoke(this, args);
                        });
                    }
                }
            }
            catch (Exception e)
            {
                logger.Error(e.Message, e);
            }
        }