예제 #1
0
        /**
         * Parses the given byte array and returns a Generic XBee packet.
         *
         * @param packet The byte array to parse.
         * @param mode The operating mode to parse the packet (API 1 or API 2).
         *
         * @return The generated Generic XBee Packet.
         *
         * @throws ArgumentException if {@code mode != OperatingMode.API } and
         *                                  if {@code mode != OperatingMode.API_ESCAPE}
         *                                  or if {@code packet.Length == 0}.
         * @throws InvalidPacketException if the given byte array does not represent
         *                                a valid frame: invalid checksum, Length,
         *                                start delimiter, etc.
         * @throws ArgumentNullException if {@code packet == null}.
         *
         * @see com.digi.xbee.api.models.OperatingMode#API
         * @see com.digi.xbee.api.models.OperatingMode#API_ESCAPE
         */
        public static XBeePacket ParsePacket(byte[] packet, OperatingMode mode)
        {
            Contract.Requires <ArgumentNullException>(packet != null, "Packet byte array cannot be null.");
            Contract.Requires <ArgumentException>(mode == OperatingMode.API || mode == OperatingMode.API_ESCAPE, "Operating mode must be API or API Escaped.");
            Contract.Requires <ArgumentException>(packet.Length != 0, "Packet Length should be greater than 0.");
            Contract.Requires <ArgumentException>(packet.Length == 1 || packet[0] == (byte)SpecialByte.HEADER_BYTE, "Invalid start delimiter.");

            XBeePacketParser parser     = new XBeePacketParser();
            XBeePacket       xbeePacket = parser.ParsePacket(new MemoryStream(packet, 1, packet.Length - 1), mode);

            return(xbeePacket);
        }
예제 #2
0
 /*throws XBeeException */
 /**
  * Sends the given XBee packet and registers the given packet listener
  * (if not {@code null}) to be notified when the answers is received.
  *
  * <p>This is a non-blocking operation. To wait for the answer use
  * {@code sendPacket(XBeePacket)}.</p>
  *
  * @param packet XBee packet to be sent.
  * @param packetReceiveListener Listener for the operation, {@code null}
  *                              not to be notified when the answer arrives.
  *
  * @throws InterfaceNotOpenException if this device connection is not open.
  * @throws ArgumentNullException if {@code packet == null}.
  * @throws XBeeException if there is any other XBee related exception.
  *
  * @see #sendPacket(XBeePacket)
  * @see #sendPacketAsync(XBeePacket)
  * @see com.digi.xbee.api.listeners.IPacketReceiveListener
  * @see com.digi.xbee.api.packet.XBeePacket
  */
 public void SendPacket(XBeePacket packet, IPacketReceiveListener packetReceiveListener)
 {
     try
     {
         SendXBeePacket(packet, packetReceiveListener);
     }
     catch (IOException e)
     {
         throw new XBeeException("Error writing in the communication interface.", e);
     }
 }
        /**
         * Parses the given API payload to get the right API packet, depending
         * on its API type ({@code payload[0]}).
         *
         * @param payload The payload of the API frame.
         *
         * @return The corresponding API packet or {@code UnknownXBeePacket} if
         *         the frame API type is unknown.
         *
         * @throws InvalidPacketException if the payload is invalid for the
         *                                specified frame type.
         *
         * @see APIFrameType
         * @see XBeePacket
         */
        private XBeePacket ParsePayload(byte[] payload)         /*throws InvalidPacketException*/
        {
            // Get the API frame type.
            APIFrameType apiType = APIFrameType.GENERIC.Get(payload[0]);

            if (apiType == APIFrameType.UNKNOWN)
            {
                // Create unknown packet.
                return(UnknownXBeePacket.CreatePacket(payload));
            }

            // Parse API payload depending on API ID.
            XBeePacket packet = null;

            switch (apiType)
            {
            case APIFrameType.TX_64:
                packet = TX64Packet.CreatePacket(payload);
                break;

            case APIFrameType.TX_16:
                packet = TX16Packet.CreatePacket(payload);
                break;

            case APIFrameType.AT_COMMAND:
                packet = ATCommandPacket.CreatePacket(payload);
                break;

            case APIFrameType.AT_COMMAND_QUEUE:
                packet = ATCommandQueuePacket.CreatePacket(payload);
                break;

            case APIFrameType.TRANSMIT_REQUEST:
                packet = TransmitPacket.createPacket(payload);
                break;

            case APIFrameType.REMOTE_AT_COMMAND_REQUEST:
                packet = RemoteATCommandPacket.createPacket(payload);
                break;

            case APIFrameType.RX_64:
                packet = RX64Packet.CreatePacket(payload);
                break;

            case APIFrameType.RX_16:
                packet = RX16Packet.CreatePacket(payload);
                break;

            case APIFrameType.RX_IO_64:
                packet = RX64IOPacket.CreatePacket(payload);
                break;

            case APIFrameType.RX_IO_16:
                packet = RX16IOPacket.CreatePacket(payload);
                break;

            case APIFrameType.AT_COMMAND_RESPONSE:
                packet = ATCommandResponsePacket.createPacket(payload);
                break;

            case APIFrameType.TX_STATUS:
                packet = TXStatusPacket.createPacket(payload);
                break;

            case APIFrameType.MODEM_STATUS:
                packet = ModemStatusPacket.CreatePacket(payload);
                break;

            case APIFrameType.TRANSMIT_STATUS:
                packet = TransmitStatusPacket.createPacket(payload);
                break;

            case APIFrameType.RECEIVE_PACKET:
                packet = ReceivePacket.createPacket(payload);
                break;

            case APIFrameType.IO_DATA_SAMPLE_RX_INDICATOR:
                packet = IODataSampleRxIndicatorPacket.CreatePacket(payload);
                break;

            case APIFrameType.REMOTE_AT_COMMAND_RESPONSE:
                packet = RemoteATCommandResponsePacket.createPacket(payload);
                break;

            case APIFrameType.GENERIC:
            default:
                packet = GenericXBeePacket.CreatePacket(payload);
                break;
            }
            return(packet);
        }
		/**
		 * Insert (if possible) the next frame ID stored in the device to the 
		 * provided packet.
		 * 
		 * @param xbeePacket The packet to add the frame ID.
		 * 
		 * @see com.digi.xbee.api.packet.XBeePacket
		 */
		private void InsertFrameID(XBeePacket xbeePacket)
		{
			if (xbeePacket is XBeeAPIPacket)
				return;

			if (((XBeeAPIPacket)xbeePacket).NeedsAPIFrameID && ((XBeeAPIPacket)xbeePacket).FrameID == XBeeAPIPacket.NO_FRAME_ID)
				((XBeeAPIPacket)xbeePacket).FrameID = GetNextFrameID();
		}
예제 #5
0
        /**
         * Dispatches the received XBee packet to the corresponding listener(s).
         *
         * @param packet The received XBee packet to be dispatched to the
         *               corresponding listeners.
         *
         * @see com.digi.xbee.api.packet.XBeeAPIPacket
         * @see com.digi.xbee.api.packet.XBeePacket
         */
        private void PacketReceived(XBeePacket packet)
        {
            // Add the packet to the packets queue.
            xbeePacketsQueue.AddPacket(packet);
            // Notify that a packet has been received to the corresponding listeners.
            NotifyPacketReceived(packet);

            // Check if the packet is an API packet.
            if (!(packet is XBeeAPIPacket))
                return;

            // Get the API packet type.
            XBeeAPIPacket apiPacket = (XBeeAPIPacket)packet;
            APIFrameType apiType = apiPacket.FrameType;
            if (apiType == APIFrameType.UNKNOWN)
                return;

            try
            {
                // Obtain the remote device from the packet.
                RemoteXBeeDevice remoteDevice = GetRemoteXBeeDeviceFromPacket(apiPacket);
                byte[] data = null;

                switch (apiType)
                {
                    case APIFrameType.RECEIVE_PACKET:
                        ReceivePacket receivePacket = (ReceivePacket)apiPacket;
                        data = receivePacket.RFData;
                        notifyDataReceived(new XBeeMessage(remoteDevice, data, apiPacket.IsBroadcast));
                        break;
                    case APIFrameType.RX_64:
                        RX64Packet rx64Packet = (RX64Packet)apiPacket;
                        data = rx64Packet.RFData;
                        notifyDataReceived(new XBeeMessage(remoteDevice, data, apiPacket.IsBroadcast));
                        break;
                    case APIFrameType.RX_16:
                        RX16Packet rx16Packet = (RX16Packet)apiPacket;
                        data = rx16Packet.RFData;
                        notifyDataReceived(new XBeeMessage(remoteDevice, data, apiPacket.IsBroadcast));
                        break;
                    case APIFrameType.IO_DATA_SAMPLE_RX_INDICATOR:
                        IODataSampleRxIndicatorPacket ioSamplePacket = (IODataSampleRxIndicatorPacket)apiPacket;
                        NotifyIOSampleReceived(remoteDevice, ioSamplePacket.IOSample);
                        break;
                    case APIFrameType.RX_IO_64:
                        RX64IOPacket rx64IOPacket = (RX64IOPacket)apiPacket;
                        NotifyIOSampleReceived(remoteDevice, rx64IOPacket.getIOSample());
                        break;
                    case APIFrameType.RX_IO_16:
                        RX16IOPacket rx16IOPacket = (RX16IOPacket)apiPacket;
                        NotifyIOSampleReceived(remoteDevice, rx16IOPacket.IOSample);
                        break;
                    case APIFrameType.MODEM_STATUS:
                        ModemStatusPacket modemStatusPacket = (ModemStatusPacket)apiPacket;
                        NotifyModemStatusReceived(modemStatusPacket.Status);
                        break;
                    default:
                        break;
                }

            }
            catch (XBeeException e)
            {
                logger.Error(e.Message, e);
            }
        }
			public async void PacketReceived(XBeePacket receivedPacket)
			{
				if (!_node.discovering)
					return;
				RemoteXBeeDevice rdevice = null;

				byte[] commandValue = _node.GetRemoteDeviceData((XBeeAPIPacket)receivedPacket);

				rdevice = await _node.ParseDiscoveryAPIData(commandValue, _node.xbeeDevice);

				// If a device with a specific id is being search and it is 
				// already found, return it.
				if (_id != null)
				{
					if (rdevice != null && _id.Equals(rdevice.NodeID))
					{
						lock (_node.deviceList)
						{
							_node.deviceList.Add(rdevice);
						}
						// If the local device is 802.15.4 wait until the 'end' command is received.
						if (_node.xbeeDevice.XBeeProtocol != XBeeProtocol.RAW_802_15_4)
							_node.discovering = false;
					}
				}
				else if (rdevice != null)
					_node.notifyDeviceDiscovered(_listeners, rdevice);
			}
 /**
  * Returns whether or not the given XBee packet is a data packet.
  *
  * @param xbeePacket The XBee packet to check if is data packet.
  *
  * @return {@code true} if the XBee packet is a data packet, {@code false}
  *         otherwise.
  *
  * @see com.digi.xbee.api.packet.XBeePacket
  */
 private bool IsDataPacket(XBeePacket xbeePacket)
 {
     if (!(xbeePacket is XBeeAPIPacket))
         return false;
     APIFrameType packetType = ((XBeeAPIPacket)xbeePacket).FrameType;
     switch (packetType)
     {
         case APIFrameType.RECEIVE_PACKET:
         case APIFrameType.RX_16:
         case APIFrameType.RX_64:
             return true;
         default:
             return false;
     }
 }
		/**
		 * Sends the provided {@code XBeePacket} and determines if the transmission 
		 * status is success for synchronous transmissions.
		 * 
		 * <p>If the status is not success, an {@code TransmitException} is thrown.</p>
		 * 
		 * @param packet The {@code XBeePacket} to be sent.
		 * @param asyncTransmission Determines whether the transmission must be 
		 *                          asynchronous.
		 * 
		 * @throws TransmitException if {@code packet} is not an instance of 
		 *                           {@code TransmitStatusPacket} or 
		 *                           if {@code packet} is not an instance of 
		 *                           {@code TXStatusPacket} or 
		 *                           if its transmit status is different than 
		 *                           {@code XBeeTransmitStatus.SUCCESS}.
		 * @throws XBeeException if there is any other XBee related error.
		 * 
		 * @see com.digi.xbee.api.packet.XBeePacket
		 */
		protected void SendAndCheckXBeePacket(XBeePacket packet, bool asyncTransmission)/*throws TransmitException, XBeeException */{
			XBeePacket receivedPacket = null;

			// Send the XBee packet.
			try
			{
				if (asyncTransmission)
					SendXBeePacketAsync(packet);
				else
					receivedPacket = SendXBeePacket(packet);
			}
			catch (IOException e)
			{
				throw new XBeeException("Error writing in the communication interface.", e);
			}

			// If the transmission is async. we are done.
			if (asyncTransmission)
				return;

			// Check if the packet received is a valid transmit status packet.
			if (receivedPacket == null)
				throw new TransmitException(XBeeTransmitStatus.UNKNOWN);
			if (receivedPacket is TransmitStatusPacket)
			{
				if (((TransmitStatusPacket)receivedPacket).getTransmitStatus() == null)
					throw new TransmitException(XBeeTransmitStatus.UNKNOWN);
				else if (((TransmitStatusPacket)receivedPacket).getTransmitStatus() != XBeeTransmitStatus.SUCCESS)
					throw new TransmitException(((TransmitStatusPacket)receivedPacket).getTransmitStatus());
			}
			else if (receivedPacket is TXStatusPacket)
			{
				if (((TXStatusPacket)receivedPacket).TransmitStatus == null)
					throw new TransmitException(XBeeTransmitStatus.UNKNOWN);
				else if (((TXStatusPacket)receivedPacket).TransmitStatus != XBeeTransmitStatus.SUCCESS)
					throw new TransmitException(((TXStatusPacket)receivedPacket).TransmitStatus);
			}
			else
				throw new TransmitException(XBeeTransmitStatus.UNKNOWN);
		}
		/**
		 * Returns whether the sent packet is the same than the received one.
		 * 
		 * @param sentPacket The packet sent.
		 * @param receivedPacket The packet received.
		 * 
		 * @return {@code true} if the sent packet is the same than the received 
		 *         one, {@code false} otherwise.
		 * 
		 * @see com.digi.xbee.api.packet.XBeePacket
		 */
		private bool isSamePacket(XBeePacket sentPacket, XBeePacket receivedPacket)
		{
			// TODO Should not we implement the {@code equals} method in the XBeePacket??
			if (HexUtils.ByteArrayToHexString(sentPacket.GenerateByteArray()).Equals(HexUtils.ByteArrayToHexString(receivedPacket.GenerateByteArray())))
				return true;
			return false;
		}
		/**
		 * Writes the given XBee packet in the connection interface of this device.
		 * 
		 * @param packet XBee packet to be written.
		 * 
		 * @throws IOException if an I/O error occurs while writing the XBee packet 
		 *                     in the connection interface.
		 * 
		 * @see com.digi.xbee.api.packet.XBeePacket
		 */
		private void WritePacket(XBeePacket packet)/*throws IOException */{
			logger.DebugFormat(ToString() + "Sending XBee packet: \n{0}", packet.ToPrettyString());
			// Write bytes with the required escaping mode.
			switch (operatingMode)
			{
				case OperatingMode.API:
				default:
					var buf = packet.GenerateByteArray();
					connectionInterface.SerialPort.Write(buf, 0, buf.Length);
					break;
				case OperatingMode.API_ESCAPE:
					var buf2 = packet.GenerateByteArrayEscaped();
					connectionInterface.SerialPort.Write(buf2, 0, buf2.Length);
					break;
			}
		}
		/**
		 * Returns the packet listener corresponding to the provided sent packet. 
		 * 
		 * <p>The listener will filter those packets  matching with the Frame ID of 
		 * the sent packet storing them in the provided responseList array.</p>
		 * 
		 * @param sentPacket The packet sent.
		 * @param responseList List of packets received that correspond to the 
		 *                     frame ID of the packet sent.
		 * 
		 * @return A packet receive listener that will filter the packets received 
		 *         corresponding to the sent one.
		 * 
		 * @see com.digi.xbee.api.listeners.IPacketReceiveListener
		 * @see com.digi.xbee.api.packet.XBeePacket
		 */
		private IPacketReceiveListener CreatePacketReceivedListener(XBeePacket sentPacket, IList<XBeePacket> responseList)
		{
			IPacketReceiveListener packetReceiveListener = new MyPacketReceiveListener(this, sentPacket, responseList);

			return packetReceiveListener;
		}
			public void PacketReceived(XBeePacket receivedPacket)
			{
				// Check if it is the packet we are waiting for.
				if (((XBeeAPIPacket)receivedPacket).CheckFrameID((((XBeeAPIPacket)_sentPacket).FrameID)))
				{
					// Security check to avoid class cast exceptions. It has been observed that parallel processes 
					// using the same connection but with different frame index may collide and cause this exception at some point.
					if (_sentPacket is XBeeAPIPacket
							&& receivedPacket is XBeeAPIPacket)
					{
						XBeeAPIPacket sentAPIPacket = (XBeeAPIPacket)_sentPacket;
						XBeeAPIPacket receivedAPIPacket = (XBeeAPIPacket)receivedPacket;

						// If the packet sent is an AT command, verify that the received one is an AT command response and 
						// the command matches in both packets.
						if (sentAPIPacket.FrameType == APIFrameType.AT_COMMAND)
						{
							if (receivedAPIPacket.FrameType != APIFrameType.AT_COMMAND_RESPONSE)
								return;
							if (!((ATCommandPacket)sentAPIPacket).Command.Equals(((ATCommandResponsePacket)receivedPacket).Command, StringComparison.InvariantCultureIgnoreCase))
								return;
						}
						// If the packet sent is a remote AT command, verify that the received one is a remote AT command response and 
						// the command matches in both packets.
						if (sentAPIPacket.FrameType == APIFrameType.REMOTE_AT_COMMAND_REQUEST)
						{
							if (receivedAPIPacket.FrameType != APIFrameType.REMOTE_AT_COMMAND_RESPONSE)
								return;
							if (!((RemoteATCommandPacket)sentAPIPacket).Command.Equals(((RemoteATCommandResponsePacket)receivedPacket).Command, StringComparison.InvariantCultureIgnoreCase))
								return;
						}
					}

					// Verify that the sent packet is not the received one! This can happen when the echo mode is enabled in the 
					// serial port.
					if (!_device.isSamePacket(_sentPacket, receivedPacket))
					{
						_responseList.Add(receivedPacket);
						lock (_responseList)
						{
							Monitor.Pulse(_responseList);
						}
					}
				}
			}
			public MyPacketReceiveListener(AbstractXBeeDevice device, XBeePacket sentPacket, IList<XBeePacket> responseList)
			{
				_device = device;
				_sentPacket = sentPacket;
				_responseList = responseList;
			}
