1/* 2 * 3 * BlueZ - Bluetooth protocol stack for Linux 4 * 5 * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org> 6 * 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 * 22 */ 23 24#ifdef HAVE_CONFIG_H 25#include <config.h> 26#endif 27 28#include <errno.h> 29#include <dbus/dbus.h> 30 31#include <bluetooth/bluetooth.h> 32 33#include "plugin.h" 34#include "adapter.h" 35#include "log.h" 36 37static void formfactor_reply(DBusPendingCall *call, void *user_data) 38{ 39 struct btd_adapter *adapter = user_data; 40 const char *formfactor = NULL; 41 DBusMessage *reply; 42 uint8_t minor = 0; 43 44 reply = dbus_pending_call_steal_reply(call); 45 46 if (dbus_set_error_from_message(NULL, reply) == TRUE) { 47 error("Failed to access HAL"); 48 dbus_message_unref(reply); 49 return; 50 } 51 52 if (dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, &formfactor, 53 DBUS_TYPE_INVALID) == FALSE) { 54 error("Wrong formfactor arguments"); 55 dbus_message_unref(reply); 56 return; 57 } 58 59 DBG("Computer is classified as %s", formfactor); 60 61 if (formfactor != NULL) { 62 if (g_str_equal(formfactor, "laptop") == TRUE) 63 minor |= (1 << 2) | (1 << 3); 64 else if (g_str_equal(formfactor, "desktop") == TRUE) 65 minor |= 1 << 2; 66 else if (g_str_equal(formfactor, "server") == TRUE) 67 minor |= 1 << 3; 68 else if (g_str_equal(formfactor, "handheld") == TRUE) 69 minor += 1 << 4; 70 } 71 72 dbus_message_unref(reply); 73 74 /* Computer major class */ 75 DBG("Setting 0x%06x for major/minor device class", (1 << 8) | minor); 76 77 btd_adapter_set_class(adapter, 0x01, minor); 78} 79 80static DBusConnection *connection; 81 82static int hal_probe(struct btd_adapter *adapter) 83{ 84 const char *property = "system.formfactor"; 85 DBusMessage *message; 86 DBusPendingCall *call; 87 88 connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); 89 if (connection == NULL) 90 return -ENOMEM; 91 92 message = dbus_message_new_method_call("org.freedesktop.Hal", 93 "/org/freedesktop/Hal/devices/computer", 94 "org.freedesktop.Hal.Device", 95 "GetPropertyString"); 96 if (message == NULL) { 97 error("Failed to create formfactor request"); 98 dbus_connection_unref(connection); 99 return -ENOMEM; 100 } 101 102 dbus_message_append_args(message, DBUS_TYPE_STRING, &property, 103 DBUS_TYPE_INVALID); 104 105 if (dbus_connection_send_with_reply(connection, message, 106 &call, -1) == FALSE) { 107 error("Failed to send formfactor request"); 108 dbus_message_unref(message); 109 dbus_connection_unref(connection); 110 return -EIO; 111 } 112 113 dbus_pending_call_set_notify(call, formfactor_reply, adapter, NULL); 114 115 dbus_pending_call_unref(call); 116 117 dbus_message_unref(message); 118 119 return 0; 120} 121 122static void hal_remove(struct btd_adapter *adapter) 123{ 124 dbus_connection_unref(connection); 125} 126 127static struct btd_adapter_driver hal_driver = { 128 .name = "hal", 129 .probe = hal_probe, 130 .remove = hal_remove, 131}; 132 133static int hal_init(void) 134{ 135 return btd_register_adapter_driver(&hal_driver); 136} 137 138static void hal_exit(void) 139{ 140 btd_unregister_adapter_driver(&hal_driver); 141} 142 143BLUETOOTH_PLUGIN_DEFINE(hal, VERSION, 144 BLUETOOTH_PLUGIN_PRIORITY_LOW, hal_init, hal_exit) 145