mqtt 0.4.0 → 0.6.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.
@@ -1,177 +1,174 @@
1
1
  # encoding: BINARY
2
2
 
3
- module MQTT::SN
3
+ module MQTT
4
+ module SN
5
+ # Class representing a MQTT::SN Packet
6
+ # Performs binary encoding and decoding of headers
7
+ class Packet
8
+ attr_accessor :duplicate # Duplicate delivery flag
9
+ attr_accessor :qos # Quality of Service level
10
+ attr_accessor :retain # Retain flag
11
+ attr_accessor :request_will # Request that gateway prompts for Will
12
+ attr_accessor :clean_session # When true, subscriptions are deleted after disconnect
13
+ attr_accessor :topic_id_type # One of :normal, :predefined or :short
14
+
15
+ DEFAULTS = {}
16
+
17
+ # Parse buffer into new packet object
18
+ def self.parse(buffer)
19
+ # Parse the fixed header (length and type)
20
+ length, type_id, body = buffer.unpack('CCa*')
21
+ length, type_id, body = buffer.unpack('xnCa*') if length == 1
22
+
23
+ # Double-check the length
24
+ if buffer.length != length
25
+ raise ProtocolException, 'Length of packet is not the same as the length header'
26
+ end
4
27
 
5
- # Class representing a MQTT::SN Packet
6
- # Performs binary encoding and decoding of headers
7
- class Packet
8
- attr_accessor :duplicate # Duplicate delivery flag
9
- attr_accessor :qos # Quality of Service level
10
- attr_accessor :retain # Retain flag
11
- attr_accessor :request_will # Request that gateway prompts for Will
12
- attr_accessor :clean_session # When true, subscriptions are deleted after disconnect
13
- attr_accessor :topic_id_type # One of :normal, :predefined or :short
28
+ packet_class = PACKET_TYPES[type_id]
29
+ if packet_class.nil?
30
+ raise ProtocolException, "Invalid packet type identifier: #{type_id}"
31
+ end
14
32
 
15
- DEFAULTS = {}
33
+ # Create a new packet object
34
+ packet = packet_class.new
35
+ packet.parse_body(body)
16
36
 
17
- # Parse buffer into new packet object
18
- def self.parse(buffer)
19
- # Parse the fixed header (length and type)
20
- length,type_id,body = buffer.unpack('CCa*')
21
- if length == 1
22
- length,type_id,body = buffer.unpack('xnCa*')
37
+ packet
23
38
  end
24
39
 
25
- # Double-check the length
26
- if buffer.length != length
27
- raise ProtocolException.new("Length of packet is not the same as the length header")
40
+ # Create a new empty packet
41
+ def initialize(args = {})
42
+ update_attributes(self.class::DEFAULTS.merge(args))
28
43
  end
29
44
 
30
- packet_class = PACKET_TYPES[type_id]
31
- if packet_class.nil?
32
- raise ProtocolException.new("Invalid packet type identifier: #{type_id}")
45
+ def update_attributes(attr = {})
46
+ attr.each_pair do |k, v|
47
+ send("#{k}=", v)
48
+ end
33
49
  end
34
50
 
35
- # Create a new packet object
36
- packet = packet_class.new
37
- packet.parse_body(body)
51
+ # Get the identifer for this packet type
52
+ def type_id
53
+ PACKET_TYPES.each_pair do |key, value|
54
+ return key if self.class == value
55
+ end
56
+ raise "Invalid packet type: #{self.class}"
57
+ end
38
58
 
39
- return packet
40
- end
59
+ # Serialise the packet
60
+ def to_s
61
+ # Get the packet's variable header and payload
62
+ body = encode_body
41
63
 
42
- # Create a new empty packet
43
- def initialize(args={})
44
- update_attributes(self.class::DEFAULTS.merge(args))
45
- end
64
+ # Build up the body length field bytes
65
+ body_length = body.length
66
+ raise 'MQTT-SN Packet is too big, maximum packet body size is 65531' if body_length > 65_531
46
67
 
47
- def update_attributes(attr={})
48
- attr.each_pair do |k,v|
49
- send("#{k}=", v)
68
+ if body_length > 253
69
+ [0x01, body_length + 4, type_id].pack('CnC') + body
70
+ else
71
+ [body_length + 2, type_id].pack('CC') + body
72
+ end
50
73
  end
51
- end
52
74
 
53
- # Get the identifer for this packet type
54
- def type_id
55
- PACKET_TYPES.each_pair do |key, value|
56
- return key if self.class == value
57
- end
58
- raise "Invalid packet type: #{self.class}"
59
- end
75
+ def parse_body(buffer); end
60
76
 
61
- # Serialise the packet
62
- def to_s
63
- # Get the packet's variable header and payload
64
- body = self.encode_body
77
+ protected
65
78
 
