* [PATCH 3/3 v2] Use libtracker-sparql in PBAP
From: Radoslaw Jablonski @ 2011-02-02 10:21 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Radoslaw Jablonski
In-Reply-To: <1296642108-14063-1-git-send-email-ext-jablonski.radoslaw@nokia.com>
Now direct tracker connection for transporting retrieved
parts of data is used, instead of D-Bus. This should result better
performance for PBAP requests.
Each part of results is now fetched from tracker asynchronously
and getting more results can be stopped in any moment -
GCancellable stored in phonebook_data is used for that purpose.
If processing of data has finished (or it was cancelled) then cleanup
of pending_reply is done in last invocation of
async_query_cursor_next_cb.
---
plugins/phonebook-tracker.c | 271 +++++++++++++++++++++++--------------------
1 files changed, 147 insertions(+), 124 deletions(-)
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 3b61d6b..79bc1c6 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -29,6 +29,7 @@
#include <dbus/dbus.h>
#include <openobex/obex.h>
#include <openobex/obex_const.h>
+#include <libtracker-sparql/tracker-sparql.h>
#include "log.h"
#include "obex.h"
@@ -891,7 +892,7 @@
"} GROUP BY ?call ORDER BY DESC(nmo:receivedDate(?call)) " \
"LIMIT 40"
-typedef void (*reply_list_foreach_t) (char **reply, int num_fields,
+typedef void (*reply_list_foreach_t) (const char **reply, int num_fields,
void *user_data);
typedef void (*add_field_t) (struct phonebook_contact *contact,
@@ -918,7 +919,7 @@ struct phonebook_data {
phonebook_cache_ready_cb ready_cb;
phonebook_entry_cb entry_cb;
int newmissedcalls;
- DBusPendingCall *call;
+ GCancellable *query_canc;
};
struct phonebook_index {
@@ -926,7 +927,7 @@ struct phonebook_index {
int index;
};
-static DBusConnection *connection = NULL;
+static TrackerSparqlConnection *connection = NULL;
static const char *name2query(const char *name)
{
@@ -999,131 +1000,139 @@ static const char *folder2query(const char *folder)
return NULL;
}
-static char **string_array_from_iter(DBusMessageIter iter, int array_len)
+static const char **string_array_from_cursor(TrackerSparqlCursor *cursor,
+ int array_len)
{
- DBusMessageIter sub;
- char **result;
+ const char **result;
int i;
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
- return NULL;
-
- result = g_new0(char *, array_len);
-
- dbus_message_iter_recurse(&iter, &sub);
-
- i = 0;
- while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
- char *arg;
+ result = g_new0(const char *, array_len);
- if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) {
- g_free(result);
- return NULL;
- }
-
- dbus_message_iter_get_basic(&sub, &arg);
+ for (i = 0; i < array_len; ++i) {
+ TrackerSparqlValueType type;
- result[i] = arg;
+ type = tracker_sparql_cursor_get_value_type(cursor, i);
- i++;
- dbus_message_iter_next(&sub);
+ if (type == TRACKER_SPARQL_VALUE_TYPE_BLANK_NODE ||
+ type == TRACKER_SPARQL_VALUE_TYPE_UNBOUND)
+ /* For null/unbound type filling result part with ""*/
+ result[i] = "";
+ else
+ /* Filling with string representation of content*/
+ result[i] = tracker_sparql_cursor_get_string(cursor, i,
+ NULL);
}
return result;
}
-static void query_reply(DBusPendingCall *call, void *user_data)
+
+static void query_free_data(void *user_data)
{
- DBusMessage *reply = dbus_pending_call_steal_reply(call);
+ DBG("");
struct pending_reply *pending = user_data;
- DBusMessageIter iter, element;
- DBusError derr;
- int err;
-
- dbus_error_init(&derr);
- if (dbus_set_error_from_message(&derr, reply)) {
- error("Replied with an error: %s, %s", derr.name,
- derr.message);
- dbus_error_free(&derr);
-
- err = -1;
- goto done;
- }
-
- dbus_message_iter_init(reply, &iter);
-
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
- error("SparqlQuery reply is not an array");
- err = -1;
- goto done;
- }
-
- dbus_message_iter_recurse(&iter, &element);
-
- err = 0;
+ if (!pending)
+ return;
- while (dbus_message_iter_get_arg_type(&element) != DBUS_TYPE_INVALID) {
- char **node;
+ g_free(pending);
+}
- if (dbus_message_iter_get_arg_type(&element) !=
- DBUS_TYPE_ARRAY) {
- error("element is not an array");
- goto done;
- }
+static void update_cancellable(struct phonebook_data *pdata,
+ GCancellable *canc)
+{
+ if (pdata->query_canc)
+ g_object_unref(pdata->query_canc);
- node = string_array_from_iter(element, pending->num_fields);
- pending->callback(node, pending->num_fields,
- pending->user_data);
+ pdata->query_canc = canc;
+}
- g_free(node);
+static void async_query_cursor_next_cb(GObject *source, GAsyncResult *result,
+ gpointer user_data)
+{
+ struct pending_reply *pending = user_data;
+ TrackerSparqlCursor *cursor = TRACKER_SPARQL_CURSOR (source);
+ GCancellable *cancellable;
+ GError *error = NULL;
+ gboolean success;
+ const char **node;
+
+ success = tracker_sparql_cursor_next_finish(
+ TRACKER_SPARQL_CURSOR (source),
+ result,
+ &error);
+
+ if (!success) {
+ if (error) {
+ DBG("cursor_next error: %s", error->message);
+ g_error_free(error);
+ } else
+ /* When tracker_sparql_cursor_next_finish ends with
+ * failure and no error is set, that means end of
+ * results returned by query */
+ pending->callback(NULL, 0, pending->user_data);
- dbus_message_iter_next(&element);
+ goto failed;
}
-done:
- /* This is the last entry */
- pending->callback(NULL, err, pending->user_data);
+ node = string_array_from_cursor(cursor, pending->num_fields);
+ pending->callback(node, pending->num_fields, pending->user_data);
+ g_free(node);
- dbus_message_unref(reply);
- /* pending data is freed in query_free_data after call is unreffed. */
-}
-
-static void query_free_data(void *user_data)
-{
- struct pending_reply *pending = user_data;
-
- if (!pending)
- return;
+ /* getting next row from query results */
+ cancellable = g_cancellable_new();
+ update_cancellable(pending->user_data, cancellable);
+ tracker_sparql_cursor_next_async(cursor, cancellable,
+ async_query_cursor_next_cb,
+ pending);
+ return;
- g_free(pending);
+failed:
+ g_object_unref(cursor);
+ query_free_data(pending);
}
-static DBusPendingCall *query_tracker(const char *query, int num_fields,
- reply_list_foreach_t callback, void *user_data, int *err)
+static void query_tracker(const char *query, int num_fields,
+ reply_list_foreach_t callback, void *user_data,
+ int *err)
+
{
struct pending_reply *pending;
- DBusPendingCall *call;
- DBusMessage *msg;
+ GCancellable *cancellable;
+ TrackerSparqlCursor *cursor;
+ GError *error = NULL;
+
+ DBG("");
if (connection == NULL)
- connection = obex_dbus_get_connection();
+ connection = tracker_sparql_connection_get_direct(
+ NULL, &error);
- msg = dbus_message_new_method_call(TRACKER_SERVICE,
- TRACKER_RESOURCES_PATH, TRACKER_RESOURCES_INTERFACE,
- "SparqlQuery");
+ if (!connection) {
+ if (error) {
+ DBG("direct-connection error: %s", error->message);
+ g_error_free(error);
+ }
- dbus_message_append_args(msg, DBUS_TYPE_STRING, &query,
- DBUS_TYPE_INVALID);
+ goto failed;
+ }
- if (dbus_connection_send_with_reply(connection, msg, &call,
- -1) == FALSE) {
- error("Could not send dbus message");
- dbus_message_unref(msg);
- if (err)
- *err = -EPERM;
- return NULL;
+ cancellable = g_cancellable_new();
+ update_cancellable(user_data, cancellable);
+ cursor = tracker_sparql_connection_query(connection, query,
+ cancellable, &error);
+
+ if (cursor == NULL) {
+ if (error) {
+ DBG("connection_query error: %s", error->message);
+ g_error_free(error);
+ }
+
+ g_object_unref(cancellable);
+ g_object_unref(cursor);
+
+ goto failed;
}
pending = g_new0(struct pending_reply, 1);
@@ -1131,14 +1140,21 @@ static DBusPendingCall *query_tracker(const char *query, int num_fields,
pending->user_data = user_data;
pending->num_fields = num_fields;
- dbus_pending_call_set_notify(call, query_reply, pending,
- query_free_data);
- dbus_message_unref(msg);
+ /* Now asynchronously going through each row of results - callback
+ * async_query_cursor_next_cb will be called ALWAYS, even if async
+ * request was canceled */
+ tracker_sparql_cursor_next_async(cursor, cancellable,
+ async_query_cursor_next_cb,
+ pending);
if (err)
*err = 0;
- return call;
+ return;
+
+failed:
+ if (err)
+ *err = -EPERM;
}
static char *iso8601_utc_to_localtime(const char *datetime)
@@ -1331,7 +1347,8 @@ static GString *gen_vcards(GSList *contacts,
return vcards;
}
-static void pull_contacts_size(char **reply, int num_fields, void *user_data)
+static void pull_contacts_size(const char **reply, int num_fields,
+ void *user_data)
{
struct phonebook_data *data = user_data;
@@ -1363,7 +1380,8 @@ static void add_affiliation(char **field, const char *value)
*field = g_strdup(value);
}
-static void contact_init(struct phonebook_contact *contact, char **reply)
+static void contact_init(struct phonebook_contact *contact,
+ const char **reply)
{
contact->fullname = g_strdup(reply[COL_FULL_NAME]);
@@ -1395,8 +1413,8 @@ static enum phonebook_number_type get_phone_type(const char *affilation)
return TEL_TYPE_OTHER;
}
-static void add_aff_number(struct phonebook_contact *contact, char *pnumber,
- char *aff_type)
+static void add_aff_number(struct phonebook_contact *contact,
+ const char *pnumber, const char *aff_type)
{
char **num_parts;
char *type, *number;
@@ -1433,7 +1451,7 @@ failed:
}
static void contact_add_numbers(struct phonebook_contact *contact,
- char **reply)
+ const char **reply)
{
char **aff_numbers;
int i;
@@ -1459,8 +1477,8 @@ static enum phonebook_field_type get_field_type(const char *affilation)
return FIELD_TYPE_OTHER;
}
-static void add_aff_field(struct phonebook_contact *contact, char *aff_email,
- add_field_t add_field_cb)
+static void add_aff_field(struct phonebook_contact *contact,
+ const char *aff_email, add_field_t add_field_cb)
{
char **email_parts;
char *type, *email;
@@ -1490,7 +1508,7 @@ failed:
}
static void contact_add_emails(struct phonebook_contact *contact,
- char **reply)
+ const char **reply)
{
char **aff_emails;
int i;
@@ -1506,7 +1524,7 @@ static void contact_add_emails(struct phonebook_contact *contact,
}
static void contact_add_addresses(struct phonebook_contact *contact,
- char **reply)
+ const char **reply)
{
char **aff_addr;
int i;
@@ -1522,7 +1540,8 @@ static void contact_add_addresses(struct phonebook_contact *contact,
g_strfreev(aff_addr);
}
-static void contact_add_urls(struct phonebook_contact *contact, char **reply)
+static void contact_add_urls(struct phonebook_contact *contact,
+ const char **reply)
{
char **aff_url;
int i;
@@ -1538,7 +1557,7 @@ static void contact_add_urls(struct phonebook_contact *contact, char **reply)
}
static void contact_add_organization(struct phonebook_contact *contact,
- char **reply)
+ const char **reply)
{
/* Adding fields connected by nco:hasAffiliation - they may be in
* separate replies */
@@ -1548,7 +1567,7 @@ static void contact_add_organization(struct phonebook_contact *contact,
add_affiliation(&contact->role, reply[COL_ORG_ROLE]);
}
-static void pull_contacts(char **reply, int num_fields, void *user_data)
+static void pull_contacts(const char **reply, int num_fields, void *user_data)
{
struct phonebook_data *data = user_data;
const struct apparam_field *params = data->params;
@@ -1649,7 +1668,7 @@ fail:
*/
}
-static void add_to_cache(char **reply, int num_fields, void *user_data)
+static void add_to_cache(const char **reply, int num_fields, void *user_data)
{
struct phonebook_data *data = user_data;
char *formatted;
@@ -1699,6 +1718,9 @@ done:
int phonebook_init(void)
{
+ g_thread_init(NULL);
+ g_type_init();
+
return 0;
}
@@ -1792,12 +1814,13 @@ void phonebook_req_finalize(void *request)
if (!data)
return;
- if (!dbus_pending_call_get_completed(data->call))
- dbus_pending_call_cancel(data->call);
-
- dbus_pending_call_unref(data->call);
+ /* canceling asynchronous operation on tracker if any is active */
+ if (data->query_canc) {
+ g_cancellable_cancel(data->query_canc);
+ g_object_unref(data->query_canc);
+ }
- /* freeing list of contacts used for generating vcards */
+ /* freeing contacts */
for (l = data->contacts; l; l = l->next) {
struct contact_data *c_data = l->data;
@@ -1828,7 +1851,8 @@ static void gstring_free_helper(gpointer data, gpointer user_data)
g_string_free(data, TRUE);
}
-static void pull_newmissedcalls(char **reply, int num_fields, void *user_data)
+static void pull_newmissedcalls(const char **reply, int num_fields,
+ void *user_data)
{
struct phonebook_data *data = user_data;
reply_list_foreach_t pull_cb;
@@ -1870,8 +1894,7 @@ done:
pull_cb = pull_contacts;
}
- dbus_pending_call_unref(data->call);
- data->call = query_tracker(query, col_amount, pull_cb, data, &err);
+ query_tracker(query, col_amount, pull_cb, data, &err);
if (err < 0)
data->cb(NULL, 0, err, 0, data->user_data);
}
@@ -1910,7 +1933,7 @@ void *phonebook_pull(const char *name, const struct apparam_field *params,
data->params = params;
data->user_data = user_data;
data->cb = cb;
- data->call = query_tracker(query, col_amount, pull_cb, data, err);
+ query_tracker(query, col_amount, pull_cb, data, err);
return data;
}
@@ -1938,8 +1961,8 @@ void *phonebook_get_entry(const char *folder, const char *id,
query = g_strdup_printf(CONTACTS_OTHER_QUERY_FROM_URI,
id, id, id);
- data->call = query_tracker(query, PULL_QUERY_COL_AMOUNT, pull_contacts,
- data, err);
+ query_tracker(query, PULL_QUERY_COL_AMOUNT,
+ pull_contacts, data, err);
g_free(query);
@@ -1965,7 +1988,7 @@ void *phonebook_create_cache(const char *name, phonebook_entry_cb entry_cb,
data->entry_cb = entry_cb;
data->ready_cb = ready_cb;
data->user_data = user_data;
- data->call = query_tracker(query, 7, add_to_cache, data, err);
+ query_tracker(query, 7, add_to_cache, data, err);
return data;
}
--
1.7.0.4
^ permalink raw reply related
* [PATCH] Fix crash while parsering of endpoint properties
From: Luiz Augusto von Dentz @ 2011-02-02 11:12 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
When parsing endpoint properties application my not have set some of the
mandatory properties, also the size of capability is now initialized with
0 so if the codec doesn't have any capabilities (e.g. pcm) the variable
won't be used uninitialized.
---
audio/media.c | 25 +++++++++++++++++--------
1 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/audio/media.c b/audio/media.c
index 402709a..9cfbe0e 100644
--- a/audio/media.c
+++ b/audio/media.c
@@ -194,9 +194,13 @@ static struct media_endpoint *media_endpoint_create(struct media_adapter *adapte
endpoint->path = g_strdup(path);
endpoint->uuid = g_strdup(uuid);
endpoint->codec = codec;
- endpoint->capabilities = g_new(uint8_t, size);
- memcpy(endpoint->capabilities, capabilities, size);
- endpoint->size = size;
+
+ if (size > 0) {
+ endpoint->capabilities = g_new(uint8_t, size);
+ memcpy(endpoint->capabilities, capabilities, size);
+ endpoint->size = size;
+ }
+
endpoint->adapter = adapter;
if (strcasecmp(uuid, A2DP_SOURCE_UUID) == 0) {
@@ -275,6 +279,9 @@ static int parse_properties(DBusMessageIter *props, const char **uuid,
gboolean *delay_reporting, uint8_t *codec,
uint8_t **capabilities, int *size)
{
+ gboolean has_uuid = FALSE;
+ gboolean has_codec = FALSE;
+
while (dbus_message_iter_get_arg_type(props) == DBUS_TYPE_DICT_ENTRY) {
const char *key;
DBusMessageIter value, entry;
@@ -291,10 +298,12 @@ static int parse_properties(DBusMessageIter *props, const char **uuid,
if (var != DBUS_TYPE_STRING)
return -EINVAL;
dbus_message_iter_get_basic(&value, uuid);
+ has_uuid = TRUE;
} else if (strcasecmp(key, "Codec") == 0) {
if (var != DBUS_TYPE_BYTE)
return -EINVAL;
dbus_message_iter_get_basic(&value, codec);
+ has_codec = TRUE;
} else if (strcasecmp(key, "DelayReporting") == 0) {
if (var != DBUS_TYPE_BOOLEAN)
return -EINVAL;
@@ -313,7 +322,7 @@ static int parse_properties(DBusMessageIter *props, const char **uuid,
dbus_message_iter_next(props);
}
- return 0;
+ return (has_uuid && has_codec) ? 0 : -EINVAL;
}
static DBusMessage *register_endpoint(DBusConnection *conn, DBusMessage *msg,
@@ -321,11 +330,11 @@ static DBusMessage *register_endpoint(DBusConnection *conn, DBusMessage *msg,
{
struct media_adapter *adapter = data;
DBusMessageIter args, props;
- const char *sender, *path, *uuid = NULL;
- gboolean delay_reporting;
+ const char *sender, *path, *uuid;
+ gboolean delay_reporting = FALSE;
uint8_t codec;
uint8_t *capabilities;
- int size;
+ int size = 0;
sender = dbus_message_get_sender(msg);
@@ -342,7 +351,7 @@ static DBusMessage *register_endpoint(DBusConnection *conn, DBusMessage *msg,
return btd_error_invalid_args(msg);
if (parse_properties(&props, &uuid, &delay_reporting, &codec,
- &capabilities, &size) || uuid == NULL)
+ &capabilities, &size) < 0)
return btd_error_invalid_args(msg);
if (media_endpoint_create(adapter, sender, path, uuid, delay_reporting,
--
1.7.1
^ permalink raw reply related
* Re: [PATCH] Fix crash while parsering of endpoint properties
From: Johan Hedberg @ 2011-02-02 11:56 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1296645176-23502-1-git-send-email-luiz.dentz@gmail.com>
Hi Luiz,
On Wed, Feb 02, 2011, Luiz Augusto von Dentz wrote:
> When parsing endpoint properties application my not have set some of the
> mandatory properties, also the size of capability is now initialized with
> 0 so if the codec doesn't have any capabilities (e.g. pcm) the variable
> won't be used uninitialized.
> ---
> audio/media.c | 25 +++++++++++++++++--------
> 1 files changed, 17 insertions(+), 8 deletions(-)
Pushed upstream. Thanks.
Johan
^ permalink raw reply
* Interested in Contributing to BlueZ
From: Vivek N @ 2011-02-02 13:59 UTC (permalink / raw)
To: linux-bluetooth
Hi,
I am Vivek Narayanan, a sophomore undergraduate student from India. I
am interested in contributing to BlueZ, the linux bluetooth project
through GSoC (Google Summer of Code) or otherwise. I am really
interested in working on a kernel and know C and Python quite well. I
am downloading the git repository right now and am looking for some
pointers on where to start first.
Thanks and Regards,
Vivek
^ permalink raw reply
* Re: Interested in Contributing to BlueZ
From: Gustavo F. Padovan @ 2011-02-02 14:45 UTC (permalink / raw)
To: Vivek N; +Cc: linux-bluetooth
In-Reply-To: <AANLkTikpZUi8ocU4Ntbn=ayX141ptTTY7zMOahuyxrTs@mail.gmail.com>
Hi Vivek,
* Vivek N <mail@vivekn.co.cc> [2011-02-02 19:29:53 +0530]:
> Hi,
>
> I am Vivek Narayanan, a sophomore undergraduate student from India. I
> am interested in contributing to BlueZ, the linux bluetooth project
> through GSoC (Google Summer of Code) or otherwise. I am really
> interested in working on a kernel and know C and Python quite well. I
> am downloading the git repository right now and am looking for some
> pointers on where to start first.
Nice that you want to contribute to BlueZ. :-)
To work with BlueZ you have first to have a good understanding of the
Bluetooth technology. For good reads are [0], [1], and many other stuff under
[2], like Profiles Overview and Architecture of many layers.
Unfortunately the only documentation we have is the source code and the git
history.
Then you have to choose some part that you want to focus on, BlueZ is a very
big project with extensive Bluetooth specifications. You won't understand all
of then easily.
We are going to setup a web page soon with project proposals for the Google
Summer of Code. It will help students choose an area in BlueZ to work on.
And a very quick overview of Bluetooth Stack in Linux: Many core parts of the
Bluetooth stack is implemented in the Linux Kernel, the HCI; L2CAP and SCO
(synchronous audio) layers; and the BNEP and RFCOMM protocols. All the rest is
done by the bluetoothd daemon in the userspace, or the obexd daemon (which is
also part of the BLueZ project, but resides in another git though).
Besides that, you have to know a bit about DBus and glib. They are two important
parts of the BlueZ.
[0] http://en.wikipedia.org/wiki/Bluetooth
[1] http://bluetooth.com/English/Technology/Works/Pages/Overview_of_Operation.aspx
[2] http://bluetooth.com/English/Technology/Works/Pages/default.aspx
Regards,
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: [PATCH] Set connection state to BT_DISCONN to avoid multiple responses
From: Gustavo F. Padovan @ 2011-02-02 14:49 UTC (permalink / raw)
To: Liang Bao; +Cc: linux-bluetooth
In-Reply-To: <1296308377-2207-1-git-send-email-tim.bao@gmail.com>
Hi Liang,
* Liang Bao <tim.bao@gmail.com> [2011-01-29 21:39:37 +0800]:
> From: Bao Liang <tim.bao@gmail.com>
>
> This patch fixes a minor issue that two connection responses will be sent
> for one L2CAP connection request. If the L2CAP connection request is first
> blocked due to security reason and responded with reason "security block",
> the state of the connection remains BT_CONNECT2. If a pairing procedure
> completes successfully before the ACL connection is down, local host will
> send another connection complete response. See the following packets
> captured by hcidump.
>
> 2010-12-07 22:21:24.928096 < ACL data: handle 12 flags 0x00 dlen 16
> 0000: 0c 00 01 00 03 19 08 00 41 00 53 00 03 00 00 00 ........A.S.....
> ... ...
>
> 2010-12-07 22:21:35.791747 > HCI Event: Auth Complete (0x06) plen 3
> status 0x00 handle 12
> ... ...
>
> 2010-12-07 22:21:35.872372 > ACL data: handle 12 flags 0x02 dlen 16
> L2CAP(s): Connect rsp: dcid 0x0054 scid 0x0040 result 0 status 0
> Connection successful
>
> Signed-off-by: Liang Bao <tim.bao@gmail.com>
> ---
> net/bluetooth/l2cap.c | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
Patch has been applied. Thanks.
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: Support for Device ID profile
From: Jose Antonio Santos Cadenas @ 2011-02-02 15:11 UTC (permalink / raw)
To: steven bluez; +Cc: Luiz Augusto von Dentz, linux-bluetooth
In-Reply-To: <AANLkTimVPFppVjbdmJSmcjeeNn7jwRf+uvLVC67xPjav@mail.gmail.com>
Hi Steven,
Bringing back this thread with some questions.
2010/9/28 steven bluez <steven.bluez@gmail.com>:
> Hi Jose,
>> Hi,
>>
>> 2010/9/24 Luiz Augusto von Dentz <luiz.dentz@gmail.com>:
>>> Hi Steven,
>>>
>>> Yes, you can use DeviceID on main.conf to add that, but as you see it
>>> is pretty limited so we are planning to have a better support for
>>> this, perhaps extend adapter driver interface where you can write a
>>> plugin to fill this information.
>>
>
> I have started to work on it thats why I cleared up my doubts.
Have you done something here? I'd like to contribute or continue the
project if you've abandoned it.
Regards.
>> Is anyone working on this plugin now. I'd like to work on it if nobody
>> is working yet.
>>
>> Regards.
>>
>>>
>>> Regards,
>>>
>>> On Fri, Sep 24, 2010 at 11:54 AM, steven bluez <steven.bluez@gmail.com> wrote:
>>>> Hi all,
>>>> Is there any support for Device ID Profile in Bluez 4.XX? versions ?\
>>>>
>>>> Regards,
>>>> Steven
>>>> --
>>>> 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
>>>>
>>>
>>>
>>>
>>> --
>>> Luiz Augusto von Dentz
>>> Computer Engineer
>>> --
>>> 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] Bluetooth: Support SCO over HCI for Atheros AR300x Bluetooth device
From: Gustavo F. Padovan @ 2011-02-02 16:16 UTC (permalink / raw)
To: Suraj Sumangala; +Cc: linux-bluetooth, Jothikumar.Mothilal
In-Reply-To: <1296211744-2487-1-git-send-email-suraj@atheros.com>
Hi Suraj,
* Suraj Sumangala <suraj@atheros.com> [2011-01-28 16:19:04 +0530]:
> This patch adds SCO over HCI support to Atheros AR300x HCI transport
> driver.
>
> Signed-off-by: Suraj Sumangala <suraj@atheros.com>
> ---
> drivers/bluetooth/hci_ath.c | 18 +++++++++---------
> 1 files changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c
> index 6a160c1..161bd20 100644
> --- a/drivers/bluetooth/hci_ath.c
> +++ b/drivers/bluetooth/hci_ath.c
> @@ -162,11 +162,6 @@ static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb)
> {
> struct ath_struct *ath = hu->priv;
>
> - if (bt_cb(skb)->pkt_type == HCI_SCODATA_PKT) {
> - kfree_skb(skb);
> - return 0;
> - }
> -
> /*
> * Update power management enable flag with parameters of
> * HCI sleep enable vendor specific HCI command.
> @@ -183,10 +178,15 @@ static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb)
> /* Prepend skb with frame type */
> memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
>
> - skb_queue_tail(&ath->txq, skb);
> - set_bit(HCI_UART_SENDING, &hu->tx_state);
> -
> - schedule_work(&ath->ctxtsw);
> + if (bt_cb(skb)->pkt_type == HCI_SCODATA_PKT) {
> + skb_queue_head(&ath->txq, skb);
> + clear_bit(HCI_UART_SENDING, &hu->tx_state);
> + hci_uart_tx_wakeup(hu);
Seems you are giving priority to SCO packets, right? why?
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: [RFC] Bluetooth: process received S-frames when socket is locked by user process
From: Gustavo F. Padovan @ 2011-02-02 16:28 UTC (permalink / raw)
To: Suraj Sumangala; +Cc: linux-bluetooth, Jothikumar.Mothilal
In-Reply-To: <1296479571-2971-1-git-send-email-suraj@atheros.com>
Hi Suraj,
* Suraj Sumangala <suraj@atheros.com> [2011-01-31 18:42:51 +0530]:
> This patch lets L2CAP process received S-frames even when socket is
> continuously being locked by user process.
>
> This issue was seen when testing with l2test without using "-D" option.
>
> Since the user process does not expect any Rx packets,
> it hogs the socket with continuous call to "send()".
>
> When the TxWindow is full Tx stops untill the I-frames are acked by the receiver.
>
> But the Rx S-Frame acknowleding the Tx frames will stay in the backlog queue
> because the "sock_owned_by_user()" call in l2cap_data_channel()
> will always return true.
>
> The user process does not have an idea about this
> mechanism and keep pumping data and locking the socket and cause a deadlock.
In which kernel are you seeing this error? I think it is already fixed.
Regards,
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: [PATCH] Bluetooth: Support SCO over HCI for Atheros AR300x Bluetooth device
From: Suraj Sumangala @ 2011-02-02 16:31 UTC (permalink / raw)
To: Gustavo F. Padovan
Cc: Suraj Sumangala, linux-bluetooth@vger.kernel.org,
Jothikumar Mothilal
In-Reply-To: <20110202161641.GC2273@joana>
Hi Gustavo,
On 2/2/2011 9:46 PM, Gustavo F. Padovan wrote:
> Hi Suraj,
>
> * Suraj Sumangala<suraj@atheros.com> [2011-01-28 16:19:04 +0530]:
>
>> This patch adds SCO over HCI support to Atheros AR300x HCI transport
>> driver.
>>
>> Signed-off-by: Suraj Sumangala<suraj@atheros.com>
>> ---
>> drivers/bluetooth/hci_ath.c | 18 +++++++++---------
>> 1 files changed, 9 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c
>> index 6a160c1..161bd20 100644
>> --- a/drivers/bluetooth/hci_ath.c
>> +++ b/drivers/bluetooth/hci_ath.c
>> @@ -162,11 +162,6 @@ static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb)
>> {
>> struct ath_struct *ath = hu->priv;
>>
>> - if (bt_cb(skb)->pkt_type == HCI_SCODATA_PKT) {
>> - kfree_skb(skb);
>> - return 0;
>> - }
>> -
>> /*
>> * Update power management enable flag with parameters of
>> * HCI sleep enable vendor specific HCI command.
>> @@ -183,10 +178,15 @@ static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb)
>> /* Prepend skb with frame type */
>> memcpy(skb_push(skb, 1),&bt_cb(skb)->pkt_type, 1);
>>
>> - skb_queue_tail(&ath->txq, skb);
>> - set_bit(HCI_UART_SENDING,&hu->tx_state);
>> -
>> - schedule_work(&ath->ctxtsw);
>> + if (bt_cb(skb)->pkt_type == HCI_SCODATA_PKT) {
>> + skb_queue_head(&ath->txq, skb);
>> + clear_bit(HCI_UART_SENDING,&hu->tx_state);
>> + hci_uart_tx_wakeup(hu);
>
> Seems you are giving priority to SCO packets, right? why?
>
Yes, There was some degradation in audio quality which improved when we
gave priority to SCO.
Do you see any potential problem with that? I will re-verify this anyway.
Regards
Suraj
^ permalink raw reply
* Re: [RFC] Bluetooth: process received S-frames when socket is locked by user process
From: Suraj Sumangala @ 2011-02-02 16:34 UTC (permalink / raw)
To: Gustavo F. Padovan
Cc: Suraj Sumangala, linux-bluetooth@vger.kernel.org,
Jothikumar Mothilal
In-Reply-To: <20110202162818.GD2273@joana>
Hi Gustavo,
On 2/2/2011 9:58 PM, Gustavo F. Padovan wrote:
> Hi Suraj,
>
> * Suraj Sumangala<suraj@atheros.com> [2011-01-31 18:42:51 +0530]:
>
>> This patch lets L2CAP process received S-frames even when socket is
>> continuously being locked by user process.
>>
>> This issue was seen when testing with l2test without using "-D" option.
>>
>> Since the user process does not expect any Rx packets,
>> it hogs the socket with continuous call to "send()".
>>
>> When the TxWindow is full Tx stops untill the I-frames are acked by the receiver.
>>
>> But the Rx S-Frame acknowleding the Tx frames will stay in the backlog queue
>> because the "sock_owned_by_user()" call in l2cap_data_channel()
>> will always return true.
>>
>> The user process does not have an idea about this
>> mechanism and keep pumping data and locking the socket and cause a deadlock.
>
> In which kernel are you seeing this error? I think it is already fixed.
>
> Regards,
>
Can you direct me to the patch which fixed it?
I had see this problem when verifying Bluetooth 3.0 in kernel version
2.6.35 and see similar code in the kernel-next tree. That is the reason
why I sent an RFC.
Regards
Suraj
^ permalink raw reply
* Re: [RFC] Bluetooth: process received S-frames when socket is locked by user process
From: Gustavo F. Padovan @ 2011-02-02 16:51 UTC (permalink / raw)
To: Suraj Sumangala
Cc: Suraj Sumangala, linux-bluetooth@vger.kernel.org,
Jothikumar Mothilal
In-Reply-To: <4D49879F.8020000@Atheros.com>
Hi Suraj,
* Suraj Sumangala <suraj@Atheros.com> [2011-02-02 22:04:39 +0530]:
> Hi Gustavo,
>
> On 2/2/2011 9:58 PM, Gustavo F. Padovan wrote:
> > Hi Suraj,
> >
> > * Suraj Sumangala<suraj@atheros.com> [2011-01-31 18:42:51 +0530]:
> >
> >> This patch lets L2CAP process received S-frames even when socket is
> >> continuously being locked by user process.
> >>
> >> This issue was seen when testing with l2test without using "-D" option.
> >>
> >> Since the user process does not expect any Rx packets,
> >> it hogs the socket with continuous call to "send()".
> >>
> >> When the TxWindow is full Tx stops untill the I-frames are acked by the receiver.
> >>
> >> But the Rx S-Frame acknowleding the Tx frames will stay in the backlog queue
> >> because the "sock_owned_by_user()" call in l2cap_data_channel()
> >> will always return true.
> >>
> >> The user process does not have an idea about this
> >> mechanism and keep pumping data and locking the socket and cause a deadlock.
> >
> > In which kernel are you seeing this error? I think it is already fixed.
> >
> > Regards,
> >
>
> Can you direct me to the patch which fixed it?
This one: e454c844644683571617896ab2a4ce0109c1943e
The issue fixed by this patch is very similar to what you reported.
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: [RFC] Bluetooth: process received S-frames when socket is locked by user process
From: Suraj Sumangala @ 2011-02-02 17:35 UTC (permalink / raw)
To: Gustavo F. Padovan
Cc: Suraj Sumangala, linux-bluetooth@vger.kernel.org,
Jothikumar Mothilal
In-Reply-To: <20110202165112.GG2273@joana>
Hi Gustavo,
On 2/2/2011 10:21 PM, Gustavo F. Padovan wrote:
> This one: e454c844644683571617896ab2a4ce0109c1943e
>
> The issue fixed by this patch is very similar to what you reported
Is this commit available in
"git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-next-2.6.git"
tree?
Sorry, could not find it there.
Regards
Suraj
^ permalink raw reply
* Re: [RFC] Bluetooth: process received S-frames when socket is locked by user process
From: Gustavo F. Padovan @ 2011-02-02 17:41 UTC (permalink / raw)
To: Suraj Sumangala
Cc: Suraj Sumangala, linux-bluetooth@vger.kernel.org,
Jothikumar Mothilal
In-Reply-To: <4D4995D7.6070408@Atheros.com>
Hi Suraj,
* Suraj Sumangala <suraj@Atheros.com> [2011-02-02 23:05:19 +0530]:
> Hi Gustavo,
>
> On 2/2/2011 10:21 PM, Gustavo F. Padovan wrote:
> > This one: e454c844644683571617896ab2a4ce0109c1943e
> >
> > The issue fixed by this patch is very similar to what you reported
>
> Is this commit available in
> "git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-next-2.6.git"
> tree?
Yes, it is also available in Linus' tree.
commit e454c844644683571617896ab2a4ce0109c1943e
Author: Gustavo F. Padovan <padovan@profusion.mobi>
Date: Tue Sep 21 16:31:11 2010 -0300
Bluetooth: Fix deadlock in the ERTM logic
The Enhanced Retransmission Mode(ERTM) is a realiable mode of operation
of the Bluetooth L2CAP layer. Think on it like a simplified version of
TCP.
The problem we were facing here was a deadlock. ERTM uses a backlog
queue to queue incomimg packets while the user is helding the lock. At
some moment the sk_sndbuf can be exceeded and we can't alloc new skbs
then the code sleep with the lock to wait for memory, that stalls the
ERTM connection once we can't read the acknowledgements packets in the
backlog queue to free memory and make the allocation of outcoming skb
successful.
successful.
This patch actually affect all users of bt_skb_send_alloc(), i.e., all
L2CAP modes and SCO.
We are safe against socket states changes or channels deletion while the
we are sleeping wait memory. Checking for the sk->sk_err and
sk->sk_shutdown make the code safe, since any action that can leave the
socket or the channel in a not usable state set one of the struct
members at least. Then we can check both of them when getting the lock
again and return with the proper error if something unexpected happens.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Signed-off-by: Ulisses Furquim <ulisses@profusion.mobi>
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: [PATCH 3/3 v2] Use libtracker-sparql in PBAP
From: Vinicius Costa Gomes @ 2011-02-02 18:15 UTC (permalink / raw)
To: Radoslaw Jablonski; +Cc: linux-bluetooth
In-Reply-To: <1296642108-14063-3-git-send-email-ext-jablonski.radoslaw@nokia.com>
Hi Radoslaw,
On 12:21 Wed 02 Feb, Radoslaw Jablonski wrote:
> Now direct tracker connection for transporting retrieved
> parts of data is used, instead of D-Bus. This should result better
> performance for PBAP requests.
> Each part of results is now fetched from tracker asynchronously
> and getting more results can be stopped in any moment -
> GCancellable stored in phonebook_data is used for that purpose.
> If processing of data has finished (or it was cancelled) then cleanup
> of pending_reply is done in last invocation of
> async_query_cursor_next_cb.
> ---
> plugins/phonebook-tracker.c | 271 +++++++++++++++++++++++--------------------
> 1 files changed, 147 insertions(+), 124 deletions(-)
>
> diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
> index 3b61d6b..79bc1c6 100644
> --- a/plugins/phonebook-tracker.c
> +++ b/plugins/phonebook-tracker.c
> @@ -29,6 +29,7 @@
> #include <dbus/dbus.h>
> #include <openobex/obex.h>
> #include <openobex/obex_const.h>
> +#include <libtracker-sparql/tracker-sparql.h>
>
> #include "log.h"
> #include "obex.h"
> @@ -891,7 +892,7 @@
> "} GROUP BY ?call ORDER BY DESC(nmo:receivedDate(?call)) " \
> "LIMIT 40"
>
> -typedef void (*reply_list_foreach_t) (char **reply, int num_fields,
> +typedef void (*reply_list_foreach_t) (const char **reply, int num_fields,
> void *user_data);
>
> typedef void (*add_field_t) (struct phonebook_contact *contact,
> @@ -918,7 +919,7 @@ struct phonebook_data {
> phonebook_cache_ready_cb ready_cb;
> phonebook_entry_cb entry_cb;
> int newmissedcalls;
> - DBusPendingCall *call;
> + GCancellable *query_canc;
> };
>
> struct phonebook_index {
> @@ -926,7 +927,7 @@ struct phonebook_index {
> int index;
> };
>
> -static DBusConnection *connection = NULL;
> +static TrackerSparqlConnection *connection = NULL;
>
> static const char *name2query(const char *name)
> {
> @@ -999,131 +1000,139 @@ static const char *folder2query(const char *folder)
> return NULL;
> }
>
> -static char **string_array_from_iter(DBusMessageIter iter, int array_len)
> +static const char **string_array_from_cursor(TrackerSparqlCursor *cursor,
> + int array_len)
> {
> - DBusMessageIter sub;
> - char **result;
> + const char **result;
> int i;
>
> - if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
> - return NULL;
> -
> - result = g_new0(char *, array_len);
> -
> - dbus_message_iter_recurse(&iter, &sub);
> -
> - i = 0;
> - while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
> - char *arg;
> + result = g_new0(const char *, array_len);
>
> - if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) {
> - g_free(result);
> - return NULL;
> - }
> -
> - dbus_message_iter_get_basic(&sub, &arg);
> + for (i = 0; i < array_len; ++i) {
> + TrackerSparqlValueType type;
>
> - result[i] = arg;
> + type = tracker_sparql_cursor_get_value_type(cursor, i);
>
> - i++;
> - dbus_message_iter_next(&sub);
> + if (type == TRACKER_SPARQL_VALUE_TYPE_BLANK_NODE ||
> + type == TRACKER_SPARQL_VALUE_TYPE_UNBOUND)
> + /* For null/unbound type filling result part with ""*/
> + result[i] = "";
> + else
> + /* Filling with string representation of content*/
> + result[i] = tracker_sparql_cursor_get_string(cursor, i,
> + NULL);
> }
>
> return result;
> }
>
> -static void query_reply(DBusPendingCall *call, void *user_data)
> +
Extra empty line here.
> +static void query_free_data(void *user_data)
> {
> - DBusMessage *reply = dbus_pending_call_steal_reply(call);
> + DBG("");
This statement should go after the declarations.
> struct pending_reply *pending = user_data;
> - DBusMessageIter iter, element;
> - DBusError derr;
> - int err;
> -
> - dbus_error_init(&derr);
> - if (dbus_set_error_from_message(&derr, reply)) {
> - error("Replied with an error: %s, %s", derr.name,
> - derr.message);
> - dbus_error_free(&derr);
> -
> - err = -1;
> - goto done;
> - }
> -
> - dbus_message_iter_init(reply, &iter);
> -
> - if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
> - error("SparqlQuery reply is not an array");
>
> - err = -1;
> - goto done;
> - }
> -
> - dbus_message_iter_recurse(&iter, &element);
> -
> - err = 0;
> + if (!pending)
> + return;
g_free() already deals with the case where the pointer is NULL, so I don't see
much point in having this function.
>
> - while (dbus_message_iter_get_arg_type(&element) != DBUS_TYPE_INVALID) {
> - char **node;
> + g_free(pending);
> +}
>
> - if (dbus_message_iter_get_arg_type(&element) !=
> - DBUS_TYPE_ARRAY) {
> - error("element is not an array");
> - goto done;
> - }
> +static void update_cancellable(struct phonebook_data *pdata,
> + GCancellable *canc)
> +{
> + if (pdata->query_canc)
> + g_object_unref(pdata->query_canc);
>
> - node = string_array_from_iter(element, pending->num_fields);
> - pending->callback(node, pending->num_fields,
> - pending->user_data);
> + pdata->query_canc = canc;
> +}
>
> - g_free(node);
> +static void async_query_cursor_next_cb(GObject *source, GAsyncResult *result,
> + gpointer user_data)
> +{
> + struct pending_reply *pending = user_data;
> + TrackerSparqlCursor *cursor = TRACKER_SPARQL_CURSOR (source);
Extra space before "(".
> + GCancellable *cancellable;
> + GError *error = NULL;
> + gboolean success;
> + const char **node;
> +
> + success = tracker_sparql_cursor_next_finish(
> + TRACKER_SPARQL_CURSOR (source),
Same here.
> + result,
> + &error);
Perhaps putting these two in the same line?
> +
> + if (!success) {
> + if (error) {
> + DBG("cursor_next error: %s", error->message);
> + g_error_free(error);
> + } else
> + /* When tracker_sparql_cursor_next_finish ends with
> + * failure and no error is set, that means end of
> + * results returned by query */
> + pending->callback(NULL, 0, pending->user_data);
>
> - dbus_message_iter_next(&element);
> + goto failed;
> }
>
> -done:
> - /* This is the last entry */
> - pending->callback(NULL, err, pending->user_data);
> + node = string_array_from_cursor(cursor, pending->num_fields);
> + pending->callback(node, pending->num_fields, pending->user_data);
> + g_free(node);
>
> - dbus_message_unref(reply);
>
> - /* pending data is freed in query_free_data after call is unreffed. */
> -}
> -
> -static void query_free_data(void *user_data)
> -{
> - struct pending_reply *pending = user_data;
> -
> - if (!pending)
> - return;
> + /* getting next row from query results */
> + cancellable = g_cancellable_new();
> + update_cancellable(pending->user_data, cancellable);
> + tracker_sparql_cursor_next_async(cursor, cancellable,
> + async_query_cursor_next_cb,
> + pending);
> + return;
>
> - g_free(pending);
> +failed:
> + g_object_unref(cursor);
> + query_free_data(pending);
> }
>
> -static DBusPendingCall *query_tracker(const char *query, int num_fields,
> - reply_list_foreach_t callback, void *user_data, int *err)
> +static void query_tracker(const char *query, int num_fields,
> + reply_list_foreach_t callback, void *user_data,
> + int *err)
> +
Extra empty line here.
> {
> struct pending_reply *pending;
> - DBusPendingCall *call;
> - DBusMessage *msg;
> + GCancellable *cancellable;
> + TrackerSparqlCursor *cursor;
> + GError *error = NULL;
> +
> + DBG("");
>
> if (connection == NULL)
> - connection = obex_dbus_get_connection();
> + connection = tracker_sparql_connection_get_direct(
> + NULL, &error);
>
> - msg = dbus_message_new_method_call(TRACKER_SERVICE,
> - TRACKER_RESOURCES_PATH, TRACKER_RESOURCES_INTERFACE,
> - "SparqlQuery");
> + if (!connection) {
> + if (error) {
> + DBG("direct-connection error: %s", error->message);
> + g_error_free(error);
> + }
>
> - dbus_message_append_args(msg, DBUS_TYPE_STRING, &query,
> - DBUS_TYPE_INVALID);
> + goto failed;
> + }
>
> - if (dbus_connection_send_with_reply(connection, msg, &call,
> - -1) == FALSE) {
> - error("Could not send dbus message");
> - dbus_message_unref(msg);
> - if (err)
> - *err = -EPERM;
> - return NULL;
> + cancellable = g_cancellable_new();
> + update_cancellable(user_data, cancellable);
> + cursor = tracker_sparql_connection_query(connection, query,
> + cancellable, &error);
> +
> + if (cursor == NULL) {
> + if (error) {
> + DBG("connection_query error: %s", error->message);
> + g_error_free(error);
> + }
> +
> + g_object_unref(cancellable);
> + g_object_unref(cursor);
This looks strange, calling unref on a NULL pointer.
> +
> + goto failed;
> }
>
> pending = g_new0(struct pending_reply, 1);
> @@ -1131,14 +1140,21 @@ static DBusPendingCall *query_tracker(const char *query, int num_fields,
> pending->user_data = user_data;
> pending->num_fields = num_fields;
>
> - dbus_pending_call_set_notify(call, query_reply, pending,
> - query_free_data);
> - dbus_message_unref(msg);
> + /* Now asynchronously going through each row of results - callback
> + * async_query_cursor_next_cb will be called ALWAYS, even if async
> + * request was canceled */
> + tracker_sparql_cursor_next_async(cursor, cancellable,
> + async_query_cursor_next_cb,
> + pending);
>
> if (err)
> *err = 0;
>
> - return call;
> + return;
> +
> +failed:
> + if (err)
> + *err = -EPERM;
> }
>
> static char *iso8601_utc_to_localtime(const char *datetime)
> @@ -1331,7 +1347,8 @@ static GString *gen_vcards(GSList *contacts,
> return vcards;
> }
>
> -static void pull_contacts_size(char **reply, int num_fields, void *user_data)
> +static void pull_contacts_size(const char **reply, int num_fields,
> + void *user_data)
> {
> struct phonebook_data *data = user_data;
>
> @@ -1363,7 +1380,8 @@ static void add_affiliation(char **field, const char *value)
> *field = g_strdup(value);
> }
>
> -static void contact_init(struct phonebook_contact *contact, char **reply)
> +static void contact_init(struct phonebook_contact *contact,
> + const char **reply)
> {
>
> contact->fullname = g_strdup(reply[COL_FULL_NAME]);
> @@ -1395,8 +1413,8 @@ static enum phonebook_number_type get_phone_type(const char *affilation)
> return TEL_TYPE_OTHER;
> }
>
> -static void add_aff_number(struct phonebook_contact *contact, char *pnumber,
> - char *aff_type)
> +static void add_aff_number(struct phonebook_contact *contact,
> + const char *pnumber, const char *aff_type)
> {
> char **num_parts;
> char *type, *number;
> @@ -1433,7 +1451,7 @@ failed:
> }
>
> static void contact_add_numbers(struct phonebook_contact *contact,
> - char **reply)
> + const char **reply)
> {
> char **aff_numbers;
> int i;
> @@ -1459,8 +1477,8 @@ static enum phonebook_field_type get_field_type(const char *affilation)
> return FIELD_TYPE_OTHER;
> }
>
> -static void add_aff_field(struct phonebook_contact *contact, char *aff_email,
> - add_field_t add_field_cb)
> +static void add_aff_field(struct phonebook_contact *contact,
> + const char *aff_email, add_field_t add_field_cb)
> {
> char **email_parts;
> char *type, *email;
> @@ -1490,7 +1508,7 @@ failed:
> }
>
> static void contact_add_emails(struct phonebook_contact *contact,
> - char **reply)
> + const char **reply)
> {
> char **aff_emails;
> int i;
> @@ -1506,7 +1524,7 @@ static void contact_add_emails(struct phonebook_contact *contact,
> }
>
> static void contact_add_addresses(struct phonebook_contact *contact,
> - char **reply)
> + const char **reply)
> {
> char **aff_addr;
> int i;
> @@ -1522,7 +1540,8 @@ static void contact_add_addresses(struct phonebook_contact *contact,
> g_strfreev(aff_addr);
> }
>
> -static void contact_add_urls(struct phonebook_contact *contact, char **reply)
> +static void contact_add_urls(struct phonebook_contact *contact,
> + const char **reply)
> {
> char **aff_url;
> int i;
> @@ -1538,7 +1557,7 @@ static void contact_add_urls(struct phonebook_contact *contact, char **reply)
> }
>
> static void contact_add_organization(struct phonebook_contact *contact,
> - char **reply)
> + const char **reply)
> {
> /* Adding fields connected by nco:hasAffiliation - they may be in
> * separate replies */
> @@ -1548,7 +1567,7 @@ static void contact_add_organization(struct phonebook_contact *contact,
> add_affiliation(&contact->role, reply[COL_ORG_ROLE]);
> }
>
> -static void pull_contacts(char **reply, int num_fields, void *user_data)
> +static void pull_contacts(const char **reply, int num_fields, void *user_data)
> {
> struct phonebook_data *data = user_data;
> const struct apparam_field *params = data->params;
> @@ -1649,7 +1668,7 @@ fail:
> */
> }
>
> -static void add_to_cache(char **reply, int num_fields, void *user_data)
> +static void add_to_cache(const char **reply, int num_fields, void *user_data)
> {
> struct phonebook_data *data = user_data;
> char *formatted;
> @@ -1699,6 +1718,9 @@ done:
>
> int phonebook_init(void)
> {
> + g_thread_init(NULL);
> + g_type_init();
> +
> return 0;
> }
>
> @@ -1792,12 +1814,13 @@ void phonebook_req_finalize(void *request)
> if (!data)
> return;
>
> - if (!dbus_pending_call_get_completed(data->call))
> - dbus_pending_call_cancel(data->call);
> -
> - dbus_pending_call_unref(data->call);
> + /* canceling asynchronous operation on tracker if any is active */
> + if (data->query_canc) {
> + g_cancellable_cancel(data->query_canc);
> + g_object_unref(data->query_canc);
> + }
>
> - /* freeing list of contacts used for generating vcards */
> + /* freeing contacts */
> for (l = data->contacts; l; l = l->next) {
> struct contact_data *c_data = l->data;
>
> @@ -1828,7 +1851,8 @@ static void gstring_free_helper(gpointer data, gpointer user_data)
> g_string_free(data, TRUE);
> }
>
> -static void pull_newmissedcalls(char **reply, int num_fields, void *user_data)
> +static void pull_newmissedcalls(const char **reply, int num_fields,
> + void *user_data)
> {
> struct phonebook_data *data = user_data;
> reply_list_foreach_t pull_cb;
> @@ -1870,8 +1894,7 @@ done:
> pull_cb = pull_contacts;
> }
>
> - dbus_pending_call_unref(data->call);
> - data->call = query_tracker(query, col_amount, pull_cb, data, &err);
> + query_tracker(query, col_amount, pull_cb, data, &err);
> if (err < 0)
> data->cb(NULL, 0, err, 0, data->user_data);
> }
> @@ -1910,7 +1933,7 @@ void *phonebook_pull(const char *name, const struct apparam_field *params,
> data->params = params;
> data->user_data = user_data;
> data->cb = cb;
> - data->call = query_tracker(query, col_amount, pull_cb, data, err);
> + query_tracker(query, col_amount, pull_cb, data, err);
>
> return data;
> }
> @@ -1938,8 +1961,8 @@ void *phonebook_get_entry(const char *folder, const char *id,
> query = g_strdup_printf(CONTACTS_OTHER_QUERY_FROM_URI,
> id, id, id);
>
> - data->call = query_tracker(query, PULL_QUERY_COL_AMOUNT, pull_contacts,
> - data, err);
> + query_tracker(query, PULL_QUERY_COL_AMOUNT,
> + pull_contacts, data, err);
>
> g_free(query);
>
> @@ -1965,7 +1988,7 @@ void *phonebook_create_cache(const char *name, phonebook_entry_cb entry_cb,
> data->entry_cb = entry_cb;
> data->ready_cb = ready_cb;
> data->user_data = user_data;
> - data->call = query_tracker(query, 7, add_to_cache, data, err);
> + query_tracker(query, 7, add_to_cache, data, err);
>
> return data;
> }
> --
> 1.7.0.4
>
> --
> 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
Cheers,
--
Vinicius
^ permalink raw reply
* Re: [PATCH 2/6 v2] Add an interactive mode to gatttool
From: Sheldon Demario @ 2011-02-02 18:53 UTC (permalink / raw)
To: Sheldon Demario, linux-bluetooth
In-Reply-To: <20110201090352.GA5278@jh-x301>
On Tue, Feb 1, 2011 at 6:03 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> On Mon, Jan 31, 2011, Sheldon Demario wrote:
>> +static gboolean cmd_connect(gpointer cmd)
>> +{
>> + const char **c = (const char **) cmd;
>> + if (conn_state != STATE_DISCONNECTED)
>
> Missing line after the variable declaration and unnecessary explicit
> type-cast (no need for void pointers). However why does this function
> take a gpointer to begin with? I'd imagine the most convenient thing to
> give the command handlers either a char* with the entire command line or
> a pre-parsed argc + argv with the help of g_shell_parse_argv.
I am trying to avoid duplicate the callbacks already used on
gatttool. The callbacks called from command line and those called from
interactive prompt are the same, that's why they use gpointer as
parameter.
>
>> + if (c[1] != NULL) {
>
> Now that's just ugly. Much better if you use g_shell_parse_argv and then
> you can use the usual getopt to separate switches from mandatory
> parameters, etc.
Using the usual getopt means that the user will type "-" in each
parameter? It seems bad for a interactive prompt.
I agree with you that this is a ugly line, but is the simpler way to
do that without create another callback to do the same thing that in
"non interactive" mode.
>
>> +static struct {
>> + char *cmd;
>
> I suppose this should be const char *
>
>> + gboolean (*func)(gpointer cmd);
>
> As I mentioned, instead of gpointer do char * or then (what I'd prefer)
> simply argc + argv.
>
>> + char *param;
>
> Again, const
>
>> + char *desc;
>
> Same here.
>
>> +} commands[] = {
>> + { "connect", cmd_connect, "<bdaddr>", "Connect"},
>> + { "disconnect", cmd_disconnect, NULL, "Disconnect"},
>> + { "characteristics", characteristics, NULL,
>> + "Characteristcs Discovery"},
>> + { NULL, NULL, NULL, NULL}
>> +};
>
> Where's the "help" command? That's the first one I'd expect to be
> implemented. Also, ctrl-d and "exit" should work from the start as ways
> of exiting the program.
>
>> +static void parse_line(char *line_read)
>> +{
>> + char **command;
>> + int j;
>
> Why j and not i?
>
>> +static int do_interactive(void)
>
> Didn't I tell you to do all the interactive stuff away from the main
> gatttool.c file? There should only be the parsing of command line
> parameters and a call to the interactive .c file in the case of
> interactive mode.
The approach will be similar to the first suggestion sent to the ML,
except the binary that it will be only one. I gonna split the
functions based on your comments and see if we reach a consensus
between code re-use and cleanness.
Sheldon.
>
> Johan
>
^ permalink raw reply
* [PATCH] Changing required GLIB version in acinclude.m4
From: ankushbansal89 @ 2011-02-02 20:04 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ankush Bansal
From: Ankush Bansal <ankushbansal89@gmail.com>
---
acinclude.m4 | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/acinclude.m4 b/acinclude.m4
index ecf4b4b..9d3f6b2 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -108,8 +108,8 @@ AC_DEFUN([AC_PATH_DBUS], [
])
AC_DEFUN([AC_PATH_GLIB], [
- PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.14, dummy=yes,
- AC_MSG_ERROR(GLib library version 2.14 or later is required))
+ PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes,
+ AC_MSG_ERROR(GLib library version 2.16 or later is required))
AC_SUBST(GLIB_CFLAGS)
AC_SUBST(GLIB_LIBS)
])
--
1.7.1
^ permalink raw reply related
* Re: [PATCH] linux-firmware: Remove ath3k-2.fw
From: Bala Shanmugam @ 2011-02-03 6:28 UTC (permalink / raw)
To: dwmw2@infradead.org
Cc: linux-bluetooth@vger.kernel.org, jkumar, Luis Rodriguez
In-Reply-To: <1296207208-4465-1-git-send-email-sbalashanmugam@atheros.com>
On 1/28/2011 3:03 PM, Shanmugamkamatchi Balashanmugam wrote:
> ath3k-2.fw is obsolete and not use by Atheros chipsets
> anymore.
>
> Signed-off-by: Bala Shanmugam<sbalashanmugam@atheros.com>
> ---
> WHENCE | 9 ---------
> ath3k-2.fw | Bin 246804 -> 0 bytes
> 2 files changed, 0 insertions(+), 9 deletions(-)
> delete mode 100644 ath3k-2.fw
>
> diff --git a/WHENCE b/WHENCE
> index 1cbd0a6..c022b4a 100644
> --- a/WHENCE
> +++ b/WHENCE
> @@ -1306,15 +1306,6 @@ Licence: Redistributable, provided by Realtek in their driver
>
> --------------------------------------------------------------------------
>
> -Driver: DFU Driver for Atheros bluetooth chipset AR3011
> -
> -File: ath3k-2.fw
> -Info: v2.0
> -
> -Licence: Redistributable. See LICENCE.atheros_firmware for details
> -
> ---------------------------------------------------------------------------
> -
> Driver: lgs8gxx - Legend Silicon GB20600 demodulator driver
>
> File: lgs8g75.fw
> diff --git a/ath3k-2.fw b/ath3k-2.fw
> deleted file mode 100644
> index 3fa8cff36301a7005936d54a407d6879923aa354..0000000000000000000000000000000000000000
> GIT binary patch
> literal 0
> HcmV?d00001
>
> literal 246804
>
Hi David,
Can you please upload this patch sent before.
Regards,
Bala.
^ permalink raw reply
* Re: [RFC] Bluetooth: process received S-frames when socket is locked by user process
From: Suraj Sumangala @ 2011-02-03 6:50 UTC (permalink / raw)
To: Gustavo F. Padovan
Cc: Suraj Sumangala, linux-bluetooth@vger.kernel.org,
Jothikumar Mothilal
In-Reply-To: <20110202174114.GI2273@joana>
Hi Gustavo,
On 2/2/2011 11:11 PM, Gustavo F. Padovan wrote:
> Hi Suraj,
>
> * Suraj Sumangala<suraj@Atheros.com> [2011-02-02 23:05:19 +0530]:
>
>> Hi Gustavo,
>>
>> On 2/2/2011 10:21 PM, Gustavo F. Padovan wrote:
>>> This one: e454c844644683571617896ab2a4ce0109c1943e
>>>
>>> The issue fixed by this patch is very similar to what you reported
>>
>> Is this commit available in
>> "git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-next-2.6.git"
>> tree?
>
> Yes, it is also available in Linus' tree.
>
> commit e454c844644683571617896ab2a4ce0109c1943e
> Author: Gustavo F. Padovan<padovan@profusion.mobi>
> Date: Tue Sep 21 16:31:11 2010 -0300
>
> Bluetooth: Fix deadlock in the ERTM logic
>
> The Enhanced Retransmission Mode(ERTM) is a realiable mode of operation
> of the Bluetooth L2CAP layer. Think on it like a simplified version of
> TCP.
> The problem we were facing here was a deadlock. ERTM uses a backlog
> queue to queue incomimg packets while the user is helding the lock. At
> some moment the sk_sndbuf can be exceeded and we can't alloc new skbs
> then the code sleep with the lock to wait for memory, that stalls the
> ERTM connection once we can't read the acknowledgements packets in the
> backlog queue to free memory and make the allocation of outcoming skb
> successful.
> successful.
>
> This patch actually affect all users of bt_skb_send_alloc(), i.e., all
> L2CAP modes and SCO.
>
> We are safe against socket states changes or channels deletion while the
> we are sleeping wait memory. Checking for the sk->sk_err and
> sk->sk_shutdown make the code safe, since any action that can leave the
> socket or the channel in a not usable state set one of the struct
> members at least. Then we can check both of them when getting the lock
> again and return with the proper error if something unexpected happens.
>
> Signed-off-by: Gustavo F. Padovan<padovan@profusion.mobi>
> Signed-off-by: Ulisses Furquim<ulisses@profusion.mobi>
>
>
>
Thanks,this patch solved my issue.
Regards
Suraj
^ permalink raw reply
* Re: [PATCH] linux-firmware: Remove ath3k-2.fw
From: David Woodhouse @ 2011-02-03 7:43 UTC (permalink / raw)
To: Bala Shanmugam; +Cc: linux-bluetooth, Luis.Rodriguez
In-Reply-To: <1296207208-4465-1-git-send-email-sbalashanmugam@atheros.com>
On Fri, 2011-01-28 at 15:03 +0530, Bala Shanmugam wrote:
> ath3k-2.fw is obsolete and not use by Atheros chipsets
> anymore.
Are you telling me that there is no extant hardware, and no old kernels,
which would use this? It was added to the linux-firmware tree and
*never* used?
--
dwmw2
^ permalink raw reply
* Re: [PATCH] linux-firmware: Remove ath3k-2.fw
From: Bala Shanmugam @ 2011-02-03 8:01 UTC (permalink / raw)
To: David Woodhouse; +Cc: linux-bluetooth@vger.kernel.org, Luis Rodriguez
In-Reply-To: <1296719005.12863.28.camel@macbook.infradead.org>
On 2/3/2011 1:13 PM, David Woodhouse wrote:
> On Fri, 2011-01-28 at 15:03 +0530, Bala Shanmugam wrote:
>> ath3k-2.fw is obsolete and not use by Atheros chipsets
>> anymore.
> Are you telling me that there is no extant hardware, and no old kernels,
> which would use this? It was added to the linux-firmware tree and
> *never* used?
>
Yes David, no older kernel uses this firmware.
We thought to have new firmware file for newer versions but
our driver patch was not accepted and we decided to
have single firmware for this chipset [ath3k-1.fw].
Thanks and Regards,
Bala.
^ permalink raw reply
* [PATCH v3] Use libtracker-sparql in PBAP
From: Radoslaw Jablonski @ 2011-02-03 8:31 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Radoslaw Jablonski
Now direct tracker connection for transporting retrieved
parts of data is used, instead of D-Bus. This should result better
performance for PBAP requests.
Each part of results is now fetched from tracker asynchronously
and getting more results can be stopped in any moment -
GCancellable stored in phonebook_data is used for that purpose.
If processing of data has finished (or it was cancelled) then cleanup
of pending_reply is done in last invocation of
async_query_cursor_next_cb.
---
plugins/phonebook-tracker.c | 272 +++++++++++++++++++++++--------------------
1 files changed, 143 insertions(+), 129 deletions(-)
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index e60cf74..214961d 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -29,6 +29,7 @@
#include <dbus/dbus.h>
#include <openobex/obex.h>
#include <openobex/obex_const.h>
+#include <libtracker-sparql/tracker-sparql.h>
#include "log.h"
#include "obex.h"
@@ -891,7 +892,7 @@
"} GROUP BY ?call ORDER BY DESC(nmo:receivedDate(?call)) " \
"LIMIT 40"
-typedef void (*reply_list_foreach_t) (char **reply, int num_fields,
+typedef void (*reply_list_foreach_t) (const char **reply, int num_fields,
void *user_data);
typedef void (*add_field_t) (struct phonebook_contact *contact,
@@ -918,7 +919,7 @@ struct phonebook_data {
phonebook_cache_ready_cb ready_cb;
phonebook_entry_cb entry_cb;
int newmissedcalls;
- DBusPendingCall *call;
+ GCancellable *query_canc;
};
struct phonebook_index {
@@ -926,7 +927,7 @@ struct phonebook_index {
int index;
};
-static DBusConnection *connection = NULL;
+static TrackerSparqlConnection *connection = NULL;
static const char *name2query(const char *name)
{
@@ -999,131 +1000,124 @@ static const char *folder2query(const char *folder)
return NULL;
}
-static char **string_array_from_iter(DBusMessageIter iter, int array_len)
+static const char **string_array_from_cursor(TrackerSparqlCursor *cursor,
+ int array_len)
{
- DBusMessageIter sub;
- char **result;
+ const char **result;
int i;
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
- return NULL;
-
- result = g_new0(char *, array_len);
-
- dbus_message_iter_recurse(&iter, &sub);
+ result = g_new0(const char *, array_len);
- i = 0;
- while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
- char *arg;
-
- if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) {
- g_free(result);
- return NULL;
- }
+ for (i = 0; i < array_len; ++i) {
+ TrackerSparqlValueType type;
- dbus_message_iter_get_basic(&sub, &arg);
+ type = tracker_sparql_cursor_get_value_type(cursor, i);
- result[i] = arg;
-
- i++;
- dbus_message_iter_next(&sub);
+ if (type == TRACKER_SPARQL_VALUE_TYPE_BLANK_NODE ||
+ type == TRACKER_SPARQL_VALUE_TYPE_UNBOUND)
+ /* For null/unbound type filling result part with ""*/
+ result[i] = "";
+ else
+ /* Filling with string representation of content*/
+ result[i] = tracker_sparql_cursor_get_string(cursor, i,
+ NULL);
}
return result;
}
-static void query_reply(DBusPendingCall *call, void *user_data)
+static void update_cancellable(struct phonebook_data *pdata,
+ GCancellable *canc)
{
- DBusMessage *reply = dbus_pending_call_steal_reply(call);
- struct pending_reply *pending = user_data;
- DBusMessageIter iter, element;
- DBusError derr;
- int err;
-
- dbus_error_init(&derr);
- if (dbus_set_error_from_message(&derr, reply)) {
- error("Replied with an error: %s, %s", derr.name,
- derr.message);
- dbus_error_free(&derr);
-
- err = -1;
- goto done;
- }
-
- dbus_message_iter_init(reply, &iter);
-
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
- error("SparqlQuery reply is not an array");
-
- err = -1;
- goto done;
- }
+ if (pdata->query_canc)
+ g_object_unref(pdata->query_canc);
- dbus_message_iter_recurse(&iter, &element);
-
- err = 0;
-
- while (dbus_message_iter_get_arg_type(&element) != DBUS_TYPE_INVALID) {
- char **node;
-
- if (dbus_message_iter_get_arg_type(&element) !=
- DBUS_TYPE_ARRAY) {
- error("element is not an array");
- goto done;
- }
-
- node = string_array_from_iter(element, pending->num_fields);
- pending->callback(node, pending->num_fields,
- pending->user_data);
+ pdata->query_canc = canc;
+}
- g_free(node);
+static void async_query_cursor_next_cb(GObject *source, GAsyncResult *result,
+ gpointer user_data)
+{
+ struct pending_reply *pending = user_data;
+ TrackerSparqlCursor *cursor = TRACKER_SPARQL_CURSOR(source);
+ GCancellable *cancellable;
+ GError *error = NULL;
+ gboolean success;
+ const char **node;
+
+ success = tracker_sparql_cursor_next_finish(
+ TRACKER_SPARQL_CURSOR(source),
+ result, &error);
+
+ if (!success) {
+ if (error) {
+ DBG("cursor_next error: %s", error->message);
+ g_error_free(error);
+ } else
+ /* When tracker_sparql_cursor_next_finish ends with
+ * failure and no error is set, that means end of
+ * results returned by query */
+ pending->callback(NULL, 0, pending->user_data);
- dbus_message_iter_next(&element);
+ goto failed;
}
-done:
- /* This is the last entry */
- pending->callback(NULL, err, pending->user_data);
-
- dbus_message_unref(reply);
+ node = string_array_from_cursor(cursor, pending->num_fields);
+ pending->callback(node, pending->num_fields, pending->user_data);
+ g_free(node);
- /* pending data is freed in query_free_data after call is unreffed. */
-}
-
-static void query_free_data(void *user_data)
-{
- struct pending_reply *pending = user_data;
- if (!pending)
- return;
+ /* getting next row from query results */
+ cancellable = g_cancellable_new();
+ update_cancellable(pending->user_data, cancellable);
+ tracker_sparql_cursor_next_async(cursor, cancellable,
+ async_query_cursor_next_cb,
+ pending);
+ return;
+failed:
+ g_object_unref(cursor);
g_free(pending);
}
-static DBusPendingCall *query_tracker(const char *query, int num_fields,
- reply_list_foreach_t callback, void *user_data, int *err)
+static void query_tracker(const char *query, int num_fields,
+ reply_list_foreach_t callback, void *user_data,
+ int *err)
{
struct pending_reply *pending;
- DBusPendingCall *call;
- DBusMessage *msg;
+ GCancellable *cancellable;
+ TrackerSparqlCursor *cursor;
+ GError *error = NULL;
+
+ DBG("");
if (connection == NULL)
- connection = obex_dbus_get_connection();
+ connection = tracker_sparql_connection_get_direct(
+ NULL, &error);
+
+ if (!connection) {
+ if (error) {
+ DBG("direct-connection error: %s", error->message);
+ g_error_free(error);
+ }
+
+ goto failed;
+ }
- msg = dbus_message_new_method_call(TRACKER_SERVICE,
- TRACKER_RESOURCES_PATH, TRACKER_RESOURCES_INTERFACE,
- "SparqlQuery");
+ cancellable = g_cancellable_new();
+ update_cancellable(user_data, cancellable);
+ cursor = tracker_sparql_connection_query(connection, query,
+ cancellable, &error);
- dbus_message_append_args(msg, DBUS_TYPE_STRING, &query,
- DBUS_TYPE_INVALID);
+ if (cursor == NULL) {
+ if (error) {
+ DBG("connection_query error: %s", error->message);
+ g_error_free(error);
+ }
- if (dbus_connection_send_with_reply(connection, msg, &call,
- -1) == FALSE) {
- error("Could not send dbus message");
- dbus_message_unref(msg);
- if (err)
- *err = -EPERM;
- return NULL;
+ g_object_unref(cancellable);
+
+ goto failed;
}
pending = g_new0(struct pending_reply, 1);
@@ -1131,14 +1125,21 @@ static DBusPendingCall *query_tracker(const char *query, int num_fields,
pending->user_data = user_data;
pending->num_fields = num_fields;
- dbus_pending_call_set_notify(call, query_reply, pending,
- query_free_data);
- dbus_message_unref(msg);
+ /* Now asynchronously going through each row of results - callback
+ * async_query_cursor_next_cb will be called ALWAYS, even if async
+ * request was canceled */
+ tracker_sparql_cursor_next_async(cursor, cancellable,
+ async_query_cursor_next_cb,
+ pending);
if (err)
*err = 0;
- return call;
+ return;
+
+failed:
+ if (err)
+ *err = -EPERM;
}
static char *iso8601_utc_to_localtime(const char *datetime)
@@ -1326,16 +1327,13 @@ static GString *gen_vcards(GSList *contacts,
struct contact_data *c_data = l->data;
phonebook_add_contact(vcards, c_data->contact,
params->filter, params->format);
-
- g_free(c_data->id);
- phonebook_contact_free(c_data->contact);
- g_free(c_data);
}
return vcards;
}
-static void pull_contacts_size(char **reply, int num_fields, void *user_data)
+static void pull_contacts_size(const char **reply, int num_fields,
+ void *user_data)
{
struct phonebook_data *data = user_data;
@@ -1367,7 +1365,8 @@ static void add_affiliation(char **field, const char *value)
*field = g_strdup(value);
}
-static void contact_init(struct phonebook_contact *contact, char **reply)
+static void contact_init(struct phonebook_contact *contact,
+ const char **reply)
{
contact->fullname = g_strdup(reply[COL_FULL_NAME]);
@@ -1399,8 +1398,8 @@ static enum phonebook_number_type get_phone_type(const char *affilation)
return TEL_TYPE_OTHER;
}
-static void add_aff_number(struct phonebook_contact *contact, char *pnumber,
- char *aff_type)
+static void add_aff_number(struct phonebook_contact *contact,
+ const char *pnumber, const char *aff_type)
{
char **num_parts;
char *type, *number;
@@ -1437,7 +1436,7 @@ failed:
}
static void contact_add_numbers(struct phonebook_contact *contact,
- char **reply)
+ const char **reply)
{
char **aff_numbers;
int i;
@@ -1463,8 +1462,8 @@ static enum phonebook_field_type get_field_type(const char *affilation)
return FIELD_TYPE_OTHER;
}
-static void add_aff_field(struct phonebook_contact *contact, char *aff_email,
- add_field_t add_field_cb)
+static void add_aff_field(struct phonebook_contact *contact,
+ const char *aff_email, add_field_t add_field_cb)
{
char **email_parts;
char *type, *email;
@@ -1494,7 +1493,7 @@ failed:
}
static void contact_add_emails(struct phonebook_contact *contact,
- char **reply)
+ const char **reply)
{
char **aff_emails;
int i;
@@ -1510,7 +1509,7 @@ static void contact_add_emails(struct phonebook_contact *contact,
}
static void contact_add_addresses(struct phonebook_contact *contact,
- char **reply)
+ const char **reply)
{
char **aff_addr;
int i;
@@ -1526,7 +1525,8 @@ static void contact_add_addresses(struct phonebook_contact *contact,
g_strfreev(aff_addr);
}
-static void contact_add_urls(struct phonebook_contact *contact, char **reply)
+static void contact_add_urls(struct phonebook_contact *contact,
+ const char **reply)
{
char **aff_url;
int i;
@@ -1542,7 +1542,7 @@ static void contact_add_urls(struct phonebook_contact *contact, char **reply)
}
static void contact_add_organization(struct phonebook_contact *contact,
- char **reply)
+ const char **reply)
{
/* Adding fields connected by nco:hasAffiliation - they may be in
* separate replies */
@@ -1552,7 +1552,7 @@ static void contact_add_organization(struct phonebook_contact *contact,
add_affiliation(&contact->role, reply[COL_ORG_ROLE]);
}
-static void pull_contacts(char **reply, int num_fields, void *user_data)
+static void pull_contacts(const char **reply, int num_fields, void *user_data)
{
struct phonebook_data *data = user_data;
const struct apparam_field *params = data->params;
@@ -1653,7 +1653,7 @@ fail:
*/
}
-static void add_to_cache(char **reply, int num_fields, void *user_data)
+static void add_to_cache(const char **reply, int num_fields, void *user_data)
{
struct phonebook_data *data = user_data;
char *formatted;
@@ -1703,6 +1703,9 @@ done:
int phonebook_init(void)
{
+ g_thread_init(NULL);
+ g_type_init();
+
return 0;
}
@@ -1789,16 +1792,27 @@ done:
void phonebook_req_finalize(void *request)
{
struct phonebook_data *data = request;
+ GSList *l;
DBG("");
if (!data)
return;
- if (!dbus_pending_call_get_completed(data->call))
- dbus_pending_call_cancel(data->call);
+ /* canceling asynchronous operation on tracker if any is active */
+ if (data->query_canc) {
+ g_cancellable_cancel(data->query_canc);
+ g_object_unref(data->query_canc);
+ }
+
+ /* freeing contacts */
+ for (l = data->contacts; l; l = l->next) {
+ struct contact_data *c_data = l->data;
- dbus_pending_call_unref(data->call);
+ g_free(c_data->id);
+ phonebook_contact_free(c_data->contact);
+ g_free(c_data);
+ }
g_slist_free(data->contacts);
g_free(data);
@@ -1822,7 +1836,8 @@ static void gstring_free_helper(gpointer data, gpointer user_data)
g_string_free(data, TRUE);
}
-static void pull_newmissedcalls(char **reply, int num_fields, void *user_data)
+static void pull_newmissedcalls(const char **reply, int num_fields,
+ void *user_data)
{
struct phonebook_data *data = user_data;
reply_list_foreach_t pull_cb;
@@ -1864,8 +1879,7 @@ done:
pull_cb = pull_contacts;
}
- dbus_pending_call_unref(data->call);
- data->call = query_tracker(query, col_amount, pull_cb, data, &err);
+ query_tracker(query, col_amount, pull_cb, data, &err);
if (err < 0)
data->cb(NULL, 0, err, 0, data->user_data);
}
@@ -1904,7 +1918,7 @@ void *phonebook_pull(const char *name, const struct apparam_field *params,
data->params = params;
data->user_data = user_data;
data->cb = cb;
- data->call = query_tracker(query, col_amount, pull_cb, data, err);
+ query_tracker(query, col_amount, pull_cb, data, err);
return data;
}
@@ -1932,8 +1946,8 @@ void *phonebook_get_entry(const char *folder, const char *id,
query = g_strdup_printf(CONTACTS_OTHER_QUERY_FROM_URI,
id, id, id);
- data->call = query_tracker(query, PULL_QUERY_COL_AMOUNT, pull_contacts,
- data, err);
+ query_tracker(query, PULL_QUERY_COL_AMOUNT,
+ pull_contacts, data, err);
g_free(query);
@@ -1959,7 +1973,7 @@ void *phonebook_create_cache(const char *name, phonebook_entry_cb entry_cb,
data->entry_cb = entry_cb;
data->ready_cb = ready_cb;
data->user_data = user_data;
- data->call = query_tracker(query, 7, add_to_cache, data, err);
+ query_tracker(query, 7, add_to_cache, data, err);
return data;
}
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH] Changing required GLIB version in acinclude.m4
From: Luiz Augusto von Dentz @ 2011-02-03 8:46 UTC (permalink / raw)
To: ankushbansal89; +Cc: linux-bluetooth
In-Reply-To: <1296677045-12603-1-git-send-email-ankushbansal89@gmail.com>
Hi,
On Wed, Feb 2, 2011 at 10:04 PM, <ankushbansal89@gmail.com> wrote:
> From: Ankush Bansal <ankushbansal89@gmail.com>
>
> ---
> acinclude.m4 | 4 ++--
> 1 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/acinclude.m4 b/acinclude.m4
> index ecf4b4b..9d3f6b2 100644
> --- a/acinclude.m4
> +++ b/acinclude.m4
> @@ -108,8 +108,8 @@ AC_DEFUN([AC_PATH_DBUS], [
> ])
>
> AC_DEFUN([AC_PATH_GLIB], [
> - PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.14, dummy=yes,
> - AC_MSG_ERROR(GLib library version 2.14 or later is required))
> + PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes,
> + AC_MSG_ERROR(GLib library version 2.16 or later is required))
> AC_SUBST(GLIB_CFLAGS)
> AC_SUBST(GLIB_LIBS)
> ])
> --
> 1.7.1
Can you provide more details why this is needed, is there any new
function we are using which requires 2.16?
--
Luiz Augusto von Dentz
Computer Engineer
^ permalink raw reply
* [PATCH 1/3 v4] Add libtracker-sparql to obexd dependencies
From: Radoslaw Jablonski @ 2011-02-03 9:43 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Radoslaw Jablonski
In PBAP tracker is used only for reading and returns rather big
parts of data, so using direct access libtracker-sparql is better
solution than tracker D-Bus API(libtracker-sparql in most PBAP
scenarios should be faster).
---
Makefile.am | 4 +++-
configure.ac | 7 +++++++
2 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index a317556..fc996ec 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -79,7 +79,8 @@ src_obexd_SOURCES = $(gdbus_sources) $(builtin_sources) $(btio_sources) \
src_obexd_LDADD = @DBUS_LIBS@ @GLIB_LIBS@ @GTHREAD_LIBS@ \
@EBOOK_LIBS@ @OPENOBEX_LIBS@ \
- @BLUEZ_LIBS@ @LIBICAL_LIBS@ -ldl
+ @BLUEZ_LIBS@ @LIBICAL_LIBS@ \
+ @TRACKER_SPARQL_LIBS@ -ldl
src_obexd_LDFLAGS = -Wl,--export-dynamic
@@ -124,6 +125,7 @@ service_DATA = $(service_in_files:.service.in=.service)
AM_CFLAGS = @OPENOBEX_CFLAGS@ @BLUEZ_CFLAGS@ @EBOOK_CFLAGS@ \
@GTHREAD_CFLAGS@ @GLIB_CFLAGS@ @DBUS_CFLAGS@ \
@LIBICAL_CFLAGS@ -D_FILE_OFFSET_BITS=64 \
+ @TRACKER_SPARQL_CFLAGS@ \
-DOBEX_PLUGIN_BUILTIN -DPLUGINDIR=\""$(plugindir)"\"
INCLUDES = -I$(builddir)/src -I$(srcdir)/src -I$(srcdir)/plugins \
diff --git a/configure.ac b/configure.ac
index e48a3cc..aa8bfb0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -136,6 +136,13 @@ if (test "${phonebook_driver}" = "ebook"); then
AC_SUBST(GTHREAD_LIBS)
fi
+if (test "${phonebook_driver}" = "tracker"); then
+ PKG_CHECK_MODULES(TRACKER_SPARQL, tracker-sparql-0.9, dummy=yes,
+ AC_MSG_ERROR(libtracker-sparql is required))
+ AC_SUBST(TRACKER_SPARQL_CFLAGS)
+ AC_SUBST(TRACKER_SPARQL_LIBS)
+fi
+
AC_SUBST([PHONEBOOK_DRIVER], [phonebook-${phonebook_driver}.c])
AC_ARG_ENABLE(server, AC_HELP_STRING([--disable-server],
--
1.7.0.4
^ permalink raw reply related
* [PATCH 2/3 v4] Move freeing contacts data to phonebook_req_finalize
From: Radoslaw Jablonski @ 2011-02-03 9:43 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Radoslaw Jablonski
In-Reply-To: <1296726203-22613-1-git-send-email-ext-jablonski.radoslaw@nokia.com>
Previously data used for generating vcards was freed only in
gen_vcards body. This may result a memory leak, if fetching data
from tracker was cancelled in the middle of process and gen_vcards
wasn't called. Phonebook_req_finalize is better place for this
kind of cleanup.
---
plugins/phonebook-tracker.c | 14 ++++++++++----
1 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index e60cf74..3b61d6b 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -1326,10 +1326,6 @@ static GString *gen_vcards(GSList *contacts,
struct contact_data *c_data = l->data;
phonebook_add_contact(vcards, c_data->contact,
params->filter, params->format);
-
- g_free(c_data->id);
- phonebook_contact_free(c_data->contact);
- g_free(c_data);
}
return vcards;
@@ -1789,6 +1785,7 @@ done:
void phonebook_req_finalize(void *request)
{
struct phonebook_data *data = request;
+ GSList *l;
DBG("");
@@ -1800,6 +1797,15 @@ void phonebook_req_finalize(void *request)
dbus_pending_call_unref(data->call);
+ /* freeing list of contacts used for generating vcards */
+ for (l = data->contacts; l; l = l->next) {
+ struct contact_data *c_data = l->data;
+
+ g_free(c_data->id);
+ phonebook_contact_free(c_data->contact);
+ g_free(c_data);
+ }
+
g_slist_free(data->contacts);
g_free(data);
}
--
1.7.0.4
^ permalink raw reply related
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