class RR3036::Connection
Attributes
com_addr[R]
operation[R]
port[R]
Public Class Methods
new(device, _options = {})
click to toggle source
# File lib/RR3036/connection.rb, line 82 def initialize(device, _options = {}) options = {:baud => 19200, :data_bits => 8, :stop_bit => 1, :parity => SerialPort::NONE, :mode => OPERATION_MODES.first}.update (_options||{}) @operation = options[:mode] @com_addr = 0x00 set_and_open_port(device, _options) end
Public Instance Methods
dump_iso15693()
click to toggle source
# File lib/RR3036/connection.rb, line 129 def dump_iso15693 response = init_device puts "Init version=%i, RFU=%i, reader_type=%s, tr_type=%i, inventory_scan_time=%i"%(response[:data].unpack('S>S>hS>C')) response = change_to_iso15693 puts "Changed to ISO15693" if response[:status] == 0 while(true) tags = [] tag = nil puts "Please press any key to start inventory" gets response = iso15693_inventory(:continue_on_errors => [0x0E]) ((response[:len] - 4) / 9).times do |i| (dsfid, uid) = response[:data][((i - 1) * 9)..((i * 9) - 1)].unpack('Ca8') puts "#{i}) ISO15693 tag #{bytes_to_hex_string uid} with uid=#{uid.unpack('i')} (dsfid=#{dsfid})" tags << {:block_data => [], :block_security_flag => [], :dsfid => dsfid, :uid => uid} end if tags.empty? next else puts "Please select a tag:" tag = tags[gets.strip.to_i] next if tag.nil? end info = iso15693_tag_info(:data => tag[:uid]) (tag[:flag], _uid, _dsfid, tag[:afi], tag[:mem_size], tag[:ic_ref]) = info[:data].unpack('hh8CCS>C') puts "ISO15693 tag #{bytes_to_hex_string tag[:uid]} info: flag=#{tag[:flag]}, afi=#{tag[:afi]}, mem_size=#{tag[:mem_size]}, ic_ref=#{tag[:ic_ref]}" # TODO 4-byte vs. 8-byte reads 64.times do |i| block = iso15693_read_4byte(:data => tag[:uid] + i.chr) tag[:block_data] << block[:data][1..-1] tag[:block_security_flag] << block[:data][0] puts "ISO15693 tag #{bytes_to_hex_string tag[:uid]} block #{i}: #{bytes_to_hex_string block[:data][0]} #{block[:data][1..-1].inspect} (#{bytes_to_hex_string block[:data][1..-1]})" end puts "ISO15693 tag #{bytes_to_hex_string tag[:uid]} joined together: #{tag[:block_data].join.strip.inspect}" end end
method_missing(m, *args)
click to toggle source
Calls superclass method
# File lib/RR3036/connection.rb, line 121 def method_missing(m, *args) if CMDS[m.to_sym] send_cmd(m.to_sym, *args) else super end end
send_cmd(cmd, _options = {})
click to toggle source
# File lib/RR3036/connection.rb, line 95 def send_cmd(cmd, _options = {}) options = {:data => '', :continue_on_errors => [], :dont_report_crc_failures => false}.update (_options||{}) return false unless CMDS.include? cmd # len | com_addr | cmd | state | data | lsb-crc16 | msb-crc16 cmd_data_block = [options[:data].bytes.size + 5, com_addr, CMDS[cmd][:cmd], (operation == :iso15693 ? CMDS[cmd][:state] & 0x0F : CMDS[cmd][:state] | 0xF0)] + options[:data].bytes cmd_data_block += crc(cmd_data_block) written_bytes = port.write cmd_data_block.pack('C*') port.flush response = {:len => 0x00, :com_addr => 0x00, :status => 0x00, :data => [], :crc => [0x00, 0x00]} response[:len] = port.readbyte (response[:addr], response[:status]) = port.read(2).bytes.to_a response[:data] = port.read(response[:len] - 4).bytes.pack('C*') response[:crc] = port.read(2).bytes.pack('C*') response[:crc_calc] = crc([response[:len], response[:addr], response[:status]] + response[:data].bytes).pack('C*') if response[:status] > 0 && !options[:continue_on_errors].include?(response[:status]) puts "Error: " << (ERROR_MSG[response[:status]][:msg].nil? ? 'UNKNOWN ERROR' : (ERROR_MSG[response[:status]][:msg] + ' ' + ERROR_MSG[response[:status]][:description]) + ' ' + response[:data].inspect) << (ERROR_MSG[response[:status]] && ERROR_MSG[response[:status]][:further_descriptions] && !response[:data].empty? && ERROR_MSG[response[:status]][:further_descriptions][response[:data]] ? ERROR_MSG[response[:status]][:further_descriptions][response[:data]] : '') end if response[:crc] != response[:crc_calc] && !options[:dont_report_crc_failures] puts "Error: CRC doesn't match." end return response end
set_and_open_port(device, _options = {})
click to toggle source
# File lib/RR3036/connection.rb, line 89 def set_and_open_port(device, _options = {}) options = {:baud => 19200, :data_bits => 8, :stop_bit => 1, :parity => SerialPort::NONE, :read_timeout => 1000}.update (_options||{}) @port = SerialPort.new(device, options[:baud], options[:data_bits], options[:stop_bit], options[:parity]) port.read_timeout = options[:read_timeout] end
Private Instance Methods
bytes_to_hex_string(b)
click to toggle source
# File lib/RR3036/connection.rb, line 172 def bytes_to_hex_string(b) (b.respond_to?(:bytes) ? b.bytes : b).map{|x| ('%2x'%(x)).sub(' ', '0')}.join end
crc(data)
click to toggle source
# File lib/RR3036/connection.rb, line 176 def crc(data) crc_value = 0xFFFF (data.kind_of?(Array) ? data : data.bytes).each do |b| crc_value = crc_value ^ b 8.times do if (crc_value & 0x0001) == 0x0001 crc_value = (crc_value >> 1) ^ CRC_POLYNOMIAL else crc_value = (crc_value >> 1) end end end # LSB-CRC-16, MSB-CRC16 return [crc_value & 0x00FF, (crc_value >> 8) & 0x00FF] end