summaryrefslogtreecommitdiffstats
path: root/hcid/dbus-device.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2006-02-23 17:17:18 +0000
committerMarcel Holtmann <marcel@holtmann.org>2006-02-23 17:17:18 +0000
commita8088aa488e3f9446b32ea4ad31295c94f3f2a8a (patch)
treea89b7c6f6df1db8d8bab938bb44dded9701c311e /hcid/dbus-device.c
parentbe9b6f152b287af5fdb8df303874e7979a1cf3c1 (diff)
Add support for setting the minor class
Diffstat (limited to 'hcid/dbus-device.c')
-rw-r--r--hcid/dbus-device.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/hcid/dbus-device.c b/hcid/dbus-device.c
index 18df99dc..49e56ea7 100644
--- a/hcid/dbus-device.c
+++ b/hcid/dbus-device.c
@@ -41,6 +41,16 @@
#include "textfile.h"
+static const char *computer_minor_cls[] = {
+ "uncategorized",
+ "desktop",
+ "server",
+ "laptop",
+ "handheld",
+ "palm",
+ "wearable"
+};
+
static char *get_peer_name(const bdaddr_t *local, const bdaddr_t *peer)
{
char filename[PATH_MAX + 1], addr[18];
@@ -357,6 +367,64 @@ static DBusMessage* handle_dev_set_discoverable_to_req(DBusMessage *msg, void *d
return reply;
}
+static DBusMessage* handle_dev_set_minor_class_req(DBusMessage *msg, void *data)
+{
+ struct hci_dbus_data *dbus_data = data;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ const char *minor;
+ uint8_t cls[3];
+ uint32_t dev_class = 0xFFFFFFFF;
+ int i, dd;
+
+ dbus_message_iter_init(msg, &iter);
+ dbus_message_iter_get_basic(&iter, &minor);
+
+ if (!minor)
+ return bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM);
+
+ /* FIXME: currently, only computer minor classes are allowed */
+ for (i = 0; i < sizeof(computer_minor_cls) / sizeof(*computer_minor_cls); i++)
+ if (!strcasecmp(minor, computer_minor_cls[i])) {
+ /* Remove the format type */
+ dev_class = i << 2;
+ break;
+ }
+
+ /* Check if it's a valid minor class */
+ if (dev_class == 0xFFFFFFFF)
+ return bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM);
+
+ dd = hci_open_dev(dbus_data->dev_id);
+ if (dd < 0) {
+ syslog(LOG_ERR, "HCI device open failed: hci%d", dbus_data->dev_id);
+ return bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV);
+ }
+
+ if (hci_read_class_of_dev(dd, cls, 1000) < 0) {
+ syslog(LOG_ERR, "Can't read class of device on hci%d: %s(%d)",
+ dbus_data->dev_id, strerror(errno), errno);
+ reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET | errno);
+ goto failed;
+ }
+
+ dev_class |= (cls[2] << 16) | (cls[1] << 8);
+
+ if (hci_write_class_of_dev(dd, dev_class, 2000) < 0) {
+ syslog(LOG_ERR, "Can't write class of device on hci%d: %s(%d)",
+ dbus_data->dev_id, strerror(errno), errno);
+ reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET | errno);
+ goto failed;
+ }
+
+ reply = dbus_message_new_method_return(msg);
+
+failed:
+ hci_close_dev(dd);
+
+ return reply;
+}
+
static DBusMessage* handle_dev_set_mode_req(DBusMessage *msg, void *data)
{
const struct hci_dbus_data *dbus_data = data;
@@ -833,6 +901,7 @@ static const struct service_data dev_services[] = {
{ DEV_SET_CLASS, handle_dev_set_class_req, DEV_SET_CLASS_SIGNATURE },
{ DEV_SET_DISCOVERABLE_TO, handle_dev_set_discoverable_to_req, DEV_SET_DISCOVERABLE_TO_SIGNATURE },
+ { DEV_SET_MINOR_CLASS, handle_dev_set_minor_class_req, DEV_SET_MINOR_CLASS_SIGNATURE },
{ DEV_SET_MODE, handle_dev_set_mode_req, DEV_SET_MODE_SIGNATURE },
{ DEV_SET_NAME, handle_dev_set_name_req, DEV_SET_NAME_SIGNATURE },