The zephyr peripheral hr example us altered create a custom GATT service with a 128 bit BT uuid instead of a 16 bit bt number. I tried the following which does not trigger the notify event:
On the peripheral role, I changed advertising data and service definitions. I won't bother you with my code, it works in nrf52 connectivity.
#define uuid_ppg_service_val BT_UUID_128_ENCODE(0x20000001, 0xA000, 0xB000, 0xC000, 0xC00000000001)
#define BT_UUID_PPGS BT_UUID_DECLARE_128(uuid_ppg_service_val)
#define BT_UUID_PPGS_MEASUREMENT BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x10000001, 0xA000, 0xB000, 0xC000, 0xC00000000002))
BT_GATT_SERVICE_DEFINE(ppg_svc,
BT_GATT_PRIMARY_SERVICE(BT_UUID_PPGS),
BT_GATT_CHARACTERISTIC(BT_UUID_PPGS_MEASUREMENT,
BT_GATT_CHRC_NOTIFY,
BT_GATT_PERM_NONE, NULL, NULL, NULL),
BT_GATT_CCC(vnd_ccc_cfg_changed,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
);
static const struct bt_data ad[] = {
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
BT_DATA_BYTES(BT_DATA_UUID16_ALL,
//BT_UUID_16_ENCODE(BT_UUID_HRS_VAL),
BT_UUID_16_ENCODE(BT_UUID_BAS_VAL),
),
BT_DATA_BYTES(BT_DATA_UUID128_ALL, uuid_ppg_service_val),
};

On the central role, I made these modifications:
static void connected(struct bt_conn *conn, uint8_t conn_err)
{
// ...
if (conn == default_conn) {
memcpy(&uuid128, BT_UUID_PPGS, sizeof(uuid128));
discover_params.uuid = &uuid128.uuid;
//...
}
static bool eir_found(struct bt_data *data, void *user_data)
{
bt_addr_le_t *addr = user_data;
int i;
int err;
printk("[AD]: %u data_len %u\n", data->type, data->data_len);
struct bt_le_conn_param *param;
param = BT_LE_CONN_PARAM_DEFAULT;
switch (data->type) {
case BT_DATA_UUID128_SOME:
printk("128bit type some");
break;
case BT_DATA_UUID128_ALL:
if (data->data_len % BT_UUID_SIZE_128 != 0U) {
printk("AD malformed\n");
return true;
}
for(i = 0; i < data->data_len; i+= BT_UUID_SIZE_128) {
printk("128bit type all");
struct bt_uuid *uuid128;
uint8_t btadvData[16];
memcpy(btadvData, data->data, 16);
uuid128 = (struct bt_uuid *)btadvData;
if(bt_uuid_cmp(uuid128, BT_UUID_PPGS_MEASUREMENT)) {
printk("uuid128 == PPGID\n");
err = bt_le_scan_stop();
if(err) {
printk("Stop LE scan failed (err %d)\n", err);
}
printk("make connection");
err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
param, &default_conn);
if (err) {
printk("Create conn failed (err %d)\n", err);
}
return false;
}
}
break;
}
return true;
}
static uint8_t discover_func(struct bt_conn *conn,
const struct bt_gatt_attr *attr,
struct bt_gatt_discover_params *params)
{
int err;
if (!attr) {
printk("Discover complete\n");
(void)memset(params, 0, sizeof(*params));
return BT_GATT_ITER_STOP;
}
printk("[ATTRIBUTE] handle %u\n", attr->handle);
if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_PPGS)) {
memcpy(&uuid128, BT_UUID_PPGS_MEASUREMENT, sizeof(uuid128));
discover_params.uuid = &uuid128.uuid;
discover_params.start_handle = attr->handle + 1;
discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
err = bt_gatt_discover(conn, &discover_params);
if (err) {
printk("Discover failed (err %d)\n", err);
}
} else if (!bt_uuid_cmp(discover_params.uuid,
BT_UUID_PPGS_MEASUREMENT)) {
memcpy(&uuid16, BT_UUID_GATT_CCC, sizeof(uuid16));
discover_params.uuid = &uuid16.uuid;
discover_params.start_handle = attr->handle + 2;
discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
subscribe_params.value_handle = bt_gatt_attr_value_handle(attr);
err = bt_gatt_discover(conn, &discover_params);
if (err) {
printk("Discover failed (err %d)\n", err);
}
} else {
subscribe_params.notify = notify_func;
subscribe_params.value = BT_GATT_CCC_NOTIFY;
subscribe_params.ccc_handle = attr->handle;
err = bt_gatt_subscribe(conn, &subscribe_params);
if (err && err != -EALREADY) {
printk("Subscribe failed (err %d)\n", err);
} else {
printk("[SUBSCRIBED]\n");
}
return BT_GATT_ITER_STOP;
}
return BT_GATT_ITER_STOP;
}
Central connects but notifications do not work. When I change back to BT_UUID_HRS value, notifications are received.