Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH v3 00/10] mSBC tests
From: Frédéric Dalleau @ 2012-10-26 17:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau

Hi,

v3 integrate latest comments from Marcel, hope it is fine now!

How to use:
sample.au should be an .au audio file 16000hz 16bits 1 channel pcm.
$ src/sbcenc  -m -b26 -B16 -s8   sample.au > sample.au.msbc
$ src/sbcinfo sample.au.msbc
$ src/sbcdec  -m -f sample.au.msbc.au sample.au.msbc
$ mplayer sample.au.msbc.au

Regards,
Frederic


Frédéric Dalleau (10):
  sbc: Add encoder_state to process input functions
  sbc: Add encoder_state to analysis functions
  sbc: Break 4 blocks processing to variable steps
  sbc: Add msbc flag and generic C primitive
  sbc: Add support for mSBC frame header
  sbc: Add mmx primitive for 1b 8s analyse
  sbc: Update sbcdec for msbc
  sbc: Update sbcenc for msbc
  sbc: Update sbcinfo for msbc
  sbc: Update copyrights

 sbc/sbc.c                   |  275 ++++++++++++++++++++++++++-----------------
 sbc/sbc.h                   |    3 +
 sbc/sbc_primitives.c        |  105 +++++++++++++----
 sbc/sbc_primitives.h        |   23 ++--
 sbc/sbc_primitives_armv6.c  |    6 +-
 sbc/sbc_primitives_iwmmxt.c |    8 +-
 sbc/sbc_primitives_mmx.c    |   27 ++++-
 sbc/sbc_primitives_neon.c   |   40 +++----
 src/sbcdec.c                |   18 ++-
 src/sbcenc.c                |   26 +++-
 src/sbcinfo.c               |   52 +++++---
 11 files changed, 392 insertions(+), 191 deletions(-)

-- 
1.7.9.5


^ permalink raw reply

* Re: [RFCv1 03/11] Bluetooth: AMP: Process Physical Link Complete evt
From: Mat Martineau @ 2012-10-26 17:16 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1351167652-12346-4-git-send-email-Andrei.Emeltchenko.news@gmail.com>


Andrei -

On Thu, 25 Oct 2012, Andrei Emeltchenko wrote:

> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Add processing for HCI Physical Link Complete event. Upon
> successful status received start L2CAP create channel process.
>
> Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> Acked-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> net/bluetooth/hci_event.c |   55 +++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 55 insertions(+)
>
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index aae8053..183d8bd 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -3637,6 +3637,57 @@ unlock:
> 	hci_dev_unlock(hdev);
> }
>
> +static void hci_phy_link_complete_evt(struct hci_dev *hdev,
> +				      struct sk_buff *skb)
> +{
> +	struct hci_ev_phy_link_complete *ev = (void *) skb->data;
> +	struct hci_conn *hcon, *bredr_hcon;
> +
> +	BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
> +	       ev->status);
> +
> +	hci_dev_lock(hdev);
> +
> +	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
> +	if (!hcon) {
> +		hci_dev_unlock(hdev);
> +		return;
> +	}
> +
> +	if (ev->status) {
> +		hci_conn_del(hcon);
> +		hci_dev_unlock(hdev);
> +		return;
> +	}
> +
> +	bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
> +
> +	hcon->state = BT_CONNECTED;
> +	bacpy(&hcon->dst, &bredr_hcon->dst);
> +
> +	hci_conn_hold(hcon);
> +	hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
> +	hci_conn_put(hcon);
> +
> +	hci_conn_hold_device(hcon);
> +	hci_conn_add_sysfs(hcon);
> +
> +	hci_dev_unlock(hdev);
> +
> +	if (hcon->out) {
> +		struct hci_dev *bredr_hdev = hci_dev_hold(bredr_hcon->hdev);
> +
> +		if (!bredr_hdev)
> +			return;
> +
> +		/* Placeholder - create chan req
> +		l2cap_chan_create_cfm(bredr_hcon, hcon->remote_id);
> +		*/

I think this is where you would call l2cap_physical_cfm(), but that 
function requires more information.  Is there enough context in hcon 
to get the local amp ID and l2cap_chan, or does the AMP manager need 
to be notified of the physical link so it can match up the physical 
link with other information?

> +
> +		hci_dev_put(bredr_hdev);
> +	}
> +}
> +
> static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
> {
> 	struct hci_ev_le_conn_complete *ev = (void *) skb->data;
> @@ -3964,6 +4015,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
> 		hci_remote_oob_data_request_evt(hdev, skb);
> 		break;
>
> +	case HCI_EV_PHY_LINK_COMPLETE:
> +		hci_phy_link_complete_evt(hdev, skb);
> +		break;
> +
> 	case HCI_EV_NUM_COMP_BLOCKS:
> 		hci_num_comp_blocks_evt(hdev, skb);
> 		break;
> -- 
> 1.7.9.5


--
Mat Martineau

Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation


^ permalink raw reply

* Re: [RFCv1 05/11] Bluetooth: AMP: Add Logical Link Create function
From: Mat Martineau @ 2012-10-26 17:01 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1351167652-12346-6-git-send-email-Andrei.Emeltchenko.news@gmail.com>


Hi Andrei -

On Thu, 25 Oct 2012, Andrei Emeltchenko wrote:

> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> After physical link is created logical link needs to be created.
> The process starts after L2CAP channel is created and L2CAP
> Configuration Response with result PENDING is received.
>
> Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> Acked-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> include/net/bluetooth/amp.h |    1 +
> net/bluetooth/amp.c         |   49 +++++++++++++++++++++++++++++++++++++++++++
> net/bluetooth/hci_event.c   |    9 ++++++++
> net/bluetooth/l2cap_core.c  |   17 +++++++++++----
> 4 files changed, 72 insertions(+), 4 deletions(-)
>
> diff --git a/include/net/bluetooth/amp.h b/include/net/bluetooth/amp.h
> index 2e7c79e..70d5c15 100644
> --- a/include/net/bluetooth/amp.h
> +++ b/include/net/bluetooth/amp.h
> @@ -46,5 +46,6 @@ void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr,
> 			struct hci_conn *hcon);
> void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle);
> void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle);
> +void amp_create_logical_link(struct l2cap_chan *chan);
>
> #endif /* __AMP_H */
> diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c
> index 231d7ef..fbb6360 100644
> --- a/net/bluetooth/amp.c
> +++ b/net/bluetooth/amp.c
> @@ -372,3 +372,52 @@ void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr,
>
> 	hci_send_cmd(hdev, HCI_OP_ACCEPT_PHY_LINK, sizeof(cp), &cp);
> }
> +
> +void amp_create_logical_link(struct l2cap_chan *chan)
> +{
> +	struct hci_cp_create_accept_logical_link cp;
> +	struct hci_conn *hcon;
> +	struct hci_dev *hdev;
> +
> +	BT_DBG("chan %p", chan);
> +
> +	if (!chan->hs_hcon)
> +		return;
> +
> +	hdev = hci_dev_hold(chan->hs_hcon->hdev);
> +	if (!hdev)
> +		return;
> +
> +	BT_DBG("chan %p ctrl_id %d dst %pMR", chan, chan->ctrl_id,
> +	       chan->conn->dst);
> +
> +	hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, chan->conn->dst);
> +	if (!hcon)
> +		goto done;
> +
> +	cp.phy_handle = hcon->handle;
> +
> +	cp.tx_flow_spec.id = chan->local_id;
> +	cp.tx_flow_spec.stype = chan->local_stype;
> +	cp.tx_flow_spec.msdu = cpu_to_le16(chan->local_msdu);
> +	cp.tx_flow_spec.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
> +	cp.tx_flow_spec.acc_lat = cpu_to_le32(chan->local_acc_lat);
> +	cp.tx_flow_spec.flush_to = cpu_to_le32(chan->local_flush_to);
> +
> +	cp.rx_flow_spec.id = chan->remote_id;
> +	cp.rx_flow_spec.stype = chan->remote_stype;
> +	cp.rx_flow_spec.msdu = cpu_to_le16(chan->remote_msdu);
> +	cp.rx_flow_spec.sdu_itime = cpu_to_le32(chan->remote_sdu_itime);
> +	cp.rx_flow_spec.acc_lat = cpu_to_le32(chan->remote_acc_lat);
> +	cp.rx_flow_spec.flush_to = cpu_to_le32(chan->remote_flush_to);
> +
> +	if (hcon->out)
> +		hci_send_cmd(hdev, HCI_OP_CREATE_LOGICAL_LINK, sizeof(cp),
> +			     &cp);
> +	else
> +		hci_send_cmd(hdev, HCI_OP_ACCEPT_LOGICAL_LINK, sizeof(cp),
> +			     &cp);
> +
> +done:
> +	hci_dev_put(hdev);
> +}
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index 00021cb..2c562a7 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -1829,6 +1829,11 @@ static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
> 	amp_write_remote_assoc(hdev, cp->phy_handle);
> }
>
> +static void hci_cs_create_logical_link(struct hci_dev *hdev, u8 status)
> +{
> +	BT_DBG("%s status 0x%2.2x", hdev->name, status);
> +}
> +
> static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
> {
> 	__u8 status = *((__u8 *) skb->data);
> @@ -2663,6 +2668,10 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
> 		hci_cs_accept_phylink(hdev, ev->status);
> 		break;
>
> +	case HCI_OP_CREATE_LOGICAL_LINK:
> +		hci_cs_create_logical_link(hdev, ev->status);
> +		break;
> +
> 	default:
> 		BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
> 		break;
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index d1728af..8e1525f 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -38,6 +38,7 @@
> #include <net/bluetooth/l2cap.h>
> #include <net/bluetooth/smp.h>
> #include <net/bluetooth/a2mp.h>
> +#include <net/bluetooth/amp.h>
>
> bool disable_ertm;
>
> @@ -1013,6 +1014,12 @@ static bool __amp_capable(struct l2cap_chan *chan)
> 		return false;
> }
>
> +static bool l2cap_check_efs(struct l2cap_chan *chan)
> +{
> +	/* Check EFS parameters */
> +	return true;
> +}
> +
> void l2cap_send_conn_req(struct l2cap_chan *chan)
> {
> 	struct l2cap_conn *conn = chan->conn;
> @@ -3948,13 +3955,15 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
> 				goto done;
> 			}
>
> -			/* check compatibility */
> -
> 			if (!chan->ctrl_id)
> 				l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
> 							0);
> -			else
> -				chan->ident = cmd->ident;
> +			else {
> +				if (l2cap_check_efs(chan)) {
> +					amp_create_logical_link(chan);
> +					chan->ident = cmd->ident;
> +				}
> +			}

Minor style issue - if one block of an if/else needs braces, then they 
all get braces.

> 		}
> 		goto done;
>
> -- 
> 1.7.9.5


--
Mat Martineau

Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply

* [PATCH BlueZ] hog: Fix selecting suspend backend
From: João Paulo Rechi Vita @ 2012-10-26 15:05 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: vinicius.gomes, claudio.takahasi, João Paulo Rechi Vita

The dummy backend was always being compiled and the --with-hog-suspend
option was not being accepted by configure. Now the backend can be
selected with --with-hog-suspend and the suspend implementation file is
generated during compile time.
---
 .gitignore   | 1 +
 Makefile.am  | 5 ++++-
 acinclude.m4 | 2 +-
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/.gitignore b/.gitignore
index b5c7356..27c4687 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,6 +35,7 @@ scripts/bluetooth.rules
 scripts/97-bluetooth.rules
 scripts/97-bluetooth-hid2hci.rules
 
+profiles/input/suspend.c
 profiles/sap/sap.c
 profiles/cups/bluetooth
 
diff --git a/Makefile.am b/Makefile.am
index 35b1520..f4bc96f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -184,7 +184,10 @@ if HOGPLUGIN
 builtin_modules += hog
 builtin_sources += profiles/input/hog_manager.c profiles/input/hog_device.h \
 			profiles/input/hog_device.c profiles/input/uhid_copy.h \
-			profiles/input/suspend-dummy.c profiles/input/suspend.h
+			profiles/input/suspend.h
+builtin_nodist += profiles/input/suspend.c
+
+EXTRA_DIST += profiles/input/suspend-dummy.c
 endif
 
 if NETWORKPLUGIN
diff --git a/acinclude.m4 b/acinclude.m4
index 4bac3f0..ddc8183 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -290,7 +290,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 		wiimote_enable=${enableval}
 	])
 
