summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2008-10-28 12:28:23 +0200
committerJohan Hedberg <johan.hedberg@nokia.com>2008-10-28 12:28:23 +0200
commit6fa921829d4fd308cba21ccc173853e6397f43ac (patch)
treeddc617affa4ebf9e316083deb3007ddd3d96e5e7 /common
parentf3a744a854ad0ee9275ea00832951a19bd838c6f (diff)
Reuse sdp_session_t during the service discovery process
Keep unused SDP sessions alive for 2 seconds so that we don't have to do a new sdp_connect for every step in the service discovery process.
Diffstat (limited to 'common')
-rw-r--r--common/glib-helper.c72
1 files changed, 70 insertions, 2 deletions
diff --git a/common/glib-helper.c b/common/glib-helper.c
index 93e9c27a..1812cc6d 100644
--- a/common/glib-helper.c
+++ b/common/glib-helper.c
@@ -44,6 +44,18 @@
#include "glib-helper.h"
+/* Number of seconds to keep a sdp_session_t in the cache */
+#define CACHE_TIMEOUT 2
+
+struct cached_sdp_session {
+ bdaddr_t src;
+ bdaddr_t dst;
+ sdp_session_t *session;
+ guint timer;
+};
+
+static GSList *cached_sdp_sessions = NULL;
+
typedef int (*resolver_t) (int fd, char *src, char *dst);
typedef BtIOError (*connect_t) (BtIO *io, BtIOFunc func);
typedef BtIOError (*listen_t) (BtIO *io, BtIOFunc func);
@@ -55,6 +67,62 @@ struct hci_cmd_data {
gpointer caller_data;
};
+static gboolean cached_session_expired(gpointer user_data)
+{
+ struct cached_sdp_session *cached = user_data;
+
+ cached_sdp_sessions = g_slist_remove(cached_sdp_sessions, cached);
+
+ sdp_close(cached->session);
+
+ g_free(cached);
+
+ return FALSE;
+}
+
+static sdp_session_t *get_sdp_session(const bdaddr_t *src, const bdaddr_t *dst)
+{
+ GSList *l;
+
+ for (l = cached_sdp_sessions; l != NULL; l = l->next) {
+ struct cached_sdp_session *c = l->data;
+ sdp_session_t *session;
+
+ if (bacmp(&c->src, src) || bacmp(&c->dst, dst))
+ continue;
+
+ g_source_remove(c->timer);
+
+ session = c->session;
+
+ cached_sdp_sessions = g_slist_remove(cached_sdp_sessions, c);
+ g_free(c);
+
+ return session;
+ }
+
+ return sdp_connect(src, dst, SDP_NON_BLOCKING);
+}
+
+static void cache_sdp_session(bdaddr_t *src, bdaddr_t *dst,
+ sdp_session_t *session)
+{
+ struct cached_sdp_session *cached;
+
+ cached = g_new0(struct cached_sdp_session, 1);
+
+ bacpy(&cached->src, src);
+ bacpy(&cached->dst, dst);
+
+ cached->session = session;
+
+ cached_sdp_sessions = g_slist_append(cached_sdp_sessions, cached);
+
+ cached->timer = g_timeout_add_seconds(CACHE_TIMEOUT,
+ cached_session_expired,
+ cached);
+}
+
int set_nonblocking(int fd)
{
long arg;
@@ -161,7 +229,7 @@ static void search_completed_cb(uint8_t type, uint16_t status,
} while (scanned < size && bytesleft > 0);
done:
- sdp_close(ctxt->session);
+ cache_sdp_session(&ctxt->src, &ctxt->dst, ctxt->session);
if (ctxt->cb)
ctxt->cb(recs, err, ctxt->user_data);
@@ -264,7 +332,7 @@ static int create_search_context(struct search_context **ctxt,
if (!ctxt)
return -EINVAL;
- s = sdp_connect(src, dst, SDP_NON_BLOCKING);
+ s = get_sdp_session(src, dst);
if (!s)
return -errno;