Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH] core: Add ControllerMode to list of supported options
From: Marcel Holtmann @ 2014-10-21 11:08 UTC (permalink / raw)
  To: Jacob Siverskog; +Cc: linux-bluetooth
In-Reply-To: <1413877738-23941-1-git-send-email-jacob@teenageengineering.com>

Hi Jacob,

> Signed-off-by: Jacob Siverskog <jacob@teenageengineering.com>

we do not add signed-off-by for userspace patches. That is only required for kernel patches.

> Prevent warning message 'Unknown key ControllerMode in main.conf'.
> ---
> src/main.c | 1 +
> 1 file changed, 1 insertion(+)
> 
> diff --git a/src/main.c b/src/main.c
> index 191dc11..061060d 100644
> --- a/src/main.c
> +++ b/src/main.c
> @@ -79,6 +79,7 @@ static const char * const supported_options[] = {
> 	"ReverseServiceDiscovery",
> 	"NameResolving",
> 	"DebugKeys",
> +	"ControllerMode",
> };

Good catch. Please resend the patch without signed-off-by line.

Regards

Marcel


^ permalink raw reply

* Re: Confused about gatttool in Makefile.tools
From: Marcel Holtmann @ 2014-10-21 11:12 UTC (permalink / raw)
  To: Qian Lei; +Cc: linux-bluetooth
In-Reply-To: <20141021183846.3ec677db@Fedora>

Hi Quian,

> I don't understand the log message "build: Only compile actually
> selected binaries" in commit ed7989e, which modifies the file
> Makefile.tools. Gatttool and some other programs are only compiled and
> do not been installed into system any more. I'm confused about it, why
> did we do this?

some tools are only useful to developers. They should not be installed. We only install tools that are generally useful (or considered legacy like hciconfig).

The jump to BlueZ 5 came with a massive cleanup of our tools and only a selected few get installed. Main operation should be done with bluetoothctl these days.

Regards

Marcel


^ permalink raw reply

* [PATCH] core: Add ControllerMode to list of supported options
From: Jacob Siverskog @ 2014-10-21 11:28 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth, Jacob Siverskog
In-Reply-To: <3055BAC9-79FC-42D1-B8ED-292E8B5D2665@holtmann.org>

Prevent warning message 'Unknown key ControllerMode in main.conf'.
---
 src/main.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/main.c b/src/main.c
index 191dc11..061060d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -79,6 +79,7 @@ static const char * const supported_options[] = {
 	"ReverseServiceDiscovery",
 	"NameResolving",
 	"DebugKeys",
+	"ControllerMode",
 };
 
 GKeyFile *btd_get_main_conf(void)
-- 
1.8.3.2

^ permalink raw reply related

* Re: [PATCH] core: Add ControllerMode to list of supported options
From: Marcel Holtmann @ 2014-10-21 11:38 UTC (permalink / raw)
  To: Jacob Siverskog; +Cc: linux-bluetooth
In-Reply-To: <1413890907-23341-1-git-send-email-jacob@teenageengineering.com>

Hi Jacob,

> Prevent warning message 'Unknown key ControllerMode in main.conf'.
> ---
> src/main.c | 1 +
> 1 file changed, 1 insertion(+)

patch has been applied.

Regards

Marcel


^ permalink raw reply

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

Hi,

On Tue, Oct 21, 2014 at 10:06 AM, Bharat Panda <bharat.panda@samsung.com> wrote:
> Changes made to add support for MSE local time and timezone offset
> parameter along with GetMessageListing response.
> ---
>  obexd/plugins/mas.c | 36 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 36 insertions(+)
>
> diff --git a/obexd/plugins/mas.c b/obexd/plugins/mas.c
> index fb97fe3..5379a01 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,33 @@ 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;
> +       char sign;
> +
> +       gettimeofday(&time_val, NULL);
> +
> +       if (!localtime_r(&time_val.tv_sec, &ltime))
> +               return NULL;
> +
> +       if (difftime(mktime(localtime(&time_val.tv_sec)),
> +                                                       mktime(gmtime(&time_val.tv_sec))) < 0)
> +               sign = '+';
> +       else
> +               sign = '-';
> +
> +       local_ts = g_strdup_printf("%04d%02d%02dT%02d%02d%02d%c%2ld%2ld",
> +                                       ltime.tm_year + 1900, ltime.tm_mon + 1,
> +                                       ltime.tm_mday, ltime.tm_hour,
> +                                       ltime.tm_min, ltime.tm_sec, sign,
> +                                       ltime.tm_gmtoff/3600, (ltime.tm_gmtoff%3600)/60);
> +
> +       return local_ts;
> +}
> +
>  static const char *yesorno(gboolean a)
>  {
>         if (a)
> @@ -243,6 +271,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 +387,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

Please check your coding style.

WARNING:LONG_LINE: line over 80 characters
#30: FILE: obexd/plugins/mas.c:245:
+ mktime(gmtime(&time_val.tv_sec))) < 0)

WARNING:LONG_LINE: line over 80 characters
#39: FILE: obexd/plugins/mas.c:254:
+ ltime.tm_gmtoff/3600, (ltime.tm_gmtoff%3600)/60);

total: 0 errors, 2 warnings, 60 lines checked


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* [PATCH v3] obexd/mas: Add Support for MSETime filter
From: Bharat Panda @ 2014-10-21 13:08 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: cpgs, Bharat Panda

Changes made to add support for MSE local time and timezone offset
parameter along with GetMessageListing response.
---
 obexd/plugins/mas.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/obexd/plugins/mas.c b/obexd/plugins/mas.c
index fb97fe3..5b95b3a 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,34 @@ 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;
+	char sign;
+
+	gettimeofday(&time_val, NULL);
+
+	if (!localtime_r(&time_val.tv_sec, &ltime))
+		return NULL;
+
+	if (difftime(mktime(localtime(&time_val.tv_sec)),
+				mktime(gmtime(&time_val.tv_sec))) < 0)
+		sign = '+';
+	else
+		sign = '-';
+
+	local_ts = g_strdup_printf("%04d%02d%02dT%02d%02d%02d%c%2ld%2ld",
+					ltime.tm_year + 1900, ltime.tm_mon + 1,
+					ltime.tm_mday, ltime.tm_hour,
+					ltime.tm_min, ltime.tm_sec, sign,
+					ltime.tm_gmtoff/3600,
+					(ltime.tm_gmtoff%3600)/60);
+
+	return local_ts;
+}
+
 static const char *yesorno(gboolean a)
 {
 	if (a)
@@ -243,6 +272,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 +388,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


^ permalink raw reply related

* RE: [PATCH v2] obexd/mas: Add Support for MSETime filter
From: Bharat Bhusan Panda @ 2014-10-21 14:05 UTC (permalink / raw)
  To: 'Luiz Augusto von Dentz'; +Cc: linux-bluetooth, cpgs
In-Reply-To: <CABBYNZ+ugOkF0OYQ9ovUFhOyFyGgUjh9Eay+o-fW2Qu20S9C8Q@mail.gmail.com>

Hi Luiz

> >  obexd/plugins/mas.c | 36 ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 36 insertions(+)
> >
> > diff --git a/obexd/plugins/mas.c b/obexd/plugins/mas.c index
> > fb97fe3..5379a01 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,33 @@ 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;
> > +       char sign;
> > +
> > +       gettimeofday(&time_val, NULL);
> > +
> > +       if (!localtime_r(&time_val.tv_sec, &ltime))
> > +               return NULL;
> > +
> > +       if (difftime(mktime(localtime(&time_val.tv_sec)),
> > +                                                       mktime(gmtime(&time_val.tv_sec))) < 0)
> > +               sign = '+';
> > +       else
> > +               sign = '-';
> > +
> > +       local_ts =
> g_strdup_printf("%04d%02d%02dT%02d%02d%02d%c%2ld%2ld",
> > +                                       ltime.tm_year + 1900, ltime.tm_mon + 1,
> > +                                       ltime.tm_mday, ltime.tm_hour,
> > +                                       ltime.tm_min, ltime.tm_sec, sign,
> > +                                       ltime.tm_gmtoff/3600,
> > + (ltime.tm_gmtoff%3600)/60);
> > +
> > +       return local_ts;
> > +}
> > +
> >  static const char *yesorno(gboolean a)  {
> >         if (a)
> > @@ -243,6 +271,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 +387,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
> 
> Please check your coding style.
> 
> WARNING:LONG_LINE: line over 80 characters
> #30: FILE: obexd/plugins/mas.c:245:
> + mktime(gmtime(&time_val.tv_sec))) < 0)
> 
> WARNING:LONG_LINE: line over 80 characters
> #39: FILE: obexd/plugins/mas.c:254:
> + ltime.tm_gmtoff/3600, (ltime.tm_gmtoff%3600)/60);
> 
> total: 0 errors, 2 warnings, 60 lines checked

I have fixed the warnings and submitted v3 patch  for the same.

Best Regards,
Bharat


^ permalink raw reply

* Re: [PATCH v4 00/11] shared/hfp: Add support for HFP HF
From: Lukasz Rymanowski @ 2014-10-21 14:54 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org; +Cc: Lukasz Rymanowski
In-Reply-To: <1412898611-12199-1-git-send-email-lukasz.rymanowski@tieto.com>

Hi,

