/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
 *
 *
 *  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 <stdlib.h>
#include <errno.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>

#include "plugin.h"
#include "adapter.h"
#include "log.h"
#include "dbus-hci.h"

#define DMI_CHASSIS_FILE "/sys/class/dmi/id/chassis_type"
#define DMI_CHASSIS_FILE_FALLBACK "/sys/devices/virtual/dmi/id/chassis_type"

/* Map the chassis type from chassis_type to a sensible type used in hal
 *
 * See also 3.3.4.1 of the "System Management BIOS Reference Specification,
 * Version 2.6.1" (Preliminary Standard) document, available from
 * http://www.dmtf.org/standards/smbios.
 *
 * TODO: figure out WTF the mapping should be; "Lunch Box"? Give me a break :-)
 *
 * Copied from hal/hald/linux/osspec.c
 */
static const char *chassis_map[] = {
	"Other",                 "unknown", /* 0x01 */
	"Unknown",               "unknown",
	"Desktop",               "desktop",
	"Low Profile Desktop",   "desktop",
	"Pizza Box",             "server",
	"Mini Tower",            "desktop",
	"Tower",                 "desktop",
	"Portable",              "laptop",
	"Laptop",                "laptop",
	"Notebook",              "laptop",
	"Hand Held",             "handheld",
	"Docking Station",       "laptop",
	"All In One",            "unknown",
	"Sub Notebook",          "laptop",
	"Space-saving",          "desktop",
	"Lunch Box",             "unknown",
	"Main Server Chassis",   "server",
	"Expansion Chassis",     "unknown",
	"Sub Chassis",           "unknown",
	"Bus Expansion Chassis", "unknown",
	"Peripheral Chassis",    "unknown",
	"RAID Chassis",          "unknown",
	"Rack Mount Chassis",    "unknown",
	"Sealed-case PC",        "unknown",
	"Multi-system",          "unknown",
	"CompactPCI",            "unknonw",
	"AdvancedTCA",           "unknown",
	"Blade",                 "server",
	"Blade Enclosure"        "unknown", /* 0x1D */
	NULL
};

static int formfactor_probe(struct btd_adapter *adapter)
{
	int chassis_type;
	uint8_t minor = 0;
	const char *formfactor;
	char *contents;

	if (g_file_get_contents(DMI_CHASSIS_FILE,
				&contents, NULL, NULL) == FALSE) {
		if (g_file_get_contents(DMI_CHASSIS_FILE_FALLBACK,
					&contents, NULL, NULL) == FALSE) {
			error("Could not get the contents of DMI chassis type");
			return 0;
		}
	}

	chassis_type = atoi(contents);
	g_free (contents);

	if (chassis_type > 0x1D || chassis_type <= 0) {
		error ("Chassis type is not a known chassis type");
		return 0;
	}

	formfactor = chassis_map[chassis_type * 2];
	if (formfactor != NULL) {
		if (g_str_equal(formfactor, "laptop") == TRUE)
			minor |= (1 << 2) | (1 << 3);
		else if (g_str_equal(formfactor, "desktop") == TRUE)
			minor |= 1 << 2;
		else if (g_str_equal(formfactor, "server") == TRUE)
			minor |= 1 << 3;
		else if (g_str_equal(formfactor, "handheld") == TRUE)
			minor += 1 << 4;
	}

	/* Computer major class */
	DBG("Setting 0x%06x for major/minor device class", (1 << 8) | minor);

	btd_adapter_set_class(adapter, 0x01, minor);

	return 0;
}

static void formfactor_remove(struct btd_adapter *adapter)
{
}

static struct btd_adapter_driver formfactor_driver = {
	.name	= "formfactor",
	.probe	= formfactor_probe,
	.remove	= formfactor_remove,
};

static int formfactor_init(void)
{
	return btd_register_adapter_driver(&formfactor_driver);
}

static void formfactor_exit(void)
{
	btd_unregister_adapter_driver(&formfactor_driver);
}

BLUETOOTH_PLUGIN_DEFINE(formfactor, VERSION,
		BLUETOOTH_PLUGIN_PRIORITY_LOW, formfactor_init, formfactor_exit)
