tests: bluetooth: tester: allow to add more CCCs
Specification states that: "Only one Client Characteristic Configuration declaration shall exist in a characteristic definition." This was wrongly understood as "Ony one CCC can exist in GATT Server". When we add next characteristic `ccc_added` flag is cleared so next CC can be added (for this characteristic). Added array for CCC values so it's no longer shared between CCCs. Signed-off-by: Krzysztof Kopyściński <krzysztof.kopyscinski@codecoup.pl>
This commit is contained in:
parent
00cdb7afa2
commit
bfb3ec5253
1 changed files with 62 additions and 8 deletions
|
@ -56,6 +56,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
|||
#define SERVER_MAX_SERVICES 10
|
||||
#define SERVER_MAX_ATTRIBUTES 50
|
||||
#define SERVER_BUF_SIZE 2048
|
||||
#define MAX_CCC_COUNT 2
|
||||
|
||||
/* bt_gatt_attr_next cannot be used on non-registered services */
|
||||
#define NEXT_DB_ATTR(attr) (attr + 1)
|
||||
|
@ -72,6 +73,7 @@ NET_BUF_POOL_DEFINE(server_pool, 1, SERVER_BUF_SIZE, 0, NULL);
|
|||
static uint8_t attr_count;
|
||||
static uint8_t svc_attr_count;
|
||||
static uint8_t svc_count;
|
||||
static bool ccc_added;
|
||||
|
||||
/*
|
||||
* gatt_buf - cache used by a gatt client (to cache data read/discovered)
|
||||
|
@ -88,6 +90,36 @@ struct get_attr_data {
|
|||
struct bt_conn *conn;
|
||||
};
|
||||
|
||||
struct ccc_value {
|
||||
struct bt_gatt_attr *attr;
|
||||
struct bt_gatt_attr *ccc;
|
||||
uint8_t value;
|
||||
};
|
||||
|
||||
static struct ccc_value ccc_values[MAX_CCC_COUNT];
|
||||
|
||||
static int ccc_find_by_attr(uint16_t handle)
|
||||
{
|
||||
for (int i = 0; i < MAX_CCC_COUNT; i++) {
|
||||
if (handle == ccc_values[i].attr->handle) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static int ccc_find_by_ccc(const struct bt_gatt_attr *attr)
|
||||
{
|
||||
for (int i = 0; i < MAX_CCC_COUNT; i++) {
|
||||
if (attr == ccc_values[i].ccc) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static void *gatt_buf_add(const void *data, size_t len)
|
||||
{
|
||||
void *ptr = gatt_buf.buf + gatt_buf.len;
|
||||
|
@ -474,6 +506,9 @@ static void add_characteristic(uint8_t *data, uint16_t len)
|
|||
}
|
||||
|
||||
rp.char_id = sys_cpu_to_le16(cmd_data.char_id);
|
||||
|
||||
ccc_added = false;
|
||||
|
||||
tester_send(BTP_SERVICE_ID_GATT, GATT_ADD_CHARACTERISTIC,
|
||||
CONTROLLER_INDEX, (uint8_t *) &rp, sizeof(rp));
|
||||
return;
|
||||
|
@ -483,26 +518,27 @@ fail:
|
|||
CONTROLLER_INDEX, BTP_STATUS_FAILED);
|
||||
}
|
||||
|
||||
static bool ccc_added;
|
||||
|
||||
static uint8_t ccc_value;
|
||||
|
||||
static void ccc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
|
||||
{
|
||||
ccc_value = value;
|
||||
int i = ccc_find_by_ccc(attr);
|
||||
|
||||
if (i >= 0) {
|
||||
ccc_values[i].value = value;
|
||||
}
|
||||
}
|
||||
|
||||
static struct bt_gatt_attr ccc = BT_GATT_CCC(ccc_cfg_changed,
|
||||
BT_GATT_PERM_READ |
|
||||
BT_GATT_PERM_WRITE);
|
||||
|
||||
static struct bt_gatt_attr *add_ccc(const struct bt_gatt_attr *attr)
|
||||
static struct bt_gatt_attr *add_ccc(struct bt_gatt_attr *attr)
|
||||
{
|
||||
struct bt_gatt_attr *attr_desc;
|
||||
struct bt_gatt_chrc *chrc = attr->user_data;
|
||||
struct gatt_value *value = NEXT_DB_ATTR(attr)->user_data;
|
||||
int i;
|
||||
|
||||
/* Fail if another CCC already exist on server */
|
||||
/* Fail if another CCC already exist for this characteristic */
|
||||
if (ccc_added) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -519,6 +555,13 @@ static struct bt_gatt_attr *add_ccc(const struct bt_gatt_attr *attr)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
i = ccc_find_by_ccc(NULL);
|
||||
if (i >= 0) {
|
||||
ccc_values[i].attr = attr;
|
||||
ccc_values[i].ccc = attr_desc;
|
||||
ccc_values[i].value = 0;
|
||||
}
|
||||
|
||||
tester_set_bit(value->flags, GATT_VALUE_CCC_FLAG);
|
||||
ccc_added = true;
|
||||
|
||||
|
@ -548,7 +591,7 @@ struct add_descriptor {
|
|||
const struct bt_uuid *uuid;
|
||||
};
|
||||
|
||||
static int alloc_descriptor(const struct bt_gatt_attr *attr,
|
||||
static int alloc_descriptor(struct bt_gatt_attr *attr,
|
||||
struct add_descriptor *d)
|
||||
{
|
||||
struct bt_gatt_attr *attr_desc;
|
||||
|
@ -762,6 +805,8 @@ static void indicate_cb(struct bt_conn *conn,
|
|||
static uint8_t alloc_value(struct bt_gatt_attr *attr, struct set_value *data)
|
||||
{
|
||||
struct gatt_value *value;
|
||||
uint8_t ccc_value;
|
||||
int i;
|
||||
|
||||
/* Value has been already set while adding CCC to the gatt_db */
|
||||
if (!bt_uuid_cmp(attr->uuid, BT_UUID_GATT_CCC)) {
|
||||
|
@ -788,6 +833,15 @@ static uint8_t alloc_value(struct bt_gatt_attr *attr, struct set_value *data)
|
|||
|
||||
memcpy(value->data, data->value, value->len);
|
||||
|
||||
/** Handle of attribute is 1 less that handle to its value */
|
||||
i = ccc_find_by_attr(attr->handle - 1);
|
||||
|
||||
if (i < 0) {
|
||||
ccc_value = 0;
|
||||
} else {
|
||||
ccc_value = ccc_values[i].value;
|
||||
}
|
||||
|
||||
if (tester_test_bit(value->flags, GATT_VALUE_CCC_FLAG) && ccc_value) {
|
||||
if (ccc_value == BT_GATT_CCC_NOTIFY) {
|
||||
bt_gatt_notify(NULL, attr, value->data, value->len);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue