Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH 3/7 v2] Remove unnecessary checking for num_fields in pull_contact
From: Radoslaw Jablonski @ 2011-02-11 14:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Radoslaw Jablonski
In-Reply-To: <1297433139-10923-1-git-send-email-ext-jablonski.radoslaw@nokia.com>

This check is no longer needed - it was used to ensure that no
error occured in querying tracker. This is redundant because
checking for that case is located in the beginning of pull_contacts
function.
---
 plugins/phonebook-tracker.c |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index a8c8a87..be94867 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -1634,9 +1634,7 @@ add_numbers:
 done:
 	vcards = gen_vcards(data->contacts, params);
 
-	if (num_fields == 0)
-		data->cb(vcards->str, vcards->len,
-					g_slist_length(data->contacts),
+	data->cb(vcards->str, vcards->len, g_slist_length(data->contacts),
 					data->newmissedcalls, data->user_data);
 
 	g_string_free(vcards, TRUE);
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 4/7 v2] Support for stop fetching data when maxlistcount is achieved
From: Radoslaw Jablonski @ 2011-02-11 14:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Radoslaw Jablonski
In-Reply-To: <1297433139-10923-1-git-send-email-ext-jablonski.radoslaw@nokia.com>

When desired number of results has been already processed,
then sending already collected data and stopping fetching
more results from tracker (previously in this scenario
unnecessarily processing data continued untill end of results
in db)
---
 plugins/phonebook-tracker.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index be94867..afd738c 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -1602,11 +1602,17 @@ static int pull_contacts(const char **reply, int num_fields, void *user_data)
 
 	last_index = params->liststartoffset + params->maxlistcount;
 
-	if ((data->index <= params->liststartoffset ||
-						data->index > last_index) &&
-						params->maxlistcount > 0)
+	if (data->index <= params->liststartoffset)
 		return 0;
 
+	/* max number of results achieved - need send vcards data that was
+	 * already collected and stop further data processing (these operations
+	 * will be invoked in "done" section) */
+	if (data->index > last_index && params->maxlistcount > 0) {
+		DBG("Maxlistcount achieved");
+		goto done;
+	}
+
 add_entry:
 	contact = g_new0(struct phonebook_contact, 1);
 	contact_init(contact, reply);
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 5/7 v2] Add support for notyfying pbap about more parts from backend
From: Radoslaw Jablonski @ 2011-02-11 14:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Radoslaw Jablonski
In-Reply-To: <1297433139-10923-1-git-send-email-ext-jablonski.radoslaw@nokia.com>

Added new parameter to phonebook_cb - lastpart variable.
If backend want to notify that more parts of current
request will be delivered later, it should use lastpart=FALSE.
Because of that, PBAP core will 'know' that should not finalize
request immediately after receiving data and wait for more
parts to come.
If result is returned in one part and no more responses part
will be sent later, then backend should use lastparam=TRUE.
Previously results of request from backend was always returned
in one part to PBAP core.
---
 plugins/irmc.c              |    5 +++--
 plugins/pbap.c              |   10 +++++++---
 plugins/phonebook-dummy.c   |    4 ++--
 plugins/phonebook-ebook.c   |    7 ++++---
 plugins/phonebook-tracker.c |   13 +++++++------
 plugins/phonebook.h         |    2 +-
 6 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/plugins/irmc.c b/plugins/irmc.c
index 0488cae..e1e83f9 100644
--- a/plugins/irmc.c
+++ b/plugins/irmc.c
@@ -133,7 +133,8 @@ static const char *owner_vcard =
 		"END:VCARD\r\n";
 
 static void phonebook_size_result(const char *buffer, size_t bufsize,
-				int vcards, int missed, void *user_data)
+					int vcards, int missed,
+					gboolean lastpart, void *user_data)
 {
 	struct irmc_session *irmc = user_data;
 
@@ -148,7 +149,7 @@ static void phonebook_size_result(const char *buffer, size_t bufsize,
 }
 
 static void query_result(const char *buffer, size_t bufsize, int vcards,
-					int missed, void *user_data)
+				int missed, gboolean lastpart, void *user_data)
 {
 	struct irmc_session *irmc = user_data;
 	const char *s, *t;
diff --git a/plugins/pbap.c b/plugins/pbap.c
index 6579d09..5775eea 100644
--- a/plugins/pbap.c
+++ b/plugins/pbap.c
@@ -148,6 +148,7 @@ struct pbap_object {
 	GString *buffer;
 	GByteArray *aparams;
 	gboolean firstpacket;
+	gboolean lastpart;
 	struct pbap_session *session;
 	void *request;
 };
@@ -254,7 +255,8 @@ static GByteArray *append_aparam_header(GByteArray *buf, uint8_t tag,
 }
 
 static void phonebook_size_result(const char *buffer, size_t bufsize,
-				int vcards, int missed, void *user_data)
+					int vcards, int missed,
+					gboolean lastpart, void *user_data)
 {
 	struct pbap_session *pbap = user_data;
 	uint16_t phonebooksize;
@@ -286,17 +288,19 @@ static void phonebook_size_result(const char *buffer, size_t bufsize,
 }
 
 static void query_result(const char *buffer, size_t bufsize, int vcards,
-					int missed, void *user_data)
+				int missed, gboolean lastpart, void *user_data)
 {
 	struct pbap_session *pbap = user_data;
 
 	DBG("");
 
-	if (pbap->obj->request) {
+	if (pbap->obj->request && lastpart) {
 		phonebook_req_finalize(pbap->obj->request);
 		pbap->obj->request = NULL;
 	}
 
+	pbap->obj->lastpart = lastpart;
+
 	if (vcards <= 0) {
 		obex_object_set_io_flags(pbap->obj, G_IO_ERR, -ENOENT);
 		return;
diff --git a/plugins/phonebook-dummy.c b/plugins/phonebook-dummy.c
index 60b7640..76dd550 100644
--- a/plugins/phonebook-dummy.c
+++ b/plugins/phonebook-dummy.c
@@ -248,7 +248,7 @@ static gboolean read_dir(void *user_data)
 	closedir(dp);
 done:
 	/* FIXME: Missing vCards fields filtering */
-	dummy->cb(buffer->str, buffer->len, count, 0, dummy->user_data);
+	dummy->cb(buffer->str, buffer->len, count, 0, TRUE, dummy->user_data);
 
 	g_string_free(buffer, TRUE);
 
@@ -346,7 +346,7 @@ static gboolean read_entry(void *user_data)
 
 	/* FIXME: Missing vCards fields filtering */
 
-	dummy->cb(buffer, count, 1, 0, dummy->user_data);
+	dummy->cb(buffer, count, 1, 0, TRUE, dummy->user_data);
 
 	return FALSE;
 }
diff --git a/plugins/phonebook-ebook.c b/plugins/phonebook-ebook.c
index 70b9c02..6cc4f31 100644
--- a/plugins/phonebook-ebook.c
+++ b/plugins/phonebook-ebook.c
@@ -186,7 +186,8 @@ static void ebookpull_cb(EBook *book, EBookStatus estatus, GList *contacts,
 
 done:
 	data->completed = TRUE;
-	data->contacts_cb(string->str, string->len, count, 0, data->user_data);
+	data->contacts_cb(string->str, string->len, count, 0, TRUE,
+							data->user_data);
 
 fail:
 	g_string_free(string, TRUE);
@@ -212,7 +213,7 @@ static void ebook_entry_cb(EBook *book, EBookStatus estatus,
 
 	if (estatus != E_BOOK_ERROR_OK) {
 		error("E-Book query failed: status %d", estatus);
-		data->contacts_cb(NULL, 0, 1, 0, data->user_data);
+		data->contacts_cb(NULL, 0, 1, 0, TRUE, data->user_data);
 		goto fail;
 	}
 
@@ -223,7 +224,7 @@ static void ebook_entry_cb(EBook *book, EBookStatus estatus,
 
 	len = vcard ? strlen(vcard) : 0;
 
-	data->contacts_cb(vcard, len, 1, 0, data->user_data);
+	data->contacts_cb(vcard, len, 1, 0, TRUE, data->user_data);
 
 	g_free(vcard);
 
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index afd738c..0762787 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -1334,7 +1334,7 @@ static int pull_contacts_size(const char **reply, int num_fields,
 	struct phonebook_data *data = user_data;
 
 	if (num_fields < 0) {
-		data->cb(NULL, 0, num_fields, 0, data->user_data);
+		data->cb(NULL, 0, num_fields, 0, TRUE, data->user_data);
 		return -EINTR;
 	}
 
@@ -1343,7 +1343,8 @@ static int pull_contacts_size(const char **reply, int num_fields,
 		return 0;
 	}
 
-	data->cb(NULL, 0, data->index, data->newmissedcalls, data->user_data);
+	data->cb(NULL, 0, data->index, data->newmissedcalls, TRUE,
+							data->user_data);
 
 	return 0;
 	/*
@@ -1561,7 +1562,7 @@ static int pull_contacts(const char **reply, int num_fields, void *user_data)
 	static char *temp_id = NULL;
 
 	if (num_fields < 0) {
-		data->cb(NULL, 0, num_fields, 0, data->user_data);
+		data->cb(NULL, 0, num_fields, 0, TRUE, data->user_data);
 		goto fail;
 	}
 
@@ -1641,7 +1642,7 @@ done:
 	vcards = gen_vcards(data->contacts, params);
 
 	data->cb(vcards->str, vcards->len, g_slist_length(data->contacts),
-					data->newmissedcalls, data->user_data);
+				data->newmissedcalls, TRUE, data->user_data);
 
 	g_string_free(vcards, TRUE);
 fail:
@@ -1868,7 +1869,7 @@ done:
 	data->contacts = NULL;
 
 	if (num_fields < 0) {
-		data->cb(NULL, 0, num_fields, 0, data->user_data);
+		data->cb(NULL, 0, num_fields, 0, TRUE, data->user_data);
 		return -EINTR;
 	}
 
@@ -1884,7 +1885,7 @@ done:
 
 	err = query_tracker(query, col_amount, pull_cb, data);
 	if (err < 0) {
-		data->cb(NULL, 0, err, 0, data->user_data);
+		data->cb(NULL, 0, err, 0, TRUE, data->user_data);
 
 		return -EINTR;
 	}
diff --git a/plugins/phonebook.h b/plugins/phonebook.h
index bfbae0f..f6df164 100644
--- a/plugins/phonebook.h
+++ b/plugins/phonebook.h
@@ -50,7 +50,7 @@ struct apparam_field {
  * Contacts will be returned in the vcard format.
  */
 typedef void (*phonebook_cb) (const char *buffer, size_t bufsize,
-		int vcards, int missed, void *user_data);
+		int vcards, int missed, gboolean lastpart, void *user_data);
 
 /*
  * Interface between the PBAP core and backends to
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 6/7 v2] Introduction of phonebook_pull_read
From: Radoslaw Jablonski @ 2011-02-11 14:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Radoslaw Jablonski
In-Reply-To: <1297433139-10923-1-git-send-email-ext-jablonski.radoslaw@nokia.com>

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.
---
 plugins/irmc.c              |   14 +++++++++++
 plugins/pbap.c              |   25 +++++++++++++++++++-
 plugins/phonebook-dummy.c   |   27 ++++++++++++++++-----
 plugins/phonebook-ebook.c   |   23 +++++++++++++-----
 plugins/phonebook-tracker.c |   52 ++++++++++++++++++++++++++----------------
 plugins/phonebook.h         |   20 +++++++++++++---
 6 files changed, 122 insertions(+), 39 deletions(-)

diff --git a/plugins/irmc.c b/plugins/irmc.c
index e1e83f9..68aa6e2 100644
--- a/plugins/irmc.c
+++ b/plugins/irmc.c
@@ -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,11 @@ 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 +319,14 @@ 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;
 	}
 
diff --git a/plugins/pbap.c b/plugins/pbap.c
index 5775eea..33e40b4 100644
--- a/plugins/pbap.c
+++ b/plugins/pbap.c
@@ -806,6 +806,12 @@ static void *vobject_pull_open(const char *name, int oflag, mode_t mode,
 	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;
 
@@ -962,6 +968,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 +994,23 @@ 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;
 	}
 }
 
diff --git a/plugins/phonebook-dummy.c b/plugins/phonebook-dummy.c
index 76dd550..532c921 100644
--- a/plugins/phonebook-dummy.c
+++ b/plugins/phonebook-dummy.c
@@ -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,
diff --git a/plugins/phonebook-ebook.c b/plugins/phonebook-ebook.c
index 6cc4f31..82019da 100644
--- a/plugins/phonebook-ebook.c
+++ b/plugins/phonebook-ebook.c
@@ -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)
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 0762787..48748f3 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -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,42 +1899,52 @@ 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) {
+	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/plugins/phonebook.h b/plugins/phonebook.h
index f6df164..00abc08 100644
--- a/plugins/phonebook.h
+++ b/plugins/phonebook.h
@@ -82,17 +82,29 @@ 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
  * return only the content based on the application parameters requested
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 7/7 v2] Support for multipart response sending from phonebook-tracker
From: Radoslaw Jablonski @ 2011-02-11 14:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Radoslaw Jablonski
In-Reply-To: <1297433139-10923-1-git-send-email-ext-jablonski.radoslaw@nokia.com>

Now data are being sent with smaller parts - vcard amount for
one part is defined in VCARDS_PART_COUNT. When one part of
data is sent, then data download from tracker is stopped.
It will be resumed when phonebook_pull_read will be called again.
This is needed to start sending data from PBAP quicker - now
transfer can be started when first part of data is processed.
Previously transfer was started when all results for response
were downloaded, and (for large responses) some PBAP clients
were disconnecting due to timeout.
---
 plugins/phonebook-tracker.c |   81 +++++++++++++++++++++++++++++++++---------
 1 files changed, 63 insertions(+), 18 deletions(-)

diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 48748f3..ab8d428 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -81,6 +81,8 @@
 #define MAIN_DELIM "\30" /* Main delimiter between phones, addresses, emails*/
 #define SUB_DELIM "\31" /* Delimiter used in telephone number strings*/
 #define MAX_FIELDS 100 /* Max amount of fields to be concatenated at once*/
+#define VCARDS_PART_COUNT 50 /* amount of vcards sent at once to PBAP core */
+#define QUERY_OFFSET_FORMAT "%s OFFSET %d"
 
 #define CONTACTS_QUERY_ALL						\
 "SELECT "								\
@@ -919,6 +921,8 @@ struct phonebook_data {
 	int newmissedcalls;
 	GCancellable *query_canc;
 	char *req_name;
+	int vcard_part_count;
+	int tracker_index;
 };
 
 struct phonebook_index {
@@ -1551,15 +1555,45 @@ static void contact_add_organization(struct phonebook_contact *contact,
 	add_affiliation(&contact->role, reply[COL_ORG_ROLE]);
 }
 
+static void free_data_contacts(struct phonebook_data *data)
+{
+	GSList *l;
+
+	/* freeing contacts */
+	for (l = data->contacts; l; l = l->next) {
+		struct contact_data *c_data = l->data;
+
+		g_free(c_data->id);
+		phonebook_contact_free(c_data->contact);
+		g_free(c_data);
+	}
+
+	g_slist_free(data->contacts);
+	data->contacts = NULL;
+}
+
+static void send_pull_part(struct phonebook_data *data,
+			const struct apparam_field *params, gboolean lastpart)
+{
+	GString *vcards;
+
+	DBG("");
+	vcards = gen_vcards(data->contacts, params);
+	data->cb(vcards->str, vcards->len, g_slist_length(data->contacts),
+			data->newmissedcalls, lastpart, data->user_data);
+
+	free_data_contacts(data);
+	g_string_free(vcards, TRUE);
+}
+
 static int pull_contacts(const char **reply, int num_fields, void *user_data)
 {
 	struct phonebook_data *data = user_data;
 	const struct apparam_field *params = data->params;
 	struct phonebook_contact *contact;
 	struct contact_data *contact_data;
-	GString *vcards;
 	int last_index, i;
-	gboolean cdata_present = FALSE;
+	gboolean cdata_present = FALSE, part_sent = FALSE;
 	static char *temp_id = NULL;
 
 	if (num_fields < 0) {
@@ -1568,6 +1602,7 @@ static int pull_contacts(const char **reply, int num_fields, void *user_data)
 	}
 
 	DBG("reply %p", reply);
+	data->tracker_index++;
 
 	if (reply == NULL)
 		goto done;
@@ -1600,6 +1635,25 @@ static int pull_contacts(const char **reply, int num_fields, void *user_data)
 		data->index++;
 		g_free(temp_id);
 		temp_id = g_strdup(reply[CONTACTS_ID_COL]);
+
+		/* Incrementing counter for vcards in current part of data,
+		 * but only if liststartoffset has been already reached */
+		if (data->index > params->liststartoffset)
+			data->vcard_part_count++;
+	}
+
+	if (data->vcard_part_count > VCARDS_PART_COUNT) {
+		DBG("Part of vcard data ready for sending...");
+		data->vcard_part_count = 0;
+		/* Sending part of data to PBAP core - more data can be still
+		 * fetched, so marking lastpart as FALSE */
+		send_pull_part(data, params, FALSE);
+
+		/* Later, after adding contact data, need to return -EINTR to
+		 * stop fetching more data for this request. Data will be
+		 * downloaded again from this point, when phonebook_pull_read
+		 * will be called again with current request as a parameter*/
+		part_sent = TRUE;
 	}
 
 	last_index = params->liststartoffset + params->maxlistcount;
@@ -1637,15 +1691,16 @@ add_numbers:
 		data->contacts = g_slist_append(data->contacts, contact_data);
 	}
 
+	if (part_sent)
+		return -EINTR;
+
 	return 0;
 
 done:
-	vcards = gen_vcards(data->contacts, params);
+	/* Processing is end, this is definitely last part of transmission
+	 * (marking lastpart as TRUE) */
+	send_pull_part(data, params, TRUE);
 
-	data->cb(vcards->str, vcards->len, g_slist_length(data->contacts),
-				data->newmissedcalls, TRUE, data->user_data);
-
-	g_string_free(vcards, TRUE);
 fail:
 	g_free(temp_id);
 	temp_id = NULL;
@@ -1797,7 +1852,6 @@ done:
 void phonebook_req_finalize(void *request)
 {
 	struct phonebook_data *data = request;
-	GSList *l;
 
 	DBG("");
 
@@ -1810,16 +1864,7 @@ void phonebook_req_finalize(void *request)
 		g_object_unref(data->query_canc);
 	}
 
-	/* freeing contacts */
-	for (l = data->contacts; l; l = l->next) {
-		struct contact_data *c_data = l->data;
-
-		g_free(c_data->id);
-		phonebook_contact_free(c_data->contact);
-		g_free(c_data);
-	}
-
-	g_slist_free(data->contacts);
+	free_data_contacts(data);
 	g_free(data->req_name);
 	g_free(data);
 }
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 1/5] Put all gatttool global options in a unique struct
From: Sheldon Demario @ 2011-02-11 14:17 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario
In-Reply-To: <20110209212642.GA11368@jh-x301>

---
 attrib/gatttool.c |  186 +++++++++++++++++++++++++++++++----------------------
 1 files changed, 108 insertions(+), 78 deletions(-)

diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index 8e8ed8e..c612309 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -46,32 +46,56 @@
 /* Minimum MTU for L2CAP connections over BR/EDR */
 #define ATT_MIN_MTU_L2CAP 48
 
-static gchar *opt_src = NULL;
-static gchar *opt_dst = NULL;
-static gchar *opt_value = NULL;
-static gchar *opt_sec_level = "low";
-static uuid_t *opt_uuid = NULL;
-static int opt_start = 0x0001;
-static int opt_end = 0xffff;
-static int opt_handle = -1;
-static int opt_mtu = 0;
-static int opt_psm = 0x1f;
-static gboolean opt_primary = FALSE;
-static gboolean opt_characteristics = FALSE;
-static gboolean opt_char_read = FALSE;
-static gboolean opt_listen = FALSE;
-static gboolean opt_char_desc = FALSE;
-static gboolean opt_le = FALSE;
-static gboolean opt_char_write = FALSE;
 static GMainLoop *event_loop;
 static gboolean got_error = FALSE;
 
+static struct main_opts {
+	gchar *src;
+	gchar *dst;
+	gchar *value;
+	gchar *sec_level;
+	uuid_t *uuid;
+	int start;
+	int end;
+	int handle;
+	int mtu;
+	int psm;
+	gboolean primary;
+	gboolean char_disc;
+	gboolean char_read;
+	gboolean listen;
+	gboolean char_desc;
+	gboolean le;
+	gboolean char_write;
+} main_opts;
+
 struct characteristic_data {
 	GAttrib *attrib;
 	uint16_t start;
 	uint16_t end;
 };
 
+static void options_init(void)
+{
+	main_opts.src = NULL;
+	main_opts.dst = NULL;
+	main_opts.value = NULL;
+	main_opts.sec_level = "low";
+	main_opts.uuid = NULL;
+	main_opts.start = 0x0001;
+	main_opts.end = 0xffff;
+	main_opts.handle = -1;
+	main_opts.mtu = 0;
+	main_opts.psm = 0x1f;
+	main_opts.primary = FALSE;
+	main_opts.char_disc = FALSE;
+	main_opts.char_read = FALSE;
+	main_opts.listen = FALSE;
+	main_opts.char_desc = FALSE;
+	main_opts.le = FALSE;
+	main_opts.char_write = FALSE;
+}
+
 static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
 {
 	if (err) {
@@ -90,31 +114,31 @@ static GIOChannel *do_connect(gboolean le)
 
 	/* This check is required because currently setsockopt() returns no
 	 * errors for MTU values smaller than the allowed minimum. */
-	if (opt_mtu != 0 && opt_mtu < ATT_MIN_MTU_L2CAP) {
+	if (main_opts.mtu != 0 && main_opts.mtu < ATT_MIN_MTU_L2CAP) {
 		g_printerr("MTU cannot be smaller than %d\n",
 							ATT_MIN_MTU_L2CAP);
 		return NULL;
 	}
 
 	/* Remote device */
-	if (opt_dst == NULL) {
+	if (main_opts.dst == NULL) {
 		g_printerr("Remote Bluetooth address required\n");
 		return NULL;
 	}
-	str2ba(opt_dst, &dba);
+	str2ba(main_opts.dst, &dba);
 
 	/* Local adapter */
-	if (opt_src != NULL) {
-		if (!strncmp(opt_src, "hci", 3))
-			hci_devba(atoi(opt_src + 3), &sba);
+	if (main_opts.src != NULL) {
+		if (!strncmp(main_opts.src, "hci", 3))
+			hci_devba(atoi(main_opts.src + 3), &sba);
 		else
-			str2ba(opt_src, &sba);
+			str2ba(main_opts.src, &sba);
 	} else
 		bacpy(&sba, BDADDR_ANY);
 
-	if (strcmp(opt_sec_level, "medium") == 0)
+	if (strcmp(main_opts.sec_level, "medium") == 0)
 		sec_level = BT_IO_SEC_MEDIUM;
-	else if (strcmp(opt_sec_level, "high") == 0)
+	else if (strcmp(main_opts.sec_level, "high") == 0)
 		sec_level = BT_IO_SEC_HIGH;
 	else
 		sec_level = BT_IO_SEC_LOW;
@@ -124,15 +148,15 @@ static GIOChannel *do_connect(gboolean le)
 				BT_IO_OPT_SOURCE_BDADDR, &sba,
 				BT_IO_OPT_DEST_BDADDR, &dba,
 				BT_IO_OPT_CID, GATT_CID,
-				BT_IO_OPT_OMTU, opt_mtu,
+				BT_IO_OPT_OMTU, main_opts.mtu,
 				BT_IO_OPT_SEC_LEVEL, sec_level,
 				BT_IO_OPT_INVALID);
 	else
 		chan = bt_io_connect(BT_IO_L2CAP, connect_cb, NULL, NULL, &err,
 				BT_IO_OPT_SOURCE_BDADDR, &sba,
 				BT_IO_OPT_DEST_BDADDR, &dba,
-				BT_IO_OPT_PSM, opt_psm,
-				BT_IO_OPT_OMTU, opt_mtu,
+				BT_IO_OPT_PSM, main_opts.psm,
+				BT_IO_OPT_OMTU, main_opts.mtu,
 				BT_IO_OPT_SEC_LEVEL, sec_level,
 				BT_IO_OPT_INVALID);
 
@@ -236,9 +260,9 @@ static gboolean primary(gpointer user_data)
 {
 	GAttrib *attrib = user_data;
 
-	if (opt_uuid)
-		gatt_discover_primary(attrib, opt_uuid, primary_by_uuid_cb,
-									NULL);
+	if (main_opts.uuid)
+		gatt_discover_primary(attrib, main_opts.uuid,
+						primary_by_uuid_cb, NULL);
 	else
 		gatt_discover_primary(attrib, NULL, primary_all_cb, NULL);
 
@@ -272,7 +296,8 @@ static gboolean characteristics(gpointer user_data)
 {
 	GAttrib *attrib = user_data;
 
-	gatt_discover_char(attrib, opt_start, opt_end, char_discovered_cb, NULL);
+	gatt_discover_char(attrib, main_opts.start, main_opts.end,
+						char_discovered_cb, NULL);
 
 	return FALSE;
 }
@@ -298,7 +323,7 @@ static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
 	g_print("\n");
 
 done:
-	if (opt_listen == FALSE)
+	if (main_opts.listen == FALSE)
 		g_main_loop_quit(event_loop);
 }
 
@@ -310,7 +335,7 @@ static void char_read_by_uuid_cb(guint8 status, const guint8 *pdu,
 	int i;
 
 	if (status == ATT_ECODE_ATTR_NOT_FOUND &&
-					char_data->start != opt_start)
+					char_data->start != main_opts.start)
 		goto done;
 
 	if (status != 0) {
@@ -339,7 +364,7 @@ static void char_read_by_uuid_cb(guint8 status, const guint8 *pdu,
 	att_data_list_free(list);
 
 	gatt_read_char_by_uuid(char_data->attrib, char_data->start,
-					char_data->end, opt_uuid,
+					char_data->end, main_opts.uuid,
 					char_read_by_uuid_cb,
 					char_data);
 
@@ -353,27 +378,28 @@ static gboolean characteristics_read(gpointer user_data)
 {
 	GAttrib *attrib = user_data;
 
-	if (opt_uuid != NULL) {
+	if (main_opts.uuid != NULL) {
 		struct characteristic_data *char_data;
 
 		char_data = g_new(struct characteristic_data, 1);
 		char_data->attrib = attrib;
-		char_data->start = opt_start;
-		char_data->end = opt_end;
+		char_data->start = main_opts.start;
+		char_data->end = main_opts.end;
 
-		gatt_read_char_by_uuid(attrib, opt_start, opt_end, opt_uuid,
-						char_read_by_uuid_cb, char_data);
+		gatt_read_char_by_uuid(attrib, main_opts.start, main_opts.end,
+					main_opts.uuid, char_read_by_uuid_cb,
+					char_data);
 
 		return FALSE;
 	}
 
-	if (opt_handle <= 0) {
+	if (main_opts.handle <= 0) {
 		g_printerr("A valid handle is required\n");
 		g_main_loop_quit(event_loop);
 		return FALSE;
 	}
 
-	gatt_read_char(attrib, opt_handle, char_read_cb, attrib);
+	gatt_read_char(attrib, main_opts.handle, char_read_cb, attrib);
 
 	return FALSE;
 }
@@ -411,23 +437,24 @@ static gboolean characteristics_write(gpointer user_data)
 	uint8_t *value;
 	size_t len;
 
-	if (opt_handle <= 0) {
+	if (main_opts.handle <= 0) {
 		g_printerr("A valid handle is required\n");
 		goto error;
 	}
 
-	if (opt_value == NULL || opt_value[0] == '\0') {
+	if (main_opts.value == NULL || main_opts.value[0] == '\0') {
 		g_printerr("A value is required\n");
 		goto error;
 	}
 
-	len = attr_data_from_string(opt_value, &value);
+	len = attr_data_from_string(main_opts.value, &value);
 	if (len == 0) {
 		g_printerr("Invalid value\n");
 		goto error;
 	}
 
-	gatt_write_cmd(attrib, opt_handle, value, len, mainloop_quit, value);
+	gatt_write_cmd(attrib, main_opts.handle, value, len, mainloop_quit,
+									value);
 
 	return FALSE;
 
@@ -474,7 +501,7 @@ static void char_desc_cb(guint8 status, const guint8 *pdu, guint16 plen,
 	att_data_list_free(list);
 
 done:
-	if (opt_listen == FALSE)
+	if (main_opts.listen == FALSE)
 		g_main_loop_quit(event_loop);
 }
 
@@ -482,7 +509,8 @@ static gboolean characteristics_desc(gpointer user_data)
 {
 	GAttrib *attrib = user_data;
 
-	gatt_find_info(attrib, opt_start, opt_end, char_desc_cb, NULL);
+	gatt_find_info(attrib, main_opts.start, main_opts.end,
+							char_desc_cb, NULL);
 
 	return FALSE;
 }
@@ -493,20 +521,20 @@ static gboolean parse_uuid(const char *key, const char *value,
 	if (!value)
 		return FALSE;
 
-	opt_uuid = g_try_malloc(sizeof(uuid_t));
-	if (opt_uuid == NULL)
+	main_opts.uuid = g_try_malloc(sizeof(uuid_t));
+	if (main_opts.uuid == NULL)
 		return FALSE;
 
-	if (bt_string2uuid(opt_uuid, value) < 0)
+	if (bt_string2uuid(main_opts.uuid, value) < 0)
 		return FALSE;
 
 	return TRUE;
 }
 
 static GOptionEntry primary_char_options[] = {
-	{ "start", 's' , 0, G_OPTION_ARG_INT, &opt_start,
+	{ "start", 's' , 0, G_OPTION_ARG_INT, &main_opts.start,
 		"Starting handle(optional)", "0x0001" },
-	{ "end", 'e' , 0, G_OPTION_ARG_INT, &opt_end,
+	{ "end", 'e' , 0, G_OPTION_ARG_INT, &main_opts.end,
 		"Ending handle(optional)", "0xffff" },
 	{ "uuid", 'u', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
 		parse_uuid, "UUID16 or UUID128(optional)", "0x1801"},
@@ -514,42 +542,42 @@ static GOptionEntry primary_char_options[] = {
 };
 
 static GOptionEntry char_rw_options[] = {
-	{ "handle", 'a' , 0, G_OPTION_ARG_INT, &opt_handle,
+	{ "handle", 'a' , 0, G_OPTION_ARG_INT, &main_opts.handle,
 		"Read/Write characteristic by handle(required)", "0x0001" },
-	{ "value", 'n' , 0, G_OPTION_ARG_STRING, &opt_value,
+	{ "value", 'n' , 0, G_OPTION_ARG_STRING, &main_opts.value,
 		"Write characteristic value (required for write operation)",
 		"0x0001" },
 	{NULL},
 };
 
 static GOptionEntry gatt_options[] = {
-	{ "primary", 0, 0, G_OPTION_ARG_NONE, &opt_primary,
+	{ "primary", 0, 0, G_OPTION_ARG_NONE, &main_opts.primary,
 		"Primary Service Discovery", NULL },
-	{ "characteristics", 0, 0, G_OPTION_ARG_NONE, &opt_characteristics,
+	{ "characteristics", 0, 0, G_OPTION_ARG_NONE, &main_opts.char_disc,
 		"Characteristics Discovery", NULL },
-	{ "char-read", 0, 0, G_OPTION_ARG_NONE, &opt_char_read,
+	{ "char-read", 0, 0, G_OPTION_ARG_NONE, &main_opts.char_read,
 		"Characteristics Value/Descriptor Read", NULL },
-	{ "char-write", 0, 0, G_OPTION_ARG_NONE, &opt_char_write,
+	{ "char-write", 0, 0, G_OPTION_ARG_NONE, &main_opts.char_write,
 		"Characteristics Value Write", NULL },
-	{ "char-desc", 0, 0, G_OPTION_ARG_NONE, &opt_char_desc,
+	{ "char-desc", 0, 0, G_OPTION_ARG_NONE, &main_opts.char_desc,
 		"Characteristics Descriptor Discovery", NULL },
-	{ "listen", 0, 0, G_OPTION_ARG_NONE, &opt_listen,
+	{ "listen", 0, 0, G_OPTION_ARG_NONE, &main_opts.listen,
 		"Listen for notifications and indications", NULL },
-	{ "le", 0, 0, G_OPTION_ARG_NONE, &opt_le,
+	{ "le", 0, 0, G_OPTION_ARG_NONE, &main_opts.le,
 		"Use Bluetooth Low Energy transport", NULL },
 	{ NULL },
 };
 
 static GOptionEntry options[] = {
-	{ "adapter", 'i', 0, G_OPTION_ARG_STRING, &opt_src,
+	{ "adapter", 'i', 0, G_OPTION_ARG_STRING, &main_opts.src,
 		"Specify local adapter interface", "hciX" },
-	{ "device", 'b', 0, G_OPTION_ARG_STRING, &opt_dst,
+	{ "device", 'b', 0, G_OPTION_ARG_STRING, &main_opts.dst,
 		"Specify remote Bluetooth address", "MAC" },
-	{ "mtu", 'm', 0, G_OPTION_ARG_INT, &opt_mtu,
+	{ "mtu", 'm', 0, G_OPTION_ARG_INT, &main_opts.mtu,
 		"Specify the MTU size", "MTU" },
-	{ "psm", 'p', 0, G_OPTION_ARG_INT, &opt_psm,
+	{ "psm", 'p', 0, G_OPTION_ARG_INT, &main_opts.psm,
 		"Specify the PSM for GATT/ATT over BR/EDR", "PSM" },
-	{ "sec-level", 'l', 0, G_OPTION_ARG_STRING, &opt_sec_level,
+	{ "sec-level", 'l', 0, G_OPTION_ARG_STRING, &main_opts.sec_level,
 		"Set security level. Default: low", "[low | medium | high]"},
 	{ NULL },
 };
@@ -563,6 +591,8 @@ int main(int argc, char *argv[])
 	GIOChannel *chan;
 	GSourceFunc callback;
 
+	options_init();
+
 	context = g_option_context_new(NULL);
 	g_option_context_add_main_entries(context, options, NULL);
 
@@ -594,15 +624,15 @@ int main(int argc, char *argv[])
 		g_error_free(gerr);
 	}
 
-	if (opt_primary)
+	if (main_opts.primary)
 		callback = primary;
-	else if (opt_characteristics)
+	else if (main_opts.char_disc)
 		callback = characteristics;
-	else if (opt_char_read)
+	else if (main_opts.char_read)
 		callback = characteristics_read;
-	else if (opt_char_write)
+	else if (main_opts.char_write)
 		callback = characteristics_write;
-	else if (opt_char_desc)
+	else if (main_opts.char_desc)
 		callback = characteristics_desc;
 	else {
 		gchar *help = g_option_context_get_help(context, TRUE, NULL);
@@ -612,7 +642,7 @@ int main(int argc, char *argv[])
 		goto done;
 	}
 
-	chan = do_connect(opt_le);
+	chan = do_connect(main_opts.le);
 	if (chan == NULL) {
 		got_error = TRUE;
 		goto done;
@@ -622,7 +652,7 @@ int main(int argc, char *argv[])
 
 	event_loop = g_main_loop_new(NULL, FALSE);
 
-	if (opt_listen)
+	if (main_opts.listen)
 		g_idle_add(listen_start, attrib);
 
 	g_idle_add(callback, attrib);
@@ -638,9 +668,9 @@ int main(int argc, char *argv[])
 
 done:
 	g_option_context_free(context);
-	g_free(opt_src);
-	g_free(opt_dst);
-	g_free(opt_uuid);
+	g_free(main_opts.src);
+	g_free(main_opts.dst);
+	g_free(main_opts.uuid);
 
 	if (got_error)
 		exit(EXIT_FAILURE);
-- 
1.7.1


^ permalink raw reply related

* [PATCH v2 2/5] Include check to readline lib on acinlude.m4
From: Sheldon Demario @ 2011-02-11 14:17 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario
In-Reply-To: <20110209212642.GA11368@jh-x301>

---
 acinclude.m4 |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/acinclude.m4 b/acinclude.m4
index 9d3f6b2..91e0956 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -153,6 +153,15 @@ AC_DEFUN([AC_PATH_SNDFILE], [
 	AC_SUBST(SNDFILE_LIBS)
 ])
 
+AC_DEFUN([AC_PATH_READLINE], [
+	AC_CHECK_HEADER(readline/readline.h,
+		AC_CHECK_LIB(readline, main,
+			[ readline_found=yes
+			AC_SUBST(READLINE_LIBS, "-lreadline")
+			], readline_found=no),
+		[])
+])
+
 AC_DEFUN([AC_PATH_OUI], [
 	AC_ARG_WITH(ouifile,
 		    AS_HELP_STRING([--with-ouifile=PATH],[Path to the oui.txt file @<:@auto@:>@]),
@@ -356,6 +365,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 	AM_CONDITIONAL(HEALTHPLUGIN, test "${health_enable}" = "yes")
 	AM_CONDITIONAL(MCAP, test "${health_enable}" = "yes")
 	AM_CONDITIONAL(HAL, test "${hal_enable}" = "yes")
+	AM_CONDITIONAL(READLINE, test "${readline_found}" = "yes")
 	AM_CONDITIONAL(ATTRIBPLUGIN, test "${attrib_enable}" = "yes")
 	AM_CONDITIONAL(ECHOPLUGIN, test "no" = "yes")
 	AM_CONDITIONAL(PNATPLUGIN, test "${pnat_enable}" = "yes")
-- 
1.7.1


^ permalink raw reply related

* [PATCH v2 3/5] Add an initial interactive mode to gatttool
From: Sheldon Demario @ 2011-02-11 14:17 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario
In-Reply-To: <20110209212642.GA11368@jh-x301>

Mode required to allow better GATT procedures control. Some scenarios
require sequential commands without disconnection and delay between
operations. It is also desirable to change some connection parameters
of an active connection.
---
 Makefile.am          |    8 ++-
 attrib/gatttool.c    |    9 ++++
 attrib/gatttool.h    |   24 +++++++++
 attrib/interactive.c |  128 ++++++++++++++++++++++++++++++++++++++++++++++++++
 configure.ac         |    1 +
 5 files changed, 168 insertions(+), 2 deletions(-)
 create mode 100644 attrib/gatttool.h
 create mode 100644 attrib/interactive.c

diff --git a/Makefile.am b/Makefile.am
index e6639a7..11f990b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -175,12 +175,16 @@ builtin_sources += plugins/service.c
 endif
 
 if ATTRIBPLUGIN
+
+if READLINE
 bin_PROGRAMS += attrib/gatttool
 
 attrib_gatttool_SOURCES = attrib/gatttool.c attrib/att.c attrib/gatt.c \
 			  attrib/gattrib.c btio/btio.c \
-			  src/glib-helper.h src/glib-helper.c
-attrib_gatttool_LDADD = lib/libbluetooth.la @GLIB_LIBS@
+			  src/glib-helper.h src/glib-helper.c \
+			  attrib/gatttool.h attrib/interactive.c
+attrib_gatttool_LDADD = lib/libbluetooth.la @GLIB_LIBS@ @READLINE_LIBS@
+endif
 
 builtin_modules += attrib
 builtin_sources += attrib/main.c \
diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index c612309..cd6e68a 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -42,6 +42,7 @@
 #include "gattrib.h"
 #include "glib-helper.h"
 #include "gatt.h"
+#include "gatttool.h"
 
 /* Minimum MTU for L2CAP connections over BR/EDR */
 #define ATT_MIN_MTU_L2CAP 48
@@ -67,6 +68,7 @@ static struct main_opts {
 	gboolean char_desc;
 	gboolean le;
 	gboolean char_write;
+	gboolean interactive;
 } main_opts;
 
 struct characteristic_data {
@@ -565,6 +567,8 @@ static GOptionEntry gatt_options[] = {
 		"Listen for notifications and indications", NULL },
 	{ "le", 0, 0, G_OPTION_ARG_NONE, &main_opts.le,
 		"Use Bluetooth Low Energy transport", NULL },
+	{ "interactive", 'I', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
+		&main_opts.interactive, "Use interactive mode", NULL },
 	{ NULL },
 };
 
@@ -624,6 +628,11 @@ int main(int argc, char *argv[])
 		g_error_free(gerr);
 	}
 
+	if (main_opts.interactive) {
+		interactive();
+		goto done;
+	}
+
 	if (main_opts.primary)
 		callback = primary;
 	else if (main_opts.char_disc)
diff --git a/attrib/gatttool.h b/attrib/gatttool.h
new file mode 100644
index 0000000..ed5d9d6
--- /dev/null
+++ b/attrib/gatttool.h
@@ -0,0 +1,24 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2011  Nokia Corporation
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+int interactive(void);
diff --git a/attrib/interactive.c b/attrib/interactive.c
new file mode 100644
index 0000000..0653609
--- /dev/null
+++ b/attrib/interactive.c
@@ -0,0 +1,128 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2011  Nokia Corporation
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+#include <strings.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <glib.h>
+
+#include <readline/readline.h>
+#include <readline/history.h>
+
+#include "gatttool.h"
+
+static GMainLoop *event_loop;
+
+static void cmd_help(int argcp, char **argvp);
+
+static void cmd_exit(int argcp, char **argvp)
+{
+	rl_callback_handler_remove();
+	g_main_loop_quit(event_loop);
+}
+
+static struct {
+	const char *cmd;
+	void (*func)(int argcp, char **argvp);
+	const char *desc;
+} commands[] = {
+	{ "help",	cmd_help,	"Show this help"},
+	{ "exit",	cmd_exit,	"Exit interactive mode"},
+	{ NULL, NULL, NULL}
+};
+
+static void cmd_help(int argcp, char **argvp)
+{
+	int i;
+
+	for (i = 0; commands[i].cmd; i++)
+		printf("%-12s\t%s\n", commands[i].cmd, commands[i].desc);
+}
+
+static void parse_line(char *line_read)
+{
+	gchar **argvp;
+	int argcp;
+	int i;
+
+	if (line_read == NULL) {
+		printf("\n");
+		cmd_exit(0, NULL);
+		return;
+	}
+
+	line_read = g_strstrip(line_read);
+
+	if (*line_read == '\0')
+		return;
+
+	add_history(line_read);
+
+	g_shell_parse_argv(line_read, &argcp, &argvp, NULL);
+
+	for (i = 0; commands[i].cmd; i++)
+		if (strcasecmp(commands[i].cmd, argvp[0]) == 0)
+			break;
+
+	if (commands[i].cmd)
+		commands[i].func(argcp, argvp);
+	else
+		printf("%s: command not found\n", argvp[0]);
+
+	g_strfreev(argvp);
+}
+
+static gboolean prompt_read(GIOChannel *chan, GIOCondition cond,
+							gpointer user_data)
+{
+	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
+		g_io_channel_unref(chan);
+		return FALSE;
+	}
+
+	rl_callback_read_char();
+
+	return TRUE;
+}
+
+int interactive(void)
+{
+	GIOChannel *pchan;
+	gint events;
+
+	event_loop = g_main_loop_new(NULL, FALSE);
+
+	pchan = g_io_channel_unix_new(fileno(stdin));
+	g_io_channel_set_close_on_unref(pchan, TRUE);
+	events = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
+	g_io_add_watch(pchan, events, prompt_read, NULL);
+
+	rl_callback_handler_install("> ", parse_line);
+
+	g_main_loop_run(event_loop);
+
+	rl_callback_handler_remove();
+	g_io_channel_unref(pchan);
+	g_main_loop_unref(event_loop);
+
+	return 0;
+}
diff --git a/configure.ac b/configure.ac
index bebdc9c..a8e8fc6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -42,6 +42,7 @@ AC_PATH_GSTREAMER
 AC_PATH_USB
 AC_PATH_SNDFILE
 AC_PATH_OUI
+AC_PATH_READLINE
 
 AC_ARG_BLUEZ
 
-- 
1.7.1


^ permalink raw reply related

* [PATCH v2 4/5] Move main_opts from gatttool.c to header file
From: Sheldon Demario @ 2011-02-11 14:17 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario
In-Reply-To: <20110209212642.GA11368@jh-x301>

---
 attrib/gatttool.c    |   22 +---------------------
 attrib/gatttool.h    |   21 +++++++++++++++++++++
 attrib/interactive.c |    2 ++
 3 files changed, 24 insertions(+), 21 deletions(-)

diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index cd6e68a..badd3b0 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -49,27 +49,7 @@
 
 static GMainLoop *event_loop;
 static gboolean got_error = FALSE;
-
-static struct main_opts {
-	gchar *src;
-	gchar *dst;
-	gchar *value;
-	gchar *sec_level;
-	uuid_t *uuid;
-	int start;
-	int end;
-	int handle;
-	int mtu;
-	int psm;
-	gboolean primary;
-	gboolean char_disc;
-	gboolean char_read;
-	gboolean listen;
-	gboolean char_desc;
-	gboolean le;
-	gboolean char_write;
-	gboolean interactive;
-} main_opts;
+static struct main_opts main_opts;
 
 struct characteristic_data {
 	GAttrib *attrib;
diff --git a/attrib/gatttool.h b/attrib/gatttool.h
index ed5d9d6..3dbe88b 100644
--- a/attrib/gatttool.h
+++ b/attrib/gatttool.h
@@ -21,4 +21,25 @@
  *
  */
 
+struct main_opts {
+	gchar *src;
+	gchar *dst;
+	gchar *value;
+	gchar *sec_level;
+	uuid_t *uuid;
+	int start;
+	int end;
+	int handle;
+	int mtu;
+	int psm;
+	gboolean primary;
+	gboolean char_disc;
+	gboolean char_read;
+	gboolean listen;
+	gboolean char_desc;
+	gboolean le;
+	gboolean char_write;
+	gboolean interactive;
+};
+
 int interactive(void);
diff --git a/attrib/interactive.c b/attrib/interactive.c
index 0653609..425a9b2 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -25,6 +25,8 @@
 #include <stdio.h>
 #include <glib.h>
 
+#include <bluetooth/sdp.h>
+
 #include <readline/readline.h>
 #include <readline/history.h>
 
-- 
1.7.1


^ permalink raw reply related

* [PATCH v2 5/5] Add connect/disconnect options on interactive mode of gatttool
From: Sheldon Demario @ 2011-02-11 14:17 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario
In-Reply-To: <20110209212642.GA11368@jh-x301>

---
 attrib/gatttool.c    |    6 +-
 attrib/gatttool.h    |    3 +-
 attrib/interactive.c |  105 +++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 108 insertions(+), 6 deletions(-)

diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index badd3b0..1b89d9f 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -87,7 +87,7 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
 	}
 }
 
-static GIOChannel *do_connect(gboolean le)
+GIOChannel *do_connect(gboolean le, BtIOConnect connect_cb)
 {
 	GIOChannel *chan;
 	bdaddr_t sba, dba;
@@ -609,7 +609,7 @@ int main(int argc, char *argv[])
 	}
 
 	if (main_opts.interactive) {
-		interactive();
+		interactive(&main_opts);
 		goto done;
 	}
 
@@ -631,7 +631,7 @@ int main(int argc, char *argv[])
 		goto done;
 	}
 
-	chan = do_connect(main_opts.le);
+	chan = do_connect(main_opts.le, connect_cb);
 	if (chan == NULL) {
 		got_error = TRUE;
 		goto done;
diff --git a/attrib/gatttool.h b/attrib/gatttool.h
index 3dbe88b..c80026c 100644
--- a/attrib/gatttool.h
+++ b/attrib/gatttool.h
@@ -42,4 +42,5 @@ struct main_opts {
 	gboolean interactive;
 };
 
-int interactive(void);
+int interactive(struct main_opts *config);
+GIOChannel *do_connect(gboolean le, BtIOConnect connect_cb);
diff --git a/attrib/interactive.c b/attrib/interactive.c
index 425a9b2..5fb6f8e 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -30,18 +30,111 @@
 #include <readline/readline.h>
 #include <readline/history.h>
 
+#include "btio.h"
+#include "gattrib.h"
 #include "gatttool.h"
 
+static GIOChannel *iochannel = NULL;
+static GAttrib *attrib = NULL;
 static GMainLoop *event_loop;
+static GString *prompt;
+static struct main_opts *main_opts;
 
 static void cmd_help(int argcp, char **argvp);
 
+enum state {
+	STATE_DISCONNECTED,
+	STATE_CONNECTING,
+	STATE_CONNECTED
+} conn_state;
+
+static char *get_prompt(void)
+{
+	if (conn_state == STATE_CONNECTING) {
+		g_string_assign(prompt, "Connecting... ");
+		return prompt->str;
+	}
+
+	if (conn_state == STATE_CONNECTED)
+		g_string_assign(prompt, "[CON]");
+	else
+		g_string_assign(prompt, "[   ]");
+
+	if (main_opts->dst)
+		g_string_append_printf(prompt, "[%17s]", main_opts->dst);
+	else
+		g_string_append_printf(prompt, "[%17s]", "");
+
+	if (main_opts->le)
+		g_string_append(prompt, "[LE]");
+	else
+		g_string_append(prompt, "[BR]");
+
+	g_string_append(prompt, "> ");
+
+	return prompt->str;
+}
+
+
+static void set_state(enum state st)
+{
+	conn_state = st;
+	rl_set_prompt(get_prompt());
+	rl_redisplay();
+}
+
+static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
+{
+	if (err) {
+		printf("connect error: %s\n", err->message);
+		return;
+	}
+
+	attrib = g_attrib_new(iochannel);
+	set_state(STATE_CONNECTED);
+}
+
 static void cmd_exit(int argcp, char **argvp)
 {
 	rl_callback_handler_remove();
 	g_main_loop_quit(event_loop);
 }
 
+static void cmd_connect(int argcp, char **argvp)
+{
+	if (conn_state != STATE_DISCONNECTED)
+		return;
+
+	if (main_opts->dst == NULL) {
+		printf("Remote Bluetooth address required\n");
+		return;
+	}
+
+	set_state(STATE_CONNECTING);
+	iochannel = do_connect(main_opts->le, connect_cb);
+	if (iochannel == NULL)
+		set_state(STATE_DISCONNECTED);
+
+	return;
+}
+
+static void cmd_disconnect(int argcp, char **argvp)
+{
+	if (conn_state == STATE_DISCONNECTED)
+		return;
+
+	g_attrib_unref(attrib);
+	attrib = NULL;
+
+	g_io_channel_shutdown(iochannel, FALSE, NULL);
+	g_io_channel_unref(iochannel);
+	iochannel = NULL;
+
+	set_state(STATE_DISCONNECTED);
+
+	return;
+}
+
 static struct {
 	const char *cmd;
 	void (*func)(int argcp, char **argvp);
@@ -49,6 +142,8 @@ static struct {
 } commands[] = {
 	{ "help",	cmd_help,	"Show this help"},
 	{ "exit",	cmd_exit,	"Exit interactive mode"},
+	{ "connect",	cmd_connect,	"Connect to a remote device"},
+	{ "disconnect",	cmd_disconnect,	"Disconnect from a remote device"},
 	{ NULL, NULL, NULL}
 };
 
@@ -106,11 +201,15 @@ static gboolean prompt_read(GIOChannel *chan, GIOCondition cond,
 	return TRUE;
 }
 
-int interactive(void)
+int interactive(struct main_opts *config)
 {
 	GIOChannel *pchan;
 	gint events;
 
+	main_opts = config;
+
+	prompt = g_string_new(NULL);
+
 	event_loop = g_main_loop_new(NULL, FALSE);
 
 	pchan = g_io_channel_unix_new(fileno(stdin));
@@ -118,13 +217,15 @@ int interactive(void)
 	events = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
 	g_io_add_watch(pchan, events, prompt_read, NULL);
 
-	rl_callback_handler_install("> ", parse_line);
+	rl_callback_handler_install(get_prompt(), parse_line);
 
 	g_main_loop_run(event_loop);
 
 	rl_callback_handler_remove();
+	cmd_disconnect(0, NULL);
 	g_io_channel_unref(pchan);
 	g_main_loop_unref(event_loop);
+	g_string_free(prompt, TRUE);
 
 	return 0;
 }
-- 
1.7.1


^ permalink raw reply related

* Re: [PATCH v2] Bluetooth: Add firmware support for Atheros 3012
From: Gustavo F. Padovan @ 2011-02-11 17:22 UTC (permalink / raw)
  To: Bala Shanmugam; +Cc: linux-bluetooth
In-Reply-To: <1297418933-15467-1-git-send-email-sbalashanmugam@atheros.com>

Hi Bala,

* Bala Shanmugam <sbalashanmugam@atheros.com> [2011-02-11 15:38:53 +0530]:

> Blacklisted AR3012 PID in btusb and added the same
> in ath3k to load patch and sysconfig files.
> 
> Signed-off-by: Bala Shanmugam <sbalashanmugam@atheros.com>
> ---
>  drivers/bluetooth/ath3k.c |  279 +++++++++++++++++++++++++++++++++++++++++++++
>  drivers/bluetooth/btusb.c |    3 +
>  2 files changed, 282 insertions(+), 0 deletions(-)

Patch has been applied. Thanks.

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* [PATCHv2] Bluetooth: hcitool: add option for LE_Scan_Type parameter
From: Emeltchenko Andrei @ 2011-02-11 17:23 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>

The LE_Scan_Type parameter controls the type of scan to perform.
---
 tools/hcitool.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/tools/hcitool.c b/tools/hcitool.c
index c097526..7ed7f98 100644
--- a/tools/hcitool.c
+++ b/tools/hcitool.c
@@ -2350,23 +2350,29 @@ done:
 static struct option lescan_options[] = {
 	{ "help",	0, 0, 'h' },
 	{ "privacy",	0, 0, 'p' },
+	{ "passive",	0, 0, 'P' },
 	{ 0, 0, 0, 0 }
 };
 
 static const char *lescan_help =
 	"Usage:\n"
-	"\tlescan [--privacy] enable privacy\n";
+	"\tlescan [--privacy] enable privacy\n"
+	"\tlescan [--passive] set scan type passive (default active)\n";
 
 static void cmd_lescan(int dev_id, int argc, char **argv)
 {
 	int err, opt, dd;
 	uint8_t own_type = 0x00;
+	uint8_t scan_type = 0x01;
 
 	for_each_opt(opt, lescan_options, NULL) {
 		switch (opt) {
 		case 'p':
 			own_type = 0x01; /* Random */
 			break;
+		case 'P':
+			scan_type = 0x00; /* Passive */
+			break;
 		default:
 			printf("%s", lescan_help);
 			return;
@@ -2383,7 +2389,7 @@ static void cmd_lescan(int dev_id, int argc, char **argv)
 		exit(1);
 	}
 
-	err = hci_le_set_scan_parameters(dd, 0x01, htobs(0x0010),
+	err = hci_le_set_scan_parameters(dd, scan_type, htobs(0x0010),
 					htobs(0x0010), own_type, 0x00);
 	if (err < 0) {
 		perror("Set scan parameters failed");
-- 
1.7.1


^ permalink raw reply related

* Re: [PATCH] btusb:fix crash with quirky dongles doing sound
From: Gustavo F. Padovan @ 2011-02-11 17:43 UTC (permalink / raw)
  To: Oliver Neukum
  Cc: Marcel Holtmann, linux-bluetooth, linux-usb, stable, ensonic
In-Reply-To: <201102111300.06470.oneukum@suse.de>

Hi Oliver,

* Oliver Neukum <oneukum@suse.de> [2011-02-11 13:00:06 +0100]:

> From befd2cd1a7875d395f72b38f2cb89a03f16edaba Mon Sep 17 00:00:00 2001
> From: Oliver Neukum <oliver@neukum.org>
> Date: Fri, 11 Feb 2011 12:35:05 +0100
> Subject: [PATCH] btusb:fix crash with quirky dongles doing sound
> 
> Quirky dongles sometimes do not use the iso interface which
> causes a crash with runtime PM
> 
> Signed-off-by: Oliver Neukum <oneukum@suse.de>
> ---
>  drivers/bluetooth/btusb.c |    4 ++--
>  1 files changed, 2 insertions(+), 2 deletions(-)

Applied. It should be in mainline soon. Thanks.

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* [PATCH 1/2] Fix wrong parameter order for memcpy in btoh128 function
From: Claudio Takahasi @ 2011-02-11 17:51 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

---
 lib/sdp.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/lib/sdp.c b/lib/sdp.c
index 8a31b55..d5b99d4 100644
--- a/lib/sdp.c
+++ b/lib/sdp.c
@@ -96,7 +96,7 @@ static inline void ntoh128(uint128_t *src, uint128_t *dst)
 
 static inline void btoh128(uint128_t *src, uint128_t *dst)
 {
-	memcpy(src, dst, sizeof(uint128_t));
+	memcpy(dst, src, sizeof(uint128_t));
 }
 
 #endif
-- 
1.7.4


^ permalink raw reply related

* [PATCH 2/2] Add const modifier to avoid wrong usage of byte order functions
From: Claudio Takahasi @ 2011-02-11 17:51 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1297446699-17349-1-git-send-email-claudio.takahasi@openbossa.org>

---
 lib/sdp.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/lib/sdp.c b/lib/sdp.c
index d5b99d4..3e3a8f8 100644
--- a/lib/sdp.c
+++ b/lib/sdp.c
@@ -62,14 +62,14 @@
 
 #if __BYTE_ORDER == __BIG_ENDIAN
 #define ntoh64(x) (x)
-static inline void ntoh128(uint128_t *src, uint128_t *dst)
+static inline void ntoh128(const uint128_t *src, uint128_t *dst)
 {
 	int i;
 	for (i = 0; i < 16; i++)
 		dst->data[i] = src->data[i];
 }
 
-static inline void btoh128(uint128_t *src, uint128_t *dst)
+static inline void btoh128(const uint128_t *src, uint128_t *dst)
 {
 	int i;
 	for (i = 0; i < 16; i++)
@@ -87,14 +87,14 @@ static inline uint64_t ntoh64(uint64_t n)
 	return h;
 }
 
-static inline void ntoh128(uint128_t *src, uint128_t *dst)
+static inline void ntoh128(const uint128_t *src, uint128_t *dst)
 {
 	int i;
 	for (i = 0; i < 16; i++)
 		dst->data[15 - i] = src->data[i];
 }
 
-static inline void btoh128(uint128_t *src, uint128_t *dst)
+static inline void btoh128(const uint128_t *src, uint128_t *dst)
 {
 	memcpy(dst, src, sizeof(uint128_t));
 }
-- 
1.7.4


^ permalink raw reply related

* [PATCHv2] Bluetooth: hcitool: add bdaddr type option to lecc
From: Emeltchenko Andrei @ 2011-02-11 18:31 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>

---
 tools/hcitool.c |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/tools/hcitool.c b/tools/hcitool.c
index 6883b28..d7a82cc 100644
--- a/tools/hcitool.c
+++ b/tools/hcitool.c
@@ -2421,12 +2421,13 @@ static void cmd_lescan(int dev_id, int argc, char **argv)
 
 static struct option lecc_options[] = {
 	{ "help",	0, 0, 'h' },
+	{ "random",	0, 0, 'r' },
 	{ 0, 0, 0, 0 }
 };
 
 static const char *lecc_help =
 	"Usage:\n"
-	"\tlecc <bdaddr>\n";
+	"\tlecc [--random] <bdaddr>\n";
 
 static void cmd_lecc(int dev_id, int argc, char **argv)
 {
@@ -2436,8 +2437,13 @@ static void cmd_lecc(int dev_id, int argc, char **argv)
 	uint16_t min_interval, supervision_timeout, window, handle;
 	uint8_t initiator_filter, own_bdaddr_type, peer_bdaddr_type;
 
+	peer_bdaddr_type = 0x00; /* Public device address */
+
 	for_each_opt(opt, lecc_options, NULL) {
 		switch (opt) {
+		case 'r':
+			peer_bdaddr_type = 0x01; /* Random */
+			break;
 		default:
 			printf("%s", lecc_help);
 			return;
@@ -2459,7 +2465,6 @@ static void cmd_lecc(int dev_id, int argc, char **argv)
 	interval = htobs(0x0004);
 	window = htobs(0x0004);
 	initiator_filter = 0x00;
-	peer_bdaddr_type = 0x00;
 	own_bdaddr_type = 0x00;
 	min_interval = htobs(0x000F);
 	max_interval = htobs(0x000F);
-- 
1.7.1


^ permalink raw reply related

* Re: [PATCH] hfp: gateway_suspend_stream should trigger a state change
From: Johan Hedberg @ 2011-02-11 19:49 UTC (permalink / raw)
  To: Daniel Wagner; +Cc: linux-bluetooth, Daniel Wagner
In-Reply-To: <1297334461-23077-1-git-send-email-wagi@monom.org>

Hi Daniel,

On Thu, Feb 10, 2011, Daniel Wagner wrote:
> When gateway_suspend_stream is called it should change the
> gateway state machine from PLAYING to CONNECTED.
> ---
>  audio/gateway.c |    1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)

Pushed upstream. Thanks.

Johan

^ permalink raw reply

* [RFC 0/7] Store UUID-128 on host order
From: Claudio Takahasi @ 2011-02-11 20:36 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

The following patches convert the internal UUID128 values representation
to host order. Currently, SDP functions use host order to store UUID-16
/UUID32 and network order to store UUID-128 values. The reason is not only
to keep the consistency, but re-use the UUID functions for ATT protocol
which uses little endian.

Claudio Takahasi (7):
  Move 64 and 128 bits byte order functions to bluetooth.h
  Use memcpy to convert from network to host order on BE hosts
  Use host byte order when converting UUID16/32 to UUID128
  Add att_get_u128
  Convert UUID128 value to host order when extracting SDP data
  Convert to network order before use it on sdp_uuid128_to_uuid
  Convert from host order to network order before to print UUID128

 attrib/att.c         |   12 ++++--
 attrib/att.h         |   10 +++++
 attrib/example.c     |    1 +
 attrib/gatt.c        |   14 ++++--
 attrib/gatttool.c    |    6 ++-
 health/hdp_manager.c |    1 +
 health/mcap_sync.c   |   17 --------
 lib/bluetooth.h      |   41 +++++++++++++++++++
 lib/sdp.c            |  107 +++++++++++++++++++-------------------------------
 lib/sdp.h            |    4 --
 src/glib-helper.c    |   14 ++++---
 src/sdp-xml.c        |    1 +
 test/hciemu.c        |   16 -------
 tools/sdptool.c      |   16 ++++---
 14 files changed, 132 insertions(+), 128 deletions(-)

-- 
1.7.4


^ permalink raw reply

* [RFC 1/7] Move 64 and 128 bits byte order functions to bluetooth.h
From: Claudio Takahasi @ 2011-02-11 20:37 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1297456626-22837-1-git-send-email-claudio.takahasi@openbossa.org>

---
 attrib/example.c     |    1 +
 attrib/gatt.c        |    1 +
 health/hdp_manager.c |    1 +
 health/mcap_sync.c   |   17 -----------------
 lib/bluetooth.h      |   43 +++++++++++++++++++++++++++++++++++++++++++
 lib/sdp.c            |   45 ---------------------------------------------
 lib/sdp.h            |    4 ----
 src/sdp-xml.c        |    1 +
 test/hciemu.c        |   16 ----------------
 9 files changed, 47 insertions(+), 82 deletions(-)

diff --git a/attrib/example.c b/attrib/example.c
index 1911912..f5fcf1b 100644
--- a/attrib/example.c
+++ b/attrib/example.c
@@ -29,6 +29,7 @@
 
 #include <arpa/inet.h>
 
+#include <bluetooth/bluetooth.h>
 #include <bluetooth/sdp.h>
 #include <bluetooth/sdp_lib.h>
 
diff --git a/attrib/gatt.c b/attrib/gatt.c
index 20bb96f..b99d39c 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
@@ -24,6 +24,7 @@
 
 #include <stdint.h>
 #include <glib.h>
+#include <bluetooth/bluetooth.h>
 #include <bluetooth/sdp.h>
 #include <bluetooth/sdp_lib.h>
 
diff --git a/health/hdp_manager.c b/health/hdp_manager.c
index 88b49fc..8ba1720 100644
--- a/health/hdp_manager.c
+++ b/health/hdp_manager.c
@@ -27,6 +27,7 @@
 #include <config.h>
 #endif
 
+#include <bluetooth/bluetooth.h>
 #include <bluetooth/sdp.h>
 #include <bluetooth/sdp_lib.h>
 
diff --git a/health/mcap_sync.c b/health/mcap_sync.c
index 6f90344..20311a2 100644
--- a/health/mcap_sync.c
+++ b/health/mcap_sync.c
@@ -92,23 +92,6 @@ struct sync_set_data {
 	gboolean role;
 };
 
-/* Ripped from lib/sdp.c */
-
-#if __BYTE_ORDER == __BIG_ENDIAN
-#define ntoh64(x) (x)
-#else
-static inline uint64_t ntoh64(uint64_t n)
-{
-        uint64_t h;
-        uint64_t tmp = ntohl(n & 0x00000000ffffffff);
-        h = ntohl(n >> 32);
-        h |= tmp << 32;
-        return h;
-}
-#endif
-
-#define hton64(x)     ntoh64(x)
-
 static gboolean csp_caps_initialized = FALSE;
 struct csp_caps _caps;
 
diff --git a/lib/bluetooth.h b/lib/bluetooth.h
index bc0921e..bc020ad 100644
--- a/lib/bluetooth.h
+++ b/lib/bluetooth.h
@@ -35,6 +35,7 @@ extern "C" {
 #include <string.h>
 #include <endian.h>
 #include <byteswap.h>
+#include <arpa/inet.h>
 
 #ifndef AF_BLUETOOTH
 #define AF_BLUETOOTH	31
@@ -88,21 +89,63 @@ enum {
 	BT_CLOSED
 };
 
+typedef struct {
+	uint8_t data[16];
+} uint128_t;
+
 /* Byte order conversions */
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 #define htobs(d)  (d)
 #define htobl(d)  (d)
 #define btohs(d)  (d)
 #define btohl(d)  (d)
+static inline uint64_t ntoh64(uint64_t n)
+{
+	uint64_t h;
+	uint64_t tmp = ntohl(n & 0x00000000ffffffff);
+	h = ntohl(n >> 32);
+	h |= tmp << 32;
+	return h;
+}
+
+static inline void ntoh128(const uint128_t *src, uint128_t *dst)
+{
+	int i;
+	for (i = 0; i < 16; i++)
+		dst->data[15 - i] = src->data[i];
+}
+
+static inline void btoh128(const uint128_t *src, uint128_t *dst)
+{
+	memcpy(dst, src, sizeof(uint128_t));
+}
 #elif __BYTE_ORDER == __BIG_ENDIAN
 #define htobs(d)  bswap_16(d)
 #define htobl(d)  bswap_32(d)
 #define btohs(d)  bswap_16(d)
 #define btohl(d)  bswap_32(d)
+#define ntoh64(x) (x)
+static inline void ntoh128(const uint128_t *src, uint128_t *dst)
+{
+	int i;
+	for (i = 0; i < 16; i++)
+		dst->data[i] = src->data[i];
+}
+
+static inline void btoh128(const uint128_t *src, uint128_t *dst)
+{
+	int i;
+	for (i = 0; i < 16; i++)
+		dst->data[15 - i] = src->data[i];
+}
 #else
 #error "Unknown byte order"
 #endif
 
+#define hton64(x)     ntoh64(x)
+#define hton128(x, y) ntoh128(x, y)
+#define htob128(x, y) btoh128(x, y)
+
 /* Bluetooth unaligned access */
 #define bt_get_unaligned(ptr)			\
 ({						\
diff --git a/lib/sdp.c b/lib/sdp.c
index 3e3a8f8..d24d1e2 100644
--- a/lib/sdp.c
+++ b/lib/sdp.c
@@ -60,51 +60,6 @@
 #define SDPDBG(fmt...)
 #endif
 
-#if __BYTE_ORDER == __BIG_ENDIAN
-#define ntoh64(x) (x)
-static inline void ntoh128(const uint128_t *src, uint128_t *dst)
-{
-	int i;
-	for (i = 0; i < 16; i++)
-		dst->data[i] = src->data[i];
-}
-
-static inline void btoh128(const uint128_t *src, uint128_t *dst)
-{
-	int i;
-	for (i = 0; i < 16; i++)
-		dst->data[15 - i] = src->data[i];
-
-}
-
-#else
-static inline uint64_t ntoh64(uint64_t n)
-{
-	uint64_t h;
-	uint64_t tmp = ntohl(n & 0x00000000ffffffff);
-	h = ntohl(n >> 32);
-	h |= tmp << 32;
-	return h;
-}
-
-static inline void ntoh128(const uint128_t *src, uint128_t *dst)
-{
-	int i;
-	for (i = 0; i < 16; i++)
-		dst->data[15 - i] = src->data[i];
-}
-
-static inline void btoh128(const uint128_t *src, uint128_t *dst)
-{
-	memcpy(dst, src, sizeof(uint128_t));
-}
-
-#endif
-
-#define hton64(x)     ntoh64(x)
-#define hton128(x, y) ntoh128(x, y)
-#define htob128(x, y) btoh128(x, y)
-
 #define BASE_UUID "00000000-0000-1000-8000-00805F9B34FB"
 
 static uint128_t bluetooth_base_uuid = {
diff --git a/lib/sdp.h b/lib/sdp.h
index 16b59fc..a8d560e 100644
--- a/lib/sdp.h
+++ b/lib/sdp.h
@@ -421,10 +421,6 @@ typedef struct {
  * Should the type of any of these change, you need only make a change here.
  */
 typedef struct {
-	uint8_t data[16];
-} uint128_t;
-
-typedef struct {
 	uint8_t type;
 	union {
 		uint16_t  uuid16;
diff --git a/src/sdp-xml.c b/src/sdp-xml.c
index 3aa9df0..48a3808 100644
--- a/src/sdp-xml.c
+++ b/src/sdp-xml.c
@@ -33,6 +33,7 @@
 #include <limits.h>
 #include <stdlib.h>
 
+#include <bluetooth/bluetooth.h>
 #include <bluetooth/sdp.h>
 #include <bluetooth/sdp_lib.h>
 
diff --git a/test/hciemu.c b/test/hciemu.c
index ba9b89d..1847ff0 100644
--- a/test/hciemu.c
+++ b/test/hciemu.c
@@ -52,22 +52,6 @@
 
 #include <glib.h>
 
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-static inline uint64_t ntoh64(uint64_t n)
-{
-	uint64_t h;
-	uint64_t tmp = ntohl(n & 0x00000000ffffffff);
-	h = ntohl(n >> 32);
-	h |= tmp << 32;
-	return h;
-}
-#elif __BYTE_ORDER == __BIG_ENDIAN
-#define ntoh64(x) (x)
-#else
-#error "Unknown byte order"
-#endif
-#define hton64(x) ntoh64(x)
-
 #define GHCI_DEV		"/dev/ghci"
 
 #define VHCI_DEV		"/dev/vhci"
-- 
1.7.4


^ permalink raw reply related

* [RFC 2/7] Use memcpy to convert from network to host order on BE hosts
From: Claudio Takahasi @ 2011-02-11 20:37 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1297456626-22837-1-git-send-email-claudio.takahasi@openbossa.org>

---
 lib/bluetooth.h |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/lib/bluetooth.h b/lib/bluetooth.h
index bc020ad..d8f36f8 100644
--- a/lib/bluetooth.h
+++ b/lib/bluetooth.h
@@ -127,9 +127,7 @@ static inline void btoh128(const uint128_t *src, uint128_t *dst)
 #define ntoh64(x) (x)
 static inline void ntoh128(const uint128_t *src, uint128_t *dst)
 {
-	int i;
-	for (i = 0; i < 16; i++)
-		dst->data[i] = src->data[i];
+	memcpy(dst, src, sizeof(uint128_t));
 }
 
 static inline void btoh128(const uint128_t *src, uint128_t *dst)
-- 
1.7.4


^ permalink raw reply related

* [RFC 3/7] Use host byte order when converting UUID16/32 to UUID128
From: Claudio Takahasi @ 2011-02-11 20:37 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1297456626-22837-1-git-send-email-claudio.takahasi@openbossa.org>

uuid_t should store the UUID-128 values in the host byte order to
keep the consistency with UUID-16 and UUID32.
---
 lib/sdp.c |   20 ++++++++++++++------
 1 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/lib/sdp.c b/lib/sdp.c
index d24d1e2..af50a16 100644
--- a/lib/sdp.c
+++ b/lib/sdp.c
@@ -2629,6 +2629,8 @@ int sdp_uuid128_cmp(const void *p1, const void *p2)
  */
 void sdp_uuid16_to_uuid128(uuid_t *uuid128, const uuid_t *uuid16)
 {
+	uint128_t n128;
+
 	/*
 	 * We have a 16 bit value, which needs to be added to
 	 * bytes 3 and 4 (at indices 2 and 3) of the Bluetooth base
@@ -2636,8 +2638,7 @@ void sdp_uuid16_to_uuid128(uuid_t *uuid128, const uuid_t *uuid16)
 	unsigned short data1;
 
 	/* allocate a 128bit UUID and init to the Bluetooth base UUID */
-	uuid128->value.uuid128 = bluetooth_base_uuid;
-	uuid128->type = SDP_UUID128;
+	n128 = bluetooth_base_uuid;
 
 	/* extract bytes 2 and 3 of 128bit BT base UUID */
 	memcpy(&data1, &bluetooth_base_uuid.data[2], 2);
@@ -2646,11 +2647,16 @@ void sdp_uuid16_to_uuid128(uuid_t *uuid128, const uuid_t *uuid16)
 	data1 += htons(uuid16->value.uuid16);
 
 	/* set bytes 2 and 3 of the 128 bit value */
-	memcpy(&uuid128->value.uuid128.data[2], &data1, 2);
+	memcpy(&n128.data[2], &data1, 2);
+
+	uuid128->type = SDP_UUID128;
+	ntoh128(&n128, &uuid128->value.uuid128);
 }
 
 void sdp_uuid32_to_uuid128(uuid_t *uuid128, const uuid_t *uuid32)
 {
+	uint128_t n128;
+
 	/*
 	 * We have a 32 bit value, which needs to be added to
 	 * bytes 1->4 (at indices 0 thru 3) of the Bluetooth base
@@ -2658,8 +2664,7 @@ void sdp_uuid32_to_uuid128(uuid_t *uuid128, const uuid_t *uuid32)
 	unsigned int data0;
 
 	/* allocate a 128bit UUID and init to the Bluetooth base UUID */
-	uuid128->value.uuid128 = bluetooth_base_uuid;
-	uuid128->type = SDP_UUID128;
+	n128 = bluetooth_base_uuid;
 
 	/* extract first 4 bytes */
 	memcpy(&data0, &bluetooth_base_uuid.data[0], 4);
@@ -2668,7 +2673,10 @@ void sdp_uuid32_to_uuid128(uuid_t *uuid128, const uuid_t *uuid32)
 	data0 += htonl(uuid32->value.uuid32);
 
 	/* set the 4 bytes of the 128 bit value */
-	memcpy(&uuid128->value.uuid128.data[0], &data0, 4);
+	memcpy(&n128.data[0], &data0, 4);
+
+	uuid128->type = SDP_UUID128;
+	ntoh128(&n128, &uuid128->value.uuid128);
 }
 
 uuid_t *sdp_uuid_to_uuid128(const uuid_t *uuid)
-- 
1.7.4


^ permalink raw reply related

* [RFC 4/7] Add att_get_u128
From: Claudio Takahasi @ 2011-02-11 20:37 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1297456626-22837-1-git-send-email-claudio.takahasi@openbossa.org>

Function to convert 128-bits values from little endian to host
order. Different than SDP, ATT uses little endian format.
---
 attrib/att.c      |   12 ++++++++----
 attrib/att.h      |   10 ++++++++++
 attrib/gatt.c     |   13 ++++++++-----
 attrib/gatttool.c |    6 ++++--
 4 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/attrib/att.c b/attrib/att.c
index dff8597..5b851a2 100644
--- a/attrib/att.c
+++ b/attrib/att.c
@@ -141,8 +141,10 @@ uint16_t dec_read_by_grp_req(const uint8_t *pdu, int len, uint16_t *start,
 	*end = att_get_u16(&pdu[3]);
 	if (len == min_len + 2)
 		sdp_uuid16_create(uuid, att_get_u16(&pdu[5]));
-	else
-		sdp_uuid128_create(uuid, &pdu[5]);
+	else {
+		uint128_t h128 = att_get_u128(&pdu[5]);
+		sdp_uuid128_create(uuid, &h128);
+	}
 
 	return len;
 }
@@ -370,8 +372,10 @@ uint16_t dec_read_by_type_req(const uint8_t *pdu, int len, uint16_t *start,
 
 	if (len == min_len + 2)
 		sdp_uuid16_create(uuid, att_get_u16(&pdu[5]));
-	else
-		sdp_uuid128_create(uuid, &pdu[5]);
+	else {
+		uint128_t h128 = att_get_u128(&pdu[5]);
+		sdp_uuid128_create(uuid, &h128);
+	}
 
 	return len;
 }
diff --git a/attrib/att.h b/attrib/att.h
index 7e81dc4..0cd6626 100644
--- a/attrib/att.h
+++ b/attrib/att.h
@@ -170,6 +170,16 @@ static inline uint32_t att_get_u32(const void *ptr)
 	return btohl(bt_get_unaligned(u32_ptr));
 }
 
+static inline uint128_t att_get_u128(const void *ptr)
+{
+	const uint128_t *u128_ptr = ptr;
+	uint128_t dst;
+
+	btoh128(u128_ptr, &dst);
+
+	return dst;
+}
+
 static inline void att_put_u8(uint8_t src, void *dst)
 {
 	bt_put_unaligned(src, (uint8_t *) dst);
diff --git a/attrib/gatt.c b/attrib/gatt.c
index b99d39c..3fedcc4 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
@@ -174,9 +174,10 @@ static void primary_all_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
 					att_get_u16(&data[4]));
 			sdp_uuid16_to_uuid128(&u128, &u16);
 
-		} else if (list->len == 20)
-			sdp_uuid128_create(&u128, &data[4]);
-		else
+		} else if (list->len == 20) {
+			uint128_t h128 = att_get_u128(&data[4]);
+			sdp_uuid128_create(&u128, &h128);
+		} else
 			/* Skipping invalid data */
 			continue;
 
@@ -271,8 +272,10 @@ static void char_discovered_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
 		if (list->len == 7) {
 			sdp_uuid16_create(&u16, att_get_u16(&value[5]));
 			sdp_uuid16_to_uuid128(&u128, &u16);
-		} else
-			sdp_uuid128_create(&u128, &value[5]);
+		} else {
+			uint128_t h128 = att_get_u128(&value[5]);
+			sdp_uuid128_create(&u128, &h128);
+		}
 
 		chars = g_try_new0(struct att_char, 1);
 		if (!chars) {
diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index 8e8ed8e..6c9394e 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -464,8 +464,10 @@ static void char_desc_cb(guint8 status, const guint8 *pdu, guint16 plen,
 
 		if (format == 0x01)
 			sdp_uuid16_create(&uuid, att_get_u16(&value[2]));
-		else
-			sdp_uuid128_create(&uuid, &value[2]);
+		else {
+			uint128_t h128 = att_get_u128(&value[2]);
+			sdp_uuid128_create(&uuid, &h128);
+		}
 
 		sdp_uuid2strn(&uuid, uuidstr, MAX_LEN_UUID_STR);
 		g_print("handle = 0x%04x, uuid = %s\n", handle, uuidstr);
-- 
1.7.4


^ permalink raw reply related

* [RFC 5/7] Convert UUID128 value to host order when extracting SDP data
From: Claudio Takahasi @ 2011-02-11 20:37 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1297456626-22837-1-git-send-email-claudio.takahasi@openbossa.org>

---
 lib/sdp.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/lib/sdp.c b/lib/sdp.c
index af50a16..d5f8984 100644
--- a/lib/sdp.c
+++ b/lib/sdp.c
@@ -1031,11 +1031,16 @@ int sdp_uuid_extract(const uint8_t *p, int bufsize, uuid_t *uuid, int *scanned)
 		*scanned += sizeof(uint32_t);
 		p += sizeof(uint32_t);
 	} else {
+		uint128_t n128, h128;
+
 		if (bufsize < (int) sizeof(uint128_t)) {
 			SDPERR("Not enough room for 128-bit UUID");
 			return -1;
 		}
-		sdp_uuid128_create(uuid, p);
+
+		memcpy(&n128, p, sizeof(uint128_t));
+		ntoh128(&n128, &h128);
+		sdp_uuid128_create(uuid, &h128);
 		*scanned += sizeof(uint128_t);
 		p += sizeof(uint128_t);
 	}
-- 
1.7.4


^ permalink raw reply related

* [RFC 6/7] Convert to network order before use it on sdp_uuid128_to_uuid
From: Claudio Takahasi @ 2011-02-11 20:37 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1297456626-22837-1-git-send-email-claudio.takahasi@openbossa.org>

---
 lib/sdp.c |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/lib/sdp.c b/lib/sdp.c
index d5f8984..3c4cd50 100644
--- a/lib/sdp.c
+++ b/lib/sdp.c
@@ -2713,18 +2713,19 @@ uuid_t *sdp_uuid_to_uuid128(const uuid_t *uuid)
 int sdp_uuid128_to_uuid(uuid_t *uuid)
 {
 	uint128_t *b = &bluetooth_base_uuid;
-	uint128_t *u = &uuid->value.uuid128;
+	uint128_t u;
 	uint32_t data;
 	unsigned int i;
 
+	hton128(&uuid->value.uuid128, &u);
 	if (uuid->type != SDP_UUID128)
 		return 1;
 
 	for (i = 4; i < sizeof(b->data); i++)
-		if (b->data[i] != u->data[i])
+		if (b->data[i] != u.data[i])
 			return 0;
 
-	memcpy(&data, u->data, 4);
+	memcpy(&data, u.data, 4);
 	data = htonl(data);
 	if (data <= 0xffff) {
 		uuid->type = SDP_UUID16;
-- 
1.7.4


^ permalink raw reply related

* [RFC 7/7] Convert from host order to network order before to print UUID128
From: Claudio Takahasi @ 2011-02-11 20:37 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1297456626-22837-1-git-send-email-claudio.takahasi@openbossa.org>

---
 lib/sdp.c         |   30 +++++++++++++++++-------------
 src/glib-helper.c |   14 ++++++++------
 tools/sdptool.c   |   16 +++++++++-------
 3 files changed, 34 insertions(+), 26 deletions(-)

diff --git a/lib/sdp.c b/lib/sdp.c
index 3c4cd50..75154e9 100644
--- a/lib/sdp.c
+++ b/lib/sdp.c
@@ -285,13 +285,15 @@ int sdp_uuid2strn(const uuid_t *uuid, char *str, size_t n)
 		unsigned short data3;
 		unsigned int   data4;
 		unsigned short data5;
+		uint128_t n128;
 
-		memcpy(&data0, &uuid->value.uuid128.data[0], 4);
-		memcpy(&data1, &uuid->value.uuid128.data[4], 2);
-		memcpy(&data2, &uuid->value.uuid128.data[6], 2);
-		memcpy(&data3, &uuid->value.uuid128.data[8], 2);
-		memcpy(&data4, &uuid->value.uuid128.data[10], 4);
-		memcpy(&data5, &uuid->value.uuid128.data[14], 2);
+		hton128(&uuid->value.uuid128, &n128);
+		memcpy(&data0, &n128.data[0], 4);
+		memcpy(&data1, &n128.data[4], 2);
+		memcpy(&data2, &n128.data[6], 2);
+		memcpy(&data3, &n128.data[8], 2);
+		memcpy(&data4, &n128.data[10], 4);
+		memcpy(&data5, &n128.data[14], 2);
 
 		snprintf(str, n, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
 				ntohl(data0), ntohs(data1),
@@ -333,13 +335,15 @@ void sdp_uuid_print(const uuid_t *uuid)
 		unsigned short data3;
 		unsigned int data4;
 		unsigned short data5;
-
-		memcpy(&data0, &uuid->value.uuid128.data[0], 4);
-		memcpy(&data1, &uuid->value.uuid128.data[4], 2);
-		memcpy(&data2, &uuid->value.uuid128.data[6], 2);
-		memcpy(&data3, &uuid->value.uuid128.data[8], 2);
-		memcpy(&data4, &uuid->value.uuid128.data[10], 4);
-		memcpy(&data5, &uuid->value.uuid128.data[14], 2);
+		uint128_t n128;
+
+		hton128(&uuid->value.uuid128, &n128);
+		memcpy(&data0, &n128.data[0], 4);
+		memcpy(&data1, &n128.data[4], 2);
+		memcpy(&data2, &n128.data[6], 2);
+		memcpy(&data3, &n128.data[8], 2);
+		memcpy(&data4, &n128.data[10], 4);
+		memcpy(&data5, &n128.data[14], 2);
 
 		SDPDBG("  uint128_t : 0x%.8x-", ntohl(data0));
 		SDPDBG("%.4x-", ntohs(data1));
diff --git a/src/glib-helper.c b/src/glib-helper.c
index 22c14e7..2b7e1b3 100644
--- a/src/glib-helper.c
+++ b/src/glib-helper.c
@@ -372,6 +372,7 @@ char *bt_uuid2string(uuid_t *uuid)
 {
 	gchar *str;
 	uuid_t uuid128;
+	uint128_t n128;
 	unsigned int data0;
 	unsigned short data1;
 	unsigned short data2;
@@ -397,12 +398,13 @@ char *bt_uuid2string(uuid_t *uuid)
 		return NULL;
 	}
 
-	memcpy(&data0, &uuid128.value.uuid128.data[0], 4);
-	memcpy(&data1, &uuid128.value.uuid128.data[4], 2);
-	memcpy(&data2, &uuid128.value.uuid128.data[6], 2);
-	memcpy(&data3, &uuid128.value.uuid128.data[8], 2);
-	memcpy(&data4, &uuid128.value.uuid128.data[10], 4);
-	memcpy(&data5, &uuid128.value.uuid128.data[14], 2);
+	hton128(&uuid128.value.uuid128, &n128);
+	memcpy(&data0, &n128.data[0], 4);
+	memcpy(&data1, &n128.data[4], 2);
+	memcpy(&data2, &n128.data[6], 2);
+	memcpy(&data3, &n128.data[8], 2);
+	memcpy(&data4, &n128.data[10], 4);
+	memcpy(&data5, &n128.data[14], 2);
 
 	str = g_try_malloc0(MAX_LEN_UUID_STR);
 	if (!str)
diff --git a/tools/sdptool.c b/tools/sdptool.c
index 140a46a..341e258 100644
--- a/tools/sdptool.c
+++ b/tools/sdptool.c
@@ -389,13 +389,15 @@ static void sdp_uuid_printf(uuid_t *uuid, struct attrib_context *context, int in
 			unsigned short data3;
 			unsigned int data4;
 			unsigned short data5;
-
-			memcpy(&data0, &uuid->value.uuid128.data[0], 4);
-			memcpy(&data1, &uuid->value.uuid128.data[4], 2);
-			memcpy(&data2, &uuid->value.uuid128.data[6], 2);
-			memcpy(&data3, &uuid->value.uuid128.data[8], 2);
-			memcpy(&data4, &uuid->value.uuid128.data[10], 4);
-			memcpy(&data5, &uuid->value.uuid128.data[14], 2);
+			uint128_t n128;
+
+			hton128(&uuid->value.uuid128, &n128);
+			memcpy(&data0, &n128.data[0], 4);
+			memcpy(&data1, &n128.data[4], 2);
+			memcpy(&data2, &n128.data[6], 2);
+			memcpy(&data3, &n128.data[8], 2);
+			memcpy(&data4, &n128.data[10], 4);
+			memcpy(&data5, &n128.data[14], 2);
 
 			printf("%.*sUUID128 : 0x%.8x-%.4x-%.4x-%.4x-%.8x-%.4x\n",
 				indent, indent_spaces,
-- 
1.7.4


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox