Determine end of USB Data OUT packet on device (STM32)
I don't know about the ST USB library, but I have some register level bare-metal programming experience with the STM32F407 OTG_FS hardware. 

First, some terminology to avoid confusion: A USB transfer consists of one or more transactions. A transaction consists of packets but we don't need to go that deep. The important thing is that a transaction can contain max-packet-size bytes or less. This is defined in the endpoint descriptor.

Actually, the logic is the same as the IN transfers. A transfer is considered to be complete if one of these two conditions are detected:


A transaction with less than max-packet-size bytes
A full length transaction followed by a ZLP


OTG_FS hardware detects the end of transfer itself and fires an interrupt if enabled. You can also obtain the actual number of bytes the transfer contains. However, before enabling the endpoint, you need to program the maximum number of bytes to expect. I don't remember what happens if this number is exceeded, but I guess the endpoint disables itself in that case.

For example, you set the OUT endpoint to receive 1000 bytes. After you get a transfer complete interrupt, you read back that register and see that it's now 900. Then you can conclude that the transfer was 100 bytes long. Look for OTG_FS_DOEPTSIZx register in the reference manual.

Of course, not all STM32 devices have OTG_FS hardware. For example, the famous STM32F103 uses a different USB hardware. I have no experience with that hardware. But if it's unable to detect end of transfers itself, you can check it yourself using the 2 rules I mentioned.