Bluetooth: tester: Return Insufficient Authorization error from app

This is related to recent changes in GATT permissions.
Authorization permissions were deleted, so that application
may return BT_ATT_ERR_AUTHORIZATION if configured.

Fixes following Test Cases:
1/9   GATT   TC_GAR_SR_BI_03_C   PASS
2/9   GATT   TC_GAR_SR_BI_09_C   PASS
3/9   GATT   TC_GAR_SR_BI_15_C   PASS
4/9   GATT   TC_GAR_SR_BI_25_C   PASS
5/9   GATT   TC_GAW_SR_BI_04_C   PASS
6/9   GATT   TC_GAW_SR_BI_11_C   PASS
7/9   GATT   TC_GAW_SR_BI_17_C   PASS
8/9   GATT   TC_GAW_SR_BI_22_C   PASS
9/9   GATT   TC_GAW_SR_BI_29_C   PASS

Change-Id: I4c37f6d597192acf34ba50910f92d5f06078201f
Signed-off-by: Mariusz Skamra <mariusz.skamra@tieto.com>
This commit is contained in:
Mariusz Skamra 2016-05-17 16:58:31 +02:00 committed by Johan Hedberg
parent d24bd64302
commit dc62813b83
2 changed files with 85 additions and 9 deletions

View File

@ -529,6 +529,13 @@ static inline void tester_set_bit(uint8_t *addr, unsigned int bit)
*p |= BIT(bit % 8);
}
static inline uint8_t tester_test_bit(const uint8_t *addr, unsigned int bit)
{
const uint8_t *p = addr + (bit / 8);
return *p & BIT(bit % 8);
}
/* L2CAP Service */
/* commands */
#define L2CAP_READ_SUPPORTED_COMMANDS 0x01

View File

