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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +51 -49
  3. data/Rakefile +6 -1
  4. data/flic.gemspec +1 -0
  5. data/lib/flic.rb +1 -0
  6. data/lib/flic/blocker.rb +59 -0
  7. data/lib/flic/client.rb +12 -7
  8. data/lib/flic/client/scan_wizard.rb +4 -0
  9. data/lib/flic/protocol.rb +20 -6
  10. data/lib/flic/protocol/commands.rb +7 -0
  11. data/lib/flic/protocol/commands/cancel_scan_wizard.rb +1 -3
  12. data/lib/flic/protocol/commands/change_mode_parameters.rb +1 -3
  13. data/lib/flic/protocol/commands/command.rb +10 -4
  14. data/lib/flic/protocol/commands/create_connection_channel.rb +1 -3
  15. data/lib/flic/protocol/commands/create_scan_wizard.rb +1 -3
  16. data/lib/flic/protocol/commands/create_scanner.rb +1 -3
  17. data/lib/flic/protocol/commands/force_disconnect.rb +0 -2
  18. data/lib/flic/protocol/commands/get_button_uuid.rb +0 -2
  19. data/lib/flic/protocol/commands/get_info.rb +0 -1
  20. data/lib/flic/protocol/commands/ping.rb +1 -3
  21. data/lib/flic/protocol/commands/remove_connection_channel.rb +1 -3
  22. data/lib/flic/protocol/commands/remove_scanner.rb +1 -3
  23. data/lib/flic/protocol/connection.rb +22 -19
  24. data/lib/flic/protocol/events.rb +9 -2
  25. data/lib/flic/protocol/events/advertisement_packet.rb +2 -4
  26. data/lib/flic/protocol/events/bluetooth_controller_state_change.rb +0 -2
  27. data/lib/flic/protocol/events/button_click_or_hold.rb +2 -4
  28. data/lib/flic/protocol/events/button_single_or_double_click.rb +2 -4
  29. data/lib/flic/protocol/events/button_single_or_double_click_or_hold.rb +2 -4
  30. data/lib/flic/protocol/events/button_up_or_down.rb +2 -4
  31. data/lib/flic/protocol/events/connection_channel_removed.rb +1 -3
  32. data/lib/flic/protocol/events/connection_status_changed.rb +1 -3
  33. data/lib/flic/protocol/events/create_connection_channel_response.rb +1 -3
  34. data/lib/flic/protocol/events/event.rb +11 -5
  35. data/lib/flic/protocol/events/get_button_uuid_response.rb +0 -2
  36. data/lib/flic/protocol/events/get_info_response.rb +4 -6
  37. data/lib/flic/protocol/events/got_space_for_new_connection.rb +1 -3
  38. data/lib/flic/protocol/events/new_verified_button.rb +0 -2
  39. data/lib/flic/protocol/events/no_space_for_new_connection.rb +1 -3
  40. data/lib/flic/protocol/events/ping_response.rb +1 -3
  41. data/lib/flic/protocol/events/scan_wizard_button_connected.rb +1 -3
  42. data/lib/flic/protocol/events/scan_wizard_completed.rb +1 -3
  43. data/lib/flic/protocol/events/scan_wizard_found_private_button.rb +1 -3
  44. data/lib/flic/protocol/events/scan_wizard_found_public_button.rb +1 -3
  45. data/lib/flic/protocol/packet_header.rb +2 -2
  46. data/lib/flic/protocol/primitives.rb +1 -0
  47. data/lib/flic/protocol/primitives/bluetooth_address.rb +2 -1
  48. data/lib/flic/protocol/primitives/bluetooth_address_type.rb +3 -0
  49. data/lib/flic/protocol/primitives/bluetooth_controller_state.rb +7 -3
  50. data/lib/flic/protocol/primitives/boolean.rb +1 -0
  51. data/lib/flic/protocol/primitives/click_type.rb +13 -6
  52. data/lib/flic/protocol/primitives/connection_status.rb +7 -4
  53. data/lib/flic/protocol/primitives/create_connection_channel_error.rb +4 -2
  54. data/lib/flic/protocol/primitives/device_name.rb +2 -1
  55. data/lib/flic/protocol/primitives/disconnect_reason.rb +8 -4
  56. data/lib/flic/protocol/primitives/disconnect_time.rb +8 -9
  57. data/lib/flic/protocol/primitives/enum.rb +12 -1
  58. data/lib/flic/protocol/primitives/latency_mode.rb +7 -3
  59. data/lib/flic/protocol/primitives/removed_reason.rb +14 -7
  60. data/lib/flic/protocol/primitives/scan_wizard_result.rb +15 -8
  61. data/lib/flic/protocol/primitives/uuid.rb +13 -3
  62. data/lib/flic/simple_client.rb +116 -78
  63. data/lib/flic/version.rb +1 -1
  64. metadata +17 -2
