procon_bypass_man 0.1.7 → 0.1.11

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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +3 -2
  3. data/.github/workflows/ruby.yml +34 -0
  4. data/.gitignore +4 -0
  5. data/.rubocop.yml +2 -0
  6. data/.ruby-version +1 -1
  7. data/CHANGELOG.md +17 -0
  8. data/Gemfile +4 -0
  9. data/Gemfile.lock +54 -2
  10. data/README.md +13 -8
  11. data/Rakefile +10 -1
  12. data/Steepfile +39 -0
  13. data/bin/console +4 -0
  14. data/bin/dev_api_server.rb +18 -0
  15. data/docs/setup_raspi.mitamae.rb +17 -2
  16. data/docs/setup_raspi_by_mitamae.md +2 -1
  17. data/lib/procon_bypass_man/background/report_thread.rb +42 -0
  18. data/lib/procon_bypass_man/boot_message.rb +40 -0
  19. data/lib/procon_bypass_man/buttons_setting_configuration.rb +102 -0
  20. data/lib/procon_bypass_man/bypass/usb_hid_logger.rb +27 -0
  21. data/lib/procon_bypass_man/bypass.rb +60 -29
  22. data/lib/procon_bypass_man/callbacks.rb +70 -0
  23. data/lib/procon_bypass_man/configuration/layer.rb +50 -4
  24. data/lib/procon_bypass_man/configuration/loader.rb +8 -8
  25. data/lib/procon_bypass_man/configuration/validator.rb +1 -1
  26. data/lib/procon_bypass_man/configuration.rb +67 -64
  27. data/lib/procon_bypass_man/device_connector.rb +13 -30
  28. data/lib/procon_bypass_man/io_monitor.rb +7 -4
  29. data/lib/procon_bypass_man/on_memory_cache.rb +34 -0
  30. data/lib/procon_bypass_man/outbound/base.rb +53 -0
  31. data/lib/procon_bypass_man/outbound/error_reporter.rb +13 -0
  32. data/lib/procon_bypass_man/outbound/pressed_buttons_reporter.rb +13 -0
  33. data/lib/procon_bypass_man/outbound/reporter.rb +12 -0
  34. data/lib/procon_bypass_man/procon/analog_stick.rb +31 -0
  35. data/lib/procon_bypass_man/procon/analog_stick_cap.rb +65 -0
  36. data/lib/procon_bypass_man/procon/button_collection.rb +15 -6
  37. data/lib/procon_bypass_man/procon/layer_changeable.rb +2 -2
  38. data/lib/procon_bypass_man/procon/macro_registry.rb +2 -2
  39. data/lib/procon_bypass_man/procon/mode_registry.rb +4 -4
  40. data/lib/procon_bypass_man/procon/press_button_aware.rb +13 -0
  41. data/lib/procon_bypass_man/procon/pressed_button_helper.rb +1 -11
  42. data/lib/procon_bypass_man/procon/user_operation.rb +15 -4
  43. data/lib/procon_bypass_man/procon.rb +25 -5
  44. data/lib/procon_bypass_man/readonly_procon.rb +32 -0
  45. data/lib/procon_bypass_man/runner.rb +39 -48
  46. data/lib/procon_bypass_man/uptime.rb +15 -0
  47. data/lib/procon_bypass_man/version.rb +1 -1
  48. data/lib/procon_bypass_man.rb +26 -33
  49. data/project_template/README.md +3 -2
  50. data/project_template/app.rb +8 -6
  51. data/project_template/systemd_units/pbm.service +1 -1
  52. data/project_template/systemd_units/pbm_web.service +11 -0
  53. data/project_template/web.rb +16 -0
  54. data/sig/README.rb +4 -0
  55. data/sig/main.rbs +507 -0
  56. metadata +25 -5
  57. data/examples/practical/app.rb +0 -21
  58. data/examples/practical/setting.yml +0 -24
