flic 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +51 -49
- data/Rakefile +6 -1
- data/flic.gemspec +1 -0
- data/lib/flic.rb +1 -0
- data/lib/flic/blocker.rb +59 -0
- data/lib/flic/client.rb +12 -7
- data/lib/flic/client/scan_wizard.rb +4 -0
- data/lib/flic/protocol.rb +20 -6
- data/lib/flic/protocol/commands.rb +7 -0
- data/lib/flic/protocol/commands/cancel_scan_wizard.rb +1 -3
- data/lib/flic/protocol/commands/change_mode_parameters.rb +1 -3
- data/lib/flic/protocol/commands/command.rb +10 -4
- data/lib/flic/protocol/commands/create_connection_channel.rb +1 -3
- data/lib/flic/protocol/commands/create_scan_wizard.rb +1 -3
- data/lib/flic/protocol/commands/create_scanner.rb +1 -3
- data/lib/flic/protocol/commands/force_disconnect.rb +0 -2
- data/lib/flic/protocol/commands/get_button_uuid.rb +0 -2
- data/lib/flic/protocol/commands/get_info.rb +0 -1
- data/lib/flic/protocol/commands/ping.rb +1 -3
- data/lib/flic/protocol/commands/remove_connection_channel.rb +1 -3
- data/lib/flic/protocol/commands/remove_scanner.rb +1 -3
- data/lib/flic/protocol/connection.rb +22 -19
- data/lib/flic/protocol/events.rb +9 -2
- data/lib/flic/protocol/events/advertisement_packet.rb +2 -4
- data/lib/flic/protocol/events/bluetooth_controller_state_change.rb +0 -2
- data/lib/flic/protocol/events/button_click_or_hold.rb +2 -4
- data/lib/flic/protocol/events/button_single_or_double_click.rb +2 -4
- data/lib/flic/protocol/events/button_single_or_double_click_or_hold.rb +2 -4
- data/lib/flic/protocol/events/button_up_or_down.rb +2 -4
- data/lib/flic/protocol/events/connection_channel_removed.rb +1 -3
- data/lib/flic/protocol/events/connection_status_changed.rb +1 -3
- data/lib/flic/protocol/events/create_connection_channel_response.rb +1 -3
- data/lib/flic/protocol/events/event.rb +11 -5
- data/lib/flic/protocol/events/get_button_uuid_response.rb +0 -2
- data/lib/flic/protocol/events/get_info_response.rb +4 -6
- data/lib/flic/protocol/events/got_space_for_new_connection.rb +1 -3
- data/lib/flic/protocol/events/new_verified_button.rb +0 -2
- data/lib/flic/protocol/events/no_space_for_new_connection.rb +1 -3
- data/lib/flic/protocol/events/ping_response.rb +1 -3
- data/lib/flic/protocol/events/scan_wizard_button_connected.rb +1 -3
- data/lib/flic/protocol/events/scan_wizard_completed.rb +1 -3
- data/lib/flic/protocol/events/scan_wizard_found_private_button.rb +1 -3
- data/lib/flic/protocol/events/scan_wizard_found_public_button.rb +1 -3
- data/lib/flic/protocol/packet_header.rb +2 -2
- data/lib/flic/protocol/primitives.rb +1 -0
- data/lib/flic/protocol/primitives/bluetooth_address.rb +2 -1
- data/lib/flic/protocol/primitives/bluetooth_address_type.rb +3 -0
- data/lib/flic/protocol/primitives/bluetooth_controller_state.rb +7 -3
- data/lib/flic/protocol/primitives/boolean.rb +1 -0
- data/lib/flic/protocol/primitives/click_type.rb +13 -6
- data/lib/flic/protocol/primitives/connection_status.rb +7 -4
- data/lib/flic/protocol/primitives/create_connection_channel_error.rb +4 -2
- data/lib/flic/protocol/primitives/device_name.rb +2 -1
- data/lib/flic/protocol/primitives/disconnect_reason.rb +8 -4
- data/lib/flic/protocol/primitives/disconnect_time.rb +8 -9
- data/lib/flic/protocol/primitives/enum.rb +12 -1
- data/lib/flic/protocol/primitives/latency_mode.rb +7 -3
- data/lib/flic/protocol/primitives/removed_reason.rb +14 -7
- data/lib/flic/protocol/primitives/scan_wizard_result.rb +15 -8
- data/lib/flic/protocol/primitives/uuid.rb +13 -3
- data/lib/flic/simple_client.rb +116 -78
- data/lib/flic/version.rb +1 -1
- metadata +17 -2
@@ -2,10 +2,12 @@ require 'flic/protocol'
|
|
2
2
|
|
3
3
|
module Flic
|
4
4
|
module Protocol
|
5
|
+
# A wrapper around a socket that allows sending/receiving commands/events
|
5
6
|
class Connection
|
6
|
-
class
|
7
|
-
class
|
7
|
+
class UnderlyingSocketClosedError < Error; end
|
8
|
+
class UnexpectedNilReturnValueFromRead < Error; end
|
8
9
|
|
10
|
+
# @return [Socket] the underlying socket
|
9
11
|
attr_reader :socket
|
10
12
|
|
11
13
|
def initialize(socket)
|
@@ -14,30 +16,32 @@ module Flic
|
|
14
16
|
@write_semaphore = Mutex.new
|
15
17
|
end
|
16
18
|
|
19
|
+
# Sends a command over the socket
|
20
|
+
# @param command [Flic::Protocol::Commands::Command]
|
17
21
|
def send_command(command)
|
18
22
|
send_packet Protocol.serialize_command(command)
|
19
23
|
end
|
20
24
|
|
25
|
+
# Receives a command from the socket
|
26
|
+
# @note This method may block
|
27
|
+
# @return [Flic::Protocol::Commands::Command]
|
21
28
|
def recv_command
|
22
29
|
Protocol.parse_command(recv_packet)
|
23
30
|
end
|
24
31
|
|
32
|
+
# Sends an event over the socket
|
33
|
+
# @param event [Flic::Protocol::Events::Event]
|
25
34
|
def send_event(event)
|
26
35
|
send_packet Protocol.serialize_event(event)
|
27
36
|
end
|
28
37
|
|
38
|
+
# Receives an event from the socket
|
39
|
+
# @note This method may block
|
40
|
+
# @return [Flic::Protocol::Events::Event]
|
29
41
|
def recv_event
|
30
42
|
Protocol.parse_event(recv_packet)
|
31
43
|
end
|
32
44
|
|
33
|
-
def closed?
|
34
|
-
@socket.closed?
|
35
|
-
end
|
36
|
-
|
37
|
-
def close
|
38
|
-
@socket.close
|
39
|
-
end
|
40
|
-
|
41
45
|
private
|
42
46
|
|
43
47
|
def send_packet(payload)
|
@@ -46,9 +50,9 @@ module Flic
|
|
46
50
|
@socket.write(packet_header.to_binary_s)
|
47
51
|
@socket.write(payload)
|
48
52
|
end
|
49
|
-
rescue IOError
|
50
|
-
if closed?
|
51
|
-
raise
|
53
|
+
rescue RuntimeError, IOError
|
54
|
+
if @socket.closed?
|
55
|
+
raise UnderlyingSocketClosedError
|
52
56
|
else
|
53
57
|
raise
|
54
58
|
end
|
@@ -59,19 +63,18 @@ module Flic
|
|
59
63
|
packet_header = Protocol::PacketHeader.new
|
60
64
|
packet_header_bytes = @socket.read packet_header.num_bytes
|
61
65
|
|
62
|
-
raise
|
66
|
+
raise UnexpectedNilReturnValueFromRead unless packet_header_bytes
|
63
67
|
|
64
68
|
packet_header.read(packet_header_bytes)
|
65
69
|
|
66
70
|
@socket.read(packet_header.byte_length)
|
67
71
|
end
|
68
|
-
rescue
|
72
|
+
rescue UnexpectedNilReturnValueFromRead
|
69
73
|
@socket.close
|
70
|
-
|
71
74
|
retry
|
72
|
-
rescue IOError
|
73
|
-
if closed?
|
74
|
-
raise
|
75
|
+
rescue RuntimeError, IOError
|
76
|
+
if @socket.closed?
|
77
|
+
raise UnderlyingSocketClosedError
|
75
78
|
else
|
76
79
|
raise
|
77
80
|
end
|
data/lib/flic/protocol/events.rb
CHANGED
@@ -2,6 +2,7 @@ require 'flic/protocol'
|
|
2
2
|
|
3
3
|
module Flic
|
4
4
|
module Protocol
|
5
|
+
# A namespace module for all of the event classes
|
5
6
|
module Events
|
6
7
|
autoload :AdvertisementPacket, 'flic/protocol/events/advertisement_packet'
|
7
8
|
autoload :BluetoothControllerStateChange, 'flic/protocol/events/bluetooth_controller_state_change'
|
@@ -47,11 +48,17 @@ module Flic
|
|
47
48
|
}.freeze
|
48
49
|
|
49
50
|
OPCODE_EVENT_CLASS = EVENT_CLASS_OPCODE.invert.freeze
|
50
|
-
|
51
|
+
|
52
|
+
# Finds the event class for a given opcode
|
53
|
+
# @param opcode [Integer]
|
54
|
+
# @return [Class]
|
51
55
|
def self.event_class_for_opcode(opcode)
|
52
56
|
OPCODE_EVENT_CLASS[opcode]
|
53
57
|
end
|
54
|
-
|
58
|
+
|
59
|
+
# Finds the opcode for a given event class
|
60
|
+
# @param event_class [Class]
|
61
|
+
# @return [Integer]
|
55
62
|
def self.opcode_for_event_class(event_class)
|
56
63
|
EVENT_CLASS_OPCODE[event_class]
|
57
64
|
end
|
@@ -8,14 +8,12 @@ module Flic
|
|
8
8
|
module Protocol
|
9
9
|
module Events
|
10
10
|
class AdvertisementPacket < Event
|
11
|
-
|
12
|
-
|
13
|
-
uint32 :scan_id
|
11
|
+
uint32le :scan_id
|
14
12
|
bluetooth_address :bluetooth_address
|
15
13
|
|
16
14
|
device_name :name
|
17
15
|
|
18
|
-
|
16
|
+
int8le :rssi
|
19
17
|
|
20
18
|
boolean :is_private
|
21
19
|
boolean :is_already_verified
|
@@ -7,12 +7,10 @@ module Flic
|
|
7
7
|
module Protocol
|
8
8
|
module Events
|
9
9
|
class ButtonClickOrHold < Event
|
10
|
-
|
11
|
-
|
12
|
-
uint32 :connection_channel_id
|
10
|
+
uint32le :connection_channel_id
|
13
11
|
click_type :click_type
|
14
12
|
boolean :was_queued
|
15
|
-
|
13
|
+
uint32le :time_difference
|
16
14
|
end
|
17
15
|
end
|
18
16
|
end
|
@@ -7,12 +7,10 @@ module Flic
|
|
7
7
|
module Protocol
|
8
8
|
module Events
|
9
9
|
class ButtonSingleOrDoubleClick < Event
|
10
|
-
|
11
|
-
|
12
|
-
uint32 :connection_channel_id
|
10
|
+
uint32le :connection_channel_id
|
13
11
|
click_type :click_type
|
14
12
|
boolean :was_queued
|
15
|
-
|
13
|
+
uint32le :time_difference
|
16
14
|
end
|
17
15
|
end
|
18
16
|
end
|
@@ -7,12 +7,10 @@ module Flic
|
|
7
7
|
module Protocol
|
8
8
|
module Events
|
9
9
|
class ButtonSingleOrDoubleClickOrHold < Event
|
10
|
-
|
11
|
-
|
12
|
-
uint32 :connection_channel_id
|
10
|
+
uint32le :connection_channel_id
|
13
11
|
click_type :click_type
|
14
12
|
boolean :was_queued
|
15
|
-
|
13
|
+
uint32le :time_difference
|
16
14
|
end
|
17
15
|
end
|
18
16
|
end
|
@@ -7,12 +7,10 @@ module Flic
|
|
7
7
|
module Protocol
|
8
8
|
module Events
|
9
9
|
class ButtonUpOrDown < Event
|
10
|
-
|
11
|
-
|
12
|
-
uint32 :connection_channel_id
|
10
|
+
uint32le :connection_channel_id
|
13
11
|
click_type :click_type
|
14
12
|
boolean :was_queued
|
15
|
-
|
13
|
+
uint32le :time_difference
|
16
14
|
end
|
17
15
|
end
|
18
16
|
end
|
@@ -7,9 +7,7 @@ module Flic
|
|
7
7
|
module Protocol
|
8
8
|
module Events
|
9
9
|
class ConnectionStatusChanged < Event
|
10
|
-
|
11
|
-
|
12
|
-
uint32 :connection_channel_id
|
10
|
+
uint32le :connection_channel_id
|
13
11
|
connection_status :connection_status
|
14
12
|
|
15
13
|
disconnect_reason :disconnect_reason # only relevant when connection_status is :disconnected
|
@@ -7,9 +7,7 @@ module Flic
|
|
7
7
|
module Protocol
|
8
8
|
module Events
|
9
9
|
class CreateConnectionChannelResponse < Event
|
10
|
-
|
11
|
-
|
12
|
-
uint32 :connection_channel_id
|
10
|
+
uint32le :connection_channel_id
|
13
11
|
create_connection_channel_error :error
|
14
12
|
connection_status :connection_status
|
15
13
|
end
|
@@ -6,14 +6,20 @@ module Flic
|
|
6
6
|
module Protocol
|
7
7
|
module Events
|
8
8
|
class Event < BinData::Record
|
9
|
-
|
10
|
-
|
11
|
-
uint8 :opcode, initial_value: -> { init_opcode }
|
9
|
+
uint8le :opcode, initial_value: :class_opcode, assert: :opcode_matcher
|
12
10
|
|
13
11
|
private
|
14
12
|
|
15
|
-
def
|
16
|
-
|
13
|
+
def class_opcode
|
14
|
+
Events.opcode_for_event_class(self.class)
|
15
|
+
end
|
16
|
+
|
17
|
+
def opcode_matcher
|
18
|
+
if class_opcode
|
19
|
+
class_opcode
|
20
|
+
else
|
21
|
+
true
|
22
|
+
end
|
17
23
|
end
|
18
24
|
end
|
19
25
|
end
|
@@ -8,18 +8,16 @@ module Flic
|
|
8
8
|
module Protocol
|
9
9
|
module Events
|
10
10
|
class GetInfoResponse < Event
|
11
|
-
endian :little
|
12
|
-
|
13
11
|
bluetooth_controller_state :bluetooth_controller_state
|
14
12
|
bluetooth_address :bluetooth_address
|
15
13
|
bluetooth_address_type :bluetooth_address_type
|
16
14
|
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
uint8le :maximum_pending_connections
|
16
|
+
int16le :maximum_concurrently_connected_buttons
|
17
|
+
uint8le :current_pending_connections
|
20
18
|
boolean :currently_no_space_for_new_connection
|
21
19
|
|
22
|
-
|
20
|
+
uint16le :verified_buttons_bluetooth_addresses_length
|
23
21
|
array :verified_buttons_bluetooth_addresses, type: :bluetooth_address, initial_length: :verified_buttons_bluetooth_addresses_length
|
24
22
|
end
|
25
23
|
end
|