-	AC_ARG_WITH(gatt, AC_HELP_STRING([--with-hog-suspend=DRIVER], [select HoG suspend driver]), [
+	AC_ARG_WITH(hog_suspend, AC_HELP_STRING([--with-hog-suspend=DRIVER], [select HoG suspend driver]), [
 		hog_suspend_driver=${withval}
 	])
 
-- 
1.7.11.7


^ permalink raw reply related

* Re: [PATCH] Bluetooth: Fix error status when pairing fails
From: Gustavo Padovan @ 2012-10-26 14:18 UTC (permalink / raw)
  To: Paulo Sérgio; +Cc: linux-bluetooth
In-Reply-To: <1351194951-7534-1-git-send-email-paulo.sergio@openbossa.org>

Hi Paulo,

* Paulo Sérgio <paulo.sergio@openbossa.org> [2012-10-25 16:55:51 -0300]:

> When pairing fails due to wrong confirm value, the management layer
> doesn't report a proper error status. It sends
> MGMT_STATUS_CONNECT_FAILED instead of MGMT_STATUS_AUTH_FAILED.
> 
> Most of management functions that receive a status as a parameter
> expects for it to be encoded as a HCI status. But when a SMP pairing
> fails, the SMP layer sends the SMP reason as the error status to the
> management layer.
> 
> This commit maps all SMP reasons to HCI_ERROR_AUTH_FAILURE, which will
> be converted to MGMT_STATUS_AUTH_FAILED in the management layer.
> 
> Reported-by: Claudio Takahasi <claudio.takahasi@openbossa.org>
> Reviewed-by: João Paulo Rechi Vita <jprvita@openbossa.org>
> Signed-off-by: Paulo Sérgio <paulo.sergio@openbossa.org>
> ---
> 
> Please, disconsider the previous patch. It had a wrong commit message.
> 
> PS: This is my first patch.
> 
>  net/bluetooth/smp.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Patch has been applied to bluetooth.git. Thanks

	Gustavo

^ permalink raw reply

* Re: [RFC v1 obexd 01/11] fuse: Add initial obexfuse files, fuse main and options parse
From: Luiz Augusto von Dentz @ 2012-10-26 14:14 UTC (permalink / raw)
  To: Michał Poczwardowski; +Cc: linux-bluetooth
In-Reply-To: <CABBYNZJ0X4j539zwAHF5Sr7BVyZ2nU5CE_pt+3in=DvoB-M3bw@mail.gmail.com>

Hi Michal,

On Fri, Oct 26, 2012 at 4:10 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> Hi Michal,
>
> On Sun, Oct 21, 2012 at 7:05 PM, Michał Poczwardowski
> <dmp0x7c5@gmail.com> wrote:
>> ---
>>  fuse/helpers.c  |   55 +++++++++++++++++++++++++
>>  fuse/helpers.h  |   49 ++++++++++++++++++++++
>>  fuse/obexfuse.c |  119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 223 insertions(+), 0 deletions(-)
>>  create mode 100644 fuse/helpers.c
>>  create mode 100644 fuse/helpers.h
>>  create mode 100644 fuse/obexfuse.c
>>
>> diff --git a/fuse/helpers.c b/fuse/helpers.c
>> new file mode 100644
>> index 0000000..53bba57
>> --- /dev/null
>> +++ b/fuse/helpers.c
>> @@ -0,0 +1,55 @@
>> +/*
>> + *  OBEX Filesystem in Userspace
>> + *
>> + *  Copyright (C) 2012  Michał Poczwardowski <dmp0x7c5@gmail.com>
>> + *
>> + *
>> + *  This program is free software; you can redistribute it and/or modify
>> + *  it under the terms of the GNU General Public License as published by
>> + *  the Free Software Foundation; either version 2 of the License, or
>> + *  (at your option) any later version.
>> + *
>> + *  This program is distributed in the hope that it will be useful,
>> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + *  GNU General Public License for more details.
>> + *
>> + *  You should have received a copy of the GNU General Public License
>> + *  along with this program; if not, write to the Free Software
>> + *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
>> + *
>> + */
>> +
>> +#include <gobex/gobex.h>
>> +#include <btio/btio.h>
>> +
>> +#include <glib.h>
>> +#include <fcntl.h>
>> +#include <errno.h>
>> +
>> +#include <bluetooth/bluetooth.h>
>> +#include <bluetooth/rfcomm.h>
>> +#include <bluetooth/sdp.h>
>> +#include <bluetooth/sdp_lib.h>
>> +
>> +#define BT_RX_MTU 32767
>> +#define BT_TX_MTU 32767
>> +
>> +#include "helpers.h"
>> +
>> +#define OBEX_FTP_UUID \
>> +       "\xF9\xEC\x7B\xC4\x95\x3C\x11\xD2\x98\x4E\x52\x54\x00\xDC\x9E\x09"
>> +#define OBEX_FTP_UUID_LEN 16
>> +
>> +#define OBEX_FTP_LS "x-obex/folder-listing"
>> +
>> +struct gobexhlp_request {
>> +       gchar *name;
>> +       gboolean complete;
>> +};
>> +
>> +struct gobexhlp_location {
>> +       gchar *dir;
>> +       gchar *file;
>> +};
>> +
>> diff --git a/fuse/helpers.h b/fuse/helpers.h
>> new file mode 100644
>> index 0000000..21972b2
>> --- /dev/null
>> +++ b/fuse/helpers.h
>> @@ -0,0 +1,49 @@
>> +/*
>> + *  OBEX Filesystem in Userspace
>> + *
>> + *  Copyright (C) 2012  Michał Poczwardowski <dmp0x7c5@gmail.com>
>> + *
>> + *
>> + *  This program is free software; you can redistribute it and/or modify
>> + *  it under the terms of the GNU General Public License as published by
>> + *  the Free Software Foundation; either version 2 of the License, or
>> + *  (at your option) any later version.
>> + *
>> + *  This program is distributed in the hope that it will be useful,
>> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + *  GNU General Public License for more details.
>> + *
>> + *  You should have received a copy of the GNU General Public License
>> + *  along with this program; if not, write to the Free Software
>> + *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
>> + *
>> + */
>> +
>> +#include <gobex/gobex.h>
>> +#include <glib.h>
>> +
>> +struct gobexhlp_request;
>> +
>> +struct gobexhlp_buffer {
>> +       void *data;
>> +       gsize tmpsize;
>> +       gsize size;
>> +       gboolean edited;
>> +};
>> +
>> +struct gobexhlp_session {
>> +       GObex *obex;
>> +       GList *lsfiles;
>> +       GIOChannel *io;
>> +       GHashTable *file_stat;
>> +       gchar *setpath;
>> +       struct gobexhlp_request *request;
>> +       struct gobexhlp_buffer *buffer;
>> +       gboolean vtouch;
>> +       gchar *vtouch_path;
>> +       gboolean rtouch;
>> +       int status;
>> +       GError *err;
>> +};
>> +
>> diff --git a/fuse/obexfuse.c b/fuse/obexfuse.c
>> new file mode 100644
>> index 0000000..fe4f4da
>> --- /dev/null
>> +++ b/fuse/obexfuse.c
>> @@ -0,0 +1,119 @@
>> +/*
>> + *  OBEX Filesystem in Userspace
>> + *
>> + *  Copyright (C) 2012  Michał Poczwardowski <dmp0x7c5@gmail.com>
>> + *
>> + *
>> + *  This program is free software; you can redistribute it and/or modify
>> + *  it under the terms of the GNU General Public License as published by
>> + *  the Free Software Foundation; either version 2 of the License, or
>> + *  (at your option) any later version.
>> + *
>> + *  This program is distributed in the hope that it will be useful,
>> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + *  GNU General Public License for more details.
>> + *
>> + *  You should have received a copy of the GNU General Public License
>> + *  along with this program; if not, write to the Free Software
>> + *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
>> + *
>> + */
>> +
>> +#define FUSE_USE_VERSION 26
>> +
>> +#include <stdio.h>
>> +#include <errno.h>
>> +#include <fcntl.h>
>> +#include <stdlib.h>
>> +#include <string.h>
>> +
>> +#include <fuse.h>
>> +#include <fuse/fuse_opt.h>
>> +
>> +#include "helpers.h"
>> +
>> +struct options {
>> +       char* dststr;
>> +       char* srcstr;
>> +} options;
>> +
>> +#define GOBEXFUSE_OPT_KEY(t, p, v) { t, offsetof(struct options, p), v }
>> +
>> +enum
>> +{
>> +   KEY_VERSION,
>> +   KEY_HELP,
>> +};
>> +
>> +static struct fuse_opt obexfuse_opts[] =
>> +{
>> +       GOBEXFUSE_OPT_KEY("--target=%s",dststr, 0),
>> +       GOBEXFUSE_OPT_KEY("-t %s",      dststr, 0),
>> +       GOBEXFUSE_OPT_KEY("--source=%s",srcstr, 0),
>> +       GOBEXFUSE_OPT_KEY("-s %s",      srcstr, 0),
>> +
>> +       FUSE_OPT_KEY("-V",             KEY_VERSION),
>> +       FUSE_OPT_KEY("--version",      KEY_VERSION),
>> +       FUSE_OPT_KEY("-h",             KEY_HELP),
>> +       FUSE_OPT_KEY("--help",         KEY_HELP),
>> +       FUSE_OPT_END
>> +};
>> +
>> +static struct fuse_operations obexfuse_oper = {
>> +};
>> +
>> +static int obexfuse_opt_proc(void *data, const char *arg, int key,
>> +                                       struct fuse_args *outargs)
>> +{
>> +       switch (key) {
>> +       case KEY_HELP:
>> +               g_printerr("Usage: %s mountpoint [options]\n"
>> +                               "\n"
>> +                               "general options:\n"
>> +                               "    -o opt,[opt...]  mount options\n"
>> +                               "    -h   --help      print help\n"
>> +                               "    -V   --version   print version\n"
>> +                               "\n"
>> +                               "obexfuse options:\n"
>> +                               "    -t   --target    target btaddr "
>> +                               "(mandatory)\n"
>> +                               "    -s   --source    source btaddr\n"
>> +                               "\n"
>> +                               , outargs->argv[0]);
>> +               fuse_opt_add_arg(outargs, "-ho");
>> +               fuse_main(outargs->argc, outargs->argv, &obexfuse_oper, NULL);
>> +               exit(1);
>> +       case KEY_VERSION:
>> +               g_print("obexfuse upon:\n");
>> +               fuse_opt_add_arg(outargs, "--version");
>> +               fuse_main(outargs->argc, outargs->argv, &obexfuse_oper, NULL);
>> +               exit(0);
>> +       }
>> +       return 1;
>> +}
>> +
>> +int main(int argc, char *argv[])
>> +{
>> +       int retfuse;
>> +       struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
>> +
>> +       memset(&options, 0, sizeof(struct options));
>> +
>> +       if (fuse_opt_parse(&args, &options, obexfuse_opts,
>> +                               obexfuse_opt_proc) == -1)
>> +               return -EINVAL;
>> +
>> +       if (options.dststr == NULL) {
>> +               g_printerr("Target not specified\n");
>> +               return -EINVAL;
>> +       }
>> +
>> +       g_thread_init(NULL);
>> +
>> +       fuse_opt_add_arg(&args, "-s"); /* force single threaded mode */
>> +       retfuse = fuse_main(args.argc, args.argv, &obexfuse_oper, NULL);
>> +
>> +       fuse_opt_free_args(&args);
>> +       return retfuse;
>> +}
>> --
>> 1.7.8.6
>
> Doesn't apply:
>
> Applying: fuse: Add initial obexfuse files, fuse main and options parse
> /home/vudentz/git/obexd/.git/rebase-apply/patch:70: new blank line at EOF.
> +
> /home/vudentz/git/obexd/.git/rebase-apply/patch:125: new blank line at EOF.
> +
> fatal: 2 lines add whitespace errors.
> Patch failed at 0001 fuse: Add initial obexfuse files, fuse main and
> options parse

Somehow patch 01 seems to mangled, it has windows style line break and
git doesn't like that.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [RFC v1 obexd 01/11] fuse: Add initial obexfuse files, fuse main and options parse
From: Luiz Augusto von Dentz @ 2012-10-26 14:10 UTC (permalink / raw)
  To: Michał Poczwardowski; +Cc: linux-bluetooth
In-Reply-To: <1350839131-12042-1-git-send-email-dmp0x7c5@gmail.com>

Hi Michal,

On Sun, Oct 21, 2012 at 7:05 PM, Michał Poczwardowski
<dmp0x7c5@gmail.com> wrote:
> ---
>  fuse/helpers.c  |   55 +++++++++++++++++++++++++
>  fuse/helpers.h  |   49 ++++++++++++++++++++++
>  fuse/obexfuse.c |  119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 223 insertions(+), 0 deletions(-)
>  create mode 100644 fuse/helpers.c
>  create mode 100644 fuse/helpers.h
>  create mode 100644 fuse/obexfuse.c
>
> diff --git a/fuse/helpers.c b/fuse/helpers.c
> new file mode 100644
> index 0000000..53bba57
> --- /dev/null
> +++ b/fuse/helpers.c
> @@ -0,0 +1,55 @@
> +/*
> + *  OBEX Filesystem in Userspace
> + *
> + *  Copyright (C) 2012  Michał Poczwardowski <dmp0x7c5@gmail.com>
> + *
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License as published by
> + *  the Free Software Foundation; either version 2 of the License, or
> + *  (at your option) any later version.
> + *
> + *  This program is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + *
> + *  You should have received a copy of the GNU General Public License
> + *  along with this program; if not, write to the Free Software
> + *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
> + *
> + */
> +
> +#include <gobex/gobex.h>
> +#include <btio/btio.h>
> +
> +#include <glib.h>
> +#include <fcntl.h>
> +#include <errno.h>
> +
> +#include <bluetooth/bluetooth.h>
> +#include <bluetooth/rfcomm.h>
> +#include <bluetooth/sdp.h>
> +#include <bluetooth/sdp_lib.h>
> +
> +#define BT_RX_MTU 32767
> +#define BT_TX_MTU 32767
> +
> +#include "helpers.h"
> +
> +#define OBEX_FTP_UUID \
> +       "\xF9\xEC\x7B\xC4\x95\x3C\x11\xD2\x98\x4E\x52\x54\x00\xDC\x9E\x09"
> +#define OBEX_FTP_UUID_LEN 16
> +
> +#define OBEX_FTP_LS "x-obex/folder-listing"
> +
> +struct gobexhlp_request {
> +       gchar *name;
> +       gboolean complete;
> +};
> +
> +struct gobexhlp_location {
> +       gchar *dir;
> +       gchar *file;
> +};
> +
> diff --git a/fuse/helpers.h b/fuse/helpers.h
> new file mode 100644
> index 0000000..21972b2
> --- /dev/null
> +++ b/fuse/helpers.h
> @@ -0,0 +1,49 @@
> +/*
> + *  OBEX Filesystem in Userspace
> + *
> + *  Copyright (C) 2012  Michał Poczwardowski <dmp0x7c5@gmail.com>
> + *
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License as published by
> + *  the Free Software Foundation; either version 2 of the License, or
> + *  (at your option) any later version.
> + *
> + *  This program is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + *
> + *  You should have received a copy of the GNU General Public License
> + *  along with this program; if not, write to the Free Software
> + *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
> + *
> + */
> +
> +#include <gobex/gobex.h>
> +#include <glib.h>
> +
> +struct gobexhlp_request;
> +
> +struct gobexhlp_buffer {
> +       void *data;
> +       gsize tmpsize;
> +       gsize size;
> +       gboolean edited;
> +};
> +
> +struct gobexhlp_session {
> +       GObex *obex;
> +       GList *lsfiles;
> +       GIOChannel *io;
> +       GHashTable *file_stat;
> +       gchar *setpath;
> +       struct gobexhlp_request *request;
> +       struct gobexhlp_buffer *buffer;
> +       gboolean vtouch;
> +       gchar *vtouch_path;
> +       gboolean rtouch;
> +       int status;
> +       GError *err;
> +};
> +
> diff --git a/fuse/obexfuse.c b/fuse/obexfuse.c
> new file mode 100644
> index 0000000..fe4f4da
> --- /dev/null
> +++ b/fuse/obexfuse.c
> @@ -0,0 +1,119 @@
> +/*
> + *  OBEX Filesystem in Userspace
> + *
> + *  Copyright (C) 2012  Michał Poczwardowski <dmp0x7c5@gmail.com>
> + *
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License as published by
> + *  the Free Software Foundation; either version 2 of the License, or
> + *  (at your option) any later version.
> + *
> + *  This program is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + *
> + *  You should have received a copy of the GNU General Public License
> + *  along with this program; if not, write to the Free Software
> + *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
> + *
> + */
> +
> +#define FUSE_USE_VERSION 26
> +
> +#include <stdio.h>
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +#include <fuse.h>
> +#include <fuse/fuse_opt.h>
> +
> +#include "helpers.h"
> +
> +struct options {
> +       char* dststr;
> +       char* srcstr;
> +} options;
> +
> +#define GOBEXFUSE_OPT_KEY(t, p, v) { t, offsetof(struct options, p), v }
> +
> +enum
> +{
> +   KEY_VERSION,
> +   KEY_HELP,
> +};
> +
> +static struct fuse_opt obexfuse_opts[] =
> +{
> +       GOBEXFUSE_OPT_KEY("--target=%s",dststr, 0),
> +       GOBEXFUSE_OPT_KEY("-t %s",      dststr, 0),
> +       GOBEXFUSE_OPT_KEY("--source=%s",srcstr, 0),
> +       GOBEXFUSE_OPT_KEY("-s %s",      srcstr, 0),
> +
> +       FUSE_OPT_KEY("-V",             KEY_VERSION),
> +       FUSE_OPT_KEY("--version",      KEY_VERSION),
> +       FUSE_OPT_KEY("-h",             KEY_HELP),
> +       FUSE_OPT_KEY("--help",         KEY_HELP),
> +       FUSE_OPT_END
> +};
> +
> +static struct fuse_operations obexfuse_oper = {
> +};
> +
> +static int obexfuse_opt_proc(void *data, const char *arg, int key,
> +                                       struct fuse_args *outargs)
> +{
> +       switch (key) {
> +       case KEY_HELP:
> +               g_printerr("Usage: %s mountpoint [options]\n"
> +                               "\n"
> +                               "general options:\n"
> +                               "    -o opt,[opt...]  mount options\n"
> +                               "    -h   --help      print help\n"
> +                               "    -V   --version   print version\n"
> +                               "\n"
> +                               "obexfuse options:\n"
> +                               "    -t   --target    target btaddr "
> +                               "(mandatory)\n"
> +                               "    -s   --source    source btaddr\n"
> +                               "\n"
> +                               , outargs->argv[0]);
> +               fuse_opt_add_arg(outargs, "-ho");
> +               fuse_main(outargs->argc, outargs->argv, &obexfuse_oper, NULL);
> +               exit(1);
> +       case KEY_VERSION:
> +               g_print("obexfuse upon:\n");
> +               fuse_opt_add_arg(outargs, "--version");
> +               fuse_main(outargs->argc, outargs->argv, &obexfuse_oper, NULL);
> +               exit(0);
> +       }
> +       return 1;
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +       int retfuse;
> +       struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
> +
> +       memset(&options, 0, sizeof(struct options));
> +
> +       if (fuse_opt_parse(&args, &options, obexfuse_opts,
> +                               obexfuse_opt_proc) == -1)
> +               return -EINVAL;
> +
> +       if (options.dststr == NULL) {
> +               g_printerr("Target not specified\n");
> +               return -EINVAL;
> +       }
> +
> +       g_thread_init(NULL);
> +
> +       fuse_opt_add_arg(&args, "-s"); /* force single threaded mode */
> +       retfuse = fuse_main(args.argc, args.argv, &obexfuse_oper, NULL);
> +
> +       fuse_opt_free_args(&args);
> +       return retfuse;
> +}
> --
> 1.7.8.6

Doesn't apply:

Applying: fuse: Add initial obexfuse files, fuse main and options parse
/home/vudentz/git/obexd/.git/rebase-apply/patch:70: new blank line at EOF.
+
/home/vudentz/git/obexd/.git/rebase-apply/patch:125: new blank line at EOF.
+
fatal: 2 lines add whitespace errors.
Patch failed at 0001 fuse: Add initial obexfuse files, fuse main and
options parse

-- 
Luiz Augusto von Dentz

^ permalink raw reply

* [PATCH BlueZ v4] AVDTP: Do not keep a internal reference
From: Luiz Augusto von Dentz @ 2012-10-26 13:44 UTC (permalink / raw)
  To: linux-bluetooth

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

Don't initialize reference with 1, instead always start disconnect timer
when reference drops to 0, so in case nobody reclaims the session it
automatically disconnect after 1 second and frees the memory.
---
v2: Fix with stream_setup flag being ignored in disconnect_timeout
v3: Do avrcp_free on connection_lost to avoid having dangling sessions in
disconnected state waiting the timeout to be freed.
v4: Remove unnecessary reference when authorizing, disconnect timer is only
started when the session is really connected.

 audio/avdtp.c | 204 +++++++++++++++++++++++-----------------------------------
 1 file changed, 82 insertions(+), 122 deletions(-)

diff --git a/audio/avdtp.c b/audio/avdtp.c
index bd91cb6..75b81fe 100644
--- a/audio/avdtp.c
+++ b/audio/avdtp.c
@@ -387,8 +387,7 @@ struct avdtp_stream {
 /* Structure describing an AVDTP connection between two devices */
 
 struct avdtp {
-	int ref;
-	int free_lock;
+	unsigned int ref;
 
 	uint16_t version;
 
@@ -657,50 +656,6 @@ static gboolean stream_open_timeout(gpointer user_data)
 	return FALSE;
 }
 
-static gboolean disconnect_timeout(gpointer user_data)
-{
-	struct avdtp *session = user_data;
-	struct audio_device *dev;
-	gboolean stream_setup;
-
-	session->dc_timer = 0;
-	stream_setup = session->stream_setup;
-	session->stream_setup = FALSE;
-
-	dev = manager_get_device(&session->server->src, &session->dst, FALSE);
-
-	if (dev && dev->sink && stream_setup)
-		sink_setup_stream(dev->sink, session);
-	else if (dev && dev->source && stream_setup)
-		source_setup_stream(dev->source, session);
-	else
-		connection_lost(session, ETIMEDOUT);
-
-	return FALSE;
-}
-
-static void remove_disconnect_timer(struct avdtp *session)
-{
-	g_source_remove(session->dc_timer);
-	session->dc_timer = 0;
-	session->stream_setup = FALSE;
-}
-
-static void set_disconnect_timer(struct avdtp *session)
-{
-	if (session->dc_timer)
-		remove_disconnect_timer(session);
-
-	if (session->device_disconnect) {
-		session->dc_timer = g_idle_add(disconnect_timeout, session);
-		return;
-	}
-
-	session->dc_timer = g_timeout_add_seconds(DISCONNECT_TIMEOUT,
-						disconnect_timeout,
-						session);
-}
-
 void avdtp_error_init(struct avdtp_error *err, uint8_t category, int id)
 {
 	err->category = category;
@@ -780,8 +735,9 @@ static void avdtp_set_state(struct avdtp *session,
 	}
 }
 
-static void stream_free(struct avdtp_stream *stream)
+static void stream_free(void *data)
 {
+	struct avdtp_stream *stream = data;
 	struct avdtp_remote_sep *rsep;
 
 	stream->lsep->info.inuse = 0;
@@ -1148,33 +1104,34 @@ static int avdtp_cancel_authorization(struct avdtp *session)
 	return 0;
 }
 
-static void connection_lost(struct avdtp *session, int err)
+static void sep_free(gpointer data)
 {
-	char address[18];
-
-	ba2str(&session->dst, address);
-	DBG("Disconnected from %s", address);
+	struct avdtp_remote_sep *sep = data;
 
-	if (err != EACCES)
-		avdtp_cancel_authorization(session);
+	g_slist_free_full(sep->caps, g_free);
+	g_free(sep);
+}
 
-	session->free_lock = 1;
+static void remove_disconnect_timer(struct avdtp *session)
+{
+	g_source_remove(session->dc_timer);
+	session->dc_timer = 0;
+	session->stream_setup = FALSE;
+}
 
-	finalize_discovery(session, err);
+static void avdtp_free(void *data)
+{
+	struct avdtp *session = data;
 
-	g_slist_foreach(session->streams, (GFunc) release_stream, session);
-	session->streams = NULL;
+	DBG("%p", session);
 
-	session->free_lock = 0;
+	g_slist_free_full(session->streams, stream_free);
 
 	if (session->io) {
 		g_io_channel_shutdown(session->io, FALSE, NULL);
 		g_io_channel_unref(session->io);
-		session->io = NULL;
 	}
 
-	avdtp_set_state(session, AVDTP_SESSION_STATE_DISCONNECTED);
-
 	if (session->io_id) {
 		g_source_remove(session->io_id);
 		session->io_id = 0;
@@ -1183,69 +1140,91 @@ static void connection_lost(struct avdtp *session, int err)
 	if (session->dc_timer)
 		remove_disconnect_timer(session);
 
-	if (session->ref != 1)
-		error("connection_lost: ref count not 1 after all callbacks");
-	else
-		avdtp_unref(session);
+	if (session->req)
+		pending_req_free(session->req);
+
+	g_slist_free_full(session->seps, sep_free);
+
+	g_free(session->buf);
+
+	g_free(session);
 }
 
-static void sep_free(gpointer data)
+static gboolean disconnect_timeout(gpointer user_data)
 {
-	struct avdtp_remote_sep *sep = data;
+	struct avdtp *session = user_data;
+	struct audio_device *dev;
+	gboolean stream_setup;
 
-	g_slist_free_full(sep->caps, g_free);
-	g_free(sep);
+	session->dc_timer = 0;
+
+	stream_setup = session->stream_setup;
+	session->stream_setup = FALSE;
+	dev = manager_get_device(&session->server->src, &session->dst, FALSE);
+
+	if (dev && dev->sink && stream_setup)
+		sink_setup_stream(dev->sink, session);
+	else if (dev && dev->source && stream_setup)
+		source_setup_stream(dev->source, session);
+	else
+		connection_lost(session, ETIMEDOUT);
+
+	return FALSE;
 }
 
-void avdtp_unref(struct avdtp *session)
+static void set_disconnect_timer(struct avdtp *session)
 {
-	struct avdtp_server *server;
+	if (session->dc_timer)
+		remove_disconnect_timer(session);
 
-	if (!session)
+	if (session->device_disconnect) {
+		session->dc_timer = g_idle_add(disconnect_timeout, session);
 		return;
+	}
 
-	session->ref--;
+	session->dc_timer = g_timeout_add_seconds(DISCONNECT_TIMEOUT,
+						disconnect_timeout,
+						session);
+}
 
-	DBG("%p: ref=%d", session, session->ref);
+static void connection_lost(struct avdtp *session, int err)
+{
+	struct avdtp_server *server = session->server;
+	char address[18];
 
-	if (session->ref == 1) {
-		if (session->state == AVDTP_SESSION_STATE_CONNECTING &&
-								session->io) {
-			avdtp_cancel_authorization(session);
-			g_io_channel_shutdown(session->io, TRUE, NULL);
-			g_io_channel_unref(session->io);
-			session->io = NULL;
-			avdtp_set_state(session,
-					AVDTP_SESSION_STATE_DISCONNECTED);
-		}
+	ba2str(&session->dst, address);
+	DBG("Disconnected from %s", address);
 
-		if (session->io)
-			set_disconnect_timer(session);
-		else if (!session->free_lock) /* Drop the local ref if we
-						 aren't connected */
-			session->ref--;
-	}
+	if (err != EACCES)
+		avdtp_cancel_authorization(session);
 
-	if (session->ref > 0)
-		return;
+	g_slist_foreach(session->streams, (GFunc) release_stream, session);
+	session->streams = NULL;
 
-	server = session->server;
+	finalize_discovery(session, err);
 
-	DBG("%p: freeing session and removing from list", session);
+	avdtp_set_state(session, AVDTP_SESSION_STATE_DISCONNECTED);
 
-	if (session->dc_timer)
-		remove_disconnect_timer(session);
+	if (session->ref > 0)
+		return;
 
 	server->sessions = g_slist_remove(server->sessions, session);
+	avdtp_free(session);
+}
 
-	if (session->req)
-		pending_req_free(session->req);
+void avdtp_unref(struct avdtp *session)
+{
+	if (!session)
+		return;
 
-	g_slist_free_full(session->seps, sep_free);
+	session->ref--;
 
-	g_free(session->buf);
+	DBG("%p: ref=%d", session, session->ref);
 
-	g_free(session);
+	if (session->ref > 0)
+		return;
+
+	set_disconnect_timer(session);
 }
 
 struct avdtp *avdtp_ref(struct avdtp *session)
@@ -2231,12 +2210,6 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
 			goto failed;
 		}
 
-		if (session->ref == 1 && !session->streams && !session->req)
-			set_disconnect_timer(session);
-
-		if (session->streams && session->dc_timer)
-			remove_disconnect_timer(session);
-
 		if (session->req && session->req->collided) {
 			DBG("Collision detected");
 			goto next;
@@ -2383,7 +2356,6 @@ static struct avdtp *avdtp_get_internal(const bdaddr_t *src, const bdaddr_t *dst
 
 	session->server = server;
 	bacpy(&session->dst, dst);
-	session->ref = 1;
 	/* We don't use avdtp_set_state() here since this isn't a state change
 	 * but just setting of the initial state */
 	session->state = AVDTP_SESSION_STATE_DISCONNECTED;
@@ -2578,7 +2550,6 @@ static void avdtp_confirm_cb(GIOChannel *chan, gpointer data)
 							auth_cb, session);
 	if (session->auth_id == 0) {
 		avdtp_set_state(session, AVDTP_SESSION_STATE_DISCONNECTED);
-		avdtp_unref(session);
 		goto drop;
 	}
 
@@ -3949,23 +3920,12 @@ proceed:
 void avdtp_exit(const bdaddr_t *src)
 {
 	struct avdtp_server *server;
-	GSList *l;
 
 	server = find_server(servers, src);
 	if (!server)
 		return;
 
-	l = server->sessions;
-	while (l) {
-		struct avdtp *session = l->data;
-
-		l = l->next;
-		/* value of l pointer should be updated before invoking
-		 * connection_lost since it internally uses avdtp_unref
-		 * which operates on server->session list as well
-		 */
-		connection_lost(session, -ECONNABORTED);
-	}
+	g_slist_free_full(server->sessions, avdtp_free);
 
 	servers = g_slist_remove(servers, server);
 
-- 
1.7.11.7


^ permalink raw reply related

* Re: [PATCH] Bluetooth: Add support for BCM20702A0 [0b05, 17b5]
From: Anderson Lizardo @ 2012-10-26 12:49 UTC (permalink / raw)
  To: jeff; +Cc: gustavo, marcel, johan.hedberg, linux-bluetooth, linux-kernel
In-Reply-To: <5089902E.9020204@deserettechnology.com>

Hi Jeff,

On Thu, Oct 25, 2012 at 3:17 PM, Jeff Cook <jeff@deserettechnology.com> wrote:
> Thanks for the help everyone. I did skim SubmittingPatches prior to
> submission, but dropped off before sections 12 and 15; the information
> seemed outdated since it made no mention of git by the time I stopped
> reading (around section 9 or so), so I looked elsewhere.
>
> I will resubmit according to the information in Section 15. Do I need to
> add something like "try 2" to the patch's subject line, or is it okay
> without that?

Usually I generate a new patch with "git format-patch HEAD^" and edit
the "[PATCH]" prefix to become "[PATCH v2]" and resend the patch
using:

git send-email --to linux-bluetooth@...  --in-reply-to AAA
0001-name-of-the-patch.patch

where "AAA" is the "Message-ID" of the original patch (as seen in the
mail headers, e.g. 5087B517.9090703@deserettechnology.com for your
original patch). and "0001-name-of-the-patch.patch" is the filename
for the patch created by git format-patch.

Hope that helps,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply

* Re: [PATCH BlueZ] core: Do not call the callback on btd_cancel_authorization
From: Johan Hedberg @ 2012-10-26 11:58 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1351252089-19329-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Fri, Oct 26, 2012, Luiz Augusto von Dentz wrote:
> btd_cancel_authorization should work like g_source_remove and not attempt
> to reach the callback as its maybe already invalid or lead to double free
> situations such as this:
> 
> Invalid write of size 4
>    at 0x13D480: connection_lost (avdtp.c:1102)
>    by 0x13F37A: session_cb (avdtp.c:2281)
>    by 0x4C7B824: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3200.4)
>    by 0x4C7BB57: ??? (in /usr/lib64/libglib-2.0.so.0.3200.4)
>    by 0x4C7BF51: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3200.4)
>    by 0x122B21: main (main.c:551)
>  Address 0x6512ac0 is 32 bytes inside a block of size 1,184 free'd
>    at 0x4A07786: free (vg_replace_malloc.c:446)
>    by 0x4C8150E: g_free (in /usr/lib64/libglib-2.0.so.0.3200.4)
>    by 0x13D4A9: connection_lost (avdtp.c:1216)
>    by 0x13D55E: auth_cb (avdtp.c:2471)
>    by 0x17E99A: service_auth_cancel (adapter.c:1021)
>    by 0x183C67: btd_cancel_authorization (adapter.c:3358)
>    by 0x13D477: connection_lost (avdtp.c:1098)
>    by 0x13F37A: session_cb (avdtp.c:2281)
>    by 0x4C7B824: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3200.4)
>    by 0x4C7BB57: ??? (in /usr/lib64/libglib-2.0.so.0.3200.4)
>    by 0x4C7BF51: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3200.4)
>    by 0x122B21: main (main.c:551)
> ---
>  src/adapter.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)

