procon_bypass_man 0.1.6 → 0.1.10
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 +41 -16
- data/.github/workflows/ruby.yml +34 -0
- data/.gitignore +4 -0
- data/.rubocop.yml +2 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +17 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +57 -6
- data/README.md +18 -10
- data/Rakefile +10 -1
- data/Steepfile +39 -0
- data/bin/report_receive_server.rb +11 -0
- data/docs/setup_raspi.md +12 -7
- data/docs/setup_raspi.mitamae.rb +60 -0
- data/docs/setup_raspi_by_mitamae.md +14 -0
- data/lib/procon_bypass_man/analog_stick_position.rb +8 -0
- data/lib/procon_bypass_man/boot_message.rb +40 -0
- data/lib/procon_bypass_man/buttons_setting_configuration.rb +100 -0
- data/lib/procon_bypass_man/bypass/usb_hid_logger.rb +20 -0
- data/lib/procon_bypass_man/bypass.rb +61 -29
- data/lib/procon_bypass_man/callbacks.rb +70 -0
- data/lib/procon_bypass_man/configuration/layer.rb +50 -4
- data/lib/procon_bypass_man/configuration/loader.rb +8 -8
- data/lib/procon_bypass_man/configuration/validator.rb +1 -1
- data/lib/procon_bypass_man/configuration.rb +68 -64
- data/lib/procon_bypass_man/device_connector.rb +13 -30
- data/lib/procon_bypass_man/io_monitor.rb +7 -4
- data/lib/procon_bypass_man/on_memory_cache.rb +34 -0
- data/lib/procon_bypass_man/outbound/base.rb +40 -0
- data/lib/procon_bypass_man/outbound/error_reporter.rb +13 -0
- data/lib/procon_bypass_man/outbound/reporter.rb +12 -0
- data/lib/procon_bypass_man/outbound/usb_hid_data_reporter.rb +13 -0
- data/lib/procon_bypass_man/procon/analog_stick_cap.rb +88 -0
- data/lib/procon_bypass_man/procon/button_collection.rb +14 -6
- data/lib/procon_bypass_man/procon/debug_dumper.rb +17 -0
- data/lib/procon_bypass_man/procon/layer_changeable.rb +2 -2
- 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/pressed_button_helper.rb +0 -10
- data/lib/procon_bypass_man/procon/user_operation.rb +14 -3
- data/lib/procon_bypass_man/procon.rb +23 -5
- data/lib/procon_bypass_man/runner.rb +36 -48
- data/lib/procon_bypass_man/uptime.rb +15 -0
- data/lib/procon_bypass_man/version.rb +1 -1
- data/lib/procon_bypass_man.rb +26 -33
- data/project_template/README.md +17 -0
- data/project_template/app.rb +20 -0
- data/project_template/setting.yml +35 -0
- data/project_template/systemd_units/pbm.service +13 -0
- 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 +507 -0
- metadata +30 -5
- data/examples/pbm.service +0 -27
- data/examples/simple.rb +0 -13
@@ -0,0 +1,40 @@
|
|
1
|
+
module ProconBypassMan
|
2
|
+
module Outbound
|
3
|
+
class Base
|
4
|
+
class Client
|
5
|
+
def initialize(path: , server: )
|
6
|
+
@path = path
|
7
|
+
if server.is_a?(Array)
|
8
|
+
@server = server.first
|
9
|
+
else
|
10
|
+
@server = server
|
11
|
+
end
|
12
|
+
@hostname = `hostname`.chomp
|
13
|
+
end
|
14
|
+
|
15
|
+
def post(body: )
|
16
|
+
# TODO ここでvalidationする
|
17
|
+
if @server.nil?
|
18
|
+
ProconBypassMan.logger.info('送信先が未設定なのでスキップしました')
|
19
|
+
return
|
20
|
+
end
|
21
|
+
|
22
|
+
uri = URI.parse("#{@server}#{@path}")
|
23
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
24
|
+
http.use_ssl = uri.scheme === "https"
|
25
|
+
response = http.post(
|
26
|
+
uri.path,
|
27
|
+
{ report: body.to_json, hostname: @hostname }.to_json,
|
28
|
+
{ "Content-Type" => "application/json" },
|
29
|
+
)
|
30
|
+
unless response.code == /^20/
|
31
|
+
ProconBypassMan.logger.error(response.body)
|
32
|
+
end
|
33
|
+
rescue => e
|
34
|
+
puts e
|
35
|
+
ProconBypassMan.logger.error(e)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "procon_bypass_man/outbound/base"
|
2
|
+
|
3
|
+
class ProconBypassMan::ErrorReporter < ProconBypassMan::Outbound::Base
|
4
|
+
PATH = "/api/error_reports"
|
5
|
+
|
6
|
+
def self.report(body: )
|
7
|
+
Client.new(
|
8
|
+
path: PATH,
|
9
|
+
server: ProconBypassMan.config.api_server,
|
10
|
+
).post(body: body.full_message.to_json)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require "procon_bypass_man/outbound/base"
|
2
|
+
|
3
|
+
class ProconBypassMan::Reporter < ProconBypassMan::Outbound::Base
|
4
|
+
PATH = "/api/reports"
|
5
|
+
|
6
|
+
def self.report(body: )
|
7
|
+
Client.new(
|
8
|
+
path: PATH,
|
9
|
+
server: ProconBypassMan.config.api_server,
|
10
|
+
).post(body: body.to_json)
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "procon_bypass_man/outbound/base"
|
2
|
+
|
3
|
+
class ProconBypassMan::UsbHidDataReporter < ProconBypassMan::Outbound::Base
|
4
|
+
PATH = "/api/usb_hid_chunks"
|
5
|
+
|
6
|
+
def self.report(body: )
|
7
|
+
Client.new(
|
8
|
+
path: PATH,
|
9
|
+
server: ProconBypassMan.config.internal_api_servers,
|
10
|
+
).post(body: body.to_json)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
@@ -0,0 +1,88 @@
|
|
1
|
+
class ProconBypassMan::Procon::AnalogStickCap
|
2
|
+
class Position
|
3
|
+
attr_accessor :x, :y
|
4
|
+
|
5
|
+
def initialize(x:, y:)
|
6
|
+
@x = x.to_i
|
7
|
+
@y = y.to_i
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_binary
|
11
|
+
analog_stick_data = [
|
12
|
+
(@x & "0xff".to_i(16)),
|
13
|
+
((@y << 4) & "0xf0".to_i(16)) | ((@x >> 8) & "0x0f".to_i(16)),
|
14
|
+
(@y >> 4) & "0xff".to_i(16),
|
15
|
+
]
|
16
|
+
hex = analog_stick_data.map{ |x| x.to_s(16).rjust(2, "0") }.join
|
17
|
+
[hex].pack("H*")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_accessor :bin_x, :bin_y
|
22
|
+
attr_accessor :neutral_position
|
23
|
+
|
24
|
+
def initialize(binary)
|
25
|
+
@neutral_position = ProconBypassMan::ButtonsSettingConfiguration.instance.neutral_position
|
26
|
+
@binary = binary
|
27
|
+
|
28
|
+
byte6 = binary[6].unpack("H*").first.to_i(16).to_s(2).rjust(8, "0")
|
29
|
+
byte7 = binary[7].unpack("H*").first.to_i(16).to_s(2).rjust(8, "0")
|
30
|
+
byte8 = binary[8].unpack("H*").first.to_i(16).to_s(2).rjust(8, "0")
|
31
|
+
|
32
|
+
self.bin_x = "#{byte7[4..7]}#{byte6}"
|
33
|
+
self.bin_y = "#{byte8}#{byte7[0..3]}"
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [ProconBypassMan::Procon::AnalogStickCap::Position]
|
37
|
+
def capped_position(cap_hypotenuse: )
|
38
|
+
if hypotenuse > cap_hypotenuse
|
39
|
+
relative_capped_x = cap_hypotenuse * Math.cos(rad * Math::PI / 180).abs
|
40
|
+
relative_capped_y = cap_hypotenuse * Math.sin(rad * Math::PI / 180).abs
|
41
|
+
relative_capped_x = -(relative_capped_x.abs) if relative_x.negative?
|
42
|
+
relative_capped_y = -(relative_capped_y.abs) if relative_y.negative?
|
43
|
+
return Position.new(
|
44
|
+
x: relative_capped_x + neutral_position.x,
|
45
|
+
y: relative_capped_y + neutral_position.y,
|
46
|
+
)
|
47
|
+
else
|
48
|
+
return position
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [ProconBypassMan::Procon::AnalogStickCap::Position]
|
53
|
+
def position
|
54
|
+
Position.new(x: abs_x, y: abs_y)
|
55
|
+
end
|
56
|
+
|
57
|
+
# 0, 0からのx
|
58
|
+
def abs_x
|
59
|
+
bin_x.to_i(2)
|
60
|
+
end
|
61
|
+
|
62
|
+
# 0, 0からのy
|
63
|
+
def abs_y
|
64
|
+
bin_y.to_i(2)
|
65
|
+
end
|
66
|
+
|
67
|
+
def relative_x
|
68
|
+
bin_x.to_i(2) - neutral_position.x
|
69
|
+
end
|
70
|
+
|
71
|
+
def relative_y
|
72
|
+
bin_y.to_i(2) - neutral_position.y
|
73
|
+
end
|
74
|
+
|
75
|
+
# @deprecated
|
76
|
+
def x; relative_x; end
|
77
|
+
def y; relative_y; end
|
78
|
+
|
79
|
+
def rad
|
80
|
+
(
|
81
|
+
Math.atan(y / x.to_f) * 180 / Math::PI
|
82
|
+
).floor(6)
|
83
|
+
end
|
84
|
+
|
85
|
+
def hypotenuse
|
86
|
+
Math.sqrt(x**2 + y**2).floor(6)
|
87
|
+
end
|
88
|
+
end
|
@@ -8,15 +8,20 @@ class ProconBypassMan::Procon::ButtonCollection
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
+
# https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/ac8093c84194b3232acb675ac1accce9bcb456a3/bluetooth_hid_notes.md
|
12
|
+
#0) Input report ID
|
13
|
+
#1) Timer. Increments very fast. Can be used to estimate excess Bluetooth latency.
|
14
|
+
#2 high nibble) Battery level. 8=full, 6=medium, 4=low, 2=critical, 0=empty. LSB=Charging.
|
15
|
+
#2 low nibble) Connection info. (con_info >> 1) & 3 - 3=JC, 0=Pro/ChrGrip. con_info & 1 - 1=Switch/USB powered.
|
11
16
|
#3) ZR R SR(right) SL(right) A B X Y
|
12
17
|
#4) Grip (none) Cap Home ThumbL ThumbR + -
|
13
18
|
#5) ZL L SL(left) SR(left) Left Right Up Down
|
14
|
-
#6) analog[0]
|
15
|
-
#7) analog[1]
|
16
|
-
#8) analog[2]
|
17
|
-
#9) analog[3]
|
18
|
-
#a) analog[4]
|
19
|
-
#b) analog[5]
|
19
|
+
#6) analog[0] Left analog stick data
|
20
|
+
#7) analog[1] Left analog stick data
|
21
|
+
#8) analog[2] Left analog stick data
|
22
|
+
#9) analog[3] Right analog stick data
|
23
|
+
#a) analog[4] Right analog stick data
|
24
|
+
#b) analog[5] Right analog stick data
|
20
25
|
BYTES_MAP = {
|
21
26
|
0 => nil,
|
22
27
|
1 => nil,
|
@@ -24,6 +29,9 @@ class ProconBypassMan::Procon::ButtonCollection
|
|
24
29
|
3 => [:zr, :r, :sr, :sl, :a, :b, :x, :y],
|
25
30
|
4 => [:grip, :_undefined_key, :cap, :home, :thumbl, :thumbr, :plus, :minus],
|
26
31
|
5 => [:zl, :l, :sl, :sr, :left, :right, :up, :down],
|
32
|
+
6 => [],
|
33
|
+
7 => [],
|
34
|
+
8 => [],
|
27
35
|
}.freeze
|
28
36
|
|
29
37
|
BUTTONS_MAP = BYTES_MAP.reduce({}) { |acc, value|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class ProconBypassMan::Procon::DebugDumper
|
2
|
+
def initialize(binary: )
|
3
|
+
@binary = binary
|
4
|
+
# ProconBypassMan.logger.debug { "<<< patched #{@binary.unpack("H*")}" }
|
5
|
+
end
|
6
|
+
|
7
|
+
def dump_analog_sticks
|
8
|
+
byte6 = @binary[6].unpack("H*").first.to_i(16).to_s(2).rjust(8, "0")
|
9
|
+
byte7 = @binary[7].unpack("H*").first.to_i(16).to_s(2).rjust(8, "0")
|
10
|
+
byte8 = @binary[8].unpack("H*").first.to_i(16).to_s(2).rjust(8, "0")
|
11
|
+
|
12
|
+
x = "#{byte7[4..7]}#{byte6}"
|
13
|
+
y = "#{byte8}#{byte7[0..3]}"
|
14
|
+
ProconBypassMan.logger.debug "x: #{x}, val: #{x.to_i(2)}"
|
15
|
+
ProconBypassMan.logger.debug "y: #{y}, val: #{y.to_i(2)}"
|
16
|
+
end
|
17
|
+
end
|
@@ -16,10 +16,10 @@ module ProconBypassMan::Procon::LayerChangeable
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def change_layer?
|
19
|
-
if ProconBypassMan::
|
19
|
+
if ProconBypassMan::ButtonsSettingConfiguration.instance.prefix_keys.empty?
|
20
20
|
raise "prefix_keysが未設定です"
|
21
21
|
end
|
22
|
-
ProconBypassMan::
|
22
|
+
ProconBypassMan::ButtonsSettingConfiguration.instance.prefix_keys.map { |b| pressed_button?(b) }.all?
|
23
23
|
end
|
24
24
|
|
25
25
|
def pressed_next_layer?
|
@@ -37,11 +37,11 @@ class ProconBypassMan::Procon::MacroRegistry
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def self.reset!
|
40
|
-
ProconBypassMan::
|
40
|
+
ProconBypassMan::ButtonsSettingConfiguration.instance.macro_plugins = {}
|
41
41
|
end
|
42
42
|
|
43
43
|
def self.plugins
|
44
|
-
ProconBypassMan::
|
44
|
+
ProconBypassMan::ButtonsSettingConfiguration.instance.macro_plugins
|
45
45
|
end
|
46
46
|
|
47
47
|
reset!
|
@@ -23,10 +23,10 @@ class ProconBypassMan::Procon::ModeRegistry
|
|
23
23
|
}
|
24
24
|
|
25
25
|
def self.install_plugin(klass)
|
26
|
-
if plugins[klass.name]
|
26
|
+
if plugins[klass.name.to_sym]
|
27
27
|
raise "すでに登録済みです"
|
28
28
|
end
|
29
|
-
plugins[klass.name] = klass.binaries
|
29
|
+
plugins[klass.name.to_sym] = klass.binaries
|
30
30
|
end
|
31
31
|
|
32
32
|
def self.load(name)
|
@@ -35,11 +35,11 @@ class ProconBypassMan::Procon::ModeRegistry
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def self.reset!
|
38
|
-
ProconBypassMan::
|
38
|
+
ProconBypassMan::ButtonsSettingConfiguration.instance.mode_plugins = {}
|
39
39
|
end
|
40
40
|
|
41
41
|
def self.plugins
|
42
|
-
ProconBypassMan::
|
42
|
+
ProconBypassMan::ButtonsSettingConfiguration.instance.mode_plugins
|
43
43
|
end
|
44
44
|
|
45
45
|
reset!
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class ProconBypassMan::PpressButtonAware
|
2
|
+
def initialize(binary)
|
3
|
+
@binary = binary
|
4
|
+
end
|
5
|
+
|
6
|
+
def pressed_button?(button)
|
7
|
+
@binary[
|
8
|
+
::ProconBypassMan::Procon::ButtonCollection.load(button).byte_position
|
9
|
+
].unpack("H*").first.to_i(16).to_s(2).reverse[
|
10
|
+
::ProconBypassMan::Procon::ButtonCollection.load(button).bit_position
|
11
|
+
] == '1'
|
12
|
+
end
|
13
|
+
end
|
@@ -1,14 +1,4 @@
|
|
1
1
|
module ProconBypassMan::Procon::PushedButtonHelper
|
2
|
-
module Static
|
3
|
-
def pressed_button?(button)
|
4
|
-
binary[
|
5
|
-
::ProconBypassMan::Procon::ButtonCollection.load(button).byte_position
|
6
|
-
].unpack("H*").first.to_i(16).to_s(2).reverse[
|
7
|
-
::ProconBypassMan::Procon::ButtonCollection.load(button).bit_position
|
8
|
-
] == '1'
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
2
|
module Dynamic
|
13
3
|
@@compiled = false
|
14
4
|
def compile_if_not_compile_yet!
|
@@ -1,7 +1,6 @@
|
|
1
1
|
class ProconBypassMan::Procon
|
2
2
|
class UserOperation
|
3
3
|
include LayerChangeable
|
4
|
-
include PushedButtonHelper::Static
|
5
4
|
extend PushedButtonHelper::Dynamic
|
6
5
|
|
7
6
|
attr_reader :binary
|
@@ -32,14 +31,22 @@ class ProconBypassMan::Procon
|
|
32
31
|
end
|
33
32
|
|
34
33
|
def unpress_button(button)
|
34
|
+
return if not pressed_button?(button)
|
35
|
+
|
35
36
|
byte_position = ButtonCollection.load(button).byte_position
|
36
|
-
value = binary[byte_position].unpack("H*").first.to_i(16) - 2**ButtonCollection.load(button).bit_position
|
37
|
+
value = binary[byte_position].unpack("H*").first.to_i(16) - (2**ButtonCollection.load(button).bit_position)
|
37
38
|
binary[byte_position] = ["%02X" % value.to_s].pack("H*")
|
38
39
|
end
|
39
40
|
|
41
|
+
def apply_left_analog_stick_cap(cap: )
|
42
|
+
binary[6..8] = ProconBypassMan::Procon::AnalogStickCap.new(binary).capped_position(cap_hypotenuse: cap).to_binary
|
43
|
+
end
|
44
|
+
|
40
45
|
def press_button(button)
|
46
|
+
return if pressed_button?(button)
|
47
|
+
|
41
48
|
byte_position = ButtonCollection.load(button).byte_position
|
42
|
-
value = binary[byte_position].unpack("H*").first.to_i(16) + 2**ButtonCollection.load(button).bit_position
|
49
|
+
value = binary[byte_position].unpack("H*").first.to_i(16) + (2**ButtonCollection.load(button).bit_position)
|
43
50
|
binary[byte_position] = ["%02X" % value.to_s].pack("H*")
|
44
51
|
end
|
45
52
|
|
@@ -68,5 +75,9 @@ class ProconBypassMan::Procon
|
|
68
75
|
binary[11] = tb[11]
|
69
76
|
self.binary
|
70
77
|
end
|
78
|
+
|
79
|
+
def pressed_button?(button)
|
80
|
+
ProconBypassMan::PpressButtonAware.new(binary).pressed_button?(button)
|
81
|
+
end
|
71
82
|
end
|
72
83
|
end
|
@@ -7,6 +7,7 @@ class ProconBypassMan::Procon
|
|
7
7
|
require "procon_bypass_man/procon/pressed_button_helper"
|
8
8
|
require "procon_bypass_man/procon/user_operation"
|
9
9
|
require "procon_bypass_man/procon/flip_cache"
|
10
|
+
require "procon_bypass_man/procon/press_button_aware"
|
10
11
|
|
11
12
|
attr_accessor :user_operation
|
12
13
|
|
@@ -30,7 +31,7 @@ class ProconBypassMan::Procon
|
|
30
31
|
def current_layer_key; @@status[:current_layer_key]; end
|
31
32
|
|
32
33
|
def current_layer
|
33
|
-
ProconBypassMan::
|
34
|
+
ProconBypassMan::ButtonsSettingConfiguration.instance.layers[current_layer_key]
|
34
35
|
end
|
35
36
|
|
36
37
|
def apply!
|
@@ -94,10 +95,23 @@ class ProconBypassMan::Procon
|
|
94
95
|
return user_operation.binary
|
95
96
|
end
|
96
97
|
|
98
|
+
current_layer.disables.each do |button|
|
99
|
+
user_operation.unpress_button(button)
|
100
|
+
end
|
101
|
+
|
102
|
+
current_layer.left_analog_stick_caps.each do |button, options|
|
103
|
+
if button.nil? || button.all? { |b| user_operation.pressed_button?(b) }
|
104
|
+
options[:force_neutral]&.each do |force_neutral_button|
|
105
|
+
user_operation.unpress_button(force_neutral_button)
|
106
|
+
end
|
107
|
+
user_operation.apply_left_analog_stick_cap(cap: options[:cap])
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
97
111
|
current_layer.flip_buttons.each do |button, options|
|
98
112
|
# 何もしないで常に連打
|
99
113
|
if !options[:if_pressed] && status[button]
|
100
|
-
user_operation.press_button(button)
|
114
|
+
user_operation.press_button(button)
|
101
115
|
next
|
102
116
|
end
|
103
117
|
|
@@ -108,7 +122,7 @@ class ProconBypassMan::Procon
|
|
108
122
|
end
|
109
123
|
|
110
124
|
options[:force_neutral]&.each do |force_neutral_button|
|
111
|
-
user_operation.
|
125
|
+
user_operation.unpress_button(force_neutral_button)
|
112
126
|
end
|
113
127
|
end
|
114
128
|
end
|
@@ -118,12 +132,16 @@ class ProconBypassMan::Procon
|
|
118
132
|
user_operation.unpress_button(from_button)
|
119
133
|
# TODO 2重でpressしないようにしたい
|
120
134
|
to_buttons[:to].each do |to_button|
|
121
|
-
user_operation.press_button(to_button)
|
135
|
+
user_operation.press_button(to_button)
|
122
136
|
end
|
123
137
|
end
|
124
138
|
end
|
125
139
|
|
126
|
-
user_operation.binary
|
140
|
+
b = user_operation.binary
|
141
|
+
ProconBypassMan.cache.fetch key: 'user_operation.binary', expires_in: 60 do
|
142
|
+
ProconBypassMan::Procon::DebugDumper.new(binary: b).dump_analog_sticks
|
143
|
+
end
|
144
|
+
b
|
127
145
|
end
|
128
146
|
|
129
147
|
private
|
@@ -1,13 +1,10 @@
|
|
1
1
|
require_relative "io_monitor"
|
2
|
+
require_relative "uptime"
|
3
|
+
require_relative "boot_message"
|
2
4
|
|
3
5
|
class ProconBypassMan::Runner
|
4
6
|
class InterruptForRestart < StandardError; end
|
5
7
|
|
6
|
-
def initialize
|
7
|
-
$will_interval_0_0_0_5 = 0
|
8
|
-
$will_interval_1_6 = 0
|
9
|
-
end
|
10
|
-
|
11
8
|
def run
|
12
9
|
first_negotiation
|
13
10
|
print_booted_message
|
@@ -38,7 +35,7 @@ class ProconBypassMan::Runner
|
|
38
35
|
Process.wait
|
39
36
|
ProconBypassMan.logger.info("Reloading config file")
|
40
37
|
begin
|
41
|
-
ProconBypassMan::
|
38
|
+
ProconBypassMan::ButtonsSettingConfiguration::Loader.reload_setting
|
42
39
|
puts "設定ファイルの再読み込みができました"
|
43
40
|
rescue ProconBypassMan::CouldNotLoadConfigError
|
44
41
|
ProconBypassMan.logger.error "設定ファイルが不正です。再読み込みができませんでした"
|
@@ -60,13 +57,6 @@ class ProconBypassMan::Runner
|
|
60
57
|
private
|
61
58
|
|
62
59
|
def main_loop
|
63
|
-
# TODO 接続確立完了をswitchを読み取るようにして、この暫定で接続完了sleepを消す
|
64
|
-
Thread.new do
|
65
|
-
sleep(5)
|
66
|
-
$will_interval_0_0_0_5 = 0.005
|
67
|
-
$will_interval_1_6 = 1.6
|
68
|
-
end
|
69
|
-
|
70
60
|
ProconBypassMan::IOMonitor.start!
|
71
61
|
# gadget => procon
|
72
62
|
# 遅くていい
|
@@ -74,17 +64,27 @@ class ProconBypassMan::Runner
|
|
74
64
|
monitor2 = ProconBypassMan::IOMonitor.new(label: "procon -> switch")
|
75
65
|
ProconBypassMan.logger.info "Thread1を起動します"
|
76
66
|
t1 = Thread.new do
|
67
|
+
timer = ProconBypassMan::Timer.new(timeout: Time.now + 10)
|
77
68
|
bypass = ProconBypassMan::Bypass.new(gadget: @gadget, procon: @procon, monitor: monitor1)
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
69
|
+
loop do
|
70
|
+
break if $will_terminate_token
|
71
|
+
timer.throw_if_timeout!
|
72
|
+
bypass.send_gadget_to_procon!
|
73
|
+
sleep(0.005)
|
74
|
+
rescue ProconBypassMan::Timer::Timeout
|
75
|
+
ProconBypassMan.logger.info "10秒経過したのでThread1を終了します"
|
76
|
+
puts "10秒経過したのでThread1を終了します"
|
77
|
+
break
|
78
|
+
rescue Errno::EIO, Errno::ENODEV, Errno::EPROTO, IOError => e
|
79
|
+
ProconBypassMan.logger.error "Proconが切断されました.終了処理を開始します"
|
80
|
+
Process.kill "TERM", Process.ppid
|
81
|
+
rescue Errno::ETIMEDOUT => e
|
82
|
+
# TODO まれにこれが発生する. 再接続したい
|
83
|
+
ProconBypassMan::ErrorReporter.report(body: e)
|
84
|
+
ProconBypassMan.logger.error "Switchとの切断されました.終了処理を開始します"
|
85
|
+
Process.kill "TERM", Process.ppid
|
87
86
|
end
|
87
|
+
ProconBypassMan.logger.info "Thread1を終了します"
|
88
88
|
end
|
89
89
|
|
90
90
|
# procon => gadget
|
@@ -92,19 +92,17 @@ class ProconBypassMan::Runner
|
|
92
92
|
ProconBypassMan.logger.info "Thread2を起動します"
|
93
93
|
t2 = Thread.new do
|
94
94
|
bypass = ProconBypassMan::Bypass.new(gadget: @gadget, procon: @procon, monitor: monitor2)
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
Process.kill "TERM", Process.ppid
|
105
|
-
end
|
106
|
-
ProconBypassMan.logger.info "Thread2を終了します"
|
95
|
+
loop do
|
96
|
+
break if $will_terminate_token
|
97
|
+
bypass.send_procon_to_gadget!
|
98
|
+
rescue EOFError => e
|
99
|
+
ProconBypassMan.logger.error "Proconと通信ができませんでした.終了処理を開始します"
|
100
|
+
Process.kill "TERM", Process.ppid
|
101
|
+
rescue Errno::EIO, Errno::ENODEV, Errno::EPROTO, IOError => e
|
102
|
+
ProconBypassMan.logger.error "Proconが切断されました。終了処理を開始します"
|
103
|
+
Process.kill "TERM", Process.ppid
|
107
104
|
end
|
105
|
+
ProconBypassMan.logger.info "Thread2を終了します"
|
108
106
|
end
|
109
107
|
|
110
108
|
self_read, self_write = IO.pipe
|
@@ -134,8 +132,6 @@ class ProconBypassMan::Runner
|
|
134
132
|
end
|
135
133
|
|
136
134
|
def first_negotiation
|
137
|
-
return if $will_terminate_token
|
138
|
-
|
139
135
|
@gadget, @procon = ProconBypassMan::DeviceConnector.connect
|
140
136
|
rescue ProconBypassMan::Timer::Timeout
|
141
137
|
::ProconBypassMan.logger.error "デバイスとの通信でタイムアウトが起きて接続ができませんでした。"
|
@@ -156,17 +152,9 @@ class ProconBypassMan::Runner
|
|
156
152
|
|
157
153
|
# @return [void]
|
158
154
|
def print_booted_message
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
pid: #{$$}
|
164
|
-
root: #{ProconBypassMan.root}
|
165
|
-
pid_path: #{ProconBypassMan.pid_path}
|
166
|
-
setting_path: #{ProconBypassMan::Configuration.instance.setting_path}
|
167
|
-
----
|
168
|
-
EOF
|
169
|
-
ProconBypassMan.logger.info(booted_message)
|
170
|
-
puts booted_message
|
155
|
+
message = ProconBypassMan::BootMessage.new
|
156
|
+
ProconBypassMan.logger.info(message.to_s)
|
157
|
+
Thread.new { ProconBypassMan::Reporter.report(body: message.to_hash) }
|
158
|
+
puts message.to_s
|
171
159
|
end
|
172
160
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "time"
|
2
|
+
|
3
|
+
module ProconBypassMan
|
4
|
+
class Uptime
|
5
|
+
def self.from_boot
|
6
|
+
result = `uptime -s`.chomp
|
7
|
+
return -1 if result == '' # darwin系だとsオプションが使えない
|
8
|
+
boot_time = result.to_i
|
9
|
+
return Time.now.to_i - boot_time.to_i
|
10
|
+
rescue => e
|
11
|
+
ProconBypassMan.logger.error(e)
|
12
|
+
return -1
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|