From a2a30d00e219c5f8630be1fe67f6946094353dfc Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 2 Apr 2008 22:34:34 +0000 Subject: Fix SetMode/SetProperty behavior so it actually call agent to confirm mode when the mode is lower. --- hcid/adapter.c | 113 ++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 79 insertions(+), 34 deletions(-) diff --git a/hcid/adapter.c b/hcid/adapter.c index 9202b69c..045d425d 100644 --- a/hcid/adapter.c +++ b/hcid/adapter.c @@ -685,6 +685,75 @@ done: return send_message_and_unref(conn, reply); } +gint find_session(struct mode_req *req, DBusMessage *msg) +{ + const char *name = dbus_message_get_sender(req->msg); + const char *sender = dbus_message_get_sender(msg); + + return strcmp(name, sender); +} + +static void confirm_mode_cb(struct agent *agent, DBusError *err, void *data) +{ + struct mode_req *req = data; + DBusMessage *derr; + + if (err && dbus_error_is_set(err)) { + derr = dbus_message_new_error(req->msg, err->name, err->message); + dbus_connection_send_and_unref(req->conn, derr); + goto cleanup; + } + + set_mode(req->conn, req->msg, req->mode, req->adapter); + + if (!g_slist_find_custom(req->adapter->sessions, req->msg, + (GCompareFunc) find_session)) + goto cleanup; + + return; + +cleanup: + dbus_connection_unref(req->conn); + dbus_message_unref(req->msg); + if (req->id) + name_listener_id_remove(req->id); + g_free(req); +} + +static DBusHandlerResult confirm_mode(DBusConnection *conn, DBusMessage *msg, + const char *mode, void *data) +{ + struct adapter *adapter = data; + struct mode_req *req; + DBusMessage *reply; + int ret; + + if (!adapter->agent) { + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + return send_message_and_unref(conn, reply); + } + + req = g_new0(struct mode_req, 1); + req->adapter = adapter; + req->conn = dbus_connection_ref(conn); + req->msg = dbus_message_ref(msg); + req->mode = str2mode(adapter->address, mode); + + ret = agent_confirm_mode_change(adapter->agent, mode, confirm_mode_cb, + req); + if (ret < 0) { + dbus_connection_unref(req->conn); + dbus_message_unref(req->msg); + g_free(req); + return error_invalid_arguments(conn, msg, NULL); + } + + return DBUS_HANDLER_RESULT_HANDLED; +} + static DBusHandlerResult adapter_set_mode(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -702,7 +771,7 @@ static DBusHandlerResult adapter_set_mode(DBusConnection *conn, adapter->global_mode = str2mode(adapter->address, mode); - if (adapter->sessions && adapter->global_mode > adapter->mode) { + if (adapter->global_mode == adapter->mode) { reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; @@ -710,6 +779,9 @@ static DBusHandlerResult adapter_set_mode(DBusConnection *conn, return send_message_and_unref(conn, reply); } + if (adapter->sessions && adapter->global_mode < adapter->mode) + return confirm_mode(conn, msg, mode, data); + return set_mode(conn, msg, str2mode(adapter->address, mode), data); } @@ -3461,7 +3533,7 @@ static DBusHandlerResult set_property(DBusConnection *conn, adapter->global_mode = str2mode(adapter->address, mode); - if (adapter->sessions && adapter->global_mode > adapter->mode) { + if (adapter->global_mode == adapter->mode) { reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; @@ -3469,6 +3541,9 @@ static DBusHandlerResult set_property(DBusConnection *conn, return send_message_and_unref(conn, reply); } + if (adapter->sessions && adapter->global_mode < adapter->mode) + return confirm_mode(conn, msg, mode, data); + return set_mode(conn, msg, str2mode(adapter->address, mode), data); } @@ -3484,7 +3559,7 @@ static void session_exit(const char *name, void *data) adapter->sessions = g_slist_remove(adapter->sessions, req); if (!adapter->sessions) { - debug("Falling back to %d mode", mode2str(adapter->global_mode)); + debug("Falling back to '%s' mode", mode2str(adapter->global_mode)); /* FIXME: fallback to previous mode set_mode(req->conn, req->msg, adapter->global_mode, adapter); */ @@ -3494,36 +3569,6 @@ static void session_exit(const char *name, void *data) g_free(req); } -static void request_mode_cb(struct agent *agent, DBusError *err, void *data) -{ - struct mode_req *req = data; - DBusMessage *derr; - - if (err && dbus_error_is_set(err)) { - derr = dbus_message_new_error(req->msg, err->name, err->message); - dbus_connection_send_and_unref(req->conn, derr); - goto cleanup; - } - - set_mode(req->conn, req->msg, req->mode, req->adapter); - - return; - -cleanup: - dbus_connection_unref(req->conn); - dbus_message_unref(req->msg); - name_listener_id_remove(req->id); - g_free(req); -} - -gint find_session(struct mode_req *req, DBusMessage *msg) -{ - const char *name = dbus_message_get_sender(req->msg); - const char *sender = dbus_message_get_sender(msg); - - return strcmp(name, sender); -} - static DBusHandlerResult request_mode(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -3570,7 +3615,7 @@ static DBusHandlerResult request_mode(DBusConnection *conn, return send_message_and_unref(conn, reply); } - ret = agent_confirm_mode_change(adapter->agent, mode, request_mode_cb, + ret = agent_confirm_mode_change(adapter->agent, mode, confirm_mode_cb, req); if (ret < 0) { dbus_connection_unref(req->conn); -- cgit