Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH v2 0/7] Move adapter config file to ini-file format
From: Frédéric Danis @ 2012-10-10  8:58 UTC (permalink / raw)
  To: linux-bluetooth

Adapter saved configuration will be saved to /var/lib/bluetooth/<adapter address>/settings
in ini-file format for BlueZ 5.
If this file does not exist, we try to convert legacy config file to it.

Access to variables during run-time is performed in adapter structure which is populated by loading saved configuration during initialization.

First 6 patches remove access to config file from run-time.
Last patch move to ini-file format style (load, save and convert).

Frédéric Danis (7):
  adapter: Read name in storage at init
  adapter: Read device class in storage at init
  adapter: Move pairable read to load_config()
  adapter: Read pairable timeout in storage at init
  adapter: Read discoverable timeout in storage at init
  adapter: Read mode in storage at init
  adapter: Move saved config to ini-file format

 TODO                  |    6 +
 plugins/adaptername.c |    9 +-
 src/adapter.c         |  330 ++++++++++++++++++++++++++++++++++++++-----------
 src/adapter.h         |    1 +
 4 files changed, 268 insertions(+), 78 deletions(-)

-- 
1.7.9.5


^ permalink raw reply

* Re: [RFCv1 3/6] Bluetooth: AMP: Add handle to hci_chan structure
From: Andrei Emeltchenko @ 2012-10-10  8:34 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1349793991.27233.91.camel@aeonflux>

Hi Marcel,

On Tue, Oct 09, 2012 at 04:46:31PM +0200, Marcel Holtmann wrote:
...
> > -
> > +struct hci_chan *hci_chan_lookup_handle(struct hci_conn *hcon, __u16 handle);
> > +struct hci_chan *hci_chan_lookup_handle_all(struct hci_dev *hdev,
> > +					    __u16 handle);
> 
> this naming is pretty bad. I have no idea what one function does
> different compared to the other. Especially since none of them take a
> hci_chan as argument, but start with that prefix.
> 
> Would be the naming hci_conn_lookup_chan be a lot clearer? Or maybe
> hci_chan_lookup_from_dev or similar.

So are names like:

hci_conn_lookup_hchan_by_handle
hci_conn_lookup_hchan_from_hdev

better?

...
> > +struct hci_chan *hci_chan_lookup_handle(struct hci_conn *hcon, __u16 handle)
> > +{
> > +	struct hci_chan *hchan;
> > +
> > +	list_for_each_entry(hchan, &hcon->chan_list, list) {
> > +		if (hchan->handle == handle)
> > +			return hchan;
> > +	}
> > +
> > +	return NULL;
> > +}
> 
> Since this function is unprotected, you better make this __hci_....
> 
> And on a different note. It is not used at all. So why is this public
> anyway?

I will make it static.

...
> > +	rcu_read_lock();
> > +
> > +	list_for_each_entry_rcu(hcon, &h->list, list) {
> > +		struct hci_chan *hchan;
> > +
> > +		hchan = hci_chan_lookup_handle(hcon, handle);
> > +		if (hchan) {
> > +			rcu_read_unlock();
> > +			return hchan;
> 
> Please use break here. Have a global hchan variable assigned to NULL and
> just break here.

OK.

Best regards 
Andrei Emeltchenko 

^ permalink raw reply

* Re: [RFCv1 4/6] Bluetooth: Handle number of compl blocks for AMP_LINK
From: Andrei Emeltchenko @ 2012-10-10  8:22 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1349794158.27233.94.camel@aeonflux>

Hi Marcel,

On Tue, Oct 09, 2012 at 04:49:18PM +0200, Marcel Holtmann wrote:
> Hi Andrei,
> 
> > Add handling blocks count for AMP link.
> > 
> > Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> > ---
> >  net/bluetooth/hci_event.c |   12 ++++++++++--
> >  1 file changed, 10 insertions(+), 2 deletions(-)
> > 
> > diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> > index 82e478a..c479732 100644
> > --- a/net/bluetooth/hci_event.c
> > +++ b/net/bluetooth/hci_event.c
> > @@ -2698,13 +2698,21 @@ static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
> >  
> >  	for (i = 0; i < ev->num_hndl; i++) {
> >  		struct hci_comp_blocks_info *info = &ev->handles[i];
> > -		struct hci_conn *conn;
> > +		struct hci_conn *conn = NULL;
> > +		struct hci_chan *chan;
> >  		__u16  handle, block_count;
> >  
> >  		handle = __le16_to_cpu(info->handle);
> >  		block_count = __le16_to_cpu(info->blocks);
> >  
> > -		conn = hci_conn_hash_lookup_handle(hdev, handle);
> > +		if (hdev->dev_type == HCI_BREDR) {
> > +			conn = hci_conn_hash_lookup_handle(hdev, handle);
> > +		} else {
> > +			chan = hci_chan_lookup_handle_all(hdev, handle);
> > +			if (chan)
> > +				conn = chan->conn;
> 
> Just in case, we better use a switch statement here.
> 
> And now coming to think about it, do we ever need the hci_chan anyway.

For AMP hchan represents logical link so it is needed.

> Then why not have a function that looks up the hci_conn.
> 
> Maybe introduce a new hci_conn_lookup_handle(hdev, handle) and it will
> do the right thing depending on what the device type is.

This looks good, will do this way.

Best regards 
Andrei Emeltchenko 

^ permalink raw reply

* Re: [PATCH v3 1/5] audio: Add check for vendor specific A2DP codec
From: Luiz Augusto von Dentz @ 2012-10-09 21:33 UTC (permalink / raw)
  To: chanyeol.park; +Cc: linux-bluetooth
In-Reply-To: <1349782548-27923-1-git-send-email-chanyeol.park@samsung.com>

Hi Chanyeol,

On Tue, Oct 9, 2012 at 1:35 PM,  <chanyeol.park@samsung.com> wrote:
> From: Chan-yeol Park <chanyeol.park@samsung.com>
>
> This patch adds checks(vendor ID, vendor specific codec ID) to make sure of
> vendor specific A2DP codec selection.
> ---
>  audio/a2dp-codecs.h |    6 +++++
>  audio/a2dp.c        |   64 ++++++++++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 69 insertions(+), 1 deletion(-)
>
> diff --git a/audio/a2dp-codecs.h b/audio/a2dp-codecs.h
> index 51c796a..2afafa5 100644
> --- a/audio/a2dp-codecs.h
> +++ b/audio/a2dp-codecs.h
> @@ -26,6 +26,7 @@
>  #define A2DP_CODEC_MPEG12              0x01
>  #define A2DP_CODEC_MPEG24              0x02
>  #define A2DP_CODEC_ATRAC               0x03
> +#define A2DP_CODEC_VENDOR              0xFF
>
>  #define SBC_SAMPLING_FREQ_16000                (1 << 3)
>  #define SBC_SAMPLING_FREQ_32000                (1 << 2)
> @@ -114,3 +115,8 @@ typedef struct {
>  #else
>  #error "Unknown byte order"
>  #endif
> +
> +typedef struct {
> +       uint8_t vendor_id[4];
> +       uint8_t codec_id[2];
> +} __attribute__ ((packed)) a2dp_vendor_codec_t;
> diff --git a/audio/a2dp.c b/audio/a2dp.c
> index fd1c494..2c9251a 100644
> --- a/audio/a2dp.c
> +++ b/audio/a2dp.c
> @@ -44,6 +44,7 @@
>  #include "sink.h"
>  #include "source.h"
>  #include "a2dp.h"
> +#include "a2dp-codecs.h"
>  #include "sdpd.h"
>
>  /* The duration that streams without users are allowed to stay in
> @@ -1427,11 +1428,62 @@ done:
>         finalize_select(setup);
>  }
>
> +static gboolean vendor_codec_is_matched(uint8_t *remote_cap,
> +                               size_t remote_cap_len, struct a2dp_sep *sep)
> +{
> +       uint8_t *capabilities;
> +       size_t  length;
> +
> +       a2dp_vendor_codec_t *local_codec;
> +       a2dp_vendor_codec_t *remote_codec;
> +
> +       if (remote_cap_len < sizeof(a2dp_vendor_codec_t))
> +               return FALSE;
> +
> +       remote_codec = (a2dp_vendor_codec_t *) remote_cap;
> +
> +       DBG("Remote vendor 0x%02x%02x%02x%02x codec 0x%02x%02x",
> +                       remote_codec->vendor_id[0], remote_codec->vendor_id[1],
> +                       remote_codec->vendor_id[2], remote_codec->vendor_id[3],
> +                       remote_codec->codec_id[0], remote_codec->codec_id[1]);
> +
> +       if (sep->endpoint == NULL)
> +               return FALSE;
> +
> +       length = sep->endpoint->get_capabilities(sep,
> +                               &capabilities, sep->user_data);
> +
> +       if (length < sizeof(a2dp_vendor_codec_t))
> +               return FALSE;
> +
> +       local_codec = (a2dp_vendor_codec_t *) capabilities;
> +
> +       DBG("Registered vendor 0x%02x%02x%02x%02x codec 0x%02x%02x",
> +                       local_codec->vendor_id[0], local_codec->vendor_id[1],
> +                       local_codec->vendor_id[2], local_codec->vendor_id[3],
> +                       local_codec->codec_id[0], local_codec->codec_id[1]);
> +
> +       if (memcmp(remote_codec->vendor_id, local_codec->vendor_id,
> +                                       sizeof(local_codec->vendor_id)))
> +               return FALSE;
> +
> +       if (memcmp(remote_codec->codec_id, local_codec->codec_id,
> +                                       sizeof(local_codec->codec_id)))
> +               return FALSE;
> +
> +       DBG("Vendor Codec info is matched");
> +
> +       return TRUE;
> +}
> +
>  static struct a2dp_sep *a2dp_find_sep(struct avdtp *session, GSList *list,
>                                         const char *sender)
>  {
>         for (; list; list = list->next) {
>                 struct a2dp_sep *sep = list->data;
> +               struct avdtp_remote_sep *rsep;
> +               struct avdtp_media_codec_capability *rsep_codec;
> +               struct avdtp_service_capability *service;
>
>                 /* Use sender's endpoint if available */
>                 if (sender) {
> @@ -1445,7 +1497,17 @@ static struct a2dp_sep *a2dp_find_sep(struct avdtp *session, GSList *list,
>                                 continue;
>                 }
>
> -               if (avdtp_find_remote_sep(session, sep->lsep) == NULL)
> +               rsep = avdtp_find_remote_sep(session, sep->lsep);
> +               if (rsep == NULL)
> +                       continue;
> +
> +               service = avdtp_get_codec(rsep);
> +               rsep_codec = (struct avdtp_media_codec_capability *)
> +                                                               service->data;
> +
> +               if (rsep_codec->media_codec_type == A2DP_CODEC_VENDOR &&
> +                       !vendor_codec_is_matched(rsep_codec->data,
> +                               service->length - sizeof(*rsep_codec), sep))
>                         continue;
>
>                 return sep;
> --
> 1.7.9.5

All 5 patches are now upstream,  I hope you don't mind but I did some
minor changes before pushing so we only print the vendor and codec
when it matches and other small tweaks to avoid too much indentation
which should make the code easier to read.

-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH BlueZ] build-sys: Remove leftover AM_YFLAGS
From: Johan Hedberg @ 2012-10-09 21:18 UTC (permalink / raw)
  To: Lucas De Marchi; +Cc: linux-bluetooth
In-Reply-To: <1349805077-30412-1-git-send-email-lucas.demarchi@profusion.mobi>

Hi Lucas,

On Tue, Oct 09, 2012, Lucas De Marchi wrote:
> ---
>  Makefile.am | 2 --
>  1 file changed, 2 deletions(-)

Applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH BlueZ] core: fix stop scanning after GCEP
From: Johan Hedberg @ 2012-10-09 21:15 UTC (permalink / raw)
  To: João Paulo Rechi Vita; +Cc: linux-bluetooth
In-Reply-To: <1349804307-20318-1-git-send-email-jprvita@openbossa.org>

Hi João Paulo,

On Tue, Oct 09, 2012, João Paulo Rechi Vita wrote:
> The session type identification on struct session req (commit 328661a0)
> broke the stop condition of the LE Genereal Connection Establishment
> Procedure. This commit creates new identificators for discovery sessions
> and makes their naming a bit more clear.
> ---
>  src/adapter.c | 26 +++++++++++++++-----------
>  1 file changed, 15 insertions(+), 11 deletions(-)

Applied. Thanks.

Johan

^ permalink raw reply

* Re: [RFC obexd 02/11] build: Add --enable-fuse for gobexfuse
From: Marcel Holtmann @ 2012-10-09 18:34 UTC (permalink / raw)
  To: Michał Poczwardowski; +Cc: linux-bluetooth
In-Reply-To: <1349806556-1978-2-git-send-email-dmp0x7c5@gmail.com>

Hi Michal,

>  Makefile.am  |    9 +++++++++
>  configure.ac |   15 +++++++++++++++
>  2 files changed, 24 insertions(+), 0 deletions(-)
> 
> diff --git a/Makefile.am b/Makefile.am
> index 724dd5d..95b99a6 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -132,6 +132,15 @@ client_obex_client_SOURCES = $(gdbus_sources) $(gobex_sources) \
>  client_obex_client_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@
>  endif
>  
> +if FUSE
> +bin_PROGRAMS = fuse/gobexfuse

I rather call this obexfuse or similar. I don't want to have any "g"
prefixes in the future anymore.

Regards

Marcel



^ permalink raw reply

* [RFC obexd 11/11] fuse: Add rename operation
From: Michał Poczwardowski @ 2012-10-09 18:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Michał Poczwardowski
In-Reply-To: <1349806556-1978-1-git-send-email-dmp0x7c5@gmail.com>

---
 fuse/gobexfuse.c |   16 ++++++++++++++++
 fuse/helpers.c   |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 fuse/helpers.h   |    3 +++
 3 files changed, 65 insertions(+), 0 deletions(-)

diff --git a/fuse/gobexfuse.c b/fuse/gobexfuse.c
index c45d056..2f6a7c0 100644
--- a/fuse/gobexfuse.c
+++ b/fuse/gobexfuse.c
@@ -237,6 +237,20 @@ static int gobexfuse_unlink(const char *path)
 	return session->status;
 }
 
+static int gobexfuse_mkdir(const char *path, mode_t mode)
+{
+	gobexhlp_mkdir(session, path);
+
+	return session->status;
+}
+
+static int gobexfuse_rename(const char *from, const char *to)
+{
+	gobexhlp_move(session, from, to);
+
+	return session->status;
+}
+
 static struct fuse_operations gobexfuse_oper = {
 	.readdir = gobexfuse_readdir,
 	.getattr = gobexfuse_getattr,
@@ -249,6 +263,8 @@ static struct fuse_operations gobexfuse_oper = {
 	.mknod = gobexfuse_mknod,
 	.unlink = gobexfuse_unlink,
 	.rmdir = gobexfuse_unlink,
+	.mkdir = gobexfuse_mkdir,
+	.rename = gobexfuse_rename,
 	.init = gobexfuse_init,
 	.destroy = gobexfuse_destroy,
 };
diff --git a/fuse/helpers.c b/fuse/helpers.c
index 0ad8cbb..698781a 100644
--- a/fuse/helpers.c
+++ b/fuse/helpers.c
@@ -690,3 +690,49 @@ void gobexhlp_delete(struct gobexhlp_session* session, const char *path)
 	request_wait_free(session);
 }
 
+void gobexhlp_mkdir(struct gobexhlp_session* session, const char *path)
+{
+	struct gobexhlp_location *l;
+	struct stat *stbuf;
+
+	g_print("gobexhlp_mkdir(%s)\n", path);
+
+	l = get_location(path);
+	gobexhlp_setpath(session, l->dir);
+
+	request_new(session, g_strdup_printf("mkdir %s", path));
+	/* g_obex_mkdir also sets path, to new folder */
+	g_obex_mkdir(session->obex, l->file, response_func, session,
+							&session->err);
+	g_free(session->setpath);
+	session->setpath = g_strdup(path);
+
+	stbuf = g_malloc0(sizeof(struct stat));
+	stbuf->st_mode = S_IFDIR;
+	stbuf->st_mtime = time(NULL);
+	g_hash_table_replace(session->file_stat, g_strdup(path), stbuf);
+
+	free_location(l);
+	request_wait_free(session);
+}
+
+void gobexhlp_move(struct gobexhlp_session* session, const char *oldpath,
+						const char* newpath)
+{
+	struct gobexhlp_location *l_from, *l_to;
+
+	l_to = get_location(newpath);
+	l_from = get_location(oldpath);
+	gobexhlp_setpath(session, l_from->dir);
+
+	g_print("gobexhlp_move(%s to %s)\n", l_from->file, l_to->file);
+
+	request_new(session, g_strdup_printf("move %s:%s",
+					oldpath, newpath));
+	g_obex_move(session->obex, l_from->file, l_to->file, response_func,
+						session, &session->err);
+	free_location(l_to);
+	free_location(l_from);
+	request_wait_free(session);
+}
+
diff --git a/fuse/helpers.h b/fuse/helpers.h
index baa6bf1..cc2d9a8 100644
--- a/fuse/helpers.h
+++ b/fuse/helpers.h
@@ -61,4 +61,7 @@ void gobexhlp_put(struct gobexhlp_session* session,
 					const char *path);
 void gobexhlp_touch(struct gobexhlp_session* session, const char *path);
 void gobexhlp_delete(struct gobexhlp_session* session, const char *path);
+void gobexhlp_mkdir(struct gobexhlp_session* session, const char *path);
+void gobexhlp_move(struct gobexhlp_session* session, const char *oldpath,
+					const char* newpath);
 
-- 
1.7.8.6


^ permalink raw reply related

* [RFC obexd 10/11] fuse: Add unlink/rmdir operation
From: Michał Poczwardowski @ 2012-10-09 18:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Michał Poczwardowski
In-Reply-To: <1349806556-1978-1-git-send-email-dmp0x7c5@gmail.com>

---
 fuse/gobexfuse.c |    9 +++++++++
 fuse/helpers.c   |   28 ++++++++++++++++++++++++++++
 fuse/helpers.h   |    1 +
 3 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/fuse/gobexfuse.c b/fuse/gobexfuse.c
index b47d203..c45d056 100644
--- a/fuse/gobexfuse.c
+++ b/fuse/gobexfuse.c
@@ -230,6 +230,13 @@ static int gobexfuse_mknod(const char *path, mode_t mode, dev_t dev)
 	return 0;
 }
 
+static int gobexfuse_unlink(const char *path)
+{
+	gobexhlp_delete(session, path);
+
+	return session->status;
+}
+
 static struct fuse_operations gobexfuse_oper = {
 	.readdir = gobexfuse_readdir,
 	.getattr = gobexfuse_getattr,
@@ -240,6 +247,8 @@ static struct fuse_operations gobexfuse_oper = {
 	.release = gobexfuse_release,
 	.utimens = gobexfuse_utimens,
 	.mknod = gobexfuse_mknod,
+	.unlink = gobexfuse_unlink,
+	.rmdir = gobexfuse_unlink,
 	.init = gobexfuse_init,
 	.destroy = gobexfuse_destroy,
 };
diff --git a/fuse/helpers.c b/fuse/helpers.c
index 05948be..0ad8cbb 100644
--- a/fuse/helpers.c
+++ b/fuse/helpers.c
@@ -618,6 +618,16 @@ void gobexhlp_put(struct gobexhlp_session* session,
 
 	g_print("gobexhlp_put(%s%s)\n", l->dir, l->file);
 
+	if (g_strcmp0(path, session->vtouch_path) == 0 &&
+				session->vtouch == TRUE) {
+		session->vtouch = FALSE;
+		g_free(session->vtouch_path);
+	} else {
+		/* delete existing file */
+		if (session->rtouch == FALSE)
+			gobexhlp_delete(session, path);
+	}
+
 	gobexhlp_setpath(session, l->dir);
 	buffer->tmpsize = 0;
 	session->buffer = buffer;
@@ -662,3 +672,21 @@ void gobexhlp_touch_real(struct gobexhlp_session* session, gchar *path)
 	session->buffer = tmpbuf;
 }
 
+void gobexhlp_delete(struct gobexhlp_session* session, const char *path)
+{
+	struct gobexhlp_location *l;
+	l = get_location(path);
+
+	g_print("gobexhlp_delete(%s)\n", l->file);
+
+	gobexhlp_setpath(session, l->dir);
+	request_new(session, g_strdup_printf("delete %s", path));
+	g_obex_delete(session->obex, l->file, response_func, session,
+							&session->err);
+
+	g_hash_table_remove(session->file_stat, path);
+
+	free_location(l);
+	request_wait_free(session);
+}
+
diff --git a/fuse/helpers.h b/fuse/helpers.h
index da5f96c..baa6bf1 100644
--- a/fuse/helpers.h
+++ b/fuse/helpers.h
@@ -60,4 +60,5 @@ void gobexhlp_put(struct gobexhlp_session* session,
 					struct gobexhlp_buffer *buffer,
 					const char *path);
 void gobexhlp_touch(struct gobexhlp_session* session, const char *path);
+void gobexhlp_delete(struct gobexhlp_session* session, const char *path);
 
-- 
1.7.8.6


^ permalink raw reply related

* [RFC obexd 09/11] fuse: Add touch operation
From: Michał Poczwardowski @ 2012-10-09 18:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Michał Poczwardowski
In-Reply-To: <1349806556-1978-1-git-send-email-dmp0x7c5@gmail.com>

---
 fuse/gobexfuse.c |   17 +++++++++++++++++
 fuse/helpers.c   |   40 ++++++++++++++++++++++++++++++++++++++++
 fuse/helpers.h   |    1 +
 3 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/fuse/gobexfuse.c b/fuse/gobexfuse.c
index a49a8f9..b47d203 100644
--- a/fuse/gobexfuse.c
+++ b/fuse/gobexfuse.c
@@ -215,6 +215,21 @@ static int gobexfuse_release(const char *path, struct fuse_file_info *fi)
 	return session->status;
 }
 
+static int gobexfuse_utimens(const char *path, const struct timespec tv[2])
+{
+	/*
+	 * Important for mknod (touch) operation
+	 */
+	return 0;
+}
+
+static int gobexfuse_mknod(const char *path, mode_t mode, dev_t dev)
+{
+	gobexhlp_touch(session, path);
+
+	return 0;
+}
+
 static struct fuse_operations gobexfuse_oper = {
 	.readdir = gobexfuse_readdir,
 	.getattr = gobexfuse_getattr,
@@ -223,6 +238,8 @@ static struct fuse_operations gobexfuse_oper = {
 	.write = gobexfuse_write,
 	.truncate = gobexfuse_truncate,
 	.release = gobexfuse_release,
+	.utimens = gobexfuse_utimens,
+	.mknod = gobexfuse_mknod,
 	.init = gobexfuse_init,
 	.destroy = gobexfuse_destroy,
 };
diff --git a/fuse/helpers.c b/fuse/helpers.c
index b807f15..05948be 100644
--- a/fuse/helpers.c
+++ b/fuse/helpers.c
@@ -56,6 +56,8 @@ struct gobexhlp_location {
 	gchar *file;
 };
 
+void gobexhlp_touch_real(struct gobexhlp_session* session, gchar *path);
+
 static uint16_t find_rfcomm_uuid(void *user_data)
 {
 	sdp_list_t *pds = (sdp_list_t*) user_data;
@@ -279,6 +281,12 @@ void request_new(struct gobexhlp_session *session,
 {
 	g_print("REQUEST %s\n", name);
 
+	if (session->vtouch == TRUE) {
+		session->vtouch = FALSE;
+		gobexhlp_touch_real(session, session->vtouch_path);
+		g_free(session->vtouch_path);
+	}
+
 	if (session->request != NULL)
 		g_error("Another request (%s) active!\n",
 					session->request->name);
@@ -622,3 +630,35 @@ void gobexhlp_put(struct gobexhlp_session* session,
 	request_wait_free(session);
 }
 
+/* virtual file creation */
+void gobexhlp_touch(struct gobexhlp_session* session, const char *path)
+{
+	struct stat *stbuf;
+
+	g_print("gobexhlp_touch(%s)\n", path);
+
+	stbuf = g_malloc0(sizeof(struct stat));
+	stbuf->st_mode = S_IFREG;
+	g_hash_table_replace(session->file_stat, g_strdup(path), stbuf);
+
+	session->vtouch = TRUE;
+	session->vtouch_path = g_strdup(path);
+}
+
+void gobexhlp_touch_real(struct gobexhlp_session* session, gchar *path)
+{
+	struct gobexhlp_buffer *buffer, *tmpbuf;
+
+	g_print("gobexhlp_touch_real(%s)\n", path);
+
+	tmpbuf = session->buffer; /* save buffer state */
+
+	buffer = g_malloc0(sizeof(struct gobexhlp_buffer));
+	session->rtouch = TRUE;
+	gobexhlp_put(session, buffer, path);
+	session->rtouch = FALSE;
+	g_free(buffer);
+
+	session->buffer = tmpbuf;
+}
+
diff --git a/fuse/helpers.h b/fuse/helpers.h
index 95987c4..da5f96c 100644
--- a/fuse/helpers.h
+++ b/fuse/helpers.h
@@ -59,4 +59,5 @@ struct gobexhlp_buffer *gobexhlp_get(struct gobexhlp_session* session,
 void gobexhlp_put(struct gobexhlp_session* session,
 					struct gobexhlp_buffer *buffer,
 					const char *path);
+void gobexhlp_touch(struct gobexhlp_session* session, const char *path);
 
-- 
1.7.8.6


^ permalink raw reply related

* [RFC obexd 08/11] fuse: Add write operation
From: Michał Poczwardowski @ 2012-10-09 18:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Michał Poczwardowski
In-Reply-To: <1349806556-1978-1-git-send-email-dmp0x7c5@gmail.com>

---
 fuse/gobexfuse.c |   44 ++++++++++++++++++++++++++++++++++++++++++++
 fuse/helpers.c   |   45 +++++++++++++++++++++++++++++++++++++++++++++
 fuse/helpers.h   |    3 +++
 3 files changed, 92 insertions(+), 0 deletions(-)

diff --git a/fuse/gobexfuse.c b/fuse/gobexfuse.c
index 446a757..a49a8f9 100644
--- a/fuse/gobexfuse.c
+++ b/fuse/gobexfuse.c
@@ -174,11 +174,55 @@ static int gobexfuse_read(const char *path, char *buf, size_t size,
 	return asize;
 }
 
+static int gobexfuse_write(const char *path, const char *buf, size_t size,
+				off_t offset, struct fuse_file_info *fi)
+{
+	gsize nsize;
+	struct gobexhlp_buffer *file_buffer = (struct gobexhlp_buffer*)fi->fh;
+
+	if (file_buffer->size < offset + size) {
+		nsize = offset + size;
+		file_buffer->data = g_realloc(file_buffer->data, nsize);
+		file_buffer->size = nsize;
+	} else {
+		nsize = file_buffer->size;
+	}
+
+	file_buffer->edited = TRUE;
+	memcpy(file_buffer->data + offset, buf, size);
+
+	return size;
+}
+
+static int gobexfuse_truncate(const char *path, off_t offset)
+{
+	/*
+	 *  Allow to change the size of a file.
+	 */
+	return 0;
+}
+
+static int gobexfuse_release(const char *path, struct fuse_file_info *fi)
+{
+	struct gobexhlp_buffer *file_buffer = (struct gobexhlp_buffer*)fi->fh;
+
+	if (file_buffer->edited == TRUE)
+		gobexhlp_put(session, file_buffer, path); /* send to device */
+
+	g_free(file_buffer->data);
+	g_free(file_buffer);
+
+	return session->status;
+}
+
 static struct fuse_operations gobexfuse_oper = {
 	.readdir = gobexfuse_readdir,
 	.getattr = gobexfuse_getattr,
 	.open = gobexfuse_open,
 	.read = gobexfuse_read,
+	.write = gobexfuse_write,
+	.truncate = gobexfuse_truncate,
+	.release = gobexfuse_release,
 	.init = gobexfuse_init,
 	.destroy = gobexfuse_destroy,
 };
diff --git a/fuse/helpers.c b/fuse/helpers.c
index 9b453e0..b807f15 100644
--- a/fuse/helpers.c
+++ b/fuse/helpers.c
@@ -577,3 +577,48 @@ struct gobexhlp_buffer *gobexhlp_get(struct gobexhlp_session* session,
 
 	return buffer;
 }
+
+static gssize async_put_producer(void *buf, gsize len, gpointer user_data)
+{
+	gssize size;
+	struct gobexhlp_session *session = user_data;
+	struct gobexhlp_buffer *buffer = session->buffer;
+
+	size = buffer->size - buffer->tmpsize;
+
+	if (size > len)
+		size = len;
+
+	g_obex_suspend(session->obex);
+	g_obex_resume(session->obex);
+
+	if (size == 0)
+		return 0;
+
+	memcpy(buf, buffer->data + buffer->tmpsize, size);
+	buffer->tmpsize += size;
+
+	return size;
+}
+
+void gobexhlp_put(struct gobexhlp_session* session,
+				struct gobexhlp_buffer *buffer,
+				const char *path)
+{
+	struct gobexhlp_location *l;
+	l = get_location(path);
+
+	g_print("gobexhlp_put(%s%s)\n", l->dir, l->file);
+
+	gobexhlp_setpath(session, l->dir);
+	buffer->tmpsize = 0;
+	session->buffer = buffer;
+	request_new(session, g_strdup_printf("put %s", path));
+	g_obex_put_req(session->obex, async_put_producer,
+					complete_func, session, &session->err,
+					G_OBEX_HDR_NAME, l->file,
+					G_OBEX_HDR_INVALID);
+	free_location(l);
+	request_wait_free(session);
+}
+
diff --git a/fuse/helpers.h b/fuse/helpers.h
index 50c750d..95987c4 100644
--- a/fuse/helpers.h
+++ b/fuse/helpers.h
@@ -56,4 +56,7 @@ struct stat *gobexhlp_getattr(struct gobexhlp_session* session,
 					const char *path);
 struct gobexhlp_buffer *gobexhlp_get(struct gobexhlp_session* session,
 					const char *path);
+void gobexhlp_put(struct gobexhlp_session* session,
+					struct gobexhlp_buffer *buffer,
+					const char *path);
 
-- 
1.7.8.6


^ permalink raw reply related

* [RFC obexd 07/11] fuse: Add open and read operations plus location helpers
From: Michał Poczwardowski @ 2012-10-09 18:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Michał Poczwardowski
In-Reply-To: <1349806556-1978-1-git-send-email-dmp0x7c5@gmail.com>

---
 fuse/gobexfuse.c |   32 ++++++++++++++++++++++++++++
 fuse/helpers.c   |   61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fuse/helpers.h   |    3 +-
 3 files changed, 95 insertions(+), 1 deletions(-)

diff --git a/fuse/gobexfuse.c b/fuse/gobexfuse.c
index c886176..446a757 100644
--- a/fuse/gobexfuse.c
+++ b/fuse/gobexfuse.c
@@ -144,9 +144,41 @@ static int gobexfuse_getattr(const char *path, struct stat *stbuf)
 	return res;
 }
 
+static int gobexfuse_open(const char *path, struct fuse_file_info *fi)
+{
+	struct gobexhlp_buffer *file_buffer;
+
+	file_buffer = gobexhlp_get(session, path);
+
+	if (file_buffer == NULL)
+		return -ENOENT;
+
+	fi->fh = (uint64_t)file_buffer;
+
+	return session->status;
+}
+
+static int gobexfuse_read(const char *path, char *buf, size_t size,
+			off_t offset, struct fuse_file_info *fi)
+{
+	gsize asize;
+	struct gobexhlp_buffer *file_buffer = (struct gobexhlp_buffer*)fi->fh;
+
+	asize = file_buffer->size - offset;
+
+	if (asize > size)
+		asize = size;
+
+	memcpy(buf, file_buffer->data + offset, asize);
+
+	return asize;
+}
+
 static struct fuse_operations gobexfuse_oper = {
 	.readdir = gobexfuse_readdir,
 	.getattr = gobexfuse_getattr,
+	.open = gobexfuse_open,
+	.read = gobexfuse_read,
 	.init = gobexfuse_init,
 	.destroy = gobexfuse_destroy,
 };
diff --git a/fuse/helpers.c b/fuse/helpers.c
index 249d0c9..9b453e0 100644
--- a/fuse/helpers.c
+++ b/fuse/helpers.c
@@ -516,3 +516,64 @@ struct stat *gobexhlp_getattr(struct gobexhlp_session* session,
 	return g_hash_table_lookup(session->file_stat, path);
 }
 
+static struct gobexhlp_location *get_location(const char *path)
+{
+	struct gobexhlp_location *location;
+	gchar **directories;
+	guint i, len, fid = 0;
+
+	location = g_malloc0(sizeof(*location));
+	directories = g_strsplit(path, "/", -1);
+	len = g_strv_length(directories);
+
+	for (i = 0; i < len; i++)
+		if (directories[i][0] != '\0') /* protect multi slashes */
+			fid = i; /* last nonempty is a file */
+
+	location->file = g_strdup(directories[fid]);
+	directories[fid][0] = '\0'; /* remove file */
+	location->dir = g_strjoinv("/", directories);
+
+	g_strfreev(directories);
+
+	return location;
+}
+
+void free_location(struct gobexhlp_location *location)
+{
+	g_free(location->file);
+	g_free(location->dir);
+	g_free(location);
+}
+
+struct gobexhlp_buffer *gobexhlp_get(struct gobexhlp_session* session,
+						const char *path)
+{
+	struct gobexhlp_location *l;
+	struct gobexhlp_buffer *buffer;
+	struct stat *stfile;
+	l = get_location(path);
+
+	g_print("gobexhlp_get(%s%s)\n", l->dir, l->file);
+
+	stfile = gobexhlp_getattr(session, path);
+	if (stfile == NULL)
+		return NULL;
+
+	buffer = g_malloc0(sizeof(*buffer));
+
+	if (stfile->st_size == 0)
+		return buffer;
+
+	gobexhlp_setpath(session, l->dir);
+	request_new(session, g_strdup_printf("get %s", path));
+	session->buffer = buffer;
+	g_obex_get_req(session->obex, async_get_consumer,
+					complete_func, session, &session->err,
+					G_OBEX_HDR_NAME, l->file,
+					G_OBEX_HDR_INVALID);
+	free_location(l);
+	request_wait_free(session);
+
+	return buffer;
+}
diff --git a/fuse/helpers.h b/fuse/helpers.h
index 0a0f366..50c750d 100644
--- a/fuse/helpers.h
+++ b/fuse/helpers.h
@@ -54,5 +54,6 @@ void gobexhlp_disconnect(struct gobexhlp_session* session);
 GList *gobexhlp_listfolder(struct gobexhlp_session* session, const char *path);
 struct stat *gobexhlp_getattr(struct gobexhlp_session* session,
 					const char *path);
-
+struct gobexhlp_buffer *gobexhlp_get(struct gobexhlp_session* session,
+					const char *path);
 
-- 
1.7.8.6


^ permalink raw reply related

* [RFC obexd 06/11] fuse: Add getattr operation
From: Michał Poczwardowski @ 2012-10-09 18:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Michał Poczwardowski
In-Reply-To: <1349806556-1978-1-git-send-email-dmp0x7c5@gmail.com>

---
 fuse/gobexfuse.c |   34 ++++++++++++++++++++++++++++++++++
 fuse/helpers.c   |    6 ++++++
 fuse/helpers.h   |    2 ++
 3 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/fuse/gobexfuse.c b/fuse/gobexfuse.c
index 2bdfc09..c886176 100644
--- a/fuse/gobexfuse.c
+++ b/fuse/gobexfuse.c
@@ -111,8 +111,42 @@ static int gobexfuse_readdir(const char *path, void *buf,
 	return session->status;
 }
 
+static int gobexfuse_getattr(const char *path, struct stat *stbuf)
+{
+	int res = 0;
+	struct stat *stfile;
+
+	memset(stbuf, 0, sizeof(struct stat));
+
+	if (strcmp(path, "/") == 0) {
+		stbuf->st_mode = S_IFDIR | 0755;
+		stbuf->st_nlink = 2;
+	} else {
+		stfile = gobexhlp_getattr(session, path);
+
+		if (stfile == NULL)
+			return -ENOENT;
+
+		if (stfile->st_mode == S_IFREG)
+			stbuf->st_mode = stfile->st_mode | 0666;
+		else /* S_IFDIR */
+			stbuf->st_mode = stfile->st_mode | 0755;
+
+		stbuf->st_nlink = 1;
+		stbuf->st_size = stfile->st_size;
+		stbuf->st_mtime = stbuf->st_atime = stbuf->st_ctime =
+						stfile->st_mtime;
+		stbuf->st_blksize = 512;
+		stbuf->st_blocks = (stbuf->st_size + stbuf->st_blksize)
+						/ stbuf->st_blksize;
+	}
+
+	return res;
+}
+
 static struct fuse_operations gobexfuse_oper = {
 	.readdir = gobexfuse_readdir,
+	.getattr = gobexfuse_getattr,
 	.init = gobexfuse_init,
 	.destroy = gobexfuse_destroy,
 };
diff --git a/fuse/helpers.c b/fuse/helpers.c
index 1d3faa5..249d0c9 100644
--- a/fuse/helpers.c
+++ b/fuse/helpers.c
@@ -510,3 +510,9 @@ GList *gobexhlp_listfolder(struct gobexhlp_session* session,
 	return session->lsfiles;
 }
 
+struct stat *gobexhlp_getattr(struct gobexhlp_session* session,
+					const char *path)
+{
+	return g_hash_table_lookup(session->file_stat, path);
+}
+
diff --git a/fuse/helpers.h b/fuse/helpers.h
index 84238c9..0a0f366 100644
--- a/fuse/helpers.h
+++ b/fuse/helpers.h
@@ -52,5 +52,7 @@ struct gobexhlp_session* gobexhlp_connect(const char *srcstr,
 void gobexhlp_disconnect(struct gobexhlp_session* session);
 
 GList *gobexhlp_listfolder(struct gobexhlp_session* session, const char *path);
+struct stat *gobexhlp_getattr(struct gobexhlp_session* session,
+					const char *path);
 
 
-- 
1.7.8.6


^ permalink raw reply related

* [RFC obexd 05/11] fuse: Add readdir operation
From: Michał Poczwardowski @ 2012-10-09 18:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Michał Poczwardowski
In-Reply-To: <1349806556-1978-1-git-send-email-dmp0x7c5@gmail.com>

---
 fuse/gobexfuse.c |   23 ++++++++++
 fuse/helpers.c   |  129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fuse/helpers.h   |    2 +
 3 files changed, 154 insertions(+), 0 deletions(-)

diff --git a/fuse/gobexfuse.c b/fuse/gobexfuse.c
index cc5fedb..2bdfc09 100644
--- a/fuse/gobexfuse.c
+++ b/fuse/gobexfuse.c
@@ -89,7 +89,30 @@ void gobexfuse_destroy()
 	g_thread_join(main_gthread);
 }
 
+static int gobexfuse_readdir(const char *path, void *buf,
+			fuse_fill_dir_t filler, off_t offset,
+				struct fuse_file_info *fi)
+{
+	int len, i;
+	gchar *string;
+	GList *files;
+
+	filler(buf, ".", NULL, 0);
+	filler(buf, "..", NULL, 0);
+
+	files = gobexhlp_listfolder(session, path);
+	len = g_list_length(files);
+
+	for (i = 1; i < len; i++) { /* element for i==0 is NULL */
+		string = g_list_nth_data(files, i);
+		filler(buf, string, NULL, 0);
+	}
+
+	return session->status;
+}
+
 static struct fuse_operations gobexfuse_oper = {
+	.readdir = gobexfuse_readdir,
 	.init = gobexfuse_init,
 	.destroy = gobexfuse_destroy,
 };
diff --git a/fuse/helpers.c b/fuse/helpers.c
index 1b8082f..1d3faa5 100644
--- a/fuse/helpers.c
+++ b/fuse/helpers.c
@@ -381,3 +381,132 @@ void gobexhlp_setpath(struct gobexhlp_session *session, const char *path)
 
 	g_strfreev(path_v);
 }
+
+static void listfolder_xml_element(GMarkupParseContext *ctxt,
+			const gchar *element, const gchar **names,
+			const gchar **values, gpointer user_data,
+			GError **gerr)
+{
+	gchar *key, *pathname, *name = NULL;
+	struct gobexhlp_session *session = user_data;
+	struct stat *stbuf;
+	gint i = 0;
+
+	stbuf = g_malloc0(sizeof(struct stat));
+
+	if ((strcasecmp("file", element) == 0)) {
+		stbuf->st_mode = S_IFREG;
+	} else if ((strcasecmp("folder", element)) == 0) {
+		stbuf->st_mode = S_IFDIR;
+		stbuf->st_mtime = time(NULL);
+	} else {
+		g_free(stbuf);
+		return;
+	}
+
+	for (key = (gchar *) names[i]; key; key = (gchar *) names[++i]) {
+		if (g_str_equal("name", key) == TRUE) {
+			session->lsfiles = g_list_append(session->lsfiles,
+						g_strdup(values[i]));
+			name = g_strdup(values[i]);
+
+		} else if (g_str_equal("size", key) == TRUE) {
+			guint64 size;
+			size = g_ascii_strtoll(values[i], NULL, 10);
+			stbuf->st_size = size;
+
+		} else if (g_str_equal("created", key) == TRUE) {
+			GTimeVal time;
+			GDateTime *datetime;
+			g_time_val_from_iso8601(values[i], &time);
+			datetime = g_date_time_new_from_timeval_utc(&time);
+			stbuf->st_mtime = g_date_time_to_unix(datetime);
+		}
+	}
+
+	if (g_str_equal("/", session->setpath) == TRUE)
+		pathname = g_strdup_printf("/%s", name);
+	else
+		pathname = g_strdup_printf("%s/%s", session->setpath, name);
+
+	g_hash_table_replace(session->file_stat, pathname, stbuf);
+	g_free(name);
+}
+
+static const GMarkupParser parser = {
+	listfolder_xml_element,
+	NULL, NULL, NULL, NULL
+};
+
+static void complete_listfolder_func(GObex *obex, GError *err,
+				gpointer user_data)
+{
+	GMarkupParseContext *ctxt;
+	struct gobexhlp_session *session = user_data;
+	struct gobexhlp_buffer *buffer = session->buffer;
+
+	if (err == NULL) {
+		ctxt = g_markup_parse_context_new(&parser, 0, session, NULL);
+		g_markup_parse_context_parse(ctxt, buffer->data, buffer->size,
+							NULL);
+		g_markup_parse_context_free(ctxt);
+	}
+
+	complete_func(obex, err, user_data);
+}
+
+static gboolean async_get_consumer(const void *buf, gsize len,
+							gpointer user_data)
+{
+	struct gobexhlp_session *session = user_data;
+	struct gobexhlp_buffer *buffer = session->buffer;
+
+	if (buffer->size == 0)
+		buffer->data = g_malloc0(sizeof(char) * len);
+	else
+		buffer->data = g_realloc(buffer->data, buffer->size + len);
+
+	memcpy(buffer->data + buffer->size, buf, len);
+	buffer->size += len;
+
+	g_obex_suspend(session->obex);
+	g_obex_resume(session->obex);
+
+	return TRUE;
+}
+
+GList *gobexhlp_listfolder(struct gobexhlp_session* session,
+					const char *path)
+{
+	struct gobexhlp_buffer *buffer;
+	GObexPacket *req;
+	guint reqpkt;
+
+	gobexhlp_setpath(session, path);
+
+	g_print("gobexhlp_listfolder(%s)\n", path);
+
+	if (session->lsfiles != NULL) {
+		g_list_free_full(session->lsfiles, g_free);
+		session->lsfiles = NULL;
+	}
+
+	session->lsfiles = g_list_alloc();
+	buffer = g_malloc0(sizeof(struct gobexhlp_buffer));
+	session->buffer = buffer;
+
+	request_new(session, g_strdup_printf("listfolder %s", path));
+	req = g_obex_packet_new(G_OBEX_OP_GET, TRUE, G_OBEX_HDR_INVALID);
+	g_obex_packet_add_bytes(req, G_OBEX_HDR_TYPE, OBEX_FTP_LS,
+						strlen(OBEX_FTP_LS) + 1);
+	reqpkt = g_obex_get_req_pkt(session->obex, req,
+				async_get_consumer,
+				complete_listfolder_func,
+				session, &session->err);
+	request_wait_free(session);
+	g_free(buffer->data);
+	g_free(buffer);
+
+	return session->lsfiles;
+}
+
diff --git a/fuse/helpers.h b/fuse/helpers.h
index f1d787b..84238c9 100644
--- a/fuse/helpers.h
+++ b/fuse/helpers.h
@@ -51,4 +51,6 @@ struct gobexhlp_session* gobexhlp_connect(const char *srcstr,
 						const char *dstsrc);
 void gobexhlp_disconnect(struct gobexhlp_session* session);
 
+GList *gobexhlp_listfolder(struct gobexhlp_session* session, const char *path);
+
 
-- 
1.7.8.6


^ permalink raw reply related

* [RFC obexd 04/11] fuse: Add request helpers and setpath operation
From: Michał Poczwardowski @ 2012-10-09 18:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Michał Poczwardowski
In-Reply-To: <1349806556-1978-1-git-send-email-dmp0x7c5@gmail.com>

---
 fuse/helpers.c |  108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 108 insertions(+), 0 deletions(-)

diff --git a/fuse/helpers.c b/fuse/helpers.c
index 856e1d5..1b8082f 100644
--- a/fuse/helpers.c
+++ b/fuse/helpers.c
@@ -273,3 +273,111 @@ void gobexhlp_disconnect(struct gobexhlp_session* session)
 
 	g_free(session);
 }
+
+void request_new(struct gobexhlp_session *session,
+					gchar *name)
+{
+	g_print("REQUEST %s\n", name);
+
+	if (session->request != NULL)
+		g_error("Another request (%s) active!\n",
+					session->request->name);
+
+	session->status = 0;
+	session->request = g_malloc0(sizeof(struct gobexhlp_request));
+	session->request->name = name;
+
+	/*
+	 * suspend/resume operations recreates g_io_add_watch(),
+	 * it fixes obex->io freeze during transfer
+	 */
+	g_obex_suspend(session->obex);
+	g_obex_resume(session->obex);
+}
+
+void request_wait_free(struct gobexhlp_session *session)
+{
+	g_print("WAIT for %s\n", session->request->name);
+
+	g_obex_suspend(session->obex);
+	g_obex_resume(session->obex);
+
+	if (session->err != NULL) {
+		g_print("ERROR: %s (%d)\n", session->err->message,
+						session->err->code);
+		g_error_free(session->err);
+		raise(SIGTERM);
+		return;
+	}
+
+	g_mutex_lock(gobexhlp_mutex);
+
+	while (session->request->complete != TRUE)
+		g_cond_wait(gobexhlp_cond, gobexhlp_mutex);
+
+	g_mutex_unlock(gobexhlp_mutex);
+
+	g_free(session->request->name);
+	g_free(session->request);
+	session->request = NULL;
+}
+
+static void complete_func(GObex *obex, GError *err,
+				gpointer user_data)
+{
+	struct gobexhlp_session *session = user_data;
+
+	if (err != NULL) {
+		g_print("ERROR: %s\n", err->message);
+		session->status = -ECANCELED;
+		g_error_free(err);
+	} else {
+		g_print("COMPLETE %s\n", session->request->name);
+	}
+
+	g_mutex_lock(gobexhlp_mutex);
+	session->request->complete = TRUE;
+	g_cond_signal(gobexhlp_cond);
+	g_mutex_unlock(gobexhlp_mutex);
+}
+
+static void response_func(GObex *obex, GError *err, GObexPacket *rsp,
+							gpointer user_data)
+{
+	complete_func(obex, err, user_data);
+}
+
+void gobexhlp_setpath(struct gobexhlp_session *session, const char *path)
+{
+	guint i = 0, split = 0;
+	gchar **path_v;
+	gsize len;
+
+	g_print("gobexhlp_setpath(%s)\n", path);
+
+	if (g_str_has_prefix(path, session->setpath)) {
+		split = strlen(session->setpath);
+	} else {
+		request_new(session, g_strdup_printf("setpath root"));
+		g_obex_setpath(session->obex, "", response_func,
+						session, &session->err);
+		request_wait_free(session);
+	}
+
+	path_v = g_strsplit(path+split, "/", -1);
+	len = g_strv_length(path_v);
+
+	for (i = 0; i < len; i++)
+		if (path_v[i][0] != '\0') {
+			request_new(session,
+				g_strdup_printf("setpath %s", path_v[i]));
+			g_obex_setpath(session->obex, path_v[i],
+					response_func, session, &session->err);
+			request_wait_free(session);
+		}
+
+	g_free(session->setpath);
+	session->setpath = g_strdup(path);
+
+	g_strfreev(path_v);
+}
-- 
1.7.8.6


^ permalink raw reply related

* [RFC obexd 03/11] fuse: Add gobexhlp_connect/disconnect functions with helpers
From: Michał Poczwardowski @ 2012-10-09 18:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Michał Poczwardowski
In-Reply-To: <1349806556-1978-1-git-send-email-dmp0x7c5@gmail.com>

---
 fuse/gobexfuse.c |   40 ++++++++++
 fuse/helpers.c   |  220 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fuse/helpers.h   |    5 +
 3 files changed, 265 insertions(+), 0 deletions(-)

diff --git a/fuse/gobexfuse.c b/fuse/gobexfuse.c
index d9709fd..cc5fedb 100644
--- a/fuse/gobexfuse.c
+++ b/fuse/gobexfuse.c
@@ -33,6 +33,10 @@
 
 #include "helpers.h"
 
+struct gobexhlp_session* session = NULL;
+static GMainLoop *main_loop;
+static GThread *main_gthread;
+
 struct options {
 	char* dststr;
 	char* srcstr;
@@ -60,7 +64,34 @@ static struct fuse_opt gobexfuse_opts[] =
 	FUSE_OPT_END
 };
 
+gpointer main_loop_func(gpointer user_data)
+{
+	main_loop = g_main_loop_new(NULL, FALSE);
+	g_main_loop_run(main_loop);
+
+	return 0;
+}
+
+void* gobexfuse_init(struct fuse_conn_info *conn)
+{
+	main_gthread = g_thread_create(main_loop_func, NULL, TRUE, NULL);
+
+	conn->async_read = 0;
+	conn->want &= ~FUSE_CAP_ASYNC_READ;
+
+	return 0;
+}
+
+void gobexfuse_destroy()
+{
+	gobexhlp_disconnect(session);
+	g_main_loop_quit(main_loop);
+	g_thread_join(main_gthread);
+}
+
 static struct fuse_operations gobexfuse_oper = {
+	.init = gobexfuse_init,
+	.destroy = gobexfuse_destroy,
 };
 
 static int gobexfuse_opt_proc(void *data, const char *arg, int key,
@@ -111,6 +142,15 @@ int main(int argc, char *argv[])
 
 	g_thread_init(NULL);
 
+	session = gobexhlp_connect(options.srcstr, options.dststr);
+	if (session == NULL || session->io == NULL) {
+		g_printerr("Connection to %s failed\n", options.dststr);
+		gobexhlp_disconnect(session);
+		return -EHOSTUNREACH;
+	} else {
+		g_print("Connected\nMounting %s\n", options.dststr);
+	}
+
 	fuse_opt_add_arg(&args, "-s"); /* force single threaded mode */
 	retfuse = fuse_main(args.argc, args.argv, &gobexfuse_oper, NULL);
 
diff --git a/fuse/helpers.c b/fuse/helpers.c
index 53bba57..856e1d5 100644
--- a/fuse/helpers.c
+++ b/fuse/helpers.c
@@ -43,6 +43,9 @@
 
 #define OBEX_FTP_LS "x-obex/folder-listing"
 
+static GCond *gobexhlp_cond;
+static GMutex *gobexhlp_mutex;
+
 struct gobexhlp_request {
 	gchar *name;
 	gboolean complete;
@@ -53,3 +56,220 @@ struct gobexhlp_location {
 	gchar *file;
 };
 
+static uint16_t find_rfcomm_uuid(void *user_data)
+{
+	sdp_list_t *pds = (sdp_list_t*) user_data;
+	uint16_t channel = 0;
+
+	for (;pds;pds = pds->next) {
+		sdp_data_t *d = (sdp_data_t*)pds->data;
+		int proto = 0;
+		for (; d; d = d->next) {
+			switch(d->dtd) {
+			case SDP_UUID16:
+			case SDP_UUID32:
+			case SDP_UUID128:
+				proto = sdp_uuid_to_proto(&d->val.uuid);
+			break;
+			case SDP_UINT8:
+				if (proto == RFCOMM_UUID)
+					channel = d->val.int8;
+				break;
+			}
+		}
+	}
+	return channel;
+}
+
+static uint16_t get_ftp_channel(bdaddr_t *src, bdaddr_t *dst)
+{
+	sdp_session_t *sdp;
+	sdp_list_t *r, *search_list, *attrid_list;
+	sdp_list_t *response_list = NULL;
+	uuid_t uuid;
+
+	/* FTP_SDP_UUID "00001106-0000-1000-8000-00805f9b34fb" */
+	uint8_t uuid_int[] = {0, 0, 0x11, 0x06, 0, 0, 0x10, 0, 0x80,
+					0, 0, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
+	uint32_t range = 0x0000ffff;
+	uint16_t channel = 0;
+
+	sdp = sdp_connect(src, dst, SDP_RETRY_IF_BUSY );
+	if (sdp == NULL)
+		return channel;
+
+	sdp_uuid128_create(&uuid, uuid_int);
+	search_list = sdp_list_append(NULL, &uuid);
+	attrid_list = sdp_list_append(NULL, &range);
+	sdp_service_search_attr_req(sdp, search_list, SDP_ATTR_REQ_RANGE,
+					attrid_list, &response_list);
+	r = response_list;
+
+	for (; r;r = r->next) {
+		sdp_record_t *rec = (sdp_record_t*) r->data;
+		sdp_list_t *proto_list;
+
+		if (sdp_get_access_protos(rec, &proto_list ) == 0) {
+			sdp_list_t *p = proto_list;
+			for (; p; p = p->next) {
+				sdp_list_t *pds = (sdp_list_t*) p->data;
+				channel = find_rfcomm_uuid(pds);
+				sdp_list_free((sdp_list_t*) p->data, 0);
+			}
+			sdp_list_free(proto_list, 0);
+		}
+		sdp_record_free(rec);
+	}
+	sdp_close(sdp);
+
+	g_free(search_list);
+	g_free(attrid_list);
+	g_free(response_list);
+
+	return channel;
+}
+
+/* taken from client/bluetooth.c - bluetooth_getpacketopt */
+static int get_packet_opt(GIOChannel *io, int *tx_mtu, int *rx_mtu)
+{
+	int sk = g_io_channel_unix_get_fd(io);
+	int type;
+	int omtu = -1;
+	int imtu = -1;
+	socklen_t len = sizeof(int);
+
+	if (getsockopt(sk, SOL_SOCKET, SO_TYPE, &type, &len) < 0)
+		return -errno;
+
+	if (type != SOCK_SEQPACKET)
+		return -EINVAL;
+
+	if (!bt_io_get(io, BT_IO_L2CAP, NULL, BT_IO_OPT_OMTU, &omtu,
+						BT_IO_OPT_IMTU, &imtu,
+						BT_IO_OPT_INVALID))
+		return -EINVAL;
+
+	if (tx_mtu)
+		*tx_mtu = omtu;
+
+	if (rx_mtu)
+		*rx_mtu = imtu;
+
+	return 0;
+}
+
+static void obex_callback(GObex *obex, GError *err, GObexPacket *rsp,
+							gpointer user_data)
+{
+	if (err != NULL) {
+		g_debug("Connect failed: %s\n", err->message);
+		g_error_free(err);
+	} else {
+		g_debug("Connect succeeded\n");
+	}
+}
+
+static void bt_io_callback(GIOChannel *io, GError *err, gpointer user_data)
+{
+	struct gobexhlp_session *session = user_data;
+	GObexTransportType type;
+	int tx_mtu = -1;
+	int rx_mtu = -1;
+
+	if (err != NULL) {
+		g_printerr("%s\n", err->message);
+		g_error_free(err);
+		return;
+	}
+
+	g_debug("Bluetooth socket connected\n");
+
+	g_io_channel_set_flags(session->io, G_IO_FLAG_NONBLOCK, NULL);
+	g_io_channel_set_close_on_unref(session->io, TRUE);
+
+	if (get_packet_opt(session->io, &tx_mtu, &rx_mtu) == 0) {
+		type = G_OBEX_TRANSPORT_PACKET;
+		g_debug("PACKET transport tx:%d rx:%d\n", tx_mtu, rx_mtu);
+	} else {
+		type = G_OBEX_TRANSPORT_STREAM;
+		g_debug("STREAM transport\n");
+	}
+
+	session->obex = g_obex_new(io, type, tx_mtu, rx_mtu);
+	g_obex_connect(session->obex, obex_callback, session, NULL,
+				G_OBEX_HDR_TARGET, OBEX_FTP_UUID,
+				OBEX_FTP_UUID_LEN, G_OBEX_HDR_INVALID);
+}
+
+struct gobexhlp_session* gobexhlp_connect(const char *srcstr,
+						const char *dststr)
+{
+	struct gobexhlp_session *session;
+	uint16_t channel;
+	bdaddr_t src, dst;
+
+	session = g_try_malloc0(sizeof(struct gobexhlp_session));
+	if (session == NULL)
+		return NULL;
+
+	if (srcstr == NULL)
+		bacpy(&src, BDADDR_ANY);
+	else
+		str2ba(srcstr, &src);
+
+	str2ba(dststr, &dst);
+	channel = get_ftp_channel(&src, &dst);
+
+	if (channel == 0)
+		return NULL;
+
+	if (channel > 31)
+		session->io = bt_io_connect(BT_IO_L2CAP, bt_io_callback,
+				session, NULL, &session->err,
+				BT_IO_OPT_SOURCE_BDADDR, &src,
+				BT_IO_OPT_DEST_BDADDR, &dst,
+				BT_IO_OPT_PSM, channel,
+				BT_IO_OPT_MODE, BT_IO_MODE_ERTM,
+				BT_IO_OPT_OMTU, BT_TX_MTU,
+				BT_IO_OPT_IMTU, BT_RX_MTU,
+				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+				BT_IO_OPT_INVALID);
+	else
+		session->io = bt_io_connect(BT_IO_RFCOMM, bt_io_callback,
+				session, NULL, &session->err,
+				BT_IO_OPT_SOURCE_BDADDR, &src,
+				BT_IO_OPT_DEST_BDADDR, &dst,
+				BT_IO_OPT_CHANNEL, channel,
+				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+				BT_IO_OPT_INVALID);
+
+	if (session->err != NULL)
+		return NULL;
+
+	session->file_stat = g_hash_table_new_full( g_str_hash, g_str_equal,
+					g_free, g_free);
+	session->setpath = g_strdup("/");
+
+	gobexhlp_mutex = g_mutex_new();
+	gobexhlp_cond = g_cond_new();
+
+	return session;
+}
+
+void gobexhlp_disconnect(struct gobexhlp_session* session)
+{
+	if (session == NULL)
+		return;
+
+	g_obex_unref(session->obex);
+	g_free(session->io);
+
+	g_hash_table_remove_all(session->file_stat);
+	g_list_free_full(session->lsfiles, g_free);
+	g_free(session->setpath);
+
+	g_mutex_free(gobexhlp_mutex);
+	g_cond_free(gobexhlp_cond);
+
+	g_free(session);
+}
diff --git a/fuse/helpers.h b/fuse/helpers.h
index 21972b2..f1d787b 100644
--- a/fuse/helpers.h
+++ b/fuse/helpers.h
@@ -47,3 +47,8 @@ struct gobexhlp_session {
 	GError *err;
 };
 
+struct gobexhlp_session* gobexhlp_connect(const char *srcstr,
+						const char *dstsrc);
+void gobexhlp_disconnect(struct gobexhlp_session* session);
+
+
-- 
1.7.8.6


^ permalink raw reply related

* [RFC obexd 02/11] build: Add --enable-fuse for gobexfuse
From: Michał Poczwardowski @ 2012-10-09 18:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Michał Poczwardowski
In-Reply-To: <1349806556-1978-1-git-send-email-dmp0x7c5@gmail.com>

---
 Makefile.am  |    9 +++++++++
 configure.ac |   15 +++++++++++++++
 2 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 724dd5d..95b99a6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -132,6 +132,15 @@ client_obex_client_SOURCES = $(gdbus_sources) $(gobex_sources) \
 client_obex_client_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@
 endif
 
+if FUSE
+bin_PROGRAMS = fuse/gobexfuse
+
+fuse_gobexfuse_SOURCES = $(gobex_sources) $(btio_sources) \
+		fuse/helpers.c fuse/gobexfuse.c
+
+fuse_gobexfuse_LDADD = @GLIB_LIBS@ @GTHREAD_LIBS@ @BLUEZ_LIBS@ @FUSE_LIBS@
+endif
+
 service_DATA = $(service_in_files:.service.in=.service)
 
 AM_CFLAGS = @BLUEZ_CFLAGS@ @EBOOK_CFLAGS@ @GTHREAD_CFLAGS@ @GLIB_CFLAGS@ \
diff --git a/configure.ac b/configure.ac
index c8e61ac..7190f3f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -180,4 +180,19 @@ AM_CONDITIONAL(CLIENT, test "${enable_client}" != "no")
 
 AM_CONDITIONAL(READLINE, test "${readline_found}" = "yes")
 
+AC_ARG_ENABLE(fuse, AC_HELP_STRING([--enable-fuse],
+			[Build gobexfuse]), [
+	PKG_CHECK_MODULES(FUSE, fuse, dummy=yes,
+				      AC_MSG_ERROR(FUSE is required))
+	AC_SUBST(FUSE_CFLAGS)
+	AC_SUBST(FUSE_LIBS)
+	enable_fuse=${enableval}
+
+	PKG_CHECK_MODULES(GTHREAD, gthread-2.0, dummy=yes,
+					AC_MSG_ERROR(libgthread is required))
+	AC_SUBST(GTHREAD_CFLAGS)
+	AC_SUBST(GTHREAD_LIBS)
+])
+AM_CONDITIONAL(FUSE, test "${enable_fuse}" != "no")
+
 AC_OUTPUT(Makefile)
-- 
1.7.8.6


^ permalink raw reply related

* [RFC obexd 01/11] fuse: Add initial gobexfuse files, fuse main and options parse
From: Michał Poczwardowski @ 2012-10-09 18:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Michał Poczwardowski

---
 fuse/gobexfuse.c |  119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fuse/helpers.c   |   55 +++++++++++++++++++++++++
 fuse/helpers.h   |   49 ++++++++++++++++++++++
 3 files changed, 223 insertions(+), 0 deletions(-)
 create mode 100644 fuse/gobexfuse.c
 create mode 100644 fuse/helpers.c
 create mode 100644 fuse/helpers.h

diff --git a/fuse/gobexfuse.c b/fuse/gobexfuse.c
new file mode 100644
index 0000000..d9709fd
--- /dev/null
+++ b/fuse/gobexfuse.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 gobexfuse_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 gobexfuse_oper = {
+};
+
+static int gobexfuse_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"
+				"gobexfuse 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, &gobexfuse_oper, NULL);
+		exit(1);
+	case KEY_VERSION:
+		g_print("gobexfuse upon:\n");
+		fuse_opt_add_arg(outargs, "--version");
+		fuse_main(outargs->argc, outargs->argv, &gobexfuse_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, gobexfuse_opts,
+				gobexfuse_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, &gobexfuse_oper, NULL);
+
+	fuse_opt_free_args(&args);
+	return retfuse;
+}
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;
+};
+
-- 
1.7.8.6


^ permalink raw reply related

* [PATCH BlueZ] build-sys: Remove leftover AM_YFLAGS
From: Lucas De Marchi @ 2012-10-09 17:51 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lucas De Marchi

---
 Makefile.am | 2 --
 1 file changed, 2 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index dbbd794..35b1520 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -405,8 +405,6 @@ EXTRA_DIST += doc/manager-api.txt \
 		doc/oob-api.txt doc/proximity-api.txt doc/heartrate-api.txt \
 		doc/thermometer-api.txt
 
-AM_YFLAGS = -d
-
 AM_CFLAGS += @DBUS_CFLAGS@ @GLIB_CFLAGS@
 
 AM_CPPFLAGS = -I$(builddir)/lib -I$(builddir)/src -I$(srcdir)/src \
-- 
1.7.12.2


^ permalink raw reply related

* Re: [PATCH] build: Add missing documentation files to EXTRA_DIST
From: Lucas De Marchi @ 2012-10-09 17:42 UTC (permalink / raw)
  To: Andrzej Kaczmarek; +Cc: linux-bluetooth
In-Reply-To: <1349790707-8464-1-git-send-email-andrzej.kaczmarek@tieto.com>

On Tue, Oct 9, 2012 at 10:51 AM, Andrzej Kaczmarek
<andrzej.kaczmarek@tieto.com> wrote:
> This patch adds missing documentation files to EXTRA_DIST variable so they
> are included when creating tarball.
> ---
>  Makefile.am | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/Makefile.am b/Makefile.am
> index 3b08f9a..dbbd794 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -401,7 +401,9 @@ EXTRA_DIST += doc/manager-api.txt \
>                 doc/network-api.txt doc/input-api.txt doc/audio-api.txt \
>                 doc/control-api.txt doc/hfp-api.txt doc/health-api.txt \
>                 doc/sap-api.txt doc/media-api.txt doc/assigned-numbers.txt \
> -               doc/supported-features.txt doc/alert-api.txt
> +               doc/supported-features.txt doc/alert-api.txt doc/mgmt-api.txt \
> +               doc/oob-api.txt doc/proximity-api.txt doc/heartrate-api.txt \
> +               doc/thermometer-api.txt
>
>  AM_YFLAGS = -d

Not related, but... what's this AM_YFLAGS doing in here? I'm sending a
patch to fix this


Lucas De Marchi

^ permalink raw reply

* [PATCH BlueZ] core: fix stop scanning after GCEP
From: João Paulo Rechi Vita @ 2012-10-09 17:38 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: João Paulo Rechi Vita

The session type identification on struct session req (commit 328661a0)
broke the stop condition of the LE Genereal Connection Establishment
Procedure. This commit creates new identificators for discovery sessions
and makes their naming a bit more clear.
---
 src/adapter.c | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index b6c1213..ad8ee06 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -87,8 +87,10 @@
 static GSList *adapter_drivers = NULL;
 
 enum session_req_type {
-	SESSION_REQ_TYPE_GLOBAL = 0,
-	SESSION_REQ_TYPE_SESSION,
+	SESSION_TYPE_MODE_GLOBAL = 0,
+	SESSION_TYPE_MODE_SESSION,
+	SESSION_TYPE_DISC_INTERLEAVED,
+	SESSION_TYPE_DISC_LE_SCAN
 };
 
 struct session_req {
@@ -345,7 +347,7 @@ static void set_session_pending_mode(struct btd_adapter *adapter,
 		session_ref(req);
 	} else
 		adapter->pending_mode = create_session(adapter, msg, new_mode,
-					SESSION_REQ_TYPE_SESSION, NULL);
+					SESSION_TYPE_MODE_SESSION, NULL);
 }
 
 static void set_discoverable(struct btd_adapter *adapter,
@@ -369,7 +371,7 @@ static void set_discoverable(struct btd_adapter *adapter,
 						strerror(-err));
 
 	adapter->pending_mode = create_session(adapter, NULL, mode,
-						SESSION_REQ_TYPE_GLOBAL, NULL);
+					SESSION_TYPE_MODE_GLOBAL, NULL);
 	adapter->pending_mode->prop_id = id;
 }
 
@@ -400,7 +402,7 @@ static void set_powered(struct btd_adapter *adapter, gboolean powered,
 						strerror(-err));
 
 	adapter->pending_mode = create_session(adapter, NULL, mode,
-						SESSION_REQ_TYPE_GLOBAL, NULL);
+					SESSION_TYPE_MODE_GLOBAL, NULL);
 	adapter->pending_mode->prop_id = id;
 }
 
@@ -560,7 +562,7 @@ static void session_remove(struct session_req *req)
 	struct btd_adapter *adapter = req->adapter;
 
 	/* Ignore global requests */
-	if (req->type == SESSION_REQ_TYPE_GLOBAL)
+	if (req->type == SESSION_TYPE_MODE_GLOBAL)
 		return;
 
 	DBG("%s session %p with %s deactivated",
@@ -1072,7 +1074,7 @@ static DBusMessage *adapter_start_discovery(DBusConnection *conn,
 		return btd_error_failed(msg, strerror(-err));
 
 done:
-	req = create_session(adapter, msg, 0, SESSION_REQ_TYPE_GLOBAL,
+	req = create_session(adapter, msg, 0, SESSION_TYPE_DISC_INTERLEAVED,
 							session_owner_exit);
 
 	adapter->disc_sessions = g_slist_append(adapter->disc_sessions, req);
@@ -1385,7 +1387,7 @@ static DBusMessage *request_session(DBusConnection *conn,
 		return dbus_message_new_method_return(msg);
 	} else {
 		req = create_session(adapter, msg, new_mode,
-				SESSION_REQ_TYPE_SESSION, session_owner_exit);
+				SESSION_TYPE_MODE_SESSION, session_owner_exit);
 		adapter->mode_sessions = g_slist_append(adapter->mode_sessions,
 							req);
 	}
@@ -2381,7 +2383,8 @@ void adapter_connect_list_add(struct btd_adapter *adapter,
 	if (adapter->disc_sessions == NULL)
 		adapter->discov_id = g_idle_add(discovery_cb, adapter);
 
-	req = create_session(adapter, NULL, 0, SESSION_REQ_TYPE_GLOBAL, NULL);
+	req = create_session(adapter, NULL, 0, SESSION_TYPE_DISC_LE_SCAN,
+									NULL);
 	adapter->disc_sessions = g_slist_append(adapter->disc_sessions, req);
 	adapter->scanning_session = req;
 }
@@ -2431,7 +2434,8 @@ void btd_adapter_start(struct btd_adapter *adapter)
 					adapter->disc_sessions != NULL)
 		return;
 
-	req = create_session(adapter, NULL, 0, SESSION_REQ_TYPE_GLOBAL, NULL);
+	req = create_session(adapter, NULL, 0, SESSION_TYPE_DISC_LE_SCAN,
+									NULL);
 	adapter->disc_sessions = g_slist_append(adapter->disc_sessions, req);
 	adapter->scanning_session = req;
 
@@ -2509,7 +2513,7 @@ static void set_mode_complete(struct btd_adapter *adapter)
 
 	err = (pending->mode != adapter->mode) ? -EINVAL : 0;
 
-	if (pending->type == SESSION_REQ_TYPE_GLOBAL) {
+	if (pending->type == SESSION_TYPE_MODE_GLOBAL) {
 		if (err < 0)
 			g_dbus_pending_property_error(conn, pending->prop_id,
 						ERROR_INTERFACE ".Failed",
-- 
1.7.11.4


^ permalink raw reply related

* Re: [RFC BlueZ 3/5] hog: Use the per handle GATT event notifier
From: Vinicius Costa Gomes @ 2012-10-09 17:22 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1349742372-18420-4-git-send-email-vinicius.gomes@openbossa.org>

Hi,

On 21:26 Mon 08 Oct, Vinicius Costa Gomes wrote:
> ---
>  profiles/input/hog_device.c | 66 ++++++++++++++++++++++++---------------------
>  1 file changed, 36 insertions(+), 30 deletions(-)
> 
> diff --git a/profiles/input/hog_device.c b/profiles/input/hog_device.c
> index 52ebd95..34f4a41 100644
> --- a/profiles/input/hog_device.c
> +++ b/profiles/input/hog_device.c
> @@ -154,22 +134,31 @@ static void report_value_cb(const uint8_t *pdu, uint16_t len,
>  static void report_ccc_written_cb(guint8 status, const guint8 *pdu,
>  					guint16 plen, gpointer user_data)
>  {
> +	struct report *report = user_data;
> +	struct hog_device *hogdev = report->hogdev;
> +
>  	if (status != 0) {
>  		error("Write report characteristic descriptor failed: %s",
>  							att_ecode2str(status));
>  		return;
>  	}
>  
> +	report->notifyid = g_attrib_register(hogdev->attrib,
> +					ATT_OP_HANDLE_NOTIFY,
> +					report->decl->value_handle,
> +					report_value_cb, report, NULL);
> +
>  	DBG("Report characteristic descriptor written: notifications enabled");
>  }
>  
>  static void write_ccc(uint16_t handle, gpointer user_data)
>  {
> -	struct hog_device *hogdev = user_data;
> +	struct report *report = user_data;
> +	struct hog_device *hogdev = report->hogdev;
>  	uint8_t value[] = { 0x01, 0x00 };
>  
>  	gatt_write_char(hogdev->attrib, handle, value, sizeof(value),
> -					report_ccc_written_cb, hogdev);
> +					report_ccc_written_cb, report);
>  }

There's a bug in this patch. So please consider it just as a proof of
concept.


Cheers,
-- 
Vinicius

^ permalink raw reply

* Re: [PATCH 7/7] adapter: Move saved config to ini-file format
From: Anderson Lizardo @ 2012-10-09 17:04 UTC (permalink / raw)
  To: Frédéric Danis; +Cc: linux-bluetooth
In-Reply-To: <1349798318-12689-8-git-send-email-frederic.danis@linux.intel.com>

Hi Frédéric,

On Tue, Oct 9, 2012 at 11:58 AM, Frédéric Danis
<frederic.danis@linux.intel.com> wrote:
> +       if (read_pairable_timeout(address, &timeout) == 0)
> +               g_key_file_set_integer(key_file, "General",
> +                                               "PairableTimeout", timeout);
> +
> +       if (read_pairable_timeout(address, &timeout) == 0)
> +               g_key_file_set_integer(key_file, "General",
> +                                               "DiscoverableTimeout", timeout);
> +

This second if() should use read_discoverable_timeout().

Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply

* Re: [PATCH] build: Add missing documentation files to EXTRA_DIST
From: Johan Hedberg @ 2012-10-09 16:47 UTC (permalink / raw)
  To: Andrzej Kaczmarek; +Cc: linux-bluetooth
In-Reply-To: <1349790707-8464-1-git-send-email-andrzej.kaczmarek@tieto.com>

Hi Andrzej,

On Tue, Oct 09, 2012, Andrzej Kaczmarek wrote:
> This patch adds missing documentation files to EXTRA_DIST variable so they
> are included when creating tarball.
> ---
>  Makefile.am | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)

Applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH BlueZ 1/2] audio: Fix memory leak of AVDTP buffer
From: Johan Hedberg @ 2012-10-09 16:44 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1349798633-28071-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Tue, Oct 09, 2012, Luiz Augusto von Dentz wrote:
> Upon disconnection all references to AVDTP session should be release
> otherwise the data associate with it cannot be freed and new connection
> may overwrite the buf pointer causing it to leak.
> ---
>  audio/sink.c   | 8 ++++++++
>  audio/source.c | 8 ++++++++
>  2 files changed, 16 insertions(+)

Both patches have been applied. Thanks.

Johan

^ 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