* [PATCH v2 11/15] device: Store SDP records in new storage
From: Frédéric Danis @ 2012-12-13 20:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1355431170-12897-1-git-send-email-frederic.danis@linux.intel.com>
Store SDP records in device file located in cache directory.
Update attributes file with primary services retrieved from attributes
entry in SDP records.
Remove store_record() from storage.[ch].
---
src/device.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
src/storage.c | 33 ----------------
src/storage.h | 2 -
3 files changed, 122 insertions(+), 36 deletions(-)
diff --git a/src/device.c b/src/device.c
index 36840a6..d49b397 100644
--- a/src/device.c
+++ b/src/device.c
@@ -2461,6 +2461,77 @@ static void uuids_changed(struct btd_device *device)
g_free(uuids);
}
+static void store_sdp_record(GKeyFile *key_file, sdp_record_t *rec)
+{
+ char handle_str[11];
+ sdp_buf_t buf;
+ int size, i;
+ char *str;
+
+ sprintf(handle_str, "0x%8.8X", rec->handle);
+
+ if (sdp_gen_record_pdu(rec, &buf) < 0)
+ return;
+
+ size = buf.data_size;
+
+ str = g_malloc0(size*2+1);
+
+ for (i = 0; i < size; i++)
+ sprintf(str + (i * 2), "%02X", buf.data[i]);
+
+ g_key_file_set_string(key_file, "ServiceRecords", handle_str, str);
+
+ free(buf.data);
+ g_free(str);
+}
+
+static void store_primaries_from_sdp_record(GKeyFile *key_file,
+ sdp_record_t *rec)
+{
+ uuid_t uuid;
+ char *att_uuid, *prim_uuid;
+ uint16_t start = 0, end = 0, psm = 0;
+ char handle[6], uuid_str[33];
+ int i;
+
+ sdp_uuid16_create(&uuid, ATT_UUID);
+ att_uuid = bt_uuid2string(&uuid);
+
+ sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
+ prim_uuid = bt_uuid2string(&uuid);
+
+ if (!record_has_uuid(rec, att_uuid))
+ goto done;
+
+ if (!gatt_parse_record(rec, &uuid, &psm, &start, &end))
+ goto done;
+
+ sprintf(handle, "%hu", start);
+ switch (uuid.type) {
+ case SDP_UUID16:
+ sprintf(uuid_str, "%4.4X", uuid.value.uuid16);
+ break;
+ case SDP_UUID32:
+ sprintf(uuid_str, "%8.8X", uuid.value.uuid32);
+ break;
+ case SDP_UUID128:
+ for (i = 0; i < 16; i++)
+ sprintf(uuid_str + (i * 2), "%2.2X",
+ uuid.value.uuid128.data[i]);
+ break;
+ default:
+ uuid_str[0] = '\0';
+ }
+
+ g_key_file_set_string(key_file, handle, "UUID", prim_uuid);
+ g_key_file_set_string(key_file, handle, "Value", uuid_str);
+
+done:
+ g_free(prim_uuid);
+ g_free(att_uuid);
+}
+
static int rec_cmp(const void *a, const void *b)
{
const sdp_record_t *r1 = a;
@@ -2474,10 +2545,32 @@ static void update_bredr_services(struct browse_req *req, sdp_list_t *recs)
struct btd_device *device = req->device;
sdp_list_t *seq;
char srcaddr[18], dstaddr[18];
+ char sdp_file[PATH_MAX + 1];
+ char att_file[PATH_MAX + 1];
+ GKeyFile *sdp_key_file = NULL;
+ GKeyFile *att_key_file = NULL;
+ char *data;
+ gsize length = 0;
ba2str(adapter_get_address(device->adapter), srcaddr);
ba2str(&device->bdaddr, dstaddr);
+ if (!device->temporary) {
+ snprintf(sdp_file, PATH_MAX, STORAGEDIR "/%s/cache/%s",
+ srcaddr, dstaddr);
+ sdp_file[PATH_MAX] = '\0';
+
+ sdp_key_file = g_key_file_new();
+ g_key_file_load_from_file(sdp_key_file, sdp_file, 0, NULL);
+
+ snprintf(att_file, PATH_MAX, STORAGEDIR "/%s/%s/attributes",
+ srcaddr, dstaddr);
+ att_file[PATH_MAX] = '\0';
+
+ att_key_file = g_key_file_new();
+ g_key_file_load_from_file(att_key_file, att_file, 0, NULL);
+ }
+
for (seq = recs; seq; seq = seq->next) {
sdp_record_t *rec = (sdp_record_t *) seq->data;
sdp_list_t *svcclass = NULL;
@@ -2531,7 +2624,11 @@ static void update_bredr_services(struct browse_req *req, sdp_list_t *recs)
continue;
}
- store_record(srcaddr, dstaddr, device->bdaddr_type, rec);
+ if (sdp_key_file)
+ store_sdp_record(sdp_key_file, rec);
+
+ if (att_key_file)
+ store_primaries_from_sdp_record(att_key_file, rec);
/* Copy record */
req->records = sdp_list_append(req->records,
@@ -2552,6 +2649,30 @@ static void update_bredr_services(struct browse_req *req, sdp_list_t *recs)
sdp_list_free(svcclass, free);
}
+
+ if (sdp_key_file) {
+ data = g_key_file_to_data(sdp_key_file, &length, NULL);
+ if (length > 0) {
+ create_file(sdp_file, S_IRUSR | S_IWUSR |
+ S_IRGRP | S_IROTH);
+ g_file_set_contents(sdp_file, data, length, NULL);
+ }
+
+ g_free(data);
+ g_key_file_free(sdp_key_file);
+ }
+
+ if (att_key_file) {
+ data = g_key_file_to_data(att_key_file, &length, NULL);
+ if (length > 0) {
+ create_file(att_file, S_IRUSR | S_IWUSR |
+ S_IRGRP | S_IROTH);
+ g_file_set_contents(att_file, data, length, NULL);
+ }
+
+ g_free(data);
+ g_key_file_free(att_key_file);
+ }
}
static gint primary_cmp(gconstpointer a, gconstpointer b)
diff --git a/src/storage.c b/src/storage.c
index d4516ed..180946f 100644
--- a/src/storage.c
+++ b/src/storage.c
@@ -245,39 +245,6 @@ ssize_t read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin)
return len;
}
-int store_record(const gchar *src, const gchar *dst, uint8_t dst_type,
- sdp_record_t *rec)
-{
- char filename[PATH_MAX + 1], key[30];
- sdp_buf_t buf;
- int err, size, i;
- char *str;
-
- create_name(filename, PATH_MAX, STORAGEDIR, src, "sdp");
-
- create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
- snprintf(key, sizeof(key), "%17s#%hhu#%08X", dst, dst_type,
- rec->handle);
-
- if (sdp_gen_record_pdu(rec, &buf) < 0)
- return -1;
-
- size = buf.data_size;
-
- str = g_malloc0(size*2+1);
-
- for (i = 0; i < size; i++)
- sprintf(str + (i * 2), "%02X", buf.data[i]);
-
- err = textfile_put(filename, key, str);
-
- free(buf.data);
- g_free(str);
-
- return err;
-}
-
sdp_record_t *record_from_string(const gchar *str)
{
sdp_record_t *rec;
diff --git a/src/storage.h b/src/storage.h
index ffc6deb..262a594 100644
--- a/src/storage.h
+++ b/src/storage.h
@@ -35,8 +35,6 @@ int read_remote_appearance(const bdaddr_t *local, const bdaddr_t *peer,
int write_lastused_info(const bdaddr_t *local, const bdaddr_t *peer,
uint8_t peer_type, struct tm *tm);
ssize_t read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin);
-int store_record(const gchar *src, const gchar *dst, uint8_t dst_type,
- sdp_record_t *rec);
sdp_record_t *record_from_string(const gchar *str);
sdp_record_t *fetch_record(const gchar *src, const gchar *dst,
uint8_t dst_type, const uint32_t handle);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 10/15] device: Load primary attributes from storage
From: Frédéric Danis @ 2012-12-13 20:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1355431170-12897-1-git-send-email-frederic.danis@linux.intel.com>
Parse device attributes file for primary services, then add UUID service
to device primaries list.
---
src/device.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/src/device.c b/src/device.c
index 24e97e6..36840a6 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1879,6 +1879,81 @@ next:
store_device_info(device);
}
+static void load_att_info(struct btd_device *device, const gchar *local,
+ const gchar *peer)
+{
+ char filename[PATH_MAX + 1];
+ GKeyFile *key_file;
+ char *prim_uuid, *str;
+ char **groups, **handle, *service_uuid;
+ struct gatt_primary *prim;
+ uuid_t uuid;
+ char tmp[3];
+ int i;
+
+ sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
+ prim_uuid = bt_uuid2string(&uuid);
+
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/attributes", local,
+ peer);
+ filename[PATH_MAX] = '\0';
+
+ key_file = g_key_file_new();
+ g_key_file_load_from_file(key_file, filename, 0, NULL);
+ groups = g_key_file_get_groups(key_file, NULL);
+
+ for (handle = groups; *handle; handle++) {
+ str = g_key_file_get_string(key_file, *handle, "UUID", NULL);
+ if (!str)
+ continue;
+
+ if (!g_str_equal(str, prim_uuid))
+ continue;
+
+ g_free(str);
+
+ str = g_key_file_get_string(key_file, *handle, "Value", NULL);
+ if (!str)
+ continue;
+
+ prim = g_new0(struct gatt_primary, 1);
+ prim->range.start = atoi(*handle);
+
+ switch (strlen(str)) {
+ case 4:
+ uuid.type = SDP_UUID16;
+ sscanf(str, "%04hx", &uuid.value.uuid16);
+ break;
+ case 8:
+ uuid.type = SDP_UUID32;
+ sscanf(str, "%08x", &uuid.value.uuid32);
+ break;
+ case 32:
+ uuid.type = SDP_UUID128;
+ memset(tmp, 0, sizeof(tmp));
+ for (i = 0; i < 16; i++) {
+ memcpy(tmp, str + (i * 2), 2);
+ uuid.value.uuid128.data[i] =
+ (uint8_t) strtol(tmp, NULL, 16);
+ }
+ break;
+ default:
+ continue;
+ }
+
+ service_uuid = bt_uuid2string(&uuid);
+ memcpy(prim->uuid, service_uuid, MAX_LEN_UUID_STR);
+ g_free(service_uuid);
+ g_free(str);
+
+ device->primaries = g_slist_append(device->primaries, prim);
+ }
+
+ g_strfreev(groups);
+ g_key_file_free(key_file);
+ g_free(prim_uuid);
+}
+
static struct btd_device *device_new(struct btd_adapter *adapter,
const gchar *address)
{
@@ -1927,6 +2002,7 @@ struct btd_device *device_create_from_storage(struct btd_adapter *adapter,
ba2str(src, srcaddr);
load_info(device, srcaddr, address, key_file);
+ load_att_info(device, srcaddr, address);
return device;
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 09/15] device: Remove stored SDP records on device removal
From: Frédéric Danis @ 2012-12-13 20:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1355431170-12897-1-git-send-email-frederic.danis@linux.intel.com>
Also remove management of legacy storage file in device_remove_stored().
Remove no more used storage functions.
---
src/device.c | 31 +++++++++++++++++--------
src/storage.c | 72 ---------------------------------------------------------
src/storage.h | 6 -----
3 files changed, 21 insertions(+), 88 deletions(-)
diff --git a/src/device.c b/src/device.c
index 36bf9bc..24e97e6 100644
--- a/src/device.c
+++ b/src/device.c
@@ -2067,24 +2067,17 @@ static void device_remove_stored(struct btd_device *device)
char adapter_addr[18];
char device_addr[18];
char filename[PATH_MAX + 1];
-
- delete_entry(src, "profiles", &device->bdaddr, dst_type);
- delete_entry(src, "trusts", &device->bdaddr, dst_type);
+ GKeyFile *key_file;
+ char *data;
+ gsize length = 0;
if (device_is_bonded(device)) {
- delete_entry(src, "linkkeys", &device->bdaddr, dst_type);
- delete_entry(src, "aliases", &device->bdaddr, dst_type);
- delete_entry(src, "longtermkeys", &device->bdaddr, dst_type);
-
device_set_bonded(device, FALSE);
device->paired = FALSE;
btd_adapter_remove_bonding(device->adapter, &device->bdaddr,
dst_type);
}
- delete_all_records(src, &device->bdaddr, dst_type);
- delete_device_service(src, &device->bdaddr, dst_type);
-
if (device->blocked)
device_unblock(device, TRUE, FALSE);
@@ -2095,6 +2088,24 @@ static void device_remove_stored(struct btd_device *device)
device_addr);
filename[PATH_MAX] = '\0';
delete_folder_tree(filename);
+
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", adapter_addr,
+ device_addr);
+ filename[PATH_MAX] = '\0';
+
+ key_file = g_key_file_new();
+ g_key_file_load_from_file(key_file, filename, 0, NULL);
+ g_key_file_remove_group(key_file, "ServiceRecords", NULL);
+
+ data = g_key_file_to_data(key_file, &length, NULL);
+ if (length > 0) {
+ create_file(filename, S_IRUSR | S_IWUSR |
+ S_IRGRP | S_IROTH);
+ g_file_set_contents(filename, data, length, NULL);
+ }
+
+ g_free(data);
+ g_key_file_free(key_file);
}
void device_remove(struct btd_device *device, gboolean remove_stored)
diff --git a/src/storage.c b/src/storage.c
index 74b19c0..d4516ed 100644
--- a/src/storage.c
+++ b/src/storage.c
@@ -245,31 +245,6 @@ ssize_t read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin)
return len;
}
-int delete_entry(const bdaddr_t *src, const char *storage, const bdaddr_t *dst,
- uint8_t dst_type)
-{
- char filename[PATH_MAX + 1], key[20];
- int err, ret;
-
- ba2str(dst, key);
- sprintf(&key[17], "#%hhu", dst_type);
-
- create_filename(filename, PATH_MAX, src, storage);
-
- err = 0;
- ret = textfile_del(filename, key);
- if (ret)
- err = ret;
-
- /* Trying without address type */
- key[17] = '\0';
- ret = textfile_del(filename, key);
- if (ret)
- err = ret;
-
- return err;
-}
-
int store_record(const gchar *src, const gchar *dst, uint8_t dst_type,
sdp_record_t *rec)
{
@@ -397,26 +372,6 @@ static void create_stored_records_from_keys(char *key, char *value,
rec_list->recs = sdp_list_append(rec_list->recs, rec);
}
-void delete_all_records(const bdaddr_t *src, const bdaddr_t *dst,
- uint8_t dst_type)
-{
- sdp_list_t *records, *seq;
- char srcaddr[18], dstaddr[18];
-
- ba2str(src, srcaddr);
- ba2str(dst, dstaddr);
-
- records = read_records(src, dst);
-
- for (seq = records; seq; seq = seq->next) {
- sdp_record_t *rec = seq->data;
- delete_record(srcaddr, dstaddr, dst_type, rec->handle);
- }
-
- if (records)
- sdp_list_free(records, (sdp_free_func_t) sdp_record_free);
-}
-
sdp_list_t *read_records(const bdaddr_t *src, const bdaddr_t *dst)
{
char filename[PATH_MAX + 1];
@@ -526,33 +481,6 @@ done:
g_slist_free_full(match.keys, g_free);
}
-int delete_device_service(const bdaddr_t *sba, const bdaddr_t *dba,
- uint8_t bdaddr_type)
-{
- char filename[PATH_MAX + 1], key[20];
-
- memset(key, 0, sizeof(key));
-
- ba2str(dba, key);
- sprintf(&key[17], "#%hhu", bdaddr_type);
-
- /* Deleting all characteristics of a given key */
- create_filename(filename, PATH_MAX, sba, "characteristics");
- delete_by_pattern(filename, key);
-
- /* Deleting all attributes values of a given key */
- create_filename(filename, PATH_MAX, sba, "attributes");
- delete_by_pattern(filename, key);
-
- /* Deleting all CCC values of a given key */
- create_filename(filename, PATH_MAX, sba, "ccc");
- delete_by_pattern(filename, key);
-
- create_filename(filename, PATH_MAX, sba, "primaries");
-
- return textfile_del(filename, key);
-}
-
char *read_device_services(const bdaddr_t *sba, const bdaddr_t *dba,
uint8_t bdaddr_type)
{
diff --git a/src/storage.h b/src/storage.h
index 2e2889d..ffc6deb 100644
--- a/src/storage.h
+++ b/src/storage.h
@@ -35,8 +35,6 @@ int read_remote_appearance(const bdaddr_t *local, const bdaddr_t *peer,
int write_lastused_info(const bdaddr_t *local, const bdaddr_t *peer,
uint8_t peer_type, struct tm *tm);
ssize_t read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin);
-int delete_entry(const bdaddr_t *src, const char *storage, const bdaddr_t *dst,
- uint8_t dst_type);
int store_record(const gchar *src, const gchar *dst, uint8_t dst_type,
sdp_record_t *rec);
sdp_record_t *record_from_string(const gchar *str);
@@ -44,15 +42,11 @@ sdp_record_t *fetch_record(const gchar *src, const gchar *dst,
uint8_t dst_type, const uint32_t handle);
int delete_record(const gchar *src, const gchar *dst, uint8_t dst_type,
const uint32_t handle);
-void delete_all_records(const bdaddr_t *src, const bdaddr_t *dst,
- uint8_t dst_type);
sdp_list_t *read_records(const bdaddr_t *src, const bdaddr_t *dst);
sdp_record_t *find_record_in_list(sdp_list_t *recs, const char *uuid);
int read_device_pairable(const bdaddr_t *local, gboolean *mode);
int write_device_services(const bdaddr_t *sba, const bdaddr_t *dba,
uint8_t bdaddr_type, const char *services);
-int delete_device_service(const bdaddr_t *sba, const bdaddr_t *dba,
- uint8_t bdaddr_type);
char *read_device_services(const bdaddr_t *sba, const bdaddr_t *dba,
uint8_t bdaddr_type);
int write_device_characteristics(const bdaddr_t *sba, const bdaddr_t *dba,
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 08/15] adapter: Convert device sdp file
From: Frédéric Danis @ 2012-12-13 20:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1355431170-12897-1-git-send-email-frederic.danis@linux.intel.com>
Save SDP records in device device file located in SDP directory.
Parse "sdp" file to retrieve services, i.e. sdp records with
attribute uuid.
Create device attributes file based on this.
---
src/adapter.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 171 insertions(+)
diff --git a/src/adapter.c b/src/adapter.c
index 241c6c8..02d54a3 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2604,6 +2604,164 @@ static void convert_file(char *file, char *address,
free(str);
}
+static gboolean record_has_uuid(const sdp_record_t *rec,
+ const char *profile_uuid)
+{
+ sdp_list_t *pat;
+
+ for (pat = rec->pattern; pat != NULL; pat = pat->next) {
+ char *uuid;
+ int ret;
+
+ uuid = bt_uuid2string(pat->data);
+ if (!uuid)
+ continue;
+
+ ret = strcasecmp(uuid, profile_uuid);
+
+ g_free(uuid);
+
+ if (ret == 0)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void store_attribute_uuid(GKeyFile *key_file, uint16_t start,
+ char *att_uuid, uuid_t uuid)
+{
+ char handle[6], uuid_str[33];
+ int i;
+
+ switch (uuid.type) {
+ case SDP_UUID16:
+ sprintf(uuid_str, "%4.4X", uuid.value.uuid16);
+ break;
+ case SDP_UUID32:
+ sprintf(uuid_str, "%8.8X", uuid.value.uuid32);
+ break;
+ case SDP_UUID128:
+ for (i = 0; i < 16; i++)
+ sprintf(uuid_str + (i * 2), "%2.2X",
+ uuid.value.uuid128.data[i]);
+ break;
+ default:
+ uuid_str[0] = '\0';
+ }
+
+ sprintf(handle, "%hu", start);
+ g_key_file_set_string(key_file, handle, "UUID", att_uuid);
+ g_key_file_set_string(key_file, handle, "Value", uuid_str);
+}
+
+static void store_sdp_record(char *local, char *peer, int handle, char *value)
+{
+ char filename[PATH_MAX + 1];
+ GKeyFile *key_file;
+ char handle_str[11];
+ char *data;
+ gsize length = 0;
+
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local, peer);
+ filename[PATH_MAX] = '\0';
+
+ key_file = g_key_file_new();
+ g_key_file_load_from_file(key_file, filename, 0, NULL);
+
+ sprintf(handle_str, "0x%8.8X", handle);
+ g_key_file_set_string(key_file, "ServiceRecords", handle_str, value);
+
+ data = g_key_file_to_data(key_file, &length, NULL);
+ if (length > 0) {
+ create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ g_file_set_contents(filename, data, length, NULL);
+ }
+
+ g_free(data);
+
+ g_key_file_free(key_file);
+}
+
+static void convert_sdp_entry(char *key, char *value, void *user_data)
+{
+ char *src_addr = user_data;
+ char dst_addr[18];
+ char type = BDADDR_BREDR;
+ int handle, ret;
+ char filename[PATH_MAX + 1];
+ GKeyFile *key_file;
+ struct stat st;
+ sdp_record_t *rec;
+ uuid_t uuid;
+ char *att_uuid, *prim_uuid;
+ uint16_t start = 0, end = 0, psm = 0;
+ int err;
+ char *data;
+ gsize length = 0;
+
+ ret = sscanf(key, "%17s#%hhu#%08X", dst_addr, &type, &handle);
+ if (ret < 3) {
+ ret = sscanf(key, "%17s#%08X", dst_addr, &handle);
+ if (ret < 2)
+ return;
+ }
+
+ if (bachk(dst_addr) != 0)
+ return;
+
+ /* Check if the device directory has been created as records should
+ * only be converted for known devices */
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s", src_addr, dst_addr);
+ filename[PATH_MAX] = '\0';
+
+ err = stat(filename, &st);
+ if (err || !S_ISDIR(st.st_mode))
+ return;
+
+ /* store device records in cache */
+ store_sdp_record(src_addr, dst_addr, handle, value);
+
+ /* Retrieve device record and check if there is an
+ * attribute entry in it */
+ sdp_uuid16_create(&uuid, ATT_UUID);
+ att_uuid = bt_uuid2string(&uuid);
+
+ sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
+ prim_uuid = bt_uuid2string(&uuid);
+
+ rec = record_from_string(value);
+
+ if (record_has_uuid(rec, att_uuid))
+ goto failed;
+
+ if (!gatt_parse_record(rec, &uuid, &psm, &start, &end))
+ goto failed;
+
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/attributes", src_addr,
+ dst_addr);
+ filename[PATH_MAX] = '\0';
+
+ key_file = g_key_file_new();
+ g_key_file_load_from_file(key_file, filename, 0, NULL);
+
+ store_attribute_uuid(key_file, start, prim_uuid, uuid);
+
+ data = g_key_file_to_data(key_file, &length, NULL);
+ if (length > 0) {
+ create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ g_file_set_contents(filename, data, length, NULL);
+ }
+
+ g_free(data);
+ g_key_file_free(key_file);
+
+failed:
+ sdp_record_free(rec);
+ g_free(prim_uuid);
+ g_free(att_uuid);
+}
+
static void convert_device_storage(struct btd_adapter *adapter)
{
char filename[PATH_MAX + 1];
@@ -2648,6 +2806,19 @@ static void convert_device_storage(struct btd_adapter *adapter)
/* Convert device ids */
convert_file("did", address, convert_did_entry, FALSE);
+
+ /* Convert sdp */
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/sdp", address);
+ filename[PATH_MAX] = '\0';
+
+ str = textfile_get(filename, "converted");
+ if (str && strcmp(str, "yes") == 0) {
+ DBG("Legacy %s file already converted", filename);
+ } else {
+ textfile_foreach(filename, convert_sdp_entry, address);
+ textfile_put(filename, "converted", "yes");
+ }
+ free(str);
}
static void convert_config(struct btd_adapter *adapter, const char *filename,
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 07/15] doc: Update Settings-storage for SDP records
From: Frédéric Danis @ 2012-12-13 20:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1355431170-12897-1-git-send-email-frederic.danis@linux.intel.com>
SDP records shouls be saved in device file located in cache
directory, as we cannot guarantee that this info is available
always and profiles should work even if the info is not there.
---
doc/settings-storage.txt | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/doc/settings-storage.txt b/doc/settings-storage.txt
index a43b7af..792c899 100644
--- a/doc/settings-storage.txt
+++ b/doc/settings-storage.txt
@@ -115,13 +115,23 @@ Sample:
Cache directory file format
============================
-Each file, named by remote device address, contains one [General] group.
-This general group contains:
+Each file, named by remote device address, may includes multiple groups
+(General and ServiceRecords).
+
+In ServiceRecords, SDP records are stored using their handle as key
+(hexadecimal format).
+
+[General] group contains:
Name String Remote device friendly name
ShortName String Remote device shortened name
+[ServiceRecords] group contains
+
+ <0x...> String SDP record as hexadecimal encoded
+ string
+
Info file format
================
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 06/15] device: Delete storage device recursively
From: Frédéric Danis @ 2012-12-13 20:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1355431170-12897-1-git-send-email-frederic.danis@linux.intel.com>
Device storage directory may contain multiple files like info or
attributes but also files stored by plug-ins or profiles,
so completely delete directory.
---
src/device.c | 36 ++++++++++++++++++++++++++++++------
1 file changed, 30 insertions(+), 6 deletions(-)
diff --git a/src/device.c b/src/device.c
index 42a7c65..36bf9bc 100644
--- a/src/device.c
+++ b/src/device.c
@@ -34,6 +34,7 @@
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <errno.h>
+#include <dirent.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/uuid.h>
@@ -2031,6 +2032,34 @@ uint16_t btd_device_get_version(struct btd_device *device)
return device->version;
}
+static void delete_folder_tree(const char *dirname)
+{
+ DIR *dir;
+ struct dirent *entry;
+ char filename[PATH_MAX + 1];
+
+ dir = opendir(dirname);
+ if (dir == NULL)
+ return;
+
+ while ((entry = readdir(dir)) != NULL) {
+ if (g_str_equal(entry->d_name, ".") ||
+ g_str_equal(entry->d_name, ".."))
+ continue;
+
+ snprintf(filename, PATH_MAX, "%s/%s", dirname, entry->d_name);
+ filename[PATH_MAX] = '\0';
+
+ if (entry->d_type == DT_DIR)
+ delete_folder_tree(filename);
+ else
+ unlink(filename);
+ }
+ closedir(dir);
+
+ rmdir(dirname);
+}
+
static void device_remove_stored(struct btd_device *device)
{
const bdaddr_t *src = adapter_get_address(device->adapter);
@@ -2062,15 +2091,10 @@ static void device_remove_stored(struct btd_device *device)
ba2str(src, adapter_addr);
ba2str(&device->bdaddr, device_addr);
- snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", adapter_addr,
- device_addr);
- filename[PATH_MAX] = '\0';
- remove(filename);
-
snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s", adapter_addr,
device_addr);
filename[PATH_MAX] = '\0';
- remove(filename);
+ delete_folder_tree(filename);
}
void device_remove(struct btd_device *device, gboolean remove_stored)
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 05/15] adapter: Probe profiles after device creation
From: Frédéric Danis @ 2012-12-13 20:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1355431170-12897-1-git-send-email-frederic.danis@linux.intel.com>
---
src/adapter.c | 40 ++++------------------------------------
1 file changed, 4 insertions(+), 36 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 3bb1ea6..241c6c8 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1628,38 +1628,6 @@ static const GDBusPropertyTable adapter_properties[] = {
{ }
};
-static void create_stored_device_from_profiles(char *key, char *value,
- void *user_data)
-{
- char address[18];
- uint8_t bdaddr_type;
- struct btd_adapter *adapter = user_data;
- GSList *list, *uuids = bt_string2list(value);
- struct btd_device *device;
-
- if (sscanf(key, "%17s#%hhu", address, &bdaddr_type) < 2)
- bdaddr_type = BDADDR_BREDR;
-
- if (g_slist_find_custom(adapter->devices,
- address, (GCompareFunc) device_address_cmp))
- return;
-
- device = device_create(adapter, address, bdaddr_type);
- if (!device)
- return;
-
- device_set_temporary(device, FALSE);
- adapter->devices = g_slist_append(adapter->devices, device);
-
- list = device_services_from_record(device, uuids);
- if (list)
- device_register_primaries(device, list, ATT_PSM);
-
- device_probe_profiles(device, uuids);
-
- g_slist_free_full(uuids, g_free);
-}
-
struct adapter_keys {
struct btd_adapter *adapter;
GSList *keys;
@@ -1843,10 +1811,6 @@ static void load_devices(struct btd_adapter *adapter)
ba2str(&adapter->bdaddr, srcaddr);
- create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, "profiles");
- textfile_foreach(filename, create_stored_device_from_profiles,
- adapter);
-
create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, "primaries");
textfile_foreach(filename, create_stored_device_from_primaries,
adapter);
@@ -1900,6 +1864,10 @@ static void load_devices(struct btd_adapter *adapter)
device_set_temporary(device, FALSE);
adapter->devices = g_slist_append(adapter->devices, device);
+ l = device_get_uuids(device);
+ if (l)
+ device_probe_profiles(device, l);
+
device_exist:
if (key_info || ltk_info) {
device_set_paired(device, TRUE);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 04/15] device: Load profiles from storage
From: Frédéric Danis @ 2012-12-13 20:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1355431170-12897-1-git-send-email-frederic.danis@linux.intel.com>
Add device_get_uuids() to retrieve UUIDs list.
It will allow to call device_probe_profiles() from
load_devices() of adapter.c after device creation.
Remove write_device_profiles from storage.[ch].
---
src/device.c | 89 ++++++++++++++++++++++++++++++---------------------------
src/device.h | 1 +
src/storage.c | 18 ------------
src/storage.h | 2 --
4 files changed, 48 insertions(+), 62 deletions(-)
diff --git a/src/device.c b/src/device.c
index e07e7b8..42a7c65 100644
--- a/src/device.c
+++ b/src/device.c
@@ -216,6 +216,7 @@ static gboolean store_device_info_cb(gpointer user_data)
char device_addr[18];
char *str;
char class[9];
+ gchar **uuids = NULL;
gsize length = 0;
device->store_id = 0;
@@ -279,6 +280,19 @@ static gboolean store_device_info_cb(gpointer user_data)
g_key_file_set_boolean(key_file, "General", "Blocked",
device->blocked);
+ if (device->uuids) {
+ GSList *l;
+ int i;
+
+ uuids = g_new0(gchar *, g_slist_length(device->uuids) + 1);
+ for (i = 0, l = device->uuids; l; l = g_slist_next(l), i++)
+ uuids[i] = l->data;
+ g_key_file_set_string_list(key_file, "General", "Profiles",
+ (const gchar **)uuids, i);
+ } else {
+ g_key_file_remove_key(key_file, "General", "Profiles", NULL);
+ }
+
if (device->vendor_src) {
g_key_file_set_integer(key_file, "DeviceID", "Source",
device->vendor_src);
@@ -299,6 +313,7 @@ static gboolean store_device_info_cb(gpointer user_data)
g_free(str);
g_key_file_free(key_file);
+ g_free(uuids);
return FALSE;
}
@@ -1740,6 +1755,7 @@ static void load_info(struct btd_device *device, const gchar *local,
char *str;
gboolean store_needed = FALSE;
gboolean blocked;
+ gchar **uuids;
int source, vendor, product, version;
char **techno, **t;
gboolean bredr = FALSE;
@@ -1819,6 +1835,27 @@ next:
if (blocked)
device_block(device, FALSE);
+ /* Load device profile list */
+ uuids = g_key_file_get_string_list(key_file, "General", "Profiles",
+ NULL, NULL);
+ if (uuids) {
+ gchar **uuid;
+
+ for (uuid = uuids; *uuid; uuid++) {
+ GSList *match;
+
+ match = g_slist_find_custom(device->uuids, *uuid,
+ bt_uuid_strcmp);
+ if (match)
+ continue;
+
+ device->uuids = g_slist_insert_sorted(device->uuids,
+ g_strdup(*uuid),
+ bt_uuid_strcmp);
+ }
+ g_strfreev(uuids);
+ }
+
/* Load device id */
source = g_key_file_get_integer(key_file, "DeviceID", "Source", NULL);
if (source) {
@@ -2124,6 +2161,11 @@ static gboolean record_has_uuid(const sdp_record_t *rec,
return FALSE;
}
+GSList *device_get_uuids(struct btd_device *device)
+{
+ return device->uuids;
+}
+
static GSList *device_match_profile(struct btd_device *device,
struct btd_profile *profile,
GSList *uuids)
@@ -2263,35 +2305,16 @@ add_uuids:
static void device_remove_profiles(struct btd_device *device, GSList *uuids)
{
char srcaddr[18], dstaddr[18];
- sdp_list_t *records;
GSList *l, *next;
ba2str(adapter_get_address(device->adapter), srcaddr);
ba2str(&device->bdaddr, dstaddr);
- records = read_records(adapter_get_address(device->adapter),
- &device->bdaddr);
-
DBG("Removing profiles for %s", dstaddr);
- for (l = uuids; l != NULL; l = g_slist_next(l)) {
- sdp_record_t *rec;
-
- device->uuids = g_slist_remove(device->uuids, l->data);
-
- rec = find_record_in_list(records, l->data);
- if (!rec)
- continue;
-
- delete_record(srcaddr, dstaddr, device->bdaddr_type,
- rec->handle);
-
- records = sdp_list_remove(records, rec);
- sdp_record_free(rec);
- }
-
- if (records)
- sdp_list_free(records, (sdp_free_func_t) sdp_record_free);
+ g_slist_free(device->uuids);
+ device->uuids = NULL;
+ store_device_info(device);
for (l = device->profiles; l != NULL; l = next) {
struct btd_profile *profile = l->data;
@@ -2460,24 +2483,6 @@ static void update_gatt_services(struct browse_req *req, GSList *current,
g_slist_free(left);
}
-static void store_profiles(struct btd_device *device)
-{
- struct btd_adapter *adapter = device->adapter;
- char *str;
-
- if (!device->uuids) {
- write_device_profiles(adapter_get_address(adapter),
- &device->bdaddr, device->bdaddr_type,
- "");
- return;
- }
-
- str = bt_list2string(device->uuids);
- write_device_profiles(adapter_get_address(adapter), &device->bdaddr,
- device->bdaddr_type, str);
- g_free(str);
-}
-
GSList *device_services_from_record(struct btd_device *device, GSList *profiles)
{
GSList *l, *prim_list = NULL;
@@ -2567,7 +2572,7 @@ send_reply:
device_svc_resolved(device, err);
if (!device->temporary)
- store_profiles(device);
+ store_device_info(device);
browse_request_free(req);
}
@@ -3820,7 +3825,7 @@ void btd_device_add_uuid(struct btd_device *device, const char *uuid)
g_free(new_uuid);
g_slist_free(uuid_list);
- store_profiles(device);
+ store_device_info(device);
uuids_changed(device);
}
diff --git a/src/device.h b/src/device.h
index a207a4f..9102e60 100644
--- a/src/device.h
+++ b/src/device.h
@@ -42,6 +42,7 @@ uint16_t btd_device_get_version(struct btd_device *device);
void device_remove(struct btd_device *device, gboolean remove_stored);
gint device_address_cmp(struct btd_device *device, const gchar *address);
gint device_bdaddr_cmp(struct btd_device *device, bdaddr_t *bdaddr);
+GSList *device_get_uuids(struct btd_device *device);
void device_probe_profiles(struct btd_device *device, GSList *profiles);
const sdp_record_t *btd_device_get_record(struct btd_device *device,
const char *uuid);
diff --git a/src/storage.c b/src/storage.c
index 0b9ed2d..74b19c0 100644
--- a/src/storage.c
+++ b/src/storage.c
@@ -245,24 +245,6 @@ ssize_t read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin)
return len;
}
-int write_device_profiles(const bdaddr_t *src, const bdaddr_t *dst,
- uint8_t dst_type, const char *profiles)
-{
- char filename[PATH_MAX + 1], key[20];
-
- if (!profiles)
- return -EINVAL;
-
- create_filename(filename, PATH_MAX, src, "profiles");
-
- create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
- ba2str(dst, key);
- sprintf(&key[17], "#%hhu", dst_type);
-
- return textfile_put(filename, key, profiles);
-}
-
int delete_entry(const bdaddr_t *src, const char *storage, const bdaddr_t *dst,
uint8_t dst_type)
{
diff --git a/src/storage.h b/src/storage.h
index cb9d836..2e2889d 100644
--- a/src/storage.h
+++ b/src/storage.h
@@ -35,8 +35,6 @@ int read_remote_appearance(const bdaddr_t *local, const bdaddr_t *peer,
int write_lastused_info(const bdaddr_t *local, const bdaddr_t *peer,
uint8_t peer_type, struct tm *tm);
ssize_t read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin);
-int write_device_profiles(const bdaddr_t *src, const bdaddr_t *dst,
- uint8_t dst_type, const char *profiles);
int delete_entry(const bdaddr_t *src, const char *storage, const bdaddr_t *dst,
uint8_t dst_type);
int store_record(const gchar *src, const gchar *dst, uint8_t dst_type,
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 03/15] adapter: Convert device profiles list
From: Frédéric Danis @ 2012-12-13 20:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1355431170-12897-1-git-send-email-frederic.danis@linux.intel.com>
---
src/adapter.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/adapter.c b/src/adapter.c
index 940cc0a..3bb1ea6 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2553,6 +2553,12 @@ static void convert_ltk_entry(GKeyFile *key_file, void *value)
g_free(str);
}
+static void convert_profiles_entry(GKeyFile *key_file, void *value)
+{
+ g_strdelimit(value, " ", ';');
+ g_key_file_set_string(key_file, "General", "Profiles", value);
+}
+
static void convert_entry(char *key, char *value, void *user_data)
{
struct device_converter *converter = user_data;
@@ -2660,6 +2666,9 @@ static void convert_device_storage(struct btd_adapter *adapter)
/* Convert blocked */
convert_file("blocked", address, convert_blocked_entry, TRUE);
+ /* Convert profiles */
+ convert_file("profiles", address, convert_profiles_entry, TRUE);
+
/* Convert linkkeys */
convert_file("linkkeys", address, convert_linkkey_entry, TRUE);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 02/15] device: Add device_create_from_storage() function
From: Frédéric Danis @ 2012-12-13 20:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1355431170-12897-1-git-send-email-frederic.danis@linux.intel.com>
This function is used from load_devices() of adapter.c
during bluetoothd start-up to re-load known devices from
storage key file.
device_create() is used to create new devices for which
no storage exists, but until all device load during start-up
has been converted we should continue to call load_info().
---
src/adapter.c | 10 +++++----
src/device.c | 69 ++++++++++++++++++++++++++++++++++++++++++++-------------
src/device.h | 2 ++
3 files changed, 61 insertions(+), 20 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 15db015..940cc0a 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1885,8 +1885,6 @@ static void load_devices(struct btd_adapter *adapter)
if (ltk_info)
ltks.keys = g_slist_append(ltks.keys, ltk_info);
- g_key_file_free(key_file);
-
l = g_slist_find_custom(adapter->devices, entry->d_name,
(GCompareFunc) device_address_cmp);
if (l) {
@@ -1894,9 +1892,10 @@ static void load_devices(struct btd_adapter *adapter)
goto device_exist;
}
- device = device_create(adapter, entry->d_name, BDADDR_BREDR);
+ device = device_create_from_storage(adapter, entry->d_name,
+ key_file);
if (!device)
- continue;
+ goto free;
device_set_temporary(device, FALSE);
adapter->devices = g_slist_append(adapter->devices, device);
@@ -1906,6 +1905,9 @@ device_exist:
device_set_paired(device, TRUE);
device_set_bonded(device, TRUE);
}
+
+free:
+ g_key_file_free(key_file);
}
closedir(dir);
diff --git a/src/device.c b/src/device.c
index 515ee61..e07e7b8 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1735,10 +1735,8 @@ failed:
}
static void load_info(struct btd_device *device, const gchar *local,
- const gchar *peer)
+ const gchar *peer, GKeyFile *key_file)
{
- char filename[PATH_MAX + 1];
- GKeyFile *key_file;
char *str;
gboolean store_needed = FALSE;
gboolean blocked;
@@ -1747,12 +1745,6 @@ static void load_info(struct btd_device *device, const gchar *local,
gboolean bredr = FALSE;
gboolean le = FALSE;
- snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", local, peer);
- filename[PATH_MAX] = '\0';
-
- key_file = g_key_file_new();
- g_key_file_load_from_file(key_file, filename, 0, NULL);
-
/* Load device name from storage info file, if that fails fall back to
* the cache.
*/
@@ -1847,18 +1839,14 @@ next:
if (store_needed)
store_device_info(device);
-
- g_key_file_free(key_file);
}
-struct btd_device *device_create(struct btd_adapter *adapter,
- const gchar *address, uint8_t bdaddr_type)
+static struct btd_device *device_new(struct btd_adapter *adapter,
+ const gchar *address)
{
gchar *address_up;
struct btd_device *device;
const gchar *adapter_path = adapter_get_path(adapter);
- const bdaddr_t *src;
- char srcaddr[18];
device = g_try_malloc0(sizeof(struct btd_device));
if (device == NULL)
@@ -1882,11 +1870,60 @@ struct btd_device *device_create(struct btd_adapter *adapter,
str2ba(address, &device->bdaddr);
device->adapter = adapter;
+
+ return btd_device_ref(device);
+}
+
+struct btd_device *device_create_from_storage(struct btd_adapter *adapter,
+ const char *address, GKeyFile *key_file)
+{
+ struct btd_device *device;
+ const bdaddr_t *src;
+ char srcaddr[18];
+
+ device = device_new(adapter, address);
+ if (device == NULL)
+ return NULL;
+
+ src = adapter_get_address(adapter);
+ ba2str(src, srcaddr);
+
+ load_info(device, srcaddr, address, key_file);
+
+ return device;
+}
+
+struct btd_device *device_create(struct btd_adapter *adapter,
+ const gchar *address, uint8_t bdaddr_type)
+{
+ struct btd_device *device;
+ const bdaddr_t *src;
+ char srcaddr[18];
+ char filename[PATH_MAX + 1];
+ GKeyFile *key_file;
+
+ device = device_new(adapter, address);
+ if (device == NULL)
+ return NULL;
+
device->bdaddr_type = bdaddr_type;
src = adapter_get_address(adapter);
ba2str(src, srcaddr);
- load_info(device, srcaddr, address);
+ /*TODO: after all device load during start-up has been converted to
+ * new key file structure, this should be replaced by :
+ * str = load_cached_name(device, srcaddr, address);
+ * if (str) {
+ * strcpy(device->name, str);
+ * g_free(str);
+ * }
+ */
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", srcaddr,
+ address);
+ key_file = g_key_file_new();
+ g_key_file_load_from_file(key_file, filename, 0, NULL);
+ load_info(device, srcaddr, address, key_file);
+ g_key_file_free(key_file);
return btd_device_ref(device);
}
diff --git a/src/device.h b/src/device.h
index b569a71..a207a4f 100644
--- a/src/device.h
+++ b/src/device.h
@@ -28,6 +28,8 @@ struct btd_device;
struct btd_device *device_create(struct btd_adapter *adapter,
const char *address, uint8_t bdaddr_type);
+struct btd_device *device_create_from_storage(struct btd_adapter *adapter,
+ const char *address, GKeyFile *key_file);
void device_set_name(struct btd_device *device, const char *name);
void device_get_name(struct btd_device *device, char *name, size_t len);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 01/15] device: Retrieve device technology from storage
From: Frédéric Danis @ 2012-12-13 20:39 UTC (permalink / raw)
To: linux-bluetooth
---
src/device.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
diff --git a/src/device.c b/src/device.c
index e7aa44d..515ee61 100644
--- a/src/device.c
+++ b/src/device.c
@@ -244,6 +244,35 @@ static gboolean store_device_info_cb(gpointer user_data)
g_key_file_remove_key(key_file, "General", "Class", NULL);
}
+ switch (device->bdaddr_type) {
+ case BDADDR_BREDR:
+ g_key_file_set_string(key_file, "General",
+ "SupportedTechnologies", "BR/EDR");
+ g_key_file_remove_key(key_file, "General",
+ "AddressType", NULL);
+ break;
+
+ case BDADDR_LE_PUBLIC:
+ g_key_file_set_string(key_file, "General",
+ "SupportedTechnologies", "LE");
+ g_key_file_set_string(key_file, "General",
+ "AddressType", "public");
+ break;
+
+ case BDADDR_LE_RANDOM:
+ g_key_file_set_string(key_file, "General",
+ "SupportedTechnologies", "LE");
+ g_key_file_set_string(key_file, "General",
+ "AddressType", "static");
+ break;
+
+ default:
+ g_key_file_remove_key(key_file, "General",
+ "SupportedTechnologies", NULL);
+ g_key_file_remove_key(key_file, "General",
+ "AddressType", NULL);
+ }
+
g_key_file_set_boolean(key_file, "General", "Trusted",
device->trusted);
@@ -1714,6 +1743,9 @@ static void load_info(struct btd_device *device, const gchar *local,
gboolean store_needed = FALSE;
gboolean blocked;
int source, vendor, product, version;
+ char **techno, **t;
+ gboolean bredr = FALSE;
+ gboolean le = FALSE;
snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", local, peer);
filename[PATH_MAX] = '\0';
@@ -1750,6 +1782,42 @@ static void load_info(struct btd_device *device, const gchar *local,
g_free(str);
}
+ /* Load device technology */
+ techno = g_key_file_get_string_list(key_file, "General",
+ "SupportedTechnologies", NULL, NULL);
+ if (!techno)
+ goto next;
+
+ for (t = techno; *t; t++) {
+ if (g_str_equal(*t, "BR/EDR"))
+ bredr = TRUE;
+ else if (g_str_equal(*t, "LE"))
+ le = TRUE;
+ else
+ error("Unknown device technology");
+ }
+
+ if (bredr && le) {
+ /* TODO: Add correct type for dual mode device */
+ } else if (bredr) {
+ device->bdaddr_type = BDADDR_BREDR;
+ } else if (le) {
+ str = g_key_file_get_string(key_file, "General",
+ "AddressType", NULL);
+
+ if (str && g_str_equal(str, "public"))
+ device->bdaddr_type = BDADDR_LE_PUBLIC;
+ else if (str && g_str_equal(str, "static"))
+ device->bdaddr_type = BDADDR_LE_RANDOM;
+ else
+ error("Unknown LE device technology");
+
+ g_free(str);
+ }
+
+ g_strfreev(techno);
+
+next:
/* Load trust */
device->trusted = g_key_file_get_boolean(key_file, "General",
"Trusted", NULL);
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH BlueZ 1/2] core: Remove RequestSession and ReleaseSession
From: Johan Hedberg @ 2012-12-13 20:15 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1355428840-27065-1-git-send-email-luiz.dentz@gmail.com>
Hi Luiz,
On Thu, Dec 13, 2012, Luiz Augusto von Dentz wrote:
> Sessions is no longer used by obexd and the concept is probably not
> relevant anymore since BlueZ 5 don't remember powered state anymore.
> ---
> doc/adapter-api.txt | 26 +---------
> src/adapter.c | 134 ----------------------------------------------------
> 2 files changed, 1 insertion(+), 159 deletions(-)
Both patches have been applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH] mgmt-api: Remove not needed restriction on add/remove OOB data
From: Johan Hedberg @ 2012-12-13 20:15 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1355407852-22047-1-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
On Thu, Dec 13, 2012, Szymon Janc wrote:
> Those commands don't send any HCI commands to controller so there is no
> need to restrict them to only powered up controller. This also clarify
> that provided OOB data is persistent over power down/up toggles.
> ---
> doc/mgmt-api.txt | 4 +---
> 1 file changed, 1 insertion(+), 3 deletions(-)
Applied. Thanks.
Johan
^ permalink raw reply
* [PATCH BlueZ 2/2] core: Remove ConfirmModeChange method
From: Luiz Augusto von Dentz @ 2012-12-13 20:00 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1355428840-27065-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This method was only used by RequestSession which is now removed.
---
doc/agent-api.txt | 9 ---------
src/agent.c | 55 -------------------------------------------------------
src/agent.h | 4 ----
3 files changed, 68 deletions(-)
diff --git a/doc/agent-api.txt b/doc/agent-api.txt
index bd8d8ff..caed7f8 100644
--- a/doc/agent-api.txt
+++ b/doc/agent-api.txt
@@ -119,15 +119,6 @@ Methods void Release()
Possible errors: org.bluez.Error.Rejected
org.bluez.Error.Canceled
- void ConfirmModeChange(string mode)
-
- This method gets called if a mode change is requested
- that needs to be confirmed by the user. An example
- would be leaving flight mode.
-
- Possible errors: org.bluez.Error.Rejected
- org.bluez.Error.Canceled
-
void Cancel()
This method gets called to indicate that the agent
diff --git a/src/agent.c b/src/agent.c
index 7ecf19a..ec183c0 100644
--- a/src/agent.c
+++ b/src/agent.c
@@ -459,61 +459,6 @@ failed:
return err;
}
-static int confirm_mode_change_request_new(struct agent_request *req,
- const char *mode)
-{
- struct agent *agent = req->agent;
-
- req->msg = dbus_message_new_method_call(agent->name, agent->path,
- "org.bluez.Agent", "ConfirmModeChange");
- if (req->msg == NULL) {
- error("Couldn't allocate D-Bus message");
- return -ENOMEM;
- }
-
- dbus_message_append_args(req->msg,
- DBUS_TYPE_STRING, &mode,
- DBUS_TYPE_INVALID);
-
- if (dbus_connection_send_with_reply(btd_get_dbus_connection(), req->msg,
- &req->call, REQUEST_TIMEOUT) == FALSE) {
- error("D-Bus send failed");
- return -EIO;
- }
-
- dbus_pending_call_set_notify(req->call, simple_agent_reply, req, NULL);
- return 0;
-}
-
-int agent_confirm_mode_change(struct agent *agent, const char *new_mode,
- agent_cb cb, void *user_data,
- GDestroyNotify destroy)
-{
- struct agent_request *req;
- int err;
-
- if (agent->request)
- return -EBUSY;
-
- DBG("Calling Agent.ConfirmModeChange: name=%s, path=%s, mode=%s",
- agent->name, agent->path, new_mode);
-
- req = agent_request_new(agent, AGENT_REQUEST_CONFIRM_MODE,
- cb, user_data, destroy);
-
- err = confirm_mode_change_request_new(req, new_mode);
- if (err < 0)
- goto failed;
-
- agent->request = req;
-
- return 0;
-
-failed:
- agent_request_free(req, FALSE);
- return err;
-}
-
static void passkey_reply(DBusPendingCall *call, void *user_data)
{
struct agent_request *req = user_data;
diff --git a/src/agent.h b/src/agent.h
index 2b011b7..3957317 100644
--- a/src/agent.h
+++ b/src/agent.h
@@ -49,10 +49,6 @@ int agent_request_pincode(struct agent *agent, struct btd_device *device,
agent_pincode_cb cb, gboolean secure,
void *user_data, GDestroyNotify destroy);
-int agent_confirm_mode_change(struct agent *agent, const char *new_mode,
- agent_cb cb, void *user_data,
- GDestroyNotify destroy);
-
int agent_request_passkey(struct agent *agent, struct btd_device *device,
agent_passkey_cb cb, void *user_data,
GDestroyNotify destroy);
--
1.7.11.7
^ permalink raw reply related
* [PATCH BlueZ 1/2] core: Remove RequestSession and ReleaseSession
From: Luiz Augusto von Dentz @ 2012-12-13 20:00 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Sessions is no longer used by obexd and the concept is probably not
relevant anymore since BlueZ 5 don't remember powered state anymore.
---
doc/adapter-api.txt | 26 +---------
src/adapter.c | 134 ----------------------------------------------------
2 files changed, 1 insertion(+), 159 deletions(-)
diff --git a/doc/adapter-api.txt b/doc/adapter-api.txt
index 5d2ea65..1817f7c 100644
--- a/doc/adapter-api.txt
+++ b/doc/adapter-api.txt
@@ -14,31 +14,7 @@ Service org.bluez
Interface org.bluez.Adapter1
Object path [variable prefix]/{hci0,hci1,...}
-Methods void RequestSession()
-
- This method requests a client session that provides
- operational Bluetooth. A possible mode change must be
- confirmed by the user via the agent.
-
- Clients may request multiple sessions. All sessions
- are released when adapter's mode is changed to off
- state.
-
- Possible Errors: org.bluez.Error.Rejected
-
- void ReleaseSession()
-
- Release a previously requested session. It sets
- adapter to the mode in use on the moment of session
- request.
-
- Setting the powered or discoverable properties
- changes adapter's mode persistently, such that session
- release will not modify it.
-
- Possible Errors: org.bluez.Error.DoesNotExist
-
- void StartDiscovery()
+Methods void StartDiscovery()
This method starts the device discovery session. This
includes an inquiry procedure and remote device name
diff --git a/src/adapter.c b/src/adapter.c
index 0a3297e..d4a03b9 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -339,18 +339,6 @@ static int adapter_set_mode(struct btd_adapter *adapter, uint8_t mode)
return err;
}
-static struct session_req *find_session_by_msg(GSList *list, const DBusMessage *msg)
-{
- for (; list; list = list->next) {
- struct session_req *req = list->data;
-
- if (req->msg == msg)
- return req;
- }
-
- return NULL;
-}
-
static int set_mode(struct btd_adapter *adapter, uint8_t new_mode)
{
int err;
@@ -392,24 +380,6 @@ done:
return 0;
}
-static void set_session_pending_mode(struct btd_adapter *adapter,
- uint8_t new_mode, DBusMessage *msg)
-{
- struct session_req *req;
-
- /*
- * Schedule the reply to be sent when a mode-change notification
- * arrives. The reply will be sent by set_mode_complete().
- */
- req = find_session_by_msg(adapter->mode_sessions, msg);
- if (req) {
- adapter->pending_mode = req;
- session_ref(req);
- } else
- adapter->pending_mode = create_session(adapter, msg, new_mode,
- SESSION_TYPE_MODE_SESSION, NULL);
-}
-
static void set_discoverable(struct btd_adapter *adapter,
gboolean discoverable, GDBusPendingPropertySet id)
{
@@ -732,45 +702,6 @@ static void session_unref(struct session_req *req)
session_free(req);
}
-static void confirm_mode_cb(struct agent *agent, DBusError *derr, void *data)
-{
- DBusConnection *conn = btd_get_dbus_connection();
- struct session_req *req = data;
- int err;
- DBusMessage *reply;
-
- req->got_reply = TRUE;
-
- if (derr && dbus_error_is_set(derr)) {
- reply = dbus_message_new_error(req->msg, derr->name,
- derr->message);
- g_dbus_send_message(conn, reply);
- session_unref(req);
- return;
- }
-
- err = set_mode(req->adapter, req->mode);
- if (err >= 0 && req->adapter->mode != req->mode) {
- set_session_pending_mode(req->adapter, req->mode, req->msg);
- goto done;
- }
-
- if (err < 0)
- reply = btd_error_failed(req->msg, strerror(-err));
- else
- reply = dbus_message_new_method_return(req->msg);
-
- /*
- * Send reply immediately only if there was an error changing mode, or
- * change is not needed. Otherwise, reply is sent in
- * set_mode_complete.
- */
- g_dbus_send_message(conn, reply);
-
-done:
- session_unref(req);
-}
-
static void set_discoverable_timeout(struct btd_adapter *adapter,
uint32_t timeout, GDBusPendingPropertySet id)
{
@@ -1409,67 +1340,6 @@ static gboolean adapter_property_get_uuids(const GDBusPropertyTable *property,
return TRUE;
}
-static DBusMessage *request_session(DBusConnection *conn,
- DBusMessage *msg, void *data)
-{
- struct btd_adapter *adapter = data;
- struct session_req *req;
- const char *sender = dbus_message_get_sender(msg);
- uint8_t new_mode;
- int err;
-
- if (!adapter->agent)
- return btd_error_agent_not_available(msg);
-
- if (!adapter->mode_sessions)
- adapter->global_mode = adapter->mode;
-
- if (adapter->discoverable)
- new_mode = MODE_DISCOVERABLE;
- else
- new_mode = MODE_CONNECTABLE;
-
- req = find_session(adapter->mode_sessions, sender);
- if (req) {
- session_ref(req);
- return dbus_message_new_method_return(msg);
- } else {
- req = create_session(adapter, msg, new_mode,
- SESSION_TYPE_MODE_SESSION, session_owner_exit);
- adapter->mode_sessions = g_slist_append(adapter->mode_sessions,
- req);
- }
-
- /* No need to change mode */
- if (adapter->mode >= new_mode)
- return dbus_message_new_method_return(msg);
-
- err = agent_confirm_mode_change(adapter->agent, mode2str(new_mode),
- confirm_mode_cb, req, NULL);
- if (err < 0) {
- session_unref(req);
- return btd_error_failed(msg, strerror(-err));
- }
-
- return NULL;
-}
-
-static DBusMessage *release_session(DBusConnection *conn,
- DBusMessage *msg, void *data)
-{
- struct btd_adapter *adapter = data;
- struct session_req *req;
- const char *sender = dbus_message_get_sender(msg);
-
- req = find_session(adapter->mode_sessions, sender);
- if (!req)
- return btd_error_failed(msg, "Invalid Session");
-
- session_unref(req);
-
- return dbus_message_new_method_return(msg);
-}
-
static uint8_t parse_io_capability(const char *capability)
{
if (g_str_equal(capability, ""))
@@ -1584,10 +1454,6 @@ static DBusMessage *unregister_agent(DBusConnection *conn, DBusMessage *msg,
}
static const GDBusMethodTable adapter_methods[] = {
- { GDBUS_ASYNC_METHOD("RequestSession", NULL, NULL,
- request_session) },
- { GDBUS_METHOD("ReleaseSession", NULL, NULL,
- release_session) },
{ GDBUS_METHOD("StartDiscovery", NULL, NULL,
adapter_start_discovery) },
{ GDBUS_ASYNC_METHOD("StopDiscovery", NULL, NULL,
--
1.7.11.7
^ permalink raw reply related
* [PATCH 2/2] Bluetooth: mgmt: Avoid using magic number in status code
From: Szymon Janc @ 2012-12-13 14:11 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1355407881-22110-1-git-send-email-szymon.janc@tieto.com>
Use MGMT_STATUS_SUCCESS for success return code.
Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
net/bluetooth/mgmt.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 65f9a2d..8752c55 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2257,7 +2257,7 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
if (err < 0)
status = MGMT_STATUS_FAILED;
else
- status = 0;
+ status = MGMT_STATUS_SUCCESS;
err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, status,
&cp->addr, sizeof(cp->addr));
@@ -2281,7 +2281,7 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
if (err < 0)
status = MGMT_STATUS_INVALID_PARAMS;
else
- status = 0;
+ status = MGMT_STATUS_SUCCESS;
err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
status, &cp->addr, sizeof(cp->addr));
@@ -2513,7 +2513,7 @@ static int block_device(struct sock *sk, struct hci_dev *hdev, void *data,
if (err < 0)
status = MGMT_STATUS_FAILED;
else
- status = 0;
+ status = MGMT_STATUS_SUCCESS;
err = cmd_complete(sk, hdev->id, MGMT_OP_BLOCK_DEVICE, status,
&cp->addr, sizeof(cp->addr));
@@ -2538,7 +2538,7 @@ static int unblock_device(struct sock *sk, struct hci_dev *hdev, void *data,
if (err < 0)
status = MGMT_STATUS_INVALID_PARAMS;
else
- status = 0;
+ status = MGMT_STATUS_SUCCESS;
err = cmd_complete(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE, status,
&cp->addr, sizeof(cp->addr));
--
1.8.0
^ permalink raw reply related
* [PATCH 1/2] Bluetooth: mgmt: Remove not needed restriction on add/remove OOB data
From: Szymon Janc @ 2012-12-13 14:11 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
Those commands don't send any HCI commands to controller so there is no
need to restrict them to only powered up controller. This also makes
implementation more consistent as already stored remote OOB data
persist power toggle.
Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
net/bluetooth/mgmt.c | 17 -----------------
1 file changed, 17 deletions(-)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 5d0ef75..65f9a2d 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2252,13 +2252,6 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
hci_dev_lock(hdev);
- if (!hdev_is_powered(hdev)) {
- err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA,
- MGMT_STATUS_NOT_POWERED, &cp->addr,
- sizeof(cp->addr));
- goto unlock;
- }
-
err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr, cp->hash,
cp->randomizer);
if (err < 0)
@@ -2269,7 +2262,6 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, status,
&cp->addr, sizeof(cp->addr));
-unlock:
hci_dev_unlock(hdev);
return err;
}
@@ -2285,14 +2277,6 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
hci_dev_lock(hdev);
- if (!hdev_is_powered(hdev)) {
- err = cmd_complete(sk, hdev->id,
- MGMT_OP_REMOVE_REMOTE_OOB_DATA,
- MGMT_STATUS_NOT_POWERED, &cp->addr,
- sizeof(cp->addr));
- goto unlock;
- }
-
err = hci_remove_remote_oob_data(hdev, &cp->addr.bdaddr);
if (err < 0)
status = MGMT_STATUS_INVALID_PARAMS;
@@ -2302,7 +2286,6 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
status, &cp->addr, sizeof(cp->addr));
-unlock:
hci_dev_unlock(hdev);
return err;
}
--
1.8.0
^ permalink raw reply related
* [PATCH] mgmt-api: Remove not needed restriction on add/remove OOB data
From: Szymon Janc @ 2012-12-13 14:10 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
Those commands don't send any HCI commands to controller so there is no
need to restrict them to only powered up controller. This also clarify
that provided OOB data is persistent over power down/up toggles.
---
doc/mgmt-api.txt | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/doc/mgmt-api.txt b/doc/mgmt-api.txt
index 202c055..60f4da4 100644
--- a/doc/mgmt-api.txt
+++ b/doc/mgmt-api.txt
@@ -701,7 +701,7 @@ Add Remote Out Of Band Data Command
Return Parameters: Address (6 Octets)
Address_Type (1 Octet)
- This command can only be used when the controller is powered.
+ Provided Out Of Band data is persistent over power down/up toggles.
This command generates a Command Complete event on success
or failure.
@@ -717,8 +717,6 @@ Remove Remote Out Of Band Data Command
Return Parameters: Address (6 Octets)
Address_Type (1 Octet)
- This command can only be used when the controller is powered.
-
This command generates a Command Complete event on success
or failure.
--
1.8.0
^ permalink raw reply related
* Re: [PATCH BlueZ] build: Remove obexd usb plugin
From: Johan Hedberg @ 2012-12-13 12:27 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1355400231-25205-1-git-send-email-luiz.dentz@gmail.com>
Hi Luiz,
On Thu, Dec 13, 2012, Luiz Augusto von Dentz wrote:
> This plugin is not longer maintained and used to work only in meego
> times.
> ---
> Makefile.obexd | 5 -
> obexd/plugins/usb.c | 299 ----------------------------------------------------
> 2 files changed, 304 deletions(-)
> delete mode 100644 obexd/plugins/usb.c
Applied. Thanks.
Johan
^ permalink raw reply
* [PATCH BlueZ] build: Remove obexd usb plugin
From: Luiz Augusto von Dentz @ 2012-12-13 12:03 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This plugin is not longer maintained and used to work only in meego
times.
---
Makefile.obexd | 5 -
obexd/plugins/usb.c | 299 ----------------------------------------------------
2 files changed, 304 deletions(-)
delete mode 100644 obexd/plugins/usb.c
diff --git a/Makefile.obexd b/Makefile.obexd
index 9498ac1..e6536bc 100644
--- a/Makefile.obexd
+++ b/Makefile.obexd
@@ -11,11 +11,6 @@ obexd_builtin_sources += obexd/plugins/filesystem.c obexd/plugins/filesystem.h
obexd_builtin_modules += bluetooth
obexd_builtin_sources += obexd/plugins/bluetooth.c
-if USB
-obexd_builtin_modules += usb
-obexd_builtin_sources += obexd/plugins/usb.c
-endif
-
if EXPERIMENTAL
obexd_builtin_modules += pcsuite
obexd_builtin_sources += obexd/plugins/pcsuite.c
diff --git a/obexd/plugins/usb.c b/obexd/plugins/usb.c
deleted file mode 100644
index 1c3da3e..0000000
--- a/obexd/plugins/usb.c
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- *
- * OBEX Server
- *
- * Copyright (C) 2007-2010 Nokia Corporation
- * Copyright (C) 2007-2010 Marcel Holtmann <marcel@holtmann.org>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <termios.h>
-#include <inttypes.h>
-
-#include <glib.h>
-#include <gdbus/gdbus.h>
-
-#include "obexd.h"
-#include "plugin.h"
-#include "server.h"
-#include "obex.h"
-#include "transport.h"
-#include "service.h"
-#include "log.h"
-
-static GIOChannel *usb_io = NULL;
-static guint usb_reconnecting = 0;
-static guint usb_watch = 0;
-static DBusConnection *connection = NULL;
-
-#define USB_RX_MTU 65535
-#define USB_TX_MTU 65535
-#define USB_DEVNODE "/dev/ttyGS0"
-
-static int usb_connect(struct obex_server *server);
-
-static void usb_disconnect(struct obex_server *server)
-{
- if (usb_reconnecting > 0) {
- g_source_remove(usb_reconnecting);
- usb_reconnecting = 0;
- }
-
- if (usb_watch > 0) {
- g_source_remove(usb_watch);
- usb_watch = 0;
- }
-
- /* already disconnected */
- if (usb_io == NULL)
- return;
-
- g_io_channel_shutdown(usb_io, TRUE, NULL);
- g_io_channel_unref(usb_io);
- usb_io = NULL;
- DBG("disconnected");
-}
-
-static gboolean usb_reconnect(void *data)
-{
- struct obex_server *server = data;
-
- DBG("reconnecting");
- usb_reconnecting = 0;
- usb_connect(server);
-
- return FALSE;
-}
-
-static gboolean usb_watchdog(GIOChannel *io, GIOCondition cond,
- void *user_data)
-{
- struct obex_server *server = user_data;
-
- usb_watch = 0;
- usb_disconnect(server);
-
- if ((cond & G_IO_NVAL) == FALSE)
- usb_reconnecting = g_idle_add(usb_reconnect, server);
-
- return FALSE;
-}
-
-static int usb_connect(struct obex_server *server)
-{
- struct termios options;
- int fd, err, arg;
- glong flags;
-
- if (usb_reconnecting > 0) {
- g_source_remove(usb_reconnecting);
- usb_reconnecting = 0;
- }
-
- /* already connected */
- if (usb_io != NULL)
- return 0;
-
- fd = open(USB_DEVNODE, O_RDWR | O_NOCTTY);
- if (fd < 0)
- return fd;
-
- flags = fcntl(fd, F_GETFL);
- fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
-
- tcgetattr(fd, &options);
- cfmakeraw(&options);
- options.c_oflag &= ~ONLCR;
- tcsetattr(fd, TCSANOW, &options);
-
- arg = fcntl(fd, F_GETFL);
- if (arg < 0) {
- err = -errno;
- goto failed;
- }
-
- arg |= O_NONBLOCK;
- if (fcntl(fd, F_SETFL, arg) < 0) {
- err = -errno;
- goto failed;
- }
-
- usb_io = g_io_channel_unix_new(fd);
- g_io_channel_set_close_on_unref(usb_io, TRUE);
-
- err = obex_server_new_connection(server, usb_io, USB_TX_MTU,
- USB_RX_MTU, TRUE);
- if (err < 0)
- goto failed;
-
- usb_watch = g_io_add_watch(usb_io, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- usb_watchdog, server);
-
- DBG("Successfully opened %s", USB_DEVNODE);
-
- return 0;
-
-failed:
- error("usb: %s (%d)", strerror(-err), -err);
- if (usb_io == NULL)
- close(fd);
- else
- usb_disconnect(server);
- return err;
-}
-
-static void sig_usb(int sig)
-{
-}
-
-static void usb_set_mode(struct obex_server *server, const char *mode)
-{
- DBG("%s", mode);
-
- if (g_str_equal(mode, "ovi_suite") == TRUE)
- usb_connect(server);
- else if (g_str_equal(mode, "USB disconnected") == TRUE)
- usb_disconnect(server);
-}
-
-static gboolean handle_signal(DBusConnection *connection,
- DBusMessage *message, void *user_data)
-{
- struct obex_server *server = user_data;
- const char *mode;
-
- dbus_message_get_args(message, NULL,
- DBUS_TYPE_STRING, &mode,
- DBUS_TYPE_INVALID);
-
- usb_set_mode(server, mode);
-
- return TRUE;
-}
-
-static void usb_stop(void *data)
-{
- guint id = GPOINTER_TO_UINT(data);
- g_dbus_remove_watch(connection, id);
-}
-
-static void mode_request_reply(DBusPendingCall *call, void *user_data)
-{
- struct obex_server *server = user_data;
- DBusMessage *reply = dbus_pending_call_steal_reply(call);
- DBusError derr;
-
- dbus_error_init(&derr);
- if (dbus_set_error_from_message(&derr, reply)) {
- error("usb: Replied with an error: %s, %s",
- derr.name, derr.message);
- dbus_error_free(&derr);
- } else {
- const char *mode;
- dbus_message_get_args(reply, NULL,
- DBUS_TYPE_STRING, &mode,
- DBUS_TYPE_INVALID);
-
- usb_set_mode(server, mode);
- }
-
- dbus_message_unref(reply);
-}
-
-static void *usb_start(struct obex_server *server, int *err)
-{
- guint id;
- DBusMessage *msg;
- DBusPendingCall *call;
-
- msg = dbus_message_new_method_call("com.meego.usb_moded",
- "/com/meego/usb_moded",
- "com.meego.usb_moded",
- "mode_request");
-
- if (dbus_connection_send_with_reply(connection,
- msg, &call, -1) == FALSE) {
- error("usb: unable to send mode_request");
- dbus_message_unref(msg);
- goto fail;
- }
-
- dbus_pending_call_set_notify(call, mode_request_reply, server, NULL);
- dbus_pending_call_unref(call);
- dbus_message_unref(msg);
-
- id = g_dbus_add_signal_watch(connection, NULL, NULL,
- "com.meego.usb_moded",
- "sig_usb_state_ind",
- handle_signal, server, NULL);
-
- if (err != NULL)
- *err = 0;
-
- return GUINT_TO_POINTER(id);
-
-fail:
- if (err != NULL)
- *err = -1;
-
- return NULL;
-}
-
-static struct obex_transport_driver driver = {
- .name = "usb",
- .service = OBEX_PCSUITE,
- .start = usb_start,
- .stop = usb_stop
-};
-
-static int usb_init(void)
-{
- struct sigaction sa;
-
- memset(&sa, 0, sizeof(sa));
- sa.sa_handler = sig_usb;
- sigaction(SIGUSR1, &sa, NULL);
- sigaction(SIGHUP, &sa, NULL);
-
- connection = g_dbus_setup_private(DBUS_BUS_SYSTEM, NULL, NULL);
- if (connection == NULL)
- return -EPERM;
-
- return obex_transport_driver_register(&driver);
-}
-
-static void usb_exit(void)
-{
- if (connection)
- dbus_connection_unref(connection);
-
- obex_transport_driver_unregister(&driver);
-}
-
-OBEX_PLUGIN_DEFINE(usb, usb_init, usb_exit)
--
1.7.11.7
^ permalink raw reply related
* Re: [BLE] org.bluez.Device1.Connect() returns org.bluez.Error.NotAvailable
From: Johan Hedberg @ 2012-12-13 7:48 UTC (permalink / raw)
To: Ting Chou; +Cc: Anderson Lizardo, linux-bluetooth@vger.kernel.org
In-Reply-To: <ADCBF04BB97EBF4AAE65663F8478B61CA99E65AC43@Luna.iaSolution.net>
Hi Ting,
On Thu, Dec 13, 2012, Ting Chou wrote:
> > > I'm not sure if I understand correctly. But do you mean the GCEP you
> > > mentioned above is applied while "reconnecting" to a supported device?
> >
> > Yes, all GAP connection procedures are applicable for re-connection.
> > There is no "reconnection" procedure as per GAP (as far as I know).
> > But note that each GATT profile can specify reconnection procedures in
> > case of disconnection due to link loss (most of those that I read have
> > this). For instance, in HTP:
> >
> > "5.2.4 Link Loss Reconnection Procedure
> > When a connection is terminated due to link loss, a Collector should
> > attempt to reconnect to the Thermometer using any of the GAP connection
> > procedures with the parameters in Table 5.2."
> >
> > This is what BlueZ is doing for profiles implemented internally, except
> > that the parameters we use are not the ones recommended on the profile
> > specs (that could be implemented in future, but for now GCEP uses fixed
> > connection parameters).
> >
>
> So I should exercise the D-Bus API like following for LE device:
>
> Adapter1.StartDiscovery
> Device1.Pair
> ...
> ...
> // link loss
> ...
> // auto reconnect
> ...
> Adapter1.RemoveDevice
>
> Is my understanding correct?
Yes, except that you should call Adapter1.StopDiscovery before calling
Device1.Pair.
Johan
^ permalink raw reply
* RE: [BLE] org.bluez.Device1.Connect() returns org.bluez.Error.NotAvailable
From: Ting Chou @ 2012-12-13 2:33 UTC (permalink / raw)
To: Anderson Lizardo; +Cc: Johan Hedberg, linux-bluetooth@vger.kernel.org
In-Reply-To: <CAJdJm_PPnSmEV0nmjeka6vLa9qG9-FvZTvhypi9mfVyw+KxH+Q@mail.gmail.com>
Hi Anderson,
> > I'm not sure if I understand correctly. But do you mean the GCEP you
> > mentioned above is applied while "reconnecting" to a supported device?
>
> Yes, all GAP connection procedures are applicable for re-connection.
> There is no "reconnection" procedure as per GAP (as far as I know).
> But note that each GATT profile can specify reconnection procedures in
> case of disconnection due to link loss (most of those that I read have
> this). For instance, in HTP:
>
> "5.2.4 Link Loss Reconnection Procedure
> When a connection is terminated due to link loss, a Collector should
> attempt to reconnect to the Thermometer using any of the GAP connection
> procedures with the parameters in Table 5.2."
>
> This is what BlueZ is doing for profiles implemented internally, except
> that the parameters we use are not the ones recommended on the profile
> specs (that could be implemented in future, but for now GCEP uses fixed
> connection parameters).
>
So I should exercise the D-Bus API like following for LE device:
Adapter1.StartDiscovery
Device1.Pair
...
...
// link loss
...
// auto reconnect
...
Adapter1.RemoveDevice
Is my understanding correct?
Thank you,
Ting
^ permalink raw reply
* Re: [RFC 12/16] Bluetooth: Use abstract chan->data in comparison
From: Gustavo Padovan @ 2012-12-12 19:57 UTC (permalink / raw)
To: Andrei Emeltchenko, linux-bluetooth, Gustavo Padovan
In-Reply-To: <20121212082009.GA7034@aemeltch-MOBL1>
Hi Andrei,
* Andrei Emeltchenko <andrei.emeltchenko.news@gmail.com> [2012-12-12 10:20:11 +0200]:
> Hi Gustavo,
>
> On Wed, Dec 12, 2012 at 02:13:40AM -0200, Gustavo Padovan wrote:
> > From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> >
> > If the L2CAP user is l2cap_sock.c chan->data is a pointer to the l2cap
> > socket so chan->sk and chan->data are the same thing. Then we can just
> > compare with chan->data instead.
> >
> > Non-socket users will have skb->sk = NULL, thus this change does not
> > interfere in other users.
> >
> > Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> > ---
> > net/bluetooth/l2cap_core.c | 3 +--
> > 1 file changed, 1 insertion(+), 2 deletions(-)
> >
> > diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> > index 934ac1b..92936db 100644
> > --- a/net/bluetooth/l2cap_core.c
> > +++ b/net/bluetooth/l2cap_core.c
> > @@ -2682,12 +2682,11 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
> > mutex_lock(&conn->chan_lock);
> >
> > list_for_each_entry(chan, &conn->chan_l, list) {
> > - struct sock *sk = chan->sk;
> > if (chan->chan_type != L2CAP_CHAN_RAW)
> > continue;
> >
> > /* Don't send frame to the socket it came from */
> > - if (skb->sk == sk)
> > + if (skb->sk && skb->sk == chan->data)
>
> In the other patch you delete chan->sk pointer and then we have only
> chan->data which points to sk. What is the reason for that? This would
> confuse people reading chan->data guessing what the hell is this.
>
> I really think we can leave chan->sk if it is needed and it is better to
> remove chan->data.
chan->data is the generic data pointer for l2cap users, l2cap_sock.c puts an
struct sock while a2mp.c puts struct amp_mgr there. I'll better add a comment
to struct l2cap_chan saying what it is for instead of re-adding struct sock.
Gustavo
^ permalink raw reply
* Re: [RFC 04/16] Bluetooth: add l2cap_state_change_and_error()
From: Gustavo Padovan @ 2012-12-12 19:26 UTC (permalink / raw)
To: Anderson Lizardo; +Cc: linux-bluetooth, Gustavo Padovan
In-Reply-To: <CAJdJm_PMBC8nivsJuYDp-wW5ei1WF7m3SJzh78RScUyQu5ApJQ@mail.gmail.com>
* Anderson Lizardo <anderson.lizardo@openbossa.org> [2012-12-12 09:40:06 -0400]:
> Hi Gustavo,
>
> On Wed, Dec 12, 2012 at 12:13 AM, Gustavo Padovan <gustavo@padovan.org> wrote:
> > @@ -238,7 +244,7 @@ static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
> > struct sock *sk = chan->sk;
> >
> > lock_sock(sk);
> > - __l2cap_chan_set_err(chan, err);
> > + chan->ops->state_change(chan, chan->state, 0);
>
> Why "0" and not "err" ?
Yes, it is "err" here. I fixed both issues you reported.
Gustavo
^ permalink raw reply
* Re: [PATCH BlueZ 01/11] obexd: Port bluetooth plugin to use external profile support
From: Johan Hedberg @ 2012-12-12 18:55 UTC (permalink / raw)
To: Mikel Astiz; +Cc: Luiz Augusto von Dentz, linux-bluetooth
In-Reply-To: <CANT-zCWrF=xz-ud=tKbds9Fag5uH+ryLL3ZiQG=APqcZgEq0ug@mail.gmail.com>
Hi Mikel,
On Wed, Dec 12, 2012, Mikel Astiz wrote:
> I'm a bit confused with these recent changes. I haven't been following
> this closely so I guess I'm missing the Big Plan but let me start with
> the basics: both bluetoothd and obexd repositories were merged but I
> believe both daemons are still going to be separate daemons, is this
> correct?
>
> If yes, it makes sense that obexd makes use of the "external profile"
> infrastructure.
>
> But in that case, why would we add any obex-specific code into
> bluetoothd? My understanding was that, if a profile is implemented as
> an external profile, the bluetoothd core would not be aware of it.
No, bluetoothd still takes care of SDP record registration,
server/client socket handling, authorization, etc. Some external
profiles (like HFP implemented through oFono) also take part in the
Device.Connect connection procedure (this is particularly important for
HFP since it needs to be the first of the audio profiles to be
connected).
>From the L2CAP/RFCOMM connection establishment onwards the external
profile takes over though through the NewConnection method.
Johan
^ 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