예제 #14
0
 /*throws TimeoutException, XBeeException */
 /**
  * Sends the given XBee packet synchronously and blocks until the response
  * is received or the configured receive timeout expires.
  *
  * <p>The received timeout is configured using the {@code setReceiveTimeout}
  * method and can be consulted with {@code getReceiveTimeout} method.</p>
  *
  * <p>Use {@code sendXBeePacketAsync(XBeePacket)} or
  * {@code #sendXBeePacket(XBeePacket, IPacketReceiveListener)} for
  * non-blocking operations.</p>
  *
  * @param packet XBee packet to be sent.
  *
  * @return An {@code XBeePacket} object containing the response of the sent
  *         packet or {@code null} if there is no response.
  *
  * @throws InterfaceNotOpenException if this device connection is not open.
  * @throws ArgumentNullException if {@code packet == null}.
  * @throws TimeoutException if there is a timeout sending the XBee packet.
  * @throws XBeeException if there is any other XBee related exception.
  *
  * @see #getReceiveTimeout()
  * @see #sendXBeePacket(XBeePacket, IPacketReceiveListener)
  * @see #sendXBeePacketAsync(XBeePacket)
  * @see #setReceiveTimeout(int)
  * @see com.digi.xbee.api.packet.XBeePacket
  */
 public XBeePacket SendPacket(XBeePacket packet)
 {
     try
     {
         return base.SendXBeePacket(packet);
     }
     catch (IOException e)
     {
         throw new XBeeException("Error writing in the communication interface.", e);
     }
 }
			public void PacketReceived(XBeePacket receivedPacket)
			{
				// Discard non API packets.
				if (!(receivedPacket is XBeeAPIPacket))
					return;
				// If we already have received an IO packet, ignore this packet.
				if (_xbeeDevice.ioPacketReceived)
					return;

				// Save the packet value (IO sample payload)
				switch (((XBeeAPIPacket)receivedPacket).FrameType)
				{
					case APIFrameType.IO_DATA_SAMPLE_RX_INDICATOR:
						_xbeeDevice.ioPacketPayload = ((IODataSampleRxIndicatorPacket)receivedPacket).RFData;
						break;
					case APIFrameType.RX_IO_16:
						_xbeeDevice.ioPacketPayload = ((RX16IOPacket)receivedPacket).RFData;
						break;
					case APIFrameType.RX_IO_64:
						_xbeeDevice.ioPacketPayload = ((RX64IOPacket)receivedPacket).RFData;
						break;
					default:
						return;
				}
				// Set the IO packet received flag.
				_xbeeDevice.ioPacketReceived = true;

				// Continue execution by notifying the lock object.
				lock (_xbeeDevice.ioLock)
				{
					Monitor.Pulse(_xbeeDevice.ioLock);
				}
			}
