summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2008-04-29 20:37:12 +0000
committerLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2008-04-29 20:37:12 +0000
commit7c2961d3277c279c77e6bcf9c7ec438fb2e4212b (patch)
treef88e1393e1fa4dd086a5bf239034b97ab3f6ccb4
parent0c5239ae4bd876e113ecc78ae383bac9483c2a83 (diff)
Fix dbus calls to the same process.
-rw-r--r--audio/manager.c238
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)