/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2011-2012 David Herrmann <dh.herrmann@googlemail.com>
 *
 *
 *  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 <bluetooth/bluetooth.h>
#include <glib.h>

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

/*
 * Nintendo Wii Remote devices require the bdaddr of the host as pin input for
 * authentication. This plugin registers a pin-callback and forces this pin
 * to be used for authentication.
 *
 * There are two ways to place the wiimote into discoverable mode.
 *  - Pressing the red-sync button on the back of the wiimote. This module
 *    supports pairing via this method. Auto-reconnect should be possible after
 *    the device was paired once.
 *  - Pressing the 1+2 buttons on the front of the wiimote. This module does
 *    not support this method since this method never enables auto-reconnect.
 *    Hence, pairing is not needed. Use it without pairing if you want.
 * After connecting the wiimote you should immediately connect to the input
 * service of the wiimote. If you don't, the wiimote will close the connection.
 * The wiimote waits about 5 seconds until it turns off again.
 * Auto-reconnect is only enabled when pairing with the wiimote via the red
 * sync-button and then connecting to the input service. If you do not connect
 * to the input service, then auto-reconnect is not enabled.
 * If enabled, the wiimote connects to the host automatically when any button
 * is pressed.
 */

static uint16_t wii_ids[][2] = {
	{ 0x057e, 0x0306 },		/* 1st gen */
	{ 0x054c, 0x0306 },		/* LEGO wiimote */
	{ 0x057e, 0x0330 },		/* 2nd gen */
};

static const char *wii_names[] = {
	"Nintendo RVL-CNT-01",		/* 1st gen */
	"Nintendo RVL-CNT-01-TR",	/* 2nd gen */
	"Nintendo RVL-CNT-01-UC",	/* Wii U Pro Controller */
	"Nintendo RVL-WBC-01",		/* Balance Board */
};

static ssize_t wii_pincb(struct btd_adapter *adapter, struct btd_device *device,
						char *pinbuf, bool *display,
						unsigned int attempt)
{
	uint16_t vendor, product;
	char addr[18], name[25];
	unsigned int i;

	/* Only try the pin code once per device. If it's not correct then it's
	 * an unknown device. */
	if (attempt > 1)
		return 0;

	ba2str(device_get_address(device), addr);

	vendor = btd_device_get_vendor(device);
	product = btd_device_get_product(device);

	device_get_name(device, name, sizeof(name));
	name[sizeof(name) - 1] = 0;

	for (i = 0; i < G_N_ELEMENTS(wii_ids); ++i) {
		if (vendor == wii_ids[i][0] && product == wii_ids[i][1])
			goto found;
	}

	for (i = 0; i < G_N_ELEMENTS(wii_names); ++i) {
		if (g_str_equal(name, wii_names[i]))
			goto found;
	}

	return 0;

found:
	DBG("Forcing fixed pin on detected wiimote %s", addr);
	memcpy(pinbuf, btd_adapter_get_address(adapter), 6);
	return 6;
}

static int wii_probe(struct btd_adapter *adapter)
{
	btd_adapter_register_pin_cb(adapter, wii_pincb);

	return 0;
}

static void wii_remove(struct btd_adapter *adapter)
{
	btd_adapter_unregister_pin_cb(adapter, wii_pincb);
}

static struct btd_adapter_driver wii_driver = {
	.name	= "wiimote",
	.probe	= wii_probe,
	.remove	= wii_remove,
};

static int wii_init(void)
{
	return btd_register_adapter_driver(&wii_driver);
}

static void wii_exit(void)
{
	btd_unregister_adapter_driver(&wii_driver);
}

BLUETOOTH_PLUGIN_DEFINE(wiimote, VERSION,
		BLUETOOTH_PLUGIN_PRIORITY_LOW, wii_init, wii_exit)
