Class: Net::Telnet::RFC2217
- Inherits:
-
Object
- Object
- Net::Telnet::RFC2217
- Defined in:
- lib/net/telnet/rfc2217/telnet.rb,
lib/net/telnet/rfc2217/version.rb,
lib/net/telnet/rfc2217.rb
Defined Under Namespace
Modules: TelnetExtensions Classes: WaitReadable
Constant Summary collapse
- VERSION =
'1.0.2'
Instance Attribute Summary collapse
-
#baud ⇒ Object
readonly
Returns the value of attribute baud.
-
#data_bits ⇒ Object
readonly
Returns the value of attribute data_bits.
-
#parity ⇒ Object
readonly
Returns the value of attribute parity.
-
#stop_bits ⇒ Object
readonly
Returns the value of attribute stop_bits.
-
#telnet ⇒ Object
readonly
Returns the value of attribute telnet.
Class Method Summary collapse
Instance Method Summary collapse
- #close ⇒ Object
- #flush ⇒ Object
-
#initialize(host, port: 23, baud: 115200, data_bits: 8, parity: :none, stop_bits: 1, &block) ⇒ RFC2217
constructor
A new instance of RFC2217.
- #read(length, outbuf = '') ⇒ Object
- #read_nonblock(length, outbuf = '', options = {}) ⇒ Object
- #readbyte ⇒ Object (also: #getbyte)
- #readpartial(length, outbuf = '') ⇒ Object
- #ready? ⇒ Boolean
- #set_modem_params(baud: nil, data_bits: nil, parity: nil, stop_bits: nil) ⇒ Object
- #sock ⇒ Object
- #ungetbyte(b) ⇒ Object
- #ungetc(c) ⇒ Object
- #wait_readable(timeout = nil) ⇒ Object
- #write(string) ⇒ Object
Constructor Details
#initialize(host, port: 23, baud: 115200, data_bits: 8, parity: :none, stop_bits: 1, &block) ⇒ RFC2217
Returns a new instance of RFC2217.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/net/telnet/rfc2217.rb', line 34 def initialize(host, port: 23, baud: 115200, data_bits: 8, parity: :none, stop_bits: 1, &block) set_modem_params(baud: baud, data_bits: data_bits, parity: parity, stop_bits: stop_bits) = { 'Host' => host, 'Port' => port, } ['Binmode'] = true ['Telnetmode'] = false @telnet = Telnet.new(, &block) telnet.write(IAC + WILL + COM_PORT_OPTION) sock.flush @buffer = '' start = Time.now.to_f loop do raise "could not negotiate serial port in time" if Time.now.to_f - start > 5 break if @negotiated readpartial(0) end end |
Instance Attribute Details
#baud ⇒ Object (readonly)
Returns the value of attribute baud.
32 33 34 |
# File 'lib/net/telnet/rfc2217.rb', line 32 def baud @baud end |
#data_bits ⇒ Object (readonly)
Returns the value of attribute data_bits.
32 33 34 |
# File 'lib/net/telnet/rfc2217.rb', line 32 def data_bits @data_bits end |
#parity ⇒ Object (readonly)
Returns the value of attribute parity.
32 33 34 |
# File 'lib/net/telnet/rfc2217.rb', line 32 def parity @parity end |
#stop_bits ⇒ Object (readonly)
Returns the value of attribute stop_bits.
32 33 34 |
# File 'lib/net/telnet/rfc2217.rb', line 32 def stop_bits @stop_bits end |
#telnet ⇒ Object (readonly)
Returns the value of attribute telnet.
14 15 16 |
# File 'lib/net/telnet/rfc2217.rb', line 14 def telnet @telnet end |
Class Method Details
.open(**kwargs) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/net/telnet/rfc2217.rb', line 17 def open(**kwargs) sp = new(opt**kwargs) if block_given? begin yield sp ensure sp.close end nil else nil end end |
Instance Method Details
#close ⇒ Object
174 175 176 |
# File 'lib/net/telnet/rfc2217.rb', line 174 def close telnet.close end |
#flush ⇒ Object
170 171 172 |
# File 'lib/net/telnet/rfc2217.rb', line 170 def flush sock.flush end |
#read(length, outbuf = '') ⇒ Object
70 71 72 73 74 75 76 |
# File 'lib/net/telnet/rfc2217.rb', line 70 def read(length, outbuf = '') readpartial(length, outbuf) while outbuf.length < length outbuf.concat(readpartial(length - outbuf.length)) end outbuf end |
#read_nonblock(length, outbuf = '', options = {}) ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/net/telnet/rfc2217.rb', line 122 def read_nonblock(length, outbuf = '', = {}) if outbuf == ({ exception: false }) = outbuf outbuf = '' end loop do result = wait_readable(0) if result == nil raise WaitReadable unless [:exception] == false return :wait_readable end # we have to try to consume control characters first readpartial(0) # and then only do a real read if we have something return readpartial(length, outbuf) unless @buffer.empty? # otherwise loop and see if there's more there end end |
#readbyte ⇒ Object Also known as: getbyte
78 79 80 |
# File 'lib/net/telnet/rfc2217.rb', line 78 def readbyte read(1)&.[](0) end |
#readpartial(length, outbuf = '') ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/net/telnet/rfc2217.rb', line 83 def readpartial(length, outbuf = '') loop do # 0 is special and means "just see if there's data to read" break if length != 0 && @buffer.length != 0 raise "could not negotiate serial port in first 1MB of data" if @buffer.length >= 1024 * 1024 data = sock.sysread([length - @buffer.length, 64 * 1024].max) # avoid getting caught in the middle of a control sequence while (data[-1] == IAC && sock.wait_readable(0)) data.concat(sock.sysread(16)) end data = @telnet.preprocess(data) do |control| if DO[0] == control[0] && COM_PORT_OPTION == control[1] # start negotiation write_modem_params @negotiated = true true elsif DONT[0] == control[0] && COM_PORT_OPTION == control[1] raise "Serial port control not supported" elsif (WILL[0] == control[0] || DONT[0] == control[0]) && OPT_ECHO == control[1] # just ignore echo requests true else false end end @buffer.concat(data) break if length == 0 end length = [length, @buffer.length].min outbuf.replace(@buffer[0...length]) @buffer = @buffer[length..-1] outbuf end |
#ready? ⇒ Boolean
148 149 150 151 152 153 154 155 |
# File 'lib/net/telnet/rfc2217.rb', line 148 def ready? loop do return true unless @buffer.empty? return false if sock.wait_readable(0).nil? # consume control characters first readpartial(0) end end |
#set_modem_params(baud: nil, data_bits: nil, parity: nil, stop_bits: nil) ⇒ Object
55 56 57 58 59 60 61 62 63 64 |
# File 'lib/net/telnet/rfc2217.rb', line 55 def set_modem_params(baud: nil, data_bits: nil, parity: nil, stop_bits: nil) raise ArgumentError, "Parity must be :none, :even, :odd, :mark, or :space" unless parity.nil? || %i{none even odd mark space}.include?(parity) @baud ||= baud || 115200 @data_bits ||= data_bits || 8 @parity ||= parity || :none @stop_bits ||= stop_bits || 1 write_modem_params if telnet end |
#sock ⇒ Object
66 67 68 |
# File 'lib/net/telnet/rfc2217.rb', line 66 def sock @telnet.sock end |
#ungetbyte(b) ⇒ Object
157 158 159 |
# File 'lib/net/telnet/rfc2217.rb', line 157 def ungetbyte(b) @buffer.insert(0, b.chr) end |
#ungetc(c) ⇒ Object
161 162 163 |
# File 'lib/net/telnet/rfc2217.rb', line 161 def ungetc(c) @buffer.insert(0, c) end |
#wait_readable(timeout = nil) ⇒ Object
141 142 143 144 145 146 |
# File 'lib/net/telnet/rfc2217.rb', line 141 def wait_readable(timeout = nil) return true unless @buffer.empty? result = sock.wait_readable(timeout) result = self if result == sock result end |
#write(string) ⇒ Object
165 166 167 168 |
# File 'lib/net/telnet/rfc2217.rb', line 165 def write(string) string = string.gsub(/#{IAC}/no, IAC + IAC) telnet.write(string) end |