diff --git a/obexd/plugins/irmc.c b/obexd/plugins/irmc.c
index e1e83f9..2cf673c 100644
--- a/obexd/plugins/irmc.c
+++ b/obexd/plugins/irmc.c
{
struct irmc_session *irmc;
struct apparam_field *param;
+ int ret;
DBG("");
irmc->params = param;
irmc->request = phonebook_pull("telecom/pb.vcf", irmc->params,
phonebook_size_result, irmc, err);
+ ret = phonebook_pull_read(irmc->request);
+ if (err)
+ *err = ret;
return irmc;
}
DBG("phonebook_pull failed...");
goto fail;
}
+
+ ret = phonebook_pull_read(irmc->request);
+ if (ret < 0) {
+ DBG("phonebook_pull_read failed...");
+ goto fail;
+ }
+
return irmc;
}
diff --git a/obexd/plugins/pbap.c b/obexd/plugins/pbap.c
index 5775eea..b04dca9 100644
--- a/obexd/plugins/pbap.c
+++ b/obexd/plugins/pbap.c
if (ret < 0)
goto fail;
+ /* reading first part of results from backend */
+ ret = phonebook_pull_read(request);
+ if (ret < 0)
+ goto fail;
+
if (err)
*err = 0;
{
struct pbap_object *obj = object;
struct pbap_session *pbap = obj->session;
+ int len, ret;
DBG("buffer %p maxlistcount %d", obj->buffer,
pbap->params->maxlistcount);
*hi = OBEX_HDR_BODY;
if (flags)
*flags = 0;
- return string_read(obj->buffer, buf, count);
+
+ len = string_read(obj->buffer, buf, count);
+ if (len == 0 && !obj->lastpart) {
+ /* in case when buffer is empty and we know that more
+ * data is still available in backend, requesting new
+ * data part via phonebook_pull_read and returning
+ * -EAGAIN to suspend request for now */
+ ret = phonebook_pull_read(obj->request);
+ if (ret)
+ return -EPERM;
+
+ return -EAGAIN;
+ }
+
+ return len;
}
}
diff --git a/obexd/plugins/phonebook-dummy.c b/obexd/plugins/phonebook-dummy.c
index 76dd550..ede4643 100644
--- a/obexd/plugins/phonebook-dummy.c
+++ b/obexd/plugins/phonebook-dummy.c
const struct apparam_field *apparams;
char *folder;
int fd;
+ guint id;
};
struct cache_query {
void phonebook_req_finalize(void *request)
{
- guint id = GPOINTER_TO_INT(request);
+ struct dummy_data *dummy = request;
- g_source_remove(id);
+ /* dummy_data will be cleaned when request will be finished via
+ * g_source_remove */
+ if (dummy && dummy->id)
+ g_source_remove(dummy->id);
}
void *phonebook_pull(const char *name, const struct apparam_field *params,
{
struct dummy_data *dummy;
char *filename, *folder;
- guint ret;
/*
* Main phonebook objects will be created dinamically based on the
dummy->folder = folder;
dummy->fd = -1;
- ret = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, read_dir, dummy,
- dummy_free);
-
if (err)
*err = 0;
- return GINT_TO_POINTER(ret);
+ return dummy;
+}
+
+int phonebook_pull_read(void *request)
+{
+ struct dummy_data *dummy = request;
+
+ if (!dummy)
+ return -ENOENT;
+
+ dummy->id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, read_dir, dummy,
+ dummy_free);
+
+ return 0;
}
void *phonebook_get_entry(const char *folder, const char *id,
diff --git a/obexd/plugins/phonebook-ebook.c b/obexd/plugins/phonebook-ebook.c
index 6cc4f31..82019da 100644
--- a/obexd/plugins/phonebook-ebook.c
+++ b/obexd/plugins/phonebook-ebook.c
phonebook_cb cb, void *user_data, int *err)
{
struct query_context *data;
- EBookQuery *query;
-
- query = e_book_query_any_field_contains("");
data = g_new0(struct query_context, 1);
data->contacts_cb = cb;
data->params = params;
data->user_data = user_data;
- e_book_async_get_contacts(ebook, query, ebookpull_cb, data);
-
- e_book_query_unref(query);
-
if (err)
*err = 0;
return data;
}
+int phonebook_pull_read(void *request)
+{
+ struct query_context *data = request;
+ EBookQuery *query;
+
+ if (!data)
+ return -ENOENT;
+
+ query = e_book_query_any_field_contains("");
+ e_book_async_get_contacts(ebook, query, ebookpull_cb, data);
+
+ e_book_query_unref(query);
+
+ return 0;
+}
+
void *phonebook_get_entry(const char *folder, const char *id,
const struct apparam_field *params,
phonebook_cb cb, void *user_data, int *err)
diff --git a/obexd/plugins/phonebook-tracker.c b/obexd/plugins/phonebook-tracker.c
index aea2365..e7f0807 100644
--- a/obexd/plugins/phonebook-tracker.c
+++ b/obexd/plugins/phonebook-tracker.c
phonebook_entry_cb entry_cb;
int newmissedcalls;
GCancellable *query_canc;
+ char *req_name;
};
struct phonebook_index {
}
g_slist_free(data->contacts);
+ g_free(data->req_name);
g_free(data);
}
phonebook_cb cb, void *user_data, int *err)
{
struct phonebook_data *data;
- const char *query;
- reply_list_foreach_t pull_cb;
- int col_amount, ret;
DBG("name %s", name);
- if (g_strcmp0(name, "telecom/mch.vcf") == 0) {
+ data = g_new0(struct phonebook_data, 1);
+ data->params = params;
+ data->user_data = user_data;
+ data->cb = cb;
+ data->req_name = g_strdup(name);
+
+ if (err)
+ *err = 0;
+
+ return data;
+}
+
+int phonebook_pull_read(void *request)
+{
+ struct phonebook_data *data = request;
+ reply_list_foreach_t pull_cb;
+ const char *query;
+ int col_amount;
+ int ret;
+
+ if(!data)
+ return -ENOENT;
+
+ if (g_strcmp0(data->req_name, "telecom/mch.vcf") == 0) {
query = NEW_MISSED_CALLS_LIST;
col_amount = PULL_QUERY_COL_AMOUNT;
pull_cb = pull_newmissedcalls;
- } else if (params->maxlistcount == 0) {
- query = name2count_query(name);
+ } else if (data->params->maxlistcount == 0) {
+ query = name2count_query(data->req_name);
col_amount = COUNT_QUERY_COL_AMOUNT;
pull_cb = pull_contacts_size;
} else {
- query = name2query(name);
+ query = name2query(data->req_name);
col_amount = PULL_QUERY_COL_AMOUNT;
pull_cb = pull_contacts;
}
- if (query == NULL) {
- if (err)
- *err = -ENOENT;
- return NULL;
- }
+ if (query == NULL)
+ return -ENOENT;
- data = g_new0(struct phonebook_data, 1);
- data->params = params;
- data->user_data = user_data;
- data->cb = cb;
ret = query_tracker(query, col_amount, pull_cb, data);
- if (err)
- *err = ret;
- return data;
+ return ret;
}
void *phonebook_get_entry(const char *folder, const char *id,
diff --git a/obexd/plugins/phonebook.h b/obexd/plugins/phonebook.h
index f6df164..00abc08 100644
--- a/obexd/plugins/phonebook.h
+++ b/obexd/plugins/phonebook.h
const char *new_folder, uint8_t flags, int *err);
/*
- * PullPhoneBook never use cached entries. PCE use this function to get all
- * entries of a given folder. The back-end MUST return only the content based
- * on the application parameters requested by the client.
+ * phonebook_pull should be used only to prepare pull request - prepared
+ * request data is returned by this function. Start of fetching data from
+ * back-end will be done only after calling phonebook_pull_read with this
+ * returned request given as a parameter.
*
- * Return value is a pointer to asynchronous request to phonebook back-end.
* phonebook_req_finalize MUST always be used to free associated resources.
*/
void *phonebook_pull(const char *name, const struct apparam_field *params,
phonebook_cb cb, void *user_data, int *err);
/*
+ * phonebook_pull_read should be used to start getting results from back-end.
+ * The back-end can return data as one response or can return it many parts.
+ * After obtaining one part, PBAP core need to call phonebook_pull_read with
+ * the same request again to get more results from back-end.
+ * The back-end MUST return only the content based on the application
+ * parameters requested by the client.
+ *
+ * Returns error code or 0 in case of success
+ */
+int phonebook_pull_read(void *request);
+
+/*
* Function used to retrieve a contact from the backend. Only contacts
* found in the cache are requested to the back-ends. The back-end MUST
* return only the content based on the application parameters requested