66
- # Build up the body length field bytes
67
- body_length = body.length
68
- if body_length > 65531
69
- raise "MQTT-SN Packet is too big, maximum packet body size is 65531"
70
- elsif body_length > 253
71
- [0x01, body_length + 4, type_id].pack('CnC') + body
72
- else
73
- [body_length + 2, type_id].pack('CC') + body
74
- end
75
- end
76
-
77
- def parse_body(buffer)
78
- end
79
+ def parse_flags(flags)
80
+ self.duplicate = ((flags & 0x80) >> 7) == 0x01
81
+ self.qos = (flags & 0x60) >> 5
82
+ self.qos = -1 if qos == 3
83
+ self.retain = ((flags & 0x10) >> 4) == 0x01
84
+ self.request_will = ((flags & 0x08) >> 3) == 0x01
85
+ self.clean_session = ((flags & 0x04) >> 2) == 0x01
79
86
 
80
- protected
81
-
82
- def parse_flags(flags)
83
- self.duplicate = ((flags & 0x80) >> 7) == 0x01
84
- self.qos = (flags & 0x60) >> 5
85
- self.qos = -1 if self.qos == 3
86
- self.retain = ((flags & 0x10) >> 4) == 0x01
87
- self.request_will = ((flags & 0x08) >> 3) == 0x01
88
- self.clean_session = ((flags & 0x04) >> 2) == 0x01
89
- case (flags & 0x03)
90
- when 0x0
91
- self.topic_id_type = :normal
92
- when 0x1
93
- self.topic_id_type = :predefined
94
- when 0x2
95
- self.topic_id_type = :short
96
- else
97
- self.topic_id_type = nil
87
+ self.topic_id_type =
88
+ case (flags & 0x03)
89
+ when 0x0
90
+ :normal
91
+ when 0x1
92
+ :predefined
93
+ when 0x2
94
+ :short
95
+ end
98
96
  end
99
- end
100
97
 
101
- # Get serialisation of packet's body (variable header and payload)
102
- def encode_body
103
- '' # No body by default
104
- end
98
+ # Get serialisation of packet's body (variable header and payload)
99
+ def encode_body
100
+ '' # No body by default
101
+ end
105
102
 
106
- def encode_flags
107
- flags = 0x00
108
- flags += 0x80 if duplicate
109
- case qos
103
+ def encode_flags
104
+ flags = 0x00
105
+ flags += 0x80 if duplicate
106
+ case qos
110
107
  when -1
111
108
  flags += 0x60
112
109
  when 1
113
110
  flags += 0x20
114
111
  when 2
115
112
  flags += 0x40
116
- end
117
- flags += 0x10 if retain
118
- flags += 0x08 if request_will
119
- flags += 0x04 if clean_session
120
- case topic_id_type
113
+ end
114
+ flags += 0x10 if retain
115
+ flags += 0x08 if request_will
116
+ flags += 0x04 if clean_session
117
+ case topic_id_type
121
118
  when :normal
122
119
  flags += 0x0
123
120
  when :predefined
124
121
  flags += 0x1
125
122
  when :short
126
123
  flags += 0x2
124
+ end
125
+ flags
127
126
  end
128
- return flags
129
- end
130
127
 
131
- def encode_topic_id
132
- if topic_id_type == :short
133
- unless topic_id.is_a?(String)
134
- raise "topic_id must be an String for type #{topic_id_type}"
135
- end
136
- (topic_id[0].ord << 8) + topic_id[1].ord
137
- else
138
- unless topic_id.is_a?(Integer)
139
- raise "topic_id must be an Integer for type #{topic_id_type}"
128
+ def encode_topic_id
129
+ if topic_id_type == :short
130
+ unless topic_id.is_a?(String)
131
+ raise "topic_id must be an String for type #{topic_id_type}"
132
+ end
133
+ (topic_id[0].ord << 8) + topic_id[1].ord
134
+ else
135
+ unless topic_id.is_a?(Integer)
136
+ raise "topic_id must be an Integer for type #{topic_id_type}"
137
+ end
138
+ topic_id
140
139
  end
141
- topic_id
142
140
  end
143
- end
144
141
 
145
- def parse_topic_id(topic_id)
146
- if topic_id_type == :short
147
- int = topic_id.to_i
148
- self.topic_id = [(int >> 8) & 0xFF, int & 0xFF].pack('CC')
149
- else
150
- self.topic_id = topic_id
142
+ def parse_topic_id(topic_id)
143
+ if topic_id_type == :short
144
+ int = topic_id.to_i
145
+ self.topic_id = [(int >> 8) & 0xFF, int & 0xFF].pack('CC')
146
+ else
147
+ self.topic_id = topic_id
148
+ end
151
149
  end
152
- end
153
150
 
154
- # Used where a field can either be a Topic Id or a Topic Name
155
- # (the Subscribe and Unsubscribe packet types)
156
- def encode_topic
157
- case topic_id_type
151
+ # Used where a field can either be a Topic Id or a Topic Name
152
+ # (the Subscribe and Unsubscribe packet types)
153
+ def encode_topic
154
+ case topic_id_type
158
155
  when :normal
