Recent

Author Topic: Detect if a USB-HID device (Keyboard emu) sends data without focus  (Read 3314 times)

af0815

  • Hero Member
  • *****
  • Posts: 1291
Detect if a USB-HID device (Keyboard emu) sends data without focus
« on: September 15, 2020, 06:11:44 am »
I have a USB Device (special Barcode reader) in simulating mode, so it simulates a keyboard. API for a other communication mode is not available for Linux and Linux-Arm.
So it can only send data to the active component. So i must hold the focus the whole time on a edit field or similar. If the window goes to the back, the focus makes problem. The data itself must not be shown to the user, so visibility is not needed.

Is it possible to detect if a USB-HID device want to send data ? It is ok for me to hijack such a device by code and use more low level function. It is a fixed installation and the device is not changed, so i can use the device IDs for detecting. 
regards
Andreas

irfanbagus

  • Jr. Member
  • **
  • Posts: 73
Re: Detect if a USB-HID device (Keyboard emu) sends data without focus
« Reply #1 on: September 15, 2020, 06:30:41 am »
i use ioctl EVIOCGRAB. this is old code from my HD. not guaranteed still working. last time i tested on armbian
Code: Pascal  [Select][+][-]
  1. unit HIDBarcodeReader;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, BaseUnix, keyboard;
  9.  
  10. type
  11.  
  12.   TInputEvent = packed record
  13.     Time: timeval;
  14.     Atype: cuint16;
  15.     Code: cuint16;
  16.     Value: cint32;
  17.   end;
  18.  
  19.   { THIDBarcodeReader }
  20.  
  21.   THIDBarcodeReader = class(TObject)
  22.   private
  23.     FDeviceName: String;
  24.     FEnable: Boolean;
  25.     FTimeOut: Integer;
  26.     procedure SetEnable(AValue: Boolean);
  27.   protected
  28.     FHandle: cint;
  29.     procedure DoOpen;
  30.     procedure DoClose;
  31.   public
  32.     constructor Create;
  33.     destructor Destroy; override;
  34.     function ReadChar(var C: Char): Boolean;
  35.     property Enable: Boolean read FEnable write SetEnable;
  36.     property DeviceName: String read FDeviceName write FDeviceName;
  37.     property TimeOut: Integer read FTimeOut write FTimeOut;
  38.   end;
  39.  
  40. implementation
  41.  
  42. const
  43.   EVIOCGRAB = $40044590;
  44.   ScancodeLookup: array [0..$3F] of Char = (
  45.   // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
  46.      #0,'?','1','2','3','4','5','6','7','8','9','0','?','?','?','?',
  47.     'Q','W','E','R','T','Y','U','I','O','P','?','?',#13,'?','A','S',
  48.     'D','F','G','H','J','K','L','?','?','?', #0,'?','Z','X','C','V',
  49.     'B','N','M','?','?','?','?','?','?','?','?','?','?','?','?','?');
  50.  
  51. { THIDBarcodeReader }
  52.  
  53. procedure THIDBarcodeReader.SetEnable(AValue: Boolean);
  54. begin
  55.   if FEnable=AValue then
  56.     Exit;
  57.   if AValue then
  58.     DoOpen
  59.   else
  60.     DoClose;
  61. end;
  62.  
  63. procedure THIDBarcodeReader.DoOpen;
  64. begin
  65.   FHandle:= FpOpen(DeviceName,O_RDONLY);
  66.   if FHandle>=0 then
  67.   begin
  68.     FpIOCtl(FHandle,EVIOCGRAB,Pointer(1));
  69.     FEnable:= True;
  70.   end;
  71. end;
  72.  
  73. procedure THIDBarcodeReader.DoClose;
  74. begin
  75.   FEnable:= False;
  76.   if FHandle>=0 then
  77.   begin
  78.     FpIOCtl(FHandle,EVIOCGRAB,Nil);
  79.     FpClose(FHandle);
  80.     FHandle:= -1;
  81.   end;
  82. end;
  83.  
  84. function THIDBarcodeReader.ReadChar(var C: Char): Boolean;
  85. var
  86.   Buffer: TInputEvent;
  87.   FDS: TFDSet;
  88. begin
  89.   Result:= False;
  90.   C:= #0;
  91.   while True do
  92.   begin
  93.     fpFD_ZERO(FDS);
  94.     fpFD_SET(FHandle,FDS);
  95.     if fpSelect(FHandle+1,@FDS,Nil,Nil,TimeOut) > 0 then
  96.     begin
  97.       if FpRead(FHandle,Buffer{%H-},SizeOf(TInputEvent)) > 0 then
  98.       begin
  99.         case Buffer.Atype of
  100.           0 : begin
  101.                 if Buffer.Value=0 then
  102.                   Result:= True;
  103.                 Break;
  104.               end;
  105.           1 : if (Buffer.Value=0) and (Buffer.Code<Length(ScancodeLookup)) then
  106.                 C:= ScancodeLookup[Buffer.Code];
  107.         end;
  108.       end;
  109.     end
  110.     else
  111.       Break;
  112.   end;
  113. end;
  114.  
  115. constructor THIDBarcodeReader.Create;
  116. begin
  117.   FHandle:= -1;
  118.   FTimeOut:= 1000;
  119. end;
  120.  
  121. destructor THIDBarcodeReader.Destroy;
  122. begin
  123.   DoClose;
  124.   inherited Destroy;
  125. end;
  126.  
  127. end.
  128.  

