/// <summary> /// This method reads bytes from the underlying input stream and performs the following tasks: /// 1. Keeps track of how many bytes we've read /// 2. Un-escapes bytes if necessary and verifies the checksum. /// </summary> /// <returns></returns> public byte Read() { if (RemainingBytes == 0) { throw new XBeeParseException("Packet has read all of its bytes"); } var b = TakeFromBuffer(ParseTimeLeft); if (XBeePacket.IsSpecialByte(b)) { Logger.LowDebug("Read special byte that needs to be unescaped"); if (b == (byte)XBeePacket.SpecialByte.Escape) { Logger.LowDebug("found escape byte"); // read next byte b = TakeFromBuffer(ParseTimeLeft); Logger.LowDebug("next byte is " + ByteUtils.FormatByte(b)); b = (byte)(0x20 ^ b); Logger.LowDebug("unescaped (xor) byte is " + ByteUtils.FormatByte(b)); _escapedBytes++; } else { // TODO some responses such as AT Response for node discover do not escape the bytes?? shouldn't occur if AP mode is 2? // while reading remote at response Found unescaped special byte base10=19,base16=0x13,base2=00010011 at position 5 Logger.LowDebug("Found unescaped special byte " + ByteUtils.FormatByte(b) + " at position " + BytesRead); } } BytesRead++; // do this only after reading length bytes if (BytesRead > 2) { // when verifying checksum you must add the checksum that we are verifying // checksum should only include unescaped bytes!!!! // when computing checksum, do not include start byte, length, or checksum; when verifying, include checksum _checksum.AddByte(b); //Logger.LowDebug("Read byte " + ByteUtils.FormatByte(b) // + " at position " + BytesRead // + ", packet length is " + Length.Get16BitValue() // + ", #escapeBytes is " + _escapedBytes // + ", remaining bytes is " + RemainingBytes); // escape bytes are not included in the stated packet length if (FrameDataBytesRead >= (Length + 1)) { // this is checksum and final byte of packet Logger.LowDebug("Checksum byte is " + b); if (!_checksum.Verify()) { throw new XBeeParseException("Checksum is incorrect. Expected 0xff, but got 0x" + ByteUtils.ToBase16(_checksum.GetChecksum())); } } } return(b); }
private void ParsePackets() #endif { #if WINDOWS_UWP while (!ct.IsCancellationRequested) #else while (!_finished) #endif { try { var b = TakeFromBuffer(); #if WINDOWS_UWP if (ct.IsCancellationRequested) { return; } #else if (_finished) { return; } #endif if (!XBeePacket.IsStartByte(b)) { continue; } var packet = ParsePacket(); if (Logger.IsActive(LogLevel.Debug)) { Logger.Debug("Received " + packet.GetType().Name + ": " + packet); } var listeners = _packetListeners.ToArray(); for (var i = 0; i < listeners.Length; i++) { var packetListener = (IPacketListener)listeners[i]; if (!packetListener.Finished) { packetListener.ProcessPacket(packet); } if (packetListener.Finished) { RemovePacketListener(packetListener); } } } catch (XBeeTimeoutException) { Logger.LowDebug("Incomplete packet received"); } catch (XBeeParseException) { Logger.Warn("Errors occured while parsing received packet"); } #if !WINDOWS_UWP catch (ThreadAbortException) { Logger.Debug("Thread aborted"); return; } #endif catch (Exception e) { Logger.Error("Unexpected exception occured while parsing packet. " + e.Message); } } }