Bluetooth: GATT: Expose ATT error codes to application callbacks
Introduce BT_GATT_ERR macro to make it possible for application callbacks to return exact ATT error codes. Change-Id: I971536508e75036fbddc40b3f33e5201e11940bc Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
parent
15ac9992a9
commit
a72d967d33
8 changed files with 55 additions and 51 deletions
|
@ -301,7 +301,7 @@ int bt_gatt_attr_read_ccc(struct bt_conn *conn,
|
|||
const struct bt_gatt_attr *attr, void *buf,
|
||||
uint16_t len, uint16_t offset)
|
||||
{
|
||||
return -ENOSYS;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
int bt_gatt_attr_write_ccc(struct bt_conn *conn,
|
||||
|
@ -312,11 +312,11 @@ int bt_gatt_attr_write_ccc(struct bt_conn *conn,
|
|||
const uint16_t *data = buf;
|
||||
|
||||
if (offset > sizeof(*data)) {
|
||||
return -EINVAL;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
|
||||
}
|
||||
|
||||
if (offset + len > sizeof(*data)) {
|
||||
return -EFBIG;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
|
||||
}
|
||||
|
||||
/* We expect to receive this only when the has really changed */
|
||||
|
@ -346,14 +346,14 @@ int bt_gatt_attr_read_cud(struct bt_conn *conn,
|
|||
const struct bt_gatt_attr *attr, void *buf,
|
||||
uint16_t len, uint16_t offset)
|
||||
{
|
||||
return -ENOSYS;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
int bt_gatt_attr_read_cpf(struct bt_conn *conn,
|
||||
const struct bt_gatt_attr *attr, void *buf,
|
||||
uint16_t len, uint16_t offset)
|
||||
{
|
||||
return -ENOSYS;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
int bt_gatt_notify(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||
|
|
|
@ -88,6 +88,17 @@ extern "C" {
|
|||
*/
|
||||
#define BT_GATT_FLUSH_SYNC 0x01
|
||||
|
||||
/** @def BT_GATT_ERR
|
||||
* @brief Construct error return value for attribute read, write and
|
||||
* flush callbacks.
|
||||
*
|
||||
* @param _att_err ATT error code
|
||||
*
|
||||
* @return Appropriate error code for the attribute callbacks.
|
||||
*
|
||||
*/
|
||||
#define BT_GATT_ERR(_att_err) (-(_att_err))
|
||||
|
||||
/** @brief GATT Attribute structure. */
|
||||
struct bt_gatt_attr {
|
||||
/** Attribute UUID */
|
||||
|
|
|
@ -571,16 +571,11 @@ static uint8_t err_to_att(int err)
|
|||
{
|
||||
BT_DBG("%d", err);
|
||||
|
||||
switch (err) {
|
||||
case -EINVAL:
|
||||
return BT_ATT_ERR_INVALID_OFFSET;
|
||||
case -EFBIG:
|
||||
return BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
|
||||
case -EACCES:
|
||||
return BT_ATT_ERR_ENCRYPTION_KEY_SIZE;
|
||||
default:
|
||||
return BT_ATT_ERR_UNLIKELY;
|
||||
if (err < 0 && err >= -0xff) {
|
||||
return -err;
|
||||
}
|
||||
|
||||
return BT_ATT_ERR_UNLIKELY;
|
||||
}
|
||||
|
||||
struct read_type_data {
|
||||
|
|
|
@ -316,11 +316,11 @@ int bt_gatt_attr_write_ccc(struct bt_conn *conn,
|
|||
size_t i;
|
||||
|
||||
if (offset > sizeof(*data)) {
|
||||
return -EINVAL;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
|
||||
}
|
||||
|
||||
if (offset + len > sizeof(*data)) {
|
||||
return -EFBIG;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
|
||||
}
|
||||
|
||||
if (bt_keys_find_addr(&conn->le.dst))
|
||||
|
@ -348,7 +348,7 @@ int bt_gatt_attr_write_ccc(struct bt_conn *conn,
|
|||
|
||||
if (i == ccc->cfg_len) {
|
||||
BT_WARN("No space to store CCC cfg");
|
||||
return -ENOMEM;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ static int write_ct(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
|||
uint8_t *value = attr->user_data;
|
||||
|
||||
if (offset + len > sizeof(ct)) {
|
||||
return -EINVAL;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
|
||||
}
|
||||
|
||||
memcpy(value + offset, buf, len);
|
||||
|
@ -198,7 +198,7 @@ static int write_vnd(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
|||
uint8_t *value = attr->user_data;
|
||||
|
||||
if (offset + len > sizeof(vnd_value)) {
|
||||
return -EINVAL;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
|
||||
}
|
||||
|
||||
memcpy(value + offset, buf, len);
|
||||
|
@ -233,7 +233,7 @@ static int write_long_vnd(struct bt_conn *conn,
|
|||
struct vnd_long_value *value = attr->user_data;
|
||||
|
||||
if (offset + len > sizeof(value->buf)) {
|
||||
return -EINVAL;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
|
||||
}
|
||||
|
||||
/* Copy to buffer */
|
||||
|
@ -258,7 +258,7 @@ static int flush_long_vnd(struct bt_conn *conn,
|
|||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);
|
||||
}
|
||||
|
||||
static const struct bt_uuid_128 vnd_long_uuid = BT_UUID_INIT_128(
|
||||
|
@ -286,7 +286,7 @@ static int write_signed(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
|||
uint8_t *value = attr->user_data;
|
||||
|
||||
if (offset + len > sizeof(signed_value)) {
|
||||
return -EINVAL;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
|
||||
}
|
||||
|
||||
memcpy(value + offset, buf, len);
|
||||
|
|
|
@ -238,12 +238,11 @@ static int write_ctrl_point(struct bt_conn *conn,
|
|||
int i;
|
||||
|
||||
if (!ctrl_point_configured) {
|
||||
/* TODO: Return CSC_ERR_CCC_CONFIG */
|
||||
return -EINVAL;
|
||||
return BT_GATT_ERR(CSC_ERR_CCC_CONFIG);
|
||||
}
|
||||
|
||||
if (!len) {
|
||||
return -EINVAL;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
|
||||
}
|
||||
|
||||
switch (req->op) {
|
||||
|
|
|
@ -328,15 +328,16 @@ static int write_temp_trigger_setting(struct bt_conn *conn,
|
|||
uint16_t offset)
|
||||
{
|
||||
const struct write_es_trigger_setting_req *req = buf;
|
||||
const struct es_trigger_setting_reference *ref;
|
||||
struct temperature_sensor *sensor = attr->user_data;
|
||||
uint16_t ref_val;
|
||||
|
||||
if (!len) {
|
||||
return -EFBIG;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
|
||||
}
|
||||
|
||||
if (req->condition > 0x09) {
|
||||
/* TODO: Return ESS_ERR_COND_NOT_SUPP */
|
||||
return -EINVAL;
|
||||
return BT_GATT_ERR(ESS_ERR_COND_NOT_SUPP);
|
||||
}
|
||||
|
||||
switch (req->condition) {
|
||||
|
@ -345,7 +346,7 @@ static int write_temp_trigger_setting(struct bt_conn *conn,
|
|||
/* fallthrough */
|
||||
case ESS_VALUE_CHANGED:
|
||||
if (len != sizeof(sensor->condition)) {
|
||||
return -EINVAL;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
|
||||
}
|
||||
|
||||
sensor->condition = req->condition;
|
||||
|
@ -355,31 +356,29 @@ static int write_temp_trigger_setting(struct bt_conn *conn,
|
|||
/* fallthrough */
|
||||
case ESS_NO_LESS_THAN_SPECIFIED_TIME:
|
||||
if (len != sizeof(struct es_trigger_setting_seconds)) {
|
||||
return -EINVAL;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
|
||||
}
|
||||
|
||||
sensor->condition = req->condition;
|
||||
sensor->seconds = le24_to_int(req->operand);
|
||||
break;
|
||||
/* Reference temperature */
|
||||
default: {
|
||||
const struct es_trigger_setting_reference *req = buf;
|
||||
uint16_t ref_val = sys_le16_to_cpu(req->ref_val);
|
||||
|
||||
if (len != sizeof(*req)) {
|
||||
return -EINVAL;
|
||||
default:
|
||||
if (len != sizeof(*ref)) {
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
|
||||
}
|
||||
|
||||
ref = buf;
|
||||
ref_val = sys_le16_to_cpu(ref->ref_val);
|
||||
|
||||
if (sensor->lower_limit > ref_val ||
|
||||
sensor->upper_limit < ref_val) {
|
||||
/* TODO: Return ERR_OUT_OF_RANGE */
|
||||
return -EINVAL;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_OUT_OF_RANGE);
|
||||
}
|
||||
|
||||
sensor->condition = req->condition;
|
||||
sensor->ref_val = ref_val;
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
|
|
@ -231,7 +231,7 @@ static int read_value(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
|||
|
||||
if ((attr->perm & GATT_PERM_ENC_READ_MASK) &&
|
||||
(value->enc_key_size > bt_conn_enc_key_size(conn))) {
|
||||
return -EACCES;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_ENCRYPTION_KEY_SIZE);
|
||||
}
|
||||
|
||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, value->data,
|
||||
|
@ -245,7 +245,7 @@ static int write_value(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
|||
|
||||
if ((attr->perm & GATT_PERM_ENC_WRITE_MASK) &&
|
||||
(value->enc_key_size > bt_conn_enc_key_size(conn))) {
|
||||
return -EACCES;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_ENCRYPTION_KEY_SIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -254,11 +254,11 @@ static int write_value(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
|||
* «Invalid Offset».
|
||||
*/
|
||||
if (offset > value->len) {
|
||||
return -EINVAL;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
|
||||
}
|
||||
|
||||
if (offset + len > value->len) {
|
||||
return -EFBIG;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
|
||||
}
|
||||
|
||||
memcpy(value->prep_data + offset, buf, len);
|
||||
|
@ -281,7 +281,7 @@ static int flush_value(struct bt_conn *conn,
|
|||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);
|
||||
}
|
||||
|
||||
static struct bt_gatt_attr chr = BT_GATT_CHARACTERISTIC(NULL, 0);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue