If it is of any help, this example here is a good start for building a custom BLE app.
https://wiki.stmicroelectronics.cn/stm32mcu/wiki/Connectivity:STM32WB_BLE_STM32CubeMX
In there they use notifications, but knowing where the notifications get activated, also shows where you have to put the functions to process the incomming bytes.
As an example with the custom BLE settings of the CubeMX:
You want to have a characteristic where the client sends data to the server and the server does not answer back. Then set the following in the characteristic:


Then in file custom_stm.c look for the if case with your characteristic. In this example CUSTOM_STM_Service_1_Char_1_ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE.

In between you can either use the switch case of the function Custom_STM_App_Notification() in file custom_app.c or wirte your own. For the sake of this example, link the parameters of interest to the struct variable Notification and pass it to the function.
In the switch of Custom_STM_App_Notification() you can work with the bytes received and give it to a function declared in the main.c file.

That is how I do it when using the Custom Template provided by CubeMX.
Hope this helps a little