Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH] Fix crash when there is no enough space to fragment avdtp packet
From: Johan Hedberg @ 2010-08-19 11:08 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1282215669-24429-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Thu, Aug 19, 2010, Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
> 
> This was catch when running codenomicon tests when the output mtu is not
> big enough to stuff fragmented packets.
> ---
>  audio/avdtp.c |    6 ++++++
>  1 files changed, 6 insertions(+), 0 deletions(-)

Thanks. The patch has been pushed upstream.

Johan

^ permalink raw reply

* [PATCH] bluetooth: fix not setting security level when creating a rfcomm session
From: Luiz Augusto von Dentz @ 2010-08-19 11:06 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: ville.tervo

From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>

This cause 'No Bonding' to be used if userspace has not yet been paired
with remote device since the l2cap socket used to create the rfcomm
session does not have any security level set.

Signed-off-by: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
---
 net/bluetooth/rfcomm/core.c |   13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 7dca91b..08f5757 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -79,7 +79,10 @@ static void rfcomm_make_uih(struct sk_buff *skb, u8 addr);
 
 static void rfcomm_process_connect(struct rfcomm_session *s);
 
-static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err);
+static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
+							bdaddr_t *dst,
+							u8 sec_level,
+							int *err);
 static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst);
 static void rfcomm_session_del(struct rfcomm_session *s);
 
@@ -402,7 +405,7 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst,
 
 	s = rfcomm_session_get(src, dst);
 	if (!s) {
-		s = rfcomm_session_create(src, dst, &err);
+		s = rfcomm_session_create(src, dst, d->sec_level, &err);
 		if (!s)
 			return err;
 	}
@@ -680,7 +683,10 @@ static void rfcomm_session_close(struct rfcomm_session *s, int err)
 	rfcomm_session_put(s);
 }
 
-static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err)
+static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
+							bdaddr_t *dst,
+							u8 sec_level,
+							int *err)
 {
 	struct rfcomm_session *s = NULL;
 	struct sockaddr_l2 addr;
@@ -705,6 +711,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst
 	sk = sock->sk;
 	lock_sock(sk);
 	l2cap_pi(sk)->imtu = l2cap_mtu;
+	l2cap_pi(sk)->sec_level = sec_level;
 	if (l2cap_ertm)
 		l2cap_pi(sk)->mode = L2CAP_MODE_ERTM;
 	release_sock(sk);
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH] Fix crash when there is no enough space to fragment avdtp packet
From: Luiz Augusto von Dentz @ 2010-08-19 11:01 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>

This was catch when running codenomicon tests when the output mtu is not
big enough to stuff fragmented packets.
---
 audio/avdtp.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/audio/avdtp.c b/audio/avdtp.c
index cf07f6c..cc7066f 100644
--- a/audio/avdtp.c
+++ b/audio/avdtp.c
@@ -537,6 +537,12 @@ static gboolean avdtp_send(struct avdtp *session, uint8_t transaction,
 		return try_send(sock, session->buf, sizeof(single) + len);
 	}
 
+	/* Check if there is enough space to start packet */
+	if (session->omtu < sizeof(start)) {
+		error("No enough space to fragment packet");
+		return FALSE;
+	}
+
 	/* Count the number of needed fragments */
 	cont_fragments = (len - (session->omtu - sizeof(start))) /
 					(session->omtu - sizeof(cont)) + 1;
-- 
1.7.0.4


^ permalink raw reply related

* Re: [PATCH] IrMC sync server support
From: Luiz Augusto von Dentz @ 2010-08-19 10:53 UTC (permalink / raw)
  To: Marcel J.E. Mol; +Cc: Marcel Holtmann, linux-bluetooth
In-Reply-To: <20100817084850.GA16821@joshua.mesa.nl>

Hi Marcel,

On Tue, Aug 17, 2010 at 11:48 AM, Marcel J.E. Mol <marcel@mesa.nl> wrote:
> Ok, then 17 is just fine for IrMC then. I posted a 3th version at the end=
 of
> last week. Are there any new comments I have to take care of? Or can it =
=A0be
> considere for inclusion in the main tree now?
>
>
> On the other hand, if the channel 'varies' it might be better to let the
> plugin manager select a channel number for each service instead of alloca=
ting
> a fixed one in the specific plugin code.
>
> What did you found about channel 11 then? On my nokia 7710 channel 11 is =
used for
> "OBEX File Transfer" (serivce 0x1106).

We decided to use 14, also Johan pushed a complete list of bluez
assigned number to:

http://git.kernel.org/?p=3Dbluetooth/bluez.git;a=3Dcommitdiff;h=3Dfbeff4fd3=
03b43fa7f6c27e95fb6f023e80720a9;hp=3D0627552640140e1d986d36bb4770ccc4b3206b=
03

Could you please update your changes to use 14? Also there seems to be
some white spaces that doesn't follow our code styling, could you
please fix those?

--=20
Luiz Augusto von Dentz
Computer Engineer

^ permalink raw reply

* Re: its possible to make a streaming video whith bluez?
From: Johan Hedberg @ 2010-08-19  8:50 UTC (permalink / raw)
  To: Alexander Orlenko, Lorenzo Brito Morales, linux-bluetooth
In-Reply-To: <20100819083323.GA7327@jh-x301>

On Thu, Aug 19, 2010, Johan Hedberg wrote:
> On Thu, Aug 19, 2010, Alexander Orlenko wrote:
> > > Do you have plans to implement this for BlueZ?
> > It's a GSoC'10 project. http://hostisdown.org/gsoc/projects/vdp
> 
> Ha. Seems I've missed that one completely (though not really a surprise
> since there doesn't seem to have been any communication about it here on
> the mailing list).

I just just took a peek at the projects git tree. There's essentially
nothing there besides some very simple stub files. Also, there doesn't
seem to be anything AVDTP related in the tree but just raw data (video)
sending over an L2CAP connection. So if that's all that there is then
the statement "nothing exists for VDP in BlueZ right now" is actually
quite close to the truth.

Johan

^ permalink raw reply

* Re: BlueZ's A2DP sink role
From: Luiz Augusto von Dentz @ 2010-08-19  8:49 UTC (permalink / raw)
  To: Pavan Savoy; +Cc: linux-bluetooth
In-Reply-To: <AANLkTimXDqAej=LAVDvDgspKuH_SAKivp9eL8R9tXPJc@mail.gmail.com>

Hi Pavan,

On Wed, Aug 18, 2010 at 11:22 PM, Pavan Savoy <pavan_savoy@sify.com> wrote:
> As I understand, the A2DP sink role is @ audio/source.c and A2DP
> source role is at sink.c ? (or what is called as the interfaces?..)
> Also How do I test out a2dp sink role in BlueZ, any test audio-server
> I can run ?

You can use PA as explained in Joao Paulo's blog:

http://jprvita.wordpress.com/2009/12/15/1-2-3-4-a2dp-stream/


-- 
Luiz Augusto von Dentz
Computer Engineer

^ permalink raw reply

* Re: its possible to make a streaming video whith bluez?
From: Johan Hedberg @ 2010-08-19  8:33 UTC (permalink / raw)
  To: Alexander Orlenko; +Cc: Lorenzo Brito Morales, linux-bluetooth
In-Reply-To: <AANLkTindRBGJtWuE8OX+fAEAQOSQHzEgLdGdUUHfOKKT@mail.gmail.com>

On Thu, Aug 19, 2010, Alexander Orlenko wrote:
> > Do you have plans to implement this for BlueZ?
> It's a GSoC'10 project. http://hostisdown.org/gsoc/projects/vdp

Ha. Seems I've missed that one completely (though not really a surprise
since there doesn't seem to have been any communication about it here on
the mailing list).

Johan

^ permalink raw reply

* Re: its possible to make a streaming video whith bluez?
From: Alexander Orlenko @ 2010-08-19  8:25 UTC (permalink / raw)
  To: Lorenzo Brito Morales, linux-bluetooth
In-Reply-To: <20100819074920.GA5401@jh-x301>

> Do you have plans to implement this for BlueZ?
It's a GSoC'10 project. http://hostisdown.org/gsoc/projects/vdp

On 19 August 2010 18:49, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi,
>
> On Thu, Aug 19, 2010, Lorenzo Brito Morales wrote:
>> its possible to make a streaming video whith bluez?
>
> Not right now.
>
>> if not, are there plans to implementing?
>
> Nothing concrete, but at least the first requirement would be for there
> to exist some devices on the market that support VDP. Do you know any?
> Do you have plans to implement this for BlueZ?
>
> Johan
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* Re: [PATCH 1/2] bluetooth: Add support Bluetooth controller of MacbookPro 6,2
From: Marcel Holtmann @ 2010-08-19  8:11 UTC (permalink / raw)
  To: Nobuhiro Iwamatsu; +Cc: linux-bluetooth, stable
In-Reply-To: <1282197259-16609-1-git-send-email-iwamatsu@nigauri.org>

Hi Nobuhiro.

> Bluetooth controller of MacbookPro 6,2 does not work.
> Because Device Class of these controllers was set 255 (Vendor Sepecific Class).
> 
> Signed-off-by: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>

it would be nice if you include the output from /proc/bus/usb/devices or
usb-devices.sh script to proof the different device class.

Regards

Marcel



^ permalink raw reply

* Re: [PATCH] Fix problem with multiple emails in vcard
From: Johan Hedberg @ 2010-08-19  8:03 UTC (permalink / raw)
  To: Radoslaw Jablonski; +Cc: linux-bluetooth
In-Reply-To: <1282200587-5475-1-git-send-email-ext-jablonski.radoslaw@nokia.com>

Hi Radek,

