2012-01-30 15:30:24

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH obexd 01/13] client: fix not checking session_request return

From: Luiz Augusto von Dentz <[email protected]>

In case session_request return an error proceed to the next
---
client/session.c | 13 ++++++++++---
1 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/client/session.c b/client/session.c
index c127974..c9df832 100644
--- a/client/session.c
+++ b/client/session.c
@@ -687,9 +687,16 @@ static void session_terminate_transfer(struct obc_session *session,

obc_session_remove_transfer(session, transfer);

- if (session->pending)
- session_request(session, session_prepare_put,
- session->pending->data);
+ while (session->pending != NULL) {
+ struct obc_transfer *transfer = session->pending->data;
+ int err;
+
+ err = session_request(session, session_prepare_put, transfer);
+ if (err == 0)
+ break;
+
+ obc_session_remove_transfer(session, transfer);
+ }

obc_session_unref(session);
}
--
1.7.7.6



2012-01-31 16:39:56

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [PATCH obexd 03/13] client: fix not queuing requests properly

Hi Mikel,

On Tue, Jan 31, 2012 at 5:28 AM, Mikel Astiz <[email protected]> wrote:
>> -struct pending_data {
>> - ? ? ? session_callback_t cb;
>> +struct pending_request {
>> ? ? ? ? struct obc_session *session;
>> ? ? ? ? struct obc_transfer *transfer;
>> + ? ? ? session_callback_t auth_complete;
>
>
> I don't see the need to have a GError* as a parameter to the auth_complete
> ballback. It looks like a type reuse, but I'd suggest replacing the callback
> type with another specific one.

Yep, we can use GCallback or something similar, gonna fix that.

>> ? ? ? ? /* Unregister any pending transfer */
>> - ? ? ? while (l) {
>> - ? ? ? ? ? ? ? struct obc_transfer *transfer = l->data;
>> -
>> - ? ? ? ? ? ? ? l = l->next;
>> -
>> - ? ? ? ? ? ? ? obc_session_remove_transfer(session, transfer);
>> - ? ? ? }
>> + ? ? ? while ((p = g_queue_pop_head(session->queue)))
>> + ? ? ? ? ? ? ? pending_request_free(p);
>
>
> Would it simpler to use g_queue_foreach just like in session_free?

Yep gonna fix this too.

>>
>> - ? ? ? pending->cb(pending->session, NULL, transfer);
>> - ? ? ? g_free(pending);
>> + ? ? ? p->auth_complete(p->session, NULL, transfer);
>
>
> It seems like (auth_complete != NULL) should be checked here, or otherwise
> the check in session_request_reply should be removed.

Yep

--
Luiz Augusto von Dentz

2012-01-31 13:28:35

by Mikel Astiz

[permalink] [raw]
Subject: Re: [PATCH obexd 03/13] client: fix not queuing requests properly

Hi Luiz,

Some minor suggestions below.

On 01/30/2012 04:30 PM, Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz<[email protected]>
>
> OBEX does not support requests in parallel so they have to be queued
> like in SendFiles.
> ---
> client/session.c | 251 +++++++++++++++++++++++++----------------------------
> 1 files changed, 118 insertions(+), 133 deletions(-)
>
> diff --git a/client/session.c b/client/session.c
> index 92ae8cf..c7a0a51 100644
> --- a/client/session.c
> +++ b/client/session.c
> @@ -60,10 +60,12 @@ struct session_callback {
> void *data;
> };
>
> -struct pending_data {
> - session_callback_t cb;
> +struct pending_request {
> struct obc_session *session;
> struct obc_transfer *transfer;
> + session_callback_t auth_complete;

I don't see the need to have a GError* as a parameter to the
auth_complete ballback. It looks like a type reuse, but I'd suggest
replacing the callback type with another specific one.

> + session_callback_t func;
> + void *data;
> };
>
> struct obc_session {
> @@ -78,10 +80,10 @@ struct obc_session {
> DBusConnection *conn;
> GObex *obex;
> struct obc_agent *agent;
> - struct session_callback *callback;
> + struct pending_request *p;
> gchar *owner; /* Session owner */
> guint watch;
> - GSList *pending;
> + GQueue *queue;
> };
>
> static GSList *sessions = NULL;
> @@ -123,6 +125,17 @@ static void session_unregistered(struct obc_session *session)
> g_free(path);
> }
>
> +static void pending_request_free(struct pending_request *p)
> +{
> + if (p->transfer)
> + obc_transfer_unregister(p->transfer);
> +
> + if (p->session)
> + obc_session_unref(p->session);
> +
> + g_free(p);
> +}
> +
> static void session_free(struct obc_session *session)
> {
> DBG("%p", session);
> @@ -132,6 +145,12 @@ static void session_free(struct obc_session *session)
> obc_agent_free(session->agent);
> }
>
> + if (session->queue) {
> + g_queue_foreach(session->queue, (GFunc) pending_request_free,
> + NULL);
> + g_queue_free(session->queue);
> + }
> +
> if (session->watch)
> g_dbus_remove_watch(session->conn, session->watch);
>
> @@ -147,9 +166,11 @@ static void session_free(struct obc_session *session)
> if (session->conn)
> dbus_connection_unref(session->conn);
>
> + if (session->p)
> + pending_request_free(session->p);
> +
> sessions = g_slist_remove(sessions, session);
>
> - g_free(session->callback);
> g_free(session->path);
> g_free(session->owner);
> g_free(session->source);
> @@ -398,6 +419,7 @@ struct obc_session *obc_session_create(const char *source,
> session->source = g_strdup(source);
> session->destination = g_strdup(destination);
> session->channel = channel;
> + session->queue = g_queue_new();
>
> if (owner)
> obc_session_set_owner(session, owner, owner_disconnected);
> @@ -414,37 +436,17 @@ proceed:
> return session;
> }
>
> -static void obc_session_add_transfer(struct obc_session *session,
> - struct obc_transfer *transfer)
> -{
> - session->pending = g_slist_append(session->pending, transfer);
> - obc_session_ref(session);
> -}
> -
> -static void obc_session_remove_transfer(struct obc_session *session,
> - struct obc_transfer *transfer)
> -{
> - session->pending = g_slist_remove(session->pending, transfer);
> - obc_transfer_unregister(transfer);
> - obc_session_unref(session);
> -}
> -
> void obc_session_shutdown(struct obc_session *session)
> {
> - GSList *l = session->pending;
> + struct pending_request *p;
>
> DBG("%p", session);
>
> obc_session_ref(session);
>
> /* Unregister any pending transfer */
> - while (l) {
> - struct obc_transfer *transfer = l->data;
> -
> - l = l->next;
> -
> - obc_session_remove_transfer(session, transfer);
> - }
> + while ((p = g_queue_pop_head(session->queue)))
> + pending_request_free(p);

Would it simpler to use g_queue_foreach just like in session_free?

>
> /* Unregister interfaces */
> if (session->path)
> @@ -588,8 +590,9 @@ static GDBusMethodTable session_methods[] = {
>
> static void session_request_reply(DBusPendingCall *call, gpointer user_data)
> {
> - struct pending_data *pending = user_data;
> - struct obc_session *session = pending->session;
> + struct obc_session *session = user_data;
> + struct pending_request *p = session->p;
> + struct obc_transfer *transfer = p->transfer;
> DBusMessage *reply = dbus_pending_call_steal_reply(call);
> const char *name;
> DBusError derr;
> @@ -605,7 +608,7 @@ static void session_request_reply(DBusPendingCall *call, gpointer user_data)
>
> g_set_error(&gerr, OBEX_IO_ERROR, -ECANCELED, "%s",
> derr.message);
> - session_terminate_transfer(session, pending->transfer, gerr);
> + session_terminate_transfer(session, transfer, gerr);
> g_clear_error(&gerr);
>
> return;
> @@ -618,9 +621,11 @@ static void session_request_reply(DBusPendingCall *call, gpointer user_data)
> DBG("Agent.Request() reply: %s", name);
>
> if (strlen(name))
> - obc_transfer_set_name(pending->transfer, name);
> + obc_transfer_set_name(transfer, name);
> +
> + if (p->auth_complete)
> + p->auth_complete(session, NULL, transfer);
>
> - pending->cb(session, NULL, pending->transfer);
> dbus_message_unref(reply);
>
> return;
> @@ -628,74 +633,102 @@ static void session_request_reply(DBusPendingCall *call, gpointer user_data)
>
> static gboolean session_request_proceed(gpointer data)
> {
> - struct pending_data *pending = data;
> - struct obc_transfer *transfer = pending->transfer;
> + struct obc_session *session = data;
> + struct pending_request *p = session->p;
> + struct obc_transfer *transfer = p->transfer;
>
> - pending->cb(pending->session, NULL, transfer);
> - g_free(pending);
> + p->auth_complete(p->session, NULL, transfer);

It seems like (auth_complete != NULL) should be checked here, or
otherwise the check in session_request_reply should be removed.

>
> return FALSE;
> }
>
> -static int session_request(struct obc_session *session, session_callback_t cb,
> - struct obc_transfer *transfer)
> +static int pending_request_auth(struct pending_request *p)
> {
> + struct obc_session *session = p->session;
> struct obc_agent *agent = session->agent;
> - struct pending_data *pending;
> const char *path;
> - int err;
> -
> - pending = g_new0(struct pending_data, 1);
> - pending->cb = cb;
> - pending->session = session;
> - pending->transfer = transfer;
>
> - path = obc_transfer_get_path(transfer);
> + path = obc_transfer_get_path(p->transfer);
>
> if (agent == NULL || path == NULL) {
> - g_idle_add(session_request_proceed, pending);
> + g_idle_add(session_request_proceed, session);
> return 0;
> }
>
> - err = obc_agent_request(agent, path, session_request_reply, pending,
> - g_free);
> + return obc_agent_request(agent, path, session_request_reply, session,
> + NULL);
> +}
> +
> +static int session_request(struct obc_session *session,
> + struct obc_transfer *transfer,
> + session_callback_t auth_complete,
> + session_callback_t func,
> + void *data)
> +{
> + struct pending_request *p;
> + int err;
> +
> + p = g_new0(struct pending_request, 1);
> + p->session = obc_session_ref(session);
> + p->transfer = transfer;
> + p->auth_complete = auth_complete;
> + p->func = func;
> + p->data = data;
> +
> + if (session->p) {
> + g_queue_push_tail(session->queue, p);
> + return 0;
> + }
> +
> + err = pending_request_auth(p);
> if (err< 0) {
> - g_free(pending);
> + pending_request_free(p);
> return err;
> }
>
> + session->p = p;
> +
> return 0;
> }
>
> +static void session_process_queue(struct obc_session *session)
> +{
> + struct pending_request *p;
> +
> + if (session->queue == NULL || g_queue_is_empty(session->queue))
> + return;
> +
> + while ((p = g_queue_pop_head(session->queue))) {
> + int err;
> +
> + err = pending_request_auth(p);
> + if (err == 0) {
> + session->p = p;
> + return;
> + }
> +
> + pending_request_free(p);
> + }
> +}
> +
> static void session_terminate_transfer(struct obc_session *session,
> struct obc_transfer *transfer,
> GError *gerr)
> {
> - struct session_callback *callback = session->callback;
> + struct pending_request *p = session->p;
>
> - if (callback) {
> - obc_session_ref(session);
> - callback->func(session, gerr, callback->data);
> - if (g_slist_find(session->pending, transfer))
> - obc_session_remove_transfer(session, transfer);
> - obc_session_unref(session);
> + if (p == NULL || p->transfer != transfer)
> return;
> - }
>
> obc_session_ref(session);
>
> - obc_session_remove_transfer(session, transfer);
> -
> - while (session->pending != NULL) {
> - struct obc_transfer *transfer = session->pending->data;
> - int err;
> + if (p->func)
> + p->func(session, gerr, p->data);
>
> - err = session_request(session, session_prepare_put, transfer);
> - if (err == 0)
> - break;
> + pending_request_free(p);
> + session->p = NULL;
>
> - obc_session_remove_transfer(session, transfer);
> - }
> + session_process_queue(session);
>
> obc_session_unref(session);
> }
> @@ -804,7 +837,6 @@ int obc_session_get(struct obc_session *session, const char *type,
> struct obc_transfer *transfer;
> struct obc_transfer_params *params = NULL;
> const char *agent;
> - int err;
>
> if (session->obex == NULL)
> return -ENOTCONN;
> @@ -833,23 +865,8 @@ int obc_session_get(struct obc_session *session, const char *type,
> return -EIO;
> }
>
> - if (func != NULL) {
> - struct session_callback *callback;
> - callback = g_new0(struct session_callback, 1);
> - callback->func = func;
> - callback->data = user_data;
> - session->callback = callback;
> - }
> -
> - err = session_request(session, session_prepare_get, transfer);
> - if (err< 0) {
> - obc_transfer_unregister(transfer);
> - return err;
> - }
> -
> - obc_session_add_transfer(session, transfer);
> -
> - return 0;
> + return session_request(session, transfer, session_prepare_get,
> + func, user_data);
> }
>
> int obc_session_send(struct obc_session *session, const char *filename,
> @@ -872,26 +889,13 @@ int obc_session_send(struct obc_session *session, const char *filename,
> return -EINVAL;
>
> err = obc_transfer_set_file(transfer);
> - if (err< 0)
> - goto fail;
> -
> - /* Transfer should start if it is the first in the pending list */
> - if (session->pending != NULL)
> - goto done;
> -
> - err = session_request(session, session_prepare_put, transfer);
> - if (err< 0)
> - goto fail;
> -
> -done:
> - obc_session_add_transfer(session, transfer);
> -
> - return 0;
> -
> -fail:
> - obc_transfer_unregister(transfer);
> + if (err< 0) {
> + obc_transfer_unregister(transfer);
> + return err;
> + }
>
> - return err;
> + return session_request(session, transfer, session_prepare_put,
> + NULL, NULL);
> }
>
> int obc_session_pull(struct obc_session *session,
> @@ -900,7 +904,6 @@ int obc_session_pull(struct obc_session *session,
> {
> struct obc_transfer *transfer;
> const char *agent;
> - int err;
>
> if (session->obex == NULL)
> return -ENOTCONN;
> @@ -918,22 +921,8 @@ int obc_session_pull(struct obc_session *session,
> return -EIO;
> }
>
> - if (function != NULL) {
> - struct session_callback *callback;
> - callback = g_new0(struct session_callback, 1);
> - callback->func = function;
> - callback->data = user_data;
> - session->callback = callback;
> - }
> -
> - err = session_request(session, session_prepare_get, transfer);
> - if (err == 0) {
> - obc_session_add_transfer(session, transfer);
> - return 0;
> - }
> -
> - obc_transfer_unregister(transfer);
> - return err;
> + return session_request(session, transfer, session_prepare_get,
> + function, user_data);
> }
>
> const char *obc_session_register(struct obc_session *session,
> @@ -990,14 +979,10 @@ int obc_session_put(struct obc_session *session, char *buf, const char *targetna
> {
> struct obc_transfer *transfer;
> const char *agent;
> - int err;
>
> if (session->obex == NULL)
> return -ENOTCONN;
>
> - if (session->pending != NULL)
> - return -EISCONN;
> -
> agent = obc_agent_get_name(session->agent);
>
> transfer = obc_transfer_register(session->conn, session->obex,
> @@ -1009,11 +994,8 @@ int obc_session_put(struct obc_session *session, char *buf, const char *targetna
>
> obc_transfer_set_buffer(transfer, buf);
>
> - err = session_request(session, session_prepare_put, transfer);
> - if (err< 0)
> - return err;
> -
> - return 0;
> + return session_request(session, transfer, session_prepare_put,
> + NULL, NULL);
> }
>
> static void agent_destroy(gpointer data, gpointer user_data)
> @@ -1085,7 +1067,10 @@ GObex *obc_session_get_obex(struct obc_session *session)
> static struct obc_transfer *obc_session_get_transfer(
> struct obc_session *session)
> {
> - return session->pending ? session->pending->data : NULL;
> + if (session->p == NULL)
> + return NULL;
> +
> + return session->p->transfer;
> }
>
> const char *obc_session_get_buffer(struct obc_session *session, size_t *size)
> --
> 1.7.7.6
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html

Cheers,
Mikel


2012-01-30 15:30:30

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH obexd 07/13] client: introduce obc_session_move

From: Luiz Augusto von Dentz <[email protected]>

---
client/session.c | 30 ++++++++++++++++++++++++++++++
client/session.h | 3 +++
2 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/client/session.c b/client/session.c
index f664372..9f07114 100644
--- a/client/session.c
+++ b/client/session.c
@@ -1340,3 +1340,33 @@ guint obc_session_copy(struct obc_session *session, const char *filename,
session->p = p;
return p->id;
}
+
+guint obc_session_move(struct obc_session *session, const char *filename,
+ const char *destname, session_callback_t func,
+ void *user_data, GError **err)
+{
+ struct pending_request *p;
+
+ if (session->obex == NULL) {
+ g_set_error(err, OBEX_IO_ERROR, -ENOTCONN,
+ strerror(-ENOTCONN));
+ return 0;
+ }
+
+ if (session->p != NULL) {
+ g_set_error(err, OBEX_IO_ERROR, -EBUSY, strerror(-EBUSY));
+ return 0;
+ }
+
+ p = pending_request_new(session, NULL, NULL, func, user_data);
+
+ p->req_id = g_obex_move(session->obex, filename, destname, async_cb, p,
+ err);
+ if (*err != NULL) {
+ pending_request_free(p);
+ return 0;
+ }
+
+ session->p = p;
+ return p->id;
+}
diff --git a/client/session.h b/client/session.h
index 57f3fcd..64548e9 100644
--- a/client/session.h
+++ b/client/session.h
@@ -83,3 +83,6 @@ guint obc_session_mkdir(struct obc_session *session, const char *folder,
guint obc_session_copy(struct obc_session *session, const char *filename,
const char *destname, session_callback_t func,
void *user_data, GError **err);
+guint obc_session_move(struct obc_session *session, const char *filename,
+ const char *destname, session_callback_t func,
+ void *user_data, GError **err);
--
1.7.7.6


2012-01-30 15:30:29

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH obexd 06/13] client: introduce obc_session_copy

From: Luiz Augusto von Dentz <[email protected]>

---
client/session.c | 30 ++++++++++++++++++++++++++++++
client/session.h | 3 +++
2 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/client/session.c b/client/session.c
index 7816a05..f664372 100644
--- a/client/session.c
+++ b/client/session.c
@@ -1310,3 +1310,33 @@ guint obc_session_mkdir(struct obc_session *session, const char *folder,
session->p = p;
return p->id;
}
+
+guint obc_session_copy(struct obc_session *session, const char *filename,
+ const char *destname, session_callback_t func,
+ void *user_data, GError **err)
+{
+ struct pending_request *p;
+
+ if (session->obex == NULL) {
+ g_set_error(err, OBEX_IO_ERROR, -ENOTCONN,
+ strerror(-ENOTCONN));
+ return 0;
+ }
+
+ if (session->p != NULL) {
+ g_set_error(err, OBEX_IO_ERROR, -EBUSY, strerror(-EBUSY));
+ return 0;
+ }
+
+ p = pending_request_new(session, NULL, NULL, func, user_data);
+
+ p->req_id = g_obex_copy(session->obex, filename, destname, async_cb, p,
+ err);
+ if (*err != NULL) {
+ pending_request_free(p);
+ return 0;
+ }
+
+ session->p = p;
+ return p->id;
+}
diff --git a/client/session.h b/client/session.h
index a424054..57f3fcd 100644
--- a/client/session.h
+++ b/client/session.h
@@ -80,3 +80,6 @@ guint obc_session_setpath(struct obc_session *session, const char *path,
guint obc_session_mkdir(struct obc_session *session, const char *folder,
session_callback_t func, void *user_data,
GError **err);
+guint obc_session_copy(struct obc_session *session, const char *filename,
+ const char *destname, session_callback_t func,
+ void *user_data, GError **err);
--
1.7.7.6


2012-01-30 15:30:31

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH obexd 08/13] client: introduce obc_session_delete

From: Luiz Augusto von Dentz <[email protected]>

---
client/session.c | 29 +++++++++++++++++++++++++++++
client/session.h | 3 +++
2 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/client/session.c b/client/session.c
index 9f07114..44d86f2 100644
--- a/client/session.c
+++ b/client/session.c
@@ -1370,3 +1370,32 @@ guint obc_session_move(struct obc_session *session, const char *filename,
session->p = p;
return p->id;
}
+
+guint obc_session_delete(struct obc_session *session, const char *file,
+ session_callback_t func, void *user_data,
+ GError **err)
+{
+ struct pending_request *p;
+
+ if (session->obex == NULL) {
+ g_set_error(err, OBEX_IO_ERROR, -ENOTCONN,
+ strerror(-ENOTCONN));
+ return 0;
+ }
+
+ if (session->p != NULL) {
+ g_set_error(err, OBEX_IO_ERROR, -EBUSY, strerror(-EBUSY));
+ return 0;
+ }
+
+ p = pending_request_new(session, NULL, NULL, func, user_data);
+
+ p->req_id = g_obex_delete(session->obex, file, async_cb, p, err);
+ if (*err != NULL) {
+ pending_request_free(p);
+ return 0;
+ }
+
+ session->p = p;
+ return p->id;
+}
diff --git a/client/session.h b/client/session.h
index 64548e9..ac5c27a 100644
--- a/client/session.h
+++ b/client/session.h
@@ -86,3 +86,6 @@ guint obc_session_copy(struct obc_session *session, const char *filename,
guint obc_session_move(struct obc_session *session, const char *filename,
const char *destname, session_callback_t func,
void *user_data, GError **err);
+guint obc_session_delete(struct obc_session *session, const char *file,
+ session_callback_t func, void *user_data,
+ GError **err);
--
1.7.7.6


2012-01-30 15:30:36

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH obexd 13/13] client: remove gobex dependency of session

From: Luiz Augusto von Dentz <[email protected]>

Modules should no longer need to access gobex directly
---
client/ftp.c | 1 -
client/session.c | 5 -----
client/session.h | 2 --
3 files changed, 0 insertions(+), 8 deletions(-)

diff --git a/client/ftp.c b/client/ftp.c
index 92fcaad..9e3f6b3 100644
--- a/client/ftp.c
+++ b/client/ftp.c
@@ -33,7 +33,6 @@
#include "log.h"

#include "session.h"
-#include "transfer.h"
#include "driver.h"
#include "ftp.h"

diff --git a/client/session.c b/client/session.c
index f2be457..868e460 100644
--- a/client/session.c
+++ b/client/session.c
@@ -1088,11 +1088,6 @@ const char *obc_session_get_target(struct obc_session *session)
return session->driver->target;
}

-GObex *obc_session_get_obex(struct obc_session *session)
-{
- return session->obex;
-}
-
static struct obc_transfer *obc_session_get_transfer(
struct obc_session *session)
{
diff --git a/client/session.h b/client/session.h
index 008b466..f082510 100644
--- a/client/session.h
+++ b/client/session.h
@@ -24,7 +24,6 @@
#include <stdint.h>
#include <glib.h>
#include <gdbus.h>
-#include <gobex.h>

struct obc_session;

@@ -56,7 +55,6 @@ const char *obc_session_get_agent(struct obc_session *session);

const char *obc_session_get_path(struct obc_session *session);
const char *obc_session_get_target(struct obc_session *session);
-GObex *obc_session_get_obex(struct obc_session *session);
const char *obc_session_get_buffer(struct obc_session *session, size_t *size);
void *obc_session_get_params(struct obc_session *session, size_t *size);

--
1.7.7.6


2012-01-30 15:30:35

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH obexd 12/13] client: remove use of gobex in ftp module

From: Luiz Augusto von Dentz <[email protected]>

gobex should not be use directly as it can interfere with ongoing
requests of the session.
---
client/ftp.c | 17 ++++++-----------
1 files changed, 6 insertions(+), 11 deletions(-)

diff --git a/client/ftp.c b/client/ftp.c
index fdadf43..92fcaad 100644
--- a/client/ftp.c
+++ b/client/ftp.c
@@ -52,7 +52,7 @@ struct ftp_data {
DBusMessage *msg;
};

-static void async_cb(GObex *obex, GError *err, GObexPacket *rsp,
+static void async_cb(struct obc_session *session, GError *err,
gpointer user_data)
{
DBusMessage *reply, *msg = user_data;
@@ -72,7 +72,6 @@ static DBusMessage *change_folder(DBusConnection *connection,
{
struct ftp_data *ftp = user_data;
struct obc_session *session = ftp->session;
- GObex *obex = obc_session_get_obex(session);
const char *folder;
GError *err = NULL;

@@ -82,7 +81,7 @@ static DBusMessage *change_folder(DBusConnection *connection,
return g_dbus_create_error(message,
"org.openobex.Error.InvalidArguments", NULL);

- g_obex_setpath(obex, folder, async_cb, message, &err);
+ obc_session_setpath(session, folder, async_cb, message, &err);
if (err != NULL) {
DBusMessage *reply;
reply = g_dbus_create_error(message,
@@ -235,7 +234,6 @@ static DBusMessage *create_folder(DBusConnection *connection,
{
struct ftp_data *ftp = user_data;
struct obc_session *session = ftp->session;
- GObex *obex = obc_session_get_obex(session);
const char *folder;
GError *err = NULL;

@@ -245,7 +243,7 @@ static DBusMessage *create_folder(DBusConnection *connection,
return g_dbus_create_error(message,
"org.openobex.Error.InvalidArguments", NULL);

- g_obex_mkdir(obex, folder, async_cb, message, &err);
+ obc_session_mkdir(session, folder, async_cb, message, &err);
if (err != NULL) {
DBusMessage *reply;
reply = g_dbus_create_error(message,
@@ -340,7 +338,6 @@ static DBusMessage *copy_file(DBusConnection *connection,
{
struct ftp_data *ftp = user_data;
struct obc_session *session = ftp->session;
- GObex *obex = obc_session_get_obex(session);
const char *filename, *destname;
GError *err = NULL;

@@ -351,7 +348,7 @@ static DBusMessage *copy_file(DBusConnection *connection,
return g_dbus_create_error(message,
"org.openobex.Error.InvalidArguments", NULL);

- g_obex_copy(obex, filename, destname, async_cb, message, &err);
+ obc_session_copy(session, filename, destname, async_cb, message, &err);
if (err != NULL) {
DBusMessage *reply;
reply = g_dbus_create_error(message,
@@ -371,7 +368,6 @@ static DBusMessage *move_file(DBusConnection *connection,
{
struct ftp_data *ftp = user_data;
struct obc_session *session = ftp->session;
- GObex *obex = obc_session_get_obex(session);
const char *filename, *destname;
GError *err = NULL;

@@ -382,7 +378,7 @@ static DBusMessage *move_file(DBusConnection *connection,
return g_dbus_create_error(message,
"org.openobex.Error.InvalidArguments", NULL);

- g_obex_move(obex, filename, destname, async_cb, message, &err);
+ obc_session_move(session, filename, destname, async_cb, message, &err);
if (err != NULL) {
DBusMessage *reply;
reply = g_dbus_create_error(message,
@@ -402,7 +398,6 @@ static DBusMessage *delete(DBusConnection *connection,
{
struct ftp_data *ftp = user_data;
struct obc_session *session = ftp->session;
- GObex *obex = obc_session_get_obex(session);
const char *file;
GError *err = NULL;

@@ -412,7 +407,7 @@ static DBusMessage *delete(DBusConnection *connection,
return g_dbus_create_error(message,
"org.openobex.Error.InvalidArguments", NULL);

- g_obex_delete(obex, file, async_cb, message, &err);
+ obc_session_delete(session, file, async_cb, message, &err);
if (err != NULL) {
DBusMessage *reply;
reply = g_dbus_create_error(message,
--
1.7.7.6


2012-01-30 15:30:34

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH obexd 11/13] client: remove use of gobex in map module

From: Luiz Augusto von Dentz <[email protected]>

gobex should not be use directly as it can interfere with ongoing
requests of the session.
---
client/map.c | 14 ++------------
1 files changed, 2 insertions(+), 12 deletions(-)

diff --git a/client/map.c b/client/map.c
index 9a76919..68b1fbc 100644
--- a/client/map.c
+++ b/client/map.c
@@ -48,23 +48,16 @@ struct map_data {

static DBusConnection *conn = NULL;

-static void simple_cb(GObex *obex, GError *err, GObexPacket *rsp,
+static void simple_cb(struct obc_session *session, GError *err,
gpointer user_data)
{
DBusMessage *reply;
struct map_data *map = user_data;
- guint8 err_code = g_obex_packet_get_operation(rsp, NULL);

if (err != NULL)
reply = g_dbus_create_error(map->msg,
"org.openobex.Error.Failed",
"%s", err->message);
- else if (err_code != G_OBEX_RSP_SUCCESS)
- reply = g_dbus_create_error(map->msg,
- "org.openobex.Error.Failed",
- "%s (0x%02x)",
- g_obex_strerror(err_code),
- err_code);
else
reply = dbus_message_new_method_return(map->msg);

@@ -77,7 +70,6 @@ static DBusMessage *map_setpath(DBusConnection *connection,
{
struct map_data *map = user_data;
const char *folder;
- GObex *obex;
GError *err = NULL;

if (dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &folder,
@@ -86,9 +78,7 @@ static DBusMessage *map_setpath(DBusConnection *connection,
"org.openobex.Error.InvalidArguments",
NULL);

- obex = obc_session_get_obex(map->session);
-
- g_obex_setpath(obex, folder, simple_cb, map, &err);
+ obc_session_setpath(map->session, folder, simple_cb, map, &err);
if (err != NULL) {
DBusMessage *reply;
reply = g_dbus_create_error(message,
--
1.7.7.6


2012-01-30 15:30:33

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH obexd 10/13] client: remove use of gobex in pbap module

From: Luiz Augusto von Dentz <[email protected]>

gobex should not be use directly as it can interfere with ongoing
requests of the session.
---
client/pbap.c | 132 ++++++++++++++++----------------------------------------
1 files changed, 38 insertions(+), 94 deletions(-)

diff --git a/client/pbap.c b/client/pbap.c
index 4a93fd5..e1db0e7 100644
--- a/client/pbap.c
+++ b/client/pbap.c
@@ -124,6 +124,8 @@ static const char *filter_list[] = {
#define PBAP_INTERFACE "org.openobex.PhonebookAccess"
#define PBAP_UUID "0000112f-0000-1000-8000-00805f9b34fb"

+#define PBAP_ERROR pbap_error_quark()
+
struct pbap_data {
struct obc_session *session;
char *path;
@@ -167,6 +169,11 @@ struct apparam_hdr {

static DBusConnection *conn = NULL;

+static GQuark pbap_error_quark(void)
+{
+ return g_quark_from_static_string("pbap-error-quark");
+}
+
static void listing_element(GMarkupParseContext *ctxt,
const gchar *element,
const gchar **names,
@@ -240,84 +247,17 @@ static gchar *build_phonebook_path(const char *location, const char *item)
return path;
}

-typedef void (*setpath_cb_t) (GError *err, gpointer user_data);
-
-struct setpath_data {
- char **remaining;
- int index;
- setpath_cb_t func;
- gpointer user_data;
-};
-
-static void setpath_complete(GError *err, struct setpath_data *data)
-{
- if (data->func)
- data->func(err, data->user_data);
- g_strfreev(data->remaining);
- g_free(data);
-}
-
-static void setpath_cb(GObex *obex, GError *err, GObexPacket *rsp,
- gpointer user_data)
-{
- struct setpath_data *data = user_data;
- char *next;
-
- if (err != NULL) {
- setpath_complete(err, data);
- return;
- }
-
- next = data->remaining[data->index];
- if (next == NULL) {
- setpath_complete(NULL, data);
- return;
- }
-
- data->index++;
-
- g_obex_setpath(obex, next, setpath_cb, data, &err);
- if (err != NULL) {
- setpath_complete(err, data);
- g_error_free(err);
- }
-}
-
-static gboolean setpath(GObex *obex, const char *path, size_t max_elem,
- setpath_cb_t func, gpointer user_data)
-{
- GError *err = NULL;
- struct setpath_data *data;
-
- data = g_new0(struct setpath_data, 1);
-
- g_obex_setpath(obex, "", setpath_cb, data, &err);
- if (err != NULL) {
- error("set_path: %s", err->message);
- g_error_free(err);
- g_free(data);
- return FALSE;
- }
-
- data->func = func;
- data->user_data = user_data;
- data->remaining = g_strsplit(path, "/", max_elem);
-
- return TRUE;
-}
-
/* should only be called inside pbap_set_path */
static void pbap_reset_path(struct pbap_data *pbap)
{
- GObex *obex = obc_session_get_obex(pbap->session);
-
if (!pbap->path)
return;

- setpath(obex, pbap->path, 3, NULL, NULL);
+ obc_session_setpath(pbap->session, pbap->path, NULL, NULL, NULL);
}

-static void pbap_setpath_cb(GError *err, gpointer user_data)
+static void pbap_setpath_cb(struct obc_session *session, GError *err,
+ gpointer user_data)
{
struct pbap_data *pbap = user_data;

@@ -339,23 +279,32 @@ static void pbap_setpath_cb(GError *err, gpointer user_data)
pbap->msg = NULL;
}

-static int pbap_set_path(struct pbap_data *pbap, const char *path)
+static gboolean pbap_setpath(struct pbap_data *pbap, const char *location,
+ const char *item, GError **err)
{
- GObex *obex = obc_session_get_obex(pbap->session);
+ char *path;

- if (!path)
- return G_OBEX_RSP_BAD_REQUEST;
+ path = build_phonebook_path(location, item);
+ if (path == NULL) {
+ g_set_error(err, PBAP_ERROR, -EINVAL, strerror(-EINVAL));
+ return FALSE;
+ }

- if (pbap->path != NULL && g_str_equal(pbap->path, path))
- return 0;
+ if (pbap->path != NULL && g_str_equal(pbap->path, path)) {
+ g_free(path);
+ return TRUE;
+ }

- if (!setpath(obex, path, 3, pbap_setpath_cb, pbap))
- return G_OBEX_RSP_INTERNAL_SERVER_ERROR;
+ obc_session_setpath(pbap->session, path, pbap_setpath_cb, pbap, err);
+ if (err != NULL) {
+ g_free(pbap->path);
+ pbap->path = path;
+ return TRUE;
+ }

- g_free(pbap->path);
- pbap->path = g_strdup(path);
+ g_free(path);

- return G_OBEX_RSP_SUCCESS;
+ return FALSE;
}

static void read_return_apparam(struct obc_session *session,
@@ -748,8 +697,7 @@ static DBusMessage *pbap_select(DBusConnection *connection,
{
struct pbap_data *pbap = user_data;
const char *item, *location;
- char *path = NULL;
- int err = 0;
+ GError *err = NULL;

if (dbus_message_get_args(message, NULL,
DBUS_TYPE_STRING, &location,
@@ -758,17 +706,13 @@ static DBusMessage *pbap_select(DBusConnection *connection,
return g_dbus_create_error(message,
ERROR_INF ".InvalidArguments", NULL);

- path = build_phonebook_path(location, item);
- if (!path)
- return g_dbus_create_error(message,
- ERROR_INF ".InvalidArguments", "InvalidPhonebook");
-
- err = pbap_set_path(pbap, path);
- g_free(path);
- if (err != G_OBEX_RSP_SUCCESS)
- return g_dbus_create_error(message,
- ERROR_INF ".Failed",
- "0x%02x", err);
+ if (!pbap_setpath(pbap, location, item, &err)) {
+ DBusMessage *reply;
+ reply = g_dbus_create_error(message, ERROR_INF ".Failed",
+ "%s", err->message);
+ g_error_free(err);
+ return reply;
+ }

pbap->msg = dbus_message_ref(message);

--
1.7.7.6


2012-01-30 15:30:32

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH obexd 09/13] client: introduce obc_session_cancel

From: Luiz Augusto von Dentz <[email protected]>

---
client/session.c | 21 +++++++++++++++++++++
client/session.h | 2 ++
2 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/client/session.c b/client/session.c
index 44d86f2..f2be457 100644
--- a/client/session.c
+++ b/client/session.c
@@ -1399,3 +1399,24 @@ guint obc_session_delete(struct obc_session *session, const char *file,
session->p = p;
return p->id;
}
+
+void obc_session_cancel(struct obc_session *session, guint id,
+ gboolean remove)
+{
+ struct pending_request *p = session->p;
+
+ if (p == NULL || p->id != id)
+ return;
+
+ if (p->req_id == 0)
+ return;
+
+ g_obex_cancel_req(session->obex, p->req_id, remove);
+ if (!remove)
+ return;
+
+ pending_request_free(p);
+ session->p = NULL;
+
+ session_process_queue(session);
+}
diff --git a/client/session.h b/client/session.h
index ac5c27a..008b466 100644
--- a/client/session.h
+++ b/client/session.h
@@ -89,3 +89,5 @@ guint obc_session_move(struct obc_session *session, const char *filename,
guint obc_session_delete(struct obc_session *session, const char *file,
session_callback_t func, void *user_data,
GError **err);
+void obc_session_cancel(struct obc_session *session, guint id,
+ gboolean remove);
--
1.7.7.6


2012-01-30 15:30:28

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH obexd 05/13] client: introduce obc_session_mkdir

From: Luiz Augusto von Dentz <[email protected]>

---
client/session.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
client/session.h | 3 ++
2 files changed, 66 insertions(+), 0 deletions(-)

diff --git a/client/session.c b/client/session.c
index ed7785c..7816a05 100644
--- a/client/session.c
+++ b/client/session.c
@@ -1247,3 +1247,66 @@ fail:
pending_request_free(p);
return 0;
}
+
+static void async_cb(GObex *obex, GError *err, GObexPacket *rsp,
+ gpointer user_data)
+{
+ struct pending_request *p = user_data;
+ struct obc_session *session = p->session;
+ GError *gerr = NULL;
+ uint8_t code;
+
+ p->req_id = 0;
+
+ if (err != NULL) {
+ if (p->func)
+ p->func(p->session, err, p->data);
+ goto done;
+ }
+
+ code = g_obex_packet_get_operation(rsp, NULL);
+ if (code != G_OBEX_RSP_SUCCESS)
+ g_set_error(&gerr, OBEX_IO_ERROR, code, "%s",
+ g_obex_strerror(code));
+
+ if (p->func)
+ p->func(p->session, gerr, p->data);
+
+ if (gerr != NULL)
+ g_clear_error(&gerr);
+
+done:
+ pending_request_free(p);
+ session->p = NULL;
+
+ session_process_queue(session);
+}
+
+guint obc_session_mkdir(struct obc_session *session, const char *folder,
+ session_callback_t func, void *user_data,
+ GError **err)
+{
+ struct pending_request *p;
+
+ if (session->obex == NULL) {
+ g_set_error(err, OBEX_IO_ERROR, -ENOTCONN,
+ strerror(-ENOTCONN));
+ return 0;
+ }
+
+ if (session->p != NULL) {
+ g_set_error(err, OBEX_IO_ERROR, -EBUSY, strerror(-EBUSY));
+ return 0;
+ }
+
+ p = pending_request_new(session, NULL, NULL, func, user_data);
+
+ p->req_id = g_obex_mkdir(session->obex, folder, async_cb, p, err);
+ if (*err != NULL) {
+ pending_request_free(p);
+ return 0;
+ }
+
+ session->p = p;
+ return p->id;
+}
diff --git a/client/session.h b/client/session.h
index 65cf4bd..a424054 100644
--- a/client/session.h
+++ b/client/session.h
@@ -77,3 +77,6 @@ int obc_session_put(struct obc_session *session, char *buf,
guint obc_session_setpath(struct obc_session *session, const char *path,
session_callback_t func, void *user_data,
GError **err);
+guint obc_session_mkdir(struct obc_session *session, const char *folder,
+ session_callback_t func, void *user_data,
+ GError **err);
--
1.7.7.6


2012-01-30 15:30:27

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH obexd 04/13] client: introduce obc_session_setpath

From: Luiz Augusto von Dentz <[email protected]>

---
client/session.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
client/session.h | 4 ++
2 files changed, 145 insertions(+), 0 deletions(-)

diff --git a/client/session.c b/client/session.c
index c7a0a51..ed7785c 100644
--- a/client/session.c
+++ b/client/session.c
@@ -61,6 +61,8 @@ struct session_callback {
};

struct pending_request {
+ guint id;
+ guint req_id;
struct obc_session *session;
struct obc_transfer *transfer;
session_callback_t auth_complete;
@@ -68,6 +70,13 @@ struct pending_request {
void *data;
};

+struct setpath_data {
+ char **remaining;
+ int index;
+ session_callback_t func;
+ void *user_data;
+};
+
struct obc_session {
guint id;
gint refcount;
@@ -125,6 +134,26 @@ static void session_unregistered(struct obc_session *session)
g_free(path);
}

+static struct pending_request *pending_request_new(struct obc_session *session,
+ struct obc_transfer *transfer,
+ session_callback_t auth,
+ session_callback_t func,
+ void *data)
+{
+ struct pending_request *p;
+ static guint id = 0;
+
+ p = g_new0(struct pending_request, 1);
+ p->id = ++id;
+ p->session = obc_session_ref(session);
+ p->transfer = transfer;
+ p->auth_complete = auth;
+ p->func = func;
+ p->data = data;
+
+ return p;
+}
+
static void pending_request_free(struct pending_request *p)
{
if (p->transfer)
@@ -1106,3 +1135,115 @@ void *obc_session_get_params(struct obc_session *session, size_t *size)

return params.data;
}
+
+static void setpath_complete(struct obc_session *session, GError *err,
+ void *user_data)
+{
+ struct pending_request *p = user_data;
+ struct setpath_data *data = p->data;
+
+ if (data->func)
+ data->func(session, err, data->user_data);
+
+ g_strfreev(data->remaining);
+ g_free(data);
+
+ if (session->p == p)
+ session->p = NULL;
+
+ pending_request_free(p);
+
+ session_process_queue(session);
+}
+
+static void setpath_cb(GObex *obex, GError *err, GObexPacket *rsp,
+ gpointer user_data)
+{
+ struct pending_request *p = user_data;
+ struct setpath_data *data = p->data;
+ char *next;
+ guint8 code;
+
+ p->req_id = 0;
+
+ if (err != NULL) {
+ setpath_complete(p->session, err, user_data);
+ return;
+ }
+
+ code = g_obex_packet_get_operation(rsp, NULL);
+ if (code != G_OBEX_RSP_SUCCESS) {
+ GError *gerr = NULL;
+ g_set_error(&gerr, OBEX_IO_ERROR, code, "%s",
+ g_obex_strerror(code));
+ setpath_complete(p->session, err, user_data);
+ g_clear_error(&gerr);
+ return;
+ }
+
+ next = data->remaining[data->index];
+ if (next == NULL) {
+ setpath_complete(p->session, NULL, user_data);
+ return;
+ }
+
+ data->index++;
+
+ p->req_id = g_obex_setpath(obex, next, setpath_cb, p, &err);
+ if (err != NULL) {
+ setpath_complete(p->session, err, data);
+ g_error_free(err);
+ }
+}
+
+guint obc_session_setpath(struct obc_session *session, const char *path,
+ session_callback_t func, void *user_data,
+ GError **err)
+{
+ struct setpath_data *data;
+ struct pending_request *p;
+ const char *first = "";
+
+ if (session->obex == NULL) {
+ g_set_error(err, OBEX_IO_ERROR, -ENOTCONN,
+ strerror(-ENOTCONN));
+ return 0;
+ }
+
+ if (session->p != NULL) {
+ g_set_error(err, OBEX_IO_ERROR, -EBUSY, strerror(-EBUSY));
+ return 0;
+ }
+
+ data = g_new0(struct setpath_data, 1);
+ data->func = func;
+ data->user_data = user_data;
+ data->remaining = g_strsplit(path, "/", 3);
+
+ p = pending_request_new(session, NULL, NULL, setpath_complete, data);
+
+ /* Relative path */
+ if (path[0] != '/') {
+ first = data->remaining[data->index];
+ data->index++;
+ }
+
+ if (first == NULL) {
+ g_set_error(err, OBEX_IO_ERROR, -EINVAL, strerror(-EINVAL));
+ goto fail;
+ }
+
+ p->req_id = g_obex_setpath(session->obex, first, setpath_cb, p, err);
+ if (*err != NULL)
+ goto fail;
+
+ session->p = p;
+
+ return p->id;
+
+fail:
+ g_strfreev(data->remaining);
+ g_free(data);
+ pending_request_free(p);
+ return 0;
+}
diff --git a/client/session.h b/client/session.h
index 511f084..65cf4bd 100644
--- a/client/session.h
+++ b/client/session.h
@@ -73,3 +73,7 @@ const char *obc_session_register(struct obc_session *session,
GDBusDestroyFunction destroy);
int obc_session_put(struct obc_session *session, char *buf,
const char *targetname);
+
+guint obc_session_setpath(struct obc_session *session, const char *path,
+ session_callback_t func, void *user_data,
+ GError **err);
--
1.7.7.6


2012-01-30 15:30:26

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH obexd 03/13] client: fix not queuing requests properly

From: Luiz Augusto von Dentz <[email protected]>

OBEX does not support requests in parallel so they have to be queued
like in SendFiles.
---
client/session.c | 251 +++++++++++++++++++++++++----------------------------
1 files changed, 118 insertions(+), 133 deletions(-)

diff --git a/client/session.c b/client/session.c
index 92ae8cf..c7a0a51 100644
--- a/client/session.c
+++ b/client/session.c
@@ -60,10 +60,12 @@ struct session_callback {
void *data;
};

-struct pending_data {
- session_callback_t cb;
+struct pending_request {
struct obc_session *session;
struct obc_transfer *transfer;
+ session_callback_t auth_complete;
+ session_callback_t func;
+ void *data;
};

struct obc_session {
@@ -78,10 +80,10 @@ struct obc_session {
DBusConnection *conn;
GObex *obex;
struct obc_agent *agent;
- struct session_callback *callback;
+ struct pending_request *p;
gchar *owner; /* Session owner */
guint watch;
- GSList *pending;
+ GQueue *queue;
};

static GSList *sessions = NULL;
@@ -123,6 +125,17 @@ static void session_unregistered(struct obc_session *session)
g_free(path);
}

+static void pending_request_free(struct pending_request *p)
+{
+ if (p->transfer)
+ obc_transfer_unregister(p->transfer);
+
+ if (p->session)
+ obc_session_unref(p->session);
+
+ g_free(p);
+}
+
static void session_free(struct obc_session *session)
{
DBG("%p", session);
@@ -132,6 +145,12 @@ static void session_free(struct obc_session *session)
obc_agent_free(session->agent);
}

+ if (session->queue) {
+ g_queue_foreach(session->queue, (GFunc) pending_request_free,
+ NULL);
+ g_queue_free(session->queue);
+ }
+
if (session->watch)
g_dbus_remove_watch(session->conn, session->watch);

@@ -147,9 +166,11 @@ static void session_free(struct obc_session *session)
if (session->conn)
dbus_connection_unref(session->conn);

+ if (session->p)
+ pending_request_free(session->p);
+
sessions = g_slist_remove(sessions, session);

- g_free(session->callback);
g_free(session->path);
g_free(session->owner);
g_free(session->source);
@@ -398,6 +419,7 @@ struct obc_session *obc_session_create(const char *source,
session->source = g_strdup(source);
session->destination = g_strdup(destination);
session->channel = channel;
+ session->queue = g_queue_new();

if (owner)
obc_session_set_owner(session, owner, owner_disconnected);
@@ -414,37 +436,17 @@ proceed:
return session;
}

-static void obc_session_add_transfer(struct obc_session *session,
- struct obc_transfer *transfer)
-{
- session->pending = g_slist_append(session->pending, transfer);
- obc_session_ref(session);
-}
-
-static void obc_session_remove_transfer(struct obc_session *session,
- struct obc_transfer *transfer)
-{
- session->pending = g_slist_remove(session->pending, transfer);
- obc_transfer_unregister(transfer);
- obc_session_unref(session);
-}
-
void obc_session_shutdown(struct obc_session *session)
{
- GSList *l = session->pending;
+ struct pending_request *p;

DBG("%p", session);

obc_session_ref(session);

/* Unregister any pending transfer */
- while (l) {
- struct obc_transfer *transfer = l->data;
-
- l = l->next;
-
- obc_session_remove_transfer(session, transfer);
- }
+ while ((p = g_queue_pop_head(session->queue)))
+ pending_request_free(p);

/* Unregister interfaces */
if (session->path)
@@ -588,8 +590,9 @@ static GDBusMethodTable session_methods[] = {

static void session_request_reply(DBusPendingCall *call, gpointer user_data)
{
- struct pending_data *pending = user_data;
- struct obc_session *session = pending->session;
+ struct obc_session *session = user_data;
+ struct pending_request *p = session->p;
+ struct obc_transfer *transfer = p->transfer;
DBusMessage *reply = dbus_pending_call_steal_reply(call);
const char *name;
DBusError derr;
@@ -605,7 +608,7 @@ static void session_request_reply(DBusPendingCall *call, gpointer user_data)

g_set_error(&gerr, OBEX_IO_ERROR, -ECANCELED, "%s",
derr.message);
- session_terminate_transfer(session, pending->transfer, gerr);
+ session_terminate_transfer(session, transfer, gerr);
g_clear_error(&gerr);

return;
@@ -618,9 +621,11 @@ static void session_request_reply(DBusPendingCall *call, gpointer user_data)
DBG("Agent.Request() reply: %s", name);

if (strlen(name))
- obc_transfer_set_name(pending->transfer, name);
+ obc_transfer_set_name(transfer, name);
+
+ if (p->auth_complete)
+ p->auth_complete(session, NULL, transfer);

- pending->cb(session, NULL, pending->transfer);
dbus_message_unref(reply);

return;
@@ -628,74 +633,102 @@ static void session_request_reply(DBusPendingCall *call, gpointer user_data)

static gboolean session_request_proceed(gpointer data)
{
- struct pending_data *pending = data;
- struct obc_transfer *transfer = pending->transfer;
+ struct obc_session *session = data;
+ struct pending_request *p = session->p;
+ struct obc_transfer *transfer = p->transfer;

- pending->cb(pending->session, NULL, transfer);
- g_free(pending);
+ p->auth_complete(p->session, NULL, transfer);

return FALSE;
}

-static int session_request(struct obc_session *session, session_callback_t cb,
- struct obc_transfer *transfer)
+static int pending_request_auth(struct pending_request *p)
{
+ struct obc_session *session = p->session;
struct obc_agent *agent = session->agent;
- struct pending_data *pending;
const char *path;
- int err;
-
- pending = g_new0(struct pending_data, 1);
- pending->cb = cb;
- pending->session = session;
- pending->transfer = transfer;

- path = obc_transfer_get_path(transfer);
+ path = obc_transfer_get_path(p->transfer);

if (agent == NULL || path == NULL) {
- g_idle_add(session_request_proceed, pending);
+ g_idle_add(session_request_proceed, session);
return 0;
}

- err = obc_agent_request(agent, path, session_request_reply, pending,
- g_free);
+ return obc_agent_request(agent, path, session_request_reply, session,
+ NULL);
+}
+
+static int session_request(struct obc_session *session,
+ struct obc_transfer *transfer,
+ session_callback_t auth_complete,
+ session_callback_t func,
+ void *data)
+{
+ struct pending_request *p;
+ int err;
+
+ p = g_new0(struct pending_request, 1);
+ p->session = obc_session_ref(session);
+ p->transfer = transfer;
+ p->auth_complete = auth_complete;
+ p->func = func;
+ p->data = data;
+
+ if (session->p) {
+ g_queue_push_tail(session->queue, p);
+ return 0;
+ }
+
+ err = pending_request_auth(p);
if (err < 0) {
- g_free(pending);
+ pending_request_free(p);
return err;
}

+ session->p = p;
+
return 0;
}

+static void session_process_queue(struct obc_session *session)
+{
+ struct pending_request *p;
+
+ if (session->queue == NULL || g_queue_is_empty(session->queue))
+ return;
+
+ while ((p = g_queue_pop_head(session->queue))) {
+ int err;
+
+ err = pending_request_auth(p);
+ if (err == 0) {
+ session->p = p;
+ return;
+ }
+
+ pending_request_free(p);
+ }
+}
+
static void session_terminate_transfer(struct obc_session *session,
struct obc_transfer *transfer,
GError *gerr)
{
- struct session_callback *callback = session->callback;
+ struct pending_request *p = session->p;

- if (callback) {
- obc_session_ref(session);
- callback->func(session, gerr, callback->data);
- if (g_slist_find(session->pending, transfer))
- obc_session_remove_transfer(session, transfer);
- obc_session_unref(session);
+ if (p == NULL || p->transfer != transfer)
return;
- }

obc_session_ref(session);

- obc_session_remove_transfer(session, transfer);
-
- while (session->pending != NULL) {
- struct obc_transfer *transfer = session->pending->data;
- int err;
+ if (p->func)
+ p->func(session, gerr, p->data);

- err = session_request(session, session_prepare_put, transfer);
- if (err == 0)
- break;
+ pending_request_free(p);
+ session->p = NULL;

- obc_session_remove_transfer(session, transfer);
- }
+ session_process_queue(session);

obc_session_unref(session);
}
@@ -804,7 +837,6 @@ int obc_session_get(struct obc_session *session, const char *type,
struct obc_transfer *transfer;
struct obc_transfer_params *params = NULL;
const char *agent;
- int err;

if (session->obex == NULL)
return -ENOTCONN;
@@ -833,23 +865,8 @@ int obc_session_get(struct obc_session *session, const char *type,
return -EIO;
}

- if (func != NULL) {
- struct session_callback *callback;
- callback = g_new0(struct session_callback, 1);
- callback->func = func;
- callback->data = user_data;
- session->callback = callback;
- }
-
- err = session_request(session, session_prepare_get, transfer);
- if (err < 0) {
- obc_transfer_unregister(transfer);
- return err;
- }
-
- obc_session_add_transfer(session, transfer);
-
- return 0;
+ return session_request(session, transfer, session_prepare_get,
+ func, user_data);
}

int obc_session_send(struct obc_session *session, const char *filename,
@@ -872,26 +889,13 @@ int obc_session_send(struct obc_session *session, const char *filename,
return -EINVAL;

err = obc_transfer_set_file(transfer);
- if (err < 0)
- goto fail;
-
- /* Transfer should start if it is the first in the pending list */
- if (session->pending != NULL)
- goto done;
-
- err = session_request(session, session_prepare_put, transfer);
- if (err < 0)
- goto fail;
-
-done:
- obc_session_add_transfer(session, transfer);
-
- return 0;
-
-fail:
- obc_transfer_unregister(transfer);
+ if (err < 0) {
+ obc_transfer_unregister(transfer);
+ return err;
+ }

- return err;
+ return session_request(session, transfer, session_prepare_put,
+ NULL, NULL);
}

int obc_session_pull(struct obc_session *session,
@@ -900,7 +904,6 @@ int obc_session_pull(struct obc_session *session,
{
struct obc_transfer *transfer;
const char *agent;
- int err;

if (session->obex == NULL)
return -ENOTCONN;
@@ -918,22 +921,8 @@ int obc_session_pull(struct obc_session *session,
return -EIO;
}

- if (function != NULL) {
- struct session_callback *callback;
- callback = g_new0(struct session_callback, 1);
- callback->func = function;
- callback->data = user_data;
- session->callback = callback;
- }
-
- err = session_request(session, session_prepare_get, transfer);
- if (err == 0) {
- obc_session_add_transfer(session, transfer);
- return 0;
- }
-
- obc_transfer_unregister(transfer);
- return err;
+ return session_request(session, transfer, session_prepare_get,
+ function, user_data);
}

const char *obc_session_register(struct obc_session *session,
@@ -990,14 +979,10 @@ int obc_session_put(struct obc_session *session, char *buf, const char *targetna
{
struct obc_transfer *transfer;
const char *agent;
- int err;

if (session->obex == NULL)
return -ENOTCONN;

- if (session->pending != NULL)
- return -EISCONN;
-
agent = obc_agent_get_name(session->agent);

transfer = obc_transfer_register(session->conn, session->obex,
@@ -1009,11 +994,8 @@ int obc_session_put(struct obc_session *session, char *buf, const char *targetna

obc_transfer_set_buffer(transfer, buf);

- err = session_request(session, session_prepare_put, transfer);
- if (err < 0)
- return err;
-
- return 0;
+ return session_request(session, transfer, session_prepare_put,
+ NULL, NULL);
}

static void agent_destroy(gpointer data, gpointer user_data)
@@ -1085,7 +1067,10 @@ GObex *obc_session_get_obex(struct obc_session *session)
static struct obc_transfer *obc_session_get_transfer(
struct obc_session *session)
{
- return session->pending ? session->pending->data : NULL;
+ if (session->p == NULL)
+ return NULL;
+
+ return session->p->transfer;
}

const char *obc_session_get_buffer(struct obc_session *session, size_t *size)
--
1.7.7.6


2012-01-30 15:30:25

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH obexd 02/13] client: remove unused field from obc_session

From: Luiz Augusto von Dentz <[email protected]>

---
client/session.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/client/session.c b/client/session.c
index c9df832..92ae8cf 100644
--- a/client/session.c
+++ b/client/session.c
@@ -76,7 +76,6 @@ struct obc_session {
struct obc_driver *driver;
gchar *path; /* Session path */
DBusConnection *conn;
- DBusMessage *msg;
GObex *obex;
struct obc_agent *agent;
struct session_callback *callback;
--
1.7.7.6