On 10 October 2014 01:50, Lukasz Rymanowski <lukasz.rymanowski@tieto.com> wrote:
> Following patches extends hfp API with HFP HF functionality.
> HFP HF parser has been added and unit test for it.
>
> To consider: how strict we should be when it comes to parsing
> AT responses. For example, at the moment, command +CCLC:<cr><lf>
> will be recognized as +CCLC: eventhough correct response format
> should be <cr><lf>+CCLC:<cr><lf>
>
> Note: As discussed on IRC I did not try to generalize code.
>
> v2:
> * minor self review fixes
> * response callback on send command, contains now result (OK/ERROR) and
> data from unsolicited response if available.
>
> v3:
> * Fix some memory leaks found on self review
>
> v4:
> * Fallback to approach from v1 in context of response callback for AT command.
> Bassically, if AT+X has +X and OK response, response callback contains only OK or
> ERROR code (including CME which will be added in following patches). To get +X
> response, user need to use hfp_hf_register() API. It is done mostly to keep hfp.c
> simple. With this approach we do not have to cache all +X in hfp.c before calling
> response callback.
>
> Lukasz Rymanowski (11):
>   shared/hfp: Add support for HFP HF
>   shared/hfp: Add set_debug and close_on_unref API for HFP HF
>   shared/hfp: Add set disconnect handler and disconnect API to HFP HF
>   shared/hfp: Add register/unregister event for HFP HF
>   shared/hfp: Add HFP HF parser
>   shared/hfp: Add send AT command API for HFP HF
>   unit/test-hfp: Provide test_handler function via struct data
>   unit/test-hfp: Add init test for HFP HF
>   unit/test-hfp: Add send command tests for HFP HF
>   unit/test-hfp: Add tests for unsolicited results for HFP HF
>   unit/test-hfp: Add some robustness tests for HFP HF
>
>  src/shared/hfp.c | 624 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  src/shared/hfp.h |  30 +++
>  unit/test-hfp.c  | 285 +++++++++++++++++++++++--
>  3 files changed, 920 insertions(+), 19 deletions(-)
>

ping

\Lukasz
> --
> 1.8.4
>

^ permalink raw reply

* Re: how to set PSCAN mode in .conf?
From: Jeff Chua @ 2014-10-21 16:19 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <A5A941D6-C4EB-45A1-96A5-8E9E2990EEDB@holtmann.org>

On Tue, Oct 21, 2014 at 7:06 PM, Marcel Holtmann <marcel@holtmann.org> wrote:
> If anyone wants to implement action 0x00 semantics on BR/EDR, then it requires using Periodic Inquiry. It is possible, but it is not a common use case these days.

Marcel,

If that's not common, perhaps not necessary.

But, I still want explore setting the "discoverable" and "connectable"
in main.conf ... will you consider a patch if I work on that? I'm
working on the raspberry Pi and every seconds count on the slow CPU
and if these config can be set without hciconfig, it'll save another
command.

Currently, I'm doing this ...
    # { sleep 3 && hciconfig hci0 piscan 2>/dev/null; } &


Thanks,
Jeff.

^ permalink raw reply

* Re: how to set PSCAN mode in .conf?
From: Marcel Holtmann @ 2014-10-21 16:44 UTC (permalink / raw)
  To: Jeff Chua; +Cc: linux-bluetooth
In-Reply-To: <CAAJw_Zvd3rq745QPRinnRivsYkYKH6QAHGSikEaFajY7go3yew@mail.gmail.com>

Hi Jeff,

>> If anyone wants to implement action 0x00 semantics on BR/EDR, then it requires using Periodic Inquiry. It is possible, but it is not a common use case these days.
> 
> Marcel,
> 
> If that's not common, perhaps not necessary.
> 
> But, I still want explore setting the "discoverable" and "connectable"
> in main.conf ... will you consider a patch if I work on that? I'm
> working on the raspberry Pi and every seconds count on the slow CPU
> and if these config can be set without hciconfig, it'll save another
> command.
> 
> Currently, I'm doing this ...
>    # { sleep 3 && hciconfig hci0 piscan 2>/dev/null; } &

I am confused why you not just use bluetoothctl (or you own tool/script) and set it. bluetoothd will enforce that setting correct for you.

Regards

Marcel


^ permalink raw reply

* Re: how to set PSCAN mode in .conf?
From: Jeff Chua @ 2014-10-21 17:02 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <AC7B3B6F-9FCF-472D-9844-B076B4D66C81@holtmann.org>

On Wed, Oct 22, 2014 at 12:44 AM, Marcel Holtmann <marcel@holtmann.org> wrote:

>> Currently, I'm doing this ...
>>    # { sleep 3 && hciconfig hci0 piscan 2>/dev/null; } &
>
> I am confused why you not just use bluetoothctl (or you own tool/script) and set it. bluetoothd will enforce that setting correct for you.

Marcel,

I guess I didn't try hard enough. I just tried bluetoothctl in my
script and it's working. No "sleep" needed.

Thank again,

Jeff.

^ permalink raw reply

* Re: BlueZ 5.24: Using the LE Heart Rate Profile
From: Sujay Sarkhel @ 2014-10-21 22:32 UTC (permalink / raw)
  To: linux-bluetooth

Some more information:

I ran the daemon in foreground with debugging:
  /usr/libexec/bluetooth/bluetoothd -n -d

Subsequently, when I execute ./test-device connect
<bluetooth_address>, I see the following debug information:

bluetoothd[11844]: src/device.c:btd_device_set_temporary() temporary 0
bluetoothd[11844]: src/device.c:device_connect_le() Connection attempt
to: FC:7A:62:1F:F9:F6
bluetoothd[11844]: src/adapter.c:connected_callback() hci0 device
FC:7A:62:1F:F9:F6 connected eir_len 0
bluetoothd[11844]: attrib/gattrib.c:g_attrib_ref() 0x334c88: ref=1
bluetoothd[11844]: Device object not found for attrib server
bluetoothd[11844]: attrib/gattrib.c:g_attrib_unref() 0x334c88: ref=0
bluetoothd[11844]: Attribute server attach failure!
bluetoothd[11844]: src/adapter.c:dev_disconnected() Device
FC:7A:62:1F:F9:F6 disconnected, reason 2
bluetoothd[11844]: src/adapter.c:adapter_remove_connection()
bluetoothd[11844]: plugins/policy.c:disconnect_cb() reason 2
bluetoothd[11844]: src/adapter.c:bonding_attempt_complete() hci0
bdaddr FC:7A:62:1F:F9:F6 type 2 status 0xe
bluetoothd[11844]: src/device.c:device_bonding_complete() bonding
(nil) status 0x0e
bluetoothd[11844]: src/device.c:device_bonding_failed() status 14

I got it to work on an Ubuntu 14.04 VM, running on a x86 system & the
corresponding log looks as follows:

