From 993e7c747c360fb05b98e316b7ec760d2fb70365 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 11 Apr 2007 08:56:50 +0000 Subject: Implement ChangeDefaultHeadset and RemoveHeadset methods --- audio/headset.c | 13 ++++++++ audio/headset.h | 1 + audio/manager.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 96 insertions(+), 11 deletions(-) (limited to 'audio') diff --git a/audio/headset.c b/audio/headset.c index e1122bd6..ab4c4d8f 100644 --- a/audio/headset.c +++ b/audio/headset.c @@ -795,6 +795,13 @@ failed: return -1; } +gint headset_path_cmp(gconstpointer headset, gconstpointer path) +{ + const struct headset *hs = headset; + + return strcmp(hs->object_path, path); +} + gint headset_bda_cmp(gconstpointer headset, gconstpointer bda) { const struct headset *hs = headset; @@ -1559,6 +1566,12 @@ void headset_unref(struct headset *hs) { assert(hs != NULL); + if (hs->state > HEADSET_STATE_DISCONNECTED) + hs_disconnect(hs, NULL); + + if (!dbus_connection_unregister_object_path(hs->conn, hs->object_path)) + error("D-Bus failed to unregister %s path", hs->object_path); + dbus_connection_unref(hs->conn); g_free(hs); diff --git a/audio/headset.h b/audio/headset.h index 9f1c1232..7c85b9bb 100644 --- a/audio/headset.h +++ b/audio/headset.h @@ -44,6 +44,7 @@ int headset_remove_ag_record(DBusConnection *conn, uint32_t rec_id); gboolean headset_server_io_cb(GIOChannel *chan, GIOCondition cond, struct manager *manager); +gint headset_path_cmp(gconstpointer headset, gconstpointer path); gint headset_bda_cmp(gconstpointer headset, gconstpointer bda); const char *headset_get_path(struct headset *hs); diff --git a/audio/manager.c b/audio/manager.c index e48d7a7a..2ce50cab 100644 --- a/audio/manager.c +++ b/audio/manager.c @@ -57,7 +57,7 @@ struct manager { DBusConnection *conn; GIOChannel *hs_server; uint32_t hs_record_id; - int default_hs; + struct headset *default_hs; GSList *headset_list; }; @@ -205,6 +205,7 @@ struct headset *manager_find_headset_by_bda(struct manager *manager, bdaddr_t *b GSList *elem; assert(manager); + elem = g_slist_find_custom(manager->headset_list, bda, headset_bda_cmp); return elem ? elem->data : NULL; @@ -212,12 +213,13 @@ struct headset *manager_find_headset_by_bda(struct manager *manager, bdaddr_t *b void manager_add_headset(struct manager *manager, struct headset *hs) { - assert(manager && hs); - - if (g_slist_find(manager->headset_list, hs)) - return; + assert(manager); + assert(hs); manager->headset_list = g_slist_append(manager->headset_list, hs); + + if (!manager->default_hs) + manager->default_hs = hs; } static DBusHandlerResult am_create_headset(struct manager *manager, @@ -268,7 +270,44 @@ static DBusHandlerResult am_create_headset(struct manager *manager, static DBusHandlerResult am_remove_headset(struct manager *manager, DBusMessage *msg) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + DBusError derr; + DBusMessage *reply; + GSList *match; + const char *path; + + dbus_error_init(&derr); + if (!dbus_message_get_args(msg, &derr, + DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID)) { + err_invalid_args(manager->conn, msg, derr.message); + return DBUS_HANDLER_RESULT_HANDLED; + } + if (dbus_error_is_set(&derr)) { + err_invalid_args(manager->conn, msg, derr.message); + dbus_error_free(&derr); + return DBUS_HANDLER_RESULT_HANDLED; + } + + match = g_slist_find_custom(manager->headset_list, path, headset_path_cmp); + if (!match) + return error_reply(manager->conn, msg, "org.bluez.Error.DoesNotExist", + "The headset does not exist"); + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + headset_unref(match->data); + manager->headset_list = g_slist_remove(manager->headset_list, match->data); + + if (manager->default_hs == match->data) { + if (!manager->headset_list) + manager->default_hs = NULL; + else + manager->default_hs = manager->headset_list->data; + } + + return send_message_and_unref(manager->conn, reply); } static DBusHandlerResult am_list_headsets(struct manager *manager, @@ -281,15 +320,18 @@ static DBusHandlerResult am_get_default_headset(struct manager *manager, DBusMessage *msg) { DBusMessage *reply; - char object_path[128]; - const char *opath = object_path; + const char *opath; + + if (!manager->default_hs) + return error_reply(manager->conn, msg, "org.bluez.Error.DoesNotExist", + "There is no default headset"); reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; - snprintf(object_path, sizeof(object_path), HEADSET_PATH_BASE "%d", - manager->default_hs); + opath = headset_get_path(manager->default_hs); + dbus_message_append_args(reply, DBUS_TYPE_STRING, &opath, DBUS_TYPE_INVALID); @@ -299,7 +341,36 @@ static DBusHandlerResult am_get_default_headset(struct manager *manager, static DBusHandlerResult am_change_default_headset(struct manager *manager, DBusMessage *msg) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + DBusError derr; + DBusMessage *reply; + GSList *match; + const char *path; + + dbus_error_init(&derr); + if (!dbus_message_get_args(msg, &derr, + DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID)) { + err_invalid_args(manager->conn, msg, derr.message); + return DBUS_HANDLER_RESULT_HANDLED; + } + if (dbus_error_is_set(&derr)) { + err_invalid_args(manager->conn, msg, derr.message); + dbus_error_free(&derr); + return DBUS_HANDLER_RESULT_HANDLED; + } + + match = g_slist_find_custom(manager->headset_list, path, headset_path_cmp); + if (!match) + return error_reply(manager->conn, msg, "org.bluez.Error.DoesNotExist", + "The headset does not exist"); + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + manager->default_hs = match->data; + + return send_message_and_unref(manager->conn, reply); } static DBusHandlerResult am_message(DBusConnection *conn, -- cgit