paho-mqtt 0.0.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,20 @@
1
+ # encoding: BINARY
2
+
3
+ module PahoMqtt
4
+ module Packet
5
+ class Disconnect < PahoMqtt::Packet::Base
6
+ # Create a new Client Disconnect packet
7
+ def initialize(args={})
8
+ super(args)
9
+ end
10
+
11
+ # Check the body
12
+ def parse_body(buffer)
13
+ super(buffer)
14
+ unless buffer.empty?
15
+ raise "Extra bytes at end of Disconnect packet"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: BINARY
2
+
3
+ module PahoMqtt
4
+ module Packet
5
+ class Pingreq < PahoMqtt::Packet::Base
6
+ # Create a new Ping Request packet
7
+ def initialize(args={})
8
+ super(args)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: BINARY
2
+
3
+ module PahoMqtt
4
+ module Packet
5
+ class Pingresp < PahoMqtt::Packet::Base
6
+ # Create a new Ping Response packet
7
+ def initialize(args={})
8
+ super(args)
9
+ end
10
+
11
+ # Check the body
12
+ def parse_body(buffer)
13
+ super(buffer)
14
+ unless buffer.empty?
15
+ raise "Extra bytes at end of Ping Response packet"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: BINARY
2
+
3
+ module PahoMqtt
4
+ module Packet
5
+ class Puback < PahoMqtt::Packet::Base
6
+ # Get serialisation of packet's body
7
+ def encode_body
8
+ encode_short(@id)
9
+ end
10
+
11
+ # Parse the body (variable header and payload) of a packet
12
+ def parse_body(buffer)
13
+ super(buffer)
14
+ @id = shift_short(buffer)
15
+ unless buffer.empty?
16
+ raise "Extra bytes at end of Publish Acknowledgment packet"
17
+ end
18
+ end
19
+
20
+ # Returns a human readable string, summarising the properties of the packet
21
+ def inspect
22
+ "\#<#{self.class}: 0x%2.2X>" % id
23
+ end
24
+ end
25
+ end
26
+ end
27
+
@@ -0,0 +1,26 @@
1
+ # encoding: BINARY
2
+
3
+ module PahoMqtt
4
+ module Packet
5
+ class Pubcomp < PahoMqtt::Packet::Base
6
+ # Get serialisation of packet's body
7
+ def encode_body
8
+ encode_short(@id)
9
+ end
10
+
11
+ # Parse the body (variable header and payload) of a packet
12
+ def parse_body(buffer)
13
+ super(buffer)
14
+ @id = shift_short(buffer)
15
+ unless buffer.empty?
16
+ raise "Extra bytes at end of Publish Complete packet"
17
+ end
18
+ end
19
+
20
+ # Returns a human readable string, summarising the properties of the packet
21
+ def inspect
22
+ "\#<#{self.class}: 0x%2.2X>" % id
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,127 @@
1
+ # encoding: BINARY
2
+
3
+ module PahoMqtt
4
+ module Packet
5
+ class Publish < PahoMqtt::Packet::Base
6
+ # Duplicate delivery flag
7
+ attr_accessor :duplicate
8
+
9
+ # Retain flag
10
+ attr_accessor :retain
11
+
12
+ # Quality of Service level (0, 1, 2)
13
+ attr_accessor :qos
14
+
15
+ # The topic name to publish to
16
+ attr_accessor :topic
17
+
18
+ # The data to be published
19
+ attr_accessor :payload
20
+
21
+ # Default attribute values
22
+ ATTR_DEFAULTS = {
23
+ :topic => nil,
24
+ :payload => ''
25
+ }
26
+
27
+ # Create a new Publish packet
28
+ def initialize(args={})
29
+ super(ATTR_DEFAULTS.merge(args))
30
+ end
31
+
32
+ def duplicate
33
+ @flags[3]
34
+ end
35
+
36
+ # Set the DUP flag (true/false)
37
+ def duplicate=(arg)
38
+ if arg.kind_of?(Integer)
39
+ @flags[3] = (arg == 0x1)
40
+ else
41
+ @flags[3] = arg
42
+ end
43
+ end
44
+
45
+ def retain
46
+ @flags[0]
47
+ end
48
+
49
+ # Set the retain flag (true/false)
50
+ def retain=(arg)
51
+ if arg.kind_of?(Integer)
52
+ @flags[0] = (arg == 0x1)
53
+ else
54
+ @flags[0] = arg
55
+ end
56
+ end
57
+
58
+ def qos
59
+ (@flags[1] ? 0x01 : 0x00) | (@flags[2] ? 0x02 : 0x00)
60
+ end
61
+
62
+ # Set the Quality of Service level (0/1/2)
63
+ def qos=(arg)
64
+ @qos = arg.to_i
65
+ if @qos < 0 or @qos > 2
66
+ raise "Invalid QoS value: #{@qos}"
67
+ else
68
+ @flags[1] = (arg & 0x01 == 0x01)
69
+ @flags[2] = (arg & 0x02 == 0x02)
70
+ end
71
+ end
72
+
73
+ # Get serialisation of packet's body
74
+ def encode_body
75
+ body = ''
76
+ if @topic.nil? or @topic.to_s.empty?
77
+ raise "Invalid topic name when serialising packet"
78
+ end
79
+ body += encode_string(@topic)
80
+ body += encode_short(@id) unless qos == 0
81
+ body += payload.to_s.dup.force_encoding('ASCII-8BIT')
82
+ return body
83
+ end
84
+
85
+ # Parse the body (variable header and payload) of a Publish packet
86
+ def parse_body(buffer)
87
+ super(buffer)
88
+ @topic = shift_string(buffer)
89
+ @id = shift_short(buffer) unless qos == 0
90
+ @payload = buffer
91
+ end
92
+
93
+ # Check that fixed header flags are valid for this packet type
94
+ # @private
95
+ def validate_flags
96
+ if qos == 3
97
+ raise "Invalid packet: QoS value of 3 is not allowed"
98
+ end
99
+ if qos == 0 and duplicate
100
+ raise "Invalid packet: DUP cannot be set for QoS 0"
101
+ end
102
+ end
103
+
104
+ # Returns a human readable string, summarising the properties of the packet
105
+ def inspect
106
+ "\#<#{self.class}: " +
107
+ "d#{duplicate ? '1' : '0'}, " +
108
+ "q#{qos}, " +
109
+ "r#{retain ? '1' : '0'}, " +
110
+ "m#{id}, " +
111
+ "'#{topic}', " +
112
+ "#{inspect_payload}>"
113
+ end
114
+
115
+ protected
116
+
117
+ def inspect_payload
118
+ str = payload.to_s
119
+ if str.bytesize < 16 and str =~ /^[ -~]*$/
120
+ "'#{str}'"
121
+ else
122
+ "... (#{str.bytesize} bytes)"
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,26 @@
1
+ # encoding: BINARY
2
+
3
+ module PahoMqtt
4
+ module Packet
5
+ class Pubrec < PahoMqtt::Packet::Base
6
+ # Get serialisation of packet's body
7
+ def encode_body
8
+ encode_short(@id)
9
+ end
10
+
11
+ # Parse the body (variable header and payload) of a packet
12
+ def parse_body(buffer)
13
+ super(buffer)
14
+ @id = shift_short(buffer)
15
+ unless buffer.empty?
16
+ raise "Extra bytes at end of Publish Received packet"
17
+ end
18
+ end
19
+
20
+ # Returns a human readable string, summarising the properties of the packet
21
+ def inspect
22
+ "\#<#{self.class}: 0x%2.2X>" % id
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,44 @@
1
+ # encoding: BINARY
2
+
3
+ module PahoMqtt
4
+ module Packet
5
+ class Pubrel < PahoMqtt::Packet::Base
6
+ # Default attribute values
7
+ ATTR_DEFAULTS = {
8
+ :flags => [false, true, false, false],
9
+ }
10
+
11
+ # Create a new Pubrel packet
12
+ def initialize(args={})
13
+ super(ATTR_DEFAULTS.merge(args))
14
+ end
15
+
16
+ # Get serialisation of packet's body
17
+ def encode_body
18
+ encode_short(@id)
19
+ end
20
+
21
+ # Parse the body (variable header and payload) of a packet
22
+ def parse_body(buffer)
23
+ super(buffer)
24
+ @id = shift_short(buffer)
25
+ unless buffer.empty?
26
+ raise "Extra bytes at end of Publish Release packet"
27
+ end
28
+ end
29
+
30
+ # Check that fixed header flags are valid for this packet type
31
+ # @private
32
+ def validate_flags
33
+ if @flags != [false, true, false, false]
34
+ raise "Invalid flags in PUBREL packet header"
35
+ end
36
+ end
37
+
38
+ # Returns a human readable string, summarising the properties of the packet
39
+ def inspect
40
+ "\#<#{self.class}: 0x%2.2X>" % id
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,56 @@
1
+ # encoding: BINARY
2
+
3
+ module PahoMqtt
4
+ module Packet
5
+ class Suback < PahoMqtt::Packet::Base
6
+ # An array of return codes, ordered by the topics that were subscribed to
7
+ attr_accessor :return_codes
8
+
9
+ # Default attribute values
10
+ ATTR_DEFAULTS = {
11
+ :return_codes => [],
12
+ }
13
+
14
+ # Create a new Subscribe Acknowledgment packet
15
+ def initialize(args={})
16
+ super(ATTR_DEFAULTS.merge(args))
17
+ end
18
+
19
+ # Set the granted QoS value for each of the topics that were subscribed to
20
+ # Can either be an integer or an array or integers.
21
+ def return_codes=(value)
22
+ if value.is_a?(Array)
23
+ @return_codes = value
24
+ elsif value.is_a?(Integer)
25
+ @return_codes = [value]
26
+ else
27
+ raise "return_codes should be an integer or an array of return codes"
28
+ end
29
+ end
30
+
31
+ # Get serialisation of packet's body
32
+ def encode_body
33
+ if @return_codes.empty?
34
+ raise "no granted QoS given when serialising packet"
35
+ end
36
+ body = encode_short(@id)
37
+ return_codes.each { |qos| body += encode_bytes(qos) }
38
+ return body
39
+ end
40
+
41
+ # Parse the body (variable header and payload) of a packet
42
+ def parse_body(buffer)
43
+ super(buffer)
44
+ @id = shift_short(buffer)
45
+ while(buffer.bytesize>0)
46
+ @return_codes << shift_byte(buffer)
47
+ end
48
+ end
49
+
50
+ # Returns a human readable string, summarising the properties of the packet
51
+ def inspect
52
+ "\#<#{self.class}: 0x%2.2X, rc=%s>" % [id, return_codes.map{|rc| "0x%2.2X" % rc}.join(',')]
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,104 @@
1
+ # encoding: BINARY
2
+
3
+ module PahoMqtt
4
+ module Packet
5
+ class Subscribe < PahoMqtt::Packet::Base
6
+ # One or more topic filters to subscribe to
7
+ attr_accessor :topics
8
+
9
+ # Default attribute values
10
+ ATTR_DEFAULTS = {
11
+ :topics => [],
12
+ :flags => [false, true, false, false],
13
+ }
14
+
15
+ # Create a new Subscribe packet
16
+ def initialize(args={})
17
+ super(ATTR_DEFAULTS.merge(args))
18
+ end
19
+
20
+ # Set one or more topic filters for the Subscribe packet
21
+ # The topics parameter should be one of the following:
22
+ # * String: subscribe to one topic with QoS 0
23
+ # * Array: subscribe to multiple topics with QoS 0
24
+ # * Hash: subscribe to multiple topics where the key is the topic and the value is the QoS level
25
+ #
26
+ # For example:
27
+ # packet.topics = 'a/b'
28
+ # packet.topics = ['a/b', 'c/d']
29
+ # packet.topics = [['a/b',0], ['c/d',1]]
30
+ # packet.topics = {'a/b' => 0, 'c/d' => 1}
31
+ #
32
+ def topics=(value)
33
+ # Get input into a consistent state
34
+ if value.is_a?(Array)
35
+ input = value.flatten
36
+ else
37
+ input = [value]
38
+ end
39
+
40
+ @topics = []
41
+ while(input.length>0)
42
+ item = input.shift
43
+ if item.is_a?(Hash)
44
+ # Convert hash into an ordered array of arrays
45
+ @topics += item.sort
46
+ elsif item.is_a?(String)
47
+ # Peek at the next item in the array, and remove it if it is an integer
48
+ if input.first.is_a?(Integer)
49
+ qos = input.shift
50
+ @topics << [item,qos]
51
+ else
52
+ @topics << [item,0]
53
+ end
54
+ else
55
+ # Meh?
56
+ raise "Invalid topics input: #{value.inspect}"
57
+ end
58
+ end
59
+ @topics
60
+ end
61
+
62
+ # Get serialisation of packet's body
63
+ def encode_body
64
+ if @topics.empty?
65
+ raise "no topics given when serialising packet"
66
+ end
67
+ body = encode_short(@id)
68
+ topics.each do |item|
69
+ body += encode_string(item[0])
70
+ body += encode_bytes(item[1])
71
+ end
72
+ return body
73
+ end
74
+
75
+ # Parse the body (variable header and payload) of a packet
76
+ def parse_body(buffer)
77
+ super(buffer)
78
+ @id = shift_short(buffer)
79
+ @topics = []
80
+ while(buffer.bytesize>0)
81
+ topic_name = shift_string(buffer)
82
+ topic_qos = shift_byte(buffer)
83
+ @topics << [topic_name,topic_qos]
84
+ end
85
+ end
86
+
87
+ # Check that fixed header flags are valid for this packet type
88
+ # @private
89
+ def validate_flags
90
+ if @flags != [false, true, false, false]
91
+ raise "Invalid flags in SUBSCRIBE packet header"
92
+ end
93
+ end
94
+
95
+ # Returns a human readable string, summarising the properties of the packet
96
+ def inspect
97
+ _str = "\#<#{self.class}: 0x%2.2X, %s>" % [
98
+ id,
99
+ topics.map {|t| "'#{t[0]}':#{t[1]}"}.join(', ')
100
+ ]
101
+ end
102
+ end
103
+ end
104
+ end