/** * 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); }
/*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(); }
/** * 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; }
/*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); } }
/*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; }
//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); } }