Linux bluetooth development
 help / color / mirror / Atom feed
* Re: Locking issue when running out of credits in 6lowpan connection
From: Peter Hurley @ 2014-10-17 13:01 UTC (permalink / raw)
  To: Jukka Rissanen, linux-bluetooth; +Cc: Johan Hedberg, Marcel Holtmann
In-Reply-To: <1413549465.2705.149.camel@jrissane-mobl.ger.corp.intel.com>

On 10/17/2014 08:37 AM, Jukka Rissanen wrote:
> Hi,
> 
> I have seen the deadlock warnings from lockdep when pushing lot of data
> through a 6lowpan link. I was converting the read/write locks in 6lowpan
> to use RCU and it helped the situation slightly as I see the lockdep
> warning less now. I will send these patches soon to ml.
> 
> I noticed that if I add huge amount of credits for the connection, then
> the issue is not seen. So when the credits are exhausted in receiving
> end, the l2cap sends message to other end, see the backtrace below
> (l2cap_recv_frame() followed by l2cap_do_send()).
> 
> At the same time a lot of data is pushed through the 6lowpan link. These
> operations then conflict as seen in the log below.
> 
> One way to reproduce the issue is like this:
> 
> host1# nc -6 -l 9999 > /dev/null
> 
> host2# nc -6 fe80::21e:abff:fe4c:5257%bt0 9999 < /dev/urandom
> 
> 
> Any ideas how to solve this?

The spin_lock() in hci_queue_acl() still needs to be spin_lock_bh().

Regards,
Peter Hurley

