// SPDX-License-Identifier: GPL-2.0
// test ir decoder
//
// Copyright (C) 2018 Sean Young <sean@mess.org>

// When sending LIRC_MODE_SCANCODE, the IR will be encoded. rc-loopback
// will send this IR to the receiver side, where we try to read the decoded
// IR. Decoding happens in a separate kernel thread, so we will need to
// wait until that is scheduled, hence we use poll to check for read
// readiness.

#include <linux/lirc.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <poll.h>
#include <time.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "../kselftest.h"

#define TEST_SCANCODES	10
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))

static const struct {
	enum rc_proto proto;
	const char *name;
	unsigned int mask;
	const char *decoder;
} protocols[] = {
	{ RC_PROTO_RC5, "rc-5", 0x1f7f, "rc-5" },
	{ RC_PROTO_RC5X_20, "rc-5x-20", 0x1f7f3f, "rc-5" },
	{ RC_PROTO_RC5_SZ, "rc-5-sz", 0x2fff, "rc-5-sz" },
	{ RC_PROTO_JVC, "jvc", 0xffff, "jvc" },
	{ RC_PROTO_SONY12, "sony-12", 0x1f007f, "sony" },
	{ RC_PROTO_SONY15, "sony-15", 0xff007f, "sony" },
	{ RC_PROTO_SONY20, "sony-20", 0x1fff7f, "sony" },
	{ RC_PROTO_NEC, "nec", 0xffff, "nec" },
	{ RC_PROTO_NECX, "nec-x", 0xffffff, "nec" },
	{ RC_PROTO_NEC32, "nec-32", 0xffffffff, "nec" },
	{ RC_PROTO_SANYO, "sanyo", 0x1fffff, "sanyo" },
	{ RC_PROTO_RC6_0, "rc-6-0", 0xffff, "rc-6" },
	{ RC_PROTO_RC6_6A_20, "rc-6-6a-20", 0xfffff, "rc-6" },
	{ RC_PROTO_RC6_6A_24, "rc-6-6a-24", 0xffffff, "rc-6" },
	{ RC_PROTO_RC6_6A_32, "rc-6-6a-32", 0xffffffff, "rc-6" },
	{ RC_PROTO_RC6_MCE, "rc-6-mce", 0x00007fff, "rc-6" },
	{ RC_PROTO_SHARP, "sharp", 0x1fff, "sharp" },
};

int lirc_open(const char *rc)
{
	struct dirent *dent;
	char buf[100];
	DIR *d;
	int fd;

	snprintf(buf, sizeof(buf), "/sys/class/rc/%s", rc);

	d = opendir(buf);
	if (!d)
		ksft_exit_fail_msg("cannot open %s: %m\n", buf);

	while ((dent = readdir(d)) != NULL) {
		if (!strncmp(dent->d_name, "lirc", 4)) {
			snprintf(buf, sizeof(buf), "/dev/%s", dent->d_name);
			break;
		}
	}

	if (!dent)
		ksft_exit_fail_msg("cannot find lirc device for %s\n", rc);

	closedir(d);

	fd = open(buf, O_RDWR | O_NONBLOCK);
	if (fd == -1)
		ksft_exit_fail_msg("cannot open: %s: %m\n", buf);

	return fd;
}

int main(int argc, char **argv)
{
	unsigned int mode;
	char buf[100];
	int rlircfd, wlircfd, protocolfd, i, n;

	srand(time(NULL));

	if (argc != 3)
		ksft_exit_fail_msg("Usage: %s <write rcN> <read rcN>\n",
				   argv[0]);

	rlircfd = lirc_open(argv[2]);
	mode = LIRC_MODE_SCANCODE;
	if (ioctl(rlircfd, LIRC_SET_REC_MODE, &mode))
		ksft_exit_fail_msg("failed to set scancode rec mode %s: %m\n",
				   argv[2]);

	wlircfd = lirc_open(argv[1]);
	if (ioctl(wlircfd, LIRC_SET_SEND_MODE, &mode))
		ksft_exit_fail_msg("failed to set scancode send mode %s: %m\n",
				   argv[1]);

	snprintf(buf, sizeof(buf), "/sys/class/rc/%s/protocols", argv[2]);
	protocolfd = open(buf, O_WRONLY);
	if (protocolfd == -1)
		ksft_exit_fail_msg("failed to open %s: %m\n", buf);

	printf("Sending IR on %s and receiving IR on %s.\n", argv[1], argv[2]);

	for (i = 0; i < ARRAY_SIZE(protocols); i++) {
		if (write(protocolfd, protocols[i].decoder,
			  strlen(protocols[i].decoder)) == -1)
			ksft_exit_fail_msg("failed to set write decoder\n");

		printf("Testing protocol %s for decoder %s (%d/%d)...\n",
		       protocols[i].name, protocols[i].decoder,
		       i + 1, (int)ARRAY_SIZE(protocols));

		for (n = 0; n < TEST_SCANCODES; n++) {
			unsigned int scancode = rand() & protocols[i].mask;
			unsigned int rc_proto = protocols[i].proto;

			if (rc_proto == RC_PROTO_RC6_MCE)
				scancode |= 0x800f0000;

			if (rc_proto == RC_PROTO_NECX &&
			    (((scancode >> 16) ^ ~(scancode >> 8)) & 0xff) == 0)
				continue;

			if (rc_proto == RC_PROTO_NEC32 &&
			    (((scancode >> 8) ^ ~scancode) & 0xff) == 0)
				continue;

			struct lirc_scancode lsc = {
				.rc_proto = rc_proto,
				.scancode = scancode
			};

			printf("Testing scancode:%x\n", scancode);

			while (write(wlircfd, &lsc, sizeof(lsc)) < 0) {
				if (errno == EINTR)
					continue;

				ksft_exit_fail_msg("failed to send ir: %m\n");
			}

			struct pollfd pfd = { .fd = rlircfd, .events = POLLIN };
			struct lirc_scancode lsc2;

			poll(&pfd, 1, 1000);

			bool decoded = true;

			while (read(rlircfd, &lsc2, sizeof(lsc2)) < 0) {
				if (errno == EINTR)
					continue;

				ksft_test_result_error("no scancode decoded: %m\n");
				decoded = false;
				break;
			}

			if (!decoded)
				continue;

			if (lsc.rc_proto != lsc2.rc_proto)
				ksft_test_result_error("decoded protocol is different: %d\n",
						       lsc2.rc_proto);

			else if (lsc.scancode != lsc2.scancode)
				ksft_test_result_error("decoded scancode is different: %llx\n",
						       lsc2.scancode);
			else
				ksft_inc_pass_cnt();
		}

		printf("OK\n");
	}

	close(rlircfd);
	close(wlircfd);
	close(protocolfd);

	if (ksft_get_fail_cnt() > 0)
		ksft_exit_fail();
	else
		ksft_exit_pass();

	return 0;
}
