class XBee::Packet
Constants
- ESCAPE
- ESCAPE_BYTES
- ESCAPE_XOR
- START_BYTE
- XOFF
- XON
Public Class Methods
checksum(bytes)
click to toggle source
# File lib/xbee/packet.rb, line 23 def checksum(bytes) 255 - bytes.reduce(&:+) % 256 end
escape(bytes, options = {})
click to toggle source
Escapes an array of bytes. Ignores the first byte unless ignore_first_byte is set to false in the options hash. @param bytes [Array<Integer>] The array of bytes to escape. @param options [Hash] Options hash. @option options [Boolean] :ignore_first_byte If the first byte should be ignored (usually true for handling an entire packet since the first byte is START_BYTE
). Default true. @return [Array<Integer>] Escaped bytes.
# File lib/xbee/packet.rb, line 33 def escape(bytes, options = {}) ignore_first_byte = options.fetch :ignore_first_byte, true prepend = [] if ignore_first_byte bytes = bytes.dup prepend = [bytes.shift] end prepend + bytes.reduce([]) do |escaped, b| if ESCAPE_BYTES.include?(b) escaped << ESCAPE escaped << (ESCAPE_XOR ^ b) else escaped << b end end end
from_byte_enum(bytes)
click to toggle source
# File lib/xbee/packet.rb, line 104 def from_byte_enum(bytes) begin loop until bytes.next == START_BYTE length = (next_unescaped_byte(bytes) << 8) + next_unescaped_byte(bytes) rescue raise IOError, 'Packet is too short, unable to read length fields.' end begin data = (1..length).map { next_unescaped_byte bytes } rescue raise IOError, "Expected data length to be #{length} but got fewer bytes" end begin crc = next_unescaped_byte bytes rescue raise IOError, 'Packet is too short, unable to read checksum' end if crc != checksum(data) raise IOError, "Expected checksum to be 0x#{checksum(data).to_s 16} but was 0x#{crc.to_s 16}" end new data end
from_bytes(bytes)
click to toggle source
# File lib/xbee/packet.rb, line 74 def from_bytes(bytes) if bytes.length < 4 raise ArgumentError, "Packet is too short (only #{bytes.length} bytes)" end if bytes[0] != START_BYTE raise ArgumentError, 'Missing start byte' end data = [START_BYTE] + unescape(bytes[1..-1]) length = (data[1] << 8) + data[2] if length != data.length - 4 raise ArgumentError, "Expected data length to be #{length} but was #{data.length - 4}" end crc = checksum(data[3..-2]) if crc != data[-1] raise ArgumentError, "Expected checksum to be 0x#{crc.to_s 16} but was 0x#{data[-1].to_s 16}" end new data[3..-2] end
new(data)
click to toggle source
@param data [Array<Integer>] Byte array
# File lib/xbee/packet.rb, line 130 def initialize(data) @data = data end
next_unescaped_byte(bytes)
click to toggle source
# File lib/xbee/packet.rb, line 94 def next_unescaped_byte(bytes) byte = bytes.next if byte == ESCAPE 0x20 ^ bytes.next else byte end end
special_byte?(byte)
click to toggle source
@param byte [Integer]
# File lib/xbee/packet.rb, line 18 def special_byte?(byte) ESCAPE_BYTES.include? byte end
unescape(bytes)
click to toggle source
When provided a byte array that has escaped data, this returns a new byte array with just the raw data. @param bytes [Array<Integer>] Array of bytes to unescape. @return [Array<Integer>] Array of unescaped bytes.
# File lib/xbee/packet.rb, line 56 def unescape(bytes) byte_escaped = false bytes.reduce([]) do |unescaped, b| if byte_escaped unescaped << (0x20 ^ b) byte_escaped = false else if b == ESCAPE byte_escaped = true else unescaped << b end end unescaped end end
Public Instance Methods
==(other)
click to toggle source
# File lib/xbee/packet.rb, line 166 def ==(other) data == other.data end
bytes()
click to toggle source
# File lib/xbee/packet.rb, line 150 def bytes [START_BYTE, length >> 8, length & 0xff] + @data + [checksum] end
bytes_escaped()
click to toggle source
# File lib/xbee/packet.rb, line 155 def bytes_escaped [START_BYTE] + bytes[1..-1].flat_map do |b| if self.class.special_byte?(b) [ESCAPE, 0x20 ^ b] else b end end end
checksum()
click to toggle source
# File lib/xbee/packet.rb, line 145 def checksum Packet.checksum @data end
data()
click to toggle source
# File lib/xbee/packet.rb, line 135 def data @data end
length()
click to toggle source
# File lib/xbee/packet.rb, line 140 def length @data.length end
to_s()
click to toggle source
# File lib/xbee/packet.rb, line 171 def to_s 'Packet [' + data.map { |b| "0x#{b.to_s 16}" }.join(', ') + ']' end