> Is there a bug in l2cap/hci layers or am I doing something wrong with
> 6lowpan connection?
> 
> 
>  =================================
>  [ INFO: inconsistent lock state ]
>  3.17.0-rc1-bt6lowpan #1 Not tainted
>  ---------------------------------
>  inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage.
>  kworker/u3:1/384 [HC0[0]:SC0[0]:HE1:SE1] takes:
>   (&(&list->lock)->rlock#6){+.?...}, at: [<f831dd4c>] hci_send_acl
> +0xac/0x290 [bluetooth]
>  {IN-SOFTIRQ-W} state was registered at:
>    [<c10915a3>] __lock_acquire+0x6d3/0x1d20
>    [<c109325d>] lock_acquire+0x9d/0x140
>    [<c1889c25>] _raw_spin_lock+0x45/0x80
>    [<f831dd4c>] hci_send_acl+0xac/0x290 [bluetooth]
>    [<f833efe0>] l2cap_do_send+0x60/0x100 [bluetooth]
>    [<f8342bb0>] l2cap_chan_send+0x7f0/0x10e0 [bluetooth]
>    [<f88dc8ee>] send_pkt+0x4e/0xa0 [bluetooth_6lowpan]
>    [<f88dcd6e>] bt_xmit+0x42e/0x890 [bluetooth_6lowpan]
>    [<c17742f4>] dev_hard_start_xmit+0x344/0x670
>    [<c17749ad>] __dev_queue_xmit+0x38d/0x680
>    [<c1774caf>] dev_queue_xmit+0xf/0x20
>    [<c177b8b0>] neigh_connected_output+0x130/0x1a0
>    [<c1812a63>] ip6_finish_output2+0x173/0x8c0
>    [<c18182db>] ip6_finish_output+0x7b/0x1b0
>    [<c18184a7>] ip6_output+0x97/0x2a0
>    [<c183a46b>] mld_sendpack+0x5eb/0x650
>    [<c183acc1>] mld_ifc_timer_expire+0x191/0x2f0
>    [<c10ac385>] call_timer_fn+0x85/0x1c0
>    [<c10acb72>] run_timer_softirq+0x192/0x280
>    [<c104fd84>] __do_softirq+0xd4/0x300
>    [<c10049fc>] do_softirq_own_stack+0x2c/0x40
>    [<c1050136>] irq_exit+0x86/0xb0
>    [<c188bd98>] smp_apic_timer_interrupt+0x38/0x50
>    [<c188b6ce>] apic_timer_interrupt+0x32/0x38
>  irq event stamp: 17003
>  hardirqs last  enabled at (17003): [<c188a065>]
> _raw_spin_unlock_irqrestore+0x55/0x70
>  hardirqs last disabled at (17002): [<c1889e03>] _raw_spin_lock_irqsave
> +0x23/0x90
>  softirqs last  enabled at (6648): [<c104ff5c>] __do_softirq+0x2ac/0x300
>  softirqs last disabled at (6619): [<c10049fc>] do_softirq_own_stack
> +0x2c/0x40
>  
>  other info that might help us debug this:
>   Possible unsafe locking scenario:
>  
>         CPU0
>         ----
>    lock(&(&list->lock)->rlock#6);
>    <Interrupt>
>      lock(&(&list->lock)->rlock#6);
>  
>   *** DEADLOCK ***
>  
>  3 locks held by kworker/u3:1/384:
>   #0:  ("%s"hdev->name#2){.+.+.+}, at: [<c10622c3>] process_one_work
> +0x113/0x4a0
>   #1:  ((&hdev->rx_work)){+.+.+.}, at: [<c10622c3>] process_one_work
> +0x113/0x4a0
>   #2:  (&chan->lock){+.+.+.}, at: [<f833e569>] l2cap_get_chan_by_dcid
> +0x89/0x90 [bluetooth]
>  
>  stack backtrace:
>  CPU: 0 PID: 384 Comm: kworker/u3:1 Not tainted 3.17.0-rc1-bt6lowpan #1
>  Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox
> 12/01/2006
>  Workqueue: hci0 hci_rx_work [bluetooth]
>   f4700000 00000000 f466bb90 c18821c1 c2344320 f466bbb0 c1880a94
> c1ad9264
>   c1ad9201 c1ad95f8 f4700614 00000006 c108e0c0 f466bbe0 c108ea8c
> 00000006
>   f4700000 f466bffc 323ca8b2 0000002a 00000004 f4700000 f4700618
> 00000003
>  Call Trace:
>   [<c18821c1>] dump_stack+0x4b/0x75
>   [<c1880a94>] print_usage_bug.part.36+0x209/0x213
>   [<c108e0c0>] ? check_usage_forwards+0x110/0x110
>   [<c108ea8c>] mark_lock+0x11c/0x6e0
>   [<c10915e4>] __lock_acquire+0x714/0x1d20
>   [<c1004b6f>] ? dump_trace+0xcf/0x1f0
>   [<c100a5f8>] ? sched_clock+0x8/0x10
>   [<c1075da9>] ? sched_clock_local+0x49/0x180
>   [<c109325d>] lock_acquire+0x9d/0x140
>   [<f831dd4c>] ? hci_send_acl+0xac/0x290 [bluetooth]
>   [<c1889c25>] _raw_spin_lock+0x45/0x80
>   [<f831dd4c>] ? hci_send_acl+0xac/0x290 [bluetooth]
>   [<f831dd4c>] hci_send_acl+0xac/0x290 [bluetooth]
>   [<c108f0b4>] ? mark_held_locks+0x64/0x90
>   [<c188a065>] ? _raw_spin_unlock_irqrestore+0x55/0x70
>   [<f833efe0>] l2cap_do_send+0x60/0x100 [bluetooth]
>   [<c108f32b>] ? trace_hardirqs_on+0xb/0x10
>   [<c188a051>] ? _raw_spin_unlock_irqrestore+0x41/0x70
>   [<c1763125>] ? skb_dequeue+0x45/0x60
>   [<f8349785>] l2cap_recv_frame+0x23e5/0x2dc0 [bluetooth]
>   [<c1075da9>] ? sched_clock_local+0x49/0x180
>   [<c100a5f8>] ? sched_clock+0x8/0x10
>   [<c1075da9>] ? sched_clock_local+0x49/0x180
>   [<c10761ef>] ? sched_clock_cpu+0x10f/0x160
>   [<c107183b>] ? get_parent_ip+0xb/0x40
>   [<c10718bb>] ? preempt_count_add+0x4b/0xa0
>   [<c13d09e2>] ? debug_smp_processor_id+0x12/0x20
>   [<c108cc04>] ? get_lock_stats+0x24/0x40
>   [<c108f0b4>] ? mark_held_locks+0x64/0x90
>   [<c188716d>] ? __mutex_unlock_slowpath+0xcd/0x1b0
>   [<c13d09ff>] ? __this_cpu_preempt_check+0xf/0x20
>   [<c108f1d4>] ? trace_hardirqs_on_caller+0xf4/0x240
>   [<c108c9a6>] ? trace_hardirqs_off_caller+0xb6/0x160
>   [<f834b6a9>] l2cap_recv_acldata+0x2f9/0x340 [bluetooth]
>   [<f8316a13>] ? hci_rx_work+0x113/0x4a0 [bluetooth]
>   [<f8316c69>] hci_rx_work+0x369/0x4a0 [bluetooth]
>   [<f8316a13>] ? hci_rx_work+0x113/0x4a0 [bluetooth]
>   [<c106234a>] process_one_work+0x19a/0x4a0
>   [<c10622c3>] ? process_one_work+0x113/0x4a0
>   [<c10629e9>] worker_thread+0x39/0x440
>   [<c10629b0>] ? init_pwq+0xc0/0xc0
>   [<c1066dc8>] kthread+0xa8/0xc0
>   [<c108f32b>] ? trace_hardirqs_on+0xb/0x10
>   [<c188ad01>] ret_from_kernel_thread+0x21/0x30
>   [<c1066d20>] ? kthread_create_on_node+0x160/0x160

^ permalink raw reply

* RE: [PATCH ] obexd/mas: Add Support fo MSETime filter
From: Bharat Bhusan Panda @ 2014-10-17 12:54 UTC (permalink / raw)
  To: 'Luiz Augusto von Dentz'; +Cc: linux-bluetooth, cpgs
In-Reply-To: <CABBYNZJ5Kq4z67EKhnH9pmL02jkW3begif2=s=qxYH+VeNBSzw@mail.gmail.com>

Hi Luiz,

> > ---
> >  obexd/plugins/mas.c | 28 ++++++++++++++++++++++++++++
> >  1 file changed, 28 insertions(+)
> >
> > diff --git a/obexd/plugins/mas.c b/obexd/plugins/mas.c index
> > fb97fe3..7f14bf8 100644
> > --- a/obexd/plugins/mas.c
> > +++ b/obexd/plugins/mas.c
> > @@ -30,6 +30,7 @@
> >  #include <glib.h>
> >  #include <fcntl.h>
> >  #include <inttypes.h>
> > +#include <sys/time.h>
> >
> >  #include <gobex/gobex.h>
> >  #include <gobex/gobex-apparam.h>
> > @@ -228,6 +229,25 @@ static void
> g_string_append_escaped_printf(GString *string,
> >         va_end(ap);
> >  }
> >
> > +static gchar *get_mse_timestamp(void) {
> > +       struct timeval time_val;
> > +       struct tm ltime;
> > +       gchar *local_ts;
> > +
> > +       gettimeofday(&time_val, NULL);
> > +
> > +       if (!localtime_r(&time_val.tv_sec, &ltime))
> > +               return NULL;
> > +
> > +       local_ts = g_strdup_printf("%04d%02d%02dT%02d%02d%02d",
> > +                                       ltime.tm_year + 1900, ltime.tm_mon + 1,
> > +                                       ltime.tm_mday, ltime.tm_hour,
> > +                                       ltime.tm_min, ltime.tm_sec);
> > +
> > +       return local_ts;
> > +}
> > +
> >  static const char *yesorno(gboolean a)  {
> >         if (a)
> > @@ -243,6 +263,7 @@ static void get_messages_listing_cb(void *session,
> > int err, uint16_t size,  {
> >         struct mas_session *mas = user_data;
> >         uint16_t max = 1024;
> > +       gchar *mse_time;
> >
> >         if (err < 0 && err != -EAGAIN) {
> >                 obex_object_set_io_flags(mas, G_IO_ERR, err); @@
> > -358,6 +379,13 @@ proceed:
> >                 mas->outparams = g_obex_apparam_set_uint8(mas->outparams,
> >                                                 MAP_AP_NEWMESSAGE,
> >                                                 newmsg ? 1 : 0);
> > +               /* Response to report the local time of MSE */
> > +               mse_time = get_mse_timestamp();
> > +               if (mse_time) {
> > +                       g_obex_apparam_set_string(mas->outparams,
> > +                                               MAP_AP_MSETIME, mse_time);
> > +                       g_free(mse_time);
> > +               }
> >         }
> >
> >         if (err != -EAGAIN)
> > --
> > 1.9.1
> 
> Does this works when the system has timedated running, perhaps we need
> to know if the time is set in UTC or not and in case of the later we probably
> need to provide the timezone as well.
>
Yes it works with system-timedated running. Only thing need to handle here is for different timezone other than UTC/GMT.
In further patches I will try to provide support with handling other timezones as well.
 
Best Regards,
Bharat



^ permalink raw reply

* [PATCH 6/6] bnep: Fix bnep_add_to_bridge() errno usage
From: Andrei Emeltchenko @ 2014-10-17 12:54 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1413550450-16577-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Avoid errno be overwritten and make code consistent.
---
 profiles/network/bnep.c | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index 18051c3..c40ed69 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -491,7 +491,7 @@ static int bnep_add_to_bridge(const char *devname, const char *bridge)
 {
 	int ifindex;
 	struct ifreq ifr;
-	int sk, err;
+	int sk, err = 0;
 
 	if (!devname || !bridge)
 		return -EINVAL;
@@ -506,16 +506,16 @@ static int bnep_add_to_bridge(const char *devname, const char *bridge)
 	strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
 	ifr.ifr_ifindex = ifindex;
 
-	err = ioctl(sk, SIOCBRADDIF, &ifr);
+	if (ioctl(sk, SIOCBRADDIF, &ifr) < 0) {
+		err = -errno;
+		error("bnep: Can't add %s to the bridge %s: %s(%d)",
+					devname, bridge, strerror(-err), -err);
+	} else
+		info("bridge %s: interface %s added", bridge, devname);
 
 	close(sk);
 
-	if (err < 0)
-		return err;
-
-	info("bridge %s: interface %s added", bridge, devname);
-
-	return 0;
+	return err;
 }
 
 static int bnep_del_from_bridge(const char *devname, const char *bridge)
@@ -561,11 +561,10 @@ int bnep_server_add(int sk, uint16_t dst, char *bridge, char *iface,
 	if (err < 0)
 		return err;
 
-	if (bnep_add_to_bridge(iface, bridge) < 0) {
-		error("bnep: Can't add %s to the bridge %s: %s(%d)",
-					iface, bridge, strerror(errno), errno);
+	err = bnep_add_to_bridge(iface, bridge);
+	if (err < 0) {
 		bnep_conndel(addr);
-		return -errno;
+		return err;
 	}
 
 	return bnep_if_up(iface);
-- 
1.9.1


^ permalink raw reply related

* [PATCH 5/6] bnep: Fix incorrect ioctl() check
From: Andrei Emeltchenko @ 2014-10-17 12:54 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1413550450-16577-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

---
 profiles/network/bnep.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index b8d2985..18051c3 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -162,7 +162,7 @@ static int bnep_conndel(const bdaddr_t *dst)
 	memset(&req, 0, sizeof(req));
 	baswap((bdaddr_t *)&req.dst, dst);
 	req.flags = 0;
-	if (ioctl(ctl, BNEPCONNDEL, &req)) {
+	if (ioctl(ctl, BNEPCONNDEL, &req) < 0) {
 		int err = -errno;
 		error("bnep: Failed to kill connection: %s (%d)",
 						strerror(-err), -err);
-- 
1.9.1


^ permalink raw reply related

* [PATCH 4/6] bnep: Fix incorrect errno use and avoid double printing
From: Andrei Emeltchenko @ 2014-10-17 12:54 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1413550450-16577-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Fixes bnep_if_up() usage since it already prints error message and
returns errno.
---
 profiles/network/bnep.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index 3a6e3a4..b8d2985 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -319,7 +319,6 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
 		goto failed;
 
 	if (bnep_if_up(session->iface)) {
-		error("bnep: could not up %s", session->iface);
 		bnep_conndel(&session->dst_addr);
 		goto failed;
 	}
@@ -569,13 +568,7 @@ int bnep_server_add(int sk, uint16_t dst, char *bridge, char *iface,
 		return -errno;
 	}
 
-	if (bnep_if_up(iface) < 0) {
-		error("bnep: Can't up the interface %s: %s(%d)",
-						iface, strerror(errno), errno);
-		return -errno;
-	}
-
-	return 0;
+	return bnep_if_up(iface);
 }
 
 void bnep_server_delete(char *bridge, char *iface, const bdaddr_t *addr)
-- 
1.9.1


^ permalink raw reply related

* [PATCH 3/6] bnep: Refactor bnep_if_up() returning -errno
From: Andrei Emeltchenko @ 2014-10-17 12:54 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1413550450-16577-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Some functions are using bnep_if_up() like bnep_server_add() referring
directly to errno which may be overwritten already.
---
 profiles/network/bnep.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index e17a130..3a6e3a4 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -195,7 +195,7 @@ static int bnep_connadd(int sk, uint16_t role, char *dev)
 static int bnep_if_up(const char *devname)
 {
 	struct ifreq ifr;
-	int sk, err;
+	int sk, err = 0;
 
 	sk = socket(AF_INET, SOCK_DGRAM, 0);
 
@@ -205,16 +205,15 @@ static int bnep_if_up(const char *devname)
 	ifr.ifr_flags |= IFF_UP;
 	ifr.ifr_flags |= IFF_MULTICAST;
 
-	err = ioctl(sk, SIOCSIFFLAGS, (void *) &ifr);
+	if (ioctl(sk, SIOCSIFFLAGS, (void *) &ifr) < 0) {
+		err = -errno;
+		error("bnep: Could not bring up %s: %s(%d)",
+				devname, strerror(-err), -err);
+	}
 
 	close(sk);
 
-	if (err < 0) {
-		error("bnep: Could not bring up %s", devname);
-		return err;
-	}
-
-	return 0;
+	return err;
 }
 
 static int bnep_if_down(const char *devname)
-- 
1.9.1


^ permalink raw reply related

* [PATCH 2/6] bnep: Make error logging more descriptive
From: Andrei Emeltchenko @ 2014-10-17 12:54 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1413550450-16577-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Add "bnep" before error message.
---
 profiles/network/bnep.c | 36 ++++++++++++++++++------------------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index 035beb1..e17a130 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -140,7 +140,7 @@ int bnep_init(void)
 		if (err == -EPROTONOSUPPORT)
 			warn("kernel lacks bnep-protocol support");
 		else
-			error("Failed to open control socket: %s (%d)",
+			error("bnep: Failed to open control socket: %s (%d)",
 						strerror(-err), -err);
 
 		return err;
@@ -164,7 +164,7 @@ static int bnep_conndel(const bdaddr_t *dst)
 	req.flags = 0;
 	if (ioctl(ctl, BNEPCONNDEL, &req)) {
 		int err = -errno;
-		error("Failed to kill connection: %s (%d)",
+		error("bnep: Failed to kill connection: %s (%d)",
 						strerror(-err), -err);
 		return err;
 	}
@@ -183,7 +183,7 @@ static int bnep_connadd(int sk, uint16_t role, char *dev)
 	req.role = role;
 	if (ioctl(ctl, BNEPCONNADD, &req) < 0) {
 		int err = -errno;
-		error("Failed to add device %s: %s(%d)",
+		error("bnep: Failed to add device %s: %s(%d)",
 				dev, strerror(-err), -err);
 		return err;
 	}
@@ -210,7 +210,7 @@ static int bnep_if_up(const char *devname)
 	close(sk);
 
 	if (err < 0) {
-		error("Could not bring up %s", devname);
+		error("bnep: Could not bring up %s", devname);
 		return err;
 	}
 
@@ -235,7 +235,7 @@ static int bnep_if_down(const char *devname)
 	close(sk);
 
 	if (err < 0) {
-		error("Could not bring down %s", devname);
+		error("bnep: Could not bring down %s", devname);
 		return err;
 	}
 
@@ -272,7 +272,7 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
 	}
 
 	if (cond & (G_IO_HUP | G_IO_ERR)) {
-		error("Hangup or error on l2cap server socket");
+		error("bnep: Hangup or error on l2cap server socket");
 		goto failed;
 	}
 
@@ -280,25 +280,25 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
 	memset(pkt, 0, BNEP_MTU);
 	r = read(sk, pkt, sizeof(pkt) - 1);
 	if (r < 0) {
-		error("IO Channel read error");
+		error("bnep: IO Channel read error");
 		goto failed;
 	}
 
 	if (r == 0) {
-		error("No packet received on l2cap socket");
+		error("bnep: No packet received on l2cap socket");
 		goto failed;
 	}
 
 	errno = EPROTO;
 
 	if ((size_t) r < sizeof(*rsp)) {
-		error("Packet received is not bnep type");
+		error("bnep: Packet received is not bnep type");
 		goto failed;
 	}
 
 	rsp = (void *) pkt;
 	if (rsp->type != BNEP_CONTROL) {
-		error("Packet received is not bnep type");
+		error("bnep: Packet received is not bnep type");
 		goto failed;
 	}
 
@@ -307,7 +307,7 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
 
 	r = ntohs(rsp->resp);
 	if (r != BNEP_SUCCESS) {
-		error("bnep failed");
+		error("bnep: failed");
 		goto failed;
 	}
 
@@ -320,7 +320,7 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
 		goto failed;
 
 	if (bnep_if_up(session->iface)) {
-		error("could not up %s", session->iface);
+		error("bnep: could not up %s", session->iface);
 		bnep_conndel(&session->dst_addr);
 		goto failed;
 	}
@@ -359,7 +359,7 @@ static int bnep_setup_conn_req(struct bnep *session)
 
 	fd = g_io_channel_unix_get_fd(session->io);
 	if (write(fd, pkt, sizeof(*req) + sizeof(*s)) < 0) {
-		error("bnep connection req send failed: %s", strerror(errno));
+		error("bnep: connection req send failed: %s", strerror(errno));
 		return -errno;
 	}
 
@@ -373,9 +373,9 @@ static gboolean bnep_conn_req_to(gpointer user_data)
 	struct bnep *session = user_data;
 
 	if (session->attempts == CON_SETUP_RETRIES) {
-		error("Too many bnep connection attempts");
+		error("bnep: Too many bnep connection attempts");
 	} else {
-		error("bnep connection setup TO, retrying...");
+		error("bnep: connection setup TO, retrying...");
 		if (bnep_setup_conn_req(session) == 0)
 			return TRUE;
 	}
@@ -444,7 +444,7 @@ int bnep_connect(struct bnep *session, bnep_connect_cb conn_cb, void *data)
 	bt_io_get(session->io, &gerr, BT_IO_OPT_DEST_BDADDR, &session->dst_addr,
 							BT_IO_OPT_INVALID);
 	if (gerr) {
-		error("%s", gerr->message);
+		error("bnep: connect failed: %s", gerr->message);
 		g_error_free(gerr);
 		return -EINVAL;
 	}
@@ -564,14 +564,14 @@ int bnep_server_add(int sk, uint16_t dst, char *bridge, char *iface,
 		return err;
 
 	if (bnep_add_to_bridge(iface, bridge) < 0) {
-		error("Can't add %s to the bridge %s: %s(%d)",
+		error("bnep: Can't add %s to the bridge %s: %s(%d)",
 					iface, bridge, strerror(errno), errno);
 		bnep_conndel(addr);
 		return -errno;
 	}
 
 	if (bnep_if_up(iface) < 0) {
-		error("Can't up the interface %s: %s(%d)",
+		error("bnep: Can't up the interface %s: %s(%d)",
 						iface, strerror(errno), errno);
 		return -errno;
 	}
-- 
1.9.1


^ permalink raw reply related

* [PATCH 1/6] bnep: Avoid double error print for bnep_connadd()
From: Andrei Emeltchenko @ 2014-10-17 12:54 UTC (permalink / raw)
  To: linux-bluetooth

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

This avoids double printing the same error with bnep connection add
ioctl.
---
 profiles/network/bnep.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index 136709d..035beb1 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -316,10 +316,8 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
 	setsockopt(sk, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));
 
 	sk = g_io_channel_unix_get_fd(session->io);
-	if (bnep_connadd(sk, session->src, session->iface)) {
-		error("bnep conn could not be added");
+	if (bnep_connadd(sk, session->src, session->iface) < 0)
 		goto failed;
-	}
 
 	if (bnep_if_up(session->iface)) {
 		error("could not up %s", session->iface);
@@ -556,14 +554,14 @@ static int bnep_del_from_bridge(const char *devname, const char *bridge)
 int bnep_server_add(int sk, uint16_t dst, char *bridge, char *iface,
 						const bdaddr_t *addr)
 {
+	int err;
+
 	if (!bridge || !iface || !addr)
 		return -EINVAL;
 
-	if (bnep_connadd(sk, dst, iface) < 0) {
-		error("Can't add connection to the bridge %s: %s(%d)",
-						bridge, strerror(errno), errno);
-		return -errno;
-	}
+	err = bnep_connadd(sk, dst, iface);
+	if (err < 0)
+		return err;
 
 	if (bnep_add_to_bridge(iface, bridge) < 0) {
 		error("Can't add %s to the bridge %s: %s(%d)",
-- 
1.9.1


^ permalink raw reply related

* [PATCH] hciattach: Add sleep|nosleep keyword
From: Andrei Emeltchenko @ 2014-10-17 12:48 UTC (permalink / raw)
  To: linux-bluetooth

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

---
 tools/hciattach.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/hciattach.c b/tools/hciattach.c
index d8ef7e7..808bbac 100644
--- a/tools/hciattach.c
+++ b/tools/hciattach.c
@@ -1276,7 +1276,9 @@ static void usage(void)
 {
 	printf("hciattach - HCI UART driver initialization utility\n");
 	printf("Usage:\n");
-	printf("\thciattach [-n] [-p] [-b] [-r] [-t timeout] [-s initial_speed] <tty> <type | id> [speed] [flow|noflow] [bdaddr]\n");
+	printf("\thciattach [-n] [-p] [-b] [-r] [-t timeout] [-s initial_speed]"
+			" <tty> <type | id> [speed] [flow|noflow]"
+			" [sleep|nosleep] [bdaddr]\n");
 	printf("\thciattach -l\n");
 }
 
-- 
1.9.1


^ permalink raw reply related

* Locking issue when running out of credits in 6lowpan connection
From: Jukka Rissanen @ 2014-10-17 12:37 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Johan Hedberg, Marcel Holtmann

Hi,

I have seen the deadlock warnings from lockdep when pushing lot of data
through a 6lowpan link. I was converting the read/write locks in 6lowpan
to use RCU and it helped the situation slightly as I see the lockdep
warning less now. I will send these patches soon to ml.

I noticed that if I add huge amount of credits for the connection, then
the issue is not seen. So when the credits are exhausted in receiving
end, the l2cap sends message to other end, see the backtrace below
(l2cap_recv_frame() followed by l2cap_do_send()).

At the same time a lot of data is pushed through the 6lowpan link. These
operations then conflict as seen in the log below.

One way to reproduce the issue is like this:

host1# nc -6 -l 9999 > /dev/null

host2# nc -6 fe80::21e:abff:fe4c:5257%bt0 9999 < /dev/urandom


Any ideas how to solve this?

Is there a bug in l2cap/hci layers or am I doing something wrong with
6lowpan connection?


 =================================
 [ INFO: inconsistent lock state ]
 3.17.0-rc1-bt6lowpan #1 Not tainted
 ---------------------------------
 inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage.
 kworker/u3:1/384 [HC0[0]:SC0[0]:HE1:SE1] takes:
  (&(&list->lock)->rlock#6){+.?...}, at: [<f831dd4c>] hci_send_acl
+0xac/0x290 [bluetooth]
 {IN-SOFTIRQ-W} state was registered at:
   [<c10915a3>] __lock_acquire+0x6d3/0x1d20
   [<c109325d>] lock_acquire+0x9d/0x140
   [<c1889c25>] _raw_spin_lock+0x45/0x80
   [<f831dd4c>] hci_send_acl+0xac/0x290 [bluetooth]
   [<f833efe0>] l2cap_do_send+0x60/0x100 [bluetooth]
   [<f8342bb0>] l2cap_chan_send+0x7f0/0x10e0 [bluetooth]
   [<f88dc8ee>] send_pkt+0x4e/0xa0 [bluetooth_6lowpan]
   [<f88dcd6e>] bt_xmit+0x42e/0x890 [bluetooth_6lowpan]
   [<c17742f4>] dev_hard_start_xmit+0x344/0x670
   [<c17749ad>] __dev_queue_xmit+0x38d/0x680
   [<c1774caf>] dev_queue_xmit+0xf/0x20
   [<c177b8b0>] neigh_connected_output+0x130/0x1a0
   [<c1812a63>] ip6_finish_output2+0x173/0x8c0
   [<c18182db>] ip6_finish_output+0x7b/0x1b0
   [<c18184a7>] ip6_output+0x97/0x2a0
   [<c183a46b>] mld_sendpack+0x5eb/0x650
   [<c183acc1>] mld_ifc_timer_expire+0x191/0x2f0
   [<c10ac385>] call_timer_fn+0x85/0x1c0
   [<c10acb72>] run_timer_softirq+0x192/0x280
   [<c104fd84>] __do_softirq+0xd4/0x300
   [<c10049fc>] do_softirq_own_stack+0x2c/0x40
   [<c1050136>] irq_exit+0x86/0xb0
   [<c188bd98>] smp_apic_timer_interrupt+0x38/0x50
   [<c188b6ce>] apic_timer_interrupt+0x32/0x38
 irq event stamp: 17003
 hardirqs last  enabled at (17003): [<c188a065>]
_raw_spin_unlock_irqrestore+0x55/0x70
 hardirqs last disabled at (17002): [<c1889e03>] _raw_spin_lock_irqsave
+0x23/0x90
 softirqs last  enabled at (6648): [<c104ff5c>] __do_softirq+0x2ac/0x300
 softirqs last disabled at (6619): [<c10049fc>] do_softirq_own_stack
+0x2c/0x40
 
 other info that might help us debug this:
  Possible unsafe locking scenario:
 
        CPU0
        ----
   lock(&(&list->lock)->rlock#6);
   <Interrupt>
     lock(&(&list->lock)->rlock#6);
 
  *** DEADLOCK ***
 
 3 locks held by kworker/u3:1/384:
  #0:  ("%s"hdev->name#2){.+.+.+}, at: [<c10622c3>] process_one_work
+0x113/0x4a0
  #1:  ((&hdev->rx_work)){+.+.+.}, at: [<c10622c3>] process_one_work
+0x113/0x4a0
  #2:  (&chan->lock){+.+.+.}, at: [<f833e569>] l2cap_get_chan_by_dcid
+0x89/0x90 [bluetooth]
 
 stack backtrace:
 CPU: 0 PID: 384 Comm: kworker/u3:1 Not tainted 3.17.0-rc1-bt6lowpan #1
 Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox
12/01/2006
 Workqueue: hci0 hci_rx_work [bluetooth]
  f4700000 00000000 f466bb90 c18821c1 c2344320 f466bbb0 c1880a94
c1ad9264
  c1ad9201 c1ad95f8 f4700614 00000006 c108e0c0 f466bbe0 c108ea8c
00000006
  f4700000 f466bffc 323ca8b2 0000002a 00000004 f4700000 f4700618
00000003
 Call Trace:
  [<c18821c1>] dump_stack+0x4b/0x75
  [<c1880a94>] print_usage_bug.part.36+0x209/0x213
  [<c108e0c0>] ? check_usage_forwards+0x110/0x110
  [<c108ea8c>] mark_lock+0x11c/0x6e0
  [<c10915e4>] __lock_acquire+0x714/0x1d20
  [<c1004b6f>] ? dump_trace+0xcf/0x1f0
  [<c100a5f8>] ? sched_clock+0x8/0x10
  [<c1075da9>] ? sched_clock_local+0x49/0x180
  [<c109325d>] lock_acquire+0x9d/0x140
  [<f831dd4c>] ? hci_send_acl+0xac/0x290 [bluetooth]
  [<c1889c25>] _raw_spin_lock+0x45/0x80
  [<f831dd4c>] ? hci_send_acl+0xac/0x290 [bluetooth]
  [<f831dd4c>] hci_send_acl+0xac/0x290 [bluetooth]
  [<c108f0b4>] ? mark_held_locks+0x64/0x90
  [<c188a065>] ? _raw_spin_unlock_irqrestore+0x55/0x70
  [<f833efe0>] l2cap_do_send+0x60/0x100 [bluetooth]
  [<c108f32b>] ? trace_hardirqs_on+0xb/0x10
  [<c188a051>] ? _raw_spin_unlock_irqrestore+0x41/0x70
  [<c1763125>] ? skb_dequeue+0x45/0x60
  [<f8349785>] l2cap_recv_frame+0x23e5/0x2dc0 [bluetooth]
  [<c1075da9>] ? sched_clock_local+0x49/0x180
  [<c100a5f8>] ? sched_clock+0x8/0x10
  [<c1075da9>] ? sched_clock_local+0x49/0x180
  [<c10761ef>] ? sched_clock_cpu+0x10f/0x160
  [<c107183b>] ? get_parent_ip+0xb/0x40
  [<c10718bb>] ? preempt_count_add+0x4b/0xa0
  [<c13d09e2>] ? debug_smp_processor_id+0x12/0x20
  [<c108cc04>] ? get_lock_stats+0x24/0x40
  [<c108f0b4>] ? mark_held_locks+0x64/0x90
  [<c188716d>] ? __mutex_unlock_slowpath+0xcd/0x1b0
  [<c13d09ff>] ? __this_cpu_preempt_check+0xf/0x20
  [<c108f1d4>] ? trace_hardirqs_on_caller+0xf4/0x240
  [<c108c9a6>] ? trace_hardirqs_off_caller+0xb6/0x160
  [<f834b6a9>] l2cap_recv_acldata+0x2f9/0x340 [bluetooth]
  [<f8316a13>] ? hci_rx_work+0x113/0x4a0 [bluetooth]
  [<f8316c69>] hci_rx_work+0x369/0x4a0 [bluetooth]
  [<f8316a13>] ? hci_rx_work+0x113/0x4a0 [bluetooth]
  [<c106234a>] process_one_work+0x19a/0x4a0
  [<c10622c3>] ? process_one_work+0x113/0x4a0
  [<c10629e9>] worker_thread+0x39/0x440
  [<c10629b0>] ? init_pwq+0xc0/0xc0
  [<c1066dc8>] kthread+0xa8/0xc0
  [<c108f32b>] ? trace_hardirqs_on+0xb/0x10
  [<c188ad01>] ret_from_kernel_thread+0x21/0x30
  [<c1066d20>] ? kthread_create_on_node+0x160/0x160



Cheers,
Jukka

^ permalink raw reply

* [PATCH] android/tester: Add missing hook removal
From: Jakub Tyszkowski @ 2014-10-17 12:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jakub Tyszkowski

Missing hook removal was resulting in memory leak:
936 bytes in 39 blocks are definitely lost in loss record 42 of 45
==15026==    at 0x4C2AB80: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==15026==    by 0x407D60: btdev_add_hook (btdev.c:3226)
==15026==    by 0x40EB75: read_info_callback (tester-main.c:364)
==15026==    by 0x4142B5: request_complete (mgmt.c:245)
==15026==    by 0x41441A: can_read_data (mgmt.c:349)
==15026==    by 0x41663C: read_callback (io-glib.c:170)
==15026==    by 0x5083CE4: g_main_context_dispatch (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==15026==    by 0x5084047: ??? (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==15026==    by 0x5084309: g_main_loop_run (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==15026==    by 0x4162D0: tester_run (tester.c:815)
==15026==    by 0x40263E: main (tester-main.c:2716)
---
 android/tester-main.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/android/tester-main.c b/android/tester-main.c
index a804f11..fc1de06 100644
--- a/android/tester-main.c
+++ b/android/tester-main.c
@@ -212,6 +212,9 @@ static void test_post_teardown(const void *test_data)
 {
 	struct test_data *data = tester_get_data();
 
+	/* remove hook for encryption change */
+	hciemu_del_hook(data->hciemu, HCIEMU_HOOK_POST_EVT, 0x08);
+
 	hciemu_unref(data->hciemu);
 	data->hciemu = NULL;
 
-- 
1.9.1


^ permalink raw reply related

* Re: [PATCH ] obexd/mas: Add Support fo MSETime filter
From: Luiz Augusto von Dentz @ 2014-10-17 11:58 UTC (permalink / raw)
  To: Bharat Panda; +Cc: linux-bluetooth@vger.kernel.org, cpgs
In-Reply-To: <1413281882-29686-1-git-send-email-bharat.panda@samsung.com>

Hi,

On Tue, Oct 14, 2014 at 12:18 PM, Bharat Panda <bharat.panda@samsung.com> wrote:
> Changes made to add support for MSE local time parameter
> along with GetMessageListing response.
> ---
>  obexd/plugins/mas.c | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
>
> diff --git a/obexd/plugins/mas.c b/obexd/plugins/mas.c
> index fb97fe3..7f14bf8 100644
> --- a/obexd/plugins/mas.c
> +++ b/obexd/plugins/mas.c
> @@ -30,6 +30,7 @@
>  #include <glib.h>
>  #include <fcntl.h>
>  #include <inttypes.h>
> +#include <sys/time.h>
>
>  #include <gobex/gobex.h>
>  #include <gobex/gobex-apparam.h>
> @@ -228,6 +229,25 @@ static void g_string_append_escaped_printf(GString *string,
>         va_end(ap);
>  }
>
> +static gchar *get_mse_timestamp(void)
> +{
> +       struct timeval time_val;
> +       struct tm ltime;
> +       gchar *local_ts;
> +
> +       gettimeofday(&time_val, NULL);
> +
> +       if (!localtime_r(&time_val.tv_sec, &ltime))
> +               return NULL;
> +
> +       local_ts = g_strdup_printf("%04d%02d%02dT%02d%02d%02d",
> +                                       ltime.tm_year + 1900, ltime.tm_mon + 1,
> +                                       ltime.tm_mday, ltime.tm_hour,
> +                                       ltime.tm_min, ltime.tm_sec);
> +
> +       return local_ts;
> +}
> +
>  static const char *yesorno(gboolean a)
>  {
>         if (a)
> @@ -243,6 +263,7 @@ static void get_messages_listing_cb(void *session, int err, uint16_t size,
>  {
>         struct mas_session *mas = user_data;
>         uint16_t max = 1024;
> +       gchar *mse_time;
>
>         if (err < 0 && err != -EAGAIN) {
>                 obex_object_set_io_flags(mas, G_IO_ERR, err);
> @@ -358,6 +379,13 @@ proceed:
>                 mas->outparams = g_obex_apparam_set_uint8(mas->outparams,
>                                                 MAP_AP_NEWMESSAGE,
>                                                 newmsg ? 1 : 0);
> +               /* Response to report the local time of MSE */
> +               mse_time = get_mse_timestamp();
> +               if (mse_time) {
> +                       g_obex_apparam_set_string(mas->outparams,
> +                                               MAP_AP_MSETIME, mse_time);
> +                       g_free(mse_time);
> +               }
>         }
>
>         if (err != -EAGAIN)
> --
> 1.9.1

Does this works when the system has timedated running, perhaps we need
to know if the time is set in UTC or not and in case of the later we
probably need to provide the timezone as well.



-- 
Luiz Augusto von Dentz

^ permalink raw reply

* [PATCH] android/pts: Update PTS files for HFP
From: Sebastian Chlad @ 2014-10-17 11:51 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sebastian Chlad

PICS and PIXITs updated to PTS 5.3. Regression done for Android
4.4.4.
---
 android/pics-hfp.txt  | 22 ++++++++++++++++++++--
 android/pixit-hfp.txt |  5 ++++-
 android/pts-hfp.txt   | 14 ++++++++------
 3 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/android/pics-hfp.txt b/android/pics-hfp.txt
index acbd25c..65f5112 100644
--- a/android/pics-hfp.txt
+++ b/android/pics-hfp.txt
@@ -1,6 +1,6 @@
 HFP PICS for the PTS tool.
 
-PTS version: 5.2
+PTS version: 5.3
 
 * - different than PTS defaults
 # - not yet implemented/supported
@@ -14,6 +14,7 @@ Parameter Name	Selected	Description
 -------------------------------------------------------------------------------
 TSPC_HFP_0_1	False		Version: Hands-Free Profile v1.5 (O.1)
 TSPC_HFP_0_2	True (*)	Version: Hands-Free Profile v1.6 (O.1)
+TSPC_HFP_0_3	False		Version: Hands-Free Profile v1.7 (O.1)
 -------------------------------------------------------------------------------
 O.1: It is mandatory to support only one of the adopted versions.
 -------------------------------------------------------------------------------
@@ -83,8 +84,10 @@ TSPC_HFP_2_21c	True (*)	Enhanced Call Status with limited network
 					notification (C.4)
 TSPC_HFP_2_22	False		Support for automatic link loss recovery (O)
 TSPC_HFP_2_23	True (*)	Individual Indicator Activation (C.9)
-TSPC_HFP_2_24	True (*)s	Wide Band Speech service (C.8)
+TSPC_HFP_2_24	True (*)	Wide Band Speech service (C.8)
 TSPC_HFP_2_25	False		Support roaming function (O)
+TSPC_HFP_2_26	False		HF Indicators (C.11)
+TSPC_HFP_2_27	False		Support CVSD eSCO s4 setting (C.12)
 -------------------------------------------------------------------------------
 C.1:  The AG must support one of item TSPC_HFP_2_4a or TSPC_HFP_2_4b
 C.2:  Mandatory if TSPC_HFP_2_12is TRUE; otherwise excluded
@@ -96,6 +99,10 @@ C.7:  Mandatory if TSPC_HFP_2_24 otherwise excluded
 C.8:  Excluded if TSPC_HFP_0_1 otherwise optional
 C.9:  Excluded if TSPC_HFP_0_1 otherwise mandatory
 C.10: Mandatory if TSPC_HFP_2_24 otherwise optional
+C.11: Optional IF HFP v1.5 (TSPC_HFP_0_1) OR HFP v1.6 (TSPC_HFP_0_2) is NOT
+	supported, otherwise Excluded.
+C.12: Excluded IF HFP v1.5 (TSPC_HFP_0_1) OR HFP v1.6 (TSPC_HFP_0_2) is
+	supported, otherwise Mandatory.
 -------------------------------------------------------------------------------
 
 
@@ -161,6 +168,8 @@ TSPC_HFP_3_21b	False		Enhanced Call Control (C.2)
 TSPC_HFP_3_22	False		Support for automatic link loss recovery (O)
 TSPC_HFP_3_23	False		Individual Indicator Activation (C.6)
 TSPC_HFP_3_24	False		Wide Band Speech service (C.6)
+TSPC_HFP_3_25	False		HF Indicators (C.8)
+TSPC_HFP_3_36	False		Support CVSD eSCO S4 setting (C.9)
 -------------------------------------------------------------------------------
 C.1: Mandatory if TSPC_HFP_3_12; otherwise excluded
 C.2: Optional if TSPC_HFP_3_12; otherwise excluded
@@ -169,6 +178,10 @@ C.4: Mandatory if TSPC_HFP_3_18a, otherwise optional
 C.5: Mandatory if TSPC_HFP_3_24 otherwise excluded
 C.6: Excluded if TSPC_HFP_0_1 otherwise optional
 C.7: Mandatory if TSPC_HFP_3_24 otherwise optional
+C.8: Optional IF HFP v1.5 (TSPC_HFP_0_1) OR HFP v1.6 (TSPC_HFP_0_2) is NOT
+	supported, otherwise Excluded.
+C.9: Excluded IF HFP v1.5 (TSPC_HFP_0_1) OR HFP v1.6 (TSPC_HFP_0_2) is
+	supported, otherwise Mandatory.
 -------------------------------------------------------------------------------
 
 
@@ -178,9 +191,14 @@ Parameter Name	Selected	Description
 -------------------------------------------------------------------------------
 TSPC_HFP_4_1	True		CVSD audio coding over SCO (M)
 TSPC_HFP_4_2	True (*)	mSBC audio coding over eSCO (C.1)
+TSPC_HFP_4_3	True (*)	CVSD audio coding over eSCO (Initiating) (C.2)
+TSPC_HFP_4_2	True (*)	CVSD audio coding over eSCO (Accepting) (C.2)
 -------------------------------------------------------------------------------
 C.1: Mandatory if Wide band speech service is supported TSPC_HFP_2_24 or
 	TSPC_HFP_3_24, otherwise excluded
+C.2: Mandatory IF TPSC_HFP_2_3b (eSCO support in Audio Connection - AG) OR
+	TSPC_HFP_3_3b (eSCO support in Audio Connection - HF); otherwise
+	Excluded.
 -------------------------------------------------------------------------------
 
 
diff --git a/android/pixit-hfp.txt b/android/pixit-hfp.txt
index eaccc75..bf1b7e5 100644
--- a/android/pixit-hfp.txt
+++ b/android/pixit-hfp.txt
@@ -1,6 +1,6 @@
 HFP PIXIT for the PTS tool.
 
-PTS version: 5.2
+PTS version: 5.3
 
 * - different than PTS defaults
 & - should be set to IUT Bluetooth address
@@ -35,4 +35,7 @@ TSPX_no_fail_verdict					FALSE
 TSPX_network_supports_correct_call_and_callstatus	TRUE
 TSPX_secure_simple_pairing_pass_key_confirmation	FALSE
 TSPX_AG_match_tester_BRSF_codec_negotiation_bit		FALSE
+TSPX_HFP_Unsupported_HF_Indicator_1			99
+TSPX_HFP_Supported_HF_Indiccator_1			1
+TSPX_Automation						FALSE
 -------------------------------------------------------------------------------
diff --git a/android/pts-hfp.txt b/android/pts-hfp.txt
index a281d6b..8d75766 100644
--- a/android/pts-hfp.txt
+++ b/android/pts-hfp.txt
@@ -1,7 +1,7 @@
 PTS test results for HFP
 
-PTS version: 5.2
-Tested: 14-Jul-2014
+PTS version: 5.3
+Tested: 16-October-2014
 Android version: 4.4.4
 
 Results:
@@ -28,6 +28,7 @@ TC_AG_ACS_BV_08_I	PASS
 TC_AG_ACS_BV_10_I	N/A
 TC_AG_ACS_BV_11_I	PASS
 TC_AG_ACS_BI_14_I	PASS
+TC_AG_ACS_BI_16_I	N/A
 TC_AG_ACR_BV_01_I	PASS
 TC_AG_ACR_BV_02_I	PASS
 TC_AG_CLI_BV_01_I	PASS
@@ -66,7 +67,7 @@ TC_AG_ENO_BV_02_I	N/A
 TC_AG_VRA_BV_01_I	PASS
 TC_AG_VRA_BV_02_I	PASS
 TC_AG_VRA_BI_01_I	PASS
-TC_AG_VRD_BV_01_I	PASS
+TC_AG_VRD_BV_01_I	N/A
 TC_AG_VTG_BV_01_I	N/A
 TC_AG_TDC_BV_01_I	PASS
 TC_AG_RSV_BV_01_I	PASS
@@ -98,6 +99,8 @@ TC_AG_SLC_BV_04_C	PASS
 TC_AG_SLC_BV_05_I	PASS
 TC_AG_SLC_BV_06_I	PASS
 TC_AG_SLC_BV_07_I	PASS
+TC_AG_SLC_BV_09_I	N/A
+TC_AG_SLC_BV_10_I	N/A
 TC_AG_ACC_BV_08_I	INC	Possible PTS issue #12039
 TC_AG_ACC_BV_09_I	PASS
 TC_AG_ACC_BV_10_I	INC	Possible PTS issue #12039
@@ -120,7 +123,8 @@ TC_AG_IID_BV_04_I	PASS
 TC_AG_IIC_BV_01_I	PASS
 TC_AG_IIC_BV_02_I	PASS
 TC_AG_IIC_BV_03_I	PASS
-
+TC_AG_HFI_BV_02_I	N/A
+TC_AG_HFI_BV_03_I	N/A
 TC_HF_OOR_BV_01_I	N/A
 TC_HF_OOR_BV_02_I	N/A
 TC_HF_TRS_BV_01_I	N/A
@@ -223,7 +227,6 @@ TC_HF_SDP_BV_03_C	N/A
 TC_HF_ATAH_BV_01_I	N/A
 TC_HF_OCA_BV_01_I	N/A
 TC_HF_IIA_BV_04_I	N/A
-
 TC_AG_COD_BV_02_I	PASS
 TC_AG_ATAH_BV_03_I	PASS
 TC_AG_ATA_BV_03_I	PASS
@@ -236,7 +239,6 @@ TC_AG_ICA_BV_09_I	PASS
 TC_AG_VRA_BV_03_I	PASS
 TC_AG_OCA_BV_01_I	PASS
 TC_AG_TCA_BV_06_I	PASS
-
 TC_HF_ATAH_BV_03_I	N/A
 TC_HF_ATA_BV_03_I	N/A
 TC_HF_ATH_BV_09_I	N/A
-- 
1.8.5.3


^ permalink raw reply related

* Re: Correct use of le_set_scan_response_data_cp / hci_send_req ?
From: Marcel Holtmann @ 2014-10-17 11:46 UTC (permalink / raw)
  To: mvogt1; +Cc: linux-bluetooth
In-Reply-To: <CAOE8yMDJOB2iNnS6DFyE2=GBbKTEd4GPE_KcNCPT1d1eaUyzfw@mail.gmail.com>

Hi Martin,

> I try to create a btle server which does advertise itsself with the
> name "HEY".
> 
> Attached is a demo program.
> Compile with:
> 
> g++ -o leserv leserv.cpp -lbluetooth
> 
> then start the program as root.
> And on another host start:
> 
> hcitool lescan
> 
> The current version prints "HEY" but I think the API
> is wrong here. Every other version which can be found
> on the internet uses the
> 
> // does not work
> //hci_le_set_scan_response_data(hciSocket,(uint8_t*)msg,strlen(msg),0);
> 
> implementation, and this one does not work.
> 
> What would be a correct example for this task?

you need to the read advertising data format struct. If you are configuring the scan response data, then it needs to follow the TLV format defined by the Bluetooth SIG.

Regards

Marcel


^ permalink raw reply

* Re: Multiple BLE connections to one GATT-Server
From: Marcel Holtmann @ 2014-10-17 11:45 UTC (permalink / raw)
  To: T. Bolten; +Cc: linux-bluetooth
In-Reply-To: <5440E4BE.3020303@gmx.com>

Hi,

> I'm new in the area of Bluetooth-programming and I hope this is the right place for my question. A web search at the usual web portals was not very helpful due to contradictory statements and I'm "lost" in the Bluetooth Core specification.
> 
> Basically my question related to Bluetooth Low Energy is the following:
> 
> Is it technically possible to connect multiple BLE GATT Clients (in my case smartphones, called in the bluetooth terminology central/master device?) to one BLE GATT Server (in my case a Linux box with Bluez, called in the bluetooth terminology slave or peripheral device?)?
> 
> 
> The basic idea here is that several different smartphones should simultaneously read (read-only, not write) some self-defined service characteristics to inform the clients about some kind of progress or event state. These progress-information is unfortunately to large to be included in the advertisement package.
> 
> 
> I have already an implementation that advertises a service with some self defined characteristics but I can connect to this GATT service only with one smartphone - then the advertising stops and I'm unable to connect to this service with an other device.

this is a hardware specific detail. BlueZ will support as many connection in peripheral role as the hardware supports. Some might have single connections in peripheral, but others might all multiple. You need to test this and see if the hardware is working correctly for your use cases.

Regards

Marcel


^ permalink raw reply

* Re: Query regarding creation of multiple MAS Instance ID:
From: Luiz Augusto von Dentz @ 2014-10-17 11:41 UTC (permalink / raw)
  To: Gowtham Anandha Babu
  Cc: linux-bluetooth@vger.kernel.org, Bharat Panda, Dmitry Kasatkin,
	cpgs
In-Reply-To: <000b01cfe94c$216de430$6449ac90$@samsung.com>

Hi,

On Thu, Oct 16, 2014 at 4:18 PM, Gowtham Anandha Babu
<gowtham.ab@samsung.com> wrote:
> Hi All,
>
> I am working on obexd MAP profile. Is it possible to create multiple MAS
> Instance in bluez?
> Because right now bluez has only one MAS Instance support (only one
> MAS_UUID), which is advertised to MCE based on the XML format followed in
> src/profile.c.
> When I add one more record to MAS_RECORD XML format by changing the value as
> 0x01, I am not able see two instances getting loaded.
>                 <attribute id=\"0x0315\">                               \
>                         <uint8 value=\"0x01\"/>                 \
>                 </attribute>                                            \

How you are doing that? You should be able to call
ProfileManager1.RegisterProfile if that is what you doing and it is
not working perhaps we have a bug somewhere. Two very important things
you need to check:

1. It cannot use the same path for both instances
2. Each instance needs a different channel

So if you are register via XML you need to take care of those details,
but perhaps you are using the default record by just providing the
UUID, that probably will not work because apparently we have hardcoded
the channel, if that is the case we should probably add a check if
there is another instance already register and use a different
channel/psm.

> Do we need to create one more UUID like OBEX_MAS1_UUID and OBEX_MAS2_UUID to
> support multiple mas instances?
> Or what could be the possible solutions?

Each instance has to have the service class set to MAS UUID, otherwise
no one will be able to discover it.

>
> Regards.
> Gowtham Anandha Babu
>
> --
> 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



-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Multiple BLE connections to one GATT-Server
From: T. Bolten @ 2014-10-17  9:43 UTC (permalink / raw)
  To: linux-bluetooth

Hello,

I'm new in the area of Bluetooth-programming and I hope this is the 
right place for my question. A web search at the usual web portals was 
not very helpful due to contradictory statements and I'm "lost" in the 
Bluetooth Core specification.

Basically my question related to Bluetooth Low Energy is the following:

Is it technically possible to connect multiple BLE GATT Clients (in my 
case smartphones, called in the bluetooth terminology central/master 
device?) to one BLE GATT Server (in my case a Linux box with Bluez, 
called in the bluetooth terminology slave or peripheral device?)?


The basic idea here is that several different smartphones should 
simultaneously read (read-only, not write) some self-defined service 
characteristics to inform the clients about some kind of progress or 
event state. These progress-information is unfortunately to large to be 
included in the advertisement package.


I have already an implementation that advertises a service with some 
self defined characteristics but I can connect to this GATT service only 
with one smartphone - then the advertising stops and I'm unable to 
connect to this service with an other device.

After reading a lot of web posts I'm unsure if my idea can work or it is 
already "broken by design"?

I am grateful for any suggestion.

Greetings
T. Bolten

^ permalink raw reply

* [PATCH BlueZ] android/avrcp-lib: Use cpu_to_* and *_to_cpu
From: Luiz Augusto von Dentz @ 2014-10-17  9:08 UTC (permalink / raw)
  To: linux-bluetooth

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

For PDU which have packed struct it is not necessary to use put_*
and get_* since it should be already aligned.
---
 android/avrcp-lib.c | 136 ++++++++++++++++++++++++++--------------------------
 1 file changed, 68 insertions(+), 68 deletions(-)

diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index 2c3d2e9..cff37a8 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -929,7 +929,7 @@ static bool parse_attributes(uint32_t *params, uint16_t params_len,
 
 	for (i = 0; i < number && params_len >= sizeof(*attrs); i++,
 					params_len -= sizeof(*attrs)) {
-		attrs[i] = get_be32(&params[i]);
+		attrs[i] = be32_to_cpu(params[i]);
 
 		if (attrs[i] == AVRCP_MEDIA_ATTRIBUTE_ILLEGAL ||
 				attrs[i] > AVRCP_MEDIA_ATTRIBUTE_LAST)
@@ -988,7 +988,7 @@ static ssize_t register_notification(struct avrcp *session, uint8_t transaction,
 
 	req = (void *) params;
 
-	interval = get_be32(&req->interval);
+	interval = be32_to_cpu(req->interval);
 
 	return player->ind->register_notification(session, transaction,
 							req->event, interval,
@@ -1037,7 +1037,7 @@ static ssize_t set_addressed(struct avrcp *session, uint8_t transaction,
 
 	req = (void *) params;
 
-	id = get_be16(&req->id);
+	id = be16_to_cpu(req->id);
 
 	return player->ind->set_addressed(session, transaction, id,
 							player->user_data);
@@ -1271,7 +1271,7 @@ static ssize_t set_browsed(struct avrcp *session, uint8_t transaction,
 
 	req = (void *) params;
 
-	id = get_be16(&req->id);
+	id = be16_to_cpu(req->id);
 
 	return player->ind->set_browsed(session, transaction, id,
 							player->user_data);
@@ -1301,16 +1301,16 @@ static ssize_t get_folder_items(struct avrcp *session, uint8_t transaction,
 	if (req->scope > AVRCP_MEDIA_NOW_PLAYING)
 		return -EBADRQC;
 
-	start = get_be32(&req->start);
-	end = get_be32(&req->end);
+	start = be32_to_cpu(req->start);
+	end = be32_to_cpu(req->end);
 
 	if (start > end)
 		return -ERANGE;
 
-	number = get_be16(&req->number);
+	number = be16_to_cpu(req->number);
 
 	for (i = 0; i < number; i++) {
-		attrs[i] = get_be32(&req->attrs[i]);
+		attrs[i] = be32_to_cpu(req->attrs[i]);
 
 		if (attrs[i] == AVRCP_MEDIA_ATTRIBUTE_ILLEGAL ||
 				attrs[i] > AVRCP_MEDIA_ATTRIBUTE_LAST)
@@ -1341,8 +1341,8 @@ static ssize_t change_path(struct avrcp *session, uint8_t transaction,
 
 	req = (void *) params;
 
-	counter = get_be16(&req->counter);
-	uid = get_be64(&req->uid);
+	counter = be16_to_cpu(req->counter);
+	uid = be64_to_cpu(req->uid);
 
 	return player->ind->change_path(session, transaction, counter,
 					req->direction, uid, player->user_data);
@@ -1372,11 +1372,11 @@ static ssize_t get_item_attributes(struct avrcp *session, uint8_t transaction,
 	if (req->scope > AVRCP_MEDIA_NOW_PLAYING)
 		return -EBADRQC;
 
-	uid = get_be64(&req->uid);
-	counter = get_be16(&req->counter);
+	uid = be64_to_cpu(req->uid);
+	counter = be16_to_cpu(req->counter);
 
 	for (i = 0; i < req->number; i++) {
-		attrs[i] = get_be32(&req->attrs[i]);
+		attrs[i] = be32_to_cpu(req->attrs[i]);
 
 		if (attrs[i] == AVRCP_MEDIA_ATTRIBUTE_ILLEGAL ||
 				attrs[i] > AVRCP_MEDIA_ATTRIBUTE_LAST)
@@ -1411,8 +1411,8 @@ static ssize_t play_item(struct avrcp *session, uint8_t transaction,
 	if (req->scope > AVRCP_MEDIA_NOW_PLAYING)
 		return -EBADRQC;
 
-	uid = get_be64(&params[1]);
-	counter = get_be16(&params[9]);
+	uid = be64_to_cpu(req->uid);
+	counter = be16_to_cpu(req->counter);
 
 	return player->ind->play_item(session, transaction, req->scope, uid,
 						counter, player->user_data);
@@ -1438,7 +1438,7 @@ static ssize_t search(struct avrcp *session, uint8_t transaction,
 
 	req = (void *) params;
 
-	len = get_be16(&req->len);
+	len = be16_to_cpu(req->len);
 	if (!len)
 		return -EINVAL;
 
@@ -1474,8 +1474,8 @@ static ssize_t add_to_now_playing(struct avrcp *session, uint8_t transaction,
 	if (req->scope > AVRCP_MEDIA_NOW_PLAYING)
 		return -EBADRQC;
 
-	uid = get_be64(&req->uid);
-	counter = get_be16(&req->counter);
+	uid = be64_to_cpu(req->uid);
+	counter = be16_to_cpu(req->counter);
 
 	return player->ind->add_to_now_playing(session, transaction, req->scope,
 							uid, counter,
@@ -1859,7 +1859,7 @@ int avrcp_register_notification(struct avrcp *session, uint8_t event,
 		return -EINVAL;
 
 	req.event = event;
-	put_be32(interval, &req.interval);
+	req.interval = cpu_to_be32(interval);
 
 	iov.iov_base = &req;
 	iov.iov_len = sizeof(req);
@@ -2345,8 +2345,8 @@ static gboolean get_play_status_rsp(struct avctp *conn,
 
 	rsp = (void *) pdu->params;
 
-	duration = get_be32(&rsp->duration);
-	position = get_be32(&rsp->position);
+	duration = be32_to_cpu(rsp->duration);
+	position = be32_to_cpu(rsp->position);
 	status = rsp->status;
 	err = 0;
 
@@ -2432,9 +2432,9 @@ static int parse_attribute_list(uint8_t *params, uint16_t params_len,
 	for (i = 0; i < number && params_len >= sizeof(*item); i++) {
 		item = (void *) params;
 
-		item->attr = get_be32(&item->attr);
-		item->charset = get_be16(&item->charset);
-		item->len = get_be16(&item->len);
+		item->attr = be32_to_cpu(item->attr);
+		item->charset = be16_to_cpu(item->charset);
+		item->len = be16_to_cpu(item->len);
 
 		params_len -= sizeof(*item);
 		params += sizeof(*item);
@@ -2584,7 +2584,7 @@ int avrcp_set_addressed_player(struct avrcp *session, uint16_t player_id)
 	struct iovec iov;
 	struct set_addressed_req req;
 
-	put_be16(player_id, &req.id);
+	req.id = cpu_to_be16(player_id);
 
 	iov.iov_base = &req;
 	iov.iov_len = sizeof(req);
@@ -2658,8 +2658,8 @@ static gboolean set_browsed_rsp(struct avctp *conn, uint8_t *operands,
 
 	rsp = (void *) pdu->params;
 
-	counter = get_be16(&rsp->counter);
-	items = get_be32(&rsp->items);
+	counter = be16_to_cpu(rsp->counter);
+	items = be32_to_cpu(rsp->items);
 
 	path = parse_folder_list(rsp->data, pdu->params_len - sizeof(*rsp),
 								rsp->depth);
@@ -2676,12 +2676,12 @@ done:
 int avrcp_set_browsed_player(struct avrcp *session, uint16_t player_id)
 {
 	struct iovec iov;
-	uint8_t pdu[2];
+	struct set_browsed_req req;
 
-	put_be16(player_id, pdu);
+	req.id = cpu_to_be16(player_id);
 
-	iov.iov_base = pdu;
-	iov.iov_len = sizeof(pdu);
+	iov.iov_base = &req;
+	iov.iov_len = sizeof(req);
 
 	return avrcp_send_browsing_req(session, AVRCP_SET_BROWSED_PLAYER,
 					&iov, 1, set_browsed_rsp, session);
@@ -2721,8 +2721,8 @@ static gboolean get_folder_items_rsp(struct avctp *conn,
 
 	rsp = (void *) pdu->params;
 
-	counter = get_be16(&rsp->counter);
-	number = get_be16(&rsp->number);
+	counter = be16_to_cpu(rsp->counter);
+	number = be16_to_cpu(rsp->number);
 	params = rsp->data;
 
 	/* FIXME: Add proper parsing for each item type */
@@ -2744,8 +2744,8 @@ int avrcp_get_folder_items(struct avrcp *session, uint8_t scope,
 	int i;
 
 	req.scope = scope;
-	put_be32(start, &req.start);
-	put_be32(end, &req.end);
+	req.start = cpu_to_be32(start);
+	req.end = cpu_to_be32(end);
 	req.number = number;
 
 	iov[0].iov_base = &req;
@@ -2757,7 +2757,7 @@ int avrcp_get_folder_items(struct avrcp *session, uint8_t scope,
 						session);
 
 	for (i = 0; i < number; i++)
-		put_be32(attrs[i], &attrs[i]);
+		attrs[i] = cpu_to_be32(attrs[i]);
 
 	iov[1].iov_base = attrs;
 	iov[1].iov_len = number * sizeof(*attrs);
@@ -2798,7 +2798,7 @@ static gboolean change_path_rsp(struct avctp *conn, uint8_t *operands,
 
 	rsp = (void *) pdu->params;
 
-	items = get_be32(&rsp->items);
+	items = be32_to_cpu(rsp->items);
 
 done:
 	player->cfm->change_path(session, err, items, player->user_data);
@@ -2812,9 +2812,9 @@ int avrcp_change_path(struct avrcp *session, uint8_t direction, uint64_t uid,
 	struct iovec iov;
 	struct change_path_req req;
 
-	put_be16(counter, &req.counter);
+	req.counter = cpu_to_be16(counter);
 	req.direction = direction;
-	put_be64(uid, &req.uid);
+	req.uid = cpu_to_be64(uid);
 
 	iov.iov_base = &req;
 	iov.iov_len = sizeof(req);
@@ -2867,8 +2867,8 @@ int avrcp_get_item_attributes(struct avrcp *session, uint8_t scope,
 	int i;
 
 	req.scope = scope;
-	put_be64(uid, &req.uid);
-	put_be16(counter, &req.counter);
+	req.uid = cpu_to_be64(uid);
+	req.counter = cpu_to_be16(counter);
 	req.number = number;
 
 	iov[0].iov_base = &req;
@@ -2887,7 +2887,7 @@ int avrcp_get_item_attributes(struct avrcp *session, uint8_t scope,
 		if (attrs[i] > AVRCP_MEDIA_ATTRIBUTE_LAST ||
 				attrs[i] == AVRCP_MEDIA_ATTRIBUTE_ILLEGAL)
 			return -EINVAL;
-		put_be32(attrs[i], &attrs[i]);
+		attrs[i] = cpu_to_be32(attrs[i]);
 	}
 
 	iov[1].iov_base = attrs;
@@ -2935,8 +2935,8 @@ int avrcp_play_item(struct avrcp *session, uint8_t scope, uint64_t uid,
 		return -EINVAL;
 
 	req.scope = scope;
-	put_be64(uid, &req.uid);
-	put_be16(counter, &req.counter);
+	req.uid = cpu_to_be64(uid);
+	req.counter = cpu_to_be16(counter);
 
 	iov.iov_base = &req;
 	iov.iov_len = sizeof(req);
@@ -2978,8 +2978,8 @@ static gboolean search_rsp(struct avctp *conn, uint8_t *operands,
 
 	rsp = (void *) pdu->params;
 
-	counter = get_be16(&rsp->counter);
-	items = get_be32(&rsp->items);
+	counter = be16_to_cpu(rsp->counter);
+	items = be32_to_cpu(rsp->items);
 
 	err = 0;
 
@@ -3000,8 +3000,8 @@ int avrcp_search(struct avrcp *session, const char *string)
 
 	len = strnlen(string, UINT8_MAX);
 
-	put_be16(AVRCP_CHARSET_UTF8, &req.charset);
-	put_be16(len, &req.len);
+	req.charset = cpu_to_be16(AVRCP_CHARSET_UTF8);
+	req.len = cpu_to_be16(len);
 
 	iov[0].iov_base = &req;
 	iov[0].iov_len = sizeof(req);
@@ -3050,8 +3050,8 @@ int avrcp_add_to_now_playing(struct avrcp *session, uint8_t scope, uint64_t uid,
 		return -EINVAL;
 
 	req.scope = scope;
-	put_be64(uid, &req.uid);
-	put_be16(counter, &req.counter);
+	req.uid = cpu_to_be64(uid);
+	req.counter = cpu_to_be16(counter);
 
 	iov.iov_base = &req;
 	iov.iov_len = sizeof(req);
@@ -3136,7 +3136,7 @@ int avrcp_get_player_attribute_text_rsp(struct avrcp *session,
 			len = strlen(text[i]);
 
 		val[i].attr = attrs[i];
-		put_be16(AVRCP_CHARSET_UTF8, &val[i].charset);
+		val[i].charset = cpu_to_be16(AVRCP_CHARSET_UTF8);
 		val[i].len = len;
 
 		iov[i + 1].iov_base = &val[i];
@@ -3177,8 +3177,8 @@ int avrcp_get_play_status_rsp(struct avrcp *session, uint8_t transaction,
 	struct iovec iov;
 	struct get_play_status_rsp rsp;
 
-	put_be32(duration, &rsp.duration);
-	put_be32(position, &rsp.position);
+	rsp.duration = cpu_to_be32(duration);
+	rsp.position = cpu_to_be32(position);
 	rsp.status = status;
 
 	iov.iov_base = &rsp;
@@ -3210,7 +3210,7 @@ int avrcp_get_player_values_text_rsp(struct avrcp *session,
 			len = strlen(text[i]);
 
 		val[i].attr = values[i];
-		put_be16(AVRCP_CHARSET_UTF8, &val[i].charset);
+		val[i].charset = cpu_to_be16(AVRCP_CHARSET_UTF8);
 		val[i].len = len;
 
 		iov[i + 1].iov_base = &val[i];
@@ -3314,8 +3314,8 @@ int avrcp_register_notification_rsp(struct avrcp *session, uint8_t transaction,
 			return -EINVAL;
 
 		player = data;
-		put_be16(player[0], &player[0]);
-		put_be16(player[1], &player[1]);
+		player[0] = cpu_to_be16(player[0]);
+		player[1] = cpu_to_be16(player[1]);
 
 		break;
 	case AVRCP_EVENT_SETTINGS_CHANGED:
@@ -3398,9 +3398,9 @@ int avrcp_set_browsed_player_rsp(struct avrcp *session, uint8_t transaction,
 					AVRCP_SET_BROWSED_PLAYER, status);
 
 	rsp.status = status;
-	put_be16(counter, &rsp.counter);
-	put_be32(items, &rsp.items);
-	put_be16(AVRCP_CHARSET_UTF8, &rsp.charset);
+	rsp.counter = cpu_to_be16(counter);
+	rsp.items = cpu_to_be32(items);
+	rsp.charset = cpu_to_be16(AVRCP_CHARSET_UTF8);
 	rsp.depth = depth;
 
 	iov[0].iov_base = &rsp;
@@ -3420,7 +3420,7 @@ int avrcp_set_browsed_player_rsp(struct avrcp *session, uint8_t transaction,
 		iov[i * 2 + 2].iov_base = (void *) folders[i];
 		iov[i * 2 + 2].iov_len = len[i];
 
-		put_be16(len[i], &len[i]);
+		len[i] = cpu_to_be16(len[i]);
 
 		iov[i * 2 + 1].iov_base = &len[i];
 		iov[i * 2 + 1].iov_len = sizeof(len[i]);
@@ -3446,8 +3446,8 @@ int avrcp_get_folder_items_rsp(struct avrcp *session, uint8_t transaction,
 					AVRCP_GET_FOLDER_ITEMS, status);
 
 	rsp.status = status;
-	put_be16(counter, &rsp.counter);
-	put_be16(number, &rsp.number);
+	rsp.counter = cpu_to_be16(counter);
+	rsp.number = cpu_to_be16(number);
 
 	iov[0].iov_base = &rsp;
 	iov[0].iov_len = sizeof(rsp);
@@ -3478,7 +3478,7 @@ int avrcp_change_path_rsp(struct avrcp *session, uint8_t transaction,
 									status);
 
 	rsp.status = status;
-	put_be32(items, &rsp.items);
+	rsp.items = cpu_to_be32(items);
 
 	iov.iov_base = &rsp;
 	iov.iov_len = sizeof(rsp);
@@ -3503,9 +3503,9 @@ static bool pack_attribute_list(struct iovec *iov, uint8_t number,
 		if (text[i])
 			len = strlen(text[i]);
 
-		put_be32(attrs[i], &val[i].attr);
-		put_be16(AVRCP_CHARSET_UTF8, &val[i].charset);
-		put_be16(len, &val[i].len);
+		val[i].attr = cpu_to_be32(attrs[i]);
+		val[i].charset = cpu_to_be16(AVRCP_CHARSET_UTF8);
+		val[i].len = cpu_to_be16(len);
 
 		iov[i].iov_base = &val[i];
 		iov[i].iov_len = sizeof(val[i]);
@@ -3563,8 +3563,8 @@ int avrcp_search_rsp(struct avrcp *session, uint8_t transaction, uint8_t status,
 								status);
 
 	rsp.status = status;
-	put_be16(counter, &rsp.counter);
-	put_be32(items, &rsp.items);
+	rsp.counter = cpu_to_be16(counter);
+	rsp.items = cpu_to_be32(items);
 
 	iov.iov_base = &rsp;
 	iov.iov_len = sizeof(rsp);
-- 
1.9.3


^ permalink raw reply related

* Re: [PATCH BlueZ 1/4] android/avrcp-lib: Add status parameter
From: Luiz Augusto von Dentz @ 2014-10-17  8:14 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org
In-Reply-To: <1413194150-21751-1-git-send-email-luiz.dentz@gmail.com>

Hi,

On Mon, Oct 13, 2014 at 11:55 AM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> This adds status parameter for functions generating browsing reponses
> as it may not be possible to respond synchronously using the return of
> the callback while processing the request.
> ---
>  android/avrcp-lib.c | 91 ++++++++++++++++++++++++++++-------------------------
>  android/avrcp-lib.h | 16 +++++-----
>  unit/test-avrcp.c   | 13 ++++----
>  3 files changed, 64 insertions(+), 56 deletions(-)
>
> diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
> index b7d0f5e..f3cdab9 100644
> --- a/android/avrcp-lib.c
> +++ b/android/avrcp-lib.c
> @@ -3337,6 +3337,20 @@ int avrcp_set_addressed_player_rsp(struct avrcp *session, uint8_t transaction,
>                                 &iov, 1);
>  }
>
> +static int avrcp_status_rsp(struct avrcp *session, uint8_t transaction,
> +                                               uint8_t pdu_id, uint8_t status)
> +{
> +       struct iovec iov;
> +
> +       if (status > AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED)
> +               return -EINVAL;
> +
> +       iov.iov_base = &status;
> +       iov.iov_len = sizeof(status);
> +
> +       return avrcp_send_browsing(session, transaction, pdu_id, &iov, 1);
> +}
> +
>  int avrcp_set_browsed_player_rsp(struct avrcp *session, uint8_t transaction,
>                                         uint8_t status, uint16_t counter,
>                                         uint32_t items, uint8_t depth,
> @@ -3347,13 +3361,9 @@ int avrcp_set_browsed_player_rsp(struct avrcp *session, uint8_t transaction,
>         uint16_t len[UINT8_MAX];
>         int i;
>
> -       if (status != AVRCP_STATUS_SUCCESS) {
> -               iov[0].iov_base = &status;
> -               iov[0].iov_len = sizeof(status);
> -               return avrcp_send_browsing(session, transaction,
> -                                               AVRCP_SET_BROWSED_PLAYER,
> -                                               iov, 1);
> -       }
> +       if (status != AVRCP_STATUS_SUCCESS)
> +               return avrcp_status_rsp(session, transaction,
> +                                       AVRCP_SET_BROWSED_PLAYER, status);
>
>         rsp.status = status;
>         put_be16(counter, &rsp.counter);
> @@ -3390,16 +3400,20 @@ int avrcp_set_browsed_player_rsp(struct avrcp *session, uint8_t transaction,
>  }
>
>  int avrcp_get_folder_items_rsp(struct avrcp *session, uint8_t transaction,
> -                                       uint16_t counter, uint8_t number,
> -                                       uint8_t *type, uint16_t *len,
> -                                       uint8_t **params)
> +                                       uint8_t status, uint16_t counter,
> +                                       uint8_t number, uint8_t *type,
> +                                       uint16_t *len, uint8_t **params)
>  {
>         struct iovec iov[UINT8_MAX * 2 + 1];
>         struct get_folder_items_rsp rsp;
>         uint8_t item[UINT8_MAX][3];
>         int i;
>
> -       rsp.status = AVRCP_STATUS_SUCCESS;
> +       if (status != AVRCP_STATUS_SUCCESS)
> +               return avrcp_status_rsp(session, transaction,
> +                                       AVRCP_GET_FOLDER_ITEMS, status);
> +
> +       rsp.status = status;
>         put_be16(counter, &rsp.counter);
>         put_be16(number, &rsp.number);
>
> @@ -3422,12 +3436,16 @@ int avrcp_get_folder_items_rsp(struct avrcp *session, uint8_t transaction,
>  }
>
>  int avrcp_change_path_rsp(struct avrcp *session, uint8_t transaction,
> -                                                               uint32_t items)
> +                                               uint8_t status, uint32_t items)
>  {
>         struct iovec iov;
>         struct change_path_rsp rsp;
>
> -       rsp.status = AVRCP_STATUS_SUCCESS;
> +       if (status != AVRCP_STATUS_SUCCESS)
> +               return avrcp_status_rsp(session, transaction, AVRCP_CHANGE_PATH,
> +                                                                       status);
> +
> +       rsp.status = status;
>         put_be32(items, &rsp.items);
>
>         iov.iov_base = &rsp;
> @@ -3477,12 +3495,9 @@ int avrcp_get_item_attributes_rsp(struct avrcp *session, uint8_t transaction,
>         if (number > AVRCP_MEDIA_ATTRIBUTE_LAST)
>                 return -EINVAL;
>
> -       if (status != AVRCP_STATUS_SUCCESS) {
> -               iov[0].iov_base = &status;
> -               iov[0].iov_len = sizeof(status);
> -               return avrcp_send_browsing(session, transaction,
> -                                       AVRCP_GET_ITEM_ATTRIBUTES, iov, 1);
> -       }
> +       if (status != AVRCP_STATUS_SUCCESS)
> +               return avrcp_status_rsp(session, transaction,
> +                                       AVRCP_GET_ITEM_ATTRIBUTES, status);
>
>         rsp.status = status;
>         rsp.number = number;
> @@ -3498,27 +3513,24 @@ int avrcp_get_item_attributes_rsp(struct avrcp *session, uint8_t transaction,
>                                         number * 2 + 1);
>  }
>
> -int avrcp_play_item_rsp(struct avrcp *session, uint8_t transaction)
> +int avrcp_play_item_rsp(struct avrcp *session, uint8_t transaction,
> +                                                               uint8_t status)
>  {
> -       struct iovec iov;
> -       struct play_item_rsp rsp;
> -
> -       rsp.status = AVRCP_STATUS_SUCCESS;
> -
> -       iov.iov_base = &rsp;
> -       iov.iov_len = sizeof(rsp);
> -
> -       return avrcp_send_browsing(session, transaction, AVRCP_PLAY_ITEM,
> -                                                               &iov, 1);
> +       return avrcp_status_rsp(session, transaction, AVRCP_PLAY_ITEM,
> +                                                               status);
>  }
>
> -int avrcp_search_rsp(struct avrcp *session, uint8_t transaction,
> +int avrcp_search_rsp(struct avrcp *session, uint8_t transaction, uint8_t status,
>                                         uint16_t counter, uint32_t items)
>  {
>         struct iovec iov;
>         struct search_rsp rsp;
>
> -       rsp.status = AVRCP_STATUS_SUCCESS;
> +       if (status != AVRCP_STATUS_SUCCESS)
> +               return avrcp_status_rsp(session, transaction, AVRCP_SEARCH,
> +                                                               status);
> +
> +       rsp.status = status;
>         put_be16(counter, &rsp.counter);
>         put_be32(items, &rsp.items);
>
> @@ -3529,18 +3541,11 @@ int avrcp_search_rsp(struct avrcp *session, uint8_t transaction,
>                                                                 &iov, 1);
>  }
>
> -int avrcp_add_to_now_playing_rsp(struct avrcp *session, uint8_t transaction)
> +int avrcp_add_to_now_playing_rsp(struct avrcp *session, uint8_t transaction,
> +                                                               uint8_t status)
>  {
> -       struct iovec iov;
> -       struct add_to_now_playing_rsp rsp;
> -
> -       rsp.status = AVRCP_STATUS_SUCCESS;
> -
> -       iov.iov_base = &rsp;
> -       iov.iov_len = sizeof(rsp);
> -
> -       return avrcp_send_browsing(session, transaction,
> -                                       AVRCP_ADD_TO_NOW_PLAYING, &iov, 1);
> +       return avrcp_status_rsp(session, transaction, AVRCP_ADD_TO_NOW_PLAYING,
> +                                                               status);
>  }
>
>  int avrcp_send_passthrough(struct avrcp *session, uint32_t vendor, uint8_t op)
> diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
> index 9985c4a..2299c83 100644
> --- a/android/avrcp-lib.h
> +++ b/android/avrcp-lib.h
> @@ -327,17 +327,19 @@ int avrcp_set_browsed_player_rsp(struct avrcp *session, uint8_t transaction,
>                                         uint32_t items, uint8_t depth,
>                                         const char **folders);
>  int avrcp_get_folder_items_rsp(struct avrcp *session, uint8_t transaction,
> -                                       uint16_t counter, uint8_t number,
> -                                       uint8_t *type, uint16_t *len,
> -                                       uint8_t **params);
> +                                       uint8_t status, uint16_t counter,
> +                                       uint8_t number, uint8_t *type,
> +                                       uint16_t *len, uint8_t **params);
>  int avrcp_change_path_rsp(struct avrcp *session, uint8_t transaction,
> -                                                               uint32_t items);
> +                                               uint8_t status, uint32_t items);
>  int avrcp_get_item_attributes_rsp(struct avrcp *session, uint8_t transaction,
>                                         uint8_t status, uint8_t number,
>                                         uint32_t *attrs, const char **text);
> -int avrcp_play_item_rsp(struct avrcp *session, uint8_t transaction);
> -int avrcp_search_rsp(struct avrcp *session, uint8_t transaction,
> +int avrcp_play_item_rsp(struct avrcp *session, uint8_t transaction,
> +                                       uint8_t status);
> +int avrcp_search_rsp(struct avrcp *session, uint8_t transaction, uint8_t status,
>                                         uint16_t counter, uint32_t items);
> -int avrcp_add_to_now_playing_rsp(struct avrcp *session, uint8_t transaction);
> +int avrcp_add_to_now_playing_rsp(struct avrcp *session, uint8_t transaction,
> +                                                               uint8_t status);
>
>  int avrcp_send_passthrough(struct avrcp *session, uint32_t vendor, uint8_t op);
> diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
> index 154175e..a6a1872 100644
> --- a/unit/test-avrcp.c
> +++ b/unit/test-avrcp.c
> @@ -719,8 +719,8 @@ static int get_folder_items(struct avrcp *session, uint8_t transaction,
>         if (start > 1)
>                 return -ERANGE;
>
> -       avrcp_get_folder_items_rsp(session, transaction, 0xabcd, 0, NULL, NULL,
> -                                                                       NULL);
> +       avrcp_get_folder_items_rsp(session, transaction, AVRCP_STATUS_SUCCESS,
> +                                               0xabcd, 0, NULL, NULL, NULL);
>
>         return -EAGAIN;
>  }
> @@ -734,7 +734,7 @@ static int change_path(struct avrcp *session, uint8_t transaction,
>         if (!uid)
>                 return -ENOTDIR;
>
> -       avrcp_change_path_rsp(session, transaction, 0);
> +       avrcp_change_path_rsp(session, transaction, AVRCP_STATUS_SUCCESS, 0);
>
>         return -EAGAIN;
>  }
> @@ -768,7 +768,7 @@ static int play_item(struct avrcp *session, uint8_t transaction, uint8_t scope,
>         if (!uid)
>                 return -ENOENT;
>
> -       avrcp_play_item_rsp(session, transaction);
> +       avrcp_play_item_rsp(session, transaction, AVRCP_STATUS_SUCCESS);
>
>         return -EAGAIN;
>  }
> @@ -778,7 +778,7 @@ static int search(struct avrcp *session, uint8_t transaction,
>  {
>         DBG("");
>
> -       avrcp_search_rsp(session, transaction, 0xaabb, 0);
> +       avrcp_search_rsp(session, transaction, AVRCP_STATUS_SUCCESS, 0xaabb, 0);
>
>         return -EAGAIN;
>  }
> @@ -792,7 +792,8 @@ static int add_to_now_playing(struct avrcp *session, uint8_t transaction,
>         if (!uid)
>                 return -ENOENT;
>
> -       avrcp_add_to_now_playing_rsp(session, transaction);
> +       avrcp_add_to_now_playing_rsp(session, transaction,
> +                                                       AVRCP_STATUS_SUCCESS);
>
>         return -EAGAIN;
>  }
> --
> 1.9.3

I went ahead and push this set.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH v2 0/5] Introduce shared/gatt-server.
From: Arman Uguray @ 2014-10-16 18:49 UTC (permalink / raw)
  To: BlueZ development
In-Reply-To: <1413234602-20566-1-git-send-email-armansito@chromium.org>

On Mon, Oct 13, 2014 at 2:09 PM, Arman Uguray <armansito@chromium.org> wrote:
> *v2:
>   - Split read_by_grp_type_cb into two functions by moving the response PDU
>     encoding loop into a helper function.
>
> *v1:
>   - Make gatt-db external to gatt-server, as initially discussed.
>   - Also implement Read By Group Type request.
>
> Arman Uguray (5):
>   shared/att: Drop the connection if a request is received while one is
>     pending.
>   shared/att: Respond with ERROR_REQUEST_NOT_SUPPORTED for unhandled
>     requests.
>   shared/gatt-server: Introduce shared/gatt-server.
>   shared/gatt-server: Support Exchange MTU request.
>   shared/gatt-server: Support Read By Group Type request.
>
>  Makefile.am              |   1 +
>  src/shared/att.c         | 124 +++++++++++------
>  src/shared/gatt-server.c | 356 +++++++++++++++++++++++++++++++++++++++++++++++
>  src/shared/gatt-server.h |  40 ++++++
>  4 files changed, 481 insertions(+), 40 deletions(-)
>  create mode 100644 src/shared/gatt-server.c
>  create mode 100644 src/shared/gatt-server.h
>
> --
> 2.1.0.rc2.206.gedb03e5
>

ping. Luiz made comments on one of the patches but I believe they've
been addressed.

^ permalink raw reply

* Re: [PATCH v2 1/5] shared/att: Drop the connection if a request is received while one is pending.
From: Arman Uguray @ 2014-10-16 18:47 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <CABBYNZLjX_r=1fBb68mb0vJ_K7p=6Wh-W77ikVWi6s+DRuHVNA@mail.gmail.com>

Hi Luiz,

>>> It seems this code is not following our coding style regarding multi
>>> line comments, check doc/coding-style.txt(M2: Multiple line comment)
>>> the first line should be empty.
>>>
>>
>> I didn't realize that was the comment style. I've seen both styles in
>> daemon code and I think I went with this one because of that. I'd
>> rather have the code be consistent (since shared/att uses this style
>> elsewhere) and maybe do a style correction pass in another patch?
>
> Sure, I can probably fix this myself just made the comment to let you
> know that we do in fact have a coding style for it.
>

Ah got it.


>>> This might cause a problem with our own code when connecting to each
>>> other if bt_att_cancel is used, apparently bt_att_cancel does not send
>>> anything to the remote side which seems to enable sending a new
>>> request without waiting any response for the first one.
>>>
>>
>> I'm confused. Do you mean if bt_att is being used in the client role,
>> it can send multiple requests this way? That is correct, though I
>> don't see how that's related to this patch? Currently bt_att_cancel
>> can be used to cancel waiting for a pending request and send the next
>> one, as you said. In that regard, it doesn't actually "cancel"
>> anything if the PDU has been sent over the air already. I don't know
>> how big of a problem this is, since the remote end should normally
>> detect the error and terminate the connection anyway. If this becomes
>> a problem we can always prevent canceling a request that has already
>> left the queue and is pending. Though, again, this isn't really
>> related to this patch unless I'm missing something.
>
> Sorry for the confusion, this patch is actually fine what we really
> need to fix is bt_att_cancel should not really remove the pending
> request otherwise the remote may disconnect if we proceed with another
> request.
>

Ok. I'll prepare a separate patch for that. We probably want
bt_att_cancel to keep the pending request pointer but it should
perhaps set the response and destroy callbacks to NULL. Same thing
applies to both outgoing requests and indications.

Cheers,
Arman

^ permalink raw reply

* Re: help needed for bluez debugging. - suspend-resume
From: John Miller @ 2014-10-16 17:39 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <CAPJhuY+vsNXuUK+yVEZoK_T34+Ldv+QaXSWxMY8xDJTPOivKRQ@mail.gmail.com>

I am hoping somebody would help.

On Wed, Oct 15, 2014 at 8:44 PM, John Miller <jmiller5611@gmail.com> wrote:
> Somebody, please help
>
>
> On Wed, Oct 15, 2014 at 5:11 PM, John Miller <jmiller5611@gmail.com> wrote:
>> Hello,
>>
>> I ran into a problem in which after resuming form suspend my bluetooth
>> headset does not autoconnect.
>>
>> i have bluez-5.19 in my system with chromium OS on kernel 3.14
>>
>> btmon says that when my HCI host tries to connect after resuming,
>> "authentication failure" error pops up.
>>
>> How can i further debug this issue?
>>
>> What could be the reason for failure?
>>
>> Please help.

^ permalink raw reply

* Correct use of le_set_scan_response_data_cp / hci_send_req ?
From: Martin Vogt @ 2014-10-16 16:01 UTC (permalink / raw)
  To: linux-bluetooth

[-- Attachment #1: Type: text/plain, Size: 580 bytes --]

Hello,

I try to create a btle server which does advertise itsself with the
name "HEY".

Attached is a demo program.
Compile with:

g++ -o leserv leserv.cpp -lbluetooth

then start the program as root.
And on another host start:

hcitool lescan

The current version prints "HEY" but I think the API
is wrong here. Every other version which can be found
on the internet uses the

// does not work
//hci_le_set_scan_response_data(hciSocket,(uint8_t*)msg,strlen(msg),0);

implementation, and this one does not work.

What would be a correct example for this task?


regards,

Martin

[-- Attachment #2: leserv.cpp --]
[-- Type: text/x-c++src, Size: 8043 bytes --]


/*

  Compile with:

  g++ -o leserv leserv.cpp -lbluetooth

*/

#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/prctl.h>
#include <unistd.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>






int lastSignal = 0;

static void signalHandler(int signal) {
  lastSignal = signal;
}

int hci_le_set_advertising_data(int dd, uint8_t* data, uint8_t length, int to)
{
  struct hci_request rq;
  le_set_advertising_data_cp data_cp;
  uint8_t status;

  memset(&data_cp, 0, sizeof(data_cp));
  data_cp.length = length;
  memcpy(&data_cp.data, data, sizeof(data_cp.data));

  memset(&rq, 0, sizeof(rq));
  rq.ogf = OGF_LE_CTL;
  rq.ocf = OCF_LE_SET_ADVERTISING_DATA;
  rq.cparam = &data_cp;
  rq.clen = LE_SET_ADVERTISING_DATA_CP_SIZE;
  rq.rparam = &status;
  rq.rlen = 1;

  if (hci_send_req(dd, &rq, to) < 0)
    return -1;

  if (status) {
    errno = EIO;
    return -1;
  }

  return 0;
}

int hci_le_set_scan_response_data(int dd, uint8_t* data, uint8_t length, int to)
{
  struct hci_request rq;
  le_set_scan_response_data_cp data_cp;
  uint8_t status;

  memset(&data_cp, 0, sizeof(data_cp));
  data_cp.length = length;
  memcpy(&data_cp.data, data, sizeof(data_cp.data));

  memset(&rq, 0, sizeof(rq));
  rq.ogf = OGF_LE_CTL;
  rq.ocf = OCF_LE_SET_SCAN_RESPONSE_DATA;
  rq.cparam = &data_cp;
  rq.clen = LE_SET_SCAN_RESPONSE_DATA_CP_SIZE;
  rq.rparam = &status;
  rq.rlen = 1;

  if (hci_send_req(dd, &rq, to) < 0)
    return -1;

  if (status) {
    errno = EIO;
    return -1;
  }

  return 0;
}


int le_advertise_enable(int hciSocket,
			int hciDeviceId,
			int previousAdapterState) {
  struct hci_dev_info hciDevInfo;
  int currentAdapterState;
  const char* adapterState = NULL;

  memset(&hciDevInfo, 0x00, sizeof(hciDevInfo));

  hciDevInfo.dev_id = hciDeviceId;
  // get HCI dev info for adapter state
  ioctl(hciSocket, HCIGETDEVINFO, (void *)&hciDevInfo);
  currentAdapterState = hci_test_bit(HCI_UP, &hciDevInfo.flags);
  
  if (previousAdapterState != currentAdapterState) {
    previousAdapterState = currentAdapterState;
    
    if (!currentAdapterState) {
      adapterState = "poweredOff";
    } else {
      hci_le_set_advertise_enable(hciSocket, 0, 1000);
      
      hci_le_set_advertise_enable(hciSocket, 1, 1000);
      
      if (hci_le_set_advertise_enable(hciSocket, 0, 1000) == -1) {
	switch (errno) {
          case EPERM:
            adapterState = "unauthorized";
            break;
          case EIO:
            adapterState = "unsupported";
            break;
          case ETIMEDOUT:
            adapterState = "timedout";
            break;
          default:
            printf("advertiseErrno %d\n", errno);
            adapterState = "unknown";
            break;
          }
        } else {
          adapterState = "poweredOn";
        }
      }

      printf("adapterState %s\n", adapterState);
  }
  return currentAdapterState;
}


void setScanResponseData(int socket,uint8_t* data, uint8_t length) {
  printf("Scan response data: len:%d\n",length);
  for (uint8_t i = 0; i < length; ++i) {
    printf("%02x ", data[i]);
  }
  printf("\n");

  int timeout = 0; // infinite

  le_set_scan_response_data_cp cp;
  memset(&cp, 0, sizeof(cp));
  cp.length = length+2;
  cp.data[0]=length+2;
  cp.data[1]=0x8;
  
  memcpy(&cp.data[2], data, length);
  struct hci_request rq;
  uint8_t status;
  memset(&rq, 0, sizeof(rq));
  rq.ogf = OGF_LE_CTL;
  rq.ocf = OCF_LE_SET_SCAN_RESPONSE_DATA;
  rq.cparam = &cp;
  rq.clen = LE_SET_SCAN_RESPONSE_DATA_CP_SIZE;
  rq.rparam = &status;
  rq.rlen = 1;
  if (hci_send_req(socket, &rq, timeout) < 0) {
    perror("hci_send_req\n");
    printf("1-Error setting advertising data\n");
  }
  if (status) {
    printf("2-Error setting advertising data");
  }
}


int main(int argc, const char* argv[])
{
  const char *hciDeviceIdOverride = NULL;
  int hciDeviceId = 0;
  int hciSocket;
  //struct hci_dev_info hciDevInfo;

  //int previousAdapterState = -1;
  int currentAdapterState=-1;
  const char* adapterState = NULL;
  
  fd_set rfds;
  struct timeval tv;
  int selectRetval;

  char stdinBuf[256 * 2 + 1];
  char advertisementDataBuf[256];
  int advertisementDataLen = 0;
  char scanDataBuf[256];
  int scanDataLen = 0;
  int len;
  int i;

  //  memset(&hciDevInfo, 0x00, sizeof(hciDevInfo));
  
  // remove buffering 
  setbuf(stdin, NULL);
  setbuf(stdout, NULL);
  setbuf(stderr, NULL);

  // setup signal handlers
  signal(SIGINT, signalHandler);
  signal(SIGKILL, signalHandler);
  signal(SIGHUP, signalHandler);
  signal(SIGUSR1, signalHandler);

  prctl(PR_SET_PDEATHSIG, SIGINT);

  if (argc > 1 && strlen(argv[1]) > 0) {
    hciDeviceIdOverride = argv[1];
  }
  if (hciDeviceIdOverride != NULL) {
    hciDeviceId = atoi(hciDeviceIdOverride);
  } else {
    // if no env variable given, use the first available device
    hciDeviceId = hci_get_route(NULL);
  }

  if (hciDeviceId < 0) {
    hciDeviceId = 0; // use device 0, if device id is invalid
  }

  printf("hciDeviceId %d\n", hciDeviceId);

  // setup HCI socket
  hciSocket = hci_open_dev(hciDeviceId);
  //hciDevInfo.dev_id = hciDeviceId;

  if (hciSocket == -1) {
    printf("adapterState unsupported\n");
    return -1;
  }
  const char* msg="HEY"; 

  while(1) {
    FD_ZERO(&rfds);
    FD_SET(0, &rfds);
    FD_SET(hciSocket, &rfds);

    tv.tv_sec = 1;
    tv.tv_usec = 0;
    currentAdapterState=le_advertise_enable(hciSocket,hciDeviceId,
					    currentAdapterState);
    // stop advertising
    hci_le_set_advertise_enable(hciSocket, 0, 1000);

    // works
    setScanResponseData(hciSocket,(uint8_t*)msg,strlen(msg));

    // does not work
    //hci_le_set_scan_response_data(hciSocket,(uint8_t*)msg,strlen(msg),0);

    // start advertising
    hci_le_set_advertise_enable(hciSocket, 1, 1000);

    selectRetval = select(hciSocket + 1, &rfds, NULL, NULL, &tv);
    printf("selectRetval:%d\n",selectRetval);
    if (-1 == selectRetval) {
      if (SIGINT == lastSignal || SIGKILL == lastSignal) {
        // done
        break;
      } else if (SIGHUP == lastSignal) {
        // stop advertising
        hci_le_set_advertise_enable(hciSocket, 0, 1000);
      } else if (SIGUSR1 == lastSignal) {
	printf("SIGUSR1\n");

      } 
    } else if (selectRetval) {
      if (FD_ISSET(0, &rfds)) {
        len = read(0, stdinBuf, sizeof(stdinBuf));
	printf("len:%d\n",len);
        if (len <= 0) {
          break;
        } 

        i = 0;
        advertisementDataLen = 0;
        while(i < len && stdinBuf[i] != ' ') {
          unsigned int data = 0;
          int token=sscanf(&stdinBuf[i], "%02x", &data);
          advertisementDataBuf[advertisementDataLen] = data;
	  printf("databuf[%d]=%x (token:%d)\n",advertisementDataLen,data,token);
          advertisementDataLen++;
          i += 2;
        }

        i++;
        scanDataLen = 0;
        while(i < len && stdinBuf[i] != '\n') {
          unsigned int data = 0;
          sscanf(&stdinBuf[i], "%02x", &data);
          scanDataBuf[scanDataLen] = data;
    	  printf("scanbuf[%d]=%x\n",scanDataLen,data);
	  scanDataLen++;
          i += 2;
        }
	const char* mesg="Martin";
	
        // stop advertising
        hci_le_set_advertise_enable(hciSocket, 0, 1000);

        // set scan data
        hci_le_set_scan_response_data(hciSocket, (uint8_t*)&scanDataBuf, scanDataLen, 1000);

        // set advertisement data
        hci_le_set_advertising_data(hciSocket, (uint8_t*)&advertisementDataBuf, advertisementDataLen, 1000);

        // start advertising
        hci_le_set_advertise_enable(hciSocket, 1, 1000);

        // set scan data
        hci_le_set_scan_response_data(hciSocket, (uint8_t*)&scanDataBuf, scanDataLen, 1000);

        // set advertisement data
        hci_le_set_advertising_data(hciSocket, (uint8_t*)&advertisementDataBuf, advertisementDataLen, 1000);
      }
    }
  }

  // stop advertising
  hci_le_set_advertise_enable(hciSocket, 0, 1000);

  close(hciSocket);

  return 0;
}

^ permalink raw reply

* Re: btusb_intr_complete returns -EPIPE
From: Naveen Kumar Parna @ 2014-10-16 15:32 UTC (permalink / raw)
  To: Alan Stern
  Cc: Oliver Neukum, linux-bluetooth@vger.kernel.org, linux-usb, acho
In-Reply-To: <Pine.LNX.4.44L0.1410161012530.1316-100000@iolanthe.rowland.org>

On Thu, Oct 16, 2014 at 7:46 PM, Alan Stern <stern@rowland.harvard.edu> wrote:
> On Thu, 16 Oct 2014, Naveen Kumar Parna wrote:
>
>> > It's entirely possible that the stall packets are created by the hub.
>> > When a full-speed device is connected to a USB-2 hub, and the device
>> > fails to respond to a packet sent by the host, the hub reports this
>> > failure as a stall.
>>
>> Here I don’t think device fails to respond to a packet sent by the
>> host. I verified this by connecting Ellisys USB analyser in between
>> host and devices.
>>
>> For example Look at the attached(Sample_HciEvt.png) HCI event captured
>> by Ellisys USB analyser. It is a valid HCI event from device to Host.
>> IN transaction 96 1 ACK FS 16 bytes (FF 2F C2 01 00 17 00 DF 00 01 10
>> 00 00 A9 EE 0F)
>> IN transaction 96 1 ACK FS 16 bytes (00 00 00 5A 06 9D 39 00 00 66 00
>> 00 00 00 00 00)
>> IN transaction 96 1 ACK FS 16 bytes (00 00 00 00 00 00 00 00 00 00 00
>> 8E 05 28 00 01)
>> IN transaction 96 1 ACK FS 1 byte (00)
>
> This doesn't prove anything.  All it means is that the device responded
> properly on these four occasions.  What if the device failed to respond
> on some other occasion?  You have to compare the output of the analyzer
> with the output from usbmon.  If usbmon shows a STALL and the analyzer
> shows a valid reply for the very same packet, then you'll know the
> device isn't at fault.
>


I forgot to post usbmon log, but usbmon shows a STALL and the analyser
shows a valid reply for the very same packet.

I tried this many number of times and always got same result.

But did not get STALL on OHCI-USB host controller on PCI card with
internal USB 1.1 hub. In both the scenario’s I used same devices.




> You should also run a similar test when you connect the device through
> a USB-2 hub.  In fact, you should run two tests.  In one test, connect
> the analyzer to the cable segment between the computer and the hub; in
> the other test, connect the analyzer to the cable segment between the
> hub and the device.
>


Ok, I will try and update you on this.




Thanks,
Naveen

^ permalink raw reply

* Re: btusb_intr_complete returns -EPIPE
From: Naveen Kumar Parna @ 2014-10-16 15:05 UTC (permalink / raw)
  To: Alan Stern
  Cc: Oliver Neukum, linux-bluetooth@vger.kernel.org, linux-usb, acho
In-Reply-To: <Pine.LNX.4.44L0.1410161007340.1316-100000@iolanthe.rowland.org>

Ok, I will do this and update you.
But Currently I am on long leave and I can update you on 27th Oct.

Thanks,
Naveen

On Thu, Oct 16, 2014 at 7:39 PM, Alan Stern <stern@rowland.harvard.edu> wrote:
> On Thu, 16 Oct 2014, Naveen Kumar Parna wrote:
>
>> > Indeed. However, it is possible to use an additional in between your
>> > devices and the internal hub.
>> >
>> >         Regards
>> >                 Oliver
>> >
>> >
>>
>>
>> Tested with this configuration(external hubs Dev 3, Dev 4, Dev 17, Dev
>> 10) and got the same result.
>>
>> /:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/2p, 480M
>>
>> /:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/2p, 480M
>>
>>     |__ Port 1: Dev 2, If 0, Class=hub, Driver=hub/6p, 480M
>>
>>         |__ Port 5: Dev 3, If 0, Class=hub, Driver=hub/7p, 12M
>>
>>             |__ Port 1: Dev 4, If 0, Class=hub, Driver=hub/7p, 12M
>
> This is not what Oliver meant.  You have to use a USB-2 hub.  And
> having one of them is enough; you don't need two.
>
> Alan Stern
>

^ 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