Beispiel #1
0
 // TODO: Double check this once XBeeQueue is implemented
 /// <summary>
 /// Adds a packet to the queue. If the queue is full, the head is removed to make room
 /// </summary>
 /// <param name="packet">The packet to be added</param>
 /// <exception cref="NotImplementedException">Thrown if packet is explicit, since that functionality isn't implemented</exception>
 protected void AddPacketQueue(XBeeAPIPacket packet)
 {
     // Data packets
     if (packet.FrameTypeValue == ApiFrameType.Byte.RECEIVE_PACKET || packet.FrameTypeValue == ApiFrameType.Byte.RX_64 ||
         packet.FrameTypeValue == ApiFrameType.Byte.RX_16)
     {
         // BUG: Race condition in the original python implementation (it has been fixed here). There was
         //      no lock between making room in the queue and adding a new element. If another packet gets
         //      added in between these two operations, the latter will throw an unhandled "XBeeQueueFullException"
         DataXBeeQueue.PutNoWait(packet, true);
     }
     else if (packet.FrameTypeValue == ApiFrameType.Byte.EXPLICIT_RX_INDICATOR)
     {
         ExplicitXBeeQueue.PutNoWait(packet, true);
         if (IsSpecialExplicitPacket((ExplicitRXIndicatorPacket)packet))
         {
             AddPacketQueue(ExplToNoExpl((ExplicitRXIndicatorPacket)packet));
         }
     }
     else if (packet.FrameTypeValue == ApiFrameType.Byte.RX_IPV4)
     {
         IPXBeeQueue.PutNoWait(packet, true);
     }
     else
     {
         XBeeQueue.PutNoWait(packet, true);
     }
 }
Beispiel #2
0
 /// <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);
     }
 }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
 /// <summary>
 /// Adds an element to the end of the queue
 /// </summary>
 /// <param name="packet">Packet to add</param>
 /// <param name="block">Whether or not to wait for a spot to open, should the queue be full</param>
 /// <param name="timeout">How long to wait, if queue is full</param>
 /// <param name="makeRoom">If true, queue will remove the oldest packet to make room for this one, after waiting the timeout</param>
 /// <exception cref="XBeeQueueFullException">Thrown if the queue is full and makeRoom is set to false</exception>
 public void Put(XBeeAPIPacket packet, bool block = false, int timeout = 0, bool makeRoom = false)
 {
     if (!block)
     {
         lock (mutex)
         {
             if (!Full)
             {
                 list.AddLast(packet);
             }
             else if (makeRoom)
             {
                 // NOTE: The original python implementation did not have this makeRoom variable,
                 //       but the original python implementation also had a bug where it never emptied
                 //       its Queues and attempted to make room anyways in a thread-unsafe way
                 list.RemoveFirst();
                 list.AddLast(packet);
             }
             else
             {
                 throw new XBeeQueueFullException();
             }
         }
     }
     else
     {
         bool     added    = false;
         DateTime deadline = DateTime.Now + new TimeSpan(0, 0, seconds: timeout);
         while (DateTime.Now < deadline && !added)
         {
             try
             {
                 Put(packet, false);
             } catch (XBeeQueueFullException)
             {
                 Thread.Sleep(100);
                 continue;
             }
             added = true;
         }
         if (!added)
         {
             if (makeRoom)
             {
                 Put(packet, makeRoom: true);
             }
             else
             {
                 throw new XBeeQueueFullException();
             }
         }
     }
 }
