mqtt 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/mqtt/packet.rb CHANGED
@@ -1,10 +1,9 @@
1
1
  # encoding: BINARY
2
2
 
3
3
  module MQTT
4
-
5
4
  # Class representing a MQTT Packet
6
5
  # Performs binary encoding and decoding of headers
7
- class MQTT::Packet
6
+ class Packet
8
7
  # The version number of the MQTT protocol to use (default 3.1.0)
9
8
  attr_accessor :version
10
9
 
@@ -36,27 +35,29 @@ module MQTT
36
35
  multiplier = 1
37
36
  body_length = 0
38
37
  pos = 1
39
- begin
38
+
39
+ loop do
40
40
  digit = read_byte(socket)
41
41
  body_length += ((digit & 0x7F) * multiplier)
42
42
  multiplier *= 0x80
43
43
  pos += 1
44
- end while ((digit & 0x80) != 0x00) and pos <= 4
44
+ break if (digit & 0x80).zero? || pos > 4
45
+ end
45
46
 
46
47
  # Store the expected body length in the packet
47
48
  packet.instance_variable_set('@body_length', body_length)
48
49
 
49
50
  # Read in the packet body
50
- packet.parse_body( socket.read(body_length) )
51
+ packet.parse_body(socket.read(body_length))
51
52
 
52
- return packet
53
+ packet
53
54
  end
54
55
 
55
56
  # Parse buffer into new packet object
56
57
  def self.parse(buffer)
57
58
  packet = parse_header(buffer)
58
59
  packet.parse_body(buffer)
59
- return packet
60
+ packet
60
61
  end
61
62
 
62
63
  # Parse the header and create a new packet object of the correct type
@@ -64,11 +65,11 @@ module MQTT
64
65
  def self.parse_header(buffer)
65
66
  # Check that the packet is a long as the minimum packet size
66
67
  if buffer.bytesize < 2
67
- raise ProtocolException.new("Invalid packet: less than 2 bytes long")
68
+ raise ProtocolException, 'Invalid packet: less than 2 bytes long'
68
69
  end
69
70
 
70
71
  # Create a new packet object
71
- bytes = buffer.unpack("C5")
72
+ bytes = buffer.unpack('C5')
72
73
  packet = create_from_header(bytes.first)
73
74
  packet.validate_flags
74
75
 
@@ -76,15 +77,18 @@ module MQTT
76
77
  body_length = 0
77
78
  multiplier = 1
78
79
  pos = 1
79
- begin
80
+
81
+ loop do
80
82
  if buffer.bytesize <= pos
81
- raise ProtocolException.new("The packet length header is incomplete")
83
+ raise ProtocolException, 'The packet length header is incomplete'
82
84
  end
85
+
83
86
  digit = bytes[pos]
84
87
  body_length += ((digit & 0x7F) * multiplier)
85
88
  multiplier *= 0x80
86
89
  pos += 1
87
- end while ((digit & 0x80) != 0x00) and pos <= 4
90
+ break if (digit & 0x80).zero? || pos > 4
91
+ end
88
92
 
89
93
  # Store the expected body length in the packet
90
94
  packet.instance_variable_set('@body_length', body_length)
@@ -92,7 +96,7 @@ module MQTT
92
96
  # Delete the fixed header from the raw packet passed in
93
97
  buffer.slice!(0...pos)
94
98
 
95
- return packet
99
+ packet
96
100
  end
97
101
 
98
102
  # Create a new packet object from the first byte of a MQTT packet
@@ -101,27 +105,27 @@ module MQTT
101
105
  type_id = ((byte & 0xF0) >> 4)
102
106
  packet_class = MQTT::PACKET_TYPES[type_id]
103
107
  if packet_class.nil?
104
- raise ProtocolException.new("Invalid packet type identifier: #{type_id}")
108
+ raise ProtocolException, "Invalid packet type identifier: #{type_id}"
105
109
  end
106
110
 
107
111
  # Convert the last 4 bits of byte into array of true/false
108
- flags = (0..3).map { |i| byte & (2 ** i) != 0 }
112
+ flags = (0..3).map { |i| byte & (2**i) != 0 }
109
113
 
110
114
  # Create a new packet object
111
115
  packet_class.new(:flags => flags)
112
116
  end
113
117
 
114
118
  # Create a new empty packet
115
- def initialize(args={})
119
+ def initialize(args = {})
116
120
  # We must set flags before the other values
117
121
  @flags = [false, false, false, false]
118
122
  update_attributes(ATTR_DEFAULTS.merge(args))
119
123
  end
120
124
 
121
125
  # Set packet attributes from a hash of attribute names and values
122
- def update_attributes(attr={})
123
- attr.each_pair do |k,v|
124
- if v.is_a?(Array) or v.is_a?(Hash)
126
+ def update_attributes(attr = {})
127
+ attr.each_pair do |k, v|
128
+ if v.is_a?(Array) || v.is_a?(Hash)
125
129
  send("#{k}=", v.dup)
