예제 #1
0
 public override string ToString()
 {
     return("command=" + UshortUtils.ToAscii(Command)
            + ",status=" + Status
            + ",value=" + (Value == null ? "null" : ByteUtils.ToBase16(Value))
            + "," + base.ToString());
 }
        public override void Parse(IPacketParser parser)
        {
            Sender = new NodeInfo
            {
                SerialNumber   = parser.ParseAddress64(),
                NetworkAddress = parser.ParseAddress16()
            };

            Option = (PacketOption)parser.Read("Option");

            Remote = new NodeInfo
            {
                NetworkAddress = parser.ParseAddress16(),
                SerialNumber   = parser.ParseAddress64()
            };

            byte ch;

            // NI is terminated with 0
            while ((ch = parser.Read("Node Identifier")) != 0)
            {
                if (ch > 32 && ch < 126)
                {
                    Remote.NodeIdentifier += (char)ch;
                }
            }

            ParentAddress = parser.ParseAddress16();
            NodeType      = (NodeType)parser.Read("Device Type");
            SourceAction  = (SourceActions)parser.Read("Source Action");
            ProfileId     = UshortUtils.ToUshort(parser.Read("Profile MSB"), parser.Read("Profile LSB"));
            MfgId         = UshortUtils.ToUshort(parser.Read("MFG MSB"), parser.Read("MFG LSB"));
        }
예제 #3
0
        private IoSample ParseIoSample(IPacketParser parser)
        {
            ushort digital = 0;
            var analog = new double[Pin.AnalogCount];

            if (ContainsDigital)
            {
                Logger.LowDebug("Sample contains digital inputs");
                digital = UshortUtils.ToUshort(parser.Read(), parser.Read());
            }

            if (ContainsAnalog)
            {
                var analogCount = 0;

                for (var i = 0; i < analog.Length; i++)
                {
                    if (!IsEnabled((Pin.Analog) i))
                        continue;

                    var reading = UshortUtils.Parse10BitAnalog(parser.Read(), parser.Read());
                    analog[i] = AdcHelper.ToMilliVolts(reading);
                    analogCount++;
                }

                Logger.LowDebug("Sample contains " + analogCount +" analog inputs");
            }

            return new IoSample(analog, digital);
        }
예제 #4
0
        private XBeeResponse ParsePacket()
        {
            try
            {
                ParseStartTime = DateTime.Now;
                BytesRead      = 0;
                _checksum.Clear();

                // length of api structure, starting here (not including start byte or length bytes, or checksum)
                // length doesn't account for escaped bytes
                Length = UshortUtils.ToUshort(Read("Length MSB"), Read("Length LSB"));

                Logger.LowDebug("packet length is " + ByteUtils.ToBase16(Length));

                // total packet length = stated length + 1 start byte + 1 checksum byte + 2 length bytes

                ApiId = (ApiId)Read("API ID");

                Logger.LowDebug("Handling ApiId: " + ApiId);

                // TODO parse I/O data page 12. 82 API Identifier Byte for 64 bit address A/D data (83 is for 16bit A/D data)
                // TODO XBeeResponse should implement an abstract parse method

                _response = GetResponse(ApiId);

                if (_response == null)
                {
                    Logger.Warn("Did not find a response handler for ApiId [" + ByteUtils.ToBase16((byte)ApiId));
                    _response = new GenericResponse();
                }

                _response.Parse(this);
                _response.Checksum = Read("Checksum");

                if (RemainingBytes > 0)
                {
                    throw new XBeeParseException("There are remaining bytes after parsing the packet");
                }

                _response.Finish();
            }
            catch (Exception e)
            {
                Logger.Error("Failed to parse packet due to exception. " + e.Message);
                _response = new ErrorResponse {
                    ErrorMsg = e.Message, Exception = e
                };
            }
            finally
            {
                if (_response != null)
                {
                    _response.Length = Length;
                    _response.ApiId  = ApiId;
                }
            }

            return(_response);
        }
예제 #5
0
        protected override void ParseFrameHeader(IPacketParser parser)
        {
            base.ParseFrameHeader(parser);

            SourceEndpoint      = parser.Read("Reading Source Endpoint");
            DestinationEndpoint = parser.Read("Reading Destination Endpoint");
            ClusterId           = UshortUtils.ToUshort(parser.Read("Reading Cluster Id MSB"), parser.Read("Reading Cluster Id LSB"));
            ProfileId           = UshortUtils.ToUshort(parser.Read("Reading Profile Id MSB"), parser.Read("Reading Profile Id LSB"));
        }