159
156
  topic_name
160
157
  when :short
161
- unless topic_name.nil?
162
- topic_name
163
- else
158
+ if topic_name.nil?
164
159
  topic_id
160
+ else
161
+ topic_name
165
162
  end
166
163
  when :predefined
167
164
  [topic_id].pack('n')
165
+ end
168
166
  end
169
- end
170
167
 
171
- # Used where a field can either be a Topic Id or a Topic Name
172
- # (the Subscribe and Unsubscribe packet types)
173
- def parse_topic(topic)
174
- case topic_id_type
168
+ # Used where a field can either be a Topic Id or a Topic Name
169
+ # (the Subscribe and Unsubscribe packet types)
170
+ def parse_topic(topic)
171
+ case topic_id_type
175
172
  when :normal
176
173
  self.topic_name = topic
177
174
  when :short
@@ -179,558 +176,518 @@ module MQTT::SN
179
176
  self.topic_id = topic
180
177
  when :predefined
181
178
  self.topic_id = topic.unpack('n').first
179
+ end
182
180
  end
183
- end
184
181
 
185
- class Advertise < Packet
186
- attr_accessor :gateway_id
187
- attr_accessor :duration
182
+ class Advertise < Packet
183
+ attr_accessor :gateway_id
184
+ attr_accessor :duration
188
185
 
189
- DEFAULTS = {
190
- :gateway_id => 0x00,
191
- :duration => 0
192
- }
186
+ DEFAULTS = {
187
+ :gateway_id => 0x00,
188
+ :duration => 0
189
+ }
193
190
 
194
- def encode_body
195
- [gateway_id, duration].pack('Cn')
196
- end
191
+ def encode_body
192
+ [gateway_id, duration].pack('Cn')
193
+ end
197
194
 
198
- def parse_body(buffer)
199
- self.gateway_id, self.duration = buffer.unpack('Cn')
195
+ def parse_body(buffer)
196
+ self.gateway_id, self.duration = buffer.unpack('Cn')
197
+ end
200
198
  end
201
- end
202
199
 
203
- class Searchgw < Packet
204
- attr_accessor :radius
205
- DEFAULTS = {
206
- :radius => 1
207
- }
200
+ class Searchgw < Packet
201
+ attr_accessor :radius
202
+ DEFAULTS = {
203
+ :radius => 1
204
+ }
208
205
 
209
- def encode_body
210
- [radius].pack('C')
211
- end
206
+ def encode_body
207
+ [radius].pack('C')
208
+ end
212
209
 
213
- def parse_body(buffer)
214
- self.radius, _ignore = buffer.unpack('C')
210
+ def parse_body(buffer)
211
+ self.radius, _ignore = buffer.unpack('C')
212
+ end
215
213
  end
216
- end
217
214
 
218
- class Gwinfo < Packet
219
- attr_accessor :gateway_id
220
- attr_accessor :gateway_address
221
- DEFAULTS = {
222
- :gateway_id => 0,
223
- :gateway_address => nil
224
- }
215
+ class Gwinfo < Packet
216
+ attr_accessor :gateway_id
217
+ attr_accessor :gateway_address
218
+ DEFAULTS = {
219
+ :gateway_id => 0,
220
+ :gateway_address => nil
221
+ }
225
222
 
226
- def encode_body
227
- [gateway_id,gateway_address].pack('Ca*')
228
- end
223
+ def encode_body
224
+ [gateway_id, gateway_address].pack('Ca*')
225
+ end
229
226
 
230
- def parse_body(buffer)
231
- if buffer.length > 1
232
- self.gateway_id, self.gateway_address = buffer.unpack('Ca*')
233
- else
234
- self.gateway_id, _ignore = buffer.unpack('C')
235
- self.gateway_address = nil
227
+ def parse_body(buffer)
228
+ if buffer.length > 1
229
+ self.gateway_id, self.gateway_address = buffer.unpack('Ca*')
230
+ else
231
+ self.gateway_id, _ignore = buffer.unpack('C')
232
+ self.gateway_address = nil
233
+ end
236
234
  end
237
235
  end
238
- end
239
236
 
240
- class Connect < Packet
241
- attr_accessor :keep_alive
242
- attr_accessor :client_id
237
+ class Connect < Packet
238
+ attr_accessor :keep_alive
239
+ attr_accessor :client_id
243
240
 
244
- DEFAULTS = {
245
- :request_will => false,
246
- :clean_session => true,
247
- :keep_alive => 15
248
- }
241
+ DEFAULTS = {
242
+ :request_will => false,
243
+ :clean_session => true,
244
+ :keep_alive => 15
245
+ }
249
246
 
250
- # Get serialisation of packet's body
251
- def encode_body
252
- if @client_id.nil? or @client_id.length < 1 or @client_id.length > 23
253
- raise "Invalid client identifier when serialising packet"
247
+ # Get serialisation of packet's body
248
+ def encode_body
249
+ if @client_id.nil? || @client_id.empty? || @client_id.length > 23
250
+ raise 'Invalid client identifier when serialising packet'
251
+ end
252
+
253
+ [encode_flags, 0x01, keep_alive, client_id].pack('CCna*')
254
254
  end
