Example #1
0
        /// <summary>
        /// Discovers and reports the first remote XBee device that matches the supplied identifier.
        /// </summary>
        /// <remarks>This method blocks until the configured timeout in the device (NT) expires.</remarks>
        /// <param name="id">The identifier of the device to be discovered.</param>
        /// <returns>The discovered remote XBee device with the given identifier, <c>null</c> if the
        /// timeout expires and the device was not found.</returns>
        /// <exception cref="InterfaceNotOpenException">If this device connection is not open.</exception>
        /// <exception cref="XBeeException">If there is an error discovering the device.</exception>
        /// <seealso cref="DiscoverDevices(IList{string})"/>
        public RemoteXBeeDevice DiscoverDevice(string id)
        {
            // Check if the connection is open.
            if (!localDevice.IsOpen)
            {
                throw new InterfaceNotOpenException();
            }

            logger.DebugFormat("{0}ND for {1} device.", xbeeDevice.ToString(), id);

            IsRunning   = true;
            discovering = true;

            PerformNodeDiscovery(id);

            XBeeNetwork      network = localDevice.GetNetwork();
            RemoteXBeeDevice rDevice = null;

            if (deviceList != null && deviceList.Count > 0)
            {
                rDevice = deviceList[0];
                if (rDevice != null)
                {
                    rDevice = network.AddRemoteDevice(rDevice);
                }
            }

            return(rDevice);
        }
        /// <summary>
        /// Returns the 16-bit address of the given remote device.
        /// </summary>
        /// <param name="device">The remote device to get its 16-bit address.</param>
        /// <returns>The 16-bit address of the device, <c>null</c> if it does not contain a valid one.</returns>
        /// <seealso cref="RemoteXBeeDevice"/>
        /// <seealso cref="XBee16BitAddress"/>
        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).XBee16BitAddr;
                break;

            case XBeeProtocol.ZIGBEE:
                address = ((RemoteZigBeeDevice)device).XBee16BitAddr;
                break;

            default:
                // TODO should we allow this operation for general remote devices?
                address = device.XBee16BitAddr;
                break;
            }

            return(address);
        }
        /// <summary>
        /// Adds the given list of remote devices to the network.
        /// </summary>
        /// <remarks>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.
        ///
        /// The way of adding a device to the network is based on the 64-bit address. If it is not
        /// configured:
        /// <list type="bullet">
        /// <item><description>For 802.15.4 and ZigBee devices, the 16-bit address will be used instead.</description></item>
        /// <item><description>For the rest will return <c>true</c> as the result of the addition.</description></item>
        /// </list></remarks>
        /// <param name="list">The list of remote devices to be added to the network.</param>
        /// <returns>A list with the successfully added devices to the network.</returns>
        /// <exception cref="ArgumentNullException">If <c><paramref name="list"/> == null</c>.</exception>
        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);
        }
        /// <summary>
        /// Removes the given remote XBee device from the network.
        /// </summary>
        /// <remarks>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.
        ///
        /// 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.</remarks>
        /// <param name="remoteDevice">The remote device to be removed from the network.</param>
        /// <exception cref="ArgumentNullException">If <c><paramref name="remoteDevice"/> == null</c>.</exception>
        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.XBee64BitAddr;

            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))
                    {
                        remotesBy64BitAddr.TryRemove(d.XBee64BitAddr, out RemoteXBeeDevice 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());
            }
        }
Example #5
0
        /// <summary>
        /// Notifies the given discovery listeners that a device was discovered.
        /// </summary>
        /// <param name="remoteDevice">The remote device discovered.</param>
        private void NotifyDeviceDiscovered(RemoteXBeeDevice remoteDevice)
        {
            logger.DebugFormat("{0}Device discovered: {1}.", xbeeDevice, remoteDevice);

            if (DeviceDiscovered == null)
            {
                lock (deviceList)
                {
                    if (deviceList != null)
                    {
                        if (!deviceList.Any(d => d.XBee64BitAddr == remoteDevice.XBee64BitAddr))
                        {
                            deviceList.Add(remoteDevice);
                        }
                    }
                }
                return;
            }

            XBeeNetwork      network  = localDevice.GetNetwork();
            RemoteXBeeDevice addedDev = network.AddRemoteDevice(remoteDevice);

            if (addedDev != null)
            {
                try
                {
                    lock (DeviceDiscovered)
                    {
                        var handler = DeviceDiscovered;
                        if (handler != null)
                        {
                            var args = new DeviceDiscoveredEventArgs(addedDev);

                            handler.GetInvocationList().AsParallel().ForAll((action) =>
                            {
                                action.DynamicInvoke(this, args);
                            });
                        }
                    }
                }
                catch (Exception e)
                {
                    logger.Error(e.Message, e);
                }
            }
            else
            {
                string error = "Error adding device '" + remoteDevice + "' to the network.";
                NotifyDiscoveryError(error);
            }
        }
        /// <summary>
        /// Returns the remote device already contained in the network whose 16-bit address matches the
        /// given one.
        /// </summary>
        /// <remarks>Note that this method does not perform a discovery, only returns the device that has
        /// been previously discovered.</remarks>
        /// <param name="address">The 16-bit address of the device to be retrieved.</param>
        /// <returns>The remote device in the network or <c>null</c> if it is not found.</returns>
        /// <exception cref="ArgumentException">If <paramref name="address"/> is
        /// <see cref="XBee16BitAddress.UNKNOWN_ADDRESS"/>.</exception>
        /// <exception cref="ArgumentNullException">If <c><paramref name="address"/> == null</c>.</exception>
        /// <exception cref="OperationNotSupportedException">If the protocol of <c>localDevice</c> is
        /// <see cref="XBeeProtocol.DIGI_MESH"/> or if it is <see cref="XBeeProtocol.DIGI_POINT"/></exception>
        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 ArgumentException("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)
            {
                remotesBy16BitAddr.TryGetValue(address, out devInNetwork);
            }

            return(devInNetwork);
        }
Example #7
0
        /// <summary>
        /// Discovers and reports all remote XBee devices that match the supplied identifiers.
        /// </summary>
        /// <remarks>This method blocks until the configured timeout in the device (NT) expires.</remarks>
        /// <param name="ids">List which contains the identifiers of the devices to be discovered.</param>
        /// <returns>A list of the discovered remote XBee devices with the given identifiers.</returns>
        /// <exception cref="InterfaceNotOpenException">If this device connection is not open.</exception>
        /// <exception cref="XBeeException">If there is an error discovering the device.</exception>
        /// <seealso cref="DiscoverDevice(string)"/>
        public List <RemoteXBeeDevice> DiscoverDevices(IList <string> ids)
        {
            // Check if the connection is open.
            if (!localDevice.IsOpen)
            {
                throw new InterfaceNotOpenException();
            }

            logger.DebugFormat("{0} ND for all '[{1}]' devices.", xbeeDevice.ToString(), string.Join(", ", ids));

            IsRunning   = true;
            discovering = true;

            PerformNodeDiscovery(null);

            List <RemoteXBeeDevice> foundDevices = new List <RemoteXBeeDevice>(0);

            if (deviceList == null)
            {
                return(foundDevices);
            }

            XBeeNetwork network = localDevice.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);
        }
Example #8
0
        /// <summary>
        /// Callback called after a discovery packet is received and the corresponding Packet Received event
        /// has been fired.
        /// </summary>
        /// <param name="sender">The object that sent the event.</param>
        /// <param name="e">The Packet Received event.</param>
        /// <param name="id">The ID of the device to find.</param>
        public async void DiscoveryPacketReceived(object sender, PacketReceivedEventArgs e, string id)
        {
            if (!discovering)
            {
                return;
            }
            RemoteXBeeDevice rdevice = null;

            byte[] commandValue = GetRemoteDeviceData((XBeeAPIPacket)e.ReceivedPacket);

            rdevice = await ParseDiscoveryAPIData(commandValue, localDevice);

            // If a device with a specific id is being searched and it was
            // already found, return it.
            if (id != null)
            {
                if (rdevice != null && id.Equals(rdevice.NodeID))
                {
                    lock (deviceList)
                    {
                        if (deviceList != null)
                        {
                            if (!deviceList.Any(d => d.XBee64BitAddr == rdevice.XBee64BitAddr))
                            {
                                deviceList.Add(rdevice);
                            }
                        }
                    }
                    // If the local device is 802.15.4 wait until the 'end' command is received.
                    if (xbeeDevice.XBeeProtocol != XBeeProtocol.RAW_802_15_4)
                    {
                        discovering = false;
                    }
                }
            }
            else if (rdevice != null)
            {
                NotifyDeviceDiscovered(rdevice);
            }
        }
 /// <summary>
 /// Sends the provided data in application layer mode to the provided XBee device choosing the optimal
 /// send method depending on the protocol of the local XBee device. Application layer mode means that you
 /// need to specify the application layer fields to be sent with the data.
 /// </summary>
 /// <remarks>This method blocks till a success or error response arrives or the configured receive timeout
 /// expires.</remarks>
 /// <param name="remoteXBeeDevice">The XBee device of the network that will receive the data.</param>
 /// <param name="sourceEndpoint">Source endpoint for the transmission.</param>
 /// <param name="destEndpoint">Destination endpoint for the transmission.</param>
 /// <param name="clusterID">Cluster ID used in the transmission.</param>
 /// <param name="profileID">Profile ID used in the transmission.</param>
 /// <param name="data">Byte array containing the data to be sent.</param>
 /// <exception cref="ArgumentNullException">If <c><paramref name="remoteXBeeDevice"/> == null</c>
 /// or if <c><paramref name="data"/> == null</c>.</exception>
 /// <exception cref="ArgumentException">If <c>clusterID.Length != 2</c>
 /// or if <c>profileID.Length != 2</c>.</exception>
 /// <exception cref="InterfaceNotOpenException">If the interface is not open.</exception>
 /// <exception cref="TimeoutException">If there is a timeout sending the given packet synchronously.</exception>
 /// <exception cref="TransmitException">If the transmit status generated when sending the packet is not
 /// an instance of <see cref="TransmitStatusPacket"/>
 /// or if it is not an instance of <see cref="Packet.Raw.TXStatusPacket"/>
 /// or if when it is correct, its status is different from <see cref="XBeeTransmitStatus.SUCCESS"/>.</exception>
 /// <exception cref="XBeeException">If there is any other XBee related error.</exception>
 /// <seealso cref="RemoteXBeeDevice"/>
 /// <seealso cref="AbstractXBeeDevice.SendExplicitData(RemoteXBeeDevice, byte, byte, byte[], byte[], byte[])"/>
 public new void SendExplicitData(RemoteXBeeDevice remoteXBeeDevice, byte sourceEndpoint, byte destEndpoint,
                                  byte[] clusterID, byte[] profileID, byte[] data)
 {
     base.SendExplicitData(remoteXBeeDevice, sourceEndpoint, destEndpoint, clusterID, profileID, data);
 }
 /// <summary>
 /// Reads new explicit data received from the given remote XBee device during the provided timeout.
 /// </summary>
 /// <remarks>
 /// This method blocks until new explicit data from the provided remote XBee device is received
 /// or the given timeout expires.
 ///
 /// For non-blocking operations, register an event handler to <see cref="AbstractXBeeDevice.ExplicitDataReceived"/>.
 /// </remarks>
 /// <param name="remoteXBeeDevice">The remote device to read explicit data from.</param>
 /// <param name="timeout">The time to wait for new explicit data in milliseconds.</param>
 /// <returns>An <see cref="ExplicitXBeeMessage"/> object containing the explicit data, the source
 /// address of the remote node that sent the data and other values related to the transmission.
 /// <c>null</c> if this device did not receive new data from the provided remote XBee device
 /// during <paramref name="timeout"/> milliseconds.</returns>
 /// <exception cref="ArgumentException">If <c><paramref name="timeout"/> <![CDATA[<]]> 0</c>.</exception>
 /// <exception cref="ArgumentNullException">If <c><paramref name="remoteXBeeDevice"/> == null</c>.</exception>
 /// <exception cref="InterfaceNotOpenException">If the interface is not open.</exception>
 /// <seealso cref="ExplicitXBeeMessage"/>
 /// <seealso cref="RemoteXBeeDevice"/>
 /// <seealso cref="AbstractXBeeDevice.ReadExplicitDataFrom(RemoteXBeeDevice, int)"/>
 public new ExplicitXBeeMessage ReadExplicitDataFrom(RemoteXBeeDevice remoteXBeeDevice, int timeout)
 {
     return(base.ReadExplicitDataFrom(remoteXBeeDevice, timeout));
 }
 /// <summary>
 /// Reads new explicit data received from the given remote XBee device during the configured
 /// receive timeout.
 /// </summary>
 /// <remarks>
 /// This method blocks until new explicit data from the provided remote XBee device is received
 /// or the configured receive timeout expires.
 ///
 /// For non-blocking operations, register an event handler to <see cref="AbstractXBeeDevice.ExplicitDataReceived"/>.
 /// </remarks>
 /// <param name="remoteXBeeDevice">The remote device to read explicit data from.</param>
 /// <returns>An <see cref="ExplicitXBeeMessage"/> object containing the explicit data, the source
 /// address of the remote node that sent the data and other values related to the transmission.
 /// <c>null</c> if this device did not receive new explicit data from the provided remote XBee
 /// device during the configured receive timeout.</returns>
 /// <exception cref="ArgumentNullException">If <c><paramref name="remoteXBeeDevice"/> == null</c>.</exception>
 /// <exception cref="InterfaceNotOpenException">If the interface is not open.</exception>
 /// <seealso cref="ExplicitXBeeMessage"/>
 /// <seealso cref="RemoteXBeeDevice"/>
 /// <seealso cref="AbstractXBeeDevice.ReadExplicitDataFrom(RemoteXBeeDevice)"/>
 public new ExplicitXBeeMessage ReadExplicitDataFrom(RemoteXBeeDevice remoteXBeeDevice)
 {
     return(base.ReadExplicitDataFrom(remoteXBeeDevice));
 }
Example #12
0
 /// <summary>
 /// Reads new data received from the given remote XBee device during the configured received
 /// timeout.
 /// </summary>
 /// <remarks>This method blocks until new data is received or the provided timeout expires.
 ///
 /// The receive timeout can be consulted/configured using the <see cref="ReceiveTimeout"/>
 /// property.</remarks>
 /// <param name="remoteXBeeDevice">The remote device to read data from.</param>
 /// <returns>An <see cref="XBeeMessage"/> object containing the data and the source address of
 /// the remote node that sent the data. <c>null</c> if this did not receive new data during
 /// the configured timeout.</returns>
 /// <exception cref="ArgumentNullException">If <paramref name="remoteXBeeDevice"/> is <c>null</c>.</exception>
 /// <exception cref="InterfaceNotOpenException">If this device connection is not open.</exception>
 /// <seealso cref="ReceiveTimeout"/>
 /// <seealso cref="ReadData()"/>
 /// <seealso cref="ReadData(int)"/>
 /// <seealso cref="ReadDataFrom(RemoteXBeeDevice, int)"/>
 /// <seealso cref="RemoteXBeeDevice"/>
 /// <seealso cref="XBeeMessage"/>
 public new XBeeMessage ReadDataFrom(RemoteXBeeDevice remoteXBeeDevice)
 {
     return(base.ReadDataFrom(remoteXBeeDevice));
 }
Example #13
0
 /// <summary>
 /// Sends the provided data to the given XBee device choosing the optimal send method depending
 /// on the protocol of the local XBee device.
 /// </summary>
 /// <remarks>This method blocks till a success or error response arrives or the configured receive
 /// timeout expires.
 ///
 /// The receive timeout can be consulted/configured using the <see cref="ReceiveTimeout"/> property.
 ///
 /// For non-blocking operations use the method <see cref="SendData(RemoteXBeeDevice, byte[])"/>.</remarks>
 /// <param name="xbeeDevice">The XBee device of the network that will receive the data.</param>
 /// <param name="data">Byte array containing the data to be sent.</param>
 /// <exception cref="ArgumentNullException">If <c><paramref name="xbeeDevice"/> == null</c>
 /// or if <c><paramref name="data"/> == null</c>.</exception>
 /// <exception cref="InterfaceNotOpenException">If this device connection is not open.</exception>
 /// <exception cref="OperationNotSupportedException">If the sender device is remote.</exception>
 /// <exception cref="TimeoutException">If there is a timeout sending the data.</exception>
 /// <exception cref="TransmitException">If the transmit status generated when sending the packet is not
 /// an instance of <see cref="Packet.Common.TransmitStatusPacket"/>
 /// or if it is not an instance of <see cref="Packet.Raw.TXStatusPacket"/>
 /// or if when it is correct, its status is different from <see cref="XBeeTransmitStatus.SUCCESS"/>.</exception>
 /// <exception cref="XBeeException">If there is any other XBee related error.</exception>
 /// <seealso cref="ReceiveTimeout"/>
 /// <seealso cref="RemoteXBeeDevice"/>
 /// <seealso cref="SendDataAsync(RemoteXBeeDevice, byte[])"/>
 public virtual new void SendData(RemoteXBeeDevice xbeeDevice, byte[] data)
 {
     base.SendData(xbeeDevice, data);
 }
Example #14
0
        /// <summary>
        /// Parses the given node discovery API data to create and return a remote
        /// XBee Device.
        /// </summary>
        /// <param name="data">Byte array with the data to parse.</param>
        /// <param name="localDevice">The local device that received the remote XBee data.</param>
        /// <returns>The discovered XBee device.</returns>
        private async Task <RemoteXBeeDevice> ParseDiscoveryAPIData(byte[] data, AbstractXBeeDevice 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:
                case XBeeProtocol.SX:
                    // 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);
        }
Example #15
0
        /// <summary>
        /// Adds the given remote device to the network.
        /// </summary>
        /// <remarks>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.
        ///
        /// The way of adding a device to the network is based on the 64-bit address. If it is not
        /// configured:
        /// <list type="bullet">
        /// <item><description>For 802.15.4 and ZigBee devices, it will use the 16-bit address.</description></item>
        /// <item><description>For the rest will return <c>true</c> as the result of the addition.</description></item>
        /// </list></remarks>
        /// <param name="remoteDevice">The remote device to be added to the network.</param>
        /// <returns>The remote XBee Device instance in the network, <c>null</c> if the device could not be
        /// successfully added.</returns>
        /// <exception cref="ArgumentNullException">If <c><paramref name="remoteDevice"/> == null</c>.</exception>
        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.XBee64BitAddr;
            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.
                    if (remotesBy16BitAddr.TryGetValue(addr16, out devInNetwork))
                    {
                        // 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);
        }