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

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.

Related

Establish a connection between smartphone and PC via Bluetooth automatically

I'm trying to establish a connection between my PC running Ubuntu and my iPhone via Bluetooth automatically when it becomes available, after being manually paired beforehand. I've seen this to be possible with certain peripherals, mainly audio. For example, my phone will automatically connect to a Bluetooth speaker when it is turned on and Bluetooth is active on my phone; another example is my phone automatically connects to my car's radio system via Bluetooth when I turn the car on.
I'm not able to connect my phone to my PC without first initiating the connection from the smartphone's Bluetooth menu. I'm thinking that I could possibly write an application for the PC to attempt to connect to the device every few minutes or something, but it seems that the phone needs to be the device to initiate the connection.
The only information that I need for what I'm trying to do ultimately is that the devices can pair successfully. Essentially I'm trying to build a sort of proximity trigger between my phone and my PC without using Wi-Fi and GPS - I can't use these for some specific reasons.
Is there any way to make this happen?
Yes this should be doable as long as you use the Background Processing feature for iOS apps. In the example I'll give below, we'll have the PC be the peripheral and the phone be the central, but you can really have it working either way. You will need to do the following:-
First initial connection needs to be performed in the foreground (this is due to iOS's background limitations).
On the iOS side, you need an application that acts as a central that scans and connects to the remove device (check this example as a starting point).
Upon connection, you need to bond with the PC. Bonding is important as it will prevent you from having to do the pairing again in the future. However, pairing/bonding is managed by the iPhone's OS so you cannot write it in your application, so the workaround is to have an encrypted characteristic on the PC side that will force the iPhone to bond (this is covered later).
On the PC side, you need to have a BlueZ script that acts as a peripheral that is always advertising. You can do this using bluetoothctl (check the examples here and here).
Before you start advertising, you need to have a GATT server on the PC side (to do this, check this example).
When registering characteristics, ensure that one of them has the encrypt-read property (you can find a full list of the properties here).
Now when you attempt to read this characteristic from the iOS side, the two devices should bond (make sure that your PC is bondable which you can do this via these commands).
Once the devices are paired, your iOS app needs to be working in the background constantly scanning and attempting to connect to the same peripheral (have a look at this and this example).
You can find more useful information at the links below:-
Getting started with Bluetooth Low Energy
The Ultimate Guide to CoreBluetooth Development
How to manage Bluetooth devices on Linux using bluetoothctl

Sending Control Commands to USB Barcode Reader

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.

Device to divert printing to PDF

I'm trying to build a device that is inserted between a client and a printer.
In the normal case this device should just allow the printing to occur as normal, but if a certain event happens it should instead divert the printing to a PDF file on disk.
In essence it should work as a print server that can decide where to send the data to be printed.
The problem is that I want to achieve this using an USB-A to USB-A cable between the client and the device, and the printer via USB to the device.
The device is at the moment a Raspberry Pie running Raspbian.
Printing from the Pie is tested using CUPS, so that works.
Now for the question(s):
How can I allow printing via USB cable from the client? Simply connecting the device and the client does not allow it to be recognised as a printer. CUPS does not seem to support this sharing option.
Can CUPS be configured to support sharing via USB?
Is there any other print software that supports this?
Is there another OS where this could be achieved easier?
Any input is appreciated!

How to receive continuous data from usb endpoint in Linux device driver

I'm writing a usb device driver for a data acquisition device in Ubuntu 16.04.
The data acquisition device is currently working in Windows and the manufacturer only provides the driver for Windows and I need it to be working in Linux.
So, to do the reverse engineering, I captured the data with Wireshark in Windows.
I figured out all the setup urbs and I can send data to the data acquisition device and works well but the problem is to receive the data.
It seems that there are continuous(periodic) data coming from endpoints 1 and 3(which are the bulk in endpoints). In Windows, there doesn't seem to be any request packet going to the usb device to receive the data from endpoints 1 and 3 but in Linux, the data is received only when I send some kind of request(for example, read file operation).
I've found that there is something called "Continuous Reader" in Windows, but I can't find any hint in Linux for reading continuous data from usb device.
https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/how-to-use-the-continous-reader-for-getting-data-from-a-usb-endpoint--umdf-
I would really appreciate your help, Thank you!
Are you sure the device doesn't have an intr-IN endpoint to announce availability of data, which is then fetched using bulk IN transfers? How does it configure EP2, which I assume is interrupt? If you use something like libusb you may need to set up an interrupt poller based on the intr-EP description.

Arduino Bluetooth N64 Controller - Writing a Linux Driver?

I'm working on a little Arduino project to create a bluetooth N64 joystick for my Ubuntu box.
I managed to find a sketch to output the controllers state via serial and it works great. Also sending the TX and RX to the little CSR bluetooth module I have works fine.
When I pair with the device I have to use "rfcomm bind" to see the device in my dev directory and 'cat'ing the output shows all the data is coming through as well.
My question is this, what are my next steps for getting Linux to recognize this device as a joystick - i.e. /dev/js0. If I know what I need to do to achieve this I can read up on the necessary steps but at the moment I have absolutely no clue where to start - having not done anything like this in the past. Should I be looking into creating a Kernel Module?
Any information or pokes in the right direction at all would be greatly appreciated - even if it's just an observation.
Writing custom kernel code is definitely not the way to go here.
To make your project appear as a joystick device in Linux you'll want to present it using the Bluetooth HID profile. With that in place everything should "just work" on the client side and you'll see an entry in /dev. The HID profile is pretty comprehensive and is used by most Bluetooth interface devices - keyboards, mice, game controllers etc. the Bluetooth part of this is actually mostly just a thin wrapper around the USB HID protocol.
From the sounds of things your device is currently not advertising itself using that profile.

Resources