예제 #16
0
 /*throws XBeeException */
 /**
  * Sends the given XBee packet asynchronously.
  *
  * <p>This is a non-blocking operation that do not wait for the answer and
  * is never notified when it arrives.</p>
  *
  * <p>To be notified when the answer is received, use
  * {@link #sendXBeePacket(XBeePacket, IPacketReceiveListener)}.</p>
  *
  * @param packet XBee packet to be sent asynchronously.
  *
  * @throws InterfaceNotOpenException if this device connection is not open.
  * @throws ArgumentNullException if {@code packet == null}.
  * @throws XBeeException if there is any other XBee related exception.
  *
  * @see #sendXBeePacket(XBeePacket)
  * @see #sendXBeePacket(XBeePacket, IPacketReceiveListener)
  * @see com.digi.xbee.api.packet.XBeePacket
  */
 public void SendPacketAsync(XBeePacket packet)
 {
     try
     {
         base.SendXBeePacket(packet, null);
     }
     catch (IOException e)
     {
         throw new XBeeException("Error writing in the communication interface.", e);
     }
 }
		/**
		 * Sends the given XBee packet asynchronously.
		 * 
		 * <p>The method will not wait for an answer for the packet.</p>
		 * 
		 * <p>To be notified when the answer is received, use 
		 * {@link #sendXBeePacket(XBeePacket, IPacketReceiveListener)}.</p>
		 * 
		 * @param packet XBee packet to be sent asynchronously.
		 * 
		 * @throws InterfaceNotOpenException if this device connection is not open.
		 * @throws InvalidOperatingModeException if the operating mode is different 
		 *                                       than {@link OperatingMode#API} and 
		 *                                       {@link OperatingMode#API_ESCAPE}.
		 * @throws IOException if an I/O error occurs while sending the XBee packet.
		 * @throws ArgumentNullException if {@code packet == null}.
		 * 
		 * @see #sendXBeePacket(XBeePacket)
		 * @see #sendXBeePacket(XBeePacket, IPacketReceiveListener)
		 * @see #sendXBeePacketAsync(XBeePacket)
		 * @see com.digi.xbee.api.packet.XBeePacket
		 */
		protected void SendXBeePacketAsync(XBeePacket packet)
		/*throws InvalidOperatingModeException, IOException*/ {
			SendXBeePacket(packet, null);
		}
 /**
  * Returns whether or not the source address of the provided XBee packet
  * matches the address of the given remote XBee device.
  *
  * @param xbeePacket The XBee packet to compare its address with the
  *                   remote XBee device.
  * @param remoteXBeeDevice The remote XBee device to compare its address
  *                         with the XBee packet.
  *
  * @return {@code true} if the source address of the provided packet (if
  *         it has) matches the address of the remote XBee device.
  *
  * @see com.digi.xbee.api.RemoteXBeeDevice
  * @see com.digi.xbee.api.packet.XBeePacket
  */
 private bool AddressesMatch(XBeePacket xbeePacket, RemoteXBeeDevice remoteXBeeDevice)
 {
     if (!(xbeePacket is XBeeAPIPacket))
         return false;
     APIFrameType packetType = ((XBeeAPIPacket)xbeePacket).FrameType;
     switch (packetType)
     {
         case APIFrameType.RECEIVE_PACKET:
             if (remoteXBeeDevice.Get64BitAddress() != null && ((ReceivePacket)xbeePacket).get64bitSourceAddress().Equals(remoteXBeeDevice.Get64BitAddress()))
                 return true;
             if (remoteXBeeDevice.Get16BitAddress() != null && ((ReceivePacket)xbeePacket).get16bitSourceAddress().Equals(remoteXBeeDevice.Get16BitAddress()))
                 return true;
             break;
         case APIFrameType.REMOTE_AT_COMMAND_RESPONSE:
             if (remoteXBeeDevice.Get64BitAddress() != null && ((RemoteATCommandResponsePacket)xbeePacket).get64bitSourceAddress().Equals(remoteXBeeDevice.Get64BitAddress()))
                 return true;
             if (remoteXBeeDevice.Get16BitAddress() != null && ((RemoteATCommandResponsePacket)xbeePacket).get16bitSourceAddress().Equals(remoteXBeeDevice.Get16BitAddress()))
                 return true;
             break;
         case APIFrameType.RX_16:
             if (((RX16Packet)xbeePacket).Get16bitSourceAddress().Equals(remoteXBeeDevice.Get16BitAddress()))
                 return true;
             break;
         case APIFrameType.RX_64:
             if (((RX64Packet)xbeePacket).SourceAddress64.Equals(remoteXBeeDevice.Get64BitAddress()))
                 return true;
             break;
         case APIFrameType.RX_IO_16:
             if (((RX16IOPacket)xbeePacket).get16bitSourceAddress().Equals(remoteXBeeDevice.Get16BitAddress()))
                 return true;
             break;
         case APIFrameType.RX_IO_64:
             if (((RX64IOPacket)xbeePacket).SourceAddress64.Equals(remoteXBeeDevice.Get64BitAddress()))
                 return true;
             break;
         default:
             return false;
     }
     return false;
 }
		/**
		 * Sends the given XBee packet asynchronously and registers the given 
		 * packet listener (if not {@code null}) to wait for an answer.
		 * 
		 * <p>The method will not wait for an answer for the packet, but the given 
		 * listener will be notified when the answer arrives.</p>
		 * 
		 * @param packet XBee packet to be sent.
		 * @param packetReceiveListener Listener for the operation, {@code null} 
		 *                              not to be notified when the answer arrives.
		 * 
		 * @throws InterfaceNotOpenException if this device connection is not open.
		 * @throws InvalidOperatingModeException if the operating mode is different 
		 *                                       than {@link OperatingMode#API} and 
		 *                                       {@link OperatingMode#API_ESCAPE}.
		 * @throws IOException if an I/O error occurs while sending the XBee packet.
		 * @throws ArgumentNullException if {@code packet == null}.
		 * 
		 * @see #sendXBeePacket(XBeePacket)
		 * @see #sendXBeePacket(XBeePacket, IPacketReceiveListener)
		 * @see #sendXBeePacketAsync(XBeePacket)
		 * @see com.digi.xbee.api.listeners.IPacketReceiveListener
		 * @see com.digi.xbee.api.packet.XBeePacket
		 */
		protected void SendXBeePacket(XBeePacket packet, IPacketReceiveListener packetReceiveListener)
		/*throws InvalidOperatingModeException, IOException*/ {
			// Check if the packet to send is null.
			if (packet == null)
				throw new ArgumentNullException("XBee packet cannot be null.");
			// Check connection.
			if (!connectionInterface.SerialPort.IsOpen)
				throw new InterfaceNotOpenException();

			OperatingMode operatingMode = GetOperatingMode();
			switch (operatingMode)
			{
				case OperatingMode.AT:
				case OperatingMode.UNKNOWN:
				default:
					throw new InvalidOperatingModeException(operatingMode);
				case OperatingMode.API:
				case OperatingMode.API_ESCAPE:
					// Add the required frame ID and subscribe listener if given.
					if (packet is XBeeAPIPacket)
					{
						if (((XBeeAPIPacket)packet).NeedsAPIFrameID)
						{
							if (((XBeeAPIPacket)packet).FrameID == XBeeAPIPacket.NO_FRAME_ID)
								((XBeeAPIPacket)packet).FrameID = GetNextFrameID();
							if (packetReceiveListener != null)
								dataReader.AddPacketReceiveListener(packetReceiveListener, ((XBeeAPIPacket)packet).FrameID);
						}
						else if (packetReceiveListener != null)
							dataReader.AddPacketReceiveListener(packetReceiveListener);
					}

					// Write packet data.
					WritePacket(packet);
					break;
			}
		}
        /// <summary>
        /// Adds the provided packet to the list of packets. If the queue is full the first packet will be discarded to add the given one.
        /// </summary>
        /// <param name="xbeePacket">The XBee packet to be added to the list.</param>
        /// <seealso cref="XBeePacket"/>
        public void AddPacket(XBeePacket xbeePacket)
        {
            if (packetsList.Count == MaxSize)
                packetsList.RemoveFirst();

            packetsList.AddLast(xbeePacket);
        }
		/**
		 * Sends the given XBee packet synchronously and blocks until response is 
		 * received or receive timeout is reached.
		 * 
		 * <p>The receive timeout is configured using the {@code setReceiveTimeout}
		 * method and can be consulted with {@code getReceiveTimeout} method.</p>
		 * 
		 * <p>Use {@link #sendXBeePacketAsync(XBeePacket)} for non-blocking 
		 * operations.</p>
		 * 
		 * @param packet XBee packet to be sent.
		 * @return An {@code XBeePacket} containing the response of the sent packet 
		 *         or {@code null} if there is no response.
		 * 
		 * @throws InterfaceNotOpenException if this device connection is not open.
		 * @throws InvalidOperatingModeException if the operating mode is different 
		 *                                       than {@link OperatingMode#API} and 
		 *                                       {@link OperatingMode#API_ESCAPE}.
		 * @throws IOException if an I/O error occurs while sending the XBee packet.
		 * @throws ArgumentNullException if {@code packet == null}.
		 * @throws TimeoutException if the configured time expires while waiting for
		 *                          the packet reply.
		 * 
		 * @see #sendXBeePacket(XBeePacket)
		 * @see #sendXBeePacket(XBeePacket, IPacketReceiveListener)
		 * @see #sendXBeePacketAsync(XBeePacket)
		 * @see XBeeDevice#setReceiveTimeout(int)
		 * @see XBeeDevice#getReceiveTimeout()
		 * @see com.digi.xbee.api.packet.XBeePacket
		 */
		protected XBeePacket SendXBeePacket(XBeePacket packet)
		/*throws InvalidOperatingModeException, TimeoutException, IOException*/ {
			// Check if the packet to send is null.
			if (packet == null)
				throw new ArgumentNullException("XBee packet cannot be null.");
			// Check connection.
			if (!connectionInterface.SerialPort.IsOpen)
				throw new InterfaceNotOpenException();

			OperatingMode operatingMode = GetOperatingMode();
			switch (operatingMode)
			{
				case OperatingMode.AT:
				case OperatingMode.UNKNOWN:
				default:
					throw new InvalidOperatingModeException(operatingMode);
				case OperatingMode.API:
				case OperatingMode.API_ESCAPE:
					// Build response container.
					var responseList = new List<XBeePacket>();

					// If the packet does not need frame ID, send it async. and return null.
					if (packet is XBeeAPIPacket)
					{
						if (!((XBeeAPIPacket)packet).NeedsAPIFrameID)
						{
							SendXBeePacketAsync(packet);
							return null;
						}
					}
					else
					{
						SendXBeePacketAsync(packet);
						return null;
					}

					// Add the required frame ID to the packet if necessary.
					InsertFrameID(packet);

					// Generate a packet received listener for the packet to be sent.
					IPacketReceiveListener packetReceiveListener = CreatePacketReceivedListener(packet, responseList);

					// Add the packet listener to the data reader.
					AddPacketListener(packetReceiveListener);

					// Write the packet data.
					WritePacket(packet);
					try
					{
						// Wait for response or timeout.
						lock (responseList)
						{
							try
							{
								Monitor.Wait(responseList, receiveTimeout);
							}
							catch (ThreadInterruptedException) { }
						}
						// After the wait check if we received any response, if not throw timeout exception.
						if (responseList.Count < 1)
							throw new Kveer.XBeeApi.Exceptions.TimeoutException();
						// Return the received packet.
						return responseList[0];
					}
					finally
					{
						// Always remove the packet listener from the list.
						RemovePacketListener(packetReceiveListener);
					}
			}
		}
 public PacketReceivedEventArgs(XBeePacket packet)
 {
     ReceivedPacket = packet;
 }
