* Virtual cable unplug not supported in BlueZ?
From: Liang Bao @ 2010-07-20 9:30 UTC (permalink / raw)
To: linux-bluetooth
Hi,
I have a question on "Virtual Cable Unplug" in current BlueZ version.
Currently BlueZ doesn't expose a D-Bus method in input/device.c for
virtually unplug cable which is a mandatory requirement to pass
TC_HOS_HCR_BV_03_I. Actually the support in kernel is already there.
Can anyone give some insight to why this is not exposed at the DBUS
API level like Connect/Disconnect/GetProperties? Can I think the
reason behind this design is we only need one of "Disconnect" and
"VirtualUnplug" to allow user to disconnect?
Thanks.
Regards,
Liang Bao
^ permalink raw reply
* Re: Virtual cable unplug not supported in BlueZ?
From: Johan Hedberg @ 2010-07-20 9:37 UTC (permalink / raw)
To: Liang Bao; +Cc: linux-bluetooth
In-Reply-To: <AANLkTimYuaveU7To6oLdtDLlxXIky1KU7QHMTD47Mwwh@mail.gmail.com>
Hi,
On Tue, Jul 20, 2010, Liang Bao wrote:
> I have a question on "Virtual Cable Unplug" in current BlueZ version.
>
> Currently BlueZ doesn't expose a D-Bus method in input/device.c for
> virtually unplug cable which is a mandatory requirement to pass
> TC_HOS_HCR_BV_03_I. Actually the support in kernel is already there.
> Can anyone give some insight to why this is not exposed at the DBUS
> API level like Connect/Disconnect/GetProperties? Can I think the
> reason behind this design is we only need one of "Disconnect" and
> "VirtualUnplug" to allow user to disconnect?
AFAIK the unplug should be sent when you do Adapter.RemoveDevice()
Johan
^ permalink raw reply
* Re: [PATCH] add variable target size support in obex_mime_type_driver_find()
From: Luiz Augusto von Dentz @ 2010-07-20 10:35 UTC (permalink / raw)
To: Marcel Mol; +Cc: linux-bluetooth
In-Reply-To: <201007190815.o6J8F4ib013820@joshua.mesa.nl>
Hi Marcel,
On Mon, Jul 19, 2010 at 10:44 AM, Marcel Mol <marcel@mesa.nl> wrote:
> targets for mime type drivers are not always fixed to TARGET_SIZE.
> (ifix started by Pierre Ossman)
>
> Signed-off-by: Marcel Mol <marcel@mesa.nl>
> ---
> plugins/filesystem.c | 3 +++
> plugins/nokia-backup.c | 1 +
> plugins/pbap.c | 3 +++
> plugins/syncevolution.c | 1 +
> src/mimetype.c | 14 ++++++++------
> src/mimetype.h | 2 ++
> src/obex.c | 10 ++++++++--
> 7 files changed, 26 insertions(+), 8 deletions(-)
>
> diff --git a/plugins/filesystem.c b/plugins/filesystem.c
> index 9fe4f00..f0e5bbe 100644
> --- a/plugins/filesystem.c
> +++ b/plugins/filesystem.c
> @@ -550,6 +550,7 @@ static struct obex_mime_type_driver file = {
>
> static struct obex_mime_type_driver capability = {
> .target = FTP_TARGET,
> + .target_size = TARGET_SIZE,
> .mimetype = "x-obex/capability",
> .open = capability_open,
> .close = capability_close,
> @@ -558,6 +559,7 @@ static struct obex_mime_type_driver capability = {
>
> static struct obex_mime_type_driver folder = {
> .target = FTP_TARGET,
> + .target_size = TARGET_SIZE,
> .mimetype = "x-obex/folder-listing",
> .open = folder_open,
> .close = string_free,
> @@ -566,6 +568,7 @@ static struct obex_mime_type_driver folder = {
>
> static struct obex_mime_type_driver pcsuite = {
> .target = FTP_TARGET,
> + .target_size = TARGET_SIZE,
> .who = PCSUITE_WHO,
> .who_size = PCSUITE_WHO_SIZE,
> .mimetype = "x-obex/folder-listing",
> diff --git a/plugins/nokia-backup.c b/plugins/nokia-backup.c
> index dffc5cd..1fe3fc5 100644
> --- a/plugins/nokia-backup.c
> +++ b/plugins/nokia-backup.c
> @@ -276,6 +276,7 @@ static ssize_t backup_write(void *object, const void *buf, size_t count)
>
> static struct obex_mime_type_driver backup = {
> .target = FTP_TARGET,
> + .target_size = TARGET_SIZE
> .mimetype = "application/vnd.nokia-backup",
> .open = backup_open,
> .close = backup_close,
> diff --git a/plugins/pbap.c b/plugins/pbap.c
> index 3c8e33e..af4b452 100644
> --- a/plugins/pbap.c
> +++ b/plugins/pbap.c
> @@ -861,6 +861,7 @@ static int vobject_close(void *object)
>
> static struct obex_mime_type_driver mime_pull = {
> .target = PBAP_TARGET,
> + .target_size = TARGET_SIZE,
> .mimetype = "x-bt/phonebook",
> .open = vobject_pull_open,
> .close = vobject_close,
> @@ -869,6 +870,7 @@ static struct obex_mime_type_driver mime_pull = {
>
> static struct obex_mime_type_driver mime_list = {
> .target = PBAP_TARGET,
> + .target_size = TARGET_SIZE,
> .mimetype = "x-bt/vcard-listing",
> .open = vobject_list_open,
> .close = vobject_close,
> @@ -877,6 +879,7 @@ static struct obex_mime_type_driver mime_list = {
>
> static struct obex_mime_type_driver mime_vcard = {
> .target = PBAP_TARGET,
> + .target_size = TARGET_SIZE,
> .mimetype = "x-bt/vcard",
> .open = vobject_vcard_open,
> .close = vobject_close,
> diff --git a/plugins/syncevolution.c b/plugins/syncevolution.c
> index 55709df..970ce29 100644
> --- a/plugins/syncevolution.c
> +++ b/plugins/syncevolution.c
> @@ -443,6 +443,7 @@ static ssize_t synce_write(void *object, const void *buf, size_t count)
>
> static struct obex_mime_type_driver synce_driver = {
> .target = SYNCML_TARGET,
> + .target_size = SYNCML_TARGET_SIZE,
> .open = synce_open,
> .close = synce_close,
> .read = synce_read,
> diff --git a/src/mimetype.c b/src/mimetype.c
> index 7b96ec2..7df1308 100644
> --- a/src/mimetype.c
> +++ b/src/mimetype.c
> @@ -118,6 +118,7 @@ static int set_io_watch(void *object, obex_object_io_func func,
> }
>
> static struct obex_mime_type_driver *find_driver(const uint8_t *target,
> + unsigned int target_size,
> const char *mimetype, const uint8_t *who,
> unsigned int who_size)
> {
> @@ -126,7 +127,7 @@ static struct obex_mime_type_driver *find_driver(const uint8_t *target,
> for (l = drivers; l; l = l->next) {
> struct obex_mime_type_driver *driver = l->data;
>
> - if (memcmp0(target, driver->target, TARGET_SIZE))
> + if (memcmp0(target, driver->target, target_size))
> continue;
>
> if (memcmp0(who, driver->who, who_size))
> @@ -140,27 +141,28 @@ static struct obex_mime_type_driver *find_driver(const uint8_t *target,
> }
>
> struct obex_mime_type_driver *obex_mime_type_driver_find(const uint8_t *target,
> + unsigned int target_size,
> const char *mimetype, const uint8_t *who,
> unsigned int who_size)
> {
> struct obex_mime_type_driver *driver;
>
> - driver = find_driver(target, mimetype, who, who_size);
> + driver = find_driver(target, target_size, mimetype, who, who_size);
> if (driver == NULL) {
> if (who != NULL) {
> /* Fallback to non-who specific */
> - driver = find_driver(target, mimetype, NULL, 0);
> + driver = find_driver(target, target_size, mimetype, NULL, 0);
> if (driver != NULL)
> return driver;
> }
>
> if (mimetype != NULL)
> /* Fallback to target default */
> - driver = find_driver(target, NULL, NULL, 0);
> + driver = find_driver(target, target_size, NULL, NULL, 0);
>
> if (driver == NULL)
> /* Fallback to general default */
> - driver = find_driver(NULL, NULL, NULL, 0);
> + driver = find_driver(NULL, 0, NULL, NULL, 0);
> }
>
> return driver;
> @@ -173,7 +175,7 @@ int obex_mime_type_driver_register(struct obex_mime_type_driver *driver)
> return -EINVAL;
> }
>
> - if (find_driver(driver->target, driver->mimetype,
> + if (find_driver(driver->target, driver->target_size, driver->mimetype,
> driver->who, driver->who_size)) {
> error("Permission denied: %s could not be registered",
> driver->mimetype);
> diff --git a/src/mimetype.h b/src/mimetype.h
> index 4cb3156..200b950 100644
> --- a/src/mimetype.h
> +++ b/src/mimetype.h
> @@ -26,6 +26,7 @@ typedef gboolean (*obex_object_io_func) (void *object, int flags, int err,
>
> struct obex_mime_type_driver {
> const uint8_t *target;
> + unsigned int target_size;
> const char *mimetype;
> const uint8_t *who;
> unsigned int who_size;
> @@ -42,6 +43,7 @@ struct obex_mime_type_driver {
> int obex_mime_type_driver_register(struct obex_mime_type_driver *driver);
> void obex_mime_type_driver_unregister(struct obex_mime_type_driver *driver);
> struct obex_mime_type_driver *obex_mime_type_driver_find(const uint8_t *target,
> + unsigned int target_size,
> const char *mimetype, const uint8_t *who,
> unsigned int who_size);
>
> diff --git a/src/obex.c b/src/obex.c
> index db04bfd..21788ba 100644
> --- a/src/obex.c
> +++ b/src/obex.c
> @@ -763,7 +763,9 @@ static void cmd_get(struct obex_session *os, obex_t *obex, obex_object_t *obj)
> os->type = g_strndup((const char *) hd.bs, hlen);
> DBG("OBEX_HDR_TYPE: %s", os->type);
> os->driver = obex_mime_type_driver_find(
> - os->service->target, os->type,
> + os->service->target,
> + os->service->target_size,
> + os->type,
> os->service->who,
> os->service->who_size);
> break;
> @@ -772,6 +774,7 @@ static void cmd_get(struct obex_session *os, obex_t *obex, obex_object_t *obj)
>
> if (os->type == NULL)
> os->driver = obex_mime_type_driver_find(os->service->target,
> + os->service->target_size,
> NULL,
> os->service->who,
> os->service->who_size);
> @@ -977,7 +980,9 @@ static gboolean check_put(obex_t *obex, obex_object_t *obj)
> os->type = g_strndup((const char *) hd.bs, hlen);
> DBG("OBEX_HDR_TYPE: %s", os->type);
> os->driver = obex_mime_type_driver_find(
> - os->service->target, os->type,
> + os->service->target,
> + os->service->target_size,
> + os->type,
> os->service->who,
> os->service->who_size);
> break;
> @@ -1001,6 +1006,7 @@ static gboolean check_put(obex_t *obex, obex_object_t *obj)
>
> if (os->type == NULL)
> os->driver = obex_mime_type_driver_find(os->service->target,
> + os->service->target_size,
> NULL,
> os->service->who,
> os->service->who_size);
> --
> 1.7.1.1
>
Could you please rebase this, we had changed memcmp0 so it takes both
buffer sizes and check them, this should conflict with this change but
it should be easy to resolve, also remember to replace TARGET_SIZE
with proper buffer sizes when fixing this.
--
Luiz Augusto von Dentz
Computer Engineer
^ permalink raw reply
* [PATCH] Fixed problem with incoming calls query
From: Rafal Michalski @ 2010-07-20 11:04 UTC (permalink / raw)
To: linux-bluetooth
From: Rafal Michalski <rafal.michalski@comarch.com>
After making some incoming, outgoing, missed calls, history lists of them
(ich, och, mch) are stored on device. In current implementation queries
towards tracker for incoming calls include also missed calls.
So list for incoming calls displayed on paired BT headset/carkit screen
(e.g. BH-903, CK-200) also contains numbers from missed calls list.
To block adding missed calls list numbers to incoming calls there should
be added info that incoming call is in fact only answered call. So macros
additionally include info: "nmo:isAnswered true ." Without this, missed
calls was treated as incoming calls.
---
plugins/phonebook-tracker.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 89c612e..98b6410 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -125,6 +125,7 @@
"?call a nmo:Call ; " \
"nmo:from ?c ; " \
"nmo:isSent false . " \
+ "nmo:isAnswered true ." \
"?c a nco:Contact . " \
"OPTIONAL { ?c nco:hasPhoneNumber ?h . } " \
"OPTIONAL { ?c nco:hasEmailAddress ?e . } " \
@@ -144,6 +145,7 @@
"?call a nmo:Call ; " \
"nmo:from ?c ; " \
"nmo:isSent false . " \
+ "nmo:isAnswered true ." \
"?c a nco:Contact . " \
"OPTIONAL { ?c nco:hasPhoneNumber ?h . } " \
"} ORDER BY DESC(nmo:receivedDate(?call))"
--
1.6.3.3
^ permalink raw reply related
* Re: obex-client: doesn't allways closes socket
From: Luiz Augusto von Dentz @ 2010-07-20 11:16 UTC (permalink / raw)
To: Vitja Makarov; +Cc: linux-bluetooth
In-Reply-To: <AANLkTikcX6_SydJf4YRG3ym4Q0GVGQ26WpAh3Mm1uyyQ@mail.gmail.com>
Hi,
On Tue, Jul 20, 2010 at 10:12 AM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
> Hi!
>
> Recently I've found that obex client doesn't allways close socket, I
> was using obexd-0.29...
> Even more sometimes it closes same socket twice using
> g_io_channel_unref() and close()
I guess the real ones are gw_obex_close and close, so both end up
closing the same fd.
> When it comes to client/session.c:rfcomm_connect() with error,
> session->sock is not set and socket is not closed on
> session_shutdown()
> Don't know why g_io_channel_unref() isn't called for that socket..
Yep, there is no much point on storing the fd on session->sock in the
other hand the io that bt_io_connect gives is the one causing the
problem here, either we release this reference and then we have to set
not to close the fd or we just keep the io reference and store it on
session so we can actually cancel the connection attempt.
--
Luiz Augusto von Dentz
Computer Engineer
^ permalink raw reply
* Re: [PATCH] Fixed problem with incoming calls query
From: Luiz Augusto von Dentz @ 2010-07-20 11:25 UTC (permalink / raw)
To: Rafal Michalski; +Cc: linux-bluetooth
In-Reply-To: <1279623875-9870-1-git-send-email-rafal.michalski@comarch.com>
Hi Rafal,
On Tue, Jul 20, 2010 at 2:04 PM, Rafal Michalski
<rafal.michalski@comarch.com> wrote:
> From: Rafal Michalski <rafal.michalski@comarch.com>
>
> After making some incoming, outgoing, missed calls, history lists of them
> (ich, och, mch) are stored on device. In current implementation queries
> towards tracker for incoming calls include also missed calls.
> So list for incoming calls displayed on paired BT headset/carkit screen
> (e.g. BH-903, CK-200) also contains numbers from missed calls list.
>
> To block adding missed calls list numbers to incoming calls there should
> be added info that incoming call is in fact only answered call. So macros
> additionally include info: "nmo:isAnswered true ." Without this, missed
> calls was treated as incoming calls.
> ---
> plugins/phonebook-tracker.c | 2 ++
> 1 files changed, 2 insertions(+), 0 deletions(-)
>
> diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
> index 89c612e..98b6410 100644
> --- a/plugins/phonebook-tracker.c
> +++ b/plugins/phonebook-tracker.c
> @@ -125,6 +125,7 @@
> "?call a nmo:Call ; " \
> "nmo:from ?c ; " \
> "nmo:isSent false . " \
> + "nmo:isAnswered true ." \
> "?c a nco:Contact . " \
> "OPTIONAL { ?c nco:hasPhoneNumber ?h . } " \
> "OPTIONAL { ?c nco:hasEmailAddress ?e . } " \
> @@ -144,6 +145,7 @@
> "?call a nmo:Call ; " \
> "nmo:from ?c ; " \
> "nmo:isSent false . " \
> + "nmo:isAnswered true ." \
> "?c a nco:Contact . " \
> "OPTIONAL { ?c nco:hasPhoneNumber ?h . } " \
> "} ORDER BY DESC(nmo:receivedDate(?call))"
> --
> 1.6.3.3
>
Actually this is not completely correct, this nmo are a list of
properties so only the last one will have the . , something like this:
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 89c612e..696b544 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -124,7 +124,8 @@
"WHERE { " \
"?call a nmo:Call ; " \
"nmo:from ?c ; " \
- "nmo:isSent false . " \
+ "nmo:isSent false ; " \
+ "nmo:isAnswered true ." \
"?c a nco:Contact . " \
"OPTIONAL { ?c nco:hasPhoneNumber ?h . } " \
"OPTIONAL { ?c nco:hasEmailAddress ?e . } " \
@@ -143,7 +144,8 @@
"WHERE { " \
"?call a nmo:Call ; " \
"nmo:from ?c ; " \
- "nmo:isSent false . " \
+ "nmo:isSent false ; " \
+ "nmo:isAnswered true ." \
"?c a nco:Contact . " \
"OPTIONAL { ?c nco:hasPhoneNumber ?h . } " \
"} ORDER BY DESC(nmo:receivedDate(?call))"
@@ -181,7 +183,7 @@
"nmo:to ?c ; " \
"nmo:isSent true . " \
"?c a nco:Contact . " \
- "OPTIONAL { ?c nco:hasPhoneNumber ?h . } " \
+ "OPTIONAL { ?c nco:hasPhoneNumber ?h . } " \
"} ORDER BY DESC(nmo:sentDate(?call))"
#define COMBINED_CALLS_QUERY \
--
1.6.1
--
Luiz Augusto von Dentz
Computer Engineer
^ permalink raw reply related
* [PATCH] Fixed problem with incoming calls query
From: Radoslaw Jablonski @ 2010-07-20 12:30 UTC (permalink / raw)
To: linux-bluetooth
From: Radoslaw Jablonski <ext-jablonski.radoslaw@nokia.com>
After making some incoming, outgoing, missed calls, history lists of them
(ich, och, mch) are stored on device. In current implementation queries
towards tracker for incoming calls include also missed calls.
So list for incoming calls displayed on paired BT headset/carkit screen
(e.g. BH-903, CK-200) also contains numbers from missed calls list.
To block adding missed calls list numbers to incoming calls there should
be added info that incoming call is in fact only answered call. So macros
additionally include info: "nmo:isAnswered true ." Without this, missed
calls was treated as incoming calls.
---
plugins/phonebook-tracker.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 89c612e..ee072d3 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -124,7 +124,8 @@
"WHERE { " \
"?call a nmo:Call ; " \
"nmo:from ?c ; " \
- "nmo:isSent false . " \
+ "nmo:isSent false ; " \
+ "nmo:isAnswered true ." \
"?c a nco:Contact . " \
"OPTIONAL { ?c nco:hasPhoneNumber ?h . } " \
"OPTIONAL { ?c nco:hasEmailAddress ?e . } " \
@@ -143,7 +144,8 @@
"WHERE { " \
"?call a nmo:Call ; " \
"nmo:from ?c ; " \
- "nmo:isSent false . " \
+ "nmo:isSent false ; " \
+ "nmo:isAnswered true ." \
"?c a nco:Contact . " \
"OPTIONAL { ?c nco:hasPhoneNumber ?h . } " \
"} ORDER BY DESC(nmo:receivedDate(?call))"
--
1.6.3.3
^ permalink raw reply related
* Re: [PATCH] Fixed problem with incoming calls query
From: Hedberg Johan (Nokia-D/Helsinki) @ 2010-07-20 12:35 UTC (permalink / raw)
To: Radoslaw Jablonski; +Cc: linux-bluetooth
In-Reply-To: <1279629030-10504-1-git-send-email-ext-jablonski.radoslaw@nokia.com>
Hi,
On Tue, Jul 20, 2010, Radoslaw Jablonski wrote:
> After making some incoming, outgoing, missed calls, history lists of them
> (ich, och, mch) are stored on device. In current implementation queries
> towards tracker for incoming calls include also missed calls.
> So list for incoming calls displayed on paired BT headset/carkit screen
> (e.g. BH-903, CK-200) also contains numbers from missed calls list.
>
> To block adding missed calls list numbers to incoming calls there should
> be added info that incoming call is in fact only answered call. So macros
> additionally include info: "nmo:isAnswered true ." Without this, missed
> calls was treated as incoming calls.
> ---
> plugins/phonebook-tracker.c | 6 ++++--
> 1 files changed, 4 insertions(+), 2 deletions(-)
Thanks for the patch. It has now been pushed upstream.
Johan
^ permalink raw reply
* Re: obex-client: doesn't allways closes socket
From: Vitja Makarov @ 2010-07-20 13:16 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <AANLkTimicKT1FS2G3MDtVha5AWLp_wV2rtW35MfHFro6@mail.gmail.com>
2010/7/20 Luiz Augusto von Dentz <luiz.dentz@gmail.com>:
> Hi,
>
> On Tue, Jul 20, 2010 at 2:46 PM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
>> 2010/7/20 Luiz Augusto von Dentz <luiz.dentz@gmail.com>:
>>> Hi,
>>>
>>> On Tue, Jul 20, 2010 at 10:12 AM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
>>>> Hi!
>>>>
>>>> Recently I've found that obex client doesn't allways close socket, I
>>>> was using obexd-0.29...
>>>> Even more sometimes it closes same socket twice using
>>>> g_io_channel_unref() and close()
>>>
>>> I guess the real ones are gw_obex_close and close, so both end up
>>> closing the same fd.
>>>
>>>> When it comes to client/session.c:rfcomm_connect() with error,
>>>> session->sock is not set and socket is not closed on
>>>> session_shutdown()
>>>> Don't know why g_io_channel_unref() isn't called for that socket..
>>>
>>> Yep, there is no much point on storing the fd on session->sock in the
>>> other hand the io that bt_io_connect gives is the one causing the
>>> problem here, either we release this reference and then we have to set
>>> not to close the fd or we just keep the io reference and store it on
>>> session so we can actually cancel the connection attempt.
>>>
>>
>> My application does send files using obex-client to all available
>> devices, after 4-5 hours obex client can't create sockets anymore (it
>> fails with ENFILE, Too many open files), making obex-client absolutely
>> unusable.
>>
>> As workaround I set session->fd even if error was detected, then
>> socket will be properly closed.
>> It seems to me that here is memory leak also.
>>
>> vitja.
>>
>
> Can you check if the patch bellow fix those issues:
>
> diff --git a/client/session.c b/client/session.c
> index 334ade4..d761bfb 100644
> --- a/client/session.c
> +++ b/client/session.c
> @@ -173,8 +173,10 @@ static void session_free(struct session_data *session)
> if (session->obex != NULL)
> gw_obex_close(session->obex);
>
> - if (session->sock > 2)
> - close(session->sock);
> + if (session->io != NULL) {
> + g_io_channel_shutdown(session->io, TRUE, NULL);
> + g_io_channel_unref(session->io);
> + }
>
> if (session->path)
> session_unregistered(session);
> @@ -215,13 +217,17 @@ static void rfcomm_callback(GIOChannel *io,
> GError *err, gpointer user_data)
> goto done;
> }
>
> + /* do not close when gw_obex is using the fd */
> + g_io_channel_set_close_on_unref(session->io, FALSE);
> + g_io_channel_unref(session->io);
> + session->io = NULL;
> +
> fd = g_io_channel_unix_get_fd(io);
>
> obex = gw_obex_setup_fd(fd, session->target,
> session->target_len, NULL, NULL);
>
> - callback->session->sock = fd;
> - callback->session->obex = obex;
> + session->obex = obex;
>
> done:
> callback->func(callback->session, callback->data);
> @@ -231,9 +237,9 @@ done:
> g_free(callback);
> }
>
> -static int rfcomm_connect(const bdaddr_t *src,
> - const bdaddr_t *dst, uint8_t channel,
> - BtIOConnect function, gpointer user_data)
> +static GIOChannel *rfcomm_connect(const bdaddr_t *src, const bdaddr_t *dst,
> + uint8_t channel, BtIOConnect function,
> + gpointer user_data)
> {
> GIOChannel *io;
> GError *err = NULL;
> @@ -245,11 +251,11 @@ static int rfcomm_connect(const bdaddr_t *src,
> BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
> BT_IO_OPT_INVALID);
> if (io != NULL)
> - return 0;
> + return io;
>
> error("%s", err->message);
> g_error_free(err);
> - return -EIO;
> + return NULL;
> }
>
> static void search_callback(uint8_t type, uint16_t status,
> @@ -309,8 +315,11 @@ static void search_callback(uint8_t type, uint16_t status,
>
> callback->session->channel = channel;
>
> - if (rfcomm_connect(&callback->session->src, &callback->session->dst,
> - channel, rfcomm_callback, callback) == 0) {
> + callback->session->io = rfcomm_connect(&callback->session->src,
> + &callback->session->dst,
> + channel, rfcomm_callback,
> + callback);
> + if (callback->session->io != NULL) {
> sdp_close(callback->sdp);
> return;
> }
> @@ -418,7 +427,6 @@ struct session_data *session_create(const char *source,
> return NULL;
>
> session->refcount = 1;
> - session->sock = -1;
> session->channel = channel;
>
> session->conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
> @@ -465,8 +473,11 @@ struct session_data *session_create(const char *source,
> callback->data = user_data;
>
> if (session->channel > 0) {
> - err = rfcomm_connect(&session->src, &session->dst,
> - session->channel, rfcomm_callback, callback);
> + session->io = rfcomm_connect(&session->src, &session->dst,
> + session->channel,
> + rfcomm_callback,
> + callback);
> + err = (session->io == NULL) ? -EINVAL : 0;
> } else {
> callback->sdp = service_connect(&session->src, &session->dst,
> service_callback, callback);
> diff --git a/client/session.h b/client/session.h
> index 73337cd..9451c25 100644
> --- a/client/session.h
> +++ b/client/session.h
> @@ -40,10 +40,10 @@ struct session_data {
> int target_len;
> uuid_t uuid; /* Bluetooth Service Class */
> gchar *path; /* Session path */
> - int sock;
> DBusConnection *conn;
> DBusMessage *msg;
> GwObex *obex;
> + GIOChannel *io;
> struct agent_data *agent;
> struct session_callback *callback;
> gchar *owner; /* Session owner */
>
>
>
> --
> Luiz Augusto von Dentz
> Computer Engineer
>
This seems to work, thanks
^ permalink raw reply
* Re: obex-client: doesn't allways closes socket
From: Vitja Makarov @ 2010-07-20 13:25 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <AANLkTikk6EAI4TTvm2YJCkDnEiwRDp-4km1TKQ8yomvx@mail.gmail.com>
2010/7/20 Vitja Makarov <vitja.makarov@gmail.com>:
> 2010/7/20 Luiz Augusto von Dentz <luiz.dentz@gmail.com>:
>> Hi,
>>
>> On Tue, Jul 20, 2010 at 2:46 PM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
>>> 2010/7/20 Luiz Augusto von Dentz <luiz.dentz@gmail.com>:
>>>> Hi,
>>>>
>>>> On Tue, Jul 20, 2010 at 10:12 AM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
>>>>> Hi!
>>>>>
>>>>> Recently I've found that obex client doesn't allways close socket, I
>>>>> was using obexd-0.29...
>>>>> Even more sometimes it closes same socket twice using
>>>>> g_io_channel_unref() and close()
>>>>
>>>> I guess the real ones are gw_obex_close and close, so both end up
>>>> closing the same fd.
>>>>
>>>>> When it comes to client/session.c:rfcomm_connect() with error,
>>>>> session->sock is not set and socket is not closed on
>>>>> session_shutdown()
>>>>> Don't know why g_io_channel_unref() isn't called for that socket..
>>>>
>>>> Yep, there is no much point on storing the fd on session->sock in the
>>>> other hand the io that bt_io_connect gives is the one causing the
>>>> problem here, either we release this reference and then we have to set
>>>> not to close the fd or we just keep the io reference and store it on
>>>> session so we can actually cancel the connection attempt.
>>>>
>>>
>>> My application does send files using obex-client to all available
>>> devices, after 4-5 hours obex client can't create sockets anymore (it
>>> fails with ENFILE, Too many open files), making obex-client absolutely
>>> unusable.
>>>
>>> As workaround I set session->fd even if error was detected, then
>>> socket will be properly closed.
>>> It seems to me that here is memory leak also.
>>>
>>> vitja.
>>>
>>
>> Can you check if the patch bellow fix those issues:
>>
>> diff --git a/client/session.c b/client/session.c
>> index 334ade4..d761bfb 100644
>> --- a/client/session.c
>> +++ b/client/session.c
>> @@ -173,8 +173,10 @@ static void session_free(struct session_data *session)
>> if (session->obex != NULL)
>> gw_obex_close(session->obex);
>>
>> - if (session->sock > 2)
>> - close(session->sock);
>> + if (session->io != NULL) {
>> + g_io_channel_shutdown(session->io, TRUE, NULL);
>> + g_io_channel_unref(session->io);
>> + }
>>
>> if (session->path)
>> session_unregistered(session);
>> @@ -215,13 +217,17 @@ static void rfcomm_callback(GIOChannel *io,
>> GError *err, gpointer user_data)
>> goto done;
>> }
>>
>> + /* do not close when gw_obex is using the fd */
>> + g_io_channel_set_close_on_unref(session->io, FALSE);
>> + g_io_channel_unref(session->io);
>> + session->io = NULL;
>> +
>> fd = g_io_channel_unix_get_fd(io);
>>
>> obex = gw_obex_setup_fd(fd, session->target,
>> session->target_len, NULL, NULL);
>>
>> - callback->session->sock = fd;
>> - callback->session->obex = obex;
>> + session->obex = obex;
>>
>> done:
>> callback->func(callback->session, callback->data);
>> @@ -231,9 +237,9 @@ done:
>> g_free(callback);
>> }
>>
>> -static int rfcomm_connect(const bdaddr_t *src,
>> - const bdaddr_t *dst, uint8_t channel,
>> - BtIOConnect function, gpointer user_data)
>> +static GIOChannel *rfcomm_connect(const bdaddr_t *src, const bdaddr_t *dst,
>> + uint8_t channel, BtIOConnect function,
>> + gpointer user_data)
>> {
>> GIOChannel *io;
>> GError *err = NULL;
>> @@ -245,11 +251,11 @@ static int rfcomm_connect(const bdaddr_t *src,
>> BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
>> BT_IO_OPT_INVALID);
>> if (io != NULL)
>> - return 0;
>> + return io;
>>
>> error("%s", err->message);
>> g_error_free(err);
>> - return -EIO;
>> + return NULL;
>> }
>>
>> static void search_callback(uint8_t type, uint16_t status,
>> @@ -309,8 +315,11 @@ static void search_callback(uint8_t type, uint16_t status,
>>
>> callback->session->channel = channel;
>>
>> - if (rfcomm_connect(&callback->session->src, &callback->session->dst,
>> - channel, rfcomm_callback, callback) == 0) {
>> + callback->session->io = rfcomm_connect(&callback->session->src,
>> + &callback->session->dst,
>> + channel, rfcomm_callback,
>> + callback);
>> + if (callback->session->io != NULL) {
>> sdp_close(callback->sdp);
>> return;
>> }
>> @@ -418,7 +427,6 @@ struct session_data *session_create(const char *source,
>> return NULL;
>>
>> session->refcount = 1;
>> - session->sock = -1;
>> session->channel = channel;
>>
>> session->conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
>> @@ -465,8 +473,11 @@ struct session_data *session_create(const char *source,
>> callback->data = user_data;
>>
>> if (session->channel > 0) {
>> - err = rfcomm_connect(&session->src, &session->dst,
>> - session->channel, rfcomm_callback, callback);
>> + session->io = rfcomm_connect(&session->src, &session->dst,
>> + session->channel,
>> + rfcomm_callback,
>> + callback);
>> + err = (session->io == NULL) ? -EINVAL : 0;
>> } else {
>> callback->sdp = service_connect(&session->src, &session->dst,
>> service_callback, callback);
>> diff --git a/client/session.h b/client/session.h
>> index 73337cd..9451c25 100644
>> --- a/client/session.h
>> +++ b/client/session.h
>> @@ -40,10 +40,10 @@ struct session_data {
>> int target_len;
>> uuid_t uuid; /* Bluetooth Service Class */
>> gchar *path; /* Session path */
>> - int sock;
>> DBusConnection *conn;
>> DBusMessage *msg;
>> GwObex *obex;
>> + GIOChannel *io;
>> struct agent_data *agent;
>> struct session_callback *callback;
>> gchar *owner; /* Session owner */
>>
>>
>>
>> --
>> Luiz Augusto von Dentz
>> Computer Engineer
>>
>
> This seems to work, thanks
>
One more question can some socket errors (GError) be forwarded to
dbus, so on client side I can get connection refused and so on,
messages?
That should be better than empty "dbus.exceptions.DBusException:
org.openobex.Error.Failed:" message
^ permalink raw reply
* Re: obex-client: doesn't allways closes socket
From: Luiz Augusto von Dentz @ 2010-07-20 13:58 UTC (permalink / raw)
To: Vitja Makarov; +Cc: linux-bluetooth
In-Reply-To: <AANLkTimLpLxxSwtUDledlnF3zOIVqtFP67KyoyAMGD_s@mail.gmail.com>
Hi,
On Tue, Jul 20, 2010 at 4:25 PM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
> 2010/7/20 Vitja Makarov <vitja.makarov@gmail.com>:
>> 2010/7/20 Luiz Augusto von Dentz <luiz.dentz@gmail.com>:
>>> Hi,
>>>
>>> On Tue, Jul 20, 2010 at 2:46 PM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
>>>> 2010/7/20 Luiz Augusto von Dentz <luiz.dentz@gmail.com>:
>>>>> Hi,
>>>>>
>>>>> On Tue, Jul 20, 2010 at 10:12 AM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
>>>>>> Hi!
>>>>>>
>>>>>> Recently I've found that obex client doesn't allways close socket, I
>>>>>> was using obexd-0.29...
>>>>>> Even more sometimes it closes same socket twice using
>>>>>> g_io_channel_unref() and close()
>>>>>
>>>>> I guess the real ones are gw_obex_close and close, so both end up
>>>>> closing the same fd.
>>>>>
>>>>>> When it comes to client/session.c:rfcomm_connect() with error,
>>>>>> session->sock is not set and socket is not closed on
>>>>>> session_shutdown()
>>>>>> Don't know why g_io_channel_unref() isn't called for that socket..
>>>>>
>>>>> Yep, there is no much point on storing the fd on session->sock in the
>>>>> other hand the io that bt_io_connect gives is the one causing the
>>>>> problem here, either we release this reference and then we have to set
>>>>> not to close the fd or we just keep the io reference and store it on
>>>>> session so we can actually cancel the connection attempt.
>>>>>
>>>>
>>>> My application does send files using obex-client to all available
>>>> devices, after 4-5 hours obex client can't create sockets anymore (it
>>>> fails with ENFILE, Too many open files), making obex-client absolutely
>>>> unusable.
>>>>
>>>> As workaround I set session->fd even if error was detected, then
>>>> socket will be properly closed.
>>>> It seems to me that here is memory leak also.
>>>>
>>>> vitja.
>>>>
>>>
>>> Can you check if the patch bellow fix those issues:
>>>
>>> diff --git a/client/session.c b/client/session.c
>>> index 334ade4..d761bfb 100644
>>> --- a/client/session.c
>>> +++ b/client/session.c
>>> @@ -173,8 +173,10 @@ static void session_free(struct session_data *session)
>>> if (session->obex != NULL)
>>> gw_obex_close(session->obex);
>>>
>>> - if (session->sock > 2)
>>> - close(session->sock);
>>> + if (session->io != NULL) {
>>> + g_io_channel_shutdown(session->io, TRUE, NULL);
>>> + g_io_channel_unref(session->io);
>>> + }
>>>
>>> if (session->path)
>>> session_unregistered(session);
>>> @@ -215,13 +217,17 @@ static void rfcomm_callback(GIOChannel *io,
>>> GError *err, gpointer user_data)
>>> goto done;
>>> }
>>>
>>> + /* do not close when gw_obex is using the fd */
>>> + g_io_channel_set_close_on_unref(session->io, FALSE);
>>> + g_io_channel_unref(session->io);
>>> + session->io = NULL;
>>> +
>>> fd = g_io_channel_unix_get_fd(io);
>>>
>>> obex = gw_obex_setup_fd(fd, session->target,
>>> session->target_len, NULL, NULL);
>>>
>>> - callback->session->sock = fd;
>>> - callback->session->obex = obex;
>>> + session->obex = obex;
>>>
>>> done:
>>> callback->func(callback->session, callback->data);
>>> @@ -231,9 +237,9 @@ done:
>>> g_free(callback);
>>> }
>>>
>>> -static int rfcomm_connect(const bdaddr_t *src,
>>> - const bdaddr_t *dst, uint8_t channel,
>>> - BtIOConnect function, gpointer user_data)
>>> +static GIOChannel *rfcomm_connect(const bdaddr_t *src, const bdaddr_t *dst,
>>> + uint8_t channel, BtIOConnect function,
>>> + gpointer user_data)
>>> {
>>> GIOChannel *io;
>>> GError *err = NULL;
>>> @@ -245,11 +251,11 @@ static int rfcomm_connect(const bdaddr_t *src,
>>> BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
>>> BT_IO_OPT_INVALID);
>>> if (io != NULL)
>>> - return 0;
>>> + return io;
>>>
>>> error("%s", err->message);
>>> g_error_free(err);
>>> - return -EIO;
>>> + return NULL;
>>> }
>>>
>>> static void search_callback(uint8_t type, uint16_t status,
>>> @@ -309,8 +315,11 @@ static void search_callback(uint8_t type, uint16_t status,
>>>
>>> callback->session->channel = channel;
>>>
>>> - if (rfcomm_connect(&callback->session->src, &callback->session->dst,
>>> - channel, rfcomm_callback, callback) == 0) {
>>> + callback->session->io = rfcomm_connect(&callback->session->src,
>>> + &callback->session->dst,
>>> + channel, rfcomm_callback,
>>> + callback);
>>> + if (callback->session->io != NULL) {
>>> sdp_close(callback->sdp);
>>> return;
>>> }
>>> @@ -418,7 +427,6 @@ struct session_data *session_create(const char *source,
>>> return NULL;
>>>
>>> session->refcount = 1;
>>> - session->sock = -1;
>>> session->channel = channel;
>>>
>>> session->conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
>>> @@ -465,8 +473,11 @@ struct session_data *session_create(const char *source,
>>> callback->data = user_data;
>>>
>>> if (session->channel > 0) {
>>> - err = rfcomm_connect(&session->src, &session->dst,
>>> - session->channel, rfcomm_callback, callback);
>>> + session->io = rfcomm_connect(&session->src, &session->dst,
>>> + session->channel,
>>> + rfcomm_callback,
>>> + callback);
>>> + err = (session->io == NULL) ? -EINVAL : 0;
>>> } else {
>>> callback->sdp = service_connect(&session->src, &session->dst,
>>> service_callback, callback);
>>> diff --git a/client/session.h b/client/session.h
>>> index 73337cd..9451c25 100644
>>> --- a/client/session.h
>>> +++ b/client/session.h
>>> @@ -40,10 +40,10 @@ struct session_data {
>>> int target_len;
>>> uuid_t uuid; /* Bluetooth Service Class */
>>> gchar *path; /* Session path */
>>> - int sock;
>>> DBusConnection *conn;
>>> DBusMessage *msg;
>>> GwObex *obex;
>>> + GIOChannel *io;
>>> struct agent_data *agent;
>>> struct session_callback *callback;
>>> gchar *owner; /* Session owner */
>>>
>>>
>>>
>>> --
>>> Luiz Augusto von Dentz
>>> Computer Engineer
>>>
>>
>> This seems to work, thanks
>>
>
> One more question can some socket errors (GError) be forwarded to
> dbus, so on client side I can get connection refused and so on,
> messages?
>
> That should be better than empty "dbus.exceptions.DBusException:
> org.openobex.Error.Failed:" message
Sure, that could be done, but lets fix one issue at time. Does the
previous patch fixed your problem?
--
Luiz Augusto von Dentz
Computer Engineer
^ permalink raw reply
* Re: [PATCH] Bluetooth: Defer SCO setup if mode change is pending
From: Marcel Holtmann @ 2010-07-20 16:56 UTC (permalink / raw)
To: Ron Shaffer; +Cc: linux-bluetooth
In-Reply-To: <4C45299D.9060504@codeaurora.org>
Hi Ron,
> > @@ -385,10 +406,13 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
> > acl->power_save = 1;
> > hci_conn_enter_active_mode(acl);
> >
> > - if (lmp_esco_capable(hdev))
> > - hci_setup_sync(sco, acl->handle);
> > - else
> > - hci_add_sco(sco, acl->handle);
> > + if (test_bit(HCI_CONN_MODE_CHANGE_PEND, &acl->pend)) {
> > + /* defer SCO setup until mode change completed */
> > + set_bit(HCI_CONN_SCO_SETUP_PEND, &acl->pend);
> > + return sco;
> > + }
> > +
> > + hci_sco_setup(acl, 0x00);
> > }
>
> Not in love with the "fake" status passed here, but the overall change
> to centralize this functionality provides a nice cleanup from the
> original patch and makes the code more readable and maintainable.
yeah, the 0x00 looks funny here. We could add a comment explaining it,
but it does make sense in the end.
> > return sco;
> > diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> > index 2069c3b..461413c 100644
> > --- a/net/bluetooth/hci_event.c
> > +++ b/net/bluetooth/hci_event.c
> > @@ -775,9 +775,6 @@ static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
> >
> > BT_DBG("%s status 0x%x", hdev->name, status);
> >
> > - if (!status)
> > - return;
> > -
> > cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
> > if (!cp)
> > return;
> > @@ -785,8 +782,13 @@ static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
> > hci_dev_lock(hdev);
> >
> > conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
> > - if (conn)
> > - clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
> > + if (conn) {
> > + if (status)
> > + clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
> > +
> > + if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
> > + hci_sco_setup(conn, status);
>
> Probably the subject for another patch, but has there been any reported
> issue where idle_timeout is set short enough that the timer expires
> after exit sniff mode has been requested but before the mode change
> event has been received?
I see that this could potentially happen. The timer is not suppose to be
running during that transaction. It should be only started when the mode
change has been completed. That needs fixing, but not in this patch.
Regards
Marcel
^ permalink raw reply
* [PATCH v3 0/5] Enhanced support for extended inquiry response
From: Inga Stotland @ 2010-07-20 21:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: rshaffer, johan.hedberg, marcel
EIR is updated whenever local SDP record database changes.
Added support for UUID128 service descriptors in EIR to allow peek at available
services offered by a remote device without establishing SDP connection.
--
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply
* [PATCH 1/5] Spec constants for Extended Inqiory Response field types
From: Inga Stotland @ 2010-07-20 21:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: rshaffer, johan.hedberg, marcel, Inga Stotland
In-Reply-To: <1279662974-16454-1-git-send-email-ingas@codeaurora.org>
---
src/sdpd.h | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/src/sdpd.h b/src/sdpd.h
index e93b0b6..7b0b3be 100644
--- a/src/sdpd.h
+++ b/src/sdpd.h
@@ -34,6 +34,19 @@
#define SDPDBG(fmt...)
#endif
+#define EIR_DATA_LENGTH 240
+
+#define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */
+#define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */
+#define EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */
+#define EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */
+#define EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */
+#define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */
+#define EIR_NAME_SHORT 0x08 /* shortened local name */
+#define EIR_NAME_COMPLETE 0x09 /* complete local name */
+#define EIR_DEVICE_ID 0x10 /* device ID */
+#define EIR_TX_POWER 0x0A /* Transmit power level */
+
typedef struct request {
bdaddr_t device;
bdaddr_t bdaddr;
--
1.7.1
--
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply related
* [PATCH 2/5] Support for adding UUID128 to extended inquiry response
From: Inga Stotland @ 2010-07-20 21:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: rshaffer, johan.hedberg, marcel, Inga Stotland
In-Reply-To: <1279662974-16454-1-git-send-email-ingas@codeaurora.org>
---
src/sdpd-service.c | 108 ++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 92 insertions(+), 16 deletions(-)
diff --git a/src/sdpd-service.c b/src/sdpd-service.c
index cdbb4f4..1314ada 100644
--- a/src/sdpd-service.c
+++ b/src/sdpd-service.c
@@ -49,6 +49,8 @@
#include "manager.h"
#include "adapter.h"
+#define SIZEOF_UUID128 16
+
static sdp_record_t *server = NULL;
static uint16_t did_vendor = 0x0000;
@@ -174,41 +176,103 @@ static void update_svclass_list(const bdaddr_t *src)
}
+static void eir_generate_uuid128(sdp_list_t *list,
+ uint8_t *ptr, uint16_t *eir_len)
+{
+ int i, k, index = 0;
+ uint16_t len = *eir_len;
+ uint8_t *uuid128;
+ gboolean truncated = FALSE;
+
+ /* Store UUID128 in place, skip 2 bytes to insert type and length later */
+ uuid128 = ptr + 2;
+
+ for (; list; list = list->next) {
+ sdp_record_t *rec = (sdp_record_t *) list->data;
+
+ if (rec->svclass.type != SDP_UUID128)
+ continue;
+
+ /* Stop if not enough space to put next UUID128 */
+ if ((len + 2 + SIZEOF_UUID128) > EIR_DATA_LENGTH) {
+ truncated = TRUE;
+ break;
+ }
+
+ /* Check for duplicates, EIR data is Little Endian */
+ for (i = 0; i < index; i++) {
+ for (k = 0; k < SIZEOF_UUID128; k++) {
+ if (uuid128[i*SIZEOF_UUID128 + k] !=
+ rec->svclass.value.uuid128.data[SIZEOF_UUID128 - k])
+ break;
+ }
+ if (k == SIZEOF_UUID128)
+ break;
+ }
+
+ if (i < index)
+ continue;
+
+ /* EIR data is Little Endian */
+ for (k = 0; k < SIZEOF_UUID128; k++)
+ uuid128[index*SIZEOF_UUID128 + k] =
+ rec->svclass.value.uuid128.data[SIZEOF_UUID128 - 1 - k];
+
+ len += SIZEOF_UUID128;
+ index++;
+ }
+
+ if (index > 0 || truncated) {
+ /* EIR Data length */
+ ptr[0] = (index * SIZEOF_UUID128) + 1;
+ /* EIR Data type */
+ ptr[1] = (truncated) ? EIR_UUID128_SOME : EIR_UUID128_ALL;
+ len += 2;
+ *eir_len = len;
+ }
+}
+
void create_ext_inquiry_response(const char *name,
int8_t tx_power, sdp_list_t *services,
uint8_t *data)
{
sdp_list_t *list = services;
uint8_t *ptr = data;
- uint16_t uuid[24];
+ uint16_t eir_len = 0;
+ uint16_t uuid16[EIR_DATA_LENGTH/2];
int i, index = 0;
+ gboolean truncated = FALSE;
if (name) {
int len = strlen(name);
+ /* EIR Data type */
if (len > 48) {
len = 48;
- ptr[1] = 0x08;
+ ptr[1] = EIR_NAME_SHORT;
} else
- ptr[1] = 0x09;
+ ptr[1] = EIR_NAME_COMPLETE;
+ /* EIR Data length */
ptr[0] = len + 1;
memcpy(ptr + 2, name, len);
- ptr += len + 2;
+ eir_len += (len + 2);
+ ptr += (len + 2);
}
if (tx_power != 0) {
*ptr++ = 2;
- *ptr++ = 0x0a;
+ *ptr++ = EIR_TX_POWER;
*ptr++ = (uint8_t) tx_power;
+ eir_len += 3;
}
if (did_vendor != 0x0000) {
uint16_t source = 0x0002;
*ptr++ = 9;
- *ptr++ = 0x10;
+ *ptr++ = EIR_DEVICE_ID;
*ptr++ = (source & 0x00ff);
*ptr++ = (source & 0xff00) >> 8;
*ptr++ = (did_vendor & 0x00ff);
@@ -217,10 +281,10 @@ void create_ext_inquiry_response(const char *name,
*ptr++ = (did_product & 0xff00) >> 8;
*ptr++ = (did_version & 0x00ff);
*ptr++ = (did_version & 0xff00) >> 8;
+ eir_len += 10;
}
- ptr[1] = 0x03;
-
+ /* Group all UUID16 types */
for (; list; list = list->next) {
sdp_record_t *rec = (sdp_record_t *) list->data;
@@ -233,30 +297,42 @@ void create_ext_inquiry_response(const char *name,
if (rec->svclass.value.uuid16 == PNP_INFO_SVCLASS_ID)
continue;
- if (index > 23) {
- ptr[1] = 0x02;
+ /* Stop if not enough space to put next UUID16 */
+ if ((eir_len + 2 + sizeof(uint16_t)) > EIR_DATA_LENGTH) {
+ truncated = TRUE;
break;
}
+ /* Check for duplicates */
for (i = 0; i < index; i++)
- if (uuid[i] == rec->svclass.value.uuid16)
+ if (uuid16[i] == rec->svclass.value.uuid16)
break;
- if (i == index - 1)
+ if (i < index)
continue;
- uuid[index++] = rec->svclass.value.uuid16;
+ uuid16[index++] = rec->svclass.value.uuid16;
+ eir_len += sizeof(uint16_t);
}
if (index > 0) {
- ptr[0] = (index * 2) + 1;
+ /* EIR Data length */
+ ptr[0] = (index * sizeof(uint16_t)) + 1;
+ /* EIR Data type */
+ ptr[1] = (truncated) ? EIR_UUID16_SOME : EIR_UUID16_ALL;
+
ptr += 2;
+ eir_len += 2;
for (i = 0; i < index; i++) {
- *ptr++ = (uuid[i] & 0x00ff);
- *ptr++ = (uuid[i] & 0xff00) >> 8;
+ *ptr++ = (uuid16[i] & 0x00ff);
+ *ptr++ = (uuid16[i] & 0xff00) >> 8;
}
}
+
+ /* Group all UUID128 types */
+ if (eir_len <= EIR_DATA_LENGTH - 2)
+ eir_generate_uuid128(services, ptr, &eir_len);
}
void register_public_browse_group(void)
--
1.7.1
--
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply related
* [PATCH 3/5] Update EIR whenever record is added or removed
From: Inga Stotland @ 2010-07-20 21:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: rshaffer, johan.hedberg, marcel, Inga Stotland
In-Reply-To: <1279662974-16454-1-git-send-email-ingas@codeaurora.org>
---
plugins/service.c | 18 ++++++++++++++++++
src/adapter.c | 23 ++++++++++++++++++++++-
src/adapter.h | 1 +
3 files changed, 41 insertions(+), 1 deletions(-)
diff --git a/plugins/service.c b/plugins/service.c
index 96280bd..ee9176b 100644
--- a/plugins/service.c
+++ b/plugins/service.c
@@ -445,6 +445,8 @@ static DBusMessage *update_record(DBusConnection *conn, DBusMessage *msg,
strerror(EIO));
}
+ adapter_update_eir_data(&src);
+
return dbus_message_new_method_return(msg);
}
@@ -516,6 +518,7 @@ static DBusMessage *add_service_record(DBusConnection *conn,
const char *sender, *record;
dbus_uint32_t handle;
int err;
+ bdaddr_t bdaddr;
if (dbus_message_get_args(msg, NULL,
DBUS_TYPE_STRING, &record, DBUS_TYPE_INVALID) == FALSE)
@@ -526,6 +529,13 @@ static DBusMessage *add_service_record(DBusConnection *conn,
if (err < 0)
return failed_strerror(msg, err);
+ if (serv_adapter->adapter)
+ adapter_get_address(serv_adapter->adapter, &bdaddr);
+ else
+ bacpy(&bdaddr, BDADDR_ANY);
+
+ adapter_update_eir_data(&bdaddr);
+
reply = dbus_message_new_method_return(msg);
if (!reply)
return NULL;
@@ -550,6 +560,7 @@ static DBusMessage *remove_service_record(DBusConnection *conn,
struct service_adapter *serv_adapter = data;
dbus_uint32_t handle;
const char *sender;
+ bdaddr_t bdaddr;
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &handle,
DBUS_TYPE_INVALID) == FALSE)
@@ -560,6 +571,13 @@ static DBusMessage *remove_service_record(DBusConnection *conn,
if (remove_record(conn, sender, serv_adapter, handle) < 0)
return not_available(msg);
+ if (serv_adapter->adapter)
+ adapter_get_address(serv_adapter->adapter, &bdaddr);
+ else
+ bacpy(&bdaddr, BDADDR_ANY);
+
+ adapter_update_eir_data(&bdaddr);
+
return dbus_message_new_method_return(msg);
}
diff --git a/src/adapter.c b/src/adapter.c
index 789a196..c1e1768 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -820,7 +820,7 @@ static DBusMessage *set_pairable_timeout(DBusConnection *conn,
static void update_ext_inquiry_response(struct btd_adapter *adapter)
{
- uint8_t fec = 0, data[240];
+ uint8_t fec = 0, data[EIR_DATA_LENGTH];
struct hci_dev *dev = &adapter->dev;
int dd;
@@ -846,6 +846,27 @@ static void update_ext_inquiry_response(struct btd_adapter *adapter)
hci_close_dev(dd);
}
+void adapter_update_eir_data(const bdaddr_t *src)
+{
+ struct btd_adapter *adapter;
+ GSList *adapters;
+
+ if (bacmp(src, BDADDR_ANY) != 0) {
+ adapter = manager_find_adapter(src);
+ if (adapter)
+ update_ext_inquiry_response(adapter);
+ else
+ error("Updating EIR failed: device not found");
+ } else {
+
+ /* Update extended inquiry reponse for ANY adapter */
+ for (adapters = manager_get_adapters(); adapters; adapters = adapters->next) {
+ adapter = adapters->data;
+ update_ext_inquiry_response(adapter);
+ }
+ }
+}
+
void adapter_set_class_complete(bdaddr_t *bdaddr, uint8_t status)
{
uint8_t class[3];
diff --git a/src/adapter.h b/src/adapter.h
index 8226514..f72eb0b 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -126,6 +126,7 @@ void adapter_service_insert(const bdaddr_t *bdaddr, void *rec);
void adapter_service_remove(const bdaddr_t *bdaddr, void *rec);
sdp_list_t *adapter_get_services(struct btd_adapter *adapter);
void adapter_set_class_complete(bdaddr_t *bdaddr, uint8_t status);
+void adapter_update_eir_data(const bdaddr_t *src);
struct agent *adapter_get_agent(struct btd_adapter *adapter);
void adapter_add_connection(struct btd_adapter *adapter,
--
1.7.1
--
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply related
* [PATCH 4/5] Handle arrays in device properties dictionary
From: Inga Stotland @ 2010-07-20 21:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: rshaffer, johan.hedberg, marcel, Inga Stotland
In-Reply-To: <1279662974-16454-1-git-send-email-ingas@codeaurora.org>
---
src/adapter.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index c1e1768..b22b086 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2715,6 +2715,7 @@ static void append_dict_valist(DBusMessageIter *iter,
DBusMessageIter dict;
const char *key;
int type;
+ int n_elements;
void *val;
dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
@@ -2726,7 +2727,12 @@ static void append_dict_valist(DBusMessageIter *iter,
while (key) {
type = va_arg(var_args, int);
val = va_arg(var_args, void *);
- dict_append_entry(&dict, key, type, val);
+ if (type == DBUS_TYPE_ARRAY) {
+ n_elements = va_arg(var_args, int);
+ if (n_elements > 0)
+ dict_append_array(&dict, key, DBUS_TYPE_STRING, val, n_elements);
+ } else
+ dict_append_entry(&dict, key, type, val);
key = va_arg(var_args, char *);
}
--
1.7.1
--
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply related
* [PATCH 5/5] Extended support for generating dictionary value of service UUIDs
From: Inga Stotland @ 2010-07-20 21:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: rshaffer, johan.hedberg, marcel, Inga Stotland
In-Reply-To: <1279662974-16454-1-git-send-email-ingas@codeaurora.org>
---
src/adapter.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
src/adapter.h | 4 +-
src/dbus-hci.c | 6 ++--
3 files changed, 97 insertions(+), 8 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index b22b086..612c3a9 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2763,8 +2763,84 @@ static void emit_device_found(const char *path, const char *address,
g_dbus_send_message(connection, signal);
}
+static int get_uuid_count_eir (uint8_t *eir_data)
+{
+ uint8_t len = 0;
+ int count = 0;
+
+ while (len < EIR_DATA_LENGTH) {
+ uint8_t type = eir_data[1];
+ uint8_t field_len = eir_data[0];
+ if ((type == EIR_UUID16_SOME) || (type == EIR_UUID16_ALL))
+ count += field_len/2;
+ else if ((type == EIR_UUID32_SOME) || (type == EIR_UUID32_ALL))
+ count += field_len/4;
+ else if ((type == EIR_UUID128_SOME) || (type == EIR_UUID128_ALL))
+ count += field_len/16;
+ len += field_len + 1;
+ eir_data += field_len + 1;
+ }
+
+ return count;
+}
+
+static void get_uuids_eir(char **uuids, uint8_t *eir_data)
+{
+ uint8_t len = 0;
+
+ /* Count UUID16, UUID32 and UUID128 */
+ while (len < EIR_DATA_LENGTH) {
+ uint8_t field_len = eir_data[0];
+ uint8_t type = eir_data[1];
+ int count;
+ uuid_t service;
+ int size;
+ uint8_t *data = &eir_data[2];
+ int i, k;
+
+ /* Generate uuids in SDP format (EIR data is Little Endian) */
+ if ((type == EIR_UUID16_SOME) || (type == EIR_UUID16_ALL)) {
+ size = 2;
+ count = field_len/size;
+ service.type = SDP_UUID16;
+ for (i = 0; i < count; i++) {
+ uint16_t val16 = data[1];
+ val16 = (val16<<8) + data[0];
+ service.value.uuid16 = val16;
+ *uuids++ = bt_uuid2string(&service);
+ data += size;
+ }
+ } else if ((type == EIR_UUID32_SOME) || (type == EIR_UUID32_ALL)) {
+ size = 4;
+ count = field_len/size;
+ service.type = SDP_UUID32;
+ for (i = 0; i < count; i++) {
+ uint32_t val32 = data[3];
+ for (k = size-2; k >= 0; k--)
+ val32 = (val32<<8) + data[k];
+ service.value.uuid32 = val32;
+ *uuids++ = bt_uuid2string(&service);
+ data += size;
+ }
+ } else if ((type == EIR_UUID128_SOME) || (type == EIR_UUID128_ALL)) {
+ size = 16;
+ count = field_len/size;
+ service.type = SDP_UUID128;
+ for (i = 0; i < count; i++) {
+ for (k = 0; k < size; k++)
+ service.value.uuid128.data[k] = data[size-k-1];
+ *uuids++ = bt_uuid2string(&service);
+ data += size;
+ }
+ }
+
+ len += field_len + 1;
+ eir_data += field_len + 1;
+ }
+}
+
void adapter_emit_device_found(struct btd_adapter *adapter,
- struct remote_dev_info *dev)
+ struct remote_dev_info *dev, uint8_t *eir_data)
{
struct btd_device *device;
char peer_addr[18], local_addr[18];
@@ -2772,6 +2848,8 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
dbus_bool_t paired = FALSE;
dbus_int16_t rssi = dev->rssi;
char *alias;
+ char **uuids = NULL;
+ int uuid_count = 0;
ba2str(&dev->bdaddr, peer_addr);
ba2str(&adapter->bdaddr, local_addr);
@@ -2791,6 +2869,15 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
} else
alias = g_strdup(dev->alias);
+ /* Extract UUIDs from extended inquiry response if any*/
+ if (eir_data != NULL)
+ uuid_count = get_uuid_count_eir(eir_data);
+
+ if (uuid_count > 0) {
+ uuids = g_new0(char *, uuid_count + 1);
+ get_uuids_eir(uuids, eir_data);
+ }
+
emit_device_found(adapter->path, paddr,
"Address", DBUS_TYPE_STRING, &paddr,
"Class", DBUS_TYPE_UINT32, &dev->class,
@@ -2800,15 +2887,17 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
"Alias", DBUS_TYPE_STRING, &alias,
"LegacyPairing", DBUS_TYPE_BOOLEAN, &dev->legacy,
"Paired", DBUS_TYPE_BOOLEAN, &paired,
+ "UUIDs", DBUS_TYPE_ARRAY, &uuids, uuid_count,
NULL);
g_free(alias);
+ g_strfreev(uuids);
}
void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
int8_t rssi, uint32_t class, const char *name,
const char *alias, gboolean legacy,
- name_status_t name_status)
+ name_status_t name_status, uint8_t *eir_data)
{
struct remote_dev_info *dev, match;
@@ -2847,7 +2936,7 @@ done:
adapter->found_devices = g_slist_sort(adapter->found_devices,
(GCompareFunc) dev_rssi_cmp);
- adapter_emit_device_found(adapter, dev);
+ adapter_emit_device_found(adapter, dev, eir_data);
}
int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr)
diff --git a/src/adapter.h b/src/adapter.h
index f72eb0b..231d2c9 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -113,10 +113,10 @@ struct remote_dev_info *adapter_search_found_devices(struct btd_adapter *adapter
void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
int8_t rssi, uint32_t class, const char *name,
const char *alias, gboolean legacy,
- name_status_t name_status);
+ name_status_t name_status, uint8_t *eir_data);
int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr);
void adapter_emit_device_found(struct btd_adapter *adapter,
- struct remote_dev_info *dev);
+ struct remote_dev_info *dev, uint8_t *eir_data);
void adapter_update_oor_devices(struct btd_adapter *adapter);
void adapter_mode_changed(struct btd_adapter *adapter, uint8_t scan_mode);
void adapter_setname_complete(bdaddr_t *local, uint8_t status);
diff --git a/src/dbus-hci.c b/src/dbus-hci.c
index b83506f..6d27caa 100644
--- a/src/dbus-hci.c
+++ b/src/dbus-hci.c
@@ -515,7 +515,7 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
if (dev) {
adapter_update_found_devices(adapter, peer, rssi, class,
NULL, NULL, dev->legacy,
- NAME_NOT_REQUIRED);
+ NAME_NOT_REQUIRED, data);
return;
}
@@ -566,7 +566,7 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
/* add in the list to track name sent/pending */
adapter_update_found_devices(adapter, peer, rssi, class, name, alias,
- legacy, name_status);
+ legacy, name_status, data);
g_free(name);
g_free(alias);
@@ -642,7 +642,7 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status,
if (dev_info) {
g_free(dev_info->name);
dev_info->name = g_strdup(name);
- adapter_emit_device_found(adapter, dev_info);
+ adapter_emit_device_found(adapter, dev_info, NULL);
}
if (device)
--
1.7.1
--
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply related
* [PATCH][RFC] Fix SDP resolving segfault
From: Manuel Naranjo @ 2010-07-20 23:33 UTC (permalink / raw)
To: BlueZ
[-- Attachment #1: Type: text/plain, Size: 162 bytes --]
Guys,
I think this patch fixes the weird segfault I had been experiencing for
the last few months.
Manuel
Signed-off-by: Manuel Naranjo<manuel@aircable.net>
[-- Attachment #2: 0001-Possible-fix-for-BlueZ-SDP-segfaults.patch --]
[-- Type: text/plain, Size: 2763 bytes --]
>From a292f1df55ace6d4c7e4e91edf833b7e4f07e5a7 Mon Sep 17 00:00:00 2001
From: Manuel Francisco Naranjo <manuel@aircable.net>
Date: Tue, 20 Jul 2010 20:12:56 -0300
Subject: [PATCH] Possible fix for BlueZ SDP segfaults
modified: src/glib-helper.c
Sometimes when you do a DiscoverServices through DBUS and the device goes out of
range then BlueZ will end with a SegFault. I've traced it, and it seems like
connect_watch is been triggered, it gets into the failed tag and when it does the
callback as the btd_device has been released before, the callback triggers the
segfault.
This patch seems to fix the problem, not sure if this is the best way, or the right
one at all. Maybe the problem is that btd_device has no direct reference to the
search_context and then when btd_device is released there's no direct search_context
release (this happens through the function bt_cancel_discovery, but I have a feeling
this approach is actually failing in some cases).
---
src/glib-helper.c | 18 ++++++++++++------
1 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/src/glib-helper.c b/src/glib-helper.c
index 41f5e3c..fef0d41 100644
--- a/src/glib-helper.c
+++ b/src/glib-helper.c
@@ -156,8 +156,10 @@ static void search_context_cleanup(struct search_context *ctxt)
{
context_list = g_slist_remove(context_list, ctxt);
- if (ctxt->destroy)
+ if (ctxt->destroy){
ctxt->destroy(ctxt->user_data);
+ ctxt->user_data = NULL;
+ }
g_free(ctxt);
}
@@ -206,7 +208,7 @@ static void search_completed_cb(uint8_t type, uint16_t status,
done:
cache_sdp_session(&ctxt->src, &ctxt->dst, ctxt->session);
- if (ctxt->cb)
+ if (ctxt->cb && ctxt->user_data)
ctxt->cb(recs, err, ctxt->user_data);
if (recs)
@@ -236,7 +238,7 @@ failed:
sdp_close(ctxt->session);
ctxt->session = NULL;
- if (ctxt->cb)
+ if (ctxt->cb && ctxt->user_data)
ctxt->cb(NULL, err, ctxt->user_data);
search_context_cleanup(ctxt);
@@ -254,6 +256,8 @@ static gboolean connect_watch(GIOChannel *chan, GIOCondition cond, gpointer user
int sk, err = 0;
sk = g_io_channel_unix_get_fd(chan);
+ if (ctxt->io_id)
+ g_source_remove(ctxt->io_id);
ctxt->io_id = 0;
len = sizeof(err);
@@ -293,7 +297,7 @@ failed:
sdp_close(ctxt->session);
ctxt->session = NULL;
- if (ctxt->cb)
+ if (ctxt->cb && ctxt->user_data)
ctxt->cb(NULL, -err, ctxt->user_data);
search_context_cleanup(ctxt);
@@ -391,11 +395,13 @@ int bt_cancel_discovery(const bdaddr_t *src, const bdaddr_t *dst)
return -ENODATA;
ctxt = match->data;
- if (!ctxt->session)
- return -ENOTCONN;
if (ctxt->io_id)
g_source_remove(ctxt->io_id);
+ ctxt->io_id = 0;
+
+ if (!ctxt->session)
+ return -ENOTCONN;
if (ctxt->session)
sdp_close(ctxt->session);
--
1.6.4.4
^ permalink raw reply related
* Re: [PATCH 1/5] Spec constants for Extended Inqiory Response field types
From: Marcel Holtmann @ 2010-07-21 8:43 UTC (permalink / raw)
To: Inga Stotland; +Cc: linux-bluetooth, rshaffer, johan.hedberg
In-Reply-To: <1279662974-16454-2-git-send-email-ingas@codeaurora.org>
Hi Inga,
> src/sdpd.h | 13 +++++++++++++
> 1 files changed, 13 insertions(+), 0 deletions(-)
>
> diff --git a/src/sdpd.h b/src/sdpd.h
> index e93b0b6..7b0b3be 100644
> --- a/src/sdpd.h
> +++ b/src/sdpd.h
> @@ -34,6 +34,19 @@
> #define SDPDBG(fmt...)
> #endif
>
> +#define EIR_DATA_LENGTH 240
> +
> +#define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */
> +#define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */
> +#define EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */
> +#define EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */
> +#define EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */
> +#define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */
> +#define EIR_NAME_SHORT 0x08 /* shortened local name */
> +#define EIR_NAME_COMPLETE 0x09 /* complete local name */
> +#define EIR_DEVICE_ID 0x10 /* device ID */
> +#define EIR_TX_POWER 0x0A /* Transmit power level */
> +
I don't wanna be picky, but 0x0A comes before 0x10 actually.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH 5/5] Extended support for generating dictionary value of service UUIDs
From: Marcel Holtmann @ 2010-07-21 8:46 UTC (permalink / raw)
To: Inga Stotland; +Cc: linux-bluetooth, rshaffer, johan.hedberg
In-Reply-To: <1279662974-16454-6-git-send-email-ingas@codeaurora.org>
Hi Inga,
> src/adapter.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
> src/adapter.h | 4 +-
> src/dbus-hci.c | 6 ++--
> 3 files changed, 97 insertions(+), 8 deletions(-)
>
> diff --git a/src/adapter.c b/src/adapter.c
> index b22b086..612c3a9 100644
> --- a/src/adapter.c
> +++ b/src/adapter.c
> @@ -2763,8 +2763,84 @@ static void emit_device_found(const char *path, const char *address,
> g_dbus_send_message(connection, signal);
> }
>
> +static int get_uuid_count_eir (uint8_t *eir_data)
> +{
please get the coding style right. It is count_eir(uint8 ...)
> + uint8_t len = 0;
> + int count = 0;
> +
> + while (len < EIR_DATA_LENGTH) {
> + uint8_t type = eir_data[1];
> + uint8_t field_len = eir_data[0];
> + if ((type == EIR_UUID16_SOME) || (type == EIR_UUID16_ALL))
> + count += field_len/2;
The double ( ) is not needed. So if (type == ... || type == ...). That
is enough actually.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH][RFC] Fix SDP resolving segfault
From: Johan Hedberg @ 2010-07-21 10:19 UTC (permalink / raw)
To: Manuel Naranjo; +Cc: BlueZ
In-Reply-To: <4C46324D.5070800@aircable.net>
Hi Manuel,
On Tue, Jul 20, 2010, Manuel Naranjo wrote:
> I think this patch fixes the weird segfault I had been experiencing
> for the last few months.
Thanks for the patch proposal. It seems like you're trying to to fix the
issue by doing all sorts of minor tweaks here and there, i.e. it seems
like there isn't a full understanding of the real root cause.
> - if (ctxt->cb)
> + if (ctxt->cb && ctxt->user_data)
> ctxt->cb(recs, err, ctxt->user_data);
This part isn't right. It should be perfectly fine for a discovery
requester to pass NULL as user_data and still expect its callback to get
called.
> - if (ctxt->cb)
> + if (ctxt->cb && ctxt->user_data)
> ctxt->cb(NULL, err, ctxt->user_data);
Same here.
> @@ -254,6 +256,8 @@ static gboolean connect_watch(GIOChannel *chan, GIOCondition cond, gpointer user
> int sk, err = 0;
>
> sk = g_io_channel_unix_get_fd(chan);
> + if (ctxt->io_id)
> + g_source_remove(ctxt->io_id);
connect_watch returns FALSE in all cases which will remove the GSource.
So the change you're doing seems redundant.
> - if (ctxt->cb)
> + if (ctxt->cb && ctxt->user_data)
> ctxt->cb(NULL, -err, ctxt->user_data);
Same issue with NULL user_data being valid.
> @@ -391,11 +395,13 @@ int bt_cancel_discovery(const bdaddr_t *src, const bdaddr_t *dst)
> return -ENODATA;
>
> ctxt = match->data;
> - if (!ctxt->session)
> - return -ENOTCONN;
>
> if (ctxt->io_id)
> g_source_remove(ctxt->io_id);
> + ctxt->io_id = 0;
> +
> + if (!ctxt->session)
> + return -ENOTCONN;
>
> if (ctxt->session)
> sdp_close(ctxt->session);
I don't really understand the need for these changes, but admitedly the
function does have issues since it first checks for !ctxt->session and
then later for ctxt->session even though at that point it's already
guaranteed that ctxt->session is not NULL.
Johan
^ permalink raw reply
* BNEP fails in the new vanilla kernels
From: Stanislav Brabec @ 2010-07-21 13:02 UTC (permalink / raw)
To: linux-bluetooth
I just tried to connect to my PDA using "pand -c". Instead of
connection, I got following backtrace:
Tested in Linux hammer 2.6.35-rc5 from last week's
http://download.opensuse.org/repositories/Kernel:/HEAD/openSUSE_11.3/
It worked in 2.6.34.
[40323.569899] ------------[ cut here ]------------
[40323.569911] WARNING: at /usr/src/packages/BUILD/kernel-desktop-2.6.35/linux-2.6.34/fs/sysfs/dir.c:451 sysfs_add_one+0xc8/0x160()
[40323.569914] Hardware name: MS-6702
[40323.569916] sysfs: cannot create duplicate filename '/class/net/bnep0'
[40323.569918] Modules linked in: autofs4 nls_iso8859_1 nls_cp437 vfat fat joydev rt2870sta(C) crc_ccitt xt_physdev rfcomm sco bridge stp llc bnep l2cap snd_pcm_oss snd_mixer_oss snd_seq edd ip6t_LOG xt_tcpudp xt_pkttype ipt_LOG xt_limit nfs lockd fscache nfs_acl auth_rpcgss sunrpc af_packet mperf ip6t_REJECT nf_conntrack_ipv6 ip6table_raw xt_NOTRACK ipt_REJECT xt_state iptable_raw iptable_filter ip6table_mangle nf_conntrack_netbios_ns nf_conntrack_ipv4 nf_conntrack nf_defrag_ipv4 ip_tables ip6table_filter ip6_tables x_tables fuse loop dm_mod snd_via82xx gameport snd_ac97_codec ac97_bus firewire_ohci snd_pcm snd_timer snd_page_alloc snd_mpu401_uart snd_rawmidi snd_seq_device firewire_core btusb ppdev floppy parport_pc usb_storage bluetooth crc_itu_t parport snd sr_mod r8169 pcspkr i2c_viapro amd64_edac_mod sg ohci1394 rfkill ieee1394 k8temp edac_core edac_mce_amd soundcore shpchp cdrom pci_hotplug ext4 jbd2 crc16 nouveau ttm drm_kms_helper drm sd_mod i2c_algo_bit button fan processor ata_generic sata_via sata_promise thermal thermal_sys pata_via libata scsi_mod
[40323.569994] Pid: 7035, comm: pand Tainted: G C 2.6.35-rc5-10-desktop #1
[40323.569996] Call Trace:
[40323.570023] [<ffffffff81005a69>] dump_trace+0x79/0x340
[40323.570031] [<ffffffff814acb05>] dump_stack+0x69/0x6f
[40323.570040] [<ffffffff8105671b>] warn_slowpath_common+0x7b/0xc0
[40323.570046] [<ffffffff81056815>] warn_slowpath_fmt+0x45/0x50
[40323.570051] [<ffffffff811b2a78>] sysfs_add_one+0xc8/0x160
[40323.570058] [<ffffffff811b346b>] sysfs_do_create_link+0x11b/0x1b0
[40323.570066] [<ffffffff813119d2>] device_add_class_symlinks+0x62/0xf0
[40323.570072] [<ffffffff81312b08>] device_add+0x228/0x420
[40323.570079] [<ffffffff813de48b>] netdev_register_kobject+0x8b/0x1a0
[40323.570087] [<ffffffff813cc965>] register_netdevice+0x1c5/0x3b0
[40323.570096] [<ffffffff813ccb86>] register_netdev+0x36/0x50
[40323.570105] [<ffffffffa00f82c5>] bnep_add_connection+0x1a5/0x2c0 [bnep]
[40323.570123] [<ffffffffa00f8994>] bnep_sock_ioctl+0x1f4/0x280 [bnep]
[40323.570132] [<ffffffff813b5199>] sock_do_ioctl+0x29/0x60
[40323.570138] [<ffffffff813b5320>] sock_ioctl+0x70/0x2b0
[40323.570144] [<ffffffff81155eb9>] vfs_ioctl+0x39/0xc0
[40323.570149] [<ffffffff81156450>] do_vfs_ioctl+0x70/0x390
[40323.570154] [<ffffffff811567f0>] sys_ioctl+0x80/0xa0
[40323.570161] [<ffffffff81002fbb>] system_call_fastpath+0x16/0x1b
[40323.570171] [<00007fb2e6649e87>] 0x7fb2e6649e87
[40323.570174] ---[ end trace 3ca3c5fdcca93270 ]---
--
Best Regards / S pozdravem,
Stanislav Brabec
software developer
---------------------------------------------------------------------
SUSE LINUX, s. r. o. e-mail: sbrabec@suse.cz
Lihovarská 1060/12 tel: +420 284 028 966, +49 911 740538747
190 00 Praha 9 fax: +420 284 028 951
Czech Republic http://www.suse.cz/
^ permalink raw reply
* Re: [PATCH][RFC] Fix SDP resolving segfault
From: Luiz Augusto von Dentz @ 2010-07-21 13:26 UTC (permalink / raw)
To: Manuel Naranjo, BlueZ
In-Reply-To: <20100721101934.GA12188@jh-x301>
Hi,
On Wed, Jul 21, 2010 at 1:19 PM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> I don't really understand the need for these changes, but admitedly the
> function does have issues since it first checks for !ctxt->session and
> then later for ctxt->session even though at that point it's already
> guaranteed that ctxt->session is not NULL.
Yep, I suspect it is something else too, there doesn't seems to be a
call to bt_cancel_discovery in the last trace sent to the list, but
the check for ctxt->session there seems buggy, we should always remove
the context doesn't matter if it is connected or not.
@Manuel: Does valgrind give you a nice bracktrace when it bluetoothd segfaults?
Normally I use something like this:
> sudo valgrind --trace-children=yes ./bluetoothd -dn
--
Luiz Augusto von Dentz
Computer Engineer
^ permalink raw reply
* Re: [PATCH][RFC] Fix SDP resolving segfault
From: Manuel Naranjo @ 2010-07-21 15:11 UTC (permalink / raw)
To: Johan Hedberg; +Cc: BlueZ
In-Reply-To: <20100721101934.GA12188@jh-x301>
Johan,
> Thanks for the patch proposal. It seems like you're trying to to fix the
> issue by doing all sorts of minor tweaks here and there, i.e. it seems
> like there isn't a full understanding of the real root cause.
>
I agree, I know this doesn't fix the root cause, it only works it out.
Like we say in Argentina we attach it with aluminium threads.
>> - if (ctxt->cb)
>> + if (ctxt->cb&& ctxt->user_data)
>> ctxt->cb(recs, err, ctxt->user_data);
>>
> This part isn't right. It should be perfectly fine for a discovery
> requester to pass NULL as user_data and still expect its callback to get
> called.
>
Then the problem is the callback function!
The trace shows that browse_cb gets right into search_cb which never
checks if user_data is NULL. It doesn't do it because MOST of the time
it isn't only when something weird happens.
>> - if (ctxt->cb)
>> + if (ctxt->cb&& ctxt->user_data)
>> ctxt->cb(NULL, err, ctxt->user_data);
>>
> Same here.
>
>
>> @@ -254,6 +256,8 @@ static gboolean connect_watch(GIOChannel *chan, GIOCondition cond, gpointer user
>> int sk, err = 0;
>>
>> sk = g_io_channel_unix_get_fd(chan);
>> + if (ctxt->io_id)
>> + g_source_remove(ctxt->io_id);
>>
> connect_watch returns FALSE in all cases which will remove the GSource.
> So the change you're doing seems redundant.
>
Ok you got me I missed that.
>> @@ -391,11 +395,13 @@ int bt_cancel_discovery(const bdaddr_t *src, const bdaddr_t *dst)
>> return -ENODATA;
>>
>> ctxt = match->data;
>> - if (!ctxt->session)
>> - return -ENOTCONN;
>>
>> if (ctxt->io_id)
>> g_source_remove(ctxt->io_id);
>> + ctxt->io_id = 0;
>> +
>> + if (!ctxt->session)
>> + return -ENOTCONN;
>>
>> if (ctxt->session)
>> sdp_close(ctxt->session);
>>
> I don't really understand the need for these changes, but admitedly the
> function does have issues since it first checks for !ctxt->session and
> then later for ctxt->session even though at that point it's already
> guaranteed that ctxt->session is not NULL.
>
I think this is the one that really fix the problem. I see connect_watch
getting called and then getting into the crash. I have a nice log with
the tracing feature I sent the other day, here's the end of it (the hole
thing is almost 40 megs if someone wants just ask for it).
+ 0 0x808a019 (from 0x17fdab) io_security_event()
+ 1 0x8087c29 (from 0x808a121) hci_test_bit()
+ 1 0x80893be (from 0x808a166) cmd_status()
+ 1 0x808812b (from 0x808a38a) check_pending_hci_req()
+ 0 0x808a019 (from 0x17fdab) io_security_event()
+ 1 0x8087c29 (from 0x808a121) hci_test_bit()
+ 1 0x8089425 (from 0x808a187) cmd_complete()
+ 1 0x808812b (from 0x808a38a) check_pending_hci_req()
+ 0 0x808a019 (from 0x17fdab) io_security_event()
+ 1 0x8087c29 (from 0x808a121) hci_test_bit()
+ 1 0x8089b72 (from 0x808a2f4) conn_complete()
+ 2 0x80add52 (from 0x8089bda) hcid_dbus_conn_complete()
+ 3 0x80ac3e0 (from 0x80adda1) get_adapter_and_device()
+ 4 0x809d9c3 (from 0x80ac405) manager_find_adapter()
+ 5 0x809d8e3 (from 0x16847e) adapter_cmp()
+ 6 0x80a44f7 (from 0x809d91b) adapter_get_address()
+ 7 0x809dff1 (from 0x80a4525) bacpy()
+ 6 0x809cf7c (from 0x809d92d) bacmp()
+ 4 0x80a0aba (from 0x80ac45b) adapter_get_device()
+ 5 0x8087840 (from 0x80a0b03) btd_debug()
+ 5 0x80a041a (from 0x80a0b22) adapter_find_device()
+ 6 0x80a883e (from 0x16847e) device_address_cmp()
....
+ 6 0x80a883e (from 0x16847e) device_address_cmp()
+ 3 0x80a80a3 (from 0x80addc4) device_get_secmode3_conn()
+ 3 0x80a80e1 (from 0x80addda) device_set_secmode3_conn()
+ 3 0x80aaddf (from 0x80added) device_is_bonding()
+ 3 0x80a9cf7 (from 0x80ade0f) device_is_temporary()
+ 1 0x808812b (from 0x808a38a) check_pending_hci_req()
+ 0 0x808a019 (from 0x17fdab) io_security_event()
+ 1 0x8087c29 (from 0x808a121) hci_test_bit()
+ 1 0x80891f0 (from 0x808a239) inquiry_complete()
+ 2 0x809d9c3 (from 0x808923f) manager_find_adapter()
+ 3 0x809d8e3 (from 0x16847e) adapter_cmp()
+ 4 0x80a44f7 (from 0x809d91b) adapter_get_address()
+ 5 0x809dff1 (from 0x80a4525) bacpy()
+ 4 0x809cf7c (from 0x809d92d) bacmp()
+ 2 0x809e7a5 (from 0x808929a) adapter_resolve_names()
+ 3 0x809dff1 (from 0x809e804) bacpy()
+ 3 0x80a46bb (from 0x809e81d) adapter_search_found_devices()
+ 2 0x80a4642 (from 0x80892b0) adapter_get_state()
+ 2 0x80a453a (from 0x80892fe) adapter_set_state()
+ 3 0x80a4d46 (from 0x80a45e5) adapter_update_oor_devices()
+ 3 0x80ac200 (from 0x80a4618) emit_property_changed()
+ 4 0x80abf1d (from 0x80ac29c) append_variant()
+ 4 0x804f543 (from 0x80ac2ae) g_dbus_send_message()
+ 1 0x808812b (from 0x808a38a) check_pending_hci_req()
+ 0 0x808a019 (from 0x17fdab) io_security_event()
+ 1 0x8087c29 (from 0x808a121) hci_test_bit()
+ 1 0x80893be (from 0x808a166) cmd_status()
+ 1 0x808812b (from 0x808a38a) check_pending_hci_req()
+ 0 0x804da4a (from 0x17fdab) watch_func()
+ 1 0x804df9b (from 0x9cc0dd) dispatch_status()
+ 2 0x804d9fb (from 0x804dfdd) queue_dispatch()
+ 0 0x804d996 (from 0x14953c) message_dispatch()
+ 1 0x8050409 (from 0x9cec8d) message_filter()
+ 1 0x804ea38 (from 0x9dbf13) generic_message()
+ 2 0x804e9b5 (from 0x804ea7b) find_interface()
+ 2 0x80a0d23 (from 0x804eafd) adapter_stop_discovery()
+ 3 0x809f488 (from 0x80a0d7f) find_session()
+ 3 0x809f895 (from 0x80a0db2) session_unref()
+ 4 0x8087840 (from 0x809f8f7) btd_debug()
+ 4 0x809f7a8 (from 0x809f913) session_free()
+ 5 0x8050a57 (from 0x809f7e3) g_dbus_remove_watch()
+ 6 0x804fd59 (from 0x8050aa2) filter_data_find_callback()
+ 6 0x804fd59 (from 0x8050aa2) filter_data_find_callback()
+ 6 0x804fd59 (from 0x8050aa2) filter_data_find_callback()
+ 6 0x804fd59 (from 0x8050aa2) filter_data_find_callback()
+ 6 0x8050032 (from 0x8050abd)
filter_data_remove_callback()
+ 7 0x804fb14 (from 0x80500db) remove_match()
+ 8 0x804f8ea (from 0x804fb4e) format_rule()
+ 8 0x804de1d (from 0x9e1783) add_timeout()
+ 8 0x804df9b (from 0x9cc0dd) dispatch_status()
+ 9 0x804d9fb (from 0x804dfdd) queue_dispatch()
+ 8 0x804decc (from 0x9e16ff) remove_timeout()
+ 8 0x804ddbf (from 0x9e1469) timeout_handler_free()
+ 7 0x804fdf7 (from 0x805011d) filter_data_free()
+ 7 0x804f790 (from 0x8050150) filter_data_find()
+ 5 0x809f58c (from 0x809f7ee) session_remove()
+ 6 0x8087840 (from 0x809f616) btd_debug()
+ 6 0x8087840 (from 0x809f721) btd_debug()
+ 6 0x809e6a8 (from 0x809f72c) pending_remote_name_cancel()
+ 7 0x809dff1 (from 0x809e70e) bacpy()
+ 7 0x80a46bb (from 0x809e727)
adapter_search_found_devices()
+ 6 0x809e391 (from 0x809f737) clear_found_devices_list()
+ 6 0x8085e04 (from 0x809f787) hciops_stop_discovery()
+ 7 0x8084898 (from 0x8085e7b) hci_test_bit()
+ 3 0x80877a4 (from 0x80a0dbe) info()
+ 0 0x808a019 (from 0x17fdab) io_security_event()
+ 1 0x8087c29 (from 0x808a121) hci_test_bit()
+ 1 0x8089425 (from 0x808a187) cmd_complete()
+ 2 0x80891f0 (from 0x808951e) inquiry_complete()
+ 3 0x809d9c3 (from 0x808923f) manager_find_adapter()
+ 4 0x809d8e3 (from 0x16847e) adapter_cmp()
+ 5 0x80a44f7 (from 0x809d91b) adapter_get_address()
+ 6 0x809dff1 (from 0x80a4525) bacpy()
+ 5 0x809cf7c (from 0x809d92d) bacmp()
+ 3 0x80a4642 (from 0x808926f) adapter_get_state()
+ 3 0x80a453a (from 0x8089288) adapter_set_state()
+ 1 0x808812b (from 0x808a38a) check_pending_hci_req()
+ 0 0x804da4a (from 0x17fdab) watch_func()
+ 1 0x804df9b (from 0x9cc0dd) dispatch_status()
+ 2 0x804d9fb (from 0x804dfdd) queue_dispatch()
+ 0 0x804d996 (from 0x14953c) message_dispatch()
+ 1 0x8050409 (from 0x9cec8d) message_filter()
+ 1 0x804ea38 (from 0x9dbf13) generic_message()
+ 2 0x804e9b5 (from 0x804ea7b) find_interface()
+ 2 0x80a0bde (from 0x804eafd) adapter_start_discovery()
+ 3 0x809f488 (from 0x80a0c3d) find_session()
+ 3 0x80a0b66 (from 0x80a0c92) adapter_start_inquiry()
+ 4 0x809e6a8 (from 0x80a0ba4) pending_remote_name_cancel()
+ 5 0x809dff1 (from 0x809e70e) bacpy()
+ 5 0x80a46bb (from 0x809e727)
adapter_search_found_devices()
+ 4 0x8085c9a (from 0x80a0bc1) hciops_start_discovery()
+ 3 0x809ed21 (from 0x80a0cdd) create_session()
+ 4 0x805092f (from 0x809ede5) g_dbus_add_disconnect_watch()
+ 5 0x8050834 (from 0x8050978) g_dbus_add_service_watch()
+ 6 0x804fbbb (from 0x8050898) filter_data_get()
+ 7 0x804f790 (from 0x804fc08) filter_data_find()
+ 7 0x804f790 (from 0x804fc6b) filter_data_find()
+ 7 0x804fa5a (from 0x804fd0c) add_match()
+ 8 0x804f8ea (from 0x804fa94) format_rule()
+ 8 0x804de1d (from 0x9e1783) add_timeout()
+ 8 0x804df9b (from 0x9cc0dd) dispatch_status()
+ 9 0x804d9fb (from 0x804dfdd) queue_dispatch()
+ 8 0x804decc (from 0x9e16ff) remove_timeout()
+ 8 0x804ddbf (from 0x9e1469) timeout_handler_free()
+ 6 0x804ff5d (from 0x80508d8) filter_data_add_callback()
+ 4 0x80877a4 (from 0x809ee20) info()
+ 4 0x809eca1 (from 0x809ee2b) session_ref()
+ 5 0x8087840 (from 0x809ed03) btd_debug()
+ 0 0x808a019 (from 0x17fdab) io_security_event()
+ 1 0x8087c29 (from 0x808a121) hci_test_bit()
+ 1 0x8089425 (from 0x808a187) cmd_complete()
+ 2 0x80890df (from 0x80894fe) start_inquiry()
+ 3 0x809d9c3 (from 0x808912e) manager_find_adapter()
+ 4 0x809d8e3 (from 0x16847e) adapter_cmp()
+ 5 0x80a44f7 (from 0x809d91b) adapter_get_address()
+ 6 0x809dff1 (from 0x80a4525) bacpy()
+ 5 0x809cf7c (from 0x809d92d) bacmp()
+ 3 0x80a4642 (from 0x8089158) adapter_get_state()
+ 3 0x80a543e (from 0x8089166) adapter_has_discov_sessions()
+ 3 0x80a453a (from 0x808918a) adapter_set_state()
+ 4 0x80ac200 (from 0x80a4618) emit_property_changed()
+ 5 0x80abf1d (from 0x80ac29c) append_variant()
+ 5 0x804f543 (from 0x80ac2ae) g_dbus_send_message()
+ 1 0x808812b (from 0x808a38a) check_pending_hci_req()
+ 0 0x80962cd (from 0x17fdab) connect_watch()
+ 1 0x80a97cf (from 0x80964ae) browse_cb()
Last call is search_cb I'm sure about it, thing is that the tracer only
traces function when they exit, not when they get in.
I think the best way to solve this is that the device structure has a
reference to the context so it can release it when it gets removed
without any issue. We don't need the sdp callback if we no longer have a
device anyway.
Manuel
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox