flic 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
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