126
130
  else
127
131
  send("#{k}=", v)
@@ -132,10 +136,8 @@ module MQTT
132
136
  # Get the identifer for this packet type
133
137
  def type_id
134
138
  index = MQTT::PACKET_TYPES.index(self.class)
135
- if index.nil?
136
- raise "Invalid packet type: #{self.class}"
137
- end
138
- return index
139
+ raise "Invalid packet type: #{self.class}" if index.nil?
140
+ index
139
141
  end
140
142
 
141
143
  # Get the name of the packet type as a string in capitals
@@ -158,11 +160,9 @@ module MQTT
158
160
 
159
161
  # Parse the body (variable header and payload) of a packet
160
162
  def parse_body(buffer)
161
- if buffer.bytesize != body_length
162
- raise ProtocolException.new(
163
- "Failed to parse packet - input buffer (#{buffer.bytesize}) is not the same as the body length header (#{body_length})"
164
- )
165
- end
163
+ return if buffer.bytesize == body_length
164
+
165
+ raise ProtocolException, "Failed to parse packet - input buffer (#{buffer.bytesize}) is not the same as the body length header (#{body_length})"
166
166
  end
167
167
 
168
168
  # Get serialisation of packet's body (variable header and payload)
@@ -170,35 +170,35 @@ module MQTT
170
170
  '' # No body by default
171
171
  end
172
172
 
173
-
174
173
  # Serialise the packet
175
174
  def to_s
176
175
  # Encode the fixed header
177
176
  header = [
178
177
  ((type_id.to_i & 0x0F) << 4) |
179
- (flags[3] ? 0x8 : 0x0) |
180
- (flags[2] ? 0x4 : 0x0) |
181
- (flags[1] ? 0x2 : 0x0) |
182
- (flags[0] ? 0x1 : 0x0)
178
+ (flags[3] ? 0x8 : 0x0) |
179
+ (flags[2] ? 0x4 : 0x0) |
180
+ (flags[1] ? 0x2 : 0x0) |
181
+ (flags[0] ? 0x1 : 0x0)
183
182
  ]
184
183
 
185
184
  # Get the packet's variable header and payload
186
- body = self.encode_body
185
+ body = encode_body
187
186
 
188
187
  # Check that that packet isn't too big
189
188
  body_length = body.bytesize
190
- if body_length > 268435455
191
- raise "Error serialising packet: body is more than 256MB"
189
+ if body_length > 268_435_455
190
+ raise 'Error serialising packet: body is more than 256MB'
192
191
  end
193
192
 
194
193
  # Build up the body length field bytes
195
- begin
194
+ loop do
196
195
  digit = (body_length % 128)
197
196
  body_length = body_length.div(128)
198
197
  # if there are more digits to encode, set the top bit of this digit
199
- digit |= 0x80 if (body_length > 0)
198
+ digit |= 0x80 if body_length > 0
200
199
  header.push(digit)
201
- end while (body_length > 0)
200
+ break if body_length <= 0
201
+ end
202
202
 
203
203
  # Convert header to binary and add on body
204
204
  header.pack('C*') + body
@@ -207,9 +207,9 @@ module MQTT
207
207
  # Check that fixed header flags are valid for types that don't use the flags
208
208
  # @private
209
209
  def validate_flags
210
- if flags != [false, false, false, false]
211
- raise ProtocolException.new("Invalid flags in #{type_name} packet header")
212
- end
210
+ return if flags == [false, false, false, false]
211
+
212
+ raise ProtocolException, "Invalid flags in #{type_name} packet header"
213
213
  end
214
214
 
215
215
  # Returns a human readable string
@@ -217,6 +217,14 @@ module MQTT
217
217
  "\#<#{self.class}>"
218
218
  end
219
219
 
220
+ # Read and unpack a single byte from a socket
221
+ def self.read_byte(socket)
222
+ byte = socket.getbyte
223
+ raise ProtocolException, 'Failed to read byte from socket' if byte.nil?
224
+
225
+ byte
226
+ end
227
+
220
228
  protected
221
229
 
222
230
  # Encode an array of bytes and return them
@@ -226,11 +234,12 @@ module MQTT
226
234
 
227
235
  # Encode an array of bits and return them
228
236
  def encode_bits(bits)
229
- [bits.map{|b| b ? '1' : '0'}.join].pack('b*')
237
+ [bits.map { |b| b ? '1' : '0' }.join].pack('b*')
230
238
  end
231
239
 
232
240
  # Encode a 16-bit unsigned integer and return it
233
241
  def encode_short(val)
242
+ raise 'Value too big for short' if val > 0xffff
234
243
  [val.to_i].pack('n')
235
244
  end
236
245
 
@@ -257,42 +266,26 @@ module MQTT
257
266
 
258
267
  # Remove 8 bits from the front of buffer
259
268
  def shift_bits(buffer)
