lib/mqtt/packet.rb in mqtt-0.1.0 vs lib/mqtt/packet.rb in mqtt-0.2.0

- old
+ new

@@ -3,16 +3,24 @@ module MQTT # Class representing a MQTT Packet # Performs binary encoding and decoding of headers class MQTT::Packet - attr_reader :duplicate # Duplicate delivery flag - attr_reader :retain # Retain flag - attr_reader :qos # Quality of Service level - attr_reader :body_length # The length of the parsed packet body + # Duplicate delivery flag + attr_reader :duplicate - DEFAULTS = { + # Retain flag + attr_reader :retain + + # Quality of Service level (0, 1, 2) + attr_reader :qos + + # The length of the parsed packet body + attr_reader :body_length + + # Default attribute values + ATTR_DEFAULTS = { :duplicate => false, :qos => 0, :retain => false, :body_length => nil } @@ -103,13 +111,14 @@ ) end # Create a new empty packet def initialize(args={}) - update_attributes(DEFAULTS.merge(args)) + update_attributes(ATTR_DEFAULTS.merge(args)) end + # Set packet attributes from a hash of attribute names and values def update_attributes(attr={}) attr.each_pair do |k,v| send("#{k}=", v) end end @@ -199,10 +208,11 @@ # Convert header to binary and add on body header.pack('C*') + body end + # Returns a human readable string def inspect "\#<#{self.class}>" end protected @@ -268,23 +278,30 @@ ## PACKET SUBCLASSES ## # Class representing an MQTT Publish message class Publish < MQTT::Packet + # The topic name to publish to attr_accessor :topic + + # Identifier for an individual publishing flow + # Only required in PUBLISH Packets where the QoS level is 1 or 2 attr_accessor :message_id + + # The data to be published attr_accessor :payload - DEFAULTS = { + # Default attribute values + ATTR_DEFAULTS = { :topic => nil, :message_id => 0, :payload => '' } # Create a new Publish packet def initialize(args={}) - super(DEFAULTS.merge(args)) + super(ATTR_DEFAULTS.merge(args)) end # Get serialisation of packet's body def encode_body body = '' @@ -303,10 +320,11 @@ @topic = shift_string(buffer) @message_id = shift_short(buffer) unless qos == 0 @payload = buffer end + # Returns a human readable string, summarising the properties of the packet def inspect "\#<#{self.class}: " + "d#{duplicate ? '1' : '0'}, " + "q#{qos}, " + "r#{retain ? '1' : '0'}, " + @@ -326,27 +344,45 @@ end end # Class representing an MQTT Connect Packet class Connect < MQTT::Packet + # The name of the protocol (defaults to MQIsdp) attr_accessor :protocol_name + + # The version number of the protocol (defaults to 3) attr_accessor :protocol_version + + # The client identifier string attr_accessor :client_id + + # Set to false to keep a persistent session with the broker attr_accessor :clean_session + + # Period the broker should keep connection open for between pings attr_accessor :keep_alive + + # The topic name to send the Will message to attr_accessor :will_topic + + # The QoS level to send the Will message as attr_accessor :will_qos + + # Set to true to make the Will message retained attr_accessor :will_retain + + # The payload of the Will message attr_accessor :will_payload + + # The username for authenticating with the broker attr_accessor :username + + # The password for authenticating with the broker attr_accessor :password - # OLD deprecated clean_start - alias :clean_start :clean_session - alias :clean_start= :clean_session= - - DEFAULTS = { + # Default attribute values + ATTR_DEFAULTS = { :protocol_name => 'MQIsdp', :protocol_version => 0x03, :client_id => nil, :clean_session => true, :keep_alive => 15, @@ -358,11 +394,11 @@ :password => nil, } # Create a new Client Connect packet def initialize(args={}) - super(DEFAULTS.merge(args)) + super(ATTR_DEFAULTS.merge(args)) end # Get serialisation of packet's body def encode_body body = '' @@ -434,10 +470,11 @@ if ((@connect_flags & 0x40) >> 6) == 0x01 and buffer.bytesize > 0 @password = shift_string(buffer) end end + # Returns a human readable string, summarising the properties of the packet def inspect str = "\#<#{self.class}: " str += "keep_alive=#{keep_alive}" str += ", clean" if clean_session str += ", client_id='#{client_id}'" @@ -447,16 +484,19 @@ end end # Class representing an MQTT Connect Acknowledgment Packet class Connack < MQTT::Packet + # The return code (defaults to 0 for connection accepted) attr_accessor :return_code - DEFAULTS = {:return_code => 0x00} + # Default attribute values + ATTR_DEFAULTS = {:return_code => 0x00} + # Create a new Client Connect packet def initialize(args={}) - super(DEFAULTS.merge(args)) + super(ATTR_DEFAULTS.merge(args)) end # Get a string message corresponding to a return code def return_msg case return_code @@ -493,23 +533,27 @@ unless buffer.empty? raise ProtocolException.new("Extra bytes at end of Connect Acknowledgment packet") end end + # Returns a human readable string, summarising the properties of the packet def inspect "\#<#{self.class}: 0x%2.2X>" % return_code end end # Class representing an MQTT Publish Acknowledgment packet class Puback < MQTT::Packet + # Identifier for an individual publishing flow attr_accessor :message_id - DEFAULTS = {:message_id => 0} + # Default attribute values + ATTR_DEFAULTS = {:message_id => 0} + # Create a new Publish Acknowledgment packet def initialize(args={}) - super(DEFAULTS.merge(args)) + super(ATTR_DEFAULTS.merge(args)) end # Get serialisation of packet's body def encode_body encode_short(@message_id) @@ -522,23 +566,27 @@ unless buffer.empty? raise ProtocolException.new("Extra bytes at end of Publish Acknowledgment packet") end end + # Returns a human readable string, summarising the properties of the packet def inspect "\#<#{self.class}: 0x%2.2X>" % message_id end end # Class representing an MQTT Publish Received packet class Pubrec < MQTT::Packet + # Identifier for an individual publishing flow attr_accessor :message_id - DEFAULTS = {:message_id => 0} + # Default attribute values + ATTR_DEFAULTS = {:message_id => 0} + # Create a new Publish Recieved packet def initialize(args={}) - super(DEFAULTS.merge(args)) + super(ATTR_DEFAULTS.merge(args)) end # Get serialisation of packet's body def encode_body encode_short(@message_id) @@ -551,23 +599,27 @@ unless buffer.empty? raise ProtocolException.new("Extra bytes at end of Publish Received packet") end end + # Returns a human readable string, summarising the properties of the packet def inspect "\#<#{self.class}: 0x%2.2X>" % message_id end end # Class representing an MQTT Publish Release packet class Pubrel < MQTT::Packet + # Identifier for an individual publishing flow attr_accessor :message_id - DEFAULTS = {:message_id => 0} + # Default attribute values + ATTR_DEFAULTS = {:message_id => 0} + # Create a new Publish Release packet def initialize(args={}) - super(DEFAULTS.merge(args)) + super(ATTR_DEFAULTS.merge(args)) end # Get serialisation of packet's body def encode_body encode_short(@message_id) @@ -580,23 +632,27 @@ unless buffer.empty? raise ProtocolException.new("Extra bytes at end of Publish Release packet") end end + # Returns a human readable string, summarising the properties of the packet def inspect "\#<#{self.class}: 0x%2.2X>" % message_id end end # Class representing an MQTT Publish Complete packet class Pubcomp < MQTT::Packet + # Identifier for an individual publishing flow attr_accessor :message_id - DEFAULTS = {:message_id => 0} + # Default attribute values + ATTR_DEFAULTS = {:message_id => 0} + # Create a new Publish Complete packet def initialize(args={}) - super(DEFAULTS.merge(args)) + super(ATTR_DEFAULTS.merge(args)) end # Get serialisation of packet's body def encode_body encode_short(@message_id) @@ -609,24 +665,30 @@ unless buffer.empty? raise ProtocolException.new("Extra bytes at end of Publish Complete packet") end end + # Returns a human readable string, summarising the properties of the packet def inspect "\#<#{self.class}: 0x%2.2X>" % message_id end end # Class representing an MQTT Client Subscribe packet class Subscribe < MQTT::Packet + # Identifier for an individual publishing flow attr_accessor :message_id + + # One or more topic names to subscribe to attr_reader :topics - DEFAULTS = {:message_id => 0} + # Default attribute values + ATTR_DEFAULTS = {:message_id => 0} + # Create a new Subscribe packet def initialize(args={}) - super(DEFAULTS.merge(args)) + super(ATTR_DEFAULTS.merge(args)) @topics ||= [] @qos = 1 # Force a QOS of 1 end # Set one or more topics for the Subscrible packet @@ -694,27 +756,33 @@ topic_qos = shift_byte(buffer) @topics << [topic_name,topic_qos] end end + # Returns a human readable string, summarising the properties of the packet def inspect - str = "\#<#{self.class}: 0x%2.2X, %s>" % [ + _str = "\#<#{self.class}: 0x%2.2X, %s>" % [ message_id, topics.map {|t| "'#{t[0]}':#{t[1]}"}.join(', ') ] end end # Class representing an MQTT Subscribe Acknowledgment packet class Suback < MQTT::Packet + # Identifier to tie the Subscribe request to the Suback response attr_accessor :message_id + + # The QoS level that was granted for the subscribe request attr_reader :granted_qos - DEFAULTS = {:message_id => 0} + # Default attribute values + ATTR_DEFAULTS = {:message_id => 0} + # Create a new Subscribe Acknowledgment packet def initialize(args={}) - super(DEFAULTS.merge(args)) + super(ATTR_DEFAULTS.merge(args)) @granted_qos ||= [] end # Set the granted QOS value for each of the topics that were subscribed to # Can either be an integer or an array or integers. @@ -745,28 +813,35 @@ while(buffer.bytesize>0) @granted_qos << shift_byte(buffer) end end + # Returns a human readable string, summarising the properties of the packet def inspect "\#<#{self.class}: 0x%2.2X, qos=%s>" % [message_id, granted_qos.join(',')] end end # Class representing an MQTT Client Unsubscribe packet class Unsubscribe < MQTT::Packet + # One or more topics to unsubscribe from attr_reader :topics + + # Identifier to tie the Unsubscribe request to the Unsuback response attr_accessor :message_id - DEFAULTS = {:message_id => 0} + # Default attribute values + ATTR_DEFAULTS = {:message_id => 0} + # Create a new Unsubscribe packet def initialize(args={}) - super(DEFAULTS.merge(args)) + super(ATTR_DEFAULTS.merge(args)) @topics ||= [] @qos = 1 # Force a QOS of 1 end + # Set one or more topics to unsubscribe from def topics=(value) if value.is_a?(Array) @topics = value else @topics = [value] @@ -790,26 +865,30 @@ while(buffer.bytesize>0) @topics << shift_string(buffer) end end + # Returns a human readable string, summarising the properties of the packet def inspect - str = "\#<#{self.class}: 0x%2.2X, %s>" % [ + "\#<#{self.class}: 0x%2.2X, %s>" % [ message_id, topics.map {|t| "'#{t}'"}.join(', ') ] end end # Class representing an MQTT Unsubscribe Acknowledgment packet class Unsuback < MQTT::Packet + # Identifier to tie the Unsubscribe request to the Unsuback response attr_accessor :message_id - DEFAULTS = {:message_id => 0} + # Default attribute values + ATTR_DEFAULTS = {:message_id => 0} + # Create a new Unsubscribe Acknowledgment packet def initialize(args={}) - super(DEFAULTS.merge(args)) + super(ATTR_DEFAULTS.merge(args)) end # Get serialisation of packet's body def encode_body encode_short(@message_id) @@ -822,9 +901,10 @@ unless buffer.empty? raise ProtocolException.new("Extra bytes at end of Unsubscribe Acknowledgment packet") end end + # Returns a human readable string, summarising the properties of the packet def inspect "\#<#{self.class}: 0x%2.2X>" % message_id end end