lib/twib.rb in twib-0.1.0 vs lib/twib.rb in twib-0.1.1
- old
+ new
@@ -6,39 +6,53 @@
require "twib/interfaces/ITwibDeviceInterface"
module Twib
class Error < RuntimeError
end
-
+
+ # An error originating from either twibd or a remote device.
class ResultError < Error
def initialize(code)
- super("0x#{code.to_s(16)}")
- @code = code
+ super("0x#{code.to_i.to_s(16)}")
+ @code = code.to_i
end
+
+ # @return [Integer] the bad result code that caused this error
attr_reader :code
end
-
+
+ # A response from either twibd or a remote device.
class Response
+ # @param device_id [Integer] ID of the device that this response originated from.
+ # @param object_id [Integer] ID of the bridge object that this response originated from.
+ # @param result_code [Integer] Result code
+ # @param tag [Integer] Tag corresponding to the request that prompted this response.
+ # @param payload [String] Raw data associated with the response
+ # @param object_ids [Array<Integer>] Object IDs sent with the response
def initialize(device_id, object_id, result_code, tag, payload, object_ids)
@device_id = device_id
@object_id = object_id
@result_code = result_code
@tag = tag
@payload = payload
@object_ids = object_ids
end
attr_reader :device_id, :object_id, :result_code, :tag, :payload, :object_ids
-
+
+ # Raises a {ResultError} if the {#result_code} is not OK.
+ # @raise [ResultError]
+ # @return [self]
def assert_ok
if @result_code != 0 then
raise ResultError.new(@result_code)
end
return self
end
end
-
+
+ # A request to be sent to a remote device.
class ActiveRequest
def initialize(tc, device_id, object_id, command_id, tag, payload, &block)
@tc = tc
@device_id = device_id
@object_id = object_id
@@ -48,37 +62,48 @@
@condvar = ConditionVariable.new
@cb = block
@response = nil
end
+ # @api private
def respond(response) # expects to be synchronized by @tc.mutex
@response = response
@condvar.broadcast
if @cb then
@tc.cb_queue.push([@cb, response])
end
end
+ # Waits for this request to receive a response.
+ # @return [Response]
def wait
@tc.mutex.synchronize do
while @response == nil do
@condvar.wait(@tc.mutex)
end
end
return @response
end
+ # Waits for this request to receive a response, and raises if the response is not OK.
+ # @raise [ResultError]
+ # @return [Response]
def wait_ok
wait.assert_ok
end
end
-
+
+ # A connection to twibd.
class TwibConnection
+ # Connects to twibd using the standard UNIX socket address.
+ # @return [TwibConnection]
def self.connect_unix
return self.new(UNIXSocket.new("/var/run/twibd.sock"))
end
-
+
+ # Creates a TwibConnection using the specified socket
+ # @param [BasicSocket] socket
def initialize(socket)
@socket = socket
@itmi = Interfaces::ITwibMetaInterface.new(self, 0, 0)
@alive = true
@active_requests = {}
@@ -110,24 +135,33 @@
@cb_queue = Queue.new
@cb_thread = Thread.new do # to avoid deadlocks on I/O thread, we execute callbacks here
while @alive do
cb, response = @cb_queue.pop
- cb.call(response)
+ if cb then
+ cb.call(response)
+ end
end
end
end
+ # @api private
attr_reader :mutex
+ # @api private
attr_reader :cb_queue
-
+
+ # Closes the socket and stops internal threads
def close
@alive = false
@socket.close
@thread.join
+ @cb_queue.close
+ @cb_thread.join
end
+ # @api private
+ # @return [ActiveRequest]
def send(device_id, object_id, command_id, payload, &block)
tag = rand(0xffffffff)
rq = ActiveRequest.new(self, device_id, object_id, command_id, tag, payload, &block)
@active_requests[tag] = rq
@@ -138,14 +172,24 @@
raise "couldn't send entire message"
end
return rq
end
-
+
+ # Returns a list of devices connected to twibd.
+ #
+ # tc.list_devices
+ # # => [{"device_id"=>507914862, "identification"=>{...}}]
+ #
+ # Use {#open_device} to connect to one.
+ #
+ # @return [Array<Hash>]
def list_devices
@itmi.list_devices
end
+ # Opens a device specified by one of the device IDs returned from {#list_devices}.
+ # @return [Interfaces::ITwibDeviceInterface]
def open_device(device_id)
return Interfaces::ITwibDeviceInterface.new(self, device_id, 0)
end
end
end