diff --git a/doc/releases/migration-guide-4.0.rst b/doc/releases/migration-guide-4.0.rst index b68664387353991..5e45b2d2c302e01 100644 --- a/doc/releases/migration-guide-4.0.rst +++ b/doc/releases/migration-guide-4.0.rst @@ -404,6 +404,10 @@ Bluetooth Audio Bluetooth Host ============== +* :c:func:`bt_gatt_subscribe` behavior has changed to if a different user/application has already + subscribed to the same handle, then the callback will contain the values aggregated of all the + users/applications. + Automatic advertiser resumption is deprecated --------------------------------------------- diff --git a/subsys/bluetooth/host/gatt.c b/subsys/bluetooth/host/gatt.c index 5503bb6b8b99928..4b02bd0d1061a17 100644 --- a/subsys/bluetooth/host/gatt.c +++ b/subsys/bluetooth/host/gatt.c @@ -5429,7 +5429,7 @@ int bt_gatt_subscribe(struct bt_conn *conn, { struct gatt_sub *sub; struct bt_gatt_subscribe_params *tmp; - bool has_subscription = false; + int err; __ASSERT(conn, "invalid parameters\n"); __ASSERT(params && params->notify, "invalid parameters\n"); @@ -5446,6 +5446,11 @@ int bt_gatt_subscribe(struct bt_conn *conn, return -ENOTCONN; } + if (params->value < BT_GATT_CCC_NOTIFY + || params->value > BT_GATT_CCC_INDICATE) { + return -EINVAL; + } + sub = gatt_sub_add(conn); if (!sub) { return -ENOMEM; @@ -5467,26 +5472,20 @@ int bt_gatt_subscribe(struct bt_conn *conn, } /* Check if another subscription exists */ - if (tmp->value_handle == params->value_handle && - tmp->value >= params->value) { - has_subscription = true; + if (tmp->value_handle == params->value_handle) { + params->value |= tmp->value; } } - /* Skip write if already subscribed */ - if (!has_subscription) { - int err; - #if defined(CONFIG_BT_GATT_AUTO_DISCOVER_CCC) - if (params->ccc_handle == BT_GATT_AUTO_DISCOVER_CCC_HANDLE) { - return gatt_ccc_discover(conn, params); - } + if (params->ccc_handle == BT_GATT_AUTO_DISCOVER_CCC_HANDLE) { + return gatt_ccc_discover(conn, params); + } #endif - err = gatt_write_ccc(conn, params, gatt_write_ccc_rsp); - if (err) { - gatt_sub_remove(conn, sub, NULL, NULL); - return err; - } + err = gatt_write_ccc(conn, params, gatt_write_ccc_rsp); + if (err) { + gatt_sub_remove(conn, sub, NULL, NULL); + return err; } /*