From 73fa3610f7c4ed51c725d60c56f6f20de29a18f1 Mon Sep 17 00:00:00 2001 From: Forrest Zhao Date: Thu, 27 Nov 2008 11:35:16 +0800 Subject: [PATCH] obexd: parsing the application parameters header of PBAP PullPhonebook --- obexd/plugins/ebook.c | 5 +- obexd/src/pbap.c | 123 ++++++++++++++++++++++++++++++++++++++---- obexd/src/phonebook.c | 9 +++- obexd/src/phonebook.h | 10 +++- 4 files changed, 132 insertions(+), 15 deletions(-) diff --git a/obexd/plugins/ebook.c b/obexd/plugins/ebook.c index abb16cb41..5316bd83c 100644 --- a/obexd/plugins/ebook.c +++ b/obexd/plugins/ebook.c @@ -78,7 +78,10 @@ static void ebooklist_cb(EBook *book, EBookStatus status, GList *list, g_object_unref(book); } -static int ebook_pullphonebook(struct phonebook_context *context) +static int ebook_pullphonebook(struct phonebook_context *context, + gchar *objname, guint64 filter, guint8 format, + guint16 maxlistcount, guint16 liststartoffset, + guint16 *phonebooksize, guint8 *newmissedcalls) { EBook *book; EBookQuery *query; diff --git a/obexd/src/pbap.c b/obexd/src/pbap.c index 6da8a3292..676d38ffe 100644 --- a/obexd/src/pbap.c +++ b/obexd/src/pbap.c @@ -29,39 +29,142 @@ #include #include +#include #include "logging.h" #include "obex.h" #define PHONEBOOK_TYPE "x-bt/phonebook" +#define ORDER_TAG 0x01 +#define SEARCHVALUE_TAG 0x02 +#define SEARCHATTRIB_TAG 0x03 +#define MAXLISTCOUNT_TAG 0x04 +#define LISTSTARTOFFSET_TAG 0x05 +#define FILTER_TAG 0x06 +#define FORMAT_TAG 0X07 +#define PHONEBOOKSIZE_TAG 0X08 +#define NEWMISSEDCALLS_TAG 0X09 + +/* The following length is in the unit of byte */ +#define ORDER_LEN 1 +#define SEARCHATTRIB_LEN 1 +#define MAXLISTCOUNT_LEN 2 +#define LISTSTARTOFFSET_LEN 2 +#define FILTER_LEN 8 +#define FORMAT_LEN 1 +#define PHONEBOOKSIZE_LEN 2 +#define NEWMISSEDCALLS_LEN 1 + +typedef struct { + uint8_t tag; + uint8_t len; + uint8_t val[0]; +} __attribute__ ((packed)) apparam_hdr; + +#define get_be64(val) GUINT64_FROM_BE(bt_get_unaligned((guint64 *) val)) +#define get_be16(val) GUINT16_FROM_BE(bt_get_unaligned((guint16 *) val)) + static GSList *session_list = NULL; +static int pbap_pullphonebook(obex_t *obex, obex_object_t *obj) +{ + struct obex_session *session; + obex_headerdata_t hd; + guint8 hi, *p, newmissedcalls, format; + guint16 maxlistcount, liststartoffset, phonebooksize; + guint32 hlen, offset; + guint64 filter; + apparam_hdr *hdr; + + session = OBEX_GetUserData(obex); + + while (OBEX_ObjectGetNextHeader(obex, obj, &hi, &hd, &hlen)) { + if (hi != OBEX_HDR_APPARAM) + continue; + + if (hlen <= sizeof(apparam_hdr)) { + error("PBAP pullphonebook app parameters header" + " is too short: %d", hlen); + return -1; + } + + p = (guint8 *) hd.bs; + hdr = (apparam_hdr *) hd.bs; + offset = 0; + while (offset < hlen) { + switch (hdr->tag) { + case FILTER_TAG: + if (hdr->len == FILTER_LEN) + filter = get_be64(hdr->val); + else + goto fail; + break; + case FORMAT_TAG: + if (hdr->len == FORMAT_LEN) + format = hdr->val[0]; + else + goto fail; + break; + case MAXLISTCOUNT_TAG: + if (hdr->len == MAXLISTCOUNT_LEN) + maxlistcount = get_be16(hdr->val); + else + goto fail; + break; + case LISTSTARTOFFSET_TAG: + if (hdr->len == LISTSTARTOFFSET_LEN) + liststartoffset = get_be16(hdr->val); + else + goto fail; + break; + default: +fail: error("Unexpected PBAP pullphonebook app" + " parameter, tag %d, len %d", + hdr->tag, hdr->len); + return -1; + } + + p += sizeof(apparam_hdr) + hdr->len; + offset += sizeof(apparam_hdr) + hdr->len; + hdr = (apparam_hdr *) p; + } + + /* Ignore multiple app param headers */ + break; + } + + return phonebook_pullphonebook(session->pbctx, session->name, filter, + format, maxlistcount, liststartoffset, + &phonebooksize, &newmissedcalls); +} + void pbap_get(obex_t *obex, obex_object_t *obj) { struct obex_session *session; obex_headerdata_t hv; - int ret; + int err; session = OBEX_GetUserData(obex); if (session == NULL) return; - if (session->type == NULL) - goto fail; - - if (g_str_equal(session->type, PHONEBOOK_TYPE) == FALSE) + if (session->type == NULL || session->name == NULL) goto fail; - ret = phonebook_pullphonebook(session->pbctx); + OBEX_ObjectReParseHeaders(obex, obj); - if (!ret) { - OBEX_SuspendRequest(obex, obj); - session->size = 0; - } + if (g_str_equal(session->type, PHONEBOOK_TYPE) == TRUE) + err = pbap_pullphonebook(obex, obj); else goto fail; + if (err < 0) + goto fail; + + OBEX_SuspendRequest(obex, obj); + session->size = 0; + /* Add body header */ hv.bs = NULL; OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_BODY, diff --git a/obexd/src/phonebook.c b/obexd/src/phonebook.c index 1b7d72383..874da7d92 100644 --- a/obexd/src/phonebook.c +++ b/obexd/src/phonebook.c @@ -101,12 +101,17 @@ void phonebook_unref(struct phonebook_context *context) } } -int phonebook_pullphonebook(struct phonebook_context *context) +int phonebook_pullphonebook(struct phonebook_context *context, gchar *objname, + guint64 filter, guint8 format, guint16 maxlistcount, + guint16 liststartoffset, guint16 *phonebooksize, + guint8 *newmissedcalls) { if (!context->driver->pullphonebook) return -1; - return context->driver->pullphonebook(context); + return context->driver->pullphonebook(context, objname, filter, format, + maxlistcount, liststartoffset, phonebooksize, + newmissedcalls); } /* if buf is NULL or size is 0, this indicate that no more result will diff --git a/obexd/src/phonebook.h b/obexd/src/phonebook.h index 440d857a9..c334c051a 100644 --- a/obexd/src/phonebook.h +++ b/obexd/src/phonebook.h @@ -49,7 +49,10 @@ static inline void phonebook_set_data(struct phonebook_context *context, context->driver_data = data; } -extern int phonebook_pullphonebook(struct phonebook_context *context); +extern int phonebook_pullphonebook(struct phonebook_context *context, + gchar *objname, guint64 filter, guint8 format, + guint16 maxlistcount, guint16 liststartoffset, + guint16 *phonebooksize, guint8 *newmissedcalls); extern void phonebook_return(struct phonebook_context *context, char *buf, int size); @@ -57,7 +60,10 @@ struct phonebook_driver { const char *name; int (*create) (struct phonebook_context *context); void (*destroy) (struct phonebook_context *context); - int (*pullphonebook) (struct phonebook_context *context); + int (*pullphonebook) (struct phonebook_context *context, + gchar *objname, guint64 filter, guint8 format, + guint16 maxlistcount, guint16 liststartoffset, + guint16 *phonebooksize, guint8 *newmissedcalls); int (*pullvcardlisting) (struct phonebook_context *context); int (*pullvcardentry) (struct phonebook_context *context); }; -- 2.47.3