Applied. Thanks.

Johan

^ permalink raw reply

* [PATCH BlueZ] core: Do not call the callback on btd_cancel_authorization
From: Luiz Augusto von Dentz @ 2012-10-26 11:48 UTC (permalink / raw)
  To: linux-bluetooth

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

btd_cancel_authorization should work like g_source_remove and not attempt
to reach the callback as its maybe already invalid or lead to double free
situations such as this:

Invalid write of size 4
   at 0x13D480: connection_lost (avdtp.c:1102)
   by 0x13F37A: session_cb (avdtp.c:2281)
   by 0x4C7B824: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3200.4)
   by 0x4C7BB57: ??? (in /usr/lib64/libglib-2.0.so.0.3200.4)
   by 0x4C7BF51: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3200.4)
   by 0x122B21: main (main.c:551)
 Address 0x6512ac0 is 32 bytes inside a block of size 1,184 free'd
   at 0x4A07786: free (vg_replace_malloc.c:446)
   by 0x4C8150E: g_free (in /usr/lib64/libglib-2.0.so.0.3200.4)
   by 0x13D4A9: connection_lost (avdtp.c:1216)
   by 0x13D55E: auth_cb (avdtp.c:2471)
   by 0x17E99A: service_auth_cancel (adapter.c:1021)
   by 0x183C67: btd_cancel_authorization (adapter.c:3358)
   by 0x13D477: connection_lost (avdtp.c:1098)
   by 0x13F37A: session_cb (avdtp.c:2281)
   by 0x4C7B824: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3200.4)
   by 0x4C7BB57: ??? (in /usr/lib64/libglib-2.0.so.0.3200.4)
   by 0x4C7BF51: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3200.4)
   by 0x122B21: main (main.c:551)
