/** * 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); }
/** * 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); }
/// <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); }
/*throws OperationNotSupportedException */ /** * 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) { 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; }