@@ -6,9 +6,7 @@ module Flic
6
6
  module Protocol
7
7
  module Commands
8
8
  class CreateScanWizard < Command
9
- endian :little
10
-
11
- uint32 :scan_wizard_id
9
+ uint32le :scan_wizard_id
12
10
  end
13
11
  end
14
12
  end
@@ -5,9 +5,7 @@ module Flic
5
5
  module Protocol
6
6
  module Commands
7
7
  class CreateScanner < Command
8
- endian :little
9
-
10
- uint32 :scan_id
8
+ uint32le :scan_id
11
9
  end
12
10
  end
13
11
  end
@@ -6,8 +6,6 @@ module Flic
6
6
  module Protocol
7
7
  module Commands
8
8
  class ForceDisconnect < Command
9
- endian :little
10
-
11
9
  bluetooth_address :bluetooth_address
12
10
  end
13
11
  end
@@ -6,8 +6,6 @@ module Flic
6
6
  module Protocol
7
7
  module Commands
8
8
  class GetButtonUuid < Command
9
- endian :little
10
-
11
9
  bluetooth_address :bluetooth_address
12
10
  end
13
11
  end
@@ -5,7 +5,6 @@ module Flic
5
5
  module Protocol
6
6
  module Commands
7
7
  class GetInfo < Command
8
- endian :little
9
8
  end
10
9
  end
11
10
  end
@@ -5,9 +5,7 @@ module Flic
5
5
  module Protocol
6
6
  module Commands
7
7
  class Ping < Command
8
- endian :little
9
-
10
- uint32 :ping_id
8
+ uint32le :ping_id
11
9
  end
12
10
  end
13
11
  end
@@ -5,9 +5,7 @@ module Flic
5
5
  module Protocol
6
6
  module Commands
7
7
  class RemoveConnectionChannel < Command
8
- endian :little
9
-
10
- uint32 :connection_channel_id
8
+ uint32le :connection_channel_id
11
9
  end
12
10
  end
13
11
  end
@@ -5,9 +5,7 @@ module Flic
5
5
  module Protocol
6
6
  module Commands
7
7
  class RemoveScanner < Command
8
- endian :little
9
-
10
- uint32 :scan_id
8
+ uint32le :scan_id
11
9
  end
12
10
  end
13
11
  end
@@ -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 ConnectionClosedError < Error; end
7
- class NilResponse < Error; end
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 ConnectionClosedError
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 NilResponse unless packet_header_bytes
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 NilResponse
72
+ rescue UnexpectedNilReturnValueFromRead
69
73
  @socket.close
70
-
71
74
  retry
72
- rescue IOError
73
- if closed?
74
- raise ConnectionClosedError
75
+ rescue RuntimeError, IOError
76
+ if @socket.closed?
77
+ raise UnderlyingSocketClosedError
75
78
  else
76
79
  raise
77
80
  end
@@ -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
- endian :little
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
- int8 :rssi
16
+ int8le :rssi
19
17
 
20
18
  boolean :is_private
21
19
  boolean :is_already_verified
@@ -6,8 +6,6 @@ module Flic
6
6
  module Protocol
7
7
  module Events
