/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2012 Google Inc.
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdbool.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

#include <bluetooth/bluetooth.h>
#include <glib.h>

#include "src/plugin.h"
#include "src/adapter.h"
#include "src/device.h"
#include "src/log.h"
#include "src/storage.h"

/*
 * Plugin to handle automatic pairing of devices with reduced user
 * interaction, including implementing the recommendation of the HID spec
 * for keyboard devices.
 *
 * The plugin works by intercepting the PIN request for devices; if the
 * device is a keyboard a random six-digit numeric PIN is generated and
 * returned, flagged for displaying using DisplayPinCode.
 *
 */

static ssize_t autopair_pincb(struct btd_adapter *adapter,
						struct btd_device *device,
						char *pinbuf, bool *display,
						unsigned int attempt)
{
	char addr[18];
	char pinstr[7];
	uint32_t class;

	ba2str(device_get_address(device), addr);

	class = btd_device_get_class(device);

	DBG("device %s 0x%x", addr, class);

	/* This is a class-based pincode guesser. Ignore devices with an
	 * unknown class.
	 */
	if (class == 0)
		return 0;

	switch ((class & 0x1f00) >> 8) {
	case 0x04:		/* Audio/Video */
		switch ((class & 0xfc) >> 2) {
		case 0x01:		/* Wearable Headset Device */
		case 0x02:		/* Hands-free Device */
		case 0x06:		/* Headphones */
		case 0x07:		/* Portable Audio */
		case 0x0a:		/* HiFi Audio Device */
			if (attempt > 1)
				return 0;
			memcpy(pinbuf, "0000", 4);
			return 4;
		}
		break;

	case 0x05:		/* Peripheral */
		switch ((class & 0xc0) >> 6) {
		case 0x01:		/* Keyboard */
		case 0x03:		/* Combo keyboard/pointing device */
			/* For keyboards rejecting the first random code
			 * in less than 500ms, try a fixed code. */
			if (attempt > 1 &&
				device_bonding_last_duration(device) < 500) {
				/* Don't try more than one dumb code */
				if (attempt > 2)
					return 0;
				/* Try "0000" as the code for the second
				 * attempt. */
				memcpy(pinbuf, "0000", 4);
				return 4;
			}

			/* Never try more than 3 random pincodes. */
			if (attempt >= 4)
				return 0;

			snprintf(pinstr, sizeof(pinstr), "%06d",
						rand() % 1000000);
			*display = true;
			memcpy(pinbuf, pinstr, 6);
			return 6;

		case 0x02: /* Pointing device */
			if (attempt > 1)
				return 0;
			memcpy(pinbuf, "0000", 4);
			return 4;
		}

		break;
	case 0x06:		/* Imaging */
		if (class & 0x80) {	/* Printer */
			if (attempt > 1)
				return 0;
			memcpy(pinbuf, "0000", 4);
			return 4;
		}
		break;
	}

	return 0;
}


static int autopair_probe(struct btd_adapter *adapter)
{
	btd_adapter_register_pin_cb(adapter, autopair_pincb);

	return 0;
}

static void autopair_remove(struct btd_adapter *adapter)
{
	btd_adapter_unregister_pin_cb(adapter, autopair_pincb);
}

static struct btd_adapter_driver autopair_driver = {
	.name = "autopair",
	.probe = autopair_probe,
	.remove = autopair_remove,
};

static int autopair_init(void)
{
	/* Initialize the random seed from /dev/urandom */
	unsigned int seed;
	int fd;

	fd = open("/dev/urandom", O_RDONLY);
	if (fd >= 0) {
		ssize_t n;

		n = read(fd, &seed, sizeof(seed));
		if (n < (ssize_t) sizeof(seed))
			seed = time(NULL);

		close(fd);
	} else
		seed = time(NULL);

	srand(seed);

	return btd_register_adapter_driver(&autopair_driver);
}

static void autopair_exit(void)
{
	btd_unregister_adapter_driver(&autopair_driver);
}

BLUETOOTH_PLUGIN_DEFINE(autopair, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
						autopair_init, autopair_exit)
