ruby_home 0.1.2 → 0.1.3

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.
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