/** * Discovers and reports the first remote XBee device that matches the * supplied identifier. * * <p>This method blocks until the device is discovered or the configured * timeout in the device (NT) expires.</p> * * @param id The identifier of the device to be discovered. * * @return The discovered remote XBee device with the given identifier, * {@code null} if the timeout expires and the device was not found. * * @throws InterfaceNotOpenException if the device is not open. * @throws XBeeException if there is an error sending the discovery command. * * @see #discoverDevices(List) */ public RemoteXBeeDevice DiscoverDevice(string id) /*throws XBeeException */ { // Check if the connection is open. if (!xbeeDevice.IsOpen) { throw new InterfaceNotOpenException(); } logger.DebugFormat("{0}ND for {1} device.", xbeeDevice.ToString(), id); running = true; discovering = true; performNodeDiscovery(null, id); XBeeNetwork network = xbeeDevice.GetNetwork(); RemoteXBeeDevice rDevice = null; if (deviceList != null && deviceList.Count > 0) { rDevice = deviceList[0]; if (rDevice != null) { rDevice = network.addRemoteDevice(rDevice); } } return(rDevice); }
/** * Notifies the given discovery listeners that a device was discovered. * * @param listeners The discovery listeners to be notified. * @param device The remote device discovered. */ private void notifyDeviceDiscovered(IList <IDiscoveryListener> listeners, RemoteXBeeDevice device) { if (listeners == null) { lock (deviceList) { deviceList.Add(device); } return; } XBeeNetwork network = xbeeDevice.GetNetwork(); RemoteXBeeDevice addedDev = network.addRemoteDevice(device); if (addedDev != null) { foreach (IDiscoveryListener listener in listeners) { listener.DeviceDiscovered(addedDev); } } else { String error = "Error adding device '" + device + "' to the network."; notifyDiscoveryError(listeners, error); } }
/** * Adds the given list of remote devices to the network. * * <p>Notice that this operation does not join the remote XBee devices to * the network; it just tells the network that it contains those devices. * However, the devices have only been added to the device list, and may * not be physically in the same network.</p> * * <p>The way of adding a device to the network is based on the 64-bit * address. If it is not configured:</p> * * <ul> * <li>For 802.15.4 and ZigBee devices, the 16-bit address will be used instead.</li> * <li>For the rest will return {@code false} as the result of the addition.</li> * </ul> * * @param list The list of remote devices to be added to the network. * * @return A list with the successfully added devices to the network. * * @throws ArgumentNullException if {@code list == null}. * * @see #addRemoteDevice(RemoteXBeeDevice) * @see RemoteXBeeDevice */ public List <RemoteXBeeDevice> addRemoteDevices(IList <RemoteXBeeDevice> list) { if (list == null) { throw new ArgumentNullException("The list of remote devices cannot be null."); } List <RemoteXBeeDevice> addedList = new List <RemoteXBeeDevice>(list.Count); if (list.Count == 0) { return(addedList); } logger.DebugFormat("{0}Adding '{1}' devices to network.", localDevice.ToString(), list.Count); for (int i = 0; i < list.Count; i++) { RemoteXBeeDevice d = addRemoteDevice(list[i]); if (d != null) { addedList.Add(d); } } return(addedList); }
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); } }
/** * Retrieves the 16-bit address of the given remote device. * * @param device The remote device to get the 16-bit address. * * @return The 16-bit address of the device, {@code null} if it does not * contain a valid one. */ private XBee16BitAddress Get16BitAddress(RemoteXBeeDevice device) { if (device == null) { return(null); } XBee16BitAddress address = null; switch (device.XBeeProtocol) { case XBeeProtocol.RAW_802_15_4: address = ((RemoteRaw802Device)device).Get16BitAddress(); break; case XBeeProtocol.ZIGBEE: address = ((RemoteZigBeeDevice)device).Get16BitAddress(); break; default: // TODO should we allow this operation for general remote devices? address = device.Get16BitAddress(); break; } return(address); }
/** * Removes the given remote XBee device from the network. * * <p>Notice that this operation does not remove the remote XBee device * from the actual XBee network; it just tells the network object that it * will no longer contain that device. However, next time a discovery is * performed, it could be added again automatically.</p> * * <p>This method will check for a device that matches the 64-bit address * of the provided one, if found, that device will be removed from the * corresponding list. In case the 64-bit address is not defined, it will * use the 16-bit address for DigiMesh and ZigBee devices.</p> * * @param remoteDevice The remote device to be removed from the network. * * @throws ArgumentNullException if {@code RemoteDevice == null}. * * @see #addRemoteDevice(RemoteXBeeDevice) * @see #clearDeviceList() * @see RemoteXBeeDevice */ public void removeRemoteDevice(RemoteXBeeDevice remoteDevice) { if (remoteDevice == null) { throw new ArgumentNullException("Remote device cannot be null."); } RemoteXBeeDevice devInNetwork = null; // Look in the 64-bit map. XBee64BitAddress addr64 = remoteDevice.Get64BitAddress(); if (addr64 != null && !addr64.Equals(XBee64BitAddress.UNKNOWN_ADDRESS)) { if (remotesBy64BitAddr.TryRemove(addr64, out devInNetwork)) { return; } } // If not found, look in the 16-bit map. XBee16BitAddress addr16 = Get16BitAddress(remoteDevice); if (addr16 != null && !addr16.Equals(XBee16BitAddress.UNKNOWN_ADDRESS)) { // The preference order is: // 1.- Look in the 64-bit map // 2.- Then in the 16-bit map. // This should be maintained in the 'getDeviceBy16BitAddress' method. // Look for the 16-bit address in the 64-bit map. ICollection <RemoteXBeeDevice> devices = remotesBy64BitAddr.Values; foreach (RemoteXBeeDevice d in devices) { XBee16BitAddress a = Get16BitAddress(d); if (a != null && a.Equals(addr16)) { RemoteXBeeDevice r; remotesBy64BitAddr.TryRemove(d.Get64BitAddress(), out r); return; } } // If not found, look for the 16-bit address in the 16-bit map. // Remove the device. if (remotesBy16BitAddr.TryRemove(addr16, out devInNetwork)) { return; } } // If the device does not contain a valid address log an error. if ((addr64 == null || addr64.Equals(XBee64BitAddress.UNKNOWN_ADDRESS)) && (addr16 == null || addr16.Equals(XBee16BitAddress.UNKNOWN_ADDRESS))) { logger.ErrorFormat("{0}Remote device '{1}' cannot be removed: 64-bit and 16-bit addresses must be specified.", localDevice.ToString(), remoteDevice.ToString()); } }
/** * Returns the remote device already contained in the network whose 16-bit * address matches the given one. * * <p>Note that this method <b>does not perform a discovery</b>, only * returns the device that has been previously discovered.</p> * * @param address The 16-bit address of the device to be retrieved. * * @return The remote device in the network or {@code null} if it is not * found. * * @throws ArgumentException if {@code address.equals(XBee16BitAddress.UNKNOWN_ADDRESS)}. * @throws ArgumentNullException if {@code address == null}. * @throws OperationNotSupportedException if the protocol of the local XBee device is DigiMesh or Point-to-Multipoint. */ public RemoteXBeeDevice GetDevice(XBee16BitAddress address) /*throws OperationNotSupportedException */ { if (localDevice.XBeeProtocol == XBeeProtocol.DIGI_MESH) { throw new OperationNotSupportedException("DigiMesh protocol does not support 16-bit addressing."); } if (localDevice.XBeeProtocol == XBeeProtocol.DIGI_POINT) { throw new OperationNotSupportedException("Point-to-Multipoint protocol does not support 16-bit addressing."); } if (address == null) { throw new ArgumentNullException("16-bit address cannot be null."); } if (address.Equals(XBee16BitAddress.UNKNOWN_ADDRESS)) { throw new ArgumentNullException("16-bit address cannot be unknown."); } logger.DebugFormat("{0}Getting device '{1}' from network.", localDevice.ToString(), address); // The preference order is: // 1.- Look in the 64-bit map // 2.- Then in the 16-bit map. // This should be maintained in the 'addRemoteDevice' method. RemoteXBeeDevice devInNetwork = null; // Look in the 64-bit map. ICollection <RemoteXBeeDevice> devices = remotesBy64BitAddr.Values; foreach (RemoteXBeeDevice d in devices) { XBee16BitAddress a = Get16BitAddress(d); if (a != null && a.Equals(address)) { devInNetwork = d; break; } } // Look in the 16-bit map. if (devInNetwork == null) { devInNetwork = remotesBy16BitAddr[address]; } return(devInNetwork); }
/** * Discovers and reports all remote XBee devices that match the supplied * identifiers. * * <p>This method blocks until the configured timeout in the device (NT) * expires.</p> * * @param ids List which contains the identifiers of the devices to be * discovered. * * @return A list of the discovered remote XBee devices with the given * identifiers. * * @throws InterfaceNotOpenException if the device is not open. * @throws XBeeException if there is an error discovering the devices. * * @see #discoverDevice(String) */ public List <RemoteXBeeDevice> discoverDevices(IList <string> ids) /*throws XBeeException */ { // Check if the connection is open. if (!xbeeDevice.IsOpen) { throw new InterfaceNotOpenException(); } logger.DebugFormat("{0}ND for all {1} devices.", xbeeDevice.ToString(), ids.ToString()); running = true; discovering = true; performNodeDiscovery(null, null); List <RemoteXBeeDevice> foundDevices = new List <RemoteXBeeDevice>(0); if (deviceList == null) { return(foundDevices); } XBeeNetwork network = xbeeDevice.GetNetwork(); foreach (RemoteXBeeDevice d in deviceList) { string nID = d.NodeID; if (nID == null) { continue; } foreach (string id in ids) { if (nID.Equals(id)) { RemoteXBeeDevice rDevice = network.addRemoteDevice(d); if (rDevice != null && !foundDevices.Contains(rDevice)) { foundDevices.Add(rDevice); } } } } return(foundDevices); }
/** * Adds the given remote device to the network. * * <p>Notice that this operation does not join the remote XBee device to the * network; it just tells the network that it contains that device. However, * the device has only been added to the device list, and may not be * physically in the same network.</p> * * <p>The way of adding a device to the network is based on the 64-bit * address. If it is not configured:</p> * * <ul> * <li>For 802.15.4 and ZigBee devices, it will use the 16-bit address.</li> * <li>For the rest will return {@code false} as the result of the addition.</li> * </ul> * * @param remoteDevice The remote device to be added to the network. * * @return The remote XBee Device instance in the network, {@code null} if * the device could not be successfully added. * * @throws ArgumentNullException if {@code RemoteDevice == null}. * * @see #addRemoteDevices(List) * @see #removeRemoteDevice(RemoteXBeeDevice) * @see RemoteXBeeDevice */ public RemoteXBeeDevice addRemoteDevice(RemoteXBeeDevice remoteDevice) { if (remoteDevice == null) throw new ArgumentNullException("Remote device cannot be null."); logger.DebugFormat("{0}Adding device '{1}' to network.", localDevice.ToString(), remoteDevice.ToString()); RemoteXBeeDevice devInNetwork = null; XBee64BitAddress addr64 = remoteDevice.Get64BitAddress(); XBee16BitAddress addr16 = Get16BitAddress(remoteDevice); // Check if the device has 64-bit address. if (addr64 != null && !addr64.Equals(XBee64BitAddress.UNKNOWN_ADDRESS)) { // The device has 64-bit address, so look in the 64-bit map. if (remotesBy64BitAddr.TryGetValue(addr64, out devInNetwork)) { // The device exists in the 64-bit map, so update the reference and return it. logger.DebugFormat("{0}Existing device '{1}' in network.", localDevice.ToString(), devInNetwork.ToString()); devInNetwork.UpdateDeviceDataFrom(remoteDevice); return devInNetwork; } else { // The device does not exist in the 64-bit map, so check its 16-bit address. if (addr16 != null && !addr16.Equals(XBee16BitAddress.UNKNOWN_ADDRESS)) { // The device has 16-bit address, so look in the 16-bit map. if (remotesBy16BitAddr.TryGetValue(addr16, out devInNetwork)) { // The device exists in the 16-bit map, so remove it and add it to the 64-bit map. logger.DebugFormat("{0}Existing device '{1}' in network.", localDevice.ToString(), devInNetwork.ToString()); remotesBy16BitAddr.TryRemove(addr16, out devInNetwork); devInNetwork.UpdateDeviceDataFrom(remoteDevice); remotesBy64BitAddr.AddOrUpdate(addr64, devInNetwork, (k, v) => devInNetwork); return devInNetwork; } else { // The device does not exist in the 16-bit map, so add it to the 64-bit map. remotesBy64BitAddr.AddOrUpdate(addr64, remoteDevice, (k, v) => remoteDevice); return remoteDevice; } } else { // The device has not 16-bit address, so add it to the 64-bit map. remotesBy64BitAddr.AddOrUpdate(addr64, remoteDevice, (k, v) => remoteDevice); return remoteDevice; } } } // If the device has not 64-bit address, check if it has 16-bit address. if (addr16 != null && !addr16.Equals(XBee16BitAddress.UNKNOWN_ADDRESS)) { // The device has 16-bit address, so look in the 64-bit map. ICollection<RemoteXBeeDevice> devices = remotesBy64BitAddr.Values; foreach (RemoteXBeeDevice d in devices) { XBee16BitAddress a = Get16BitAddress(d); if (a != null && a.Equals(addr16)) { devInNetwork = d; break; } } // Check if the device exists in the 64-bit map. if (devInNetwork != null) { // The device exists in the 64-bit map, so update the reference and return it. logger.DebugFormat("{0}Existing device '{1}' in network.", localDevice.ToString(), devInNetwork.ToString()); devInNetwork.UpdateDeviceDataFrom(remoteDevice); return devInNetwork; } else { // The device does not exist in the 64-bit map, so look in the 16-bit map. devInNetwork = remotesBy16BitAddr[addr16]; if (devInNetwork != null) { // The device exists in the 16-bit map, so update the reference and return it. logger.DebugFormat("{0}Existing device '{1}' in network.", localDevice.ToString(), devInNetwork.ToString()); devInNetwork.UpdateDeviceDataFrom(remoteDevice); return devInNetwork; } else { // The device does not exist in the 16-bit map, so add it. remotesBy16BitAddr.AddOrUpdate(addr16, remoteDevice, (k, v) => remoteDevice); return remoteDevice; } } } // If the device does not contain a valid address, return null. logger.ErrorFormat("{0}Remote device '{1}' cannot be added: 64-bit and 16-bit addresses must be specified.", localDevice.ToString(), remoteDevice.ToString()); return null; }
/** * Reads a new data packet received by this XBee device during the provided * timeout. * * <p>This method blocks until new data is received or the given timeout * expires.</p> * * <p>If the provided remote XBee device is {@code null} the method returns * the first data packet read from any remote device. * <br> * If it the remote device is not {@code null} the method returns the first * data package read from the provided device. * </p> * * @param remoteXBeeDevice The remote device to get a data packet from. * {@code null} to read a data packet sent by any * remote XBee device. * @param timeout The time to wait for a data packet in milliseconds. * * @return An {@code XBeeMessage} received by this device, containing the * data and the source address of the remote node that sent the * data. {@code null} if this device did not receive new data * during {@code timeout} milliseconds, or if any error occurs while * trying to get the source of the message. * * @throws InterfaceNotOpenException if this device connection is not open. * * @see RemoteXBeeDevice * @see com.digi.xbee.api.models.XBeeMessage */ private XBeeMessage ReadDataPacket(RemoteXBeeDevice remoteXBeeDevice, int timeout) { // Check connection. if (!connectionInterface.SerialPort.IsOpen) throw new InterfaceNotOpenException(); XBeePacketsQueue xbeePacketsQueue = dataReader.XBeePacketsQueue; XBeePacket xbeePacket = null; if (remoteXBeeDevice != null) xbeePacket = xbeePacketsQueue.getFirstDataPacketFrom(remoteXBeeDevice, timeout); else xbeePacket = xbeePacketsQueue.getFirstDataPacket(timeout); if (xbeePacket == null) return null; // Obtain the remote device from the packet. RemoteXBeeDevice remoteDevice = null; try { remoteDevice = dataReader.GetRemoteXBeeDeviceFromPacket((XBeeAPIPacket)xbeePacket); // If the provided device is not null, add it to the network, so the // device provided is the one that will remain in the network. if (remoteXBeeDevice != null) remoteDevice = GetNetwork().addRemoteDevice(remoteXBeeDevice); // The packet always contains information of the source so the // remote device should never be null. if (remoteDevice == null) return null; } catch (XBeeException e) { logger.Error(e.Message, e); return null; } // Obtain the data from the packet. byte[] data = null; switch (((XBeeAPIPacket)xbeePacket).FrameType) { case APIFrameType.RECEIVE_PACKET: ReceivePacket receivePacket = (ReceivePacket)xbeePacket; data = receivePacket.RFData; break; case APIFrameType.RX_16: RX16Packet rx16Packet = (RX16Packet)xbeePacket; data = rx16Packet.RFData; break; case APIFrameType.RX_64: RX64Packet rx64Packet = (RX64Packet)xbeePacket; data = rx64Packet.RFData; break; default: return null; } // Create and return the XBee message. return new XBeeMessage(remoteDevice, data, ((XBeeAPIPacket)xbeePacket).IsBroadcast); }
/** * Retrieves the 16-bit address of the given remote device. * * @param device The remote device to get the 16-bit address. * * @return The 16-bit address of the device, {@code null} if it does not * contain a valid one. */ private XBee16BitAddress Get16BitAddress(RemoteXBeeDevice device) { if (device == null) return null; XBee16BitAddress address = null; switch (device.XBeeProtocol) { case XBeeProtocol.RAW_802_15_4: address = ((RemoteRaw802Device)device).Get16BitAddress(); break; case XBeeProtocol.ZIGBEE: address = ((RemoteZigBeeDevice)device).Get16BitAddress(); break; default: // TODO should we allow this operation for general remote devices? address = device.Get16BitAddress(); break; } return address; }
/** * Reads new data received from the given remote XBee device during the * configured received timeout. * * <p>This method blocks until new data from the provided remote XBee * device is received or the configured receive timeout expires.</p> * * <p>The received timeout is configured using the {@code setReceiveTimeout} * method and can be consulted with {@code getReceiveTimeout} method.</p> * * <p>For non-blocking operations, register a {@code IDataReceiveListener} * using the method {@link #addDataListener(IDataReceiveListener)}.</p> * * @param remoteXBeeDevice The remote device to read data from. * * @return An {@code XBeeMessage} object containing the data and the source * address of the remote node that sent the data. {@code null} if * this device did not receive new data from the provided remote * XBee device during the configured receive timeout. * * @throws InterfaceNotOpenException if this device connection is not open. * @throws ArgumentNullException if {@code remoteXBeeDevice == null}. * * @see #readDataFrom(RemoteXBeeDevice, int) * @see #getReceiveTimeout() * @see #setReceiveTimeout(int) * @see #readData() * @see #readData(int) * @see RemoteXBeeDevice * @see com.digi.xbee.api.models.XBeeMessage */ public XBeeMessage readDataFrom(RemoteXBeeDevice remoteXBeeDevice) { if (remoteXBeeDevice == null) throw new ArgumentNullException("Remote XBee device cannot be null."); return ReadDataPacket(remoteXBeeDevice, TIMEOUT_READ_PACKET); }
/** * Adds the given remote device to the network. * * <p>Notice that this operation does not join the remote XBee device to the * network; it just tells the network that it contains that device. However, * the device has only been added to the device list, and may not be * physically in the same network.</p> * * <p>The way of adding a device to the network is based on the 64-bit * address. If it is not configured:</p> * * <ul> * <li>For 802.15.4 and ZigBee devices, it will use the 16-bit address.</li> * <li>For the rest will return {@code false} as the result of the addition.</li> * </ul> * * @param remoteDevice The remote device to be added to the network. * * @return The remote XBee Device instance in the network, {@code null} if * the device could not be successfully added. * * @throws ArgumentNullException if {@code RemoteDevice == null}. * * @see #addRemoteDevices(List) * @see #removeRemoteDevice(RemoteXBeeDevice) * @see RemoteXBeeDevice */ public RemoteXBeeDevice addRemoteDevice(RemoteXBeeDevice remoteDevice) { if (remoteDevice == null) { throw new ArgumentNullException("Remote device cannot be null."); } logger.DebugFormat("{0}Adding device '{1}' to network.", localDevice.ToString(), remoteDevice.ToString()); RemoteXBeeDevice devInNetwork = null; XBee64BitAddress addr64 = remoteDevice.Get64BitAddress(); XBee16BitAddress addr16 = Get16BitAddress(remoteDevice); // Check if the device has 64-bit address. if (addr64 != null && !addr64.Equals(XBee64BitAddress.UNKNOWN_ADDRESS)) { // The device has 64-bit address, so look in the 64-bit map. if (remotesBy64BitAddr.TryGetValue(addr64, out devInNetwork)) { // The device exists in the 64-bit map, so update the reference and return it. logger.DebugFormat("{0}Existing device '{1}' in network.", localDevice.ToString(), devInNetwork.ToString()); devInNetwork.UpdateDeviceDataFrom(remoteDevice); return(devInNetwork); } else { // The device does not exist in the 64-bit map, so check its 16-bit address. if (addr16 != null && !addr16.Equals(XBee16BitAddress.UNKNOWN_ADDRESS)) { // The device has 16-bit address, so look in the 16-bit map. if (remotesBy16BitAddr.TryGetValue(addr16, out devInNetwork)) { // The device exists in the 16-bit map, so remove it and add it to the 64-bit map. logger.DebugFormat("{0}Existing device '{1}' in network.", localDevice.ToString(), devInNetwork.ToString()); remotesBy16BitAddr.TryRemove(addr16, out devInNetwork); devInNetwork.UpdateDeviceDataFrom(remoteDevice); remotesBy64BitAddr.AddOrUpdate(addr64, devInNetwork, (k, v) => devInNetwork); return(devInNetwork); } else { // The device does not exist in the 16-bit map, so add it to the 64-bit map. remotesBy64BitAddr.AddOrUpdate(addr64, remoteDevice, (k, v) => remoteDevice); return(remoteDevice); } } else { // The device has not 16-bit address, so add it to the 64-bit map. remotesBy64BitAddr.AddOrUpdate(addr64, remoteDevice, (k, v) => remoteDevice); return(remoteDevice); } } } // If the device has not 64-bit address, check if it has 16-bit address. if (addr16 != null && !addr16.Equals(XBee16BitAddress.UNKNOWN_ADDRESS)) { // The device has 16-bit address, so look in the 64-bit map. ICollection <RemoteXBeeDevice> devices = remotesBy64BitAddr.Values; foreach (RemoteXBeeDevice d in devices) { XBee16BitAddress a = Get16BitAddress(d); if (a != null && a.Equals(addr16)) { devInNetwork = d; break; } } // Check if the device exists in the 64-bit map. if (devInNetwork != null) { // The device exists in the 64-bit map, so update the reference and return it. logger.DebugFormat("{0}Existing device '{1}' in network.", localDevice.ToString(), devInNetwork.ToString()); devInNetwork.UpdateDeviceDataFrom(remoteDevice); return(devInNetwork); } else { // The device does not exist in the 64-bit map, so look in the 16-bit map. devInNetwork = remotesBy16BitAddr[addr16]; if (devInNetwork != null) { // The device exists in the 16-bit map, so update the reference and return it. logger.DebugFormat("{0}Existing device '{1}' in network.", localDevice.ToString(), devInNetwork.ToString()); devInNetwork.UpdateDeviceDataFrom(remoteDevice); return(devInNetwork); } else { // The device does not exist in the 16-bit map, so add it. remotesBy16BitAddr.AddOrUpdate(addr16, remoteDevice, (k, v) => remoteDevice); return(remoteDevice); } } } // If the device does not contain a valid address, return null. logger.ErrorFormat("{0}Remote device '{1}' cannot be added: 64-bit and 16-bit addresses must be specified.", localDevice.ToString(), remoteDevice.ToString()); return(null); }
/*throws TimeoutException, XBeeException */ /** * Sends the provided data to the given XBee device choosing the optimal * send method depending on the protocol of the local XBee device. * * <p>This method blocks till a success or error response arrives or the * configured receive timeout expires.</p> * * <p>The received timeout is configured using the {@code setReceiveTimeout} * method and can be consulted with {@code getReceiveTimeout} method.</p> * * <p>For non-blocking operations use the method * {@link #sendDataAsync(RemoteXBeeDevice, byte[])}.</p> * * @param xbeeDevice The XBee device of the network that will receive the * data. * @param data Byte array containing the data to be sent. * * @throws InterfaceNotOpenException if this device connection is not open. * @throws ArgumentNullException if {@code xbeeDevice == null} or * if {@code data == null}. * @throws TimeoutException if there is a timeout sending the data. * @throws XBeeException if there is any other XBee related exception. * * @see #getReceiveTimeout() * @see #setReceiveTimeout(int) * @see #sendDataAsync(RemoteXBeeDevice, byte[]) */ public void SendData(RemoteXBeeDevice xbeeDevice, byte[] data) { if (xbeeDevice == null) throw new ArgumentNullException("Remote XBee device cannot be null"); switch (XBeeProtocol) { case XBeeProtocol.ZIGBEE: case XBeeProtocol.DIGI_POINT: if (xbeeDevice.Get64BitAddress() != null && xbeeDevice.Get16BitAddress() != null) SendData(xbeeDevice.Get64BitAddress(), xbeeDevice.Get16BitAddress(), data); else SendData(xbeeDevice.Get64BitAddress(), data); break; case XBeeProtocol.RAW_802_15_4: if (this is Raw802Device) { if (xbeeDevice.Get64BitAddress() != null) ((Raw802Device)this).SendData(xbeeDevice.Get64BitAddress(), data); else ((Raw802Device)this).SendData(xbeeDevice.Get16BitAddress(), data); } else SendData(xbeeDevice.Get64BitAddress(), data); break; case XBeeProtocol.DIGI_MESH: default: SendData(xbeeDevice.Get64BitAddress(), data); break; } }
/** * Reads new data received from the given remote XBee device during the * provided timeout. * * <p>This method blocks until new data from the provided remote XBee * device is received or the given timeout expires.</p> * * <p>For non-blocking operations, register a {@code IDataReceiveListener} * using the method {@link #addDataListener(IDataReceiveListener)}.</p> * * @param remoteXBeeDevice The remote device to read data from. * @param timeout The time to wait for new data in milliseconds. * * @return An {@code XBeeMessage} object containing the data and the source * address of the remote node that sent the data. {@code null} if * this device did not receive new data from the provided remote * XBee device during {@code timeout} milliseconds. * * @throws ArgumentException if {@code timeout < 0}. * @throws InterfaceNotOpenException if this device connection is not open. * @throws ArgumentNullException if {@code remoteXBeeDevice == null}. * * @see #readDataFrom(RemoteXBeeDevice) * @see #getReceiveTimeout() * @see #setReceiveTimeout(int) * @see #readData() * @see #readData(int) * @see RemoteXBeeDevice * @see com.digi.xbee.api.models.XBeeMessage */ public XBeeMessage readDataFrom(RemoteXBeeDevice remoteXBeeDevice, int timeout) { if (remoteXBeeDevice == null) throw new ArgumentNullException("Remote XBee device cannot be null."); if (timeout < 0) throw new ArgumentException("Read timeout must be 0 or greater."); return ReadDataPacket(remoteXBeeDevice, timeout); }
/** * Parses the given node discovery API data to create and return a remote * XBee Device. * * @param data Byte array with the data to parse. * @param localDevice The local device that received the remote XBee data. * * @return Discovered XBee device. */ private async Task <RemoteXBeeDevice> ParseDiscoveryAPIData(byte[] data, XBeeDevice localDevice) { if (data == null) { return(null); } RemoteXBeeDevice device = null; XBee16BitAddress addr16 = null; XBee64BitAddress addr64 = null; String id = null; // TODO role of the device: coordinator, router, end device or unknown. //XBeeDeviceType role = XBeeDeviceType.UNKNOWN; int signalStrength = 0; byte[] profileID = null; byte[] manufacturerID = null; using (var inputStream = new MemoryStream(data)) { // Read 16 bit address. addr16 = new XBee16BitAddress(await ByteUtils.ReadBytes(2, inputStream)); // Read 64 bit address. addr64 = new XBee64BitAddress(await ByteUtils.ReadBytes(8, inputStream)); switch (localDevice.XBeeProtocol) { case XBeeProtocol.ZIGBEE: case XBeeProtocol.DIGI_MESH: case XBeeProtocol.ZNET: case XBeeProtocol.DIGI_POINT: case XBeeProtocol.XLR: // TODO [XLR_DM] The next version of the XLR will add DigiMesh support. // For the moment only point-to-multipoint is supported in this kind of devices. case XBeeProtocol.XLR_DM: // Read node identifier. id = ByteUtils.ReadString(inputStream); // Read parent address. XBee16BitAddress parentAddress = new XBee16BitAddress(await ByteUtils.ReadBytes(2, inputStream)); // TODO Read device type. //role = XBeeDeviceType.get(inputStream.read()); // Consume status byte, it is not used yet. await ByteUtils.ReadBytes(1, inputStream); // Read profile ID. profileID = await ByteUtils.ReadBytes(2, inputStream); // Read manufacturer ID. manufacturerID = await ByteUtils.ReadBytes(2, inputStream); logger.DebugFormat("{0}Discovered {1} device: 16-bit[{2}], 64-bit[{3}], id[{4}], parent[{5}], profile[{6}], manufacturer[{7}].", xbeeDevice.ToString(), localDevice.XBeeProtocol.GetDescription(), addr16, addr64, id, parentAddress, HexUtils.ByteArrayToHexString(profileID), HexUtils.ByteArrayToHexString(manufacturerID)); break; case XBeeProtocol.RAW_802_15_4: // Read strength signal byte. signalStrength = inputStream.ReadByte(); // Read node identifier. id = ByteUtils.ReadString(inputStream); logger.DebugFormat("{0}Discovered {1} device: 16-bit[{2}], 64-bit[{3}], id[{4}], rssi[{5}].", xbeeDevice.ToString(), localDevice.XBeeProtocol.GetDescription(), addr16, addr64, id, signalStrength); break; case XBeeProtocol.UNKNOWN: default: logger.DebugFormat("{0}Discovered {1} device: 16-bit[{2}], 64-bit[{3}].", xbeeDevice.ToString(), localDevice.XBeeProtocol.GetDescription(), addr16, addr64); break; } // Create device and fill with parameters. switch (localDevice.XBeeProtocol) { case XBeeProtocol.ZIGBEE: device = new RemoteZigBeeDevice(localDevice, addr64, addr16, id /*, role*/); // TODO profileID and manufacturerID break; case XBeeProtocol.DIGI_MESH: device = new RemoteDigiMeshDevice(localDevice, addr64, id /*, role*/); // TODO profileID and manufacturerID break; case XBeeProtocol.DIGI_POINT: device = new RemoteDigiPointDevice(localDevice, addr64, id /*, role*/); // TODO profileID and manufacturerID break; case XBeeProtocol.RAW_802_15_4: device = new RemoteRaw802Device(localDevice, addr64, addr16, id /*, role*/); // TODO signalStrength break; default: device = new RemoteXBeeDevice(localDevice, addr64, addr16, id /*, role*/); break; } } return(device); }
/*throws XBeeException */ /** * Sends the provided data to the provided XBee device asynchronously. * * <p>Asynchronous transmissions do not wait for answer from the remote * device or for transmit status packet.</p> * * @param xbeeDevice The XBee device of the network that will receive the * data. * @param data Byte array containing the data to be sent. * * @throws InterfaceNotOpenException if this device connection is not open. * @throws ArgumentNullException if {@code xbeeDevice == null} or * if {@code data == null}. * @throws XBeeException if there is any XBee related exception. * * @see #sendData(RemoteXBeeDevice, byte[]) * @see RemoteXBeeDevice */ public void SendDataAsync(RemoteXBeeDevice xbeeDevice, byte[] data) { if (xbeeDevice == null) throw new ArgumentNullException("Remote XBee device cannot be null"); SendDataAsync(xbeeDevice.Get64BitAddress(), data); }
/** * Removes the given remote XBee device from the network. * * <p>Notice that this operation does not remove the remote XBee device * from the actual XBee network; it just tells the network object that it * will no longer contain that device. However, next time a discovery is * performed, it could be added again automatically.</p> * * <p>This method will check for a device that matches the 64-bit address * of the provided one, if found, that device will be removed from the * corresponding list. In case the 64-bit address is not defined, it will * use the 16-bit address for DigiMesh and ZigBee devices.</p> * * @param remoteDevice The remote device to be removed from the network. * * @throws ArgumentNullException if {@code RemoteDevice == null}. * * @see #addRemoteDevice(RemoteXBeeDevice) * @see #clearDeviceList() * @see RemoteXBeeDevice */ public void removeRemoteDevice(RemoteXBeeDevice remoteDevice) { if (remoteDevice == null) throw new ArgumentNullException("Remote device cannot be null."); RemoteXBeeDevice devInNetwork = null; // Look in the 64-bit map. XBee64BitAddress addr64 = remoteDevice.Get64BitAddress(); if (addr64 != null && !addr64.Equals(XBee64BitAddress.UNKNOWN_ADDRESS)) { if (remotesBy64BitAddr.TryRemove(addr64, out devInNetwork)) return; } // If not found, look in the 16-bit map. XBee16BitAddress addr16 = Get16BitAddress(remoteDevice); if (addr16 != null && !addr16.Equals(XBee16BitAddress.UNKNOWN_ADDRESS)) { // The preference order is: // 1.- Look in the 64-bit map // 2.- Then in the 16-bit map. // This should be maintained in the 'getDeviceBy16BitAddress' method. // Look for the 16-bit address in the 64-bit map. ICollection<RemoteXBeeDevice> devices = remotesBy64BitAddr.Values; foreach (RemoteXBeeDevice d in devices) { XBee16BitAddress a = Get16BitAddress(d); if (a != null && a.Equals(addr16)) { RemoteXBeeDevice r; remotesBy64BitAddr.TryRemove(d.Get64BitAddress(), out r); return; } } // If not found, look for the 16-bit address in the 16-bit map. // Remove the device. if (remotesBy16BitAddr.TryRemove(addr16, out devInNetwork)) return; } // If the device does not contain a valid address log an error. if ((addr64 == null || addr64.Equals(XBee64BitAddress.UNKNOWN_ADDRESS)) && (addr16 == null || addr16.Equals(XBee16BitAddress.UNKNOWN_ADDRESS))) logger.ErrorFormat("{0}Remote device '{1}' cannot be removed: 64-bit and 16-bit addresses must be specified.", localDevice.ToString(), remoteDevice.ToString()); }
/** * Notifies the given discovery listeners that a device was discovered. * * @param listeners The discovery listeners to be notified. * @param device The remote device discovered. */ private void notifyDeviceDiscovered(IList<IDiscoveryListener> listeners, RemoteXBeeDevice device) { if (listeners == null) { lock (deviceList) { deviceList.Add(device); } return; } XBeeNetwork network = xbeeDevice.GetNetwork(); RemoteXBeeDevice addedDev = network.addRemoteDevice(device); if (addedDev != null) { foreach (IDiscoveryListener listener in listeners) listener.DeviceDiscovered(addedDev); } else { String error = "Error adding device '" + device + "' to the network."; notifyDiscoveryError(listeners, error); } }
/** * Parses the given node discovery API data to create and return a remote * XBee Device. * * @param data Byte array with the data to parse. * @param localDevice The local device that received the remote XBee data. * * @return Discovered XBee device. */ private async Task<RemoteXBeeDevice> ParseDiscoveryAPIData(byte[] data, XBeeDevice localDevice) { if (data == null) return null; RemoteXBeeDevice device = null; XBee16BitAddress addr16 = null; XBee64BitAddress addr64 = null; String id = null; // TODO role of the device: coordinator, router, end device or unknown. //XBeeDeviceType role = XBeeDeviceType.UNKNOWN; int signalStrength = 0; byte[] profileID = null; byte[] manufacturerID = null; using (var inputStream = new MemoryStream(data)) { // Read 16 bit address. addr16 = new XBee16BitAddress(await ByteUtils.ReadBytes(2, inputStream)); // Read 64 bit address. addr64 = new XBee64BitAddress(await ByteUtils.ReadBytes(8, inputStream)); switch (localDevice.XBeeProtocol) { case XBeeProtocol.ZIGBEE: case XBeeProtocol.DIGI_MESH: case XBeeProtocol.ZNET: case XBeeProtocol.DIGI_POINT: case XBeeProtocol.XLR: // TODO [XLR_DM] The next version of the XLR will add DigiMesh support. // For the moment only point-to-multipoint is supported in this kind of devices. case XBeeProtocol.XLR_DM: // Read node identifier. id = ByteUtils.ReadString(inputStream); // Read parent address. XBee16BitAddress parentAddress = new XBee16BitAddress(await ByteUtils.ReadBytes(2, inputStream)); // TODO Read device type. //role = XBeeDeviceType.get(inputStream.read()); // Consume status byte, it is not used yet. await ByteUtils.ReadBytes(1, inputStream); // Read profile ID. profileID = await ByteUtils.ReadBytes(2, inputStream); // Read manufacturer ID. manufacturerID = await ByteUtils.ReadBytes(2, inputStream); logger.DebugFormat("{0}Discovered {1} device: 16-bit[{2}], 64-bit[{3}], id[{4}], parent[{5}], profile[{6}], manufacturer[{7}].", xbeeDevice.ToString(), localDevice.XBeeProtocol.GetDescription(), addr16, addr64, id, parentAddress, HexUtils.ByteArrayToHexString(profileID), HexUtils.ByteArrayToHexString(manufacturerID)); break; case XBeeProtocol.RAW_802_15_4: // Read strength signal byte. signalStrength = inputStream.ReadByte(); // Read node identifier. id = ByteUtils.ReadString(inputStream); logger.DebugFormat("{0}Discovered {1} device: 16-bit[{2}], 64-bit[{3}], id[{4}], rssi[{5}].", xbeeDevice.ToString(), localDevice.XBeeProtocol.GetDescription(), addr16, addr64, id, signalStrength); break; case XBeeProtocol.UNKNOWN: default: logger.DebugFormat("{0}Discovered {1} device: 16-bit[{2}], 64-bit[{3}].", xbeeDevice.ToString(), localDevice.XBeeProtocol.GetDescription(), addr16, addr64); break; } // Create device and fill with parameters. switch (localDevice.XBeeProtocol) { case XBeeProtocol.ZIGBEE: device = new RemoteZigBeeDevice(localDevice, addr64, addr16, id/*, role*/); // TODO profileID and manufacturerID break; case XBeeProtocol.DIGI_MESH: device = new RemoteDigiMeshDevice(localDevice, addr64, id/*, role*/); // TODO profileID and manufacturerID break; case XBeeProtocol.DIGI_POINT: device = new RemoteDigiPointDevice(localDevice, addr64, id/*, role*/); // TODO profileID and manufacturerID break; case XBeeProtocol.RAW_802_15_4: device = new RemoteRaw802Device(localDevice, addr64, addr16, id/*, role*/); // TODO signalStrength break; default: device = new RemoteXBeeDevice(localDevice, addr64, addr16, id/*, role*/); break; } } return device; }