On Thu, Aug 19, 2010, Radoslaw Jablonski wrote:
> Previously only one email appeared in generated vcard, even if contact
> had defined multiple email addresses in contact data.
> Changed vcard struct and phonebook-tracker pull_contacts func to support
> multiple emails.
> ---
>  plugins/phonebook-tracker.c |   99 +++++++++++++++++++++++++++++-------------
>  plugins/vcard.c             |   12 ++++-
>  plugins/vcard.h             |    2 +-
>  3 files changed, 78 insertions(+), 35 deletions(-)

Thanks. The patch is now upstream.

Johan

^ permalink raw reply

* Re: its possible to make a streaming video whith bluez?
From: Johan Hedberg @ 2010-08-19  7:49 UTC (permalink / raw)
  To: Lorenzo Brito Morales; +Cc: linux-bluetooth
In-Reply-To: <AANLkTikEHVwEXQg=0ahqwDOANa-VPLjd11xC2ri2N8d5@mail.gmail.com>

Hi,

On Thu, Aug 19, 2010, Lorenzo Brito Morales wrote:
> its possible to make a streaming video whith bluez?

Not right now.

> if not, are there plans to implementing?

Nothing concrete, but at least the first requirement would be for there
to exist some devices on the market that support VDP. Do you know any?
Do you have plans to implement this for BlueZ?

Johan

^ permalink raw reply

* its possible to make a streaming video whith bluez?
From: Lorenzo Brito Morales @ 2010-08-19  6:57 UTC (permalink / raw)
  To: linux-bluetooth

its possible to make a streaming video whith bluez? if not, are there
plans to implementing?

^ permalink raw reply

* [PATCH] Fix problem with multiple emails in vcard
From: Radoslaw Jablonski @ 2010-08-19  6:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Radoslaw Jablonski

Previously only one email appeared in generated vcard, even if contact
had defined multiple email addresses in contact data.
Changed vcard struct and phonebook-tracker pull_contacts func to support
multiple emails.
---
 plugins/phonebook-tracker.c |   99 +++++++++++++++++++++++++++++-------------
 plugins/vcard.c             |   12 ++++-
 plugins/vcard.h             |    2 +-
 3 files changed, 78 insertions(+), 35 deletions(-)

diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 618ce8d..1109968 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -43,14 +43,16 @@
 #define TRACKER_RESOURCES_INTERFACE "org.freedesktop.Tracker1.Resources"
 
 #define TRACKER_DEFAULT_CONTACT_ME "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#default-contact-me"
-#define CONTACTS_ID_COL 20
-#define PULL_QUERY_COL_AMOUNT 21
+#define CONTACTS_ID_COL 21
+#define PULL_QUERY_COL_AMOUNT 22
 #define COL_HOME_NUMBER 0
+#define COL_HOME_EMAIL 7
 #define COL_WORK_NUMBER 8
 #define COL_FAX_NUMBER 16
-#define COL_DATE 17
-#define COL_SENT 18
-#define COL_ANSWERED 19
+#define COL_WORK_EMAIL 17
+#define COL_DATE 18
+#define COL_SENT 19
+#define COL_ANSWERED 20
 
 #define CONTACTS_QUERY_ALL						\
 	"SELECT ?v nco:fullname(?c) "					\
@@ -59,8 +61,8 @@
 	"nco:nameHonorificSuffix(?c) nco:emailAddress(?e) "		\
 	"nco:phoneNumber(?w) nco:pobox(?p) nco:extendedAddress(?p) "	\
 	"nco:streetAddress(?p) nco:locality(?p) nco:region(?p) "	\
-	"nco:postalcode(?p) nco:country(?p) ?f \"NOTACALL\" \"false\" "	\
-	"\"false\" ?c "							\
+	"nco:postalcode(?p) nco:country(?p) ?f nco:emailAddress(?ew) "	\
+	"\"NOTACALL\" \"false\" \"false\" ?c "				\
 	"WHERE { "							\
 		"?c a nco:PersonContact . "				\
 	"OPTIONAL { ?c nco:hasPhoneNumber ?h . 				\
@@ -77,7 +79,8 @@
 	"OPTIONAL { ?c nco:hasPostalAddress ?p . } "			\
 	"OPTIONAL { "							\
 		"?c nco:hasAffiliation ?a . "				\
-		"?a nco:hasPhoneNumber ?w . "				\
+		"OPTIONAL { ?a nco:hasPhoneNumber ?w . } " 		\
+		"OPTIONAL { ?a nco:hasEmailAddress ?ew . } "		\
 	"} "								\
 	"}"
 
@@ -102,7 +105,8 @@
 	"nco:nameHonorificSuffix(?c) nco:emailAddress(?e) "		\
 	"nco:phoneNumber(?w) nco:pobox(?p) nco:extendedAddress(?p) "	\
 	"nco:streetAddress(?p) nco:locality(?p) nco:region(?p) "	\
-	"nco:postalcode(?p) nco:country(?p) ?f nmo:receivedDate(?call) "\
+	"nco:postalcode(?p) nco:country(?p) ?f nco:emailAddress(?ew) "	\
+	"nmo:receivedDate(?call) "					\
 	"nmo:isSent(?call) nmo:isAnswered(?call) ?c "			\
 	"WHERE { "							\
 		"?call a nmo:Call ; "					\
@@ -120,7 +124,8 @@
 	"OPTIONAL { ?c nco:hasPostalAddress ?p . } "			\
 	"OPTIONAL { "							\
 		"?c nco:hasAffiliation ?a . "				\
-		"?a nco:hasPhoneNumber ?w . "				\
+		"OPTIONAL { ?a nco:hasPhoneNumber ?w . } " 		\
+		"OPTIONAL { ?a nco:hasEmailAddress ?ew . } "		\
 	"} "								\
 	"} ORDER BY DESC(nmo:receivedDate(?call))"
 
@@ -145,7 +150,8 @@
 	"nco:nameHonorificSuffix(?c) nco:emailAddress(?e) "		\
 	"nco:phoneNumber(?w) nco:pobox(?p) nco:extendedAddress(?p) "	\
 	"nco:streetAddress(?p) nco:locality(?p) nco:region(?p) "	\
-	"nco:postalcode(?p) nco:country(?p) ?f nmo:receivedDate(?call) "\
+	"nco:postalcode(?p) nco:country(?p) ?f nco:emailAddress(?ew) "	\
+	"nmo:receivedDate(?call) "					\
 	"nmo:isSent(?call) nmo:isAnswered(?call) ?c "			\
 	"WHERE { "							\
 		"?call a nmo:Call ; "					\
@@ -163,7 +169,8 @@
 	"OPTIONAL { ?c nco:hasPostalAddress ?p . } "			\
 	"OPTIONAL { "							\
 		"?c nco:hasAffiliation ?a . "				\
-		"?a nco:hasPhoneNumber ?w . "				\
+		"OPTIONAL { ?a nco:hasPhoneNumber ?w . } " 		\
+		"OPTIONAL { ?a nco:hasEmailAddress ?ew . } "		\
 	"} "								\
 	"} ORDER BY DESC(nmo:receivedDate(?call))"
 
@@ -188,7 +195,8 @@
 	"nco:nameHonorificSuffix(?c) nco:emailAddress(?e) "		\
 	"nco:phoneNumber(?w) nco:pobox(?p) nco:extendedAddress(?p) "	\
 	"nco:streetAddress(?p) nco:locality(?p) nco:region(?p) "	\
-	"nco:postalcode(?p) nco:country(?p) ?f nmo:receivedDate(?call) "\
+	"nco:postalcode(?p) nco:country(?p) ?f nco:emailAddress(?ew)"	\
+	"nmo:receivedDate(?call) "					\
 	"nmo:isSent(?call) nmo:isAnswered(?call) ?c "			\
 	"WHERE { "							\
 		"?call a nmo:Call ; "					\
@@ -205,7 +213,8 @@
 	"OPTIONAL { ?c nco:hasPostalAddress ?p . } "			\
 	"OPTIONAL { "							\
 		"?c nco:hasAffiliation ?a . "				\
-		"?a nco:hasPhoneNumber ?w . "				\
+		"OPTIONAL { ?a nco:hasPhoneNumber ?w . } " 		\
+		"OPTIONAL { ?a nco:hasEmailAddress ?ew . } "		\
 	"} "								\
 	"} ORDER BY DESC(nmo:sentDate(?call))"
 
@@ -229,7 +238,8 @@
 	"nco:nameHonorificSuffix(?c) nco:emailAddress(?e) "		\
 	"nco:phoneNumber(?w) nco:pobox(?p) nco:extendedAddress(?p) "	\
 	"nco:streetAddress(?p) nco:locality(?p) nco:region(?p) "	\
-	"nco:postalcode(?p) nco:country(?p) ?f nmo:receivedDate(?call) "\
+	"nco:postalcode(?p) nco:country(?p) ?f nco:emailAddress(?ew) "	\
+	"nmo:receivedDate(?call) "					\
 	"nmo:isSent(?call) nmo:isAnswered(?call) ?c "			\
 	"WHERE { "							\
 	"{ "								\
@@ -243,12 +253,12 @@
 		"nco:phoneNumber ?f . "					\
 		"}"							\
 	"} "								\
-		"OPTIONAL { ?c nco:hasEmailAddress ?e . } "		\
-		"OPTIONAL { ?c nco:hasPostalAddress ?p . } "		\
-		"OPTIONAL { "						\
-			"?c nco:hasAffiliation ?a . "			\
-			"?a nco:hasPhoneNumber ?w . "			\
-		"} "							\
+	"OPTIONAL { ?c nco:hasEmailAddress ?e . } "			\
+	"OPTIONAL { ?c nco:hasPostalAddress ?p . } "			\
+	"OPTIONAL { ?c nco:hasAffiliation ?a . "			\
+		"OPTIONAL { ?a nco:hasPhoneNumber ?w . } " 		\
+		"OPTIONAL { ?a nco:hasEmailAddress ?ew . } "		\
+	"} "								\
 	"} UNION { "							\
 		"?call a nmo:Call ; "					\
 		"nmo:from ?c ; "					\
