Automatically start notification upon connection event (manually write cccd?) - Short tutorial on notifications


I want to implement a Peripheral (GATT Server) that automatically starts notification once a Central connects. No bonding is provided in our system (connection is between arbitrary devices).

I have read several times that notifications must be initiated by the GATT Client. But when a bonding exists between the devices, the former configuration (e.g. notification) is restored upon connection. It sounds like the device manager is able to restore the notification state (cccd) at the moment a connection is established.

Can this be done manually / in my own code, e.g. by writing to cccd? I couldn't find any SD interface function that enables notifications. Manually writing to cccd results in error code 15 (NRF_ERROR_FORBIDDEN).

My code looks something like this...

static void on_connect(ble_myservice_t* p_service, ble_evt_t* p_event)
    uint32_t result;
    ble_gatts_value_t value;
    uint16_t data;

    p_service->conn_handle = p_event->evt.gap_evt.conn_handle;

    // Seems we need this, otherwise sd_ble_gatts_hvx() fails
    result = sd_ble_gatts_sys_attr_set(p_service->conn_handle, NULL, 0, 0);

    // Just for robustness, check for valid cccd handle
    if (p_service->mydata_handles.cccd_handle)
        data = 1;  // 1 = Enable notifications
        value.len = 2;
        value.offset = 0;
        value.p_value = (uint8_t*)(&data);
        result = sd_ble_gatts_value_set(p_service->conn_handle, p_service->mydata_handles.cccd_handle, &value);
        // Here we get error 15 (NRF_ERROR_FORBIDDEN)

Any suggestions? Or is the only way to write to cccd from the Central / GATT Client each time (which will cause additional latency that I would like to avoid)?

Update: I tried to update cccd after connection establishment by directly using the handle (which fails). After some research, it seems like ´sd_ble_gatts_sys_attr_set()´is used for setting cccd values. But I can nowhere find any specification about the buffer content that is handed over to ´sd_ble_gatts_sys_attr_set()´... shouldn't this be in the documentation at