xref: /linux/samples/hid/hid_mouse.bpf.c (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
16008105bSBenjamin Tissoires // SPDX-License-Identifier: GPL-2.0
26008105bSBenjamin Tissoires 
36008105bSBenjamin Tissoires #include "vmlinux.h"
46008105bSBenjamin Tissoires #include <bpf/bpf_helpers.h>
56008105bSBenjamin Tissoires #include <bpf/bpf_tracing.h>
66008105bSBenjamin Tissoires #include "hid_bpf_helpers.h"
76008105bSBenjamin Tissoires 
hid_y_event(struct hid_bpf_ctx * hctx)8e342d6f6SBenjamin Tissoires static int hid_y_event(struct hid_bpf_ctx *hctx)
96008105bSBenjamin Tissoires {
106008105bSBenjamin Tissoires 	s16 y;
116008105bSBenjamin Tissoires 	__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */);
126008105bSBenjamin Tissoires 
136008105bSBenjamin Tissoires 	if (!data)
146008105bSBenjamin Tissoires 		return 0; /* EPERM check */
156008105bSBenjamin Tissoires 
166008105bSBenjamin Tissoires 	bpf_printk("event: size: %d", hctx->size);
176008105bSBenjamin Tissoires 	bpf_printk("incoming event: %02x %02x %02x",
186008105bSBenjamin Tissoires 		   data[0],
196008105bSBenjamin Tissoires 		   data[1],
206008105bSBenjamin Tissoires 		   data[2]);
216008105bSBenjamin Tissoires 	bpf_printk("                %02x %02x %02x",
226008105bSBenjamin Tissoires 		   data[3],
236008105bSBenjamin Tissoires 		   data[4],
246008105bSBenjamin Tissoires 		   data[5]);
256008105bSBenjamin Tissoires 	bpf_printk("                %02x %02x %02x",
266008105bSBenjamin Tissoires 		   data[6],
276008105bSBenjamin Tissoires 		   data[7],
286008105bSBenjamin Tissoires 		   data[8]);
296008105bSBenjamin Tissoires 
306008105bSBenjamin Tissoires 	y = data[3] | (data[4] << 8);
316008105bSBenjamin Tissoires 
326008105bSBenjamin Tissoires 	y = -y;
336008105bSBenjamin Tissoires 
346008105bSBenjamin Tissoires 	data[3] = y & 0xFF;
356008105bSBenjamin Tissoires 	data[4] = (y >> 8) & 0xFF;
366008105bSBenjamin Tissoires 
376008105bSBenjamin Tissoires 	bpf_printk("modified event: %02x %02x %02x",
386008105bSBenjamin Tissoires 		   data[0],
396008105bSBenjamin Tissoires 		   data[1],
406008105bSBenjamin Tissoires 		   data[2]);
416008105bSBenjamin Tissoires 	bpf_printk("                %02x %02x %02x",
426008105bSBenjamin Tissoires 		   data[3],
436008105bSBenjamin Tissoires 		   data[4],
446008105bSBenjamin Tissoires 		   data[5]);
456008105bSBenjamin Tissoires 	bpf_printk("                %02x %02x %02x",
466008105bSBenjamin Tissoires 		   data[6],
476008105bSBenjamin Tissoires 		   data[7],
486008105bSBenjamin Tissoires 		   data[8]);
496008105bSBenjamin Tissoires 
506008105bSBenjamin Tissoires 	return 0;
516008105bSBenjamin Tissoires }
526008105bSBenjamin Tissoires 
hid_x_event(struct hid_bpf_ctx * hctx)53e342d6f6SBenjamin Tissoires static int hid_x_event(struct hid_bpf_ctx *hctx)
546008105bSBenjamin Tissoires {
556008105bSBenjamin Tissoires 	s16 x;
566008105bSBenjamin Tissoires 	__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */);
576008105bSBenjamin Tissoires 
586008105bSBenjamin Tissoires 	if (!data)
596008105bSBenjamin Tissoires 		return 0; /* EPERM check */
606008105bSBenjamin Tissoires 
616008105bSBenjamin Tissoires 	x = data[1] | (data[2] << 8);
626008105bSBenjamin Tissoires 
636008105bSBenjamin Tissoires 	x = -x;
646008105bSBenjamin Tissoires 
656008105bSBenjamin Tissoires 	data[1] = x & 0xFF;
666008105bSBenjamin Tissoires 	data[2] = (x >> 8) & 0xFF;
676008105bSBenjamin Tissoires 	return 0;
686008105bSBenjamin Tissoires }
696008105bSBenjamin Tissoires 
70*a67a1debSBenjamin Tissoires SEC("struct_ops/hid_device_event")
BPF_PROG(hid_event,struct hid_bpf_ctx * hctx,enum hid_report_type type)71e342d6f6SBenjamin Tissoires int BPF_PROG(hid_event, struct hid_bpf_ctx *hctx, enum hid_report_type type)
72e342d6f6SBenjamin Tissoires {
73e342d6f6SBenjamin Tissoires 	int ret = hid_y_event(hctx);
74e342d6f6SBenjamin Tissoires 
75e342d6f6SBenjamin Tissoires 	if (ret)
76e342d6f6SBenjamin Tissoires 		return ret;
77e342d6f6SBenjamin Tissoires 
78e342d6f6SBenjamin Tissoires 	return hid_x_event(hctx);
79e342d6f6SBenjamin Tissoires }
80e342d6f6SBenjamin Tissoires 
81e342d6f6SBenjamin Tissoires 
82*a67a1debSBenjamin Tissoires SEC("struct_ops/hid_rdesc_fixup")
BPF_PROG(hid_rdesc_fixup,struct hid_bpf_ctx * hctx)836008105bSBenjamin Tissoires int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hctx)
846008105bSBenjamin Tissoires {
856008105bSBenjamin Tissoires 	__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 4096 /* size */);
866008105bSBenjamin Tissoires 
876008105bSBenjamin Tissoires 	if (!data)
886008105bSBenjamin Tissoires 		return 0; /* EPERM check */
896008105bSBenjamin Tissoires 
906008105bSBenjamin Tissoires 	bpf_printk("rdesc: %02x %02x %02x",
916008105bSBenjamin Tissoires 		   data[0],
926008105bSBenjamin Tissoires 		   data[1],
936008105bSBenjamin Tissoires 		   data[2]);
946008105bSBenjamin Tissoires 	bpf_printk("       %02x %02x %02x",
956008105bSBenjamin Tissoires 		   data[3],
966008105bSBenjamin Tissoires 		   data[4],
976008105bSBenjamin Tissoires 		   data[5]);
986008105bSBenjamin Tissoires 	bpf_printk("       %02x %02x %02x ...",
996008105bSBenjamin Tissoires 		   data[6],
1006008105bSBenjamin Tissoires 		   data[7],
1016008105bSBenjamin Tissoires 		   data[8]);
1026008105bSBenjamin Tissoires 
1036008105bSBenjamin Tissoires 	/*
1046008105bSBenjamin Tissoires 	 * The original report descriptor contains:
1056008105bSBenjamin Tissoires 	 *
1066008105bSBenjamin Tissoires 	 * 0x05, 0x01,                    //   Usage Page (Generic Desktop)      30
1076008105bSBenjamin Tissoires 	 * 0x16, 0x01, 0x80,              //   Logical Minimum (-32767)          32
1086008105bSBenjamin Tissoires 	 * 0x26, 0xff, 0x7f,              //   Logical Maximum (32767)           35
1096008105bSBenjamin Tissoires 	 * 0x09, 0x30,                    //   Usage (X)                         38
1106008105bSBenjamin Tissoires 	 * 0x09, 0x31,                    //   Usage (Y)                         40
1116008105bSBenjamin Tissoires 	 *
1126008105bSBenjamin Tissoires 	 * So byte 39 contains Usage X and byte 41 Usage Y.
1136008105bSBenjamin Tissoires 	 *
1146008105bSBenjamin Tissoires 	 * We simply swap the axes here.
1156008105bSBenjamin Tissoires 	 */
1166008105bSBenjamin Tissoires 	data[39] = 0x31;
1176008105bSBenjamin Tissoires 	data[41] = 0x30;
1186008105bSBenjamin Tissoires 
1196008105bSBenjamin Tissoires 	return 0;
1206008105bSBenjamin Tissoires }
1216008105bSBenjamin Tissoires 
122e342d6f6SBenjamin Tissoires SEC(".struct_ops.link")
123e342d6f6SBenjamin Tissoires struct hid_bpf_ops mouse_invert = {
124*a67a1debSBenjamin Tissoires 	.hid_rdesc_fixup = (void *)hid_rdesc_fixup,
125*a67a1debSBenjamin Tissoires 	.hid_device_event = (void *)hid_event,
126e342d6f6SBenjamin Tissoires };
127e342d6f6SBenjamin Tissoires 
1286008105bSBenjamin Tissoires char _license[] SEC("license") = "GPL";
129