@@ -260,12 +270,12 @@
 		"nco:phoneNumber ?f . "					\
 		"}"							\
 	"} "								\
-		"OPTIONAL { ?c nco:hasEmailAddress ?e . } "		\
-		"OPTIONAL { ?c nco:hasPostalAddress ?p . } "		\
-		"OPTIONAL { "						\
-			"?c nco:hasAffiliation ?a . "			\
-			"?a nco:hasPhoneNumber ?w . "			\
-		"} "							\
+	"OPTIONAL { ?c nco:hasEmailAddress ?e . } "			\
+	"OPTIONAL { ?c nco:hasPostalAddress ?p . } "			\
+	"OPTIONAL { ?c nco:hasAffiliation ?a . "			\
+		"OPTIONAL { ?a nco:hasPhoneNumber ?w . } " 		\
+		"OPTIONAL { ?a nco:hasEmailAddress ?ew . } "		\
+	"} "								\
 	"} } ORDER BY DESC(nmo:receivedDate(?call))"
 
 #define COMBINED_CALLS_LIST						\
@@ -295,8 +305,8 @@
 	"nco:nameHonorificSuffix(<%s>) nco:emailAddress(?e) "		\
 	"nco:phoneNumber(?w) nco:pobox(?p) nco:extendedAddress(?p) "	\
 	"nco:streetAddress(?p) nco:locality(?p) nco:region(?p) "	\
-	"nco:postalcode(?p) nco:country(?p) ?f \"NOTACALL\" \"false\" "	\
-	"\"false\" <%s> "						\
+	"nco:postalcode(?p) nco:country(?p) ?f  nco:emailAddress(?ew)"	\
+	"\"NOTACALL\" \"false\" \"false\" <%s> "			\
 	"WHERE { "							\
 		"<%s> a nco:Contact . "					\
 	"OPTIONAL { <%s> nco:hasPhoneNumber ?h . 			\
@@ -313,7 +323,8 @@
 	"OPTIONAL { <%s> nco:hasPostalAddress ?p . } "			\
 	"OPTIONAL { "							\
 		"<%s> nco:hasAffiliation ?a . "				\
-		"?a nco:hasPhoneNumber ?w . "				\
+		"OPTIONAL { ?a nco:hasPhoneNumber ?w . }" 		\
+		"OPTIONAL { ?a nco:hasEmailAddress ?ew . }"		\
 	"} "								\
 	"}"
 
@@ -651,6 +662,29 @@ static void add_phone_number(struct phonebook_contact *contact,
 	contact->numbers = g_slist_append(contact->numbers, number);
 }
 