예제 #23
0
        //public event EventHandler<PacketReceivedEventArgs> PacketReceived;
        /**
         * Notifies subscribed XBee packet listeners that a new XBee packet has
         * been received.
         *
         * @param packet The received XBee packet.
         *
         * @see com.digi.xbee.api.packet.XBeeAPIPacket
         * @see com.digi.xbee.api.packet.XBeePacket
         */
        private void NotifyPacketReceived(XBeePacket packet)
        {
            logger.DebugFormat(connectionInterface.ToString() + "Packet received: \n{0}", packet.ToPrettyString());

            try
            {
                lock (packetReceiveListeners)
                {
                    var removeListeners = new List<IPacketReceiveListener>();

                    var tasks = new ConcurrentBag<Task>();
                    foreach (IPacketReceiveListener listener in packetReceiveListeners.Keys)
                    {
                        tasks.Add(Task.Factory.StartNew((state) =>
                        {
                            var listener0 = (IPacketReceiveListener)state;
                            lock (listener0)
                            {
                                if (packetReceiveListeners[listener0] == ALL_FRAME_IDS)
                                    listener0.PacketReceived(packet);
                                else if (((XBeeAPIPacket)packet).NeedsAPIFrameID &&
                                        ((XBeeAPIPacket)packet).FrameID == packetReceiveListeners[listener0])
                                {
                                    listener0.PacketReceived(packet);
                                    removeListeners.Add(listener0);
                                }
                            }
                        }, listener));
                    }
                    Task.WaitAll(tasks.ToArray());
                    //executor.shutdown();
                    // Remove required listeners.
                    foreach (IPacketReceiveListener listener in removeListeners)
                    {
                        int value;
                        packetReceiveListeners.TryRemove(listener, out value);
                    }
                }
            }
            catch (Exception e)
            {
                logger.Error(e.Message, e);
            }
        }