Bluetooth: Host: Fix unsafe ccc cast
Changes the implementation of `bt_gatt_is_subscribed` to use the attribute read method instead of casting the user data pointer when extracting the CCC Attribute Value. Signed-off-by: Håvard Reierstad <haavard.reierstad@nordicsemi.no>
This commit is contained in:
parent
43149c1056
commit
68361eacfa
|
@ -3473,7 +3473,9 @@ static uint8_t disconnected_cb(const struct bt_gatt_attr *attr, uint16_t handle,
|
|||
bool bt_gatt_is_subscribed(struct bt_conn *conn,
|
||||
const struct bt_gatt_attr *attr, uint16_t ccc_type)
|
||||
{
|
||||
const struct _bt_gatt_ccc *ccc;
|
||||
uint16_t ccc_bits;
|
||||
uint8_t ccc_bits_encoded[sizeof(ccc_bits)];
|
||||
ssize_t len;
|
||||
|
||||
__ASSERT(conn, "invalid parameter\n");
|
||||
__ASSERT(attr, "invalid parameter\n");
|
||||
|
@ -3484,8 +3486,7 @@ bool bt_gatt_is_subscribed(struct bt_conn *conn,
|
|||
|
||||
/* Check if attribute is a characteristic declaration */
|
||||
if (!bt_uuid_cmp(attr->uuid, BT_UUID_GATT_CHRC)) {
|
||||
uint8_t properties = 0;
|
||||
ssize_t len;
|
||||
uint8_t properties;
|
||||
|
||||
if (!attr->read) {
|
||||
LOG_ERR("Read method not set");
|
||||
|
@ -3494,7 +3495,7 @@ bool bt_gatt_is_subscribed(struct bt_conn *conn,
|
|||
/* The charactestic properties is the first byte of the attribute value */
|
||||
len = attr->read(NULL, attr, &properties, sizeof(properties), 0);
|
||||
if (len < 0) {
|
||||
LOG_ERR("Failed to read attribute (err %zd)", len);
|
||||
LOG_ERR("Failed to read attribute %p (err %zd)", attr, len);
|
||||
return false;
|
||||
} else if (len != sizeof(properties)) {
|
||||
LOG_ERR("Invalid read length: %zd", len);
|
||||
|
@ -3532,16 +3533,25 @@ bool bt_gatt_is_subscribed(struct bt_conn *conn,
|
|||
return false;
|
||||
}
|
||||
|
||||
ccc = attr->user_data;
|
||||
if (!attr->read) {
|
||||
LOG_ERR("Read method not set");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check if the connection is subscribed */
|
||||
for (size_t i = 0; i < BT_GATT_CCC_MAX; i++) {
|
||||
const struct bt_gatt_ccc_cfg *cfg = &ccc->cfg[i];
|
||||
len = attr->read(conn, attr, ccc_bits_encoded, sizeof(ccc_bits_encoded), 0);
|
||||
if (len < 0) {
|
||||
LOG_ERR("Failed to read attribute %p (err %zd)", attr, len);
|
||||
return false;
|
||||
} else if (len != sizeof(ccc_bits_encoded)) {
|
||||
LOG_ERR("Invalid read length: %zd", len);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bt_conn_is_peer_addr_le(conn, cfg->id, &cfg->peer) &&
|
||||
(ccc_type & ccc->cfg[i].value)) {
|
||||
return true;
|
||||
}
|
||||
ccc_bits = sys_get_le16(ccc_bits_encoded);
|
||||
|
||||
/* Check if the CCC bits match the subscription type */
|
||||
if (ccc_bits & ccc_type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
Loading…
Reference in New Issue