module SVICall

Constants

SVI_PACKET_SIZE

Public Instance Methods

call(*_args) click to toggle source
# File lib/svi/svi.rb, line 33
def call(*_args)
  args = _args.reverse
  noreturn = false
  resp = nil
  packet = ""

  raise ArgumentError, 'Wrong arguments count' if args.count == 0

  if args[-1] == :noreturn
    noreturn = true
    args.pop
  end

  name = args.pop

  raise ArgumentError, "Invalid syscall name #{name}" unless $svi_api_desc.has_key? name
  raise ArgumentError, 'SVI is not configured' unless svi_configured?

  packet << name.to_s << "\0"

  args.reverse!

  $svi_api_desc[name][:args].each_with_index do |arg, i|
    packet << arg.put_to_svipack(args[i])
  end

  raise ArgumentError, 'Too long svc call' if packet.length > SVI_PACKET_SIZE

  packet << ([0]*(SVI_PACKET_SIZE-packet.length)).pack('C*')

  res = nil

  open_interface(svi_if) do |handle|
    res = handle.bulk_transfer(:endpoint => svi_if_ep_out, :dataOut => packet)

    raise IOError, 'Sending failed' unless res == SVI_PACKET_SIZE

    resp = []

    res = handle.bulk_transfer(:endpoint => svi_if_ep_in | 0x80, :dataIn => SVI_PACKET_SIZE, :timeout => @svi_timeout) unless $svi_api_desc[name][:response].empty? || noreturn
  end

  unless $svi_api_desc[name][:response].empty? || noreturn
    $svi_api_desc[name][:response].each do |resptype|
      resp_token, res = resptype.scan_from_svipack res
      resp << resp_token
    end
  else
    resp << 0
  end

  resp
end
method_missing(*args) click to toggle source
# File lib/svi/svi.rb, line 87
def method_missing *args
  call *args
end