+static gchar *find_email(GSList *emails, const char *email)
+{
+	GSList *l;
+
+	for (l = emails; l; l = l->next)
+		if (g_strcmp0(l->data, email) == 0)
+			return l->data;
+
+	return NULL;
+}
+
+static void add_email(struct phonebook_contact *contact, const char *email)
+{
+	if (email == NULL || strlen(email) == 0)
+		return;
+
+	/* Not adding email if there is already added with the same value */
+	if (find_email(contact->emails, email))
+		return;
+
+	contact->emails = g_slist_append(contact->emails, g_strdup(email));
+}
+
 static GString *gen_vcards(GSList *contacts,
 					const struct apparam_field *params)
 {
@@ -733,7 +767,6 @@ add_entry:
 	contact->additional = g_strdup(reply[4]);
 	contact->prefix = g_strdup(reply[5]);
 	contact->suffix = g_strdup(reply[6]);
-	contact->email = g_strdup(reply[7]);
 	contact->pobox = g_strdup(reply[9]);
 	contact->extended = g_strdup(reply[10]);
 	contact->street = g_strdup(reply[11]);
@@ -751,6 +784,10 @@ add_numbers:
 	add_phone_number(contact, reply[COL_WORK_NUMBER], TEL_TYPE_WORK);
 	add_phone_number(contact, reply[COL_FAX_NUMBER], TEL_TYPE_FAX);
 
+	/* Adding emails */
+	add_email(contact, reply[COL_HOME_EMAIL]);
+	add_email(contact, reply[COL_WORK_EMAIL]);
+
 	DBG("contact %p", contact);
 
 	/* Adding contacts data to wrapper struct - this data will be used to
diff --git a/plugins/vcard.c b/plugins/vcard.c
index af00cb5..18b5952 100644
--- a/plugins/vcard.c
+++ b/plugins/vcard.c
@@ -344,8 +344,12 @@ void phonebook_add_contact(GString *vcards, struct phonebook_contact *contact,
 		}
 	}
 
-	if (filter & FILTER_EMAIL)
-		vcard_printf_email(vcards, contact->email);
+	if (filter & FILTER_EMAIL) {
+		GSList *l;
+
+		for (l = contact->emails; l; l = l->next)
+			vcard_printf_email(vcards, l->data);
+	}
 
 	if (filter & FILTER_ADR)
 		vcard_printf_adr(vcards, contact);
@@ -372,11 +376,13 @@ void phonebook_contact_free(struct phonebook_contact *contact)
 	g_slist_foreach(contact->numbers, number_free, NULL);
 	g_slist_free(contact->numbers);
 
+	g_slist_foreach(contact->emails, (GFunc) g_free, NULL);
+	g_slist_free(contact->emails);
+
 	g_free(contact->fullname);
 	g_free(contact->given);
 	g_free(contact->family);
 	g_free(contact->additional);
-	g_free(contact->email);
 	g_free(contact->prefix);
 	g_free(contact->suffix);
 	g_free(contact->pobox);
diff --git a/plugins/vcard.h b/plugins/vcard.h
index 06bcd35..fa571e4 100644
--- a/plugins/vcard.h
+++ b/plugins/vcard.h
@@ -45,7 +45,7 @@ struct phonebook_contact {
 	char *family;
 	char *additional;
 	GSList *numbers;
-	char *email;
+	GSList *emails;
 	char *prefix;
 	char *suffix;
 	char *pobox;
-- 
1.7.0.4


^ permalink raw reply related

* Re: [PATCH] Fix problem with multiple emails in vcard
From: Radoslaw Jablonski @ 2010-08-19  6:44 UTC (permalink / raw)
  To: Hedberg Johan (Nokia-MS/Helsinki); +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <20100819063420.GA3661@jh-x301>

  Hi
Sorry this belongs to another set of patches.
I'll resend modified patch without this unnecessary data.

BR,
Radek

On 08/19/2010 09:34 AM, Hedberg Johan (Nokia-MS/Helsinki) wrote:
> Hi Radek,
>
> On Thu, Aug 19, 2010, Radoslaw Jablonski wrote:
>> +	char *birthday;
>> +	char *nickname;
>> +	char *website;
>> +	char *photo;
>> +	char *company;
>> +	char *department;
>> +	char *title;
> How is this part related to your patch (about email support in vCards)?
> Seems like it belongs to some other patch. The rest of the patch seems
> fine to me.
>
> Johan


^ permalink raw reply

* Re: [PATCH] Fix problem with multiple emails in vcard
From: Johan Hedberg @ 2010-08-19  6:34 UTC (permalink / raw)
  To: Radoslaw Jablonski; +Cc: linux-bluetooth
In-Reply-To: <1282198407-4025-1-git-send-email-ext-jablonski.radoslaw@nokia.com>

Hi Radek,

On Thu, Aug 19, 2010, Radoslaw Jablonski wrote:
> +	char *birthday;
> +	char *nickname;
> +	char *website;
> +	char *photo;
> +	char *company;
> +	char *department;
> +	char *title;

How is this part related to your patch (about email support in vCards)?
Seems like it belongs to some other patch. The rest of the patch seems
fine to me.

Johan

^ permalink raw reply

* [PATCH] Fix problem with multiple emails in vcard
From: Radoslaw Jablonski @ 2010-08-19  6:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Radoslaw Jablonski

Previously only one email appeared in generated vcard, even if contact
had defined multiple email addresses in contact data.
Changed vcard struct and phonebook-tracker pull_contacts func to support
multiple emails.
---
 plugins/phonebook-tracker.c |   99 +++++++++++++++++++++++++++++-------------
 plugins/vcard.c             |   12 ++++-
 plugins/vcard.h             |    9 ++++-
 3 files changed, 85 insertions(+), 35 deletions(-)

diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 618ce8d..1109968 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -43,14 +43,16 @@
 #define TRACKER_RESOURCES_INTERFACE "org.freedesktop.Tracker1.Resources"
 
 #define TRACKER_DEFAULT_CONTACT_ME "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#default-contact-me"
-#define CONTACTS_ID_COL 20
-#define PULL_QUERY_COL_AMOUNT 21
+#define CONTACTS_ID_COL 21
+#define PULL_QUERY_COL_AMOUNT 22
 #define COL_HOME_NUMBER 0
+#define COL_HOME_EMAIL 7
 #define COL_WORK_NUMBER 8
 #define COL_FAX_NUMBER 16
-#define COL_DATE 17
-#define COL_SENT 18
-#define COL_ANSWERED 19
+#define COL_WORK_EMAIL 17
+#define COL_DATE 18
+#define COL_SENT 19
+#define COL_ANSWERED 20
 
 #define CONTACTS_QUERY_ALL						\
 	"SELECT ?v nco:fullname(?c) "					\
@@ -59,8 +61,8 @@
 	"nco:nameHonorificSuffix(?c) nco:emailAddress(?e) "		\
 	"nco:phoneNumber(?w) nco:pobox(?p) nco:extendedAddress(?p) "	\
 	"nco:streetAddress(?p) nco:locality(?p) nco:region(?p) "	\
-	"nco:postalcode(?p) nco:country(?p) ?f \"NOTACALL\" \"false\" "	\
-	"\"false\" ?c "							\
+	"nco:postalcode(?p) nco:country(?p) ?f nco:emailAddress(?ew) "	\
+	"\"NOTACALL\" \"false\" \"false\" ?c "				\
 	"WHERE { "							\
 		"?c a nco:PersonContact . "				\
 	"OPTIONAL { ?c nco:hasPhoneNumber ?h . 				\
@@ -77,7 +79,8 @@
 	"OPTIONAL { ?c nco:hasPostalAddress ?p . } "			\
 	"OPTIONAL { "							\
 		"?c nco:hasAffiliation ?a . "				\
-		"?a nco:hasPhoneNumber ?w . "				\
+		"OPTIONAL { ?a nco:hasPhoneNumber ?w . } " 		\
+		"OPTIONAL { ?a nco:hasEmailAddress ?ew . } "		\
 	"} "								\
 	"}"
 
@@ -102,7 +105,8 @@
 	"nco:nameHonorificSuffix(?c) nco:emailAddress(?e) "		\
 	"nco:phoneNumber(?w) nco:pobox(?p) nco:extendedAddress(?p) "	\
 	"nco:streetAddress(?p) nco:locality(?p) nco:region(?p) "	\
-	"nco:postalcode(?p) nco:country(?p) ?f nmo:receivedDate(?call) "\
+	"nco:postalcode(?p) nco:country(?p) ?f nco:emailAddress(?ew) "	\
+	"nmo:receivedDate(?call) "					\
 	"nmo:isSent(?call) nmo:isAnswered(?call) ?c "			\
 	"WHERE { "							\
 		"?call a nmo:Call ; "					\
@@ -120,7 +124,8 @@
 	"OPTIONAL { ?c nco:hasPostalAddress ?p . } "			\
 	"OPTIONAL { "							\
 		"?c nco:hasAffiliation ?a . "				\
-		"?a nco:hasPhoneNumber ?w . "				\
+		"OPTIONAL { ?a nco:hasPhoneNumber ?w . } " 		\
+		"OPTIONAL { ?a nco:hasEmailAddress ?ew . } "		\
 	"} "								\
 	"} ORDER BY DESC(nmo:receivedDate(?call))"
 
@@ -145,7 +150,8 @@
 	"nco:nameHonorificSuffix(?c) nco:emailAddress(?e) "		\
 	"nco:phoneNumber(?w) nco:pobox(?p) nco:extendedAddress(?p) "	\
 	"nco:streetAddress(?p) nco:locality(?p) nco:region(?p) "	\
-	"nco:postalcode(?p) nco:country(?p) ?f nmo:receivedDate(?call) "\
+	"nco:postalcode(?p) nco:country(?p) ?f nco:emailAddress(?ew) "	\
+	"nmo:receivedDate(?call) "					\
 	"nmo:isSent(?call) nmo:isAnswered(?call) ?c "			\
 	"WHERE { "							\
 		"?call a nmo:Call ; "					\
@@ -163,7 +169,8 @@
 	"OPTIONAL { ?c nco:hasPostalAddress ?p . } "			\
 	"OPTIONAL { "							\
 		"?c nco:hasAffiliation ?a . "				\
-		"?a nco:hasPhoneNumber ?w . "				\
+		"OPTIONAL { ?a nco:hasPhoneNumber ?w . } " 		\
+		"OPTIONAL { ?a nco:hasEmailAddress ?ew . } "		\
 	"} "								\
 	"} ORDER BY DESC(nmo:receivedDate(?call))"
 
@@ -188,7 +195,8 @@
 	"nco:nameHonorificSuffix(?c) nco:emailAddress(?e) "		\
 	"nco:phoneNumber(?w) nco:pobox(?p) nco:extendedAddress(?p) "	\
 	"nco:streetAddress(?p) nco:locality(?p) nco:region(?p) "	\
-	"nco:postalcode(?p) nco:country(?p) ?f nmo:receivedDate(?call) "\
+	"nco:postalcode(?p) nco:country(?p) ?f nco:emailAddress(?ew)"	\
+	"nmo:receivedDate(?call) "					\
 	"nmo:isSent(?call) nmo:isAnswered(?call) ?c "			\
 	"WHERE { "							\
 		"?call a nmo:Call ; "					\
@@ -205,7 +213,8 @@
 	"OPTIONAL { ?c nco:hasPostalAddress ?p . } "			\
 	"OPTIONAL { "							\
 		"?c nco:hasAffiliation ?a . "				\
-		"?a nco:hasPhoneNumber ?w . "				\
+		"OPTIONAL { ?a nco:hasPhoneNumber ?w . } " 		\
+		"OPTIONAL { ?a nco:hasEmailAddress ?ew . } "		\
 	"} "								\
 	"} ORDER BY DESC(nmo:sentDate(?call))"
 
@@ -229,7 +238,8 @@
 	"nco:nameHonorificSuffix(?c) nco:emailAddress(?e) "		\
 	"nco:phoneNumber(?w) nco:pobox(?p) nco:extendedAddress(?p) "	\
 	"nco:streetAddress(?p) nco:locality(?p) nco:region(?p) "	\
-	"nco:postalcode(?p) nco:country(?p) ?f nmo:receivedDate(?call) "\
+	"nco:postalcode(?p) nco:country(?p) ?f nco:emailAddress(?ew) "	\
+	"nmo:receivedDate(?call) "					\
 	"nmo:isSent(?call) nmo:isAnswered(?call) ?c "			\
 	"WHERE { "							\
 	"{ "								\
@@ -243,12 +253,12 @@
 		"nco:phoneNumber ?f . "					\
 		"}"							\
 	"} "								\
-		"OPTIONAL { ?c nco:hasEmailAddress ?e . } "		\
-		"OPTIONAL { ?c nco:hasPostalAddress ?p . } "		\
-		"OPTIONAL { "						\
-			"?c nco:hasAffiliation ?a . "			\
-			"?a nco:hasPhoneNumber ?w . "			\
-		"} "							\
+	"OPTIONAL { ?c nco:hasEmailAddress ?e . } "			\
+	"OPTIONAL { ?c nco:hasPostalAddress ?p . } "			\
+	"OPTIONAL { ?c nco:hasAffiliation ?a . "			\
+		"OPTIONAL { ?a nco:hasPhoneNumber ?w . } " 		\
+		"OPTIONAL { ?a nco:hasEmailAddress ?ew . } "		\
+	"} "								\
 	"} UNION { "							\
 		"?call a nmo:Call ; "					\
 		"nmo:from ?c ; "					\
@@ -260,12 +270,12 @@
 		"nco:phoneNumber ?f . "					\
 		"}"							\
 	"} "								\
-		"OPTIONAL { ?c nco:hasEmailAddress ?e . } "		\
-		"OPTIONAL { ?c nco:hasPostalAddress ?p . } "		\
-		"OPTIONAL { "						\
-			"?c nco:hasAffiliation ?a . "			\
-			"?a nco:hasPhoneNumber ?w . "			\
-		"} "							\
+	"OPTIONAL { ?c nco:hasEmailAddress ?e . } "			\
+	"OPTIONAL { ?c nco:hasPostalAddress ?p . } "			\
+	"OPTIONAL { ?c nco:hasAffiliation ?a . "			\
+		"OPTIONAL { ?a nco:hasPhoneNumber ?w . } " 		\
+		"OPTIONAL { ?a nco:hasEmailAddress ?ew . } "		\
+	"} "								\
 	"} } ORDER BY DESC(nmo:receivedDate(?call))"
 
 #define COMBINED_CALLS_LIST						\
@@ -295,8 +305,8 @@
 	"nco:nameHonorificSuffix(<%s>) nco:emailAddress(?e) "		\
 	"nco:phoneNumber(?w) nco:pobox(?p) nco:extendedAddress(?p) "	\
 	"nco:streetAddress(?p) nco:locality(?p) nco:region(?p) "	\
-	"nco:postalcode(?p) nco:country(?p) ?f \"NOTACALL\" \"false\" "	\
-	"\"false\" <%s> "						\
+	"nco:postalcode(?p) nco:country(?p) ?f  nco:emailAddress(?ew)"	\
+	"\"NOTACALL\" \"false\" \"false\" <%s> "			\
 	"WHERE { "							\
 		"<%s> a nco:Contact . "					\
 	"OPTIONAL { <%s> nco:hasPhoneNumber ?h . 			\
@@ -313,7 +323,8 @@
 	"OPTIONAL { <%s> nco:hasPostalAddress ?p . } "			\
 	"OPTIONAL { "							\
 		"<%s> nco:hasAffiliation ?a . "				\
-		"?a nco:hasPhoneNumber ?w . "				\
+		"OPTIONAL { ?a nco:hasPhoneNumber ?w . }" 		\
+		"OPTIONAL { ?a nco:hasEmailAddress ?ew . }"		\
 	"} "								\
 	"}"
 
@@ -651,6 +662,29 @@ static void add_phone_number(struct phonebook_contact *contact,
 	contact->numbers = g_slist_append(contact->numbers, number);
 }
 
+static gchar *find_email(GSList *emails, const char *email)
+{
+	GSList *l;
+
+	for (l = emails; l; l = l->next)
+		if (g_strcmp0(l->data, email) == 0)
+			return l->data;
+
+	return NULL;
+}
+
+static void add_email(struct phonebook_contact *contact, const char *email)
+{
+	if (email == NULL || strlen(email) == 0)
+		return;
+
+	/* Not adding email if there is already added with the same value */
+	if (find_email(contact->emails, email))
+		return;
+
+	contact->emails = g_slist_append(contact->emails, g_strdup(email));
+}
+
 static GString *gen_vcards(GSList *contacts,
 					const struct apparam_field *params)
 {
@@ -733,7 +767,6 @@ add_entry:
 	contact->additional = g_strdup(reply[4]);
 	contact->prefix = g_strdup(reply[5]);
 	contact->suffix = g_strdup(reply[6]);
-	contact->email = g_strdup(reply[7]);
 	contact->pobox = g_strdup(reply[9]);
 	contact->extended = g_strdup(reply[10]);
 	contact->street = g_strdup(reply[11]);
@@ -751,6 +784,10 @@ add_numbers:
 	add_phone_number(contact, reply[COL_WORK_NUMBER], TEL_TYPE_WORK);
 	add_phone_number(contact, reply[COL_FAX_NUMBER], TEL_TYPE_FAX);
 
+	/* Adding emails */
+	add_email(contact, reply[COL_HOME_EMAIL]);
+	add_email(contact, reply[COL_WORK_EMAIL]);
+
 	DBG("contact %p", contact);
 
 	/* Adding contacts data to wrapper struct - this data will be used to
diff --git a/plugins/vcard.c b/plugins/vcard.c
index af00cb5..18b5952 100644
--- a/plugins/vcard.c
+++ b/plugins/vcard.c
@@ -344,8 +344,12 @@ void phonebook_add_contact(GString *vcards, struct phonebook_contact *contact,
 		}
 	}
 
-	if (filter & FILTER_EMAIL)
-		vcard_printf_email(vcards, contact->email);
+	if (filter & FILTER_EMAIL) {
+		GSList *l;
+
+		for (l = contact->emails; l; l = l->next)
+			vcard_printf_email(vcards, l->data);
+	}
 
 	if (filter & FILTER_ADR)
 		vcard_printf_adr(vcards, contact);
@@ -372,11 +376,13 @@ void phonebook_contact_free(struct phonebook_contact *contact)
 	g_slist_foreach(contact->numbers, number_free, NULL);
 	g_slist_free(contact->numbers);
 
+	g_slist_foreach(contact->emails, (GFunc) g_free, NULL);
+	g_slist_free(contact->emails);
+
 	g_free(contact->fullname);
 	g_free(contact->given);
 	g_free(contact->family);
 	g_free(contact->additional);
-	g_free(contact->email);
 	g_free(contact->prefix);
 	g_free(contact->suffix);
 	g_free(contact->pobox);
diff --git a/plugins/vcard.h b/plugins/vcard.h
index 06bcd35..0f52425 100644
--- a/plugins/vcard.h
+++ b/plugins/vcard.h
@@ -45,7 +45,7 @@ struct phonebook_contact {
 	char *family;
 	char *additional;
 	GSList *numbers;
-	char *email;
+	GSList *emails;
 	char *prefix;
 	char *suffix;
 	char *pobox;
@@ -55,6 +55,13 @@ struct phonebook_contact {
 	char *region;
 	char *postal;
 	char *country;
+	char *birthday;
+	char *nickname;
+	char *website;
+	char *photo;
+	char *company;
+	char *department;
+	char *title;
 	char *datetime;
 	int calltype;
 };
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 2/2] bluetooth: Add support Bluetooth controller of MacbookPro 7,1
From: Nobuhiro Iwamatsu @ 2010-08-19  5:54 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: stable, Nobuhiro Iwamatsu
In-Reply-To: <1282197259-16609-1-git-send-email-iwamatsu@nigauri.org>

Bluetooth controller of MacbookPro 7,1 does not work.
Because Device Class of these controllers was set 255 (Vendor Sepecific Class).

Signed-off-by: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
---
 drivers/bluetooth/btusb.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 9fb8635..3da2ba2 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -59,6 +59,9 @@ static struct usb_device_id btusb_table[] = {
 	/* Generic Bluetooth USB device */
 	{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
 
+	/* Apple MacBookPro 7,1 */
+	{ USB_DEVICE(0x05ac, 0x8213) },
+
 	/* Apple iMac11,1 */
 	{ USB_DEVICE(0x05ac, 0x8215) },
 
-- 
1.7.1


^ permalink raw reply related

* [PATCH 1/2] bluetooth: Add support Bluetooth controller of MacbookPro 6,2
From: Nobuhiro Iwamatsu @ 2010-08-19  5:54 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: stable, Nobuhiro Iwamatsu

Bluetooth controller of MacbookPro 6,2 does not work.
Because Device Class of these controllers was set 255 (Vendor Sepecific Class).

Signed-off-by: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
---
 drivers/bluetooth/btusb.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index d22ce3c..9fb8635 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -62,6 +62,9 @@ static struct usb_device_id btusb_table[] = {
 	/* Apple iMac11,1 */
 	{ USB_DEVICE(0x05ac, 0x8215) },
 
+	/* Apple MacBookPro6,2 */
+	{ USB_DEVICE(0x05ac, 0x8218) },
+
 	/* AVM BlueFRITZ! USB v2.0 */
 	{ USB_DEVICE(0x057c, 0x3800) },
 
-- 
1.7.1


^ permalink raw reply related

* [PATCH 3/3] Parsing of AMP specific HCI events
From: Inga Stotland @ 2010-08-18 23:38 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: rshaffer, johan.hedberg, marcel, Inga Stotland
In-Reply-To: <1282174734-1314-1-git-send-email-ingas@codeaurora.org>

---
 parser/hci.c |   94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 94 insertions(+), 0 deletions(-)

diff --git a/parser/hci.c b/parser/hci.c
index 5de5128..250ba58 100644
--- a/parser/hci.c
+++ b/parser/hci.c
@@ -3265,6 +3265,80 @@ static inline void le_meta_ev_dump(int level, struct frame *frm)
 	}
 }
 
+static inline void phys_link_complete_dump(int level, struct frame *frm)
+{
+	evt_physical_link_complete *evt = frm->ptr;
+
+	p_indent(level, frm);
+	printf("status 0x%2.2x handle %d\n", evt->status, evt->handle);
+
+	if (evt->status > 0) {
+		p_indent(level, frm);
+		printf("Error: %s\n", status2str(evt->status));
+	}
+}
+
+static inline void disconn_phys_link_complete_dump(int level, struct frame *frm)
+{
+	evt_disconn_physical_link_complete *evt = frm->ptr;
+
+	p_indent(level, frm);
+	printf("status 0x%2.2x handle %d reason 0x%2.2x\n",
+				evt->status, evt->handle, evt->reason);
+
+	if (evt->status > 0) {
+		p_indent(level, frm);
+		printf("Error: %s\n", status2str(evt->status));
+	} else if (evt->reason > 0) {
+		p_indent(level, frm);
+		printf("Reason: %s\n", status2str(evt->reason));
+	}
+}
+
+static inline void phys_link_loss_warning_dump(int level, struct frame *frm)
+{
+	evt_physical_link_loss_warning *evt = frm->ptr;
+
+	p_indent(level, frm);
+	printf("handle %d reason 0x%2.2x\n", evt->handle, evt->reason);
+}
+
+static inline void phys_link_handle_dump(int level, struct frame *frm)
+{
+	evt_physical_link_recovery *evt = frm->ptr;
+
+	p_indent(level, frm);
+	printf("handle %d\n", evt->handle);
+}
+
+static inline void logical_link_complete_dump(int level, struct frame *frm)
+{
+	evt_logical_link_complete *evt = frm->ptr;
+
+	p_indent(level, frm);
+	printf("status 0x%2.2x log_handle %d handle %d tx_flow_id %d\n",
+			evt->status, btohs(evt->log_handle), evt->handle,
+			evt->tx_flow_id);
+
+	if (evt->status > 0) {
+		p_indent(level, frm);
+		printf("Error: %s\n", status2str(evt->status));
+	}
+}
+
+static inline void flow_spec_modify_dump(int level, struct frame *frm)
+{
+	evt_flow_spec_modify_complete *evt = frm->ptr;
+
+	p_indent(level, frm);
+	printf("status 0x%2.2x handle %d\n", evt->status, btohs(evt->handle));
+
+	if (evt->status > 0) {
+		p_indent(level, frm);
+		printf("Error: %s\n", status2str(evt->status));
+	}
+}
+
 static inline void event_dump(int level, struct frame *frm)
 {
 	hci_event_hdr *hdr = frm->ptr;
@@ -3361,6 +3435,7 @@ static inline void event_dump(int level, struct frame *frm)
 		conn_request_dump(level + 1, frm);
 		break;
 	case EVT_DISCONN_COMPLETE:
+	case EVT_DISCONNECT_LOGICAL_LINK_COMPLETE:
 		disconn_complete_dump(level + 1, frm);
 		break;
 	case EVT_AUTH_COMPLETE:
@@ -3471,6 +3546,25 @@ static inline void event_dump(int level, struct frame *frm)
 	case EVT_LE_META_EVENT:
 		le_meta_ev_dump(level + 1, frm);
 		break;
+	case EVT_PHYSICAL_LINK_COMPLETE:
+		phys_link_complete_dump(level + 1, frm);
+		break;
+	case EVT_DISCONNECT_PHYSICAL_LINK_COMPLETE:
+		disconn_phys_link_complete_dump(level + 1, frm);
+		break;
+	case EVT_PHYSICAL_LINK_LOSS_EARLY_WARNING:
+		phys_link_loss_warning_dump(level + 1, frm);
+		break;
+	case EVT_PHYSICAL_LINK_RECOVERY:
+	case EVT_CHANNEL_SELECTED:
+		phys_link_handle_dump(level + 1, frm);
+		break;
+	case EVT_LOGICAL_LINK_COMPLETE:
+		logical_link_complete_dump(level + 1, frm);
+		break;
+	case EVT_FLOW_SPEC_MODIFY_COMPLETE:
+		flow_spec_modify_dump(level + 1, frm);
+		break;
 	default:
 		raw_dump(level, frm);
 		break;
-- 
1.7.2

-- 
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply related

* [PATCH 2/3] Parse Command Complete events corresponding to AMP related HCI commands
From: Inga Stotland @ 2010-08-18 23:38 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: rshaffer, johan.hedberg, marcel, Inga Stotland
In-Reply-To: <1282174734-1314-1-git-send-email-ingas@codeaurora.org>

---
 parser/hci.c |   80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 80 insertions(+), 0 deletions(-)

diff --git a/parser/hci.c b/parser/hci.c
index b768a98..5de5128 100644
--- a/parser/hci.c
+++ b/parser/hci.c
@@ -2360,6 +2360,71 @@ static inline void read_clock_dump(int level, struct frame *frm)
 	}
 }
 