260
- buffer.slice!(0...1).unpack('b8').first.split('').map {|b| b == '1'}
269
+ buffer.slice!(0...1).unpack('b8').first.split('').map { |b| b == '1' }
261
270
  end
262
271
 
263
272
  # Remove n bytes from the front of buffer
264
- def shift_data(buffer,bytes)
273
+ def shift_data(buffer, bytes)
265
274
  buffer.slice!(0...bytes)
266
275
  end
267
276
 
268
277
  # Remove string from the front of buffer
269
278
  def shift_string(buffer)
270
279
  len = shift_short(buffer)
271
- str = shift_data(buffer,len)
280
+ str = shift_data(buffer, len)
272
281
  # Strings in MQTT v3.1 are all UTF-8
273
282
  str.force_encoding('UTF-8')
274
283
  end
275
284
 
276
-
277
- private
278
-
279
- # Read and unpack a single byte from a socket
280
- def self.read_byte(socket)
281
- byte = socket.read(1)
282
- if byte.nil?
283
- raise ProtocolException.new("Failed to read byte from socket")
284
- end
285
- byte.unpack('C').first
286
- end
287
-
288
-
289
-
290
285
  ## PACKET SUBCLASSES ##
291
286
 
292
-
293
287
  # Class representing an MQTT Publish message
294
288
  class Publish < MQTT::Packet
295
-
296
289
  # Duplicate delivery flag
297
290
  attr_accessor :duplicate
298
291
 
@@ -315,7 +308,7 @@ module MQTT
315
308
  }
316
309
 
317
310
  # Create a new Publish packet
318
- def initialize(args={})
311
+ def initialize(args = {})
319
312
  super(ATTR_DEFAULTS.merge(args))
320
313
  end
321
314
 
@@ -325,11 +318,7 @@ module MQTT
325
318
 
326
319
  # Set the DUP flag (true/false)
327
320
  def duplicate=(arg)
328
- if arg.kind_of?(Integer)
329
- @flags[3] = (arg == 0x1)
330
- else
331
- @flags[3] = arg
332
- end
321
+ @flags[3] = arg.is_a?(Integer) ? (arg == 0x1) : arg
333
322
  end
334
323
 
335
324
  def retain
@@ -338,11 +327,7 @@ module MQTT
338
327
 
339
328
  # Set the retain flag (true/false)
340
329
  def retain=(arg)
341
- if arg.kind_of?(Integer)
342
- @flags[0] = (arg == 0x1)
343
- else
344
- @flags[0] = arg
345
- end
330
+ @flags[0] = arg.is_a?(Integer) ? (arg == 0x1) : arg
346
331
  end
347
332
 
348
333
  def qos
@@ -352,61 +337,55 @@ module MQTT
352
337
  # Set the Quality of Service level (0/1/2)
353
338
  def qos=(arg)
354
339
  @qos = arg.to_i
355
- if @qos < 0 or @qos > 2
356
- raise "Invalid QoS value: #{@qos}"
357
- else
358
- @flags[1] = (arg & 0x01 == 0x01)
359
- @flags[2] = (arg & 0x02 == 0x02)
360
- end
340
+ raise "Invalid QoS value: #{@qos}" if @qos < 0 || @qos > 2
341
+
342
+ @flags[1] = (arg & 0x01 == 0x01)
343
+ @flags[2] = (arg & 0x02 == 0x02)
361
344
  end
362
345
 
363
346
  # Get serialisation of packet's body
364
347
  def encode_body
365
348
  body = ''
366
- if @topic.nil? or @topic.to_s.empty?
367
- raise "Invalid topic name when serialising packet"
349
+ if @topic.nil? || @topic.to_s.empty?
350
+ raise 'Invalid topic name when serialising packet'
368
351
  end
369
352
  body += encode_string(@topic)
370
- body += encode_short(@id) unless qos == 0
353
+ body += encode_short(@id) unless qos.zero?
371
354
  body += payload.to_s.dup.force_encoding('ASCII-8BIT')
372
- return body
355
+ body
373
356
  end
374
357
 
375
358
  # Parse the body (variable header and payload) of a Publish packet
376
359
  def parse_body(buffer)
377
360
  super(buffer)
378
361
  @topic = shift_string(buffer)
379
- @id = shift_short(buffer) unless qos == 0
362
+ @id = shift_short(buffer) unless qos.zero?
380
363
  @payload = buffer
381
364
  end
382
365
 
383
366
  # Check that fixed header flags are valid for this packet type
384
367
  # @private
385
368
  def validate_flags
386
- if qos == 3
387
- raise ProtocolException.new("Invalid packet: QoS value of 3 is not allowed")
388
- end
389
- if qos == 0 and duplicate
390
- raise ProtocolException.new("Invalid packet: DUP cannot be set for QoS 0")
391
- end
369
+ raise ProtocolException, 'Invalid packet: QoS value of 3 is not allowed' if qos == 3
370
+ raise ProtocolException, 'Invalid packet: DUP cannot be set for QoS 0' if qos.zero? && duplicate
392
371
  end
