Bluetooth; GATT: Consolidate code for finding a CCC config

This consolidates code for finding a CCC config in a helper function
thus reducing the amount of duplicated code.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
Luiz Augusto von Dentz 2019-02-18 18:05:09 +02:00 committed by Anas Nashif
commit efb064ab9b

View file

@ -958,25 +958,38 @@ struct bt_gatt_attr *bt_gatt_attr_next(const struct bt_gatt_attr *attr)
return next;
}
static struct bt_gatt_ccc_cfg *find_ccc_cfg(struct bt_conn *conn,
struct _bt_gatt_ccc *ccc)
{
size_t i;
for (i = 0; i < ccc->cfg_len; i++) {
if (conn) {
if (conn->id == ccc->cfg[i].id &&
!bt_conn_addr_le_cmp(conn, &ccc->cfg[i].peer)) {
return &ccc->cfg[i];
}
} else if (!bt_addr_le_cmp(&ccc->cfg[i].peer, BT_ADDR_LE_ANY)) {
return &ccc->cfg[i];
}
}
return NULL;
}
ssize_t bt_gatt_attr_read_ccc(struct bt_conn *conn,
const struct bt_gatt_attr *attr, void *buf,
u16_t len, u16_t offset)
{
struct _bt_gatt_ccc *ccc = attr->user_data;
struct bt_gatt_ccc_cfg *cfg;
u16_t value;
size_t i;
for (i = 0; i < ccc->cfg_len; i++) {
if (bt_conn_addr_le_cmp(conn, &ccc->cfg[i].peer)) {
continue;
}
value = sys_cpu_to_le16(ccc->cfg[i].value);
break;
}
/* Default to disable if there is no cfg for the peer */
if (i == ccc->cfg_len) {
cfg = find_ccc_cfg(conn, ccc);
if (cfg) {
value = sys_cpu_to_le16(cfg->value);
} else {
/* Default to disable if there is no cfg for the peer */
value = 0x0000;
}
@ -1011,8 +1024,8 @@ ssize_t bt_gatt_attr_write_ccc(struct bt_conn *conn,
u16_t len, u16_t offset, u8_t flags)
{
struct _bt_gatt_ccc *ccc = attr->user_data;
struct bt_gatt_ccc_cfg *cfg;
u16_t value;
size_t i;
if (offset > sizeof(u16_t)) {
return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
@ -1024,14 +1037,8 @@ ssize_t bt_gatt_attr_write_ccc(struct bt_conn *conn,
value = sys_get_le16(buf);
for (i = 0; i < ccc->cfg_len; i++) {
/* Check for existing configuration */
if (!bt_conn_addr_le_cmp(conn, &ccc->cfg[i].peer)) {
break;
}
}
if (i == ccc->cfg_len) {
cfg = find_ccc_cfg(conn, ccc);
if (!cfg) {
/* If there's no existing entry, but the new value is zero,
* we don't need to do anything, since a disabled CCC is
* behavioraly the same as no written CCC.
@ -1040,20 +1047,13 @@ ssize_t bt_gatt_attr_write_ccc(struct bt_conn *conn,
return len;
}
for (i = 0; i < ccc->cfg_len; i++) {
/* Check for unused configuration */
if (bt_addr_le_cmp(&ccc->cfg[i].peer, BT_ADDR_LE_ANY)) {
continue;
}
bt_addr_le_copy(&ccc->cfg[i].peer, &conn->le.dst);
break;
}
if (i == ccc->cfg_len) {
cfg = find_ccc_cfg(NULL, ccc);
if (!cfg) {
BT_WARN("No space to store CCC cfg");
return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
}
bt_addr_le_copy(&cfg->peer, &conn->le.dst);
}
/* Confirm write if cfg is managed by application */
@ -1061,12 +1061,12 @@ ssize_t bt_gatt_attr_write_ccc(struct bt_conn *conn,
return BT_GATT_ERR(BT_ATT_ERR_WRITE_NOT_PERMITTED);
}
ccc->cfg[i].value = value;
cfg->value = value;
BT_DBG("handle 0x%04x value %u", attr->handle, ccc->cfg[i].value);
BT_DBG("handle 0x%04x value %u", attr->handle, cfg->value);
/* Update cfg if don't match */
if (ccc->cfg[i].value != ccc->value) {
if (cfg->value != ccc->value) {
gatt_ccc_changed(attr, ccc);
#if defined(CONFIG_BT_SETTINGS_CCC_STORE_ON_WRITE)
@ -1085,8 +1085,8 @@ ssize_t bt_gatt_attr_write_ccc(struct bt_conn *conn,
/* Disabled CCC is the same as no configured CCC, so clear the entry */
if (!value) {
bt_addr_le_copy(&ccc->cfg[i].peer, BT_ADDR_LE_ANY);
ccc->cfg[i].value = 0;
bt_addr_le_copy(&cfg->peer, BT_ADDR_LE_ANY);
cfg->value = 0;
}
return len;