af0815

  • Hero Member
  • *****
  • Posts: 1291
Re: Detect if a USB-HID device (Keyboard emu) sends data without focus
« Reply #2 on: September 15, 2020, 07:27:07 am »
i use ioctl EVIOCGRAB. this is old code from my HD. not guaranteed still working. last time i tested on armbian
Thanks for this interesting code, EVIOCGRAB is new for me :-) I'll dig into this.

Edit: Inforesources - for the record
About the eventstructure
https://www.kernel.org/doc/Documentation/input/input.txt

« Last Edit: September 15, 2020, 08:03:59 am by af0815 »
regards
Andreas

MarkMLl

  • Hero Member
  • *****
  • Posts: 6686
Re: Detect if a USB-HID device (Keyboard emu) sends data without focus
« Reply #3 on: September 15, 2020, 12:38:38 pm »
Thanks from me as well. Careful with some of those low-level HID ioctl functions: (working from memory) I've tinkered with some of them in the past and found that they were so dependant on exactly the right layout of packed data that there was really no alternative to using libraries compiled by the distro maintainers.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

irfanbagus

  • Jr. Member
  • **
  • Posts: 73
Re: Detect if a USB-HID device (Keyboard emu) sends data without focus
« Reply #4 on: September 15, 2020, 01:22:18 pm »
Thanks from me as well. Careful with some of those low-level HID ioctl functions: (working from memory) I've tinkered with some of them in the past and found that they were so dependant on exactly the right layout of packed data that there was really no alternative to using libraries compiled by the distro maintainers.

MarkMLl
that right, AFAIR i write that code based on event logs from my usb keybord and usb barcode reader. i simply ignored most of event which i think not necessary. so there is chance that not working with other hardware.

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: Detect if a USB-HID device (Keyboard emu) sends data without focus
« Reply #5 on: September 15, 2020, 04:08:56 pm »
If provided code does not work, then you should be able to put USB scanner in non keyboard hid emulation mode, and then sniff USB packages with WireShark while normal use of barcode scanner with it's regular driver. Depending on the USB protocol used, you would then build your linux application trying to catch and decode USB messages you are interested in (probably with libusb).
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

MarkMLl

  • Hero Member
  • *****
  • Posts: 6686
Re: Detect if a USB-HID device (Keyboard emu) sends data without focus
« Reply #6 on: September 15, 2020, 04:22:48 pm »
Also note the Linux evtest program. Working out the relationship between USB vid:pid and named devices in /dev can be painful.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

af0815

  • Hero Member
  • *****
  • Posts: 1291
Re: Detect if a USB-HID device (Keyboard emu) sends data without focus
« Reply #7 on: September 15, 2020, 09:57:15 pm »
regards
Andreas


sash

  • Sr. Member
  • ****
  • Posts: 366
Re: Detect if a USB-HID device (Keyboard emu) sends data without focus
« Reply #9 on: September 16, 2020, 06:55:19 pm »
If device is registered as keyboard, did you tried /dev/input/{by-id|by-path} ?
Is there it there?
Lazarus 2.0.10 FPC 3.2.0 x86_64-linux-gtk2 @ Ubuntu 20.04 XFCE

af0815

  • Hero Member
  • *****
  • Posts: 1291
Re: Detect if a USB-HID device (Keyboard emu) sends data without focus
« Reply #10 on: September 17, 2020, 06:32:23 am »
If device is registered as keyboard, did you tried /dev/input/{by-id|by-path} ?
Is there it there?
I can look next week for this, my last device is by a customer :-) - with a focus based solution.
regards
Andreas

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: Detect if a USB-HID device (Keyboard emu) sends data without focus
« Reply #11 on: September 17, 2020, 11:51:57 am »
my last device is by a customer :-) - with a focus based solution.
If scanner sends numerics as keyboard input in a fixed specific format (like 13 digits), then you can intercept messages and if format is recognized you can do a redirection, or even put scanned data into some queue.
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

 

TinyPortal © 2005-2018