8
8
  class BluetoothControllerStateChange < Event
9
- endian :little
10
-
11
9
  bluetooth_controller_state :bluetooth_controller_state
12
10
  end
13
11
  end
@@ -7,12 +7,10 @@ module Flic
7
7
  module Protocol
8
8
  module Events
9
9
  class ButtonClickOrHold < Event
10
- endian :little
11
-
12
- uint32 :connection_channel_id
10
+ uint32le :connection_channel_id
13
11
  click_type :click_type
14
12
  boolean :was_queued
15
- uint32 :time_difference
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
- endian :little
11
-
12
- uint32 :connection_channel_id
10
+ uint32le :connection_channel_id
13
11
  click_type :click_type
14
12
  boolean :was_queued
15
- uint32 :time_difference
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
- endian :little
11
-
12
- uint32 :connection_channel_id
10
+ uint32le :connection_channel_id
13
11
  click_type :click_type
14
12
  boolean :was_queued
15
- uint32 :time_difference
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
- endian :little
11
-
12
- uint32 :connection_channel_id
10
+ uint32le :connection_channel_id
13
11
  click_type :click_type
14
12
  boolean :was_queued
15
- uint32 :time_difference
13
+ uint32le :time_difference
16
14
  end
17
15
  end
18
16
  end
@@ -6,9 +6,7 @@ module Flic
6
6
  module Protocol
7
7
  module Events
8
8
  class ConnectionChannelRemoved < Event
9
- endian :little
10
-
11
- uint32 :connection_channel_id
9
+ uint32le :connection_channel_id
12
10
  removed_reason :reason
13
11
  end
14
12
  end
@@ -7,9 +7,7 @@ module Flic
7
7
  module Protocol
8
8
  module Events
9
9
  class ConnectionStatusChanged < Event
10
- endian :little
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
- endian :little
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
- endian :little
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 init_opcode
16
- Event.opcode_for_event_class(self.class)
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
@@ -7,8 +7,6 @@ module Flic
7
7
  module Protocol
8
8
  module Events
9
9
  class GetButtonUuidResponse < Event
10
- endian :little
11
-
12
10
  bluetooth_address :bluetooth_address
13
11
  uuid :uuid
14
12
  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
- uint8 :maximum_pending_connections
18
- int16 :maximum_concurrently_connected_buttons
19
- uint8 :current_pending_connections
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
- uint16 :verified_buttons_bluetooth_addresses_length
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
@@ -5,9 +5,7 @@ module Flic
5
5
  module Protocol
6
6
  module Events
7
7
  class GotSpaceForNewConnection < Event
8
- endian :little
9
-
10
- uint8 :maximum_concurrently_connected_buttons
8
+ uint8le :maximum_concurrently_connected_buttons
11
9
  end
12
10
  end
13
11
  end
@@ -6,8 +6,6 @@ module Flic
6
6
  module Protocol
7
7
  module Events
8
8
  class NewVerifiedButton < Event
9
- endian :little
10
-
11
9
  bluetooth_address :bluetooth_address
12
10
  end
13
11
  end
@@ -5,9 +5,7 @@ module Flic
5
5
  module Protocol
6
6
  module Events
7
7
  class NoSpaceForNewConnection < Event
8
- endian :little
9
-
10
- uint8 :maximum_concurrently_connected_buttons
8
+ uint8le :maximum_concurrently_connected_buttons
11
9
  end
12
10
  end
13
11
  end
@@ -5,9 +5,7 @@ module Flic
5
5
  module Protocol
6
6
  module Events
7
7
  class PingResponse < Event
8
- endian :little
9
-
10
- uint32 :ping_id
8
+ uint32le :ping_id
11
9
  end
12
10
  end
13
11
  end
@@ -5,9 +5,7 @@ module Flic
5
5
  module Protocol
6
6
  module Events
7
7
  class ScanWizardButtonConnected < Event
8
- endian :little
9
-
10
- uint32 :scan_wizard_id
8
+ uint32le :scan_wizard_id
11
9
  end
12
10
  end
13
11
  end