255
255
 
256
- [encode_flags, 0x01, keep_alive, client_id].pack('CCna*')
257
- end
256
+ def parse_body(buffer)
257
+ flags, protocol_id, self.keep_alive, self.client_id = buffer.unpack('CCna*')
258
258
 
259
- def parse_body(buffer)
260
- flags, protocol_id, self.keep_alive, self.client_id = buffer.unpack('CCna*')
259
+ if protocol_id != 0x01
260
+ raise ProtocolException, "Unsupported protocol ID number: #{protocol_id}"
261
+ end
261
262
 
262
- if protocol_id != 0x01
263
- raise ProtocolException.new("Unsupported protocol ID number: #{protocol_id}")
263
+ parse_flags(flags)
264
264
  end
265
-
266
- parse_flags(flags)
267
265
  end
268
- end
269
266
 
270
- class Connack < Packet
271
- attr_accessor :return_code
267
+ class Connack < Packet
268
+ attr_accessor :return_code
272
269
 
273
- # Get a string message corresponding to a return code
274
- def return_msg
275
- case return_code
270
+ # Get a string message corresponding to a return code
271
+ def return_msg
272
+ case return_code
276
273
  when 0x00
277
- "Accepted"
274
+ 'Accepted'
278
275
  when 0x01
279
- "Rejected: congestion"
276
+ 'Rejected: congestion'
280
277
  when 0x02
281
- "Rejected: invalid topic ID"
278
+ 'Rejected: invalid topic ID'
282
279
  when 0x03
283
- "Rejected: not supported"
280
+ 'Rejected: not supported'
284
281
  else
285
282
  "Rejected: error code #{return_code}"
283
+ end
286
284
  end
287
- end
288
285
 
289
- def encode_body
290
- unless return_code.is_a?(Integer)
291
- raise "return_code must be an Integer"
286
+ def encode_body
287
+ raise 'return_code must be an Integer' unless return_code.is_a?(Integer)
288
+
289
+ [return_code].pack('C')
292
290
  end
293
291
 
294
- [return_code].pack('C')
292
+ def parse_body(buffer)
293
+ self.return_code = buffer.unpack('C')[0]
294
+ end
295
295
  end
296
296
 
297
- def parse_body(buffer)
298
- self.return_code = buffer.unpack('C')[0]
297
+ class Willtopicreq < Packet
298
+ # No attributes
299
299
  end
300
- end
301
300
 
302
- class Willtopicreq < Packet
303
- # No attributes
304
- end
301
+ class Willtopic < Packet
302
+ attr_accessor :topic_name
305
303
 
306
- class Willtopic < Packet
307
- attr_accessor :topic_name
304
+ DEFAULTS = {
305
+ :qos => 0,
306
+ :retain => false,
307
+ :topic_name => nil
308
+ }
308
309
 
309
- DEFAULTS = {
310
- :qos => 0,
311
- :retain => false,
312
- :topic_name => nil
313
- }
310
+ def encode_body
311
+ if topic_name.nil? || topic_name.empty?
312
+ ''
313
+ else
314
+ [encode_flags, topic_name].pack('Ca*')
315
+ end
316
+ end
314
317
 
315
- def encode_body
316
- if topic_name.nil? or topic_name.empty?
317
- ''
318
- else
319
- [encode_flags, topic_name].pack('Ca*')
318
+ def parse_body(buffer)
319
+ if buffer.length > 1
320
+ flags, self.topic_name = buffer.unpack('Ca*')
321
+ else
322
+ flags, _ignore = buffer.unpack('C')
323
+ self.topic_name = nil
324
+ end
325
+ parse_flags(flags)
320
326
  end
321
327
  end
322
328
 
323
- def parse_body(buffer)
324
- if buffer.length > 1
325
- flags, self.topic_name = buffer.unpack('Ca*')
326
- else
327
- flags, _ignore = buffer.unpack('C')
328
- self.topic_name = nil
329
- end
330
- parse_flags(flags)
329
+ class Willmsgreq < Packet
330
+ # No attributes
331
331
  end
332
- end
333
332
 
334
- class Willmsgreq < Packet
335
- # No attributes
336
- end
333
+ class Willmsg < Packet
334
+ attr_accessor :data
337
335
 
338
- class Willmsg < Packet
339
- attr_accessor :data
336
+ def encode_body
337
+ data
338
+ end
340
339
 
341
- def encode_body
342
- data
340
+ def parse_body(buffer)
341
+ self.data = buffer
342
+ end
343
343
  end
344
344
 
345
- def parse_body(buffer)
346
- self.data = buffer
347
- end
348
- end
345
+ class Register < Packet
346
+ attr_accessor :id
347
+ attr_accessor :topic_id
348
+ attr_accessor :topic_name
349
349
 
