procon_bypass_man 0.1.8 → 0.1.12
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/.circleci/config.yml +3 -2
- data/.github/workflows/ruby.yml +5 -4
- data/.gitignore +5 -0
- data/.rubocop.yml +2 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +18 -1
- data/Gemfile +4 -0
- data/Gemfile.lock +53 -2
- data/README.md +14 -8
- data/Steepfile +39 -0
- data/bin/console +4 -0
- data/bin/dev_api_server.rb +18 -0
- data/docs/setup_raspi.mitamae.rb +12 -0
- data/lib/procon_bypass_man/background/has_server_pool.rb +54 -0
- data/lib/procon_bypass_man/background/http_client.rb +70 -0
- data/lib/procon_bypass_man/background/job_performer.rb +16 -0
- data/lib/procon_bypass_man/background/job_runnable.rb +16 -0
- data/lib/procon_bypass_man/background/job_runner.rb +44 -0
- data/lib/procon_bypass_man/background/jobs/base_job.rb +12 -0
- data/lib/procon_bypass_man/background/jobs/report_boot_job.rb +10 -0
- data/lib/procon_bypass_man/background/jobs/report_error_job.rb +10 -0
- data/lib/procon_bypass_man/background/jobs/report_heartbeat_job.rb +10 -0
- data/lib/procon_bypass_man/background/jobs/report_pressed_buttons_job.rb +18 -0
- data/lib/procon_bypass_man/background/jobs/report_reload_config_job.rb +10 -0
- data/lib/procon_bypass_man/background.rb +10 -0
- data/lib/procon_bypass_man/boot_message.rb +42 -0
- data/lib/procon_bypass_man/{configuration → buttons_setting_configuration}/layer.rb +50 -4
- data/lib/procon_bypass_man/{configuration → buttons_setting_configuration}/loader.rb +12 -11
- data/lib/procon_bypass_man/{configuration → buttons_setting_configuration}/validator.rb +1 -1
- data/lib/procon_bypass_man/buttons_setting_configuration.rb +101 -0
- data/lib/procon_bypass_man/bypass/usb_hid_logger.rb +36 -0
- data/lib/procon_bypass_man/bypass.rb +61 -29
- data/lib/procon_bypass_man/callbacks.rb +70 -0
- data/lib/procon_bypass_man/commands/connect_device_command.rb +11 -0
- data/lib/procon_bypass_man/commands/print_boot_message_command.rb +9 -0
- data/lib/procon_bypass_man/commands/send_error_command.rb +18 -0
- data/lib/procon_bypass_man/commands/send_reload_config_event_command.rb +10 -0
- data/lib/procon_bypass_man/commands/write_device_id_command.rb +11 -0
- data/lib/procon_bypass_man/commands/write_session_id_command.rb +13 -0
- data/lib/procon_bypass_man/commands.rb +6 -0
- data/lib/procon_bypass_man/configuration.rb +92 -67
- data/lib/procon_bypass_man/device_connector.rb +11 -29
- data/lib/procon_bypass_man/io_monitor.rb +16 -8
- data/lib/procon_bypass_man/on_memory_cache.rb +34 -0
- data/lib/procon_bypass_man/procon/analog_stick.rb +31 -0
- data/lib/procon_bypass_man/procon/analog_stick_cap.rb +65 -0
- data/lib/procon_bypass_man/procon/button_collection.rb +15 -6
- data/lib/procon_bypass_man/procon/{data.rb → consts.rb} +1 -1
- data/lib/procon_bypass_man/procon/layer_changer.rb +40 -0
- data/lib/procon_bypass_man/procon/macro_registry.rb +2 -2
- data/lib/procon_bypass_man/procon/mode_registry.rb +4 -4
- data/lib/procon_bypass_man/procon/press_button_aware.rb +13 -0
- data/lib/procon_bypass_man/procon/user_operation.rb +21 -16
- data/lib/procon_bypass_man/procon.rb +23 -9
- data/lib/procon_bypass_man/procon_reader.rb +31 -0
- data/lib/procon_bypass_man/runner.rb +43 -64
- data/lib/procon_bypass_man/uptime.rb +14 -2
- data/lib/procon_bypass_man/version.rb +1 -1
- data/lib/procon_bypass_man.rb +38 -43
- data/project_template/README.md +1 -1
- data/project_template/app.rb +7 -5
- data/project_template/systemd_units/pbm_web.service +11 -0
- data/project_template/web.rb +16 -0
- data/sig/README.rb +4 -0
- data/sig/main.rbs +505 -0
- metadata +42 -11
- data/examples/practical/app.rb +0 -21
- data/examples/practical/setting.yml +0 -24
- data/lib/procon_bypass_man/procon/layer_changeable.rb +0 -28
- data/lib/procon_bypass_man/procon/pressed_button_helper.rb +0 -25
@@ -0,0 +1,42 @@
|
|
1
|
+
class ProconBypassMan::BootMessage
|
2
|
+
def initialize
|
3
|
+
@table = {}
|
4
|
+
@table[:ruby_version] = RUBY_VERSION
|
5
|
+
@table[:pbm_version] = ProconBypassMan::VERSION
|
6
|
+
@table[:pid] = $$
|
7
|
+
@table[:root_path] = ProconBypassMan.root
|
8
|
+
@table[:pid_path] = ProconBypassMan.pid_path
|
9
|
+
@table[:setting_path] = ProconBypassMan::ButtonsSettingConfiguration.instance.setting_path
|
10
|
+
@table[:uptime_from_boot] = ProconBypassMan::Uptime.from_boot
|
11
|
+
|
12
|
+
# 開発中のHEADを取りたかったけど、Gem::Specification経由から取得する必要がありそう
|
13
|
+
# build_version = `git rev-parse --short HEAD`.chomp
|
14
|
+
# if build_version.empty?
|
15
|
+
# @table[:build_version] = 'release version'
|
16
|
+
# else
|
17
|
+
# @table[:build_version] = build_version
|
18
|
+
# end
|
19
|
+
|
20
|
+
# build version: #{@table[:build_version]}
|
21
|
+
end
|
22
|
+
|
23
|
+
# @return [String]
|
24
|
+
def to_s
|
25
|
+
booted_message = <<~EOF
|
26
|
+
----
|
27
|
+
RUBY_VERSION: #{@table[:ruby_version]}
|
28
|
+
ProconBypassMan: #{@table[:pbm_version]}
|
29
|
+
pid: #{@table[:pid]}
|
30
|
+
root: #{@table[:root_path]}
|
31
|
+
pid_path: #{@table[:pid_path]}
|
32
|
+
setting_path: #{@table[:setting_path]}
|
33
|
+
uptime from boot: #{@table[:uptime_from_boot]} sec
|
34
|
+
----
|
35
|
+
EOF
|
36
|
+
end
|
37
|
+
|
38
|
+
# @return [Hash]
|
39
|
+
def to_hash
|
40
|
+
@table
|
41
|
+
end
|
42
|
+
end
|
@@ -1,13 +1,15 @@
|
|
1
1
|
module ProconBypassMan
|
2
|
-
class
|
2
|
+
class ButtonsSettingConfiguration
|
3
3
|
class Layer
|
4
|
-
attr_accessor :mode, :flips, :macros, :remaps
|
4
|
+
attr_accessor :mode, :flips, :macros, :remaps, :left_analog_stick_caps, :disables
|
5
5
|
|
6
|
-
def initialize(mode: :manual
|
6
|
+
def initialize(mode: :manual)
|
7
7
|
self.mode = mode
|
8
8
|
self.flips = {}
|
9
9
|
self.macros = {}
|
10
10
|
self.remaps = {}
|
11
|
+
self.left_analog_stick_caps = {}
|
12
|
+
self.disables = []
|
11
13
|
instance_eval(&block) if block_given?
|
12
14
|
end
|
13
15
|
|
@@ -50,7 +52,6 @@ module ProconBypassMan
|
|
50
52
|
end
|
51
53
|
end
|
52
54
|
|
53
|
-
PRESET_MACROS = [:fast_return]
|
54
55
|
def macro(name, if_pressed: )
|
55
56
|
if name.respond_to?(:name)
|
56
57
|
macro_name = name.name.to_sym
|
@@ -72,6 +73,51 @@ module ProconBypassMan
|
|
72
73
|
end
|
73
74
|
end
|
74
75
|
|
76
|
+
def left_analog_stick_cap(cap: , if_pressed: nil, force_neutral: nil)
|
77
|
+
hash = { cap: cap }
|
78
|
+
|
79
|
+
case if_pressed
|
80
|
+
when TrueClass
|
81
|
+
raise "not support class"
|
82
|
+
when Symbol, String
|
83
|
+
if_pressed = [if_pressed]
|
84
|
+
when Array, FalseClass
|
85
|
+
# sono mama
|
86
|
+
when NilClass
|
87
|
+
if_pressed = nil
|
88
|
+
else
|
89
|
+
raise "not support if_pressed"
|
90
|
+
end
|
91
|
+
|
92
|
+
if force_neutral
|
93
|
+
case force_neutral
|
94
|
+
when TrueClass, FalseClass
|
95
|
+
raise "ボタンを渡してください"
|
96
|
+
when Symbol, String
|
97
|
+
hash[:force_neutral] = [force_neutral]
|
98
|
+
when Array
|
99
|
+
hash[:force_neutral] = force_neutral
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
left_analog_stick_caps[if_pressed] = hash
|
104
|
+
end
|
105
|
+
|
106
|
+
def disable(button)
|
107
|
+
case button
|
108
|
+
when TrueClass, FalseClass, NilClass
|
109
|
+
raise "not support class"
|
110
|
+
when Symbol
|
111
|
+
disables << button
|
112
|
+
when String
|
113
|
+
disables << button.to_sym
|
114
|
+
when Array
|
115
|
+
button.each { |b| disables << b }
|
116
|
+
else
|
117
|
+
raise "unknown"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
75
121
|
# @return [Array]
|
76
122
|
def flip_buttons
|
77
123
|
flips
|
@@ -1,13 +1,13 @@
|
|
1
1
|
module ProconBypassMan
|
2
|
-
class
|
2
|
+
class ButtonsSettingConfiguration
|
3
3
|
module Loader
|
4
4
|
require 'digest/md5'
|
5
5
|
|
6
6
|
def self.load(setting_path: )
|
7
|
-
ProconBypassMan::
|
7
|
+
ProconBypassMan::ButtonsSettingConfiguration.switch_new_context(:validation) do |new_instance|
|
8
8
|
yaml = YAML.load_file(setting_path) or raise "読み込みに失敗しました"
|
9
|
-
|
10
|
-
validator = Validator.new(
|
9
|
+
new_instance.instance_eval(yaml["setting"])
|
10
|
+
validator = Validator.new(new_instance)
|
11
11
|
if validator.valid?
|
12
12
|
next
|
13
13
|
else
|
@@ -19,26 +19,27 @@ module ProconBypassMan
|
|
19
19
|
raise ProconBypassMan::CouldNotLoadConfigError, "yamlのシンタックスエラーです"
|
20
20
|
end
|
21
21
|
|
22
|
-
|
23
|
-
ProconBypassMan::
|
24
|
-
ProconBypassMan::Configuration.instance.reset!
|
22
|
+
ProconBypassMan::ButtonsSettingConfiguration.instance.setting_path = setting_path
|
23
|
+
ProconBypassMan::ButtonsSettingConfiguration.instance.reset!
|
25
24
|
ProconBypassMan.reset!
|
26
25
|
|
26
|
+
yaml = YAML.load_file(setting_path)
|
27
|
+
ProconBypassMan.config.raw_setting = yaml.dup
|
27
28
|
case yaml["version"]
|
28
29
|
when 1.0, nil
|
29
|
-
ProconBypassMan::
|
30
|
+
ProconBypassMan::ButtonsSettingConfiguration.instance.instance_eval(yaml["setting"])
|
30
31
|
else
|
31
32
|
ProconBypassMan.logger.warn "不明なバージョンです。failoverします"
|
32
|
-
ProconBypassMan::
|
33
|
+
ProconBypassMan::ButtonsSettingConfiguration.instance.instance_eval(yaml["setting"])
|
33
34
|
end
|
34
35
|
|
35
36
|
File.write(ProconBypassMan.digest_path, Digest::MD5.hexdigest(yaml["setting"]))
|
36
37
|
|
37
|
-
ProconBypassMan::
|
38
|
+
ProconBypassMan::ButtonsSettingConfiguration.instance
|
38
39
|
end
|
39
40
|
|
40
41
|
def self.reload_setting
|
41
|
-
self.load(setting_path: ProconBypassMan::
|
42
|
+
self.load(setting_path: ProconBypassMan::ButtonsSettingConfiguration.instance.setting_path)
|
42
43
|
end
|
43
44
|
end
|
44
45
|
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require "procon_bypass_man/buttons_setting_configuration/validator"
|
2
|
+
require "procon_bypass_man/buttons_setting_configuration/loader"
|
3
|
+
require "procon_bypass_man/buttons_setting_configuration/layer"
|
4
|
+
|
5
|
+
module ProconBypassMan
|
6
|
+
class AnalogStickPosition < Struct.new(:x, :y); end
|
7
|
+
|
8
|
+
class ButtonsSettingConfiguration
|
9
|
+
attr_accessor :layers,
|
10
|
+
:setting_path,
|
11
|
+
:mode_plugins,
|
12
|
+
:macro_plugins,
|
13
|
+
:context,
|
14
|
+
:current_context_key,
|
15
|
+
:neutral_position
|
16
|
+
|
17
|
+
def self.instance
|
18
|
+
@@current_context_key ||= :main
|
19
|
+
@@context ||= {}
|
20
|
+
@@context[@@current_context_key] ||= new
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.switch_new_context(key)
|
24
|
+
@@context[key] = new
|
25
|
+
previous_key = @@current_context_key
|
26
|
+
if block_given?
|
27
|
+
@@current_context_key = key
|
28
|
+
value = yield(@@context[key])
|
29
|
+
@@current_context_key = previous_key
|
30
|
+
return value
|
31
|
+
else
|
32
|
+
@@current_context_key = key
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize
|
37
|
+
reset!
|
38
|
+
end
|
39
|
+
|
40
|
+
module ManualMode
|
41
|
+
def self.name
|
42
|
+
'manual'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
def layer(direction, mode: ManualMode, &block)
|
46
|
+
mode_name = case mode
|
47
|
+
when String
|
48
|
+
mode.to_sym
|
49
|
+
when Symbol
|
50
|
+
mode
|
51
|
+
else
|
52
|
+
mode.name.to_sym
|
53
|
+
end
|
54
|
+
unless ([ManualMode.name.to_sym] + ProconBypassMan::Procon::ModeRegistry.plugins.keys).include?(mode_name)
|
55
|
+
raise("#{mode_name} mode is unknown")
|
56
|
+
end
|
57
|
+
|
58
|
+
layer = Layer.new(mode: mode_name)
|
59
|
+
layer.instance_eval(&block) if block_given?
|
60
|
+
self.layers[direction] = layer
|
61
|
+
self
|
62
|
+
end
|
63
|
+
|
64
|
+
def install_mode_plugin(klass)
|
65
|
+
ProconBypassMan::Procon::ModeRegistry.install_plugin(klass)
|
66
|
+
self
|
67
|
+
end
|
68
|
+
|
69
|
+
def install_macro_plugin(klass)
|
70
|
+
ProconBypassMan::Procon::MacroRegistry.install_plugin(klass)
|
71
|
+
self
|
72
|
+
end
|
73
|
+
|
74
|
+
def prefix_keys_for_changing_layer(buttons)
|
75
|
+
@prefix_keys_for_changing_layer = buttons
|
76
|
+
self
|
77
|
+
end
|
78
|
+
|
79
|
+
def set_neutral_position(x, y)
|
80
|
+
self.neutral_position = AnalogStickPosition.new(x, y)
|
81
|
+
self
|
82
|
+
end
|
83
|
+
|
84
|
+
def prefix_keys
|
85
|
+
@prefix_keys_for_changing_layer
|
86
|
+
end
|
87
|
+
|
88
|
+
def reset!
|
89
|
+
@prefix_keys_for_changing_layer = []
|
90
|
+
self.mode_plugins = {}
|
91
|
+
self.macro_plugins = {}
|
92
|
+
self.layers = {
|
93
|
+
up: Layer.new,
|
94
|
+
down: Layer.new,
|
95
|
+
left: Layer.new,
|
96
|
+
right: Layer.new,
|
97
|
+
}
|
98
|
+
@neutral_position = AnalogStickPosition.new(2124, 1808)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class ProconBypassMan::Bypass
|
2
|
+
module UsbHidLogger
|
3
|
+
extend ProconBypassMan::Callbacks::ClassMethods
|
4
|
+
include ProconBypassMan::Callbacks
|
5
|
+
|
6
|
+
define_callbacks :send_gadget_to_procon
|
7
|
+
define_callbacks :send_procon_to_gadget
|
8
|
+
|
9
|
+
set_callback :send_gadget_to_procon, :after, :log_send_gadget_to_procon
|
10
|
+
set_callback :send_procon_to_gadget, :after, :log_procon_to_gadget
|
11
|
+
|
12
|
+
def log_send_gadget_to_procon
|
13
|
+
ProconBypassMan.logger.debug { ">>> #{bypass_value.to_text}" }
|
14
|
+
end
|
15
|
+
|
16
|
+
def log_procon_to_gadget
|
17
|
+
if ProconBypassMan.config.verbose_bypass_log
|
18
|
+
ProconBypassMan.logger.debug { "<<< #{bypass_value.to_text}" }
|
19
|
+
else
|
20
|
+
ProconBypassMan.cache.fetch key: 'bypass_log', expires_in: 1 do
|
21
|
+
ProconBypassMan.logger.debug { "<<< #{bypass_value.to_text}" }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
ProconBypassMan.cache.fetch key: 'pressed_buttons_reporter', expires_in: 5 do
|
26
|
+
ProconBypassMan::ReportPressedButtonsJob.perform_async(
|
27
|
+
ProconBypassMan::ProconReader.new(binary: bypass_value.binary).to_hash
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
ProconBypassMan.cache.fetch key: 'heartbeat_reporter', expires_in: 60 do
|
32
|
+
ProconBypassMan::ReportHeartbeatJob.perform_async(ProconBypassMan::BootMessage.new.to_hash)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -1,5 +1,16 @@
|
|
1
|
+
require "procon_bypass_man/bypass/usb_hid_logger"
|
2
|
+
|
1
3
|
class ProconBypassMan::Bypass
|
2
|
-
|
4
|
+
include ProconBypassMan::Bypass::UsbHidLogger
|
5
|
+
|
6
|
+
class BypassValue < Struct.new(:binary, :sent)
|
7
|
+
def to_text
|
8
|
+
"#{binary.unpack("H*").first} #{'x' unless sent}"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_accessor :gadget, :procon, :monitor, :bypass_value
|
13
|
+
|
3
14
|
def initialize(gadget: , procon: , monitor: )
|
4
15
|
self.gadget = gadget
|
5
16
|
self.procon = procon
|
@@ -10,43 +21,64 @@ class ProconBypassMan::Bypass
|
|
10
21
|
def send_gadget_to_procon!
|
11
22
|
monitor.record(:start_function)
|
12
23
|
input = nil
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
24
|
+
self.bypass_value = BypassValue.new(input, sent = false)
|
25
|
+
|
26
|
+
run_callbacks(:send_gadget_to_procon) do
|
27
|
+
begin
|
28
|
+
break if $will_terminate_token
|
29
|
+
# TODO blocking readにしたいが、接続時のフェーズによって長さが違うので厳しい
|
30
|
+
input = self.gadget.read_nonblock(64)
|
31
|
+
self.bypass_value.binary = input
|
32
|
+
rescue IO::EAGAINWaitReadable
|
33
|
+
monitor.record(:eagain_wait_readable_on_read)
|
34
|
+
sleep(0.001)
|
35
|
+
retry
|
36
|
+
end
|
22
37
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
38
|
+
begin
|
39
|
+
self.procon.write_nonblock(input)
|
40
|
+
self.bypass_value.sent = true
|
41
|
+
rescue IO::EAGAINWaitReadable
|
42
|
+
monitor.record(:eagain_wait_readable_on_write)
|
43
|
+
break
|
44
|
+
end
|
28
45
|
end
|
46
|
+
|
29
47
|
monitor.record(:end_function)
|
30
48
|
end
|
31
49
|
|
32
50
|
def send_procon_to_gadget!
|
33
51
|
monitor.record(:start_function)
|
34
52
|
output = nil
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
53
|
+
self.bypass_value = BypassValue.new(output, sent = false)
|
54
|
+
|
55
|
+
run_callbacks(:send_procon_to_gadget) do
|
56
|
+
begin
|
57
|
+
break if $will_terminate_token
|
58
|
+
Timeout.timeout(1) do
|
59
|
+
output = self.procon.read(64)
|
60
|
+
self.bypass_value.binary = output
|
61
|
+
end
|
62
|
+
rescue Timeout::Error
|
63
|
+
ProconBypassMan.logger.debug { "read timeout! do sleep. by send_procon_to_gadget!" }
|
64
|
+
ProconBypassMan.error_logger.error { "read timeout! do sleep. by send_procon_to_gadget!" }
|
65
|
+
ProconBypassMan::SendErrorCommand.execute(error: "read timeout! do sleep. by send_procon_to_gadget!")
|
66
|
+
monitor.record(:eagain_wait_readable_on_read)
|
67
|
+
retry
|
68
|
+
rescue IO::EAGAINWaitReadable
|
69
|
+
ProconBypassMan.logger.debug { "EAGAINWaitReadable" }
|
70
|
+
monitor.record(:eagain_wait_readable_on_read)
|
71
|
+
sleep(0.005)
|
72
|
+
retry
|
73
|
+
end
|
44
74
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
75
|
+
begin
|
76
|
+
self.gadget.write_nonblock(ProconBypassMan::Processor.new(output).process)
|
77
|
+
self.bypass_value.sent = true
|
78
|
+
rescue IO::EAGAINWaitReadable
|
79
|
+
monitor.record(:eagain_wait_readable_on_write)
|
80
|
+
break
|
81
|
+
end
|
50
82
|
end
|
51
83
|
monitor.record(:end_function)
|
52
84
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module ProconBypassMan
|
2
|
+
module Callbacks
|
3
|
+
class CallbacksChain
|
4
|
+
attr_accessor :filter, :chain_method
|
5
|
+
def initialize(filter: , chain_method: , block: )
|
6
|
+
@filter = filter
|
7
|
+
@chain_method = chain_method
|
8
|
+
@block = block
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# TODO __callbacksをincludeしたクラス側で保持する. 今はnemespaceがない
|
13
|
+
module M
|
14
|
+
class << self
|
15
|
+
attr_accessor :__callbacks
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
def define_callbacks(name)
|
21
|
+
self.singleton_class.attr_accessor "_#{name}_callbacks"
|
22
|
+
send "_#{name}_callbacks=", [name] # CallbacksChain
|
23
|
+
|
24
|
+
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
25
|
+
def _run_#{name}_callbacks(&block)
|
26
|
+
__run_callbacks__(_#{name}_callbacks, &block)
|
27
|
+
end
|
28
|
+
RUBY
|
29
|
+
end
|
30
|
+
|
31
|
+
def set_callback(kind, filter, chain_method, &block)
|
32
|
+
ProconBypassMan::Callbacks::M.__callbacks ||= {}
|
33
|
+
ProconBypassMan::Callbacks::M.__callbacks[kind] = CallbacksChain.new(
|
34
|
+
filter: filter,
|
35
|
+
chain_method: chain_method,
|
36
|
+
block: block,
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# TODO haltしたらcallbackを止める
|
42
|
+
# TODO 複数をチェインできるようにする
|
43
|
+
def run_callbacks(kind, &block)
|
44
|
+
chain = get_callbacks(kind) or raise("unknown callback")
|
45
|
+
case chain.filter
|
46
|
+
when :before
|
47
|
+
send chain.chain_method
|
48
|
+
block.call
|
49
|
+
when :after
|
50
|
+
block.call
|
51
|
+
send chain.chain_method
|
52
|
+
else
|
53
|
+
raise("unknown filter")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# def __run_callbacks__(name, &block)
|
58
|
+
# puts "called"
|
59
|
+
# end
|
60
|
+
|
61
|
+
def get_callbacks(kind) # :nodoc:
|
62
|
+
ProconBypassMan::Callbacks::M.__callbacks[kind.to_sym]
|
63
|
+
end
|
64
|
+
|
65
|
+
def set_callbacks(name, callbacks) # :nodoc:
|
66
|
+
send "_#{name}_callbacks=", callbacks
|
67
|
+
ProconBypassMan::Callbacks::M.__callbacks[kind.to_sym] = callbacks
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class ProconBypassMan::ConnectDeviceCommand
|
2
|
+
# @return [void]
|
3
|
+
def self.execute!
|
4
|
+
gadget, procon = ProconBypassMan::DeviceConnector.connect
|
5
|
+
rescue ProconBypassMan::Timer::Timeout
|
6
|
+
::ProconBypassMan.logger.error "デバイスとの通信でタイムアウトが起きて接続ができませんでした。"
|
7
|
+
gadget&.close
|
8
|
+
procon&.close
|
9
|
+
raise ::ProconBypassMan::EternalConnectionError
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class ProconBypassMan::PrintBootMessageCommand
|
2
|
+
# @return [void]
|
3
|
+
def self.execute
|
4
|
+
message = ProconBypassMan::BootMessage.new
|
5
|
+
ProconBypassMan::ReportBootJob.perform_async(message.to_hash)
|
6
|
+
ProconBypassMan::ReportBootJob.perform_async(ProconBypassMan.config.raw_setting)
|
7
|
+
puts message.to_s
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class ProconBypassMan::SendErrorCommand
|
2
|
+
# @param [String, Hash, Exception] error
|
3
|
+
# @return [void]
|
4
|
+
def self.execute(error: )
|
5
|
+
body =
|
6
|
+
case error
|
7
|
+
when String, Hash
|
8
|
+
error
|
9
|
+
else
|
10
|
+
error.full_message
|
11
|
+
end
|
12
|
+
|
13
|
+
ProconBypassMan.logger.error body
|
14
|
+
puts body
|
15
|
+
|
16
|
+
ProconBypassMan::ReportErrorJob.perform_async(error)
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class ProconBypassMan::SendReloadConfigEventCommand
|
2
|
+
def self.execute
|
3
|
+
puts "設定ファイルの再読み込みができました"
|
4
|
+
ProconBypassMan.logger.info "設定ファイルの再読み込みができました"
|
5
|
+
ProconBypassMan::ReportReloadConfigJob.perform_async(
|
6
|
+
ProconBypassMan.config.raw_setting
|
7
|
+
)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class ProconBypassMan::WriteDeviceIdCommand
|
2
|
+
def self.execute
|
3
|
+
path = "#{ProconBypassMan.root}/device_id"
|
4
|
+
if(sid = File.read(path))
|
5
|
+
return sid
|
6
|
+
end
|
7
|
+
rescue Errno::ENOENT
|
8
|
+
File.write(path, "m_#{SecureRandom.uuid}")
|
9
|
+
return SecureRandom.uuid
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class ProconBypassMan::WriteSessionIdCommand
|
2
|
+
# @return [String] session_id ラズパイが起動してからshutdownするまで同じ文字列を返す
|
3
|
+
# 起動すると/tmp がなくなる前提の実装
|
4
|
+
def self.execute
|
5
|
+
path = "/tmp/pbm_session_id"
|
6
|
+
if(sid = File.read(path))
|
7
|
+
return sid
|
8
|
+
end
|
9
|
+
rescue Errno::ENOENT
|
10
|
+
File.write(path, "s_#{SecureRandom.uuid}")
|
11
|
+
return SecureRandom.uuid
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
require "procon_bypass_man/commands/print_boot_message_command"
|
2
|
+
require "procon_bypass_man/commands/write_session_id_command"
|
3
|
+
require "procon_bypass_man/commands/write_device_id_command"
|
4
|
+
require "procon_bypass_man/commands/send_reload_config_event_command"
|
5
|
+
require "procon_bypass_man/commands/send_error_command"
|
6
|
+
require "procon_bypass_man/commands/connect_device_command"
|