OSDN Git Service

core: Fix SDP resolving for incoming external profile connections
authorJohan Hedberg <johan.hedberg@intel.com>
Thu, 31 Jan 2013 16:00:12 +0000 (10:00 -0600)
committerJohan Hedberg <johan.hedberg@intel.com>
Thu, 31 Jan 2013 16:05:30 +0000 (10:05 -0600)
This patch ensures that the reverse SDP procedure completes before we
accept incoming profiles for external profiles.

src/profile.c

index de0a4a0..e1e8b18 100644 (file)
@@ -563,6 +563,7 @@ struct ext_io {
        uint8_t chan;
 
        guint auth_id;
+       unsigned int svc_id;
        DBusPendingCall *pending;
 };
 
@@ -662,6 +663,10 @@ static void ext_io_destroy(gpointer p)
        if (ext_io->auth_id != 0)
                btd_cancel_authorization(ext_io->auth_id);
 
+       if (ext_io->svc_id != 0)
+               device_remove_svc_complete_callback(ext_io->device,
+                                                       ext_io->svc_id);
+
        if (ext_io->pending) {
                dbus_pending_call_cancel(ext_io->pending);
                dbus_pending_call_unref(ext_io->pending);
@@ -909,6 +914,38 @@ drop:
        ext_io_destroy(conn);
 }
 
+static void ext_svc_complete(struct btd_device *dev, int err, void *user_data)
+{
+       struct ext_io *conn = user_data;
+       struct ext_profile *ext = conn->ext;
+       const bdaddr_t *bdaddr;
+       GError *gerr = NULL;
+       char addr[18];
+
+       conn->svc_id = 0;
+
+       bdaddr = device_get_address(dev);
+       ba2str(bdaddr, addr);
+
+       if (err < 0) {
+               error("Service resolving failed for %s: %s (%d)",
+                                               addr, strerror(-err), -err);
+               goto drop;
+       }
+
+       DBG("Services resolved for %s. Accepting connection", addr);
+
+       if (!bt_io_accept(conn->io, ext_connect, conn, NULL, &gerr)) {
+               error("bt_io_accept: %s", gerr->message);
+               g_error_free(gerr);
+               goto drop;
+       }
+
+drop:
+       ext->conns = g_slist_remove(ext->conns, conn);
+       ext_io_destroy(conn);
+}
+
 static void ext_auth(DBusError *err, void *user_data)
 {
        struct ext_io *conn = user_data;
@@ -931,14 +968,12 @@ static void ext_auth(DBusError *err, void *user_data)
                goto drop;
        }
 
-       if (!bt_io_accept(conn->io, ext_connect, conn, NULL, &gerr)) {
-               error("bt_io_accept: %s", gerr->message);
-               g_error_free(gerr);
-               goto drop;
-       }
-
        DBG("%s authorized to connect to %s", addr, ext->name);
 
+       conn->svc_id = device_wait_for_svc_complete(conn->device,
+                                                       ext_svc_complete,
+                                                       conn);
+
        return;
 
 drop: