After a few notifications in short succession this code will reliably get stuck in an infinite loop (15.2.0). Can sd_ble_gatts_hvx not be used in this way? Do you have to wait for BLE_GATTS_EVT_HVN_TX_COMPLETE? This makes things more difficult as you then have to queue the notifications in the application.
do { err_code = sd_ble_gatts_hvx(conn_handle, ¶ms); } while (err_code == NRF_ERROR_RESOURCES);