Diff between 7f18c7db870ac0e814bb7755d3a99f69fe89774c and 73fa3610f7c4ed51c725d60c56f6f20de29a18f1

Changed Files

File Additions Deletions Status
obexd/plugins/ebook.c +4 -1 modified
obexd/src/pbap.c +113 -10 modified
obexd/src/phonebook.c +7 -2 modified
obexd/src/phonebook.h +8 -2 modified

Full Patch

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
@@ -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 6da8a32..676d38f 100644
--- a/obexd/src/pbap.c
+++ b/obexd/src/pbap.c
@@ -29,39 +29,142 @@
 #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
@@ -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 440d857..c334c05 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);
 };