2012-10-24 14:34:02

by Frederic Danis

[permalink] [raw]
Subject: [PATCH v7 00/16] Move storage config and names files to ini-file format

Adapter saved configuration will be saved to /var/lib/bluetooth/<adapter address>/settings
in ini-file format for BlueZ 5.
Devices name cache will be saved in 1 file per device (named by device address)
under /var/lib/bluetooth/<adapter address>/cache/ directory.
If this files does not exist, we try to convert legacy files to this new format.

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

Patches 2 to 8 remove access to config file from run-time.
Patch 9 moves to ini-file format style (load, save and convert).
Patches 11 to 16 move devices name cache to new files (read, write and convert).

Frédéric Danis (16):
doc: Add settings storage documentation
adapter: Read name in storage at init
adaptername: Retrieve config name from adapter
adapter: Remove device class storage
adapter: Move pairable read to load_config()
adapter: Read pairable timeout in storage at init
adapter: Read discoverable timeout in storage at init
adapter: Read mode in storage at init
adapter: Move saved config to ini-file format
TODO: Add entry to remove storage convertion function
adapter: Move storage names to cache directory
event: Remove write of LastSeen info
device: Retrieve name from cache directory
dbusoob: Store device name in cache directory
input: Retrieve device name from cache directory
hcitool: Retrieve names from cache directory

Makefile.tools | 2 +-
TODO | 6 +
doc/settings-storage.txt | 183 ++++++++++++++++++++++
plugins/adaptername.c | 6 +-
plugins/dbusoob.c | 26 +++-
plugins/neard.c | 2 +-
profiles/input/device.c | 26 +++-
src/adapter.c | 387 +++++++++++++++++++++++++++++++++++-----------
src/adapter.h | 3 +-
src/device.c | 25 ++-
src/event.c | 37 +++--
src/mgmt.c | 19 +--
src/mgmt.h | 1 +
tools/hcitool.c | 31 +++-
14 files changed, 615 insertions(+), 139 deletions(-)
create mode 100644 doc/settings-storage.txt

--
1.7.9.5



2012-10-25 09:55:53

by Johan Hedberg

[permalink] [raw]
Subject: Re: [PATCH v7 16/16] hcitool: Retrieve names from cache directory

Fr?d?ric,

On Wed, Oct 24, 2012, Fr?d?ric Danis wrote:
> static char *get_device_name(const bdaddr_t *local, const bdaddr_t *peer)
> {
> - char filename[PATH_MAX + 1], addr[18];
> + char filename[PATH_MAX + 1];
> + char local_addr[18], peer_addr[18];
> + GKeyFile *key_file;
> + char *str = NULL;
> + int len;
> +
> + ba2str(local, local_addr);
> + ba2str(peer, peer_addr);
> +
> + snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local_addr,
> + peer_addr);
> + filename[PATH_MAX] = '\0';
> + key_file = g_key_file_new();
> +
> + if (g_key_file_load_from_file(key_file, filename, 0, NULL)) {
> + str = g_key_file_get_string(key_file, "General", "Name", NULL);
> + if (str) {
> + len = strlen(str);
> + if (len > HCI_MAX_NAME_LENGTH)
> + str[HCI_MAX_NAME_LENGTH] = '\0';
> + }
> + }
>
> - ba2str(local, addr);
> - create_name(filename, PATH_MAX, STORAGEDIR, addr, "names");
> + g_key_file_free(key_file);
>
> - ba2str(peer, addr);
> - return textfile_get(filename, addr);
> + return str;
> }

This is the one exception where it's ok to directly go digging in the
cache, as we don't have the concept of btd_device in hcitool.

Johan

2012-10-25 09:55:12

by Johan Hedberg

[permalink] [raw]
Subject: Re: [PATCH v7 15/16] input: Retrieve device name from cache directory

Hi Fr?d?ric,

