/// <summary> /// Returns whether or not the source address of the provided packet matches the given remote device. /// </summary> /// <param name="packet">The packet to get the address to compare</param> /// <param name="remoteDevice">The remote device to get the address to compare</param> /// <returns>True is the remote device matches, false otherwise</returns> /// <exception cref="NotImplementedException">Thrown if the provided packets are RX, which aren't supported</exception> protected static bool RemoteDeviceMatch(XBeeAPIPacket packet, RemoteXBeeDevice remoteDevice) { if (packet.FrameTypeValue == ApiFrameType.Byte.RECEIVE_PACKET) { return((((ReceivePacket)packet).X64bit_addr.Equals(remoteDevice.Address64bit)) || (((ReceivePacket)packet).X16bit_addr.Equals(remoteDevice.Address16bit)) && ((remoteDevice.Protocol == XBeeProtocol.Byte.RAW_802_15_4 || remoteDevice.Protocol == XBeeProtocol.Byte.DIGI_POINT || remoteDevice.Protocol == XBeeProtocol.Byte.ZIGBEE))); } else if (packet.FrameTypeValue == ApiFrameType.Byte.REMOTE_AT_COMMAND_RESPONSE) { return((((RemoteATCommandPacket)packet).X64bit_addr.Equals(remoteDevice.Address64bit)) || (((ReceivePacket)packet).X16bit_addr.Equals(remoteDevice.Address16bit)) && ((remoteDevice.Protocol == XBeeProtocol.Byte.RAW_802_15_4 || remoteDevice.Protocol == XBeeProtocol.Byte.DIGI_POINT || remoteDevice.Protocol == XBeeProtocol.Byte.ZIGBEE))); } else if (packet.FrameTypeValue == ApiFrameType.Byte.RX_16 || packet.FrameTypeValue == ApiFrameType.Byte.RX_64 || packet.FrameTypeValue == ApiFrameType.Byte.RX_IO_16 || packet.FrameTypeValue == ApiFrameType.Byte.RX_IO_64) { throw new NotImplementedException("This method does not support RX packets"); } else if (packet.FrameTypeValue == ApiFrameType.Byte.EXPLICIT_RX_INDICATOR) { return(((ExplicitRXIndicatorPacket)packet).X64BitAddress.Equals(remoteDevice.Address64bit)); } else { return(false); } }
/** * Returns the first data packet from the queue whose 64-bit source * address matches the address of the provided remote XBee device. * * <p>The methods waits up to the specified timeout if necessary for an * XBee data packet to become available. {@code null} if the queue is * empty or there is not any XBee data packet sent by the provided remote * XBee device.</p> * * @param remoteXBeeDevice The XBee device containing the 64-bit address * to look for in the list of packets. * @param timeout The time in milliseconds to wait for an XBee data packet * from the specified remote XBee device to become * available. 0 to return immediately. * * @return The first XBee data packet whose its 64-bit address matches the * address of the provided remote XBee device. {@code null} if no * data packets from the specified XBee device are found in the * queue. * * @see com.digi.xbee.api.RemoteXBeeDevice * @see com.digi.xbee.api.packet.XBeePacket */ public XBeePacket getFirstDataPacketFrom(RemoteXBeeDevice remoteXBeeDevice, int timeout) { if (timeout > 0) { XBeePacket xbeePacket = getFirstDataPacketFrom(remoteXBeeDevice, 0); // Wait for a timeout or until an XBee packet from remoteXBeeDevice is read. long deadLine = CurrentTimeMillis() + timeout; while (xbeePacket == null && deadLine > CurrentTimeMillis()) { Sleep(100); xbeePacket = getFirstDataPacketFrom(remoteXBeeDevice, 0); } return(xbeePacket); } else { for (int i = 0; i < packetsList.Count; i++) { XBeePacket xbeePacket = packetsList.ElementAt(i); if (IsDataPacket(xbeePacket) && AddressesMatch(xbeePacket, remoteXBeeDevice)) { packetsList.Remove(xbeePacket); return(xbeePacket); } } } return(null); }
/** * 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); }
public void SendData(RemoteXBeeDevice rxb, byte[] data) { if (Monitor.TryEnter(Coordinator, COORDINATOR_LOCK_TIMEOUT)) { try { //XBCoordinator.SendDataAsync(XBRemoteDevice, buffer); long msSinceLastSent = (DateTime.Now.Ticks - DataLastSent.Ticks) / TimeSpan.TicksPerMillisecond; if (msSinceLastSent < SEND_DATA_THROTTLE) { int sleep = (int)(SEND_DATA_THROTTLE - msSinceLastSent); System.Threading.Thread.Sleep(sleep); } Coordinator.SendData(rxb, data); DataLastSent = DateTime.Now; } finally { Monitor.Exit(Coordinator); } } else { //TODO: couldn't obain a lock.. for now we just let it pass } }
/** * 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); } }
/// <summary> /// Initializes new instance of class <see cref="XBeeMessage"/>. /// </summary> /// <param name="remoteXBeeDevice">The remote XBee device the message belongs to.</param> /// <param name="data">Byte array containing the data of the message.</param> /// <param name="isBroadcast">Indicates if the message was received via broadcast.</param> /// <exception cref="ArgumentNullException">if <paramref name="remoteXBeeDevice"/> is null of <paramref name="data"/> is null.</exception> public XBeeMessage(RemoteXBeeDevice remoteXBeeDevice, byte[] data, bool isBroadcast) { Contract.Requires<ArgumentNullException>(remoteXBeeDevice != null, "Remote XBee device cannot be null."); Contract.Requires<ArgumentNullException>(data != null, "Data cannot be null."); this.Device = remoteXBeeDevice; this.Data = data; this.IsBroadcast = isBroadcast; }
/// <summary> /// Initializes new instance of class <see cref="XBeeMessage"/>. /// </summary> /// <param name="remoteXBeeDevice">The remote XBee device the message belongs to.</param> /// <param name="data">Byte array containing the data of the message.</param> /// <param name="isBroadcast">Indicates if the message was received via broadcast.</param> /// <exception cref="ArgumentNullException">if <paramref name="remoteXBeeDevice"/> is null of <paramref name="data"/> is null.</exception> public XBeeMessage(RemoteXBeeDevice remoteXBeeDevice, byte[] data, bool isBroadcast) { Contract.Requires <ArgumentNullException>(remoteXBeeDevice != null, "Remote XBee device cannot be null."); Contract.Requires <ArgumentNullException>(data != null, "Data cannot be null."); this.Device = remoteXBeeDevice; this.Data = data; this.IsBroadcast = isBroadcast; }
/// <summary> /// This scrapes the provided packet for information about a remote node, creates an object for that node and attempts to add it to the network. /// </summary> /// <param name="packet">API packet, ideally one sent from a remote node</param> /// <returns>The remote xbee device</returns> protected RemoteXBeeDevice TryAddRemoteDevice(XBeeAPIPacket packet) { RemoteXBeeDevice remote = null; Tuple <XBee64BitAddress, XBee16BitAddress> addresses = GetRemoteDeviceDataFromPacket(packet); if (addresses.Item1 != null || addresses.Item2 != null) { remote = xbeeDevice.Network.AddIfNotExist(addresses.Item1, addresses.Item2); } return(remote); }
public XBeeRemoteSerialPort(XBeeNetworkGatewayModule xBeeGateway, SerializableXBeeAddress remoteXBeeAddress) { RemoteXBeeAddress = remoteXBeeAddress; XBeeGateway = xBeeGateway; remoteDevice = XBeeGateway.GetRemoteDevice(RemoteXBeeAddress); var test = Encoding.UTF8.GetBytes("This is a test!"); this.Write(test, 0, test.Length); //TODO: Set remote mode and destination address??? }
/// <summary> /// Class constructor. Instantiates a new object of type <c>ExplicitXBeeMessage</c> /// with the given parameters. /// </summary> /// <param name="remoteXBeeDevice">The remote XBee device the message belongs to /// (device that sent the message).</param> /// <param name="sourceEndpoint">Endpoint of the source that initiated the transmission.</param> /// <param name="destEndpoint">Endpoint of the destination the message was addressed to.</param> /// <param name="clusterID">Cluster ID the packet was addressed to.</param> /// <param name="profileID">Profile ID the packet was addressed to.</param> /// <param name="data">Byte array containing the data of the message.</param> /// <param name="isBroadcast">Indicates if the message was received via broadcast.</param> /// <exception cref="ArgumentException">If <c>sourceEndpoint.Length != 2</c> or /// if <c>destEndpoint.Length != 2</c>.</exception> /// <exception cref="ArgumentNullException">If <c>remoteXBeeDevice == null</c> or /// if <c>data == null</c>.</exception> public ExplicitXBeeMessage(RemoteXBeeDevice remoteXBeeDevice, byte sourceEndpoint, byte destEndpoint, byte[] clusterID, byte[] profileID, byte[] data, bool isBroadcast) : base(remoteXBeeDevice, data, isBroadcast) { if (clusterID.Length != 2) { throw new ArgumentException("Cluster ID must be 2 bytes."); } if (profileID.Length != 2) { throw new ArgumentException("Profile ID must be 2 bytes."); } SourceEndpoint = sourceEndpoint; DestEndpoint = destEndpoint; ClusterID = clusterID; ProfileID = profileID; }
public RemoteXBeeDevice Connect(String remoteNodeID) { if (Monitor.TryEnter(Coordinator, COORDINATOR_LOCK_TIMEOUT)) { RemoteXBeeDevice rxb = null; try { if (!Coordinator.IsOpen) { //Console.WriteLine("Opening coordinator while opening connection to {0}", remoteNodeID); Coordinator.Open(); } //always perform a network discovery XBeeNetwork network = Coordinator.GetNetwork(); if (network == null) { throw new NetworkNotFoundException(String.Format("Open: Cannot find coordinator network when looking for NodeID {0}", remoteNodeID)); } rxb = network.DiscoverDevice(remoteNodeID); if (rxb == null) { throw new BoardNotFoundException(String.Format("Open: Cannot find XBee with NodeID {0}", remoteNodeID)); } //delay for a while ... System.Threading.Thread.Sleep(DELAY_AFTER_CONNECT); //return the remote xb device to be used for calls to send data return(rxb); } finally { Monitor.Exit(Coordinator); } } else { throw new TimeoutException(String.Format("TryConnect: could not obtain lock when trying to connect to NodeID {0}", remoteNodeID)); } }
/// <summary> /// Executes callbacks corresponding to the received packet. /// </summary> /// <param name="xbeePacket">The received packet.</param> /// <param name="remote">The XBee device that sent the packet.</param> protected void ExecuteUserCallbacks(XBeeAPIPacket xbeePacket, RemoteXBeeDevice remote = null) { OnPacketReceived(xbeePacket); // If the packet is a Receive Packet, add it to the data queue if (xbeePacket.FrameTypeValue == ApiFrameType.Byte.RECEIVE_PACKET) { byte[] data = ((ReceivePacket)xbeePacket).Rfdata; bool isBroadcast = ((ReceivePacket)xbeePacket).ReceiveOptions == ReceiveOptions.BROADCAST_PACKET; OnDataReceived(new XBeeMessage(data, remote, Utils.TimeNow(), isBroadcast)); Log.Info(String.Format(LOG_PATTERN, xbeeDevice.ComPort.PortName, "RECEIVED", "DATA", remote?.Address64bit, Utils.BytesToHexString(((ReceivePacket)xbeePacket).Rfdata, true))); } else if (xbeePacket.FrameTypeValue == ApiFrameType.Byte.RX_64 || xbeePacket.FrameTypeValue == ApiFrameType.Byte.RX_16) { throw new NotImplementedException("Callback does not support RX_64 or RX_16 packets yet"); } else if (xbeePacket.FrameTypeValue == ApiFrameType.Byte.MODEM_STATUS) { throw new NotImplementedException("Callback does not support Modem Status packets yet"); } else if (xbeePacket.FrameTypeValue == ApiFrameType.Byte.RX_IO_16 || xbeePacket.FrameTypeValue == ApiFrameType.Byte.RX_IO_64 || xbeePacket.FrameTypeValue == ApiFrameType.Byte.IO_DATA_SAMPLE_RX_INDICATOR) { throw new NotImplementedException("Callback does not support RX IO 16, RX IO 64, or IO data sample RX indicator packets yet"); } else if (xbeePacket.FrameTypeValue == ApiFrameType.Byte.EXPLICIT_RX_INDICATOR) { throw new NotImplementedException("Callback does not support Explicit RX indicator packets yet"); } else if (xbeePacket.FrameTypeValue == ApiFrameType.Byte.RX_IPV4) { throw new NotImplementedException("Callback does not support RX IPv4 packets yet"); } else if (xbeePacket.FrameTypeValue == ApiFrameType.Byte.RX_SMS) { throw new NotImplementedException("Callback does not support RX SMS packets yet"); } }
/// <summary> /// Returns the first element of the queue that had been sent by the remote device /// </summary> /// <param name="remote">Remote device that we're looking for a packet from</param> /// <param name="timeout">Time to wait if there's no packet immediately available</param> /// <returns>Packet from remote device, if any is available in allotted time. Otherwise, null</returns> /// <exception cref="NotImplementedException">Thrown if an RX packet is found in the queue. RX packets aren't supported yet</exception> /// <exception cref="TimeoutException">Thrown if timeout expires before a element is found</exception> public XBeeAPIPacket GetByRemote(RemoteXBeeDevice remote, int timeout = 0) { if (timeout <= 0) { // Lock down the queue lock (mutex) { // Scan through the list for a packet matching the remote device var node = list.First; while (node != null) { if (RemoteDeviceMatch(node.Value, remote)) { list.Remove(node); return(node.Value); } node = node.Next; } } return(null); } else { // Call the above non-waiting block of code multiple times until we get a matching packet or the timeout expires XBeeAPIPacket packet = GetByRemote(remote, 0); DateTime deadline = DateTime.Now + new TimeSpan(0, 0, seconds: timeout); while (packet == null && DateTime.Now < deadline) { Thread.Sleep(100); packet = GetByRemote(remote, 0); } if (packet == null) { throw new TimeoutException(); } return(packet); } }
/// <summary> /// Instantiates a <see cref="DeviceDiscoveredEventArgs"/> object with the provided parameters. /// </summary> /// <param name="discoveredDevice">The discovered remote device.</param> public DeviceDiscoveredEventArgs(RemoteXBeeDevice discoveredDevice) { DiscoveredDevice = discoveredDevice; }
/// <summary> /// Function for PacketListener to loop in /// </summary> private void Run() { try { stop = false; while (!stop) { byte[] rawPacket = TryReadPacket(xbeeDevice.OpMode); if (rawPacket != null) { // If the protocol is 802.15.4, check if the packet is valid. If not, skip it if (xbeeDevice.Protocol == XBeeProtocol.Byte.RAW_802_15_4 && !CheckPacket802_15_4(rawPacket)) { continue; } // Build the packet XBeeAPIPacket readPacket; try { readPacket = (XBeeAPIPacket)Factory.BuildFrame(rawPacket, xbeeDevice.OpMode); } catch (InvalidPacketException e) { Log.Error(String.Format("Error processing packet {0} : {1}", Utils.BytesToHexString(rawPacket, true), e.Message)); continue; } Log.Debug(String.Format(XBeeDevice.LOG_PATTERN, xbeeDevice.ComPort.PortName, "RECEIVED", OperatingMode.Get(xbeeDevice.OpMode), Utils.BytesToHexString(rawPacket, true))); // Add the packet to the queue AddPacketQueue(readPacket); // If the packet has information about a remote device, extract it and update the remote device RemoteXBeeDevice remote = TryAddRemoteDevice(readPacket); // Execute callbacks to process API packets OnPacketReceivedAPI(readPacket); ExecuteUserCallbacks(readPacket, remote); } } } catch (Exception e) { if (!stop) { Log.Error(e); Console.Write(e.StackTrace); } } finally { if (!stop) { stop = true; if (comPort.IsOpen) { comPort.Close(); } } } }
/// <summary> /// Programmatic trigger for IOSampleReceived event /// </summary> /// <param name="sample">Received IO Sample</param> /// <param name="remote">Remote XBee device that sent the packet</param> /// <param name="time">Time packet was received</param> protected virtual void OnIOSampleReceived(object sample, RemoteXBeeDevice remote, int time) { IOSampleReceived?.Invoke(this, sample, remote, time); }
/// <summary> /// Instantiates a <see cref="IOSampleReceivedEventArgs"/> object with the provided parameters. /// </summary> /// <param name="remoteDevice">The remote XBee device.</param> /// <param name="ioSample">The IO sample.</param> public IOSampleReceivedEventArgs(RemoteXBeeDevice remoteDevice, IOSample ioSample) { RemoteDevice = remoteDevice; IOSample = ioSample; }
/// <summary> /// Returns the remote XBee device from where the given package was sent from. /// </summary> /// <remarks>This is for internal use only. /// /// If the package does not contain information about the source, this method returns <c>null</c> /// (for example, <see cref="ModemStatusPacket"/>). /// /// First the device that sent the provided package is looked in the network of the local /// XBee device. If the remote device is not in the network, it is automatically added only /// if the packet contains information about the origin of the package.</remarks> /// <param name="apiPacket">The packet sent from the remote device.</param> /// <returns>The remote XBee device that sends the given packet. It may be <c>null</c> if the /// packet is not a known frame (<see cref="APIFrameType"/>) or if it does not contain information /// of the source device.</returns> /// <exception cref="ArgumentNullException">If <c><paramref name="apiPacket"/> == null</c>.</exception> /// <exception cref="XBeeException">If any error occurred while adding the device to the /// network.</exception> public RemoteXBeeDevice GetRemoteXBeeDeviceFromPacket(XBeeAPIPacket apiPacket) { if (apiPacket == null) { throw new ArgumentNullException("XBee API packet cannot be null."); } APIFrameType apiType = apiPacket.FrameType; RemoteXBeeDevice remoteDevice = null; XBee64BitAddress addr64 = null; XBee16BitAddress addr16 = null; XBeeNetwork network = xbeeDevice.GetNetwork(); switch (apiType) { case APIFrameType.RECEIVE_PACKET: ReceivePacket receivePacket = (ReceivePacket)apiPacket; addr64 = receivePacket.SourceAddress64; addr16 = receivePacket.SourceAddress16; if (!addr64.Equals(XBee64BitAddress.UNKNOWN_ADDRESS)) { remoteDevice = network.GetDevice(addr64); } else if (!addr16.Equals(XBee16BitAddress.UNKNOWN_ADDRESS)) { remoteDevice = network.GetDevice(addr16); } break; case APIFrameType.RX_64: RX64Packet rx64Packet = (RX64Packet)apiPacket; addr64 = rx64Packet.SourceAddress64; remoteDevice = network.GetDevice(addr64); break; case APIFrameType.RX_16: RX16Packet rx16Packet = (RX16Packet)apiPacket; addr64 = XBee64BitAddress.UNKNOWN_ADDRESS; addr16 = rx16Packet.SourceAddress16; remoteDevice = network.GetDevice(addr16); break; case APIFrameType.IO_DATA_SAMPLE_RX_INDICATOR: IODataSampleRxIndicatorPacket ioSamplePacket = (IODataSampleRxIndicatorPacket)apiPacket; addr64 = ioSamplePacket.SourceAddress64; addr16 = ioSamplePacket.SourceAddress16; remoteDevice = network.GetDevice(addr64); break; case APIFrameType.RX_IO_64: RX64IOPacket rx64IOPacket = (RX64IOPacket)apiPacket; addr64 = rx64IOPacket.SourceAddress64; remoteDevice = network.GetDevice(addr64); break; case APIFrameType.RX_IO_16: RX16IOPacket rx16IOPacket = (RX16IOPacket)apiPacket; addr64 = XBee64BitAddress.UNKNOWN_ADDRESS; addr16 = rx16IOPacket.SourceAddress16; remoteDevice = network.GetDevice(addr16); break; case APIFrameType.EXPLICIT_RX_INDICATOR: ExplicitRxIndicatorPacket explicitDataPacket = (ExplicitRxIndicatorPacket)apiPacket; addr64 = explicitDataPacket.SourceAddress64; addr16 = explicitDataPacket.SourceAddress16; remoteDevice = network.GetDevice(addr64); break; default: // Rest of the types are considered not to contain information // about the origin of the packet. return(remoteDevice); } // If the origin is not in the network, add it. if (remoteDevice == null) { remoteDevice = CreateRemoteXBeeDevice(addr64, addr16, null); if (!addr64.Equals(XBee64BitAddress.UNKNOWN_ADDRESS) || !addr16.Equals(XBee16BitAddress.UNKNOWN_ADDRESS)) { network.AddRemoteDevice(remoteDevice); } } return(remoteDevice); }
/** * 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; }
/** * 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); } }
/** * 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); }
/// <summary> /// Returns whether or not the source address of the provided XBee packet matches the address /// of the given remote XBee device. /// </summary> /// <param name="xbeePacket">The XBee packet to compare its address with the remote XBee /// device.</param> /// <param name="remoteXBeeDevice">The remote XBee device to compare its address with the XBee /// packet.</param> /// <returns><c>true</c> if the source address of the provided packet (if it has) matches the /// address of the remote XBee device.</returns> /// <seealso cref="RemoteXBeeDevice"/> /// <seealso cref="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.XBee64BitAddr != null && ((ReceivePacket)xbeePacket).SourceAddress64.Equals(remoteXBeeDevice.XBee64BitAddr)) { return(true); } if (remoteXBeeDevice.XBee16BitAddr != null && !remoteXBeeDevice.XBee16BitAddr.Equals(XBee16BitAddress.UNKNOWN_ADDRESS) && ((ReceivePacket)xbeePacket).SourceAddress16.Equals(remoteXBeeDevice.XBee16BitAddr)) { return(true); } break; case APIFrameType.REMOTE_AT_COMMAND_RESPONSE: if (remoteXBeeDevice.XBee64BitAddr != null && ((RemoteATCommandResponsePacket)xbeePacket).SourceAddress64.Equals(remoteXBeeDevice.XBee64BitAddr)) { return(true); } if (remoteXBeeDevice.XBee16BitAddr != null && !remoteXBeeDevice.XBee16BitAddr.Equals(XBee16BitAddress.UNKNOWN_ADDRESS) && ((RemoteATCommandResponsePacket)xbeePacket).SourceAddress16.Equals(remoteXBeeDevice.XBee16BitAddr)) { return(true); } break; case APIFrameType.RX_16: if (((RX16Packet)xbeePacket).SourceAddress16.Equals(remoteXBeeDevice.XBee16BitAddr)) { return(true); } break; case APIFrameType.RX_64: if (((RX64Packet)xbeePacket).SourceAddress64.Equals(remoteXBeeDevice.XBee64BitAddr)) { return(true); } break; case APIFrameType.RX_IO_16: if (((RX16IOPacket)xbeePacket).SourceAddress16.Equals(remoteXBeeDevice.XBee16BitAddr)) { return(true); } break; case APIFrameType.RX_IO_64: if (((RX64IOPacket)xbeePacket).SourceAddress64.Equals(remoteXBeeDevice.XBee64BitAddr)) { return(true); } break; case APIFrameType.EXPLICIT_RX_INDICATOR: if (((ExplicitRxIndicatorPacket)xbeePacket).SourceAddress64.Equals(remoteXBeeDevice.XBee64BitAddr)) { return(true); } break; default: return(false); } return(false); }
/// <summary> /// Dispatches the received XBee packet to the corresponding event handler(s). /// </summary> /// <param name="packet">The received XBee packet to be dispatched to the corresponding event /// handlers.</param> /// <seealso cref="XBeeAPIPacket"/> /// <seealso cref="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 event handlers. 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; 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.IoSample); 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; case APIFrameType.EXPLICIT_RX_INDICATOR: ExplicitRxIndicatorPacket explicitDataPacket = (ExplicitRxIndicatorPacket)apiPacket; byte sourceEndpoint = explicitDataPacket.SourceEndpoint; byte destEndpoint = explicitDataPacket.DestEndpoint; byte[] clusterID = explicitDataPacket.ClusterID; byte[] profileID = explicitDataPacket.ProfileID; data = explicitDataPacket.RFData; // If this is an explicit packet for data transmissions in the Digi profile, // notify also the data event handler and add a Receive packet to the queue. if (sourceEndpoint == ExplicitRxIndicatorPacket.DATA_ENDPOINT && destEndpoint == ExplicitRxIndicatorPacket.DATA_ENDPOINT && clusterID.SequenceEqual(ExplicitRxIndicatorPacket.DATA_CLUSTER) && profileID.SequenceEqual(ExplicitRxIndicatorPacket.DIGI_PROFILE)) { NotifyDataReceived(new XBeeMessage(remoteDevice, data, apiPacket.IsBroadcast)); XBeePacketsQueue.AddPacket(new ReceivePacket(explicitDataPacket.SourceAddress64, explicitDataPacket.SourceAddress16, explicitDataPacket.ReceiveOptions, explicitDataPacket.RFData)); } NotifyExplicitDataReceived(new ExplicitXBeeMessage(remoteDevice, sourceEndpoint, destEndpoint, clusterID, profileID, data, explicitDataPacket.IsBroadcast)); break; case APIFrameType.USER_DATA_RELAY_OUTPUT: UserDataRelayOutputPacket relayPacket = (UserDataRelayOutputPacket)apiPacket; NotifyUserDataRelayReceived(new UserDataRelayMessage(relayPacket.SourceInterface, relayPacket.Data)); break; case APIFrameType.RX_IPV4: RXIPv4Packet rxIPv4Packet = (RXIPv4Packet)apiPacket; NotifyIPDataReceived(new IPMessage( rxIPv4Packet.SourceAddress, rxIPv4Packet.SourcePort, rxIPv4Packet.DestPort, rxIPv4Packet.Protocol, rxIPv4Packet.Data)); break; case APIFrameType.RX_SMS: RXSMSPacket rxSMSPacket = (RXSMSPacket)apiPacket; NotifySMSReceived(new SMSMessage(rxSMSPacket.PhoneNumber, rxSMSPacket.Data)); break; default: break; } } catch (XBeeException e) { logger.Error(e.Message, e); } }
/// <summary> /// Class constructor. Instantiates a new object of type <see cref="ExplicitXBeeMessage"/> with /// the given parameters. /// </summary> /// <param name="remoteXBeeDevice">The remote XBee device the message belongs to (device that /// sent the message).</param> /// <param name="sourceEndpoint">Endpoint of the source that initiated the transmission.</param> /// <param name="destEndpoint">Endpoint of the destination the message was addressed to.</param> /// <param name="clusterID">Cluster ID the packet was addressed to.</param> /// <param name="profileID">Profile ID the packet was addressed to.</param> /// <param name="data">Byte array containing the data of the message.</param> /// <exception cref="ArgumentException">If <c>sourceEndpoint.Length != 2</c> /// or if <c>destEndpoint.Length != 2</c>.</exception> /// <exception cref="ArgumentNullException">If <c>remoteXBeeDevice == null</c> /// or if <c>data == null</c>.</exception> public ExplicitXBeeMessage(RemoteXBeeDevice remoteXBeeDevice, byte sourceEndpoint, byte destEndpoint, byte[] clusterID, byte[] profileID, byte[] data) : this(remoteXBeeDevice, sourceEndpoint, destEndpoint, clusterID, profileID, data, false) { }
public void Write(RemoteXBeeDevice remoteDevice, byte[] data) { xBee.SendData(remoteDevice, data); }
public void Write(SerializableXBeeAddress remoteAddress, byte[] data) { var remoteDevice = new RemoteXBeeDevice(xBee, remoteAddress.XBee64BitAddress); Write(remoteDevice, data); }
/// <summary> /// Initializes new instance of class <see cref="XBeeMessage"/>. /// </summary> /// <param name="remoteXBeeDevice">The remote XBee device the message belongs to.</param> /// <param name="data">Byte array containing the data of the message.</param> /// <param name="isBroadcast">Indicates if the message was received via broadcast.</param> /// <exception cref="ArgumentNullException">If <paramref name="remoteXBeeDevice"/> is <c>null</c> /// or if <paramref name="data"/> is <c>null</c>.</exception> /// <seealso cref="RemoteXBeeDevice"/> public XBeeMessage(RemoteXBeeDevice remoteXBeeDevice, byte[] data, bool isBroadcast) { Device = remoteXBeeDevice ?? throw new ArgumentNullException("Remote XBee device cannot be null."); Data = data ?? throw new ArgumentNullException("Data cannot be null."); IsBroadcast = isBroadcast; }
/// <summary> /// Converts an explicit packet to an explicit message /// </summary> /// <param name="remote">The remote XBee device that sent the packet</param> /// <param name="broadcast">Flag indicating whether the message is broadcast (default is false)</param> /// <param name="packet">The packet to be converted</param> /// <returns>The explicit message genereated from the provided parameters</returns> protected static ExplicitXBeeMessage ExplToMessage(RemoteXBeeDevice remote, bool broadcast, ExplicitRXIndicatorPacket packet) { return(new ExplicitXBeeMessage(packet.RfData, remote, Utils.TimeNow(), packet.SourceEndpoint, packet.DestEndpoint, packet.ClusterID, packet.ProfileID, broadcast)); }
/** * Returns the first packet from the queue whose 64-bit source address * matches the address of the provided remote XBee device. * * <p>The methods waits up to the specified timeout if necessary for an * XBee packet to become available. Null if the queue is empty or there is * not any XBee packet sent by the provided remote XBee device.</p> * * @param remoteXBeeDevice The remote XBee device containing the 64-bit * address to look for in the list of packets. * @param timeout The time in milliseconds to wait for an XBee packet from * the specified remote XBee device to become available. * 0 to return immediately. * * @return The first XBee packet whose 64-bit address matches the address * of the provided remote XBee device. {@code null} if no packets * from the specified XBee device are found in the queue. * * @see com.digi.xbee.api.RemoteXBeeDevice * @see com.digi.xbee.api.packet.XBeePacket */ public XBeePacket getFirstPacketFrom(RemoteXBeeDevice remoteXBeeDevice, int timeout) { if (timeout > 0) { XBeePacket xbeePacket = getFirstPacketFrom(remoteXBeeDevice, 0); // Wait for a timeout or until an XBee packet from remoteXBeeDevice is read. long deadLine = CurrentTimeMillis() + timeout; while (xbeePacket == null && deadLine > CurrentTimeMillis()) { Sleep(100); xbeePacket = getFirstPacketFrom(remoteXBeeDevice, 0); } return xbeePacket; } else { for (int i = 0; i < packetsList.Count; i++) { XBeePacket xbeePacket = packetsList.ElementAt(i); if (AddressesMatch(xbeePacket, remoteXBeeDevice)) { packetsList.Remove(xbeePacket); return xbeePacket; } } } return 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; }
/** * Returns the remote XBee device from where the given package was sent * from. * * <p><b>This is for internal use only.</b></p> * * <p>If the package does not contain information about the source, this * method returns {@code null} (for example, {@code ModemStatusPacket}).</p> * * <p>First the device that sent the provided package is looked in the * network of the local XBee device. If the remote device is not in the * network, it is automatically added only if the packet contains * information about the origin of the package.</p> * * @param packet The packet sent from the remote device. * * @return The remote XBee device that sends the given packet. It may be * {@code null} if the packet is not a known frame (see * {@link APIFrameType}) or if it does not contain information of * the source device. * * @throws ArgumentNullException if {@code packet == null} * @throws XBeeException if any error occur while adding the device to the * network. */ public RemoteXBeeDevice GetRemoteXBeeDeviceFromPacket(XBeeAPIPacket packet) /*throws XBeeException*/ { if (packet == null) { throw new ArgumentNullException("XBee API packet cannot be null."); } XBeeAPIPacket apiPacket = (XBeeAPIPacket)packet; APIFrameType apiType = apiPacket.FrameType; if (apiType == APIFrameType.UNKNOWN) { return(null); } RemoteXBeeDevice remoteDevice = null; XBee64BitAddress addr64 = null; XBee16BitAddress addr16 = null; XBeeNetwork network = xbeeDevice.GetNetwork(); switch (apiType) { case APIFrameType.RECEIVE_PACKET: ReceivePacket receivePacket = (ReceivePacket)apiPacket; addr64 = receivePacket.get64bitSourceAddress(); addr16 = receivePacket.get16bitSourceAddress(); remoteDevice = network.GetDevice(addr64); break; case APIFrameType.RX_64: RX64Packet rx64Packet = (RX64Packet)apiPacket; addr64 = rx64Packet.SourceAddress64; remoteDevice = network.GetDevice(addr64); break; case APIFrameType.RX_16: RX16Packet rx16Packet = (RX16Packet)apiPacket; addr64 = XBee64BitAddress.UNKNOWN_ADDRESS; addr16 = rx16Packet.Get16bitSourceAddress(); remoteDevice = network.GetDevice(addr16); break; case APIFrameType.IO_DATA_SAMPLE_RX_INDICATOR: IODataSampleRxIndicatorPacket ioSamplePacket = (IODataSampleRxIndicatorPacket)apiPacket; addr64 = ioSamplePacket.get64bitSourceAddress(); addr16 = ioSamplePacket.get16bitSourceAddress(); remoteDevice = network.GetDevice(addr64); break; case APIFrameType.RX_IO_64: RX64IOPacket rx64IOPacket = (RX64IOPacket)apiPacket; addr64 = rx64IOPacket.SourceAddress64; remoteDevice = network.GetDevice(addr64); break; case APIFrameType.RX_IO_16: RX16IOPacket rx16IOPacket = (RX16IOPacket)apiPacket; addr64 = XBee64BitAddress.UNKNOWN_ADDRESS; addr16 = rx16IOPacket.get16bitSourceAddress(); remoteDevice = network.GetDevice(addr16); break; default: // Rest of the types are considered not to contain information // about the origin of the packet. return(remoteDevice); } // If the origin is not in the network, add it. if (remoteDevice == null) { remoteDevice = createRemoteXBeeDevice(addr64, addr16, null); network.addRemoteDevice(remoteDevice); } return(remoteDevice); }
/// <summary> /// Initializes new instance of class <see cref="XBeeMessage"/>. /// </summary> /// <param name="remoteXBeeDevice">The remote XBee device the message belongs to.</param> /// <param name="data">Byte array containing the data of the message.</param> public XBeeMessage(RemoteXBeeDevice remoteXBeeDevice, byte[] data) : this(remoteXBeeDevice, data, false) { }
public IOSampleReceivedEventArgs(RemoteXBeeDevice remoteDevice, IOSample ioSample) { RemoteDevice = remoteDevice; IOSample = ioSample; }