diff options
-rw-r--r-- | src/attrib-server.c | 19 | ||||
-rw-r--r-- | src/device.c | 5 | ||||
-rw-r--r-- | src/device.h | 1 | ||||
-rw-r--r-- | src/storage.c | 26 | ||||
-rw-r--r-- | src/storage.h | 8 |
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); |