Class: Alien::AlienConnection

Inherits:
Object
  • Object
show all
Defined in:
lib/alien/alienconnection.rb

Direct Known Subclasses

AlienReader

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeAlienConnection

Returns a new instance of AlienConnection.



19
20
21
22
# File 'lib/alien/alienconnection.rb', line 19

def initialize
  @connected = false
  @raise_errors = true
end

Instance Attribute Details

#raise_errorsObject

Returns the value of attribute raise_errors.



17
18
19
# File 'lib/alien/alienconnection.rb', line 17

def raise_errors
  @raise_errors
end

Instance Method Details

#close(send_quit = true) ⇒ Object

Close the socket.



172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/alien/alienconnection.rb', line 172

def close(send_quit=true)
  if @connected
    if send_quit
      @sock.write("quit\r\n")
      sleep 1
    end
    @sock.close()
  end

  @connected = false
  return true
end

#connect(ipaddress = 'localhost', port = 23) ⇒ Object

Try to open a socket connection to the reader.



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/alien/alienconnection.rb', line 108

def connect(ipaddress='localhost', port=23)
  @connected = false

  #connect to a reader and grab the welcome message...
  begin
    timeout(3) {
      @sock = TCPSocket.new(ipaddress, port)
    }

    s = receive() #Grab the welcome message
    if s.include?("later.")  #Reader is busy. Please call back later.
      raise "Trouble Connecting to #{ipaddress}. (Someone else is talking to the reader.)"
    end
    @connected = true
  rescue RuntimeError
    raise
  rescue Timeout::Error, Errno::ETIMEDOUT
    raise "Trouble Connecting to #{ipaddress}. (No reader at this IP?)"
  rescue Errno::ECONNREFUSED
    raise "Trouble Connecting to #{ipaddress}. (Connection refused.)"
  end

  return @connected
end

#connectedObject

Returns the connected status of this AlienReader.



25
26
27
# File 'lib/alien/alienconnection.rb', line 25

def connected
  return @connected
end

#open(ipaddress = "localhost", port = 23, username = "alien", password = "password") ⇒ Object

Execute both the connect and login methods in one call.



160
161
162
163
164
165
166
167
168
# File 'lib/alien/alienconnection.rb', line 160

def open(ipaddress="localhost", port=23, username="alien", password="password")
  connect(ipaddress,port)

  if @connected
    (username,password)
  end

  return @connected
end

#receive(opts = {}) ⇒ Object

Read from the open socket until a null character is found. Strips off the trailing rn from the response



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/alien/alienconnection.rb', line 32

def receive(opts={})
  timeout = opts.fetch(:timeout, 40).to_i
  wait_for_null = opts.fetch(:wait_for_null, true)

  s = ""

  # Wait for data to become available on the socket
  res = select([@sock], nil, nil, timeout)
  if (res == nil)
    raise "Timeout waiting for reader response." if @raise_errors
  end

  if (wait_for_null)
    # Some readers don't put a null on the end of the 'call back later' message.
    # Check for 'later' to know when to punt on the read.
    begin
      timeout(timeout) {
        char = @sock.recv(1)
        while (char != "\0")
          s << char
          char = @sock.recv(1)
        end
      }
    rescue Timeout::Error
      raise "Timeout waiting for reader response." if @raise_errors
    end

    s.strip!

    if s.include? "Error"
      raise s if @raise_errors
    end

    # If this is a response to a Quit command, the reader will close the socket.
    # If there is an active connection, the reader will reject our attempt to connect.
    # Either way, we're not connected anymore...
    if (s.include? "Goodbye!")
      close(false)
    end

    return s
  else
    # Simply try to read up to 1 kB and return it
    return @sock.recv(1024)
  end
end

#send(msg = "") ⇒ Object

Send a message over an open socket (Alien terse msg format to suppress prompts on reply)



81
82
83
84
85
# File 'lib/alien/alienconnection.rb', line 81

def send (msg="")
  if @connected
    @sock.write "\1#{msg}\r\n" # leading \1 for terse reply
  end
end

#sendreceive(msg = "", opts = {}) ⇒ Object

Send a message over an open socket and wait for a reply



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/alien/alienconnection.rb', line 89

def sendreceive(msg="", opts={})
  timeout = opts.fetch(:timeout, 40)
  wait_for_null = opts.fetch(:wait_for_null, true)

  begin
    if @connected
      send(msg)
      receive(:timeout=>timeout, :wait_for_null=>wait_for_null)
    else
      raise "Not connected to reader."
    end
  rescue
    err = "Error in alienconnection:\nTried to send:\"#{msg}\"\nand got:\n\"" + String($!) +"\""
    raise err
  end
end