* [PATCH 1/4] android/bluetooth: Add initial support for permanent storage
2013-12-18 14:05 [PATCH 0/4] android: Permanent storage support Szymon Janc
@ 2013-12-18 14:05 ` Szymon Janc
2013-12-19 8:29 ` Johan Hedberg
2013-12-18 14:05 ` [PATCH 2/4] android/bluetooth: Add initial support for storing device info Szymon Janc
` (2 subsequent siblings)
3 siblings, 1 reply; 9+ messages in thread
From: Szymon Janc @ 2013-12-18 14:05 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
This patch adds initial support for storing adapter configuration.
Currently stored data is address, name and discoverable timeout.
Since Android daemon storage format is to be simpler than Linux check
if correct adapter is used before going operational. This is
a precaution to avoid e.g. using linkkeys generated for different
controller.
---
android/Android.mk | 3 +-
android/bluetooth.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++---
configure.ac | 3 ++
3 files changed, 95 insertions(+), 6 deletions(-)
diff --git a/android/Android.mk b/android/Android.mk
index ebc3219..2953a6e 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -8,7 +8,8 @@ pathmap_INCL += glib:external/bluetooth/glib
# Specify common compiler flags
BLUEZ_COMMON_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\" \
- -DPLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION)
+ -DPLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION) \
+ -DANDROID_STORAGEDIR=\"/data/misc/bluetooth\" \
# Disable warnings enabled by Android but not enabled in autotools build
BLUEZ_COMMON_CFLAGS += -Wno-pointer-arith -Wno-missing-field-initializers
diff --git a/android/bluetooth.c b/android/bluetooth.c
index 97d4aae..114a466 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -27,6 +27,10 @@
#include <errno.h>
#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#include <glib.h>
@@ -123,6 +127,75 @@ static GSList *devices = NULL;
/* This list contains addresses which are asked for records */
static GSList *browse_reqs;
+static void store_adapter_config(void)
+{
+ GKeyFile *key_file;
+ gsize length = 0;
+ char addr[18];
+ char *data;
+
+ key_file = g_key_file_new();
+
+ if (!g_key_file_load_from_file(key_file, ANDROID_STORAGEDIR"/settings",
+ 0, NULL)) {
+ int fd = open(ANDROID_STORAGEDIR"/settings", O_CREAT, 0600);
+ if (fd < 0) {
+ error("Failed to create adapter config file: %d (%s)",
+ errno, strerror(errno));
+ return;
+ }
+
+ close(fd);
+ }
+
+ ba2str(&adapter.bdaddr, addr);
+
+ g_key_file_set_string(key_file, "General", "Address", addr);
+ g_key_file_set_string(key_file, "General", "Name", adapter.name);
+ g_key_file_set_integer(key_file, "General", "DiscoverableTimeout",
+ adapter.discoverable_timeout);
+
+ data = g_key_file_to_data(key_file, &length, NULL);
+
+ g_file_set_contents(ANDROID_STORAGEDIR"/settings", data, length, NULL);
+
+ g_free(data);
+ g_key_file_free(key_file);
+}
+
+static void load_adapter_config(void)
+{
+ GError *gerr = NULL;
+ GKeyFile *key_file;
+ char *str;
+
+ key_file = g_key_file_new();
+
+ g_key_file_load_from_file(key_file, ANDROID_STORAGEDIR"/settings", 0,
+ NULL);
+
+ str = g_key_file_get_string(key_file, "General", "Address", NULL);
+ if (!str) {
+ g_key_file_free(key_file);
+ return;
+ }
+
+ str2ba(str, &adapter.bdaddr);
+ g_free(str);
+
+ adapter.name = g_key_file_get_string(key_file, "General", "Name", NULL);
+
+ adapter.discoverable_timeout = g_key_file_get_integer(key_file,
+ "General", "DiscoverableTimeout", &gerr);
+ if (gerr) {
+ adapter.discoverable_timeout = DEFAULT_DISCOVERABLE_TIMEOUT;
+ g_error_free(gerr);
+ gerr = NULL;
+ }
+
+ g_key_file_free(key_file);
+}
+
static int bdaddr_cmp(gconstpointer a, gconstpointer b)
{
const bdaddr_t *bda = a;
@@ -215,6 +288,8 @@ static void adapter_set_name(const uint8_t *name)
g_free(adapter.name);
adapter.name = g_strdup((const char *) name);
+ store_adapter_config();
+
adapter_name_changed(name);
}
@@ -1385,9 +1460,10 @@ static uint8_t set_adapter_discoverable_timeout(const void *buf, uint16_t len)
* There is no need to use kernel feature for that.
* Just need to store this value here */
- /* TODO: This should be in some storage */
memcpy(&adapter.discoverable_timeout, timeout, sizeof(uint32_t));
+ store_adapter_config();
+
send_adapter_property(HAL_PROP_ADAPTER_DISC_TIMEOUT,
sizeof(adapter.discoverable_timeout),
&adapter.discoverable_timeout);
@@ -1434,17 +1510,26 @@ static void read_info_complete(uint8_t status, uint16_t length,
goto failed;
}
+ load_adapter_config();
+
+ if (!bacmp(&adapter.bdaddr, BDADDR_ANY)) {
+ bacpy(&adapter.bdaddr, &rp->bdaddr);
+ adapter.name = g_strdup((const char *) rp->name);
+ store_adapter_config();
+ set_adapter_name(rp->name, strlen((char *)rp->name));
+ } else if (bacmp(&adapter.bdaddr, &rp->bdaddr)) {
+ error("Bluetooth address mismatch");
+ err = -ENODEV;
+ goto failed;
+ }
+
/* Store adapter information */
- bacpy(&adapter.bdaddr, &rp->bdaddr);
adapter.dev_class = rp->dev_class[0] | (rp->dev_class[1] << 8) |
(rp->dev_class[2] << 16);
- adapter.name = g_strdup((const char *) rp->name);
supported_settings = btohs(rp->supported_settings);
adapter.current_settings = btohs(rp->current_settings);
- /* TODO: Read discoverable timeout from storage here */
-
/* TODO: Register all event notification handlers */
register_mgmt_handlers();
diff --git a/configure.ac b/configure.ac
index 18d0b55..5171c38 100644
--- a/configure.ac
+++ b/configure.ac
@@ -252,4 +252,7 @@ AC_ARG_ENABLE(android, AC_HELP_STRING([--enable-android],
[enable_android=${enableval}])
AM_CONDITIONAL(ANDROID, test "${enable_android}" = "yes")
+AC_DEFINE_UNQUOTED(ANDROID_STORAGEDIR, "${storagedir}/android",
+ [Directory for the Android daemon storage files])
+
AC_OUTPUT(Makefile src/bluetoothd.8 lib/bluez.pc)
--
1.8.3.2
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH 1/4] android/bluetooth: Add initial support for permanent storage
2013-12-18 14:05 ` [PATCH 1/4] android/bluetooth: Add initial support for permanent storage Szymon Janc
@ 2013-12-19 8:29 ` Johan Hedberg
2013-12-19 8:35 ` Szymon Janc
0 siblings, 1 reply; 9+ messages in thread
From: Johan Hedberg @ 2013-12-19 8:29 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
Hi Szymon,
On Wed, Dec 18, 2013, Szymon Janc wrote:
> +static void store_adapter_config(void)
> +{
> + GKeyFile *key_file;
> + gsize length = 0;
> + char addr[18];
> + char *data;
> +
> + key_file = g_key_file_new();
> +
> + if (!g_key_file_load_from_file(key_file, ANDROID_STORAGEDIR"/settings",
> + 0, NULL)) {
> + int fd = open(ANDROID_STORAGEDIR"/settings", O_CREAT, 0600);
> + if (fd < 0) {
> + error("Failed to create adapter config file: %d (%s)",
> + errno, strerror(errno));
> + return;
> + }
> +
> + close(fd);
> + }
> +
> + ba2str(&adapter.bdaddr, addr);
> +
> + g_key_file_set_string(key_file, "General", "Address", addr);
> + g_key_file_set_string(key_file, "General", "Name", adapter.name);
> + g_key_file_set_integer(key_file, "General", "DiscoverableTimeout",
> + adapter.discoverable_timeout);
> +
> + data = g_key_file_to_data(key_file, &length, NULL);
> +
> + g_file_set_contents(ANDROID_STORAGEDIR"/settings", data, length, NULL);
The whole open(..., O_CREAT, ...) trick you do seems completely
unnecessary as g_key_file_to_data will create the file if it doesn't
exist. Instead, if you want to log an error you'd need to check if
g_key_file_contents failed or not. Adding a GError into the mix and
logging the exact error message would be even better.
Johan
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH 1/4] android/bluetooth: Add initial support for permanent storage
2013-12-19 8:29 ` Johan Hedberg
@ 2013-12-19 8:35 ` Szymon Janc
2013-12-19 9:14 ` Johan Hedberg
0 siblings, 1 reply; 9+ messages in thread
From: Szymon Janc @ 2013-12-19 8:35 UTC (permalink / raw)
To: Johan Hedberg; +Cc: linux-bluetooth
Hi Johan,
> Hi Szymon,
>
> On Wed, Dec 18, 2013, Szymon Janc wrote:
> > +static void store_adapter_config(void)
> > +{
> > + GKeyFile *key_file;
> > + gsize length = 0;
> > + char addr[18];
> > + char *data;
> > +
> > + key_file = g_key_file_new();
> > +
> > + if (!g_key_file_load_from_file(key_file, ANDROID_STORAGEDIR"/settings",
> > + 0, NULL)) {
> > + int fd = open(ANDROID_STORAGEDIR"/settings", O_CREAT, 0600);
> > + if (fd < 0) {
> > + error("Failed to create adapter config file: %d (%s)",
> > + errno, strerror(errno));
> > + return;
> > + }
> > +
> > + close(fd);
> > + }
> > +
> > + ba2str(&adapter.bdaddr, addr);
> > +
> > + g_key_file_set_string(key_file, "General", "Address", addr);
> > + g_key_file_set_string(key_file, "General", "Name", adapter.name);
> > + g_key_file_set_integer(key_file, "General", "DiscoverableTimeout",
> > + adapter.discoverable_timeout);
> > +
> > + data = g_key_file_to_data(key_file, &length, NULL);
> > +
> > + g_file_set_contents(ANDROID_STORAGEDIR"/settings", data, length, NULL);
>
> The whole open(..., O_CREAT, ...) trick you do seems completely
> unnecessary as g_key_file_to_data will create the file if it doesn't
> exist. Instead, if you want to log an error you'd need to check if
> g_key_file_contents failed or not. Adding a GError into the mix and
> logging the exact error message would be even better.
This was done only to make sure proper permissions are used for file. Since
glib doens't offer any API (at least I couldn't find any) for that in g_file_*
(other than wrappers to standard unix calls)
--
BR
Szymon Janc
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH 1/4] android/bluetooth: Add initial support for permanent storage
2013-12-19 8:35 ` Szymon Janc
@ 2013-12-19 9:14 ` Johan Hedberg
2013-12-19 9:46 ` Szymon Janc
0 siblings, 1 reply; 9+ messages in thread
From: Johan Hedberg @ 2013-12-19 9:14 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
Hi Szymon,
On Thu, Dec 19, 2013, Szymon Janc wrote:
> > On Wed, Dec 18, 2013, Szymon Janc wrote:
> > > +static void store_adapter_config(void)
> > > +{
> > > + GKeyFile *key_file;
> > > + gsize length = 0;
> > > + char addr[18];
> > > + char *data;
> > > +
> > > + key_file = g_key_file_new();
> > > +
> > > + if (!g_key_file_load_from_file(key_file, ANDROID_STORAGEDIR"/settings",
> > > + 0, NULL)) {
> > > + int fd = open(ANDROID_STORAGEDIR"/settings", O_CREAT, 0600);
> > > + if (fd < 0) {
> > > + error("Failed to create adapter config file: %d (%s)",
> > > + errno, strerror(errno));
> > > + return;
> > > + }
> > > +
> > > + close(fd);
> > > + }
> > > +
> > > + ba2str(&adapter.bdaddr, addr);
> > > +
> > > + g_key_file_set_string(key_file, "General", "Address", addr);
> > > + g_key_file_set_string(key_file, "General", "Name", adapter.name);
> > > + g_key_file_set_integer(key_file, "General", "DiscoverableTimeout",
> > > + adapter.discoverable_timeout);
> > > +
> > > + data = g_key_file_to_data(key_file, &length, NULL);
> > > +
> > > + g_file_set_contents(ANDROID_STORAGEDIR"/settings", data, length, NULL);
> >
> > The whole open(..., O_CREAT, ...) trick you do seems completely
> > unnecessary as g_key_file_to_data will create the file if it doesn't
> > exist. Instead, if you want to log an error you'd need to check if
> > g_key_file_contents failed or not. Adding a GError into the mix and
> > logging the exact error message would be even better.
>
> This was done only to make sure proper permissions are used for file. Since
> glib doens't offer any API (at least I couldn't find any) for that in g_file_*
> (other than wrappers to standard unix calls)
What permissions does the file get created with if you omit this? Maybe
the right fix is to set the umask explicitly in our main() or to modify
how the daemon gets executed?
Johan
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH 1/4] android/bluetooth: Add initial support for permanent storage
2013-12-19 9:14 ` Johan Hedberg
@ 2013-12-19 9:46 ` Szymon Janc
0 siblings, 0 replies; 9+ messages in thread
From: Szymon Janc @ 2013-12-19 9:46 UTC (permalink / raw)
To: Johan Hedberg; +Cc: linux-bluetooth
Hi Johan,
> Hi Szymon,
>
> On Thu, Dec 19, 2013, Szymon Janc wrote:
> > > On Wed, Dec 18, 2013, Szymon Janc wrote:
> > > > +static void store_adapter_config(void)
> > > > +{
> > > > + GKeyFile *key_file;
> > > > + gsize length = 0;
> > > > + char addr[18];
> > > > + char *data;
> > > > +
> > > > + key_file = g_key_file_new();
> > > > +
> > > > + if (!g_key_file_load_from_file(key_file, ANDROID_STORAGEDIR"/settings",
> > > > + 0, NULL)) {
> > > > + int fd = open(ANDROID_STORAGEDIR"/settings", O_CREAT, 0600);
> > > > + if (fd < 0) {
> > > > + error("Failed to create adapter config file: %d (%s)",
> > > > + errno, strerror(errno));
> > > > + return;
> > > > + }
> > > > +
> > > > + close(fd);
> > > > + }
> > > > +
> > > > + ba2str(&adapter.bdaddr, addr);
> > > > +
> > > > + g_key_file_set_string(key_file, "General", "Address", addr);
> > > > + g_key_file_set_string(key_file, "General", "Name", adapter.name);
> > > > + g_key_file_set_integer(key_file, "General", "DiscoverableTimeout",
> > > > + adapter.discoverable_timeout);
> > > > +
> > > > + data = g_key_file_to_data(key_file, &length, NULL);
> > > > +
> > > > + g_file_set_contents(ANDROID_STORAGEDIR"/settings", data, length, NULL);
> > >
> > > The whole open(..., O_CREAT, ...) trick you do seems completely
> > > unnecessary as g_key_file_to_data will create the file if it doesn't
> > > exist. Instead, if you want to log an error you'd need to check if
> > > g_key_file_contents failed or not. Adding a GError into the mix and
> > > logging the exact error message would be even better.
> >
> > This was done only to make sure proper permissions are used for file. Since
> > glib doens't offer any API (at least I couldn't find any) for that in g_file_*
> > (other than wrappers to standard unix calls)
>
> What permissions does the file get created with if you omit this? Maybe
> the right fix is to set the umask explicitly in our main() or to modify
> how the daemon gets executed?
It was 0600 on Android so it looks like Android init is setting good mask, but
it was 0644 on Linux host.
I suppose we could fix system-emulator to set umask to have correct permissions
on host.
Will send V2.
--
BR
Szymon Janc
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/4] android/bluetooth: Add initial support for storing device info
2013-12-18 14:05 [PATCH 0/4] android: Permanent storage support Szymon Janc
2013-12-18 14:05 ` [PATCH 1/4] android/bluetooth: Add initial support for permanent storage Szymon Janc
@ 2013-12-18 14:05 ` Szymon Janc
2013-12-18 14:05 ` [PATCH 3/4] android/bluetooth: Add support for storing link keys Szymon Janc
2013-12-18 14:05 ` [PATCH 4/4] android/bluetooth: Add support for restoring devices from storage Szymon Janc
3 siblings, 0 replies; 9+ messages in thread
From: Szymon Janc @ 2013-12-18 14:05 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
This allows to store information about remote device. For now this is
stored only for bonded devices. Currently stored data includes devices
ddress, type, name, friendly name, class and uuids.
---
android/bluetooth.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 68 insertions(+), 1 deletion(-)
diff --git a/android/bluetooth.c b/android/bluetooth.c
index 114a466..b8f078f 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -196,6 +196,69 @@ static void load_adapter_config(void)
g_key_file_free(key_file);
}
+static void store_device_info(struct device *dev)
+{
+ GKeyFile *key_file;
+ char addr[18];
+ gsize length = 0;
+ char **uuids = NULL;
+ char *str;
+
+ if (dev->bond_state != HAL_BOND_STATE_BONDED)
+ return;
+
+ ba2str(&dev->bdaddr, addr);
+
+ key_file = g_key_file_new();
+ g_key_file_load_from_file(key_file, ANDROID_STORAGEDIR"/devices", 0,
+ NULL);
+
+ g_key_file_set_integer(key_file, addr, "Type", dev->bdaddr_type);
+
+ g_key_file_set_string(key_file, addr, "Name", dev->name);
+
+ if (dev->friendly_name)
+ g_key_file_set_string(key_file, addr, "FriendlyName",
+ dev->friendly_name);
+ else
+ g_key_file_remove_key(key_file, addr, "FriendlyName", NULL);
+
+ if (dev->class)
+ g_key_file_set_integer(key_file, addr, "Class", dev->class);
+ else
+ g_key_file_remove_key(key_file, addr, "Class", NULL);
+
+ if (dev->uuids) {
+ GSList *l;
+ int i;
+
+ uuids = g_new0(char *, g_slist_length(dev->uuids) + 1);
+
+ for (i = 0, l = dev->uuids; l; l = g_slist_next(l), i++) {
+ int j;
+ uint8_t *u = l->data;
+ char *uuid_str = g_malloc0(33);
+
+ for (j = 0; j < 16; j++)
+ sprintf(uuid_str + (j * 2), "%2.2X", u[j]);
+
+ uuids[i] = uuid_str;
+ }
+
+ g_key_file_set_string_list(key_file, addr, "Services",
+ (const char **)uuids, i);
+ } else {
+ g_key_file_remove_key(key_file, addr, "Services", NULL);
+ }
+
+ str = g_key_file_to_data(key_file, &length, NULL);
+ g_file_set_contents(ANDROID_STORAGEDIR"/devices", str, length, NULL);
+ g_free(str);
+
+ g_key_file_free(key_file);
+ g_strfreev(uuids);
+}
+
static int bdaddr_cmp(gconstpointer a, gconstpointer b)
{
const bdaddr_t *bda = a;
@@ -458,6 +521,8 @@ static void set_device_bond_state(const bdaddr_t *addr, uint8_t status,
if (dev->bond_state != state) {
dev->bond_state = state;
send_bond_state_change(&dev->bdaddr, status, state);
+
+ store_device_info(dev);
}
}
@@ -498,6 +563,8 @@ static void set_device_uuids(struct device *dev, GSList *uuids)
g_slist_free_full(dev->uuids, g_free);
dev->uuids = uuids;
+ store_device_info(dev);
+
send_device_uuids_notif(dev);
}
@@ -2539,7 +2606,7 @@ static uint8_t set_device_friendly_name(struct device *dev, const uint8_t *val,
g_free(dev->friendly_name);
dev->friendly_name = g_strndup((const char *) val, len);
- /* TODO store friendly name */
+ store_device_info(dev);
send_device_property(&dev->bdaddr, HAL_PROP_DEVICE_FRIENDLY_NAME,
strlen(dev->friendly_name), dev->friendly_name);
--
1.8.3.2
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH 3/4] android/bluetooth: Add support for storing link keys
2013-12-18 14:05 [PATCH 0/4] android: Permanent storage support Szymon Janc
2013-12-18 14:05 ` [PATCH 1/4] android/bluetooth: Add initial support for permanent storage Szymon Janc
2013-12-18 14:05 ` [PATCH 2/4] android/bluetooth: Add initial support for storing device info Szymon Janc
@ 2013-12-18 14:05 ` Szymon Janc
2013-12-18 14:05 ` [PATCH 4/4] android/bluetooth: Add support for restoring devices from storage Szymon Janc
3 siblings, 0 replies; 9+ messages in thread
From: Szymon Janc @ 2013-12-18 14:05 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
When new linkkey event is received store linkkey in devices info file.
Stored info includes linkkey, linkkey type and pin length.
---
android/bluetooth.c | 36 ++++++++++++++++++++++++++++++++----
1 file changed, 32 insertions(+), 4 deletions(-)
diff --git a/android/bluetooth.c b/android/bluetooth.c
index b8f078f..dd16a54 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -493,7 +493,35 @@ static void mgmt_dev_class_changed_event(uint16_t index, uint16_t length,
static void store_link_key(const bdaddr_t *dst, const uint8_t *key,
uint8_t type, uint8_t pin_length)
{
- /* TODO store link key */
+ GKeyFile *key_file;
+ char key_str[33];
+ gsize length = 0;
+ char addr[18];
+ char *data;
+ int i;
+
+ key_file = g_key_file_new();
+
+ if (!g_key_file_load_from_file(key_file, ANDROID_STORAGEDIR"/devices",
+ 0, NULL))
+ return;
+
+ ba2str(dst, addr);
+
+ DBG("%s type %u pin_len %u", addr, type, pin_length);
+
+ for (i = 0; i < 16; i++)
+ sprintf(key_str + (i * 2), "%2.2X", key[i]);
+
+ g_key_file_set_string(key_file, addr, "LinkKey", key_str);
+ g_key_file_set_integer(key_file, addr, "LinkKeyType", type);
+ g_key_file_set_integer(key_file, addr, "LinkKeyPINLength", pin_length);
+
+ data = g_key_file_to_data(key_file, &length, NULL);
+ g_file_set_contents(ANDROID_STORAGEDIR"/devices", data, length, NULL);
+ g_free(data);
+
+ g_key_file_free(key_file);
}
static void send_bond_state_change(const bdaddr_t *addr, uint8_t status,
@@ -720,6 +748,9 @@ static void new_link_key_callback(uint16_t index, uint16_t length,
return;
}
+ set_device_bond_state(&addr->bdaddr, HAL_STATUS_SUCCESS,
+ HAL_BOND_STATE_BONDED);
+
if (ev->store_hint) {
const struct mgmt_link_key_info *key = &ev->key;
@@ -727,9 +758,6 @@ static void new_link_key_callback(uint16_t index, uint16_t length,
key->pin_len);
}
- set_device_bond_state(&addr->bdaddr, HAL_STATUS_SUCCESS,
- HAL_BOND_STATE_BONDED);
-
browse_remote_sdp(&addr->bdaddr);
}
--
1.8.3.2
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH 4/4] android/bluetooth: Add support for restoring devices from storage
2013-12-18 14:05 [PATCH 0/4] android: Permanent storage support Szymon Janc
` (2 preceding siblings ...)
2013-12-18 14:05 ` [PATCH 3/4] android/bluetooth: Add support for storing link keys Szymon Janc
@ 2013-12-18 14:05 ` Szymon Janc
3 siblings, 0 replies; 9+ messages in thread
From: Szymon Janc @ 2013-12-18 14:05 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
This adds support to restore bonded devices from storage (including
linkkeys).
---
android/bluetooth.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 112 insertions(+), 1 deletion(-)
diff --git a/android/bluetooth.c b/android/bluetooth.c
index dd16a54..c7fb95f 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -1576,6 +1576,117 @@ static void clear_uuids(void)
sizeof(cp), &cp, NULL, NULL, NULL);
}
+static void create_device_from_info(GKeyFile *key_file, const char *peer)
+{
+ struct device *dev;
+ uint8_t type;
+ bdaddr_t bdaddr;
+ char **uuids;
+ char *str;
+
+ DBG("%s", peer);
+
+ type = g_key_file_get_integer(key_file, peer, "Type", NULL);
+
+ str2ba(peer, &bdaddr);
+ dev = create_device(&bdaddr, type);
+
+ dev->bond_state = HAL_BOND_STATE_BONDED;
+
+ str = g_key_file_get_string(key_file, peer, "Name", NULL);
+ if (str) {
+ g_free(dev->name);
+ dev->name = str;
+ }
+
+ str = g_key_file_get_string(key_file, peer, "FriendlyName", NULL);
+ if (str) {
+ g_free(dev->friendly_name);
+ dev->friendly_name = str;
+ }
+
+ dev->class = g_key_file_get_integer(key_file, peer, "Class", NULL);
+
+ uuids = g_key_file_get_string_list(key_file, peer, "Services", NULL,
+ NULL);
+ if (uuids) {
+ char **uuid;
+
+ for (uuid = uuids; *uuid; uuid++) {
+ uint8_t *u = g_malloc0(16);
+ int i;
+
+ for (i = 0; i < 16; i++)
+ sscanf((*uuid) + (i * 2), "%02hhX", &u[i]);
+
+ dev->uuids = g_slist_append(dev->uuids, u);
+ }
+
+ g_strfreev(uuids);
+ }
+}
+
+static struct mgmt_link_key_info *get_key_info(GKeyFile *key_file, const char *peer)
+{
+ struct mgmt_link_key_info *info = NULL;
+ char *str;
+ unsigned int i;
+
+ str = g_key_file_get_string(key_file, peer, "LinkKey", NULL);
+ if (!str || strlen(str) != 32)
+ goto failed;
+
+ info = g_new0(struct mgmt_link_key_info, 1);
+
+ str2ba(peer, &info->addr.bdaddr);
+
+ info->addr.type = g_key_file_get_integer(key_file, peer, "Type", NULL);
+
+ for (i = 0; i < sizeof(info->val); i++)
+ sscanf(str + (i * 2), "%02hhX", &info->val[i]);
+
+ info->type = g_key_file_get_integer(key_file, peer, "LinkKeyType",
+ NULL);
+ info->pin_len = g_key_file_get_integer(key_file, peer,
+ "LinkKeyPINLength", NULL);
+
+failed:
+ g_free(str);
+
+ return info;
+}
+
+static void load_devices_info(bt_bluetooth_ready cb)
+{
+ GKeyFile *key_file;
+ gchar **devs;
+ gsize len = 0;
+ unsigned int i;
+ GSList *keys = NULL;
+
+ key_file = g_key_file_new();
+
+ g_key_file_load_from_file(key_file, ANDROID_STORAGEDIR"/devices", 0,
+ NULL);
+
+ devs = g_key_file_get_groups(key_file, &len);
+
+ for (i = 0; i < len; i++) {
+ struct mgmt_link_key_info *key_info;
+
+ create_device_from_info(key_file, devs[i]);
+
+ key_info = get_key_info(key_file, devs[i]);
+ if (key_info)
+ keys = g_slist_prepend(keys, key_info);
+
+ /* TODO ltk */
+ }
+
+ load_link_keys(keys, cb);
+ g_slist_free_full(keys, g_free);
+}
+
static void read_info_complete(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
@@ -1630,7 +1741,7 @@ static void read_info_complete(uint8_t status, uint16_t length,
clear_uuids();
- load_link_keys(NULL, cb);
+ load_devices_info(cb);
set_io_capability();
set_device_id();
--
1.8.3.2
^ permalink raw reply related [flat|nested] 9+ messages in thread