@@ -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)
11
+ end
12
+ end
13
+
@@ -0,0 +1,13 @@
1
+ require "procon_bypass_man/outbound/base"
2
+
3
+ class ProconBypassMan::PressedButtonsReporter < ProconBypassMan::Outbound::Base
4
+ PATH = "/api/pressed_buttons"
5
+
6
+ def self.report(body: )
7
+ Client.new(
8
+ path: PATH,
9
+ server: ProconBypassMan.config.internal_api_servers,
10
+ ).post(body: body)
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)
11
+ end
12
+ end
@@ -0,0 +1,31 @@
1
+ class ProconBypassMan::Procon::AnalogStick
2
+ attr_accessor :neutral_position
3
+ attr_accessor :bin_x, :bin_y
4
+
5
+ def initialize(binary: )
6
+ @neutral_position = ProconBypassMan::ButtonsSettingConfiguration.instance.neutral_position
7
+
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
+ self.bin_x = "#{byte7[4..7]}#{byte6}"
13
+ self.bin_y = "#{byte8}#{byte7[0..3]}"
14
+ end
15
+
16
+ def abs_x
17
+ bin_x.to_i(2)
18
+ end
19
+
20
+ def abs_y
21
+ bin_y.to_i(2)
22
+ end
23
+
24
+ def relative_x
25
+ bin_x.to_i(2) - neutral_position.x
26
+ end
27
+
28
+ def relative_y
29
+ bin_y.to_i(2) - neutral_position.y
30
+ end
31
+ end
@@ -0,0 +1,65 @@
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
+ def initialize(binary)
22
+ @binary = binary
23
+ @analog_stick = ProconBypassMan::Procon::AnalogStick.new(binary: binary)
24
+ end
25
+
26
+ # @return [ProconBypassMan::Procon::AnalogStickCap::Position]
27
+ def capped_position(cap_hypotenuse: )
28
+ if hypotenuse > cap_hypotenuse
29
+ relative_capped_x = cap_hypotenuse * Math.cos(rad * Math::PI / 180).abs
30
+ relative_capped_y = cap_hypotenuse * Math.sin(rad * Math::PI / 180).abs
31
+ relative_capped_x = -(relative_capped_x.abs) if relative_x.negative?
32
+ relative_capped_y = -(relative_capped_y.abs) if relative_y.negative?
33
+ return Position.new(
34
+ x: relative_capped_x + @analog_stick.neutral_position.x,
35
+ y: relative_capped_y + @analog_stick.neutral_position.y,
36
+ )
37
+ else
38
+ return position
39
+ end
40
+ end
41
+
42
+ # @return [ProconBypassMan::Procon::AnalogStickCap::Position]
43
+ def position
44
+ Position.new(x: abs_x, y: abs_y)
45
+ end
46
+
47
+ def abs_x; @analog_stick.abs_x; end # 0, 0からのx
48
+ def abs_y; @analog_stick.abs_y; end # 0, 0からのy
49
+ def relative_x; @analog_stick.relative_x; end
50
+ def relative_y; @analog_stick.relative_y; end
51
+
52
+ # @deprecated
53
+ def x; relative_x; end
54
+ def y; relative_y; end
55
+
56
+ def rad
57
+ (
58
+ Math.atan(relative_y / relative_x.to_f) * 180 / Math::PI
59
+ ).floor(6)
60
+ end
61
+
62
+ def hypotenuse
63
+ Math.sqrt(relative_x**2 + relative_y**2).floor(6)
64
+ end
65
+ 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,11 +29,15 @@ 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|
30
38
  next acc if value[1].nil?
31
39
  value[1].reverse.each.with_index do |button, index|
40
+ next(acc) if button == :grip || button == :_undefined_key
32
41
  acc[button] = { byte_position: value[0], bit_position: index }
33
42
  end
34
43
  acc
@@ -16,10 +16,10 @@ module ProconBypassMan::Procon::LayerChangeable
16
16
  end
17
17
 
18
18
  def change_layer?
19
- if ProconBypassMan::Configuration.instance.prefix_keys.empty?
19
+ if ProconBypassMan::ButtonsSettingConfiguration.instance.prefix_keys.empty?
20
20
  raise "prefix_keysが未設定です"
21
21
  end
22
- ProconBypassMan::Configuration.instance.prefix_keys.map { |b| pressed_button?(b) }.all?
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::Configuration.instance.macro_plugins = {}
40
+ ProconBypassMan::ButtonsSettingConfiguration.instance.macro_plugins = {}
41
41
  end
42
42
 
43
43
  def self.plugins
44
- ProconBypassMan::Configuration.instance.macro_plugins
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::Configuration.instance.mode_plugins = {}
38
+ ProconBypassMan::ButtonsSettingConfiguration.instance.mode_plugins = {}
39
39
  end
40
40
 
41
41
  def self.plugins
42
- ProconBypassMan::Configuration.instance.mode_plugins
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
- 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
-
1
+ module ProconBypassMan::Procon::PressedButtonHelper
12
2
  module Dynamic
13
3
  @@compiled = false
14
4
  def compile_if_not_compile_yet!
