procon_bypass_man 0.1.6 → 0.1.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +41 -16
  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 +57 -6
  10. data/README.md +18 -10
  11. data/Rakefile +10 -1
  12. data/Steepfile +39 -0
  13. data/bin/report_receive_server.rb +11 -0
  14. data/docs/setup_raspi.md +12 -7
  15. data/docs/setup_raspi.mitamae.rb +60 -0
  16. data/docs/setup_raspi_by_mitamae.md +14 -0
  17. data/lib/procon_bypass_man/analog_stick_position.rb +8 -0
  18. data/lib/procon_bypass_man/boot_message.rb +40 -0
  19. data/lib/procon_bypass_man/buttons_setting_configuration.rb +100 -0
  20. data/lib/procon_bypass_man/bypass/usb_hid_logger.rb +20 -0
  21. data/lib/procon_bypass_man/bypass.rb +61 -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 +68 -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 +40 -0
  31. data/lib/procon_bypass_man/outbound/error_reporter.rb +13 -0
  32. data/lib/procon_bypass_man/outbound/reporter.rb +12 -0
  33. data/lib/procon_bypass_man/outbound/usb_hid_data_reporter.rb +13 -0
  34. data/lib/procon_bypass_man/procon/analog_stick_cap.rb +88 -0
  35. data/lib/procon_bypass_man/procon/button_collection.rb +14 -6
  36. data/lib/procon_bypass_man/procon/debug_dumper.rb +17 -0
  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 +0 -10
  42. data/lib/procon_bypass_man/procon/user_operation.rb +14 -3
  43. data/lib/procon_bypass_man/procon.rb +23 -5
  44. data/lib/procon_bypass_man/runner.rb +36 -48
  45. data/lib/procon_bypass_man/uptime.rb +15 -0
  46. data/lib/procon_bypass_man/version.rb +1 -1
  47. data/lib/procon_bypass_man.rb +26 -33
  48. data/project_template/README.md +17 -0
  49. data/project_template/app.rb +20 -0
  50. data/project_template/setting.yml +35 -0
  51. data/project_template/systemd_units/pbm.service +13 -0
  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 +30 -5
  57. data/examples/pbm.service +0 -27
  58. 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::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
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::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,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) 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
+ 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::Configuration::Loader.reload_setting
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
- 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を終了します"
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
- 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を終了します"
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
- 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
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ProconBypassMan
4
- VERSION = "0.1.6"
4
+ VERSION = "0.1.10"
5
5
  end