From c1a11f84561bff0a79fb210e931ce3748b4fc556 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 3 Oct 2012 18:29:14 +0300 Subject: [PATCH] core: Add SDP resolving callback for external profiles --- src/profile.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/src/profile.c b/src/profile.c index 5637bfa58..31f4556b0 100644 --- a/src/profile.c +++ b/src/profile.c @@ -246,12 +246,22 @@ static void new_conn_reply(DBusPendingCall *call, void *user_data) dbus_pending_call_unref(conn->new_conn); conn->new_conn = NULL; - if (!dbus_error_is_set(&err)) + if (!dbus_error_is_set(&err)) { + if (conn->cb) { + conn->cb(&ext->p, conn->device, 0); + conn->cb = NULL; + } return; + } error("%s replied with an error: %s, %s", ext->name, err.name, err.message); + if (conn->cb) { + conn->cb(&ext->p, conn->device, -ECONNREFUSED); + conn->cb = NULL; + } + if (dbus_error_has_name(&err, DBUS_ERROR_NO_REPLY)) ext_cancel(ext); @@ -691,8 +701,71 @@ static int connect_io(struct ext_io *conn, bdaddr_t *src, bdaddr_t *dst) static void record_cb(sdp_list_t *recs, int err, gpointer user_data) { struct ext_io *conn = user_data; + struct ext_profile *ext = conn->ext; + bdaddr_t src, dst; + sdp_list_t *r; conn->resolving = false; + + if (err < 0) { + error("Unable to get %s SDP record: %s", ext->name, + strerror(-err)); + goto failed; + } + + if (!recs || !recs->data) { + error("No SDP records found for %s", ext->name); + goto failed; + } + + for (r = recs; r != NULL; r = r->next) { + sdp_record_t *rec = r->data; + sdp_list_t *protos; + int port; + + if (sdp_get_access_protos(rec, &protos) < 0) { + error("Unable to get proto list from %s record", + ext->name); + goto failed; + } + + port = sdp_get_proto_port(protos, L2CAP_UUID); + if (port > 0) + ext->psm = port; + + port = sdp_get_proto_port(protos, RFCOMM_UUID); + if (port > 0) + ext->chan = port; + + sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, + NULL); + sdp_list_free(protos, NULL); + + if (ext->chan || ext->psm) + break; + } + + if (!ext->chan && !ext->psm) { + error("Failed to find L2CAP PSM or RFCOMM channel for %s", + ext->name); + goto failed; + } + + adapter_get_address(conn->adapter, &src); + device_get_address(conn->device, &dst, NULL); + + err = connect_io(conn, &src, &dst); + if (err < 0) { + error("Connecting %s failed: %s", ext->name, strerror(-err)); + goto failed; + } + + return; + +failed: + conn->cb(&ext->p, conn->device, err); + ext->conns = g_slist_remove(ext->conns, conn); + ext_io_destroy(conn); } static int resolve_service(struct ext_io *conn, bdaddr_t *src, bdaddr_t *dst) -- 2.47.3