mqtt-v3 0.0.1.ci.release
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.
- checksums.yaml +7 -0
- data/lib/mqtt/v3/async/client.rb +28 -0
- data/lib/mqtt/v3/client/connection.rb +19 -0
- data/lib/mqtt/v3/client/session.rb +37 -0
- data/lib/mqtt/v3/client.rb +23 -0
- data/lib/mqtt/v3/errors.rb +7 -0
- data/lib/mqtt/v3/packet/ack_success.rb +25 -0
- data/lib/mqtt/v3/packet/connack.rb +72 -0
- data/lib/mqtt/v3/packet/connect.rb +93 -0
- data/lib/mqtt/v3/packet/disconnect.rb +19 -0
- data/lib/mqtt/v3/packet/ping_req.rb +20 -0
- data/lib/mqtt/v3/packet/ping_resp.rb +20 -0
- data/lib/mqtt/v3/packet/pub_ack.rb +28 -0
- data/lib/mqtt/v3/packet/pub_comp.rb +29 -0
- data/lib/mqtt/v3/packet/pub_rec.rb +29 -0
- data/lib/mqtt/v3/packet/pub_rel.rb +29 -0
- data/lib/mqtt/v3/packet/publish.rb +47 -0
- data/lib/mqtt/v3/packet/sub_ack.rb +45 -0
- data/lib/mqtt/v3/packet/subscribe.rb +53 -0
- data/lib/mqtt/v3/packet/unsub_ack.rb +29 -0
- data/lib/mqtt/v3/packet/unsubscribe.rb +39 -0
- data/lib/mqtt/v3/packet.rb +38 -0
- data/lib/mqtt/v3/packets.rb +24 -0
- data/lib/mqtt/v3/version.rb +11 -0
- data/lib/mqtt/v3.rb +4 -0
- metadata +78 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: ec59d893849846a0f086529c3acf5cf9a04c1556a172cde7c3d5d7808d36c004
|
|
4
|
+
data.tar.gz: 6e031482950ee155832e34b0aebf286ef1fcd811da2465bd23c0f134cff35054
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 411041e65bcf34536b7a32d2d4f74a2c1cfa89d7d66900aff56fc279a2f3876ec95495e6a9258d0c5f083b4753398619ed90b9af3a33dd33f8adb2bd1c9c6274
|
|
7
|
+
data.tar.gz: ab9b41bf396a640c74c04223aa12b534496ef314977c785348ed6511849881c9a725a4c9bd33d5cf6bdc2562ac12c72d48d20d140d374e809017f60aae4a4df8
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'async'
|
|
4
|
+
require_relative '../client'
|
|
5
|
+
|
|
6
|
+
module MQTT
|
|
7
|
+
module V3
|
|
8
|
+
module Async
|
|
9
|
+
# An Async {MQTT::Core::Client} for MQTT 5.0
|
|
10
|
+
class Client < MQTT::V3::Client
|
|
11
|
+
class << self
|
|
12
|
+
# Create a new {Client}
|
|
13
|
+
def open(*io_args, **run_args, &)
|
|
14
|
+
unless block_given? || ::Async::Task.current?
|
|
15
|
+
raise MQTT::Error, 'async open requires a block or to be running within the async reactor'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
super
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def mqtt_monitor
|
|
22
|
+
async_monitor
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'mqtt/core/client'
|
|
4
|
+
module MQTT
|
|
5
|
+
module V3
|
|
6
|
+
class Client < MQTT::Core::Client
|
|
7
|
+
# Client protocol for MQTT 5.0
|
|
8
|
+
class Connection < MQTT::Core::Client::Connection
|
|
9
|
+
def_delegators :session, :clean_session
|
|
10
|
+
|
|
11
|
+
def handle_publish(packet)
|
|
12
|
+
raise ProtocolError, 'Received PUBLISH with DUP and QoS 0' if packet.qos.zero? && packet.dup
|
|
13
|
+
|
|
14
|
+
super
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'mqtt/core/client'
|
|
4
|
+
require_relative '../packet'
|
|
5
|
+
|
|
6
|
+
module MQTT
|
|
7
|
+
module V3
|
|
8
|
+
class Client < MQTT::Core::Client
|
|
9
|
+
# Client Session specialisation for MQTT 3.1.1
|
|
10
|
+
#
|
|
11
|
+
# Session expiry and auto-assigned client ids are simulated since they are not supported by the protocol itself.
|
|
12
|
+
# * An empty client_id and non-zero expiry_interval will auto-generate an id at the first connection.
|
|
13
|
+
# * Session expiry is only checked on the client side before sending a CONNECT packet.
|
|
14
|
+
# * The clean_session property is always set true for anonymous sessions (zero expiry + client_id empty) and
|
|
15
|
+
# this combination is not recoverable.
|
|
16
|
+
class Session < MQTT::Core::Client::Session
|
|
17
|
+
# If session expiry is non-zero and client_id is empty, then auto generate a client_id if supported by
|
|
18
|
+
# the session_store.
|
|
19
|
+
|
|
20
|
+
def connect_data(**connect)
|
|
21
|
+
check_session_managed_fields(:connect, connect, :clean_session)
|
|
22
|
+
assign_client_id if client_id.empty? && session_store.expiry_interval.positive?
|
|
23
|
+
super.merge!(client_id:, clean_session: clean?)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
# Anonymous sessions in MQTT3.0 are abandoned at disconnect.
|
|
29
|
+
# If we have a long-lived session (ie with non-zero expiry) then we need to fake server assigned id by
|
|
30
|
+
# generating one now.
|
|
31
|
+
def assign_client_id
|
|
32
|
+
session_store.client_id = session_store.generate_client_id
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'mqtt/core/client'
|
|
4
|
+
require_relative 'packets'
|
|
5
|
+
require_relative 'client/connection'
|
|
6
|
+
require_relative 'client/session'
|
|
7
|
+
|
|
8
|
+
module MQTT
|
|
9
|
+
module V3
|
|
10
|
+
# An MQTT 3.1.1 Client
|
|
11
|
+
class Client < MQTT::Core::Client
|
|
12
|
+
class << self
|
|
13
|
+
def packet_module
|
|
14
|
+
Packet
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def protocol_version
|
|
18
|
+
3
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module MQTT
|
|
4
|
+
module V3
|
|
5
|
+
module Packet
|
|
6
|
+
# MQTT 3.1.1 acknowledgement module
|
|
7
|
+
#
|
|
8
|
+
# Most V3 ACK packets have no error codes - the packet arrives successfully, or the connection is closed.
|
|
9
|
+
# This module provides success!, success?, and failed? methods for these packets.
|
|
10
|
+
module AckSuccess
|
|
11
|
+
def success?
|
|
12
|
+
true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def success!
|
|
16
|
+
self
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def failed?
|
|
20
|
+
false
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../packet'
|
|
4
|
+
|
|
5
|
+
module MQTT
|
|
6
|
+
module V3
|
|
7
|
+
class ConnectionRefused < MQTT::V3::ResponseError; end
|
|
8
|
+
|
|
9
|
+
module Packet
|
|
10
|
+
# MQTT 3.1.1 CONNACK packet
|
|
11
|
+
#
|
|
12
|
+
# Connection acknowledgement sent by broker in response to a CONNECT packet.
|
|
13
|
+
#
|
|
14
|
+
# @see Core::Client#connect
|
|
15
|
+
# @see http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718033 MQTT 3.1.1 Spec §3.2
|
|
16
|
+
class Connack
|
|
17
|
+
include Packet
|
|
18
|
+
|
|
19
|
+
fixed(2)
|
|
20
|
+
|
|
21
|
+
# @!attribute [r] session_present
|
|
22
|
+
# @return [Boolean] whether the broker has a stored session for this client
|
|
23
|
+
|
|
24
|
+
# @!attribute [r] return_code
|
|
25
|
+
# @return [Integer] connection return code:
|
|
26
|
+
#
|
|
27
|
+
# - `0x00` Connection accepted
|
|
28
|
+
# - `0x01` Unacceptable protocol version
|
|
29
|
+
# - `0x02` Identifier rejected
|
|
30
|
+
# - `0x03` Server unavailable
|
|
31
|
+
# - `0x04` Bad user name or password
|
|
32
|
+
# - `0x05` Not authorized
|
|
33
|
+
|
|
34
|
+
variable(
|
|
35
|
+
flags: flags([:reserved, 7], [:session_present, 1]),
|
|
36
|
+
return_code: :int8
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
RETURN_CODES = {
|
|
40
|
+
0x00 => :success,
|
|
41
|
+
0x01 => :unacceptable_protocol_version,
|
|
42
|
+
0x02 => :identifier_rejected,
|
|
43
|
+
0x03 => :server_unavailable,
|
|
44
|
+
0x04 => :bad_user_name_or_password,
|
|
45
|
+
0x05 => :not_authorized
|
|
46
|
+
}.freeze
|
|
47
|
+
|
|
48
|
+
def success!
|
|
49
|
+
return self if success?
|
|
50
|
+
|
|
51
|
+
raise ConnectionRefused, RETURN_CODES.fetch(return_code, :unknown_error)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def success?
|
|
55
|
+
return_code.zero?
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def failed?
|
|
59
|
+
!success?
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
alias connect_return_code return_code # align with spec naming
|
|
63
|
+
alias session_present? session_present
|
|
64
|
+
|
|
65
|
+
# @!visibility private
|
|
66
|
+
def defaults
|
|
67
|
+
super.merge!(session_present: false, return_code: 0x00)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../packet'
|
|
4
|
+
require 'mqtt/core/packet/connect'
|
|
5
|
+
|
|
6
|
+
module MQTT
|
|
7
|
+
module V3
|
|
8
|
+
module Packet
|
|
9
|
+
# MQTT 3.1.1 CONNECT packet
|
|
10
|
+
#
|
|
11
|
+
# Sent by client to establish connection with the broker.
|
|
12
|
+
#
|
|
13
|
+
# @see Core::Client#connect
|
|
14
|
+
# @see http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718028 MQTT 3.1.1 Spec §3.1
|
|
15
|
+
class Connect
|
|
16
|
+
include Packet
|
|
17
|
+
include Core::Packet::Connect
|
|
18
|
+
|
|
19
|
+
fixed(1)
|
|
20
|
+
|
|
21
|
+
# @!attribute [r] protocol_name
|
|
22
|
+
# @return [String<UTF8>] protocol name (managed automatically)
|
|
23
|
+
# @!attribute [r] protocol_version
|
|
24
|
+
# @return [Integer] protocol version (managed automatically)
|
|
25
|
+
# @!attribute [r] clean_session
|
|
26
|
+
# @return [Boolean] if true server will abandon any stored session (managed automatically from session store)
|
|
27
|
+
# @!attribute [r] will_qos
|
|
28
|
+
# @return [Integer] QoS level for the Will message: 0, 1, or 2 (default 0)
|
|
29
|
+
# @!attribute [r] will_retain
|
|
30
|
+
# @return [Boolean] should the Will message be retained (default false)
|
|
31
|
+
# @!attribute [r] keep_alive
|
|
32
|
+
# @return [Integer] maximum duration in seconds between packets sent by the client (default 60)
|
|
33
|
+
|
|
34
|
+
# @!attribute [r] client_id
|
|
35
|
+
# @return [String<UTF8>] client identifier string (auto-assigned if empty with non-zero session expiry)
|
|
36
|
+
# @!attribute [r] will_topic
|
|
37
|
+
# @return [String<UTF8>] topic name to send the Will message to
|
|
38
|
+
# @!attribute [r] will_payload
|
|
39
|
+
# @return [String<Binary>] payload of the Will message
|
|
40
|
+
# @!attribute [r] username
|
|
41
|
+
# @return [String<UTF8>] username for authenticating with the server
|
|
42
|
+
# @!attribute [r] password
|
|
43
|
+
# @return [String<Binary>] password for authenticating with the server
|
|
44
|
+
|
|
45
|
+
variable(
|
|
46
|
+
protocol_name: :utf8string,
|
|
47
|
+
protocol_version: :int8,
|
|
48
|
+
connect_flags: flags(
|
|
49
|
+
:username_flag, :password_flag,
|
|
50
|
+
:will_retain,
|
|
51
|
+
[:will_qos, 2],
|
|
52
|
+
:will_flag,
|
|
53
|
+
:clean_session,
|
|
54
|
+
:reserved
|
|
55
|
+
),
|
|
56
|
+
keep_alive: :int16
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
payload(
|
|
60
|
+
client_id: :utf8string,
|
|
61
|
+
will_topic: { type: :utf8string, if: :will_flag },
|
|
62
|
+
will_payload: { type: :binary, if: :will_flag },
|
|
63
|
+
username: { type: :utf8string, if: :username },
|
|
64
|
+
password: { type: :binary, if: :password }
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
alias clean_requested? clean_session
|
|
68
|
+
alias username? :username_flag
|
|
69
|
+
alias password? :password_flag
|
|
70
|
+
alias will_flag? :will_flag
|
|
71
|
+
|
|
72
|
+
# @!visibility private
|
|
73
|
+
def defaults
|
|
74
|
+
super.merge!(client_id: nil, keep_alive: 60, clean_session: true, will_qos: 0, will_retain: false)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# @!visibility private
|
|
78
|
+
def apply_overrides(data)
|
|
79
|
+
super
|
|
80
|
+
data.merge!(
|
|
81
|
+
protocol_name: 'MQTT',
|
|
82
|
+
protocol_version: PROTOCOL_VERSION
|
|
83
|
+
)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# @!visibility private
|
|
87
|
+
def success!(connack)
|
|
88
|
+
connack.success!
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module MQTT
|
|
4
|
+
module V3
|
|
5
|
+
module Packet
|
|
6
|
+
# MQTT 3.1.1 DISCONNECT packet
|
|
7
|
+
#
|
|
8
|
+
# Sent by client to gracefully disconnect from the broker.
|
|
9
|
+
#
|
|
10
|
+
# @see Core::Client#disconnect
|
|
11
|
+
# @see http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718090 MQTT 3.1.1 Spec §3.14
|
|
12
|
+
class Disconnect
|
|
13
|
+
include Packet
|
|
14
|
+
|
|
15
|
+
fixed(14)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../packet'
|
|
4
|
+
|
|
5
|
+
module MQTT
|
|
6
|
+
module V3
|
|
7
|
+
module Packet
|
|
8
|
+
# MQTT 3.1.1 PINGREQ packet
|
|
9
|
+
#
|
|
10
|
+
# Sent by client to keep the connection alive.
|
|
11
|
+
#
|
|
12
|
+
# @see http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718081 MQTT 3.1.1 Spec §3.12
|
|
13
|
+
class PingReq
|
|
14
|
+
include Packet
|
|
15
|
+
|
|
16
|
+
fixed(12)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../packet'
|
|
4
|
+
|
|
5
|
+
module MQTT
|
|
6
|
+
module V3
|
|
7
|
+
module Packet
|
|
8
|
+
# MQTT 3.1.1 PINGRESP packet
|
|
9
|
+
#
|
|
10
|
+
# Sent by broker in response to a PINGREQ packet.
|
|
11
|
+
#
|
|
12
|
+
# @see http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718086 MQTT 3.1.1 Spec §3.13
|
|
13
|
+
class PingResp
|
|
14
|
+
include Packet
|
|
15
|
+
|
|
16
|
+
fixed(13)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../packet'
|
|
4
|
+
require_relative 'ack_success'
|
|
5
|
+
module MQTT
|
|
6
|
+
module V3
|
|
7
|
+
module Packet
|
|
8
|
+
# MQTT 3.1.1 PUBACK packet
|
|
9
|
+
#
|
|
10
|
+
# QoS 1 acknowledgement sent by broker in response to a PUBLISH packet.
|
|
11
|
+
#
|
|
12
|
+
# @see Core::Client#publish
|
|
13
|
+
# @see http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718043 MQTT 3.1.1 Spec §3.4
|
|
14
|
+
class PubAck
|
|
15
|
+
include Packet
|
|
16
|
+
|
|
17
|
+
fixed(4)
|
|
18
|
+
|
|
19
|
+
# @!attribute [r] packet_identifier
|
|
20
|
+
# @return [Integer] packet identifier matching the PUBLISH packet (receive only)
|
|
21
|
+
|
|
22
|
+
variable(packet_identifier: :int16)
|
|
23
|
+
|
|
24
|
+
include AckSuccess
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../packet'
|
|
4
|
+
require_relative 'ack_success'
|
|
5
|
+
|
|
6
|
+
module MQTT
|
|
7
|
+
module V3
|
|
8
|
+
module Packet
|
|
9
|
+
# MQTT 3.1.1 PUBCOMP packet
|
|
10
|
+
#
|
|
11
|
+
# QoS 2 publish complete (part 3) sent by broker in response to a PUBREL packet.
|
|
12
|
+
#
|
|
13
|
+
# @see Core::Client#publish
|
|
14
|
+
# @see http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718058 MQTT 3.1.1 Spec §3.7
|
|
15
|
+
class PubComp
|
|
16
|
+
include Packet
|
|
17
|
+
|
|
18
|
+
fixed(7)
|
|
19
|
+
|
|
20
|
+
# @!attribute [r] packet_identifier
|
|
21
|
+
# @return [Integer] packet identifier matching the PUBREL packet (receive only)
|
|
22
|
+
|
|
23
|
+
variable(packet_identifier: :int16)
|
|
24
|
+
|
|
25
|
+
include AckSuccess
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../packet'
|
|
4
|
+
require_relative 'ack_success'
|
|
5
|
+
|
|
6
|
+
module MQTT
|
|
7
|
+
module V3
|
|
8
|
+
module Packet
|
|
9
|
+
# MQTT 3.1.1 PUBREC packet
|
|
10
|
+
#
|
|
11
|
+
# QoS 2 acknowledgement (part 1) sent by broker in response to a PUBLISH packet.
|
|
12
|
+
#
|
|
13
|
+
# @see Core::Client#publish
|
|
14
|
+
# @see http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718048 MQTT 3.1.1 Spec §3.5
|
|
15
|
+
class PubRec
|
|
16
|
+
include Packet
|
|
17
|
+
|
|
18
|
+
fixed(5)
|
|
19
|
+
|
|
20
|
+
# @!attribute [r] packet_identifier
|
|
21
|
+
# @return [Integer] packet identifier matching the PUBLISH packet (receive only)
|
|
22
|
+
|
|
23
|
+
variable(packet_identifier: :int16)
|
|
24
|
+
|
|
25
|
+
include AckSuccess
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../packet'
|
|
4
|
+
require_relative 'ack_success'
|
|
5
|
+
|
|
6
|
+
module MQTT
|
|
7
|
+
module V3
|
|
8
|
+
module Packet
|
|
9
|
+
# MQTT 3.1.1 PUBREL packet
|
|
10
|
+
#
|
|
11
|
+
# QoS 2 publish release (part 2) sent by client in response to a PUBREC packet.
|
|
12
|
+
#
|
|
13
|
+
# @see Core::Client#publish
|
|
14
|
+
# @see http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718053 MQTT 3.1.1 Spec §3.6
|
|
15
|
+
class PubRel
|
|
16
|
+
include Packet
|
|
17
|
+
|
|
18
|
+
fixed(6, [:reserved, 4, 0b0010])
|
|
19
|
+
|
|
20
|
+
# @!attribute [r] packet_identifier
|
|
21
|
+
# @return [Integer] packet identifier matching the PUBREC packet (receive only)
|
|
22
|
+
|
|
23
|
+
variable(packet_identifier: :int16)
|
|
24
|
+
|
|
25
|
+
include AckSuccess
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../packet'
|
|
4
|
+
require 'mqtt/core/packet/publish'
|
|
5
|
+
|
|
6
|
+
module MQTT
|
|
7
|
+
module V3
|
|
8
|
+
module Packet
|
|
9
|
+
# MQTT 3.1.1 PUBLISH packet
|
|
10
|
+
#
|
|
11
|
+
# Sent by client to publish a message to the broker, or received from broker when subscribed to a topic.
|
|
12
|
+
#
|
|
13
|
+
# @see Core::Client#publish
|
|
14
|
+
# @see http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718037 MQTT 3.1.1 Spec §3.3
|
|
15
|
+
class Publish
|
|
16
|
+
include Packet
|
|
17
|
+
include Core::Packet::Publish
|
|
18
|
+
|
|
19
|
+
# @!attribute [r] dup
|
|
20
|
+
# @return [Boolean] duplicate delivery flag (managed automatically by session)
|
|
21
|
+
# @!attribute [r] qos
|
|
22
|
+
# @return [Integer] QoS level: 0, 1, or 2 (default 0)
|
|
23
|
+
# @!attribute [r] retain
|
|
24
|
+
# @return [Boolean] retain flag (default false)
|
|
25
|
+
|
|
26
|
+
fixed(3, :dup, [:qos, 2], :retain)
|
|
27
|
+
|
|
28
|
+
# @!attribute [r] topic_name
|
|
29
|
+
# @return [String<UTF8>] topic name to publish to
|
|
30
|
+
# @!attribute [r] packet_identifier
|
|
31
|
+
# @return [Integer] packet identifier for QoS 1/2 exchanges (managed automatically by session)
|
|
32
|
+
|
|
33
|
+
variable(
|
|
34
|
+
topic_name: :utf8string,
|
|
35
|
+
packet_identifier: { type: :int16, if: -> { qos.positive? } }
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# @!attribute [r] payload
|
|
39
|
+
# @return [String<Binary>] message payload
|
|
40
|
+
|
|
41
|
+
payload(payload: :remaining)
|
|
42
|
+
|
|
43
|
+
alias topic topic_name
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../packet'
|
|
4
|
+
|
|
5
|
+
module MQTT
|
|
6
|
+
module V3
|
|
7
|
+
module Packet
|
|
8
|
+
class SubscriptionFailed < MQTT::V3::ResponseError; end
|
|
9
|
+
|
|
10
|
+
# MQTT 3.1.1 SUBACK packet
|
|
11
|
+
#
|
|
12
|
+
# Subscription acknowledgement sent by broker in response to a SUBSCRIBE packet.
|
|
13
|
+
#
|
|
14
|
+
# @see Core::Client#subscribe
|
|
15
|
+
# @see http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718068 MQTT 3.1.1 Spec §3.9
|
|
16
|
+
class SubAck
|
|
17
|
+
include Packet
|
|
18
|
+
|
|
19
|
+
fixed(9)
|
|
20
|
+
|
|
21
|
+
# @!attribute [r] packet_identifier
|
|
22
|
+
# @return [Integer] packet identifier matching the SUBSCRIBE packet (receive only)
|
|
23
|
+
|
|
24
|
+
# @!attribute [r] return_codes
|
|
25
|
+
# @return [Array<Integer>]
|
|
26
|
+
# return code for each subscription:
|
|
27
|
+
#
|
|
28
|
+
# - `0x00` Granted QoS 0
|
|
29
|
+
# - `0x01` Granted QoS 1
|
|
30
|
+
# - `0x02` Granted QoS 2
|
|
31
|
+
# - `0x80` Failure
|
|
32
|
+
|
|
33
|
+
variable(packet_identifier: :int16)
|
|
34
|
+
payload(return_codes: list(:int8))
|
|
35
|
+
|
|
36
|
+
RETURN_CODES = {
|
|
37
|
+
0x00 => 'Granted QoS 0',
|
|
38
|
+
0x01 => 'Granted QoS 1',
|
|
39
|
+
0x02 => 'Granted QoS 2',
|
|
40
|
+
0x80 => 'Failure'
|
|
41
|
+
}.freeze
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../packet'
|
|
4
|
+
require 'mqtt/core/packet/subscribe'
|
|
5
|
+
|
|
6
|
+
module MQTT
|
|
7
|
+
module V3
|
|
8
|
+
module Packet
|
|
9
|
+
# MQTT 3.1.1 SUBSCRIBE packet
|
|
10
|
+
#
|
|
11
|
+
# Sent by client to subscribe to one or more topic filters.
|
|
12
|
+
#
|
|
13
|
+
# @see Core::Client#subscribe
|
|
14
|
+
# @see http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718063 MQTT 3.1.1 Spec §3.8
|
|
15
|
+
class Subscribe
|
|
16
|
+
include Packet
|
|
17
|
+
|
|
18
|
+
fixed(8, [:reserved, 4, 0b0010])
|
|
19
|
+
|
|
20
|
+
# @!attribute [r] packet_identifier
|
|
21
|
+
# @return [Integer] packet identifier for matching with SUBACK (managed automatically by session)
|
|
22
|
+
|
|
23
|
+
# @!parse
|
|
24
|
+
# class TopicFilter
|
|
25
|
+
# # @!attribute [r] topic_filter
|
|
26
|
+
# # @return [String<UTF8>] topic filter pattern
|
|
27
|
+
# # @!attribute [r] requested_qos
|
|
28
|
+
# # @return [Integer] maximum QoS level accepted by the client: 0, 1, or 2
|
|
29
|
+
# end
|
|
30
|
+
|
|
31
|
+
# @!attribute [r] topic_filters
|
|
32
|
+
# @return [Array<TopicFilter>] list of topic filters to subscribe to
|
|
33
|
+
|
|
34
|
+
variable(packet_identifier: :int16)
|
|
35
|
+
payload(
|
|
36
|
+
topic_filters: list(
|
|
37
|
+
:topic_filter,
|
|
38
|
+
topic_filter: :utf8string,
|
|
39
|
+
subscription_options: flags(
|
|
40
|
+
[:reserved, 6],
|
|
41
|
+
[:requested_qos, 2]
|
|
42
|
+
)
|
|
43
|
+
) do
|
|
44
|
+
alias_method :max_qos, :requested_qos
|
|
45
|
+
end
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
MAX_QOS_FIELD = :requested_qos
|
|
49
|
+
include MQTT::Core::Packet::Subscribe
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../packet'
|
|
4
|
+
require_relative 'ack_success'
|
|
5
|
+
|
|
6
|
+
module MQTT
|
|
7
|
+
module V3
|
|
8
|
+
module Packet
|
|
9
|
+
# MQTT 3.1.1 UNSUBACK packet
|
|
10
|
+
#
|
|
11
|
+
# Unsubscribe acknowledgement sent by broker in response to an UNSUBSCRIBE packet.
|
|
12
|
+
#
|
|
13
|
+
# @see Core::Client::Subscription#unsubscribe
|
|
14
|
+
# @see http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718077 MQTT 3.1.1 Spec §3.11
|
|
15
|
+
class UnsubAck
|
|
16
|
+
include Packet
|
|
17
|
+
|
|
18
|
+
fixed(11)
|
|
19
|
+
|
|
20
|
+
# @!attribute [r] packet_identifier
|
|
21
|
+
# @return [Integer] packet identifier matching the UNSUBSCRIBE packet (receive only)
|
|
22
|
+
|
|
23
|
+
variable(packet_identifier: :int16)
|
|
24
|
+
|
|
25
|
+
include AckSuccess
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../packet'
|
|
4
|
+
require 'mqtt/core/packet/unsubscribe'
|
|
5
|
+
|
|
6
|
+
module MQTT
|
|
7
|
+
module V3
|
|
8
|
+
module Packet
|
|
9
|
+
# MQTT 3.1.1 UNSUBSCRIBE packet
|
|
10
|
+
#
|
|
11
|
+
# Sent by client to unsubscribe from one or more topic filters.
|
|
12
|
+
#
|
|
13
|
+
# @see Core::Client::Subscription#unsubscribe
|
|
14
|
+
# @see http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718072 MQTT 3.1.1 Spec §3.10
|
|
15
|
+
class Unsubscribe
|
|
16
|
+
include Packet
|
|
17
|
+
include Core::Packet::Unsubscribe
|
|
18
|
+
|
|
19
|
+
fixed(10, [:reserved, 4, 0b0010])
|
|
20
|
+
|
|
21
|
+
# @!attribute [r] packet_identifier
|
|
22
|
+
# @return [Integer] packet identifier for matching with UNSUBACK (managed automatically by session)
|
|
23
|
+
|
|
24
|
+
# @!attribute [r] topic_filters
|
|
25
|
+
# @return [Array<String<UTF8>>] list of topic filters to unsubscribe from
|
|
26
|
+
|
|
27
|
+
variable(packet_identifier: :int16)
|
|
28
|
+
payload(topic_filters: list(:utf8string))
|
|
29
|
+
|
|
30
|
+
alias unsubscribed_topic_filters topic_filters
|
|
31
|
+
|
|
32
|
+
# @!visibility private
|
|
33
|
+
def success!(_unsuback)
|
|
34
|
+
self
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'mqtt/core/packet'
|
|
4
|
+
require_relative 'version'
|
|
5
|
+
require_relative 'errors'
|
|
6
|
+
|
|
7
|
+
module MQTT
|
|
8
|
+
module V3
|
|
9
|
+
# MQTT 5.0 base packet definition
|
|
10
|
+
#
|
|
11
|
+
# Inherited constants (referenced via self:: in {MQTT::Core::Packet}
|
|
12
|
+
module Packet
|
|
13
|
+
VALUE_TYPES = {
|
|
14
|
+
utf8string: MQTT::Core::Type::UTF8String,
|
|
15
|
+
binary: MQTT::Core::Type::Binary,
|
|
16
|
+
remaining: MQTT::Core::Type::Remaining,
|
|
17
|
+
int8: MQTT::Core::Type::Int8,
|
|
18
|
+
int16: MQTT::Core::Type::Int16,
|
|
19
|
+
int32: MQTT::Core::Type::Int32,
|
|
20
|
+
intvar: MQTT::Core::Type::VarInt,
|
|
21
|
+
varint: MQTT::Core::Type::VarInt,
|
|
22
|
+
boolean: MQTT::Core::Type::BooleanByte
|
|
23
|
+
}.freeze
|
|
24
|
+
|
|
25
|
+
PROPERTY_TYPES = [].freeze
|
|
26
|
+
|
|
27
|
+
# rubocop:disable Style/MutableConstant
|
|
28
|
+
PACKET_TYPES = {}
|
|
29
|
+
# rubocop:enable Style/MutableConstant
|
|
30
|
+
|
|
31
|
+
extend MQTT::Core::Packet::ModuleMethods
|
|
32
|
+
|
|
33
|
+
def self.included(mod)
|
|
34
|
+
mod.include(MQTT::Core::Packet)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# MQTT 5.0
|
|
4
|
+
module MQTT
|
|
5
|
+
# MQTT 3.1.1 protocol implementation
|
|
6
|
+
module V3
|
|
7
|
+
require_relative 'packet/connect'
|
|
8
|
+
require_relative 'packet/connack'
|
|
9
|
+
require_relative 'packet/disconnect'
|
|
10
|
+
require_relative 'packet/ping_req'
|
|
11
|
+
require_relative 'packet/ping_resp'
|
|
12
|
+
require_relative 'packet/publish'
|
|
13
|
+
require_relative 'packet/pub_ack'
|
|
14
|
+
require_relative 'packet/pub_rec'
|
|
15
|
+
require_relative 'packet/pub_rel'
|
|
16
|
+
require_relative 'packet/pub_comp'
|
|
17
|
+
require_relative 'packet/subscribe'
|
|
18
|
+
require_relative 'packet/sub_ack'
|
|
19
|
+
require_relative 'packet/unsubscribe'
|
|
20
|
+
require_relative 'packet/unsub_ack'
|
|
21
|
+
|
|
22
|
+
MQTT::V3::Packet::PACKET_TYPES.freeze
|
|
23
|
+
end
|
|
24
|
+
end
|
data/lib/mqtt/v3.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: mqtt-v3
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1.ci.release
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Grant Gardner
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: mqtt-core
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
26
|
+
description: MQTT version 3.1.1 protocol implementation
|
|
27
|
+
email:
|
|
28
|
+
- grant@lastweekend.com.au
|
|
29
|
+
executables: []
|
|
30
|
+
extensions: []
|
|
31
|
+
extra_rdoc_files: []
|
|
32
|
+
files:
|
|
33
|
+
- lib/mqtt/v3.rb
|
|
34
|
+
- lib/mqtt/v3/async/client.rb
|
|
35
|
+
- lib/mqtt/v3/client.rb
|
|
36
|
+
- lib/mqtt/v3/client/connection.rb
|
|
37
|
+
- lib/mqtt/v3/client/session.rb
|
|
38
|
+
- lib/mqtt/v3/errors.rb
|
|
39
|
+
- lib/mqtt/v3/packet.rb
|
|
40
|
+
- lib/mqtt/v3/packet/ack_success.rb
|
|
41
|
+
- lib/mqtt/v3/packet/connack.rb
|
|
42
|
+
- lib/mqtt/v3/packet/connect.rb
|
|
43
|
+
- lib/mqtt/v3/packet/disconnect.rb
|
|
44
|
+
- lib/mqtt/v3/packet/ping_req.rb
|
|
45
|
+
- lib/mqtt/v3/packet/ping_resp.rb
|
|
46
|
+
- lib/mqtt/v3/packet/pub_ack.rb
|
|
47
|
+
- lib/mqtt/v3/packet/pub_comp.rb
|
|
48
|
+
- lib/mqtt/v3/packet/pub_rec.rb
|
|
49
|
+
- lib/mqtt/v3/packet/pub_rel.rb
|
|
50
|
+
- lib/mqtt/v3/packet/publish.rb
|
|
51
|
+
- lib/mqtt/v3/packet/sub_ack.rb
|
|
52
|
+
- lib/mqtt/v3/packet/subscribe.rb
|
|
53
|
+
- lib/mqtt/v3/packet/unsub_ack.rb
|
|
54
|
+
- lib/mqtt/v3/packet/unsubscribe.rb
|
|
55
|
+
- lib/mqtt/v3/packets.rb
|
|
56
|
+
- lib/mqtt/v3/version.rb
|
|
57
|
+
licenses:
|
|
58
|
+
- MIT
|
|
59
|
+
metadata:
|
|
60
|
+
rubygems_mfa_required: 'true'
|
|
61
|
+
rdoc_options: []
|
|
62
|
+
require_paths:
|
|
63
|
+
- lib
|
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '3.4'
|
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
|
+
requirements:
|
|
71
|
+
- - ">="
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '0'
|
|
74
|
+
requirements: []
|
|
75
|
+
rubygems_version: 3.6.9
|
|
76
|
+
specification_version: 4
|
|
77
|
+
summary: Ruby MQTT 3.1.1
|
|
78
|
+
test_files: []
|