flic 0.0.5 → 0.0.6
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/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
|