/*
 * pnphctl.c -- userland scenario driver for the DF-2316 pnpparse.c
 * harness (/dev/pnph0).  Usage: pnphctl <scenario> [arg]
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <err.h>
#include <sys/ioctl.h>
#include "pnph.h"

static void
pr_req(struct pnph_req *r)
{
	int i;

	printf("  rc=%u tag=%s declared=%u need=%u attrib=%u pass=%u "
	    "nfields=%u child=%s\n", r->o_rc, r->o_tagname, r->o_declared,
	    r->o_needlen, r->o_attrib, r->o_pass, r->o_nfields, r->o_child);
	if (r->o_nfields) {
		printf("  fields:");
		for (i = 0; i < (int)r->o_nfields && i < 8; i++)
			printf(" [%d]=%#x/%#x", i, r->o_field[i],
			    r->o_expect[i]);
		printf("\n");
	}
	if (r->o_chunk1 || r->o_chunk2)
		printf("  chunk1=%016llx chunk2=%016llx wrote=%u\n",
		    (unsigned long long)r->o_chunk1,
		    (unsigned long long)r->o_chunk2, r->o_wrote);
	if (r->o_before[0] || r->o_after[0]) {
		printf("  canary before:");
		for (i = 0; i < 8; i++)
			printf(" %02x", r->o_before[i]);
		printf(" after:");
		for (i = 0; i < 8; i++)
			printf(" %02x", r->o_after[i]);
		printf("\n");
	}
	if (r->o_leakraw[0]) {
		printf("  leakraw:");
		for (i = 0; i < 8; i++)
			printf(" %08x", r->o_leakraw[i]);
		printf("\n");
	}
}

int
main(int argc, char **argv)
{
	struct pnph_req r;
	int fd, sc, arg = 0;

	if (argc < 2) {
		fprintf(stderr, "usage: %s <scenario> [arg]\n", argv[0]);
		return (2);
	}
	sc = atoi(argv[1]);
	if (argc > 2)
		arg = atoi(argv[2]);

	memset(&r, 0, sizeof(r));
	r.scenario = (uint32_t)sc;
	r.arg = (uint32_t)arg;

	fd = open("/dev/pnph0", O_RDWR);
	if (fd < 0)
		err(1, "open /dev/pnph0");
	if (ioctl(fd, PNPHIOC_RUN, &r) < 0)
		err(1, "ioctl scenario %d", sc);
	printf("SC %d arg=%d:", sc, arg);
	pr_req(&r);
	return (r.o_rc ? 1 : 0);
}