@@ -1,8 +1,7 @@
1
1
  class ProconBypassMan::Procon
2
2
  class UserOperation
3
3
  include LayerChangeable
4
- include PushedButtonHelper::Static
5
- extend PushedButtonHelper::Dynamic
4
+ extend PressedButtonHelper::Dynamic
6
5
 
7
6
  attr_reader :binary
8
7
 
@@ -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::Configuration.instance.layers[current_layer_key]
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) unless user_operation.pressed_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.pressed_button?(force_neutral_button) && user_operation.unpress_button(force_neutral_button)
125
+ user_operation.unpress_button(force_neutral_button)
112
126
  end
113
127
  end
114
128
  end
@@ -118,12 +132,18 @@ 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) unless user_operation.pressed_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
+ left_analog_stick = ProconBypassMan::ReadonlyProcon.new(binary: b).left_analog_stick
143
+ ProconBypassMan.logger.debug "x: #{left_analog_stick[:x]}, val: #{left_analog_stick[:x].to_s(2)}"
144
+ ProconBypassMan.logger.debug "y: #{left_analog_stick[:y]}, val: #{left_analog_stick[:y].to_s(2)}"
145
+ end
146
+ b
127
147
  end
128
148
 
129
149
  private
@@ -0,0 +1,32 @@
1
+ # read
2
+ class ProconBypassMan::ReadonlyProcon
3
+ def initialize(binary: )
4
+ @binary = binary
5
+ @user_operation = ProconBypassMan::Procon::UserOperation.new(binary.dup)
6
+ @analog_stick = ProconBypassMan::Procon::AnalogStick.new(binary: binary)
7
+ end
8
+
9
+ # @return [Array<Symbol>]
10
+ def pressed
11
+ pressed_table = ::ProconBypassMan::Procon::ButtonCollection::BUTTONS.reduce({}) do |acc, button|
12
+ acc[button] = @user_operation.pressed_button?(button)
13
+ acc
14
+ end
15
+ pressed_table.select { |_key, value| value }.keys
16
+ end
17
+
18
+ def left_analog_stick
19
+ { x: @analog_stick.relative_x, y: @analog_stick.relative_y }
20
+ end
21
+
22
+ def left_analog_stick_by_abs
23
+ { x: @analog_stick.abs_x, y: @analog_stick.abs_y }
24
+ end
25
+
26
+ def to_hash
27
+ { left_analog_stick: left_analog_stick,
28
+ left_analog_stick_by_abs: left_analog_stick_by_abs,
29
+ buttons: pressed,
30
+ }
31
+ end
32
+ end
@@ -1,13 +1,11 @@
1
1
  require_relative "io_monitor"
2
+ require_relative "uptime"
3
+ require_relative "boot_message"
4
+ require_relative "background/report_thread"
2
5
 
3
6
  class ProconBypassMan::Runner
4
7
  class InterruptForRestart < StandardError; end
5
8
 
6
- def initialize
7
- $will_interval_0_0_0_5 = 0
8
- $will_interval_1_6 = 0
9
- end
10
-
11
9
  def run
12
10
  first_negotiation
13
11
  print_booted_message
@@ -38,7 +36,7 @@ class ProconBypassMan::Runner
38
36
  Process.wait
39
37
  ProconBypassMan.logger.info("Reloading config file")
40
38
  begin
41
- ProconBypassMan::Configuration::Loader.reload_setting
39
+ ProconBypassMan::ButtonsSettingConfiguration::Loader.reload_setting
42
40
  puts "設定ファイルの再読み込みができました"
43
41
  rescue ProconBypassMan::CouldNotLoadConfigError
44
42
  ProconBypassMan.logger.error "設定ファイルが不正です。再読み込みができませんでした"
@@ -60,31 +58,36 @@ class ProconBypassMan::Runner
60
58
  private
61
59
 
62
60
  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
61
  ProconBypassMan::IOMonitor.start!
62
+ ProconBypassMan::Background::Reporter.start!
63
+
71
64
  # gadget => procon
72
65
  # 遅くていい
73
66
  monitor1 = ProconBypassMan::IOMonitor.new(label: "switch -> procon")
74
67
  monitor2 = ProconBypassMan::IOMonitor.new(label: "procon -> switch")
75
68
  ProconBypassMan.logger.info "Thread1を起動します"
76
69
  t1 = Thread.new do
70
+ timer = ProconBypassMan::Timer.new(timeout: Time.now + 10)
77
71
  bypass = ProconBypassMan::Bypass.new(gadget: @gadget, procon: @procon, monitor: monitor1)
