flic 0.0.1 → 0.0.2
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/lib/flic.rb +2 -1
- data/lib/flic/callbacks.rb +36 -0
- data/lib/flic/client.rb +52 -203
- data/lib/flic/client/connection_channel.rb +21 -0
- data/lib/flic/client/features.rb +15 -0
- data/lib/flic/client/features/connection_channel.rb +175 -0
- data/lib/flic/client/features/force_disconnect.rb +13 -0
- data/lib/flic/client/features/get_button_uuid.rb +43 -0
- data/lib/flic/client/features/get_info.rb +52 -0
- data/lib/flic/client/features/ping.rb +55 -0
- data/lib/flic/client/features/scan.rb +112 -0
- data/lib/flic/client/features/scan_wizard.rb +131 -0
- data/lib/flic/client/scan_wizard.rb +14 -0
- data/lib/flic/client/scanner.rb +12 -0
- data/lib/flic/client/server_info.rb +16 -0
- data/lib/flic/protocol.rb +1 -0
- data/lib/flic/protocol/commands/change_mode_parameters.rb +3 -2
- data/lib/flic/protocol/commands/create_connection_channel.rb +3 -2
- data/lib/flic/protocol/commands/remove_connection_channel.rb +1 -1
- data/lib/flic/{client → protocol}/connection.rb +20 -26
- data/lib/flic/protocol/events/button_click_or_hold.rb +1 -1
- data/lib/flic/protocol/events/button_single_or_double_click.rb +1 -1
- data/lib/flic/protocol/events/button_single_or_double_click_or_hold.rb +1 -1
- data/lib/flic/protocol/events/button_up_or_down.rb +1 -1
- data/lib/flic/protocol/events/connection_channel_removed.rb +2 -2
- data/lib/flic/protocol/events/connection_status_changed.rb +1 -1
- data/lib/flic/protocol/events/create_connection_channel_response.rb +1 -1
- data/lib/flic/protocol/events/get_info_response.rb +3 -2
- data/lib/flic/protocol/primitives.rb +1 -0
- data/lib/flic/protocol/primitives/disconnect_time.rb +29 -0
- data/lib/flic/simple_client.rb +116 -0
- data/lib/flic/version.rb +1 -1
- metadata +18 -6
- data/lib/flic/event_bus.rb +0 -81
- data/lib/flic/event_bus/driver.rb +0 -23
- data/lib/flic/event_bus/subscription.rb +0 -66
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c7e0c99f004d000f1ed0b0296403fbc8e723a4a
|
4
|
+
data.tar.gz: d48a0bb111640992b77d6bac24f3cdd2e70b2b79
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fccb7b55b186dbae110a268d78682ae2cc1213b7fc3f0883f08c1fc330549c44b61e868a4a17c8b859e11688cefcc1fa3834cd34932316da3ac5def7135f7796
|
7
|
+
data.tar.gz: 2181c732b2ad6340fc12bd4865de9d2da1dea2e2118b4c09dc2ee9fa5a1d221ee88299609ab2495cb20c665e19d8d3b5618831f3fcaf71be95554ee240bb04fd
|
data/lib/flic.rb
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'flic'
|
2
|
+
|
3
|
+
require 'thread'
|
4
|
+
|
5
|
+
module Flic
|
6
|
+
module Callbacks
|
7
|
+
SEMAPHORE = Mutex.new
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def define_callbacks(*callback_names)
|
12
|
+
callback_names.each do |callback_name|
|
13
|
+
semaphore_instance_variable = :"@#{callback_name}_callbacks_semaphore"
|
14
|
+
callbacks_instance_variable = :"@#{callback_name}_callbacks"
|
15
|
+
|
16
|
+
define_method :"#{callback_name}" do |*args, &callback|
|
17
|
+
semaphore = SEMAPHORE.synchronize do
|
18
|
+
instance_variable_get(semaphore_instance_variable) ||
|
19
|
+
instance_variable_set(semaphore_instance_variable, Mutex.new)
|
20
|
+
end
|
21
|
+
|
22
|
+
semaphore.synchronize do
|
23
|
+
callbacks = instance_variable_get(callbacks_instance_variable) ||
|
24
|
+
instance_variable_set(callbacks_instance_variable, [])
|
25
|
+
|
26
|
+
if callback
|
27
|
+
callbacks << callback
|
28
|
+
else
|
29
|
+
callbacks.each { |callback| callback.call *args }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/flic/client.rb
CHANGED
@@ -1,14 +1,29 @@
|
|
1
1
|
require 'flic'
|
2
|
-
|
3
|
-
require '
|
2
|
+
|
3
|
+
require 'thread'
|
4
|
+
require 'socket'
|
4
5
|
|
5
6
|
module Flic
|
6
7
|
class Client
|
7
|
-
autoload :Connection, 'flic/client/connection'
|
8
|
-
|
9
8
|
class Error < StandardError; end
|
10
9
|
class ClientShutdownError < Error; end
|
11
10
|
|
11
|
+
autoload :ConnectionChannel, 'flic/client/connection_channel'
|
12
|
+
autoload :Features, 'flic/client/features'
|
13
|
+
autoload :ScanWizard, 'flic/client/scan_wizard'
|
14
|
+
autoload :Scanner, 'flic/client/scanner'
|
15
|
+
autoload :ServerInfo, 'flic/client/server_info'
|
16
|
+
|
17
|
+
extend Callbacks
|
18
|
+
|
19
|
+
prepend Features::ConnectionChannel
|
20
|
+
prepend Features::ForceDisconnect
|
21
|
+
prepend Features::GetButtonUuid
|
22
|
+
prepend Features::GetInfo
|
23
|
+
prepend Features::Ping
|
24
|
+
prepend Features::Scan
|
25
|
+
prepend Features::ScanWizard
|
26
|
+
|
12
27
|
class << self
|
13
28
|
def open(*args)
|
14
29
|
client = new(*args)
|
@@ -21,227 +36,61 @@ module Flic
|
|
21
36
|
end
|
22
37
|
end
|
23
38
|
|
24
|
-
attr_reader :
|
39
|
+
attr_reader :host, :port, :socket, :connection
|
25
40
|
|
26
|
-
|
27
|
-
|
41
|
+
define_callbacks :new_button_verified, :bluetooth_controller_state_changed,
|
42
|
+
:connections_exhausted, :connection_available
|
28
43
|
|
29
|
-
@driver = EventBus::Driver.new do |event_bus|
|
30
|
-
begin
|
31
|
-
connection.listen do |event|
|
32
|
-
event_bus.broadcast(event)
|
33
|
-
end
|
34
|
-
rescue Connection::ConnectionClosedError
|
35
|
-
nil
|
36
|
-
rescue Protocol::Error => protocol_error
|
37
|
-
warn protocol_error
|
38
|
-
|
39
|
-
retry
|
40
|
-
end
|
41
|
-
end
|
42
44
|
|
45
|
+
def initialize(host = 'localhost', port = 5551)
|
46
|
+
@host, @port = host, port
|
47
|
+
@handle_next_event_semaphore = Mutex.new
|
48
|
+
@socket = TCPSocket.new(host, port)
|
49
|
+
@connection = Protocol::Connection.new(socket)
|
43
50
|
yield self if block_given?
|
44
51
|
end
|
45
52
|
|
46
|
-
def hostname
|
47
|
-
connection.hostname
|
48
|
-
end
|
49
|
-
|
50
|
-
def port
|
51
|
-
connection.port
|
52
|
-
end
|
53
|
-
|
54
|
-
def shutdown?
|
55
|
-
connection.closed?
|
56
|
-
end
|
57
|
-
|
58
53
|
def shutdown
|
59
54
|
connection.close
|
60
55
|
end
|
61
56
|
|
62
|
-
def
|
63
|
-
|
64
|
-
Protocol::Events::PingResponse === event &&
|
65
|
-
event.ping_id == ping_id
|
66
|
-
end
|
67
|
-
|
68
|
-
true
|
69
|
-
end
|
70
|
-
|
71
|
-
def server_info
|
72
|
-
request Protocol::Commands::GetInfo, Protocol::Events::GetInfoResponse
|
73
|
-
end
|
74
|
-
|
75
|
-
def button_uuid(bluetooth_address)
|
76
|
-
command = Protocol::Commands::GetButtonUuid.new(bluetooth_address: bluetooth_address)
|
77
|
-
|
78
|
-
response = request command do |event|
|
79
|
-
Protocol::Events::GetButtonUuidResponse === event &&
|
80
|
-
event.bluetooth_address == command.bluetooth_address
|
81
|
-
end
|
82
|
-
|
83
|
-
unless response.uuid == Protocol::INVALID_BUTTON_UUID
|
84
|
-
response.uuid
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
def buttons
|
89
|
-
server_info.verified_buttons
|
90
|
-
end
|
91
|
-
|
92
|
-
def disconnect_button(bluetooth_address)
|
93
|
-
send_command Protocol::Commands::ForceDisconnect.new(bluetooth_address: bluetooth_address)
|
94
|
-
end
|
95
|
-
|
96
|
-
def connect_button
|
97
|
-
bluetooth_address = nil
|
98
|
-
|
99
|
-
result = scan_wizard do |button_type, _bluetooth_address|
|
100
|
-
bluetooth_address = _bluetooth_address if button_type == :public
|
101
|
-
end
|
102
|
-
|
103
|
-
bluetooth_address if result == :success
|
104
|
-
end
|
105
|
-
|
106
|
-
def scan(scan_id = rand(2**32))
|
107
|
-
subscribe do |subscription|
|
108
|
-
send_command Protocol::Commands::CreateScanner.new(scan_id: scan_id)
|
109
|
-
|
110
|
-
begin
|
111
|
-
subscription.listen do |event|
|
112
|
-
if Protocol::Events::AdvertisementPacket === event && event.scan_id == scan_id
|
113
|
-
yield event.bluetooth_address, event.name, event.rssi, event.is_private, event.is_already_verified
|
114
|
-
end
|
115
|
-
end
|
116
|
-
ensure
|
117
|
-
send_command Protocol::Commands::RemoveScanner.new(scan_id: scan_id)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
def scan_wizard(scan_wizard_id = rand(2**32))
|
123
|
-
subscribe do |subscription|
|
124
|
-
send_command Protocol::Commands::CreateScanWizard.new(scan_wizard_id: scan_wizard_id)
|
125
|
-
|
57
|
+
def handle_next_event
|
58
|
+
@handle_next_event_semaphore.synchronize do
|
126
59
|
begin
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
result = subscription.listen do |event|
|
131
|
-
case event
|
132
|
-
when Protocol::Events::ScanWizardFoundPrivateButton
|
133
|
-
yield :private, nil, nil
|
134
|
-
when Protocol::Events::ScanWizardFoundPublicButton
|
135
|
-
bluetooth_address, name = event.bluetooth_address, event.name
|
136
|
-
when Protocol::Events::ScanWizardButtonConnected
|
137
|
-
yield :public, bluetooth_address, name
|
138
|
-
when Protocol::Events::ScanWizardCompleted
|
139
|
-
break event.scan_wizard_result
|
140
|
-
end
|
141
|
-
end
|
142
|
-
ensure
|
143
|
-
send_command Protocol::Commands::CancelScanWizard.new(scan_wizard_id: scan_wizard_id) unless result
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
def channel(bluetooth_address, latency_mode = :normal, auto_disconnect_time = nil, connection_id = rand(2**32))
|
149
|
-
auto_disconnect_time = 512 unless auto_disconnect_time # 512 means disabled
|
150
|
-
|
151
|
-
subscribe do |subscription|
|
152
|
-
send_command Protocol::Commands::CreateConnectionChannel.new(
|
153
|
-
connection_id: connection_id,
|
154
|
-
bluetooth_address: bluetooth_address,
|
155
|
-
latency_mode: latency_mode,
|
156
|
-
auto_disconnect_time: auto_disconnect_time
|
157
|
-
)
|
60
|
+
handle_event connection.recv_event
|
61
|
+
rescue Protocol::Connection::ConnectionClosedError
|
62
|
+
shutdown
|
158
63
|
|
159
|
-
|
160
|
-
|
161
|
-
begin
|
162
|
-
subscription.listen do |event|
|
163
|
-
case event
|
164
|
-
when Protocol::Events::ButtonSingleOrDoubleClickOrHold
|
165
|
-
yield bluetooth_address, event.click_type, event.time_difference
|
166
|
-
when Protocol::Events::ConnectionChannelRemoved
|
167
|
-
is_removed = true
|
168
|
-
break
|
169
|
-
end
|
170
|
-
end
|
171
|
-
ensure
|
172
|
-
send_command Protocol::Commands::RemoveConnectionChannel.new(connection_id: connection_id) unless is_removed
|
64
|
+
raise ClientShutdownError, 'The connection has been closed'
|
173
65
|
end
|
174
66
|
end
|
175
67
|
end
|
176
68
|
|
177
|
-
def
|
178
|
-
|
179
|
-
connection_id_bluetooth_address = {}
|
180
|
-
|
181
|
-
begin
|
182
|
-
bluetooth_addresses.each do |bluetooth_address|
|
183
|
-
connection_id = rand(2**32)
|
184
|
-
|
185
|
-
send_command Protocol::Commands::CreateConnectionChannel.new(
|
186
|
-
connection_id: connection_id,
|
187
|
-
bluetooth_address: bluetooth_address,
|
188
|
-
latency_mode: :normal,
|
189
|
-
auto_disconnect_time: 512
|
190
|
-
)
|
191
|
-
|
192
|
-
connection_id_bluetooth_address[connection_id] = bluetooth_address
|
193
|
-
end
|
194
|
-
|
195
|
-
subscription.listen do |event|
|
196
|
-
case event
|
197
|
-
when Protocol::Events::ButtonSingleOrDoubleClickOrHold
|
198
|
-
bluetooth_address = connection_id_bluetooth_address[event.connection_id]
|
199
|
-
yield bluetooth_address, event.click_type, event.time_difference
|
200
|
-
when Protocol::Events::ConnectionChannelRemoved
|
201
|
-
bluetooth_address = connection_id_bluetooth_address[event.connection_id]
|
202
|
-
connection_id_bluetooth_address.delete event.connection_id
|
203
|
-
raise "connection to #{bluetooth_address} was removed"
|
204
|
-
end
|
205
|
-
end
|
206
|
-
ensure
|
207
|
-
connection_id_bluetooth_address.each do |connection_id, _|
|
208
|
-
send_command Protocol::Commands::RemoveConnectionChannel.new(
|
209
|
-
connection_id: connection_id
|
210
|
-
)
|
211
|
-
end
|
212
|
-
end
|
213
|
-
end
|
69
|
+
def enter_main_loop
|
70
|
+
loop { handle_next_event }
|
214
71
|
end
|
215
72
|
|
216
73
|
private
|
217
74
|
|
218
|
-
def event_bus
|
219
|
-
@event_bus ||= driver.event_bus
|
220
|
-
end
|
221
|
-
|
222
75
|
def send_command(command)
|
223
|
-
command = command.new if Class === command
|
224
76
|
connection.send_command(command)
|
225
|
-
rescue
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
break event
|
242
|
-
end
|
243
|
-
end
|
77
|
+
rescue Protocol::Connection::ConnectionClosedError
|
78
|
+
shutdown
|
79
|
+
|
80
|
+
raise ClientShutdownError, 'The connection has been closed'
|
81
|
+
end
|
82
|
+
|
83
|
+
def handle_event(event)
|
84
|
+
case event
|
85
|
+
when Protocol::Events::NewVerifiedButton
|
86
|
+
new_button_verified event.bluetooth_address
|
87
|
+
when Protocol::Events::BluetoothControllerStateChange
|
88
|
+
bluetooth_controller_state_changed event.bluetooth_controller_state
|
89
|
+
when Protocol::Events::NoSpaceForNewConnection
|
90
|
+
connections_exhausted
|
91
|
+
when Protocol::Events::GotSpaceForNewConnection
|
92
|
+
connection_available
|
244
93
|
end
|
245
94
|
end
|
246
95
|
end
|
247
|
-
end
|
96
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'flic/client'
|
2
|
+
|
3
|
+
module Flic
|
4
|
+
class Client
|
5
|
+
class ConnectionChannel
|
6
|
+
extend Callbacks
|
7
|
+
|
8
|
+
attr_reader :button_bluetooth_address, :latency_mode, :auto_disconnect_time
|
9
|
+
attr_accessor :status
|
10
|
+
|
11
|
+
define_callbacks :added, :removed, :failed_to_add, :status_changed,
|
12
|
+
:button_up_or_down, :button_click_or_hold,
|
13
|
+
:button_single_click_or_double_click, :button_single_click_or_double_click_or_hold
|
14
|
+
|
15
|
+
def initialize(button_bluetooth_address, latency_mode, auto_disconnect_time = nil)
|
16
|
+
@button_bluetooth_address, @latency_mode, @auto_disconnect_time = button_bluetooth_address, latency_mode, auto_disconnect_time
|
17
|
+
@status = :disconnected
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'flic/client'
|
2
|
+
|
3
|
+
module Flic
|
4
|
+
class Client
|
5
|
+
module Features
|
6
|
+
autoload :ConnectionChannel, 'flic/client/features/connection_channel'
|
7
|
+
autoload :ForceDisconnect, 'flic/client/features/force_disconnect'
|
8
|
+
autoload :GetButtonUuid, 'flic/client/features/get_button_uuid'
|
9
|
+
autoload :GetInfo, 'flic/client/features/get_info'
|
10
|
+
autoload :Ping, 'flic/client/features/ping'
|
11
|
+
autoload :Scan, 'flic/client/features/scan'
|
12
|
+
autoload :ScanWizard, 'flic/client/features/scan_wizard'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
require 'flic/client/features'
|
2
|
+
|
3
|
+
require 'thread'
|
4
|
+
|
5
|
+
module Flic
|
6
|
+
class Client
|
7
|
+
module Features
|
8
|
+
module ConnectionChannel
|
9
|
+
def initialize(*)
|
10
|
+
@connection_channel_id_connection_channel_semaphore = Mutex.new
|
11
|
+
@connection_channel_id_connection_channel = {}
|
12
|
+
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def connection_channels
|
17
|
+
@connection_channel_id_connection_channel_semaphore.synchronize { @connection_channel_id_connection_channel.values }
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_connection_channel(connection_channel)
|
21
|
+
connection_channel_id = _add_connection_channel(connection_channel)
|
22
|
+
|
23
|
+
if connection_channel_id
|
24
|
+
send_command Protocol::Commands::CreateConnectionChannel.new(
|
25
|
+
connection_channel_id: connection_channel_id,
|
26
|
+
bluetooth_address: connection_channel.button_bluetooth_address,
|
27
|
+
latency_mode: connection_channel.latency_mode,
|
28
|
+
auto_disconnect_time: connection_channel.auto_disconnect_time
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def remove_connection_channel(connection_channel)
|
34
|
+
connection_channel_id = find_connection_channel_id_by_connection_channel(connection_channel)
|
35
|
+
|
36
|
+
if connection_channel_id
|
37
|
+
send_command Protocol::Commands::RemoveConnectionChannel.new(
|
38
|
+
connection_channel_id: connection_channel_id
|
39
|
+
)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def shutdown(*)
|
44
|
+
connection_channels.each do |connection_channel|
|
45
|
+
_remove_connection_channel(connection_channel)
|
46
|
+
connection_channel.removed self
|
47
|
+
end
|
48
|
+
|
49
|
+
super
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def handle_event(event)
|
55
|
+
case event
|
56
|
+
when Protocol::Events::CreateConnectionChannelResponse
|
57
|
+
connection_channel = find_connection_channel_by_connection_channel_id(event.connection_channel_id)
|
58
|
+
|
59
|
+
if connection_channel
|
60
|
+
if event.error == :no_error
|
61
|
+
connection_channel.added self
|
62
|
+
else
|
63
|
+
_remove_connection_channel(connection_channel)
|
64
|
+
connection_channel.failed_to_add self, event.error
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
when Protocol::Events::ConnectionStatusChanged
|
69
|
+
connection_channel = find_connection_channel_by_connection_channel_id(event.connection_channel_id)
|
70
|
+
|
71
|
+
if connection_channel
|
72
|
+
connection_channel.status = event.connection_status
|
73
|
+
connection_channel.status_changed event.connection_status
|
74
|
+
end
|
75
|
+
|
76
|
+
when Protocol::Events::ButtonUpOrDown
|
77
|
+
connection_channel = find_connection_channel_by_connection_channel_id(event.connection_channel_id)
|
78
|
+
|
79
|
+
if connection_channel
|
80
|
+
connection_channel.button_up_or_down event.click_type, event.time_difference, event.was_queued
|
81
|
+
end
|
82
|
+
when Protocol::Events::ButtonClickOrHold
|
83
|
+
connection_channel = find_connection_channel_by_connection_channel_id(event.connection_channel_id)
|
84
|
+
|
85
|
+
if connection_channel
|
86
|
+
connection_channel.button_click_or_hold event.click_type, event.time_difference, event.was_queued
|
87
|
+
end
|
88
|
+
|
89
|
+
when Protocol::Events::ButtonSingleOrDoubleClick
|
90
|
+
connection_channel = find_connection_channel_by_connection_channel_id(event.connection_channel_id)
|
91
|
+
|
92
|
+
if connection_channel
|
93
|
+
connection_channel.button_single_click_or_double_click event.click_type, event.time_difference, event.was_queued
|
94
|
+
end
|
95
|
+
|
96
|
+
when Protocol::Events::ButtonSingleOrDoubleClickOrHold
|
97
|
+
connection_channel = find_connection_channel_by_connection_channel_id(event.connection_channel_id)
|
98
|
+
|
99
|
+
if connection_channel
|
100
|
+
connection_channel.button_single_click_or_double_click_or_hold event.click_type, event.time_difference, event.was_queued
|
101
|
+
end
|
102
|
+
|
103
|
+
when Protocol::Events::ConnectionChannelRemoved
|
104
|
+
connection_channel = find_connection_channel_by_connection_channel_id(event.connection_channel_id)
|
105
|
+
|
106
|
+
if connection_channel
|
107
|
+
_remove_connection_channel(connection_channel)
|
108
|
+
connection_channel.removed self, event.reason
|
109
|
+
end
|
110
|
+
|
111
|
+
else
|
112
|
+
super
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def find_connection_channel_by_connection_channel_id(needle)
|
117
|
+
@connection_channel_id_connection_channel_semaphore.synchronize do
|
118
|
+
@connection_channel_id_connection_channel.each do |connection_channel_id, connection_channel|
|
119
|
+
return connection_channel if connection_channel_id == needle
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
nil
|
124
|
+
end
|
125
|
+
|
126
|
+
def find_connection_channel_id_by_connection_channel(needle)
|
127
|
+
@connection_channel_id_connection_channel_semaphore.synchronize do
|
128
|
+
@connection_channel_id_connection_channel.each do |connection_channel_id, connection_channel|
|
129
|
+
return connection_channel_id if connection_channel == needle
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
nil
|
134
|
+
end
|
135
|
+
|
136
|
+
def _add_connection_channel(connection_channel)
|
137
|
+
connection_channel_id = nil
|
138
|
+
|
139
|
+
@connection_channel_id_connection_channel_semaphore.synchronize do
|
140
|
+
unless @connection_channel_id_connection_channel.values.include?(connection_channel)
|
141
|
+
loop do
|
142
|
+
connection_channel_id = rand(2**32)
|
143
|
+
|
144
|
+
break unless @connection_channel_id_connection_channel.has_key?(connection_channel_id)
|
145
|
+
end
|
146
|
+
|
147
|
+
@connection_channel_id_connection_channel[connection_channel_id] = connection_channel
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
connection_channel_id
|
152
|
+
end
|
153
|
+
|
154
|
+
def _remove_connection_channel(connection_channel)
|
155
|
+
connection_channel_id = nil
|
156
|
+
|
157
|
+
@connection_channel_id_connection_channel_semaphore.synchronize do
|
158
|
+
if @connection_channel_id_connection_channel.values.include?(connection_channel)
|
159
|
+
@connection_channel_id_connection_channel.each do |_connection_channel_id, _connection_channel|
|
160
|
+
if connection_channel == _connection_channel
|
161
|
+
connection_channel_id = _connection_channel_id
|
162
|
+
break
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
@connection_channel_id_connection_channel.delete connection_channel_id if connection_channel_id
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
connection_channel_id
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|