@ -34,10 +34,20 @@
#define CONTROLLER_INDEX 0
#define MAX_BUFFER_SIZE 2048
/* This masks Permission bits from GATT API */
#define GATT_PERM_MASK (BT_GATT_PERM_READ | \
BT_GATT_PERM_READ_AUTHEN | \
BT_GATT_PERM_READ_ENCRYPT | \
BT_GATT_PERM_WRITE | \
BT_GATT_PERM_WRITE_AUTHEN | \
BT_GATT_PERM_WRITE_ENCRYPT)
#define GATT_PERM_ENC_READ_MASK (BT_GATT_PERM_READ_ENCRYPT | \
BT_GATT_PERM_READ_AUTHEN)
#define GATT_PERM_ENC_WRITE_MASK (BT_GATT_PERM_WRITE_ENCRYPT | \
BT_GATT_PERM_WRITE_AUTHEN)
#define GATT_PERM_READ_AUTHORIZATION 0x40
#define GATT_PERM_WRITE_AUTHORIZATION 0x80
/* GATT server context */
#define SERVER_MAX_ATTRIBUTES 50
#define SERVER_BUF_SIZE 2048
@ -259,7 +269,13 @@ struct gatt_value {
uint8_t *data;
uint8_t *prep_data;
uint8_t enc_key_size;
bool has_ccc;
uint8_t flags[1];
};
enum {
GATT_VALUE_CCC_FLAG,
GATT_VALUE_READ_AUTHOR_FLAG,
GATT_VALUE_WRITE_AUTHOR_FLAG,
};
static ssize_t read_value(struct bt_conn *conn, const struct bt_gatt_attr *attr,
@ -267,6 +283,10 @@ static ssize_t read_value(struct bt_conn *conn, const struct bt_gatt_attr *attr,
{
const struct gatt_value *value = attr->user_data;
if (tester_test_bit(value->flags, GATT_VALUE_READ_AUTHOR_FLAG)) {
return BT_GATT_ERR(BT_ATT_ERR_AUTHORIZATION);
}
if ((attr->perm & GATT_PERM_ENC_READ_MASK) &&
(value->enc_key_size > bt_conn_enc_key_size(conn))) {
return BT_GATT_ERR(BT_ATT_ERR_ENCRYPTION_KEY_SIZE);
@ -282,6 +302,10 @@ static ssize_t write_value(struct bt_conn *conn,
{
struct gatt_value *value = attr->user_data;
if (tester_test_bit(value->flags, GATT_VALUE_WRITE_AUTHOR_FLAG)) {
return BT_GATT_ERR(BT_ATT_ERR_AUTHORIZATION);
}
if ((attr->perm & GATT_PERM_ENC_WRITE_MASK) &&
(value->enc_key_size > bt_conn_enc_key_size(conn))) {
return BT_GATT_ERR(BT_ATT_ERR_ENCRYPTION_KEY_SIZE);
@ -346,12 +370,30 @@ static int alloc_characteristic(struct add_characteristic *ch)
memset(&value, 0, sizeof(value));
if (ch->permissions & GATT_PERM_READ_AUTHORIZATION) {
tester_set_bit(value.flags, GATT_VALUE_READ_AUTHOR_FLAG);
/* To maintain backward compatibility, set Read Permission */
if (!(ch->permissions & GATT_PERM_ENC_READ_MASK)) {
ch->permissions |= BT_GATT_PERM_READ;
}
}
if (ch->permissions & GATT_PERM_WRITE_AUTHORIZATION) {
tester_set_bit(value.flags, GATT_VALUE_WRITE_AUTHOR_FLAG);
/* To maintain backward compatibility, set Write Permission */
if (!(ch->permissions & GATT_PERM_ENC_WRITE_MASK)) {
ch->permissions |= BT_GATT_PERM_WRITE;
}
}
/* Add Characteristic Value */
attr_value = gatt_db_add(&(struct bt_gatt_attr)
BT_GATT_LONG_DESCRIPTOR(ch->uuid,
ch->permissions, read_value,
write_value, flush_value, &value),
sizeof(value));
ch->permissions & GATT_PERM_MASK,
read_value, write_value, flush_value,
&value), sizeof(value));
if (!attr_value) {
server_buf_pull(sizeof(*chrc_data));
/* Characteristic attribute uuid has constant length */
@ -443,7 +485,7 @@ static struct bt_gatt_attr *add_ccc(const struct bt_gatt_attr *attr)
}
value = attr->user_data;
value->has_ccc = true;
tester_set_bit(value->flags, GATT_VALUE_CCC_FLAG);
ccc_added = true;
return attr_desc;
@ -485,11 +527,38 @@ static int alloc_descriptor(const struct bt_gatt_attr *attr,
} else {
memset(&value, 0, sizeof(value));
if (d->permissions & GATT_PERM_READ_AUTHORIZATION) {
tester_set_bit(value.flags,
GATT_VALUE_READ_AUTHOR_FLAG);
/*
* To maintain backward compatibility,
* set Read Permission
*/
if (!(d->permissions & GATT_PERM_ENC_READ_MASK)) {
d->permissions |= BT_GATT_PERM_READ;
}
}
if (d->permissions & GATT_PERM_WRITE_AUTHORIZATION) {
tester_set_bit(value.flags,
GATT_VALUE_WRITE_AUTHOR_FLAG);
/*
* To maintain backward compatibility,
* set Write Permission
*/
if (!(d->permissions & GATT_PERM_ENC_WRITE_MASK)) {
d->permissions |= BT_GATT_PERM_WRITE;
}
}
attr_desc = gatt_db_add(&(struct bt_gatt_attr)
BT_GATT_LONG_DESCRIPTOR(d->uuid,
d->permissions, read_value,
write_value, flush_value,
&value), sizeof(value));
d->permissions & GATT_PERM_MASK,
read_value, write_value,
flush_value, &value),
sizeof(value));
}
if (!attr_desc) {
@ -640,7 +709,7 @@ static uint8_t alloc_value(struct bt_gatt_attr *attr, struct set_value *data)
memcpy(value->data, data->value, value->len);
if (value->has_ccc) {
if (tester_test_bit(value->flags, GATT_VALUE_CCC_FLAG)) {
bt_gatt_notify(NULL, attr, value->data, value->len);
}