maxcube-client 0.4.1 → 0.5.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.
- checksums.yaml +4 -4
- data/.gitignore +6 -0
- data/.rubocop.yml +0 -3
- data/.yardopts +1 -0
- data/README.md +17 -2
- data/bin/maxcube-client +2 -27
- data/doc/MaxCube.html +502 -0
- data/doc/MaxCube/Messages.html +1927 -0
- data/doc/MaxCube/Messages/Handler.html +2912 -0
- data/doc/MaxCube/Messages/InvalidMessage.html +140 -0
- data/doc/MaxCube/Messages/InvalidMessageBody.html +264 -0
- data/doc/MaxCube/Messages/InvalidMessageFormat.html +247 -0
- data/doc/MaxCube/Messages/InvalidMessageLength.html +247 -0
- data/doc/MaxCube/Messages/InvalidMessageType.html +263 -0
- data/doc/MaxCube/Messages/Parser.html +520 -0
- data/doc/MaxCube/Messages/Serializer.html +701 -0
- data/doc/MaxCube/Messages/TCP.html +172 -0
- data/doc/MaxCube/Messages/TCP/Handler.html +1396 -0
- data/doc/MaxCube/Messages/TCP/Parser.html +462 -0
- data/doc/MaxCube/Messages/TCP/Parser/MessageA.html +186 -0
- data/doc/MaxCube/Messages/TCP/Parser/MessageC.html +1077 -0
- data/doc/MaxCube/Messages/TCP/Parser/MessageF.html +206 -0
- data/doc/MaxCube/Messages/TCP/Parser/MessageH.html +338 -0
- data/doc/MaxCube/Messages/TCP/Parser/MessageL.html +535 -0
- data/doc/MaxCube/Messages/TCP/Parser/MessageM.html +510 -0
- data/doc/MaxCube/Messages/TCP/Parser/MessageN.html +226 -0
- data/doc/MaxCube/Messages/TCP/Parser/MessageS.html +225 -0
- data/doc/MaxCube/Messages/TCP/Serializer.html +460 -0
- data/doc/MaxCube/Messages/TCP/Serializer/MessageA.html +186 -0
- data/doc/MaxCube/Messages/TCP/Serializer/MessageC.html +185 -0
- data/doc/MaxCube/Messages/TCP/Serializer/MessageF.html +206 -0
- data/doc/MaxCube/Messages/TCP/Serializer/MessageL.html +185 -0
- data/doc/MaxCube/Messages/TCP/Serializer/MessageM.html +428 -0
- data/doc/MaxCube/Messages/TCP/Serializer/MessageN.html +209 -0
- data/doc/MaxCube/Messages/TCP/Serializer/MessageQ.html +185 -0
- data/doc/MaxCube/Messages/TCP/Serializer/MessageS.html +1168 -0
- data/doc/MaxCube/Messages/TCP/Serializer/MessageT.html +240 -0
- data/doc/MaxCube/Messages/TCP/Serializer/MessageU.html +206 -0
- data/doc/MaxCube/Messages/TCP/Serializer/MessageZ.html +252 -0
- data/doc/MaxCube/Messages/UDP.html +164 -0
- data/doc/MaxCube/Messages/UDP/Handler.html +832 -0
- data/doc/MaxCube/Messages/UDP/Parser.html +609 -0
- data/doc/MaxCube/Messages/UDP/Parser/MessageH.html +218 -0
- data/doc/MaxCube/Messages/UDP/Parser/MessageI.html +215 -0
- data/doc/MaxCube/Messages/UDP/Parser/MessageN.html +226 -0
- data/doc/MaxCube/Messages/UDP/Serializer.html +484 -0
- data/doc/MaxCube/Network.html +167 -0
- data/doc/MaxCube/Network/TCP.html +150 -0
- data/doc/MaxCube/Network/TCP/Client.html +1930 -0
- data/doc/MaxCube/Network/TCP/Client/Commands.html +2457 -0
- data/doc/MaxCube/Network/TCP/SampleServer.html +910 -0
- data/doc/MaxCube/Network/UDP.html +150 -0
- data/doc/MaxCube/Network/UDP/Client.html +518 -0
- data/doc/MaxCube/Network/UDP/SampleSocket.html +628 -0
- data/doc/MaxCube/Runner.html +355 -0
- data/doc/_index.html +518 -0
- data/doc/class_list.html +51 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +58 -0
- data/doc/css/style.css +499 -0
- data/doc/file.README.html +140 -0
- data/doc/file_list.html +56 -0
- data/doc/frames.html +17 -0
- data/doc/index.html +140 -0
- data/doc/js/app.js +248 -0
- data/doc/js/full_list.js +216 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +1699 -0
- data/doc/top-level-namespace.html +110 -0
- data/lib/maxcube.rb +11 -0
- data/lib/maxcube/messages.rb +85 -8
- data/lib/maxcube/messages/handler.rb +138 -4
- data/lib/maxcube/messages/parser.rb +33 -2
- data/lib/maxcube/messages/serializer.rb +64 -16
- data/lib/maxcube/messages/tcp.rb +11 -7
- data/lib/maxcube/messages/tcp/handler.rb +50 -2
- data/lib/maxcube/messages/tcp/parser.rb +18 -17
- data/lib/maxcube/messages/tcp/serializer.rb +20 -21
- data/lib/maxcube/messages/tcp/type/a.rb +6 -6
- data/lib/maxcube/messages/tcp/type/c.rb +5 -3
- data/lib/maxcube/messages/tcp/type/f.rb +5 -3
- data/lib/maxcube/messages/tcp/type/h.rb +3 -2
- data/lib/maxcube/messages/tcp/type/l.rb +8 -7
- data/lib/maxcube/messages/tcp/type/m.rb +11 -7
- data/lib/maxcube/messages/tcp/type/n.rb +5 -3
- data/lib/maxcube/messages/tcp/type/q.rb +2 -2
- data/lib/maxcube/messages/tcp/type/s.rb +5 -2
- data/lib/maxcube/messages/tcp/type/t.rb +5 -4
- data/lib/maxcube/messages/tcp/type/u.rb +2 -1
- data/lib/maxcube/messages/tcp/type/z.rb +4 -2
- data/lib/maxcube/messages/udp.rb +7 -0
- data/lib/maxcube/messages/udp/handler.rb +28 -0
- data/lib/maxcube/messages/udp/parser.rb +23 -6
- data/lib/maxcube/messages/udp/serializer.rb +17 -1
- data/lib/maxcube/messages/udp/type/h.rb +2 -0
- data/lib/maxcube/messages/udp/type/i.rb +3 -0
- data/lib/maxcube/messages/udp/type/n.rb +3 -0
- data/lib/maxcube/network.rb +5 -1
- data/lib/maxcube/network/tcp.rb +3 -0
- data/lib/maxcube/network/tcp/client.rb +117 -3
- data/lib/maxcube/network/tcp/client/commands.rb +306 -239
- data/lib/maxcube/network/tcp/sample_server.rb +1 -0
- data/lib/maxcube/network/udp.rb +3 -0
- data/lib/maxcube/network/udp/client.rb +2 -0
- data/lib/maxcube/network/udp/sample_socket.rb +1 -0
- data/lib/maxcube/runner.rb +45 -0
- data/lib/maxcube/version.rb +2 -1
- data/maxcube-client.gemspec +2 -0
- metadata +84 -3
@@ -3,11 +3,14 @@ module MaxCube
|
|
3
3
|
module Messages
|
4
4
|
module TCP
|
5
5
|
class Parser
|
6
|
+
# Configuration message.
|
6
7
|
module MessageC
|
7
8
|
private
|
8
9
|
|
10
|
+
# Mandatory hash keys.
|
9
11
|
KEYS = %i[length address rf_address device_type
|
10
12
|
test_result serial_number].freeze
|
13
|
+
# Optional hash keys.
|
11
14
|
OPT_KEYS = %i[
|
12
15
|
firmware_version _firmware_version room_id
|
13
16
|
|
@@ -25,7 +28,6 @@ module MaxCube
|
|
25
28
|
|
26
29
|
LENGTHS = [6].freeze
|
27
30
|
|
28
|
-
# Configuration message
|
29
31
|
def parse_tcp_c(body)
|
30
32
|
addr, enc_data = parse_tcp_c_split(body)
|
31
33
|
|
@@ -233,11 +235,11 @@ module MaxCube
|
|
233
235
|
end
|
234
236
|
|
235
237
|
class Serializer
|
238
|
+
# Request for configuration message (C).
|
239
|
+
# Does not contain any data.
|
236
240
|
module MessageC
|
237
241
|
private
|
238
242
|
|
239
|
-
# Request for configuration message (C)
|
240
|
-
# Does not contain any data
|
241
243
|
def serialize_tcp_c(_hash)
|
242
244
|
''
|
243
245
|
end
|
@@ -3,12 +3,13 @@ module MaxCube
|
|
3
3
|
module Messages
|
4
4
|
module TCP
|
5
5
|
class Parser
|
6
|
+
# NTP server message.
|
6
7
|
module MessageF
|
7
8
|
private
|
8
9
|
|
10
|
+
# Mandatory hash keys.
|
9
11
|
KEYS = %i[ntp_servers].freeze
|
10
12
|
|
11
|
-
# NTP server message
|
12
13
|
def parse_tcp_f(body)
|
13
14
|
{ ntp_servers: body.split(',') }
|
14
15
|
end
|
@@ -16,13 +17,14 @@ module MaxCube
|
|
16
17
|
end
|
17
18
|
|
18
19
|
class Serializer
|
20
|
+
# Request for NTP servers message (F).
|
21
|
+
# Optionally, updates can be done.
|
19
22
|
module MessageF
|
20
23
|
private
|
21
24
|
|
25
|
+
# Optional hash keys.
|
22
26
|
OPT_KEYS = %i[ntp_servers].freeze
|
23
27
|
|
24
|
-
# Request for NTP servers message (F)
|
25
|
-
# Optionally, updates can be done
|
26
28
|
def serialize_tcp_f(hash)
|
27
29
|
hash.key?(:ntp_servers) ? hash[:ntp_servers].join(',') : ''
|
28
30
|
end
|
@@ -3,11 +3,13 @@ module MaxCube
|
|
3
3
|
module Messages
|
4
4
|
module TCP
|
5
5
|
class Parser
|
6
|
+
# Hello message
|
6
7
|
module MessageH
|
7
8
|
private
|
8
9
|
|
9
10
|
LENGTHS = [10, 6, 4, 8, 8, 2, 2, 6, 4, 2, 4].freeze
|
10
11
|
|
12
|
+
# Mandatory hash keys.
|
11
13
|
KEYS = %i[
|
12
14
|
serial_number
|
13
15
|
rf_address
|
@@ -21,7 +23,6 @@ module MaxCube
|
|
21
23
|
ntp_counter
|
22
24
|
].freeze
|
23
25
|
|
24
|
-
# Hello message
|
25
26
|
def parse_tcp_h(body)
|
26
27
|
values = body.split(',')
|
27
28
|
check_msg_part_lengths(LENGTHS, *values)
|
@@ -55,7 +56,7 @@ module MaxCube
|
|
55
56
|
hours = time[0..1].to_i(16)
|
56
57
|
minutes = time[2..3].to_i(16)
|
57
58
|
|
58
|
-
values[7] =
|
59
|
+
values[7] = Time.new(year, month, day, hours, minutes)
|
59
60
|
values.delete_at(8)
|
60
61
|
rescue ArgumentError
|
61
62
|
raise InvalidMessageBody
|
@@ -3,14 +3,15 @@ module MaxCube
|
|
3
3
|
module Messages
|
4
4
|
module TCP
|
5
5
|
class Parser
|
6
|
+
# Device list message.
|
6
7
|
module MessageL
|
7
8
|
private
|
8
9
|
|
9
10
|
LENGTHS = [6, 11, 12].freeze
|
10
11
|
|
12
|
+
# Mandatory hash keys.
|
11
13
|
KEYS = %i[devices].freeze
|
12
14
|
|
13
|
-
# Device list message
|
14
15
|
def parse_tcp_l(body)
|
15
16
|
@io = StringIO.new(decode(body), 'rb')
|
16
17
|
|
@@ -22,7 +23,7 @@ module MaxCube
|
|
22
23
|
parse_tcp_l_submsg_3(subhash, temperature_msb) if @length > 11
|
23
24
|
|
24
25
|
hash[:devices] << subhash
|
25
|
-
end
|
26
|
+
end
|
26
27
|
|
27
28
|
hash
|
28
29
|
end
|
@@ -82,11 +83,11 @@ module MaxCube
|
|
82
83
|
# Sometimes when device is in 'auto' mode,
|
83
84
|
# this field can contain 'actual_temperature' instead
|
84
85
|
# (but never if it is already contained in next byte)
|
85
|
-
# !It seems that '
|
86
|
+
# !It seems that 'date' is used for 'vacation' mode,
|
86
87
|
# but it is not sure ...
|
87
88
|
begin
|
88
|
-
subhash[:datetime_until] =
|
89
|
-
|
89
|
+
subhash[:datetime_until] = Time.new(year, month, day,
|
90
|
+
hours, minutes)
|
90
91
|
rescue ArgumentError
|
91
92
|
if @mode != :auto || @length > 11
|
92
93
|
raise InvalidMessageBody
|
@@ -116,11 +117,11 @@ module MaxCube
|
|
116
117
|
end
|
117
118
|
|
118
119
|
class Serializer
|
120
|
+
# Command to resend device list (L).
|
121
|
+
# Does not contain any data.
|
119
122
|
module MessageL
|
120
123
|
private
|
121
124
|
|
122
|
-
# Command to resend device list (L)
|
123
|
-
# Does not contain any data
|
124
125
|
def serialize_tcp_l(_hash)
|
125
126
|
''
|
126
127
|
end
|
@@ -3,15 +3,16 @@ module MaxCube
|
|
3
3
|
module Messages
|
4
4
|
module TCP
|
5
5
|
class Parser
|
6
|
+
# Metadata message.
|
6
7
|
module MessageM
|
7
8
|
private
|
8
9
|
|
9
10
|
LENGTHS = [2, 2].freeze
|
10
11
|
|
12
|
+
# Mandatory hash keys.
|
11
13
|
KEYS = %i[index count unknown1 unknown2
|
12
14
|
rooms_count rooms devices_count devices].freeze
|
13
15
|
|
14
|
-
# Metadata message
|
15
16
|
def parse_tcp_m(body)
|
16
17
|
index, count, enc_data = parse_tcp_m_split(body)
|
17
18
|
|
@@ -104,18 +105,21 @@ module MaxCube
|
|
104
105
|
end
|
105
106
|
|
106
107
|
class Serializer
|
108
|
+
# Serializes metadata for Cube.
|
109
|
+
# Message body has the same format as response (M)
|
110
|
+
# -> reverse operations.
|
111
|
+
# Cube does not check data format,
|
112
|
+
# so things could break if invalid data is sent.
|
113
|
+
#
|
114
|
+
# ! I couldn't verify the assumption that bodies should be the same.
|
107
115
|
module MessageM
|
108
116
|
private
|
109
117
|
|
118
|
+
# Mandatory hash keys.
|
110
119
|
KEYS = %i[rooms_count rooms devices_count devices].freeze
|
120
|
+
# Optional hash keys.
|
111
121
|
OPT_KEYS = %i[index unknown1 unknown2].freeze
|
112
122
|
|
113
|
-
# Serialize metadata for Cube
|
114
|
-
# Message body has the same format as response (M)
|
115
|
-
# -> reverse operations
|
116
|
-
# ! I couldn't verify the assumption that bodies should be the same
|
117
|
-
# ! Cube does not check data format,
|
118
|
-
# so things could break if invalid data is sent
|
119
123
|
def serialize_tcp_m(hash)
|
120
124
|
index = hash.key?(:index) ? to_int(0, 'index', hash[:index]) : 0
|
121
125
|
head = format('%02x,', index)
|
@@ -3,12 +3,13 @@ module MaxCube
|
|
3
3
|
module Messages
|
4
4
|
module TCP
|
5
5
|
class Parser
|
6
|
+
# New device (pairing) message.
|
6
7
|
module MessageN
|
7
8
|
private
|
8
9
|
|
10
|
+
# Mandatory hash keys.
|
9
11
|
KEYS = %i[device_type rf_address serial_number unknown].freeze
|
10
12
|
|
11
|
-
# New device (pairing) message
|
12
13
|
def parse_tcp_n(body)
|
13
14
|
@io = StringIO.new(decode(body), 'rb')
|
14
15
|
|
@@ -26,13 +27,14 @@ module MaxCube
|
|
26
27
|
end
|
27
28
|
|
28
29
|
class Serializer
|
30
|
+
# Command to set the Cube into pairing mode
|
31
|
+
# with optional +timeout+ in seconds.
|
29
32
|
module MessageN
|
30
33
|
private
|
31
34
|
|
35
|
+
# Optional hash keys.
|
32
36
|
OPT_KEYS = %i[timeout].freeze
|
33
37
|
|
34
|
-
# Command to set the Cube into pairing mode
|
35
|
-
# with optional +timeout+ in seconds
|
36
38
|
def serialize_tcp_n(hash)
|
37
39
|
return '' unless hash.key?(:timeout)
|
38
40
|
format('%04x', to_int(0, 'timeout', hash[:timeout]))
|
@@ -3,11 +3,11 @@ module MaxCube
|
|
3
3
|
module Messages
|
4
4
|
module TCP
|
5
5
|
class Serializer
|
6
|
+
# Quit message - terminates connection.
|
7
|
+
# Does not contain any data.
|
6
8
|
module MessageQ
|
7
9
|
private
|
8
10
|
|
9
|
-
# Quit message - terminates connection
|
10
|
-
# Does not contain any data
|
11
11
|
def serialize_tcp_q(_hash)
|
12
12
|
''
|
13
13
|
end
|
@@ -3,18 +3,19 @@ module MaxCube
|
|
3
3
|
module Messages
|
4
4
|
module TCP
|
5
5
|
class Parser
|
6
|
+
# Response to send command message.
|
6
7
|
module MessageS
|
7
8
|
private
|
8
9
|
|
9
10
|
LENGTHS = [2, 1, 2].freeze
|
10
11
|
|
12
|
+
# Mandatory hash keys.
|
11
13
|
KEYS = %i[
|
12
14
|
duty_cycle
|
13
15
|
command_processed
|
14
16
|
free_memory_slots
|
15
17
|
].freeze
|
16
18
|
|
17
|
-
# Send command message (response)
|
18
19
|
def parse_tcp_s(body)
|
19
20
|
values = body.split(',')
|
20
21
|
check_msg_part_lengths(LENGTHS, *values)
|
@@ -27,10 +28,13 @@ module MaxCube
|
|
27
28
|
end
|
28
29
|
|
29
30
|
class Serializer
|
31
|
+
# Message to send command to Cube.
|
30
32
|
module MessageS
|
31
33
|
private
|
32
34
|
|
35
|
+
# Mandatory hash keys.
|
33
36
|
KEYS = %i[command].freeze
|
37
|
+
# Optional hash keys.
|
34
38
|
OPT_KEYS = %i[
|
35
39
|
unknown
|
36
40
|
rf_flags
|
@@ -76,7 +80,6 @@ module MaxCube
|
|
76
80
|
display_temperature: 0x0,
|
77
81
|
}.freeze
|
78
82
|
|
79
|
-
# Message to send command to Cube
|
80
83
|
def serialize_tcp_s(hash)
|
81
84
|
@io = StringIO.new('', 'wb')
|
82
85
|
|
@@ -3,15 +3,16 @@ module MaxCube
|
|
3
3
|
module Messages
|
4
4
|
module TCP
|
5
5
|
class Serializer
|
6
|
+
# Command to delete one or more devices from the Cube.
|
7
|
+
# Acknowledgement (A) follows.
|
6
8
|
module MessageT
|
7
9
|
private
|
8
10
|
|
9
|
-
#
|
10
|
-
#
|
11
|
+
# Mandatory hash keys.
|
12
|
+
# +count+ key would cause ambuigity if it was optional
|
13
|
+
# due to +rf_addresses+ has variable size.
|
11
14
|
KEYS = %i[count force rf_addresses].freeze
|
12
15
|
|
13
|
-
# Command to delete one or more devices from the Cube
|
14
|
-
# Acknowledgement (A) follows
|
15
16
|
def serialize_tcp_t(hash)
|
16
17
|
force = to_bool('force mode', hash[:force]) ? '1' : '0'
|
17
18
|
rf_addresses = to_ints(0, 'RF addresses', *hash[:rf_addresses])
|
@@ -3,12 +3,13 @@ module MaxCube
|
|
3
3
|
module Messages
|
4
4
|
module TCP
|
5
5
|
class Serializer
|
6
|
+
# Command to configure Cube's portal URL
|
6
7
|
module MessageU
|
7
8
|
private
|
8
9
|
|
10
|
+
# Mandatory hash keys.
|
9
11
|
KEYS = %i[url port].freeze
|
10
12
|
|
11
|
-
# Command to configure Cube's portal URL
|
12
13
|
def serialize_tcp_u(hash)
|
13
14
|
"#{hash[:url]}:#{to_int(0, 'port', hash[:port])}"
|
14
15
|
end
|
@@ -3,14 +3,16 @@ module MaxCube
|
|
3
3
|
module Messages
|
4
4
|
module TCP
|
5
5
|
class Serializer
|
6
|
+
# Wakeup command.
|
7
|
+
# Acknowledgement (A) follows.
|
6
8
|
module MessageZ
|
7
9
|
private
|
8
10
|
|
11
|
+
# Mandatory hash keys.
|
9
12
|
KEYS = %i[time scope].freeze
|
13
|
+
# Optional hash keys.
|
10
14
|
OPT_KEYS = %i[id].freeze
|
11
15
|
|
12
|
-
# Wakeup command
|
13
|
-
# Acknowledgement (A) follows
|
14
16
|
def serialize_tcp_z(hash)
|
15
17
|
time = format('%02x', to_int(0, 'time', hash[:time]))
|
16
18
|
scope = hash[:scope].to_sym
|
data/lib/maxcube/messages/udp.rb
CHANGED
@@ -2,7 +2,14 @@ require 'maxcube/messages'
|
|
2
2
|
|
3
3
|
module MaxCube
|
4
4
|
module Messages
|
5
|
+
# This module contains classes aimed onto UDP messages of Cube protocol.
|
6
|
+
#
|
7
|
+
# Structure of every UDP Cube message:
|
8
|
+
# * Starts with {MSG_PREFIX}
|
9
|
+
# @example
|
10
|
+
# eQ3MaxApKEQ0523864>I
|
5
11
|
module UDP
|
12
|
+
# Prefix of any UDP Cube message
|
6
13
|
MSG_PREFIX = 'eQ3Max'.freeze
|
7
14
|
end
|
8
15
|
end
|
@@ -4,32 +4,60 @@ require 'maxcube/messages/handler'
|
|
4
4
|
module MaxCube
|
5
5
|
module Messages
|
6
6
|
module UDP
|
7
|
+
# Extends {Messages::Handler} of routines connected to UDP Cube messages.
|
7
8
|
module Handler
|
8
9
|
include Messages::Handler
|
9
10
|
|
11
|
+
# Validates whether message contains correct {MSG_PREFIX}
|
12
|
+
# (suffix of the prefix differs for parser and serializer).
|
13
|
+
# @param msg [String] input message.
|
14
|
+
# @return [Boolean] whether message prefix is valid.
|
10
15
|
def valid_udp_msg_prefix(msg)
|
11
16
|
msg.start_with?(self.class.const_get('MSG_PREFIX'))
|
12
17
|
end
|
13
18
|
|
19
|
+
# As {#valid_udp_msg_prefix},
|
20
|
+
# but it raises exception if the prefix is not valid.
|
21
|
+
# @param msg [String] input message.
|
22
|
+
# @return [String] input message.
|
23
|
+
# @raise [InvalidMessageFormat] if the prefix is not valid.
|
14
24
|
def check_udp_msg_prefix(msg)
|
15
25
|
raise InvalidMessageFormat unless valid_udp_msg_prefix(msg)
|
26
|
+
msg
|
16
27
|
end
|
17
28
|
|
29
|
+
# Validates whether given message is a valid UDP Cube message.
|
30
|
+
# It calls {#valid_udp_msg_prefix} and {#valid_msg}.
|
31
|
+
# @param msg [String] input message.
|
32
|
+
# @return [Boolean] whether message is valid.
|
18
33
|
def valid_udp_msg(msg)
|
19
34
|
valid_udp_msg_prefix(msg) &&
|
20
35
|
valid_msg(msg)
|
21
36
|
end
|
22
37
|
|
38
|
+
# As {#valid_udp_msg}, but raises exception if message is not valid.
|
39
|
+
# It calls {#check_udp_msg_prefix} and {#check_msg}.
|
40
|
+
# @param msg [String] input message.
|
41
|
+
# @return [String] input message.
|
23
42
|
def check_udp_msg(msg)
|
24
43
|
check_udp_msg_prefix(msg)
|
25
44
|
check_msg(msg)
|
26
45
|
msg
|
27
46
|
end
|
28
47
|
|
48
|
+
# Validates whether given hash with message contents
|
49
|
+
# is valid for UDP Cube messaging purposes.
|
50
|
+
# It only calls {#valid_hash}.
|
51
|
+
# @param hash [Hash] input hash.
|
52
|
+
# @return [Boolean] whether hash is valid.
|
29
53
|
def valid_udp_hash(hash)
|
30
54
|
valid_hash(hash)
|
31
55
|
end
|
32
56
|
|
57
|
+
# As {#valid_udp_hash}, but raises exception if hash is not valid.
|
58
|
+
# It only calls {#check_hash}.
|
59
|
+
# @param hash [Hash] input hash.
|
60
|
+
# @return [Hash] input hash.
|
33
61
|
def check_udp_hash(hash)
|
34
62
|
check_hash(hash)
|
35
63
|
hash
|
@@ -4,22 +4,32 @@ require 'maxcube/messages/parser'
|
|
4
4
|
module MaxCube
|
5
5
|
module Messages
|
6
6
|
module UDP
|
7
|
+
# Extends {Messages::Parser} and {UDP::Handler} of routines
|
8
|
+
# connected to UDP Cube messages parsing.
|
7
9
|
class Parser
|
8
|
-
include Handler
|
10
|
+
include UDP::Handler
|
9
11
|
include Messages::Parser
|
10
12
|
|
13
|
+
# Mandatory hash keys common for all UDP Cube messages.
|
11
14
|
KEYS = %i[prefix serial_number id].freeze
|
12
15
|
|
13
|
-
%w[i n h].each
|
16
|
+
%w[i n h].each do |f|
|
17
|
+
require_relative 'type/' << f
|
18
|
+
include const_get('Message' << f.upcase)
|
19
|
+
end
|
14
20
|
|
21
|
+
# Known message types in the direction Cube -> client.
|
15
22
|
MSG_TYPES = %w[I N h c].freeze
|
16
23
|
|
17
|
-
|
18
|
-
include MessageN
|
19
|
-
include MessageH
|
20
|
-
|
24
|
+
# {UDP::MSG_PREFIX} with a suffix.
|
21
25
|
MSG_PREFIX = (UDP::MSG_PREFIX + 'Ap').freeze
|
22
26
|
|
27
|
+
# Parses single message.
|
28
|
+
# Subsequently calls {#check_udp_msg},
|
29
|
+
# {#parse_udp_msg_head}, {#parse_msg_body}
|
30
|
+
# and {#check_udp_hash}.
|
31
|
+
# @param msg [String] input message.
|
32
|
+
# @return [Hash] particular message contents separated into hash.
|
23
33
|
def parse_udp_msg(msg)
|
24
34
|
check_udp_msg(msg)
|
25
35
|
hash = parse_udp_msg_head(msg)
|
@@ -29,10 +39,17 @@ module MaxCube
|
|
29
39
|
|
30
40
|
private
|
31
41
|
|
42
|
+
# Tells how to get message type from a message.
|
43
|
+
# @param msg [String] input message.
|
44
|
+
# @return [String] message type.
|
32
45
|
def msg_msg_type(msg)
|
33
46
|
msg[19]
|
34
47
|
end
|
35
48
|
|
49
|
+
# Parses head of UDP Cube message, that is common to all of these.
|
50
|
+
# Internal +IO+ variable contains message body string at the end.
|
51
|
+
# @param msg [String] input message.
|
52
|
+
# @return [Hash] particular message head contents separated into hash.
|
36
53
|
def parse_udp_msg_head(msg)
|
37
54
|
@io = StringIO.new(msg, 'rb')
|
38
55
|
hash = {
|