aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/attrib-server.c19
-rw-r--r--src/device.c5
-rw-r--r--src/device.h1
-rw-r--r--src/storage.c26
-rw-r--r--src/storage.h8
5 files changed, 43 insertions, 16 deletions
diff --git a/src/attrib-server.c b/src/attrib-server.c
index 21b1501e..3291e2df 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -737,6 +737,7 @@ static uint16_t read_value(struct gatt_channel *channel, uint16_t handle,
uint8_t status;
GList *l;
uint16_t cccval;
+ uint8_t bdaddr_type;
guint h = handle;
l = g_list_find_custom(channel->server->database,
@@ -747,9 +748,11 @@ static uint16_t read_value(struct gatt_channel *channel, uint16_t handle,
a = l->data;
+ bdaddr_type = device_get_addr_type(channel->device);
+
if (bt_uuid_cmp(&ccc_uuid, &a->uuid) == 0 &&
- read_device_ccc(&channel->src, &channel->dst,
- handle, &cccval) == 0) {
+ read_device_ccc(&channel->src, &channel->dst, bdaddr_type,
+ handle, &cccval) == 0) {
uint8_t config[2];
att_put_u16(cccval, config);
@@ -775,6 +778,7 @@ static uint16_t read_blob(struct gatt_channel *channel, uint16_t handle,
uint8_t status;
GList *l;
uint16_t cccval;
+ uint8_t bdaddr_type;
guint h = handle;
l = g_list_find_custom(channel->server->database,
@@ -789,9 +793,11 @@ static uint16_t read_blob(struct gatt_channel *channel, uint16_t handle,
return enc_error_resp(ATT_OP_READ_BLOB_REQ, handle,
ATT_ECODE_INVALID_OFFSET, pdu, len);
+ bdaddr_type = device_get_addr_type(channel->device);
+
if (bt_uuid_cmp(&ccc_uuid, &a->uuid) == 0 &&
- read_device_ccc(&channel->src, &channel->dst,
- handle, &cccval) == 0) {
+ read_device_ccc(&channel->src, &channel->dst, bdaddr_type,
+ handle, &cccval) == 0) {
uint8_t config[2];
att_put_u16(cccval, config);
@@ -847,7 +853,10 @@ static uint16_t write_value(struct gatt_channel *channel, uint16_t handle,
}
} else {
uint16_t cccval = att_get_u16(value);
- write_device_ccc(&channel->src, &channel->dst, handle, cccval);
+ uint8_t bdaddr_type = device_get_addr_type(channel->device);
+
+ write_device_ccc(&channel->src, &channel->dst, bdaddr_type,
+ handle, cccval);
}
return enc_write_resp(pdu, len);
diff --git a/src/device.c b/src/device.c
index 26fd7645..3a744c23 100644
--- a/src/device.c
+++ b/src/device.c
@@ -2210,6 +2210,11 @@ void device_set_addr_type(struct btd_device *device, uint8_t bdaddr_type)
device->bdaddr_type = bdaddr_type;
}
+uint8_t device_get_addr_type(struct btd_device *device)
+{
+ return device->bdaddr_type;
+}
+
const gchar *device_get_path(struct btd_device *device)
{
if (!device)
diff --git a/src/device.h b/src/device.h
index 51140c74..26e17f7e 100644
--- a/src/device.h
+++ b/src/device.h
@@ -62,6 +62,7 @@ struct btd_adapter *device_get_adapter(struct btd_device *device);
void device_get_address(struct btd_device *device, bdaddr_t *bdaddr,
uint8_t *bdaddr_type);
void device_set_addr_type(struct btd_device *device, uint8_t bdaddr_type);
+uint8_t device_get_addr_type(struct btd_device *device);
const gchar *device_get_path(struct btd_device *device);
struct agent *device_get_agent(struct btd_device *device);
gboolean device_is_bredr(struct btd_device *device);
diff --git a/src/storage.c b/src/storage.c
index dc9055e3..77c3fa4e 100644
--- a/src/storage.c
+++ b/src/storage.c
@@ -1335,23 +1335,34 @@ int read_device_attributes(const bdaddr_t *sba, textfile_cb func, void *data)
return textfile_foreach(filename, func, data);
}
-int read_device_ccc(bdaddr_t *local, bdaddr_t *peer, uint16_t handle,
- uint16_t *value)
+int read_device_ccc(bdaddr_t *local, bdaddr_t *peer, uint8_t bdaddr_type,
+ uint16_t handle, uint16_t *value)
{
- char filename[PATH_MAX + 1], addr[18], key[23];
+ char filename[PATH_MAX + 1], addr[18], key[25];
char *str;
unsigned int config;
int err = 0;
create_filename(filename, PATH_MAX, local, "ccc");
+ memset(key, 0, sizeof(key));
+
+ /* New format: address#type */
ba2str(peer, addr);
+ snprintf(key, sizeof(key), "%17s#%hhu#%04X", addr, bdaddr_type, handle);
+
+ str = textfile_caseget(filename, key);
+ if (str != NULL)
+ goto done;
+
+ /* Old format: address only */
snprintf(key, sizeof(key), "%17s#%04X", addr, handle);
str = textfile_caseget(filename, key);
if (str == NULL)
return -ENOENT;
+done:
if (sscanf(str, "%04X", &config) != 1)
err = -ENOENT;
else
@@ -1362,18 +1373,19 @@ int read_device_ccc(bdaddr_t *local, bdaddr_t *peer, uint16_t handle,
return err;
}
-int write_device_ccc(bdaddr_t *local, bdaddr_t *peer, uint16_t handle,
- uint16_t value)
+int write_device_ccc(bdaddr_t *local, bdaddr_t *peer, uint8_t bdaddr_type,
+ uint16_t handle, uint16_t value)
{
- char filename[PATH_MAX + 1], addr[18], key[23], config[5];
+ char filename[PATH_MAX + 1], addr[18], key[25], config[5];
create_filename(filename, PATH_MAX, local, "ccc");
create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ /* New format: address#type */
ba2str(peer, addr);
+ snprintf(key, sizeof(key), "%17s#%hhu#%04X", addr, bdaddr_type, handle);
- snprintf(key, sizeof(key), "%17s#%04X", addr, handle);
snprintf(config, sizeof(config), "%04X", value);
return textfile_put(filename, key, config);
diff --git a/src/storage.h b/src/storage.h
index 31f4da70..5660fcfd 100644
--- a/src/storage.h
+++ b/src/storage.h
@@ -90,10 +90,10 @@ char *read_device_characteristics(const bdaddr_t *sba, const bdaddr_t *dba,
int write_device_attribute(const bdaddr_t *sba, const bdaddr_t *dba,
uint16_t handle, const char *chars);
int read_device_attributes(const bdaddr_t *sba, textfile_cb func, void *data);
-int read_device_ccc(bdaddr_t *local, bdaddr_t *peer, uint16_t handle,
- uint16_t *value);
-int write_device_ccc(bdaddr_t *local, bdaddr_t *peer, uint16_t handle,
- uint16_t value);
+int read_device_ccc(bdaddr_t *local, bdaddr_t *peer, uint8_t bdaddr_type,
+ uint16_t handle, uint16_t *value);
+int write_device_ccc(bdaddr_t *local, bdaddr_t *peer, uint8_t bdaddr_type,
+ uint16_t handle, uint16_t value);
void delete_device_ccc(bdaddr_t *local, bdaddr_t *peer);
int write_longtermkeys(bdaddr_t *local, bdaddr_t *peer, const char *key);
gboolean has_longtermkeys(bdaddr_t *local, bdaddr_t *peer);