* [PATCH v3 3/4] Extract service UUIDs from advertising data
From: Vinicius Costa Gomes @ 2010-11-11 23:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bruna Moreira
In-Reply-To: <1289518769-3009-1-git-send-email-vinicius.gomes@openbossa.org>
From: Bruna Moreira <bruna.moreira@openbossa.org>
Make get_eir_uuids() return a GSList of strings, so it can be reused to
extract UUIDs from LE advertising data. The bt_strlist2array() helper
function was created to convert a GSList into a plain array of strings
(needed to send through D-Bus).
---
src/adapter.c | 71 ++++++++++++++++++++++++++++++++++++++++++++-------------
src/adapter.h | 1 +
2 files changed, 56 insertions(+), 16 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 724ea74..49ba5fc 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -202,6 +202,8 @@ static void dev_info_free(struct remote_dev_info *dev)
{
g_free(dev->name);
g_free(dev->alias);
+ g_slist_foreach(dev->services, (GFunc) g_free, NULL);
+ g_slist_free(dev->services);
g_free(dev);
}
@@ -2962,11 +2964,27 @@ static void emit_device_found(const char *path, const char *address,
g_dbus_send_message(connection, signal);
}
-static char **get_eir_uuids(uint8_t *eir_data, size_t eir_length,
- size_t *uuid_count)
+static char **strlist2array(GSList *list)
+{
+ GSList *l;
+ unsigned int i, n;
+ char **array;
+
+ if (list == NULL)
+ return NULL;
+
+ n = g_slist_length(list);
+ array = g_new0(char *, n + 1);
+
+ for (l = list, i = 0; l; l = l->next, i++)
+ array[i] = g_strdup((const gchar *) l->data);
+
+ return array;
+}
+
+static GSList *get_eir_uuids(uint8_t *eir_data, size_t eir_length, GSList *list)
{
uint16_t len = 0;
- char **uuids;
size_t total;
size_t uuid16_count = 0;
size_t uuid32_count = 0;
@@ -2975,10 +2993,11 @@ static char **get_eir_uuids(uint8_t *eir_data, size_t eir_length,
uint8_t *uuid32;
uint8_t *uuid128;
uuid_t service;
+ char *uuid_str;
unsigned int i;
if (eir_data == NULL || eir_length == 0)
- return NULL;
+ return list;
while (len < eir_length - 1) {
uint8_t field_len = eir_data[0];
@@ -3011,15 +3030,12 @@ static char **get_eir_uuids(uint8_t *eir_data, size_t eir_length,
/* Bail out if got incorrect length */
if (len > eir_length)
- return NULL;
+ return list;
total = uuid16_count + uuid32_count + uuid128_count;
- *uuid_count = total;
if (!total)
- return NULL;
-
- uuids = g_new0(char *, total + 1);
+ return list;
/* Generate uuids in SDP format (EIR data is Little Endian) */
service.type = SDP_UUID16;
@@ -3028,7 +3044,12 @@ static char **get_eir_uuids(uint8_t *eir_data, size_t eir_length,
val16 = (val16 << 8) + uuid16[0];
service.value.uuid16 = val16;
- uuids[i] = bt_uuid2string(&service);
+ uuid_str = bt_uuid2string(&service);
+ if (g_slist_find_custom(list, uuid_str,
+ (GCompareFunc) strcmp) == NULL)
+ list = g_slist_append(list, uuid_str);
+ else
+ g_free(uuid_str);
uuid16 += 2;
}
@@ -3041,7 +3062,12 @@ static char **get_eir_uuids(uint8_t *eir_data, size_t eir_length,
val32 = (val32 << 8) + uuid32[k];
service.value.uuid32 = val32;
- uuids[i] = bt_uuid2string(&service);
+ uuid_str = bt_uuid2string(&service);
+ if (g_slist_find_custom(list, uuid_str,
+ (GCompareFunc) strcmp) == NULL)
+ list = g_slist_append(list, uuid_str);
+ else
+ g_free(uuid_str);
uuid32 += 4;
}
@@ -3052,11 +3078,16 @@ static char **get_eir_uuids(uint8_t *eir_data, size_t eir_length,
for (k = 0; k < 16; k++)
service.value.uuid128.data[k] = uuid128[16 - k - 1];
- uuids[i] = bt_uuid2string(&service);
+ uuid_str = bt_uuid2string(&service);
+ if (g_slist_find_custom(list, uuid_str,
+ (GCompareFunc) strcmp) == NULL)
+ list = g_slist_append(list, uuid_str);
+ else
+ g_free(uuid_str);
uuid128 += 16;
}
- return uuids;
+ return list;
}
void adapter_emit_device_found(struct btd_adapter *adapter,
@@ -3070,7 +3101,7 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
dbus_int16_t rssi = dev->rssi;
char *alias;
char **uuids = NULL;
- size_t uuid_count = 0;
+ size_t uuid_count;
ba2str(&dev->bdaddr, peer_addr);
ba2str(&adapter->bdaddr, local_addr);
@@ -3090,8 +3121,16 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
} else
alias = g_strdup(dev->alias);
- /* Extract UUIDs from extended inquiry response if any*/
- uuids = get_eir_uuids(eir_data, eir_length, &uuid_count);
+ /* Extract UUIDs from extended inquiry response if any */
+ dev->services = get_eir_uuids(eir_data, eir_length, dev->services);
+ uuid_count = g_slist_length(dev->services);
+
+ if (dev->services) {
+ uuids = strlist2array(dev->services);
+ g_slist_foreach(dev->services, (GFunc) g_free, NULL);
+ g_slist_free(dev->services);
+ dev->services = NULL;
+ }
emit_device_found(adapter->path, paddr,
"Address", DBUS_TYPE_STRING, &paddr,
diff --git a/src/adapter.h b/src/adapter.h
index e6d2fe6..25fd3c8 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -71,6 +71,7 @@ struct remote_dev_info {
name_status_t name_status;
gboolean le;
/* LE adv data */
+ GSList *services;
uint8_t evt_type;
uint8_t bdaddr_type;
};
--
1.7.3.2
^ permalink raw reply related
* [PATCH v3 4/4] Emit "DeviceFound" signal for LE devices
From: Vinicius Costa Gomes @ 2010-11-11 23:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bruna Moreira
In-Reply-To: <1289518769-3009-1-git-send-email-vinicius.gomes@openbossa.org>
From: Bruna Moreira <bruna.moreira@openbossa.org>
The adapter_emit_device_found() function was modified to emit
DeviceFound signal for LE devices as well.
---
src/adapter.c | 30 +++++++++++++++++++++++++-----
1 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 49ba5fc..92087f6 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3110,6 +3110,27 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
if (device)
paired = device_is_paired(device);
+ /* Extract UUIDs from extended inquiry response if any */
+ dev->services = get_eir_uuids(eir_data, eir_length, dev->services);
+ uuid_count = g_slist_length(dev->services);
+
+ if (dev->services)
+ uuids = strlist2array(dev->services);
+
+ if (dev->le) {
+ emit_device_found(adapter->path, paddr,
+ "Address", DBUS_TYPE_STRING, &paddr,
+ "RSSI", DBUS_TYPE_INT16, &rssi,
+ "Name", DBUS_TYPE_STRING, &dev->name,
+ "Paired", DBUS_TYPE_BOOLEAN, &paired,
+ "UUIDs", DBUS_TYPE_ARRAY, &uuids, uuid_count,
+ NULL);
+
+ g_strfreev(uuids);
+
+ return;
+ }
+
icon = class_to_icon(dev->class);
if (!dev->alias) {
@@ -3121,12 +3142,7 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
} else
alias = g_strdup(dev->alias);
- /* Extract UUIDs from extended inquiry response if any */
- dev->services = get_eir_uuids(eir_data, eir_length, dev->services);
- uuid_count = g_slist_length(dev->services);
-
if (dev->services) {
- uuids = strlist2array(dev->services);
g_slist_foreach(dev->services, (GFunc) g_free, NULL);
g_slist_free(dev->services);
dev->services = NULL;
@@ -3205,6 +3221,10 @@ void adapter_update_device_from_info(struct btd_adapter *adapter,
if (tmp_name)
dev->name = tmp_name;
}
+
+ /* FIXME: check if other information was changed before emitting the
+ * signal */
+ adapter_emit_device_found(adapter, dev, info->data, info->length);
}
void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
--
1.7.3.2
^ permalink raw reply related
* RE: [PATCH v2 1/7] Fix invalid memory access when EIR field length is zero
From: Inga Stotland @ 2010-11-12 0:24 UTC (permalink / raw)
To: 'Johan Hedberg', 'Vinicius Costa Gomes'
Cc: linux-bluetooth, 'Bruna Moreira'
In-Reply-To: <20101111210705.GB24514@jh-x301>
Hi Johan,
-----Original Message-----
From: linux-bluetooth-owner@vger.kernel.org
[mailto:linux-bluetooth-owner@vger.kernel.org] On Behalf Of Johan Hedberg
Sent: Thursday, November 11, 2010 1:07 PM
To: Vinicius Costa Gomes
Cc: linux-bluetooth@vger.kernel.org; Bruna Moreira
Subject: Re: [PATCH v2 1/7] Fix invalid memory access when EIR field length
is zero
Hi,
On Thu, Nov 11, 2010, Vinicius Costa Gomes wrote:
> diff --git a/src/adapter.c b/src/adapter.c
> index b1aabbd..8b742b7 100644
> --- a/src/adapter.c
> +++ b/src/adapter.c
> @@ -2977,14 +2977,13 @@ static char **get_eir_uuids(uint8_t *eir_data,
size_t *uuid_count)
> unsigned int i;
>
> while (len < EIR_DATA_LENGTH - 1) {
> - uint8_t type = eir_data[1];
> uint8_t field_len = eir_data[0];
>
> /* Check for the end of EIR */
> if (field_len == 0)
> break;
>
> - switch (type) {
> + switch (eir_data[1]) {
> case EIR_UUID16_SOME:
> case EIR_UUID16_ALL:
> uuid16_count = field_len / 2;
Pushed upstream. Thanks.
Johan
--
Was there a bug to begin with? :)
The access to eir_data[1] was always valid due to the check (len <
EIR_DATA_LENGTH - 1)
and the fact that eir_data is a buffer of fixed length of EIR_DATA_LENGTH
(240 bytes).
Oh well, it's upstream already.
Inga
^ permalink raw reply
* Re: [PATCH v2] Add iwmmxt optimization for sbc for pxa series cpu
From: Keith Mok @ 2010-11-12 7:35 UTC (permalink / raw)
To: Siarhei Siamashka; +Cc: linux-bluetooth
In-Reply-To: <201011111346.58906.siarhei.siamashka@gmail.com>
> Did you run some benchmarks with these optimizations to measure how much they
> are helping?
Tested on Marvell PXA platform.
== Before ==
$ time ./sbcenc -b53 -s8 -j c.au > /dev/null
real 0m 0.41s
user 0m 0.40s
sys 0m 0.00s
== After ==
$ time ./sbcenc -b53 -s8 -j c.au > /dev/null
real 0m 0.19s
user 0m 0.17s
sys 0m 0.02s
> Using back-to-back WLDRD instructions has some performance penalty
I rearrange the instructions and keep the original one as for reference in
the block that comment out. Since the code is really difficult to read
after interleaved.
> The MMX code was using PCMPGTD and the other instructions just because MMX
> instruction set is very limited and did not have the needed instructions. But
> you can use WABS and WMAX instructions to do this job better. You can refer to
> the original C code and also to ARM NEON optimizations to get some ideas about
> how to do this operation faster.
Changed as suggested.
But got a question that the __IWMMXT__ builtin gcc definition is not a
reliable way to
determine whether mcpu=iwmmxt2 is turned on or not. It will break when
compile under pxa270
which does not support wabs with just mcpu=iwmmx on.
Keith
Signed-off-by: Keith Mok <ek9852@gmail.com>
---
diff --git a/Makefile.am b/Makefile.am
index da308a7..03a9bf2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -65,6 +65,7 @@ noinst_LTLIBRARIES += sbc/libsbc.la
sbc_libsbc_la_SOURCES = sbc/sbc.h sbc/sbc.c sbc/sbc_math.h sbc/sbc_tables.h \
sbc/sbc_primitives.h sbc/sbc_primitives.c \
sbc/sbc_primitives_mmx.h sbc/sbc_primitives_mmx.c \
+ sbc/sbc_primitives_iwmmxt.h sbc/sbc_primitives_iwmmxt.c \
sbc/sbc_primitives_neon.h sbc/sbc_primitives_neon.c \
sbc/sbc_primitives_armv6.h sbc/sbc_primitives_armv6.c
diff --git a/sbc/sbc_primitives.c b/sbc/sbc_primitives.c
index f87fb5a..ad780d0 100644
--- a/sbc/sbc_primitives.c
+++ b/sbc/sbc_primitives.c
@@ -33,6 +33,7 @@
#include "sbc_primitives.h"
#include "sbc_primitives_mmx.h"
+#include "sbc_primitives_iwmmxt.h"
#include "sbc_primitives_neon.h"
#include "sbc_primitives_armv6.h"
@@ -544,6 +545,9 @@ void sbc_init_primitives(struct sbc_encoder_state *state)
#ifdef SBC_BUILD_WITH_ARMV6_SUPPORT
sbc_init_primitives_armv6(state);
#endif
+#ifdef SBC_BUILD_WITH_IWMMXT_SUPPORT
+ sbc_init_primitives_iwmmxt(state);
+#endif
#ifdef SBC_BUILD_WITH_NEON_SUPPORT
sbc_init_primitives_neon(state);
#endif
diff --git a/sbc/sbc_primitives_iwmmxt.c b/sbc/sbc_primitives_iwmmxt.c
new file mode 100644
index 0000000..b988bb1
--- /dev/null
+++ b/sbc/sbc_primitives_iwmmxt.c
@@ -0,0 +1,599 @@
+/*
+ *
+ * Bluetooth low-complexity, subband codec (SBC) library
+ *
+ * Copyright (C) 2010 Keith Mok <ek9852@gmail.com>
+ * Based on sbc_primitives_mmx.c
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <stdint.h>
+#include <limits.h>
+#include "sbc.h"
+#include "sbc_math.h"
+#include "sbc_tables.h"
+
+#include "sbc_primitives_iwmmxt.h"
+
+/*
+ * IWMMXT optimizations
+ */
+
+#ifdef SBC_BUILD_WITH_IWMMXT_SUPPORT
+
+static inline void sbc_analyze_four_iwmmxt(const int16_t *in, int32_t *out,
+ const FIXED_T *consts)
+{
+ asm volatile (
+ "wldrd wr0, [%0]\n"
+ "tbcstw wr4, %2\n"
+ "wldrd wr2, [%1]\n"
+ "wldrd wr1, [%0, #8]\n"
+ "wldrd wr3, [%1, #8]\n"
+ "wmadds wr0, wr2, wr0\n"
+ "wldrd wr6, [%0, #16]\n"
+ "wmadds wr1, wr3, wr1\n"
+ "wldrd wr7, [%0, #24]\n"
+ "waddwss wr0, wr0, wr4\n"
+ "wldrd wr8, [%1, #16]\n"
+ "waddwss wr1, wr1, wr4\n"
+ "wldrd wr9, [%1, #24]\n"
+ "wmadds wr6, wr8, wr6\n"
+ "wldrd wr2, [%0, #32]\n"
+ "wmadds wr7, wr9, wr7\n"
+ "wldrd wr3, [%0, #40]\n"
+ "waddwss wr0, wr6, wr0\n"
+ "wldrd wr4, [%1, #32]\n"
+ "waddwss wr1, wr7, wr1\n"
+ "wldrd wr5, [%1, #40]\n"
+ "wmadds wr2, wr4, wr2\n"
+ "wldrd wr6, [%0, #48]\n"
+ "wmadds wr3, wr5, wr3\n"
+ "wldrd wr7, [%0, #56]\n"
+ "waddwss wr0, wr2, wr0\n"
+ "wldrd wr8, [%1, #48]\n"
+ "waddwss wr1, wr3, wr1\n"
+ "wldrd wr9, [%1, #56]\n"
+ "wmadds wr6, wr8, wr6\n"
+ "wldrd wr2, [%0, #64]\n"
+ "wmadds wr7, wr9, wr7\n"
+ "wldrd wr3, [%0, #72]\n"
+ "waddwss wr0, wr6, wr0\n"
+ "wldrd wr4, [%1, #64]\n"
+ "waddwss wr1, wr7, wr1\n"
+ "wldrd wr5, [%1, #72]\n"
+ "wmadds wr2, wr4, wr2\n"
+ "wmadds wr3, wr5, wr3\n"
+ "waddwss wr0, wr2, wr0\n"
+ "waddwss wr1, wr3, wr1\n"
+ "\n"
+ "tmcr wcgr0, %4\n"
+ "wsrawg wr0, wr0, wcgr0\n"
+ "wldrd wr4, [%1, #80]\n"
+ "wsrawg wr1, wr1, wcgr0\n"
+ "wldrd wr5, [%1, #88]\n"
+ "wpackwss wr0, wr0, wr0\n"
+ "wldrd wr6, [%1, #96]\n"
+ "wpackwss wr1, wr1, wr1\n"
+ "wldrd wr7, [%1, #104]\n"
+ "wmadds wr2, wr5, wr0\n"
+ "wmadds wr0, wr4, wr0\n"
+ "\n"
+ "wmadds wr3, wr7, wr1\n"
+ "wmadds wr1, wr6, wr1\n"
+ "waddwss wr0, wr1, wr0\n"
+ "waddwss wr2, wr3, wr2\n"
+ "\n"
+ "wstrd wr0, [%3]\n"
+ "wstrd wr2, [%3, #8]\n"
+ :
+ : "r" (in), "r" (consts),
+ "r" (1 << (SBC_PROTO_FIXED4_SCALE - 1)), "r" (out),
+ "r" (SBC_PROTO_FIXED4_SCALE)
+ : "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
+ "wr8", "wr9", "wcgr0", "memory");
+#if 0
+ /* without pipeline and resultant latency consideration
+ * keep it here for reference
+ * since the latency optimizated code above is difficult to read */
+ asm volatile (
+ "tbcstw wr4, %2\n"
+ "wldrd wr0, [%0]\n"
+ "wldrd wr1, [%0, #8]\n"
+ "wldrd wr2, [%1]\n"
+ "wldrd wr3, [%1, #8]\n"
+ "wmadds wr0, wr2, wr0\n"
+ "wmadds wr1, wr3, wr1\n"
+ "waddwss wr0, wr0, wr4\n"
+ "waddwss wr1, wr1, wr4\n"
+ "\n"
+ "wldrd wr2, [%0, #16]\n"
+ "wldrd wr3, [%0, #24]\n"
+ "wldrd wr4, [%1, #16]\n"
+ "wldrd wr5, [%1, #24]\n"
+ "wmadds wr2, wr4, wr2\n"
+ "wmadds wr3, wr5, wr3\n"
+ "waddwss wr0, wr2, wr0\n"
+ "waddwss wr1, wr3, wr1\n"
+ "\n"
+ "wldrd wr2, [%0, #32]\n"
+ "wldrd wr3, [%0, #40]\n"
+ "wldrd wr4, [%1, #32]\n"
+ "wldrd wr5, [%1, #40]\n"
+ "wmadds wr2, wr4, wr2\n"
+ "wmadds wr3, wr5, wr3\n"
+ "waddwss wr0, wr2, wr0\n"
+ "waddwss wr1, wr3, wr1\n"
+ "\n"
+ "wldrd wr2, [%0, #48]\n"
+ "wldrd wr3, [%0, #56]\n"
+ "wldrd wr4, [%1, #48]\n"
+ "wldrd wr5, [%1, #56]\n"
+ "wmadds wr2, wr4, wr2\n"
+ "wmadds wr3, wr5, wr3\n"
+ "waddwss wr0, wr2, wr0\n"
+ "waddwss wr1, wr3, wr1\n"
+ "\n"
+ "wldrd wr2, [%0, #64]\n"
+ "wldrd wr3, [%0, #72]\n"
+ "wldrd wr4, [%1, #64]\n"
+ "wldrd wr5, [%1, #72]\n"
+ "wmadds wr2, wr4, wr2\n"
+ "wmadds wr3, wr5, wr3\n"
+ "waddwss wr0, wr2, wr0\n"
+ "waddwss wr1, wr3, wr1\n"
+ "\n"
+ "tmcr wcgr0, %4\n"
+ "wsrawg wr0, wr0, wcgr0\n"
+ "wsrawg wr1, wr1, wcgr0\n"
+ "wpackwss wr0, wr0, wr0\n"
+ "wpackwss wr1, wr1, wr1\n"
+ "\n"
+ "wldrd wr4, [%1, #80]\n"
+ "wldrd wr5, [%1, #88]\n"
+ "wldrd wr6, [%1, #96]\n"
+ "wldrd wr7, [%1, #104]\n"
+ "wmadds wr2, wr5, wr0\n"
+ "wmadds wr0, wr4, wr0\n"
+ "\n"
+ "wmadds wr3, wr7, wr1\n"
+ "wmadds wr1, wr6, wr1\n"
+ "waddwss wr0, wr1, wr0\n"
+ "waddwss wr2, wr3, wr2\n"
+ "\n"
+ "wstrd wr0, [%3]\n"
+ "wstrd wr2, [%3, #8]\n"
+ :
+ : "r" (in), "r" (consts),
+ "r" (1 << (SBC_PROTO_FIXED4_SCALE - 1)), "r" (out),
+ "r" (SBC_PROTO_FIXED4_SCALE)
+ : "memory");
+#endif
+}
+
+static inline void sbc_analyze_eight_iwmmxt(const int16_t *in, int32_t *out,
+ const FIXED_T *consts)
+{
+ asm volatile (
+ "wldrd wr0, [%0]\n"
+ "tbcstw wr15, %2\n"
+ "wldrd wr1, [%0, #8]\n"
+ "wldrd wr2, [%0, #16]\n"
+ "wldrd wr3, [%0, #24]\n"
+ "wldrd wr4, [%1]\n"
+ "wldrd wr5, [%1, #8]\n"
+ "wldrd wr6, [%1, #16]\n"
+ "wldrd wr7, [%1, #24]\n"
+ "wmadds wr0, wr0, wr4\n"
+ "wldrd wr8, [%1, #32]\n"
+ "wmadds wr1, wr1, wr5\n"
+ "wldrd wr9, [%1, #40]\n"
+ "wmadds wr2, wr2, wr6\n"
+ "wldrd wr10, [%1, #48]\n"
+ "wmadds wr3, wr3, wr7\n"
+ "wldrd wr11, [%1, #56]\n"
+ "waddwss wr0, wr0, wr15\n"
+ "wldrd wr4, [%0, #32]\n"
+ "waddwss wr1, wr1, wr15\n"
+ "wldrd wr5, [%0, #40]\n"
+ "waddwss wr2, wr2, wr15\n"
+ "wldrd wr6, [%0, #48]\n"
+ "waddwss wr3, wr3, wr15\n"
+ "wldrd wr7, [%0, #56]\n"
+ "wmadds wr4, wr4, wr8\n"
+ "wldrd wr12, [%0, #64]\n"
+ "wmadds wr5, wr5, wr9\n"
+ "wldrd wr13, [%0, #72]\n"
+ "wmadds wr6, wr6, wr10\n"
+ "wldrd wr14, [%0, #80]\n"
+ "wmadds wr7, wr7, wr11\n"
+ "wldrd wr15, [%0, #88]\n"
+ "waddwss wr0, wr4, wr0\n"
+ "wldrd wr8, [%1, #64]\n"
+ "waddwss wr1, wr5, wr1\n"
+ "wldrd wr9, [%1, #72]\n"
+ "waddwss wr2, wr6, wr2\n"
+ "wldrd wr10, [%1, #80]\n"
+ "waddwss wr3, wr7, wr3\n"
+ "wldrd wr11, [%1, #88]\n"
+ "wmadds wr12, wr12, wr8\n"
+ "wldrd wr4, [%0, #96]\n"
+ "wmadds wr13, wr13, wr9\n"
+ "wldrd wr5, [%0, #104]\n"
+ "wmadds wr14, wr14, wr10\n"
+ "wldrd wr6, [%0, #112]\n"
+ "wmadds wr15, wr15, wr11\n"
+ "wldrd wr7, [%0, #120]\n"
+ "waddwss wr0, wr12, wr0\n"
+ "wldrd wr8, [%1, #96]\n"
+ "waddwss wr1, wr13, wr1\n"
+ "wldrd wr9, [%1, #104]\n"
+ "waddwss wr2, wr14, wr2\n"
+ "wldrd wr10, [%1, #112]\n"
+ "waddwss wr3, wr15, wr3\n"
+ "wldrd wr11, [%1, #120]\n"
+ "wmadds wr4, wr4, wr8\n"
+ "wldrd wr12, [%0, #128]\n"
+ "wmadds wr5, wr5, wr9\n"
+ "wldrd wr13, [%0, #136]\n"
+ "wmadds wr6, wr6, wr10\n"
+ "wldrd wr14, [%0, #144]\n"
+ "wmadds wr7, wr7, wr11\n"
+ "wldrd wr15, [%0, #152]\n"
+ "waddwss wr0, wr4, wr0\n"
+ "wldrd wr8, [%1, #128]\n"
+ "waddwss wr1, wr5, wr1\n"
+ "wldrd wr9, [%1, #136]\n"
+ "waddwss wr2, wr6, wr2\n"
+ "wldrd wr10, [%1, #144]\n"
+ "waddwss wr3, wr7, wr3\n"
+ "wldrd wr11, [%1, #152]\n"
+ "wmadds wr12, wr12, wr8\n"
+ "wmadds wr13, wr13, wr9\n"
+ "wmadds wr14, wr14, wr10\n"
+ "wmadds wr15, wr15, wr11\n"
+ "waddwss wr0, wr12, wr0\n"
+ "waddwss wr1, wr13, wr1\n"
+ "waddwss wr2, wr14, wr2\n"
+ "waddwss wr3, wr15, wr3\n"
+ "\n"
+ "tmcr wcgr0, %4\n"
+ "wsrawg wr0, wr0, wcgr0\n"
+ "wsrawg wr1, wr1, wcgr0\n"
+ "wsrawg wr2, wr2, wcgr0\n"
+ "wsrawg wr3, wr3, wcgr0\n"
+ "\n"
+ "wpackwss wr0, wr0, wr0\n"
+ "wpackwss wr1, wr1, wr1\n"
+ "wldrd wr4, [%1, #160]\n"
+ "wpackwss wr2, wr2, wr2\n"
+ "wldrd wr5, [%1, #168]\n"
+ "wpackwss wr3, wr3, wr3\n"
+ "wldrd wr6, [%1, #192]\n"
+ "wmadds wr4, wr4, wr0\n"
+ "wldrd wr7, [%1, #200]\n"
+ "wmadds wr5, wr5, wr0\n"
+ "wldrd wr8, [%1, #224]\n"
+ "wmadds wr6, wr6, wr1\n"
+ "wldrd wr9, [%1, #232]\n"
+ "wmadds wr7, wr7, wr1\n"
+ "waddwss wr4, wr6, wr4\n"
+ "waddwss wr5, wr7, wr5\n"
+ "wmadds wr8, wr8, wr2\n"
+ "wldrd wr6, [%1, #256]\n"
+ "wmadds wr9, wr9, wr2\n"
+ "wldrd wr7, [%1, #264]\n"
+ "waddwss wr4, wr8, wr4\n"
+ "waddwss wr5, wr9, wr5\n"
+ "wmadds wr6, wr6, wr3\n"
+ "wmadds wr7, wr7, wr3\n"
+ "waddwss wr4, wr6, wr4\n"
+ "waddwss wr5, wr7, wr5\n"
+ "\n"
+ "wstrd wr4, [%3]\n"
+ "wstrd wr5, [%3, #8]\n"
+ "\n"
+ "wldrd wr6, [%1, #176]\n"
+ "wldrd wr5, [%1, #184]\n"
+ "wmadds wr5, wr5, wr0\n"
+ "wldrd wr8, [%1, #208]\n"
+ "wmadds wr0, wr6, wr0\n"
+ "wldrd wr9, [%1, #216]\n"
+ "wmadds wr9, wr9, wr1\n"
+ "wldrd wr6, [%1, #240]\n"
+ "wmadds wr1, wr8, wr1\n"
+ "wldrd wr7, [%1, #248]\n"
+ "waddwss wr0, wr1, wr0\n"
+ "waddwss wr5, wr9, wr5\n"
+ "wmadds wr7, wr7, wr2\n"
+ "wldrd wr8, [%1, #272]\n"
+ "wmadds wr2, wr6, wr2\n"
+ "wldrd wr9, [%1, #280]\n"
+ "waddwss wr0, wr2, wr0\n"
+ "waddwss wr5, wr7, wr5\n"
+ "wmadds wr9, wr9, wr3\n"
+ "wmadds wr3, wr8, wr3\n"
+ "waddwss wr0, wr3, wr0\n"
+ "waddwss wr5, wr9, wr5\n"
+ "\n"
+ "wstrd wr0, [%3, #16]\n"
+ "wstrd wr5, [%3, #24]\n"
+ :
+ : "r" (in), "r" (consts),
+ "r" (1 << (SBC_PROTO_FIXED8_SCALE - 1)), "r" (out),
+ "r" (SBC_PROTO_FIXED8_SCALE)
+ : "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
+ "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15",
+ "wcgr0", "memory");
+#if 0
+ /* without pipeline and resultant latency consideration
+ * keep it here for reference
+ * since the latency optimizated code above is difficult to read */
+ asm volatile (
+ "tbcstw wr8, %2\n"
+ "wldrd wr0, [%0]\n"
+ "wldrd wr1, [%0, #8]\n"
+ "wldrd wr2, [%0, #16]\n"
+ "wldrd wr3, [%0, #24]\n"
+ "wldrd wr4, [%1]\n"
+ "wldrd wr5, [%1, #8]\n"
+ "wldrd wr6, [%1, #16]\n"
+ "wldrd wr7, [%1, #24]\n"
+ "wmadds wr0, wr0, wr4\n"
+ "wmadds wr1, wr1, wr5\n"
+ "wmadds wr2, wr2, wr6\n"
+ "wmadds wr3, wr3, wr7\n"
+ "waddwss wr0, wr0, wr8\n"
+ "waddwss wr1, wr1, wr8\n"
+ "waddwss wr2, wr2, wr8\n"
+ "waddwss wr3, wr3, wr8\n"
+ "\n"
+ "wldrd wr4, [%0, #32]\n"
+ "wldrd wr5, [%0, #40]\n"
+ "wldrd wr6, [%0, #48]\n"
+ "wldrd wr7, [%0, #56]\n"
+ "wldrd wr8, [%1, #32]\n"
+ "wldrd wr9, [%1, #40]\n"
+ "wldrd wr10, [%1, #48]\n"
+ "wldrd wr11, [%1, #56]\n"
+ "wmadds wr4, wr4, wr8\n"
+ "wmadds wr5, wr5, wr9\n"
+ "wmadds wr6, wr6, wr10\n"
+ "wmadds wr7, wr7, wr11\n"
+ "waddwss wr0, wr4, wr0\n"
+ "waddwss wr1, wr5, wr1\n"
+ "waddwss wr2, wr6, wr2\n"
+ "waddwss wr3, wr7, wr3\n"
+ "\n"
+ "wldrd wr4, [%0, #64]\n"
+ "wldrd wr5, [%0, #72]\n"
+ "wldrd wr6, [%0, #80]\n"
+ "wldrd wr7, [%0, #88]\n"
+ "wldrd wr8, [%1, #64]\n"
+ "wldrd wr9, [%1, #72]\n"
+ "wldrd wr10, [%1, #80]\n"
+ "wldrd wr11, [%1, #88]\n"
+ "wmadds wr4, wr4, wr8\n"
+ "wmadds wr5, wr5, wr9\n"
+ "wmadds wr6, wr6, wr10\n"
+ "wmadds wr7, wr7, wr11\n"
+ "waddwss wr0, wr4, wr0\n"
+ "waddwss wr1, wr5, wr1\n"
+ "waddwss wr2, wr6, wr2\n"
+ "waddwss wr3, wr7, wr3\n"
+ "\n"
+ "wldrd wr4, [%0, #96]\n"
+ "wldrd wr5, [%0, #104]\n"
+ "wldrd wr6, [%0, #112]\n"
+ "wldrd wr7, [%0, #120]\n"
+ "wldrd wr8, [%1, #96]\n"
+ "wldrd wr9, [%1, #104]\n"
+ "wldrd wr10, [%1, #112]\n"
+ "wldrd wr11, [%1, #120]\n"
+ "wmadds wr4, wr4, wr8\n"
+ "wmadds wr5, wr5, wr9\n"
+ "wmadds wr6, wr6, wr10\n"
+ "wmadds wr7, wr7, wr11\n"
+ "waddwss wr0, wr4, wr0\n"
+ "waddwss wr1, wr5, wr1\n"
+ "waddwss wr2, wr6, wr2\n"
+ "waddwss wr3, wr7, wr3\n"
+ "\n"
+ "wldrd wr4, [%0, #128]\n"
+ "wldrd wr5, [%0, #136]\n"
+ "wldrd wr6, [%0, #144]\n"
+ "wldrd wr7, [%0, #152]\n"
+ "wldrd wr8, [%1, #128]\n"
+ "wldrd wr9, [%1, #136]\n"
+ "wldrd wr10, [%1, #144]\n"
+ "wldrd wr11, [%1, #152]\n"
+ "wmadds wr4, wr4, wr8\n"
+ "wmadds wr5, wr5, wr9\n"
+ "wmadds wr6, wr6, wr10\n"
+ "wmadds wr7, wr7, wr11\n"
+ "waddwss wr0, wr4, wr0\n"
+ "waddwss wr1, wr5, wr1\n"
+ "waddwss wr2, wr6, wr2\n"
+ "waddwss wr3, wr7, wr3\n"
+ "\n"
+ "tmcr wcgr0, %4\n"
+ "wsrawg wr0, wr0, wcgr0\n"
+ "wsrawg wr1, wr1, wcgr0\n"
+ "wsrawg wr2, wr2, wcgr0\n"
+ "wsrawg wr3, wr3, wcgr0\n"
+ "\n"
+ "wpackwss wr0, wr0, wr0\n"
+ "wpackwss wr1, wr1, wr1\n"
+ "wpackwss wr2, wr2, wr2\n"
+ "wpackwss wr3, wr3, wr3\n"
+ "\n"
+ "wldrd wr4, [%1, #160]\n"
+ "wldrd wr5, [%1, #168]\n"
+ "wmadds wr4, wr4, wr0\n"
+ "wmadds wr5, wr5, wr0\n"
+ "\n"
+ "wldrd wr6, [%1, #192]\n"
+ "wldrd wr7, [%1, #200]\n"
+ "wmadds wr6, wr6, wr1\n"
+ "wmadds wr7, wr7, wr1\n"
+ "waddwss wr4, wr6, wr4\n"
+ "waddwss wr5, wr7, wr5\n"
+ "\n"
+ "wldrd wr6, [%1, #224]\n"
+ "wldrd wr7, [%1, #232]\n"
+ "wmadds wr6, wr6, wr2\n"
+ "wmadds wr7, wr7, wr2\n"
+ "waddwss wr4, wr6, wr4\n"
+ "waddwss wr5, wr7, wr5\n"
+ "\n"
+ "wldrd wr6, [%1, #256]\n"
+ "wldrd wr7, [%1, #264]\n"
+ "wmadds wr6, wr6, wr3\n"
+ "wmadds wr7, wr7, wr3\n"
+ "waddwss wr4, wr6, wr4\n"
+ "waddwss wr5, wr7, wr5\n"
+ "\n"
+ "wstrd wr4, [%3]\n"
+ "wstrd wr5, [%3, #8]\n"
+ "\n"
+ "wldrd wr4, [%1, #176]\n"
+ "wldrd wr5, [%1, #184]\n"
+ "wmadds wr5, wr5, wr0\n"
+ "wmadds wr0, wr4, wr0\n"
+ "\n"
+ "wldrd wr4, [%1, #208]\n"
+ "wldrd wr7, [%1, #216]\n"
+ "wmadds wr7, wr7, wr1\n"
+ "wmadds wr1, wr4, wr1\n"
+ "waddwss wr0, wr1, wr0\n"
+ "waddwss wr5, wr7, wr5\n"
+ "\n"
+ "wldrd wr4, [%1, #240]\n"
+ "wldrd wr7, [%1, #248]\n"
+ "wmadds wr7, wr7, wr2\n"
+ "wmadds wr2, wr4, wr2\n"
+ "waddwss wr0, wr2, wr0\n"
+ "waddwss wr5, wr7, wr5\n"
+ "\n"
+ "wldrd wr4, [%1, #272]\n"
+ "wldrd wr7, [%1, #280]\n"
+ "wmadds wr7, wr7, wr3\n"
+ "wmadds wr3, wr4, wr3\n"
+ "waddwss wr0, wr3, wr0\n"
+ "waddwss wr5, wr7, wr5\n"
+ "\n"
+ "wstrd wr0, [%3, #16]\n"
+ "wstrd wr5, [%3, #24]\n"
+ :
+ : "r" (in), "r" (consts),
+ "r" (1 << (SBC_PROTO_FIXED8_SCALE - 1)), "r" (out),
+ "r" (SBC_PROTO_FIXED8_SCALE)
+ : "memory");
+#endif
+}
+
+static inline void sbc_analyze_4b_4s_iwmmxt(int16_t *x, int32_t *out,
+ int out_stride)
+{
+ /* Analyze blocks */
+ sbc_analyze_four_iwmmxt(x + 12, out, analysis_consts_fixed4_simd_odd);
+ out += out_stride;
+ sbc_analyze_four_iwmmxt(x + 8, out, analysis_consts_fixed4_simd_even);
+ out += out_stride;
+ sbc_analyze_four_iwmmxt(x + 4, out, analysis_consts_fixed4_simd_odd);
+ out += out_stride;
+ sbc_analyze_four_iwmmxt(x + 0, out, analysis_consts_fixed4_simd_even);
+}
+
+static inline void sbc_analyze_4b_8s_iwmmxt(int16_t *x, int32_t *out,
+ int out_stride)
+{
+ /* Analyze blocks */
+ sbc_analyze_eight_iwmmxt(x + 24, out, analysis_consts_fixed8_simd_odd);
+ out += out_stride;
+ sbc_analyze_eight_iwmmxt(x + 16, out, analysis_consts_fixed8_simd_even);
+ out += out_stride;
+ sbc_analyze_eight_iwmmxt(x + 8, out, analysis_consts_fixed8_simd_odd);
+ out += out_stride;
+ sbc_analyze_eight_iwmmxt(x + 0, out, analysis_consts_fixed8_simd_even);
+}
+
+static void sbc_calc_scalefactors_iwmmxt2(
+ int32_t sb_sample_f[16][2][8],
+ uint32_t scale_factor[2][8],
+ int blocks, int channels, int subbands)
+{
+ int ch, sb;
+ for (ch = 0; ch < channels; ch++) {
+ for (sb = 0; sb < subbands; sb += 2) {
+ int blk = blocks;
+ int32_t *in = &sb_sample_f[0][ch][sb];
+ /* For iwmmxt2, since we use wabs */
+ asm volatile (
+ "wldrd wr1, [%[in]], %[inc]\n"
+ "tbcstw wr0, %[c1]\n"
+ "wldrd wr2, [%[in]], %[inc]\n"
+ "wldrd wr3, [%[in]], %[inc]\n"
+ "wldrd wr4, [%[in]], %[inc]\n"
+ "1:\n"
+ "wabsw wr1, wr1\n"
+ "wabsw wr2, wr2\n"
+ "wabsw wr3, wr3\n"
+ "wabsw wr4, wr4\n"
+ "wmaxuw wr5, wr1, wr2\n"
+ "wldrd wr1, [%[in]], %[inc]\n"
+ "wmaxuw wr6, wr3, wr4\n"
+ "wldrd wr2, [%[in]], %[inc]\n"
+ "wmaxuw wr5, wr5, wr6\n"
+ "wldrd wr3, [%[in]], %[inc]\n"
+ "wmaxuw wr0, wr0, wr5\n"
+ "wldrd wr4, [%[in]], %[inc]\n"
+ "subs %[blk], %[blk], #4\n"
+ "bgt 1b\n"
+
+ "tmrrc %0, %1, wr0\n"
+ "sub %0, %0, #1\n"
+ "clz %0, %0\n"
+ "rsb %0, %0, %[c2]\n"
+ "str %0, [%[out]]\n"
+
+ "sub %1, %1, #1\n"
+ "clz %1, %1\n"
+ "rsb %1, %1, %[c2]\n"
+ "str %1, [%[out], #4]\n"
+ : [in] "+r" (in), [blk] "+r" (blk)
+ : [inc] "i" ((char *) &sb_sample_f[1][0][0] -
+ (char *) &sb_sample_f[0][0][0]),
+ [out] "r" (&scale_factor[ch][sb]),
+ [c1] "r" ((1 << SCALE_OUT_BITS) + 1),
+ [c2] "i" (SCALE_OUT_BITS+1)
+ : "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6",
+ "cc", "memory");
+ }
+ }
+}
+
+void sbc_init_primitives_iwmmxt(struct sbc_encoder_state *state)
+{
+ state->sbc_analyze_4b_4s = sbc_analyze_4b_4s_iwmmxt;
+ state->sbc_analyze_4b_8s = sbc_analyze_4b_8s_iwmmxt;
+ state->sbc_calc_scalefactors = sbc_calc_scalefactors_iwmmxt2;
+ state->implementation_info = "IWMMXT";
+}
+
+#endif
diff --git a/sbc/sbc_primitives_iwmmxt.h b/sbc/sbc_primitives_iwmmxt.h
new file mode 100644
index 0000000..827d811
--- /dev/null
+++ b/sbc/sbc_primitives_iwmmxt.h
@@ -0,0 +1,38 @@
+/*
+ *
+ * Bluetooth low-complexity, subband codec (SBC) library
+ *
+ * Based on sbc_primitives_mmx.c
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __SBC_PRIMITIVES_IWMMXT_H
+#define __SBC_PRIMITIVES_IWMMXT_H
+
+#include "sbc_primitives.h"
+
+#if defined(__GNUC__) && defined(__IWMMXT__) && \
+ !defined(SBC_HIGH_PRECISION) && (SCALE_OUT_BITS == 15)
+
+#define SBC_BUILD_WITH_IWMMXT_SUPPORT
+
+void sbc_init_primitives_iwmmxt(struct sbc_encoder_state *encoder_state);
+
+#endif
+
+#endif
^ permalink raw reply related
* [PATCH] Fix pull phonebook with non-zero offset parameter
From: Rafal Michalski @ 2010-11-12 10:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Rafal Michalski
For non-zero liststartoffset parameter, contacts which index was before
offset were indexed more than once (e.g. when contact had more than one
phone number or address etc.), so pulling was started earlier - before
offset index was reached. This patch fix this problem and each contact
is indexed only once.
---
plugins/phonebook-tracker.c | 11 ++++++++++-
1 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 672d59f..811e4f0 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -1361,6 +1361,7 @@ static void pull_contacts(char **reply, int num_fields, void *user_data)
int last_index, i;
gboolean cdata_present = FALSE;
char *home_addr, *work_addr, *other_addr;
+ static gchar *temp_id;
if (num_fields < 0) {
data->cb(NULL, 0, num_fields, 0, data->user_data);
@@ -1396,7 +1397,14 @@ static void pull_contacts(char **reply, int num_fields, void *user_data)
TRACKER_DEFAULT_CONTACT_ME))
return;
- data->index++;
+ if (data->index == 0)
+ temp_id = NULL;
+
+ if (g_strcmp0(temp_id, reply[CONTACTS_ID_COL])) {
+ data->index++;
+ g_free(temp_id);
+ temp_id = g_strdup(reply[CONTACTS_ID_COL]);
+ }
last_index = params->liststartoffset + params->maxlistcount;
@@ -1495,6 +1503,7 @@ done:
fail:
g_slist_free(data->contacts);
g_free(data);
+ g_free(temp_id);
}
static void add_to_cache(char **reply, int num_fields, void *user_data)
--
1.6.3.3
^ permalink raw reply related
* Re: [PATCH v2] Add iwmmxt optimization for sbc for pxa series cpu
From: Siarhei Siamashka @ 2010-11-12 13:22 UTC (permalink / raw)
To: Keith Mok; +Cc: linux-bluetooth
In-Reply-To: <AANLkTi=rVvmwXwtZgMgwfBigyFXKsWRGy==rdcVjkitW@mail.gmail.com>
[-- Attachment #1: Type: Text/Plain, Size: 5034 bytes --]
On Friday 12 November 2010 09:35:04 Keith Mok wrote:
> > Did you run some benchmarks with these optimizations to measure how much
> > they are helping?
>
> Tested on Marvell PXA platform.
> == Before ==
> $ time ./sbcenc -b53 -s8 -j c.au > /dev/null
> real 0m 0.41s
> user 0m 0.40s
> sys 0m 0.00s
>
> == After ==
> $ time ./sbcenc -b53 -s8 -j c.au > /dev/null
> real 0m 0.19s
> user 0m 0.17s
> sys 0m 0.02s
Thanks, this looks consistent with the results of optimizations on the other
platforms where the performance increases roughly twice after adding SIMD
optimizations to the sbc analysis filter.
But maybe it's better to use a bit bigger test file, so that the total time
increases to at least several seconds. With very small times, it's hard to say
whether it is an actual improvement or random noise. It may be ok for such a
huge performance improvement, but with less significant optimizations the
precision of measurements may become a problem.
Also do you have oprofile available on PXA platform? It may provide a nice
statistics about what functions are used and are the performance hot spots.
> > Using back-to-back WLDRD instructions has some performance penalty
>
> I rearrange the instructions and keep the original one as for reference in
> the block that comment out. Since the code is really difficult to read
> after interleaved.
Thanks, this looks like it really should run quite a bit faster than the
previous variant (based on my understanding of intel pdf files).
I sometimes use different indentation levels in such cases in order to improve
readability after instructions reordering, so that each logically independent
block of code has its own indentation level and it is still easily visible
after instructions reordering. For example, with the original code:
A1
A2
A3
A4
B1
B2
B3
B4
If the instructions need to be reordered in order to improve scheduling for the
cpu pipeline, then for example
A1
A2
B1
A3
B2
A4
B3
B4
looks much more readable to me than
A1
A2
B1
A3
B2
A4
B3
B4
With different indentation levels, one can still see the flow of instructions
as independent streams. If different levels of indentation in inline assembly
pass coding style test by checkpatch.pl script, then it should be fine.
Also I'm quite curious whether better instructions scheduling provide any clear
improvement, so some numbers comparing older and newer implementation would
be appreciated. I did not suggest that just for entertainment purposes ;) It
really should provide some practical benefit.
If you have time and want to make such a test, iwmmxt intrinsics could be also
tried, so that instructions scheduling and registers allocation becomes a
responsibility of the compiler. But my previous experiments with arm neon
intrinsics showed that the compiler does a very poor job and can't be trusted
to generate fast code. But maybe iwmmxt could be different or gcc could have
improved since than.
> > The MMX code was using PCMPGTD and the other instructions just because
> > MMX instruction set is very limited and did not have the needed
> > instructions. But you can use WABS and WMAX instructions to do this job
> > better. You can refer to the original C code and also to ARM NEON
> > optimizations to get some ideas about how to do this operation faster.
>
> Changed as suggested.
> But got a question that the __IWMMXT__ builtin gcc definition is not a
> reliable way to
> determine whether mcpu=iwmmxt2 is turned on or not. It will break when
> compile under pxa270
> which does not support wabs with just mcpu=iwmmx on.
Well, as I said before, I'm not familiar with iwmmxt and pxa platform. And I
did not notice that there are actually several revisions of iwmmxt isa, my bad.
So looks like iwmmxt1 is just as restrictive as the original mmx and the direct
conversion from mmx like you did before may be the right thing. For arm neon
optimizations, the effect of using vector ABS/MAX instructions was just
about 1% of overall performance improvement. Not so much, but every little bit
helps. And if for iwmmxt it causes such backwards compatibility issues, then it
might be not worth it. It's up to you to decide.
I would still suggest to initially have just optimizations for
sbc_analyze_four_iwmmxt/sbc_analyze_eight_iwmmxt in the first patch (or maybe
in two patches). And then add optimization for sbc_calc_scalefactors in a
separate patch later.
Regarding the benchmarks and functions usage:
1. sbc_analyze_four_iwmmxt is important for 4 subbands case ('-s4' option for
sbcenc)
2. sbc_analyze_eight_iwmmxt is important for 8 subbands case ('-s8' option for
sbcenc)
3. sbc_calc_scalefactors is important for either mono audio, or when joint
stereo is *not* used (sbcenc is run without '-j' option).
All of this is better to be benchmarked/tested separately.
--
Best regards,
Siarhei Siamashka
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* [PATCH] [RFC] Show multiple classes in Device UUIDs property
From: Elvis Pfützenreuter @ 2010-11-12 14:52 UTC (permalink / raw)
To: linux-bluetooth; +Cc: epx
This patch adds support for multiple service classes in a single SDP record,
This is a common case for HDP profile (a HDP device which is both source and
sink will have classes 0x1401 and 0x1402, but often just one SDP record).
Current implementation gets only the first UUID in record, which can be
any of the two, and prevents an application to filter e.g. sources by
UUIDs property alone.
The patch also prevents a device driver from being probed and/or removed
twice, if two different UUIDs are served by the same driver. Moreover, it
detects the case when one UUID is removed (e.g. 0x1401) but another one
showed up (0x1402) and both are served by the same driver, which means
the driver must not be removed.
NOTE: the main reason I am submitting this patch, is to reopen the
multiple-UUIDs-in-a-profile discussion. This has been tested mainly with
HDP but there may be issues that affect other drivers and invalidates this
solution completely. I am prepared for the lapidation :)
---
src/device.c | 123 +++++++++++++++++++++++++++++++++++++++++----------------
1 files changed, 88 insertions(+), 35 deletions(-)
diff --git a/src/device.c b/src/device.c
index 7c421e3..83ca441 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1186,6 +1186,14 @@ static GSList *device_match_driver(struct btd_device *device,
return uuids;
}
+static int device_drivers_cmp(const void *a, const void *b)
+{
+ const struct btd_driver_data *driver_data = a;
+ const struct btd_device_driver *driver = b;
+
+ return (driver_data->driver == driver ? 0 : 1);
+}
+
void device_probe_drivers(struct btd_device *device, GSList *profiles)
{
GSList *list;
@@ -1208,20 +1216,25 @@ void device_probe_drivers(struct btd_device *device, GSList *profiles)
if (!probe_uuids)
continue;
- driver_data = g_new0(struct btd_driver_data, 1);
-
err = driver->probe(device, probe_uuids);
if (err < 0) {
error("probe failed with driver %s for device %s",
driver->name, device->path);
- g_free(driver_data);
g_slist_free(probe_uuids);
continue;
}
+ if (g_slist_find_custom(device->drivers, driver,
+ (GCompareFunc) device_drivers_cmp)) {
+ g_slist_free(probe_uuids);
+ continue;
+ }
+
+ driver_data = g_new0(struct btd_driver_data, 1);
driver_data->driver = driver;
device->drivers = g_slist_append(device->drivers, driver_data);
+
g_slist_free(probe_uuids);
}
@@ -1254,13 +1267,45 @@ static void device_remove_drivers(struct btd_device *device, GSList *uuids)
DBG("Remove drivers for %s", device->path);
+ for (list = uuids; list; list = list->next) {
+ sdp_record_t *rec;
+
+ device->uuids = g_slist_remove(device->uuids, list->data);
+
+ rec = find_record_in_list(records, list->data);
+ if (!rec)
+ continue;
+
+ delete_record(srcaddr, dstaddr, rec->handle);
+
+ records = sdp_list_remove(records, rec);
+ sdp_record_free(rec);
+
+ }
+
+ if (records)
+ sdp_list_free(records, (sdp_free_func_t) sdp_record_free);
+
for (list = device->drivers; list; list = next) {
struct btd_driver_data *driver_data = list->data;
struct btd_device_driver *driver = driver_data->driver;
const char **uuid;
+ gboolean in_use_by_another_uuid;
next = list->next;
+ in_use_by_another_uuid = FALSE;
+ for (uuid = driver->uuids; *uuid; uuid++) {
+ if (g_slist_find_custom(device->uuids, *uuid,
+ (GCompareFunc) strcasecmp)) {
+ in_use_by_another_uuid = TRUE;
+ break;
+ }
+ }
+
+ if (in_use_by_another_uuid)
+ continue;
+
for (uuid = driver->uuids; *uuid; uuid++) {
if (!g_slist_find_custom(uuids, *uuid,
(GCompareFunc) strcasecmp))
@@ -1277,25 +1322,6 @@ static void device_remove_drivers(struct btd_device *device, GSList *uuids)
break;
}
}
-
- for (list = uuids; list; list = list->next) {
- sdp_record_t *rec;
-
- device->uuids = g_slist_remove(device->uuids, list->data);
-
- rec = find_record_in_list(records, list->data);
- if (!rec)
- continue;
-
- delete_record(srcaddr, dstaddr, rec->handle);
-
- records = sdp_list_remove(records, rec);
- sdp_record_free(rec);
-
- }
-
- if (records)
- sdp_list_free(records, (sdp_free_func_t) sdp_record_free);
}
static void services_changed(struct btd_device *device)
@@ -1323,6 +1349,43 @@ static int rec_cmp(const void *a, const void *b)
return r1->handle - r2->handle;
}
+static void append_uuids(GSList *existing, GSList **uuids, sdp_list_t *svcclass)
+{
+ gchar *uuid;
+ GSList *l;
+
+ do {
+ uuid = bt_uuid2string(svcclass->data);
+
+ l = g_slist_find_custom(existing, uuid, (GCompareFunc) strcmp);
+ if (l) {
+ g_free(uuid);
+ continue;
+ }
+
+ l = g_slist_find_custom(*uuids, uuid, (GCompareFunc) strcmp);
+ if (!l)
+ *uuids = g_slist_append(*uuids, uuid);
+ else
+ g_free(uuid);
+ } while ((svcclass = svcclass->next));
+}
+
+static void remove_uuids(GSList **uuids, sdp_list_t *svcclass)
+{
+ gchar *uuid;
+ GSList *l;
+
+ do {
+ uuid = bt_uuid2string(svcclass->data);
+ l = g_slist_find_custom(*uuids, uuid, (GCompareFunc) strcmp);
+
+ if (l)
+ *uuids = g_slist_remove(*uuids, l->data);
+ g_free(uuid);
+ } while ((svcclass = svcclass->next));
+}
+
static void update_services(struct browse_req *req, sdp_list_t *recs)
{
struct btd_device *device = req->device;
@@ -1339,7 +1402,6 @@ static void update_services(struct browse_req *req, sdp_list_t *recs)
sdp_record_t *rec = (sdp_record_t *) seq->data;
sdp_list_t *svcclass = NULL;
gchar *profile_uuid;
- GSList *l;
if (!rec)
break;
@@ -1394,19 +1456,10 @@ static void update_services(struct browse_req *req, sdp_list_t *recs)
req->records = sdp_list_append(req->records,
sdp_copy_record(rec));
- l = g_slist_find_custom(device->uuids, profile_uuid,
- (GCompareFunc) strcmp);
- if (!l)
- req->profiles_added =
- g_slist_append(req->profiles_added,
- profile_uuid);
- else {
- req->profiles_removed =
- g_slist_remove(req->profiles_removed,
- l->data);
- g_free(profile_uuid);
- }
+ append_uuids(device->uuids, &req->profiles_added, svcclass);
+ remove_uuids(&req->profiles_removed, svcclass);
+ g_free(profile_uuid);
sdp_list_free(svcclass, free);
}
}
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH v2 1/7] Fix invalid memory access when EIR field length is zero
From: Johan Hedberg @ 2010-11-12 16:54 UTC (permalink / raw)
To: Inga Stotland
Cc: 'Vinicius Costa Gomes', linux-bluetooth,
'Bruna Moreira'
In-Reply-To: <000b01cb8200$02c24c90$0846e5b0$@org>
Hi Inga,
On Thu, Nov 11, 2010, Inga Stotland wrote:
> Was there a bug to begin with? :)
> The access to eir_data[1] was always valid due to the check (len <
> EIR_DATA_LENGTH - 1)
> and the fact that eir_data is a buffer of fixed length of EIR_DATA_LENGTH
> (240 bytes).
On closer inspection it seems you might be right, however it'd be nice
to get some comments from the original patch author about this (were
there e.g. crashes or some valgrind warnings observed or was this just
speculation based on looking at the code).
Btw, it seems I may need to slow down on my response time to patches so
there's better time for other people to review them too. E.g. both you
and Luiz were a bit late to the game on a couple of recent patches.
Maybe a 24 hour period before I push anything might be good enough?
Johan
^ permalink raw reply
* Re: [PATCH] Fix pull phonebook with non-zero offset parameter
From: Johan Hedberg @ 2010-11-12 17:10 UTC (permalink / raw)
To: Rafal Michalski; +Cc: linux-bluetooth
In-Reply-To: <1289558357-25724-1-git-send-email-michalski.raf@gmail.com>
Hi Rafal,
On Fri, Nov 12, 2010, Rafal Michalski wrote:
> For non-zero liststartoffset parameter, contacts which index was before
> offset were indexed more than once (e.g. when contact had more than one
> phone number or address etc.), so pulling was started earlier - before
> offset index was reached. This patch fix this problem and each contact
> is indexed only once.
> ---
> plugins/phonebook-tracker.c | 11 ++++++++++-
> 1 files changed, 10 insertions(+), 1 deletions(-)
Several issues with this patch:
> @@ -1361,6 +1361,7 @@ static void pull_contacts(char **reply, int num_fields, void *user_data)
> int last_index, i;
> gboolean cdata_present = FALSE;
> char *home_addr, *work_addr, *other_addr;
> + static gchar *temp_id;
Use char instead of gchar and initialize this to NULL here (static
variabled get initialized to 0 implicitly, but it's good to have this
explicit for clarity imo).
> + if (data->index == 0)
> + temp_id = NULL;
Is this supposed to compensate for the lack of initialization upon
declaration or do you really want to set to NULL here in case some
previous calls to the function left it as non-NULL. In the later case
you're missing a g_free call.
> @@ -1495,6 +1503,7 @@ done:
> fail:
> g_slist_free(data->contacts);
> g_free(data);
> + g_free(temp_id);
> }
Since this is a static variable you don't want it keeping it's value
after freeing it. So set to NULL after the g_free.
Btw, doesn't it bother you at all that this pull_contacts function is
huge? Feel free to send a refactoring patch for it. E.g. separate
functions called add_entry and add_numbers might not be a bad idea. The
function is also inconsistent in the usage of column numbers: sometimes
a define is used and sometimes a hard coded number.
Johan
^ permalink raw reply
* Re: [PATCH v2 1/7] Fix invalid memory access when EIR field length is zero
From: Gustavo F. Padovan @ 2010-11-12 17:38 UTC (permalink / raw)
To: Inga Stotland, 'Vinicius Costa Gomes', linux-bluetooth,
'Bruna Moreira'
In-Reply-To: <20101112165434.GA13238@jh-x301>
Hi Johan,
* Johan Hedberg <johan.hedberg@gmail.com> [2010-11-12 18:54:34 +0200]:
> Hi Inga,
>
> On Thu, Nov 11, 2010, Inga Stotland wrote:
> > Was there a bug to begin with? :)
> > The access to eir_data[1] was always valid due to the check (len <
> > EIR_DATA_LENGTH - 1)
> > and the fact that eir_data is a buffer of fixed length of EIR_DATA_LENGTH
> > (240 bytes).
>
> On closer inspection it seems you might be right, however it'd be nice
> to get some comments from the original patch author about this (were
> there e.g. crashes or some valgrind warnings observed or was this just
> speculation based on looking at the code).
>
> Btw, it seems I may need to slow down on my response time to patches so
> there's better time for other people to review them too. E.g. both you
> and Luiz were a bit late to the game on a couple of recent patches.
> Maybe a 24 hour period before I push anything might be good enough?
I would say 48h, give more time to people review, in case you spent a
whole day off the linux-bluetooth.
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* [PATCH] compat: support building on RHEL 6 kernels
From: John W. Linville @ 2010-11-12 18:11 UTC (permalink / raw)
To: linux-wireless, linux-bluetooth
RHEL kernels in general (and RHEL 6 kernels in particular) often
contain features backported from later upstream kernels. This means
that the normal KERNEL_VERSION checks are not always correct for RHEL
kernels. This patch augments a number of such tests to be compatible
with building compat-wireless on RHEL 6 kernels.
Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
This patch contains the general compat portions...
diff -up compat-wireless-2.6.36-4/compat/compat_firmware_class.c.orig compat-wireless-2.6.36-4/compat/compat_firmware_class.c
--- compat-wireless-2.6.36-4/compat/compat_firmware_class.c.orig 2010-11-12 12:00:39.050193706 -0500
+++ compat-wireless-2.6.36-4/compat/compat_firmware_class.c 2010-11-12 12:10:47.288513373 -0500
@@ -314,9 +314,15 @@ static ssize_t firmware_loading_store(st
static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store);
+#if !defined(RHEL_MAJOR) || (RHEL_MAJOR != 6)
static ssize_t firmware_data_read(struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buffer, loff_t offset, size_t count)
+#else
+static ssize_t firmware_data_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buffer, loff_t offset, size_t count)
+#endif
{
struct device *dev = to_dev(kobj);
struct firmware_priv *fw_priv = to_firmware_priv(dev);
@@ -407,9 +413,15 @@ static int fw_realloc_buffer(struct firm
* Data written to the 'data' attribute will be later handed to
* the driver as a firmware image.
**/
+#if !defined(RHEL_MAJOR) || (RHEL_MAJOR != 6)
static ssize_t firmware_data_write(struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buffer, loff_t offset, size_t count)
+#else
+static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buffer, loff_t offset, size_t count)
+#endif
{
struct device *dev = to_dev(kobj);
struct firmware_priv *fw_priv = to_firmware_priv(dev);
diff -up compat-wireless-2.6.36-4/include/linux/compat-2.6.33.h.orig compat-wireless-2.6.36-4/include/linux/compat-2.6.33.h
--- compat-wireless-2.6.36-4/include/linux/compat-2.6.33.h.orig 2010-11-12 10:25:13.561172060 -0500
+++ compat-wireless-2.6.36-4/include/linux/compat-2.6.33.h 2010-11-12 11:19:10.369172382 -0500
@@ -47,7 +47,9 @@ static inline void compat_release_firmwa
}
#endif
+#if (!defined(RHEL_MAJOR) || (RHEL_MAJOR != 6))
#define KEY_RFKILL 247 /* Key that controls all radios */
+#endif
#define IFF_DONT_BRIDGE 0x800 /* disallow bridging this ether dev */
/* source: include/linux/if.h */
@@ -55,6 +57,7 @@ static inline void compat_release_firmwa
/* this will never happen on older kernels */
#define NETDEV_POST_INIT 0xffff
+#if (!defined(RHEL_MAJOR) || (RHEL_MAJOR != 6))
static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev,
unsigned int length)
{
@@ -64,6 +67,7 @@ static inline struct sk_buff *netdev_all
skb_reserve(skb, NET_IP_ALIGN);
return skb;
}
+#endif
#if defined(CONFIG_PCCARD) || defined(CONFIG_PCCARD_MODULE)
diff -up compat-wireless-2.6.36-4/include/linux/compat-2.6.34.h.orig compat-wireless-2.6.36-4/include/linux/compat-2.6.34.h
--- compat-wireless-2.6.36-4/include/linux/compat-2.6.34.h.orig 2010-11-12 10:25:44.165172202 -0500
+++ compat-wireless-2.6.36-4/include/linux/compat-2.6.34.h 2010-11-12 11:19:29.315182613 -0500
@@ -19,12 +19,14 @@
/* netdev_printk helpers, similar to dev_printk */
+#if (!defined(RHEL_MAJOR) || (RHEL_MAJOR != 6))
static inline const char *netdev_name(const struct net_device *dev)
{
if (dev->reg_state != NETREG_REGISTERED)
return "(unregistered net_device)";
return dev->name;
}
+#endif
#define netdev_printk(level, netdev, format, args...) \
dev_printk(level, (netdev)->dev.parent, \
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* [PATCH] compat-wireless: support backporting bluetooth to RHEL 6
From: John W. Linville @ 2010-11-12 18:13 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: linux-wireless, linux-bluetooth
RHEL kernels in general (and RHEL 6 kernels in particular) often
contain features backported from later upstream kernels. This means
that the normal KERNEL_VERSION checks are not always correct for RHEL
kernels. This patch augments a number of such tests to be compatible
with building compat-wireless on RHEL 6 kernels.
Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
This patch contains the bluetooth backporting portions...
diff -up compat-wireless-2.6.36-4/patches/16-bluetooth.patch.orig compat-wireless-2.6.36-4/patches/16-bluetooth.patch
--- compat-wireless-2.6.36-4/patches/16-bluetooth.patch.orig 2010-11-12 12:42:52.602182539 -0500
+++ compat-wireless-2.6.36-4/patches/16-bluetooth.patch 2010-11-12 12:46:36.049287339 -0500
@@ -35,7 +35,7 @@ here still, but for now we keep this her
}
EXPORT_SYMBOL(bt_sock_unregister);
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32))
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)) || (defined(RHEL_MAJOR) && (RHEL_MAJOR == 6))
static int bt_sock_create(struct net *net, struct socket *sock, int proto,
int kern)
+#else
@@ -48,7 +48,7 @@ here still, but for now we keep this her
read_lock(&bt_proto_lock);
if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32))
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)) || (defined(RHEL_MAJOR) && (RHEL_MAJOR == 6))
err = bt_proto[proto]->create(net, sock, proto, kern);
+#else
+ err = bt_proto[proto]->create(net, sock, proto);
@@ -127,7 +127,7 @@ here still, but for now we keep this her
.obj_size = sizeof(struct hci_pinfo)
};
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32))
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)) || (defined(RHEL_MAJOR) && (RHEL_MAJOR == 6))
static int hci_sock_create(struct net *net, struct socket *sock, int protocol,
int kern)
+#else
@@ -180,7 +180,7 @@ here still, but for now we keep this her
return hidp_queue_report(session, buf, rsize);
}
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) || (defined(RHEL_MAJOR) && (RHEL_MAJOR == 6))
static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count,
unsigned char report_type)
{
@@ -438,7 +438,7 @@ here still, but for now we keep this her
return sk;
}
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32))
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)) || (defined(RHEL_MAJOR) && (RHEL_MAJOR == 6))
static int rfcomm_sock_create(struct net *net, struct socket *sock,
int protocol, int kern)
+#else
@@ -505,7 +505,7 @@ here still, but for now we keep this her
return sk;
}
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32))
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)) || (defined(RHEL_MAJOR) && (RHEL_MAJOR == 6))
static int sco_sock_create(struct net *net, struct socket *sock, int protocol,
int kern)
+#else
@@ -532,7 +532,7 @@ here still, but for now we keep this her
.obj_size = sizeof(struct bt_sock)
};
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32))
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)) || (defined(RHEL_MAJOR) && (RHEL_MAJOR == 6))
static int bnep_sock_create(struct net *net, struct socket *sock, int protocol,
int kern)
+#else
@@ -547,7 +547,7 @@ here still, but for now we keep this her
.obj_size = sizeof(struct bt_sock)
};
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32))
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)) || (defined(RHEL_MAJOR) && (RHEL_MAJOR == 6))
static int cmtp_sock_create(struct net *net, struct socket *sock, int protocol,
int kern)
+#else
@@ -562,7 +562,7 @@ here still, but for now we keep this her
.obj_size = sizeof(struct bt_sock)
};
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32))
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)) || (defined(RHEL_MAJOR) && (RHEL_MAJOR == 6))
static int hidp_sock_create(struct net *net, struct socket *sock, int protocol,
int kern)
+#else
@@ -577,7 +577,7 @@ here still, but for now we keep this her
return sk;
}
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32))
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)) || (defined(RHEL_MAJOR) && (RHEL_MAJOR == 6))
static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
int kern)
+#else
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* Re: [PATCH 3/4] Add DBus OOB API documentation.
From: jaikumar Ganesh @ 2010-11-12 18:20 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1288865461-3760-4-git-send-email-szymon.janc@tieto.com>
Hi Szymon:
On Thu, Nov 4, 2010 at 3:11 AM, Szymon Janc <szymon.janc@tieto.com> wrote:
> ---
> Makefile.am | 3 +-
> doc/oob-api.txt | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 64 insertions(+), 1 deletions(-)
> create mode 100644 doc/oob-api.txt
>
> diff --git a/Makefile.am b/Makefile.am
> index d6cbf92..b5157cd 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -358,7 +358,8 @@ EXTRA_DIST += doc/manager-api.txt \
> doc/service-api.txt doc/agent-api.txt doc/attribute-api.txt \
> doc/serial-api.txt doc/network-api.txt \
> doc/input-api.txt doc/audio-api.txt doc/control-api.txt \
> - doc/hfp-api.txt doc/assigned-numbers.txt
> + doc/hfp-api.txt doc/assigned-numbers.txt doc/oob-api.txt
> +
>
> AM_YFLAGS = -d
>
> diff --git a/doc/oob-api.txt b/doc/oob-api.txt
> new file mode 100644
> index 0000000..fce18a7
> --- /dev/null
> +++ b/doc/oob-api.txt
> @@ -0,0 +1,62 @@
> +BlueZ D-Bus OOB API description
> +*******************************
> +
> +Copyright (C) 2010 ST-Ericsson SA
> +
> +Author: Szymon Janc <szymon.janc@tieto.com> for ST-Ericsson
> +
> +OOB hierarchy
> +=================
> +
> +Service unique name
> +Interface org.bluez.OOB
> +Object path freely definable
> +
> +Methods array{bye}, array{byte} RequestRemoteOobData(string address)
> +
> + This method gets called when the service daemon needs to
> + get hash and randomizer for an OOB authentication.
> +
> + The return value should be pair of arrays of 16 bytes
> + each. First hash, second randomizer.
> +
> + If no OOB data is present for specified address empty
> + reply should be returned.
> +
> + void Deactivate()
Would it better to make this a signal ? Deactivate by itself as the
only method doesn't seem to be right.
> +
> + This method gets called when DBus plug-in for OOB was
> + deactivated. There is no need to unregister provider,
> + because when this method gets called it has already been
> + unregistered.
> +
> +--------------------------------------------------------------------------------
> +
> +Service org.bluez
> +Interface org.bluez.OOB
> +Object path /org/bluez
> +
> + void RegisterProvider(object provider)
> +
> + This method registers provider for DBus OOB plug-in.
> + When provider is successfully registered plug-in becomes
> + active. Only one provider can be registered at time.
Why are we enforcing this limitation ?
> +
> + Possible errors: org.bluez.Error.AlreadyExists
> +
> + void UnregisterProvider(object provider)
> +
> + This method unregisters provider for DBus OOB plug-in.
> + When provider is successfully unregistered plug-in
> + becomes inactive and will emit Deactivated() signal.
> +
> + Possible errors: org.bluez.Error.DoesNotExist
> +
> + array{bye}, array{byte} UpdateLocalOobData(string address)
You are not updating anything here. You are just reading the local
adapter OOB data
> +
> + This method generates new local OOB data for specified
> + address (adapter). Return value is pair of arrays 16
> + bytes each. First hash, second randomizer. Only
> + registered provider should call this method.
> +
> + Possible errors: org.bluez.Error.UpdateFailed
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCH 3/4] Add DBus OOB API documentation.
From: Johan Hedberg @ 2010-11-12 18:29 UTC (permalink / raw)
To: jaikumar Ganesh; +Cc: Szymon Janc, linux-bluetooth
In-Reply-To: <AANLkTikZrbVTCDB2HRtqRJjUjYP3Z5PBieOovZZgP9id@mail.gmail.com>
Hi Jaikumar,
On Fri, Nov 12, 2010, jaikumar Ganesh wrote:
> > + void Deactivate()
>
> Would it better to make this a signal ? Deactivate by itself as the
> only method doesn't seem to be right.
I guess this is analogous to the Release() method which we have for
agents, so in that sense a method call would be consistent with the rest
of the BlueZ D-Bus API (but you'd really need to rename this to Release
then).
Johan
^ permalink raw reply
* Re: [PATCH] compat-wireless: support backporting bluetooth to RHEL 6
From: Johannes Berg @ 2010-11-12 18:39 UTC (permalink / raw)
To: John W. Linville; +Cc: Luis R. Rodriguez, linux-wireless, linux-bluetooth
In-Reply-To: <20101112181348.GG2338@tuxdriver.com>
On Fri, 2010-11-12 at 13:13 -0500, John W. Linville wrote:
>
> -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32))
> ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)) || (defined(RHEL_MAJOR) && (RHEL_MAJOR == 6))
Hmmm. I kinda support this, but I'd rather see something like a header
file having
#if (LINUX_VERSION ...) || ...
#define OLD_BT_API 1
#endif
and then using ifdef OLD_BT_API? That way, other distros don't get into
a huge mess trying to add that too, and something like we had two days
ago where we had to make it work on some other custom kernel would be
much easier too since we can just amend the one check or define/undef
the OLD_BT_API symbol.
johannes
^ permalink raw reply
* Re: [PATCH 3/4] Add DBus OOB API documentation.
From: jaikumar Ganesh @ 2010-11-12 19:07 UTC (permalink / raw)
To: jaikumar Ganesh, Szymon Janc, linux-bluetooth
In-Reply-To: <20101112182921.GA15584@jh-x301>
Hi Szymon:
On Fri, Nov 12, 2010 at 10:29 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi Jaikumar,
>
> On Fri, Nov 12, 2010, jaikumar Ganesh wrote:
>> > + void Deactivate()
>>
>> Would it better to make this a signal ? Deactivate by itself as the
>> only method doesn't seem to be right.
>
> I guess this is analogous to the Release() method which we have for
> agents, so in that sense a method call would be consistent with the rest
> of the BlueZ D-Bus API (but you'd really need to rename this to Release
> then).
>
> Johan
>
So the only APIs added are these provider ones and one API in Agent
code for approval.
So how does bluetoothd decide whether OOB is present for a particular
remote device for an outgoing pairing case ? Just on the basis of
whether a provider is registered or am I missing something here.
RequestRemoteOobData is called before initiating pairing or when the
remote end asks for the OOB data ?
Its unclear from the API description.
Thanks
Jaikumar
^ permalink raw reply
* Re: [PATCH v2 1/7] Fix invalid memory access when EIR field length is zero
From: Anderson Lizardo @ 2010-11-13 1:00 UTC (permalink / raw)
To: Inga Stotland, Vinicius Costa Gomes, linux-bluetooth,
Bruna Moreira
In-Reply-To: <20101112165434.GA13238@jh-x301>
On 11/12/10, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi Inga,
>
> On Thu, Nov 11, 2010, Inga Stotland wrote:
>> Was there a bug to begin with? :)
>> The access to eir_data[1] was always valid due to the check (len <
>> EIR_DATA_LENGTH - 1)
>> and the fact that eir_data is a buffer of fixed length of EIR_DATA_LENGTH
>> (240 bytes).
>
> On closer inspection it seems you might be right, however it'd be nice
> to get some comments from the original patch author about this (were
> there e.g. crashes or some valgrind warnings observed or was this just
> speculation based on looking at the code).
There were valgrind "unintialized value" warnings related to this
after we started using it for parsing adv data (which is max 31 bytes
long but may be smaller because spec allows radio to strip non
significant bytes before sending, which explains why we added a length
parameter in a later patch). Actually I dont think the current code is
"safe" as it assumes the EIR data is aways 240 bytes long, which seems
true as per spec , but less data could be sent, causing reading beyond
buffer.
> Btw, it seems I may need to slow down on my response time to patches so
> there's better time for other people to review them too. E.g. both you
> and Luiz were a bit late to the game on a couple of recent patches.
> Maybe a 24 hour period before I push anything might be good enough?
I appreciate if you could send your comments ASAP, so we can fix them
quickly. Pushing upstream can be delayed for non trivial patches.
PS: I'm out of office until next Tuesday so I may not be able answer
quickly until then. thanks to Vinicius for pushing the patches fixed
versions :)
Regards
--
Anderson Lizardo
OpenBossa Labs - INdT
Manaus - Brazil
^ permalink raw reply
* Re: [PATCH v3] Add iwmmxt optimization for sbc for pxa series cpu
From: Keith Mok @ 2010-11-15 2:46 UTC (permalink / raw)
To: Siarhei Siamashka; +Cc: linux-bluetooth
In-Reply-To: <201011121522.51428.siarhei.siamashka@gmail.com>
> I sometimes use different indentation levels in such cases in order to improve
> readability after instructions reordering, so that each logically independent
> block of code has its own indentation level and it is still easily visible
> after instructions reordering. For example, with the original code:
Thanks for the hints. I rearranged the code.
> Not so much, but every little bit
> helps. And if for iwmmxt it causes such backwards compatibility issues, then it
> might be not worth it. It's up to you to decide.
I removed the scale_factor optimization since from the result I
tested, it shows little help in performance.
> Regarding the benchmarks and functions usage:
> 1. sbc_analyze_four_iwmmxt is important for 4 subbands case ('-s4' option for
> sbcenc)
> 2. sbc_analyze_eight_iwmmxt is important for 8 subbands case ('-s8' option for
> sbcenc)
=== Before (4 bands) ====
$ time ./sbcenc_orig -s 4 long.au > /dev/null
real 0m 2.44s
user 0m 2.39s
sys 0m 0.05s
=== After (4 bands) ====
$ time ./sbcenc -s 4 long.au > /dev/null
real 0m 1.59s
user 0m 1.49s
sys 0m 0.10s
=== Before (8 bands) ====
$ time ./sbcenc_orig -s 8 long.au > /dev/null
real 0m 4.05s
user 0m 3.98s
sys 0m 0.07s
=== After (8 bands) ====
$ time ./sbcenc -s 8 long.au > /dev/null
real 0m 1.48s
user 0m 1.41s
sys 0m 0.06s
=== Before (a2dp usage) ====
$ time ./sbcenc_orig -b53 -s8 -j long.au > /dev/null
real 0m 4.51s
user 0m 4.41s
sys 0m 0.10s
=== After (a2dp usage) ====
$ time ./sbcenc -b53 -s8 -j long.au > /dev/null
real 0m 2.05s
user 0m 1.99s
sys 0m 0.06s
Keith
Signed-off-by: Keith Mok <ek9852@gmail.com>
---
Makefile.am | 1 +
sbc/sbc_primitives.c | 4 +
sbc/sbc_primitives_iwmmxt.c | 301 +++++++++++++++++++++++++++++++++++++++++++
sbc/sbc_primitives_iwmmxt.h | 38 ++++++
4 files changed, 344 insertions(+), 0 deletions(-)
create mode 100644 sbc/sbc_primitives_iwmmxt.c
create mode 100644 sbc/sbc_primitives_iwmmxt.h
diff --git a/Makefile.am b/Makefile.am
index da308a7..03a9bf2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -65,6 +65,7 @@ noinst_LTLIBRARIES += sbc/libsbc.la
sbc_libsbc_la_SOURCES = sbc/sbc.h sbc/sbc.c sbc/sbc_math.h sbc/sbc_tables.h \
sbc/sbc_primitives.h sbc/sbc_primitives.c \
sbc/sbc_primitives_mmx.h sbc/sbc_primitives_mmx.c \
+ sbc/sbc_primitives_iwmmxt.h sbc/sbc_primitives_iwmmxt.c \
sbc/sbc_primitives_neon.h sbc/sbc_primitives_neon.c \
sbc/sbc_primitives_armv6.h sbc/sbc_primitives_armv6.c
diff --git a/sbc/sbc_primitives.c b/sbc/sbc_primitives.c
index f87fb5a..ad780d0 100644
--- a/sbc/sbc_primitives.c
+++ b/sbc/sbc_primitives.c
@@ -33,6 +33,7 @@
#include "sbc_primitives.h"
#include "sbc_primitives_mmx.h"
+#include "sbc_primitives_iwmmxt.h"
#include "sbc_primitives_neon.h"
#include "sbc_primitives_armv6.h"
@@ -544,6 +545,9 @@ void sbc_init_primitives(struct sbc_encoder_state *state)
#ifdef SBC_BUILD_WITH_ARMV6_SUPPORT
sbc_init_primitives_armv6(state);
#endif
+#ifdef SBC_BUILD_WITH_IWMMXT_SUPPORT
+ sbc_init_primitives_iwmmxt(state);
+#endif
#ifdef SBC_BUILD_WITH_NEON_SUPPORT
sbc_init_primitives_neon(state);
#endif
diff --git a/sbc/sbc_primitives_iwmmxt.c b/sbc/sbc_primitives_iwmmxt.c
new file mode 100644
index 0000000..fc462d2
--- /dev/null
+++ b/sbc/sbc_primitives_iwmmxt.c
@@ -0,0 +1,301 @@
+/*
+ *
+ * Bluetooth low-complexity, subband codec (SBC) library
+ *
+ * Copyright (C) 2010 Keith Mok <ek9852@gmail.com>
+ * Based on sbc_primitives_mmx.c
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <stdint.h>
+#include <limits.h>
+#include "sbc.h"
+#include "sbc_math.h"
+#include "sbc_tables.h"
+
+#include "sbc_primitives_iwmmxt.h"
+
+/*
+ * IWMMXT optimizations
+ */
+
+#ifdef SBC_BUILD_WITH_IWMMXT_SUPPORT
+
+static inline void sbc_analyze_four_iwmmxt(const int16_t *in, int32_t *out,
+ const FIXED_T *consts)
+{
+ asm volatile (
+ "wldrd wr0, [%0]\n"
+ "tbcstw wr4, %2\n"
+ "wldrd wr2, [%1]\n"
+ "wldrd wr1, [%0, #8]\n"
+ "wldrd wr3, [%1, #8]\n"
+ "wmadds wr0, wr2, wr0\n"
+ " wldrd wr6, [%0, #16]\n"
+ "wmadds wr1, wr3, wr1\n"
+ " wldrd wr7, [%0, #24]\n"
+ "waddwss wr0, wr0, wr4\n"
+ " wldrd wr8, [%1, #16]\n"
+ "waddwss wr1, wr1, wr4\n"
+ " wldrd wr9, [%1, #24]\n"
+ " wmadds wr6, wr8, wr6\n"
+ " wldrd wr2, [%0, #32]\n"
+ " wmadds wr7, wr9, wr7\n"
+ " wldrd wr3, [%0, #40]\n"
+ " waddwss wr0, wr6, wr0\n"
+ " wldrd wr4, [%1, #32]\n"
+ " waddwss wr1, wr7, wr1\n"
+ " wldrd wr5, [%1, #40]\n"
+ " wmadds wr2, wr4, wr2\n"
+ "wldrd wr6, [%0, #48]\n"
+ " wmadds wr3, wr5, wr3\n"
+ "wldrd wr7, [%0, #56]\n"
+ " waddwss wr0, wr2, wr0\n"
+ "wldrd wr8, [%1, #48]\n"
+ " waddwss wr1, wr3, wr1\n"
+ "wldrd wr9, [%1, #56]\n"
+ "wmadds wr6, wr8, wr6\n"
+ " wldrd wr2, [%0, #64]\n"
+ "wmadds wr7, wr9, wr7\n"
+ " wldrd wr3, [%0, #72]\n"
+ "waddwss wr0, wr6, wr0\n"
+ " wldrd wr4, [%1, #64]\n"
+ "waddwss wr1, wr7, wr1\n"
+ " wldrd wr5, [%1, #72]\n"
+ " wmadds wr2, wr4, wr2\n"
+ "tmcr wcgr0, %4\n"
+ " wmadds wr3, wr5, wr3\n"
+ " waddwss wr0, wr2, wr0\n"
+ " waddwss wr1, wr3, wr1\n"
+ "\n"
+ "wsrawg wr0, wr0, wcgr0\n"
+ " wldrd wr4, [%1, #80]\n"
+ "wsrawg wr1, wr1, wcgr0\n"
+ " wldrd wr5, [%1, #88]\n"
+ "wpackwss wr0, wr0, wr0\n"
+ " wldrd wr6, [%1, #96]\n"
+ "wpackwss wr1, wr1, wr1\n"
+ "wmadds wr2, wr5, wr0\n"
+ " wldrd wr7, [%1, #104]\n"
+ "wmadds wr0, wr4, wr0\n"
+ "\n"
+ " wmadds wr3, wr7, wr1\n"
+ " wmadds wr1, wr6, wr1\n"
+ " waddwss wr2, wr3, wr2\n"
+ " waddwss wr0, wr1, wr0\n"
+ "\n"
+ "wstrd wr0, [%3]\n"
+ "wstrd wr2, [%3, #8]\n"
+ :
+ : "r" (in), "r" (consts),
+ "r" (1 << (SBC_PROTO_FIXED4_SCALE - 1)), "r" (out),
+ "r" (SBC_PROTO_FIXED4_SCALE)
+ : "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
+ "wr8", "wr9", "wcgr0", "memory");
+}
+
+static inline void sbc_analyze_eight_iwmmxt(const int16_t *in, int32_t *out,
+ const FIXED_T *consts)
+{
+ asm volatile (
+ "wldrd wr0, [%0]\n"
+ "tbcstw wr15, %2\n"
+ "wldrd wr1, [%0, #8]\n"
+ "wldrd wr2, [%0, #16]\n"
+ "wldrd wr3, [%0, #24]\n"
+ "wldrd wr4, [%1]\n"
+ "wldrd wr5, [%1, #8]\n"
+ "wldrd wr6, [%1, #16]\n"
+ "wldrd wr7, [%1, #24]\n"
+ "wmadds wr0, wr0, wr4\n"
+ " wldrd wr8, [%1, #32]\n"
+ "wmadds wr1, wr1, wr5\n"
+ " wldrd wr9, [%1, #40]\n"
+ "wmadds wr2, wr2, wr6\n"
+ " wldrd wr10, [%1, #48]\n"
+ "wmadds wr3, wr3, wr7\n"
+ " wldrd wr11, [%1, #56]\n"
+ "waddwss wr0, wr0, wr15\n"
+ " wldrd wr4, [%0, #32]\n"
+ "waddwss wr1, wr1, wr15\n"
+ " wldrd wr5, [%0, #40]\n"
+ "waddwss wr2, wr2, wr15\n"
+ " wldrd wr6, [%0, #48]\n"
+ "waddwss wr3, wr3, wr15\n"
+ " wldrd wr7, [%0, #56]\n"
+ " wmadds wr4, wr4, wr8\n"
+ " wldrd wr12, [%0, #64]\n"
+ " wmadds wr5, wr5, wr9\n"
+ " wldrd wr13, [%0, #72]\n"
+ " wmadds wr6, wr6, wr10\n"
+ " wldrd wr14, [%0, #80]\n"
+ " wmadds wr7, wr7, wr11\n"
+ " wldrd wr15, [%0, #88]\n"
+ " waddwss wr0, wr4, wr0\n"
+ " wldrd wr8, [%1, #64]\n"
+ " waddwss wr1, wr5, wr1\n"
+ " wldrd wr9, [%1, #72]\n"
+ " waddwss wr2, wr6, wr2\n"
+ " wldrd wr10, [%1, #80]\n"
+ " waddwss wr3, wr7, wr3\n"
+ " wldrd wr11, [%1, #88]\n"
+ " wmadds wr12, wr12, wr8\n"
+ "wldrd wr4, [%0, #96]\n"
+ " wmadds wr13, wr13, wr9\n"
+ "wldrd wr5, [%0, #104]\n"
+ " wmadds wr14, wr14, wr10\n"
+ "wldrd wr6, [%0, #112]\n"
+ " wmadds wr15, wr15, wr11\n"
+ "wldrd wr7, [%0, #120]\n"
+ " waddwss wr0, wr12, wr0\n"
+ "wldrd wr8, [%1, #96]\n"
+ " waddwss wr1, wr13, wr1\n"
+ "wldrd wr9, [%1, #104]\n"
+ " waddwss wr2, wr14, wr2\n"
+ "wldrd wr10, [%1, #112]\n"
+ " waddwss wr3, wr15, wr3\n"
+ "wldrd wr11, [%1, #120]\n"
+ "wmadds wr4, wr4, wr8\n"
+ " wldrd wr12, [%0, #128]\n"
+ "wmadds wr5, wr5, wr9\n"
+ " wldrd wr13, [%0, #136]\n"
+ "wmadds wr6, wr6, wr10\n"
+ " wldrd wr14, [%0, #144]\n"
+ "wmadds wr7, wr7, wr11\n"
+ " wldrd wr15, [%0, #152]\n"
+ "waddwss wr0, wr4, wr0\n"
+ " wldrd wr8, [%1, #128]\n"
+ "waddwss wr1, wr5, wr1\n"
+ " wldrd wr9, [%1, #136]\n"
+ "waddwss wr2, wr6, wr2\n"
+ " wldrd wr10, [%1, #144]\n"
+ " waddwss wr3, wr7, wr3\n"
+ " wldrd wr11, [%1, #152]\n"
+ " wmadds wr12, wr12, wr8\n"
+ "tmcr wcgr0, %4\n"
+ " wmadds wr13, wr13, wr9\n"
+ " wmadds wr14, wr14, wr10\n"
+ " wmadds wr15, wr15, wr11\n"
+ " waddwss wr0, wr12, wr0\n"
+ " waddwss wr1, wr13, wr1\n"
+ " waddwss wr2, wr14, wr2\n"
+ " waddwss wr3, wr15, wr3\n"
+ "\n"
+ "wsrawg wr0, wr0, wcgr0\n"
+ "wsrawg wr1, wr1, wcgr0\n"
+ "wsrawg wr2, wr2, wcgr0\n"
+ "wsrawg wr3, wr3, wcgr0\n"
+ "\n"
+ "wpackwss wr0, wr0, wr0\n"
+ "wpackwss wr1, wr1, wr1\n"
+ " wldrd wr4, [%1, #160]\n"
+ "wpackwss wr2, wr2, wr2\n"
+ " wldrd wr5, [%1, #168]\n"
+ "wpackwss wr3, wr3, wr3\n"
+ " wldrd wr6, [%1, #192]\n"
+ " wmadds wr4, wr4, wr0\n"
+ " wldrd wr7, [%1, #200]\n"
+ " wmadds wr5, wr5, wr0\n"
+ " wldrd wr8, [%1, #224]\n"
+ " wmadds wr6, wr6, wr1\n"
+ " wldrd wr9, [%1, #232]\n"
+ " wmadds wr7, wr7, wr1\n"
+ " waddwss wr4, wr6, wr4\n"
+ " waddwss wr5, wr7, wr5\n"
+ " wmadds wr8, wr8, wr2\n"
+ "wldrd wr6, [%1, #256]\n"
+ " wmadds wr9, wr9, wr2\n"
+ "wldrd wr7, [%1, #264]\n"
+ "waddwss wr4, wr8, wr4\n"
+ " waddwss wr5, wr9, wr5\n"
+ "wmadds wr6, wr6, wr3\n"
+ "wmadds wr7, wr7, wr3\n"
+ "waddwss wr4, wr6, wr4\n"
+ "waddwss wr5, wr7, wr5\n"
+ "\n"
+ "wstrd wr4, [%3]\n"
+ "wstrd wr5, [%3, #8]\n"
+ "\n"
+ "wldrd wr6, [%1, #176]\n"
+ "wldrd wr5, [%1, #184]\n"
+ "wmadds wr5, wr5, wr0\n"
+ "wldrd wr8, [%1, #208]\n"
+ "wmadds wr0, wr6, wr0\n"
+ "wldrd wr9, [%1, #216]\n"
+ "wmadds wr9, wr9, wr1\n"
+ "wldrd wr6, [%1, #240]\n"
+ "wmadds wr1, wr8, wr1\n"
+ "wldrd wr7, [%1, #248]\n"
+ "waddwss wr0, wr1, wr0\n"
+ "waddwss wr5, wr9, wr5\n"
+ "wmadds wr7, wr7, wr2\n"
+ "wldrd wr8, [%1, #272]\n"
+ "wmadds wr2, wr6, wr2\n"
+ "wldrd wr9, [%1, #280]\n"
+ "waddwss wr0, wr2, wr0\n"
+ "waddwss wr5, wr7, wr5\n"
+ "wmadds wr9, wr9, wr3\n"
+ "wmadds wr3, wr8, wr3\n"
+ "waddwss wr0, wr3, wr0\n"
+ "waddwss wr5, wr9, wr5\n"
+ "\n"
+ "wstrd wr0, [%3, #16]\n"
+ "wstrd wr5, [%3, #24]\n"
+ :
+ : "r" (in), "r" (consts),
+ "r" (1 << (SBC_PROTO_FIXED8_SCALE - 1)), "r" (out),
+ "r" (SBC_PROTO_FIXED8_SCALE)
+ : "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
+ "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15",
+ "wcgr0", "memory");
+}
+
+static inline void sbc_analyze_4b_4s_iwmmxt(int16_t *x, int32_t *out,
+ int out_stride)
+{
+ /* Analyze blocks */
+ sbc_analyze_four_iwmmxt(x + 12, out, analysis_consts_fixed4_simd_odd);
+ out += out_stride;
+ sbc_analyze_four_iwmmxt(x + 8, out, analysis_consts_fixed4_simd_even);
+ out += out_stride;
+ sbc_analyze_four_iwmmxt(x + 4, out, analysis_consts_fixed4_simd_odd);
+ out += out_stride;
+ sbc_analyze_four_iwmmxt(x + 0, out, analysis_consts_fixed4_simd_even);
+}
+
+static inline void sbc_analyze_4b_8s_iwmmxt(int16_t *x, int32_t *out,
+ int out_stride)
+{
+ /* Analyze blocks */
+ sbc_analyze_eight_iwmmxt(x + 24, out, analysis_consts_fixed8_simd_odd);
+ out += out_stride;
+ sbc_analyze_eight_iwmmxt(x + 16, out, analysis_consts_fixed8_simd_even);
+ out += out_stride;
+ sbc_analyze_eight_iwmmxt(x + 8, out, analysis_consts_fixed8_simd_odd);
+ out += out_stride;
+ sbc_analyze_eight_iwmmxt(x + 0, out, analysis_consts_fixed8_simd_even);
+}
+
+void sbc_init_primitives_iwmmxt(struct sbc_encoder_state *state)
+{
+ state->sbc_analyze_4b_4s = sbc_analyze_4b_4s_iwmmxt;
+ state->sbc_analyze_4b_8s = sbc_analyze_4b_8s_iwmmxt;
+ state->implementation_info = "IWMMXT";
+}
+
+#endif
diff --git a/sbc/sbc_primitives_iwmmxt.h b/sbc/sbc_primitives_iwmmxt.h
new file mode 100644
index 0000000..827d811
--- /dev/null
+++ b/sbc/sbc_primitives_iwmmxt.h
@@ -0,0 +1,38 @@
+/*
+ *
+ * Bluetooth low-complexity, subband codec (SBC) library
+ *
+ * Based on sbc_primitives_mmx.c
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __SBC_PRIMITIVES_IWMMXT_H
+#define __SBC_PRIMITIVES_IWMMXT_H
+
+#include "sbc_primitives.h"
+
+#if defined(__GNUC__) && defined(__IWMMXT__) && \
+ !defined(SBC_HIGH_PRECISION) && (SCALE_OUT_BITS == 15)
+
+#define SBC_BUILD_WITH_IWMMXT_SUPPORT
+
+void sbc_init_primitives_iwmmxt(struct sbc_encoder_state *encoder_state);
+
+#endif
+
+#endif
--
1.6.3.3
^ permalink raw reply related
* Re: [PATCH 3/4] Add DBus OOB API documentation.
From: Szymon Janc @ 2010-11-15 8:54 UTC (permalink / raw)
To: jaikumar Ganesh; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <AANLkTikZrbVTCDB2HRtqRJjUjYP3Z5PBieOovZZgP9id@mail.gmail.com>
Hi Jaikumar,
> > + void Deactivate()
>
> Would it better to make this a signal ? Deactivate by itself as the
> only method doesn't seem to be right.
I'll change it to Release() to be consistent with other (Agent) API as
suggested by Johan.
> > + void RegisterProvider(object provider)
> > +
> > + This method registers provider for DBus OOB plug-in.
> > + When provider is successfully registered plug-in becomes
> > + active. Only one provider can be registered at time.
>
> Why are we enforcing this limitation ?
Spec requires that each hash&randomizer values should be used only for one OOB
transfer. Implementation enforces that by allowing only one active OOB plugin
at time and DBUS OOB plugin only 'expose' plugin API over DBUS. So this
limitation is a consequence of that.
This limitation also allows for (IMHO) simpler plugins implementation as they
don't have to care about other plugins hanging around to fulfill that
requirement.
> > + array{bye}, array{byte} UpdateLocalOobData(string address)
>
> You are not updating anything here. You are just reading the local
> adapter OOB data
It is updating hash and randomizer. Underlying functions are called Read* as
this is how corresponding HCI command is called (see Vol2. Part E. 7.3.60).
I'll change it to Read to keep all calls name consistent with HCI command name
and add appropriate note in API documentation as this name may be somewhat
misleading (yet OOB plugin implementer should be aware of that already).
--
Szymon Janc
^ permalink raw reply
* Re: [PATCH 3/4] Add DBus OOB API documentation.
From: Szymon Janc @ 2010-11-15 10:11 UTC (permalink / raw)
To: jaikumar Ganesh; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <AANLkTikFAc43uU-976tRSFrntFHYApe9h9zzVHto22_6@mail.gmail.com>
Hi,
> So the only APIs added are these provider ones and one API in Agent
> code for approval.
>
> So how does bluetoothd decide whether OOB is present for a particular
> remote device for an outgoing pairing case ? Just on the basis of
> whether a provider is registered or am I missing something here.
If there is an active OOB plugin then it is asked for remote OOB data when
io capabilities are established. Based on the answer oob_data field in io
capability reply is set. Dbus OOB plugin becomes active when provider is
registered. If no oob plugin is active oob_data field is always set to 0x00.
> RequestRemoteOobData is called before initiating pairing or when the
> remote end asks for the OOB data ?
> Its unclear from the API description.
I can see that OOB mechanism is somewhat unclear, let me try to clarify:
- local oob data are data generated by local adapter
- remote oob data are data received from remote device
- remote and/or local data are exchange through some OOB mechanism - this takes
place before SSP is started
(note that data exchanged on OOB also contains BT address)
- during SSP active oob plugin is asked for oob data for remote device
So, RequestRemoteOobData is called when io capabilities are being established,
but this asks plugin if it already has OOB data for this device and not
a remote device to provide this data.
Hope this clarifies things a bit :)
--
Szymon Janc
^ permalink raw reply
* [PATCH v2] Fix pull phonebook with non-zero offset parameter
From: Rafal Michalski @ 2010-11-15 10:41 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Rafal Michalski
For non-zero liststartoffset parameter, contacts which index was before
offset were indexed more than once (e.g. when contact had more than one
phone number or address etc.), so pulling was started earlier - before
offset index was reached. This patch fix this problem and each contact
is indexed only once.
---
plugins/phonebook-tracker.c | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 672d59f..4309e28 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -1361,6 +1361,7 @@ static void pull_contacts(char **reply, int num_fields, void *user_data)
int last_index, i;
gboolean cdata_present = FALSE;
char *home_addr, *work_addr, *other_addr;
+ static char *temp_id = NULL;
if (num_fields < 0) {
data->cb(NULL, 0, num_fields, 0, data->user_data);
@@ -1396,7 +1397,11 @@ static void pull_contacts(char **reply, int num_fields, void *user_data)
TRACKER_DEFAULT_CONTACT_ME))
return;
- data->index++;
+ if (g_strcmp0(temp_id, reply[CONTACTS_ID_COL])) {
+ data->index++;
+ g_free(temp_id);
+ temp_id = g_strdup(reply[CONTACTS_ID_COL]);
+ }
last_index = params->liststartoffset + params->maxlistcount;
@@ -1495,6 +1500,8 @@ done:
fail:
g_slist_free(data->contacts);
g_free(data);
+ g_free(temp_id);
+ temp_id = NULL;
}
static void add_to_cache(char **reply, int num_fields, void *user_data)
--
1.6.3.3
^ permalink raw reply related
* Re: [PATCH v3] Add iwmmxt optimization for sbc for pxa series cpu
From: Siarhei Siamashka @ 2010-11-15 11:08 UTC (permalink / raw)
To: Keith Mok; +Cc: linux-bluetooth
In-Reply-To: <AANLkTimQR5wMTTEO6KGuv3YvPBaftO-i+96WKYQEOzFU@mail.gmail.com>
[-- Attachment #1: Type: Text/Plain, Size: 2142 bytes --]
On Monday 15 November 2010 04:46:25 Keith Mok wrote:
> > I sometimes use different indentation levels in such cases in order to
> > improve readability after instructions reordering, so that each
> > logically independent block of code has its own indentation level and it
> > is still easily visible
>
> > after instructions reordering. For example, with the original code:
> Thanks for the hints. I rearranged the code.
Thanks, now the assembly code looks ok to me. I also discovered that qemu
supports iwmmxt1 emulation just fine and also tried to test your optimizations
for correctness myself (with a script which tries different encoding paramaters
for different audio samples and checks md5 checksums), no problems detected.
So if somebody else could check whether the other things are right (copyright
notices for example), then we are done with it.
> I removed the scale_factor optimization since from the result I
> tested, it shows little help in performance.
I guess after easily doubling performance by adding simd optimizations to the
sbc analysis filter, just roughly ~10% improvement (as measured for x86 and
arm neon) does not look particularly impressive anymore:
http://git.kernel.org/?p=bluetooth/bluez.git;a=commit;h=95465b816f0ce7f0ec10a183ce7ff0c6f83d86eb
http://git.kernel.org/?p=bluetooth/bluez.git;a=commit;h=d049a9a2aec2b518e04f11ef0ecc355db8237291
But I still think that every little bit helps. Did you also get something like
10% speedup, or was it even worse than that?
A bit more important in practice is the optimization for joint stereo scale
factors calculation (because it is typically used for A2DP). And it provided
almost 20% of performance improvement for arm neon:
http://git.kernel.org/?p=bluetooth/bluez.git;a=commit;h=e1ea3e76c72d56041c30b317818e8d7b5a0c7350
So 'sbc_calc_scalefactors_j_iwmmxt' may be a nice addition too, optimized
either as a whole for best performance (like in arm neon code), or just with
some small chunks of assembly like in 'sbc_calc_scalefactors_mmx' because it
is easier this way.
--
Best regards,
Siarhei Siamashka
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* [PATCH 1/2] Using field names instead of numbers in PBAP
From: Bartosz Szatkowski @ 2010-11-15 12:01 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bartosz Szatkowski
Previously addressing via field numbers and field names were mixed in PBAP
query replies. Now there is defined name for each data base reply field.
---
plugins/phonebook-tracker.c | 104 +++++++++++++++++++++++++++++++-----------
1 files changed, 77 insertions(+), 27 deletions(-)
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 672d59f..8f8a6e2 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -43,21 +43,65 @@
#define TRACKER_RESOURCES_INTERFACE "org.freedesktop.Tracker1.Resources"
#define TRACKER_DEFAULT_CONTACT_ME "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#default-contact-me"
-#define CONTACTS_ID_COL 47
+#define ADDR_FIELD_AMOUNT 7
#define PULL_QUERY_COL_AMOUNT 48
#define COUNT_QUERY_COL_AMOUNT 1
+
#define COL_HOME_NUMBER 0
+#define COL_FULL_NAME 1
+#define COL_FAMILY_NAME 2
+#define COL_GIVEN_NAME 3
+#define COL_ADDITIONAL_NAME 4
+#define COL_NAME_PREFIX 5
+#define COL_NAME_SUFFIX 6
#define COL_HOME_EMAIL 7
#define COL_WORK_NUMBER 8
+
+#define COL_HOME_ADDR_POBOX 9
+#define COL_HOME_ADDR_EXT 10
+#define COL_HOME_ADDR_STREET 11
+#define COL_HOME_ADDR_LOCALITY 12
+#define COL_HOME_ADDR_REGION 13
+#define COL_HOME_ADDR_CODE 14
+#define COL_HOME_ADDR_COUNTRY 15
+
#define COL_FAX_NUMBER 16
#define COL_WORK_EMAIL 17
+#define COL_BIRTH_DATE 18
+#define COL_NICKNAME 19
+#define COL_URL 20
+#define COL_PHOTO 21
+
+#define COL_ORG_NAME 22
+#define COL_ORG_DEPARTMENT 23
+#define COL_ORG_ROLE 24
+
+#define COL_WORK_ADDR_POBOX 25
+#define COL_WORK_ADDR_EXT 26
+#define COL_WORK_ADDR_STREET 27
+#define COL_WORK_ADDR_LOCALITY 28
+#define COL_WORK_ADDR_REGION 29
+#define COL_WORK_ADDR_CODE 30
+#define COL_WORK_ADDR_COUNTRY 31
+
+#define COL_UID 32
+#define COL_TITLE 33
#define COL_OTHER_NUMBER 34
+
+#define COL_OTHER_ADDR_POBOX 35
+#define COL_OTHER_ADDR_EXT 36
+#define COL_OTHER_ADDR_STREET 37
+#define COL_OTHER_ADDR_LOCALITY 38
+#define COL_OTHER_ADDR_REGION 39
+#define COL_OTHER_ADDR_CODE 40
+#define COL_OTHER_ADDR_COUNTRY 41
+
#define COL_OTHER_EMAIL 42
#define COL_CELL_NUMBER 43
#define COL_DATE 44
#define COL_SENT 45
#define COL_ANSWERED 46
-#define ADDR_FIELD_AMOUNT 7
+#define CONTACTS_ID_COL 47
#define CONTACT_ID_PREFIX "contact:"
#define CONTACTS_QUERY_ALL \
@@ -1407,21 +1451,21 @@ static void pull_contacts(char **reply, int num_fields, void *user_data)
add_entry:
contact = g_new0(struct phonebook_contact, 1);
- contact->fullname = g_strdup(reply[1]);
- contact->family = g_strdup(reply[2]);
- contact->given = g_strdup(reply[3]);
- contact->additional = g_strdup(reply[4]);
- contact->prefix = g_strdup(reply[5]);
- contact->suffix = g_strdup(reply[6]);
- contact->birthday = g_strdup(reply[18]);
- contact->nickname = g_strdup(reply[19]);
- contact->website = g_strdup(reply[20]);
- contact->photo = g_strdup(reply[21]);
- contact->company = g_strdup(reply[22]);
- contact->department = g_strdup(reply[23]);
- contact->role = g_strdup(reply[24]);
- contact->uid = g_strdup(reply[32]);
- contact->title = g_strdup(reply[33]);
+ contact->fullname = g_strdup(reply[COL_FULL_NAME]);
+ contact->family = g_strdup(reply[COL_FAMILY_NAME]);
+ contact->given = g_strdup(reply[COL_GIVEN_NAME]);
+ contact->additional = g_strdup(reply[COL_ADDITIONAL_NAME]);
+ contact->prefix = g_strdup(reply[COL_NAME_PREFIX]);
+ contact->suffix = g_strdup(reply[COL_NAME_SUFFIX]);
+ contact->birthday = g_strdup(reply[COL_BIRTH_DATE]);
+ contact->nickname = g_strdup(reply[COL_NICKNAME]);
+ contact->website = g_strdup(reply[COL_URL]);
+ contact->photo = g_strdup(reply[COL_PHOTO]);
+ contact->company = g_strdup(reply[COL_ORG_NAME]);
+ contact->department = g_strdup(reply[COL_ORG_DEPARTMENT]);
+ contact->role = g_strdup(reply[COL_ORG_ROLE]);
+ contact->uid = g_strdup(reply[COL_UID]);
+ contact->title = g_strdup(reply[COL_TITLE]);
set_call_type(contact, reply[COL_DATE], reply[COL_SENT],
reply[COL_ANSWERED]);
@@ -1444,16 +1488,22 @@ add_numbers:
/* Adding addresses */
home_addr = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s",
- reply[9], reply[10], reply[11], reply[12],
- reply[13], reply[14], reply[15]);
+ reply[COL_HOME_ADDR_POBOX], reply[COL_HOME_ADDR_EXT],
+ reply[COL_HOME_ADDR_STREET], reply[COL_HOME_ADDR_LOCALITY],
+ reply[COL_HOME_ADDR_REGION], reply[COL_HOME_ADDR_CODE],
+ reply[COL_HOME_ADDR_COUNTRY]);
work_addr = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s",
- reply[25], reply[26], reply[27], reply[28],
- reply[29], reply[30], reply[31]);
+ reply[COL_WORK_ADDR_POBOX], reply[COL_WORK_ADDR_EXT],
+ reply[COL_WORK_ADDR_STREET], reply[COL_WORK_ADDR_LOCALITY],
+ reply[COL_WORK_ADDR_REGION], reply[COL_WORK_ADDR_CODE],
+ reply[COL_WORK_ADDR_COUNTRY]);
other_addr = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s",
- reply[35], reply[36], reply[37], reply[38],
- reply[39], reply[40], reply[41]);
+ reply[COL_OTHER_ADDR_POBOX], reply[COL_OTHER_ADDR_EXT],
+ reply[COL_OTHER_ADDR_STREET], reply[COL_OTHER_ADDR_LOCALITY],
+ reply[COL_OTHER_ADDR_REGION], reply[COL_OTHER_ADDR_CODE],
+ reply[COL_OTHER_ADDR_COUNTRY]);
add_address(contact, home_addr, ADDR_TYPE_HOME);
add_address(contact, work_addr, ADDR_TYPE_WORK);
@@ -1465,10 +1515,10 @@ add_numbers:
/* Adding fields connected by nco:hasAffiliation - they may be in
* separate replies */
- add_affiliation(&contact->title, reply[33]);
- add_affiliation(&contact->company, reply[22]);
- add_affiliation(&contact->department, reply[23]);
- add_affiliation(&contact->role, reply[24]);
+ add_affiliation(&contact->title, reply[COL_TITLE]);
+ add_affiliation(&contact->company, reply[COL_ORG_NAME]);
+ add_affiliation(&contact->department, reply[COL_ORG_DEPARTMENT]);
+ add_affiliation(&contact->role, reply[COL_ORG_ROLE]);
DBG("contact %p", contact);
--
1.7.0.4
^ permalink raw reply related
* [PATCH 2/2] Split pull_contacts to smaller functions
From: Bartosz Szatkowski @ 2010-11-15 12:01 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bartosz Szatkowski
In-Reply-To: <1289822497-5338-1-git-send-email-bulislaw@linux.com>
Parts of pull_contact responsible for filling contact fields moved
to new functions.
---
plugins/phonebook-tracker.c | 159 ++++++++++++++++++++++++------------------
1 files changed, 91 insertions(+), 68 deletions(-)
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 8f8a6e2..e9fc3ab 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -1395,6 +1395,92 @@ static void add_affiliation(char **field, const char *value)
*field = g_strdup(value);
}
+static void contact_init(struct phonebook_contact **contact, char **reply)
+{
+ if (*contact == NULL)
+ *contact = g_new0(struct phonebook_contact, 1);
+
+ (*contact)->fullname = g_strdup(reply[COL_FULL_NAME]);
+ (*contact)->family = g_strdup(reply[COL_FAMILY_NAME]);
+ (*contact)->given = g_strdup(reply[COL_GIVEN_NAME]);
+ (*contact)->additional = g_strdup(reply[COL_ADDITIONAL_NAME]);
+ (*contact)->prefix = g_strdup(reply[COL_NAME_PREFIX]);
+ (*contact)->suffix = g_strdup(reply[COL_NAME_SUFFIX]);
+ (*contact)->birthday = g_strdup(reply[COL_BIRTH_DATE]);
+ (*contact)->nickname = g_strdup(reply[COL_NICKNAME]);
+ (*contact)->website = g_strdup(reply[COL_URL]);
+ (*contact)->photo = g_strdup(reply[COL_PHOTO]);
+ (*contact)->company = g_strdup(reply[COL_ORG_NAME]);
+ (*contact)->department = g_strdup(reply[COL_ORG_DEPARTMENT]);
+ (*contact)->role = g_strdup(reply[COL_ORG_ROLE]);
+ (*contact)->uid = g_strdup(reply[COL_UID]);
+ (*contact)->title = g_strdup(reply[COL_TITLE]);
+
+ set_call_type(*contact, reply[COL_DATE], reply[COL_SENT],
+ reply[COL_ANSWERED]);
+}
+
+static void contact_add_numbers(struct phonebook_contact **contact, char **reply)
+{
+ add_phone_number(*contact, reply[COL_HOME_NUMBER], TEL_TYPE_HOME);
+ add_phone_number(*contact, reply[COL_WORK_NUMBER], TEL_TYPE_WORK);
+ add_phone_number(*contact, reply[COL_FAX_NUMBER], TEL_TYPE_FAX);
+ add_phone_number(*contact, reply[COL_CELL_NUMBER], TEL_TYPE_MOBILE);
+ if ((g_strcmp0(reply[COL_OTHER_NUMBER], reply[COL_CELL_NUMBER]) != 0) &&
+ (g_strcmp0(reply[COL_OTHER_NUMBER], reply[COL_WORK_NUMBER]) != 0) &&
+ (g_strcmp0(reply[COL_OTHER_NUMBER], reply[COL_HOME_NUMBER]) != 0))
+ add_phone_number(*contact, reply[COL_OTHER_NUMBER], TEL_TYPE_OTHER);
+}
+
+static void contact_add_emails(struct phonebook_contact **contact, char **reply)
+{
+ add_email(*contact, reply[COL_HOME_EMAIL], EMAIL_TYPE_HOME);
+ add_email(*contact, reply[COL_WORK_EMAIL], EMAIL_TYPE_WORK);
+ add_email(*contact, reply[COL_OTHER_EMAIL], EMAIL_TYPE_OTHER);
+}
+
+static void contact_add_addresses(struct phonebook_contact **contact, char **reply)
+{
+
+ char *home_addr, *work_addr, *other_addr;
+
+ home_addr = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s",
+ reply[COL_HOME_ADDR_POBOX], reply[COL_HOME_ADDR_EXT],
+ reply[COL_HOME_ADDR_STREET], reply[COL_HOME_ADDR_LOCALITY],
+ reply[COL_HOME_ADDR_REGION], reply[COL_HOME_ADDR_CODE],
+ reply[COL_HOME_ADDR_COUNTRY]);
+
+ work_addr = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s",
+ reply[COL_WORK_ADDR_POBOX], reply[COL_WORK_ADDR_EXT],
+ reply[COL_WORK_ADDR_STREET], reply[COL_WORK_ADDR_LOCALITY],
+ reply[COL_WORK_ADDR_REGION], reply[COL_WORK_ADDR_CODE],
+ reply[COL_WORK_ADDR_COUNTRY]);
+
+ other_addr = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s",
+ reply[COL_OTHER_ADDR_POBOX], reply[COL_OTHER_ADDR_EXT],
+ reply[COL_OTHER_ADDR_STREET], reply[COL_OTHER_ADDR_LOCALITY],
+ reply[COL_OTHER_ADDR_REGION], reply[COL_OTHER_ADDR_CODE],
+ reply[COL_OTHER_ADDR_COUNTRY]);
+
+ add_address(*contact, home_addr, ADDR_TYPE_HOME);
+ add_address(*contact, work_addr, ADDR_TYPE_WORK);
+ add_address(*contact, other_addr, ADDR_TYPE_OTHER);
+
+ g_free(home_addr);
+ g_free(work_addr);
+ g_free(other_addr);
+}
+
+static void contact_add_organization(struct phonebook_contact **contact, char **reply)
+{
+ /* Adding fields connected by nco:hasAffiliation - they may be in
+ * separate replies */
+ add_affiliation(&(*contact)->title, reply[COL_TITLE]);
+ add_affiliation(&(*contact)->company, reply[COL_ORG_NAME]);
+ add_affiliation(&(*contact)->department, reply[COL_ORG_DEPARTMENT]);
+ add_affiliation(&(*contact)->role, reply[COL_ORG_ROLE]);
+}
+
static void pull_contacts(char **reply, int num_fields, void *user_data)
{
struct phonebook_data *data = user_data;
@@ -1404,7 +1490,6 @@ static void pull_contacts(char **reply, int num_fields, void *user_data)
GString *vcards;
int last_index, i;
gboolean cdata_present = FALSE;
- char *home_addr, *work_addr, *other_addr;
if (num_fields < 0) {
data->cb(NULL, 0, num_fields, 0, data->user_data);
@@ -1450,75 +1535,13 @@ static void pull_contacts(char **reply, int num_fields, void *user_data)
return;
add_entry:
- contact = g_new0(struct phonebook_contact, 1);
- contact->fullname = g_strdup(reply[COL_FULL_NAME]);
- contact->family = g_strdup(reply[COL_FAMILY_NAME]);
- contact->given = g_strdup(reply[COL_GIVEN_NAME]);
- contact->additional = g_strdup(reply[COL_ADDITIONAL_NAME]);
- contact->prefix = g_strdup(reply[COL_NAME_PREFIX]);
- contact->suffix = g_strdup(reply[COL_NAME_SUFFIX]);
- contact->birthday = g_strdup(reply[COL_BIRTH_DATE]);
- contact->nickname = g_strdup(reply[COL_NICKNAME]);
- contact->website = g_strdup(reply[COL_URL]);
- contact->photo = g_strdup(reply[COL_PHOTO]);
- contact->company = g_strdup(reply[COL_ORG_NAME]);
- contact->department = g_strdup(reply[COL_ORG_DEPARTMENT]);
- contact->role = g_strdup(reply[COL_ORG_ROLE]);
- contact->uid = g_strdup(reply[COL_UID]);
- contact->title = g_strdup(reply[COL_TITLE]);
-
- set_call_type(contact, reply[COL_DATE], reply[COL_SENT],
- reply[COL_ANSWERED]);
+ contact_init(&contact, reply);
add_numbers:
- /* Adding phone numbers to contact struct */
- add_phone_number(contact, reply[COL_HOME_NUMBER], TEL_TYPE_HOME);
- add_phone_number(contact, reply[COL_WORK_NUMBER], TEL_TYPE_WORK);
- add_phone_number(contact, reply[COL_FAX_NUMBER], TEL_TYPE_FAX);
- add_phone_number(contact, reply[COL_CELL_NUMBER], TEL_TYPE_MOBILE);
- if ((g_strcmp0(reply[COL_OTHER_NUMBER], reply[COL_CELL_NUMBER]) != 0) &&
- (g_strcmp0(reply[COL_OTHER_NUMBER], reply[COL_WORK_NUMBER]) != 0) &&
- (g_strcmp0(reply[COL_OTHER_NUMBER], reply[COL_HOME_NUMBER]) != 0))
- add_phone_number(contact, reply[COL_OTHER_NUMBER], TEL_TYPE_OTHER);
-
- /* Adding emails */
- add_email(contact, reply[COL_HOME_EMAIL], EMAIL_TYPE_HOME);
- add_email(contact, reply[COL_WORK_EMAIL], EMAIL_TYPE_WORK);
- add_email(contact, reply[COL_OTHER_EMAIL], EMAIL_TYPE_OTHER);
-
- /* Adding addresses */
- home_addr = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s",
- reply[COL_HOME_ADDR_POBOX], reply[COL_HOME_ADDR_EXT],
- reply[COL_HOME_ADDR_STREET], reply[COL_HOME_ADDR_LOCALITY],
- reply[COL_HOME_ADDR_REGION], reply[COL_HOME_ADDR_CODE],
- reply[COL_HOME_ADDR_COUNTRY]);
-
- work_addr = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s",
- reply[COL_WORK_ADDR_POBOX], reply[COL_WORK_ADDR_EXT],
- reply[COL_WORK_ADDR_STREET], reply[COL_WORK_ADDR_LOCALITY],
- reply[COL_WORK_ADDR_REGION], reply[COL_WORK_ADDR_CODE],
- reply[COL_WORK_ADDR_COUNTRY]);
-
- other_addr = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s",
- reply[COL_OTHER_ADDR_POBOX], reply[COL_OTHER_ADDR_EXT],
- reply[COL_OTHER_ADDR_STREET], reply[COL_OTHER_ADDR_LOCALITY],
- reply[COL_OTHER_ADDR_REGION], reply[COL_OTHER_ADDR_CODE],
- reply[COL_OTHER_ADDR_COUNTRY]);
-
- add_address(contact, home_addr, ADDR_TYPE_HOME);
- add_address(contact, work_addr, ADDR_TYPE_WORK);
- add_address(contact, other_addr, ADDR_TYPE_OTHER);
-
- g_free(home_addr);
- g_free(work_addr);
- g_free(other_addr);
-
- /* Adding fields connected by nco:hasAffiliation - they may be in
- * separate replies */
- add_affiliation(&contact->title, reply[COL_TITLE]);
- add_affiliation(&contact->company, reply[COL_ORG_NAME]);
- add_affiliation(&contact->department, reply[COL_ORG_DEPARTMENT]);
- add_affiliation(&contact->role, reply[COL_ORG_ROLE]);
+ contact_add_numbers(&contact, reply);
+ contact_add_emails(&contact, reply);
+ contact_add_addresses(&contact, reply);
+ contact_add_organization(&contact, reply);
DBG("contact %p", contact);
--
1.7.0.4
^ permalink raw reply related
* [RFC] Interface to set LE connection parameters
From: Ville Tervo @ 2010-11-15 12:06 UTC (permalink / raw)
To: linux-bluetooth
Hi,
LE profiles have different requirements for connection parameters. Mainly
trying to balance between power consumption and latencies. Probably more will
factors will be in future.
Currently I have plan to introduce new l2cap socket option which can be used
before connection creation to set inital settings and also change settings
while having a connection.
Since there is no equivalents in EDR/BR connection I'm planning to make then
apply only LE connection.
Other question which parameters should be exposed to user space? Connection
creation and connection update have these common parameters. Connection
creation has in addition some other parameters also but they should be handled
in some other way.
__le16 conn_interval_min;
__le16 conn_interval_max;
__le16 conn_latency;
__le16 supervision_timeout;
__le16 min_ce_len;
__le16 max_ce_len;
So far I have had two ideas. The first is to simply expose all these fields
with sock_opt. In that way profiles would be able to define their requirements
also in future without any sock opt changes.
Second is to define BT_LE_LOW_LAT for low latency connection requirements and
BT_LE_LOW_POWER connection where the latency is not an issue. It would make
usage of this sock opt interface simplier. OTOH the only user should be
bluetoothd so it doesn't need to be as simple as possible.
Comments please.
--
Ville
^ 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