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 | |
8 | SEC("fmod_ret/hid_bpf_device_event" ) |
9 | int 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 | |
54 | SEC("fmod_ret/hid_bpf_device_event" ) |
55 | int 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 | |
72 | SEC("fmod_ret/hid_bpf_rdesc_fixup" ) |
73 | int 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 | |
112 | char _license[] SEC("license" ) = "GPL" ; |
113 | |