OSDN Git Service

core: Add support for powered property within adapter handling
authorMarcel Holtmann <marcel@holtmann.org>
Sat, 5 Jan 2013 04:29:50 +0000 (20:29 -0800)
committerMarcel Holtmann <marcel@holtmann.org>
Sat, 5 Jan 2013 04:29:50 +0000 (20:29 -0800)
src/adapter.c

index df817db..6254c1a 100644 (file)
@@ -432,29 +432,6 @@ static void new_settings_callback(uint16_t index, uint16_t length,
        adapter_update_settings(adapter, settings);
 }
 
-static void set_powered(struct btd_adapter *adapter, gboolean powered,
-                                               GDBusPendingPropertySet id)
-{
-       int err;
-
-       if (mgmt_powered(adapter->current_settings) == powered) {
-               g_dbus_pending_property_success(id);
-               return;
-       }
-
-       err = mgmt_set_powered(adapter->dev_id, powered);
-       if (err < 0) {
-               g_dbus_pending_property_error(id, ERROR_INTERFACE ".Failed",
-                                                       strerror(-err));
-               return;
-       }
-
-       if (powered == FALSE)
-               adapter->off_requested = TRUE;
-
-       g_dbus_pending_property_success(id);
-}
-
 static void set_pairable(struct btd_adapter *adapter, gboolean pairable,
                                bool reply, GDBusPendingPropertySet id)
 {
@@ -1324,37 +1301,107 @@ static gboolean adapter_property_get_class(const GDBusPropertyTable *property,
        return TRUE;
 }
 
-static gboolean adapter_property_get_powered(
-                                       const GDBusPropertyTable *property,
-                                       DBusMessageIter *iter, void *data)
+static gboolean property_get_powered(const GDBusPropertyTable *property,
+                                       DBusMessageIter *iter, void *user_data)
 {
-       struct btd_adapter *adapter = data;
-       dbus_bool_t value;
-       bool powered = mgmt_powered(adapter->current_settings);
+       struct btd_adapter *adapter = user_data;
+       dbus_bool_t powered;
 
-       value = (powered && !adapter->off_requested) ? TRUE : FALSE;
-       dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &value);
+       if (adapter->current_settings & MGMT_SETTING_POWERED)
+               powered = TRUE;
+       else
+               powered = FALSE;
+
+       dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &powered);
 
        return TRUE;
 }
 
-static void adapter_property_set_powered(
-                               const GDBusPropertyTable *property,
-                               DBusMessageIter *value,
-                               GDBusPendingPropertySet id, void *data)
+struct property_set_data {
+       struct btd_adapter *adapter;
+       GDBusPendingPropertySet id;
+};
+
+static void set_powered_complete(uint8_t status, uint16_t length,
+                                       const void *param, void *user_data)
 {
-       dbus_bool_t powered;
+       struct property_set_data *data = user_data;
+       struct btd_adapter *adapter = data->adapter;
+       uint32_t settings;
 
-       if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) {
-               g_dbus_pending_property_error(id,
-                                       ERROR_INTERFACE ".InvalidArguments",
-                                       "Invalid arguments in method call");
+       if (status != MGMT_STATUS_SUCCESS) {
+               error("Failed to set powered: %s (0x%02x)",
+                                               mgmt_errstr(status), status);
+               g_dbus_pending_property_error(data->id,
+                                               ERROR_INTERFACE ".Failed",
+                                               mgmt_errstr(status));
+               return;
+       }
+
+       if (length < sizeof(settings)) {
+               error("Wrong size of set powered response");
+               g_dbus_pending_property_error(data->id,
+                                               ERROR_INTERFACE ".Failed",
+                                               "Invalid response data");
                return;
        }
 
+       settings = bt_get_le32(param);
+
+       DBG("Settings: 0x%08x", settings);
+
+       adapter->current_settings = settings;
+
+       g_dbus_pending_property_success(data->id);
+
+       g_dbus_emit_property_changed(dbus_conn, adapter->path,
+                                       ADAPTER_INTERFACE, "Powered");
+}
+
+static void property_set_powered(const GDBusPropertyTable *property,
+                               DBusMessageIter *value,
+                               GDBusPendingPropertySet id, void *user_data)
+{
+       struct btd_adapter *adapter = user_data;
+       struct property_set_data *data;
+       struct mgmt_mode cp;
+       dbus_bool_t powered, current_powered;
+
        dbus_message_iter_get_basic(value, &powered);
 
-       set_powered(data, powered, id);
+       if (adapter->current_settings & MGMT_SETTING_POWERED)
+               current_powered = TRUE;
+       else
+               current_powered = FALSE;
+
+       if (powered == current_powered) {
+               g_dbus_pending_property_success(id);
+               return;
+       }
+
+       memset(&cp, 0, sizeof(cp));
+       cp.val = (powered == TRUE) ? 0x01 : 0x00;
+
+       DBG("sending set powered command for index %u", adapter->dev_id);
+
+       data = g_try_new0(struct property_set_data, 1);
+       if (!data)
+               goto failed;
+
+       data->adapter = adapter;
+       data->id = id;
+
+       if (mgmt_send(adapter->mgmt, MGMT_OP_SET_POWERED,
+                               adapter->dev_id, sizeof(cp), &cp,
+                               set_powered_complete, data, g_free) > 0)
+               return;
+
+       g_free(data);
+
+failed:
+       error("Failed to set powered for index %u", adapter->dev_id);
+
+       g_dbus_pending_property_error(id, ERROR_INTERFACE ".Failed", NULL);
 }
 
 static gboolean adapter_property_get_discoverable(
@@ -1595,8 +1642,7 @@ static const GDBusPropertyTable adapter_properties[] = {
        { "Alias", "s", adapter_property_get_alias,
                                        adapter_property_set_alias },
        { "Class", "u", adapter_property_get_class },
-       { "Powered", "b", adapter_property_get_powered,
-                                       adapter_property_set_powered },
+       { "Powered", "b", property_get_powered, property_set_powered },
        { "Discoverable", "b", adapter_property_get_discoverable,
                                        adapter_property_set_discoverable },
        { "Pairable", "b", adapter_property_get_pairable,