* UHID Device Reports Do Not Generate OS Activity
@ 2018-02-10 9:33 R0b0t1
2018-02-11 19:46 ` Roderick Colenbrander
0 siblings, 1 reply; 3+ messages in thread
From: R0b0t1 @ 2018-02-10 9:33 UTC (permalink / raw)
To: linux-input, linux-usb
[-- Attachment #1: Type: text/plain, Size: 559 bytes --]
Hello,
I am trying to simulate a keyboard using the uhid interface. The fake
device shows up in dmesg, but attempting to press the "a" key does
nothing I can see. No input appears in the active terminal, nor in an
xev window.
The program receives UHID_OPEN, UHID_START, and UHID_CLOSE.
Many different report descriptors were tried. The one currently
uncommented is the one distributed with the USB implementor forum's
HID report descriptor tool. The other is one found in a description of
a boot device compatible keyboard.
Thanks in advance,
R0b0t1
[-- Attachment #2: kbd.c --]
[-- Type: text/x-csrc, Size: 4931 bytes --]
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <sys/ioctl.h>
#include <linux/uhid.h>
#define handle_error(m) \
do { perror(m); exit(EXIT_FAILURE); } while (0)
static unsigned char rdesc[] = {
0x05, 0x01,
0x09, 0x06,
0xa1, 0x01,
0x05, 0x07,
0x19, 0xe0,
0x29, 0xe7,
0x15, 0x00,
0x25, 0x01,
0x75, 0x01,
0x95, 0x08,
0x81, 0x02,
0x95, 0x01,
0x75, 0x08,
0x81, 0x03,
0x95, 0x05,
0x75, 0x01,
0x05, 0x08,
0x19, 0x01,
0x29, 0x05,
0x91, 0x02,
0x95, 0x01,
0x75, 0x03,
0x91, 0x03,
0x95, 0x06,
0x75, 0x08,
0x15, 0x00,
0x25, 0x65,
0x05, 0x07,
0x19, 0x00,
0x29, 0x65,
0x81, 0x00,
0xc0
};
/*
static unsigned char rdesc[] = {
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x06, // Usage (Keyboard)
0xa1, 0x01, // Collection (Application)
// Modifier report.
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x05, 0x07, // Usage Page (Key Codes)
0x19, 0xe0, // Usage Minimum (224)
0x29, 0xe7, // Usage Maximum (231)
0x15, 0x00, // Logical Minimum (0) - Shorten (0x14)?
0x25, 0x01, // Logical Maximum (1)
0x81, 0x02, // Input (Data, Variable, Absolute)
// Reserved byte.
0x95, 0x01, // Report Count (1)
0x75, 0x08, // Report Size (8)
0x81, 0x01, // Input (Constant)
// LED report.
0x95, 0x05, // Report Count (5)
0x75, 0x01, // Report Size (1)
0x05, 0x08, // Usage Page (LEDs)
0x19, 0x01, // Usage Minimum (1)
0x29, 0x05, // Usage Maximum (5)
0x91, 0x02, // Output (Data, Variable, Absolute)
// LED report padding.
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x91, 0x01, // Output (Constant)
// Key code report.
0x95, 0x06, // Report Count (6)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xff, 0x00, // Logical Maximum (255)
0x05, 0x07, // Usage Page (Key Codes)
0x19, 0x00, // Usage Minimum (0)
0x29, 0xff, // Usage Maximum (255)
0x81, 0x00, // Input (Data, Array)
0xc0 // End Collection
};
*/
static int
uhid_write(int fd, const struct uhid_event *he)
{
ssize_t r = write(fd, he, sizeof(*he));
if (r < 0) {
fprintf(stderr, "write: cannot write to uhid: %m\n");
return -errno;
} else if (r != sizeof(*he)) {
fprintf(stderr, "write: wrong size written to uhid: %ld != %lu\n",
r, sizeof(*he));
return -EFAULT;
} else return 0;
}
static int
uhid_event(int fd)
{
struct uhid_event he;
ssize_t sz;
if ((sz = read(fd, &he, sizeof(he))) == -1)
handle_error("read");
switch (he.type) {
case UHID_START:
fprintf(stderr, "UHID_START from uhid-dev.\n");
break;
case UHID_STOP:
fprintf(stderr, "UHID_STOP from uhid-dev.\n");
break;
case UHID_OPEN:
fprintf(stderr, "UHID_OPEN from uhid-dev.\n");
return 0;
case UHID_CLOSE:
fprintf(stderr, "UHID_CLOSE from uhid-dev.\n");
break;
case UHID_OUTPUT:
fprintf(stderr, "UHID_OUTPUT from uhid-dev.\n");
// TODO: Handle output.
break;
case UHID_OUTPUT_EV:
fprintf(stderr, "UHID_OUTPUT_EV from uhid-dev.\n");
break;
default:
fprintf(stderr, "Invalid event from uhid-dev: %u.\n", he.type);
}
return 1;
}
int
main(int argc, char *argv[])
{
int fd;
ssize_t sz;
struct uhid_event he;
if ((fd = open("/dev/uhid", O_RDWR | O_CLOEXEC)) == -1)
handle_error("open");
struct pollfd fds[1] = {
{.fd = fd, .events = POLLIN}
};
memset(&he, 0, sizeof(he));
he.type = UHID_CREATE2;
strcpy((char *)he.u.create.name, "kb-daemon-device");
memcpy(he.u.create2.rd_data, rdesc, sizeof(rdesc));
he.u.create2.rd_size = sizeof(rdesc);
he.u.create2.bus = BUS_USB;
he.u.create2.vendor = 0x15d9;
he.u.create2.product = 0x0a37;
he.u.create2.version = 0;
he.u.create2.country = 0;
if (uhid_write(fd, &he))
handle_error("uhid_write");
char cont = 1;
while (cont) {
int n = ppoll(fds, sizeof(fds), NULL, NULL);
if (n == -1)
handle_error("ppoll");
for (int i = 0; i < n; i++) {
if (fds[i].fd == fd &&
fds[i].revents & POLLIN)
cont = uhid_event(fds[i].fd);
}
}
memset(&he, 0, sizeof(he));
he.type = UHID_INPUT2;
he.u.input2.size = 8;
he.u.input2.data[0] = 0x00;
he.u.input2.data[1] = 0x00;
he.u.input2.data[2] = 0x04;
he.u.input2.data[3] = 0x00;
he.u.input2.data[4] = 0x00;
he.u.input2.data[5] = 0x00;
he.u.input2.data[6] = 0x00;
he.u.input2.data[7] = 0x00;
if (uhid_write(fd, &he))
handle_error("uhid_write");
memset(&he, 0, sizeof(he));
he.type = UHID_INPUT2;
he.u.input2.size = 8;
he.u.input2.data[0] = 0x00;
he.u.input2.data[1] = 0x00;
he.u.input2.data[2] = 0x00;
he.u.input2.data[3] = 0x00;
he.u.input2.data[4] = 0x00;
he.u.input2.data[5] = 0x00;
he.u.input2.data[6] = 0x00;
he.u.input2.data[7] = 0x00;
if (uhid_write(fd, &he))
handle_error("uhid_write");
memset(&he, 0, sizeof(he));
he.type = UHID_DESTROY;
if (uhid_write(fd, &he))
handle_error("uhid_write");
uhid_event(fd);
return EXIT_SUCCESS;
}
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: UHID Device Reports Do Not Generate OS Activity
2018-02-10 9:33 UHID Device Reports Do Not Generate OS Activity R0b0t1
@ 2018-02-11 19:46 ` Roderick Colenbrander
[not found] ` <CAEc3jaAyQiNDLbOvNkT65n-Vju-LOHjoSuiOqDunBFna0YDaBQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 3+ messages in thread
From: Roderick Colenbrander @ 2018-02-11 19:46 UTC (permalink / raw)
To: R0b0t1; +Cc: linux-input, linux-usb
It is hard to say what is wrong. I would start with reading the uhid /
hid code and see where you are getting stuck (and double check uhid
docs). Even for others we would need to do that as it is not easy to
see what is wrong.
I'm not sure what your goal is obvious you want to simulate a keyboard
for some purpose, but do you really need to operate at the HID layer?
If not it is much more convenient to use uinput, which will create a
evdev device for you.
Thanks,
Roderick
On Sat, Feb 10, 2018 at 1:33 AM, R0b0t1 <r030t1@gmail.com> wrote:
> Hello,
>
> I am trying to simulate a keyboard using the uhid interface. The fake
> device shows up in dmesg, but attempting to press the "a" key does
> nothing I can see. No input appears in the active terminal, nor in an
> xev window.
>
> The program receives UHID_OPEN, UHID_START, and UHID_CLOSE.
>
> Many different report descriptors were tried. The one currently
> uncommented is the one distributed with the USB implementor forum's
> HID report descriptor tool. The other is one found in a description of
> a boot device compatible keyboard.
>
> Thanks in advance,
> R0b0t1
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2018-02-11 20:22 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-02-10 9:33 UHID Device Reports Do Not Generate OS Activity R0b0t1
2018-02-11 19:46 ` Roderick Colenbrander
[not found] ` <CAEc3jaAyQiNDLbOvNkT65n-Vju-LOHjoSuiOqDunBFna0YDaBQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-02-11 20:22 ` R0b0t1
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).