Beispiel #5
0
        // TODO: Verify this works with escaped packets
        /// <summary>
        /// Reads the next packet. Starts to read when finds the start delimiter. The last byte read is the checksum.
        /// </summary>
        /// <remarks>
        /// If there is something in the COM buffer after the start delimiter, this method discards it.<para/>
        /// If the method can't read a complete and correct packet, it will return null.
        /// </remarks>
        /// <param name="operatingMode">The operating mode in which the packet should be read</param>
        /// <returns>The read packet as a byte array if a packet is read, null otherwise.</returns>
        /// <exception cref="InvalidOperationException">COM port isn't open</exception>
        protected byte[] TryReadPacket(OperatingMode.Byte operatingMode = OperatingMode.Byte.API_MODE)
        {
            try
            {
                byte headerByte = (byte)comPort.ReadByte();
                if (headerByte != SpecialByte.HEADER_BYTE)
                {
                    return(null);
                }

                byte[] tempArray = ReadNextByte(operatingMode);
                tempArray = tempArray.Concat(ReadNextByte(operatingMode)).ToArray();

                int length;
                if (operatingMode == OperatingMode.Byte.ESCAPED_API_MODE)
                {
                    length = Utils.LengthToInt(XBeeAPIPacket.UnescapeData(tempArray));
                }
                else
                {
                    length = Utils.LengthToInt(tempArray);
                }

                // Define byte array: header byte + packet length + data + checksum.
                // Assume worst case scenario: the last 2 fields have escaped every single byte
                byte[] xbeePacket = new byte[1 + 2 * (tempArray.Length + length + 1)];

                xbeePacket[0] = headerByte;
                Array.Copy(tempArray, 0, xbeePacket, 1, tempArray.Length);
                int j = 1 + tempArray.Length;
                for (int i = 0; i <= length; i++)
                {
                    tempArray = ReadNextByte(operatingMode);
                    Array.Copy(tempArray, 0, xbeePacket, j, tempArray.Length);
                    j += tempArray.Length;
                }

                if (operatingMode == OperatingMode.Byte.ESCAPED_API_MODE)
                {
                    return(XBeeAPIPacket.UnescapeData(xbeePacket.Take(j).ToArray()));
                }
                else
                {
                    return(xbeePacket.Take(j).ToArray());
                }
            } catch (TimeoutException err)
            {
                return(null);
            }
        }
        /// <summary>
        /// Notifies subscribed XBee packet event handlers that a new XBee Packet has been received.
        /// </summary>
        /// <param name="packet">The received XBee packet.</param>
        /// <seealso cref="XBeeAPIPacket"/>
        /// <seealso cref="XBeePacket"/>
        private void NotifyPacketReceived(XBeePacket packet)
        {
            logger.DebugFormat(connectionInterface.ToString() + "Packet received: \n{0}", packet.ToPrettyString());

            try
            {
                lock (packetReceivedHandlers)
                {
                    var           args      = new PacketReceivedEventArgs(packet);
                    XBeeAPIPacket apiPacket = (XBeeAPIPacket)packet;
                    List <CustomPacketReceivedEventHandler> handlersToRemove = new List <CustomPacketReceivedEventHandler>();

                    // Need to go over the list of Packet received handlers to
                    // verify which ones need to be notified of the received packet.
                    foreach (var packetHandler in packetReceivedHandlers)
                    {
                        if (packetHandler.Handler != null)
                        {
                            if (packetHandler.FrameId == ALL_FRAME_IDS)
                            {
                                packetHandler.Handler.DynamicInvoke(this, args);
                            }
                            else if (apiPacket.NeedsAPIFrameID &&
                                     apiPacket.FrameID == packetHandler.FrameId)
                            {
                                packetHandler.Handler.DynamicInvoke(this, args);
                                handlersToRemove.Add(packetHandler);
                            }
                        }
                    }
                    foreach (CustomPacketReceivedEventHandler handlerToRemove in handlersToRemove)
                    {
                        RemovePacketReceivedHandler(handlerToRemove.Handler);
                    }
                }
            }
            catch (Exception e)
            {
                logger.Error(e.Message, e);
            }
        }
        /**
         * Returns a byte array with the remote device data to be parsed.
         *
         * @param packet The API packet that contains the data.
         *
         * @return A byte array with the data to be parsed.
         */
        private byte[] GetRemoteDeviceData(XBeeAPIPacket packet)
        {
            byte[] data = null;

            logger.TraceFormat("{0}Received packet: {1}.", xbeeDevice.ToString(), packet);

            APIFrameType frameType = packet.FrameType;

            switch (frameType)
            {
            case APIFrameType.AT_COMMAND_RESPONSE:
                ATCommandResponsePacket atResponse = (ATCommandResponsePacket)packet;
                // Check the frame ID.
                if (atResponse.FrameID != frameID)
                {
                    return(null);
                }
                // Check the command.
                if (!atResponse.Command.Equals(ND_COMMAND))
                {
                    return(null);
                }
                // Check if the 'end' command is received (empty response with OK status).
                if (atResponse.CommandValue == null || atResponse.CommandValue.Length == 0)
                {
                    discovering = atResponse.Status != ATCommandStatus.OK;
                    return(null);
                }

                logger.DebugFormat("{0}Received self response: {1}.", xbeeDevice.ToString(), packet);

                data = atResponse.CommandValue;
                break;

            default:
                break;
            }

            return(data);
        }
Beispiel #8
0
        /// <summary>
        /// Returns the first element of the queue if there is some element ready
        /// </summary>
        /// <param name="block">Suppposed to be a flag to block, but it's not even used</param>
        /// <param name="timeout">Time, in seconds, to wait for the queue to return something</param>
        /// <returns>A packet if there's any available before the timeout. Null otherwise</returns>
        /// <exception cref="TimeoutException">Thrown if timeout expires before a element is found</exception>
        public XBeeAPIPacket Get(bool block = true, int timeout = 0)
        {
            XBeeAPIPacket packet = null;

            if (timeout <= 0)
            {
                // Lock down access to the queue
                lock (mutex)
                {
                    // Attempt to remove and return the first packet, but give up at the slightest sign of trouble
                    try
                    {
                        packet = list.First.Value;
                        list.RemoveFirst();
                    }
                    catch (Exception)
                    {
                        packet = null;
                    }
                }
                return(packet);
            }
            else
            {
                // Call the above non-waiting block of code multiple times until we get a matching packet or the timeout expires
                packet = Get(block, 0);
                DateTime deadline = DateTime.Now + new TimeSpan(0, 0, seconds: timeout);
                while (packet == null && DateTime.Now < deadline)
                {
                    Thread.Sleep(100);
                    packet = Get(block, 0);
                }
                if (packet == null)
                {
                    throw new TimeoutException();
                }
                return(packet);
            }
        }
Beispiel #9
0
        /// <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");
            }
        }
Beispiel #10
0
 /// <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);
     }
 }
Beispiel #11
0
        // NOTE: GetByIP not translated

        /// <summary>
        /// Returns the first packet from the queue whose frame ID matches the provided one
        /// </summary>
        /// <param name="frameID">Frame ID to search for</param>
        /// <param name="timeout">Timeout in seconds</param>
        /// <returns>Packet if any is available. Otherwise, null</returns>
        /// <exception cref="TimeoutException">Thrown if timeout is larger than 0 and expires</exception>
        public XBeeAPIPacket GetByID(int frameID, int timeout = 0)
        {
            if (timeout <= 0)
            {
                // Lock down the queue
                lock (mutex)
                {
                    // Scan through the list for a packet with the matching frame ID
                    var node = list.First;
                    while (node != null)
                    {
                        if (node.Value.NeedsID() && node.Value.FrameID == frameID)
                        {
                            list.Remove(node);
                            return(node.Value);
                        }
                        node = node.Next;
                    }
                }
                return(null);
            }
            else
            {
                XBeeAPIPacket packet   = GetByID(frameID, 0);
                DateTime      deadline = DateTime.Now + new TimeSpan(0, 0, seconds: timeout);
                while (packet == null && DateTime.Now < deadline)
                {
                    Thread.Sleep(100);
                    packet = GetByID(frameID, 0);
                }
                if (packet == null)
                {
                    throw new TimeoutException();
                }
                return(packet);
            }
        }
