| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- // SPDX-License-Identifier: GPL-2.0
- #include "vmlinux.h"
- #include <bpf/bpf_helpers.h>
- #include <bpf/bpf_tracing.h>
- #include "hid_bpf_helpers.h"
- static int hid_y_event(struct hid_bpf_ctx *hctx)
- {
- s16 y;
- __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */);
- if (!data)
- return 0; /* EPERM check */
- bpf_printk("event: size: %d", hctx->size);
- bpf_printk("incoming event: %02x %02x %02x",
- data[0],
- data[1],
- data[2]);
- bpf_printk(" %02x %02x %02x",
- data[3],
- data[4],
- data[5]);
- bpf_printk(" %02x %02x %02x",
- data[6],
- data[7],
- data[8]);
- y = data[3] | (data[4] << 8);
- y = -y;
- data[3] = y & 0xFF;
- data[4] = (y >> 8) & 0xFF;
- bpf_printk("modified event: %02x %02x %02x",
- data[0],
- data[1],
- data[2]);
- bpf_printk(" %02x %02x %02x",
- data[3],
- data[4],
- data[5]);
- bpf_printk(" %02x %02x %02x",
- data[6],
- data[7],
- data[8]);
- return 0;
- }
- static int hid_x_event(struct hid_bpf_ctx *hctx)
- {
- s16 x;
- __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */);
- if (!data)
- return 0; /* EPERM check */
- x = data[1] | (data[2] << 8);
- x = -x;
- data[1] = x & 0xFF;
- data[2] = (x >> 8) & 0xFF;
- return 0;
- }
- SEC("struct_ops/hid_device_event")
- int BPF_PROG(hid_event, struct hid_bpf_ctx *hctx, enum hid_report_type type)
- {
- int ret = hid_y_event(hctx);
- if (ret)
- return ret;
- return hid_x_event(hctx);
- }
- SEC("struct_ops/hid_rdesc_fixup")
- int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hctx)
- {
- __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 4096 /* size */);
- if (!data)
- return 0; /* EPERM check */
- bpf_printk("rdesc: %02x %02x %02x",
- data[0],
- data[1],
- data[2]);
- bpf_printk(" %02x %02x %02x",
- data[3],
- data[4],
- data[5]);
- bpf_printk(" %02x %02x %02x ...",
- data[6],
- data[7],
- data[8]);
- /*
- * The original report descriptor contains:
- *
- * 0x05, 0x01, // Usage Page (Generic Desktop) 30
- * 0x16, 0x01, 0x80, // Logical Minimum (-32767) 32
- * 0x26, 0xff, 0x7f, // Logical Maximum (32767) 35
- * 0x09, 0x30, // Usage (X) 38
- * 0x09, 0x31, // Usage (Y) 40
- *
- * So byte 39 contains Usage X and byte 41 Usage Y.
- *
- * We simply swap the axes here.
- */
- data[39] = 0x31;
- data[41] = 0x30;
- return 0;
- }
- SEC(".struct_ops.link")
- struct hid_bpf_ops mouse_invert = {
- .hid_rdesc_fixup = (void *)hid_rdesc_fixup,
- .hid_device_event = (void *)hid_event,
- };
- char _license[] SEC("license") = "GPL";
|