---
 src/adapter.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/adapter.c b/src/adapter.c
index 54b1a64..32cc0a2 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3355,7 +3355,10 @@ int btd_cancel_authorization(guint id)
 
 	g_queue_remove(auth->adapter->auths, auth);
 
-	service_auth_cancel(auth);
+	if (auth->agent != NULL)
+		agent_cancel(auth->agent);
+
+	g_free(auth);
 
 	return 0;
 }
-- 
1.7.11.7


^ permalink raw reply related

* [PATCH v9 5/5] hcitool: Retrieve names from cache directory
From: Frédéric Danis @ 2012-10-26 10:08 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1351246097-22285-1-git-send-email-frederic.danis@linux.intel.com>

---
 Makefile.tools  |    2 +-
 tools/hcitool.c |   31 ++++++++++++++++++++++++++-----
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/Makefile.tools b/Makefile.tools
index ec79cea..f7c85ef 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -28,7 +28,7 @@ tools_hciconfig_LDADD = lib/libbluetooth-private.la
 
 tools_hcitool_SOURCES = tools/hcitool.c src/oui.h src/oui.c \
 						src/textfile.h src/textfile.c
-tools_hcitool_LDADD = lib/libbluetooth-private.la
+tools_hcitool_LDADD = lib/libbluetooth-private.la @GLIB_LIBS@
 
 tools_sdptool_SOURCES = tools/sdptool.c src/sdp-xml.h src/sdp-xml.c
 tools_sdptool_LDADD = lib/libbluetooth-private.la @GLIB_LIBS@
diff --git a/tools/hcitool.c b/tools/hcitool.c
index aefbd68..a05e31f 100644
--- a/tools/hcitool.c
+++ b/tools/hcitool.c
@@ -40,6 +40,8 @@
 #include <sys/socket.h>
 #include <signal.h>
 
+#include <glib.h>
+
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/hci.h>
 #include <bluetooth/hci_lib.h>
@@ -409,13 +411,32 @@ static char *major_classes[] = {
 
 static char *get_device_name(const bdaddr_t *local, const bdaddr_t *peer)
 {
-	char filename[PATH_MAX + 1], addr[18];
+	char filename[PATH_MAX + 1];
+	char local_addr[18], peer_addr[18];
+	GKeyFile *key_file;
+	char *str = NULL;
+	int len;
+
+	ba2str(local, local_addr);
+	ba2str(peer, peer_addr);
+
+	snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local_addr,
+			peer_addr);
+	filename[PATH_MAX] = '\0';
+	key_file = g_key_file_new();
+
+	if (g_key_file_load_from_file(key_file, filename, 0, NULL)) {
+		str = g_key_file_get_string(key_file, "General", "Name", NULL);
+		if (str) {
+			len = strlen(str);
+			if (len > HCI_MAX_NAME_LENGTH)
+				str[HCI_MAX_NAME_LENGTH] = '\0';
+		}
+	}
 
-	ba2str(local, addr);
-	create_name(filename, PATH_MAX, STORAGEDIR, addr, "names");
+	g_key_file_free(key_file);
 
-	ba2str(peer, addr);
-	return textfile_get(filename, addr);
+	return str;
 }
 
 /* Display local devices */
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v9 4/5] input: Retrieve device name from device object
From: Frédéric Danis @ 2012-10-26 10:08 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1351246097-22285-1-git-send-email-frederic.danis@linux.intel.com>

---
 profiles/input/device.c |    9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/profiles/input/device.c b/profiles/input/device.c
index fbc3d6f..108be39 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -777,7 +777,7 @@ static struct input_device *input_device_new(struct btd_device *device,
 {
 	struct btd_adapter *adapter = device_get_adapter(device);
 	struct input_device *idev;
-	char name[249], src_addr[18], dst_addr[18];
+	char name[HCI_MAX_NAME_LENGTH + 1];
 
 	idev = g_new0(struct input_device, 1);
 	bacpy(&idev->src, adapter_get_address(adapter));
@@ -787,11 +787,8 @@ static struct input_device *input_device_new(struct btd_device *device,
 	idev->handle = handle;
 	idev->disable_sdp = disable_sdp;
 
-	ba2str(&idev->src, src_addr);
-	ba2str(&idev->dst, dst_addr);
-
-	if (read_device_name(src_addr, dst_addr, device_get_addr_type(device),
-				name) == 0)
+	device_get_name(device, name, HCI_MAX_NAME_LENGTH);
+	if (strlen(name) > 0)
 		idev->name = g_strdup(name);
 
 	if (g_dbus_register_interface(btd_get_dbus_connection(),
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v9 3/5] dbusoob: Set device name in device object
From: Frédéric Danis @ 2012-10-26 10:08 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1351246097-22285-1-git-send-email-frederic.danis@linux.intel.com>

---
 plugins/dbusoob.c |   11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/plugins/dbusoob.c b/plugins/dbusoob.c
index 5c5b6ef..82cd304 100644
--- a/plugins/dbusoob.c
+++ b/plugins/dbusoob.c
@@ -191,9 +191,11 @@ static gboolean parse_data(DBusMessageIter *data, struct oob_data *remote_data)
 	return TRUE;
 }
 
-static gboolean store_data(struct btd_adapter *adapter, struct oob_data *data)
+static gboolean store_data(struct btd_adapter *adapter, const char *address,
+				struct oob_data *data)
 {
 	bdaddr_t bdaddr;
+	struct btd_device *device;
 
 	str2ba(data->addr, &bdaddr);
 
@@ -203,13 +205,14 @@ static gboolean store_data(struct btd_adapter *adapter, struct oob_data *data)
 			return FALSE;
 	}
 
+	device = adapter_get_device(adapter, address);
+
 	if (data->class)
 		write_remote_class(adapter_get_address(adapter), &bdaddr,
 								data->class);
 
 	if (data->name)
-		write_device_name(adapter_get_address(adapter), &bdaddr, 0,
-								data->name);
+		device_set_name(device, data->name);
 
 	return TRUE;
 }
@@ -245,7 +248,7 @@ static DBusMessage *add_remote_data(DBusConnection *conn, DBusMessage *msg,
 	if (!parse_data(&data, &remote_data))
 		return btd_error_invalid_args(msg);
 
-	if (!store_data(adapter, &remote_data))
+	if (!store_data(adapter, remote_data.addr, &remote_data))
 		return btd_error_failed(msg, "Request failed");
 
 	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v9 2/5] device: Retrieve name from storage
From: Frédéric Danis @ 2012-10-26 10:08 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1351246097-22285-1-git-send-email-frederic.danis@linux.intel.com>

Try to retrieve name from device info file.
If that fails fall back to the cache and save it to device info file.

When device name is updated, save it.
---
 src/device.c |  102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 101 insertions(+), 1 deletion(-)

diff --git a/src/device.c b/src/device.c
index bc7f8dd..9749bfd 100644
--- a/src/device.c
+++ b/src/device.c
@@ -76,6 +76,9 @@
 #define DISCONNECT_TIMER	2
 #define DISCOVERY_TIMER		2
 
+#define INFO_PATH STORAGEDIR "/%s/%s/info"
+#define CACHE_PATH STORAGEDIR "/%s/cache/%s"
+
 struct btd_disconnect_data {
 	guint id;
 	disconnect_watch watch;
@@ -202,6 +205,36 @@ static uint16_t uuid_list[] = {
 	0
 };
 
+static void store_device_info(struct btd_device *device)
+{
+	GKeyFile *key_file;
+	char filename[PATH_MAX + 1];
+	char adapter_addr[18];
+	char device_addr[18];
+	char *str;
+	gsize length = 0;
+
+	if (device->temporary)
+		return;
+
+	key_file = g_key_file_new();
+
+	g_key_file_set_string(key_file, "General", "Name", device->name);
+
+	ba2str(adapter_get_address(device->adapter), adapter_addr);
+	ba2str(&device->bdaddr, device_addr);
+	snprintf(filename, PATH_MAX, INFO_PATH, adapter_addr, device_addr);
+	filename[PATH_MAX] = '\0';
+
+	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+	str = g_key_file_to_data(key_file, &length, NULL);
+	g_file_set_contents(filename, str, length, NULL);
+	g_free(str);
+
+	g_key_file_free(key_file);
+}
+
 static void browse_request_free(struct browse_req *req)
 {
 	if (req->listener_id)
@@ -1564,6 +1597,70 @@ static void device_set_version(struct btd_device *device, uint16_t value)
 						DEVICE_INTERFACE, "Version");
 }
 
+static char *load_cached_name(struct btd_device *device, const char *local,
+				const gchar *peer)
+{
+	char filename[PATH_MAX + 1];
+	GKeyFile *key_file;
+	char *str = NULL;
+	int len;
+
+	snprintf(filename, PATH_MAX, CACHE_PATH, local, peer);
+	filename[PATH_MAX] = '\0';
+
+	key_file = g_key_file_new();
+
+	if (!g_key_file_load_from_file(key_file, filename, 0, NULL))
+		goto failed;
+
+	str = g_key_file_get_string(key_file, "General", "Name", NULL);
+	if (str) {
+		len = strlen(str);
+		if (len > HCI_MAX_NAME_LENGTH)
+			str[HCI_MAX_NAME_LENGTH] = '\0';
+	}
+
+failed:
+	g_key_file_free(key_file);
+
+	return str;
+}
+
+static void load_info(struct btd_device *device, const gchar *local,
+			const gchar *peer)
+{
+	char filename[PATH_MAX + 1];
+	GKeyFile *key_file;
+	char *str;
+	gboolean store_needed = FALSE;
+
+	snprintf(filename, PATH_MAX, INFO_PATH, local, peer);
+	filename[PATH_MAX] = '\0';
+
+	key_file = g_key_file_new();
+	g_key_file_load_from_file(key_file, filename, 0, NULL);
+
+	/* Load device name from storage info file, if that fails fall back to
+	 * the cache.
+	 */
+	str = g_key_file_get_string(key_file, "General", "Name", NULL);
+	if (str == NULL) {
+		str = load_cached_name(device, local, peer);
+		if (str)
+			store_needed = TRUE;
+	}
+
+	if (str) {
+		strcpy(device->name, str);
+		g_free(str);
+	}
+
+	if (store_needed)
+		store_device_info(device);
+
+	g_key_file_free(key_file);
+}
+
 struct btd_device *device_create(struct btd_adapter *adapter,
 				const gchar *address, uint8_t bdaddr_type)
 {
@@ -1600,7 +1697,8 @@ struct btd_device *device_create(struct btd_adapter *adapter,
 	src = adapter_get_address(adapter);
 	ba2str(src, srcaddr);
 
-	read_device_name(srcaddr, address, bdaddr_type, device->name);
+	load_info(device, srcaddr, address);
+
 	if (read_device_alias(srcaddr, address, bdaddr_type, alias,
 							sizeof(alias)) == 0)
 		device->alias = g_strdup(alias);
@@ -1640,6 +1738,8 @@ void device_set_name(struct btd_device *device, const char *name)
 
 	strncpy(device->name, name, MAX_NAME_LENGTH);
 
+	store_device_info(device);
+
 	g_dbus_emit_property_changed(btd_get_dbus_connection(), device->path,
 						DEVICE_INTERFACE, "Name");
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v9 1/5] doc: Update settings-storage.txt
From: Frédéric Danis @ 2012-10-26 10:08 UTC (permalink / raw)
  To: linux-bluetooth

Device name should be saved in device info file.
---
 doc/settings-storage.txt |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/doc/settings-storage.txt b/doc/settings-storage.txt
index 93184d1..1174d44 100644
--- a/doc/settings-storage.txt
+++ b/doc/settings-storage.txt
@@ -132,6 +132,8 @@ Long term key) related to a remote device.
 
 [General] group contains:
 
+  Name			String		Remote device friendly name
+
   Alias			String		Alias name
 
   Class			String		Device class in hexadecimal,
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v8 5/5] hcitool: Retrieve names from cache directory
From: Frédéric Danis @ 2012-10-26  9:25 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1351243505-20702-1-git-send-email-frederic.danis@linux.intel.com>

---
 Makefile.tools  |    2 +-
 tools/hcitool.c |   31 ++++++++++++++++++++++++++-----
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/Makefile.tools b/Makefile.tools
index ec79cea..f7c85ef 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -28,7 +28,7 @@ tools_hciconfig_LDADD = lib/libbluetooth-private.la
 
 tools_hcitool_SOURCES = tools/hcitool.c src/oui.h src/oui.c \
 						src/textfile.h src/textfile.c
-tools_hcitool_LDADD = lib/libbluetooth-private.la
+tools_hcitool_LDADD = lib/libbluetooth-private.la @GLIB_LIBS@
 
 tools_sdptool_SOURCES = tools/sdptool.c src/sdp-xml.h src/sdp-xml.c
 tools_sdptool_LDADD = lib/libbluetooth-private.la @GLIB_LIBS@
diff --git a/tools/hcitool.c b/tools/hcitool.c
index aefbd68..a05e31f 100644
--- a/tools/hcitool.c
+++ b/tools/hcitool.c
@@ -40,6 +40,8 @@
 #include <sys/socket.h>
 #include <signal.h>
 
+#include <glib.h>
+
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/hci.h>
 #include <bluetooth/hci_lib.h>
@@ -409,13 +411,32 @@ static char *major_classes[] = {
 
 static char *get_device_name(const bdaddr_t *local, const bdaddr_t *peer)
 {
-	char filename[PATH_MAX + 1], addr[18];
+	char filename[PATH_MAX + 1];
+	char local_addr[18], peer_addr[18];
+	GKeyFile *key_file;
+	char *str = NULL;
+	int len;
+
+	ba2str(local, local_addr);
+	ba2str(peer, peer_addr);
+
+	snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local_addr,
+			peer_addr);
+	filename[PATH_MAX] = '\0';
+	key_file = g_key_file_new();
+
+	if (g_key_file_load_from_file(key_file, filename, 0, NULL)) {
+		str = g_key_file_get_string(key_file, "General", "Name", NULL);
+		if (str) {
+			len = strlen(str);
+			if (len > HCI_MAX_NAME_LENGTH)
+				str[HCI_MAX_NAME_LENGTH] = '\0';
+		}
+	}
 
-	ba2str(local, addr);
-	create_name(filename, PATH_MAX, STORAGEDIR, addr, "names");
+	g_key_file_free(key_file);
 
-	ba2str(peer, addr);
-	return textfile_get(filename, addr);
+	return str;
 }
 
 /* Display local devices */
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v8 4/5] input: Retrieve device name from device object
From: Frédéric Danis @ 2012-10-26  9:25 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1351243505-20702-1-git-send-email-frederic.danis@linux.intel.com>

---
 profiles/input/device.c |    9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/profiles/input/device.c b/profiles/input/device.c
index fbc3d6f..108be39 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -777,7 +777,7 @@ static struct input_device *input_device_new(struct btd_device *device,
 {
 	struct btd_adapter *adapter = device_get_adapter(device);
 	struct input_device *idev;
-	char name[249], src_addr[18], dst_addr[18];
+	char name[HCI_MAX_NAME_LENGTH + 1];
 
 	idev = g_new0(struct input_device, 1);
 	bacpy(&idev->src, adapter_get_address(adapter));
@@ -787,11 +787,8 @@ static struct input_device *input_device_new(struct btd_device *device,
 	idev->handle = handle;
 	idev->disable_sdp = disable_sdp;
 
-	ba2str(&idev->src, src_addr);
-	ba2str(&idev->dst, dst_addr);
-
-	if (read_device_name(src_addr, dst_addr, device_get_addr_type(device),
-				name) == 0)
+	device_get_name(device, name, HCI_MAX_NAME_LENGTH);
+	if (strlen(name) > 0)
 		idev->name = g_strdup(name);
 
 	if (g_dbus_register_interface(btd_get_dbus_connection(),
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v8 3/5] dbusoob: Set device name in device object
From: Frédéric Danis @ 2012-10-26  9:25 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1351243505-20702-1-git-send-email-frederic.danis@linux.intel.com>

---
 plugins/dbusoob.c |   11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/plugins/dbusoob.c b/plugins/dbusoob.c
index 5c5b6ef..82cd304 100644
--- a/plugins/dbusoob.c
+++ b/plugins/dbusoob.c
@@ -191,9 +191,11 @@ static gboolean parse_data(DBusMessageIter *data, struct oob_data *remote_data)
 	return TRUE;
 }
 
-static gboolean store_data(struct btd_adapter *adapter, struct oob_data *data)
+static gboolean store_data(struct btd_adapter *adapter, const char *address,
+				struct oob_data *data)
 {
 	bdaddr_t bdaddr;
+	struct btd_device *device;
 
 	str2ba(data->addr, &bdaddr);
 
@@ -203,13 +205,14 @@ static gboolean store_data(struct btd_adapter *adapter, struct oob_data *data)
 			return FALSE;
 	}
 
+	device = adapter_get_device(adapter, address);
+
 	if (data->class)
 		write_remote_class(adapter_get_address(adapter), &bdaddr,
 								data->class);
 
 	if (data->name)
-		write_device_name(adapter_get_address(adapter), &bdaddr, 0,
-								data->name);
+		device_set_name(device, data->name);
 
 	return TRUE;
 }
@@ -245,7 +248,7 @@ static DBusMessage *add_remote_data(DBusConnection *conn, DBusMessage *msg,
 	if (!parse_data(&data, &remote_data))
 		return btd_error_invalid_args(msg);
 
-	if (!store_data(adapter, &remote_data))
+	if (!store_data(adapter, remote_data.addr, &remote_data))
 		return btd_error_failed(msg, "Request failed");
 
 	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v8 2/5] device: Retrieve name from storage
From: Frédéric Danis @ 2012-10-26  9:25 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1351243505-20702-1-git-send-email-frederic.danis@linux.intel.com>

Try to retrieve name from device info file.
If that fails fall back to the cache and save it to device info file.

When device name is updated, save it.
---
 src/device.c |   99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 98 insertions(+), 1 deletion(-)

diff --git a/src/device.c b/src/device.c
index bc7f8dd..d27fd31 100644
--- a/src/device.c
+++ b/src/device.c
@@ -76,6 +76,9 @@
 #define DISCONNECT_TIMER	2
 #define DISCOVERY_TIMER		2
 
+#define INFO_PATH STORAGEDIR "/%s/%s/info"
+#define CACHE_PATH STORAGEDIR "/%s/cache/%s"
+
 struct btd_disconnect_data {
 	guint id;
 	disconnect_watch watch;
@@ -202,6 +205,33 @@ static uint16_t uuid_list[] = {
 	0
 };
 
+static void store_device_info(struct btd_device *device)
+{
+	GKeyFile *key_file;
+	char filename[PATH_MAX + 1];
+	char adapter_addr[18];
+	char device_addr[18];
+	char *str;
+	gsize length = 0;
+
+	key_file = g_key_file_new();
+
+	g_key_file_set_string(key_file, "General", "Name", device->name);
+
+	ba2str(adapter_get_address(device->adapter), adapter_addr);
+	ba2str(&device->bdaddr, device_addr);
+	snprintf(filename, PATH_MAX, INFO_PATH, adapter_addr, device_addr);
+	filename[PATH_MAX] = '\0';
+
+	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+	str = g_key_file_to_data(key_file, &length, NULL);
+	g_file_set_contents(filename, str, length, NULL);
+	g_free(str);
+
+	g_key_file_free(key_file);
+}
+
 static void browse_request_free(struct browse_req *req)
 {
 	if (req->listener_id)
@@ -1564,6 +1594,70 @@ static void device_set_version(struct btd_device *device, uint16_t value)
 						DEVICE_INTERFACE, "Version");
 }
 
+static char *load_cached_name(struct btd_device *device, const char *local,
+				const gchar *peer)
+{
+	char filename[PATH_MAX + 1];
+	GKeyFile *key_file;
+	char *str = NULL;
+	int len;
+
+	snprintf(filename, PATH_MAX, CACHE_PATH, local, peer);
+	filename[PATH_MAX] = '\0';
+
+	key_file = g_key_file_new();
+
+	if (!g_key_file_load_from_file(key_file, filename, 0, NULL))
+		goto failed;
+
+	str = g_key_file_get_string(key_file, "General", "Name", NULL);
+	if (str) {
+		len = strlen(str);
+		if (len > HCI_MAX_NAME_LENGTH)
+			str[HCI_MAX_NAME_LENGTH] = '\0';
+	}
+
+failed:
+	g_key_file_free(key_file);
+
+	return str;
+}
+
+static void load_info(struct btd_device *device, const gchar *local,
+			const gchar *peer)
+{
+	char filename[PATH_MAX + 1];
+	GKeyFile *key_file;
+	char *str;
+	gboolean store_needed = FALSE;
+
+	snprintf(filename, PATH_MAX, INFO_PATH, local, peer);
+	filename[PATH_MAX] = '\0';
+
+	key_file = g_key_file_new();
+	g_key_file_load_from_file(key_file, filename, 0, NULL);
+
+	/* Load device name from storage info file, if that fails fall back to
+	 * the cache.
+	 */
+	str = g_key_file_get_string(key_file, "General", "Name", NULL);
+	if (str == NULL) {
+		str = load_cached_name(device, local, peer);
+		if (str)
+			store_needed = TRUE;
+	}
+
+	if (str) {
+		strcpy(device->name, str);
+		g_free(str);
+	}
+
+	if (store_needed)
+		store_device_info(device);
+
+	g_key_file_free(key_file);
+}
+
 struct btd_device *device_create(struct btd_adapter *adapter,
 				const gchar *address, uint8_t bdaddr_type)
 {
@@ -1600,7 +1694,8 @@ struct btd_device *device_create(struct btd_adapter *adapter,
 	src = adapter_get_address(adapter);
 	ba2str(src, srcaddr);
 
-	read_device_name(srcaddr, address, bdaddr_type, device->name);
+	load_info(device, srcaddr, address);
+
 	if (read_device_alias(srcaddr, address, bdaddr_type, alias,
 							sizeof(alias)) == 0)
 		device->alias = g_strdup(alias);
@@ -1640,6 +1735,8 @@ void device_set_name(struct btd_device *device, const char *name)
 
 	strncpy(device->name, name, MAX_NAME_LENGTH);
 
+	store_device_info(device);
+
 	g_dbus_emit_property_changed(btd_get_dbus_connection(), device->path,
 						DEVICE_INTERFACE, "Name");
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v8 1/5] doc: Update settings-storage.txt
From: Frédéric Danis @ 2012-10-26  9:25 UTC (permalink / raw)
  To: linux-bluetooth

Device name should be saved in device info file.
---
 doc/settings-storage.txt |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/doc/settings-storage.txt b/doc/settings-storage.txt
index 93184d1..1174d44 100644
--- a/doc/settings-storage.txt
+++ b/doc/settings-storage.txt
@@ -132,6 +132,8 @@ Long term key) related to a remote device.
 
 [General] group contains:
 
+  Name			String		Remote device friendly name
+
   Alias			String		Alias name
 
   Class			String		Device class in hexadecimal,
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH BlueZ v3] AVDTP: Do not keep a internal reference
From: Luiz Augusto von Dentz @ 2012-10-26  8:30 UTC (permalink / raw)
  To: linux-bluetooth

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

Don't initialize reference with 1, instead always start disconnect timer
when reference drops to 0, so in case nobody reclaims the session it
automatically disconnect after 1 second and frees the memory.
---
v2: Fix with stream_setup flag being ignored in disconnect_timeout
v3: Do avrcp_free on connection_lost to avoid having dangling sessions in
disconnected state waiting the timeout to be freed.

 audio/avdtp.c | 211 +++++++++++++++++++++++++---------------------------------
 1 file changed, 89 insertions(+), 122 deletions(-)

diff --git a/audio/avdtp.c b/audio/avdtp.c
index bd91cb6..9a5dbe6 100644
--- a/audio/avdtp.c
+++ b/audio/avdtp.c
@@ -387,8 +387,7 @@ struct avdtp_stream {
 /* Structure describing an AVDTP connection between two devices */
 
 struct avdtp {
-	int ref;
-	int free_lock;
+	unsigned int ref;
 
 	uint16_t version;
 
@@ -657,50 +656,6 @@ static gboolean stream_open_timeout(gpointer user_data)
 	return FALSE;
 }
 
-static gboolean disconnect_timeout(gpointer user_data)
-{
-	struct avdtp *session = user_data;
-	struct audio_device *dev;
-	gboolean stream_setup;
-
-	session->dc_timer = 0;
-	stream_setup = session->stream_setup;
-	session->stream_setup = FALSE;
-
-	dev = manager_get_device(&session->server->src, &session->dst, FALSE);
-
-	if (dev && dev->sink && stream_setup)
-		sink_setup_stream(dev->sink, session);
-	else if (dev && dev->source && stream_setup)
-		source_setup_stream(dev->source, session);
-	else
-		connection_lost(session, ETIMEDOUT);
-
-	return FALSE;
-}
-
-static void remove_disconnect_timer(struct avdtp *session)
-{
-	g_source_remove(session->dc_timer);
-	session->dc_timer = 0;
-	session->stream_setup = FALSE;
-}
-
-static void set_disconnect_timer(struct avdtp *session)
-{
-	if (session->dc_timer)
-		remove_disconnect_timer(session);
-
-	if (session->device_disconnect) {
-		session->dc_timer = g_idle_add(disconnect_timeout, session);
-		return;
-	}
-
-	session->dc_timer = g_timeout_add_seconds(DISCONNECT_TIMEOUT,
-						disconnect_timeout,
-						session);
-}
-
 void avdtp_error_init(struct avdtp_error *err, uint8_t category, int id)
 {
 	err->category = category;
@@ -780,8 +735,9 @@ static void avdtp_set_state(struct avdtp *session,
 	}
 }
 
-static void stream_free(struct avdtp_stream *stream)
+static void stream_free(void *data)
 {
+	struct avdtp_stream *stream = data;
 	struct avdtp_remote_sep *rsep;
 
 	stream->lsep->info.inuse = 0;
@@ -1144,37 +1100,39 @@ static int avdtp_cancel_authorization(struct avdtp *session)
 		return err;
 
 	session->auth_id = 0;
+	avdtp_unref(session);
 
 	return 0;
 }
 
-static void connection_lost(struct avdtp *session, int err)
+static void sep_free(gpointer data)
 {
-	char address[18];
-
-	ba2str(&session->dst, address);
-	DBG("Disconnected from %s", address);
+	struct avdtp_remote_sep *sep = data;
 
-	if (err != EACCES)
-		avdtp_cancel_authorization(session);
+	g_slist_free_full(sep->caps, g_free);
+	g_free(sep);
+}
 
-	session->free_lock = 1;
+static void remove_disconnect_timer(struct avdtp *session)
+{
+	g_source_remove(session->dc_timer);
+	session->dc_timer = 0;
+	session->stream_setup = FALSE;
+}
 
-	finalize_discovery(session, err);
+static void avdtp_free(void *data)
+{
+	struct avdtp *session = data;
 
-	g_slist_foreach(session->streams, (GFunc) release_stream, session);
-	session->streams = NULL;
+	DBG("%p", session);
 
-	session->free_lock = 0;
+	g_slist_free_full(session->streams, stream_free);
 
 	if (session->io) {
 		g_io_channel_shutdown(session->io, FALSE, NULL);
 		g_io_channel_unref(session->io);
-		session->io = NULL;
 	}
 
-	avdtp_set_state(session, AVDTP_SESSION_STATE_DISCONNECTED);
-
 	if (session->io_id) {
 		g_source_remove(session->io_id);
 		session->io_id = 0;
@@ -1183,69 +1141,91 @@ static void connection_lost(struct avdtp *session, int err)
 	if (session->dc_timer)
 		remove_disconnect_timer(session);
 
-	if (session->ref != 1)
-		error("connection_lost: ref count not 1 after all callbacks");
-	else
-		avdtp_unref(session);
+	if (session->req)
+		pending_req_free(session->req);
+
+	g_slist_free_full(session->seps, sep_free);
+
+	g_free(session->buf);
+
+	g_free(session);
 }
 
-static void sep_free(gpointer data)
+static gboolean disconnect_timeout(gpointer user_data)
 {
-	struct avdtp_remote_sep *sep = data;
+	struct avdtp *session = user_data;
+	struct audio_device *dev;
+	gboolean stream_setup;
 
-	g_slist_free_full(sep->caps, g_free);
-	g_free(sep);
+	session->dc_timer = 0;
+
+	stream_setup = session->stream_setup;
+	session->stream_setup = FALSE;
+	dev = manager_get_device(&session->server->src, &session->dst, FALSE);
+
+	if (dev && dev->sink && stream_setup)
+		sink_setup_stream(dev->sink, session);
+	else if (dev && dev->source && stream_setup)
+		source_setup_stream(dev->source, session);
+	else
+		connection_lost(session, ETIMEDOUT);
+
+	return FALSE;
 }
 
-void avdtp_unref(struct avdtp *session)
+static void set_disconnect_timer(struct avdtp *session)
 {
-	struct avdtp_server *server;
+	if (session->dc_timer)
+		remove_disconnect_timer(session);
 
-	if (!session)
+	if (session->device_disconnect) {
+		session->dc_timer = g_idle_add(disconnect_timeout, session);
 		return;
+	}
 
-	session->ref--;
+	session->dc_timer = g_timeout_add_seconds(DISCONNECT_TIMEOUT,
+						disconnect_timeout,
+						session);
+}
 
-	DBG("%p: ref=%d", session, session->ref);
+static void connection_lost(struct avdtp *session, int err)
+{
+	struct avdtp_server *server = session->server;
+	char address[18];
 
-	if (session->ref == 1) {
-		if (session->state == AVDTP_SESSION_STATE_CONNECTING &&
-								session->io) {
-			avdtp_cancel_authorization(session);
-			g_io_channel_shutdown(session->io, TRUE, NULL);
-			g_io_channel_unref(session->io);
-			session->io = NULL;
-			avdtp_set_state(session,
-					AVDTP_SESSION_STATE_DISCONNECTED);
-		}
+	ba2str(&session->dst, address);
+	DBG("Disconnected from %s", address);
 
-		if (session->io)
-			set_disconnect_timer(session);
-		else if (!session->free_lock) /* Drop the local ref if we
-						 aren't connected */
-			session->ref--;
-	}
+	if (err != EACCES)
+		avdtp_cancel_authorization(session);
 
-	if (session->ref > 0)
-		return;
+	g_slist_foreach(session->streams, (GFunc) release_stream, session);
+	session->streams = NULL;
 
-	server = session->server;
+	finalize_discovery(session, err);
 
-	DBG("%p: freeing session and removing from list", session);
+	avdtp_set_state(session, AVDTP_SESSION_STATE_DISCONNECTED);
 
-	if (session->dc_timer)
-		remove_disconnect_timer(session);
+	if (session->ref > 0)
+		return;
 
 	server->sessions = g_slist_remove(server->sessions, session);
+	avdtp_free(session);
+}
 
-	if (session->req)
-		pending_req_free(session->req);
+void avdtp_unref(struct avdtp *session)
+{
+	if (!session)
+		return;
 
-	g_slist_free_full(session->seps, sep_free);
+	session->ref--;
 
-	g_free(session->buf);
+	DBG("%p: ref=%d", session, session->ref);
 
-	g_free(session);
+	if (session->ref > 0)
+		return;
+
+	set_disconnect_timer(session);
 }
 
 struct avdtp *avdtp_ref(struct avdtp *session)
@@ -2231,12 +2211,6 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
 			goto failed;
 		}
 
-		if (session->ref == 1 && !session->streams && !session->req)
-			set_disconnect_timer(session);
-
-		if (session->streams && session->dc_timer)
-			remove_disconnect_timer(session);
-
 		if (session->req && session->req->collided) {
 			DBG("Collision detected");
 			goto next;
@@ -2383,7 +2357,7 @@ static struct avdtp *avdtp_get_internal(const bdaddr_t *src, const bdaddr_t *dst
 
 	session->server = server;
 	bacpy(&session->dst, dst);
-	session->ref = 1;
+	set_disconnect_timer(session);
 	/* We don't use avdtp_set_state() here since this isn't a state change
 	 * but just setting of the initial state */
 	session->state = AVDTP_SESSION_STATE_DISCONNECTED;
@@ -2490,6 +2464,8 @@ static void auth_cb(DBusError *derr, void *user_data)
 	struct avdtp *session = user_data;
 	GError *err = NULL;
 
+	avdtp_unref(session);
+
 	if (derr && dbus_error_is_set(derr)) {
 		error("Access denied: %s", derr->message);
 		connection_lost(session, EACCES);
@@ -2578,10 +2554,12 @@ static void avdtp_confirm_cb(GIOChannel *chan, gpointer data)
 							auth_cb, session);
 	if (session->auth_id == 0) {
 		avdtp_set_state(session, AVDTP_SESSION_STATE_DISCONNECTED);
-		avdtp_unref(session);
 		goto drop;
 	}
 
+	/* Disable disconnect timer while authorizing */
+	avdtp_ref(session);
+
 	dev->auto_connect = auto_connect;
 
 	return;
@@ -3949,23 +3927,12 @@ proceed:
 void avdtp_exit(const bdaddr_t *src)
 {
 	struct avdtp_server *server;
-	GSList *l;
 
 	server = find_server(servers, src);
 	if (!server)
 		return;
 
-	l = server->sessions;
-	while (l) {
-		struct avdtp *session = l->data;
-
-		l = l->next;
-		/* value of l pointer should be updated before invoking
-		 * connection_lost since it internally uses avdtp_unref
-		 * which operates on server->session list as well
-		 */
-		connection_lost(session, -ECONNABORTED);
-	}
+	g_slist_free_full(server->sessions, avdtp_free);
 
 	servers = g_slist_remove(servers, server);
 
-- 
1.7.11.7


^ permalink raw reply related

* Re: [PATCH BlueZ] core: Fix memory leak
From: Johan Hedberg @ 2012-10-26  8:01 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1351238216-7583-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Fri, Oct 26, 2012, Luiz Augusto von Dentz wrote:
> 1,262 (64 direct, 1,198 indirect) bytes in 1 blocks are definitely lost in loss record 280 of 290
>    at 0x4A0881C: malloc (vg_replace_malloc.c:270)
>    by 0x4C813FE: g_malloc (in /usr/lib64/libglib-2.0.so.0.3200.4)
>    by 0x4C95801: g_slice_alloc (in /usr/lib64/libglib-2.0.so.0.3200.4)
>    by 0x4C95D55: g_slice_alloc0 (in /usr/lib64/libglib-2.0.so.0.3200.4)
>    by 0x4C746AA: g_key_file_new (in /usr/lib64/libglib-2.0.so.0.3200.4)
>    by 0x18136C: load_config (adapter.c:2620)
>    by 0x18353B: adapter_init (adapter.c:2708)
>    by 0x17E62E: btd_manager_register_adapter (manager.c:337)
>    by 0x191171: mgmt_event.part.36 (mgmt.c:1081)
>    by 0x4C7B824: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3200.4)
>    by 0x4C7BB57: ??? (in /usr/lib64/libglib-2.0.so.0.3200.4)
>    by 0x4C7BF51: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3200.4)
> ---
>  src/adapter.c | 2 ++
>  1 file changed, 2 insertions(+)

Applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH v0] network: Remove unnecessary field from connect_req
From: Johan Hedberg @ 2012-10-26  8:00 UTC (permalink / raw)
  To: Mikel Astiz; +Cc: linux-bluetooth, Mikel Astiz
In-Reply-To: <1351230929-4484-1-git-send-email-mikel.astiz.oss@gmail.com>

Hi Mikel,

On Fri, Oct 26, 2012, Mikel Astiz wrote:
> The device pointer in struct connect_req can be completely removed since
> the callback already receives such pointer, and the network_peer takes
> care of the device refcounting.
> ---
>  profiles/network/manager.c | 7 +------
>  1 file changed, 1 insertion(+), 6 deletions(-)

Applied. Thanks.

Johan

^ permalink raw reply

* [PATCH BlueZ] core: Fix memory leak
From: Luiz Augusto von Dentz @ 2012-10-26  7:56 UTC (permalink / raw)
  To: linux-bluetooth

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

1,262 (64 direct, 1,198 indirect) bytes in 1 blocks are definitely lost in loss record 280 of 290
   at 0x4A0881C: malloc (vg_replace_malloc.c:270)
   by 0x4C813FE: g_malloc (in /usr/lib64/libglib-2.0.so.0.3200.4)
   by 0x4C95801: g_slice_alloc (in /usr/lib64/libglib-2.0.so.0.3200.4)
   by 0x4C95D55: g_slice_alloc0 (in /usr/lib64/libglib-2.0.so.0.3200.4)
   by 0x4C746AA: g_key_file_new (in /usr/lib64/libglib-2.0.so.0.3200.4)
   by 0x18136C: load_config (adapter.c:2620)
   by 0x18353B: adapter_init (adapter.c:2708)
   by 0x17E62E: btd_manager_register_adapter (manager.c:337)
   by 0x191171: mgmt_event.part.36 (mgmt.c:1081)
   by 0x4C7B824: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3200.4)
   by 0x4C7BB57: ??? (in /usr/lib64/libglib-2.0.so.0.3200.4)
   by 0x4C7BF51: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3200.4)
---
 src/adapter.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/adapter.c b/src/adapter.c
index c7b8c7f..54b1a64 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2684,6 +2684,8 @@ static void load_config(struct btd_adapter *adapter)
 	mgmt_set_connectable(adapter->dev_id, TRUE);
 	mgmt_set_discoverable(adapter->dev_id, adapter->discoverable,
 				adapter->discov_timeout);
+
+	g_key_file_free(key_file);
 }
 
 gboolean adapter_init(struct btd_adapter *adapter, gboolean up)
-- 
1.7.11.7


^ permalink raw reply related


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