* [PATCH v5 11/15] adapter: Move storage names to cache directory
From: Frédéric Danis @ 2012-10-18 9:00 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1350550858-12239-1-git-send-email-frederic.danis@linux.intel.com>
---
src/adapter.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
src/event.c | 51 ++++++++++++++++++++++++---
2 files changed, 150 insertions(+), 7 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 30fda1f..ca47111 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2511,6 +2511,83 @@ void btd_adapter_unref(struct btd_adapter *adapter)
g_free(path);
}
+struct converter {
+ char *addr;
+ char *group;
+ char *key;
+};
+
+static void convert_cache(char *key, char *value, void *user_data)
+{
+ struct converter *convert = 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", convert->addr,
+ 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, convert->group, convert->key, 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;
+ struct converter convert;
+
+ ba2str(&adapter->bdaddr, address);
+ convert.addr = address;
+ convert.group = "General";
+
+ /* 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 {
+ convert.key = "Name";
+ textfile_foreach(filename, convert_cache, &convert);
+ textfile_put(filename, "converted", "yes");
+ }
+ free(str);
+
+ /* Convert lastseen device cache */
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/lastseen", address);
+ filename[PATH_MAX] = '\0';
+
+ str = textfile_get(filename, "converted");
+ if (str && strcmp(str, "yes") == 0) {
+ DBG("Legacy lastseen file already converted");
+ } else {
+ convert.key = "LastSeen";
+ textfile_foreach(filename, convert_cache, &convert);
+ textfile_put(filename, "converted", "yes");
+ }
+ free(str);
+}
+
static void convert_config(struct btd_adapter *adapter, const char *filename,
GKeyFile *key_file)
{
@@ -2684,6 +2761,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);
@@ -2965,9 +3043,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..b9eb368 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>
@@ -224,11 +225,36 @@ static void update_lastseen(bdaddr_t *sba, bdaddr_t *dba, uint8_t dba_type)
{
time_t t;
struct tm *tm;
+ char filename[PATH_MAX + 1];
+ char s_addr[18], d_addr[18];
+ char str[24];
+ GKeyFile *key_file;
+ char *data;
+ gsize length = 0;
t = time(NULL);
tm = gmtime(&t);
- write_lastseen_info(sba, dba, dba_type, tm);
+
+ memset(str, 0, sizeof(str));
+ strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S %Z", tm);
+
+ ba2str(sba, s_addr);
+ ba2str(dba, 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", "LastSeen", str);
+
+ 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 update_lastused(bdaddr_t *sba, bdaddr_t *dba, uint8_t dba_type)
@@ -265,7 +291,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 +312,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
^ permalink raw reply related
* [PATCH v5 10/15] TODO: Add entry to remove storage convertion function
From: Frédéric Danis @ 2012-10-18 9:00 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1350550858-12239-1-git-send-email-frederic.danis@linux.intel.com>
---
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
^ permalink raw reply related
* [PATCH v5 09/15] adapter: Move saved config to ini-file format
From: Frédéric Danis @ 2012-10-18 9:00 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1350550858-12239-1-git-send-email-frederic.danis@linux.intel.com>
Read and write config file in ini-file format.
If the file can not be loaded, try to convert legacy configuration.
---
src/adapter.c | 234 ++++++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 189 insertions(+), 45 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 155293e..30fda1f 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,56 @@ 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);
+
+ str = g_strdup_printf("0x%2.2x%2.2x%2.2x",
+ (adapter->dev_class >> 16) & 0xFF,
+ (adapter->dev_class >> 8) & 0xFF,
+ adapter->dev_class & 0xFF);
+ g_key_file_set_string(key_file, "General", "Class", str);
+ g_free(str);
+
+ 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 +331,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 +362,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;
}
@@ -451,7 +502,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");
@@ -713,7 +764,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");
@@ -733,7 +784,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");
@@ -749,10 +800,10 @@ 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;
+ store_adapter_info(adapter);
+
if (main_opts.gatt_enabled) {
uint8_t cls[3];
@@ -806,7 +857,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;
}
@@ -2294,13 +2345,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);
@@ -2462,58 +2511,153 @@ 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];
- uint8_t class[3];
char address[18];
- char mode[14];
+ char str[MAX_NAME_LENGTH + 1];
+ char config_path[PATH_MAX + 1];
+ char *converted;
+ uint8_t class[3];
+ 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_local_class(&adapter->bdaddr, class) == 0) {
+ sprintf(str, "0x%2.2x%2.2x%2.2x", class[2], class[1], class[0]);
+ g_key_file_set_string(key_file, "General", "Class", 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];
+ char *str;
+ 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);
/* Get class */
- if (read_local_class(&adapter->bdaddr, class) == 0)
- adapter->dev_class = class[0] | (class[1] << 8) |
- (class[2] << 16);
- else
+ str = g_key_file_get_string(key_file, "General", "Class", NULL);
+ if (str) {
+ adapter->dev_class = strtol(str, NULL, 16);
+ g_free(str);
+ } else
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
^ permalink raw reply related
* [PATCH v5 08/15] adapter: Read mode in storage at init
From: Frédéric Danis @ 2012-10-18 9:00 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1350550858-12239-1-git-send-email-frederic.danis@linux.intel.com>
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 20fa1d0..155293e 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;
}
@@ -375,11 +368,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;
@@ -1416,7 +1406,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) {
@@ -2130,25 +2123,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;
@@ -2234,10 +2217,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");
@@ -2481,6 +2467,7 @@ static void load_config(struct btd_adapter *adapter)
char name[MAX_NAME_LENGTH + 1];
uint8_t class[3];
char address[18];
+ char mode[14];
int timeout;
ba2str(&adapter->bdaddr, address);
@@ -2513,6 +2500,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)
@@ -2893,9 +2898,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 */
@@ -3198,17 +3205,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 ad180c3..18a653e 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
^ permalink raw reply related
* [PATCH v5 07/15] adapter: Read discoverable timeout in storage at init
From: Frédéric Danis @ 2012-10-18 9:00 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1350550858-12239-1-git-send-email-frederic.danis@linux.intel.com>
---
src/adapter.c | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 6d2aadc..20fa1d0 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2107,16 +2107,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;
@@ -2161,7 +2151,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;
@@ -2242,7 +2232,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)
@@ -2518,6 +2507,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
^ permalink raw reply related
* [PATCH v5 06/15] adapter: Read pairable timeout in storage at init
From: Frédéric Danis @ 2012-10-18 9:00 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1350550858-12239-1-git-send-email-frederic.danis@linux.intel.com>
---
src/adapter.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 74c36ec..6d2aadc 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2117,16 +2117,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;
@@ -2253,7 +2243,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)
@@ -2502,6 +2491,10 @@ static void load_config(struct btd_adapter *adapter)
{
char name[MAX_NAME_LENGTH + 1];
uint8_t class[3];
+ char address[18];
+ int timeout;
+
+ ba2str(&adapter->bdaddr, address);
/* Get name */
if (read_local_name(&adapter->bdaddr, name) < 0)
@@ -2519,6 +2512,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
^ permalink raw reply related
* [PATCH v5 05/15] adapter: Move pairable read to load_config()
From: Frédéric Danis @ 2012-10-18 9:00 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1350550858-12239-1-git-send-email-frederic.danis@linux.intel.com>
---
src/adapter.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index dd06d46..74c36ec 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2515,6 +2515,10 @@ static void load_config(struct btd_adapter *adapter)
(class[2] << 16);
else
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)
@@ -2542,10 +2546,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
^ permalink raw reply related
* [PATCH v5 04/15] adapter: Read device class in storage at init
From: Frédéric Danis @ 2012-10-18 9:00 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1350550858-12239-1-git-send-email-frederic.danis@linux.intel.com>
---
src/adapter.c | 21 ++++++++++-----------
src/adapter.h | 2 +-
src/mgmt.c | 2 +-
3 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 233527a..dd06d46 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2177,18 +2177,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)
@@ -2257,7 +2250,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);
@@ -2509,6 +2501,7 @@ void btd_adapter_unref(struct btd_adapter *adapter)
static void load_config(struct btd_adapter *adapter)
{
char name[MAX_NAME_LENGTH + 1];
+ uint8_t class[3];
/* Get name */
if (read_local_name(&adapter->bdaddr, name) < 0)
@@ -2516,6 +2509,12 @@ static void load_config(struct btd_adapter *adapter)
else
adapter->name = g_strdup(name);
+ /* Get class */
+ if (read_local_class(&adapter->bdaddr, class) == 0)
+ adapter->dev_class = class[0] | (class[1] << 8) |
+ (class[2] << 16);
+ else
+ 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 627fb4b..ad180c3 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
^ permalink raw reply related
* [PATCH v5 03/15] adaptername: Retrieve config name from adapter
From: Frédéric Danis @ 2012-10-18 9:00 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1350550858-12239-1-git-send-email-frederic.danis@linux.intel.com>
---
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
^ permalink raw reply related
* [PATCH v5 02/15] adapter: Read name in storage at init
From: Frédéric Danis @ 2012-10-18 9:00 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1350550858-12239-1-git-send-email-frederic.danis@linux.intel.com>
---
src/adapter.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/src/adapter.c b/src/adapter.c
index 3b24816..233527a 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2506,6 +2506,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;
@@ -2525,6 +2537,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
^ permalink raw reply related
* [PATCH v5 01/15] doc: Add settings storage documentation
From: Frédéric Danis @ 2012-10-18 9:00 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1350550858-12239-1-git-send-email-frederic.danis@linux.intel.com>
---
doc/settings-storage.txt | 106 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 106 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..bc9ac66
--- /dev/null
+++ b/doc/settings-storage.txt
@@ -0,0 +1,106 @@
+Information related to local adapters and remote devices are stored in storage
+directory (default: /var/lib/bluetooth).
+Files are in ini-file format.
+
+There is one directory per adapter, named by its bluetooth address, which
+contains:
+ - a settings file for the local adapter
+ - an attribute_db file containing attributes of supported LE services
+ - names file containing names of all devices already seen
+ - one directory per remote device, named by remote device address, which
+ contains:
+ - a settings file
+ - a key file accessible only by root
+ - an attribute_db file containing attributes of remote LE services
+
+So the directory structure should be:
+ /var/lib/bluetooth/<adapter address>/
+ ./settings
+ ./attributes
+ ./cache/
+ ./<remote device address>
+ ./<remote device address>
+ ...
+ ./<remote device address>/
+ ./info
+ ./attributes
+ ./<remote device address>/
+ ./info
+ ./attributes
+ ...
+
+Adapter directory files
+=======================
+
+Settings file contains 1 [General] group with adapter info:
+ [General]
+ Name=
+ Class=0x000000
+ Discoverable=<true|false>
+ Connectable=<true|false>
+ Pairable=<true|false>
+ Powered=<true|false>
+ PairableTimeout=0
+ DiscoverableTimeout=0
+
+The attributes file is a list of handles (group name) with UUID and Value as
+keys, for example:
+ [0x0001]
+ UUID=00002800-0000-1000-8000-00805f9b34fb
+ Value=0018
+
+ [0x0004]
+ UUID=00002803-0000-1000-8000-00805f9b34fb
+ Value=020600002A
+
+ [0x0006]
+ UUID=00002a00-0000-1000-8000-00805f9b34fb
+ Value=4578616D706C6520446576696365
+
+Cache directory files
+======================
+
+Each files, named by remote device address, contains 1 [General] group:
+ [General]
+ Name=device name a
+ LastSeen=yyyy-mm-dd hh:mm:ss GMT
+
+Device directory files
+======================
+
+Remote device info file will include a [General] group with device info,
+[DeviceID], [LinkKey] and [LongTermKey] groups with related info:
+ [General]
+ Alias=
+ Class=0x000000
+ Manufacturer=0
+ LmpVersion=
+ LmpSubversion=
+ Features=0000000000000000
+ SupportedTechnologies=<BR/EDR|LE>;<BR/EDR|LE>
+ AddressType=<static|public>
+ LastSeen=yyyy-mm-dd hh:mm:ss GMT
+ LastUsed=yyyy-mm-dd hh:mm:ss GMT
+ Trusted=<true|false>
+ Profiles=<128 bits UUID of profile 1>;<128 bits UUID of profile 2>;...
+
+ [DeviceID]
+ Source=0
+ Vendor=0
+ Product=0
+ Version=0
+
+ [LinkKey]
+ Key=
+ Type=0
+ PINLength=0
+
+ [LongTermKey]
+ Key=
+ Authenticated=<true|false>
+ EncSize=0
+ EDiv=0
+ Rand=0
+
+The attribute_db file is a list of handles (group name) with UUID and Value as
+keys (cf. attribute_db in adapter directory).
--
1.7.9.5
^ permalink raw reply related
* [PATCH v5 00/15] Move storage config and names files to ini-file format
From: Frédéric Danis @ 2012-10-18 9:00 UTC (permalink / raw)
To: linux-bluetooth
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 10 to 15 move devices name cache to new files (read, write and convert).
Frédéric Danis (15):
doc: Add settings storage documentation
adapter: Read name in storage at init
adaptername: Retrieve config name from adapter
adapter: Read device class in storage at init
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
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 | 106 ++++++++++++
plugins/adaptername.c | 6 +-
plugins/dbusoob.c | 26 ++-
plugins/neard.c | 2 +-
profiles/input/device.c | 26 ++-
src/adapter.c | 433 ++++++++++++++++++++++++++++++++++++----------
src/adapter.h | 3 +-
src/device.c | 25 ++-
src/event.c | 51 +++++-
src/mgmt.c | 19 +-
src/mgmt.h | 1 +
tools/hcitool.c | 31 +++-
14 files changed, 610 insertions(+), 127 deletions(-)
create mode 100644 doc/settings-storage.txt
--
1.7.9.5
^ permalink raw reply
* Re: a short question: what are BREDR and AMP?
From: Anand Anand @ 2012-10-18 8:59 UTC (permalink / raw)
To: Kevin Wilson; +Cc: linux-bluetooth
In-Reply-To: <CAGXs5wXpovbxBH6OY_VwL4-cYbaBQgrkKK95QWf1cY1bo0DZdA@mail.gmail.com>
Hi Kevin,
In short :-
BREDR would stand for basic rate enhanced data rate controllers and
AMP would stand for Alternate MAC/PHY(AMP) controllers.
Kindly go through the specification document-
BLUETOOTH SPECIFICATION Version 4.0 for better understanding.
Some excerpts from the spec say :-
Core has two components :-
a)Host
b)Controllers
"An implementation of the Bluetooth Core has only one Primary Controller
which may be one of the following configurations:
• BR/EDR Controller including the Radio, Baseband, Link Manager and
optionally HCI.
• an LE Controller including the LE PHY, Link Layer and optionally HCI.
• a combined BR/EDR Controller portion and LE controller portion (as identified
in the previous two bullets) into a single Controller. This configuration
has only one Bluetooth device address shared by the combination in the
combined Controller.
A Bluetooth core system may additionally have one or more Secondary Controllers
described by the following configuration:
• an Alternate MAC/PHY (AMP) Controller including an 802.11 PAL (Protocol
Adaptation Layer), 802.11 MAC and PHY, and optionally HCI
"
quoted from Bluetooth core documentation.
Hope it helped.
Regards,
Anand
On Thu, Oct 18, 2012 at 1:56 PM, Kevin Wilson <wkevils@gmail.com> wrote:
> Hi,
> I see that the device type of hci_dev can be HCI_BREDR or HCI_AMP.
> (hci_register_dev() in net/bluetooth/hci_core.c).
>
> I have a question if I may: what are these two types?
>
> rgs,
> Kevin
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [RFC] attrib: Fix memleak if att_data_list_alloc fails
From: Ludek Finstrle @ 2012-10-18 8:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ludek Finstrle
In-Reply-To: <CAJdJm_NiL522WPLrV-RiaJKBZeOBBgo_vSzQCwTdZwLZLTw88A@mail.gmail.com>
Fix for memory leak which was introduced in commit f8619bef3406a2134082dc41c208105fe028c09f.
I tested it with older bluez and rebase for git. Please review it.
---
src/attrib-server.c | 12 +++++++++---
1 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/src/attrib-server.c b/src/attrib-server.c
index ea27b13..4489edc 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -490,9 +490,11 @@ static uint16_t read_by_group(struct gatt_channel *channel, uint16_t start,
length = g_slist_length(groups);
adl = att_data_list_alloc(length, last_size + 4);
- if (adl == NULL)
+ if (adl == NULL) {
+ g_slist_free_full(groups, g_free);
return enc_error_resp(ATT_OP_READ_BY_GROUP_REQ, start,
ATT_ECODE_UNLIKELY, pdu, len);
+ }
for (i = 0, l = groups; l; l = l->next, i++) {
uint8_t *value;
@@ -577,9 +579,11 @@ static uint16_t read_by_type(struct gatt_channel *channel, uint16_t start,
length += 2;
adl = att_data_list_alloc(num, length);
- if (adl == NULL)
+ if (adl == NULL) {
+ g_slist_free(types);
return enc_error_resp(ATT_OP_READ_BY_TYPE_REQ, start,
ATT_ECODE_UNLIKELY, pdu, len);
+ }
for (i = 0, l = types; l; i++, l = l->next) {
uint8_t *value;
@@ -655,9 +659,11 @@ static uint16_t find_info(struct gatt_channel *channel, uint16_t start,
}
adl = att_data_list_alloc(num, length + 2);
- if (adl == NULL)
+ if (adl == NULL) {
+ g_slist_free(info);
return enc_error_resp(ATT_OP_FIND_INFO_REQ, start,
ATT_ECODE_UNLIKELY, pdu, len);
+ }
for (i = 0, l = info; l; i++, l = l->next) {
uint8_t *value;
--
1.7.1
^ permalink raw reply related
* Re: [PATCHv2 10/19] Bluetooth: Add logical link confirm
From: Andrei Emeltchenko @ 2012-10-18 8:36 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: Mat Martineau, linux-bluetooth, gustavo, sunnyk
In-Reply-To: <1350494529.26318.121.camel@aeonflux>
Hi,
On Wed, Oct 17, 2012 at 10:22:09AM -0700, Marcel Holtmann wrote:
> Hi Mat,
>
> > The logical link confirm callback is executed when the AMP controller
> > completes its logical link setup. During a channel move, a newly
> > formed logical link allows a move responder to send a move channel
> > response. A move initiator will send a move channel confirm. A
> > failed logical link will end the channel move and send an appropriate
> > response or confirm command indicating a failure.
> >
> > If the channel is being created on an AMP controller, L2CAP
> > configuration is started after the logical link is set up.
> >
> > Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
> > ---
> > net/bluetooth/l2cap_core.c | 114 ++++++++++++++++++++++++++++++++++++++++++++-
> > 1 file changed, 112 insertions(+), 2 deletions(-)
> >
> > diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> > index 5e4796c..ddd8c72 100644
> > --- a/net/bluetooth/l2cap_core.c
> > +++ b/net/bluetooth/l2cap_core.c
> > @@ -3799,6 +3799,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
> > goto unlock;
> > }
> >
> > + chan->ident = cmd->ident;
> > l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
> > chan->num_conf_rsp++;
> >
> > @@ -4241,11 +4242,120 @@ static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
> > l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
> > }
> >
> > +/* Call with chan locked */
> > static void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
> > u8 status)
> > {
> > - /* Placeholder */
> > - return;
> > + BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
> > +
> > + if (status) {
> > + /* Logical link setup failed */
> > + if (chan->state != BT_CONNECTED) {
> > + /* Create channel failure, disconnect */
> > + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
> > + } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
> > + l2cap_move_revert(chan);
> > + chan->move_role = L2CAP_MOVE_ROLE_NONE;
> > + chan->move_state = L2CAP_MOVE_STABLE;
> > + l2cap_send_move_chan_rsp(chan->conn, chan->ident,
> > + chan->dcid, L2CAP_MR_NOT_SUPP);
> > + } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
> > + if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
> > + chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
> > + /* Remote has only sent pending or
> > + * success responses, clean up
> > + */
> > + l2cap_move_revert(chan);
> > + chan->move_role = L2CAP_MOVE_ROLE_NONE;
> > + chan->move_state = L2CAP_MOVE_STABLE;
> > + }
> > +
> > + /* Other amp move states imply that the move
> > + * has already aborted
> > + */
> > + l2cap_send_move_chan_cfm(chan->conn, chan, chan->scid,
> > + L2CAP_MC_UNCONFIRMED);
> > + __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
> > + }
> > +
> > + chan->hs_hchan = NULL;
> > + chan->hs_hcon = NULL;
> > +
> > + /* Placeholder - free logical link */
> > +
> > + } else if (chan->state != BT_CONNECTED) {
> > + struct l2cap_conf_rsp rsp;
> > + u8 code;
> > +
> > + /* Create channel complete */
> > +
> > + /* Ignore logical link if channel is on BR/EDR */
> > + if (!chan->local_amp_id)
> > + return;
> > +
> > + chan->hs_hcon = hchan->conn;
I was thinking that hs_hcon might be assigned when physical link is
completed. Isn't this assignment a bit late?
> > + chan->hs_hcon->l2cap_data = chan->conn;
> > +
> > + code = l2cap_build_conf_rsp(chan, &rsp,
> > + L2CAP_CONF_SUCCESS, 0);
> > + l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CONF_RSP, code,
> > + &rsp);
> > + set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
> > +
> > + if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
> > + int err = 0;
> > +
> > + set_default_fcs(chan);
> > +
> > + err = l2cap_ertm_init(chan);
> > + if (err < 0)
> > + l2cap_send_disconn_req(chan->conn, chan, -err);
> > + else
> > + l2cap_chan_ready(chan);
> > + }
> > + } else {
> > + /* Channel move */
> > + chan->hs_hcon = hchan->conn;
> > + chan->hs_hcon->l2cap_data = chan->conn;
> > +
> > + BT_DBG("move_state %d", chan->move_state);
> > +
> > + switch (chan->move_state) {
> > + case L2CAP_MOVE_WAIT_LOGICAL_COMP:
> > + /* Move confirm will be sent after a success
> > + * response is received
> > + */
> > + chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
> > + break;
> > + case L2CAP_MOVE_WAIT_LOGICAL_CFM:
> > + if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
> > + chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
> > + } else if (chan->move_role ==
> > + L2CAP_MOVE_ROLE_INITIATOR) {
> > + chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
> > + l2cap_send_move_chan_cfm(chan->conn, chan,
> > + chan->scid,
> > + L2CAP_MR_SUCCESS);
> > + __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
> > + } else if (chan->move_role ==
> > + L2CAP_MOVE_ROLE_RESPONDER) {
> > + chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
> > + l2cap_send_move_chan_rsp(chan->conn,
> > + chan->ident,
> > + chan->dcid,
> > + L2CAP_MR_SUCCESS);
> > + }
> > + break;
> > + default:
> > + /* Move was not in expected state, free the channel */
> > + chan->hs_hchan = NULL;
> > + chan->hs_hcon = NULL;
> > +
> > + /* Placeholder - free the logical link */
> > +
> > + chan->move_state = L2CAP_MOVE_STABLE;
> > + }
> > + }
> > }
> >
>
> I find this this function still a little bit too complex. Any chance we
> can split into more logical pieces. It is fine if not, but we should at
> least give it another try.
IMO this would be much cleaner if you would handle (status) case first
then channel create and then channel move without "if else", maybe
splitting to functions would be better.
Best regards
Andrei Emeltchenko
^ permalink raw reply
* a short question: what are BREDR and AMP?
From: Kevin Wilson @ 2012-10-18 8:26 UTC (permalink / raw)
To: linux-bluetooth
Hi,
I see that the device type of hci_dev can be HCI_BREDR or HCI_AMP.
(hci_register_dev() in net/bluetooth/hci_core.c).
I have a question if I may: what are these two types?
rgs,
Kevin
^ permalink raw reply
* Re: [PATCHv2 07/19] Bluetooth: Add move channel confirm handling
From: Andrei Emeltchenko @ 2012-10-18 7:48 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: Mat Martineau, linux-bluetooth, gustavo, sunnyk
In-Reply-To: <1350494187.26318.119.camel@aeonflux>
Hi Marcel,
On Wed, Oct 17, 2012 at 10:16:27AM -0700, Marcel Holtmann wrote:
> Hi Mat,
>
> > After sending a move channel response, a move responder waits for a
> > move channel confirm command. If the received command has a
> > "confirmed" result the move is proceeding, and "unconfirmed" means the
> > move has failed and the channel will not change controllers.
> >
> > Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
> > ---
> > net/bluetooth/l2cap_core.c | 70 ++++++++++++++++++++++++++++++++++++++++++++--
> > 1 file changed, 67 insertions(+), 3 deletions(-)
> >
> > diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> > index 9663292..ed2c23f 100644
> > --- a/net/bluetooth/l2cap_core.c
> > +++ b/net/bluetooth/l2cap_core.c
> > @@ -1036,6 +1036,42 @@ static void l2cap_move_setup(struct l2cap_chan *chan)
> > set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
> > }
> >
> > +static void l2cap_move_success(struct l2cap_chan *chan)
> > +{
> > + BT_DBG("chan %p", chan);
> > +
> > + if (chan->mode != L2CAP_MODE_ERTM)
> > + return;
> > +
> > + switch (chan->move_role) {
> > + case L2CAP_MOVE_ROLE_INITIATOR:
> > + l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
> > + chan->rx_state = L2CAP_RX_STATE_WAIT_F;
> > + break;
> > + case L2CAP_MOVE_ROLE_RESPONDER:
> > + chan->rx_state = L2CAP_RX_STATE_WAIT_P;
> > + break;
> > + }
> > +}
> > +
> > +static void l2cap_move_revert(struct l2cap_chan *chan)
> > +{
> > + BT_DBG("chan %p", chan);
> > +
> > + if (chan->mode != L2CAP_MODE_ERTM)
> > + return;
> > +
> > + switch (chan->move_role) {
> > + case L2CAP_MOVE_ROLE_INITIATOR:
> > + l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
> > + chan->rx_state = L2CAP_RX_STATE_WAIT_F;
> > + break;
> > + case L2CAP_MOVE_ROLE_RESPONDER:
> > + chan->rx_state = L2CAP_RX_STATE_WAIT_P;
> > + break;
> > + }
> > +}
> > +
> > static void l2cap_chan_ready(struct l2cap_chan *chan)
> > {
> > /* This clears all conf flags, including CONF_NOT_COMPLETE */
> > @@ -4302,11 +4338,12 @@ static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn,
> > return 0;
> > }
> >
> > -static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn,
> > - struct l2cap_cmd_hdr *cmd,
> > - u16 cmd_len, void *data)
> > +static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
> > + struct l2cap_cmd_hdr *cmd,
> > + u16 cmd_len, void *data)
> > {
> > struct l2cap_move_chan_cfm *cfm = data;
> > + struct l2cap_chan *chan;
> > u16 icid, result;
> >
> > if (cmd_len != sizeof(*cfm))
> > @@ -4317,8 +4354,35 @@ static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn,
> >
> > BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
> >
> > + chan = l2cap_get_chan_by_dcid(conn, icid);
> > + if (!chan)
> > + goto send_move_confirm_response;
> > +
> > + if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
> > + chan->move_state = L2CAP_MOVE_STABLE;
> > + if (result == L2CAP_MC_CONFIRMED) {
> > + chan->local_amp_id = chan->move_id;
> > + if (!chan->local_amp_id) {
> > + /* Have moved off of AMP, free the channel */
> > + chan->hs_hchan = NULL;
> > + chan->hs_hcon = NULL;
> > +
> > + /* Placeholder - free the logical link */
> > + }
> > + l2cap_move_success(chan);
> > + } else {
> > + chan->move_id = chan->local_amp_id;
> > + l2cap_move_revert(chan);
> > + }
> > + chan->move_role = L2CAP_MOVE_ROLE_NONE;
> > + }
> > +
> > +send_move_confirm_response:
> > l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
> >
> > + if (chan)
> > + l2cap_chan_unlock(chan);
> > +
>
> still not a big fan of the if (chan) check before the unlock. This way
> of dealing with locks makes my brain hurt ;)
I think in this case the solution would be to invoke
l2cap_send_move_chan_cfm_rsp 2 times: 1st time atfer checking (!chan) and
second time here. Since this message does not need any error code this
looks OK to me.
Best regards
Andrei Emeltchenko
^ permalink raw reply
* Re: [PATCHv2 05/19] Bluetooth: Channel move request handling
From: Andrei Emeltchenko @ 2012-10-18 7:38 UTC (permalink / raw)
To: Mat Martineau; +Cc: linux-bluetooth, gustavo, sunnyk, marcel
In-Reply-To: <1350430593-23565-6-git-send-email-mathewm@codeaurora.org>
Hi Mat,
On Tue, Oct 16, 2012 at 04:36:19PM -0700, Mat Martineau wrote:
> On receipt of a channel move request, the request must be validated
> based on the L2CAP mode, connection state, and controller
> capabilities. ERTM channels must have their state machines cleared
> and transmission paused while the channel move takes place.
>
> If the channel is being moved to an AMP controller then
> an AMP physical link must be prepared. Moving the channel back to
> BR/EDR proceeds immediately.
>
> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
> Acked-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> net/bluetooth/l2cap_core.c | 108 ++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 107 insertions(+), 1 deletion(-)
>
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index b5b849b..2fb0567 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -734,6 +734,12 @@ static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
> hci_send_acl(conn->hchan, skb, flags);
> }
>
> +static bool __chan_is_moving(struct l2cap_chan *chan)
> +{
> + return chan->move_state != L2CAP_MOVE_STABLE &&
> + chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
> +}
this one looks good now
> +
> static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
> {
> struct hci_conn *hcon = chan->conn->hcon;
> @@ -995,6 +1001,41 @@ void l2cap_send_conn_req(struct l2cap_chan *chan)
> l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
> }
>
> +static void l2cap_move_setup(struct l2cap_chan *chan)
> +{
> + struct sk_buff *skb;
> +
> + BT_DBG("chan %p", chan);
> +
> + if (chan->mode != L2CAP_MODE_ERTM)
> + return;
> +
> + __clear_retrans_timer(chan);
> + __clear_monitor_timer(chan);
> + __clear_ack_timer(chan);
> +
> + chan->retry_count = 0;
> + skb_queue_walk(&chan->tx_q, skb) {
> + if (bt_cb(skb)->control.retries)
> + bt_cb(skb)->control.retries = 1;
> + else
> + break;
> + }
> +
> + chan->expected_tx_seq = chan->buffer_seq;
> +
> + clear_bit(CONN_REJ_ACT, &chan->conn_state);
> + clear_bit(CONN_SREJ_ACT, &chan->conn_state);
> + l2cap_seq_list_clear(&chan->retrans_list);
> + l2cap_seq_list_clear(&chan->srej_list);
> + skb_queue_purge(&chan->srej_q);
> +
> + chan->tx_state = L2CAP_TX_STATE_XMIT;
> + chan->rx_state = L2CAP_RX_STATE_MOVE;
> +
> + set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
> +}
> +
> static void l2cap_chan_ready(struct l2cap_chan *chan)
> {
> /* This clears all conf flags, including CONF_NOT_COMPLETE */
> @@ -4169,9 +4210,74 @@ static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
> if (!enable_hs)
> return -EINVAL;
>
> - /* Placeholder: Always refuse */
> + chan = l2cap_get_chan_by_dcid(conn, icid);
> +
extra line here
> + if (!chan || chan->scid < L2CAP_CID_DYN_START ||
> + chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
> + (chan->mode != L2CAP_MODE_ERTM &&
> + chan->mode != L2CAP_MODE_STREAMING)) {
> + result = L2CAP_MR_NOT_ALLOWED;
> + goto send_move_response;
> + }
> +
> + if (chan->local_amp_id == req->dest_amp_id) {
> + result = L2CAP_MR_SAME_ID;
> + goto send_move_response;
> + }
> +
> + if (req->dest_amp_id) {
here you compare "(val)"
> + struct hci_dev *hdev;
> + hdev = hci_dev_get(req->dest_amp_id);
> + if (!hdev || hdev->dev_type != HCI_AMP ||
> + !test_bit(HCI_UP, &hdev->flags)) {
> + if (hdev)
> + hci_dev_put(hdev);
> +
> + result = L2CAP_MR_BAD_ID;
> + goto send_move_response;
> + }
> + hci_dev_put(hdev);
> + }
> +
> + /* Detect a move collision. Only send a collision response
> + * if this side has "lost", otherwise proceed with the move.
> + * The winner has the larger bd_addr.
> + */
> + if ((__chan_is_moving(chan) ||
> + chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
> + bacmp(conn->src, conn->dst) > 0) {
> + result = L2CAP_MR_COLLISION;
> + goto send_move_response;
> + }
> +
> + chan->ident = cmd->ident;
> + chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
> + l2cap_move_setup(chan);
> + chan->move_id = req->dest_amp_id;
> + icid = chan->dcid;
> +
> + if (req->dest_amp_id == 0) {
and here "(val == 0)"
I think it is better to use the single style "(val)"
> + /* Moving to BR/EDR */
> + if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
> + chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
> + result = L2CAP_MR_PEND;
> + } else {
> + chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
> + result = L2CAP_MR_SUCCESS;
> + }
> + } else {
> + chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
> + /* Placeholder - uncomment when amp functions are available */
> + /*amp_accept_physical(chan, req->dest_amp_id);*/
> + result = L2CAP_MR_PEND;
> + }
> +
> +send_move_response:
> l2cap_send_move_chan_rsp(conn, cmd->ident, icid, result);
>
> + if (chan)
> + l2cap_chan_unlock(chan);
> +
> return 0;
> }
Best regards
Andrei Emeltchenko
^ permalink raw reply
* Re: [RFC BlueZ] adapter: Fix memory leak on discovery cleanup
From: Johan Hedberg @ 2012-10-18 7:33 UTC (permalink / raw)
To: Anderson Lizardo; +Cc: linux-bluetooth
In-Reply-To: <1350515709-30389-1-git-send-email-anderson.lizardo@openbossa.org>
Hi Lizardo,
On Wed, Oct 17, 2012, Anderson Lizardo wrote:
> During discovery cleanup, it was attempted to send a DevicesFound()
> D-Bus signal for pending found devices, but adapter->discovery was set
> to NULL before calling send_devices_found(), therefore it never sent any
> signal (and there was a leak of discovery->pending list).
>
> Fixes this memory leak when pairing two LE devices:
>
> ==1822== 8 bytes in 1 blocks are definitely lost in loss record 42 of
> 246
> ==1822== at 0x482BE68: malloc (in
> /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
> ==1822== by 0x48869AA: standard_malloc (gmem.c:85)
> ==1822== by 0x4886E42: g_malloc (gmem.c:159)
> ==1822== by 0x489B26D: g_slice_alloc (gslice.c:1003)
> ==1822== by 0x489C10A: g_slist_prepend (gslist.c:265)
> ==1822== by 0x1855AE: adapter_update_found_devices (adapter.c:2846)
> ==1822== by 0x191431: btd_event_device_found (event.c:260)
> ==1822== by 0xBC01001A: ???
> ==1822==
> ---
> src/adapter.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
Applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCHv2 04/19] Bluetooth: Lookup channel structure based on DCID
From: Andrei Emeltchenko @ 2012-10-18 7:30 UTC (permalink / raw)
To: Mat Martineau; +Cc: linux-bluetooth, gustavo, sunnyk, marcel
In-Reply-To: <1350430593-23565-5-git-send-email-mathewm@codeaurora.org>
Hi Mat,
On Tue, Oct 16, 2012 at 04:36:18PM -0700, Mat Martineau wrote:
> Processing a move channel request involves getting the channel
> structure using the destination channel ID. Previous code could only
> look up using the source channel ID.
>
> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
> ---
> net/bluetooth/l2cap_core.c | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
>
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index ec2b4d9..b5b849b 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -100,6 +100,22 @@ static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
> return c;
> }
>
> +/* Find channel with given DCID.
> + * Returns locked channel. */
> +static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
> + u16 cid)
> +{
> + struct l2cap_chan *c;
> +
> + mutex_lock(&conn->chan_lock);
> + c = __l2cap_get_chan_by_dcid(conn, cid);
> + if (c)
> + l2cap_chan_lock(c);
> + mutex_unlock(&conn->chan_lock);
> +
> + return c;
> +}
> +
> static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
> u8 ident)
> {
> @@ -4139,6 +4155,7 @@ static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
> u16 cmd_len, void *data)
> {
> struct l2cap_move_chan_req *req = data;
> + struct l2cap_chan *chan;
This line seems do not belong to the patch.
Best regards
Andrei Emeltchenko
> u16 icid = 0;
> u16 result = L2CAP_MR_NOT_ALLOWED;
^ permalink raw reply
* [RFC BlueZ] adapter: Fix memory leak on discovery cleanup
From: Anderson Lizardo @ 2012-10-17 23:15 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
During discovery cleanup, it was attempted to send a DevicesFound()
D-Bus signal for pending found devices, but adapter->discovery was set
to NULL before calling send_devices_found(), therefore it never sent any
signal (and there was a leak of discovery->pending list).
Fixes this memory leak when pairing two LE devices:
==1822== 8 bytes in 1 blocks are definitely lost in loss record 42 of
246
==1822== at 0x482BE68: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==1822== by 0x48869AA: standard_malloc (gmem.c:85)
==1822== by 0x4886E42: g_malloc (gmem.c:159)
==1822== by 0x489B26D: g_slice_alloc (gslice.c:1003)
==1822== by 0x489C10A: g_slist_prepend (gslist.c:265)
==1822== by 0x1855AE: adapter_update_found_devices (adapter.c:2846)
==1822== by 0x191431: btd_event_device_found (event.c:260)
==1822== by 0xBC01001A: ???
==1822==
---
src/adapter.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 7c2aec0..3b24816 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -556,8 +556,6 @@ static void discovery_cleanup(struct btd_adapter *adapter)
{
struct discovery *discovery = adapter->discovery;
- adapter->discovery = NULL;
-
if (!discovery)
return;
@@ -566,6 +564,8 @@ static void discovery_cleanup(struct btd_adapter *adapter)
send_devices_found(adapter);
+ adapter->discovery = NULL;
+
g_slist_free_full(discovery->found, invalidate_rssi);
g_free(discovery);
--
1.7.9.5
^ permalink raw reply related
* obex-client: support authentication response?
From: Mike @ 2012-10-17 21:13 UTC (permalink / raw)
To: linux-bluetooth
I'm trying to pass TP/SSM/BV-6-C (respond to authentication requests)
for PBAP. As far as I can see, there is code in the obex server to
respond to challenge requests, but I don't think I see any for the
client. As for when it runs against PTS, obex-client initiates a
disconnect when it gets the unauthorized response code. Am I missing
something?
Thanks,
Mike
^ permalink raw reply
* Re: [PATCH BlueZ 2/2] core: Update gdbus function calls
From: Lucas De Marchi @ 2012-10-17 18:33 UTC (permalink / raw)
To: Anderson Lizardo; +Cc: linux-bluetooth
In-Reply-To: <CAJdJm_OqOs4-U4E+nN9VQ362F0aWe+qJnyxWVF_ABscwQE+5wA@mail.gmail.com>
On Wed, Oct 17, 2012 at 1:25 PM, Anderson Lizardo
<anderson.lizardo@openbossa.org> wrote:
> Hi again,
>
> On Wed, Oct 17, 2012 at 1:20 PM, Anderson Lizardo
> <anderson.lizardo@openbossa.org> wrote:
>> Hi Lucas,
>>
>> On Wed, Oct 17, 2012 at 12:14 PM, Lucas De Marchi
>> <lucas.demarchi@profusion.mobi> wrote:
>>> @@ -827,24 +824,21 @@ static void set_name(struct btd_adapter *adapter, const char *name,
>>> int ret;
>>>
>>> if (adapter->allow_name_changes == FALSE)
>>> - return g_dbus_pending_property_error(btd_get_dbus_connection(),
>>> - id, ERROR_INTERFACE ".Failed",
>>> + return g_dbus_pending_property_error(id,
>>> + ERROR_INTERFACE ".Failed",
>>> strerror(EPERM));
>>>
>>> ret = adapter_set_name(adapter, name);
>>> - if (ret >= 0) {
>>> - g_dbus_pending_property_success(btd_get_dbus_connection(), id);
>>> - return;
>>> - }
>>> + if (ret >= 0)
>>> + return g_dbus_pending_property_success(id);
>>
>> Out of curiosity, is this style of returning "void" (instead of just
>> "return;") common in gdbus?
>
> Just realized that this is BlueZ specific code. Anyway, just found it
> odd (but answering my question, seems to be common).
It may be common because I used it a lot in the first conversions :-).
I don't know about other places using it. In gdbus-related code it's
very convenient because the function usually returns void as well, so
we can shortcut it with the g_dbus_pending_property_* calls.
Lucas De Marchi
^ permalink raw reply
* Re: [PATCHv2 17/19] Bluetooth: Send create channel request instead of connect for AMP
From: Marcel Holtmann @ 2012-10-17 17:24 UTC (permalink / raw)
To: Mat Martineau; +Cc: linux-bluetooth, gustavo, sunnyk
In-Reply-To: <1350430593-23565-18-git-send-email-mathewm@codeaurora.org>
Hi Mat,
> When the channel policy is set to prefer AMP, then an L2CAP channel is
> set up using the "create channel" command rather than the "connect"
> command. A physical link is also set up before sending "create
> channel".
>
> Behavior is unchanged if enable_hs is false.
>
> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
> ---
> net/bluetooth/l2cap_core.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 42 insertions(+)
>
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index 7e8fe84..17d917b 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -58,6 +58,9 @@ static void l2cap_send_disconn_req(struct l2cap_conn *conn,
> static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
> struct sk_buff_head *skbs, u8 event);
>
> +static void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
> + u8 status);
> +
any chance to avoid this forward declaration by moving some functions
around?
> /* ---- L2CAP channels ---- */
>
> static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
> @@ -576,6 +579,13 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
> mgr->bredr_chan = NULL;
> }
>
> + if (chan->hs_hchan) {
> + chan->hs_hchan = NULL;
> + chan->hs_hcon = NULL;
> +
> + /* Placeholder - free logical link */
> + }
> +
> chan->ops->teardown(chan, err);
>
> if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
> @@ -1126,6 +1136,7 @@ static void l2cap_start_connection(struct l2cap_chan *chan)
> {
> if (__amp_capable(chan)) {
> BT_DBG("chan %p AMP capable: discover AMPs", chan);
> + set_bit(CONF_CONNECT_PEND, &chan->conf_state);
> a2mp_discover_amp(chan);
> } else {
> l2cap_send_conn_req(chan);
> @@ -1271,6 +1282,16 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
> rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
> }
>
> + if (rsp.result == __constant_cpu_to_le16(L2CAP_CR_SUCCESS) &&
> + chan->local_amp_id) {
> + /* Placeholder - uncomment when amp functions
> + * are available
> + amp_accept_physical(chan, chan->local_amp_id);
> + */
> + l2cap_chan_unlock(chan);
> + continue;
> + }
> +
> l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
> sizeof(rsp), &rsp);
>
> @@ -3359,6 +3380,18 @@ done:
> rfc.mode = chan->mode;
> }
>
> + if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state) &&
> + chan->local_amp_id) {
> + struct hci_chan *hchan = NULL;
> +
> + /* Placeholder - get hci_chan for logical link */
> +
> + if (hchan && hchan->state == BT_CONNECTED) {
> + l2cap_logical_cfm(chan, hchan,
> + L2CAP_MR_SUCCESS);
> + }
> + }
> +
> if (result == L2CAP_CONF_SUCCESS)
> set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
> }
> @@ -6367,6 +6400,15 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
> stat = L2CAP_CS_AUTHOR_PEND;
> chan->ops->defer(chan);
> } else {
> + if (chan->local_amp_id) {
> + /* Placeholder - accept physical
> + * link
> + amp_accept_physical(chan,
> + chan->local_amp_id);
> + */
> + continue;
> + }
> +
> __l2cap_state_change(chan, BT_CONFIG);
> res = L2CAP_CR_SUCCESS;
> stat = L2CAP_CS_NO_INFO;
Check the forward declaration and fix it if possible. Otherwise this is
fine.
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Regards
Marcel
^ permalink raw reply
* Re: [PATCHv2 10/19] Bluetooth: Add logical link confirm
From: Marcel Holtmann @ 2012-10-17 17:22 UTC (permalink / raw)
To: Mat Martineau; +Cc: linux-bluetooth, gustavo, sunnyk
In-Reply-To: <1350430593-23565-11-git-send-email-mathewm@codeaurora.org>
Hi Mat,
> The logical link confirm callback is executed when the AMP controller
> completes its logical link setup. During a channel move, a newly
> formed logical link allows a move responder to send a move channel
> response. A move initiator will send a move channel confirm. A
> failed logical link will end the channel move and send an appropriate
> response or confirm command indicating a failure.
>
> If the channel is being created on an AMP controller, L2CAP
> configuration is started after the logical link is set up.
>
> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
> ---
> net/bluetooth/l2cap_core.c | 114 ++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 112 insertions(+), 2 deletions(-)
>
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index 5e4796c..ddd8c72 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -3799,6 +3799,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
> goto unlock;
> }
>
> + chan->ident = cmd->ident;
> l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
> chan->num_conf_rsp++;
>
> @@ -4241,11 +4242,120 @@ static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
> l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
> }
>
> +/* Call with chan locked */
> static void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
> u8 status)
> {
> - /* Placeholder */
> - return;
> + BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
> +
> + if (status) {
> + /* Logical link setup failed */
> + if (chan->state != BT_CONNECTED) {
> + /* Create channel failure, disconnect */
> + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
> + } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
> + l2cap_move_revert(chan);
> + chan->move_role = L2CAP_MOVE_ROLE_NONE;
> + chan->move_state = L2CAP_MOVE_STABLE;
> + l2cap_send_move_chan_rsp(chan->conn, chan->ident,
> + chan->dcid, L2CAP_MR_NOT_SUPP);
> + } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
> + if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
> + chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
> + /* Remote has only sent pending or
> + * success responses, clean up
> + */
> + l2cap_move_revert(chan);
> + chan->move_role = L2CAP_MOVE_ROLE_NONE;
> + chan->move_state = L2CAP_MOVE_STABLE;
> + }
> +
> + /* Other amp move states imply that the move
> + * has already aborted
> + */
> + l2cap_send_move_chan_cfm(chan->conn, chan, chan->scid,
> + L2CAP_MC_UNCONFIRMED);
> + __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
> + }
> +
> + chan->hs_hchan = NULL;
> + chan->hs_hcon = NULL;
> +
> + /* Placeholder - free logical link */
> +
> + } else if (chan->state != BT_CONNECTED) {
> + struct l2cap_conf_rsp rsp;
> + u8 code;
> +
> + /* Create channel complete */
> +
> + /* Ignore logical link if channel is on BR/EDR */
> + if (!chan->local_amp_id)
> + return;
> +
> + chan->hs_hcon = hchan->conn;
> + chan->hs_hcon->l2cap_data = chan->conn;
> +
> + code = l2cap_build_conf_rsp(chan, &rsp,
> + L2CAP_CONF_SUCCESS, 0);
> + l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CONF_RSP, code,
> + &rsp);
> + set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
> +
> + if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
> + int err = 0;
> +
> + set_default_fcs(chan);
> +
> + err = l2cap_ertm_init(chan);
> + if (err < 0)
> + l2cap_send_disconn_req(chan->conn, chan, -err);
> + else
> + l2cap_chan_ready(chan);
> + }
> + } else {
> + /* Channel move */
> + chan->hs_hcon = hchan->conn;
> + chan->hs_hcon->l2cap_data = chan->conn;
> +
> + BT_DBG("move_state %d", chan->move_state);
> +
> + switch (chan->move_state) {
> + case L2CAP_MOVE_WAIT_LOGICAL_COMP:
> + /* Move confirm will be sent after a success
> + * response is received
> + */
> + chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
> + break;
> + case L2CAP_MOVE_WAIT_LOGICAL_CFM:
> + if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
> + chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
> + } else if (chan->move_role ==
> + L2CAP_MOVE_ROLE_INITIATOR) {
> + chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
> + l2cap_send_move_chan_cfm(chan->conn, chan,
> + chan->scid,
> + L2CAP_MR_SUCCESS);
> + __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
> + } else if (chan->move_role ==
> + L2CAP_MOVE_ROLE_RESPONDER) {
> + chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
> + l2cap_send_move_chan_rsp(chan->conn,
> + chan->ident,
> + chan->dcid,
> + L2CAP_MR_SUCCESS);
> + }
> + break;
> + default:
> + /* Move was not in expected state, free the channel */
> + chan->hs_hchan = NULL;
> + chan->hs_hcon = NULL;
> +
> + /* Placeholder - free the logical link */
> +
> + chan->move_state = L2CAP_MOVE_STABLE;
> + }
> + }
> }
>
I find this this function still a little bit too complex. Any chance we
can split into more logical pieces. It is fine if not, but we should at
least give it another try.
Regards
Marcel
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox