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