예제 #6
0
        public override void Parse(IPacketParser parser)
        {
            base.Parse(parser);

            Command = UshortUtils.ToUshort(
                parser.Read("AT Response Char 1"),
                parser.Read("AT Response Char 2"));

            Status = (AtResponseStatus)parser.Read("AT Response Status");
            Value  = parser.ReadRemainingBytes();
        }
예제 #7
0
        public override void Parse(IPacketParser parser)
        {
            FrameId = parser.Read("Frame Id");

            RemoteSerial  = parser.ParseAddress64();
            RemoteAddress = parser.ParseAddress16();

            Command = UshortUtils.ToUshort(
                parser.Read("AT Response Char 1"),
                parser.Read("AT Response Char 2"));

            Status = (AtResponseStatus)parser.Read("AT Response Status");
            Value  = parser.ReadRemainingBytes();
        }
예제 #8
0
        /// <summary>
        /// Performs the necessary activities to construct an XBee packet from the frame data.
        /// This includes: computing the checksum, escaping the necessary bytes, adding the start byte and length bytes.
        /// The format of a packet is as follows:
        /// start byte - msb length byte - lsb length byte - frame data - checksum byte
        /// </summary>
        /// <param name="request"></param>
        public static byte[] GetBytes(XBeeRequest request)
        {
            var frameData = request.GetFrameData();

            // packet size is frame data + start byte + 2 length bytes + checksum byte
            var bytes = new byte[frameData.Length + 4];

            bytes[0] = (byte)SpecialByte.StartByte;

            // Packet length does not include escape bytes or start, length and checksum bytes
            var length = (ushort)frameData.Length;

            // msb length (will be zero until maybe someday when > 255 bytes packets are supported)
            bytes[1] = UshortUtils.Msb(length);
            // lsb length
            bytes[2] = UshortUtils.Lsb(length);

            Array.Copy(frameData, 0, bytes, 3, frameData.Length);

            // set last byte as checksum
            // note: if checksum is not correct, XBee won't send out packet or return error.  ask me how I know.

            bytes[bytes.Length - 1] = Checksum.Compute(frameData, 0, frameData.Length);

            var preEscapeLength = bytes.Length;

            // TODO save escaping for the serial out method. this is an unnecessary operation
            bytes = EscapePacket(bytes);

            var escapeLength = bytes.Length;

            var packetStr = "Packet: ";

            for (var i = 0; i < escapeLength; i++)
            {
                packetStr += ByteUtils.ToBase16(bytes[i]);

                if (i < escapeLength - 1)
                {
                    packetStr += " ";
                }
            }

            Logger.LowDebug(packetStr);
            Logger.LowDebug("pre-escape packet size is " + preEscapeLength + ", post-escape packet size is " + escapeLength);

            return(bytes);
        }
예제 #9
0
        /// <summary>
        /// If digital I/O line (DIO0) is enabled: returns true if digital 0 is HIGH (ON); false if it is LOW (OFF).
        /// If digital I/O line is not enabled this method returns false.
        /// </summary>
        /// <remarks>
        /// Important: the pin number corresponds to the logical pin (e.g. D4), not the physical pin number.
        /// Digital I/O pins seem to report high when open circuit (unconnected)
        /// </remarks>
        /// <param name="pin"></param>
        /// <returns></returns>
        public bool IsDigitalOn(Pin pin)
        {
            if (!IsDigitalEnabled(pin))
            {
                return(false);
            }

            var pinNumber = (byte)pin;

            if (pinNumber >= 0 && pinNumber <= 7)
            {
                return(ByteUtils.GetBit(UshortUtils.Lsb(Digital), pinNumber));
            }

            return(ByteUtils.GetBit(UshortUtils.Msb(Digital), pinNumber - 8));
        }
예제 #10
0
        public bool IsDigitalEnabled(Pin pin)
        {
            var pinNumber = (byte)pin;

            if (pinNumber >= 0 && pinNumber <= 7)
            {
                return(ByteUtils.GetBit(UshortUtils.Lsb(DigitalChannelMask), pinNumber));
            }

            if (pinNumber >= 10 && pinNumber <= 12)
            {
                return(ByteUtils.GetBit(UshortUtils.Msb(DigitalChannelMask), pinNumber - 8));
            }

            throw new ArgumentOutOfRangeException("Unsupported pin: " + pin);
        }
