Class: RR3036::Connection

Inherits:
Object
  • Object
show all
Defined in:
lib/RR3036/connection.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(device, _options = {}) ⇒ Connection

Returns a new instance of Connection.



82
83
84
85
86
87
# 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

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args) ⇒ Object



121
122
123
124
125
126
127
# 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

Instance Attribute Details

#com_addrObject (readonly)

Returns the value of attribute com_addr.



80
81
82
# File 'lib/RR3036/connection.rb', line 80

def com_addr
  @com_addr
end

#operationObject (readonly)

Returns the value of attribute operation.



80
81
82
# File 'lib/RR3036/connection.rb', line 80

def operation
  @operation
end

#portObject (readonly)

Returns the value of attribute port.



80
81
82
# File 'lib/RR3036/connection.rb', line 80

def port
  @port
end

Instance Method Details

#dump_iso15693Object



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# 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

#send_cmd(cmd, _options = {}) ⇒ Object



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
# 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 = {}) ⇒ Object



89
90
91
92
93
# 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