procon_bypass_man 0.1.23 → 0.2.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/.github/workflows/gitleacks.yml +11 -0
- data/CHANGELOG.md +10 -0
- data/Gemfile.lock +1 -1
- data/docs/setup_raspi.md +0 -1
- data/lib/procon_bypass_man/buttons_setting_configuration/loader.rb +1 -1
- data/lib/procon_bypass_man/{commands → bypass}/bypass_command.rb +11 -19
- data/lib/procon_bypass_man/bypass.rb +6 -9
- data/lib/procon_bypass_man/commands/print_boot_message_command.rb +1 -2
- data/lib/procon_bypass_man/commands/send_error_command.rb +2 -2
- data/lib/procon_bypass_man/commands.rb +0 -3
- data/lib/procon_bypass_man/configuration.rb +21 -2
- data/lib/procon_bypass_man/device_connection/command.rb +28 -0
- data/lib/procon_bypass_man/{device_connector.rb → device_connection/executor.rb} +51 -38
- data/lib/procon_bypass_man/device_connection/output_report_generator.rb +42 -0
- data/lib/procon_bypass_man/device_connection/output_report_markerable.rb +28 -0
- data/lib/procon_bypass_man/device_connection/output_report_sub_command_table.rb +133 -0
- data/lib/procon_bypass_man/device_connection/output_report_watcher.rb +41 -0
- data/lib/procon_bypass_man/device_connection/pre_bypass.rb +67 -0
- data/lib/procon_bypass_man/device_connection/procon_setting_overrider.rb +78 -0
- data/lib/procon_bypass_man/device_connection/spoofing_output_report_watcher.rb +39 -0
- data/lib/procon_bypass_man/device_connection.rb +16 -0
- data/lib/procon_bypass_man/device_model.rb +17 -0
- data/lib/procon_bypass_man/io_monitor.rb +20 -1
- data/lib/procon_bypass_man/procon/macro_builder.rb +5 -3
- data/lib/procon_bypass_man/{commands → remote_pbm_action/commands}/run_remote_pbm_action_dispatch_command.rb +0 -0
- data/lib/procon_bypass_man/remote_pbm_action/restore_pbm_setting.rb +7 -1
- data/lib/procon_bypass_man/remote_pbm_action.rb +1 -0
- data/lib/procon_bypass_man/runner.rb +3 -7
- data/lib/procon_bypass_man/support/never_exit_accidentally.rb +3 -3
- data/lib/procon_bypass_man/support/usb_device_controller.rb +2 -2
- data/lib/procon_bypass_man/support/yaml_loader.rb +12 -0
- data/lib/procon_bypass_man/version.rb +1 -1
- data/lib/procon_bypass_man/websocket/client.rb +1 -4
- data/lib/procon_bypass_man.rb +65 -41
- data/project_template/app.rb +7 -1
- data/sig/main.rbs +3 -3
- metadata +17 -6
- data/lib/procon_bypass_man/commands/connect_device_command.rb +0 -18
@@ -0,0 +1,41 @@
|
|
1
|
+
class ProconBypassMan::DeviceConnection::OutputReportWatcher
|
2
|
+
include ProconBypassMan::DeviceConnection::OutputReportMarkerable
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@hid_sub_command_request_table = ProconBypassMan::DeviceConnection::OutputReportSubCommandTable.new
|
6
|
+
@timer = ProconBypassMan::SafeTimeout.new
|
7
|
+
end
|
8
|
+
|
9
|
+
# @param [String] sub_command
|
10
|
+
# @param [String] sub_command_arg
|
11
|
+
# @return [Boolean]
|
12
|
+
def sent?(sub_command: , sub_command_arg: )
|
13
|
+
@hid_sub_command_request_table.has_key?(sub_command: sub_command, sub_command_arg: sub_command_arg)
|
14
|
+
end
|
15
|
+
|
16
|
+
# @param [String] sub_command
|
17
|
+
# @param [String] sub_command_arg
|
18
|
+
# @return [Boolean]
|
19
|
+
def received?(sub_command: , sub_command_arg: )
|
20
|
+
@hid_sub_command_request_table.has_value?(sub_command: sub_command, sub_command_arg: sub_command_arg)
|
21
|
+
end
|
22
|
+
|
23
|
+
# @return [Boolean]
|
24
|
+
def completed?
|
25
|
+
@hid_sub_command_request_table.completed?
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [Boolean]
|
29
|
+
# @raise [Timeout::Error]
|
30
|
+
def timeout_or_completed?
|
31
|
+
if @timer.timeout?
|
32
|
+
ProconBypassMan::SendErrorCommand.execute(error: "[pre_bypass] pre_bypassフェーズがタイムアウトしました")
|
33
|
+
return true
|
34
|
+
end
|
35
|
+
|
36
|
+
if completed?
|
37
|
+
ProconBypassMan.logger.info "[pre_bypass] pre_bypassフェーズが想定通り終了しました"
|
38
|
+
return true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
class ProconBypassMan::DeviceConnection::PreBypass
|
2
|
+
attr_accessor :gadget, :procon, :output_report_watcher
|
3
|
+
|
4
|
+
def initialize(gadget: , procon: )
|
5
|
+
self.gadget = ProconBypassMan::DeviceModel.new(gadget)
|
6
|
+
self.procon = ProconBypassMan::DeviceModel.new(procon)
|
7
|
+
self.output_report_watcher = ProconBypassMan::DeviceConnection::OutputReportWatcher.new
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [void]
|
11
|
+
def execute!
|
12
|
+
loop do
|
13
|
+
run_once
|
14
|
+
|
15
|
+
if output_report_watcher.timeout_or_completed?
|
16
|
+
break
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [void]
|
22
|
+
def run_once
|
23
|
+
begin
|
24
|
+
raw_data = non_blocking_read_switch
|
25
|
+
output_report_watcher.mark_as_send(raw_data)
|
26
|
+
ProconBypassMan.logger.info "[pre_bypass] >>> #{raw_data.unpack("H*").first}"
|
27
|
+
send_procon(raw_data)
|
28
|
+
rescue IO::EAGAINWaitReadable
|
29
|
+
# no-op
|
30
|
+
end
|
31
|
+
|
32
|
+
3.times do
|
33
|
+
begin
|
34
|
+
raw_data = non_blocking_read_procon
|
35
|
+
output_report_watcher.mark_as_receive(raw_data)
|
36
|
+
ProconBypassMan.logger.info "[pre_bypass] <<< #{raw_data.unpack("H*").first}"
|
37
|
+
send_switch(raw_data)
|
38
|
+
rescue IO::EAGAINWaitReadable
|
39
|
+
# no-op
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
# @raise [IO::EAGAINWaitReadable]
|
47
|
+
# @return [String]
|
48
|
+
def non_blocking_read_switch
|
49
|
+
gadget.non_blocking_read
|
50
|
+
end
|
51
|
+
|
52
|
+
# @raise [IO::EAGAINWaitReadable]
|
53
|
+
# @return [String]
|
54
|
+
def non_blocking_read_procon
|
55
|
+
procon.non_blocking_read
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return [void]
|
59
|
+
def send_procon(raw_data)
|
60
|
+
procon.send(raw_data)
|
61
|
+
end
|
62
|
+
|
63
|
+
# @return [void]
|
64
|
+
def send_switch(raw_data)
|
65
|
+
gadget.send(raw_data)
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
class ProconBypassMan::DeviceConnection::ProconSettingOverrider
|
2
|
+
attr_accessor :procon, :output_report_watcher, :output_report_generator
|
3
|
+
|
4
|
+
SUB_COMMAND_HOME_LED_ON = "38"
|
5
|
+
SUB_COMMAND_ARG_HOME_LED_ON = "1FF0FF"
|
6
|
+
SPECIAL_SUB_COMMAND_ARGS = {
|
7
|
+
SUB_COMMAND_HOME_LED_ON => SUB_COMMAND_ARG_HOME_LED_ON,
|
8
|
+
}
|
9
|
+
SETTING_HOME_LED_ON = { home_led_on: [SUB_COMMAND_HOME_LED_ON, SUB_COMMAND_ARG_HOME_LED_ON] }
|
10
|
+
ALL_SETTINGS = SETTING_HOME_LED_ON
|
11
|
+
|
12
|
+
def initialize(procon: )
|
13
|
+
use_steps = {}
|
14
|
+
if ProconBypassMan.config.enable_home_led_on_connect
|
15
|
+
use_steps.merge!(SETTING_HOME_LED_ON)
|
16
|
+
end
|
17
|
+
|
18
|
+
@setting_steps = use_steps.keys
|
19
|
+
self.procon = ProconBypassMan::DeviceModel.new(procon)
|
20
|
+
self.output_report_watcher = ProconBypassMan::DeviceConnection::SpoofingOutputReportWatcher.new(expected_sub_commands: use_steps.values)
|
21
|
+
self.output_report_generator = ProconBypassMan::DeviceConnection::OutputReportGenerator.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def execute!
|
25
|
+
loop do
|
26
|
+
run_once
|
27
|
+
|
28
|
+
if output_report_watcher.timeout_or_completed?
|
29
|
+
break
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def run_once
|
35
|
+
begin
|
36
|
+
raw_data = non_blocking_read_procon
|
37
|
+
rescue IO::EAGAINWaitReadable
|
38
|
+
return
|
39
|
+
end
|
40
|
+
|
41
|
+
ProconBypassMan.logger.info "[procon_setting_overrider] <<< #{raw_data.unpack("H*").first}"
|
42
|
+
output_report_watcher.mark_as_receive(raw_data)
|
43
|
+
if output_report_watcher.has_unreceived_command?
|
44
|
+
re_override_setting_by_cmd(output_report_watcher.unreceived_sub_command_with_arg)
|
45
|
+
else
|
46
|
+
if(setting_step = @setting_steps.shift)
|
47
|
+
override_setting_by_step(setting_step)
|
48
|
+
else
|
49
|
+
return
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
# @return [void]
|
57
|
+
def override_setting_by_step(setting_step)
|
58
|
+
raw_data = output_report_generator.generate_by_step(setting_step)
|
59
|
+
ProconBypassMan.logger.info "[procon_setting_overrider] >>> #{raw_data.unpack("H*").first}"
|
60
|
+
output_report_watcher.mark_as_send(raw_data)
|
61
|
+
send_procon(raw_data)
|
62
|
+
end
|
63
|
+
|
64
|
+
# @return [void]
|
65
|
+
def re_override_setting_by_cmd(sub_command_with_arg)
|
66
|
+
raw_data = output_report_generator.generate_by_sub_command_with_arg(sub_command_with_arg)
|
67
|
+
ProconBypassMan.logger.info "[procon_setting_overrider] >>> #{raw_data.unpack("H*").first}"
|
68
|
+
send_procon(raw_data)
|
69
|
+
end
|
70
|
+
|
71
|
+
def non_blocking_read_procon
|
72
|
+
procon.non_blocking_read
|
73
|
+
end
|
74
|
+
|
75
|
+
def send_procon(raw_data)
|
76
|
+
procon.send(raw_data)
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class ProconBypassMan::DeviceConnection::SpoofingOutputReportWatcher
|
2
|
+
include ProconBypassMan::DeviceConnection::OutputReportMarkerable
|
3
|
+
|
4
|
+
def initialize(expected_sub_commands: )
|
5
|
+
@timer = ProconBypassMan::SafeTimeout.new
|
6
|
+
@hid_sub_command_request_table = ProconBypassMan::DeviceConnection::OutputReportSubCommandTable.new
|
7
|
+
@expected_sub_commands = expected_sub_commands
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [Boolean]
|
11
|
+
def has_unreceived_command?
|
12
|
+
@hid_sub_command_request_table.has_unreceived_command?
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [String, NilClass]
|
16
|
+
def unreceived_sub_command_with_arg
|
17
|
+
@hid_sub_command_request_table.unreceived_sub_command_with_arg
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Boolean]
|
21
|
+
def completed?
|
22
|
+
@expected_sub_commands.all? do |sub_command, sub_command_arg|
|
23
|
+
@hid_sub_command_request_table.has_value?(sub_command: sub_command, sub_command_arg: sub_command_arg)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Boolean]
|
28
|
+
def timeout_or_completed?
|
29
|
+
if @timer.timeout?
|
30
|
+
ProconBypassMan.logger.info "[procon setting override] プロコンの設定上書き処理がタイムアウトしました"
|
31
|
+
return true
|
32
|
+
end
|
33
|
+
|
34
|
+
if completed?
|
35
|
+
ProconBypassMan.logger.info "[procon setting override] プロコンの設定上書き処理が想定通り終了しました"
|
36
|
+
return true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module ProconBypassMan::DeviceConnection
|
2
|
+
class BytesMismatchError < StandardError; end
|
3
|
+
class NotFoundProconError < StandardError; end
|
4
|
+
class TimeoutErrorInConditionalRoute < StandardError; end
|
5
|
+
class TimeoutError < StandardError; end
|
6
|
+
end
|
7
|
+
|
8
|
+
require_relative "device_connection/executor"
|
9
|
+
require_relative "device_connection/pre_bypass"
|
10
|
+
require_relative "device_connection/command"
|
11
|
+
require_relative "device_connection/output_report_markerable"
|
12
|
+
require_relative "device_connection/procon_setting_overrider"
|
13
|
+
require_relative "device_connection/output_report_generator"
|
14
|
+
require_relative "device_connection/output_report_sub_command_table"
|
15
|
+
require_relative "device_connection/spoofing_output_report_watcher"
|
16
|
+
require_relative "device_connection/output_report_watcher"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class ProconBypassMan::DeviceModel
|
2
|
+
# @param [File] device
|
3
|
+
def initialize(device)
|
4
|
+
@device = device
|
5
|
+
end
|
6
|
+
|
7
|
+
# @param [String] raw_data
|
8
|
+
def send(raw_data)
|
9
|
+
@device.write_nonblock(raw_data)
|
10
|
+
end
|
11
|
+
|
12
|
+
# @raise [IO::EAGAINWaitReadable]
|
13
|
+
# @return [String]
|
14
|
+
def non_blocking_read
|
15
|
+
@device.read_nonblock(64)
|
16
|
+
end
|
17
|
+
end
|
@@ -1,4 +1,15 @@
|
|
1
1
|
module ProconBypassMan
|
2
|
+
class NullCounter
|
3
|
+
def initialize(label: )
|
4
|
+
end
|
5
|
+
|
6
|
+
def record(_)
|
7
|
+
end
|
8
|
+
|
9
|
+
def shutdown
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
2
13
|
class Counter
|
3
14
|
attr_accessor :label, :table, :previous_table, :active
|
4
15
|
|
@@ -40,7 +51,11 @@ module ProconBypassMan
|
|
40
51
|
end
|
41
52
|
|
42
53
|
module IOMonitor
|
54
|
+
@@thread = nil
|
55
|
+
|
43
56
|
def self.new(label: )
|
57
|
+
return NullCounter.new(label: label) if not started?
|
58
|
+
|
44
59
|
counter = Counter.new(label: label)
|
45
60
|
@@list << counter
|
46
61
|
counter
|
@@ -51,9 +66,13 @@ module ProconBypassMan
|
|
51
66
|
@@list
|
52
67
|
end
|
53
68
|
|
69
|
+
def self.started?
|
70
|
+
!!@@thread
|
71
|
+
end
|
72
|
+
|
54
73
|
# ここで集計する
|
55
74
|
def self.start!
|
56
|
-
Thread.start do
|
75
|
+
@@thread = Thread.start do
|
57
76
|
max_output_length = 0
|
58
77
|
loop do
|
59
78
|
list = @@list.select(&:active).dup
|
@@ -5,9 +5,11 @@ class ProconBypassMan::Procon::MacroBuilder
|
|
5
5
|
return subjects.first.to_steps
|
6
6
|
end
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
subjects.inject([[], []]) do |acc, item|
|
9
|
+
acc[0] << item.to_steps[0]
|
10
|
+
acc[1] << item.to_steps[1]
|
11
|
+
acc
|
12
|
+
end
|
11
13
|
end
|
12
14
|
end
|
13
15
|
|
File without changes
|
@@ -17,7 +17,8 @@ module ProconBypassMan
|
|
17
17
|
path: ProconBypassMan::ButtonsSettingConfiguration.instance.setting_path,
|
18
18
|
content: setting,
|
19
19
|
)
|
20
|
-
|
20
|
+
|
21
|
+
hot_reload!
|
21
22
|
end
|
22
23
|
|
23
24
|
private
|
@@ -29,6 +30,11 @@ module ProconBypassMan
|
|
29
30
|
def after_action_callback
|
30
31
|
be_processed
|
31
32
|
end
|
33
|
+
|
34
|
+
# @return [void]
|
35
|
+
def hot_reload!
|
36
|
+
Process.kill(:USR2, ProconBypassMan.pid)
|
37
|
+
end
|
32
38
|
end
|
33
39
|
end
|
34
40
|
end
|
@@ -6,6 +6,7 @@ module ProconBypassMan
|
|
6
6
|
require "procon_bypass_man/remote_pbm_action/stop_pbm_action"
|
7
7
|
require "procon_bypass_man/remote_pbm_action/restore_pbm_setting.rb"
|
8
8
|
require "procon_bypass_man/remote_pbm_action/commands/update_remote_pbm_action_status_command"
|
9
|
+
require "procon_bypass_man/remote_pbm_action/commands/run_remote_pbm_action_dispatch_command"
|
9
10
|
require "procon_bypass_man/remote_pbm_action/value_objects/remote_pbm_action_object"
|
10
11
|
|
11
12
|
ACTION_CHANGE_PBM_VERSION = "change_pbm_version"
|
@@ -8,8 +8,6 @@ class ProconBypassMan::Runner
|
|
8
8
|
def initialize(gadget: , procon: )
|
9
9
|
@gadget = gadget
|
10
10
|
@procon = procon
|
11
|
-
|
12
|
-
ProconBypassMan::PrintBootMessageCommand.execute
|
13
11
|
end
|
14
12
|
|
15
13
|
def run
|
@@ -41,9 +39,9 @@ class ProconBypassMan::Runner
|
|
41
39
|
handle_signal(signal)
|
42
40
|
end
|
43
41
|
rescue InterruptForRestart
|
42
|
+
ProconBypassMan::PrintMessageCommand.execute(text: "設定ファイルの再読み込みを開始します")
|
44
43
|
Process.kill("USR2", child_pid)
|
45
44
|
Process.wait
|
46
|
-
ProconBypassMan::PrintMessageCommand.execute(text: "Reloading config file")
|
47
45
|
begin
|
48
46
|
ProconBypassMan::ButtonsSettingConfiguration::Loader.reload_setting
|
49
47
|
ProconBypassMan::SendReloadConfigEventCommand.execute
|
@@ -53,12 +51,10 @@ class ProconBypassMan::Runner
|
|
53
51
|
end
|
54
52
|
ProconBypassMan::PrintMessageCommand.execute(text: "バイパス処理を再開します")
|
55
53
|
rescue Interrupt
|
54
|
+
puts
|
55
|
+
ProconBypassMan::PrintMessageCommand.execute(text: "処理を終了します")
|
56
56
|
Process.kill("TERM", child_pid)
|
57
57
|
Process.wait
|
58
|
-
ProconBypassMan::PrintMessageCommand.execute(text: "処理を終了します")
|
59
|
-
ProconBypassMan::UsbDeviceController.reset
|
60
|
-
@gadget&.close
|
61
|
-
@procon&.close
|
62
58
|
break
|
63
59
|
end
|
64
60
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module ProconBypassMan
|
2
2
|
module NeverExitAccidentally
|
3
|
-
def
|
3
|
+
def self.exit_if_allow_at_config
|
4
4
|
if ProconBypassMan.never_exit_accidentally
|
5
|
-
eternal_sleep
|
5
|
+
ProconBypassMan.eternal_sleep
|
6
6
|
else
|
7
7
|
yield if block_given?
|
8
|
-
exit
|
8
|
+
exit 1
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
class ProconBypassMan::UsbDeviceController
|
2
2
|
class << self
|
3
|
-
def reset
|
3
|
+
def reset(cooldown: 0.5)
|
4
4
|
[ "echo > /sys/kernel/config/usb_gadget/procon/UDC",
|
5
5
|
"ls /sys/class/udc > /sys/kernel/config/usb_gadget/procon/UDC",
|
6
6
|
].each do |shell|
|
7
7
|
system shell
|
8
8
|
ProconBypassMan.logger.debug { "[SHELL] #{shell}" }
|
9
9
|
end
|
10
|
-
sleep
|
10
|
+
sleep cooldown
|
11
11
|
end
|
12
12
|
|
13
13
|
def init
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class ProconBypassMan::YamlLoader
|
2
|
+
# @param [String] path
|
3
|
+
# @return [Hash]
|
4
|
+
def self.load(path: )
|
5
|
+
YAML.load_file(path).tap do |y|
|
6
|
+
# 行末に空白があるとto_yamlしたときに改行コードがエスケープされてしまうのでstrip
|
7
|
+
y.transform_values do |v|
|
8
|
+
v.strip! if v.is_a?(String)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -23,8 +23,7 @@ module ProconBypassMan
|
|
23
23
|
ProconBypassMan.logger.info('websocket client: successfully connected in ProconBypassMan::Websocket::Client')
|
24
24
|
}
|
25
25
|
client.subscribed { |msg|
|
26
|
-
ProconBypassMan.logger.info(
|
27
|
-
puts({ event: :subscribed, msg: msg })
|
26
|
+
ProconBypassMan.logger.info("websocket client: subscribed(#{msg})")
|
28
27
|
ProconBypassMan::SyncDeviceStatsJob.perform(ProconBypassMan::DeviceStatus.current)
|
29
28
|
}
|
30
29
|
|
@@ -39,13 +38,11 @@ module ProconBypassMan
|
|
39
38
|
|
40
39
|
client.disconnected {
|
41
40
|
ProconBypassMan.logger.info('websocket client: disconnected!!')
|
42
|
-
puts :disconnected
|
43
41
|
client.reconnect!
|
44
42
|
sleep 2
|
45
43
|
}
|
46
44
|
client.errored { |msg|
|
47
45
|
ProconBypassMan.logger.error("websocket client: errored!!, #{msg}")
|
48
|
-
puts :errored
|
49
46
|
client.reconnect!
|
50
47
|
sleep 2
|
51
48
|
}
|
data/lib/procon_bypass_man.rb
CHANGED
@@ -14,11 +14,14 @@ require "pbmenv"
|
|
14
14
|
require_relative "procon_bypass_man/version"
|
15
15
|
require_relative "procon_bypass_man/remote_pbm_action"
|
16
16
|
require_relative "procon_bypass_man/remote_macro"
|
17
|
+
|
18
|
+
require_relative "procon_bypass_man/device_connection"
|
17
19
|
require_relative "procon_bypass_man/support/usb_device_controller"
|
18
20
|
require_relative "procon_bypass_man/support/device_procon_finder"
|
19
21
|
require_relative "procon_bypass_man/support/device_mouse_finder"
|
20
22
|
require_relative "procon_bypass_man/support/signal_handler"
|
21
23
|
require_relative "procon_bypass_man/support/callbacks"
|
24
|
+
require_relative "procon_bypass_man/support/yaml_loader"
|
22
25
|
require_relative "procon_bypass_man/support/yaml_writer"
|
23
26
|
require_relative "procon_bypass_man/support/safe_timeout"
|
24
27
|
require_relative "procon_bypass_man/support/compress_array"
|
@@ -36,13 +39,13 @@ require_relative "procon_bypass_man/support/cycle_sleep"
|
|
36
39
|
require_relative "procon_bypass_man/background"
|
37
40
|
require_relative "procon_bypass_man/commands"
|
38
41
|
require_relative "procon_bypass_man/bypass"
|
39
|
-
require_relative "procon_bypass_man/device_connector"
|
40
42
|
require_relative "procon_bypass_man/device_status"
|
41
43
|
require_relative "procon_bypass_man/runner"
|
42
44
|
require_relative "procon_bypass_man/processor"
|
43
45
|
require_relative "procon_bypass_man/configuration"
|
44
46
|
require_relative "procon_bypass_man/buttons_setting_configuration"
|
45
47
|
require_relative "procon_bypass_man/procon"
|
48
|
+
require_relative "procon_bypass_man/device_model"
|
46
49
|
require_relative "procon_bypass_man/procon/button"
|
47
50
|
require_relative "procon_bypass_man/procon/analog_stick_cap"
|
48
51
|
require_relative "procon_bypass_man/procon/analog_stick_manipulator"
|
@@ -61,52 +64,59 @@ module ProconBypassMan
|
|
61
64
|
extend ProconBypassMan::NeverExitAccidentally
|
62
65
|
|
63
66
|
class CouldNotLoadConfigError < StandardError; end
|
64
|
-
class
|
67
|
+
class NotFoundProconError < StandardError; end
|
65
68
|
|
66
69
|
# @return [void]
|
67
70
|
def self.run(setting_path: nil)
|
68
|
-
ProconBypassMan::Scheduler.start!
|
69
|
-
ProconBypassMan::Background::JobRunner.start!
|
70
|
-
ProconBypassMan::Websocket::Client.start!
|
71
|
-
ProconBypassMan::QueueOverProcess.start!
|
72
|
-
|
73
71
|
ProconBypassMan::PrintMessageCommand.execute(text: "PBMを起動しています")
|
74
72
|
initialize_pbm
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
FileUtils.rm_rf(ProconBypassMan.pid_path)
|
87
|
-
FileUtils.rm_rf(ProconBypassMan.digest_path)
|
88
|
-
ProconBypassMan::QueueOverProcess.shutdown
|
73
|
+
|
74
|
+
begin
|
75
|
+
ProconBypassMan::ButtonsSettingConfiguration::Loader.load(setting_path: setting_path)
|
76
|
+
rescue ProconBypassMan::CouldNotLoadConfigError
|
77
|
+
ProconBypassMan::SendErrorCommand.execute(error: "設定ファイルが不正です。設定ファイルの読み込みに失敗しました")
|
78
|
+
ProconBypassMan::DeviceStatus.change_to_setting_syntax_error_and_shutdown!
|
79
|
+
# TODO シグナルトラップをしていないのでUSR2を送ったときにプロセスが停止している. 明示的にハンドリングするべき.
|
80
|
+
ProconBypassMan::NeverExitAccidentally.exit_if_allow_at_config do
|
81
|
+
terminate_pbm
|
82
|
+
end
|
83
|
+
return
|
89
84
|
end
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
ProconBypassMan::
|
85
|
+
|
86
|
+
begin
|
87
|
+
gadget, procon = ProconBypassMan::DeviceConnection::Command.execute!
|
88
|
+
rescue ProconBypassMan::DeviceConnection::NotFoundProconError
|
89
|
+
ProconBypassMan::SendErrorCommand.execute(error: "プロコンが見つかりませんでした。")
|
90
|
+
ProconBypassMan::DeviceStatus.change_to_procon_not_found_error!
|
91
|
+
# TODO シグナルトラップをしていないので以下の状態に、USR2を送ったときにプロセスが停止してしまう
|
92
|
+
ProconBypassMan::NeverExitAccidentally.exit_if_allow_at_config do
|
93
|
+
terminate_pbm
|
94
|
+
end
|
95
|
+
return
|
96
|
+
rescue ProconBypassMan::DeviceConnection::TimeoutError
|
97
|
+
ProconBypassMan::SendErrorCommand.execute(error: "接続の見込みがないのでsleepしまくります")
|
98
|
+
ProconBypassMan::DeviceStatus.change_to_connected_but_sleeping!
|
99
|
+
%w(TERM INT).each do |sig|
|
100
|
+
Kernel.trap(sig) { exit 0 }
|
101
|
+
end
|
102
|
+
Kernel.trap :USR2 do
|
103
|
+
exit 0 # TODO retryする
|
104
|
+
end
|
105
|
+
eternal_sleep
|
106
|
+
return
|
98
107
|
end
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
eternal_sleep
|
108
|
+
|
109
|
+
ready_pbm
|
110
|
+
Runner.new(gadget: gadget, procon: procon).run # ここでblockingする
|
111
|
+
terminate_pbm
|
104
112
|
end
|
105
113
|
|
114
|
+
# 実行ファイル(app.rb)から呼び出している
|
115
|
+
# @return [void]
|
106
116
|
def self.configure(&block)
|
107
117
|
@@configuration = ProconBypassMan::Configuration.new
|
108
118
|
@@configuration.instance_eval(&block)
|
109
|
-
|
119
|
+
nil
|
110
120
|
end
|
111
121
|
|
112
122
|
# @return [ProconBypassMan::Configuration]
|
@@ -123,20 +133,34 @@ module ProconBypassMan
|
|
123
133
|
ProconBypassMan::IOMonitor.reset!
|
124
134
|
end
|
125
135
|
|
136
|
+
# @return [void]
|
126
137
|
def self.initialize_pbm
|
138
|
+
ProconBypassMan::Scheduler.start!
|
139
|
+
ProconBypassMan::Background::JobRunner.start!
|
140
|
+
ProconBypassMan::Websocket::Client.start!
|
141
|
+
ProconBypassMan::QueueOverProcess.start!
|
142
|
+
|
127
143
|
ProconBypassMan::WriteDeviceIdCommand.execute
|
128
144
|
ProconBypassMan::WriteSessionIdCommand.execute
|
129
|
-
|
145
|
+
`renice -n -20 -p #{$$}`
|
130
146
|
File.write(pid_path, $$)
|
131
147
|
ProconBypassMan::DeviceStatus.change_to_running!
|
132
148
|
end
|
133
149
|
|
134
|
-
def self.
|
135
|
-
|
150
|
+
def self.ready_pbm
|
151
|
+
ProconBypassMan::PrintBootMessageCommand.execute
|
152
|
+
ProconBypassMan::ReportLoadConfigJob.perform_async(ProconBypassMan.config.raw_setting)
|
153
|
+
end
|
154
|
+
|
155
|
+
# @return [void]
|
156
|
+
def self.terminate_pbm
|
157
|
+
FileUtils.rm_rf(ProconBypassMan.pid_path)
|
158
|
+
FileUtils.rm_rf(ProconBypassMan.digest_path)
|
159
|
+
ProconBypassMan::QueueOverProcess.shutdown
|
136
160
|
end
|
137
161
|
|
138
|
-
# @return [
|
139
|
-
def self.
|
140
|
-
|
162
|
+
# @return [void]
|
163
|
+
def self.eternal_sleep
|
164
|
+
sleep(999999999)
|
141
165
|
end
|
142
166
|
end
|
data/project_template/app.rb
CHANGED
@@ -6,7 +6,7 @@ begin
|
|
6
6
|
gemfile do
|
7
7
|
source 'https://rubygems.org'
|
8
8
|
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
9
|
-
gem 'procon_bypass_man', '0.
|
9
|
+
gem 'procon_bypass_man', '0.2.0'
|
10
10
|
end
|
11
11
|
rescue Bundler::Source::Git::GitCommandError => e
|
12
12
|
# install中に強制終了するとgitの管理ファイルが不正状態になり、次のエラーが起きるので発生したらcache directoryを削除する
|
@@ -34,6 +34,12 @@ ProconBypassMan.configure do |config|
|
|
34
34
|
# pbm-cloudで使う場合はnever_exitにtrueをセットしてください. trueがセットされている場合、不慮の事故が発生してもプロセスが終了しなくなります
|
35
35
|
config.never_exit_accidentally = true
|
36
36
|
|
37
|
+
# 毎秒行ったIOをログに出力するか
|
38
|
+
config.io_monitor_logging = false
|
39
|
+
|
40
|
+
# 接続に成功したらコントローラーのHOME LEDを光らせるか
|
41
|
+
config.enable_home_led_on_connect = true
|
42
|
+
|
37
43
|
# 操作が高頻度で固まるときは、 gadget_to_procon_interval の数値は大きくしてください
|
38
44
|
config.bypass_mode = { mode: :normal, gadget_to_procon_interval: 5 }
|
39
45
|
end
|