Beispiel #12
0
        /// <summary>
        /// Returns the 64bit and 16bit addresses of a packet.
        /// </summary>
        /// <remarks>
        /// Note this has different functionality than python, as it can accept any of 7 packets.
        /// The original python API only accepts 4 kinds.
        /// It is also somewhat redundant to Devices.XBeeNetwork.GetDataForRemote, although that takes a raw byte array instead of a packet
        /// </remarks>
        /// <param name="packet">The API packet to scrape addresses from</param>
        /// <returns>A pair of 64bit and 16bit addresses</returns>
        protected static Tuple <XBee64BitAddress, XBee16BitAddress> GetRemoteDeviceDataFromPacket(XBeeAPIPacket packet)
        {
            XBee64BitAddress x64bitAddr = null;
            XBee16BitAddress x16bitAddr = null;

            if (((Dictionary <DictKeys, object>)packet.GetFrameSpecDataDict()[DictKeys.API_DATA]).ContainsKey(DictKeys.X64BIT_ADDR))
            {
                x64bitAddr = (XBee64BitAddress)((Dictionary <DictKeys, object>)packet.GetFrameSpecDataDict()[DictKeys.API_DATA])[DictKeys.X64BIT_ADDR];
            }
            if (((Dictionary <DictKeys, object>)packet.GetFrameSpecDataDict()[DictKeys.API_DATA]).ContainsKey(DictKeys.X16BIT_ADDR))
            {
                x16bitAddr = (XBee16BitAddress)((Dictionary <DictKeys, object>)packet.GetFrameSpecDataDict()[DictKeys.API_DATA])[DictKeys.X16BIT_ADDR];
            }

            return(new Tuple <XBee64BitAddress, XBee16BitAddress>(x64bitAddr, x16bitAddr));
        }
Beispiel #13
0
 /// <summary>
 /// Attempts to add a packet to the queue, but does not wait around if it is full
 /// </summary>
 /// <param name="packet">Packet to add to queue</param>
 /// <param name="makeRoom">If true, queue will remove the oldest packet to make room for this one</param>
 /// <exception cref="XBeeQueueFullException">Thrown if the queue is full and makeRoom is set to false</exception>
 public void PutNoWait(XBeeAPIPacket packet, bool makeRoom = false)
 {
     Put(packet, makeRoom: makeRoom);
 }
        /// <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);
            }
        }
Beispiel #15
0
        /**
         * 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);
            }
        }
Beispiel #16
0
        /// <summary>
        /// Scrapes the 64bit and 16bit addresses from the provided packet and returns a remote XBee device from those
        /// </summary>
        /// <param name="packet">The API packet coming from (or possibly, going to) the remote device</param>
        /// <returns>RemoteXBeeDevice object</returns>
        protected RemoteXBeeDevice CreateRemoteDeviceFromPacket(XBeeAPIPacket packet)
        {
            Tuple <XBee64BitAddress, XBee16BitAddress> addresses = GetRemoteDeviceDataFromPacket(packet);

            return(new RemoteXBeeDevice(xbeeDevice, addresses.Item1, addresses.Item2));
        }
Beispiel #17
0
 /// <summary>
 /// Programmatic trigger for PacketReceived event
 /// </summary>
 /// <param name="packet">The received packet</param>
 protected virtual void OnPacketReceived(XBeeAPIPacket packet)
 {
     PacketReceived?.Invoke(this, packet);
 }
Beispiel #18
0
 /// <summary>
 /// Programmatic trigger for PacketReceived event
 /// </summary>
 /// <param name="packet">The received packet</param>
 protected virtual void OnPacketReceivedAPI(XBeeAPIPacket packet)
 {
     // This could be consolidated with the PacketReceived event, but the python implementation
     // has a separate one, so oh well
     PacketReceivedAPI?.Invoke(this, packet);
 }
Beispiel #19
0
        /**
         * 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>
        /// 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);
        }