* [RFC v3 obexd 03/10] fuse: Add obexhlp_connect/disconnect functions with helpers
From: Michał Poczwardowski @ 2012-12-01 23:14 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Michał Poczwardowski
In-Reply-To: <1354403695-18985-1-git-send-email-dmp0x7c5@gmail.com>
---
fuse/helpers.c | 268 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
fuse/helpers.h | 4 +
fuse/obexfuse.c | 40 ++++++++
3 files changed, 312 insertions(+), 0 deletions(-)
diff --git a/fuse/helpers.c b/fuse/helpers.c
index 2dc309a..82797d9 100644
--- a/fuse/helpers.c
+++ b/fuse/helpers.c
@@ -43,6 +43,9 @@
#define OBEX_FTP_LS "x-obex/folder-listing"
+static GCond *obexhlp_cond;
+static GMutex *obexhlp_mutex;
+
struct obexhlp_request {
gchar *name;
gboolean complete;
@@ -52,3 +55,268 @@ struct obexhlp_location {
gchar *dir;
gchar *file;
};
+
+static volatile sig_atomic_t __sdp_io_finished = 0;
+
+/* adopted from client/bluetooth.c - search_callback() */
+static void search_callback(uint8_t type, uint16_t status,
+ uint8_t *rsp, size_t size, void *user_data)
+{
+ struct obexhlp_session *session = user_data;
+ unsigned int scanned, bytesleft = size;
+ int seqlen = 0;
+ uint8_t dataType;
+ uint16_t port = 0;
+
+ if (status || type != SDP_SVC_SEARCH_ATTR_RSP)
+ goto done;
+
+ scanned = sdp_extract_seqtype(rsp, bytesleft, &dataType, &seqlen);
+ if (!scanned || !seqlen)
+ goto done;
+
+ rsp += scanned;
+ bytesleft -= scanned;
+ do {
+ sdp_record_t *rec;
+ sdp_list_t *protos;
+ sdp_data_t *data;
+ int recsize, ch = -1;
+
+ recsize = 0;
+ rec = sdp_extract_pdu(rsp, bytesleft, &recsize);
+ if (!rec)
+ break;
+
+ if (!recsize) {
+ sdp_record_free(rec);
+ break;
+ }
+
+ if (!sdp_get_access_protos(rec, &protos)) {
+ port = sdp_get_proto_port(protos, RFCOMM_UUID);
+ sdp_list_foreach(protos,
+ (sdp_list_func_t) sdp_list_free, NULL);
+ sdp_list_free(protos, NULL);
+ protos = NULL;
+ goto done;
+ }
+
+ data = sdp_data_get(rec, 0x0200);
+ /* PSM must be odd and lsb of upper byte must be 0 */
+ if (data != NULL && (data->val.uint16 & 0x0101) == 0x0001)
+ ch = data->val.uint16;
+
+ sdp_record_free(rec);
+
+ if (ch > 0) {
+ port = ch;
+ break;
+ }
+
+ scanned += recsize;
+ rsp += recsize;
+ bytesleft -= recsize;
+ } while (scanned < size && bytesleft > 0);
+
+done:
+ session->channel = port;
+ __sdp_io_finished = 1;
+}
+
+static uint16_t get_ftp_channel(struct obexhlp_session* session,
+ bdaddr_t *src, bdaddr_t *dst)
+{
+ sdp_list_t *search, *attrid;
+ uint32_t range = 0x0000ffff;
+ sdp_session_t *sdp;
+ uuid_t uuid;
+
+ sdp = sdp_connect(src, dst, SDP_RETRY_IF_BUSY);
+ if (sdp == NULL)
+ return 0;
+
+ /* FTP_SDP_UUID "00001106-0000-1000-8000-00805f9b34fb" */
+ uint8_t uuid_int[] = {0, 0, 0x11, 0x06, 0, 0, 0x10, 0, 0x80,
+ 0, 0, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
+ sdp_uuid128_create(&uuid, uuid_int);
+
+ if (sdp_set_notify(sdp, search_callback, session) < 0)
+ goto done;
+
+ search = sdp_list_append(NULL, &uuid);
+ attrid = sdp_list_append(NULL, &range);
+
+ if (sdp_service_search_attr_async(sdp,
+ search, SDP_ATTR_REQ_RANGE, attrid) < 0) {
+ sdp_list_free(attrid, NULL);
+ sdp_list_free(search, NULL);
+ goto done;
+ }
+
+ sdp_list_free(attrid, NULL);
+ sdp_list_free(search, NULL);
+
+ while (!__sdp_io_finished)
+ sdp_process(sdp);
+
+done:
+ return session->channel;
+}
+
+/* taken from client/bluetooth.c - bluetooth_getpacketopt */
+static int get_packet_opt(GIOChannel *io, int *tx_mtu, int *rx_mtu)
+{
+ int sk = g_io_channel_unix_get_fd(io);
+ int type;
+ int omtu = -1;
+ int imtu = -1;
+ socklen_t len = sizeof(int);
+
+ if (getsockopt(sk, SOL_SOCKET, SO_TYPE, &type, &len) < 0)
+ return -errno;
+
+ if (type != SOCK_SEQPACKET)
+ return -EINVAL;
+
+ if (!bt_io_get(io, NULL, BT_IO_OPT_OMTU, &omtu,
+ BT_IO_OPT_IMTU, &imtu,
+ BT_IO_OPT_INVALID))
+ return -EINVAL;
+
+ if (tx_mtu)
+ *tx_mtu = omtu;
+
+ if (rx_mtu)
+ *rx_mtu = imtu;
+
+ return 0;
+}
+
+static void obex_callback(GObex *obex, GError *err, GObexPacket *rsp,
+ gpointer user_data)
+{
+ if (err != NULL) {
+ g_print("OBEX Connect failed: %s\n", err->message);
+ g_error_free(err);
+ } else {
+ g_print("OBEX Connect succeeded\n");
+ }
+}
+
+static void bt_io_callback(GIOChannel *io, GError *err, gpointer user_data)
+{
+ struct obexhlp_session *session = user_data;
+ GObexTransportType type;
+ int tx_mtu = -1;
+ int rx_mtu = -1;
+
+ if (err != NULL) {
+ g_printerr("%s\n", err->message);
+ g_error_free(err);
+ return;
+ }
+
+ g_print("Bluetooth socket connected\n");
+
+ g_io_channel_set_close_on_unref(io, FALSE);
+
+ if (get_packet_opt(io, &tx_mtu, &rx_mtu) == 0) {
+ type = G_OBEX_TRANSPORT_PACKET;
+ g_print("PACKET transport tx:%d rx:%d\n", tx_mtu, rx_mtu);
+ } else {
+ type = G_OBEX_TRANSPORT_STREAM;
+ g_print("STREAM transport\n");
+ }
+
+ session->obex = g_obex_new(io, type, tx_mtu, rx_mtu);
+ if (session->obex == NULL) {
+ g_print("ERROR: obex is NULL");
+ raise(SIGTERM);
+ }
+
+ g_io_channel_set_close_on_unref(io, TRUE);
+
+ g_obex_connect(session->obex, obex_callback, session, &err,
+ G_OBEX_HDR_TARGET, OBEX_FTP_UUID,
+ OBEX_FTP_UUID_LEN, G_OBEX_HDR_INVALID);
+
+ if (err != NULL) {
+ g_print("ERROR: %s\n", err->message);
+ g_obex_unref(session->obex);
+ raise(SIGTERM);
+ }
+}
+
+struct obexhlp_session* obexhlp_connect(const char *srcstr,
+ const char *dststr)
+{
+ struct obexhlp_session *session;
+ uint16_t channel;
+ bdaddr_t src, dst;
+
+ session = g_try_malloc0(sizeof(struct obexhlp_session));
+ if (session == NULL)
+ return NULL;
+
+ if (srcstr == NULL)
+ bacpy(&src, BDADDR_ANY);
+ else
+ str2ba(srcstr, &src);
+
+ str2ba(dststr, &dst);
+ channel = get_ftp_channel(session, &src, &dst);
+
+ if (channel == 0)
+ return NULL;
+
+ if (channel > 31)
+ session->io = bt_io_connect(bt_io_callback, session,
+ NULL, &session->err,
+ BT_IO_OPT_SOURCE_BDADDR, &src,
+ BT_IO_OPT_DEST_BDADDR, &dst,
+ BT_IO_OPT_PSM, channel,
+ BT_IO_OPT_MODE, BT_IO_MODE_ERTM,
+ BT_IO_OPT_OMTU, BT_TX_MTU,
+ BT_IO_OPT_IMTU, BT_RX_MTU,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+ BT_IO_OPT_INVALID);
+ else
+ session->io = bt_io_connect(bt_io_callback, session,
+ NULL, &session->err,
+ BT_IO_OPT_SOURCE_BDADDR, &src,
+ BT_IO_OPT_DEST_BDADDR, &dst,
+ BT_IO_OPT_CHANNEL, channel,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+ BT_IO_OPT_INVALID);
+
+ if (session->err != NULL)
+ return NULL;
+
+ session->file_stat = g_hash_table_new_full( g_str_hash, g_str_equal,
+ g_free, g_free);
+ session->setpath = g_strdup("/");
+
+ obexhlp_mutex = g_mutex_new();
+ obexhlp_cond = g_cond_new();
+
+ return session;
+}
+
+void obexhlp_disconnect(struct obexhlp_session* session)
+{
+ if (session == NULL)
+ return;
+
+ g_obex_unref(session->obex);
+ g_free(session->io);
+
+ g_hash_table_remove_all(session->file_stat);
+ g_list_free_full(session->lsfiles, g_free);
+ g_free(session->setpath);
+
+ g_mutex_free(obexhlp_mutex);
+ g_cond_free(obexhlp_cond);
+
+ g_free(session);
+}
diff --git a/fuse/helpers.h b/fuse/helpers.h
index abbdd70..3ef924e 100644
--- a/fuse/helpers.h
+++ b/fuse/helpers.h
@@ -47,3 +47,7 @@ struct obexhlp_session {
int status;
GError *err;
};
+
+struct obexhlp_session* obexhlp_connect(const char *srcstr,
+ const char *dstsrc);
+void obexhlp_disconnect(struct obexhlp_session* session);
diff --git a/fuse/obexfuse.c b/fuse/obexfuse.c
index fe4f4da..d6a87f3 100644
--- a/fuse/obexfuse.c
+++ b/fuse/obexfuse.c
@@ -33,6 +33,10 @@
#include "helpers.h"
+struct obexhlp_session* session = NULL;
+static GMainLoop *main_loop;
+static GThread *main_gthread;
+
struct options {
char* dststr;
char* srcstr;
@@ -60,7 +64,34 @@ static struct fuse_opt obexfuse_opts[] =
FUSE_OPT_END
};
+gpointer main_loop_func(gpointer user_data)
+{
+ main_loop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(main_loop);
+
+ return 0;
+}
+
+void* obexfuse_init(struct fuse_conn_info *conn)
+{
+ main_gthread = g_thread_create(main_loop_func, NULL, TRUE, NULL);
+
+ conn->async_read = 0;
+ conn->want &= ~FUSE_CAP_ASYNC_READ;
+
+ return 0;
+}
+
+void obexfuse_destroy()
+{
+ obexhlp_disconnect(session);
+ g_main_loop_quit(main_loop);
+ g_thread_join(main_gthread);
+}
+
static struct fuse_operations obexfuse_oper = {
+ .init = obexfuse_init,
+ .destroy = obexfuse_destroy,
};
static int obexfuse_opt_proc(void *data, const char *arg, int key,
@@ -111,6 +142,15 @@ int main(int argc, char *argv[])
g_thread_init(NULL);
+ session = obexhlp_connect(options.srcstr, options.dststr);
+ if (session == NULL || session->io == NULL) {
+ g_printerr("Connection to %s failed\n", options.dststr);
+ obexhlp_disconnect(session);
+ return -EHOSTUNREACH;
+ } else {
+ g_print("Connected\nMounting %s\n", options.dststr);
+ }
+
fuse_opt_add_arg(&args, "-s"); /* force single threaded mode */
retfuse = fuse_main(args.argc, args.argv, &obexfuse_oper, NULL);
--
1.7.8.6
^ permalink raw reply related
* [RFC v3 obexd 02/10] build: Add --enable-fuse for obexfuse
From: Michał Poczwardowski @ 2012-12-01 23:14 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Michał Poczwardowski
In-Reply-To: <1354403695-18985-1-git-send-email-dmp0x7c5@gmail.com>
---
Makefile.am | 9 +++++++++
configure.ac | 15 +++++++++++++++
2 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 724dd5d..01441dc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -132,6 +132,15 @@ client_obex_client_SOURCES = $(gdbus_sources) $(gobex_sources) \
client_obex_client_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@
endif
+if FUSE
+bin_PROGRAMS = fuse/obexfuse
+
+fuse_obexfuse_SOURCES = $(gobex_sources) $(btio_sources) \
+ fuse/helpers.c fuse/obexfuse.c
+
+fuse_obexfuse_LDADD = @GLIB_LIBS@ @GTHREAD_LIBS@ @BLUEZ_LIBS@ @FUSE_LIBS@
+endif
+
service_DATA = $(service_in_files:.service.in=.service)
AM_CFLAGS = @BLUEZ_CFLAGS@ @EBOOK_CFLAGS@ @GTHREAD_CFLAGS@ @GLIB_CFLAGS@ \
diff --git a/configure.ac b/configure.ac
index 69d636f..7d0a904 100644
--- a/configure.ac
+++ b/configure.ac
@@ -180,4 +180,19 @@ AM_CONDITIONAL(CLIENT, test "${enable_client}" != "no")
AM_CONDITIONAL(READLINE, test "${readline_found}" = "yes")
+AC_ARG_ENABLE(fuse, AC_HELP_STRING([--enable-fuse],
+ [Build obexfuse]), [
+ PKG_CHECK_MODULES(FUSE, fuse, dummy=yes,
+ AC_MSG_ERROR(FUSE is required))
+ AC_SUBST(FUSE_CFLAGS)
+ AC_SUBST(FUSE_LIBS)
+ enable_fuse=${enableval}
+
+ PKG_CHECK_MODULES(GTHREAD, gthread-2.0, dummy=yes,
+ AC_MSG_ERROR(libgthread is required))
+ AC_SUBST(GTHREAD_CFLAGS)
+ AC_SUBST(GTHREAD_LIBS)
+])
+AM_CONDITIONAL(FUSE, test "${enable_fuse}" != "no")
+
AC_OUTPUT(Makefile)
--
1.7.8.6
^ permalink raw reply related
* [RFC v3 obexd 01/10] fuse: Add initial obexfuse files, fuse main and options parse
From: Michał Poczwardowski @ 2012-12-01 23:14 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Michał Poczwardowski
---
fuse/helpers.c | 54 +++++++++++++++++++++++++
fuse/helpers.h | 49 ++++++++++++++++++++++
fuse/obexfuse.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 222 insertions(+), 0 deletions(-)
create mode 100644 fuse/helpers.c
create mode 100644 fuse/helpers.h
create mode 100644 fuse/obexfuse.c
diff --git a/fuse/helpers.c b/fuse/helpers.c
new file mode 100644
index 0000000..2dc309a
--- /dev/null
+++ b/fuse/helpers.c
@@ -0,0 +1,54 @@
+/*
+ * OBEX Filesystem in Userspace
+ *
+ * Copyright (C) 2012 Michał Poczwardowski <dmp0x7c5@gmail.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <gobex/gobex.h>
+#include <btio/btio.h>
+
+#include <glib.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/rfcomm.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
+
+#define BT_RX_MTU 32767
+#define BT_TX_MTU 32767
+
+#include "helpers.h"
+
+#define OBEX_FTP_UUID \
+ "\xF9\xEC\x7B\xC4\x95\x3C\x11\xD2\x98\x4E\x52\x54\x00\xDC\x9E\x09"
+#define OBEX_FTP_UUID_LEN 16
+
+#define OBEX_FTP_LS "x-obex/folder-listing"
+
+struct obexhlp_request {
+ gchar *name;
+ gboolean complete;
+};
+
+struct obexhlp_location {
+ gchar *dir;
+ gchar *file;
+};
diff --git a/fuse/helpers.h b/fuse/helpers.h
new file mode 100644
index 0000000..abbdd70
--- /dev/null
+++ b/fuse/helpers.h
@@ -0,0 +1,49 @@
+/*
+ * OBEX Filesystem in Userspace
+ *
+ * Copyright (C) 2012 Michał Poczwardowski <dmp0x7c5@gmail.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <gobex/gobex.h>
+#include <glib.h>
+
+struct obexhlp_request;
+
+struct obexhlp_buffer {
+ void *data;
+ gsize tmpsize;
+ gsize size;
+ gboolean edited;
+};
+
+struct obexhlp_session {
+ GObex *obex;
+ uint16_t channel;
+ GList *lsfiles;
+ GIOChannel *io;
+ GHashTable *file_stat;
+ gchar *setpath;
+ struct obexhlp_request *request;
+ struct obexhlp_buffer *buffer;
+ gboolean vtouch;
+ gchar *vtouch_path;
+ gboolean rtouch;
+ int status;
+ GError *err;
+};
diff --git a/fuse/obexfuse.c b/fuse/obexfuse.c
new file mode 100644
index 0000000..fe4f4da
--- /dev/null
+++ b/fuse/obexfuse.c
@@ -0,0 +1,119 @@
+/*
+ * OBEX Filesystem in Userspace
+ *
+ * Copyright (C) 2012 Michał Poczwardowski <dmp0x7c5@gmail.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#define FUSE_USE_VERSION 26
+
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <fuse.h>
+#include <fuse/fuse_opt.h>
+
+#include "helpers.h"
+
+struct options {
+ char* dststr;
+ char* srcstr;
+} options;
+
+#define GOBEXFUSE_OPT_KEY(t, p, v) { t, offsetof(struct options, p), v }
+
+enum
+{
+ KEY_VERSION,
+ KEY_HELP,
+};
+
+static struct fuse_opt obexfuse_opts[] =
+{
+ GOBEXFUSE_OPT_KEY("--target=%s",dststr, 0),
+ GOBEXFUSE_OPT_KEY("-t %s", dststr, 0),
+ GOBEXFUSE_OPT_KEY("--source=%s",srcstr, 0),
+ GOBEXFUSE_OPT_KEY("-s %s", srcstr, 0),
+
+ FUSE_OPT_KEY("-V", KEY_VERSION),
+ FUSE_OPT_KEY("--version", KEY_VERSION),
+ FUSE_OPT_KEY("-h", KEY_HELP),
+ FUSE_OPT_KEY("--help", KEY_HELP),
+ FUSE_OPT_END
+};
+
+static struct fuse_operations obexfuse_oper = {
+};
+
+static int obexfuse_opt_proc(void *data, const char *arg, int key,
+ struct fuse_args *outargs)
+{
+ switch (key) {
+ case KEY_HELP:
+ g_printerr("Usage: %s mountpoint [options]\n"
+ "\n"
+ "general options:\n"
+ " -o opt,[opt...] mount options\n"
+ " -h --help print help\n"
+ " -V --version print version\n"
+ "\n"
+ "obexfuse options:\n"
+ " -t --target target btaddr "
+ "(mandatory)\n"
+ " -s --source source btaddr\n"
+ "\n"
+ , outargs->argv[0]);
+ fuse_opt_add_arg(outargs, "-ho");
+ fuse_main(outargs->argc, outargs->argv, &obexfuse_oper, NULL);
+ exit(1);
+ case KEY_VERSION:
+ g_print("obexfuse upon:\n");
+ fuse_opt_add_arg(outargs, "--version");
+ fuse_main(outargs->argc, outargs->argv, &obexfuse_oper, NULL);
+ exit(0);
+ }
+ return 1;
+}
+
+int main(int argc, char *argv[])
+{
+ int retfuse;
+ struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
+
+ memset(&options, 0, sizeof(struct options));
+
+ if (fuse_opt_parse(&args, &options, obexfuse_opts,
+ obexfuse_opt_proc) == -1)
+ return -EINVAL;
+
+ if (options.dststr == NULL) {
+ g_printerr("Target not specified\n");
+ return -EINVAL;
+ }
+
+ g_thread_init(NULL);
+
+ fuse_opt_add_arg(&args, "-s"); /* force single threaded mode */
+ retfuse = fuse_main(args.argc, args.argv, &obexfuse_oper, NULL);
+
+ fuse_opt_free_args(&args);
+ return retfuse;
+}
--
1.7.8.6
^ permalink raw reply related
* Re: [PATCH BlueZ] control: Add methods FastForward and Rewind
From: Johan Hedberg @ 2012-12-01 9:25 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1354279699-1245-1-git-send-email-luiz.dentz@gmail.com>
Hi Luiz,
On Fri, Nov 30, 2012, Luiz Augusto von Dentz wrote:
> These method can be used to fast-forward and rewind the playback, their
> action will keep active until another method is called.
>
> The commands are reapeated every 2 seconds to conform with AVC spec.
> ---
> doc/control-api.txt | 10 ++++
> profiles/audio/avctp.c | 148 ++++++++++++++++++++++++++++++++++++++++++-----
> profiles/audio/control.c | 14 +++++
> 3 files changed, 157 insertions(+), 15 deletions(-)
Applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH BlueZ v2 1/2] input: Fix emitting a signal for a non-existant interface
From: Johan Hedberg @ 2012-12-01 9:13 UTC (permalink / raw)
To: Vinicius Costa Gomes; +Cc: linux-bluetooth
In-Reply-To: <1354322217-11219-1-git-send-email-vinicius.gomes@openbossa.org>
Hi Vinicius,
On Fri, Nov 30, 2012, Vinicius Costa Gomes wrote:
> When the 'org.bluez.Input' interface was removed, this should have been
> removed as well, now it is causing a segmentation fault.
> ---
> profiles/input/device.c | 6 ------
> 1 file changed, 6 deletions(-)
Both patches have been applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH 1/4] gas: Fix memory leak at gas struct removal
From: Johan Hedberg @ 2012-12-01 9:11 UTC (permalink / raw)
To: Paulo Borges; +Cc: linux-bluetooth
In-Reply-To: <1354300294-9105-1-git-send-email-paulo.borges@openbossa.org>
Hi Paulo,
On Fri, Nov 30, 2012, Paulo Borges wrote:
> ---
> profiles/gatt/gas.c | 1 +
> 1 file changed, 1 insertion(+)
All four patches have been applied. Thanks.
Johan
^ permalink raw reply
* [PATCH BlueZ v2 2/2] input: Remove leftovers from the Input iface removal
From: Vinicius Costa Gomes @ 2012-12-01 0:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1354322217-11219-1-git-send-email-vinicius.gomes@openbossa.org>
Now that the Input interface is removed, the only way to connect is
via the Profile interface, so no need to separate the way that
connection is made.
---
profiles/input/device.c | 37 ++++++-------------------------------
1 file changed, 6 insertions(+), 31 deletions(-)
diff --git a/profiles/input/device.c b/profiles/input/device.c
index 7538297..8464062 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -64,14 +64,8 @@
#define FI_FLAG_CONNECTED 1
struct pending_connect {
- bool local;
- union {
- struct {
- struct btd_profile *profile;
- btd_profile_cb cb;
- } p;
- DBusMessage *msg;
- };
+ struct btd_profile *profile;
+ btd_profile_cb cb;
};
struct input_device {
@@ -119,11 +113,8 @@ static void input_device_free(struct input_device *idev)
g_free(idev->name);
g_free(idev->path);
- if (idev->pending) {
- if (idev->pending->local)
- dbus_message_unref(idev->pending->msg);
+ if (idev->pending)
g_free(idev->pending);
- }
if (idev->ctrl_watch > 0)
g_source_remove(idev->ctrl_watch);
@@ -510,8 +501,6 @@ static void connect_reply(struct input_device *idev, int err,
const char *err_msg)
{
struct pending_connect *pending = idev->pending;
- DBusConnection *conn = btd_get_dbus_connection();
- DBusMessage *reply;
if (!pending)
return;
@@ -521,20 +510,7 @@ static void connect_reply(struct input_device *idev, int err,
if (err_msg)
error("%s", err_msg);
- if (!pending->local) {
- pending->p.cb(pending->p.profile, idev->device, err);
- g_free(pending);
- return;
- }
-
- if (err_msg) {
- reply = btd_error_failed(idev->pending->msg, err_msg);
- g_dbus_send_message(conn, reply);
- } else {
- g_dbus_send_reply(conn, pending->msg, DBUS_TYPE_INVALID);
- }
-
- dbus_message_unref(pending->msg);
+ pending->cb(pending->profile, idev->device, err);
g_free(pending);
}
@@ -667,9 +643,8 @@ int input_device_connect(struct btd_device *dev, struct btd_profile *profile,
return -EALREADY;
idev->pending = g_new0(struct pending_connect, 1);
- idev->pending->local = false;
- idev->pending->p.profile = profile;
- idev->pending->p.cb = cb;
+ idev->pending->profile = profile;
+ idev->pending->cb = cb;
return dev_connect(idev);
}
--
1.8.0
^ permalink raw reply related
* [PATCH BlueZ v2 1/2] input: Fix emitting a signal for a non-existant interface
From: Vinicius Costa Gomes @ 2012-12-01 0:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
When the 'org.bluez.Input' interface was removed, this should have been
removed as well, now it is causing a segmentation fault.
---
profiles/input/device.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/profiles/input/device.c b/profiles/input/device.c
index 2871cc3..7538297 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -160,9 +160,6 @@ static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data
if ((cond & (G_IO_HUP | G_IO_ERR)) && idev->ctrl_watch)
g_io_channel_shutdown(chan, TRUE, NULL);
- g_dbus_emit_property_changed(idev->conn, idev->path,
- INPUT_DEVICE_INTERFACE, "Connected");
-
device_remove_disconnect_watch(idev->device, idev->dc_id);
idev->dc_id = 0;
@@ -503,9 +500,6 @@ static int input_device_connected(struct input_device *idev)
if (err < 0)
return err;
- g_dbus_emit_property_changed(idev->conn, idev->path,
- INPUT_DEVICE_INTERFACE, "Connected");
-
idev->dc_id = device_add_disconnect_watch(idev->device, disconnect_cb,
idev, NULL);
--
1.8.0
^ permalink raw reply related
* Re: [PATCH BlueZ] input: Fix emitting a signal for a non-existant interface
From: Vinicius Gomes @ 2012-11-30 23:45 UTC (permalink / raw)
To: BlueZ development; +Cc: Vinicius Costa Gomes
In-Reply-To: <1354318625-15066-1-git-send-email-vinicius.gomes@openbossa.org>
Hi,
On Fri, Nov 30, 2012 at 8:37 PM, Vinicius Costa Gomes
<vinicius.gomes@openbossa.org> wrote:
> When the 'org.bluez.Input' interface was removed, this should have been
> removed as well, now it is causing a segmentation fault.
> ---
Please ignore this patch. I didn't notice that the signal is emitted
in another place too. Updated version coming soon.
Cheers,
--
Vinicius
^ permalink raw reply
* [PATCH BlueZ] input: Fix emitting a signal for a non-existant interface
From: Vinicius Costa Gomes @ 2012-11-30 23:37 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
When the 'org.bluez.Input' interface was removed, this should have been
removed as well, now it is causing a segmentation fault.
---
profiles/input/device.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/profiles/input/device.c b/profiles/input/device.c
index 2871cc3..421af64 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -503,9 +503,6 @@ static int input_device_connected(struct input_device *idev)
if (err < 0)
return err;
- g_dbus_emit_property_changed(idev->conn, idev->path,
- INPUT_DEVICE_INTERFACE, "Connected");
-
idev->dc_id = device_add_disconnect_watch(idev->device, disconnect_cb,
idev, NULL);
--
1.8.0
^ permalink raw reply related
* [PATCH 4/4] gatt: Improve characteristics discovery
From: Paulo Borges @ 2012-11-30 18:31 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Paulo Borges
In-Reply-To: <1354300294-9105-1-git-send-email-paulo.borges@openbossa.org>
In the Discover Characteristics by UUID sub-procedure, if a fetched
characteristic doesn't matches with the target UUID, all others
characteristics in that response were discarded.
Because of this, the procedure will make a new request to possibly
rediscover the characteristics in the range beyond this last
characteristic.
At present, this procedure works because the gatt library will send a
Read by Type Request starting at the first attribute after the non
matching characteristic.
This commit makes the rest of the characteristics to be checked for a
matching type, which should reduce the number of requests sent during
the discovery of characteristics.
---
attrib/gatt.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/attrib/gatt.c b/attrib/gatt.c
index b834b13..38c050e 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
@@ -476,7 +476,7 @@ static void char_discovered_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
uuid = att_get_uuid128(&value[5]);
if (dc->uuid && bt_uuid_cmp(dc->uuid, &uuid))
- break;
+ continue;
chars = g_try_new0(struct gatt_char, 1);
if (!chars) {
--
1.7.9.5
^ permalink raw reply related
* [PATCH 3/4] gatt: Fix memory leak in characteristic discovery
From: Paulo Borges @ 2012-11-30 18:31 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Paulo Borges
In-Reply-To: <1354300294-9105-1-git-send-email-paulo.borges@openbossa.org>
If the Discover Characteristics by UUID sub-procedure has been
executed and the first characteristic is not the target, a memory
leak occurs.
This commit fixes this leak by postponing the allocation to after
the UUID verification.
---
attrib/gatt.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/attrib/gatt.c b/attrib/gatt.c
index 963fa20..b834b13 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
@@ -475,15 +475,15 @@ static void char_discovered_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
} else
uuid = att_get_uuid128(&value[5]);
+ if (dc->uuid && bt_uuid_cmp(dc->uuid, &uuid))
+ break;
+
chars = g_try_new0(struct gatt_char, 1);
if (!chars) {
err = ATT_ECODE_INSUFF_RESOURCES;
goto done;
}
- if (dc->uuid && bt_uuid_cmp(dc->uuid, &uuid))
- break;
-
chars->handle = last;
chars->properties = value[2];
chars->value_handle = att_get_u16(&value[3]);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 2/4] input: Fix memory leak at hogdev struct removal
From: Paulo Borges @ 2012-11-30 18:31 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Paulo Borges
In-Reply-To: <1354300294-9105-1-git-send-email-paulo.borges@openbossa.org>
---
profiles/input/hog_device.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/profiles/input/hog_device.c b/profiles/input/hog_device.c
index 0a5fb58..a873eac 100644
--- a/profiles/input/hog_device.c
+++ b/profiles/input/hog_device.c
@@ -705,6 +705,7 @@ static void hog_device_free(struct hog_device *hogdev)
{
btd_device_unref(hogdev->device);
g_slist_free_full(hogdev->reports, report_free);
+ g_attrib_unref(hogdev->attrib);
g_free(hogdev->hog_primary);
g_free(hogdev);
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH 1/4] gas: Fix memory leak at gas struct removal
From: Paulo Borges @ 2012-11-30 18:31 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Paulo Borges
---
profiles/gatt/gas.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/profiles/gatt/gas.c b/profiles/gatt/gas.c
index 0e82097..e6cddad 100644
--- a/profiles/gatt/gas.c
+++ b/profiles/gatt/gas.c
@@ -64,6 +64,7 @@ static void gas_free(struct gas *gas)
if (gas->attioid)
btd_device_remove_attio_callback(gas->device, gas->attioid);
+ g_attrib_unref(gas->attrib);
btd_device_unref(gas->device);
g_free(gas);
}
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCHv2 4/4] Bluetooth: trivial: Change NO_FCS_RECV to RECV_NO_FCS
From: Gustavo Padovan @ 2012-11-30 17:50 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1354203968-1335-4-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
* Andrei Emeltchenko <Andrei.Emeltchenko.news@gmail.com> [2012-11-29 17:46:08 +0200]:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Make code more readable by changing CONF_NO_FCS_RECV which is read
> as "No L2CAP FCS option received" to CONF_RECV_NO_FCS which means
> "Received L2CAP option NO_FCS". This flag really means that we have
> received L2CAP FRAME CHECK SEQUENCE (FCS) OPTION with value "No FCS".
>
> Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> ---
> include/net/bluetooth/l2cap.h | 2 +-
> net/bluetooth/l2cap_core.c | 10 +++++-----
> 2 files changed, 6 insertions(+), 6 deletions(-)
All patches have been applied to bluetooth-next. Thanks.
Gustavo
^ permalink raw reply
* [PATCH] Bluetooth: Fix using locked state_change for A2MP chan
From: Andrei Emeltchenko @ 2012-11-30 14:51 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
A2MP channel do not have sk associated so use unlocked version
of state_change. chan is already locked.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
net/bluetooth/l2cap_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 2414cff..6de4287 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1276,7 +1276,7 @@ static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
}
if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
- l2cap_state_change(chan, BT_DISCONN);
+ __l2cap_state_change(chan, BT_DISCONN);
return;
}
--
1.7.10.4
^ permalink raw reply related
* [RFC V3 12/12] event: Store long term key infos in device info file
From: Frédéric Danis @ 2012-11-30 14:47 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354286826-24016-1-git-send-email-frederic.danis@linux.intel.com>
---
src/event.c | 89 ++++++++++++++++++++++++++++++-----------------------------
1 file changed, 46 insertions(+), 43 deletions(-)
diff --git a/src/event.c b/src/event.c
index 5e83c09..61fa0f4 100644
--- a/src/event.c
+++ b/src/event.c
@@ -304,54 +304,59 @@ void btd_event_remote_name(const bdaddr_t *local, bdaddr_t *peer,
device_set_name(device, name);
}
-static char *buf2str(uint8_t *data, int datalen)
+static void store_longtermkey(bdaddr_t *local, bdaddr_t *peer,
+ uint8_t bdaddr_type, unsigned char *key,
+ uint8_t master, uint8_t authenticated,
+ uint8_t enc_size, uint16_t ediv,
+ uint8_t rand[8])
{
- char *buf;
+ char adapter_addr[18];
+ char device_addr[18];
+ char filename[PATH_MAX + 1];
+ GKeyFile *key_file;
+ char key_str[35];
+ char rand_str[19];
+ char *str;
int i;
+ gsize length = 0;
- buf = g_try_new0(char, (datalen * 2) + 1);
- if (buf == NULL)
- return NULL;
-
- for (i = 0; i < datalen; i++)
- sprintf(buf + (i * 2), "%2.2x", data[i]);
+ ba2str(local, adapter_addr);
+ ba2str(peer, device_addr);
- return buf;
-}
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", adapter_addr,
+ device_addr);
+ filename[PATH_MAX] = '\0';
-static int store_longtermkey(bdaddr_t *local, bdaddr_t *peer,
- uint8_t bdaddr_type, unsigned char *key,
- uint8_t master, uint8_t authenticated,
- uint8_t enc_size, uint16_t ediv, uint8_t rand[8])
-{
- GString *newkey;
- char *val, *str;
- int err;
+ key_file = g_key_file_new();
+ g_key_file_load_from_file(key_file, filename, 0, NULL);
- val = buf2str(key, 16);
- if (val == NULL)
- return -ENOMEM;
+ key_str[0] = '0';
+ key_str[1] = 'x';
+ for (i = 0; i < 16; i++)
+ sprintf(key_str + 2 + (i * 2), "%2.2X", key[i]);
- newkey = g_string_new(val);
- g_free(val);
+ g_key_file_set_string(key_file, "LongTermKey", "Key", key_str);
- g_string_append_printf(newkey, " %d %d %d %d ", authenticated, master,
- enc_size, ediv);
+ g_key_file_set_integer(key_file, "LongTermKey", "Authenticated",
+ authenticated);
+ g_key_file_set_integer(key_file, "LongTermKey", "Master", master);
+ g_key_file_set_integer(key_file, "LongTermKey", "EncSize", enc_size);
+ g_key_file_set_integer(key_file, "LongTermKey", "EDiv", ediv);
- str = buf2str(rand, 8);
- if (str == NULL) {
- g_string_free(newkey, TRUE);
- return -ENOMEM;
- }
+ rand_str[0] = '0';
+ rand_str[1] = 'x';
+ for (i = 0; i < 8; i++)
+ sprintf(rand_str + 2 + (i * 2), "%2.2X", rand[i]);
- newkey = g_string_append(newkey, str);
- g_free(str);
+ g_key_file_set_string(key_file, "LongTermKey", "Rand", rand_str);
- err = write_longtermkeys(local, peer, bdaddr_type, newkey->str);
+ create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
- g_string_free(newkey, TRUE);
+ str = g_key_file_to_data(key_file, &length, NULL);
+ g_file_set_contents(filename, str, length, NULL);
+ g_free(str);
- return err;
+ g_key_file_free(key_file);
}
static void store_link_key(struct btd_adapter *adapter,
@@ -425,21 +430,19 @@ int btd_event_ltk_notify(bdaddr_t *local, bdaddr_t *peer, uint8_t bdaddr_type,
{
struct btd_adapter *adapter;
struct btd_device *device;
- int ret;
if (!get_adapter_and_device(local, peer, &adapter, &device, TRUE))
return -ENODEV;
- ret = store_longtermkey(local, peer, bdaddr_type, key, master,
+ store_longtermkey(local, peer, bdaddr_type, key, master,
authenticated, enc_size, ediv, rand);
- if (ret == 0) {
- device_set_bonded(device, TRUE);
- if (device_is_temporary(device))
- device_set_temporary(device, FALSE);
- }
+ device_set_bonded(device, TRUE);
- return ret;
+ if (device_is_temporary(device))
+ device_set_temporary(device, FALSE);
+
+ return 0;
}
void btd_event_conn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t bdaddr_type,
--
1.7.9.5
^ permalink raw reply related
* [RFC V3 11/12] adapter: Upload long term keys from new storage
From: Frédéric Danis @ 2012-11-30 14:47 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354286826-24016-1-git-send-email-frederic.danis@linux.intel.com>
Remove check of long term keys from device_create,
this moves to load_devices.
---
src/adapter.c | 127 +++++++++++++++++++++++----------------------------------
src/device.c | 6 ---
2 files changed, 51 insertions(+), 82 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index ff9d2e7..a0ae04c 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1790,77 +1790,57 @@ failed:
return info;
}
-static struct smp_ltk_info *get_ltk_info(const char *addr, uint8_t bdaddr_type,
- const char *value)
+static struct smp_ltk_info *get_ltk_info(GKeyFile *key_file, const char *peer)
{
- struct smp_ltk_info *ltk;
- char *ptr;
- int i, ret;
+ struct smp_ltk_info *ltk = NULL;
+ char *key;
+ char *rand = NULL;
+ char *type = NULL;
+ uint8_t bdaddr_type;
- if (strlen(value) < 60) {
- error("Unexpectedly short (%zu) LTK", strlen(value));
- return NULL;
- }
+ key = g_key_file_get_string(key_file, "LongTermKey", "Key", NULL);
+ if (!key || strlen(key) != 34)
+ goto failed;
- ltk = g_new0(struct smp_ltk_info, 1);
+ rand = g_key_file_get_string(key_file, "LongTermKey", "Rand", NULL);
+ if (!rand || strlen(rand) != 18)
+ goto failed;
- str2ba(addr, <k->bdaddr);
+ type = g_key_file_get_string(key_file, "General", "AddressType", NULL);
+ if (!type)
+ goto failed;
- ltk->bdaddr_type = bdaddr_type;
+ if (g_str_equal(type, "public"))
+ bdaddr_type = BDADDR_LE_PUBLIC;
+ else if (g_str_equal(type, "static"))
+ bdaddr_type = BDADDR_LE_RANDOM;
+ else
+ goto failed;
- str2buf(value, ltk->val, sizeof(ltk->val));
+ ltk = g_new0(struct smp_ltk_info, 1);
- ptr = (char *) value + 2 * sizeof(ltk->val) + 1;
+ str2ba(peer, <k->bdaddr);
+ ltk->bdaddr_type = bdaddr_type;
+ str2buf(&key[2], ltk->val, sizeof(ltk->val));
+ str2buf(&rand[2], ltk->rand, sizeof(ltk->rand));
- ret = sscanf(ptr, " %hhd %hhd %hhd %hd %n",
- <k->authenticated, <k->master, <k->enc_size,
- <k->ediv, &i);
- if (ret < 2) {
- g_free(ltk);
- return NULL;
- }
- ptr += i;
+ ltk->authenticated = g_key_file_get_integer(key_file, "LongTermKey",
+ "Authenticated", NULL);
+ ltk->master = g_key_file_get_integer(key_file, "LongTermKey", "Master",
+ NULL);
+ ltk->enc_size = g_key_file_get_integer(key_file, "LongTermKey",
+ "EncSize", NULL);
+ ltk->ediv = g_key_file_get_integer(key_file, "LongTermKey", "EDiv",
+ NULL);
- str2buf(ptr, ltk->rand, sizeof(ltk->rand));
+failed:
+ g_free(key);
+ g_free(rand);
+ g_free(type);
return ltk;
}
-static void create_stored_device_from_ltks(char *key, char *value,
- void *user_data)
-{
- struct adapter_keys *keys = user_data;
- struct btd_adapter *adapter = keys->adapter;
- struct btd_device *device;
- struct smp_ltk_info *info;
- char address[18], srcaddr[18];
- uint8_t bdaddr_type;
-
- if (sscanf(key, "%17s#%hhu", address, &bdaddr_type) < 2)
- return;
-
- info = get_ltk_info(address, bdaddr_type, value);
- if (info == NULL)
- return;
-
- keys->keys = g_slist_append(keys->keys, info);
-
- if (g_slist_find_custom(adapter->devices, address,
- (GCompareFunc) device_address_cmp))
- return;
-
- ba2str(&adapter->bdaddr, srcaddr);
-
- if (g_strcmp0(srcaddr, address) == 0)
- return;
-
- device = device_create(adapter, address, bdaddr_type);
- if (device) {
- device_set_temporary(device, FALSE);
- adapter->devices = g_slist_append(adapter->devices, device);
- }
-}
-
static GSList *string_to_primary_list(char *str)
{
GSList *l = NULL;
@@ -1935,18 +1915,12 @@ static void create_stored_device_from_primaries(char *key, char *value,
g_slist_free(uuids);
}
-static void smp_key_free(void *data)
-{
- struct smp_ltk_info *info = data;
-
- g_free(info);
-}
-
static void load_devices(struct btd_adapter *adapter)
{
char filename[PATH_MAX + 1];
char srcaddr[18];
struct adapter_keys keys = { adapter, NULL };
+ struct adapter_keys ltks = { adapter, NULL };
int err;
DIR *dir;
struct dirent *entry;
@@ -1961,16 +1935,6 @@ static void load_devices(struct btd_adapter *adapter)
textfile_foreach(filename, create_stored_device_from_primaries,
adapter);
- create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, "longtermkeys");
- textfile_foreach(filename, create_stored_device_from_ltks, &keys);
-
- err = mgmt_load_ltks(adapter->dev_id, keys.keys);
- if (err < 0)
- error("Unable to load ltks: %s (%d)", strerror(-err), -err);
-
- g_slist_free_full(keys.keys, smp_key_free);
- keys.keys = NULL;
-
snprintf(filename, PATH_MAX, STORAGEDIR "/%s", srcaddr);
filename[PATH_MAX] = '\0';
@@ -1985,6 +1949,7 @@ static void load_devices(struct btd_adapter *adapter)
char filename[PATH_MAX + 1];
GKeyFile *key_file;
struct link_key_info *key_info;
+ struct smp_ltk_info *ltk_info;
GSList *l;
if (entry->d_type != DT_DIR || bachk(entry->d_name) < 0)
@@ -2000,6 +1965,10 @@ static void load_devices(struct btd_adapter *adapter)
if (key_info)
keys.keys = g_slist_append(keys.keys, key_info);
+ ltk_info = get_ltk_info(key_file, entry->d_name);
+ if (ltk_info)
+ ltks.keys = g_slist_append(ltks.keys, ltk_info);
+
g_key_file_free(key_file);
l = g_slist_find_custom(adapter->devices, entry->d_name,
@@ -2017,7 +1986,7 @@ static void load_devices(struct btd_adapter *adapter)
adapter->devices = g_slist_append(adapter->devices, device);
device_exist:
- if (key_info) {
+ if (key_info || ltk_info) {
device_set_paired(device, TRUE);
device_set_bonded(device, TRUE);
}
@@ -2032,6 +2001,12 @@ device_exist:
strerror(-err), -err);
g_slist_free_full(keys.keys, g_free);
+
+ err = mgmt_load_ltks(adapter->dev_id, ltks.keys);
+ if (err < 0)
+ error("Unable to load ltks: %s (%d)", strerror(-err), -err);
+
+ g_slist_free_full(ltks.keys, g_free);
}
int btd_adapter_block_address(struct btd_adapter *adapter,
diff --git a/src/device.c b/src/device.c
index bb5689b..a5bdf4c 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1904,12 +1904,6 @@ struct btd_device *device_create(struct btd_adapter *adapter,
load_info(device, srcaddr, address);
- if (device_is_le(device) && has_longtermkeys(src, &device->bdaddr,
- device->bdaddr_type)) {
- device_set_paired(device, TRUE);
- device_set_bonded(device, TRUE);
- }
-
return btd_device_ref(device);
}
--
1.7.9.5
^ permalink raw reply related
* [RFC V3 10/12] adapter: Convert storage longtermkeys file
From: Frédéric Danis @ 2012-11-30 14:47 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354286826-24016-1-git-send-email-frederic.danis@linux.intel.com>
---
src/adapter.c | 43 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/src/adapter.c b/src/adapter.c
index 17f478c..ff9d2e7 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2655,6 +2655,46 @@ static void convert_linkkey_entry(GKeyFile *key_file, void *value)
g_key_file_set_integer(key_file, "LinkKey", "PINLength", val);
}
+static void convert_ltk_entry(GKeyFile *key_file, void *value)
+{
+ char *auth_str, *rand_str, *str;
+ int i, ret;
+ unsigned char auth, master, enc_size;
+ unsigned short ediv;
+
+ auth_str = strchr(value, ' ');
+ if (!auth_str)
+ return;
+
+ *(auth_str++) = 0;
+
+ for (i = 0, rand_str = auth_str; i < 4; i++) {
+ rand_str = strchr(rand_str, ' ');
+ if (!rand_str || rand_str[1] == '\0')
+ return;
+
+ rand_str++;
+ }
+
+ ret = sscanf(auth_str, " %hhd %hhd %hhd %hd", &auth, &master,
+ &enc_size, &ediv);
+ if (ret < 4)
+ return;
+
+ str = g_strconcat("0x", value, NULL);
+ g_key_file_set_string(key_file, "LongTermKey", "Key", str);
+ g_free(str);
+
+ g_key_file_set_integer(key_file, "LongTermKey", "Authenticated", auth);
+ g_key_file_set_integer(key_file, "LongTermKey", "Master", master);
+ g_key_file_set_integer(key_file, "LongTermKey", "EncSize", enc_size);
+ g_key_file_set_integer(key_file, "LongTermKey", "EDiv", ediv);
+
+ str = g_strconcat("0x", rand_str, NULL);
+ g_key_file_set_string(key_file, "LongTermKey", "Rand", str);
+ g_free(str);
+}
+
static void convert_entry(char *key, char *value, void *user_data)
{
struct device_converter *converter = user_data;
@@ -2766,6 +2806,9 @@ static void convert_device_storage(struct btd_adapter *adapter)
/* Convert linkkeys */
convert_file("linkkeys", address, convert_linkkey_entry, TRUE);
+ /* Convert longtermkeys */
+ convert_file("longtermkeys", address, convert_ltk_entry, TRUE);
+
/* Convert classes */
convert_file("classes", address, convert_classes_entry, FALSE);
--
1.7.9.5
^ permalink raw reply related
* [RFC V3 09/12] event: Store link key infos in device info file
From: Frédéric Danis @ 2012-11-30 14:47 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354286826-24016-1-git-send-email-frederic.danis@linux.intel.com>
---
src/event.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 47 insertions(+), 12 deletions(-)
diff --git a/src/event.c b/src/event.c
index 7fc8f02..5e83c09 100644
--- a/src/event.c
+++ b/src/event.c
@@ -354,33 +354,68 @@ static int store_longtermkey(bdaddr_t *local, bdaddr_t *peer,
return err;
}
+static void store_link_key(struct btd_adapter *adapter,
+ struct btd_device *device, uint8_t *key,
+ uint8_t type, uint8_t pin_length)
+{
+ char adapter_addr[18];
+ char device_addr[18];
+ char filename[PATH_MAX + 1];
+ GKeyFile *key_file;
+ char key_str[35];
+ char *str;
+ int i;
+ gsize length = 0;
+
+ ba2str(adapter_get_address(adapter), adapter_addr);
+ ba2str(device_get_address(device), device_addr);
+
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", adapter_addr,
+ device_addr);
+ filename[PATH_MAX] = '\0';
+
+ key_file = g_key_file_new();
+ g_key_file_load_from_file(key_file, filename, 0, NULL);
+
+ key_str[0] = '0';
+ key_str[1] = 'x';
+ for (i = 0; i < 16; i++)
+ sprintf(key_str + 2 + (i * 2), "%2.2X", key[i]);
+
+ g_key_file_set_string(key_file, "LinkKey", "Key", key_str);
+
+ g_key_file_set_integer(key_file, "LinkKey", "Type", type);
+ g_key_file_set_integer(key_file, "LinkKey", "PINLength", pin_length);
+
+ create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+ str = g_key_file_to_data(key_file, &length, NULL);
+ g_file_set_contents(filename, str, length, NULL);
+ g_free(str);
+
+ g_key_file_free(key_file);
+}
+
int btd_event_link_key_notify(bdaddr_t *local, bdaddr_t *peer,
uint8_t *key, uint8_t key_type,
uint8_t pin_length)
{
struct btd_adapter *adapter;
struct btd_device *device;
- uint8_t peer_type;
- int ret;
if (!get_adapter_and_device(local, peer, &adapter, &device, TRUE))
return -ENODEV;
DBG("storing link key of type 0x%02x", key_type);
- peer_type = device_get_addr_type(device);
+ store_link_key(adapter, device, key, key_type, pin_length);
- ret = write_link_key(local, peer, peer_type, key, key_type,
- pin_length);
+ device_set_bonded(device, TRUE);
- if (ret == 0) {
- device_set_bonded(device, TRUE);
-
- if (device_is_temporary(device))
- device_set_temporary(device, FALSE);
- }
+ if (device_is_temporary(device))
+ device_set_temporary(device, FALSE);
- return ret;
+ return 0;
}
int btd_event_ltk_notify(bdaddr_t *local, bdaddr_t *peer, uint8_t bdaddr_type,
--
1.7.9.5
^ permalink raw reply related
* [RFC V3 08/12] adapter: Upload link keys from new storage
From: Frédéric Danis @ 2012-11-30 14:47 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354286826-24016-1-git-send-email-frederic.danis@linux.intel.com>
Remove read_link_key() from device_create, this moves to load_devices.
---
src/adapter.c | 110 +++++++++++++++++++++++++--------------------------------
src/device.c | 6 ----
2 files changed, 49 insertions(+), 67 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index bf20580..17f478c 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1766,31 +1766,26 @@ static int str2buf(const char *str, uint8_t *buf, size_t blen)
return 0;
}
-static struct link_key_info *get_key_info(const char *addr, const char *value)
+static struct link_key_info *get_key_info(GKeyFile *key_file, const char *peer)
{
- struct link_key_info *info;
- char tmp[3];
- long int l;
+ struct link_key_info *info = NULL;
+ char *str;
- if (strlen(value) < 36) {
- error("Unexpectedly short (%zu) link key line", strlen(value));
- return NULL;
- }
+ str = g_key_file_get_string(key_file, "LinkKey", "Key", NULL);
+ if (!str || strlen(str) != 34)
+ goto failed;
info = g_new0(struct link_key_info, 1);
- str2ba(addr, &info->bdaddr);
-
- str2buf(value, info->key, sizeof(info->key));
+ str2ba(peer, &info->bdaddr);
+ str2buf(&str[2], info->key, sizeof(info->key));
- memcpy(tmp, value + 33, 2);
- info->type = (uint8_t) strtol(tmp, NULL, 10);
+ info->type = g_key_file_get_integer(key_file, "LinkKey", "Type", NULL);
+ info->pin_len = g_key_file_get_integer(key_file, "LinkKey", "PINLength",
+ NULL);
- memcpy(tmp, value + 35, 2);
- l = strtol(tmp, NULL, 10);
- if (l < 0)
- l = 0;
- info->pin_len = l;
+failed:
+ g_free(str);
return info;
}
@@ -1831,34 +1826,6 @@ static struct smp_ltk_info *get_ltk_info(const char *addr, uint8_t bdaddr_type,
return ltk;
}
-static void create_stored_device_from_linkkeys(char *key, char *value,
- void *user_data)
-{
- char address[18];
- uint8_t bdaddr_type;
- struct adapter_keys *keys = user_data;
- struct btd_adapter *adapter = keys->adapter;
- struct btd_device *device;
- struct link_key_info *info;
-
- if (sscanf(key, "%17s#%hhu", address, &bdaddr_type) < 2)
- bdaddr_type = BDADDR_BREDR;
-
- info = get_key_info(address, value);
- if (info)
- keys->keys = g_slist_append(keys->keys, info);
-
- if (g_slist_find_custom(adapter->devices, address,
- (GCompareFunc) device_address_cmp))
- return;
-
- device = device_create(adapter, address, bdaddr_type);
- if (device) {
- device_set_temporary(device, FALSE);
- adapter->devices = g_slist_append(adapter->devices, device);
- }
-}
-
static void create_stored_device_from_ltks(char *key, char *value,
void *user_data)
{
@@ -1994,18 +1961,6 @@ static void load_devices(struct btd_adapter *adapter)
textfile_foreach(filename, create_stored_device_from_primaries,
adapter);
- create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, "linkkeys");
- textfile_foreach(filename, create_stored_device_from_linkkeys, &keys);
-
- err = mgmt_load_link_keys(adapter->dev_id, keys.keys,
- main_opts.debug_keys);
- if (err < 0)
- error("Unable to load link keys: %s (%d)",
- strerror(-err), -err);
-
- g_slist_free_full(keys.keys, g_free);
- keys.keys = NULL;
-
create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, "longtermkeys");
textfile_foreach(filename, create_stored_device_from_ltks, &keys);
@@ -2027,13 +1982,32 @@ static void load_devices(struct btd_adapter *adapter)
while ((entry = readdir(dir)) != NULL) {
struct btd_device *device;
+ char filename[PATH_MAX + 1];
+ GKeyFile *key_file;
+ struct link_key_info *key_info;
+ GSList *l;
if (entry->d_type != DT_DIR || bachk(entry->d_name) < 0)
continue;
- if (g_slist_find_custom(adapter->devices, entry->d_name,
- (GCompareFunc) device_address_cmp))
- continue;
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", srcaddr,
+ entry->d_name);
+
+ key_file = g_key_file_new();
+ g_key_file_load_from_file(key_file, filename, 0, NULL);
+
+ key_info = get_key_info(key_file, entry->d_name);
+ if (key_info)
+ keys.keys = g_slist_append(keys.keys, key_info);
+
+ g_key_file_free(key_file);
+
+ l = g_slist_find_custom(adapter->devices, entry->d_name,
+ (GCompareFunc) device_address_cmp);
+ if (l) {
+ device = l->data;
+ goto device_exist;
+ }
device = device_create(adapter, entry->d_name, BDADDR_BREDR);
if (!device)
@@ -2041,9 +2015,23 @@ static void load_devices(struct btd_adapter *adapter)
device_set_temporary(device, FALSE);
adapter->devices = g_slist_append(adapter->devices, device);
+
+device_exist:
+ if (key_info) {
+ device_set_paired(device, TRUE);
+ device_set_bonded(device, TRUE);
+ }
}
closedir(dir);
+
+ err = mgmt_load_link_keys(adapter->dev_id, keys.keys,
+ main_opts.debug_keys);
+ if (err < 0)
+ error("Unable to load link keys: %s (%d)",
+ strerror(-err), -err);
+
+ g_slist_free_full(keys.keys, g_free);
}
int btd_adapter_block_address(struct btd_adapter *adapter,
diff --git a/src/device.c b/src/device.c
index 1db8a48..bb5689b 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1904,12 +1904,6 @@ struct btd_device *device_create(struct btd_adapter *adapter,
load_info(device, srcaddr, address);
- if (read_link_key(src, &device->bdaddr, device->bdaddr_type, NULL,
- NULL) == 0) {
- device_set_paired(device, TRUE);
- device_set_bonded(device, TRUE);
- }
-
if (device_is_le(device) && has_longtermkeys(src, &device->bdaddr,
device->bdaddr_type)) {
device_set_paired(device, TRUE);
--
1.7.9.5
^ permalink raw reply related
* [RFC V3 07/12] adapter: Convert storage linkkeys file
From: Frédéric Danis @ 2012-11-30 14:47 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354286826-24016-1-git-send-email-frederic.danis@linux.intel.com>
---
src/adapter.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/src/adapter.c b/src/adapter.c
index f3b1c5d..bf20580 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2639,6 +2639,34 @@ static void convert_did_entry(GKeyFile *key_file, void *value)
g_key_file_set_integer(key_file, "DeviceID", "Version", val);
}
+static void convert_linkkey_entry(GKeyFile *key_file, void *value)
+{
+ char *type_str, *length_str, *str;
+ gint val;
+
+ type_str = strchr(value, ' ');
+ if (!type_str)
+ return;
+
+ *(type_str++) = 0;
+
+ length_str = strchr(type_str, ' ');
+ if (!length_str)
+ return;
+
+ *(length_str++) = 0;
+
+ str = g_strconcat("0x", value, NULL);
+ g_key_file_set_string(key_file, "LinkKey", "Key", str);
+ g_free(str);
+
+ val = strtol(type_str, NULL, 16);
+ g_key_file_set_integer(key_file, "LinkKey", "Type", val);
+
+ val = strtol(length_str, NULL, 16);
+ g_key_file_set_integer(key_file, "LinkKey", "PINLength", val);
+}
+
static void convert_entry(char *key, char *value, void *user_data)
{
struct device_converter *converter = user_data;
@@ -2747,6 +2775,9 @@ static void convert_device_storage(struct btd_adapter *adapter)
/* Convert blocked */
convert_file("blocked", address, convert_blocked_entry, TRUE);
+ /* Convert linkkeys */
+ convert_file("linkkeys", address, convert_linkkey_entry, TRUE);
+
/* Convert classes */
convert_file("classes", address, convert_classes_entry, FALSE);
--
1.7.9.5
^ permalink raw reply related
* [RFC V3 06/12] adapter: Load devices from new storage architecture
From: Frédéric Danis @ 2012-11-30 14:47 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354286826-24016-1-git-send-email-frederic.danis@linux.intel.com>
Parse storage directory and create devices from device sub-directories.
Remove create device from 'blocked' file, this is already converted.
---
src/adapter.c | 50 +++++++++++++++++++++++++++++++-------------------
1 file changed, 31 insertions(+), 19 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index c5e856d..f3b1c5d 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -35,6 +35,7 @@
#include <sys/ioctl.h>
#include <sys/file.h>
#include <sys/stat.h>
+#include <dirent.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/uuid.h>
@@ -1893,23 +1894,6 @@ static void create_stored_device_from_ltks(char *key, char *value,
}
}
-static void create_stored_device_from_blocked(char *key, char *value,
- void *user_data)
-{
- struct btd_adapter *adapter = user_data;
- struct btd_device *device;
-
- if (g_slist_find_custom(adapter->devices,
- key, (GCompareFunc) device_address_cmp))
- return;
-
- device = device_create(adapter, key, BDADDR_BREDR);
- if (device) {
- device_set_temporary(device, FALSE);
- adapter->devices = g_slist_append(adapter->devices, device);
- }
-}
-
static GSList *string_to_primary_list(char *str)
{
GSList *l = NULL;
@@ -1997,6 +1981,8 @@ static void load_devices(struct btd_adapter *adapter)
char srcaddr[18];
struct adapter_keys keys = { adapter, NULL };
int err;
+ DIR *dir;
+ struct dirent *entry;
ba2str(&adapter->bdaddr, srcaddr);
@@ -2030,8 +2016,34 @@ static void load_devices(struct btd_adapter *adapter)
g_slist_free_full(keys.keys, smp_key_free);
keys.keys = NULL;
- create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, "blocked");
- textfile_foreach(filename, create_stored_device_from_blocked, adapter);
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s", srcaddr);
+ filename[PATH_MAX] = '\0';
+
+ dir = opendir(filename);
+ if (!dir) {
+ error("Unable to open adapter storage directory: %s", filename);
+ return;
+ }
+
+ while ((entry = readdir(dir)) != NULL) {
+ struct btd_device *device;
+
+ if (entry->d_type != DT_DIR || bachk(entry->d_name) < 0)
+ continue;
+
+ if (g_slist_find_custom(adapter->devices, entry->d_name,
+ (GCompareFunc) device_address_cmp))
+ continue;
+
+ device = device_create(adapter, entry->d_name, BDADDR_BREDR);
+ if (!device)
+ continue;
+
+ device_set_temporary(device, FALSE);
+ adapter->devices = g_slist_append(adapter->devices, device);
+ }
+
+ closedir(dir);
}
int btd_adapter_block_address(struct btd_adapter *adapter,
--
1.7.9.5
^ permalink raw reply related
* [RFC V3 05/12] adapter: Convert device type
From: Frédéric Danis @ 2012-11-30 14:46 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354286826-24016-1-git-send-email-frederic.danis@linux.intel.com>
Each time an entry is converted, check device technology and
update device info file
---
src/adapter.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 46 insertions(+), 1 deletion(-)
diff --git a/src/adapter.c b/src/adapter.c
index a976793..c5e856d 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2530,6 +2530,44 @@ struct device_converter {
gboolean force;
};
+static void set_device_type(GKeyFile *key_file, char type)
+{
+ char *techno;
+ char *addr_type = NULL;
+ char *str;
+
+ switch (type) {
+ case BDADDR_BREDR:
+ techno = "BR/EDR";
+ break;
+ case BDADDR_LE_PUBLIC:
+ techno = "LE";
+ addr_type = "public";
+ break;
+ case BDADDR_LE_RANDOM:
+ techno = "LE";
+ addr_type = "static";
+ break;
+ default:
+ return;
+ }
+
+ str = g_key_file_get_string(key_file, "General",
+ "SupportedTechnologies", NULL);
+ if (!str)
+ g_key_file_set_string(key_file, "General",
+ "SupportedTechnologies", techno);
+ else if (!strstr(str, techno))
+ g_key_file_set_string(key_file, "General",
+ "SupportedTechnologies", "BR/EDR;LE");
+
+ g_free(str);
+
+ if (addr_type)
+ g_key_file_set_string(key_file, "General", "AddressType",
+ addr_type);
+}
+
static void convert_aliases_entry(GKeyFile *key_file, void *value)
{
g_key_file_set_string(key_file, "General", "Alias", value);
@@ -2592,13 +2630,16 @@ static void convert_did_entry(GKeyFile *key_file, void *value)
static void convert_entry(char *key, char *value, void *user_data)
{
struct device_converter *converter = user_data;
+ char device_type = -1;
char filename[PATH_MAX + 1];
GKeyFile *key_file;
char *data;
gsize length = 0;
- if (key[17] == '#')
+ if (key[17] == '#') {
key[17] = '\0';
+ device_type = key[18] - '0';
+ }
if (bachk(key) != 0)
return;
@@ -2622,6 +2663,10 @@ static void convert_entry(char *key, char *value, void *user_data)
key_file = g_key_file_new();
g_key_file_load_from_file(key_file, filename, 0, NULL);
+
+ if (device_type >= 0)
+ set_device_type(key_file, device_type);
+
converter->cb(key_file, value);
data = g_key_file_to_data(key_file, &length, NULL);
--
1.7.9.5
^ permalink raw reply related
* [RFC V3 04/12] adapter: Add force dir creation to convert_file()
From: Frédéric Danis @ 2012-11-30 14:46 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1354286826-24016-1-git-send-email-frederic.danis@linux.intel.com>
Some device information, like class or device id, should only be
converted if directory for this device has already been created
during previous conversion (from aliases, trusts, blocked, ...
files).
---
src/adapter.c | 33 +++++++++++++++++++++++++--------
1 file changed, 25 insertions(+), 8 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 8e3251b..a976793 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -34,6 +34,7 @@
#include <stdbool.h>
#include <sys/ioctl.h>
#include <sys/file.h>
+#include <sys/stat.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/uuid.h>
@@ -2526,6 +2527,7 @@ static void convert_names_entry(char *key, char *value, void *user_data)
struct device_converter {
char *address;
void (*cb)(GKeyFile *key_file, void *value);
+ gboolean force;
};
static void convert_aliases_entry(GKeyFile *key_file, void *value)
@@ -2601,6 +2603,19 @@ static void convert_entry(char *key, char *value, void *user_data)
if (bachk(key) != 0)
return;
+ if (converter->force == FALSE) {
+ struct stat st;
+ int err;
+
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s",
+ converter->address, key);
+ filename[PATH_MAX] = '\0';
+
+ err = stat(filename, &st);
+ if (err || !S_ISDIR(st.st_mode))
+ return;
+ }
+
snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
converter->address, key);
filename[PATH_MAX] = '\0';
@@ -2621,7 +2636,8 @@ static void convert_entry(char *key, char *value, void *user_data)
}
static void convert_file(char *file, char *address,
- void (*cb)(GKeyFile *key_file, void *value))
+ void (*cb)(GKeyFile *key_file, void *value),
+ gboolean force)
{
char filename[PATH_MAX + 1];
struct device_converter converter;
@@ -2636,6 +2652,7 @@ static void convert_file(char *file, char *address,
} else {
converter.address = address;
converter.cb = cb;
+ converter.force = force;
textfile_foreach(filename, convert_entry, &converter);
textfile_put(filename, "converted", "yes");
@@ -2665,19 +2682,19 @@ static void convert_device_storage(struct btd_adapter *adapter)
free(str);
/* Convert aliases */
- convert_file("aliases", address, convert_aliases_entry);
+ convert_file("aliases", address, convert_aliases_entry, TRUE);
/* Convert trusts */
- convert_file("trusts", address, convert_trusts_entry);
-
- /* Convert classes */
- convert_file("classes", address, convert_classes_entry);
+ convert_file("trusts", address, convert_trusts_entry, TRUE);
/* Convert blocked */
- convert_file("blocked", address, convert_blocked_entry);
+ convert_file("blocked", address, convert_blocked_entry, TRUE);
+
+ /* Convert classes */
+ convert_file("classes", address, convert_classes_entry, FALSE);
/* Convert device ids */
- convert_file("did", address, convert_did_entry);
+ convert_file("did", address, convert_did_entry, FALSE);
}
static void convert_config(struct btd_adapter *adapter, const char *filename,
--
1.7.9.5
^ 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