Class: XBeeRuby::Packet
- Inherits:
-
Object
- Object
- XBeeRuby::Packet
- Defined in:
- lib/xbee-ruby/packet.rb
Constant Summary collapse
- START_BYTE =
0x7e
- ESCAPE =
0x7d
- XON =
0x11
- XOFF =
0x13
Class Method Summary collapse
- .checksum(bytes) ⇒ Object
- .from_byte_enum(bytes) ⇒ Object
- .from_bytes(bytes) ⇒ Object
- .next_unescaped_byte(bytes) ⇒ Object
- .special_byte?(byte) ⇒ Boolean
- .unescape(bytes) ⇒ Object
Instance Method Summary collapse
- #==(other) ⇒ Object
- #bytes ⇒ Object
- #bytes_escaped ⇒ Object
- #checksum ⇒ Object
- #data ⇒ Object
-
#initialize(data) ⇒ Packet
constructor
A new instance of Packet.
- #length ⇒ Object
- #to_s ⇒ Object
Constructor Details
#initialize(data) ⇒ Packet
Returns a new instance of Packet.
90 91 92 |
# File 'lib/xbee-ruby/packet.rb', line 90 def initialize data @data = data end |
Class Method Details
.checksum(bytes) ⇒ Object
24 25 26 |
# File 'lib/xbee-ruby/packet.rb', line 24 def self.checksum bytes 255 - bytes.reduce(&:+) % 256 end |
.from_byte_enum(bytes) ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/xbee-ruby/packet.rb', line 67 def self.from_byte_enum bytes begin loop until bytes.next == Packet::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 != Packet::checksum(data) then raise IOError, "Excpected checksum to be 0x#{Packet::checksum(data).to_s 16} but was 0x#{crc.to_s 16}" end Packet.new data end |
.from_bytes(bytes) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/xbee-ruby/packet.rb', line 39 def self.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 self.new data[3..-2] end |
.next_unescaped_byte(bytes) ⇒ Object
58 59 60 61 62 63 64 65 |
# File 'lib/xbee-ruby/packet.rb', line 58 def self.next_unescaped_byte bytes byte = bytes.next if byte == ESCAPE then 0x20 ^ bytes.next else byte end end |
.special_byte?(byte) ⇒ Boolean
20 21 22 |
# File 'lib/xbee-ruby/packet.rb', line 20 def self.special_byte? byte [START_BYTE, ESCAPE, XON, XOFF].include? byte end |
.unescape(bytes) ⇒ Object
28 29 30 31 32 33 34 35 36 37 |
# File 'lib/xbee-ruby/packet.rb', line 28 def self.unescape bytes bytes.inject([]) do |unescaped, b| if unescaped.last == ESCAPE unescaped.pop unescaped << (0x20 ^ b) else unescaped << b end end end |
Instance Method Details
#==(other) ⇒ Object
119 120 121 |
# File 'lib/xbee-ruby/packet.rb', line 119 def == other self.data == other.data end |
#bytes ⇒ Object
106 107 108 |
# File 'lib/xbee-ruby/packet.rb', line 106 def bytes [START_BYTE, length >> 8, length & 0xff] + @data + [checksum] end |
#bytes_escaped ⇒ Object
110 111 112 113 114 115 116 117 |
# File 'lib/xbee-ruby/packet.rb', line 110 def bytes_escaped [START_BYTE] + bytes[1..-1].flat_map { |b| if Packet.special_byte?(b) then [ESCAPE, 0x20 ^ b] else b end } end |
#checksum ⇒ Object
102 103 104 |
# File 'lib/xbee-ruby/packet.rb', line 102 def checksum Packet.checksum @data end |
#data ⇒ Object
94 95 96 |
# File 'lib/xbee-ruby/packet.rb', line 94 def data @data end |
#length ⇒ Object
98 99 100 |
# File 'lib/xbee-ruby/packet.rb', line 98 def length @data.length end |
#to_s ⇒ Object
123 124 125 |
# File 'lib/xbee-ruby/packet.rb', line 123 def to_s 'Packet [' + data.map { |b| "0x#{b.to_s 16}" }.join(', ') + ']' end |