In modern phone networks, calls are no longer circuit-switched but rather use a
protocol much akin to SIP for control and standard RTP for audio. This switch happened
around the time of HSPA with VoHSPA/IR.58. This wasn't very used during the HSPA era because
UMTS, which HSPA depended on, still handled calls over the older circuit-switched mechanism.
But something changed during LTE. No longer was there a circuit-switched native LTE fallback;
if you wanted to handle a circuit-switched call, you had to fall back to UMTS/GSM/CDMA2000.
This obviously isn't a usable experience for most people, and also means carriers would need to maintain
double the necessary infra for both voice and high-speed data coverage. This is when the switch to
packet-switched voice happened, using a SIP derivative called IMS, with EAP-AKA for auth.
Bafflingly, despite the existence of Linux-based phones such as the PinePhone Pro or Librem 5, there is
no good open-source client for this in userspace. These phones, for VoLTE, handled the control and RTP media streams
directly in the modem's baseband. What IMS-Py does is implement the control plane interface, IMS, and its auth
(over the PC/SC smart card interface) directly in Python and hosts a SIP server instead, forwarding the RTP media streams
to any proper SIP+RTP client supporting AMR-NB such as BareSIP. Since most modems don't directly expose the IMS bearer
over to your OS, you have to work around this by connecting to the internal IMS network a different way. This actually isn't
that hard: most carriers operate something called an "ePDG", which is literally an IKEv2 VPN server (using EAP-AKA auth again)
into the internal network with the IMS server. This exists for VoWiFi, an iPhone and Android feature which allows you to make phone calls
from a WiFi network in areas of poor LTE coverage. It's possible to patch strongSwan into using EAP-AKA for auth, but an easier
way is using a Python-based IPsec and IKEv2 VPN client that someone else already made called SWU-IKEv2, also supporting EAP-AKA
with a SIM card in any PC/SC-compatible reader.
Of course, this is easier said than done, as are most things post the circuit-switched era of telecom. Carriers loosely implement
spec, including IMS, so for auth I had to get packet traces of a SIM card in an iPhone 12 trying to auth VoWiFi from a friend. Luckily,
Xcode is able to read packet data even inside of the ePDG tunnel for an iPhone connected over USB, so after getting the correct headers for
phone call creation and auth, it wasn't that bad and I was able to connect to Verizon's ePDG and IMS core with about 4-5 days of work.
Now the project is working on my ThinkPad T540p and a Sierra Wireless EM7455 modem. I also wrote a small PC/SC smart card driver which
ran AT+CSIM over the AT command channel to send raw APDU to the SIM card — that way you didn't need an external smart card reader.
My hope is that this project is able to be used by Linux phone vendors to properly implement VoWiFi or even VoLTE on harder-to-support
hardware such as phone modems newer than the Snapdragon 845.
I also posted my project on Twitter where it was a minor hit. Here is a video from there.