diff options
author | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2008-04-29 20:37:12 +0000 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2008-04-29 20:37:12 +0000 |
commit | 7c2961d3277c279c77e6bcf9c7ec438fb2e4212b (patch) | |
tree | f88e1393e1fa4dd086a5bf239034b97ab3f6ccb4 | |
parent | 0c5239ae4bd876e113ecc78ae383bac9483c2a83 (diff) |
Fix dbus calls to the same process.
-rw-r--r-- | audio/manager.c | 238 |
1 files changed, 33 insertions, 205 deletions
diff --git a/audio/manager.c b/audio/manager.c index d548bff6..9211ccb7 100644 --- a/audio/manager.c +++ b/audio/manager.c @@ -64,6 +64,7 @@ #include "manager.h" #include "sdpd.h" #include "plugin.h" +#include "glib-helper.h" typedef enum { HEADSET = 1 << 0, @@ -87,7 +88,6 @@ struct audio_sdp_data { DBusMessage *msg; /* Method call or NULL */ - GSList *handles; /* uint32_t * */ GSList *records; /* sdp_record_t * */ audio_sdp_state_t state; @@ -121,9 +121,7 @@ static struct enabled_interfaces enabled = { .control = TRUE, }; -static void get_next_record(struct audio_sdp_data *data); -static DBusHandlerResult get_handles(const char *uuid, - struct audio_sdp_data *data); +static DBusHandlerResult get_records(uuid_t *uuid, struct audio_sdp_data *data); static struct device *create_device(bdaddr_t *bda) { @@ -329,8 +327,6 @@ static void finish_sdp(struct audio_sdp_data *data, gboolean success) debug("Audio service discovery completed with %s", success ? "success" : "failure"); - device_finish_sdp_transaction(data->device); - if (!success) goto done; @@ -390,237 +386,66 @@ done: } if (data->msg) dbus_message_unref(data->msg); - g_slist_foreach(data->handles, (GFunc) g_free, NULL); - g_slist_free(data->handles); g_slist_foreach(data->records, (GFunc) sdp_record_free, NULL); g_slist_free(data->records); g_free(data); } -static void get_record_reply(DBusPendingCall *call, - struct audio_sdp_data *data) +static void get_records_cb(sdp_list_t *recs, int err, gpointer user_data) { - DBusMessage *reply; - DBusError derr; - uint8_t *array; - int array_len, record_len; - sdp_record_t *record; - - reply = dbus_pending_call_steal_reply(call); - - dbus_error_init(&derr); - if (dbus_set_error_from_message(&derr, reply)) { - /* FIXME : forward error message as is */ - error("GetRemoteServiceRecord failed: %s", derr.message); - if (dbus_error_has_name(&derr, - "org.bluez.Error.ConnectionAttemptFailed")) - error_connection_attempt_failed(connection, data->msg, - EHOSTDOWN); - else - error_failed(connection, data->msg, derr.message); - dbus_error_free(&derr); - goto failed; - } - - if (!dbus_message_get_args(reply, NULL, - DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &array, &array_len, - DBUS_TYPE_INVALID)) { - error_failed(connection, data->msg, - "Unable to get args from GetRecordReply"); - goto failed; - } - - record = sdp_extract_pdu(array, &record_len); - if (!record) { - error("Unable to extract service record from reply"); - goto done; - } - - if (record_len != array_len) - debug("warning: array len (%d) != record len (%d)", - array_len, record_len); - - data->records = g_slist_append(data->records, record); - -done: - dbus_message_unref(reply); - - if (data->handles) - get_next_record(data); - else - finish_sdp(data, TRUE); - - return; - -failed: - if (reply) - dbus_message_unref(reply); - finish_sdp(data, FALSE); -} - -static void get_next_record(struct audio_sdp_data *data) -{ - DBusMessage *msg; - DBusPendingCall *pending; - char address[18], *ptr = address; - dbus_uint32_t *handle; - - msg = dbus_message_new_method_call("org.bluez", - data->device->adapter_path, - "org.bluez.Adapter", - "GetRemoteServiceRecord"); - if (!msg) { - error("Unable to allocate new method call"); - error_out_of_memory(connection, data->msg); - finish_sdp(data, FALSE); - return; - } - - handle = data->handles->data; - - data->handles = g_slist_remove(data->handles, data->handles->data); - - ba2str(&data->device->dst, address); - - dbus_message_append_args(msg, DBUS_TYPE_STRING, &ptr, - DBUS_TYPE_UINT32, handle, - DBUS_TYPE_INVALID); - - g_free(handle); + struct audio_sdp_data *data = user_data; + sdp_list_t *seq; + uuid_t uuid; - if (!dbus_connection_send_with_reply(connection, msg, &pending, -1)) { - error("Sending GetRemoteServiceRecord failed"); - error_connection_attempt_failed(connection, data->msg, EIO); + if (err < 0) { + error_connection_attempt_failed(connection, data->msg, -err); finish_sdp(data, FALSE); return; } - dbus_pending_call_set_notify(pending, - (DBusPendingCallNotifyFunction) get_record_reply, - data, NULL); - dbus_pending_call_unref(pending); - dbus_message_unref(msg); -} - -static GSList *find_handle(GSList *handles, dbus_uint32_t handle) -{ - while (handles) { - if (*(dbus_uint32_t *) handles->data == handle) - return handles; - handles = handles->next; - } - - return NULL; -} - -static void get_handles_reply(DBusPendingCall *call, - struct audio_sdp_data *data) -{ - DBusMessage *reply; - DBusError derr; - dbus_uint32_t *array = NULL; - int array_len, i; + for (seq = recs; seq; seq = seq->next) { + sdp_record_t *rec = (sdp_record_t *) seq->data; - reply = dbus_pending_call_steal_reply(call); + if (!rec) + break; - dbus_error_init(&derr); - if (dbus_set_error_from_message(&derr, reply)) { - /* FIXME : forward error message as is */ - error("GetRemoteServiceHandles failed: %s", derr.message); - if (dbus_error_has_name(&derr, - "org.bluez.Error.ConnectionAttemptFailed")) - error_connection_attempt_failed(connection, data->msg, - EHOSTDOWN); - else - error_failed(connection, data->msg, derr.message); - dbus_error_free(&derr); - goto failed; + data->records = g_slist_append(data->records, rec); } - if (!dbus_message_get_args(reply, NULL, - DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, - &array, &array_len, - DBUS_TYPE_INVALID)) { - error_failed(connection, data->msg, - "Unable to get args from reply"); - goto failed; - } - - for (i = 0; i < array_len; i++) { - if (!find_handle(data->handles, array[i])) { - dbus_uint32_t *handle = g_new(dbus_uint32_t, 1); - *handle = array[i]; - data->handles = g_slist_append(data->handles, handle); - } - } + sdp_list_free(recs, NULL); data->state++; switch (data->state) { case ADVANCED_AUDIO: - get_handles(ADVANCED_AUDIO_UUID, data); + sdp_uuid16_create(&uuid, ADVANCED_AUDIO_SVCLASS_ID); break; case AV_REMOTE: - get_handles(AVRCP_REMOTE_UUID, data); + sdp_uuid16_create(&uuid, AV_REMOTE_SVCLASS_ID); break; default: - if (data->handles) - get_next_record(data); - else - finish_sdp(data, TRUE); + finish_sdp(data, TRUE); + return; } - dbus_message_unref(reply); - - return; - -failed: - dbus_message_unref(reply); - finish_sdp(data, FALSE); + get_records(&uuid, data); } -static DBusHandlerResult get_handles(const char *uuid, - struct audio_sdp_data *data) +static DBusHandlerResult get_records(uuid_t *uuid, struct audio_sdp_data *data) { - DBusPendingCall *pending; - char address[18]; - const char *ptr = address; - DBusMessage *msg; - - msg = dbus_message_new_method_call("org.bluez", - data->device->adapter_path, - "org.bluez.Adapter", - "GetRemoteServiceHandles"); - if (!msg) { - error_failed(connection, data->msg, - "Could not create a new dbus message"); - goto failed; - } - - ba2str(&data->device->dst, address); - - dbus_message_append_args(msg, DBUS_TYPE_STRING, &ptr, - DBUS_TYPE_STRING, &uuid, - DBUS_TYPE_INVALID); + struct device *device = data->device; + int err; - if (!dbus_connection_send_with_reply(connection, msg, &pending, -1)) { - error_failed(connection, data->msg, - "Sending GetRemoteServiceHandles failed"); - goto failed; - } - - dbus_pending_call_set_notify(pending, - (DBusPendingCallNotifyFunction) get_handles_reply, - data, NULL); - dbus_pending_call_unref(pending); - dbus_message_unref(msg); + err = bt_search_service(&device->src, &device->dst, uuid, + get_records_cb, data, NULL); + if (!err) + return DBUS_HANDLER_RESULT_HANDLED; - return DBUS_HANDLER_RESULT_HANDLED; + if (data->msg) + error_connection_attempt_failed(connection, data->msg, -err); -failed: - if (msg) - dbus_message_unref(msg); finish_sdp(data, FALSE); + return DBUS_HANDLER_RESULT_HANDLED; } @@ -630,6 +455,7 @@ static DBusHandlerResult resolve_services(DBusMessage *msg, void *user_data) { struct audio_sdp_data *sdp_data; + uuid_t uuid; sdp_data = g_new0(struct audio_sdp_data, 1); if (msg) @@ -638,7 +464,9 @@ static DBusHandlerResult resolve_services(DBusMessage *msg, sdp_data->cb = cb; sdp_data->cb_data = user_data; - return get_handles(GENERIC_AUDIO_UUID, sdp_data); + sdp_uuid16_create(&uuid, GENERIC_AUDIO_SVCLASS_ID); + + return get_records(&uuid, sdp_data); } struct device *manager_device_connected(bdaddr_t *bda, const char *uuid) |