obexd: Introduction of phonebook_pull_read

Previosly reading from backend was initialized in phonebook_pull.
Now phonebook_pull should be used only for preparing request data
and phonebook_pull_read for 'real' reading vcards data from back-end.
The back-end can return data in one response or it can return data in
many parts. After obtaining one part, PBAP core need to call
phonebook_pull_read with the same request again to get more results.
Using that, PBAP core has control of its the buffer size - it can
ask for new parts of data when buffer is empty or when its size
will be lower than some level.
This commit is contained in:
Radoslaw Jablonski 2011-02-14 11:19:50 +02:00 committed by Marcel Holtmann
parent 8042fbf632
commit 7169587d4d
6 changed files with 122 additions and 44 deletions

View File

@ -197,6 +197,7 @@ static void *irmc_connect(struct obex_session *os, int *err)
{
struct irmc_session *irmc;
struct apparam_field *param;
int ret;
DBG("");
@ -224,6 +225,9 @@ static void *irmc_connect(struct obex_session *os, int *err)
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;
}
@ -313,6 +317,13 @@ static void *irmc_open_pb(const char *name, struct irmc_session *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;
}

View File

@ -803,6 +803,11 @@ static void *vobject_pull_open(const char *name, int oflag, mode_t mode,
request = phonebook_pull(name, pbap->params, cb, pbap, &ret);
if (ret < 0)
goto fail;
/* reading first part of results from backend */
ret = phonebook_pull_read(request);
if (ret < 0)
goto fail;
@ -962,6 +967,7 @@ static ssize_t vobject_pull_read(void *object, void *buf, size_t count,
{
struct pbap_object *obj = object;
struct pbap_session *pbap = obj->session;
int len, ret;
DBG("buffer %p maxlistcount %d", obj->buffer,
pbap->params->maxlistcount);
@ -987,7 +993,21 @@ static ssize_t vobject_pull_read(void *object, void *buf, size_t count,
*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;
}
}

View File

@ -52,6 +52,7 @@ struct dummy_data {
const struct apparam_field *apparams;
char *folder;
int fd;
guint id;
};
struct cache_query {
@ -449,9 +450,12 @@ done:
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,
@ -459,7 +463,6 @@ 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
@ -492,13 +495,23 @@ void *phonebook_pull(const char *name, const struct apparam_field *params,
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,

View File

@ -453,25 +453,34 @@ void *phonebook_pull(const char *name, const struct apparam_field *params,
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)

View File

@ -918,6 +918,7 @@ struct phonebook_data {
phonebook_entry_cb entry_cb;
int newmissedcalls;
GCancellable *query_canc;
char *req_name;
};
struct phonebook_index {
@ -1819,6 +1820,7 @@ void phonebook_req_finalize(void *request)
}
g_slist_free(data->contacts);
g_free(data->req_name);
g_free(data);
}
@ -1897,43 +1899,54 @@ void *phonebook_pull(const char *name, const struct apparam_field *params,
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) {
query = NEW_MISSED_CALLS_LIST;
col_amount = PULL_QUERY_COL_AMOUNT;
pull_cb = pull_newmissedcalls;
} else if (params->maxlistcount == 0) {
query = name2count_query(name);
col_amount = COUNT_QUERY_COL_AMOUNT;
pull_cb = pull_contacts_size;
} else {
query = name2query(name);
col_amount = PULL_QUERY_COL_AMOUNT;
pull_cb = pull_contacts;
}
if (query == NULL) {
if (err)
*err = -ENOENT;
return NULL;
}
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);
data->req_name = g_strdup(name);
if (err)
*err = ret;
*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 (data->params->maxlistcount == 0) {
query = name2count_query(data->req_name);
col_amount = COUNT_QUERY_COL_AMOUNT;
pull_cb = pull_contacts_size;
} else {
query = name2query(data->req_name);
col_amount = PULL_QUERY_COL_AMOUNT;
pull_cb = pull_contacts;
}
if (query == NULL)
return -ENOENT;
ret = query_tracker(query, col_amount, pull_cb, data);
return ret;
}
void *phonebook_get_entry(const char *folder, const char *id,
const struct apparam_field *params,
phonebook_cb cb, void *user_data, int *err)

View File

@ -82,16 +82,28 @@ char *phonebook_set_folder(const char *current_folder,
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