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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +13 -14
  3. data/README.md +1 -1
  4. data/bin/rubyhome +1 -1
  5. data/lib/ruby_home/accessory_info.rb +33 -72
  6. data/lib/ruby_home/device_id.rb +0 -2
  7. data/lib/ruby_home/dns/service.rb +1 -6
  8. data/lib/ruby_home/dns/text_record.rb +0 -2
  9. data/lib/ruby_home/factories/accessory_factory.rb +0 -5
  10. data/lib/ruby_home/factories/characteristic_factory.rb +0 -3
  11. data/lib/ruby_home/factories/templates/characteristic_template.rb +0 -1
  12. data/lib/ruby_home/factories/templates/service_template.rb +0 -2
  13. data/lib/ruby_home/hap/accessory.rb +2 -2
  14. data/lib/ruby_home/hap/characteristic.rb +2 -2
  15. data/lib/ruby_home/hap/crypto/chacha20poly1305.rb +0 -4
  16. data/lib/ruby_home/hap/crypto/hkdf.rb +0 -2
  17. data/lib/ruby_home/hap/http_decryption.rb +5 -6
  18. data/lib/ruby_home/hap/http_encryption.rb +21 -11
  19. data/lib/ruby_home/hap/service.rb +0 -3
  20. data/lib/ruby_home/hap/tlv.rb +28 -21
  21. data/lib/ruby_home/hex_helper.rb +15 -0
  22. data/lib/ruby_home/http/application.rb +24 -19
  23. data/lib/ruby_home/http/controllers/accessories_controller.rb +1 -2
  24. data/lib/ruby_home/http/controllers/application_controller.rb +60 -13
  25. data/lib/ruby_home/http/controllers/characteristics_controller.rb +2 -3
  26. data/lib/ruby_home/http/controllers/pair_setups_controller.rb +41 -78
  27. data/lib/ruby_home/http/controllers/pair_verifies_controller.rb +22 -24
  28. data/lib/ruby_home/http/controllers/pairings_controller.rb +8 -8
  29. data/lib/ruby_home/http/hap_request.rb +2 -6
  30. data/lib/ruby_home/http/hap_response.rb +2 -8
  31. data/lib/ruby_home/http/hap_server.rb +7 -12
  32. data/lib/ruby_home/http/serializers/object_serializer.rb +0 -2
  33. data/lib/ruby_home/http/services/start_srp_service.rb +46 -0
  34. data/lib/ruby_home/http/services/verify_srp_service.rb +55 -0
  35. data/lib/ruby_home/rack/handler/hap_server.rb +2 -7
  36. data/lib/ruby_home/version.rb +1 -1
  37. data/lib/ruby_home/yaml_record.rb +440 -0
  38. data/lib/ruby_home.rb +45 -6
  39. data/rubyhome.gemspec +4 -4
  40. metadata +44 -49
  41. data/lib/ruby_home/broadcast.rb +0 -31
  42. data/lib/ruby_home/hap/hex_pad.rb +0 -13
  43. data/lib/ruby_home/http/cache.rb +0 -30
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6ccc3aa90b30716b6e6d39417f7c1bef28d9f46c9eede93dde811436d2ddfb8e
4
- data.tar.gz: ad86b1dbbb0744be8eb76d82da287a9d2ee13d1e43d3bb5f137669fe3c865c82
3
+ metadata.gz: cc7188fc5cc51dd567a013d39cff0c8693474aeb6ae70861defaae3a72556334
4
+ data.tar.gz: e309c541c56c9ef4fde63a3559cb2148a264c32fcbda7bcc685b9d499382c942
5
5
  SHA512:
6
- metadata.gz: 03c859f3cd8129b26576402d2ecc8d3fff54adb7fcce812e36a910bec254d8c26e6f1192b570889ed6c7462f83f2a7a3a7e9f616e4941be0b82fb7af688e0ed0
7
- data.tar.gz: ea4e4033a81221b8f798a8adb50a3e625b405d1136f43c690834f53af9a07cdf36eb8269241a1a69397b68fe3ca4f8dbf1673c3e0ffd750420686bdb61ace4dd
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
- before_install:
5
- - sudo apt-get -qq update
6
- - sudo apt-get install -y libavahi-compat-libdnssd-dev
7
- - gem update --system
8
- - gem --version
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
- matrix:
18
- fast_finish: true
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
@@ -39,7 +39,7 @@ fan.characteristic(:on).on(:updated) do |new_value|
39
39
  end
40
40
  end
41
41
 
