/// <summary> /// Reads one byte from the input stream. /// </summary> /// <remarks>This operation checks several things like the working mode in order to consider /// escaped bytes.</remarks> /// <param name="inputStream">The input stream to read bytes from.</param> /// <param name="mode">The XBee device working mode.</param> /// <returns>The read byte.</returns> /// <exception cref="InvalidPacketException">If there is not enough data in the stream /// or if there is an error verifying the checksum.</exception> /// <exception cref="ArgumentException">If input stream cannot be read.</exception> /// <exception cref="ArgumentNullException">If <paramref name="inputStream"/> is <c>null</c>.</exception> private int ReadByte(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."); } int timeout = 300; int b = ReadByteFrom(inputStream, timeout); if (b == -1) { throw new InvalidPacketException("Error parsing packet: Incomplete packet."); } /* Process the byte for API1. */ if (mode == OperatingMode.API) { return(b); } /* Process the byte for API2. */ // Check if the byte is special. if (!SpecialByte.ESCAPE_BYTE.IsSpecialByte((byte)b)) { return(b); } // Check if the byte is ESCAPE. if (b == SpecialByte.ESCAPE_BYTE.GetValue()) { // Read next byte and escape it. b = ReadByteFrom(inputStream, timeout); if (b == -1) { throw new InvalidPacketException("Error parsing packet: Incomplete packet."); } b ^= 0x20; } else { // If the byte is not a escape there is a special byte not escaped. throw new InvalidPacketException("Special byte not escaped: 0x" + HexUtils.ByteToHexString((byte)(b & 0xFF)) + "."); } return(b); }
private int ReadByte(SerialPort serialPort, OperatingMode mode) /*throws InvalidPacketException, IOException*/ { Contract.Requires <ArgumentNullException>(serialPort != null, "Input stream cannot be null."); Contract.Requires <ArgumentException>(serialPort.IsOpen); int timeout = 300; int b = ReadByteFrom(serialPort, timeout); if (b == -1) { throw new InvalidPacketException("Error parsing packet: Incomplete packet."); } /* Process the byte for API1. */ if (mode == OperatingMode.API) { return(b); } /* Process the byte for API2. */ // Check if the byte is special. if (!SpecialByte.ESCAPE_BYTE.IsSpecialByte((byte)b)) { return(b); } // Check if the byte is ESCAPE. if (b == SpecialByte.ESCAPE_BYTE.GetValue()) { // Read next byte and escape it. b = ReadByteFrom(serialPort, timeout); if (b == -1) { throw new InvalidPacketException("Error parsing packet: Incomplete packet."); } b ^= 0x20; } else { // If the byte is not a escape there is a special byte not escaped. throw new InvalidPacketException("Special byte not escaped: 0x" + HexUtils.ByteToHexString((byte)(b & 0xFF)) + "."); } return(b); }
/** * Parses the bytes from the given array depending on the provided operating * mode and returns the API packet. * * <p>The operating mode must be {@link OperatingMode#API} or * {@link OperatingMode#API_ESCAPE}.</p> * * @param packetByteArray Byte array with the complete frame, starting from * the header and ending in the checksum. * @param mode XBee device operating mode. * * @return Parsed packet from the given byte array. * * @throws InvalidPacketException if there is not enough data in the array or * if there is an error verifying the checksum or * if the payload is invalid for the specified frame type. * @throws ArgumentException if {@code mode != OperatingMode.API } and * if {@code mode != OperatingMode.API_ESCAPE}. * @throws ArgumentNullException if {@code packetByteArray == null} or * if {@code mode == null}. * * @see XBeePacket * @see com.digi.xbee.api.models.OperatingMode#API * @see com.digi.xbee.api.models.OperatingMode#API_ESCAPE */ public XBeePacket ParsePacket(byte[] packetByteArray, OperatingMode mode) { Contract.Requires <ArgumentNullException>(packetByteArray != null, "Packet byte array cannot be null."); Contract.Requires <ArgumentNullException>(mode != null, "Operating mode cannot be null."); Contract.Requires <ArgumentException>(mode == OperatingMode.API || mode == OperatingMode.API_ESCAPE, "Operating mode must be API or API Escaped."); Contract.Requires <InvalidOperationException>(packetByteArray.Length >= 4, "Error parsing packet: Incomplete packet."); // Check the header of the frame. if ((packetByteArray[0] & 0xFF) != SpecialByte.HEADER_BYTE.GetValue()) { throw new InvalidPacketException("Invalid start delimiter (expected 0x" + HexUtils.ByteToHexString((byte)SpecialByte.HEADER_BYTE.GetValue()) + ")."); } return(ParsePacket(new MemoryStream(packetByteArray, 1, packetByteArray.Length - 1), mode)); }
/// <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); } }
public XBeePacket ParsePacket(SerialPort serialPort, OperatingMode mode) { Contract.Requires <ArgumentNullException>(serialPort != null, "Input stream cannot be null."); Contract.Requires <ArgumentException>(serialPort.IsOpen); Contract.Requires <ArgumentException>(mode == OperatingMode.API || mode == OperatingMode.API_ESCAPE, "Operating mode must be API or API Escaped."); try { // Read packet size. int hSize = ReadByte(serialPort, mode); int lSize = ReadByte(serialPort, mode); int Length = hSize << 8 | lSize; // Read the payload. byte[] payload = ReadBytes(serialPort, 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(serialPort, 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); } }
/// <summary> /// Parses the bytes from the given array depending on the provided operating 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="packetByteArray">Byte array with the complete frame, starting from the /// header and ending in the checksum.</param> /// <param name="mode">XBee device operating mode.</param> /// <returns>Parsed packet from the given byte array.</returns> /// <exception cref="InvalidPacketException">If there is not enough data in the array /// or if there is an error verifying the checksum /// or if the payload is invalid for the specified frame type.</exception> /// <exception cref="ArgumentException">If <c><paramref name="mode"/> != <see cref="OperatingMode.API"/></c> /// and if <c><paramref name="mode"/> != <see cref="OperatingMode.API_ESCAPE"/></c></exception> /// <exception cref="ArgumentNullException">If <c><paramref name="packetByteArray"/> == null</c>.</exception> /// <seealso cref="XBeePacket"/> /// <seealso cref="OperatingMode.API"/> /// <seealso cref="OperatingMode.API_ESCAPE"/> public XBeePacket ParsePacket(byte[] packetByteArray, OperatingMode mode) { if (packetByteArray == null) { throw new ArgumentNullException("Packet byte array cannot be null."); } if (mode != OperatingMode.API && mode != OperatingMode.API_ESCAPE) { throw new ArgumentException("Operating mode must be API or API Escaped."); } if (packetByteArray.Length < 4) { throw new InvalidPacketException("Error parsing packet: Incomplete packet."); } // Check the header of the frame. if ((packetByteArray[0] & 0xFF) != SpecialByte.HEADER_BYTE.GetValue()) { throw new InvalidPacketException("Invalid start delimiter (expected 0x" + HexUtils.ByteToHexString(SpecialByte.HEADER_BYTE.GetValue()) + ")."); } return(ParsePacket(new MemoryStream(packetByteArray, 1, packetByteArray.Length - 1), mode)); }
/// <summary> /// Gets the string representation of the API output mode. /// </summary> /// <param name="source"></param> /// <returns>String representation of the API output mode.</returns> public static string ToDisplayString(this APIOutputMode source) { return(HexUtils.ByteToHexString((byte)source) + ": " + lookupTable[source]); }
public static string ToDisplayString(this HardwareVersionEnum source) { return(string.Format("{0}: {1}", HexUtils.ByteToHexString((byte)source.GetValue()), source.GetDescription())); }
public static string ToDisplayString(this AssociationIndicationStatus source) { var data = lookupTable[source]; return(string.Format("{0}: {1}", HexUtils.ByteToHexString((byte)source), data)); }
public static string ToDisplayString(this PowerLevel source) { return(string.Format("{0}: {1}", HexUtils.ByteToHexString((byte)source), lookupTable[source])); }
/// <summary> /// Returns the <see cref="ModemStatusEvent"/> in string format. /// </summary> /// <param name="source"></param> /// <returns>The <see cref="ModemStatusEvent"/> in string format.</returns> public static string ToDisplayString(this ModemStatusEvent source) { return(string.Format("{0}: {1}", HexUtils.ByteToHexString((byte)(int)source), source.GetDescription())); }
/// <summary> /// Returns the <see cref="CellularAssociationIndicationStatus"/> in string format. /// </summary> /// <param name="source"></param> /// <returns>The <see cref="CellularAssociationIndicationStatus"/> in string format.</returns> public static string ToDisplayString(this CellularAssociationIndicationStatus source) { return(string.Format("{0}: {1}", HexUtils.ByteToHexString((byte)(int)source), source.GetDescription())); }
/// <summary> /// Returns the <see cref="XBeeLocalInterface"/> in string format. /// </summary> /// <param name="source"></param> /// <returns>The <see cref="XBeeLocalInterface"/> in string format.</returns> public static string ToDisplayString(this XBeeLocalInterface source) { return(HexUtils.ByteToHexString((byte)source) + ": " + lookupTable[source]); }