/*
 * rfkill userspace tool
 */

#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/poll.h>
#include <sys/time.h>

#include "rfkill.h"
#include "core.h"

static void rfkill_event(void)
{
	struct rfkill_event event;
	struct timeval tv;
	struct pollfd p;
	ssize_t len;
	int fd, n;

	fd = open("/dev/rfkill", O_RDONLY);
	if (fd < 0) {
		perror("Can't open RFKILL control device");
		return;
	}

	memset(&p, 0, sizeof(p));
	p.fd = fd;
	p.events = POLLIN | POLLHUP;

	while (1) {
		n = poll(&p, 1, -1);
		if (n < 0) {
			perror("Failed to poll RFKILL control device");
			break;
		}

		if (n == 0)
			continue;

		len = read(fd, &event, sizeof(event));
		if (len < 0) {
			perror("Reading of RFKILL events failed");
			break;
		}

		if (len != RFKILL_EVENT_SIZE_V1) {
			fprintf(stderr, "Wrong size of RFKILL event\n");
			continue;
		}

		gettimeofday(&tv, NULL);
		printf("%ld.%06u: idx %u type %u op %u soft %u hard %u\n",
			(long) tv.tv_sec, (unsigned int) tv.tv_usec,
			event.idx, event.type, event.op, event.soft, event.hard);
		fflush(stdout);
	}

	close(fd);
}

static const char *get_name(__u32 idx)
{
	static char name[128];
	ssize_t len;
	char *pos, filename[64];
	int fd;

	snprintf(filename, sizeof(filename) - 1,
				"/sys/class/rfkill/rfkill%u/name", idx);

	fd = open(filename, O_RDONLY);
	if (fd < 0)
		return NULL;

	memset(name, 0, sizeof(name));
	len = read(fd, name, sizeof(name) - 1);

	pos = strchr(name, '\n');
	if (pos)
		*pos = '\0';

	close(fd);

	return name;
}

static const char *type2string(enum rfkill_type type)
{
	switch (type) {
	case RFKILL_TYPE_ALL:
		return "All";
	case RFKILL_TYPE_WLAN:
		return "Wireless LAN";
	case RFKILL_TYPE_BLUETOOTH:
		return "Bluetooth";
	case RFKILL_TYPE_UWB:
		return "Ultra-Wideband";
	case RFKILL_TYPE_WIMAX:
		return "WiMAX";
	case RFKILL_TYPE_WWAN:
		return "Wireless WAN";
	case RFKILL_TYPE_GPS:
		return "GPS";
	case RFKILL_TYPE_FM:
		return "FM";
	case NUM_RFKILL_TYPES:
		return NULL;
	}

	return NULL;
}

struct rfkill_type_str {
	enum rfkill_type type;
	const char *name;
};
static const struct rfkill_type_str rfkill_type_strings[] = {
	{	.type = RFKILL_TYPE_ALL,		.name = "all"	},
	{	.type = RFKILL_TYPE_WLAN,		.name = "wifi"	},
	{	.type = RFKILL_TYPE_WLAN,		.name = "wlan"	}, /* alias */
	{	.type = RFKILL_TYPE_BLUETOOTH,	.name = "bluetooth"	},
	{	.type = RFKILL_TYPE_UWB,		.name = "uwb"	},
	{	.type = RFKILL_TYPE_UWB,		.name = "ultrawideband"	}, /* alias */
	{	.type = RFKILL_TYPE_WIMAX,		.name = "wimax"	},
	{	.type = RFKILL_TYPE_WWAN,		.name = "wwan"	},
	{	.type = RFKILL_TYPE_GPS,		.name = "gps"	},
	{	.type = RFKILL_TYPE_FM,			.name = "fm"	},
	{	.name = NULL }
};

struct rfkill_id {
	union {
		enum rfkill_type type;
		__u32 index;
	};
	enum {
		RFKILL_IS_INVALID,
		RFKILL_IS_TYPE,
		RFKILL_IS_INDEX,
	} result;
};

static struct rfkill_id rfkill_id_to_type(const char *s)
{
	const struct rfkill_type_str *p;
	struct rfkill_id ret;

	if (islower(*s)) {
		for (p = rfkill_type_strings; p->name != NULL; p++) {
			if ((strlen(s) == strlen(p->name)) && (!strcmp(s,p->name))) {
				ret.type = p->type;
				ret.result = RFKILL_IS_TYPE;
				return ret;
			}
		}
	} else if (isdigit(*s)) {
		/* assume a numeric character implies an index. */
		ret.index = atoi(s);
		ret.result = RFKILL_IS_INDEX;
		return ret;
	}

	ret.result = RFKILL_IS_INVALID;
	return ret;
}

static int rfkill_list(const char *param)
{
	struct rfkill_id id = { .result = RFKILL_IS_INVALID };
	struct rfkill_event event;
	const char *name;
	ssize_t len;
	int fd;

	if (param) {
		id = rfkill_id_to_type(param);
		if (id.result == RFKILL_IS_INVALID) {
			fprintf(stderr, "Bogus %s argument '%s'.\n", "list", param);
			return 2;
		}
		/* don't filter "all" */
		if (id.result == RFKILL_IS_TYPE && id.type == RFKILL_TYPE_ALL)
			id.result = RFKILL_IS_INVALID;
	}

	fd = open("/dev/rfkill", O_RDONLY);
	if (fd < 0) {
		perror("Can't open RFKILL control device");
		return 1;
	}

	if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
		perror("Can't set RFKILL control device to non-blocking");
		close(fd);
		return 1;
	}

	while (1) {
		len = read(fd, &event, sizeof(event));
		if (len < 0) {
			if (errno == EAGAIN)
				break;
			perror("Reading of RFKILL events failed");
			break;
		}

		if (len != RFKILL_EVENT_SIZE_V1) {
			fprintf(stderr, "Wrong size of RFKILL event\n");
			continue;
		}

		if (event.op != RFKILL_OP_ADD)
			continue;

		/* filter out unwanted results */
		switch (id.result)
		{
		case RFKILL_IS_TYPE:
			if (event.type != id.type)
				continue;
			break;
		case RFKILL_IS_INDEX:
			if (event.idx != id.index)
				continue;
			break;
		case RFKILL_IS_INVALID:; /* must be last */
		}

		name = get_name(event.idx);

		printf("%u: %s: %s\n", event.idx, name,
						type2string(event.type));
		printf("\tSoft blocked: %s\n", event.soft ? "yes" : "no");
		printf("\tHard blocked: %s\n", event.hard ? "yes" : "no");
	}

	close(fd);
	return 0;
}

static int rfkill_block(__u8 block, const char *param)
{
	struct rfkill_id id;
	struct rfkill_event event;
	ssize_t len;
	int fd;

	id = rfkill_id_to_type(param);
	if (id.result == RFKILL_IS_INVALID) {
		fprintf(stderr, "Bogus %s argument '%s'.\n", block ? "block" : "unblock", param);
		return 2;
	}

	fd = open("/dev/rfkill", O_RDWR);
	if (fd < 0) {
		perror("Can't open RFKILL control device");
		return 1;
	}

	memset(&event, 0, sizeof(event));
	switch (id.result) {
	case RFKILL_IS_TYPE:
		event.op = RFKILL_OP_CHANGE_ALL;
		event.type = id.type;
		break;
	case RFKILL_IS_INDEX:
		event.op = RFKILL_OP_CHANGE;
		event.idx = id.index;
		break;
	case RFKILL_IS_INVALID:; /* must be last */
	}
	event.soft = block;

	len = write(fd, &event, sizeof(event));
	if (len < 0)
		perror("Failed to change RFKILL state");

	close(fd);
	return 0;
}

static const char *argv0;

static void usage(void)
{
	fprintf(stderr, "Usage:\t%s [options] command\n", argv0);
	fprintf(stderr, "Options:\n");
	fprintf(stderr, "\t--version\tshow version (%s)\n", rfkill_version);
	fprintf(stderr, "Commands:\n");
	fprintf(stderr, "\thelp\n");
	fprintf(stderr, "\tevent\n");
	fprintf(stderr, "\tlist [IDENTIFIER]\n");
	fprintf(stderr, "\tblock IDENTIFIER\n");
	fprintf(stderr, "\tunblock IDENTIFIER\n");
	fprintf(stderr, "where IDENTIFIER is the index no. of an rfkill switch or one of:\n");
	fprintf(stderr, "\t<idx> all wifi wlan bluetooth uwb ultrawideband wimax wwan gps\n");
}

static void version(void)
{
	printf("rfkill %s\n", rfkill_version);
}

int main(int argc, char **argv)
{
	int ret = 0;

	/* strip off self */
	argc--;
	argv0 = *argv++;

	if (argc > 0 && strcmp(*argv, "--version") == 0) {
		version();
		return 0;
	}

	if (argc == 0 || strcmp(*argv, "help") == 0) {
		usage();
		return 0;
	}

	if (strcmp(*argv, "event") == 0) {
		rfkill_event();
	} else if (strcmp(*argv, "list") == 0) {
		argc--;
		argv++;
		rfkill_list(*argv); /* NULL is acceptable */
	} else if (strcmp(*argv, "block") == 0 && argc > 1) {
		argc--;
		argv++;
		ret = rfkill_block(1,*argv);
	} else if (strcmp(*argv, "unblock") == 0 && argc > 1) {
		argc--;
		argv++;
		ret = rfkill_block(0,*argv);
	} else {
		usage();
		return 1;
	}

	return ret;
}