78
- begin
79
- loop do
80
- break if $will_terminate_token
81
- bypass.send_gadget_to_procon!
82
- rescue Errno::EIO, Errno::ENODEV, Errno::EPROTO, IOError => e
83
- ProconBypassMan.logger.error "Proconが切断されました.終了処理を開始します"
84
- Process.kill "TERM", Process.ppid
85
- end
86
- ProconBypassMan.logger.info "Thread1を終了します"
72
+ loop do
73
+ break if $will_terminate_token
74
+ timer.throw_if_timeout!
75
+ bypass.send_gadget_to_procon!
76
+ sleep(0.005)
77
+ rescue ProconBypassMan::Timer::Timeout
78
+ ProconBypassMan.logger.info "10秒経過したのでThread1を終了します"
79
+ puts "10秒経過したのでThread1を終了します"
80
+ break
81
+ rescue Errno::EIO, Errno::ENODEV, Errno::EPROTO, IOError => e
82
+ ProconBypassMan.logger.error "Proconが切断されました.終了処理を開始します"
83
+ Process.kill "TERM", Process.ppid
84
+ rescue Errno::ETIMEDOUT => e
85
+ # TODO まれにこれが発生する. 再接続したい
86
+ ProconBypassMan::ErrorReporter.report(body: e)
87
+ ProconBypassMan.logger.error "Switchとの切断されました.終了処理を開始します"
88
+ Process.kill "TERM", Process.ppid
87
89
  end
90
+ ProconBypassMan.logger.info "Thread1を終了します"
88
91
  end
89
92
 
90
93
  # procon => gadget
@@ -92,19 +95,17 @@ class ProconBypassMan::Runner
92
95
  ProconBypassMan.logger.info "Thread2を起動します"
93
96
  t2 = Thread.new do
94
97
  bypass = ProconBypassMan::Bypass.new(gadget: @gadget, procon: @procon, monitor: monitor2)
95
- begin
96
- loop do
97
- break if $will_terminate_token
98
- bypass.send_procon_to_gadget!
99
- rescue EOFError => e
100
- ProconBypassMan.logger.error "Proconと通信ができませんでした.終了処理を開始します"
101
- Process.kill "TERM", Process.ppid
102
- rescue Errno::EIO, Errno::ENODEV, Errno::EPROTO, IOError => e
103
- ProconBypassMan.logger.error "Proconが切断されました。終了処理を開始します"
104
- Process.kill "TERM", Process.ppid
105
- end
106
- ProconBypassMan.logger.info "Thread2を終了します"
98
+ loop do
99
+ break if $will_terminate_token
100
+ bypass.send_procon_to_gadget!
101
+ rescue EOFError => e
102
+ ProconBypassMan.logger.error "Proconと通信ができませんでした.終了処理を開始します"
103
+ Process.kill "TERM", Process.ppid
104
+ rescue Errno::EIO, Errno::ENODEV, Errno::EPROTO, IOError => e
105
+ ProconBypassMan.logger.error "Proconが切断されました。終了処理を開始します"
106
+ Process.kill "TERM", Process.ppid
107
107
  end
108
+ ProconBypassMan.logger.info "Thread2を終了します"
108
109
  end
109
110
 
110
111
  self_read, self_write = IO.pipe
@@ -134,8 +135,6 @@ class ProconBypassMan::Runner
134
135
  end
135
136
 
136
137
  def first_negotiation
137
- return if $will_terminate_token
138
-
139
138
  @gadget, @procon = ProconBypassMan::DeviceConnector.connect
140
139
  rescue ProconBypassMan::Timer::Timeout
141
140
  ::ProconBypassMan.logger.error "デバイスとの通信でタイムアウトが起きて接続ができませんでした。"
@@ -156,17 +155,9 @@ class ProconBypassMan::Runner
156
155
 
157
156
  # @return [void]
158
157
  def print_booted_message
159
- booted_message = <<~EOF
160
- ----
161
- RUBY_VERSION: #{RUBY_VERSION}
162
- ProconBypassMan: #{ProconBypassMan::VERSION}
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
158
+ message = ProconBypassMan::BootMessage.new
159
+ ProconBypassMan.logger.info(message.to_s)
160
+ Thread.new { ProconBypassMan::Reporter.report(body: message.to_hash) }
161
+ puts message.to_s
171
162
  end
172
163
  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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ProconBypassMan
4
- VERSION = "0.1.7"
4
+ VERSION = "0.1.11"
5
5
  end