1// SPDX-License-Identifier: GPL-2.0
2
3#include "vmlinux.h"
4#include <bpf/bpf_helpers.h>
5#include <bpf/bpf_tracing.h>
6#include "hid_bpf_helpers.h"
7
8SEC("fmod_ret/hid_bpf_device_event")
9int BPF_PROG(hid_y_event, struct hid_bpf_ctx *hctx)
10{
11 s16 y;
12 __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */);
13
14 if (!data)
15 return 0; /* EPERM check */
16
17 bpf_printk("event: size: %d", hctx->size);
18 bpf_printk("incoming event: %02x %02x %02x",
19 data[0],
20 data[1],
21 data[2]);
22 bpf_printk(" %02x %02x %02x",
23 data[3],
24 data[4],
25 data[5]);
26 bpf_printk(" %02x %02x %02x",
27 data[6],
28 data[7],
29 data[8]);
30
31 y = data[3] | (data[4] << 8);
32
33 y = -y;
34
35 data[3] = y & 0xFF;
36 data[4] = (y >> 8) & 0xFF;
37
38 bpf_printk("modified event: %02x %02x %02x",
39 data[0],
40 data[1],
41 data[2]);
42 bpf_printk(" %02x %02x %02x",
43 data[3],
44 data[4],
45 data[5]);
46 bpf_printk(" %02x %02x %02x",
47 data[6],
48 data[7],
49 data[8]);
50
51 return 0;
52}
53
54SEC("fmod_ret/hid_bpf_device_event")
55int BPF_PROG(hid_x_event, struct hid_bpf_ctx *hctx)
56{
57 s16 x;
58 __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */);
59
60 if (!data)
61 return 0; /* EPERM check */
62
63 x = data[1] | (data[2] << 8);
64
65 x = -x;
66
67 data[1] = x & 0xFF;
68 data[2] = (x >> 8) & 0xFF;
69 return 0;
70}
71
72SEC("fmod_ret/hid_bpf_rdesc_fixup")
73int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hctx)
74{
75 __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 4096 /* size */);
76
77 if (!data)
78 return 0; /* EPERM check */
79
80 bpf_printk("rdesc: %02x %02x %02x",
81 data[0],
82 data[1],
83 data[2]);
84 bpf_printk(" %02x %02x %02x",
85 data[3],
86 data[4],
87 data[5]);
88 bpf_printk(" %02x %02x %02x ...",
89 data[6],
90 data[7],
91 data[8]);
92
93 /*
94 * The original report descriptor contains:
95 *
96 * 0x05, 0x01, // Usage Page (Generic Desktop) 30
97 * 0x16, 0x01, 0x80, // Logical Minimum (-32767) 32
98 * 0x26, 0xff, 0x7f, // Logical Maximum (32767) 35
99 * 0x09, 0x30, // Usage (X) 38
100 * 0x09, 0x31, // Usage (Y) 40
101 *
102 * So byte 39 contains Usage X and byte 41 Usage Y.
103 *
104 * We simply swap the axes here.
105 */
106 data[39] = 0x31;
107 data[41] = 0x30;
108
109 return 0;
110}
111
112char _license[] SEC("license") = "GPL";
113

source code of linux/samples/hid/hid_mouse.bpf.c