+static inline void read_local_amp_info_dump(int level, struct frame *frm)
+{
+	read_local_amp_info_rp *rp = frm->ptr;
+
+	p_indent(level, frm);
+	printf("status 0x%2.2x amp status 0x%2.2x\n",
+			rp->status, rp->amp_status);
+	if (rp->status > 0) {
+		p_indent(level, frm);
+		printf("Error: %s\n", status2str(rp->status));
+	} else {
+		p_indent(level, frm);
+		printf("total bandwidth %d, max guaranteed bandwidth %d\n",
+			btohl(rp->total_bandwidth),
+			btohl(rp->max_guaranteed_bandwidth));
+		p_indent(level, frm);
+		printf("min latency %d, max PDU %d, controller type 0x%2.2x\n",
+			btohl(rp->min_latency), btohl(rp->max_pdu_size),
+			rp->controller_type);
+		p_indent(level, frm);
+		printf("pal caps 0x%4.4x, max assoc len %d\n",
+			btohs(rp->pal_caps), btohs(rp->max_amp_assoc_length));
+		p_indent(level, frm);
+		printf("max flush timeout %d, best effort flush timeout %d\n",
+			btohl(rp->max_flush_timeout),
+			btohl(rp->best_effort_flush_timeout));
+	}
+}
+
+static inline void read_local_amp_assoc_dump(int level, struct frame *frm)
+{
+	read_local_amp_assoc_rp *rp = frm->ptr;
+	uint16_t len = btohs(rp->length);
+	int i;
+
+	p_indent(level, frm);
+	printf("status 0x%2.2x handle 0x%2.2x length %d\n",
+			rp->status, rp->handle, len);
+	if (rp->status > 0) {
+		p_indent(level, frm);
+		printf("Error: %s\n", status2str(rp->status));
+	} else {
+		for (i = 0; i < len; i++) {
+			if (!(i % 16)) {
+				printf("\n");
+				p_indent(level, frm);
+			}
+			printf("%2.2x ", rp->fragment[i]);
+		}
+		printf("\n");
+	}
+}
+
+static inline void write_remote_amp_assoc_dump(int level, struct frame *frm)
+{
+	write_remote_amp_assoc_rp *rp = frm->ptr;
+
+	p_indent(level, frm);
+	printf("status 0x%2.2x handle 0x%2.2x\n", rp->status, rp->handle);
+	if (rp->status > 0) {
+		p_indent(level, frm);
+		printf("Error: %s\n", status2str(rp->status));
+	}
+}
+
 static inline void cmd_complete_dump(int level, struct frame *frm)
 {
 	evt_cmd_complete *evt = frm->ptr;
@@ -2460,6 +2525,7 @@ static inline void cmd_complete_dump(int level, struct frame *frm)
 			return;
 		case OCF_READ_CONN_ACCEPT_TIMEOUT:
 		case OCF_READ_PAGE_TIMEOUT:
+		case OCF_READ_LOGICAL_LINK_ACCEPT_TIMEOUT:
 			read_page_timeout_dump(level, frm);
 			return;
 		case OCF_READ_PAGE_ACTIVITY:
@@ -2528,7 +2594,12 @@ static inline void cmd_complete_dump(int level, struct frame *frm)
 		case OCF_HOST_BUFFER_SIZE:
 		case OCF_REFRESH_ENCRYPTION_KEY:
 		case OCF_SEND_KEYPRESS_NOTIFY:
+		case OCF_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT:
+		case OCF_SET_EVENT_MASK_PAGE_2:
 		case OCF_WRITE_LOCATION_DATA:
+		case OCF_WRITE_FLOW_CONTROL_MODE:
+		case OCF_READ_BEST_EFFORT_FLUSH_TIMEOUT:
+		case OCF_WRITE_BEST_EFFORT_FLUSH_TIMEOUT:
 			status_response_dump(level, frm);
 			return;
 		}