42
- RubyHome::Broadcast.run
42
+ RubyHome.run
43
43
  ```
44
44
 
45
45
  ## Development
data/bin/rubyhome CHANGED
@@ -13,4 +13,4 @@ fan.characteristic(:on).on(:updated) do |new_value|
13
13
  end
14
14
  end
15
15
 
16
- RubyHome::Broadcast.run
16
+ RubyHome.run
@@ -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
- PERSISTABLE = [ :device_id, :paired_clients, :password, :signature_key, :username ].freeze
5
+ class AccessoryInfo < YamlRecord::Base
6
+ USERNAME = -'Pair-Setup'
8
7
 
9
- def initialize(store)
10
- @store = store
8
+ properties :device_id, :paired_clients, :password, :signature_key
9
+ source 'accessory_info.yml'
11
10
 
12
- read
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
- @device_id ||= DeviceID.generate
15
- @paired_clients ||= []
16
- @signature_key ||= Ed25519::SigningKey.generate.to_bytes.unpack1('H*')
16
+ def self.instance
17
+ first || create
17
18
  end
18
19
 
19
- attr_reader :store
20
- attr_reader :device_id, :signature_key, :paired_clients, :password, :username
21
- attr_writer :device_id, :paired_clients, :password, :username
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 signing_key
29
- @signing_key ||= Ed25519::SigningKey.new([signature_key].pack('H*'))
25
+ def remove_paired_client(identifier)
26
+ paired_clients.delete_if { |h| h[:identifier] == identifier }
27
+ save
30
28
  end
31
29
 
32
- def username
33
- 'Pair-Setup'
30
+ def paired?
31
+ paired_clients.any?
34
32
  end
35
33
 
36
- def password
37
- '031-45-154'
34
+ def signing_key
35
+ @signing_key ||= RbNaCl::Signatures::Ed25519::SigningKey.new([signature_key].pack('H*'))
38
36
  end
39
37
 
40
- def to_hash
41
- Hash[*PERSISTABLE.flat_map { |attribute| [attribute, send(attribute)] }]
38
+ def username
39
+ USERNAME
42
40
  end
43
41
 
44
- def read
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 save
53
- store.transaction do
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 self.pstore=(new_storage)
59
- @@accessory_info = AccessoryInfo.new(new_storage)
48
+ def set_paired_clients
49
+ self.paired_clients = []
60
50
  end
61
51
 
62
- @@accessory_info = AccessoryInfo.new(YAML::Store.new 'accessory_info.yml')
63
-
64
- class << self
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
- def remove_paired_client(identifier)
94
- @@accessory_info.paired_clients.delete_if { |h| h[:identifier] == identifier }
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
@@ -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,5 +1,3 @@
1
- require 'dnssd/text_record'
2
-
3
1
  module RubyHome
4
2
  class TextRecord < DNSSD::TextRecord
5
3
  def initialize(accessory_info:)
@@ -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,6 +1,3 @@
1
- require_relative '../hap/service'
2
- require_relative '../hap/accessory'
3
-
4
1
  module RubyHome
5
2
  class CharacteristicFactory
6
3
  DEFAULT_VALUES = {
@@ -40,4 +40,3 @@ module RubyHome
40
40
  end
41
41
  end
42
42
  end
43
-
@@ -1,5 +1,3 @@
1
- require_relative 'characteristic_template'
2
-
3
1
  module RubyHome
4
2
  class ServiceTemplate
5
3
  FILEPATH = (File.dirname(__FILE__) + '/../../config/services.yml').freeze
@@ -4,8 +4,8 @@ module RubyHome
4
4
  @services = []
5
5
  end
6
6
 
7
- attr_reader :id, :services
8
- attr_writer :id
7
+ attr_accessor :id
8
+ attr_reader :services
9
9
 
10
10
  def characteristics
11
11
  services.flat_map(&:characteristics)
@@ -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,5 +1,3 @@
1
- require 'rbnacl/libsodium'
2
-
3
1
  module RubyHome
4
2
  module HAP
5
3
  module Crypto
@@ -27,5 +25,3 @@ module RubyHome
27
25
  end
28
26
  end
29
27
  end
30
-
31
-
@@ -1,5 +1,3 @@
1
- require 'rbnacl/libsodium'
2
-
3
1
  GEM_HKDF = HKDF
4
2
 
5
3
  module RubyHome
@@ -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
- HexPad.pad([count].pack('Q<'))
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
- data.chars.each_slice(1024).map(&:join).map do |message|
13
- additional_data = [message.length].pack('v')
13
+ encrypted_data = []
14
+ read_pointer = 0
14
15
 
15
- encrypted_data = chacha20poly1305ietf.encrypt(nonce, message, additional_data)
16
- increment_count!
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
- [additional_data, encrypted_data].join
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
- HexPad.pad([count].pack('Q<'))
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
-
@@ -1,6 +1,3 @@
1
- Dir[File.dirname(__FILE__) + '/services/*.rb'].each { |file| require file }
2
- require_relative 'characteristic'
3
-
4
1
  module RubyHome
5
2
  class Service
6
3
  def initialize(accessory: , primary: false, hidden: false, name:, description:, uuid:)
@@ -1,27 +1,34 @@
1
- require 'bindata'
2
-
3
1
  module RubyHome
4
2
  module HAP
5
3
  module TLV
6
- extend self
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
- TYPE_NAMES = {
9
- 0 => 'kTLVType_Method',
10
- 1 => 'kTLVType_Identifier',
11
- 2 => 'kTLVType_Salt',
12
- 3 => 'kTLVType_PublicKey',
13
- 4 => 'kTLVType_Proof',
14
- 5 => 'kTLVType_EncryptedData',
15
- 6 => 'kTLVType_State',
16
- 7 => 'kTLVType_Error',
17
- 8 => 'kTLVType_RetryDelay',
18
- 9 => 'kTLVType_Certificate',
19
- 10 => 'kTLVType_Signature',
20
- 11 => 'kTLVType_Permissions',
21
- 12 => 'kTLVType_FragmentData',
22
- 13 => 'kTLVType_FragmentLast',
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
- NAME_TYPES = TYPE_NAMES.invert.freeze
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
- require 'sinatra/base'
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 < Sinatra::Base
10
- Dir[File.dirname(__FILE__) + '/controllers/*.rb'].each {|file| require file }
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
- disable :protection
13
- disable :logging
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
- use AccessoriesController
22
- use CharacteristicsController
23
- use PairSetupsController
24
- use PairVerifiesController
25
- use PairingsController
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 '/accessories' do
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 ||= begin
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 ||= begin
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 request_id
29
- Application.request_id
34
+ def cache
35
+ RequestStore.store
30
36
  end
31
37
 
32
- def cache
33
- GlobalCache.instance[request_id] ||= Cache.new
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