ruby_home 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +13 -14
- data/README.md +1 -1
- data/bin/rubyhome +1 -1
- data/lib/ruby_home/accessory_info.rb +33 -72
- data/lib/ruby_home/device_id.rb +0 -2
- data/lib/ruby_home/dns/service.rb +1 -6
- data/lib/ruby_home/dns/text_record.rb +0 -2
- data/lib/ruby_home/factories/accessory_factory.rb +0 -5
- data/lib/ruby_home/factories/characteristic_factory.rb +0 -3
- data/lib/ruby_home/factories/templates/characteristic_template.rb +0 -1
- data/lib/ruby_home/factories/templates/service_template.rb +0 -2
- data/lib/ruby_home/hap/accessory.rb +2 -2
- data/lib/ruby_home/hap/characteristic.rb +2 -2
- data/lib/ruby_home/hap/crypto/chacha20poly1305.rb +0 -4
- data/lib/ruby_home/hap/crypto/hkdf.rb +0 -2
- data/lib/ruby_home/hap/http_decryption.rb +5 -6
- data/lib/ruby_home/hap/http_encryption.rb +21 -11
- data/lib/ruby_home/hap/service.rb +0 -3
- data/lib/ruby_home/hap/tlv.rb +28 -21
- data/lib/ruby_home/hex_helper.rb +15 -0
- data/lib/ruby_home/http/application.rb +24 -19
- data/lib/ruby_home/http/controllers/accessories_controller.rb +1 -2
- data/lib/ruby_home/http/controllers/application_controller.rb +60 -13
- data/lib/ruby_home/http/controllers/characteristics_controller.rb +2 -3
- data/lib/ruby_home/http/controllers/pair_setups_controller.rb +41 -78
- data/lib/ruby_home/http/controllers/pair_verifies_controller.rb +22 -24
- data/lib/ruby_home/http/controllers/pairings_controller.rb +8 -8
- data/lib/ruby_home/http/hap_request.rb +2 -6
- data/lib/ruby_home/http/hap_response.rb +2 -8
- data/lib/ruby_home/http/hap_server.rb +7 -12
- data/lib/ruby_home/http/serializers/object_serializer.rb +0 -2
- data/lib/ruby_home/http/services/start_srp_service.rb +46 -0
- data/lib/ruby_home/http/services/verify_srp_service.rb +55 -0
- data/lib/ruby_home/rack/handler/hap_server.rb +2 -7
- data/lib/ruby_home/version.rb +1 -1
- data/lib/ruby_home/yaml_record.rb +440 -0
- data/lib/ruby_home.rb +45 -6
- data/rubyhome.gemspec +4 -4
- metadata +44 -49
- data/lib/ruby_home/broadcast.rb +0 -31
- data/lib/ruby_home/hap/hex_pad.rb +0 -13
- data/lib/ruby_home/http/cache.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc7188fc5cc51dd567a013d39cff0c8693474aeb6ae70861defaae3a72556334
|
4
|
+
data.tar.gz: e309c541c56c9ef4fde63a3559cb2148a264c32fcbda7bcc685b9d499382c942
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0db967bfe7d94e2b5158fb5345711312c40aba7bf396d6e8ec8215ddc2e222bf757353e0c551fc927e55b0f022c8d16bd74762562b864e4a1905bc767d7a05b2
|
7
|
+
data.tar.gz: eec3bff1b8067acd972b146081df4a0b29f469f6353b3965de3634e2e1efa7486d6f25623004ab295c1702d36fad69bef5a3a4913c7960e1f38d77f15eb1bd5b
|
data/.travis.yml
CHANGED
@@ -1,21 +1,20 @@
|
|
1
|
-
language: ruby
|
2
1
|
cache: bundler
|
3
|
-
|
4
|
-
|
5
|
-
-
|
6
|
-
-
|
7
|
-
- gem
|
8
|
-
-
|
9
|
-
- gem install bundler -v 1.16.1
|
10
|
-
- bundle --version
|
2
|
+
language: ruby
|
3
|
+
install:
|
4
|
+
- 'gem update --system'
|
5
|
+
- 'gem --version'
|
6
|
+
- 'gem install bundler -v 1.16.1'
|
7
|
+
- 'bundle --version'
|
11
8
|
- bundle
|
12
|
-
|
13
9
|
rvm:
|
14
10
|
- 2.5.0
|
15
11
|
- ruby-head
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
12
|
+
os:
|
13
|
+
- linux
|
14
|
+
- osx
|
15
|
+
addons:
|
16
|
+
apt:
|
17
|
+
packages:
|
18
|
+
- libavahi-compat-libdnssd-dev
|
20
19
|
notifications:
|
21
20
|
email: false
|
data/README.md
CHANGED
data/bin/rubyhome
CHANGED
@@ -1,99 +1,60 @@
|
|
1
|
-
require 'ed25519'
|
2
|
-
require 'yaml/store'
|
3
1
|
require_relative 'device_id'
|
2
|
+
require_relative 'yaml_record'
|
4
3
|
|
5
4
|
module RubyHome
|
6
|
-
class AccessoryInfo
|
7
|
-
|
5
|
+
class AccessoryInfo < YamlRecord::Base
|
6
|
+
USERNAME = -'Pair-Setup'
|
8
7
|
|
9
|
-
|
10
|
-
|
8
|
+
properties :device_id, :paired_clients, :password, :signature_key
|
9
|
+
source 'accessory_info.yml'
|
11
10
|
|
12
|
-
|
11
|
+
set_callback :before_create, :set_device_id
|
12
|
+
set_callback :before_create, :set_paired_clients
|
13
|
+
set_callback :before_create, :set_password
|
14
|
+
set_callback :before_create, :set_signature_key
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
@signature_key ||= Ed25519::SigningKey.generate.to_bytes.unpack1('H*')
|
16
|
+
def self.instance
|
17
|
+
first || create
|
17
18
|
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
def signature_key=(signature_key)
|
24
|
-
@signing_key = nil
|
25
|
-
@signature_key = signature_key
|
20
|
+
def add_paired_client(admin: false, identifier: , public_key: )
|
21
|
+
paired_clients << { admin: admin, identifier: identifier, public_key: public_key }
|
22
|
+
save
|
26
23
|
end
|
27
24
|
|
28
|
-
def
|
29
|
-
|
25
|
+
def remove_paired_client(identifier)
|
26
|
+
paired_clients.delete_if { |h| h[:identifier] == identifier }
|
27
|
+
save
|
30
28
|
end
|
31
29
|
|
32
|
-
def
|
33
|
-
|
30
|
+
def paired?
|
31
|
+
paired_clients.any?
|
34
32
|
end
|
35
33
|
|
36
|
-
def
|
37
|
-
'
|
34
|
+
def signing_key
|
35
|
+
@signing_key ||= RbNaCl::Signatures::Ed25519::SigningKey.new([signature_key].pack('H*'))
|
38
36
|
end
|
39
37
|
|
40
|
-
def
|
41
|
-
|
38
|
+
def username
|
39
|
+
USERNAME
|
42
40
|
end
|
43
41
|
|
44
|
-
|
45
|
-
store.transaction(true) do
|
46
|
-
store.fetch(:accessory_info, {}).each do |key, value|
|
47
|
-
send("#{key}=", value)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
42
|
+
private
|
51
43
|
|
52
|
-
def
|
53
|
-
|
54
|
-
store[:accessory_info] = to_hash
|
55
|
-
end
|
44
|
+
def set_device_id
|
45
|
+
self.device_id ||= DeviceID.generate
|
56
46
|
end
|
57
47
|
|
58
|
-
def
|
59
|
-
|
48
|
+
def set_paired_clients
|
49
|
+
self.paired_clients = []
|
60
50
|
end
|
61
51
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
PERSISTABLE.each do |attribute|
|
66
|
-
define_method("#{attribute}=") do |value, save=true|
|
67
|
-
@@accessory_info.send("#{attribute}=", value)
|
68
|
-
save
|
69
|
-
end
|
70
|
-
|
71
|
-
define_method(attribute) do
|
72
|
-
@@accessory_info.send(attribute)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def save
|
77
|
-
@@accessory_info.save
|
78
|
-
end
|
79
|
-
|
80
|
-
def signing_key
|
81
|
-
@@accessory_info.signing_key
|
82
|
-
end
|
83
|
-
|
84
|
-
def paired?
|
85
|
-
@@accessory_info.paired_clients.any?
|
86
|
-
end
|
87
|
-
|
88
|
-
def add_paired_client(admin: false, identifier: , public_key: )
|
89
|
-
@@accessory_info.paired_clients << { admin: admin, identifier: identifier, public_key: public_key }
|
90
|
-
save
|
91
|
-
end
|
52
|
+
def set_password
|
53
|
+
self.password ||= '031-45-154'
|
54
|
+
end
|
92
55
|
|
93
|
-
|
94
|
-
|
95
|
-
save
|
96
|
-
end
|
56
|
+
def set_signature_key
|
57
|
+
self.signature_key ||= RbNaCl::Signatures::Ed25519::SigningKey.generate.to_bytes.unpack1('H*')
|
97
58
|
end
|
98
59
|
end
|
99
60
|
end
|
data/lib/ruby_home/device_id.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
module RubyHome
|
2
2
|
class DeviceID
|
3
3
|
class << self
|
4
|
-
|
5
4
|
DELIMITER = ':'
|
6
5
|
|
7
6
|
# Device ID of the accessory must be a unique random number generated at every
|
@@ -24,7 +23,6 @@ module RubyHome
|
|
24
23
|
.times
|
25
24
|
.map { random_hexadecimal }
|
26
25
|
end
|
27
|
-
|
28
26
|
end
|
29
27
|
end
|
30
28
|
end
|
@@ -1,7 +1,3 @@
|
|
1
|
-
require 'dnssd'
|
2
|
-
require_relative '../accessory_info'
|
3
|
-
require_relative 'text_record'
|
4
|
-
|
5
1
|
module RubyHome
|
6
2
|
module DNS
|
7
3
|
class Service
|
@@ -36,9 +32,8 @@ module RubyHome
|
|
36
32
|
attr_reader :port
|
37
33
|
|
38
34
|
def text_record
|
39
|
-
TextRecord.new(accessory_info: AccessoryInfo)
|
35
|
+
TextRecord.new(accessory_info: AccessoryInfo.instance)
|
40
36
|
end
|
41
37
|
end
|
42
38
|
end
|
43
39
|
end
|
44
|
-
|
@@ -1,8 +1,3 @@
|
|
1
|
-
require_relative '../hap/service'
|
2
|
-
require_relative '../hap/accessory'
|
3
|
-
require_relative 'templates/service_template'
|
4
|
-
require_relative 'templates/characteristic_template'
|
5
|
-
|
6
1
|
module RubyHome
|
7
2
|
class AccessoryFactory
|
8
3
|
def self.create(service_name, characteristics: {}, **options)
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'wisper'
|
2
|
-
|
3
1
|
module RubyHome
|
4
2
|
class Characteristic
|
5
3
|
include Wisper::Publisher
|
@@ -38,6 +36,8 @@ module RubyHome
|
|
38
36
|
end
|
39
37
|
|
40
38
|
def value=(new_value)
|
39
|
+
return if name == :identify
|
40
|
+
|
41
41
|
@value = new_value
|
42
42
|
broadcast(:updated, new_value)
|
43
43
|
end
|
@@ -1,10 +1,9 @@
|
|
1
|
-
require 'rbnacl/libsodium'
|
2
|
-
|
3
1
|
module RubyHome
|
4
2
|
module HAP
|
5
3
|
class HTTPDecryption
|
6
|
-
AAD_LENGTH_BYTES = 2
|
7
|
-
AUTHENTICATE_TAG_LENGTH_BYTES = 16
|
4
|
+
AAD_LENGTH_BYTES = 2.freeze
|
5
|
+
AUTHENTICATE_TAG_LENGTH_BYTES = 16.freeze
|
6
|
+
NONCE_32_BIT_FIX_COMMENT_PART = [0].pack('L').freeze
|
8
7
|
|
9
8
|
def initialize(key, count: 0)
|
10
9
|
@key = key
|
@@ -47,11 +46,11 @@ module RubyHome
|
|
47
46
|
end
|
48
47
|
|
49
48
|
def nonce
|
50
|
-
|
49
|
+
NONCE_32_BIT_FIX_COMMENT_PART + [count].pack('Q')
|
51
50
|
end
|
52
51
|
|
53
52
|
def chacha20poly1305ietf
|
54
|
-
HAP::Crypto::ChaCha20Poly1305.new(key)
|
53
|
+
@_chacha20poly1305ietf ||= HAP::Crypto::ChaCha20Poly1305.new(key)
|
55
54
|
end
|
56
55
|
end
|
57
56
|
end
|
@@ -1,22 +1,34 @@
|
|
1
|
-
require 'rbnacl/libsodium'
|
2
|
-
|
3
1
|
module RubyHome
|
4
2
|
module HAP
|
5
3
|
class HTTPEncryption
|
4
|
+
MAX_FRAME_LENGTH = 1024.freeze
|
5
|
+
NONCE_32_BIT_FIX_COMMENT_PART = [0].pack('L').freeze
|
6
|
+
|
6
7
|
def initialize(key, count: 0)
|
7
8
|
@key = key
|
8
9
|
@count = count
|
9
10
|
end
|
10
11
|
|
11
12
|
def encrypt(data)
|
12
|
-
|
13
|
-
|
13
|
+
encrypted_data = []
|
14
|
+
read_pointer = 0
|
14
15
|
|
15
|
-
|
16
|
-
|
16
|
+
while read_pointer < data.length
|
17
|
+
encrypted_frame = ""
|
18
|
+
|
19
|
+
frame = data[read_pointer...read_pointer+MAX_FRAME_LENGTH]
|
20
|
+
length_of_encrypted_data = frame.length
|
21
|
+
little_endian_length_of_encrypted_data = [length_of_encrypted_data].pack('v')
|
22
|
+
|
23
|
+
encrypted_frame += little_endian_length_of_encrypted_data
|
24
|
+
encrypted_frame += chacha20poly1305ietf.encrypt(nonce, frame, little_endian_length_of_encrypted_data)
|
25
|
+
encrypted_data << encrypted_frame
|
17
26
|
|
18
|
-
|
27
|
+
read_pointer += length_of_encrypted_data
|
28
|
+
increment_count!
|
19
29
|
end
|
30
|
+
|
31
|
+
encrypted_data
|
20
32
|
end
|
21
33
|
|
22
34
|
attr_reader :count
|
@@ -30,14 +42,12 @@ module RubyHome
|
|
30
42
|
end
|
31
43
|
|
32
44
|
def nonce
|
33
|
-
|
45
|
+
NONCE_32_BIT_FIX_COMMENT_PART + [count].pack('Q')
|
34
46
|
end
|
35
47
|
|
36
48
|
def chacha20poly1305ietf
|
37
|
-
HAP::Crypto::ChaCha20Poly1305.new(key)
|
49
|
+
@_chacha20poly1305ietf ||= HAP::Crypto::ChaCha20Poly1305.new(key)
|
38
50
|
end
|
39
51
|
end
|
40
52
|
end
|
41
53
|
end
|
42
|
-
|
43
|
-
|
data/lib/ruby_home/hap/tlv.rb
CHANGED
@@ -1,27 +1,34 @@
|
|
1
|
-
require 'bindata'
|
2
|
-
|
3
1
|
module RubyHome
|
4
2
|
module HAP
|
5
3
|
module TLV
|
6
|
-
|
4
|
+
ERROR_TYPES = {
|
5
|
+
unknown: 1,
|
6
|
+
authentication: 2,
|
7
|
+
backoff: 3,
|
8
|
+
max_peers: 4,
|
9
|
+
max_tries: 5,
|
10
|
+
unavailable: 6,
|
11
|
+
busy: 7,
|
12
|
+
}.freeze
|
13
|
+
TYPE_ERRORS = ERROR_TYPES.invert.freeze
|
7
14
|
|
8
|
-
|
9
|
-
0
|
10
|
-
1
|
11
|
-
2
|
12
|
-
3
|
13
|
-
4
|
14
|
-
5
|
15
|
-
6
|
16
|
-
7
|
17
|
-
8
|
18
|
-
9
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
15
|
+
NAME_TYPES = {
|
16
|
+
method: 0,
|
17
|
+
identifier: 1,
|
18
|
+
salt: 2,
|
19
|
+
public_key: 3,
|
20
|
+
proof: 4,
|
21
|
+
encrypted_data: 5,
|
22
|
+
state: 6,
|
23
|
+
error: 7,
|
24
|
+
retry_delay: 8,
|
25
|
+
certificate: 9,
|
26
|
+
signature: 10,
|
27
|
+
permissions: 11,
|
28
|
+
fragment_data: 12,
|
29
|
+
fragment_last: 13,
|
23
30
|
}.freeze
|
24
|
-
|
31
|
+
TYPE_NAMES = NAME_TYPES.invert.freeze
|
25
32
|
|
26
33
|
class Bytes < BinData::String; end
|
27
34
|
|
@@ -58,7 +65,7 @@ module RubyHome
|
|
58
65
|
|
59
66
|
READER = BinData::Array.new(type: :tlv, read_until: :eof)
|
60
67
|
|
61
|
-
def read(input)
|
68
|
+
def self.read(input)
|
62
69
|
READER.clear
|
63
70
|
READER.read(input)
|
64
71
|
READER.snapshot.each_with_object({}) do |(hash), memo|
|
@@ -73,7 +80,7 @@ module RubyHome
|
|
73
80
|
end
|
74
81
|
end
|
75
82
|
|
76
|
-
def encode(hash)
|
83
|
+
def self.encode(hash)
|
77
84
|
hash.to_hash.each_with_object(String.new) do |(key, value), memo|
|
78
85
|
type_id = NAME_TYPES[key]
|
79
86
|
next unless type_id
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module RubyHome
|
2
|
+
module HexHelper
|
3
|
+
def self.pad(input, pad_length: 24)
|
4
|
+
pack_hex_string(unpack_hex_string(input).rjust(pad_length, '0'))
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.unpack_hex_string(input)
|
8
|
+
input.to_s.unpack1('H*')
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.pack_hex_string(input)
|
12
|
+
[input].pack('H*')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,28 +1,33 @@
|
|
1
|
-
|
2
|
-
require_relative '../rack/handler/hap_server'
|
3
|
-
require_relative 'cache'
|
4
|
-
|
5
|
-
Rack::Handler.register 'hap_server', RubyHome::Rack::Handler::HAPServer
|
1
|
+
Dir[File.dirname(__FILE__) + '/controllers/*.rb'].each {|file| require file }
|
6
2
|
|
7
3
|
module RubyHome
|
8
4
|
module HTTP
|
9
|
-
class Application
|
10
|
-
|
5
|
+
class Application
|
6
|
+
def run
|
7
|
+
RubyHome::Rack::Handler::HAPServer.run rack_builder,
|
8
|
+
Port: port,
|
9
|
+
Host: bind_address,
|
10
|
+
ServerSoftware: 'RubyHome'
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
set :bind, '0.0.0.0'
|
15
|
-
set :quiet, true
|
16
|
-
set :server, :hap_server
|
17
|
-
set :server_settings, AcceptCallback: -> (sock) do
|
18
|
-
self.set :request_id, sock.object_id
|
13
|
+
def port
|
14
|
+
@_port ||= Integer(ENV['PORT'] && !ENV['PORT'].empty? ? ENV['PORT'] : 4567)
|
19
15
|
end
|
20
16
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
17
|
+
def bind_address
|
18
|
+
'0.0.0.0'
|
19
|
+
end
|
20
|
+
|
21
|
+
def rack_builder
|
22
|
+
::Rack::Builder.new do
|
23
|
+
use ::Rack::CommonLogger
|
24
|
+
map('/accessories', &Proc.new { run AccessoriesController })
|
25
|
+
map('/characteristics', &Proc.new { run CharacteristicsController })
|
26
|
+
map('/pair-setup', &Proc.new { run PairSetupsController })
|
27
|
+
map('/pair-verify', &Proc.new { run PairVerifiesController })
|
28
|
+
map('/pairings', &Proc.new { run PairingsController })
|
29
|
+
end
|
30
|
+
end
|
26
31
|
end
|
27
32
|
end
|
28
33
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
require_relative 'application_controller'
|
2
|
-
require_relative '../serializers/accessory_serializer'
|
3
2
|
|
4
3
|
module RubyHome
|
5
4
|
module HTTP
|
6
5
|
class AccessoriesController < ApplicationController
|
7
|
-
get '/
|
6
|
+
get '/' do
|
8
7
|
content_type 'application/hap+json'
|
9
8
|
|
10
9
|
if cache[:controller_to_accessory_key] && cache[:accessory_to_controller_key]
|
@@ -3,34 +3,81 @@ module RubyHome
|
|
3
3
|
class ApplicationController < Sinatra::Base
|
4
4
|
disable :protection
|
5
5
|
|
6
|
+
if ENV['DEBUG']
|
7
|
+
enable :logging
|
8
|
+
set :logger, Logger.new(STDOUT)
|
9
|
+
end
|
10
|
+
|
11
|
+
before do
|
12
|
+
logger.debug "Cache"
|
13
|
+
logger.debug cache.inspect
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
6
18
|
def unpack_request
|
7
|
-
@_unpack_request ||=
|
8
|
-
request.body.rewind
|
9
|
-
HAP::TLV.read(request.body.read)
|
10
|
-
end
|
19
|
+
@_unpack_request ||= _unpack_request
|
11
20
|
end
|
12
21
|
|
13
22
|
def json_body
|
14
|
-
@_json_body ||=
|
15
|
-
request.body.rewind
|
16
|
-
JSON.parse(request.body.read)
|
17
|
-
end
|
23
|
+
@_json_body ||= _unpack_json
|
18
24
|
end
|
19
25
|
|
20
26
|
def accessory_info
|
21
|
-
AccessoryInfo
|
27
|
+
AccessoryInfo.instance
|
22
28
|
end
|
23
29
|
|
24
30
|
def identifier_cache
|
25
31
|
IdentifierCache
|
26
32
|
end
|
27
33
|
|
28
|
-
def
|
29
|
-
|
34
|
+
def cache
|
35
|
+
RequestStore.store
|
30
36
|
end
|
31
37
|
|
32
|
-
def
|
33
|
-
|
38
|
+
def clear_cache
|
39
|
+
RequestStore.clear!
|
40
|
+
end
|
41
|
+
|
42
|
+
def tlv(object)
|
43
|
+
logger.debug "Response"
|
44
|
+
logger.debug object.inspect
|
45
|
+
HAP::TLV.encode(object)
|
46
|
+
end
|
47
|
+
|
48
|
+
def logger
|
49
|
+
if settings.respond_to?(:logger)
|
50
|
+
settings.logger
|
51
|
+
else
|
52
|
+
request.logger
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def rewind_request
|
59
|
+
if request.body.size > 0
|
60
|
+
request.body.rewind
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def request_body
|
65
|
+
rewind_request
|
66
|
+
request.body.read
|
67
|
+
end
|
68
|
+
|
69
|
+
def _unpack_request
|
70
|
+
HAP::TLV.read(request_body).tap do |request_tlv|
|
71
|
+
logger.debug "Request"
|
72
|
+
logger.debug request_tlv.inspect
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def _unpack_json
|
77
|
+
JSON.parse(request_body).tap do |request_json|
|
78
|
+
logger.debug "Request"
|
79
|
+
logger.debug request_json.inspect
|
80
|
+
end
|
34
81
|
end
|
35
82
|
end
|
36
83
|
end
|