@@ -2575,6 +2646,15 @@ static inline void cmd_complete_dump(int level, struct frame *frm)
 		case OCF_READ_CLOCK:
 			read_clock_dump(level, frm);
 			return;
+		case OCF_READ_LOCAL_AMP_INFO:
+			read_local_amp_info_dump(level, frm);
+			return;
+		case OCF_READ_LOCAL_AMP_ASSOC:
+			read_local_amp_assoc_dump(level, frm);
+			return;
+		case OCF_WRITE_REMOTE_AMP_ASSOC:
+			write_remote_amp_assoc_dump(level, frm);
+			return;
 		}
 		break;
 
-- 
1.7.2

-- 
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply related

* [PATCH 1/3] Add parsing of AMP related HCI commands
From: Inga Stotland @ 2010-08-18 23:38 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: rshaffer, johan.hedberg, marcel, Inga Stotland
In-Reply-To: <1282174734-1314-1-git-send-email-ingas@codeaurora.org>

---
 parser/hci.c |   64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/parser/hci.c b/parser/hci.c
index b9e8d28..b768a98 100644
--- a/parser/hci.c
+++ b/parser/hci.c
@@ -141,7 +141,7 @@ static char *ev_le_meta_str[LE_EV_NUM + 1] = {
 	"LE Long Term Key Request",
 };
 
-#define CMD_LINKCTL_NUM 52
+#define CMD_LINKCTL_NUM 60
 static char *cmd_linkctl_str[CMD_LINKCTL_NUM + 1] = {
 	"Unknown",
 	"Inquiry",
@@ -196,6 +196,14 @@ static char *cmd_linkctl_str[CMD_LINKCTL_NUM + 1] = {
 	"Unknown",
 	"Remote OOB Data Request Negative Reply",
 	"IO Capability Request Negative Reply",
+	"Create Physical Link",
+	"Accept Physical Link",
+	"Disconnect Physical Link",
+	"Create Logical Link",
+	"Accept Logical Link",
+	"Disconnect Logical Link",
+	"Logical Link Cancel",
+	"Flow Spec Modify",
 };
 
 #define CMD_LINKPOL_NUM 17
@@ -348,7 +356,7 @@ static char *cmd_info_str[CMD_INFO_NUM + 1] = {
 	"Read BD ADDR",
 };
 
-#define CMD_STATUS_NUM 7
+#define CMD_STATUS_NUM 11
 static char *cmd_status_str[CMD_STATUS_NUM + 1] = {
 	"Unknown",
 	"Read Failed Contact Counter",
@@ -358,6 +366,10 @@ static char *cmd_status_str[CMD_STATUS_NUM + 1] = {
 	"Read RSSI",
 	"Read AFH Channel Map",
 	"Read Clock",
+	"Read Encryption Key Size",
+	"Read Local AMP Info",
+	"Read Local AMP ASSOC",
+	"Write Remote AMP ASSOC"
 };
 
 #define CMD_TESTING_NUM 4
@@ -1003,6 +1015,39 @@ static inline void setup_sync_conn_dump(int level, struct frame *frm)
 		btohs(cp->pkt_type));
 }
 
+static inline void create_physical_link_dump(int level, struct frame *frm)
+{
+	create_physical_link_cp *cp = frm->ptr;
+	int i;
+
+	p_indent(level, frm);
+
+	printf("handle %d key length %d key type %d\n",
+		cp->handle, cp->key_length, cp->key_type);
+	printf("key ");
+
+	for (i = 0; i < cp->key_length && cp->key_length < 32; i++)
+		printf("%2.2x", cp->key[i]);
+	printf("\n");
+}
+
+static inline void create_logical_link_dump(int level, struct frame *frm)
+{
+	create_logical_link_cp *cp = frm->ptr;
+	int i;
+
+	p_indent(level, frm);
+
+	printf("handle %d\n", cp->handle);
+	printf("tx_flow ");
+	for (i = 0; i < 16; i++)
+		printf("%2.2x", cp->tx_flow[i]);
+	printf("\nrx_flow ");
+	for (i = 0; i < 16; i++)
+		printf("%2.2x", cp->rx_flow[i]);
+	printf("\n");
+}
+
 static inline void hold_mode_dump(int level, struct frame *frm)
 {
 	hold_mode_cp *cp = frm->ptr;
@@ -1523,6 +1568,7 @@ static inline void command_dump(int level, struct frame *frm)
 		case OCF_READ_REMOTE_VERSION:
 		case OCF_READ_CLOCK_OFFSET:
 		case OCF_READ_LMP_HANDLE:
+		case OCF_DISCONNECT_LOGICAL_LINK:
 			generic_command_dump(level + 1, frm);
 			return;
 		case OCF_MASTER_LINK_KEY:
@@ -1537,6 +1583,14 @@ static inline void command_dump(int level, struct frame *frm)
 		case OCF_SETUP_SYNC_CONN:
 			setup_sync_conn_dump(level + 1, frm);
 			return;
+		case OCF_CREATE_PHYSICAL_LINK:
+		case OCF_ACCEPT_PHYSICAL_LINK:
+			create_physical_link_dump(level + 1, frm);
+			return;
+		case OCF_CREATE_LOGICAL_LINK:
+		case OCF_ACCEPT_LOGICAL_LINK:
+			create_logical_link_dump(level + 1, frm);
+			return;
 		}
 		break;
 
