Posso impedire a Linux di ascoltare un dispositivo di input USB come tastiera, ma di catturare comunque eventi con un programma?


11

Ho uno scanner di codici a barre USB su /dev/input/event0( /dev/input/by-id/usb-Metrologic_Metrologic_Scanner-event-kbd) e la scansione di un codice a barre provoca l'invio di eventi di pressione dei tasti. Sto catturando questi tasti premuti usando la libreria ruby libdevinput , che funziona alla grande. Il problema è che ogni codice a barre viene inserito anche come nome utente e successivamente come password su Raspberry Pi, causando molti tentativi di accesso non riusciti. (Il Raspberry Pi sarà senza testa e all'interno di un forno a microonde.)

Come posso impedire a Linux di vedere lo scanner di codici a barre come dispositivo di input e che il mio programma sia l'unico consumatore di eventi? O c'è una soluzione diversa, migliore?


4
Non consiglio di mettere l'elettronica in un forno a microonde. Certamente non in esecuzione.
Ignacio Vazquez-Abrams,

1
Questa è sicuramente la parte più "wtf" di questa domanda.
Bratchley,

1
Gabbia di Faraday economica? Forse c'è molta RF nell'area.
charlesbridge,

4
Hahaha, non nel microonde. Tutto si trova dietro il PCB del controller del forno a microonde e non intendo cucinare il mio Raspberry Pi. Sto aggiungendo uno scanner di codici a barre per le istruzioni di cottura, nonché il controllo vocale e un touch pad riprogettato.
ndbroadbent

Risposte:


6

Ho scoperto che devo inviare un ioctl EVIOCGRAB al dispositivo, che lo afferra per uso esclusivo .

Ecco come farlo 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

Nota : è necessario installare le libdevinputgemme ffie le intestazioni di Linux. Se si utilizza una versione Linux tra 3.2.0e 3.6.11, è possibile sostituire la FFI::ConstGeneratorparte con EVIOCGRAB = 1074021776e quindi non è necessario ffio le intestazioni Linux.


2

Sembra in qualche modo simile a questo problema , quindi proverei questa soluzione  : se capisco correttamente il tuo problema, lo scanner di codici a barre dovrebbe apparire come un puntatore slave di "Tastiera del core virtuale" quando lo fai

xinput --list

Quindi forse ottenere il suo ID e forzarlo a float potrebbe aiutare:

xinput float <id>

Penso che OP stia vedendo questi sulla console, non su X. Ma in X dovrebbe funzionare.
derobert il

Ah giusto. Inoltre ha già trovato una soluzione ...
Skippy le Grand Gourou,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.