diff --git a/obexd/client/session.c b/obexd/client/session.c
index 482ee20..e946cfd 100644
--- a/obexd/client/session.c
+++ b/obexd/client/session.c
#define SESSION_BASEPATH "/org/openobex"
#define OBEX_IO_ERROR obex_io_error_quark()
+#define OBEX_IO_ERROR_FIRST (0xff + 1)
+
+enum {
+ OBEX_IO_DISCONNECTED = OBEX_IO_ERROR_FIRST,
+ OBEX_IO_BUSY,
+};
static guint64 counter = 0;
};
struct pending_request {
+ guint id;
+ guint req_id;
struct obc_session *session;
struct obc_transfer *transfer;
GFunc auth_complete;
void *data;
};
+struct setpath_data {
+ char **remaining;
+ int index;
+ session_callback_t func;
+ void *user_data;
+};
+
struct obc_session {
guint id;
gint refcount;
g_free(path);
}
+static struct pending_request *pending_request_new(struct obc_session *session,
+ struct obc_transfer *transfer,
+ GFunc auth_complete,
+ 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_complete;
+ p->func = func;
+ p->data = data;
+
+ return p;
+}
+
static void pending_request_free(struct pending_request *p)
{
if (p->transfer)
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;
+ p = pending_request_new(session, transfer, auth_complete, func, data);
if (session->p) {
g_queue_push_tail(session->queue, p);
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, OBEX_IO_DISCONNECTED,
+ "Session disconnected");
+ return 0;
+ }
+
+ if (session->p != NULL) {
+ g_set_error(err, OBEX_IO_ERROR, OBEX_IO_BUSY,
+ "Session busy");
+ 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++;
+ }
+
+ 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/obexd/client/session.h b/obexd/client/session.h
index 511f084..65cf4bd 100644
--- a/obexd/client/session.h
+++ b/obexd/client/session.h
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);