How does VoLTE works on Qualcomm based SoC?
Introduction
Currently VoLTE isn't just working when your Qualcomm based smartphone is switch to LTE (at least for 95% of the phones). The data connection works just fine, but voice calls either doesn't work at all or your phone has to switch to 2G or 3G to do the voice calls.
To reverse engineer VoLTE on Qualcomm SoCs, I've used an OnePlus 6T as a target which is based on an Qualcomm SDM845. The OnePlus 6T has been released in 2018. I'll use LineageOS instead of the vendor-provided Android OS, because it makes it easier to get root access. Further it allows to get a newer Android version onto the device.
First of all, VoLTE works only when both Android and the baseband are working together. I'll use the term Android for software running on the APU (Application processor, the ARM processor) and baseband for the proprietary firmware running on the Hexagon DSP.
QMI
Most of the communication between the baseband and Android is done using QMI messages.
A short recap on QMI:
QMI has 3 types of messages:
- Request
- Response
- Indication

Android does a request towards the baseband and it answers with a response. QMI has message ids to match a request to a response, allowing multiple requests and responses as the same time.
An indication is a message informing the Android side about a state change or an event. An incoming call is an indication. Also if the network cell changes, an indication is sent to the Android. Some indication are sent, without asking for, For others, a request must be used to enable them.
You could describe QMI with the common server/client model: The baseband is the server and Android the client.
If there would be only a single service on the baseband, the amount of message types would be huge. QMI offers multiple services instead. This also allows to have more contained code. The service for the UIM (sim card) doesn't have to know anything about the radio frequencies.

Android runs multiple daemons and each daemon can open a QMI connection to a service or to multiple services at the same time.
While libqmi supports many services, there are more. Also some OEMs may create additional vendor specific ones Here are the most important services:
- CTL (Control), controls the QMI connections, used to establish a connection towards a service
- DMS (Device Management Service), controls device power, e.g. airplane mode
- NAS (Network Access Service), access and selection of the mobile network
- UIM (User Identification Module), access to the sim card, enter the PIN
- WDS (Wireless Data Service), manage the data session, create, close
- WMS (Wireless Messaging Service), SMS, cell broadcast
If you know a public specification or documentation of QMI, please reach out to me.
IP multimedia subsystem / VoLTE
The IMS functionality of the baseband consists of multiple QMI services, in difference to the other logical functions, which are usually concentrated into a single service.

- IMS Application (IMSA)
- IMS Settings (called IMS by libqmi)
- IMS Presence (IMSP)
- IMS RTP (IMSRTP)
- IMS DCM (IMSDCM)
The IMS application is at the top level view of the current state of the IMS. "Is the phone registered to VoLTE?"
The IMS settings service is the configuration endpoint, it allows settings many configurations options, from basic enable VoLTE, over codec, over handover and many more.
The IMS presence controls the SIP presence.
The IMS RTP service, RTP settings, but no data frames (as long as I've seen). I've not looked into this service more deeply.
The IMS DCM service, data control manager (not yet certain, what DCM stands for). But this is where many of the magic happens.
At the moment, I expect I've to use only IMS application, settings and DCM services to have a fully functional IMS service.
IMS DCM
The DCM service doesn't fit into the common case of the baseband being the server and Android being a client, because it's vice versa. Android is the server and the baseband the client!
The baseband requests a data session for the VoLTE traffic over the DCM service. Android will open a PDN session by talking again to the WDS service and responds back to the baseband.
Message sequence chart

There are a couple of unknown parts in there:
- Why is the modem opening the IMS PDN (on the LTE) before the Start Network of the IMS daemon? Is there an unknown service? Or because of the PDC profile?
- Why are there calls towards WDS and QOS to bind the subscription and set the mux? Maybe legacy API and modern API?
- How does the IMSDCM daemon knows the IPv6 address? Does it sent the IPv6 RS and handles the RA (IP selection)?
- The IMSDCM sends back PDP Connection Id 0x14. Is this local generated by the IMSDCM or has it something to do with the WDS connection id? But if it would be the WDS connection id, how does it know it?
Even with a couple unknowns left, I'm confident to have the required parts to implementing a daemon to talk to the IMS services.
What's next?
The next step is a PDC (Persistent Device Configuration) daemon, to select a baseband profile which supports IMS.
Afterwards I'll implement prototype openimsd prototype.