Sending Control Commands to USB Barcode Reader - barcode-scanner

We are integrating a new barcode reader (Newland NLS-FM430) in one of our products and we need to control its functionality. We have already implemented this behavior with another reader but it was an RS232 version, so we were able to send commands and wait for its input. The new one is a USB version which makes things different.
Generally, we want to initialize the barcode reader when the application is started (e.g. to disable reading setup codes) and turn it off. Then we want to enable it at the moment we need input from it and disable it again once we have read the data. There are commands for all these operations, documented in the user guide.
The issue comes when trying to communicate with the USB device. When connected to the computer it acts as a normal keyboard (Human Interface Device, HID in Device Manager) and we need to send commands to it. For this we need to open a stream to the device and write in it. We tried different libraries and solutions and opening the device always fails with an ACCESS_DENIED error. My suspicion is that the device is locked because Windows uses it as a keyboard.
I found this topic which discusses a similar problem. They found a workaround by deleting the suffix /kbd in the Device Path (and ours also has as this suffix) but removing it does not work for us - it says it cannot find the device.
I am looking into a solution in C# or C/C++ that would make it possible to open a connection to the USB device and write to it. Any help is highly appreciated.

Your introduced user guide states that the scanner still supports serial port mode.
Page 76 : USB CDC
Page 79 : IBM SurePOS (Handheld)
Page 79 : IBM SurePOS (Tabletop)
You can stop using it in keyboard input emulation mode and use serial port mode.
This is because, also on page 14 Chapter 3 System Settings of the User Guide, it is stated that the user can program by serial command.
Command Programming
The FM430 can also be configured by serial commands sent from the host device.
Users can design an application program to send those command strings to the scanners to perform device configuration
For more information, refer to the Programming Guide Based on Newland Unified Command s Set.
What's more, the vendor-provided configuration tool, also on page 13 Chapter 2 EasySet of the User Guide, does not support configuration in keyboard input simulation mode.
EasySet can communicate with device via one of the following interface: RS 232, USB COM Port Emulation (UFCOM driver required), USB CDC (UFCOM driver required), USB DataPipe (UFCOM driver required), USB HID POS.
In addition, the HID POS (POS HID Barcode Scanner) mode on page 77 allows for configuration and input/output as a variant of HID as described in the USB.org specification HID Point of Sale Usage Tables 1.02.
However, that method will not be able to notify the barcode read by the keyboard input emulation method. And it will require more complicated programming than setting/input/output in serial port mode.

Related

How to send feature-report to the HOST_PC via Linux USB_GADGET

I have this configuration of the devices HOST_PS <----> Transmitter<---- Touchscreen.
Currently on my transmitter I have created a composite USB gadget device which could contain up to 5 HID devices, (2Mouse, 2Keyboard, Touchscreen). HOST PC could enumerate all of them and everything is working properly. From transmitter side I am writing HID report data comeing from the touchscreen to the corresponding /dev/hidg device and Host PC acts correctly. The problem occurred when
I have bought a new usb_touchscreen.
Extracted the report descriptor from that touchscreen.
Pass the report descriptor and all the corresponding data(dev, no_out_endpoint, protocol, report_desc, report_length, subclass) to /sys/kernel/config/usb_gadget/Nhid/functions/hid.usb0/.
After all this steps the HOST_PC could enumerate the touchscreen properly but the tocushes doesn't work(I also know why).
HOST_PC printing this message hid-multitouch xxx:yyy:zzz.uuu: failed to fetch feature 7.
Some touchscreens using Feature reports for allowing the HOST to have configurable device. If I connect the Touchscreen directly to the PC I can see the following under the hood. I'll describe the final steps before sending the input reports from the touchscreen.
pc -> touchscreen (GetDescriptor(Report))
pc -> touchscreen (GetReport(Feature eport))
touchscreen ->pc (Input Report)This is already HID report that sends the touchscreen
The problem hid-multitouch xxx:yyy:zzz.uuu: failed to fetch feature 7 is though I am setting the report descriptor to USB_GADGET's HID device and HOST_PS enumerates it properly, I am not sending the feature report to the host as it requested in step 2 above.
QUESTION:
How to send feature report from device to HOST_PC, if the device is USB_GADGET composite HID device. In usual for sending the Input report (HID data) I am writing the incoming data from the touchscreen to the corresponding /dev/hidg<N> device.
NOTES:
The HOST_PC is Linux(Ubuntu, CentOS,... doesn't metter) and I ma not interested on Windows.
The Touchscreen works perfectly if I connect it to the PC directly.
I don't want to modify the touchscreen's report descriptor, remove feature report part and solve the problem like that.
PS:
I know this is a little bit complicated but Thanks in advance.
In case someone would have this kind of problem in future.
This is not a bug in Linux USB_GADGET driver but I would honestly say that it is a missing feature which is not implemented. This is a link to the place where the implementation wasn't done
https://github.com/torvalds/linux/blob/master/drivers/usb/gadget/function/f_hid.c#L652.
If someone wants to send feature_report(s) from device to HOST, than you probably will need to implement it in driver.
This is my modification to USB_GADGET driver that will allow to send feature reports to the HOST.
https://github.com/torvalds/linux/compare/master...AydinyanNarek:patch-1
PS. I don't have enough time to create pull request and other staff for applying this patch to the kernel. If someone would be interested on this than you can take this patch that I have created, polish the code and apply for a patch.

Enumerate commands available for a usb chip in fedora 24

I am learning to program a USB device (iBall 3.5g USB Dongle) using libusb.h header library.
Until now I am able to identify my device using the Vendor ID and also open the device for operation.
As a next step I would like to know the available commands (or the controls) for example : command to scan the surroundings for available GSM networks.
Obviously I will have to talk to the devices' firmware to extract the necessary information.
I tried to search for the technical datasheet for the 3g dongle, but couldn't find any.
The dongle is powered by a Qualcomm chip
Do you know any of the methods in which I can get the control commands for a usb device ?
Thanks in advance.
There is no simple procedure for figuring out what commands a USB device has. You need to use a combination of looking at the descriptors reported by the device, seeing if the device supports any particular USB device class, reading the USB specification, and maybe doing some reverse engineering using a protocol analyzer.
A good first step would be for you to use lsusb -v to print human-readable descriptions of the device's USB descriptors.

What data can a HID device receive?

I am designing a USB keyboard with special capabilities. What information can such a HID device receive from the host?
Can I via USB:
Read data from a form on the screen?
Find out what OS the user is on?
Find out if there's been an error message?
Even 'know' what's going on visually on the screen, i.e. what program is selected or whether the program is windowed or fullscreen?
Thank you!
The device can't get any of this information from a standard driver that the operating system supplies because that would be a security issue. It can receive any information that your own driver or application sends it. There are many ways to communicate with it - your device could present multiple interfaces (which will appear as separate devices), multiple endpoints, or use the control channel. You will definitely need to study the spec, and I also found this tutorial helpful.
I have done something similar and used the control channel to exchange feature data with a Windows application (over the standard Windows driver). On Windows, the API calls are HidD_SetFeature() and HidD_GetFeature().
On the device side, my hardware ran embedded Linux and I used the GadgetFS library to create a user-mode driver - much easier to debug than a kernel driver.
As others have said, you'll run into issues if you try this with a normal HID. However, there is a project called the USB Rubber Ducky. From their description:
The USB Rubber Ducky isn't your ordinary HID (Human Interface Device).
Coupled with a powerful 60 MHz 32-bit processor and a simple scripting language
The USB Rubber Ducky looks like a usb-device and is recognized as a HID, but is programmable. You can make a small script that will be typed onto the screen which will allow you to performs the queries you seek.
With the USB Rubber Ducky you can:
Read data from a form on the screen? Yes
Find out what OS the user is on? Yes
Find out if there's been an error message? Yes
Even 'know' what's going on visually on the screen, i.e. what program is selected or whether the program is windowed or fullscreen? Yes
If you aren't hoping to buy this device, at least their firmware is on github so it can provide you a starting point

pcsc-lite : multiple ACR122T devices with no unique serial number - linux

I have multiple ACR122T smart card devices with no unique serial numbers (from ACS). I need to know which physical smart card I am connected to from within pcsc-lite. I know from using lsusb which USB Port a physical device is on, but how to map that USB port information with SCardGetAttribute(SCARD_ATTR_DEVICE_UNIT) ?
It seems the map should be at the OS level as I cant find a way to read USB Port info (lsusb results) from within the pscs-lite API.
This post mentions a method, Smartcard reader ACR122U has no unique serial number
but I dont understand the details behind "used that dev number to ensure I always used the right reader".
Any help appreciated.
Thanks, -Phil
Disclaimer: I'm working on Windows, not Linux.
The ACR122T (and ACR122U) devices not only have no serial number (other than the one printed on the back) but also have no USB serial number so that they can only be differentiated by the USB port they are plugged in. Additionally all the ACR122Ts and Us I have here (we bought a bunch) identify themselves as "ACS ACR122" to Windows. Using the proprietary API to get the firmware version both the ACR122T and the ACR122U identify themselves as a ACR122U (e.g. "ACR122U207" or "ACR122U214").
That means that the OS itself is not able to differentiate multiple devices in any other way then the USB port it's plugged in.
I also tried to make a connection between the pcsc device and the OS device, but apart from this function (which is only available starting Windows 8) I have not found anything, so it looks to me like there is no way to do that through pcsc calls.
The device unit is given out by the pcsc layer sequentially so you can differentiate between devices you are connected to but not identify a specific device.

How to send keystrokes from one computer to another by USB?

Is there a way to use one computer to send keystrokes to another by usb ?
What i'm looking to do is to capture the usb signal used by a keyboard (with USBTrace for example) and use it with PC-1 to send it to PC-2.
So that PC-2 reconize it as a regular keyboard input.
Some leads to do this would be very appreciated.
What you essentially need is a USB port on PC-1 that will act as a USB device for PC-2.
That is not possible for the vast majority of PC systems because USB is an asymmetric bus, with a host/device (or master/slave, if you wish) architecture. USB controllers (and their ports) on most PCs can only work in host mode and cannot simulate a device.
That is the reason that you cannot network computers through USB without a special cable with specialised electronics.
The only exception is if you somehow have a PC that supports the USB On-The-Go standard that allows for a USB port to act in both host and device mode. USB-OTG devices do exist, but they are usually embedded devices (smartphones etc). I don't know if there is a way to add a USB-OTG port to a commodity PC.
EDIT:
If you do not need a keyboard before the OS on PC-2 boots, you might be able to use a pair of USB Bluetooth dongles - one on each PC. You'd have to use specialised software on PC-1, but it is definitely possible - I've already seen a possible implementation on Linux, and I am reasonably certain that there must be one for Windows. You will also need Bluetooth HID drivers on PC-2, if they are not already installed.
On a different note, have you considered a purely software/network solution such as TightVNC?
There is a solution:
https://github.com/Flowm/etherkey
This uses a network connection from your computer to the raspi which is connected to a teensy (usb developer board) to send the key strokes.
This solution is not an out-of-the-box product. The required skill is similar to programming some other devices like arduino. But it's a complete and working setup.
The cheapest options are commercial microcontrollers (eg arduino platform, pic, etc) or ready built usb keyboard controllers (eg i-pac, arcade controllers,etc)
SEARCH THIS PROGRAM:
TWedge: Keyboard Wedge Software (RS232, Serial, TCP, Bluetooth)
then, MAKE YOUR OWN CONNECTION CABLE WITH:
(usb <-> rs232) + (NULL MODEM) + (rs232 <-> usb)
Connect 2 computer, write your own program to send signal to your (usb <-> rs232) unit, then you can control another computer under the help of TWedge.
The above mentionned https://github.com/Flowm/etherkey is one way. The keyboard is emulated from an rPi, but the principle can be used from PC to PC (or Mac to Whatever). The core answer to your question is to use an OTG-capable chip, and then you control this chip via a USB-serial adapter.
https://euer.krebsco.de/a-software-kvm-switch.html
uses a very similar method, using an Arduino instead of the Teensy.
The generic answer is: you need an OTG capable, or slave capable device: Arduino, Teensy, Pi 0 (either from Rapberry or Orange brands, both work; only the ZERO models are OTG capable), or, an rPi-A with heavy customisation (since it does not include USB hub, it can theoretically be converted into a slave; never found any public tutorial to do it), or any smartphone (Samsung, Nokia, HTC, Oukitel ... most smartphones are OTG capable). If you go for a Pi or a phone, then, you want to dig around USB Gadget. Cheaper solutions (Arduino/Teensy) need custom firmware.

Resources