예제 #11
0
        protected override void ParseFramePayload(IPacketParser parser)
        {
            // eat sample size.. always 1
            var size = parser.Read("ZNet RX IO Sample Size");

            if (size != 1)
            {
                throw new XBeeParseException("Sample size is not supported if > 1 for ZNet I/O");
            }

            DigitalChannelMask = UshortUtils.ToUshort(parser.Read("ZNet RX IO Sample Digital Mask 1"),
                                                      parser.Read("ZNet RX IO Sample Digital Mask 2"));

            // TODO apparent bug: channel mask on ZigBee Pro firmware has DIO10/P0 as enabled even though it's set to 01 (RSSI).  Digital value reports low.
            DigitalChannelMask &= 0x1CFF; //11100 zero out all but bits 3-5

            AnalogChannelMask  = parser.Read("ZNet RX IO Sample Analog Channel Mask");
            AnalogChannelMask &= 0x8f; //10001111 zero out n/a bits

            if (ContainsDigital)
            {
                Digital = UshortUtils.ToUshort(parser.Read("ZNet RX IO DIO MSB"),
                                               parser.Read("ZNet RX IO DIO LSB"));
            }

            // parse 10-bit analog values

            Analog = new int[5];

            for (var pin = Pin.A0; pin <= Pin.A3; pin++)
            {
                if (!IsAnalogEnabled(pin))
                {
                    continue;
                }

                Analog[(byte)pin] = UshortUtils.Parse10BitAnalog(parser.Read(), parser.Read());
            }

            if (IsAnalogEnabled(Pin.SupplyVoltage))
            {
                Analog[SupplyVoltageIndex] = UshortUtils.Parse10BitAnalog(parser.Read(), parser.Read());
            }
        }
예제 #12
0
        public override void Parse(IPacketParser parser)
        {
            Source = parser.ApiId == ApiId.Rx16IoResponse
             ? (XBeeAddress)parser.ParseAddress16()
             : parser.ParseAddress64();

            base.Parse(parser);

            SampleCount = parser.Read();
            ChannelIndicator = UshortUtils.ToUshort(parser.Read(), parser.Read());
            ContainsDigital = (ChannelIndicator & DigitalMask) > 0;
            ContainsAnalog = (ChannelIndicator & AnalogMask) > 0;
            Samples = new IoSample[SampleCount];

            for (var i = 0; i < SampleCount; i++)
            {
                Logger.LowDebug("Parsing I/O sample nr " + (i + 1));
                Samples[i] = ParseIoSample(parser);
            }
        }
예제 #13
0
 public bool IsEnabled(Pin.Digital input)
 {
     return UshortUtils.GetBit(ChannelIndicator, (byte)input);
 }
예제 #14
0
 protected int GetDiscoverTimeout(AtResponse response)
 {
     // ms + 1 extra second
     return(UshortUtils.ToUshort(response.Value) * 100 + 1000);
 }
예제 #15
0
 public RemoteAtCommand(string command, XBeeAddress64 remoteSerial, XBeeAddress16 remoteAddress, byte[] value = null, bool applyChanges = true)
     : this(UshortUtils.FromAscii(command), remoteSerial, remoteAddress, value, applyChanges)
 {
 }
예제 #16
0
 /// <summary>
 /// Get digital pin state.
 /// </summary>
 /// <param name="pin">Digital pin</param>
 /// <returns>Returns <c>true</c> if low, <c>false</c> if high.</returns>
 public bool GetValue(Pin.Digital pin)
 {
     return(UshortUtils.GetBit(_digital, (byte)pin));
 }
예제 #17
0
 public bool IsEnabled(Pin.Analog input)
 {
     var bitNumber = (byte) ((byte)input + Pin.DigitalCount);
     return UshortUtils.GetBit(ChannelIndicator, bitNumber);
 }
예제 #18
0
 public AtCommand(string command, params byte[] value)
     : this(UshortUtils.FromAscii(command), value)
 {
 }
예제 #19
0
 public override string ToString()
 {
     return(base.ToString()
            + ",command=" + UshortUtils.ToAscii(Command)
            + ",value=" + (Value == null ? "null" : ByteUtils.ToBase16(Value)));
 }