LIBUSB Bulk Transfer, First URB failed, easy peasy - linux

I'm trying to update a program from USB 0.1.4 to LIBUSB, So far everything seems to be working except:
//endp = 0x01 or 0x81 both return the same error
//static unsigned char samples[8*400];
//size=(samplelength*numberofDevices)<<1;
return(usb_bulk_read(devh,endp,samples,size,timeout));
Currently I've tried
int nread;
struct libusb_transfer *xfr;
xfr = libusb_alloc_transfer(0);
libusb_fill_bulk_transfer(xfr, devh, endp, samples,size, callbackUSB, &nread, timeout);
if(libusb_submit_transfer(xfr) < 0){
libusb_free_transfer(xfr);
}
return sizeof(samples)*8;
And
int nread;
int r = 0;
r = libusb_bulk_transfer(devh, endp, samples,size, &nread, timeout);
if(r <0){
printf("libusb_bulk_transfer\n");
printf("%s\n", libusb_error_name(r));
exit(1);
}
return sizeof(samples)*8;
I'm getting this error before program crashes:
libusb: debug [libusb_submit_transfer] transfer 0x12fba50
libusb: debug [add_to_flying_list] arm timerfd for timeout in 100ms (first in line)
libusb: debug [submit_bulk_transfer] need 1 urbs for new transfer with length 1568
libusb: error [submit_bulk_transfer] submiturb failed error -1 errno=2
libusb: debug [submit_bulk_transfer] first URB failed, easy peasy
libusb: debug [disarm_timerfd]
libusb: debug [libusb_free_transfer] transfer 0x12fba50
Device in question:
Bus 001 Device 012: ID ffff:ffff
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 255 Vendor Specific Class
bDeviceSubClass 255 Vendor Specific Subclass
bDeviceProtocol 255 Vendor Specific Protocol
bMaxPacketSize0 64
idVendor 0xffff
idProduct 0xffff
bcdDevice 1.00
iManufacturer 0
iProduct 0
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 25
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xc0
Self Powered
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
Device Status: 0x0001
Self Powered
Awaiting legal department to change the VID/PID, but it has been working for the last 22 years as ffff:ffff
Same error on RHEL 7.3, 7.6, Ubuntu 18.
Any Suggestions on how to account for an easy peasy URB error?

bMaxPacketSize0 64 I Believe was the issue. It seems I was trying to Jam 1024x4 into the transfer. Once I adjusted that and used endpoint 0x81 It seems to work fine.
On to the next bug...

Related

Find port of RFID reader

I am using pyembedded in for a Python program using Ubuntu 22.04.
I am trying to get the ID that the RFID reader should provide when it reads a card. By using pyembedded I need to specify the port of the RFID using this line of code:
rfid = RFID(port='{USB}', baud_rate=9600)
I cannot find the actual USB port that is in use the RFID. Here is the udevadm info:
sudo udevadm info --query=all --name=/dev/input/event16
P: /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/0003:2518:6022.0003/input/input21/event16
N: input/event16
L: 0
S: input/by-id/usb-NSCCN_wCopy_Smart_Reader-event-if00
S: input/by-path/pci-0000:00:14.0-usb-0:2:1.0-event
E: DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/0003:2518:6022.0003/input/input21/event16
E: DEVNAME=/dev/input/event16
E: MAJOR=13
E: MINOR=80
E: SUBSYSTEM=input
E: USEC_INITIALIZED=1191291401
E: ID_INPUT=1
E: ID_VENDOR=NSCCN
E: ID_VENDOR_ENC=NSCCN
E: ID_VENDOR_ID=2518
E: ID_MODEL=wCopy_Smart_Reader
E: ID_MODEL_ENC=wCopy\x20Smart\x20Reader
E: ID_MODEL_ID=6022
E: ID_REVISION=0103
E: ID_SERIAL=NSCCN_wCopy_Smart_Reader
E: ID_TYPE=hid
E: ID_BUS=usb
E: ID_USB_INTERFACES=:030000:
E: ID_USB_INTERFACE_NUM=00
E: ID_USB_DRIVER=usbhid
E: ID_PATH=pci-0000:00:14.0-usb-0:2:1.0
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_2_1_0
E: LIBINPUT_DEVICE_GROUP=3/2518/6022:usb-0000:00:14.0-2
E: DEVLINKS=/dev/input/by-id/usb-NSCCN_wCopy_Smart_Reader-event-if00 /dev/input/by-path/pci-0000:00:14.0-usb-0:2:1.0-event
Is it specified here somewhere the path of the USB port in use and I cannot see it?
I also tried multiple ways so far, but none of the seemed to be working. I added also an udev rule containing the vendor and product ID of the RFID that looks like this:
SUBSYSTEM=="USB", ATTRS{idVendor}=="2518", ATTRS{idProduct}=="6022", MODE="0660", GROUP="plugdev"
Here is the full device info that I get using usb.core:
DEVICE ID 2518:6022 on Bus 001 Address 007 =================
bLength : 0x12 (18 bytes)
bDescriptorType : 0x1 Device
bcdUSB : 0x110 USB 1.1
bDeviceClass : 0x0 Specified at interface
bDeviceSubClass : 0x0
bDeviceProtocol : 0x0
bMaxPacketSize0 : 0x40 (64 bytes)
idVendor : 0x2518
idProduct : 0x6022
bcdDevice : 0x103 Device 1.03
iManufacturer : 0x1 NSCCN
iProduct : 0x2 wCopy Smart Reader
iSerialNumber : 0x3
bNumConfigurations : 0x1
CONFIGURATION 1: 400 mA ==================================
bLength : 0x9 (9 bytes)
bDescriptorType : 0x2 Configuration
wTotalLength : 0x29 (41 bytes)
bNumInterfaces : 0x1
bConfigurationValue : 0x1
iConfiguration : 0x0
bmAttributes : 0xc0 Self Powered
bMaxPower : 0xc8 (400 mA)
INTERFACE 0: Human Interface Device ====================
bLength : 0x9 (9 bytes)
bDescriptorType : 0x4 Interface
bInterfaceNumber : 0x0
bAlternateSetting : 0x0
bNumEndpoints : 0x2
bInterfaceClass : 0x3 Human Interface Device
bInterfaceSubClass : 0x0
bInterfaceProtocol : 0x0
iInterface : 0x0
ENDPOINT 0x81: Interrupt IN ==========================
bLength : 0x7 (7 bytes)
bDescriptorType : 0x5 Endpoint
bEndpointAddress : 0x81 IN
bmAttributes : 0x3 Interrupt
wMaxPacketSize : 0x40 (64 bytes)
bInterval : 0x1
ENDPOINT 0x2: Interrupt OUT ==========================
bLength : 0x7 (7 bytes)
bDescriptorType : 0x5 Endpoint
bEndpointAddress : 0x2 OUT
bmAttributes : 0x3 Interrupt
wMaxPacketSize : 0x40 (64 bytes)
bInterval : 0x1
Also, when I am running:
rfid = RFID(port='/dev/bus/usb/001/009', baud_rate=9600)
I get:
serial.serialutil.SerialException: Could not configure port: (25, 'Inappropriate ioctl for device')
From where can I get the path of the port in use by this device?
From pyembedded website:
Note: Use port as ‘COM1’, ‘COM2’ etc in case of windows machine. Use port as ‘/dev/ttyUSB0’ in case of linux based devices:
I suppose you are taking /dev/bus/usb/001/009 from the lsusb command output. Check this question(https://askubuntu.com/questions/435861/what-is-the-difference-between-dev-tty-and-dev-bus-usb-001-002) to understand the difference between both paths.
I should use dmesg and connect/disconnect the device to see how Linux is managing the rfid reader. Then if the reader is being mapped to a tty you can use the path to call RFID(port, baud_rate)

Read the bar- QR-code with a scanner on windows 10 system

I have connected a bar- / qr-code scanner to my windows 10 pc via usb.
The scanner is registered on the system.
Now I want to write a python app to read bar- and qr-codes with the scanner.
Yet I am not able to read codes, I get an object as a result.
What I have to do, whta is going wrong???
To access the complete parameter from the scanner is possible.
#importing modules
import usb
import usb.core
import usb.util
import usb.backend.libusb1
#device vid / pid
VID = 0x2010
PID = 0x7638
#access the device registry
backend = usb.backend.libusb1.get_backend(find_library=lambda X: "C:\ProgramData\Anaconda3\libusb\amd64")
#some tries to get parameters / informations about the device
usb_error = usb.USBError('USB-Error', error_code='error', errno=None)
dev = usb.core.find(idVendor=VID, idProduct=PID)
dev.set_configuration()
if not dev:
raise ValueError ("USB device not found")
exit(1)
config = dev.configurations
cfg = dev.get_active_configuration()
intf = cfg[(0,0)]
ep = usb.util.find_descriptor(
intf,
custom_match = lambda e: usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_IN)
ep_adr = ep.bEndpointAddress
dev.backend.open_device
adress = dev.address
manufaktur = dev.manufacturer
conf2 = dev.bNumConfigurations
dev_descriptor = dev.bDescriptorType
ser_num = dev.serial_number
busses = usb.busses()
for bus in busses:
devices = bus.devices
for dev in devices:
print ("Device:", dev.filename)
print (" idVendor: %d (0x%04x)" % (dev.idVendor, dev.idVendor))
print (" idProduct: %d (0x%04x)" % (dev.idProduct, dev.idProduct))
print('cfg: ', str(cfg))
print('Manufacturer: ', str(manufaktur))
print('Serial Number', str(ser_num))
print('EP: ', ep)
print('Descriptor: ', dev_descriptor)
the actual result:
Device:
idVendor: 8208 (0x2010)
idProduct: 30264 (0x7638)
cfg: CONFIGURATION 1: 400 mA ==================================
bLength : 0x9 (9 bytes)
bDescriptorType : 0x2 Configuration
wTotalLength : 0x22 (34 bytes)
bNumInterfaces : 0x1
bConfigurationValue : 0x1
iConfiguration : 0x0
bmAttributes : 0x80 Bus Powered
bMaxPower : 0xc8 (400 mA)
INTERFACE 0: Human Interface Device ====================
bLength : 0x9 (9 bytes)
bDescriptorType : 0x4 Interface
bInterfaceNumber : 0x0
bAlternateSetting : 0x0
bNumEndpoints : 0x1
bInterfaceClass : 0x3 Human Interface Device
bInterfaceSubClass : 0x1
bInterfaceProtocol : 0x1
iInterface : 0x0
ENDPOINT 0x83: Interrupt IN ==========================
bLength : 0x7 (7 bytes)
bDescriptorType : 0x5 Endpoint
bEndpointAddress : 0x83 IN
bmAttributes : 0x3 Interrupt
wMaxPacketSize : 0x8 (8 bytes)
bInterval : 0x1
Manufacturer: USBKey Chip
Serial Number 202730041341
EP: ENDPOINT 0x83: Interrupt IN ==========================
bLength : 0x7 (7 bytes)
bDescriptorType : 0x5 Endpoint
bEndpointAddress : 0x83 IN
bmAttributes : 0x3 Interrupt
wMaxPacketSize : 0x8 (8 bytes)
bInterval : 0x1
Descriptor: 1
The object you get must be a string with the resulting scan output. Try scanning to a console...
The scanner you have is emulating only a USB keyboard as OUTPUT.
All the SW inside the scanner produces is a string of bytes as a result of the scanned image.
What you are trying to do is use libusb to talk the the USB hw directly, which will only get you an emulated HID keyboard.
If you want to hack down, you need to jtag the scanner board or scan config images to trigger configuration changes on the device.
my Barcode scanner connected via USB is acting like standard input device (like Keyboard) in Windows 10. When barcode is scanned on opened text file in Notepad, the scanned digits appears in text file, like typing on Keyboard.
Hence for reading into Python39 shell or file in Windows 10, used the python code 'input("scan Barcode: ")' and scanned. I got scanned digits from scanner device.
C:\Project\Python39>python
Python 3.9.0 (tags/v3.9.0:9cf6752, Oct 5 2020, 15:34:40) [MSC v.1927 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>>
>>> input("scan Barcode: ")
scan Barcode: 88H-1010UB-0TV
'88H-1010UB-0TV'
>>>
>>> myBarCodeId = input("Scan barCode please ...")
Scan barCode please ...TARNLK002563
>>>
>>> print(myBarCodeId)
TARNLK002563
>>>
>>> mibar=input("scan me please \n")
scan me please
88H-1010UB-0TV
>>>
>>> print(mibar)
88H-1010UB-0TV
>>>

If I have only one PCIe EP and only one function, Do I need “interrupt-map” function in device tree (DTS)?

I’m using legacy PCIe Interrupt mechanism(Virtual INTx), As per my PCIe controller user guide, In legacy Interrupt mechanism Assert or Deassert Virtual INTx messages will be received from the EP device and according to that PCIe Core it will generate or clear interrupt signal respectively.
If I have only one EP and only one function, Do I need “interrupt-map” function in device tree (DTS)?
As per my understanding,
PCIe EP will send Assert_INTA message
PCIe RP decode this message and send Interrupt to Interrupt generating pin INTA_OUT
In design INTA_OUT is directly connected to Interrupt controller Input pin
In Linux kernel this IRQ will invoke PCIe RP ISR and also Endpoint functions ISR
Am I correct in my understanding ?
pci#0xfb000000 {
interrupts = <1 1>; //PCIe RP INTA  IRQ1, Only this info is enough ??
interrupt-parent = <&pic>;
/*Do we need follow info also ??? */
#interrupt-cells = <0x1>;
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
interrupt-map = < 0x0 0x0 0x0 0x1 &pcie_intc 0x1
0x0 0x0 0x0 0x2 &pcie_intc 0x2
0x0 0x0 0x0 0x3 &pcie_intc 0x3
0x0 0x0 0x0 0x4 &pcie_intc 0x4 >;
}

Not able to transfer data through libusb

I am trying to run this program for sending data using libusb. I am not able to find the endpoint of my USB port. This parameter is required in the libusb_bulk_transfer function.
#include <iostream>
#include <libusb.h>
using namespace std;
int main() {
libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices
libusb_device_handle *dev_handle; //a device handle
libusb_context *ctx = NULL; //a libusb session
int r; //for return values
ssize_t cnt; //holding number of devices in list
r = libusb_init(&ctx); //initialize the library for the session we just declared
if(r < 0) {
cout<<"Init Error "<<r<<endl; //there was an error
return 1;
}
libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in the documentation
cnt = libusb_get_device_list(ctx, &devs); //get the list of devices
if(cnt < 0) {
cout<<"Get Device Error"<<endl; //there was an error
return 1;
}
cout<<cnt<<" Devices in list."<<endl;
dev_handle = libusb_open_device_with_vid_pid(ctx, 5118, 7424); //these are vendorID and productID I found for my usb device
if(dev_handle == NULL)
cout<<"Cannot open device"<<endl;
else
cout<<"Device Opened"<<endl;
libusb_free_device_list(devs, 1); //free the list, unref the devices in it
unsigned char *data = new unsigned char[4]; //data to write
data[0]='a';data[1]='b';data[2]='c';data[3]='d'; //some dummy values
int actual; //used to find out how many bytes were written
if(libusb_kernel_driver_active(dev_handle, 0) == 1) { //find out if kernel driver is attached
cout<<"Kernel Driver Active"<<endl;
if(libusb_detach_kernel_driver(dev_handle, 0) == 0) //detach it
cout<<"Kernel Driver Detached!"<<endl;
}
r = libusb_claim_interface(dev_handle, 0); //claim interface 0 (the first) of device (mine had jsut 1)
if(r < 0) {
cout<<"Cannot Claim Interface"<<endl;
return 1;
}
cout<<"Claimed Interface"<<endl;
cout<<"Data->"<<data<<"<-"<<endl; //just to see the data we want to write : abcd
cout<<"Writing Data..."<<endl;
r = libusb_bulk_transfer(dev_handle, (2 | LIBUSB_ENDPOINT_OUT), data, 4, &actual, 0); //my device's out endpoint was 2, found with trial- the device had 2 endpoints: 2 and 129
if(r == 0 && actual == 4) //we wrote the 4 bytes successfully
cout<<"Writing Successful!"<<endl;
else
cout<<"Write Error"<<endl;
r = libusb_release_interface(dev_handle, 0); //release the claimed interface
if(r!=0) {
cout<<"Cannot Release Interface"<<endl;
return 1;
}
cout<<"Released Interface"<<endl;
libusb_close(dev_handle); //close the device we opened
libusb_exit(ctx); //needs to be called to end the
delete[] data; //delete the allocated memory for data
return 0;
}
The following is the program on my host PC to receive the data.
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include <sys/stat.h>
#include <fcntl.h>
void main()
{
read_port();
//return 0;
}
read_port(void)
{
int fd = open("/dev/ttyACM0", O_RDONLY | O_NOCTTY);
if (fd == -1)
{
/* Could not open the port. */
perror("open_port: Unable to open /dev/ttyACM0) - ");
}
char buffer[32];
for(;;)
{
int n = read(fd, buffer, sizeof(buffer));
if (n < 0)
fputs("read failed!\n", stderr);
printf("\n %d", n);
}
}
Please help.
Thanks in advance.
In answer to your actual question, if you want to find out what actual endpoints are attached the device, lsusb is your friend
If you are unsure what your device's vendor and device ID are, type:
lsusb
and you will get something like this:
Bus 001 Device 005: ID 093a:2510 Pixart Imaging, Inc. Optical Mouse
Bus 001 Device 015: ID 413c:2003 Dell Computer Corp. Keyboard
Bus 001 Device 020: ID 0483:3748 STMicroelectronics ST-LINK/V2
Bus 001 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Let's say we want to know what endpoints are present on the ST-LINK/V2, we use lsusb in verbose mode using the -v option, and specify only the device we're interested in with the -d option with the ID:
lsusb -v -d 0483:3748
We will get a big list of fields from this. The topology is roughly:
device->configuration->interface->endpoints
| interface->endpoints
| interface->endpoints
|
->configuration->interface->endpoints
interface->endpoints
...
So locate the interface you want to use (often 0):
locate the interface descriptor
encapsulated inside this you can see the endpoint descriptors
then look for the term bEndpointAddress to get the actual value
In this case we have a bulk in endpoint with an address of 0x81:
bEndpointAddress 0x81 EP 1 IN
And another a little further down:
bEndpointAddress 0x02 EP 2 OUT
And another in endpoint:
bEndpointAddress 0x83 EP 3 IN
For completeness here is the full dump:
Bus 001 Device 020: ID 0483:3748 STMicroelectronics ST-LINK/V2
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0483 STMicroelectronics
idProduct 0x3748 ST-LINK/V2
bcdDevice 1.00
iManufacturer 1 STMicroelectronics
iProduct 2 STM32 STLink
iSerial 3 000000000001
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 39
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 4 ST Link
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN *!eg end point address!*
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Device Status: 0x0000
(Bus Powered)

USB HID Device only reporting first event

I have a eDIO USB Multi Remote Controller( a Infrared Reciever) that came with ASUS PSR 2000 Web Surfing Remote Control.
I am trying to connect the Remote COntroller to my pi so that it recieves the keystrokes sent by the remote.
The controller is detected as a HID device. Here are the details from the lsusb -v command
Bus 001 Device 007: ID 147a:e001 Formosa Industrial Computing, Inc.
Couldn't open device, some information will be missing
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x147a Formosa Industrial Computing, Inc.
idProduct 0xe001
bcdDevice 1.22
iManufacturer 1
iProduct 2
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 34
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 4
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 300mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 2 Mouse
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.10
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 20
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0004 1x 4 bytes
bInterval 10
I can also the device in the dev folder with an event created
pi#raspberrypi /dev/input/by-id $ dir
usb-Cypress_Semiconductor_eDio_USB_Multi_Remote_Controlle-event-if00
The event handler associated with it is as follows as seen from the following command.
pi#raspberrypi /proc/bus/input $ cat devices
I: Bus=0003 Vendor=147a Product=e001 Version=0110
N: Name="Cypress Semiconductor eDio USB Multi Remote Controlle"
P: Phys=usb-bcm2708_usb-1.2/input0
S: Sysfs=/devices/platform/bcm2708_usb/usb1/1-1/1-1.2/1-1.2:1.0/input/input2
U: Uniq=
H: Handlers=event0
B: PROP=0
B: EV=1
The problem is when I am trying to read the output from the event handler created for the device.The first keystroke is registered but the subsequent key strokes are not displayed by the CAT command.
pi#raspberrypi /dev/input $ cat event0 | xxd
0000000: e007 9450 9476 0900 0000 0000 0000 0000 ...P.v..........
Please suggest me what can I do to get the device working. Pressing any keys after the first keystroke doesn't return anything unless the device is replugged.
Please suggest what needs to be done to fix the issue.
Depending on what you ultimately want to do, mapping the buttons of the HID remote to keystrokes might be enough and is fairly easy to achieve with tools such as QJoyPad.
That seems hard to build on a Raspberry Pi, so you might want to try joy2key instead, which is available in the repos: sudo apt-get install joy2key.
Finally I got time to write my own implementation using the PyUSB library which is a wrapper for Libusb.
I am posting the code here.Might help someone.
I have another piece of code that creates the configuration file which is used here.Haven't mapped all the remote keys since I don't need all of them.
import usb.core
import usb.util
import ConfigParser
import shlex
import subprocess
import logging
# find our device
diction={
6402315641282315:'1',
6402415641282415:'2',
6402515641282515:'3',
6402615641282615:'4',
6402715641282715:'5',
6402815641282815:'6',
6402915641282915:'7',
6403015641283015:'8',
6403115641283115:'9',
}
def load_config():
dict={}
config = ConfigParser.RawConfigParser()
config.read('/codes/remote/remote.cfg')
dict['vendor']=config.getint('Settings','idVendor')
dict['product']=config.getint('Settings','idProduct')
dict['interface']=config.getint('Settings', 'interface')
r=config.options('Key Mappings')
for item in r:
if config.get('Key Mappings',item)!='':
dict[item]=config.get('Key Mappings',item)
#print config.get('Key Mappings',item)
return dict
def pyus():
try:
load_log()
dict=load_config()
join_int = lambda nums: int(''.join(str(i) for i in nums))
#print dict
dev = usb.core.find(idVendor=dict['vendor'], idProduct=dict['product'])
interface=dict['interface']
if dev is None:
raise ValueError('Device not found')
if dev.is_kernel_driver_active(interface) is True:
#print "but we need to detach kernel driver"
dev.detach_kernel_driver(interface)
#dev.detatch_kernel_driver(interface)
# set the active configuration. With no arguments, the first
# configuration will be the active one
dev.set_configuration()
# get an endpoint instance
cfg = dev.get_active_configuration()
interface_number = cfg[(0,0)].bInterfaceNumber
alternate_setting = usb.control.get_interface(dev,interface_number)
intf = usb.util.find_descriptor(
cfg, bInterfaceNumber = interface_number,
bAlternateSetting = alternate_setting
)
ep = usb.util.find_descriptor(
intf,
# match the first IN endpoint
custom_match = \
lambda e: \
usb.util.endpoint_direction(e.bEndpointAddress) == \
usb.util.ENDPOINT_IN
)
assert ep is not None
#print 'packet details',ep.bEndpointAddress , ep.wMaxPacketSize
while 1:
try:
data = dev.read(ep.bEndpointAddress, ep.wMaxPacketSize*2,interface,1000)
data=data.tolist()
key=join_int(data)
#print "Key is " , key
if key in diction:
try:
args=shlex.split(dict[diction[key]])
#print args
p=subprocess.Popen(args, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
#print "Pressed key is ",diction[key]
except:
pass
except usb.core.USBError as e:
pass
except:
pass
pyus()
#____________________________REPORT DESCRIPTOR EXAMPLE___________________
# Bus 001 Device 007: ID 147a:e001 Formosa Industrial Computing, Inc.
# Couldn't open device, some information will be missing
# Device Descriptor:
# bLength 18
# bDescriptorType 1
# bcdUSB 1.10
# bDeviceClass 0 (Defined at Interface level)
# bDeviceSubClass 0
# bDeviceProtocol 0
# bMaxPacketSize0 8
# idVendor 0x147a Formosa Industrial Computing, Inc.
# idProduct 0xe001
# bcdDevice 1.22
# iManufacturer 1
# iProduct 2
# iSerial 0
# bNumConfigurations 1
# Configuration Descriptor:
# bLength 9
# bDescriptorType 2
# wTotalLength 34
# bNumInterfaces 1
# bConfigurationValue 1
# iConfiguration 4
# bmAttributes 0xa0
# (Bus Powered)
# Remote Wakeup
# MaxPower 300mA
# Interface Descriptor:
# bLength 9
# bDescriptorType 4
# bInterfaceNumber 0
# bAlternateSetting 0
# bNumEndpoints 1
# bInterfaceClass 3 Human Interface Device
# bInterfaceSubClass 1 Boot Interface Subclass
# bInterfaceProtocol 2 Mouse
# iInterface 0
# HID Device Descriptor:
# bLength 9
# bDescriptorType 33
# bcdHID 1.10
# bCountryCode 0 Not supported
# bNumDescriptors 1
# bDescriptorType 34 Report
# wDescriptorLength 20
# Report Descriptors:
# ** UNAVAILABLE **
# Endpoint Descriptor:
# bLength 7
# bDescriptorType 5
# bEndpointAddress 0x81 EP 1 IN
# bmAttributes 3
# Transfer Type Interrupt
# Synch Type None
# Usage Type Data
# wMaxPacketSize 0x0004 1x 4 bytes
# bInterval 10

Resources