350
- class Register < Packet
351
- attr_accessor :id
352
- attr_accessor :topic_id
353
- attr_accessor :topic_name
350
+ DEFAULTS = {
351
+ :id => 0x00,
352
+ :topic_id_type => :normal
353
+ }
354
354
 
355
- DEFAULTS = {
356
- :id => 0x00,
357
- :topic_id_type => :normal
358
- }
355
+ def encode_body
356
+ raise 'id must be an Integer' unless id.is_a?(Integer)
359
357
 
360
- def encode_body
361
- unless id.is_a?(Integer)
362
- raise "id must be an Integer"
363
- end
358
+ raise 'topic_id must be an Integer' unless topic_id.is_a?(Integer)
364
359
 
365
- unless topic_id.is_a?(Integer)
366
- raise "topic_id must be an Integer"
360
+ [topic_id, id, topic_name].pack('nna*')
367
361
  end
368
362
 
369
- [topic_id, id, topic_name].pack('nna*')
363
+ def parse_body(buffer)
364
+ self.topic_id, self.id, self.topic_name = buffer.unpack('nna*')
365
+ end
370
366
  end
371
367
 
372
- def parse_body(buffer)
373
- self.topic_id, self.id, self.topic_name = buffer.unpack('nna*')
374
- end
375
- end
368
+ class Regack < Packet
369
+ attr_accessor :id
370
+ attr_accessor :topic_id
371
+ attr_accessor :return_code
376
372
 
377
- class Regack < Packet
378
- attr_accessor :id
379
- attr_accessor :topic_id
380
- attr_accessor :return_code
373
+ DEFAULTS = {
374
+ :id => 0x00,
375
+ :topic_id => 0x00,
376
+ :topic_id_type => :normal
377
+ }
381
378
 
382
- DEFAULTS = {
383
- :id => 0x00,
384
- :topic_id => 0x00,
385
- :topic_id_type => :normal
386
- }
379
+ def encode_body
380
+ raise 'id must be an Integer' unless id.is_a?(Integer)
387
381
 
388
- def encode_body
389
- unless id.is_a?(Integer)
390
- raise "id must be an Integer"
391
- end
382
+ raise 'topic_id must be an Integer' unless topic_id.is_a?(Integer)
392
383
 
393
- unless topic_id.is_a?(Integer)
394
- raise "topic_id must be an Integer"
384
+ [topic_id, id, return_code].pack('nnC')
395
385
  end
396
386
 
397
- [topic_id, id, return_code].pack('nnC')
387
+ def parse_body(buffer)
388
+ self.topic_id, self.id, self.return_code = buffer.unpack('nnC')
389
+ end
398
390
  end
399
391
 
400
- def parse_body(buffer)
401
- self.topic_id, self.id, self.return_code = buffer.unpack('nnC')
402
- end
403
- end
392
+ class Publish < Packet
393
+ attr_accessor :topic_id
394
+ attr_accessor :id
395
+ attr_accessor :data
404
396
 
405
- class Publish < Packet
406
- attr_accessor :topic_id
407
- attr_accessor :id
408
- attr_accessor :data
397
+ DEFAULTS = {
398
+ :id => 0x00,
399
+ :duplicate => false,
400
+ :qos => 0,
401
+ :retain => false,
402
+ :topic_id_type => :normal
403
+ }
409
404
 
410
- DEFAULTS = {
411
- :id => 0x00,
412
- :duplicate => false,
413
- :qos => 0,
414
- :retain => false,
415
- :topic_id_type => :normal
416
- }
405
+ def encode_body
406
+ raise 'id must be an Integer' unless id.is_a?(Integer)
417
407
 
418
- def encode_body
419
- unless id.is_a?(Integer)
420
- raise "id must be an Integer"
408
+ [encode_flags, encode_topic_id, id, data].pack('Cnna*')
421
409
  end
422
410
 
423
- [encode_flags, encode_topic_id, id, data].pack('Cnna*')
411
+ def parse_body(buffer)
412
+ flags, topic_id, self.id, self.data = buffer.unpack('Cnna*')
413
+ parse_flags(flags)
414
+ parse_topic_id(topic_id)
415
+ end
424
416
  end
425
417
 
426
- def parse_body(buffer)
427
- flags, topic_id, self.id, self.data = buffer.unpack('Cnna*')
428
- parse_flags(flags)
429
- parse_topic_id(topic_id)
430
- end
431
- end
418
+ class Puback < Packet
419
+ attr_accessor :topic_id
420
+ attr_accessor :id
421
+ attr_accessor :return_code
432
422
 
433
- class Puback < Packet
434
- attr_accessor :topic_id
435
- attr_accessor :id
436
- attr_accessor :return_code
423
+ DEFAULTS = {
424
+ :id => 0x00,
425
+ :topic_id => nil,
426
+ :return_code => 0x00
427
+ }
437
428
 
438
- DEFAULTS = {
439
- :id => 0x00,
440
- :topic_id => nil,
441
- :return_code => 0x00,
442
- }
429
+ def encode_body
430
+ raise 'id must be an Integer' unless id.is_a?(Integer)
443
431
 
444
- def encode_body
445
- unless id.is_a?(Integer)
446
- raise "id must be an Integer"
447
- end
432
+ raise 'topic_id must be an Integer' unless topic_id.is_a?(Integer)
448
433
 
449
- unless topic_id.is_a?(Integer)
450
- raise "topic_id must be an Integer"
434
+ [topic_id, id, return_code].pack('nnC')
451
435
  end
452
436
 
453
- [topic_id, id, return_code].pack('nnC')
437
+ def parse_body(buffer)
438
+ self.topic_id, self.id, self.return_code = buffer.unpack('nnC')
439
+ end
454
440
  end
455
441
 
456
- def parse_body(buffer)
457
- self.topic_id, self.id, self.return_code = buffer.unpack('nnC')
458
- end
459
- end
442
+ class Pubcomp < Packet
443
+ attr_accessor :id
460
444
 
461
- class Pubcomp < Packet
462
- attr_accessor :id
445
+ DEFAULTS = {
446
+ :id => 0x00
447
+ }
463
448
 
464
- DEFAULTS = {
465
- :id => 0x00
466
- }
449
+ def encode_body
450
+ raise 'id must be an Integer' unless id.is_a?(Integer)
467
451
 
468
- def encode_body
469
- unless id.is_a?(Integer)
470
- raise "id must be an Integer"
452
+ [id].pack('n')
471
453
  end
472
454
 
473
- [id].pack('n')
455
+ def parse_body(buffer)
456
+ self.id, _ignore = buffer.unpack('n')
457
+ end
474
458
  end
475
459
 
476
- def parse_body(buffer)
477
- self.id, _ignore = buffer.unpack('n')
478
- end
479
- end
460
+ class Pubrec < Packet
461
+ attr_accessor :id
480
462
 
481
- class Pubrec < Packet
482
- attr_accessor :id
463
+ DEFAULTS = {
464
+ :id => 0x00
465
+ }
483
466
 
484
- DEFAULTS = {
485
- :id => 0x00
486
- }
467
+ def encode_body
468
+ raise 'id must be an Integer' unless id.is_a?(Integer)
487
469
 
488
- def encode_body
489
- unless id.is_a?(Integer)
490
- raise "id must be an Integer"
470
+ [id].pack('n')
491
471
  end
492
472
 
493
- [id].pack('n')
473
+ def parse_body(buffer)
474
+ self.id, _ignore = buffer.unpack('n')
475
+ end
494
476
  end
495
477
 
496
- def parse_body(buffer)
497
- self.id, _ignore = buffer.unpack('n')
498
- end
499
- end
478
+ class Pubrel < Packet
479
+ attr_accessor :id
500
480
 
501
- class Pubrel < Packet
502
- attr_accessor :id
481
+ DEFAULTS = {
482
+ :id => 0x00
483
+ }
503
484
 
504
- DEFAULTS = {
505
- :id => 0x00
506
- }
485
+ def encode_body
486
+ raise 'id must be an Integer' unless id.is_a?(Integer)
507
487
 
508
- def encode_body
509
- unless id.is_a?(Integer)
510
- raise "id must be an Integer"
488
+ [id].pack('n')
511
489
  end
512
490
 
513
- [id].pack('n')
491
+ def parse_body(buffer)
492
+ self.id, _ignore = buffer.unpack('n')
493
+ end
514
494
  end
515
495
 
516
- def parse_body(buffer)
517
- self.id, _ignore = buffer.unpack('n')
518
- end
519
- end
496
+ class Subscribe < Packet
497
+ attr_accessor :id
498
+ attr_accessor :topic_id
499
+ attr_accessor :topic_name
520
500
 
521
- class Subscribe < Packet
522
- attr_accessor :id
523
- attr_accessor :topic_id
524
- attr_accessor :topic_name
501
+ DEFAULTS = {
502
+ :id => 0x00,
503
+ :topic_id_type => :normal
504
+ }
525
505
 
526
- DEFAULTS = {
527
- :id => 0x00,
528
- :topic_id_type => :normal
529
- }
506
+ def encode_body
507
+ raise 'id must be an Integer' unless id.is_a?(Integer)
530
508
 
531
- def encode_body
532
- unless id.is_a?(Integer)
533
- raise "id must be an Integer"
509
+ [encode_flags, id, encode_topic].pack('Cna*')
534
510
  end
535
511
 
536
- [encode_flags, id, encode_topic].pack('Cna*')
512
+ def parse_body(buffer)
513
+ flags, self.id, topic = buffer.unpack('Cna*')
514
+ parse_flags(flags)
515
+ parse_topic(topic)
516
+ end
537
517
  end
538
518
 
539
- def parse_body(buffer)
540
- flags, self.id, topic = buffer.unpack('Cna*')
541
- parse_flags(flags)
542
- parse_topic(topic)
543
- end
544
- end
519
+ class Suback < Packet
520
+ attr_accessor :id
521
+ attr_accessor :topic_id
522
+ attr_accessor :return_code
545
523
 
546
- class Suback < Packet
547
- attr_accessor :id
548
- attr_accessor :topic_id
549
- attr_accessor :return_code
524
+ DEFAULTS = {
525
+ :qos => 0,
526
+ :id => 0x00,
527
+ :topic_id => 0x00,
528
+ :topic_id_type => :normal
529
+ }
550
530
 
551
- DEFAULTS = {
552
- :qos => 0,
553
- :id => 0x00,
554
- :topic_id => 0x00,
555
- :topic_id_type => :normal
556
- }
531
+ def encode_body
532
+ raise 'id must be an Integer' unless id.is_a?(Integer)
557
533
 
558
- def encode_body
559
- unless id.is_a?(Integer)
560
- raise "id must be an Integer"
534
+ [encode_flags, encode_topic_id, id, return_code].pack('CnnC')
561
535
  end
562
536
 
563
- [encode_flags, encode_topic_id, id, return_code].pack('CnnC')
537
+ def parse_body(buffer)
538
+ flags, topic_id, self.id, self.return_code = buffer.unpack('CnnC')
539
+ parse_flags(flags)
540
+ parse_topic_id(topic_id)
541
+ end
564
542
  end
565
543
 
566
- def parse_body(buffer)
567
- flags, topic_id, self.id, self.return_code = buffer.unpack('CnnC')
568
- parse_flags(flags)
569
- parse_topic_id(topic_id)
570
- end
571
- end
544
+ class Unsubscribe < Packet
545
+ attr_accessor :id
546
+ attr_accessor :topic_id
547
+ attr_accessor :topic_name
572
548
 
573
- class Unsubscribe < Packet
574
- attr_accessor :id
575
- attr_accessor :topic_id
576
- attr_accessor :topic_name
549
+ DEFAULTS = {
550
+ :id => 0x00,
551
+ :topic_id_type => :normal
552
+ }
577
553
 
578
- DEFAULTS = {
579
- :id => 0x00,
580
- :topic_id_type => :normal
581
- }
554
+ def encode_body
555
+ raise 'id must be an Integer' unless id.is_a?(Integer)
582
556
 
583
- def encode_body
584
- unless id.is_a?(Integer)
585
- raise "id must be an Integer"
557
+ [encode_flags, id, encode_topic].pack('Cna*')
586
558
  end
587
559
 
588
- [encode_flags, id, encode_topic].pack('Cna*')
560
+ def parse_body(buffer)
561
+ flags, self.id, topic = buffer.unpack('Cna*')
562
+ parse_flags(flags)
563
+ parse_topic(topic)
564
+ end
589
565
  end
590
566
 
591
- def parse_body(buffer)
592
- flags, self.id, topic = buffer.unpack('Cna*')
593
- parse_flags(flags)
594
- parse_topic(topic)
595
- end
596
- end
567
+ class Unsuback < Packet
568
+ attr_accessor :id
597
569
 
598
- class Unsuback < Packet
599
- attr_accessor :id
570
+ DEFAULTS = {
571
+ :id => 0x00
572
+ }
600
573
 
601
- DEFAULTS = {
602
- :id => 0x00,
603
- }
574
+ def encode_body
575
+ raise 'id must be an Integer' unless id.is_a?(Integer)
604
576
 
605
- def encode_body
606
- unless id.is_a?(Integer)
607
- raise "id must be an Integer"
577
+ [id].pack('n')
608
578
  end
609
579
 
610
- [id].pack('n')
580
+ def parse_body(buffer)
581
+ self.id = buffer.unpack('n').first
582
+ end
611
583
  end
612
584
 
613
- def parse_body(buffer)
614
- self.id = buffer.unpack('n').first
585
+ class Pingreq < Packet
586
+ # No attributes
615
587
  end
616
- end
617
-
618
- class Pingreq < Packet
619
- # No attributes
620
- end
621
588
 
622
- class Pingresp < Packet
623
- # No attributes
624
- end
589
+ class Pingresp < Packet
590
+ # No attributes
591
+ end
625
592
 
626
- class Disconnect < Packet
627
- attr_accessor :duration
593
+ class Disconnect < Packet
594
+ attr_accessor :duration
628
595
 
629
- DEFAULTS = {
630
- :duration => nil
631
- }
596
+ DEFAULTS = {
597
+ :duration => nil
598
+ }
632
599
 
633
- def encode_body
634
- if duration.nil? or duration == 0
635
- ''
636
- else
637
- [duration].pack('n')
600
+ def encode_body
601
+ if duration.nil? || duration.zero?
602
+ ''
603
+ else
604
+ [duration].pack('n')
605
+ end
638
606
  end
639
- end
640
607
 
641
- def parse_body(buffer)
642
- if buffer.length == 2
643
- self.duration = buffer.unpack('n').first
644
- else
645
- self.duration = nil
608
+ def parse_body(buffer)
609
+ self.duration = buffer.length == 2 ? buffer.unpack('n').first : nil
646
610
  end
647
611
  end
648
- end
649
612
 
650
- class Willtopicupd < Packet
651
- attr_accessor :topic_name
613
+ class Willtopicupd < Packet
614
+ attr_accessor :topic_name
652
615
 
653
- DEFAULTS = {
654
- :qos => 0,
655
- :retain => false,
656
- :topic_name => nil
657
- }
616
+ DEFAULTS = {
617
+ :qos => 0,
618
+ :retain => false,
619
+ :topic_name => nil
620
+ }
658
621
 
659
- def encode_body
660
- if topic_name.nil? or topic_name.empty?
661
- ''
662
- else
663
- [encode_flags, topic_name].pack('Ca*')
622
+ def encode_body
623
+ if topic_name.nil? || topic_name.empty?
624
+ ''
625
+ else
626
+ [encode_flags, topic_name].pack('Ca*')
627
+ end
664
628
  end
665
- end
666
629
 
667
- def parse_body(buffer)
668
- if buffer.length > 1
669
- flags, self.topic_name = buffer.unpack('Ca*')
670
- parse_flags(flags)
671
- else
672
- self.topic_name = nil
630
+ def parse_body(buffer)
631
+ if buffer.length > 1
632
+ flags, self.topic_name = buffer.unpack('Ca*')
633
+ parse_flags(flags)
634
+ else
635
+ self.topic_name = nil
636
+ end
673
637
  end
674
638
  end
675
- end
676
639
 
677
- class Willtopicresp < Packet
678
- attr_accessor :return_code
640
+ class Willtopicresp < Packet
641
+ attr_accessor :return_code
679
642
 
680
- DEFAULTS = {
681
- :return_code => 0x00
682
- }
643
+ DEFAULTS = {
644
+ :return_code => 0x00
645
+ }
683
646
 
684
- def encode_body
685
- unless return_code.is_a?(Integer)
686
- raise "return_code must be an Integer"
647
+ def encode_body
648
+ raise 'return_code must be an Integer' unless return_code.is_a?(Integer)
649
+
650
+ [return_code].pack('C')
687
651
  end
688
652
 
689
- [return_code].pack('C')
653
+ def parse_body(buffer)
654
+ self.return_code, _ignore = buffer.unpack('C')
655
+ end
690
656
  end
691
657
 
692
- def parse_body(buffer)
693
- self.return_code, _ignore = buffer.unpack('C')
694
- end
695
- end
658
+ class Willmsgupd < Packet
659
+ attr_accessor :data
696
660
 
697
- class Willmsgupd < Packet
698
- attr_accessor :data
661
+ def encode_body
662
+ data
663
+ end
699
664
 
700
- def encode_body
701
- data
665
+ def parse_body(buffer)
666
+ self.data = buffer
667
+ end
702
668
  end
703
669
 
704
- def parse_body(buffer)
705
- self.data = buffer
706
- end
707
- end
670
+ class Willmsgresp < Packet
671
+ attr_accessor :return_code
708
672
 
709
- class Willmsgresp < Packet
710
- attr_accessor :return_code
673
+ DEFAULTS = {
674
+ :return_code => 0x00
675
+ }
711
676
 
712
- DEFAULTS = {
713
- :return_code => 0x00
714
- }
677
+ def encode_body
678
+ raise 'return_code must be an Integer' unless return_code.is_a?(Integer)
715
679
 
716
- def encode_body
717
- unless return_code.is_a?(Integer)
718
- raise "return_code must be an Integer"
680
+ [return_code].pack('C')
719
681
  end
720
682
 
721
- [return_code].pack('C')
722
- end
723
-
724
- def parse_body(buffer)
725
- self.return_code, _ignore = buffer.unpack('C')
683
+ def parse_body(buffer)
684
+ self.return_code, _ignore = buffer.unpack('C')
685
+ end
726
686
  end
727
687
  end
728
688
 
729
- end
730
-
731
-
732
- # An enumeration of the MQTT-SN packet types
733
- PACKET_TYPES = {
689
+ # An enumeration of the MQTT-SN packet types
690
+ PACKET_TYPES = {
734
691
  0x00 => MQTT::SN::Packet::Advertise,
735
692
  0x01 => MQTT::SN::Packet::Searchgw,
736
693
  0x02 => MQTT::SN::Packet::Gwinfo,
@@ -757,7 +714,7 @@ module MQTT::SN
757
714
  0x1a => MQTT::SN::Packet::Willtopicupd,
758
715
  0x1b => MQTT::SN::Packet::Willtopicresp,
759
716
  0x1c => MQTT::SN::Packet::Willmsgupd,
760
- 0x1d => MQTT::SN::Packet::Willmsgresp,
761
- }
762
-
717
+ 0x1d => MQTT::SN::Packet::Willmsgresp
718
+ }
719
+ end
763
720
  end