OSDN Git Service

auto import from //branches/cupcake/...@131421
[android-x86/external-bluetooth-bluez.git] / utils / audio / sink.c
index 2af74bb..31a54be 100644 (file)
@@ -142,14 +142,17 @@ static gboolean stream_setup_retry(gpointer user_data)
        struct pending_request *pending = sink->connect;
 
        if (sink->state >= AVDTP_STATE_OPEN) {
-               DBusMessage *reply;
                debug("Stream successfully created, after XCASE connect:connect");
-               reply = dbus_message_new_method_return(pending->msg);
-               dbus_connection_send(pending->conn, reply, NULL);
-               dbus_message_unref(reply);
+               if (pending->msg) {
+                       DBusMessage *reply;
+                       reply = dbus_message_new_method_return(pending->msg);
+                       dbus_connection_send(pending->conn, reply, NULL);
+                       dbus_message_unref(reply);
+               }
        } else {
                debug("Stream setup failed, after XCASE connect:connect");
-               error_failed(pending->conn, pending->msg, "Stream setup failed");
+               if (pending->msg)
+                       error_failed(pending->conn, pending->msg, "Stream setup failed");
        }
 
        sink->connect = NULL;
@@ -168,27 +171,32 @@ static void stream_setup_complete(struct avdtp *session, struct a2dp_sep *sep,
        pending = sink->connect;
 
        if (stream) {
-               DBusMessage *reply;
+               debug("Stream successfully created");
+
+               if (pending->msg) {
+                       DBusMessage *reply;
+                       reply = dbus_message_new_method_return(pending->msg);
+                       dbus_connection_send(pending->conn, reply, NULL);
+                       dbus_message_unref(reply);
+               }
                sink->connect = NULL;
-               reply = dbus_message_new_method_return(pending->msg);
-               dbus_connection_send(pending->conn, reply, NULL);
-               dbus_message_unref(reply);
                pending_request_free(pending);
-               debug("Stream successfully created");
+               return;
+       }
+
+       avdtp_unref(sink->session);
+       sink->session = NULL;
+       if (avdtp_error_type(err) == AVDTP_ERROR_ERRNO
+                       && avdtp_error_posix_errno(err) != EHOSTDOWN) {
+               debug("connect:connect XCASE detected");
+               g_timeout_add(STREAM_SETUP_RETRY_TIMER,
+                               stream_setup_retry, sink);
        } else {
-               avdtp_unref(sink->session);
-               sink->session = NULL;
-               if (avdtp_error_type(err) == AVDTP_ERROR_ERRNO
-                               && avdtp_error_posix_errno(err) != EHOSTDOWN) {
-                       debug("connect:connect XCASE detected");
-                       g_timeout_add(STREAM_SETUP_RETRY_TIMER,
-                                       stream_setup_retry, sink);
-               } else {
-                       sink->connect = NULL;
+               if (pending->msg)
                        error_failed(pending->conn, pending->msg, "Stream setup failed");
-                       pending_request_free(pending);
-                       debug("Stream setup failed : %s", avdtp_strerror(err));
-               }
+               sink->connect = NULL;
+               pending_request_free(pending);
+               debug("Stream setup failed : %s", avdtp_strerror(err));
        }
 }
 
@@ -375,11 +383,28 @@ static void discovery_complete(struct avdtp *session, GSList *seps, struct avdtp
        return;
 
 failed:
+       if (pending->msg)
+               error_failed(pending->conn, pending->msg, "Stream setup failed");
        pending_request_free(pending);
        sink->connect = NULL;
        avdtp_unref(sink->session);
        sink->session = NULL;
-       error_failed(pending->conn, pending->msg, "Stream setup failed");
+}
+
+gboolean sink_setup_stream(struct sink *sink, struct avdtp *session)
+{
+       if (sink->connect || sink->disconnect)
+               return FALSE;
+
+       if (session && !sink->session)
+               sink->session = avdtp_ref(session);
+
+       if (avdtp_discover(sink->session, discovery_complete, sink) < 0)
+               return FALSE;
+
+       sink->connect = g_new0(struct pending_request, 1);
+
+       return TRUE;
 }
 
 static DBusMessage *sink_connect(DBusConnection *conn,
@@ -405,12 +430,13 @@ static DBusMessage *sink_connect(DBusConnection *conn,
                                                ".AlreadyConnected",
                                                "Device Already Connected");
 
-       pending = g_new0(struct pending_request, 1);
+       if (!sink_setup_stream(sink, NULL))
+               return g_dbus_create_error(msg, ERROR_INTERFACE ".FAILED",
+                                               "Failed to create a stream");
+
+       pending = sink->connect;
        pending->conn = dbus_connection_ref(conn);
        pending->msg = dbus_message_ref(msg);
-       sink->connect = pending;
-
-       avdtp_discover(sink->session, discovery_complete, sink);
 
        debug("stream creation in progress");