393
372
 
394
373
  # Returns a human readable string, summarising the properties of the packet
395
374
  def inspect
396
- "\#<#{self.class}: " +
397
- "d#{duplicate ? '1' : '0'}, " +
398
- "q#{qos}, " +
399
- "r#{retain ? '1' : '0'}, " +
400
- "m#{id}, " +
401
- "'#{topic}', " +
402
- "#{inspect_payload}>"
375
+ "\#<#{self.class}: " \
376
+ "d#{duplicate ? '1' : '0'}, " \
377
+ "q#{qos}, " \
378
+ "r#{retain ? '1' : '0'}, " \
379
+ "m#{id}, " \
380
+ "'#{topic}', " \
381
+ "#{inspect_payload}>"
403
382
  end
404
383
 
405
384
  protected
406
385
 
407
386
  def inspect_payload
408
387
  str = payload.to_s
409
- if str.bytesize < 16 and str =~ /^[ -~]*$/
388
+ if str.bytesize < 16 && str =~ /^[ -~]*$/
410
389
  "'#{str}'"
411
390
  else
412
391
  "... (#{str.bytesize} bytes)"
@@ -459,39 +438,38 @@ module MQTT
459
438
  :will_retain => false,
460
439
  :will_payload => '',
461
440
  :username => nil,
462
- :password => nil,
441
+ :password => nil
463
442
  }
464
443
 
465
444
  # Create a new Client Connect packet
466
- def initialize(args={})
445
+ def initialize(args = {})
467
446
  super(ATTR_DEFAULTS.merge(args))
468
447
 
469
- if version == '3.1.0' or version == '3.1'
448
+ if version == '3.1.0' || version == '3.1'
470
449
  self.protocol_name ||= 'MQIsdp'
471
450
  self.protocol_level ||= 0x03
472
451
  elsif version == '3.1.1'
473
452
  self.protocol_name ||= 'MQTT'
474
453
  self.protocol_level ||= 0x04
475
454
  else
476
- raise ArgumentError.new("Unsupported protocol version: #{version}")
455
+ raise ArgumentError, "Unsupported protocol version: #{version}"
477
456
  end
478
457
  end
479
458
 
480
459
  # Get serialisation of packet's body
481
460
  def encode_body
482
461
  body = ''
462
+
483
463
  if @version == '3.1.0'
484
- if @client_id.nil? or @client_id.bytesize < 1
485
- raise "Client identifier too short while serialising packet"
486
- elsif @client_id.bytesize > 23
487
- raise "Client identifier too long when serialising packet"
488
- end
464
+ raise 'Client identifier too short while serialising packet' if @client_id.nil? || @client_id.bytesize < 1
465
+ raise 'Client identifier too long when serialising packet' if @client_id.bytesize > 23
489
466
  end
467
+
490
468
  body += encode_string(@protocol_name)
491
469
  body += encode_bytes(@protocol_level.to_i)
492
470
 
493
471
  if @keep_alive < 0
494
- raise "Invalid keep-alive value: cannot be less than 0"
472
+ raise 'Invalid keep-alive value: cannot be less than 0'
495
473
  end
496
474
 
497
475
  # Set the Connect flags
@@ -513,7 +491,7 @@ module MQTT
513
491
  end
514
492
  body += encode_string(@username) unless @username.nil?
515
493
  body += encode_string(@password) unless @password.nil?
516
- return body
494
+ body
517
495
  end
518
496
 
519
497
  # Parse the body (variable header and payload) of a Connect packet
@@ -521,14 +499,12 @@ module MQTT
521
499
  super(buffer)
522
500
  @protocol_name = shift_string(buffer)
523
501
  @protocol_level = shift_byte(buffer).to_i
524
- if @protocol_name == 'MQIsdp' and @protocol_level == 3
502
+ if @protocol_name == 'MQIsdp' && @protocol_level == 3
525
503
  @version = '3.1.0'
526
- elsif @protocol_name == 'MQTT' and @protocol_level == 4
504
+ elsif @protocol_name == 'MQTT' && @protocol_level == 4
527
505
  @version = '3.1.1'
528
506
  else
529
- raise ProtocolException.new(
530
- "Unsupported protocol: #{@protocol_name}/#{@protocol_level}"
531
- )
507
+ raise ProtocolException, "Unsupported protocol: #{@protocol_name}/#{@protocol_level}"
532
508
  end
533
509
 
534
510
  @connect_flags = shift_byte(buffer)
@@ -543,27 +519,26 @@ module MQTT
543
519
  # The MQTT v3.1 specification says that the payload is a UTF-8 string
544
520
  @will_payload = shift_string(buffer)
545
521
  end
546
- if ((@connect_flags & 0x80) >> 7) == 0x01 and buffer.bytesize > 0
522
+ if ((@connect_flags & 0x80) >> 7) == 0x01 && buffer.bytesize > 0
547
523
  @username = shift_string(buffer)
