summaryrefslogtreecommitdiff
path: root/plugins/formfactor.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/formfactor.c')
-rw-r--r--plugins/formfactor.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/plugins/formfactor.c b/plugins/formfactor.c
new file mode 100644
index 0000000..758d481
--- /dev/null
+++ b/plugins/formfactor.c
@@ -0,0 +1,148 @@
+/*
+ *
+ * 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 "plugin.h"
+#include "adapter.h"
+#include "log.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)