13

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
  • 5
    I do not recommend putting electronics in a microwave. Certainly not a running one. May 31, 2013 at 11:40
  • 1
    That is definitely the most "wtf" part of this question.
    – Bratchley
    May 31, 2013 at 11:45
  • 1
    Cheap Faraday cage? Maybe there's a lot of RF in the area. May 31, 2013 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. May 31, 2013 at 22:45

2 Answers 2

7

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.

3

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>
2
  • I think OP is seeing these on the console, not X. But in X this should work.
    – derobert
    Oct 4, 2013 at 14:53
  • Ah, right. Plus he has already found a solution… Oct 4, 2013 at 15:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .