diff --git a/obexd/plugins/ebook.c b/obexd/plugins/ebook.c
index abb16cb..5316bd8 100644
--- a/obexd/plugins/ebook.c
+++ b/obexd/plugins/ebook.c
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 6da8a32..676d38f 100644
--- a/obexd/src/pbap.c
+++ b/obexd/src/pbap.c
#include <openobex/obex_const.h>
#include <glib.h>
+#include <bluetooth/bluetooth.h>
#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 1b7d723..874da7d 100644
--- a/obexd/src/phonebook.c
+++ b/obexd/src/phonebook.c
}
}
-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 440d857..c334c05 100644
--- a/obexd/src/phonebook.h
+++ b/obexd/src/phonebook.h
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);
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);
};