bluetoothd[3519]: src/device.c:btd_device_set_temporary() temporary 0
bluetoothd[3519]: src/device.c:device_connect_le() Connection attempt
to: FC:7A:62:1F:F9:F6
bluetoothd[3519]: src/adapter.c:connected_callback() hci0 device
FC:7A:62:1F:F9:F6 connected eir_len 0
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=1
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=2
bluetoothd[3519]: src/adapter.c:adapter_connect_list_remove() device
/org/bluez/hci0/dev_FC_7A_62_1F_F9_F6 is not on the list, ignoring
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=3
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=4
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=3
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=4
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=3
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=4
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=3
bluetoothd[3519]: src/device.c:primary_cb() status 0
bluetoothd[3519]: src/device.c:find_included_services() service count 5
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=4
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=5
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=4
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=3
bluetoothd[3519]: src/device.c:find_included_cb() status 0
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=4
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=5
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=4
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=3
bluetoothd[3519]: src/device.c:find_included_cb() status 0
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=4
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=5
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=4
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=3
bluetoothd[3519]: src/device.c:find_included_cb() status 0
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=4
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=5
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=4
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=3
bluetoothd[3519]: src/device.c:find_included_cb() status 0
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=4
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=5
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=4
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=3
bluetoothd[3519]: src/device.c:find_included_cb() status 0
bluetoothd[3519]: src/device.c:update_gatt_services() UUID Added:
00001800-0000-1000-8000-00805f9b34fb
bluetoothd[3519]: src/device.c:update_gatt_services() UUID Added:
00001801-0000-1000-8000-00805f9b34fb
bluetoothd[3519]: src/device.c:update_gatt_services() UUID Added:
6c721826-5bf1-4f64-9170-381c08ec57ee
bluetoothd[3519]: src/device.c:update_gatt_services() UUID Added:
0000180a-0000-1000-8000-00805f9b34fb
bluetoothd[3519]: src/device.c:update_gatt_services() UUID Added:
0000180d-0000-1000-8000-00805f9b34fb
bluetoothd[3519]: src/device.c:device_probe_profiles() Probing
profiles for device FC:7A:62:1F:F9:F6
bluetoothd[3519]: src/device.c:btd_device_add_attio_callback()
0x82038b8 registered ATT connection callback
bluetoothd[3519]: src/device.c:device_set_auto_connect()
FC:7A:62:1F:F9:F6 auto connect: 1
bluetoothd[3519]: src/device.c:device_set_auto_connect() Already connected
bluetoothd[3519]: src/service.c:change_state() 0x8205cf8: device
FC:7A:62:1F:F9:F6 profile Heart Rate GATT Driver state changed:
unavailable -> disconnected (0)
bluetoothd[3519]:
profiles/proximity/reporter.c:register_reporter_device() register on
device /org/bluez/hci0/dev_FC_7A_62_1F_F9_F6
bluetoothd[3519]: src/service.c:change_state() 0x8207960: device
FC:7A:62:1F:F9:F6 profile Proximity Reporter GATT Driver state
changed: unavailable -> disconnected (0)
bluetoothd[3519]: src/device.c:btd_device_add_attio_callback()
0x82038b8 registered ATT connection callback
bluetoothd[3519]: src/device.c:device_set_auto_connect()
FC:7A:62:1F:F9:F6 auto connect: 1
bluetoothd[3519]: src/service.c:change_state() 0x82079e0: device
FC:7A:62:1F:F9:F6 profile deviceinfo state changed: unavailable ->
disconnected (0)
bluetoothd[3519]: src/device.c:btd_device_add_attio_callback()
0x82038b8 registered ATT connection callback
bluetoothd[3519]: src/device.c:device_set_auto_connect()
FC:7A:62:1F:F9:F6 auto connect: 1
bluetoothd[3519]: src/service.c:change_state() 0x8200348: device
FC:7A:62:1F:F9:F6 profile gap-gatt-profile state changed: unavailable
-> disconnected (0)
bluetoothd[3519]: src/device.c:device_svc_resolved()
/org/bluez/hci0/dev_FC_7A_62_1F_F9_F6 err 0
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=2
bluetoothd[3519]: src/device.c:notify_attios()
bluetoothd[3519]: src/device.c:attio_connected()
bluetoothd[3519]: profiles/heartrate/heartrate.c:attio_connected_cb()
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=3
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=4
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=5
bluetoothd[3519]: src/device.c:attio_connected()
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=6
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=7
bluetoothd[3519]: src/device.c:attio_connected()
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=8
bluetoothd[3519]: profiles/gatt/gas.c:attio_connected_cb() MTU
Exchange: Requesting 672
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=9
bluetoothd[3519]: src/device.c:notify_attios()
bluetoothd[3519]: src/device.c:notify_attios()
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=8
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=9
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=8
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=9
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=8
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=9
bluetoothd[3519]: profiles/gatt/gas.c:exchange_mtu_cb() MTU exchange
succeeded: 23
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=8
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=9
bluetoothd[3519]: profiles/gatt/gas.c:gap_appearance_cb() GAP Appearance: 0x0340
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=8
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=9
bluetoothd[3519]: Discover Service Changed handle: No attribute found
within the given range
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=8
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=7
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=8
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=9
bluetoothd[3519]: profiles/heartrate/heartrate.c:discover_char_cb()
Body Sensor Location supported
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=8
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=7
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=8
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=7
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=8
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=7
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=6
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=7
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=6
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=7
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=6
bluetoothd[3519]: attrib/gattrib.c:g_attrib_ref() 0x8203360: ref=7
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=6
bluetoothd[3519]: attrib/gattrib.c:g_attrib_unref() 0x8203360: ref=5
bluetoothd[3519]: src/device.c:device_set_auto_connect()
FC:7A:62:1F:F9:F6 auto connect: 0
bluetoothd[3519]: src/adapter.c:adapter_connect_list_remove() device
/org/bluez/hci0/dev_FC_7A_62_1F_F9_F6 is not on the list, ignoring
bluetoothd[3519]: src/adapter.c:dev_disconnected() Device
FC:7A:62:1F:F9:F6 disconnected, reason 2
bluetoothd[3519]: src/adapter.c:adapter_remove_connection()
bluetoothd[3519]: plugins/policy.c:disconnect_cb() reason 2
bluetoothd[3519]: src/adapter.c:bonding_attempt_complete() hci0 bdaddr
FC:7A:62:1F:F9:F6 type 2 status 0xe
bluetoothd[3519]: src/device.c:device_bonding_complete() bonding (nil)
status 0x0e
bluetoothd[3519]: src/device.c:device_bonding_failed() status 14

Any idea as to why it's working on an x86 machine and not on the ARM
board? As far as I can tell, I've been following the same installation
procedure on both these systems

^ permalink raw reply

* Re: [PATCHv5 00/14] Included service discovery
From: Marcin Kraglak @ 2014-10-22  6:25 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org development
In-Reply-To: <1413454646-23076-1-git-send-email-marcin.kraglak@tieto.com>

On 16 October 2014 12:17, Marcin Kraglak <marcin.kraglak@tieto.com> wrote:
> v3:
> In this version after primary service discovery,
> secondary services are discovered. Next included
> services are resolved. With this approach we
> don't have recursively search for included service,
> like it was TODO in previous proposal.
> There is also small coding style fix suggested by Arman.
>
> v4:
> If no secondary services found, continue include services search (fixed
> in gatt-client.c).
> Fixed wrong debug logs (primary->secondary).
> Fixed searching descriptors
>
> v5:
> Ignore Unsupported Group Type Error in response to secondary service
> discovery and continue included services discovery.
>
> Marcin Kraglak (14):
>   shared/gatt: Add discover_secondary_services()
>   shared/gatt: Add initial implementation of discover_included_services
>   shared/gatt: Discover included services 128 bit UUIDS
>   shared/gatt: Add extra check in characteristic iterator
>   shared/gatt: Add included service iterator
>   shared/gatt: Remove not needed function parameter
>   shared/gatt: Distinguish Primary from Secondary services
>   tools/btgatt-client: Print type of service
>   shared/gatt: Discover secondary services
>   shared/gatt: Discover included services
>   shared/gatt: Add gatt-client include service iterator
>   tools/btgatt-client: Print found include services
>   shared/gatt: Fix searching descriptors
>   shared/gatt: Add function bt_gatt_result_included_count()
>
>  src/shared/gatt-client.c  | 263 +++++++++++++++++++++++++++--
>  src/shared/gatt-client.h  |  18 ++
>  src/shared/gatt-helpers.c | 418 +++++++++++++++++++++++++++++++++++++++++++---
>  src/shared/gatt-helpers.h |  10 +-
>  tools/btgatt-client.c     |  17 +-
>  5 files changed, 690 insertions(+), 36 deletions(-)
>
> --
> 1.9.3
>

Ping

^ permalink raw reply

* [PATCH] android/pts: Updated AVCTP PICS and PIXITs for PTS 5.3
From: Ruslan Mstoi @ 2014-10-22  7:11 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ruslan Mstoi

---
 android/pics-avctp.txt  | 2 +-
 android/pixit-avctp.txt | 6 +++---
 android/pts-avctp.txt   | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/android/pics-avctp.txt b/android/pics-avctp.txt
index 5900d00..0afa33c 100644
--- a/android/pics-avctp.txt
+++ b/android/pics-avctp.txt
@@ -1,6 +1,6 @@
 AVCTP PICS for the PTS tool.
 
-PTS version: 5.2
+PTS version: 5.3
 
 * - different than PTS defaults
 # - not yet implemented/supported
diff --git a/android/pixit-avctp.txt b/android/pixit-avctp.txt
index 3c6a864..06a0798 100644
--- a/android/pixit-avctp.txt
+++ b/android/pixit-avctp.txt
@@ -1,6 +1,6 @@
 AVCTP PIXIT for the PTS tool.
 
-PTS version: 5.2
+PTS version: 5.3
 
 * - different than PTS defaults
 & - should be set to IUT Bluetooth address
@@ -12,7 +12,7 @@ Parameter Name			Value
 -------------------------------------------------------------------------------
 TSPX_avctp_psm			0017
 TSPX_avctp_profile_id		110E
-TSPX_connect_avdtp		FALSE (*)
+TSPX_connect_avdtp		TRUE
 TSPX_avctp_tester_command_data
 TSPX_avctp_tester_response_data
 TSPX_avctp_iut_command_data
@@ -25,7 +25,7 @@ TSPX_class_of_device		20050C
 TSPX_player_feature_bitmask	0000000000000007FFF00070000000000
 TSPX_avrcp_version
 TSPX_establish_avdtp_stream	TRUE
-TSPX_tester_av_role
+TSPX_tester_av_role		SNK
 TSPX_time_guard			300000
 TSPX_avrcp_only			FALSE
 TSPX_use_implicit_send		TRUE
diff --git a/android/pts-avctp.txt b/android/pts-avctp.txt
index a461ee9..fd22ee1 100644
--- a/android/pts-avctp.txt
+++ b/android/pts-avctp.txt
@@ -1,7 +1,7 @@
 PTS test results for AVCTP
 
-PTS version: 5.2
-Tested: 10-July-2014
+PTS version: 5.3
+Tested: 22-October-2014
 Android version: 4.4.4
 
 Results:
-- 
1.9.1


^ permalink raw reply related

* Re: [PATCH] android/pts: Updated AVCTP PICS and PIXITs for PTS 5.3
From: Szymon Janc @ 2014-10-22  7:55 UTC (permalink / raw)
  To: Ruslan Mstoi; +Cc: linux-bluetooth
In-Reply-To: <1413961860-11390-1-git-send-email-ruslan.mstoi@linux.intel.com>

Hi Ruslan,

On Wednesday 22 of October 2014 10:11:00 Ruslan Mstoi wrote:
> ---
>  android/pics-avctp.txt  | 2 +-
>  android/pixit-avctp.txt | 6 +++---
>  android/pts-avctp.txt   | 4 ++--
>  3 files changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/android/pics-avctp.txt b/android/pics-avctp.txt
> index 5900d00..0afa33c 100644
> --- a/android/pics-avctp.txt
> +++ b/android/pics-avctp.txt
> @@ -1,6 +1,6 @@
>  AVCTP PICS for the PTS tool.
>  
> -PTS version: 5.2
> +PTS version: 5.3
>  
>  * - different than PTS defaults
>  # - not yet implemented/supported
> diff --git a/android/pixit-avctp.txt b/android/pixit-avctp.txt
> index 3c6a864..06a0798 100644
> --- a/android/pixit-avctp.txt
> +++ b/android/pixit-avctp.txt
> @@ -1,6 +1,6 @@
>  AVCTP PIXIT for the PTS tool.
>  
> -PTS version: 5.2
> +PTS version: 5.3
>  
>  * - different than PTS defaults
>  & - should be set to IUT Bluetooth address
> @@ -12,7 +12,7 @@ Parameter Name			Value
>  -------------------------------------------------------------------------------
>  TSPX_avctp_psm			0017
>  TSPX_avctp_profile_id		110E
> -TSPX_connect_avdtp		FALSE (*)
> +TSPX_connect_avdtp		TRUE
>  TSPX_avctp_tester_command_data
>  TSPX_avctp_tester_response_data
>  TSPX_avctp_iut_command_data
> @@ -25,7 +25,7 @@ TSPX_class_of_device		20050C
>  TSPX_player_feature_bitmask	0000000000000007FFF00070000000000
>  TSPX_avrcp_version
>  TSPX_establish_avdtp_stream	TRUE
> -TSPX_tester_av_role
> +TSPX_tester_av_role		SNK
>  TSPX_time_guard			300000
>  TSPX_avrcp_only			FALSE
>  TSPX_use_implicit_send		TRUE
> diff --git a/android/pts-avctp.txt b/android/pts-avctp.txt
> index a461ee9..fd22ee1 100644
> --- a/android/pts-avctp.txt
> +++ b/android/pts-avctp.txt
> @@ -1,7 +1,7 @@
>  PTS test results for AVCTP
>  
> -PTS version: 5.2
> -Tested: 10-July-2014
> +PTS version: 5.3
> +Tested: 22-October-2014
>  Android version: 4.4.4
>  
>  Results:
> 

Applied, thanks.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* [PATCH v3 bluetooth-next 0/4] 6lowpan: Move skb delivery out of IPHC
From: Martin Townsend @ 2014-10-22  8:39 UTC (permalink / raw)
  To: linux-bluetooth, linux-wpan
  Cc: marcel, alex.aring, jukka.rissanen, Martin Townsend

This series moves skb delivery out of IPHC and into the receive routines of
both bluetooth and 802.15.4.  The reason is that we need to support more
(de)compression schemes in the future.  It also means that calling 
lowpan_process_data now only returns error codes or 0 for success so 
this has been cleaned up.  The final patch then renames occurences of
lowpan_process_data and process_data to something more meaningful.

v1 -> v2

* Handle freeing of skb in lowpan_give_skb_to_devices for 802.15.14
* Added another skb_consume in bluetooth code for uncompressed IPv6 headers
* Added missing skb_consume for local_skb for bluetooth in compreesed IPv6 header
  path
* Combine patch 4 into 1.

v2 -> v3

* Ensure error codes aren't returned in the bluetooth skb delivery function.
* In lowpan_give_skb_to_devices return NET_RX_DROP when the first call to
  netif_rx fails.

Martin Townsend (4):
  6lowpan: remove skb_deliver from IPHC
  6lowpan: fix process_data return values
  bluetooth:6lowpan: use consume_skb when packet processed successfully
  ieee802154: 6lowpan: rename process_data and lowpan_process_data

 include/net/6lowpan.h         | 12 ++++++------
 net/6lowpan/iphc.c            | 42 ++++++++++++-----------------------------
 net/bluetooth/6lowpan.c       | 36 +++++++++++++++++++++++------------
 net/ieee802154/6lowpan_rtnl.c | 44 ++++++++++++++++++++++---------------------
 4 files changed, 65 insertions(+), 69 deletions(-)

-- 
1.9.1

^ permalink raw reply

* [PATCH v3 bluetooth-next 1/4] 6lowpan: remove skb_deliver from IPHC
From: Martin Townsend @ 2014-10-22  8:39 UTC (permalink / raw)
  To: linux-bluetooth, linux-wpan
  Cc: marcel, alex.aring, jukka.rissanen, Martin Townsend,
	Martin Townsend
In-Reply-To: <1413967190-28890-1-git-send-email-martin.townsend@xsilon.com>

Separating skb delivery from decompression ensures that we can support further
decompression schemes and removes the mixed return value of error codes with
NET_RX_FOO.

Signed-off-by: Martin Townsend <mtownsend1973@gmail.com>
---
 include/net/6lowpan.h         |  4 +---
 net/6lowpan/iphc.c            | 32 ++++++--------------------------
 net/bluetooth/6lowpan.c       | 14 ++++++++++++--
 net/ieee802154/6lowpan_rtnl.c | 25 +++++++++++++------------
 4 files changed, 32 insertions(+), 43 deletions(-)

diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h
index d184df1..abfa359 100644
--- a/include/net/6lowpan.h
+++ b/include/net/6lowpan.h
@@ -372,12 +372,10 @@ lowpan_uncompress_size(const struct sk_buff *skb, u16 *dgram_offset)
 	return skb->len + uncomp_header - ret;
 }
 
-typedef int (*skb_delivery_cb)(struct sk_buff *skb, struct net_device *dev);
-
 int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
 		const u8 *saddr, const u8 saddr_type, const u8 saddr_len,
 		const u8 *daddr, const u8 daddr_type, const u8 daddr_len,
-		u8 iphc0, u8 iphc1, skb_delivery_cb skb_deliver);
+		u8 iphc0, u8 iphc1);
 int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,
 			unsigned short type, const void *_daddr,
 			const void *_saddr, unsigned int len);
diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c
index 747b3cc..45714fe 100644
--- a/net/6lowpan/iphc.c
+++ b/net/6lowpan/iphc.c
@@ -171,29 +171,6 @@ static int uncompress_context_based_src_addr(struct sk_buff *skb,
 	return 0;
 }
 
-static int skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr,
-		       struct net_device *dev, skb_delivery_cb deliver_skb)
-{
-	int stat;
-
-	skb_push(skb, sizeof(struct ipv6hdr));
-	skb_reset_network_header(skb);
-	skb_copy_to_linear_data(skb, hdr, sizeof(struct ipv6hdr));
-
-	skb->protocol = htons(ETH_P_IPV6);
-	skb->pkt_type = PACKET_HOST;
-	skb->dev = dev;
-
-	raw_dump_table(__func__, "raw skb data dump before receiving",
-		       skb->data, skb->len);
-
-	stat = deliver_skb(skb, dev);
-
-	consume_skb(skb);
-
-	return stat;
-}
-
 /* Uncompress function for multicast destination address,
  * when M bit is set.
  */
@@ -327,7 +304,7 @@ static const u8 lowpan_ttl_values[] = { 0, 1, 64, 255 };
 int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
 			const u8 *saddr, const u8 saddr_type, const u8 saddr_len,
 			const u8 *daddr, const u8 daddr_type, const u8 daddr_len,
-			u8 iphc0, u8 iphc1, skb_delivery_cb deliver_skb)
+			u8 iphc0, u8 iphc1)
 {
 	struct ipv6hdr hdr = {};
 	u8 tmp, num_context = 0;
@@ -492,10 +469,13 @@ int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
 		hdr.version, ntohs(hdr.payload_len), hdr.nexthdr,
 		hdr.hop_limit, &hdr.daddr);
 
-	raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr));
+	skb_push(skb, sizeof(hdr));
+	skb_reset_network_header(skb);
+	skb_copy_to_linear_data(skb, &hdr, sizeof(hdr));
 
-	return skb_deliver(skb, &hdr, dev, deliver_skb);
+	raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr));
 
+	return 0;
 drop:
 	kfree_skb(skb);
 	return -EINVAL;
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 6c5c2ef..45d9a9f 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -252,7 +252,7 @@ static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev)
 
 	skb_cp = skb_copy(skb, GFP_ATOMIC);
 	if (!skb_cp)
-		return -ENOMEM;
+		return NET_RX_DROP;
 
 	return netif_rx(skb_cp);
 }
@@ -290,7 +290,7 @@ static int process_data(struct sk_buff *skb, struct net_device *netdev,
 	return lowpan_process_data(skb, netdev,
 				   saddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN,
 				   daddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN,
-				   iphc0, iphc1, give_skb_to_upper);
+				   iphc0, iphc1);
 
 drop:
 	kfree_skb(skb);
@@ -350,6 +350,16 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
 			if (ret != NET_RX_SUCCESS)
 				goto drop;
 
+			local_skb->protocol = htons(ETH_P_IPV6);
+			local_skb->pkt_type = PACKET_HOST;
+			local_skb->dev = dev;
+
+			if (give_skb_to_upper(local_skb, dev)
+					!= NET_RX_SUCCESS) {
+				kfree_skb(local_skb);
+				goto drop;
+			}
+
 			dev->stats.rx_bytes += skb->len;
 			dev->stats.rx_packets++;
 
diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c
index 0c1a49b..1cdb8e4 100644
--- a/net/ieee802154/6lowpan_rtnl.c
+++ b/net/ieee802154/6lowpan_rtnl.c
@@ -146,15 +146,20 @@ static int lowpan_give_skb_to_devices(struct sk_buff *skb,
 		if (lowpan_dev_info(entry->ldev)->real_dev == skb->dev) {
 			skb_cp = skb_copy(skb, GFP_ATOMIC);
 			if (!skb_cp) {
-				stat = -ENOMEM;
-				break;
+				kfree_skb(skb);
+				rcu_read_unlock();
+				return NET_RX_DROP;
 			}
 
 			skb_cp->dev = entry->ldev;
 			stat = netif_rx(skb_cp);
+			if (stat == NET_RX_DROP)
+				break;
 		}
 	rcu_read_unlock();
 
+	consume_skb(skb);
+
 	return stat;
 }
 
@@ -190,8 +195,7 @@ static int process_data(struct sk_buff *skb, const struct ieee802154_hdr *hdr)
 
 	return lowpan_process_data(skb, skb->dev, sap, sa.addr_type,
 				   IEEE802154_ADDR_LEN, dap, da.addr_type,
-				   IEEE802154_ADDR_LEN, iphc0, iphc1,
-				   lowpan_give_skb_to_devices);
+				   IEEE802154_ADDR_LEN, iphc0, iphc1);
 
 drop:
 	kfree_skb(skb);
@@ -528,15 +532,8 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
 
 	/* check that it's our buffer */
 	if (skb->data[0] == LOWPAN_DISPATCH_IPV6) {
-		skb->protocol = htons(ETH_P_IPV6);
-		skb->pkt_type = PACKET_HOST;
-
 		/* Pull off the 1-byte of 6lowpan header. */
 		skb_pull(skb, 1);
-
-		ret = lowpan_give_skb_to_devices(skb, NULL);
-		if (ret == NET_RX_DROP)
-			goto drop;
 	} else {
 		switch (skb->data[0] & 0xe0) {
 		case LOWPAN_DISPATCH_IPHC:	/* ipv6 datagram */
@@ -565,7 +562,11 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
 		}
 	}
 
-	return NET_RX_SUCCESS;
+	/* Pass IPv6 packet up to the next layer */
+	skb->protocol = htons(ETH_P_IPV6);
+	skb->pkt_type = PACKET_HOST;
+	return lowpan_give_skb_to_devices(skb, NULL);
+
 drop_skb:
 	kfree_skb(skb);
 drop:
-- 
1.9.1

^ permalink raw reply related

* [PATCH v3 bluetooth-next 2/4] 6lowpan: fix process_data return values
From: Martin Townsend @ 2014-10-22  8:39 UTC (permalink / raw)
  To: linux-bluetooth, linux-wpan
  Cc: marcel, alex.aring, jukka.rissanen, Martin Townsend,
	Martin Townsend
In-Reply-To: <1413967190-28890-1-git-send-email-martin.townsend@xsilon.com>

As process_data now returns just error codes fix up the calls to this
function to only drop the skb if an error code is returned.

Signed-off-by: Martin Townsend <mtownsend1973@gmail.com>
---
 net/bluetooth/6lowpan.c       | 2 +-
 net/ieee802154/6lowpan_rtnl.c | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 45d9a9f..94bbb66 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -347,7 +347,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
 				goto drop;
 
 			ret = process_data(local_skb, dev, chan);
-			if (ret != NET_RX_SUCCESS)
+			if (ret < 0)
 				goto drop;
 
 			local_skb->protocol = htons(ETH_P_IPV6);
diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c
index 1cdb8e4..83a0731 100644
--- a/net/ieee802154/6lowpan_rtnl.c
+++ b/net/ieee802154/6lowpan_rtnl.c
@@ -538,14 +538,14 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
 		switch (skb->data[0] & 0xe0) {
 		case LOWPAN_DISPATCH_IPHC:	/* ipv6 datagram */
 			ret = process_data(skb, &hdr);
-			if (ret == NET_RX_DROP)
+			if (ret < 0)
 				goto drop;
 			break;
 		case LOWPAN_DISPATCH_FRAG1:	/* first fragment header */
 			ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1);
 			if (ret == 1) {
 				ret = process_data(skb, &hdr);
-				if (ret == NET_RX_DROP)
+				if (ret < 0)
 					goto drop;
 			}
 			break;
@@ -553,7 +553,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
 			ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN);
 			if (ret == 1) {
 				ret = process_data(skb, &hdr);
-				if (ret == NET_RX_DROP)
+				if (ret < 0)
 					goto drop;
 			}
 			break;
-- 
1.9.1

^ permalink raw reply related

* [PATCH v3 bluetooth-next 3/4] bluetooth:6lowpan: use consume_skb when packet processed successfully
From: Martin Townsend @ 2014-10-22  8:39 UTC (permalink / raw)
  To: linux-bluetooth, linux-wpan
  Cc: marcel, alex.aring, jukka.rissanen, Martin Townsend
In-Reply-To: <1413967190-28890-1-git-send-email-martin.townsend@xsilon.com>

From: Martin Townsend <mtownsend1973@gmail.com>

Signed-off-by: Martin Townsend <mtownsend1973@gmail.com>
---
 net/bluetooth/6lowpan.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 94bbb66..40e2cec 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -337,8 +337,8 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
 		dev->stats.rx_bytes += skb->len;
 		dev->stats.rx_packets++;
 
-		kfree_skb(local_skb);
-		kfree_skb(skb);
+		consume_skb(local_skb);
+		consume_skb(skb);
 	} else {
 		switch (skb->data[0] & 0xe0) {
 		case LOWPAN_DISPATCH_IPHC:	/* ipv6 datagram */
@@ -363,7 +363,8 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
 			dev->stats.rx_bytes += skb->len;
 			dev->stats.rx_packets++;
 
-			kfree_skb(skb);
+			consume_skb(local_skb);
+			consume_skb(skb);
 			break;
 		default:
 			break;
-- 
1.9.1

^ permalink raw reply related

* [PATCH v3 bluetooth-next 4/4] ieee802154: 6lowpan: rename process_data and lowpan_process_data
From: Martin Townsend @ 2014-10-22  8:39 UTC (permalink / raw)
  To: linux-bluetooth, linux-wpan
  Cc: marcel, alex.aring, jukka.rissanen, Martin Townsend
In-Reply-To: <1413967190-28890-1-git-send-email-martin.townsend@xsilon.com>

From: Martin Townsend <mtownsend1973@gmail.com>

As we have decouple decompression from data delivery we can now rename all
occurences of process_data in receive path.

Signed-off-by: Martin Townsend <mtownsend1973@gmail.com>
---
 include/net/6lowpan.h         | 10 ++++++----
 net/6lowpan/iphc.c            | 12 +++++++-----
 net/bluetooth/6lowpan.c       | 15 ++++++++-------
 net/ieee802154/6lowpan_rtnl.c | 15 ++++++++-------
 4 files changed, 29 insertions(+), 23 deletions(-)

diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h
index abfa359..dc03d77 100644
--- a/include/net/6lowpan.h
+++ b/include/net/6lowpan.h
@@ -372,10 +372,12 @@ lowpan_uncompress_size(const struct sk_buff *skb, u16 *dgram_offset)
 	return skb->len + uncomp_header - ret;
 }
 
-int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
-		const u8 *saddr, const u8 saddr_type, const u8 saddr_len,
-		const u8 *daddr, const u8 daddr_type, const u8 daddr_len,
-		u8 iphc0, u8 iphc1);
+int
+lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
+			 const u8 *saddr, const u8 saddr_type,
+			 const u8 saddr_len, const u8 *daddr,
+			 const u8 daddr_type, const u8 daddr_len,
+			 u8 iphc0, u8 iphc1);
 int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,
 			unsigned short type, const void *_daddr,
 			const void *_saddr, unsigned int len);
diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c
index 45714fe..73a7065 100644
--- a/net/6lowpan/iphc.c
+++ b/net/6lowpan/iphc.c
@@ -301,10 +301,12 @@ err:
 /* TTL uncompression values */
 static const u8 lowpan_ttl_values[] = { 0, 1, 64, 255 };
 
-int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
-			const u8 *saddr, const u8 saddr_type, const u8 saddr_len,
-			const u8 *daddr, const u8 daddr_type, const u8 daddr_len,
-			u8 iphc0, u8 iphc1)
+int
+lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
+			 const u8 *saddr, const u8 saddr_type,
+			 const u8 saddr_len, const u8 *daddr,
+			 const u8 daddr_type, const u8 daddr_len,
+			 u8 iphc0, u8 iphc1)
 {
 	struct ipv6hdr hdr = {};
 	u8 tmp, num_context = 0;
@@ -480,7 +482,7 @@ drop:
 	kfree_skb(skb);
 	return -EINVAL;
 }
-EXPORT_SYMBOL_GPL(lowpan_process_data);
+EXPORT_SYMBOL_GPL(lowpan_header_decompress);
 
 static u8 lowpan_compress_addr_64(u8 **hc_ptr, u8 shift,
 				  const struct in6_addr *ipaddr,
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 40e2cec..aa6ebbf 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -257,8 +257,8 @@ static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev)
 	return netif_rx(skb_cp);
 }
 
-static int process_data(struct sk_buff *skb, struct net_device *netdev,
-			struct l2cap_chan *chan)
+static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev,
+			   struct l2cap_chan *chan)
 {
 	const u8 *saddr, *daddr;
 	u8 iphc0, iphc1;
@@ -287,10 +287,11 @@ static int process_data(struct sk_buff *skb, struct net_device *netdev,
 	if (lowpan_fetch_skb_u8(skb, &iphc1))
 		goto drop;
 
-	return lowpan_process_data(skb, netdev,
-				   saddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN,
-				   daddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN,
-				   iphc0, iphc1);
+	return lowpan_header_decompress(skb, netdev,
+					saddr, IEEE802154_ADDR_LONG,
+					EUI64_ADDR_LEN, daddr,
+					IEEE802154_ADDR_LONG, EUI64_ADDR_LEN,
+					iphc0, iphc1);
 
 drop:
 	kfree_skb(skb);
@@ -346,7 +347,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
 			if (!local_skb)
 				goto drop;
 
-			ret = process_data(local_skb, dev, chan);
+			ret = iphc_decompress(local_skb, dev, chan);
 			if (ret < 0)
 				goto drop;
 
diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c
index 83a0731..e033f13 100644
--- a/net/ieee802154/6lowpan_rtnl.c
+++ b/net/ieee802154/6lowpan_rtnl.c
@@ -163,7 +163,8 @@ static int lowpan_give_skb_to_devices(struct sk_buff *skb,
 	return stat;
 }
 
-static int process_data(struct sk_buff *skb, const struct ieee802154_hdr *hdr)
+static int
+iphc_decompress(struct sk_buff *skb, const struct ieee802154_hdr *hdr)
 {
 	u8 iphc0, iphc1;
 	struct ieee802154_addr_sa sa, da;
@@ -193,9 +194,9 @@ static int process_data(struct sk_buff *skb, const struct ieee802154_hdr *hdr)
 	else
 		dap = &da.hwaddr;
 
-	return lowpan_process_data(skb, skb->dev, sap, sa.addr_type,
-				   IEEE802154_ADDR_LEN, dap, da.addr_type,
-				   IEEE802154_ADDR_LEN, iphc0, iphc1);
+	return lowpan_header_decompress(skb, skb->dev, sap, sa.addr_type,
+					IEEE802154_ADDR_LEN, dap, da.addr_type,
+					IEEE802154_ADDR_LEN, iphc0, iphc1);
 
 drop:
 	kfree_skb(skb);
@@ -537,14 +538,14 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
 	} else {
 		switch (skb->data[0] & 0xe0) {
 		case LOWPAN_DISPATCH_IPHC:	/* ipv6 datagram */
-			ret = process_data(skb, &hdr);
+			ret = iphc_decompress(skb, &hdr);
 			if (ret < 0)
 				goto drop;
 			break;
 		case LOWPAN_DISPATCH_FRAG1:	/* first fragment header */
 			ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1);
 			if (ret == 1) {
-				ret = process_data(skb, &hdr);
+				ret = iphc_decompress(skb, &hdr);
 				if (ret < 0)
 					goto drop;
 			}
@@ -552,7 +553,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
 		case LOWPAN_DISPATCH_FRAGN:	/* next fragments headers */
 			ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN);
 			if (ret == 1) {
-				ret = process_data(skb, &hdr);
+				ret = iphc_decompress(skb, &hdr);
 				if (ret < 0)
 					goto drop;
 			}
-- 
1.9.1

^ permalink raw reply related

* rtk_btusb issues
From: Patrick Shirkey @ 2014-10-22 10:35 UTC (permalink / raw)
  To: linux-bluetooth

Hi,

I have an android device running the rtk_btusb driver. The original driver
was a couple of years old and there was a problem with stability with BLE.
In addition the localname was not found in the scan_response data.

I upgraded the bluetooth stack by manually backporting from a recent
kernel. That fixed the issue wit the scan_repsonse data but there were
still stability issues with BLE devices (although slightly improved
compared to the older bluetooth stack).

I have tried upgrading the driver to the latest version of the rtk_btusb
driver from the git repo and ported the hooks for bluedroid from the old
driver however I get issues with hci send command when loading the driver.

http://pastebin.com/hXALmXBr

I traced the command but I am not sure where the send value is generated.
I can see the function definition in the hci_dev struct but not the
location where the value is actually set.

I thought it might be an issue specific to bluedroid so I installed bluez
but the issue is still there so it appears to be a bug in my version of
the driver or something wrong with the bluetooth kernel layer.

I went back to the older version of the driver running against  bluez
instead of bluedroid. That gets me further along but I still cannot
initialise the bluetooth system on the device.

http://pastebin.com/HcSZXiMu

Does anyone have any suggestions for how to go about resolving this
situation I have got myself into?



--
Patrick Shirkey
Boost Hardware Ltd

^ permalink raw reply

* Re: [PATCH 1/3] obexd/map: Add support for MAP feature bits
From: Luiz Augusto von Dentz @ 2014-10-22 10:44 UTC (permalink / raw)
  To: Gowtham Anandha Babu
  Cc: linux-bluetooth@vger.kernel.org, Dmitry Kasatkin, Bharat Panda,
	cpgs
In-Reply-To: <1413817469-4255-1-git-send-email-gowtham.ab@samsung.com>

Hi,

On Mon, Oct 20, 2014 at 6:04 PM, Gowtham Anandha Babu
<gowtham.ab@samsung.com> wrote:
> Handles MAP supported feature bits as per the
> MAP 1.2 specs section 7.1.1.
> ---
>  obexd/client/map.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
>
> diff --git a/obexd/client/map.c b/obexd/client/map.c
> index 44db96c..43b0471 100644
> --- a/obexd/client/map.c
> +++ b/obexd/client/map.c
> @@ -100,6 +100,7 @@ struct map_data {
>         GHashTable *messages;
>         int16_t mas_instance_id;
>         uint8_t supported_message_types;
> +       uint32_t supported_features;
>  };
>
>  struct pending_request {
> @@ -2003,6 +2004,14 @@ static void parse_service_record(struct map_data *map)
>                 map->supported_message_types = *(uint8_t *)data;
>         else
>                 DBG("Failed to read supported message types");
> +
> +       /* Supported Feature Bits */
> +       data = obc_session_get_attribute(map->session,
> +                                       SDP_ATTR_MAP_SUPPORTED_FEATURES);
> +       if(data != NULL)
> +               map->supported_features = *(uint32_t *)data;
> +       else
> +               map->supported_features = 0x0000001f;
>  }
>
>  static int map_probe(struct obc_session *session)
> --
> 1.9.1

Applied, thanks.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH v4 08/11] unit/test-hfp: Add init test for HFP HF
From: Szymon Janc @ 2014-10-22 11:00 UTC (permalink / raw)
  To: Lukasz Rymanowski; +Cc: linux-bluetooth
In-Reply-To: <1412898611-12199-9-git-send-email-lukasz.rymanowski@tieto.com>

Hi Łukasz,

On Friday 10 of October 2014 01:50:08 Lukasz Rymanowski wrote:
> This patch adds basic infrastruction for HFP HF test plus
> init test.
> 
> It also moves send_pdu function in the file so it can be used by
> test_hf_handler
> ---
>  unit/test-hfp.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++----------
>  1 file changed, 84 insertions(+), 18 deletions(-)
> 
> diff --git a/unit/test-hfp.c b/unit/test-hfp.c
> index 4b3473b..274ee55 100644
> --- a/unit/test-hfp.c
> +++ b/unit/test-hfp.c
> @@ -36,6 +36,7 @@ struct context {
>  	int fd_server;
>  	int fd_client;
>  	struct hfp_gw *hfp;
> +	struct hfp_hf *hfp_hf;
>  	const struct test_data *data;
>  	unsigned int pdu_offset;
>  };
> @@ -52,6 +53,8 @@ struct test_data {
>  	char *test_name;
>  	struct test_pdu *pdu_list;
>  	hfp_result_func_t result_func;
> +	hfp_response_func_t response_func;
> +	hfp_hf_result_func_t hf_result_func;
>  	GIOFunc test_handler;
>  };
>  
> @@ -99,6 +102,22 @@ struct test_data {
>  		data.test_handler = test_handler;			\
>  	} while (0)
>  
> +#define define_hf_test(name, function, result_func, response_function,	\
> +								args...)\
> +	do {								\
> +		const struct test_pdu pdus[] = {			\
> +			args, { }					\
> +		};							\
> +		static struct test_data data;				\
> +		data.test_name = g_strdup(name);			\
> +		data.pdu_list = g_malloc(sizeof(pdus));			\
> +		data.hf_result_func = result_func;			\
> +		data.response_func = response_function;			\
> +		memcpy(data.pdu_list, pdus, sizeof(pdus));		\
> +		g_test_add_data_func(name, &data, function);		\
> +		data.test_handler = test_hf_handler;			\
> +	} while (0)
> +
>  static void context_quit(struct context *context)
>  {
>  	g_main_loop_quit(context->main_loop);
> @@ -128,6 +147,52 @@ static gboolean test_handler(GIOChannel *channel, GIOCondition cond,
>  	return FALSE;
>  }
>  
> +static gboolean send_pdu(gpointer user_data)
> +{
> +	struct context *context = user_data;
> +	const struct test_pdu *pdu;
> +	ssize_t len;
> +
> +	pdu = &context->data->pdu_list[context->pdu_offset++];
> +
> +	if (pdu && !pdu->valid)
> +		return FALSE;
> +
> +	len = write(context->fd_server, pdu->data, pdu->size);
> +	g_assert_cmpint(len, ==, pdu->size);
> +
> +	pdu = &context->data->pdu_list[context->pdu_offset];
> +	if (pdu->fragmented)
> +		g_idle_add(send_pdu, context);
> +
> +	return FALSE;
> +}
> +
> +static gboolean test_hf_handler(GIOChannel *channel, GIOCondition cond,
> +							gpointer user_data)
> +{
> +	struct context *context = user_data;
> +	gchar buf[60];
> +	gsize bytes_read;
> +	GError *error = NULL;
> +
> +	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL))
> +		goto done;
> +
> +	/* dummy read */
> +	g_io_channel_read_chars(channel, buf, 60, &bytes_read, &error);
> +
> +	send_pdu(context);
> +
> +	return TRUE;
> +
> +done:
> +	context_quit(context);
> +	context->watch_id = 0;
> +
> +	return FALSE;
> +}
> +
>  static void cmd_handler(const char *command, void *user_data)
>  {
>  	struct context *context = user_data;
> @@ -203,6 +268,9 @@ static void execute_context(struct context *context)
>  	if (context->hfp)
>  		hfp_gw_unref(context->hfp);
>  
> +	if (context->hfp_hf)
> +		hfp_hf_unref(context->hfp_hf);
> +
>  	g_free(context);
>  }
>  
> @@ -275,24 +343,6 @@ static void test_register(gconstpointer data)
>  	execute_context(context);
>  }
>  
> -static gboolean send_pdu(gpointer user_data)
> -{
> -	struct context *context = user_data;
> -	const struct test_pdu *pdu;
> -	ssize_t len;
> -
> -	pdu = &context->data->pdu_list[context->pdu_offset++];
> -
> -	len = write(context->fd_server, pdu->data, pdu->size);
> -	g_assert_cmpint(len, ==, pdu->size);
> -
> -	pdu = &context->data->pdu_list[context->pdu_offset];
> -	if (pdu->fragmented)
> -		g_idle_add(send_pdu, context);
> -
> -	return FALSE;
> -}
> -
>  static void test_fragmented(gconstpointer data)
>  {
>  	struct context *context = create_context(data);
> @@ -404,6 +454,20 @@ static void check_string_2(struct hfp_gw_result *result,
>  	hfp_gw_send_result(context->hfp, HFP_RESULT_ERROR);
>  }
>  
> +static void test_hf_init(gconstpointer data)
> +{
> +	struct context *context = create_context(data);
> +
> +	context->hfp_hf = hfp_hf_new(context->fd_client);
> +	g_assert(context->hfp_hf);
> +	g_assert(hfp_hf_set_close_on_unref(context->hfp_hf, true));
> +
> +	hfp_hf_unref(context->hfp_hf);
> +	context->hfp_hf = NULL;
> +
> +	execute_context(context);
> +}
> +
>  int main(int argc, char *argv[])
>  {
>  	g_test_init(&argc, &argv, NULL);
> @@ -473,5 +537,7 @@ int main(int argc, char *argv[])
>  			raw_pdu('\r'),
>  			data_end());
>  
> +	define_hf_test("/hfp/test_init", test_hf_init, NULL, NULL, data_end());

I'd prefer if all hfp_hf tests were prefixed like this:
"/hfp_hf/test_foo"

This will allow to avoid doubling tests name like this one (there is already
/hfp/test_init test).

> +
>  	return g_test_run();
>  }
> 

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* Re: [PATCH v4 06/11] shared/hfp: Add send AT command API for HFP HF
From: Szymon Janc @ 2014-10-22 11:00 UTC (permalink / raw)
  To: Lukasz Rymanowski; +Cc: linux-bluetooth
