summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2016-02-17 14:03:20 +0200
committerJohan Hedberg <johan.hedberg@intel.com>2016-02-17 15:05:34 +0000
commita72d967d338af41bca90da7d5046de9e89d6ab96 (patch)
tree9b155924c02573646a10dfb3153ae85dd85192e7
parent15ac9992a9a10ef2ccc511c0fbaa1d21661c3e7b (diff)
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>
-rw-r--r--drivers/nble/gatt.c10
-rw-r--r--include/bluetooth/gatt.h11
-rw-r--r--net/bluetooth/att.c13
-rw-r--r--net/bluetooth/gatt.c6
-rw-r--r--samples/bluetooth/peripheral/src/main.c10
-rw-r--r--samples/bluetooth/peripheral_csc/src/main.c5
-rw-r--r--samples/bluetooth/peripheral_esp/src/main.c37
-rw-r--r--tests/bluetooth/tester/src/gatt.c10
8 files changed, 53 insertions, 49 deletions
diff --git a/drivers/nble/gatt.c b/drivers/nble/gatt.c
index 897c2c639..0aec22674 100644
--- a/drivers/nble/gatt.c
+++ b/drivers/nble/gatt.c
@@ -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,
diff --git a/include/bluetooth/gatt.h b/include/bluetooth/gatt.h
index 7e78992fa..d57b1c433 100644
--- a/include/bluetooth/gatt.h
+++ b/include/bluetooth/gatt.h
@@ -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 */
diff --git a/net/bluetooth/att.c b/net/bluetooth/att.c
index 5f2e68bd5..351d86929 100644
--- a/net/bluetooth/att.c
+++ b/net/bluetooth/att.c
@@ -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 {
diff --git a/net/bluetooth/gatt.c b/net/bluetooth/gatt.c
index 74cd5c94d..7c952c569 100644
--- a/net/bluetooth/gatt.c
+++ b/net/bluetooth/gatt.c
@@ -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);
}
}
diff --git a/samples/bluetooth/peripheral/src/main.c b/samples/bluetooth/peripheral/src/main.c
index b13b7ad15..08ab9a494 100644
--- a/samples/bluetooth/peripheral/src/main.c
+++ b/samples/bluetooth/peripheral/src/main.c
@@ -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);
diff --git a/samples/bluetooth/peripheral_csc/src/main.c b/samples/bluetooth/peripheral_csc/src/main.c
index eeaa28055..04f985f67 100644
--- a/samples/bluetooth/peripheral_csc/src/main.c
+++ b/samples/bluetooth/peripheral_csc/src/main.c
@@ -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) {
diff --git a/samples/bluetooth/peripheral_esp/src/main.c b/samples/bluetooth/peripheral_esp/src/main.c
index 3dbc10b24..a55741060 100644
--- a/samples/bluetooth/peripheral_esp/src/main.c
+++ b/samples/bluetooth/peripheral_esp/src/main.c
@@ -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,30 +356,28 @@ 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);
+ }
- if (sensor->lower_limit > ref_val ||
- sensor->upper_limit < ref_val) {
- /* TODO: Return ERR_OUT_OF_RANGE */
- return -EINVAL;
- }
+ ref = buf;
+ ref_val = sys_le16_to_cpu(ref->ref_val);
- sensor->condition = req->condition;
- sensor->ref_val = ref_val;
+ if (sensor->lower_limit > ref_val ||
+ sensor->upper_limit < ref_val) {
+ return BT_GATT_ERR(BT_ATT_ERR_OUT_OF_RANGE);
}
+
+ sensor->condition = req->condition;
+ sensor->ref_val = ref_val;
}
return len;
diff --git a/tests/bluetooth/tester/src/gatt.c b/tests/bluetooth/tester/src/gatt.c
index 35f743403..ee0a18c34 100644
--- a/tests/bluetooth/tester/src/gatt.c
+++ b/tests/bluetooth/tester/src/gatt.c
@@ -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);