548
524
  end
549
- if ((@connect_flags & 0x40) >> 6) == 0x01 and buffer.bytesize > 0
525
+ if ((@connect_flags & 0x40) >> 6) == 0x01 && buffer.bytesize > 0 # rubocop: disable Style/GuardClause
550
526
  @password = shift_string(buffer)
551
527
  end
552
528
  end
553
529
 
554
530
  # Returns a human readable string, summarising the properties of the packet
555
531
  def inspect
556
- str = "\#<#{self.class}: "
557
- str += "keep_alive=#{keep_alive}"
558
- str += ", clean" if clean_session
532
+ str = "\#<#{self.class}: " \
533
+ "keep_alive=#{keep_alive}"
534
+ str += ', clean' if clean_session
559
535
  str += ", client_id='#{client_id}'"
560
536
  str += ", username='#{username}'" unless username.nil?
561
- str += ", password=..." unless password.nil?
562
- str += ">"
537
+ str += ', password=...' unless password.nil?
538
+ str + '>'
563
539
  end
564
540
 
565
541
  # ---- Deprecated attributes and methods ---- #
566
- public
567
542
 
568
543
  # @deprecated Please use {#protocol_level} instead
569
544
  def protocol_version
@@ -585,10 +560,10 @@ module MQTT
585
560
  attr_accessor :return_code
586
561
 
587
562
  # Default attribute values
588
- ATTR_DEFAULTS = {:return_code => 0x00}
563
+ ATTR_DEFAULTS = { :return_code => 0x00 }
589
564
 
590
565
  # Create a new Client Connect packet
591
- def initialize(args={})
566
+ def initialize(args = {})
592
567
  # We must set flags before other attributes
593
568
  @connack_flags = [false, false, false, false, false, false, false, false]
594
569
  super(ATTR_DEFAULTS.merge(args))
@@ -601,30 +576,26 @@ module MQTT
601
576
 
602
577
  # Set the Session Present flag
603
578
  def session_present=(arg)
604
- if arg.kind_of?(Integer)
605
- @connack_flags[0] = (arg == 0x1)
606
- else
607
- @connack_flags[0] = arg
608
- end
579
+ @connack_flags[0] = arg.is_a?(Integer) ? (arg == 0x1) : arg
609
580
  end
610
581
 
611
582
  # Get a string message corresponding to a return code
612
583
  def return_msg
613
584
  case return_code
614
- when 0x00
615
- "Connection Accepted"
616
- when 0x01
617
- "Connection refused: unacceptable protocol version"
618
- when 0x02
619
- "Connection refused: client identifier rejected"
620
- when 0x03
621
- "Connection refused: server unavailable"
622
- when 0x04
623
- "Connection refused: bad user name or password"
624
- when 0x05
625
- "Connection refused: not authorised"
626
- else
627
- "Connection refused: error code #{return_code}"
585
+ when 0x00
586
+ 'Connection Accepted'
587
+ when 0x01
588
+ 'Connection refused: unacceptable protocol version'
589
+ when 0x02
590
+ 'Connection refused: client identifier rejected'
591
+ when 0x03
592
+ 'Connection refused: server unavailable'
593
+ when 0x04
594
+ 'Connection refused: bad user name or password'
595
+ when 0x05
596
+ 'Connection refused: not authorised'
597
+ else
598
+ "Connection refused: error code #{return_code}"
628
599
  end
629
600
  end
630
601
 
@@ -633,20 +604,20 @@ module MQTT
633
604
  body = ''
634
605
  body += encode_bits(@connack_flags)
635
606
  body += encode_bytes(@return_code.to_i)
636
- return body
607
+ body
637
608
  end
638
609
 
639
610
  # Parse the body (variable header and payload) of a Connect Acknowledgment packet
640
611
  def parse_body(buffer)
641
612
  super(buffer)
642
613
  @connack_flags = shift_bits(buffer)
643
- unless @connack_flags[1,7] == [false, false, false, false, false, false, false]
644
- raise ProtocolException.new("Invalid flags in Connack variable header")
614
+ unless @connack_flags[1, 7] == [false, false, false, false, false, false, false]
615
+ raise ProtocolException, 'Invalid flags in Connack variable header'
645
616
  end
646
617
  @return_code = shift_byte(buffer)
647
- unless buffer.empty?
648
- raise ProtocolException.new("Extra bytes at end of Connect Acknowledgment packet")
649
- end
618
+
619
+ return if buffer.empty?
620
+ raise ProtocolException, 'Extra bytes at end of Connect Acknowledgment packet'
650
621
  end
651
622
 
652
623
  # Returns a human readable string, summarising the properties of the packet
@@ -666,9 +637,9 @@ module MQTT
666
637
  def parse_body(buffer)
667
638
  super(buffer)
668
639
  @id = shift_short(buffer)
669
- unless buffer.empty?
670
- raise ProtocolException.new("Extra bytes at end of Publish Acknowledgment packet")
671
- end
640
+
641
+ return if buffer.empty?
642
+ raise ProtocolException, 'Extra bytes at end of Publish Acknowledgment packet'
672
643
  end
673
644
 
674
645
  # Returns a human readable string, summarising the properties of the packet
@@ -688,9 +659,9 @@ module MQTT
688
659
  def parse_body(buffer)
689
660
  super(buffer)
690
661
  @id = shift_short(buffer)
691
- unless buffer.empty?
692
- raise ProtocolException.new("Extra bytes at end of Publish Received packet")
693
- end
662
+
663
+ return if buffer.empty?
664
+ raise ProtocolException, 'Extra bytes at end of Publish Received packet'
694
665
  end
695
666
 
696
667
  # Returns a human readable string, summarising the properties of the packet
@@ -701,14 +672,13 @@ module MQTT
701
672
 
702
673
  # Class representing an MQTT Publish Release packet
703
674
  class Pubrel < MQTT::Packet
704
-
705
675
  # Default attribute values
706
676
  ATTR_DEFAULTS = {
707
- :flags => [false, true, false, false],
677
+ :flags => [false, true, false, false]
708
678
  }
709
679
 
710
680
  # Create a new Pubrel packet
711
- def initialize(args={})
681
+ def initialize(args = {})
712
682
  super(ATTR_DEFAULTS.merge(args))
713
683
  end
714
684
 
@@ -721,17 +691,16 @@ module MQTT
721
691
  def parse_body(buffer)
722
692
  super(buffer)
723
693
  @id = shift_short(buffer)
724
- unless buffer.empty?
725
- raise ProtocolException.new("Extra bytes at end of Publish Release packet")
726
- end
694
+
695
+ return if buffer.empty?
696
+ raise ProtocolException, 'Extra bytes at end of Publish Release packet'
727
697
  end
728
698
 
729
699
  # Check that fixed header flags are valid for this packet type
730
700
  # @private
731
701
  def validate_flags
732
- if @flags != [false, true, false, false]
733
- raise ProtocolException.new("Invalid flags in PUBREL packet header")
734
- end
702
+ return if @flags == [false, true, false, false]
703
+ raise ProtocolException, 'Invalid flags in PUBREL packet header'
735
704
  end
736
705
 
737
706
  # Returns a human readable string, summarising the properties of the packet
@@ -751,9 +720,9 @@ module MQTT
751
720
  def parse_body(buffer)
752
721
  super(buffer)
753
722
  @id = shift_short(buffer)
754
- unless buffer.empty?
755
- raise ProtocolException.new("Extra bytes at end of Publish Complete packet")
756
- end
723
+
724
+ return if buffer.empty?
725
+ raise ProtocolException, 'Extra bytes at end of Publish Complete packet'
757
726
  end
758
727
 
759
728
  # Returns a human readable string, summarising the properties of the packet
@@ -770,11 +739,11 @@ module MQTT
770
739
  # Default attribute values
771
740
  ATTR_DEFAULTS = {
772
741
  :topics => [],
773
- :flags => [false, true, false, false],
742
+ :flags => [false, true, false, false]
774
743
  }
775
744
 
776
745
  # Create a new Subscribe packet
777
- def initialize(args={})
746
+ def initialize(args = {})
778
747
  super(ATTR_DEFAULTS.merge(args))
779
748
  end
780
749
 
@@ -792,14 +761,10 @@ module MQTT
792
761
  #
793
762
  def topics=(value)
794
763
  # Get input into a consistent state
795
- if value.is_a?(Array)
796
- input = value.flatten
797
- else
798
- input = [value]
799
- end
764
+ input = value.is_a?(Array) ? value.flatten : [value]
800
765
 
801
766
  @topics = []
802
- while(input.length>0)
767
+ until input.empty?
803
768
  item = input.shift
804
769
  if item.is_a?(Hash)
805
770
  # Convert hash into an ordered array of arrays
@@ -808,9 +773,9 @@ module MQTT
808
773
  # Peek at the next item in the array, and remove it if it is an integer
809
774
  if input.first.is_a?(Integer)
810
775
  qos = input.shift
811
- @topics << [item,qos]
776
+ @topics << [item, qos]
812
777
  else
813
- @topics << [item,0]
778
+ @topics << [item, 0]
814
779
  end
815
780
  else
816
781
  # Meh?
@@ -822,15 +787,13 @@ module MQTT
822
787
 
823
788
  # Get serialisation of packet's body
824
789
  def encode_body
825
- if @topics.empty?
826
- raise "no topics given when serialising packet"
827
- end
790
+ raise 'no topics given when serialising packet' if @topics.empty?
828
791
  body = encode_short(@id)
829
792
  topics.each do |item|
830
793
  body += encode_string(item[0])
831
794
  body += encode_bytes(item[1])
832
795
  end
833
- return body
796
+ body
834
797
  end
835
798
 
836
799
  # Parse the body (variable header and payload) of a packet
@@ -838,26 +801,25 @@ module MQTT
838
801
  super(buffer)
839
802
  @id = shift_short(buffer)
840
803
  @topics = []
841
- while(buffer.bytesize>0)
804
+ while buffer.bytesize > 0
842
805
  topic_name = shift_string(buffer)
843
806
  topic_qos = shift_byte(buffer)
844
- @topics << [topic_name,topic_qos]
807
+ @topics << [topic_name, topic_qos]
845
808
  end
846
809
  end
847
810
 
848
811
  # Check that fixed header flags are valid for this packet type
849
812
  # @private
850
813
  def validate_flags
851
- if @flags != [false, true, false, false]
852
- raise ProtocolException.new("Invalid flags in SUBSCRIBE packet header")
853
- end
814
+ return if @flags == [false, true, false, false]
815
+ raise ProtocolException, 'Invalid flags in SUBSCRIBE packet header'
854
816
  end
855
817
 
856
818
  # Returns a human readable string, summarising the properties of the packet
857
819
  def inspect
858
820
  _str = "\#<#{self.class}: 0x%2.2X, %s>" % [
859
821
  id,
860
- topics.map {|t| "'#{t[0]}':#{t[1]}"}.join(', ')
822
+ topics.map { |t| "'#{t[0]}':#{t[1]}" }.join(', ')
861
823
  ]
862
824
  end
863
825
  end
@@ -869,11 +831,11 @@ module MQTT
869
831
 
870
832
  # Default attribute values
871
833
  ATTR_DEFAULTS = {
872
- :return_codes => [],
834
+ :return_codes => []
873
835
  }
874
836
 
875
837
  # Create a new Subscribe Acknowledgment packet
876
- def initialize(args={})
838
+ def initialize(args = {})
877
839
  super(ATTR_DEFAULTS.merge(args))
878
840
  end
879
841
 
@@ -885,36 +847,33 @@ module MQTT
885
847
  elsif value.is_a?(Integer)
886
848
  @return_codes = [value]
887
849
  else
888
- raise "return_codes should be an integer or an array of return codes"
850
+ raise 'return_codes should be an integer or an array of return codes'
889
851
  end
890
852
  end
891
853
 
892
854
  # Get serialisation of packet's body
893
855
  def encode_body
894
856
  if @return_codes.empty?
895
- raise "no granted QoS given when serialising packet"
857
+ raise 'no granted QoS given when serialising packet'
896
858
  end
897
859
  body = encode_short(@id)
898
860
  return_codes.each { |qos| body += encode_bytes(qos) }
899
- return body
861
+ body
900
862
  end
901
863
 
902
864
  # Parse the body (variable header and payload) of a packet
903
865
  def parse_body(buffer)
904
866
  super(buffer)
905
867
  @id = shift_short(buffer)
906
- while(buffer.bytesize>0)
907
- @return_codes << shift_byte(buffer)
908
- end
868
+ @return_codes << shift_byte(buffer) while buffer.bytesize > 0
909
869
  end
910
870
 
911
871
  # Returns a human readable string, summarising the properties of the packet
912
872
  def inspect
913
- "\#<#{self.class}: 0x%2.2X, rc=%s>" % [id, return_codes.map{|rc| "0x%2.2X" % rc}.join(',')]
873
+ "\#<#{self.class}: 0x%2.2X, rc=%s>" % [id, return_codes.map { |rc| '0x%2.2X' % rc }.join(',')]
914
874
  end
915
875
 
916
876
  # ---- Deprecated attributes and methods ---- #
917
- public
918
877
 
919
878
  # @deprecated Please use {#return_codes} instead
920
879
  def granted_qos
@@ -935,55 +894,46 @@ module MQTT
935
894
  # Default attribute values
936
895
  ATTR_DEFAULTS = {
937
896
  :topics => [],
938
- :flags => [false, true, false, false],
897
+ :flags => [false, true, false, false]
939
898
  }
940
899
 
941
900
  # Create a new Unsubscribe packet
942
- def initialize(args={})
901
+ def initialize(args = {})
943
902
  super(ATTR_DEFAULTS.merge(args))
944
903
  end
945
904
 
946
905
  # Set one or more topic paths to unsubscribe from
947
906
  def topics=(value)
948
- if value.is_a?(Array)
949
- @topics = value
950
- else
951
- @topics = [value]
952
- end
907
+ @topics = value.is_a?(Array) ? value : [value]
953
908
  end
954
909
 
955
910
  # Get serialisation of packet's body
956
911
  def encode_body
957
- if @topics.empty?
958
- raise "no topics given when serialising packet"
959
- end
912
+ raise 'no topics given when serialising packet' if @topics.empty?
960
913
  body = encode_short(@id)
961
914
  topics.each { |topic| body += encode_string(topic) }
962
- return body
915
+ body
963
916
  end
964
917
 
965
918
  # Parse the body (variable header and payload) of a packet
966
919
  def parse_body(buffer)
