/// <summary> /// Generates the XBee packet byte array. /// </summary> /// <remarks>Use only while working in <see cref="OperatingMode.API"/> mode. If working in /// <see cref="OperatingMode.API_ESCAPE"/> mode, use<see cref="GenerateByteArrayEscaped"/>.</remarks> /// <returns>The XBee packet byte array.</returns> /// <seealso cref="GenerateByteArrayEscaped"/> public byte[] GenerateByteArray() { checksum.Reset(); byte[] packetData = GetPacketData(); using (var os = new MemoryStream()) { os.WriteByte(SpecialByte.HEADER_BYTE.GetValue()); if (packetData != null) { byte[] Length = ByteUtils.ShortToByteArray((short)packetData.Length); var msb = Length[0]; var lsb = Length[1]; os.WriteByte(msb); os.WriteByte(lsb); for (int i = 0; i < packetData.Length; i++) { checksum.Add(packetData[i]); os.WriteByte(packetData[i]); } } else { os.WriteByte(0); os.WriteByte(0); } os.WriteByte((byte)(checksum.Generate() & 0xFF)); return(os.ToArray()); } }
/// <summary> /// Parses the bytes from the given <paramref name="inputStream"/> depending on the provided /// <paramref name="mode"/> and returns the API packet. /// </summary> /// <remarks>The operating mode must be <see cref="OperatingMode.API"/> or /// <see cref="OperatingMode.API_ESCAPE"/>.</remarks> /// <param name="inputStream">Input stream to read bytes from.</param> /// <param name="mode">XBee device operating mode.</param> /// <returns>Parsed packet from the input stream.</returns> /// <exception cref="ArgumentException">If <paramref name="mode"/> is invalid /// or if the <paramref name="inputStream"/> cannot be read.</exception> /// <exception cref="ArgumentNullException">If <paramref name="inputStream"/> is <c>null</c>.</exception> /// <exception cref="InvalidPacketException">If there is not enough data in the stream or if there /// is an error verifying the checksum or if the payload is invalid for the specified frame type.</exception> public XBeePacket ParsePacket(Stream inputStream, OperatingMode mode) { if (inputStream == null) { throw new ArgumentNullException("Input stream cannot be null."); } if (!inputStream.CanRead) { throw new ArgumentException("Could not read from the input stream."); } if (mode != OperatingMode.API && mode != OperatingMode.API_ESCAPE) { throw new ArgumentException("Operating mode must be API or API Escaped."); } try { // Read packet size. int hSize = ReadByte(inputStream, mode); int lSize = ReadByte(inputStream, mode); int Length = hSize << 8 | lSize; // Read the payload. byte[] payload = ReadBytes(inputStream, mode, Length); // Calculate the expected checksum. XBeeChecksum checksum = new XBeeChecksum(); checksum.Add(payload); byte expectedChecksum = (byte)(checksum.Generate() & 0xFF); // Read checksum from the input stream. byte readChecksum = (byte)(ReadByte(inputStream, mode) & 0xFF); // Verify the checksum of the read bytes. if (readChecksum != expectedChecksum) { throw new InvalidPacketException("Invalid checksum (expected 0x" + HexUtils.ByteToHexString(expectedChecksum) + ")."); } return(ParsePayload(payload)); } catch (IOException e) { throw new InvalidPacketException("Error parsing packet: " + e.Message, e); } }