In-Reply-To: <1412898611-12199-7-git-send-email-lukasz.rymanowski@tieto.com>

Hi Łukasz,

On Friday 10 of October 2014 01:50:06 Lukasz Rymanowski wrote:
> This patch adds handling send and response of AT command.
> Note that we always wait for AT command response before sending next
> command, however user can fill hfp_hf with more than one command.
> All the commands are queued and send one by one.
> ---
>  src/shared/hfp.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  src/shared/hfp.h |   8 +++
>  2 files changed, 183 insertions(+)
> 
> diff --git a/src/shared/hfp.c b/src/shared/hfp.c
> index 5179092..8bebe97 100644
> --- a/src/shared/hfp.c
> +++ b/src/shared/hfp.c
> @@ -70,6 +70,9 @@ struct hfp_hf {
>  	struct ringbuf *read_buf;
>  	struct ringbuf *write_buf;
>  
> +	bool writer_active;
> +	struct queue *cmd_queue;
> +
>  	struct queue *event_handlers;
>  
>  	hfp_debug_func_t debug_callback;
> @@ -101,6 +104,14 @@ struct hfp_hf_result {
>  	unsigned int offset;
>  };
>  
> +struct cmd_response {
> +	char *prefix;
> +	hfp_response_func_t resp_cb;
> +	struct hfp_hf_result *response;
> +	char *resp_data;
> +	void *user_data;
> +};
> +
>  struct event_handler {
>  	char *prefix;
>  	void *user_data;
> @@ -868,17 +879,103 @@ static void destroy_event_handler(void *data)
>  	free(handler);
>  }
>  
> +static bool hf_can_write_data(struct io *io, void *user_data)
> +{
> +	struct hfp_hf *hfp = user_data;
> +	ssize_t bytes_written;
> +
> +	bytes_written = ringbuf_write(hfp->write_buf, hfp->fd);
> +	if (bytes_written < 0)
> +		return false;
> +
> +	if (ringbuf_len(hfp->write_buf) > 0)
> +		return true;
> +
> +	return false;
> +}
> +
> +static void hf_write_watch_destroy(void *user_data)
> +{
> +	struct hfp_hf *hfp = user_data;
> +
> +	hfp->writer_active = false;
> +}
> +
>  static void hf_skip_whitespace(struct hfp_hf_result *result)
>  {
>  	while (result->data[result->offset] == ' ')
>  		result->offset++;
>  }
>  
> +static bool is_response(const char *prefix, enum hfp_result *result)
> +{
> +	if (strcmp(prefix, "OK") == 0) {
> +		*result = HFP_RESULT_OK;
> +		return true;
> +	}
> +
> +	if (strcmp(prefix, "ERROR") == 0) {
> +		*result = HFP_RESULT_ERROR;
> +		return true;
> +	}
> +
> +	if (strcmp(prefix, "NO CARRIER") == 0) {
> +		*result = HFP_RESULT_NO_CARRIER;
> +		return true;
> +	}
> +
> +	if (strcmp(prefix, "CONNECT") == 0) {

Shouldn't this be "BUSY"?

> +		*result = HFP_RESULT_CONNECT;

And this enum value looks bogus to me.
I couldn't find it in HFP nor HSP spec. Probably leftover from AT spec.
I'd just handle what is defined in HFP spec here.

> +		return true;
> +	}
> +
> +	if (strcmp(prefix, "NO ANSWER") == 0) {
> +		*result = HFP_RESULT_NO_ANSWER;
> +		return true;
> +	}
> +
> +	if (strcmp(prefix, "DELAYED") == 0) {
> +		*result = HFP_RESULT_DELAYED;
> +		return true;
> +	}
> +
> +	if (strcmp(prefix, "BLACKLISTED") == 0) {
> +		*result = HFP_RESULT_BLACKLISTED;
> +		return true;
> +	}
> +
> +	return false;
> +}
> +
> +static void hf_wakeup_writer(struct hfp_hf *hfp)
> +{
> +	if (hfp->writer_active)
> +		return;
> +
> +	if (!ringbuf_len(hfp->write_buf))
> +		return;
> +
> +	if (!io_set_write_handler(hfp->io, hf_can_write_data,
> +					hfp, hf_write_watch_destroy))
> +		return;
> +
> +	hfp->writer_active = true;
> +}
> +
> +static void destroy_cmd_response(void *data)
> +{
> +	struct cmd_response *cmd = data;
> +
> +	free(cmd->prefix);
> +	free(cmd);
> +}
> +
>  static void hf_call_prefix_handler(struct hfp_hf *hfp, const char *data)
>  {
>  	struct event_handler *handler;
>  	const char *separators = ";:\0";
>  	struct hfp_hf_result result_data;
> +	enum hfp_result result;
>  	char lookup_prefix[18];
>  	uint8_t pref_len = 0;
>  	const char *prefix;
> @@ -904,6 +1001,22 @@ static void hf_call_prefix_handler(struct hfp_hf *hfp, const char *data)
>  	lookup_prefix[pref_len] = '\0';
>  	result_data.offset += pref_len + 1;
>  
> +	if (is_response(lookup_prefix, &result)) {
> +		struct cmd_response *cmd;
> +
> +		cmd = queue_peek_head(hfp->cmd_queue);
> +		if (!cmd)
> +			return;
> +
> +		cmd->resp_cb(cmd->prefix, result, cmd->user_data);
> +
> +		queue_remove(hfp->cmd_queue, cmd);
> +		destroy_cmd_response(cmd);
> +
> +		hf_wakeup_writer(hfp);
> +		return;
> +	}
> +
>  	handler = queue_find(hfp->event_handlers, match_handler_event_prefix,
>  								lookup_prefix);
>  	if (!handler)
> @@ -1032,6 +1145,18 @@ struct hfp_hf *hfp_hf_new(int fd)
>  		return NULL;
>  	}
>  
> +	hfp->cmd_queue = queue_new();
> +	if (!hfp->cmd_queue) {
> +		io_destroy(hfp->io);
> +		ringbuf_free(hfp->write_buf);
> +		ringbuf_free(hfp->read_buf);
> +		queue_destroy(hfp->event_handlers, NULL);
> +		free(hfp);
> +		return NULL;
> +	}
> +
> +	hfp->writer_active = false;
> +
>  	if (!io_set_read_handler(hfp->io, hf_can_read_data, hfp,
>  							read_watch_destroy)) {
>  		queue_destroy(hfp->event_handlers,
> @@ -1083,6 +1208,9 @@ void hfp_hf_unref(struct hfp_hf *hfp)
>  	queue_destroy(hfp->event_handlers, destroy_event_handler);
>  	hfp->event_handlers = NULL;
>  
> +	queue_destroy(hfp->cmd_queue, destroy_cmd_response);
> +	hfp->cmd_queue = NULL;
> +
>  	if (!hfp->in_disconnect) {
>  		free(hfp);
>  		return;
> @@ -1142,6 +1270,53 @@ bool hfp_hf_set_close_on_unref(struct hfp_hf *hfp, bool do_close)
>  	return true;
>  }
>  
> +bool hfp_hf_send_command(struct hfp_hf *hfp, hfp_response_func_t resp_cb,
> +				void *user_data, const char *format, ...)
> +{
> +	va_list ap;
> +	char *fmt;
> +	int len;
> +	const char *separators = ";?=\0";
> +	uint8_t prefix_len;
> +	struct cmd_response *cmd;
> +
> +	if (!hfp || !format || !resp_cb)
> +		return false;
> +
> +	if (asprintf(&fmt, "%s\r", format) < 0)
> +		return false;
> +
> +	cmd = new0(struct cmd_response, 1);
> +	if (!cmd)
> +		return false;
> +
> +	va_start(ap, format);
> +	len = ringbuf_vprintf(hfp->write_buf, fmt, ap);
> +	va_end(ap);
> +
> +	free(fmt);
> +
> +	if (len < 0) {
> +		free(cmd);
> +		return false;
> +	}
> +
> +	prefix_len = strcspn(format, separators);

I'd explore possibility of passing prefix as separate argument to the
function to avoid need of this extra parsing. Also do we really need this
prefix at all? We should not have more than one pending AT command anyway.

> +	cmd->prefix = strndup(format, prefix_len);
> +	cmd->resp_cb = resp_cb;
> +	cmd->user_data = user_data;
> +
> +	if (!queue_push_tail(hfp->cmd_queue, cmd)) {
> +		ringbuf_drain(hfp->write_buf, len);
> +		free(cmd);
> +		return false;
> +	}
> +
> +	hf_wakeup_writer(hfp);
> +
> +	return true;
> +}
> +
>  bool hfp_hf_register(struct hfp_hf *hfp, hfp_hf_result_func_t callback,
>  						const char *prefix,
>  						void *user_data,
> diff --git a/src/shared/hfp.h b/src/shared/hfp.h
> index 85037b1..5ee3017 100644
> --- a/src/shared/hfp.h
> +++ b/src/shared/hfp.h
> @@ -32,6 +32,8 @@ enum hfp_result {
>  	HFP_RESULT_NO_DIALTONE	= 6,
>  	HFP_RESULT_BUSY		= 7,
>  	HFP_RESULT_NO_ANSWER	= 8,
> +	HFP_RESULT_DELAYED	= 9,
> +	HFP_RESULT_BLACKLISTED	= 10,
>  };
>  
>  enum hfp_error {
> @@ -83,6 +85,10 @@ typedef void (*hfp_command_func_t)(const char *command, void *user_data);
>  
>  typedef void (*hfp_disconnect_func_t)(void *user_data);
>  
> +typedef void (*hfp_response_func_t)(const char *prefix,
> +							enum hfp_result result,
> +							void *user_data);
> +
>  struct hfp_gw;
>  struct hfp_hf;
>  
> @@ -146,3 +152,5 @@ bool hfp_hf_register(struct hfp_hf *hfp, hfp_hf_result_func_t callback,
>  					const char *prefix, void *user_data,
>  					hfp_destroy_func_t destroy);
>  bool hfp_hf_unregister(struct hfp_hf *hfp, const char *prefix);
> +bool hfp_hf_send_command(struct hfp_hf *hfp, hfp_response_func_t resp_cb,
> +				void *user_data, const char *format, ...);
> 

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* Re: [PATCH v4 05/11] shared/hfp: Add HFP HF parser
From: Szymon Janc @ 2014-10-22 11:00 UTC (permalink / raw)
  To: Lukasz Rymanowski; +Cc: linux-bluetooth
In-Reply-To: <1412898611-12199-6-git-send-email-lukasz.rymanowski@tieto.com>

Hi Łukasz,

On Friday 10 of October 2014 01:50:05 Lukasz Rymanowski wrote:
> This patch adds parser for AT responses and unsolicited results.
> ---
>  src/shared/hfp.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 129 insertions(+)
> 
> diff --git a/src/shared/hfp.c b/src/shared/hfp.c
> index b1cf08e..5179092 100644
> --- a/src/shared/hfp.c
> +++ b/src/shared/hfp.c
> @@ -868,6 +868,126 @@ static void destroy_event_handler(void *data)
>  	free(handler);
>  }
>  
> +static void hf_skip_whitespace(struct hfp_hf_result *result)
> +{
> +	while (result->data[result->offset] == ' ')
> +		result->offset++;
> +}
> +
> +static void hf_call_prefix_handler(struct hfp_hf *hfp, const char *data)
> +{
> +	struct event_handler *handler;
> +	const char *separators = ";:\0";
> +	struct hfp_hf_result result_data;
> +	char lookup_prefix[18];
> +	uint8_t pref_len = 0;
> +	const char *prefix;
> +	int i;
> +
> +	result_data.offset = 0;
> +	result_data.data = data;
> +
> +	hf_skip_whitespace(&result_data);
> +
> +	if (strlen(data + result_data.offset) < 2)
> +		return;
> +
> +	prefix = data + result_data.offset;
> +
> +	pref_len = strcspn(prefix, separators);
> +	if (pref_len > 17 || pref_len < 2)
> +		return;
> +
> +	for (i = 0; i < pref_len; i++)
> +		lookup_prefix[i] = toupper(prefix[i]);
> +
> +	lookup_prefix[pref_len] = '\0';
> +	result_data.offset += pref_len + 1;
> +
> +	handler = queue_find(hfp->event_handlers, match_handler_event_prefix,
> +								lookup_prefix);
> +	if (!handler)
> +		return;
> +
> +	handler->callback(&result_data, handler->user_data);
> +}
> +
> +static char *find_cr_lf(char *str, size_t len)
> +{
> +	char *ptr;
> +	int count;
> +	int offset;
> +
> +	offset = 0;
> +
> +	ptr = memchr(str, '\r', len);
> +	while (ptr) {
> +		/*
> +		 * Check if there is more data after '\r'. If so check for
> +		 * '\n'
> +		 */
> +		count = ptr-str;

Style: spaces around -

> +		if ((count < (int) (len - 1)) && *(ptr + 1) == '\n')
> +			return ptr;

If you make count size_t then this cast is not needed.

> +
> +		/* There is only '\r'? Let's try to find next one */
> +		offset += count + 1;
> +
> +		if (offset >= (int)len)

If you make offset size_t then this cast is not needed.
Also such casting should have space '(int) foo'.

> +			return NULL;
> +
> +		ptr = memchr(str + offset, '\r', len - offset);
> +	}
> +
> +	return NULL;
> +}
> +
> +static void hf_process_input(struct hfp_hf *hfp)
> +{
> +	char *str, *ptr;
> +	size_t len, count, offset;
> +
> +	str = ringbuf_peek(hfp->read_buf, 0, &len);
> +	if (!str)
> +		return;
> +
> +	offset = 0;
> +
> +	ptr = find_cr_lf(str, len);
> +	while (ptr) {
> +		count = ptr - (str + offset);

If you would adjust str pointer instead of using str + offset everywhere
then this code would be a bit simpler to follow.

Also this would not handle wrapped string correctly. Check how this is handled
in process_input().

> +		if (count == 0) {
> +			/* 2 is for <cr><lf> */
> +			offset += 2;
> +		} else {
> +			*ptr = '\0';
> +			hf_call_prefix_handler(hfp, str + offset);
> +			offset += count + 2;
> +		}
> +
> +		if (offset >= len)
> +			break;
> +
> +		ptr = find_cr_lf(str + offset, len - offset);
> +	}
> +
> +	ringbuf_drain(hfp->read_buf, offset < len ? offset : len);
> +}
> +
> +static bool hf_can_read_data(struct io *io, void *user_data)
> +{
> +	struct hfp_hf *hfp = user_data;
> +	ssize_t bytes_read;
> +
> +	bytes_read = ringbuf_read(hfp->read_buf, hfp->fd);
> +	if (bytes_read < 0)
> +		return false;
> +
> +	hf_process_input(hfp);
> +
> +	return true;
> +}
> +
>  struct hfp_hf *hfp_hf_new(int fd)
>  {
>  	struct hfp_hf *hfp;
> @@ -912,6 +1032,15 @@ struct hfp_hf *hfp_hf_new(int fd)
>  		return NULL;
>  	}
>  
> +	if (!io_set_read_handler(hfp->io, hf_can_read_data, hfp,
> +							read_watch_destroy)) {
> +		queue_destroy(hfp->event_handlers,
> +						destroy_event_handler);
> +		io_destroy(hfp->io);
> +		ringbuf_free(hfp->write_buf);
> +		ringbuf_free(hfp->read_buf);

You are missing free(hfp); return NULL; here.

> +	}
> +
>  	return hfp_hf_ref(hfp);
>  }
>  
> 

-- 
Best regards, 
Szymon Janc

^ 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