11

I have a USB barcode scanner at /dev/input/event0 (/dev/input/by-id/usb-Metrologic_Metrologic_Scanner-event-kbd), and scanning a barcode causes it to send keypress events. I'm capturing these keypresses using the libdevinput Ruby library, which works great. The issue is that each barcode is also entered as a username, and subsequently a password on the Raspberry Pi, causing lots of failed login attempts. (The Raspberry Pi will be headless, and inside a microwave.)

How can I stop Linux from seeing the barcode scanner as an input device, and have my program be the sole event consumer? Or is there a different, better solution?

  • 4
    I do not recommend putting electronics in a microwave. Certainly not a running one. – Ignacio Vazquez-Abrams May 31 '13 at 11:40
  • 1
    That is definitely the most "wtf" part of this question. – Bratchley May 31 '13 at 11:45
  • 1
    Cheap Faraday cage? Maybe there's a lot of RF in the area. – charlesbridge May 31 '13 at 16:47
  • 4
    Hahaha, not IN the microwave. Everything sits behind the microwave's controller PCB, and I am not intending to cook my Raspberry Pi. I'm adding a barcode scanner for cooking instructions, as well as voice control and a redesigned touch pad. – ndbroadbent May 31 '13 at 22:45
6

I found out that I need to send an EVIOCGRAB ioctl to the device, which grabs it for exclusive use.

Here's how to do it in Ruby:

#!/usr/bin/env ruby
BARCODE_SCANNER = "/dev/input/by-id/usb-Metrologic_Metrologic_Scanner-event-kbd"

require 'rubygems'
require 'libdevinput'
require 'ffi'
require 'ffi/tools/const_generator'

# We need access to the file
DevInput.class_eval { attr_reader :dev }

# Look up value of EVIOCGRAB constant
cg = FFI::ConstGenerator.new('input') do |gen|
  gen.include('linux/input.h')
  gen.const(:EVIOCGRAB, '%u', '(unsigned)')
end
EVIOCGRAB = cg['EVIOCGRAB'].to_i

scanner = DevInput.new(BARCODE_SCANNER)
# Send EVIOCGRAB to scanner, which grabs it for exclusive use by our process
scanner.dev.ioctl(EVIOCGRAB, 1)


puts "Waiting for events..."
scanner.each do |event|
  # Ignore everything except key press events
  next unless event.type == 1 && event.value == 1
  puts "Key: #{event.code_str}"
end

Note: You'll need to install the libdevinput gem, ffi, and Linux headers. If you are using a Linux version between 3.2.0 and 3.6.11, you can replace the FFI::ConstGenerator part with EVIOCGRAB = 1074021776, and then you don't need ffi or Linux headers.

2

Sounds somehow similar to this issue, so I'd try this solution : if I understand correctly your problem, the barcode scanner should appear as a slave pointer of "Virtual core keyboard" when you do

xinput --list

Then maybe getting its ID and forcing it to float could help :

xinput float <id>
  • I think OP is seeing these on the console, not X. But in X this should work. – derobert Oct 4 '13 at 14:53
  • Ah, right. Plus he has already found a solution… – Skippy le Grand Gourou Oct 4 '13 at 15:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.