On Wed, Oct 24, 2012, Fr?d?ric Danis wrote:
> ---
> profiles/input/device.c | 26 ++++++++++++++++++++++----
> 1 file changed, 22 insertions(+), 4 deletions(-)
>
> diff --git a/profiles/input/device.c b/profiles/input/device.c
> index 9dd8002..41b7a5c 100644
> --- a/profiles/input/device.c
> +++ b/profiles/input/device.c
> @@ -37,6 +37,7 @@
> #include <bluetooth/sdp_lib.h>
> #include <bluetooth/uuid.h>
>
> +#include <glib.h>
> #include <gdbus.h>
>
> #include "log.h"
> @@ -757,7 +758,9 @@ static struct input_device *input_device_new(struct btd_device *device,
> {
> struct btd_adapter *adapter = device_get_adapter(device);
> struct input_device *idev;
> - char name[249], src_addr[18], dst_addr[18];
> + char src_addr[18], dst_addr[18];
> + char filename[PATH_MAX + 1];
> + GKeyFile *key_file;
>
> idev = g_new0(struct input_device, 1);
> bacpy(&idev->src, adapter_get_address(adapter));
> @@ -770,9 +773,24 @@ static struct input_device *input_device_new(struct btd_device *device,
> ba2str(&idev->src, src_addr);
> ba2str(&idev->dst, dst_addr);
>
> - if (read_device_name(src_addr, dst_addr, device_get_addr_type(device),
> - name) == 0)
> - idev->name = g_strdup(name);
> + snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", src_addr,
> + dst_addr);
> + filename[PATH_MAX] = '\0';
> + key_file = g_key_file_new();
> +
> + if (g_key_file_load_from_file(key_file, filename, 0, NULL)) {
> + int len;
> +
> + idev->name = g_key_file_get_string(key_file, "General",
> + "Name", NULL);
> + if (idev->name) {
> + len = strlen(idev->name);
> + if (len > HCI_MAX_NAME_LENGTH)
> + idev->name[HCI_MAX_NAME_LENGTH] = '\0';
> + }
> + }
> +
> + g_key_file_free(key_file);
>
> if (g_dbus_register_interface(btd_get_dbus_connection(),
> idev->path, INPUT_DEVICE_INTERFACE,

Same thing here with accessing core-daemon keyfiles directly. Just use
the btd_device_get_name function.

Johan

2012-10-25 09:54:19

by Johan Hedberg

[permalink] [raw]
Subject: Re: [PATCH v7 14/16] dbusoob: Store device name in cache directory

Hi Fr?d?ric,

On Wed, Oct 24, 2012, Fr?d?ric Danis wrote:
> ---
> plugins/dbusoob.c | 26 +++++++++++++++++++++++---
> 1 file changed, 23 insertions(+), 3 deletions(-)
>
> diff --git a/plugins/dbusoob.c b/plugins/dbusoob.c
> index 5c5b6ef..82d512c 100644
> --- a/plugins/dbusoob.c
> +++ b/plugins/dbusoob.c
> @@ -31,6 +31,7 @@
>
> #include <errno.h>
> #include <gdbus.h>
> +#include <sys/stat.h>
>
> #include <bluetooth/bluetooth.h>
> #include <bluetooth/hci.h>
> @@ -194,6 +195,11 @@ static gboolean parse_data(DBusMessageIter *data, struct oob_data *remote_data)
> static gboolean store_data(struct btd_adapter *adapter, struct oob_data *data)
> {
> bdaddr_t bdaddr;
> + char filename[PATH_MAX + 1];
> + char s_addr[18];
> + GKeyFile *key_file;
> + char *str;
> + gsize length = 0;
>
> str2ba(data->addr, &bdaddr);
>
> @@ -207,9 +213,23 @@ static gboolean store_data(struct btd_adapter *adapter, struct oob_data *data)
> write_remote_class(adapter_get_address(adapter), &bdaddr,
> data->class);
>
> - if (data->name)
> - write_device_name(adapter_get_address(adapter), &bdaddr, 0,
> - data->name);
> + if (data->name) {
> + ba2str(adapter_get_address(adapter), s_addr);
> + snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s",
> + s_addr, data->addr);
> + filename[PATH_MAX] = '\0';
> + create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
> +
> + key_file = g_key_file_new();
> + g_key_file_load_from_file(key_file, filename, 0, NULL);
> + g_key_file_set_string(key_file, "General", "Name", data->name);
> +
> + 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);
> + }

There shouldn't this kind of core-daemon keyfile access from plugins, In
this case you should get a btd_device object and simply do a
btd_device_set_name (and if that function doesn't yet write to storage
update it so that it does).

Johan

2012-10-25 09:52:12

by Johan Hedberg

[permalink] [raw]
Subject: Re: [PATCH v7 13/16] device: Retrieve name from cache directory

Hi Fr?d?ric,

On Wed, Oct 24, 2012, Fr?d?ric Danis wrote:
> ---
> src/device.c | 25 ++++++++++++++++++++++++-
> 1 file changed, 24 insertions(+), 1 deletion(-)

I've applied patches 1-12 since they seemed fine to me but there are
some things to consider with 13-16:

> --- a/src/device.c
> +++ b/src/device.c
> @@ -1573,6 +1573,8 @@ struct btd_device *device_create(struct btd_adapter *adapter,
> const bdaddr_t *src;
> char srcaddr[18], alias[MAX_NAME_LENGTH + 1];
> uint16_t vendor, product, version;
> + char filename[PATH_MAX + 1];
> + GKeyFile *key_file;
>
> device = g_try_malloc0(sizeof(struct btd_device));
> if (device == NULL)
> @@ -1600,7 +1602,28 @@ struct btd_device *device_create(struct btd_adapter *adapter,
> src = adapter_get_address(adapter);
> ba2str(src, srcaddr);
>
> - read_device_name(srcaddr, address, bdaddr_type, device->name);
> + snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", srcaddr,
> + address);
> + filename[PATH_MAX] = '\0';
> + key_file = g_key_file_new();
> +
> + if (g_key_file_load_from_file(key_file, filename, 0, NULL)) {
> + char *str;
> + int len;
> +
> + str = g_key_file_get_string(key_file, "General", "Name", NULL);
> + if (str) {
> + len = strlen(str);
> + if (len > HCI_MAX_NAME_LENGTH)
> + str[HCI_MAX_NAME_LENGTH] = '\0';
> +
> + strcpy(device->name, str);
> + g_free(str);
> + }
> + }
> +
> + g_key_file_free(key_file);
> +

I'd rather have you split off a separate function to load the config
like you have for adapters.

Regarding the device name, I think the idea is that removing the cache
shouldn't cause any bad behavior with the persistent part of the storage
(i.e. configured devices). So we should probably also have the name in
the per-device storage file and try to read it from there first and if
that fails fall back to the cache.

Johan

2012-10-24 14:34:18

by Frederic Danis

[permalink] [raw]
Subject: [PATCH v7 16/16] hcitool: Retrieve names from cache directory

---
Makefile.tools | 2 +-
tools/hcitool.c | 31 ++++++++++++++++++++++++++-----
2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/Makefile.tools b/Makefile.tools
index ec79cea..f7c85ef 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -28,7 +28,7 @@ tools_hciconfig_LDADD = lib/libbluetooth-private.la

tools_hcitool_SOURCES = tools/hcitool.c src/oui.h src/oui.c \
src/textfile.h src/textfile.c
-tools_hcitool_LDADD = lib/libbluetooth-private.la
+tools_hcitool_LDADD = lib/libbluetooth-private.la @GLIB_LIBS@

tools_sdptool_SOURCES = tools/sdptool.c src/sdp-xml.h src/sdp-xml.c
tools_sdptool_LDADD = lib/libbluetooth-private.la @GLIB_LIBS@
diff --git a/tools/hcitool.c b/tools/hcitool.c
index aefbd68..a05e31f 100644
--- a/tools/hcitool.c
+++ b/tools/hcitool.c
@@ -40,6 +40,8 @@
#include <sys/socket.h>
#include <signal.h>

+#include <glib.h>
+
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
@@ -409,13 +411,32 @@ static char *major_classes[] = {

static char *get_device_name(const bdaddr_t *local, const bdaddr_t *peer)
{
- char filename[PATH_MAX + 1], addr[18];
+ char filename[PATH_MAX + 1];
+ char local_addr[18], peer_addr[18];
+ GKeyFile *key_file;
+ char *str = NULL;
+ int len;
+
+ ba2str(local, local_addr);
+ ba2str(peer, peer_addr);
+
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local_addr,
+ peer_addr);
+ filename[PATH_MAX] = '\0';
+ key_file = g_key_file_new();
+
+ if (g_key_file_load_from_file(key_file, filename, 0, NULL)) {
+ str = g_key_file_get_string(key_file, "General", "Name", NULL);
+ if (str) {
+ len = strlen(str);
+ if (len > HCI_MAX_NAME_LENGTH)
+ str[HCI_MAX_NAME_LENGTH] = '\0';
+ }
+ }

- ba2str(local, addr);
- create_name(filename, PATH_MAX, STORAGEDIR, addr, "names");
+ g_key_file_free(key_file);

- ba2str(peer, addr);
- return textfile_get(filename, addr);
+ return str;
}

/* Display local devices */
--
1.7.9.5


2012-10-24 14:34:17

by Frederic Danis

[permalink] [raw]
Subject: [PATCH v7 15/16] input: Retrieve device name from cache directory

---
profiles/input/device.c | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/profiles/input/device.c b/profiles/input/device.c
index 9dd8002..41b7a5c 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -37,6 +37,7 @@
#include <bluetooth/sdp_lib.h>
#include <bluetooth/uuid.h>

+#include <glib.h>
#include <gdbus.h>

#include "log.h"
@@ -757,7 +758,9 @@ static struct input_device *input_device_new(struct btd_device *device,
{
struct btd_adapter *adapter = device_get_adapter(device);
struct input_device *idev;
- char name[249], src_addr[18], dst_addr[18];
+ char src_addr[18], dst_addr[18];
+ char filename[PATH_MAX + 1];
+ GKeyFile *key_file;

idev = g_new0(struct input_device, 1);
bacpy(&idev->src, adapter_get_address(adapter));
@@ -770,9 +773,24 @@ static struct input_device *input_device_new(struct btd_device *device,
ba2str(&idev->src, src_addr);
ba2str(&idev->dst, dst_addr);

- if (read_device_name(src_addr, dst_addr, device_get_addr_type(device),
- name) == 0)
- idev->name = g_strdup(name);
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", src_addr,
+ dst_addr);
+ filename[PATH_MAX] = '\0';
+ key_file = g_key_file_new();
+
+ if (g_key_file_load_from_file(key_file, filename, 0, NULL)) {
+ int len;
+
+ idev->name = g_key_file_get_string(key_file, "General",
+ "Name", NULL);
+ if (idev->name) {
+ len = strlen(idev->name);
+ if (len > HCI_MAX_NAME_LENGTH)
+ idev->name[HCI_MAX_NAME_LENGTH] = '\0';
+ }
+ }
+
+ g_key_file_free(key_file);

if (g_dbus_register_interface(btd_get_dbus_connection(),
idev->path, INPUT_DEVICE_INTERFACE,
--
1.7.9.5


2012-10-24 14:34:16

by Frederic Danis

[permalink] [raw]
Subject: [PATCH v7 14/16] dbusoob: Store device name in cache directory

---
plugins/dbusoob.c | 26 +++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/plugins/dbusoob.c b/plugins/dbusoob.c
index 5c5b6ef..82d512c 100644
--- a/plugins/dbusoob.c
+++ b/plugins/dbusoob.c
@@ -31,6 +31,7 @@

#include <errno.h>
#include <gdbus.h>
+#include <sys/stat.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
@@ -194,6 +195,11 @@ static gboolean parse_data(DBusMessageIter *data, struct oob_data *remote_data)
static gboolean store_data(struct btd_adapter *adapter, struct oob_data *data)
{
bdaddr_t bdaddr;
+ char filename[PATH_MAX + 1];
+ char s_addr[18];
+ GKeyFile *key_file;
+ char *str;
+ gsize length = 0;

str2ba(data->addr, &bdaddr);

@@ -207,9 +213,23 @@ static gboolean store_data(struct btd_adapter *adapter, struct oob_data *data)
write_remote_class(adapter_get_address(adapter), &bdaddr,
data->class);

- if (data->name)
- write_device_name(adapter_get_address(adapter), &bdaddr, 0,
- data->name);
+ if (data->name) {
+ ba2str(adapter_get_address(adapter), s_addr);
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s",
+ s_addr, data->addr);
+ filename[PATH_MAX] = '\0';
+ create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+ key_file = g_key_file_new();
+ g_key_file_load_from_file(key_file, filename, 0, NULL);
+ g_key_file_set_string(key_file, "General", "Name", data->name);
+
+ 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);
+ }

return TRUE;
}
--
1.7.9.5


2012-10-24 14:34:15

by Frederic Danis

[permalink] [raw]
Subject: [PATCH v7 13/16] device: Retrieve name from cache directory

---
src/device.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/src/device.c b/src/device.c
index bc7f8dd..4e0ac58 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1573,6 +1573,8 @@ struct btd_device *device_create(struct btd_adapter *adapter,
const bdaddr_t *src;
char srcaddr[18], alias[MAX_NAME_LENGTH + 1];
uint16_t vendor, product, version;
+ char filename[PATH_MAX + 1];
+ GKeyFile *key_file;

device = g_try_malloc0(sizeof(struct btd_device));
if (device == NULL)
@@ -1600,7 +1602,28 @@ struct btd_device *device_create(struct btd_adapter *adapter,
src = adapter_get_address(adapter);
ba2str(src, srcaddr);

- read_device_name(srcaddr, address, bdaddr_type, device->name);
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", srcaddr,
+ address);
+ filename[PATH_MAX] = '\0';
+ key_file = g_key_file_new();
+
+ if (g_key_file_load_from_file(key_file, filename, 0, NULL)) {
+ char *str;
+ int len;
+
+ str = g_key_file_get_string(key_file, "General", "Name", NULL);
+ if (str) {
+ len = strlen(str);
+ if (len > HCI_MAX_NAME_LENGTH)
+ str[HCI_MAX_NAME_LENGTH] = '\0';
+
+ strcpy(device->name, str);
+ g_free(str);
+ }
+ }
+
+ g_key_file_free(key_file);
+
if (read_device_alias(srcaddr, address, bdaddr_type, alias,
sizeof(alias)) == 0)
device->alias = g_strdup(alias);
--
1.7.9.5


2012-10-24 14:34:14

by Frederic Danis

[permalink] [raw]
Subject: [PATCH v7 12/16] event: Remove write of LastSeen info

---
src/event.c | 13 -------------
1 file changed, 13 deletions(-)

diff --git a/src/event.c b/src/event.c
index 3c43135..d7daed2 100644
--- a/src/event.c
+++ b/src/event.c
@@ -221,17 +221,6 @@ void btd_event_simple_pairing_complete(bdaddr_t *local, bdaddr_t *peer,
device_simple_pairing_complete(device, status);
}

-static void update_lastseen(bdaddr_t *sba, bdaddr_t *dba, uint8_t dba_type)
-{
- time_t t;
- struct tm *tm;
-
- t = time(NULL);
- tm = gmtime(&t);
-
- write_lastseen_info(sba, dba, dba_type, tm);
-}
-
static void update_lastused(bdaddr_t *sba, bdaddr_t *dba, uint8_t dba_type)
{
time_t t;
@@ -256,8 +245,6 @@ void btd_event_device_found(bdaddr_t *local, bdaddr_t *peer, uint8_t bdaddr_type
return;
}

- update_lastseen(local, peer, bdaddr_type);
-
adapter_update_found_devices(adapter, peer, bdaddr_type, rssi,
confirm_name, legacy, data, data_len);
}
--
1.7.9.5


2012-10-24 14:34:13

by Frederic Danis

[permalink] [raw]
Subject: [PATCH v7 11/16] adapter: Move storage names to cache directory

---
src/adapter.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
src/event.c | 24 ++++++++++++++---
2 files changed, 99 insertions(+), 6 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index ecdc948..8e6cbaa 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2493,6 +2493,58 @@ void btd_adapter_unref(struct btd_adapter *adapter)
g_free(path);
}

+static void convert_names_entry(char *key, char *value, void *user_data)
+{
+ char *address = user_data;
+ char filename[PATH_MAX + 1];
+ char *str = key;
+ GKeyFile *key_file;
+ char *data;
+ gsize length = 0;
+
+ if (strchr(key, '#'))
+ str[17] = '\0';
+
+ if (bachk(str) != 0)
+ return;
+
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", address, str);
+ filename[PATH_MAX] = '\0';
+ create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+ key_file = g_key_file_new();
+ g_key_file_load_from_file(key_file, filename, 0, NULL);
+ g_key_file_set_string(key_file, "General", "Name", value);
+
+ data = g_key_file_to_data(key_file, &length, NULL);
+ g_file_set_contents(filename, data, length, NULL);
+ g_free(data);
+
+ g_key_file_free(key_file);
+}
+
+static void convert_device_storage(struct btd_adapter *adapter)
+{
+ char filename[PATH_MAX + 1];
+ char address[18];
+ char *str;
+
+ ba2str(&adapter->bdaddr, address);
+
+ /* Convert device's name cache */
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/names", address);
+ filename[PATH_MAX] = '\0';
+
+ str = textfile_get(filename, "converted");
+ if (str && strcmp(str, "yes") == 0) {
+ DBG("Legacy names file already converted");
+ } else {
+ textfile_foreach(filename, convert_names_entry, address);
+ textfile_put(filename, "converted", "yes");
+ }
+ free(str);
+}
+
static void convert_config(struct btd_adapter *adapter, const char *filename,
GKeyFile *key_file)
{
@@ -2654,6 +2706,7 @@ gboolean adapter_init(struct btd_adapter *adapter, gboolean up)
btd_adapter_gatt_server_start(adapter);

load_config(adapter);
+ convert_device_storage(adapter);
load_drivers(adapter);
btd_profile_foreach(probe_profile, adapter);
clear_blocked(adapter);
@@ -2935,9 +2988,31 @@ void adapter_update_found_devices(struct btd_adapter *adapter,
write_remote_appearance(&adapter->bdaddr, bdaddr, bdaddr_type,
eir_data.appearance);

- if (eir_data.name != NULL && eir_data.name_complete)
- write_device_name(&adapter->bdaddr, bdaddr, bdaddr_type,
- eir_data.name);
+ if (eir_data.name != NULL && eir_data.name_complete) {
+ char filename[PATH_MAX + 1];
+ char s_addr[18], d_addr[18];
+ GKeyFile *key_file;
+ char *data;
+ gsize length = 0;
+
+ ba2str(&adapter->bdaddr, s_addr);
+ ba2str(bdaddr, d_addr);
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s",
+ s_addr, d_addr);
+ filename[PATH_MAX] = '\0';
+ create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+ key_file = g_key_file_new();
+ g_key_file_load_from_file(key_file, filename, 0, NULL);
+ g_key_file_set_string(key_file, "General", "Name",
+ eir_data.name);
+
+ data = g_key_file_to_data(key_file, &length, NULL);
+ g_file_set_contents(filename, data, length, NULL);
+ g_free(data);
+
+ g_key_file_free(key_file);
+ }

/* Avoid creating LE device if it's not discoverable */
if (bdaddr_type != BDADDR_BREDR &&
diff --git a/src/event.c b/src/event.c
index 48aeffd..3c43135 100644
--- a/src/event.c
+++ b/src/event.c
@@ -34,6 +34,7 @@
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
+#include <sys/stat.h>

#include <bluetooth/bluetooth.h>

@@ -265,7 +266,11 @@ void btd_event_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name)
{
struct btd_adapter *adapter;
struct btd_device *device;
- uint8_t peer_type;
+ char filename[PATH_MAX + 1];
+ char local_addr[18], peer_addr[18];
+ GKeyFile *key_file;
+ char *data;
+ gsize length = 0;

if (!g_utf8_validate(name, -1, NULL)) {
int i;
@@ -282,9 +287,22 @@ void btd_event_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name)
if (!get_adapter_and_device(local, peer, &adapter, &device, FALSE))
return;

- peer_type = device_get_addr_type(device);
+ ba2str(local, local_addr);
+ ba2str(peer, peer_addr);
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local_addr,
+ peer_addr);
+ filename[PATH_MAX] = '\0';
+ create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+ key_file = g_key_file_new();
+ g_key_file_load_from_file(key_file, filename, 0, NULL);
+ g_key_file_set_string(key_file, "General", "Name", name);
+
+ data = g_key_file_to_data(key_file, &length, NULL);
+ g_file_set_contents(filename, data, length, NULL);
+ g_free(data);

- write_device_name(local, peer, peer_type, name);
+ g_key_file_free(key_file);

if (device)
device_set_name(device, name);
--
1.7.9.5


2012-10-24 14:34:11

by Frederic Danis

[permalink] [raw]
Subject: [PATCH v7 09/16] adapter: Move saved config to ini-file format

Read and write config file in ini-file format.
If the file can not be loaded, try to convert legacy configuration.
---
src/adapter.c | 206 ++++++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 168 insertions(+), 38 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index a2a5da9..ecdc948 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -33,6 +33,7 @@
#include <stdlib.h>
#include <stdbool.h>
#include <sys/ioctl.h>
+#include <sys/file.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/uuid.h>
@@ -83,6 +84,8 @@
#define REMOVE_TEMP_TIMEOUT (3 * 60)
#define PENDING_FOUND_MAX 5

+#define SETTINGS_PATH STORAGEDIR "/%s/settings"
+
static GSList *adapter_drivers = NULL;

enum session_req_type {
@@ -209,6 +212,49 @@ static uint8_t get_mode(const char *mode)
return MODE_UNKNOWN;
}

+static void store_adapter_info(struct btd_adapter *adapter)
+{
+ GKeyFile *key_file;
+ char filename[PATH_MAX + 1];
+ char address[18];
+ char *str;
+ gsize length = 0;
+
+ key_file = g_key_file_new();
+
+ g_key_file_set_string(key_file, "General", "Name", adapter->name);
+
+ g_key_file_set_boolean(key_file, "General", "Powered",
+ adapter->mode > MODE_OFF);
+
+ g_key_file_set_boolean(key_file, "General", "Pairable",
+ adapter->pairable);
+
+ if (adapter->pairable_timeout != main_opts.pairto)
+ g_key_file_set_integer(key_file, "General", "PairableTimeout",
+ adapter->pairable_timeout);
+
+ g_key_file_set_boolean(key_file, "General", "Discoverable",
+ adapter->discoverable);
+
+ if (adapter->discov_timeout != main_opts.discovto)
+ g_key_file_set_integer(key_file, "General",
+ "DiscoverableTimeout",
+ adapter->discov_timeout);
+
+ ba2str(&adapter->bdaddr, address);
+ snprintf(filename, PATH_MAX, SETTINGS_PATH, address);
+ filename[PATH_MAX] = '\0';
+
+ 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);
+}
+
static struct session_req *session_ref(struct session_req *req)
{
req->refcount++;
@@ -278,7 +324,6 @@ static struct session_req *find_session_by_msg(GSList *list, const DBusMessage *
static int set_mode(struct btd_adapter *adapter, uint8_t new_mode)
{
int err;
- const char *modestr;

if (adapter->pending_mode != NULL)
return -EALREADY;
@@ -310,10 +355,9 @@ static int set_mode(struct btd_adapter *adapter, uint8_t new_mode)
return err;

done:
- modestr = mode2str(new_mode);
- write_device_mode(&adapter->bdaddr, modestr);
+ store_adapter_info(adapter);

- DBG("%s", modestr);
+ DBG("%s", mode2str(new_mode));

return 0;
}
@@ -448,7 +492,7 @@ void btd_adapter_pairable_changed(struct btd_adapter *adapter,
{
adapter->pairable = pairable;

- write_device_pairable(&adapter->bdaddr, pairable);
+ store_adapter_info(adapter);

g_dbus_emit_property_changed(btd_get_dbus_connection(), adapter->path,
ADAPTER_INTERFACE, "Pairable");
@@ -710,7 +754,7 @@ static void set_discoverable_timeout(struct btd_adapter *adapter,

adapter->discov_timeout = timeout;

- write_discoverable_timeout(&adapter->bdaddr, timeout);
+ store_adapter_info(adapter);

g_dbus_emit_property_changed(conn, adapter->path, ADAPTER_INTERFACE,
"DiscoverableTimeout");
@@ -730,7 +774,7 @@ static void set_pairable_timeout(struct btd_adapter *adapter,

adapter->pairable_timeout = timeout;

- write_pairable_timeout(&adapter->bdaddr, timeout);
+ store_adapter_info(adapter);

g_dbus_emit_property_changed(conn, adapter->path, ADAPTER_INTERFACE,
"PairableTimeout");
@@ -801,7 +845,7 @@ int adapter_set_name(struct btd_adapter *adapter, const char *name)
adapter->name = g_strdup(maxname);
}

- write_local_name(&adapter->bdaddr, maxname);
+ store_adapter_info(adapter);

return 0;
}
@@ -2284,13 +2328,11 @@ static void set_mode_complete(struct btd_adapter *adapter)
{
DBusConnection *conn = btd_get_dbus_connection();
struct session_req *pending;
- const char *modestr;
int err;

- modestr = mode2str(adapter->mode);
- write_device_mode(&adapter->bdaddr, modestr);
+ store_adapter_info(adapter);

- DBG("%s", modestr);
+ DBG("%s", mode2str(adapter->mode));

if (adapter->mode == MODE_OFF) {
g_slist_free_full(adapter->mode_sessions, session_free);
@@ -2451,53 +2493,141 @@ void btd_adapter_unref(struct btd_adapter *adapter)
g_free(path);
}

-static void load_config(struct btd_adapter *adapter)
+static void convert_config(struct btd_adapter *adapter, const char *filename,
+ GKeyFile *key_file)
{
- char name[MAX_NAME_LENGTH + 1];
char address[18];
- char mode[14];
+ char str[MAX_NAME_LENGTH + 1];
+ char config_path[PATH_MAX + 1];
+ char *converted;
+ gboolean flag;
int timeout;
+ uint8_t mode;
+ char *data;
+ gsize length = 0;

ba2str(&adapter->bdaddr, address);
+ snprintf(config_path, PATH_MAX, STORAGEDIR "/%s/config", address);
+ config_path[PATH_MAX] = '\0';
+
+ converted = textfile_get(config_path, "converted");
+ if (converted) {
+ if (strcmp(converted, "yes") == 0) {
+ DBG("Legacy config file already converted");
+ return;
+ }
+
+ g_free(converted);
+ }
+
+ if (read_local_name(&adapter->bdaddr, str) == 0)
+ g_key_file_set_string(key_file, "General", "Name", str);
+
+ if (read_device_pairable(&adapter->bdaddr, &flag) == 0)
+ g_key_file_set_boolean(key_file, "General", "Pairable", flag);
+
+ if (read_pairable_timeout(address, &timeout) == 0)
+ g_key_file_set_integer(key_file, "General",
+ "PairableTimeout", timeout);
+
+ if (read_discoverable_timeout(address, &timeout) == 0)
+ g_key_file_set_integer(key_file, "General",
+ "DiscoverableTimeout", timeout);
+
+ if (read_device_mode(address, str, sizeof(str)) == 0) {
+ mode = get_mode(str);
+ g_key_file_set_boolean(key_file, "General", "Powered",
+ mode > MODE_OFF);
+ }
+
+ if (read_on_mode(address, str, sizeof(str)) == 0) {
+ mode = get_mode(str);
+ g_key_file_set_boolean(key_file, "General", "Discoverable",
+ mode == MODE_DISCOVERABLE);
+ }
+
+ create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+ data = g_key_file_to_data(key_file, &length, NULL);
+ g_file_set_contents(filename, data, length, NULL);
+ g_free(data);
+
+ textfile_put(config_path, "converted", "yes");
+}
+
+static void load_config(struct btd_adapter *adapter)
+{
+ GKeyFile *key_file;
+ char filename[PATH_MAX + 1];
+ char address[18];
+ gboolean powered;
+ GError *gerr = NULL;
+
+ ba2str(&adapter->bdaddr, address);
+
+ key_file = g_key_file_new();
+
+ snprintf(filename, PATH_MAX, SETTINGS_PATH, address);
+ filename[PATH_MAX] = '\0';
+
+ if (!g_key_file_load_from_file(key_file, filename, 0, NULL))
+ convert_config(adapter, filename, key_file);

/* Get name */
- if (read_local_name(&adapter->bdaddr, name) < 0)
- adapter->name = NULL;
- else
- adapter->name = g_strdup(name);
+ adapter->name = g_key_file_get_string(key_file, "General",
+ "Name", NULL);

/* Set class */
adapter->dev_class = main_opts.class;

/* Get pairable mode */
- if (read_device_pairable(&adapter->bdaddr, &adapter->pairable) < 0)
+ adapter->pairable = g_key_file_get_boolean(key_file, "General",
+ "Pairable", &gerr);
+ if (gerr) {
adapter->pairable = TRUE;
+ g_error_free(gerr);
+ gerr = NULL;
+ }

/* Get pairable timeout */
- if (read_pairable_timeout(address, &timeout) < 0)
+ adapter->pairable_timeout = g_key_file_get_integer(key_file, "General",
+ "PairableTimeout", &gerr);
+ if (gerr) {
adapter->pairable_timeout = main_opts.pairto;
- else
- adapter->pairable_timeout = timeout;
+ g_error_free(gerr);
+ gerr = NULL;
+ }
+
+ /* Get discoverable mode */
+ adapter->discoverable = g_key_file_get_boolean(key_file, "General",
+ "Discoverable", &gerr);
+ if (gerr) {
+ adapter->discoverable = (main_opts.mode == MODE_DISCOVERABLE);
+ g_error_free(gerr);
+ gerr = NULL;
+ }

/* Get discoverable timeout */
- if (read_discoverable_timeout(address, &timeout) < 0)
+ adapter->discov_timeout = g_key_file_get_integer(key_file, "General",
+ "DiscoverableTimeout", &gerr);
+ if (gerr) {
adapter->discov_timeout = main_opts.discovto;
- else
- adapter->discov_timeout = timeout;
+ g_error_free(gerr);
+ gerr = NULL;
+ }

- /* Get mode */
- if (main_opts.remember_powered == FALSE)
- adapter->mode = main_opts.mode;
- else if (read_device_mode(address, mode, sizeof(mode)) == 0)
- adapter->mode = get_mode(mode);
- else
+ /* Get powered mode */
+ powered = g_key_file_get_boolean(key_file, "General", "Powered",
+ &gerr);
+ if (gerr) {
adapter->mode = main_opts.mode;
-
- /* Get on mode */
- if (read_on_mode(address, mode, sizeof(mode)) == 0)
- adapter->discoverable = (strcasecmp("discoverable", mode) == 0);
- else
- adapter->discoverable = (adapter->mode == MODE_DISCOVERABLE);
+ g_error_free(gerr);
+ gerr = NULL;
+ } else if (powered) {
+ adapter->mode = adapter->discoverable ? MODE_DISCOVERABLE :
+ MODE_CONNECTABLE;
+ } else
+ adapter->mode = MODE_OFF;

mgmt_set_connectable(adapter->dev_id, TRUE);
mgmt_set_discoverable(adapter->dev_id, adapter->discoverable,
--
1.7.9.5


2012-10-24 14:34:12

by Frederic Danis

[permalink] [raw]
Subject: [PATCH v7 10/16] TODO: Add entry to remove storage convertion function

---
TODO | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/TODO b/TODO
index ca72cd6..bc9bf9c 100644
--- a/TODO
+++ b/TODO
@@ -30,6 +30,12 @@ General
Priority: Low
Complexity: C1

+- Function in src/adapter.c to convert old storage files to new ini-file format
+ should be removed 6-8 months after first BlueZ 5 release.
+
+ Priority: Low
+ Complexity: C1
+
BlueZ 5
=======

--
1.7.9.5


2012-10-24 14:34:10

by Frederic Danis

[permalink] [raw]
Subject: [PATCH v7 08/16] adapter: Read mode in storage at init

Mgmt interface allows to change connectable and discoverable adapter
status even if the adapter is off. So both status are changed during
adapter init.
Remove on_mode from btd_adapter_get_mode(), as it is no more used.
Update src/mgmt.c and plugins/neard.c
---
plugins/neard.c | 2 +-
src/adapter.c | 75 +++++++++++++++++++++++++++++--------------------------
src/adapter.h | 1 -
src/mgmt.c | 17 +++----------
src/mgmt.h | 1 +
5 files changed, 45 insertions(+), 51 deletions(-)

diff --git a/plugins/neard.c b/plugins/neard.c
index 2da5024..8018977 100644
--- a/plugins/neard.c
+++ b/plugins/neard.c
@@ -376,7 +376,7 @@ static int check_adapter(struct btd_adapter *adapter)
if (btd_adapter_check_oob_handler(adapter))
return -EINPROGRESS;

- btd_adapter_get_mode(adapter, NULL, NULL, NULL, &pairable);
+ btd_adapter_get_mode(adapter, NULL, NULL, &pairable);

if (!pairable || !adapter_get_agent(adapter))
return -ENOENT;
diff --git a/src/adapter.c b/src/adapter.c
index a91e9bb..a2a5da9 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -156,6 +156,7 @@ struct btd_adapter {
guint auto_timeout_id; /* Automatic connections timeout */
sdp_list_t *services; /* Services associated to adapter */

+ gboolean discoverable; /* discoverable state */
gboolean pairable; /* pairable state */
gboolean initialized;

@@ -196,7 +197,7 @@ static const char *mode2str(uint8_t mode)
}
}

-static uint8_t get_mode(const bdaddr_t *bdaddr, const char *mode)
+static uint8_t get_mode(const char *mode)
{
if (strcasecmp("off", mode) == 0)
return MODE_OFF;
@@ -204,15 +205,7 @@ static uint8_t get_mode(const bdaddr_t *bdaddr, const char *mode)
return MODE_CONNECTABLE;
else if (strcasecmp("discoverable", mode) == 0)
return MODE_DISCOVERABLE;
- else if (strcasecmp("on", mode) == 0) {
- char onmode[14], srcaddr[18];
-
- ba2str(bdaddr, srcaddr);
- if (read_on_mode(srcaddr, onmode, sizeof(onmode)) < 0)
- return MODE_CONNECTABLE;
-
- return get_mode(bdaddr, onmode);
- } else
+ else
return MODE_UNKNOWN;
}

@@ -373,11 +366,8 @@ static void set_powered(struct btd_adapter *adapter, gboolean powered,
uint8_t mode;
int err;

- if (powered) {
- mode = get_mode(&adapter->bdaddr, "on");
- return set_discoverable(adapter, mode == MODE_DISCOVERABLE,
- id);
- }
+ if (powered)
+ return set_discoverable(adapter, adapter->discoverable, id);

mode = MODE_OFF;

@@ -1406,7 +1396,10 @@ static DBusMessage *request_session(DBusConnection *conn,
if (!adapter->mode_sessions)
adapter->global_mode = adapter->mode;

- new_mode = get_mode(&adapter->bdaddr, "on");
+ if (adapter->discoverable)
+ new_mode = MODE_DISCOVERABLE;
+ else
+ new_mode = MODE_CONNECTABLE;

req = find_session(adapter->mode_sessions, sender);
if (req) {
@@ -2120,25 +2113,15 @@ static void call_adapter_powered_callbacks(struct btd_adapter *adapter,
}

void btd_adapter_get_mode(struct btd_adapter *adapter, uint8_t *mode,
- uint8_t *on_mode,
uint16_t *discoverable_timeout,
gboolean *pairable)
{
- char str[14], address[18];
+ char address[18];

ba2str(&adapter->bdaddr, address);

- if (mode) {
- if (main_opts.remember_powered == FALSE)
- *mode = main_opts.mode;
- else if (read_device_mode(address, str, sizeof(str)) == 0)
- *mode = get_mode(&adapter->bdaddr, str);
- else
- *mode = main_opts.mode;
- }
-
- if (on_mode)
- *on_mode = get_mode(&adapter->bdaddr, "on");
+ if (mode)
+ *mode = adapter->mode;

if (discoverable_timeout)
*discoverable_timeout = adapter->discov_timeout;
@@ -2224,10 +2207,13 @@ void btd_adapter_start(struct btd_adapter *adapter)
adapter->up = TRUE;
adapter->off_timer = 0;

- if (adapter->scan_mode & SCAN_INQUIRY)
+ if (adapter->scan_mode & SCAN_INQUIRY) {
adapter->mode = MODE_DISCOVERABLE;
- else
+ adapter->discoverable = TRUE;
+ } else {
adapter->mode = MODE_CONNECTABLE;
+ adapter->discoverable = FALSE;
+ }

g_dbus_emit_property_changed(btd_get_dbus_connection(), adapter->path,
ADAPTER_INTERFACE, "Powered");
@@ -2469,6 +2455,7 @@ static void load_config(struct btd_adapter *adapter)
{
char name[MAX_NAME_LENGTH + 1];
char address[18];
+ char mode[14];
int timeout;

ba2str(&adapter->bdaddr, address);
@@ -2497,6 +2484,24 @@ static void load_config(struct btd_adapter *adapter)
adapter->discov_timeout = main_opts.discovto;
else
adapter->discov_timeout = timeout;
+
+ /* Get mode */
+ if (main_opts.remember_powered == FALSE)
+ adapter->mode = main_opts.mode;
+ else if (read_device_mode(address, mode, sizeof(mode)) == 0)
+ adapter->mode = get_mode(mode);
+ else
+ adapter->mode = main_opts.mode;
+
+ /* Get on mode */
+ if (read_on_mode(address, mode, sizeof(mode)) == 0)
+ adapter->discoverable = (strcasecmp("discoverable", mode) == 0);
+ else
+ adapter->discoverable = (adapter->mode == MODE_DISCOVERABLE);
+
+ mgmt_set_connectable(adapter->dev_id, TRUE);
+ mgmt_set_discoverable(adapter->dev_id, adapter->discoverable,
+ adapter->discov_timeout);
}

gboolean adapter_init(struct btd_adapter *adapter, gboolean up)
@@ -2877,9 +2882,11 @@ void adapter_mode_changed(struct btd_adapter *adapter, uint8_t scan_mode)
break;
case SCAN_PAGE:
adapter->mode = MODE_CONNECTABLE;
+ adapter->discoverable = FALSE;
break;
case (SCAN_PAGE | SCAN_INQUIRY):
adapter->mode = MODE_DISCOVERABLE;
+ adapter->discoverable = TRUE;
break;
default:
/* ignore, reserved */
@@ -3182,17 +3189,13 @@ gboolean adapter_powering_down(struct btd_adapter *adapter)

int btd_adapter_restore_powered(struct btd_adapter *adapter)
{
- char mode[14], address[18];
-
if (!main_opts.remember_powered)
return -EINVAL;

if (adapter->up)
return 0;

- ba2str(&adapter->bdaddr, address);
- if (read_device_mode(address, mode, sizeof(mode)) == 0 &&
- g_str_equal(mode, "off"))
+ if (adapter->mode == MODE_OFF)
return 0;

return mgmt_set_powered(adapter->dev_id, TRUE);
diff --git a/src/adapter.h b/src/adapter.h
index be69781..54f9ea7 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -81,7 +81,6 @@ void btd_adapter_start(struct btd_adapter *adapter);
int btd_adapter_stop(struct btd_adapter *adapter);

void btd_adapter_get_mode(struct btd_adapter *adapter, uint8_t *mode,
- uint8_t *on_mode,
uint16_t *discoverable_timeout,
gboolean *pairable);

diff --git a/src/mgmt.c b/src/mgmt.c
index f179dfa..8fe5100 100644
--- a/src/mgmt.c
+++ b/src/mgmt.c
@@ -207,7 +207,7 @@ static int mgmt_set_mode(int index, uint16_t opcode, uint8_t val)
return 0;
}

-static int mgmt_set_connectable(int index, gboolean connectable)
+int mgmt_set_connectable(int index, gboolean connectable)
{
DBG("index %d connectable %d", index, connectable);
return mgmt_set_mode(index, MGMT_OP_SET_CONNECTABLE, connectable);
@@ -315,27 +315,18 @@ static void update_settings(struct btd_adapter *adapter, uint32_t settings)
{
struct controller_info *info;
gboolean pairable;
- uint8_t on_mode;
uint16_t index, discoverable_timeout;

DBG("new settings %x", settings);

- btd_adapter_get_mode(adapter, NULL, &on_mode, &discoverable_timeout,
- &pairable);
+ btd_adapter_get_mode(adapter, NULL, &discoverable_timeout, &pairable);

index = adapter_get_dev_id(adapter);

info = &controllers[index];

- if (on_mode == MODE_DISCOVERABLE && !mgmt_discoverable(settings)) {
- if(!mgmt_connectable(settings))
- mgmt_set_connectable(index, TRUE);
- mgmt_set_discoverable(index, TRUE, discoverable_timeout);
- } else if (on_mode == MODE_CONNECTABLE && !mgmt_connectable(settings)) {
- mgmt_set_connectable(index, TRUE);
- } else if (mgmt_powered(settings)) {
+ if (mgmt_powered(settings))
adapter_mode_changed(adapter, create_mode(settings));
- }

if (mgmt_pairable(settings) != pairable)
mgmt_set_pairable(index, pairable);
@@ -1108,7 +1099,7 @@ static void read_info_complete(int sk, uint16_t index, void *buf, size_t len)
btd_adapter_get_major_minor(adapter, &major, &minor);
mgmt_set_dev_class(index, major, minor);

- btd_adapter_get_mode(adapter, &mode, NULL, NULL, NULL);
+ btd_adapter_get_mode(adapter, &mode, NULL, NULL);
if (mode == MODE_OFF && mgmt_powered(info->current_settings)) {
mgmt_set_powered(index, FALSE);
return;
diff --git a/src/mgmt.h b/src/mgmt.h
index a2c0497..daa168a 100644
--- a/src/mgmt.h
+++ b/src/mgmt.h
@@ -26,6 +26,7 @@ int mgmt_setup(void);
void mgmt_cleanup(void);

int mgmt_set_powered(int index, gboolean powered);
+int mgmt_set_connectable(int index, gboolean connectable);
int mgmt_set_discoverable(int index, gboolean discoverable, uint16_t timeout);
int mgmt_set_pairable(int index, gboolean pairable);
int mgmt_set_name(int index, const char *name);
--
1.7.9.5


2012-10-24 14:34:09

by Frederic Danis

[permalink] [raw]
Subject: [PATCH v7 07/16] adapter: Read discoverable timeout in storage at init

---
src/adapter.c | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 918991c..a91e9bb 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2097,16 +2097,6 @@ static void load_connections(struct btd_adapter *adapter)
g_slist_free_full(conns, g_free);
}

-static int get_discoverable_timeout(const char *src)
-{
- int timeout;
-
- if (read_discoverable_timeout(src, &timeout) == 0)
- return timeout;
-
- return main_opts.discovto;
-}
-
static void set_auto_connect(gpointer data, gpointer user_data)
{
struct btd_device *device = data;
@@ -2151,7 +2141,7 @@ void btd_adapter_get_mode(struct btd_adapter *adapter, uint8_t *mode,
*on_mode = get_mode(&adapter->bdaddr, "on");

if (discoverable_timeout)
- *discoverable_timeout = get_discoverable_timeout(address);
+ *discoverable_timeout = adapter->discov_timeout;

if (pairable)
*pairable = adapter->pairable;
@@ -2232,7 +2222,6 @@ void btd_adapter_start(struct btd_adapter *adapter)

adapter->off_requested = FALSE;
adapter->up = TRUE;
- adapter->discov_timeout = get_discoverable_timeout(address);
adapter->off_timer = 0;

if (adapter->scan_mode & SCAN_INQUIRY)
@@ -2502,6 +2491,12 @@ static void load_config(struct btd_adapter *adapter)
adapter->pairable_timeout = main_opts.pairto;
else
adapter->pairable_timeout = timeout;
+
+ /* Get discoverable timeout */
+ if (read_discoverable_timeout(address, &timeout) < 0)
+ adapter->discov_timeout = main_opts.discovto;
+ else
+ adapter->discov_timeout = timeout;
}

gboolean adapter_init(struct btd_adapter *adapter, gboolean up)
--
1.7.9.5


2012-10-24 14:34:08

by Frederic Danis

[permalink] [raw]
Subject: [PATCH v7 06/16] adapter: Read pairable timeout in storage at init

---
src/adapter.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index d0a8404..918991c 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2107,16 +2107,6 @@ static int get_discoverable_timeout(const char *src)
return main_opts.discovto;
}

-static int get_pairable_timeout(const char *src)
-{
- int timeout;
-
- if (read_pairable_timeout(src, &timeout) == 0)
- return timeout;
-
- return main_opts.pairto;
-}
-
static void set_auto_connect(gpointer data, gpointer user_data)
{
struct btd_device *device = data;
@@ -2243,7 +2233,6 @@ void btd_adapter_start(struct btd_adapter *adapter)
adapter->off_requested = FALSE;
adapter->up = TRUE;
adapter->discov_timeout = get_discoverable_timeout(address);
- adapter->pairable_timeout = get_pairable_timeout(address);
adapter->off_timer = 0;

if (adapter->scan_mode & SCAN_INQUIRY)
@@ -2490,6 +2479,10 @@ void btd_adapter_unref(struct btd_adapter *adapter)
static void load_config(struct btd_adapter *adapter)
{
char name[MAX_NAME_LENGTH + 1];
+ char address[18];
+ int timeout;
+
+ ba2str(&adapter->bdaddr, address);

/* Get name */
if (read_local_name(&adapter->bdaddr, name) < 0)
@@ -2503,6 +2496,12 @@ static void load_config(struct btd_adapter *adapter)
/* Get pairable mode */
if (read_device_pairable(&adapter->bdaddr, &adapter->pairable) < 0)
adapter->pairable = TRUE;
+
+ /* Get pairable timeout */
+ if (read_pairable_timeout(address, &timeout) < 0)
+ adapter->pairable_timeout = main_opts.pairto;
+ else
+ adapter->pairable_timeout = timeout;
}

gboolean adapter_init(struct btd_adapter *adapter, gboolean up)
--
1.7.9.5


2012-10-24 14:34:06

by Frederic Danis

[permalink] [raw]
Subject: [PATCH v7 04/16] adapter: Remove device class storage

---
src/adapter.c | 18 +++++-------------
src/adapter.h | 2 +-
src/mgmt.c | 2 +-
3 files changed, 7 insertions(+), 15 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 6333837..310d1cf 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -756,8 +756,6 @@ void btd_adapter_class_changed(struct btd_adapter *adapter, uint8_t *new_class)
if (class == adapter->dev_class)
return;

- write_local_class(&adapter->bdaddr, new_class);
-
adapter->dev_class = class;

if (main_opts.gatt_enabled) {
@@ -2169,18 +2167,11 @@ void btd_adapter_get_mode(struct btd_adapter *adapter, uint8_t *mode,
*pairable = adapter->pairable;
}

-void btd_adapter_read_class(struct btd_adapter *adapter, uint8_t *major,
+void btd_adapter_get_major_minor(struct btd_adapter *adapter, uint8_t *major,
uint8_t *minor)
{
- uint8_t cls[3];
-
- if (read_local_class(&adapter->bdaddr, cls) < 0) {
- uint32_t class = htobl(main_opts.class);
- memcpy(cls, &class, 3);
- }
-
- *major = cls[1];
- *minor = cls[0];
+ *major = (adapter->dev_class >> 8) & 0xFF;
+ *minor = adapter->dev_class & 0xFF;
}

uint32_t btd_adapter_get_class(struct btd_adapter *adapter)
@@ -2249,7 +2240,6 @@ void btd_adapter_start(struct btd_adapter *adapter)

ba2str(&adapter->bdaddr, address);

- adapter->dev_class = 0;
adapter->off_requested = FALSE;
adapter->up = TRUE;
adapter->discov_timeout = get_discoverable_timeout(address);
@@ -2507,6 +2497,8 @@ static void load_config(struct btd_adapter *adapter)
else
adapter->name = g_strdup(name);

+ /* Set class */
+ adapter->dev_class = main_opts.class;
}

gboolean adapter_init(struct btd_adapter *adapter, gboolean up)
diff --git a/src/adapter.h b/src/adapter.h
index d53c658..be69781 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -85,7 +85,7 @@ void btd_adapter_get_mode(struct btd_adapter *adapter, uint8_t *mode,
uint16_t *discoverable_timeout,
gboolean *pairable);

-void btd_adapter_read_class(struct btd_adapter *adapter, uint8_t *major,
+void btd_adapter_get_major_minor(struct btd_adapter *adapter, uint8_t *major,
uint8_t *minor);

uint32_t btd_adapter_get_class(struct btd_adapter *adapter);
diff --git a/src/mgmt.c b/src/mgmt.c
index bef66cd..f179dfa 100644
--- a/src/mgmt.c
+++ b/src/mgmt.c
@@ -1105,7 +1105,7 @@ static void read_info_complete(int sk, uint16_t index, void *buf, size_t len)
else
adapter_name_changed(adapter, (char *) rp->name);

- btd_adapter_read_class(adapter, &major, &minor);
+ btd_adapter_get_major_minor(adapter, &major, &minor);
mgmt_set_dev_class(index, major, minor);

btd_adapter_get_mode(adapter, &mode, NULL, NULL, NULL);
--
1.7.9.5


2012-10-24 14:34:07

by Frederic Danis

[permalink] [raw]
Subject: [PATCH v7 05/16] adapter: Move pairable read to load_config()

---
src/adapter.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 310d1cf..d0a8404 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2499,6 +2499,10 @@ static void load_config(struct btd_adapter *adapter)

/* Set class */
adapter->dev_class = main_opts.class;
+
+ /* Get pairable mode */
+ if (read_device_pairable(&adapter->bdaddr, &adapter->pairable) < 0)
+ adapter->pairable = TRUE;
}

gboolean adapter_init(struct btd_adapter *adapter, gboolean up)
@@ -2526,10 +2530,6 @@ gboolean adapter_init(struct btd_adapter *adapter, gboolean up)
clear_blocked(adapter);
load_devices(adapter);

- /* Set pairable mode */
- if (read_device_pairable(&adapter->bdaddr, &adapter->pairable) < 0)
- adapter->pairable = TRUE;
-
/* retrieve the active connections: address the scenario where
* the are active connections before the daemon've started */
load_connections(adapter);
--
1.7.9.5


2012-10-24 14:34:03

by Frederic Danis

[permalink] [raw]
Subject: [PATCH v7 01/16] doc: Add settings storage documentation

---
doc/settings-storage.txt | 183 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 183 insertions(+)
create mode 100644 doc/settings-storage.txt

diff --git a/doc/settings-storage.txt b/doc/settings-storage.txt
new file mode 100644
index 0000000..a9ff260
--- /dev/null
+++ b/doc/settings-storage.txt
@@ -0,0 +1,183 @@
+BlueZ settings storage
+**********************
+
+Purpose
+=======
+
+The purpose of this document is to describe the directory structure of BlueZ
+settings storage. In effect, this document will serve as the primary, up to
+date source of BlueZ storage information. It is intended for developers,
+managers and users needing to understand the storage directory.
+
+Adapter and remote device info are read form the storage during object
+initialization.
+Write to storage is performed immediately on every value change.
+
+Default storage directory is /var/lib/bluetooth.
+
+All files are in ini-file format.
+
+Storage directory structure
+===========================
+
+There is one directory per adapter, named by its bluetooth address, which
+contains:
+ - a settings file for the local adapter
+ - an attributes file containing attributes of supported LE services
+ - a cache directory containing:
+ - one file per device, named by remote device address, which contains
+ device name
+ - one directory per remote device, named by remote device address, which
+ contains:
+ - an info file
+ - an attributes file containing attributes of remote LE services
+
+So the directory structure is:
+ /var/lib/bluetooth/<adapter address>/
+ ./settings
+ ./attributes
+ ./cache/
+ ./<remote device address>
+ ./<remote device address>
+ ...
+ ./<remote device address>/
+ ./info
+ ./attributes
+ ./<remote device address>/
+ ./info
+ ./attributes
+ ...
+
+Settings file format
+====================
+
+Settings file contains one [General] group with adapter info like:
+
+ Name String Friendly name advertised for
+ this adapter
+
+ Discoverable Boolean Discoverability of the adapter
+
+ Connectable Boolean Connectability of the adapter
+
+ Pairable Boolean Can the adapter accept pairing
+ request ?
+
+ Powered Boolean Is the adapter powered ?
+
+ PairableTimeout Integer How long to stay in pairable mode
+ before going back to non-pairable.
+ The value is in seconds.
+ 0 = disable timer, i.e. stay
+ pairable forever
+
+ DiscoverableTimeout Integer How long to stay in discoverable mode
+ before going back to non-discoverable.
+ The value is in seconds.
+ 0 = disable timer, i.e. stay
+ discoverable forever
+
+Sample:
+ [General]
+ Name=My PC
+ Discoverable=false
+ Connectable=true
+ Pairable=true
+ Powered=true
+ DiscoverableTimeout=0
+
+Attributes file format
+======================
+
+The attributes file lists all attributes supported by the local adapter or
+remote device.
+
+Attributes are stored using their handle as group name (decimal format).
+
+Each group contains:
+
+ UUID String 128-bit UUID of the attribute
+
+ Value String Value of the attribute as hexadecimal encoded
+ string
+
+Sample:
+ [1]
+ UUID=00002800-0000-1000-8000-00805f9b34fb
+ Value=0018
+
+ [4]
+ UUID=00002803-0000-1000-8000-00805f9b34fb
+ Value=020600002A
+
+ [6]
+ UUID=00002a00-0000-1000-8000-00805f9b34fb
+ Value=4578616D706C6520446576696365
+
+Cache directory file format
+============================
+
+Each file, named by remote device address, contains one [General] group.
+This general group contains:
+
+ Name String Remote device friendly name
+
+ ShortName String Remote device shortened name
+
+Info file format
+================
+
+Info file may includes multiple groups (General, Device ID, Link key and
+Long term key) related to a remote device.
+
+[General] group contains:
+
+ Alias String Alias name
+
+ Class String Device class in hexadecimal,
+ i.e. 0x000000
+
+ Features String Bluetooth device features in
+ hexadecimal, i.e. 0x0000000000000000
+
+ AddressType String An address can be "static" or "public"
+
+ Trusted Boolean True if the remote device is trusted
+
+ Profiles List of List of profiles advertised by remote,
+ strings in 128-bits UUID format, separated by
+ ";"
+
+
+[DeviceID] group contains:
+
+ Source Integer Assigner of Device ID
+
+ Vendor Integer Device vendor
+
+ Product Integer Device product
+
+ Version Integer Device version
+
+
+[LinkKey] group contains:
+
+ Key String Key in hexadecimal format
+
+ Type Integer Type of link key
+
+ PINLength Integer Length of PIN
+
+
+[LongTermKey] group contains:
+
+ Key String Long term key in hexadecimal format
+
+ Authenticated Boolean True if remote device has been
+ authenticated
+
+ EncSize Integer Encrypted size
+
+ EDiv Integer Encrypted diversifier
+
+ Rand Integer Randomizer
--
1.7.9.5


2012-10-24 14:34:05

by Frederic Danis

[permalink] [raw]
Subject: [PATCH v7 03/16] adaptername: Retrieve config name from adapter

---
plugins/adaptername.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/plugins/adaptername.c b/plugins/adaptername.c
index f58fb0f..353f11c 100644
--- a/plugins/adaptername.c
+++ b/plugins/adaptername.c
@@ -211,8 +211,10 @@ static int adaptername_probe(struct btd_adapter *adapter)
adapter_set_allow_name_changes(adapter, TRUE);
current_id = adapter_get_dev_id(adapter);

- if (read_local_name(adapter_get_address(adapter), name) < 0)
- expand_name(name, MAX_NAME_LENGTH, main_opts.name, current_id);
+ if (btd_adapter_get_name(adapter) != NULL)
+ return 0;
+
+ expand_name(name, MAX_NAME_LENGTH, main_opts.name, current_id);

DBG("Setting name '%s' for device 'hci%d'", name, current_id);
adapter_set_name(adapter, name);
--
1.7.9.5


2012-10-24 14:34:04

by Frederic Danis

[permalink] [raw]
Subject: [PATCH v7 02/16] adapter: Read name in storage at init

---
src/adapter.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/src/adapter.c b/src/adapter.c
index 9ed8af2..6333837 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2497,6 +2497,18 @@ void btd_adapter_unref(struct btd_adapter *adapter)
g_free(path);
}

+static void load_config(struct btd_adapter *adapter)
+{
+ char name[MAX_NAME_LENGTH + 1];
+
+ /* Get name */
+ if (read_local_name(&adapter->bdaddr, name) < 0)
+ adapter->name = NULL;
+ else
+ adapter->name = g_strdup(name);
+
+}
+
gboolean adapter_init(struct btd_adapter *adapter, gboolean up)
{
adapter->up = up;
@@ -2516,6 +2528,7 @@ gboolean adapter_init(struct btd_adapter *adapter, gboolean up)
if (main_opts.gatt_enabled)
btd_adapter_gatt_server_start(adapter);

+ load_config(adapter);
load_drivers(adapter);
btd_profile_foreach(probe_profile, adapter);
clear_blocked(adapter);
--
1.7.9.5