diff --git a/obexd/plugins/ebook.c b/obexd/plugins/ebook.c
index 7c78a57..abb16cb 100644
--- a/obexd/plugins/ebook.c
+++ b/obexd/plugins/ebook.c
DBG("context %p", context);
}
-static int ebook_pullphonebook(struct phonebook_context *context)
+static void ebooklist_cb(EBook *book, EBookStatus status, GList *list,
+ gpointer user_data)
{
- EBook *book;
- EBookQuery *query;
- GList *contacts = NULL;
+ struct phonebook_context *context = user_data;
+ GList *contacts = list;
GString *pb;
gchar *result;
-
- DBG("context %p", context);
-
- book = e_book_new_default_addressbook(NULL);
-
- e_book_open(book, FALSE, NULL);
-
- query = e_book_query_any_field_contains("");
-
- e_book_get_contacts(book, query, &contacts, NULL);
+ gint32 str_len;
pb = g_string_new(NULL);
}
result = g_string_free(pb, FALSE);
- phonebook_return(context, result, strlen(result));
- g_free(result);
+ str_len = strlen(result);
+ phonebook_return(context, result, str_len);
- e_book_query_unref(query);
+ if (str_len != 0)
+ phonebook_return(context, NULL, 0);
+ g_free(result);
+ phonebook_unref(context);
g_object_unref(book);
+}
+
+static int ebook_pullphonebook(struct phonebook_context *context)
+{
+ EBook *book;
+ EBookQuery *query;
+
+ DBG("context %p", context);
+
+ phonebook_ref(context);
+
+ book = e_book_new_default_addressbook(NULL);
+
+ e_book_open(book, FALSE, NULL);
+
+ query = e_book_query_any_field_contains("");
+
+ e_book_async_get_contacts(book, query, ebooklist_cb, context);
return 0;
}
diff --git a/obexd/src/obex.c b/obexd/src/obex.c
index 84409ff..a0e5e75 100644
--- a/obexd/src/obex.c
+++ b/obexd/src/obex.c
if (os->current_folder)
g_free(os->current_folder);
+ if (!memcmp(os->target, PBAP_TARGET, TARGET_SIZE))
+ pbap_phonebook_context_destroy(os);
+
g_free(os);
}
os->server->services & OBEX_PBAP) {
os->target = PBAP_TARGET;
os->cmds = &pbap;
+ pbap_phonebook_context_create(os);
break;
}
return -EPERM;
if (os->fd < 0) {
- if (os->buf == NULL)
+ if (os->buf == NULL && os->finished == FALSE)
return -EIO;
len = MIN(os->size - os->offset, os->tx_mtu);
OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_BODY, hd, len,
OBEX_FL_STREAM_DATA);
+ if (!memcmp(os->target, PBAP_TARGET, TARGET_SIZE))
+ if (os->offset == os->size && os->finished == FALSE)
+ OBEX_SuspendRequest(obex, obj);
+
return len;
}
}
OBEX_SetUserData(obex, os);
+ os->handle = obex;
OBEX_SetTransportMTU(obex, os->rx_mtu, os->tx_mtu);
diff --git a/obexd/src/obex.h b/obexd/src/obex.h
index d903095..188e0a8 100644
--- a/obexd/src/obex.h
+++ b/obexd/src/obex.h
#include <glib.h>
+#include "phonebook.h"
+
#define OBEX_OPP (1 << 0)
#define OBEX_FTP (1 << 2)
#define OBEX_BIP (1 << 3)
struct obex_commands *cmds;
struct server *server;
gboolean checked;
+ obex_t *handle;
+ struct phonebook_context *pbctx;
+ gboolean finished;
};
gint obex_session_start(gint fd, struct server *server);
void ftp_setpath(obex_t *obex, obex_object_t *obj);
void pbap_get(obex_t *obex, obex_object_t *obj);
+gboolean pbap_phonebook_context_create(struct obex_session *session);
+void pbap_phonebook_context_destroy(struct obex_session *session);
+struct obex_session *pbap_get_session(struct phonebook_context *context);
gboolean os_prepare_get(struct obex_session *os, gchar *file, guint32 *size);
gint os_prepare_put(struct obex_session *os);
diff --git a/obexd/src/pbap.c b/obexd/src/pbap.c
index 9c2126a..ac288f0 100644
--- a/obexd/src/pbap.c
+++ b/obexd/src/pbap.c
#include <glib.h>
-#include "phonebook.h"
#include "logging.h"
#include "obex.h"
#define PHONEBOOK_TYPE "x-bt/phonebook"
-static void test_phonebook(void)
-{
- struct phonebook_context *context;
- struct phonebook_driver *driver;
-
- driver = phonebook_get_driver(NULL);
- if (driver == NULL)
- return;
-
- context = phonebook_create(driver);
- if (context == NULL)
- return;
-
- phonebook_pullphonebook(context);
-
- phonebook_unref(context);
-}
+static GSList *session_list = NULL;
void pbap_get(obex_t *obex, obex_object_t *obj)
{
- struct obex_session *os;
+ struct obex_session *session;
obex_headerdata_t hv;
- guint32 size;
+ int ret;
- os = OBEX_GetUserData(obex);
- if (os == NULL)
+ session = OBEX_GetUserData(obex);
+ if (session == NULL)
return;
- if (os->type == NULL)
+ if (session->type == NULL)
goto fail;
- if (g_str_equal(os->type, PHONEBOOK_TYPE) == FALSE)
+ if (g_str_equal(session->type, PHONEBOOK_TYPE) == FALSE)
goto fail;
- test_phonebook();
- size = 0;
+ ret = phonebook_pullphonebook(session->pbctx);
- hv.bq4 = size;
- OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_LENGTH, hv, 4, 0);
+ if (!ret)
+ OBEX_SuspendRequest(obex, obj);
+ else
+ goto fail;
/* Add body header */
hv.bs = NULL;
- if (size == 0)
- OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_BODY,
- hv, 0, OBEX_FL_FIT_ONE_PACKET);
- else
- OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_BODY,
- hv, 0, OBEX_FL_STREAM_START);
+ OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_BODY,
+ hv, 0, OBEX_FL_STREAM_START);
OBEX_ObjectSetRsp(obj, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS);
fail:
OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN);
}
+
+gboolean pbap_phonebook_context_create(struct obex_session *session)
+{
+ struct phonebook_context *context;
+ struct phonebook_driver *driver;
+
+ driver = phonebook_get_driver(NULL);
+ if (driver == NULL)
+ return FALSE;
+
+ context = phonebook_create(driver);
+ if (context == NULL)
+ return FALSE;
+
+ session->pbctx = context;
+
+ session_list = g_slist_append(session_list, session);
+
+ return TRUE;
+}
+
+void pbap_phonebook_context_destroy(struct obex_session *session)
+{
+ struct phonebook_context *context;
+
+ context = session->pbctx;
+ phonebook_unref(context);
+
+ session_list = g_slist_remove(session_list, session);
+}
+
+struct obex_session *pbap_get_session(struct phonebook_context *context)
+{
+ GSList *current;
+
+ for (current = session_list; current != NULL; current = current->next) {
+ struct obex_session *session = current->data;
+ if (session->pbctx == context)
+ return session;
+ }
+
+ return NULL;
+}
diff --git a/obexd/src/phonebook.c b/obexd/src/phonebook.c
index 2dab918..4b760b2 100644
--- a/obexd/src/phonebook.c
+++ b/obexd/src/phonebook.c
#include <config.h>
#endif
+#include <string.h>
#include <glib.h>
+#include <stdlib.h>
+
+#include <openobex/obex.h>
+#include <openobex/obex_const.h>
#include "logging.h"
-#include "phonebook.h"
+#include "obex.h"
static GSList *driver_list = NULL;
}
}
-void phonebook_pullphonebook(struct phonebook_context *context)
+int phonebook_pullphonebook(struct phonebook_context *context)
{
- DBG("context %p", context);
-
- if (context->driver->pullphonebook) {
- phonebook_ref(context);
+ if (!context->driver->pullphonebook)
+ return -1;
- context->driver->pullphonebook(context);
- }
+ return context->driver->pullphonebook(context);
}
+/* if buf is NULL or size is 0, this indicate that no more result will
+ * be returned by PBAP plugin
+ * */
void phonebook_return(struct phonebook_context *context,
char *buf, int size)
{
DBG("context %p", context);
- phonebook_unref(context);
+ struct obex_session *session;
+
+ session = pbap_get_session(context);
+
+ if (buf == NULL || size == 0) {
+ session->finished = 1;
+ OBEX_ResumeRequest(session->handle);
+ return;
+ }
+
+ session->buf = g_realloc(session->buf, session->size + size);
+ memcpy(session->buf + session->size, buf, size);
+ session->size += size;
+
+ OBEX_ResumeRequest(session->handle);
}
struct phonebook_driver *phonebook_get_driver(const char *name)
diff --git a/obexd/src/phonebook.h b/obexd/src/phonebook.h
index fbc98f4..440d857 100644
--- a/obexd/src/phonebook.h
+++ b/obexd/src/phonebook.h
void *driver_data;
};
-extern struct phonebook_context *phonebook_create(struct phonebook_driver *driver);
-extern struct phonebook_context *phonebook_ref(struct phonebook_context *context);
+extern struct phonebook_context *phonebook_create(
+ struct phonebook_driver *driver);
+extern struct phonebook_context *phonebook_ref(
+ struct phonebook_context *context);
extern void phonebook_unref(struct phonebook_context *context);
static inline void *phonebook_get_data(struct phonebook_context *context)
context->driver_data = data;
}
-extern void phonebook_pullphonebook(struct phonebook_context *context);
+extern int phonebook_pullphonebook(struct phonebook_context *context);
extern void phonebook_return(struct phonebook_context *context,
char *buf, int size);