Approach for receiving unknown length of data
I'm not a professional, but I guess the only way is to receive 1 byte at a time, and copy it to a ring buffer or other buffer that can store multiple messages (or 1 if you can handle one message fast enough).

Than you have two possibilities:


If it is easy to find out if the end of a message is received (for example when it ends with a certain value, or if you store the expected number of bytes so you can check against that value), than verify this in the interrupt, and set a Boolean. This Boolean can be checked in the main (non interrupt) code to process the message and clear the message. A ring buffer is ideal for this.
If it is not easy to find out the end of a message, than set a Boolean that a new byte has been received, and in the main code verify if a complete message is received, if so, execute it and delete it.


Pseudo code for possibility 1:

Global

volatile uint8_t ringBuffer[MAX_BUFFFER]; 
volatile uint8_t … // Additional variables to keep track of ring buffer space
volatile bool uartMessageCompleted = false;


Initially:

HAL_UART_Receive_IT(1 byte)


Callback:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    Store byte in ring buffer
    HAL_UART_Receive_IT(1 byte)

    if (isCompleteUartMessageReceived())
    {
       uartMessageCompleted = true;
    }
}

bool isCompleteUartMessageReceived
{
    return true if a complete message is received
}


In Main (or a function called from main):

void main()
{
   …
   if (uartMessageCompleted )
   {
      excecuteUartMessage(); // Implement yourself
      remove message from ring buffer
   }
   …
}