Bluetooth: tester: Add Get Attribute Value command implementation
This procedure will be used to query GATT Server for attribute value. Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
This commit is contained in:
parent
c168769b95
commit
85f16efbeb
@ -535,6 +535,16 @@ struct gatt_attr {
|
||||
u8_t type[0];
|
||||
} __packed;
|
||||
|
||||
#define GATT_GET_ATTRIBUTE_VALUE 0x1d
|
||||
struct gatt_get_attribute_value_cmd {
|
||||
u16_t handle;
|
||||
} __packed;
|
||||
struct gatt_get_attribute_value_rp {
|
||||
u8_t att_response;
|
||||
u16_t value_length;
|
||||
u8_t value[0];
|
||||
} __packed;
|
||||
|
||||
/* GATT events */
|
||||
#define GATT_EV_NOTIFICATION 0x80
|
||||
struct gatt_notification_ev {
|
||||
|
||||
@ -201,6 +201,7 @@ static void supported_commands(u8_t *data, u16_t len)
|
||||
tester_set_bit(cmds, GATT_CFG_NOTIFY);
|
||||
tester_set_bit(cmds, GATT_CFG_INDICATE);
|
||||
tester_set_bit(cmds, GATT_GET_ATTRIBUTES);
|
||||
tester_set_bit(cmds, GATT_GET_ATTRIBUTE_VALUE);
|
||||
|
||||
tester_send(BTP_SERVICE_ID_GATT, GATT_READ_SUPPORTED_COMMANDS,
|
||||
CONTROLLER_INDEX, (u8_t *) rp, sizeof(cmds));
|
||||
@ -1781,6 +1782,62 @@ static void get_attrs(u8_t *data, u16_t len)
|
||||
buf->data, buf->len);
|
||||
}
|
||||
|
||||
static u8_t err_to_att(int err)
|
||||
{
|
||||
if (err < 0 && err >= -0xff) {
|
||||
return -err;
|
||||
}
|
||||
|
||||
return BT_ATT_ERR_UNLIKELY;
|
||||
}
|
||||
|
||||
static u8_t get_attr_val_rp(const struct bt_gatt_attr *attr, void *user_data)
|
||||
{
|
||||
struct net_buf_simple *buf = user_data;
|
||||
struct gatt_get_attribute_value_rp *rp;
|
||||
ssize_t read, to_read;
|
||||
|
||||
rp = net_buf_simple_add(buf, sizeof(*rp));
|
||||
rp->value_length = 0x0000;
|
||||
rp->att_response = 0x00;
|
||||
|
||||
do {
|
||||
to_read = net_buf_simple_tailroom(buf);
|
||||
|
||||
read = attr->read(NULL, attr, buf->data + buf->len, to_read,
|
||||
rp->value_length);
|
||||
if (read < 0) {
|
||||
rp->att_response = err_to_att(read);
|
||||
break;
|
||||
}
|
||||
|
||||
rp->value_length += read;
|
||||
|
||||
net_buf_simple_add(buf, read);
|
||||
} while (read == to_read);
|
||||
|
||||
return BT_GATT_ITER_STOP;
|
||||
}
|
||||
|
||||
static void get_attr_val(u8_t *data, u16_t len)
|
||||
{
|
||||
const struct gatt_get_attribute_value_cmd *cmd = (void *) data;
|
||||
struct net_buf_simple *buf = NET_BUF_SIMPLE(BTP_DATA_MAX_SIZE);
|
||||
u16_t handle = sys_le16_to_cpu(cmd->handle);
|
||||
|
||||
net_buf_simple_init(buf, 0);
|
||||
|
||||
bt_gatt_foreach_attr(handle, handle, get_attr_val_rp, buf);
|
||||
|
||||
if (buf->len) {
|
||||
tester_send(BTP_SERVICE_ID_GATT, GATT_GET_ATTRIBUTE_VALUE,
|
||||
CONTROLLER_INDEX, buf->data, buf->len);
|
||||
} else {
|
||||
tester_rsp(BTP_SERVICE_ID_GATT, GATT_GET_ATTRIBUTE_VALUE,
|
||||
CONTROLLER_INDEX, BTP_STATUS_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
void tester_handle_gatt(u8_t opcode, u8_t index, u8_t *data,
|
||||
u16_t len)
|
||||
{
|
||||
@ -1855,6 +1912,9 @@ void tester_handle_gatt(u8_t opcode, u8_t index, u8_t *data,
|
||||
case GATT_GET_ATTRIBUTES:
|
||||
get_attrs(data, len);
|
||||
return;
|
||||
case GATT_GET_ATTRIBUTE_VALUE:
|
||||
get_attr_val(data, len);
|
||||
return;
|
||||
default:
|
||||
tester_rsp(BTP_SERVICE_ID_GATT, opcode, index,
|
||||
BTP_STATUS_UNKNOWN_CMD);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user