@@ -1581,6 +1635,7 @@ static inline void command_dump(int level, struct frame *frm)
 		case OCF_CREATE_NEW_UNIT_KEY:
 			return;
 		case OCF_SET_EVENT_MASK:
+		case OCF_SET_EVENT_MASK_PAGE_2:
 			set_event_mask_dump(level + 1, frm);
 			return;
 		case OCF_SET_EVENT_FLT:
@@ -1613,6 +1668,7 @@ static inline void command_dump(int level, struct frame *frm)
 		case OCF_SET_CONTROLLER_TO_HOST_FC:
 			write_scan_enable_dump(level + 1, frm);
 			return;
+		case OCF_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT:
 		case OCF_WRITE_CONN_ACCEPT_TIMEOUT:
 		case OCF_WRITE_PAGE_TIMEOUT:
 			write_page_timeout_dump(level + 1, frm);
@@ -1644,6 +1700,7 @@ static inline void command_dump(int level, struct frame *frm)
 		case OCF_FLUSH:
 		case OCF_READ_LINK_SUPERVISION_TIMEOUT:
 		case OCF_REFRESH_ENCRYPTION_KEY:
+		case OCF_READ_BEST_EFFORT_FLUSH_TIMEOUT:
 			generic_command_dump(level + 1, frm);
 			return;
 		case OCF_WRITE_LINK_SUPERVISION_TIMEOUT:
@@ -1653,6 +1710,7 @@ static inline void command_dump(int level, struct frame *frm)
 			write_ext_inquiry_response_dump(level + 1, frm);
 			return;
 		case OCF_WRITE_SIMPLE_PAIRING_MODE:
+		case OCF_WRITE_FLOW_CONTROL_MODE:
 			generic_write_mode_dump(level + 1, frm);
 			return;
 		case OCF_WRITE_INQUIRY_TRANSMIT_POWER_LEVEL:
@@ -2435,6 +2493,7 @@ static inline void cmd_complete_dump(int level, struct frame *frm)
 			read_local_oob_data_dump(level, frm);
 			return;
 		case OCF_READ_SIMPLE_PAIRING_MODE:
+		case OCF_READ_FLOW_CONTROL_MODE:
 			status_mode_dump(level, frm);
 			return;
 		case OCF_FLUSH:
@@ -2469,6 +2528,7 @@ static inline void cmd_complete_dump(int level, struct frame *frm)
 		case OCF_HOST_BUFFER_SIZE:
 		case OCF_REFRESH_ENCRYPTION_KEY:
 		case OCF_SEND_KEYPRESS_NOTIFY:
+		case OCF_WRITE_LOCATION_DATA:
 			status_response_dump(level, frm);
 			return;
 		}
-- 
1.7.2

-- 
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply related

* [PATCH 0/3] Parsing of AMP related HCI commands and events
From: Inga Stotland @ 2010-08-18 23:38 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: rshaffer, johan.hedberg, marcel

Added support for interpreting of the following HCI commands:

Create Physical Link,
Accept Physical Link,
Disconnect Physical Link,
Create Logical Link,
Accept Logical Link,
Disconnect Logical Link,
Logical Link Cancel,
Flow Spec Modify,
Read Encryption Key Size,
Read Local AMP Info,
Read Local AMP ASSOC,
Write Remote AMP ASSOC

and HCI events:

Physical Link Complete,
Disconnect Physical Link Complete,
Physical Link Loss Early Warning,
Physical Link Recovery,
Logical Link Complete,
Disconnect Logical Link Complete,
Flow Spec Modify Complete

 
-- 
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply

* Re: [PATCH v2] Firmware download for Qualcomm Bluetooth devices
From: Johan Hedberg @ 2010-08-18 22:35 UTC (permalink / raw)
  To: Ron Shaffer; +Cc: Matthew Wilson, linux-bluetooth, marcel
In-Reply-To: <4C6BFF05.5040506@codeaurora.org>

Hi Ron,

On Wed, Aug 18, 2010, Ron Shaffer wrote:
> On 8/13/2010 10:33 AM, Matthew Wilson wrote:
> > Configures device address from hciattach parameter.
> > UART speed limited to 115200.
> > Requires separate device specific firmware.
> > ---
> >  Makefile.tools             |    3 +-
> >  tools/hciattach.c          |    8 ++
> >  tools/hciattach.h          |    1 +
> >  tools/hciattach_qualcomm.c |  279 ++++++++++++++++++++++++++++++++++++++++++++
> >  4 files changed, 290 insertions(+), 1 deletions(-)
> >  create mode 100644 tools/hciattach_qualcomm.c
<snip>
> Ping

Sorry about forgetting about this one. Unfortunately it doesn't apply
anymore to bluez.git due to the ath3k patches that got merged earlier
today. So you'll need to fix the conflicts and resubmit. Other than that
the patch seems fine to me.

Johan

^ permalink raw reply

* BlueZ's A2DP sink role
From: Pavan Savoy @ 2010-08-18 20:22 UTC (permalink / raw)
  To: linux-bluetooth

As I understand, the A2DP sink role is @ audio/source.c and A2DP
source role is at sink.c ? (or what is called as the interfaces?..)
Also How do I test out a2dp sink role in BlueZ, any test audio-server
I can run ?

Thanks in advance.

^ permalink raw reply

* Re: [PATCH v2] Firmware download for Qualcomm Bluetooth devices
From: Ron Shaffer @ 2010-08-18 15:40 UTC (permalink / raw)
  To: Matthew Wilson; +Cc: linux-bluetooth, marcel, johan.hedberg
In-Reply-To: <1281713636-24955-1-git-send-email-mtwilson@codeaurora.org>

On 8/13/2010 10:33 AM, Matthew Wilson wrote:
> Configures device address from hciattach parameter.
> UART speed limited to 115200.
> Requires separate device specific firmware.
> ---
>  Makefile.tools             |    3 +-
>  tools/hciattach.c          |    8 ++
>  tools/hciattach.h          |    1 +
>  tools/hciattach_qualcomm.c |  279 ++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 290 insertions(+), 1 deletions(-)
>  create mode 100644 tools/hciattach_qualcomm.c
> 
> diff --git a/Makefile.tools b/Makefile.tools
> index 2dbf925..0ce7b75 100644
> --- a/Makefile.tools
> +++ b/Makefile.tools
> @@ -23,7 +23,8 @@ tools_l2ping_LDADD = lib/libbluetooth.la
>  tools_hciattach_SOURCES = tools/hciattach.c tools/hciattach.h \
>  						tools/hciattach_st.c \
>  						tools/hciattach_ti.c \
> -						tools/hciattach_tialt.c
> +						tools/hciattach_tialt.c \
> +						tools/hciattach_qualcomm.c
>  tools_hciattach_LDADD = lib/libbluetooth.la
>  
>  tools_hciconfig_SOURCES = tools/hciconfig.c tools/csr.h tools/csr.c \
> diff --git a/tools/hciattach.c b/tools/hciattach.c
> index 81aea7b..4d4b0a1 100644
> --- a/tools/hciattach.c
> +++ b/tools/hciattach.c
> @@ -299,6 +299,11 @@ static int texasalt(int fd, struct uart_t *u, struct termios *ti)
>  	return texasalt_init(fd, u->speed, ti);
>  }
>  
> +static int qualcomm(int fd, struct uart_t *u, struct termios *ti)
> +{
> +	return qualcomm_init(fd, u->speed, ti, u->bdaddr);
> +}
> +
>  static int read_check(int fd, void *buf, int count)
>  {
>  	int res;
> @@ -1073,6 +1078,9 @@ struct uart_t uart[] = {
>  	/* Broadcom BCM2035 */
>  	{ "bcm2035",    0x0A5C, 0x2035, HCI_UART_H4,   115200, 460800, FLOW_CTL, NULL, bcm2035  },
>  
> +	/* QUALCOMM BTS */
> +	{ "qualcomm",   0x0000, 0x0000, HCI_UART_H4,   115200, 115200, FLOW_CTL, NULL, qualcomm },
> +
>  	{ NULL, 0 }
>  };
>  
> diff --git a/tools/hciattach.h b/tools/hciattach.h
> index c0b80a1..3d5605b 100644
> --- a/tools/hciattach.h
> +++ b/tools/hciattach.h
> @@ -49,3 +49,4 @@ int texas_post(int fd, struct termios *ti);
>  int texasalt_init(int fd, int speed, struct termios *ti);
>  int stlc2500_init(int fd, bdaddr_t *bdaddr);
>  int bgb2xx_init(int dd, bdaddr_t *bdaddr);
> +int qualcomm_init(int fd, int speed, struct termios *ti, const char *bdaddr);
> diff --git a/tools/hciattach_qualcomm.c b/tools/hciattach_qualcomm.c
> new file mode 100644
> index 0000000..31ca3c8
> --- /dev/null
> +++ b/tools/hciattach_qualcomm.c
> @@ -0,0 +1,279 @@
> +/*
> + *
> + *  BlueZ - Bluetooth protocol stack for Linux
> + *
> + *  Copyright (C) 2005-2010  Marcel Holtmann <marcel@holtmann.org>
> + *  Copyright (c) 2010, Code Aurora Forum. All rights reserved.
> + *
> + *
> + *  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
> + *
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +
> +#include <stdio.h>
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <signal.h>
> +#include <syslog.h>
> +#include <termios.h>
> +#include <time.h>
> +#include <sys/time.h>
> +#include <sys/poll.h>
> +#include <sys/param.h>
> +#include <sys/ioctl.h>
> +#include <sys/socket.h>
> +#include <sys/uio.h>
> +
> +#include <bluetooth/bluetooth.h>
> +#include <bluetooth/hci.h>
> +#include <bluetooth/hci_lib.h>
> +
> +#include "hciattach.h"
> +
> +#define FAILIF(x, args...) do {   \
> +	if (x) {					  \
> +		fprintf(stderr, ##args);  \
> +		return -1;				  \
> +	}							  \
> +} while(0)
> +
> +typedef struct {
> +	uint8_t uart_prefix;
> +	hci_event_hdr hci_hdr;
> +	evt_cmd_complete cmd_complete;
> +	uint8_t status;
> +	uint8_t data[16];
> +} __attribute__((packed)) command_complete_t;
> +
> +
> +static int read_command_complete(int fd, unsigned short opcode, unsigned char len) {
> +	command_complete_t resp;
> +	unsigned char vsevent[512];
> +	int n;
> +
> +	/* Read reply. */
> +	n = read_hci_event(fd, vsevent, sizeof(vsevent));
> +	FAILIF(n < 0, "Failed to read response");
> +
> +	FAILIF(vsevent[1] != 0xFF, "Failed to read response");
> +
> +	n = read_hci_event(fd, (unsigned char *)&resp, sizeof(resp));
> +	FAILIF(n < 0, "Failed to read response");
> +
> +	FAILIF(resp.hci_hdr.evt != EVT_CMD_COMPLETE, /* event must be event-complete */
> +		   "Error in response: not a cmd-complete event, "
> +		   "but 0x%02x!\n", resp.hci_hdr.evt);
> +
> +	FAILIF(resp.hci_hdr.plen < 4, /* plen >= 4 for EVT_CMD_COMPLETE */
> +		   "Error in response: plen is not >= 4, but 0x%02x!\n",
> +		   resp.hci_hdr.plen);
> +
> +	/* cmd-complete event: opcode */
> +	FAILIF(resp.cmd_complete.opcode != 0,
> +		   "Error in response: opcode is 0x%04x, not 0!",
> +		   resp.cmd_complete.opcode);
> +
> +	return resp.status == 0 ? 0 : -1;
> +}
> +
> +static int qualcomm_load_firmware(int fd, const char *firmware, const char *bdaddr_s) {
> +
> +	int fw = open(firmware, O_RDONLY);
> +
> +	fprintf(stdout, "Opening firmware file: %s\n", firmware);
> +
> +	FAILIF(fw < 0,
> +		   "Could not open firmware file %s: %s (%d).\n",
> +		   firmware, strerror(errno), errno);
> +
> +	fprintf(stdout, "Uploading firmware...\n");
> +	do {
> +		/* Read each command and wait for a response. */
> +		unsigned char data[1024];
> +		unsigned char cmdp[1 + sizeof(hci_command_hdr)];
> +		hci_command_hdr *cmd = (hci_command_hdr *)(cmdp + 1);
> +		int nr;
> +		nr = read(fw, cmdp, sizeof(cmdp));
> +		if (!nr)
> +			break;
> +		FAILIF(nr != sizeof(cmdp), "Could not read H4 + HCI header!\n");
> +		FAILIF(*cmdp != HCI_COMMAND_PKT, "Command is not an H4 command packet!\n");
> +
> +		FAILIF(read(fw, data, cmd->plen) != cmd->plen,
> +			   "Could not read %d bytes of data for command with opcode %04x!\n",
> +			   cmd->plen,
> +			   cmd->opcode);
> +
> +		if ((data[0] == 1) && (data[1] == 2) && (data[2] == 6)) {
> +			bdaddr_t bdaddr;
> +			if (bdaddr_s != NULL) {
> +				(void) str2ba(bdaddr_s, &bdaddr);
> +				memcpy(&data[3], &bdaddr, sizeof(bdaddr_t));
> +			}
> +		}
> +
> +		{
> +			int nw;
> +			struct iovec iov_cmd[2];
> +			iov_cmd[0].iov_base = cmdp;
> +			iov_cmd[0].iov_len	= sizeof(cmdp);
> +			iov_cmd[1].iov_base = data;
> +			iov_cmd[1].iov_len	= cmd->plen;
> +			nw = writev(fd, iov_cmd, 2);
> +			FAILIF(nw != (int) sizeof(cmdp) + cmd->plen,
> +				   "Could not send entire command (sent only %d bytes)!\n",
> +				   nw);
> +		}
> +
> +		/* Wait for response */
> +		if (read_command_complete(fd,
> +					  cmd->opcode,
> +					  cmd->plen) < 0) {
> +			return -1;
> +		}
> +
> +	} while(1);
> +	fprintf(stdout, "Firmware upload successful.\n");
> +
> +	close(fw);
> +	return 0;
> +}
> +
> +int qualcomm_init(int fd, int speed, struct termios *ti, const char *bdaddr)
> +{
> +	struct timespec tm = {0, 50000};
> +	char cmd[5];
> +	unsigned char resp[100];		/* Response */
> +	char fw[100];
> +	int n;
> +
> +	memset(resp,'\0', 100);
> +
> +	/* Get Manufacturer and LMP version */
> +	cmd[0] = HCI_COMMAND_PKT;
> +	cmd[1] = 0x01;
> +	cmd[2] = 0x10;
> +	cmd[3] = 0x00;
> +
> +	do {
> +		n = write(fd, cmd, 4);
> +		if (n < 0) {
> +			perror("Failed to write init command (READ_LOCAL_VERSION_INFORMATION)");
> +			return -1;
> +		}
> +		if (n < 4) {
> +			fprintf(stderr, "Wanted to write 4 bytes, could only write %d. Stop\n", n);
> +			return -1;
> +		}
> +
> +		/* Read reply. */
> +		if (read_hci_event(fd, resp, 100) < 0) {
> +			perror("Failed to read init response (READ_LOCAL_VERSION_INFORMATION)");
> +			return -1;
> +		}
> +
> +		/* Wait for command complete event for our Opcode */
> +	} while (resp[4] != cmd[1] && resp[5] != cmd[2]);
> +
> +	/* Verify manufacturer */
> +	if ((resp[11] & 0xFF) != 0x1d)
> +		fprintf(stderr,"WARNING : module's manufacturer is not Qualcomm\n");
> +
> +	/* Print LMP version */
> +	fprintf(stderr, "Qualcomm module LMP version : 0x%02x\n", resp[10] & 0xFF);
> +
> +	/* Print LMP subversion */
> +	{
> +		unsigned short lmp_subv = resp[13] | (resp[14] << 8);
> +
> +		fprintf(stderr, "Qualcomm module LMP sub-version : 0x%04x\n", lmp_subv);
> +
> +	}
> +
> +	/* Get SoC type */
> +	cmd[0] = HCI_COMMAND_PKT;
> +	cmd[1] = 0x00;
> +	cmd[2] = 0xFC;
> +	cmd[3] = 0x01;
> +	cmd[4] = 0x06;
> +
> +	do {
> +		n = write(fd, cmd, 5);
> +		if (n < 0) {
> +			perror("Failed to write init command");
> +			return -1;
> +		}
> +		if (n < 5) {
> +			fprintf(stderr, "Wanted to write 5 bytes, could only write %d. Stop\n", n);
> +			return -1;
> +		}
> +
> +		/* Read reply. */
> +		if ((n = read_hci_event(fd, resp, 100)) < 0) {
> +			perror("Failed to read init response");
> +			return -1;
> +		}
> +
> +	} while (resp[3] != 0 && resp[4] != 2);
> +
> +	snprintf(fw, sizeof(fw),
> +		"/etc/firmware/%c%c%c%c%c%c_%c%c%c%c.bin",
> +		resp[18], resp[19], resp[20], resp[21],
> +		resp[22], resp[23],
> +		resp[32], resp[33], resp[34], resp[35]);
> +
> +	/* Wait for command complete event for our Opcode */
> +	if (read_hci_event(fd, resp, 100) < 0) {
> +		perror("Failed to read init response");
> +		return -1;
> +	}
> +
> +	qualcomm_load_firmware(fd, fw, bdaddr);
> +
> +	/* Reset */
> +	cmd[0] = HCI_COMMAND_PKT;
> +	cmd[1] = 0x03;
> +	cmd[2] = 0x0C;
> +	cmd[3] = 0x00;
> +
> +	do {
> +		n = write(fd, cmd, 4);
> +		if (n < 0) {
> +			perror("Failed to write reset command");
> +			return -1;
> +		}
> +		if (n < 4) {
> +			fprintf(stderr, "Wanted to write 4 bytes, could only write %d. Stop\n", n);
> +			return -1;
> +		}
> +
> +		/* Read reply. */
> +		if ((n = read_hci_event(fd, resp, 100)) < 0) {
> +			perror("Failed to read reset response");
> +			return -1;
> +		}
> +
> +	} while (resp[4] != cmd[1] && resp[5] != cmd[2]);
> +
> +	nanosleep(&tm, NULL);
> +	return 0;
> +}

Ping

-- 
Ron Shaffer
Employee of the Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply


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