diff --git a/obexd/client/session.c b/obexd/client/session.c
index e8915cf..266d00c 100644
--- a/obexd/client/session.c
+++ b/obexd/client/session.c
struct pending_data *pending;
};
+static GSList *sessions = NULL;
+
static void session_prepare_put(struct session_data *session, GError *err,
void *data);
static void session_terminate_transfer(struct session_data *session,
dbus_connection_unref(session->conn);
}
+ sessions = g_slist_remove(sessions, session);
+
g_free(session->callback);
g_free(session->path);
+ g_free(session->service);
g_free(session->owner);
g_free(session);
}
session->obex = obex;
+ sessions = g_slist_prepend(sessions, session);
+
done:
callback->func(callback->session, err, callback->data);
return sdp;
}
+static gboolean connection_complete(gpointer data)
+{
+ struct callback_data *cb = data;
+
+ cb->func(cb->session, 0, cb->data);
+
+ session_unref(cb->session);
+
+ g_free(cb);
+
+ return FALSE;
+}
+
static void owner_disconnected(DBusConnection *connection, void *user_data)
{
struct session_data *session = user_data;
return 0;
}
+static struct session_data *session_find(const char *source,
+ const char *destination,
+ const char *service,
+ uint8_t channel,
+ const char *owner)
+{
+ GSList *l;
+
+ for (l = sessions; l; l = l->next) {
+ struct session_data *session = l->data;
+ bdaddr_t adr;
+
+ if (source) {
+ str2ba(source, &adr);
+ if (bacmp(&session->src, &adr))
+ continue;
+ }
+
+ str2ba(destination, &adr);
+ if (bacmp(&session->dst, &adr))
+ continue;
+
+ if (g_strcmp0(service, session->service))
+ continue;
+
+ if (channel && session->channel != channel)
+ continue;
+
+ if (g_strcmp0(owner, session->owner))
+ continue;
+
+ return session;
+ }
+
+ return NULL;
+}
+
struct session_data *session_create(const char *source,
const char *destination,
const char *service,
if (destination == NULL)
return NULL;
+ session = session_find(source, destination, service, channel, owner);
+ if (session) {
+ session_ref(session);
+ goto proceed;
+ }
+
session = g_try_malloc0(sizeof(*session));
if (session == NULL)
return NULL;
str2ba(source, &session->src);
str2ba(destination, &session->dst);
+ session->service = g_strdup(service);
if (!g_ascii_strncasecmp(service, "OPP", 3)) {
sdp_uuid16_create(&session->uuid, OBEX_OBJPUSH_SVCLASS_ID);
return NULL;
}
+proceed:
callback = g_try_malloc0(sizeof(*callback));
if (callback == NULL) {
- session_free(session);
+ session_unref(session);
return NULL;
}
callback->func = function;
callback->data = user_data;
- if (session->channel > 0) {
+ if (session->obex) {
+ g_idle_add(connection_complete, callback);
+ err = 0;
+ } else if (session->channel > 0) {
session->io = rfcomm_connect(&session->src, &session->dst,
session->channel,
rfcomm_callback,
}
if (err < 0) {
- session_free(session);
+ session_unref(session);
g_free(callback);
return NULL;
}
diff --git a/obexd/client/session.h b/obexd/client/session.h
index eee439f..6f8a434 100644
--- a/obexd/client/session.h
+++ b/obexd/client/session.h
bdaddr_t src;
bdaddr_t dst;
uint8_t channel;
+ char *service; /* Service friendly name */
const char *target; /* OBEX Target UUID */
int target_len;
uuid_t uuid; /* Bluetooth Service Class */