class SDN::Client

Constants

WAIT_TIME

Public Class Methods

new(port) click to toggle source
# File lib/sdn/client.rb, line 5
def initialize(port)
  uri = URI.parse(port)
  @io = if uri.scheme == "tcp"
    require 'socket'
    TCPSocket.new(uri.host, uri.port)
  elsif uri.scheme == "telnet" || uri.scheme == "rfc2217"
    require 'net/telnet/rfc2217'
    Net::Telnet::RFC2217.new(host: uri.host,
     port: uri.port || 23,
     baud: 4800,
     data_bits: 8,
     parity: :odd,
     stop_bits: 1)
  elsif port == "/dev/ptmx"
    require 'pty'
    io, slave = PTY.open
    puts "Slave PTY available at #{slave.path}"
    io
  else
    require 'ccutrer-serialport'
    CCutrer::SerialPort.new(port, baud: 4800, data_bits: 8, parity: :odd, stop_bits: 1)
  end
  @buffer = ""
end

Public Instance Methods

ensure(message) click to toggle source
# File lib/sdn/client.rb, line 40
def ensure(message)
  loop do
    messages = transact(message)
    next if messages.empty?
    next unless message.class.expected_response?(messages.first)
    return messages.first
  end
end
receive(timeout = nil) { |message| ... } click to toggle source
# File lib/sdn/client.rb, line 51
def receive(timeout = nil)
  messages = []

  loop do
    message, bytes_read = Message.parse(@buffer.bytes)
    # discard how much we read
    @buffer = @buffer[bytes_read..-1] if bytes_read
    unless message
      break unless messages.empty?

      begin
        block = @io.read_nonblock(64 * 1024)
        SDN.logger.debug "read #{block.unpack("H*").first.gsub(/\h{2}/, "\\0 ")}"
        @buffer.concat(block)
        next
      rescue IO::WaitReadable, EOFError
        wait = @buffer.empty? ? timeout : WAIT_TIME
        if @io.wait_readable(wait).nil?
          # timed out; just discard everything
          SDN.logger.debug "discarding #{@buffer.unpack("H*").first.gsub(/\h{2}/, "\\0 ")} due to timeout"
          @buffer = ""
        end
      end
      next
    end
    if block_given?
      yield message
    else
      messages << message
    end
  end

  messages
end
send(message) click to toggle source
# File lib/sdn/client.rb, line 30
def send(message)
  @io.write(message.serialize)
end
transact(message) click to toggle source
# File lib/sdn/client.rb, line 34
def transact(message)
  message.ack_requested = true
  send(message)
  receive(1)
end