class MQTT::SN::Packet
Class representing a MQTT::SN Packet Performs binary encoding and decoding of headers
Constants
- DEFAULTS
Attributes
clean_session[RW]
duplicate[RW]
qos[RW]
request_will[RW]
retain[RW]
topic_id_type[RW]
Public Class Methods
new(args={})
click to toggle source
Create a new empty packet
# File lib/mqttbridge/sn/packet.rb, line 42 def initialize(args={}) update_attributes(self.class::DEFAULTS.merge(args)) end
parse(buffer)
click to toggle source
Parse buffer into new packet object
# File lib/mqttbridge/sn/packet.rb, line 17 def self.parse(buffer) # Parse the fixed header (length and type) length,type_id,body = buffer.unpack('CCa*') if length == 1 length,type_id,body = buffer.unpack('xnCa*') end # Double-check the length if buffer.length != length raise ProtocolException.new("Length of packet is not the same as the length header") end packet_class = PACKET_TYPES[type_id] if packet_class.nil? raise ProtocolException.new("Invalid packet type identifier: #{type_id}") end # Create a new packet object packet = packet_class.new packet.parse_body(body) return packet end
Public Instance Methods
parse_body(buffer)
click to toggle source
# File lib/mqttbridge/sn/packet.rb, line 76 def parse_body(buffer) end
to_s()
click to toggle source
Serialise the packet
# File lib/mqttbridge/sn/packet.rb, line 61 def to_s # Get the packet's variable header and payload body = self.encode_body # Build up the body length field bytes body_length = body.length if body_length > 65531 raise "MQTT-SN Packet is too big, maximum packet body size is 65531" elsif body_length > 253 [0x01, body_length + 4, type_id].pack('CnC') + body else [body_length + 2, type_id].pack('CC') + body end end
type_id()
click to toggle source
Get the identifer for this packet type
# File lib/mqttbridge/sn/packet.rb, line 53 def type_id PACKET_TYPES.each_pair do |key, value| return key if self.class == value end raise "Invalid packet type: #{self.class}" end
update_attributes(attr={})
click to toggle source
# File lib/mqttbridge/sn/packet.rb, line 46 def update_attributes(attr={}) attr.each_pair do |k,v| send("#{k}=", v) end end
Protected Instance Methods
encode_body()
click to toggle source
Get serialisation of packet's body (variable header and payload)
# File lib/mqttbridge/sn/packet.rb, line 101 def encode_body '' # No body by default end
encode_flags()
click to toggle source
# File lib/mqttbridge/sn/packet.rb, line 105 def encode_flags flags = 0x00 flags += 0x80 if duplicate case qos when -1 flags += 0x60 when 1 flags += 0x20 when 2 flags += 0x40 end flags += 0x10 if retain flags += 0x08 if request_will flags += 0x04 if clean_session case topic_id_type when :normal flags += 0x0 when :predefined flags += 0x1 when :short flags += 0x2 end return flags end
encode_topic()
click to toggle source
Used where a field can either be a Topic Id or a Topic Name (the Subscribe and Unsubscribe packet types)
# File lib/mqttbridge/sn/packet.rb, line 155 def encode_topic case topic_id_type when :normal topic_name when :short unless topic_name.nil? topic_name else topic_id end when :predefined [topic_id].pack('n') end end
encode_topic_id()
click to toggle source
# File lib/mqttbridge/sn/packet.rb, line 130 def encode_topic_id if topic_id_type == :short unless topic_id.is_a?(String) raise "topic_id must be an String for type #{topic_id_type}" end (topic_id[0].ord << 8) + topic_id[1].ord else unless topic_id.is_a?(Integer) raise "topic_id must be an Integer for type #{topic_id_type}" end topic_id end end
parse_flags(flags)
click to toggle source
# File lib/mqttbridge/sn/packet.rb, line 81 def parse_flags(flags) self.duplicate = ((flags & 0x80) >> 7) == 0x01 self.qos = (flags & 0x60) >> 5 self.qos = -1 if self.qos == 3 self.retain = ((flags & 0x10) >> 4) == 0x01 self.request_will = ((flags & 0x08) >> 3) == 0x01 self.clean_session = ((flags & 0x04) >> 2) == 0x01 case (flags & 0x03) when 0x0 self.topic_id_type = :normal when 0x1 self.topic_id_type = :predefined when 0x2 self.topic_id_type = :short else self.topic_id_type = nil end end
parse_topic(topic)
click to toggle source
Used where a field can either be a Topic Id or a Topic Name (the Subscribe and Unsubscribe packet types)
# File lib/mqttbridge/sn/packet.rb, line 172 def parse_topic(topic) case topic_id_type when :normal self.topic_name = topic when :short self.topic_name = topic self.topic_id = topic when :predefined self.topic_id = topic.unpack('n').first end end
parse_topic_id(topic_id)
click to toggle source
# File lib/mqttbridge/sn/packet.rb, line 144 def parse_topic_id(topic_id) if topic_id_type == :short int = topic_id.to_i self.topic_id = [(int >> 8) & 0xFF, int & 0xFF].pack('CC') else self.topic_id = topic_id end end