967
920
  super(buffer)
968
921
  @id = shift_short(buffer)
969
- while(buffer.bytesize>0)
970
- @topics << shift_string(buffer)
971
- end
922
+ @topics << shift_string(buffer) while buffer.bytesize > 0
972
923
  end
973
924
 
974
925
  # Check that fixed header flags are valid for this packet type
975
926
  # @private
976
927
  def validate_flags
977
- if @flags != [false, true, false, false]
978
- raise ProtocolException.new("Invalid flags in UNSUBSCRIBE packet header")
979
- end
928
+ return if @flags == [false, true, false, false]
929
+ raise ProtocolException, 'Invalid flags in UNSUBSCRIBE packet header'
980
930
  end
981
931
 
982
932
  # Returns a human readable string, summarising the properties of the packet
983
933
  def inspect
984
934
  "\#<#{self.class}: 0x%2.2X, %s>" % [
985
935
  id,
986
- topics.map {|t| "'#{t}'"}.join(', ')
936
+ topics.map { |t| "'#{t}'" }.join(', ')
987
937
  ]
988
938
  end
989
939
  end
@@ -991,7 +941,7 @@ module MQTT
991
941
  # Class representing an MQTT Unsubscribe Acknowledgment packet
992
942
  class Unsuback < MQTT::Packet
993
943
  # Create a new Unsubscribe Acknowledgment packet
994
- def initialize(args={})
944
+ def initialize(args = {})
995
945
  super(args)
996
946
  end
997
947
 
@@ -1004,9 +954,9 @@ module MQTT
1004
954
  def parse_body(buffer)
1005
955
  super(buffer)
1006
956
  @id = shift_short(buffer)
1007
- unless buffer.empty?
1008
- raise ProtocolException.new("Extra bytes at end of Unsubscribe Acknowledgment packet")
1009
- end
957
+
958
+ return if buffer.empty?
959
+ raise ProtocolException, 'Extra bytes at end of Unsubscribe Acknowledgment packet'
1010
960
  end
1011
961
 
1012
962
  # Returns a human readable string, summarising the properties of the packet
@@ -1018,52 +968,51 @@ module MQTT
1018
968
  # Class representing an MQTT Ping Request packet
1019
969
  class Pingreq < MQTT::Packet
1020
970
  # Create a new Ping Request packet
1021
- def initialize(args={})
971
+ def initialize(args = {})
1022
972
  super(args)
1023
973
  end
1024
974
 
1025
975
  # Check the body
1026
976
  def parse_body(buffer)
1027
977
  super(buffer)
1028
- unless buffer.empty?
1029
- raise ProtocolException.new("Extra bytes at end of Ping Request packet")
1030
- end
978
+
979
+ return if buffer.empty?
980
+ raise ProtocolException, 'Extra bytes at end of Ping Request packet'
1031
981
  end
1032
982
  end
1033
983
 
1034
984
  # Class representing an MQTT Ping Response packet
1035
985
  class Pingresp < MQTT::Packet
1036
986
  # Create a new Ping Response packet
1037
- def initialize(args={})
987
+ def initialize(args = {})
1038
988
  super(args)
1039
989
  end
1040
990
 
1041
991
  # Check the body
1042
992
  def parse_body(buffer)
1043
993
  super(buffer)
1044
- unless buffer.empty?
1045
- raise ProtocolException.new("Extra bytes at end of Ping Response packet")
1046
- end
994
+
995
+ return if buffer.empty?
996
+ raise ProtocolException, 'Extra bytes at end of Ping Response packet'
1047
997
  end
1048
998
  end
1049
999
 
1050
1000
  # Class representing an MQTT Client Disconnect packet
1051
1001
  class Disconnect < MQTT::Packet
1052
1002
  # Create a new Client Disconnect packet
1053
- def initialize(args={})
1003
+ def initialize(args = {})
1054
1004
  super(args)
1055
1005
  end
1056
1006
 
1057
1007
  # Check the body
1058
1008
  def parse_body(buffer)
1059
1009
  super(buffer)
1060
- unless buffer.empty?
1061
- raise ProtocolException.new("Extra bytes at end of Disconnect packet")
1062
- end
1010
+
1011
+ return if buffer.empty?
1012
+ raise ProtocolException, 'Extra bytes at end of Disconnect packet'
1063
1013
  end
1064
1014
  end
1065
1015
 
1066
-
1067
1016
  # ---- Deprecated attributes and methods ---- #
1068
1017
  public
1069
1018
 
@@ -1078,7 +1027,6 @@ module MQTT
1078
1027
  end
1079
1028
  end
1080
1029
 
1081
-
1082
1030
  # An enumeration of the MQTT packet types
1083
1031
  PACKET_TYPES = [
1084
1032
  nil,
@@ -1098,5 +1046,4 @@ module MQTT
1098
1046
  MQTT::Packet::Disconnect,
1099
1047
  nil
1100
1048
  ]
1101
-
1102
1049
  end