Discovery Project · ECE 1100
IMS-Py
An open-source, userspace LTE IMS voice client, so a plain SIP softphone can place a real carrier call.
- Status
- Working prototype
- Language
- Python
- Tested on
- Verizon
- Hardware
- T540p · EM7455
- Source
- Open
Modern phone calls aren't circuit-switched anymore; they run on a SIP derivative called IMS. Bafflingly, despite Linux phones like the PinePhone Pro and Librem 5 existing, there's still no good open-source IMS client you can actually run in userspace. IMS-Py is my attempt to build one from scratch in plain Python. Here's how it came together.
§1 · The problem
Where did voice go?
For most of cellular history a phone call was circuit-switched: a dedicated channel held open end to end. That started shifting around HSPA with VoHSPA/IR.58, but it never really caught on, since UMTS still handled calls the old circuit-switched way. LTE is where it actually changed. There's no native circuit-switched voice path in LTE, so if you want a legacy call the phone has to fall back to UMTS / GSM / CDMA2000. That isn't a usable experience for most people, and it forces carriers to keep two whole networks running side by side just to carry voice.
So the switch to packet-switched voice happened: VoLTE and VoWiFi, built on IMS, an IP Multimedia Subsystem that's basically SIP for signaling and RTP for audio, with EAP-AKA for auth. What bugs me is that none of this lives anywhere you can actually see it. On these phones voice gets handled invisibly inside the modem's baseband, so there's nothing you can read, fix, or reuse.
§2 · The pitch
Put the IMS client in userspace
IMS-Py started as one question: could I implement the IMS control plane myself, in userspace Python, and then expose it as an ordinary SIP server, so any standard softphone could dial through it and place a real call on a carrier's network?
If this works, then it can be used by Linux phone vendors to bring VoWiFi and VoLTE to phones whose basebands don't support it out of the box, instead of relying on closed modem firmware.
§3 · The process
How a call actually flows
Most modems don't expose the IMS bearer to your OS, so you have to reach the internal IMS network another way. This actually isn't that hard: most carriers run something called an ePDG (Evolved Packet Data Gateway), which is literally an IKEv2 VPN server into the network, authenticating with the same EAP-AKA credentials on the SIM. It exists for VoWiFi, the feature that lets an iPhone or Android make calls over Wi-Fi in bad coverage. So instead of fighting the modem, IMS-Py just opens that VPN itself (using an existing Python IKEv2 client someone already wrote, SWU-IKEv2) and speaks IMS across it. On the near side it hosts a normal SIP server and forwards the AMR-NB RTP media out to a plain softphone like BareSIP.
§4 · Roadblocks & failures
Spec is a suggestion
Of course this is easier said than done, like most things after the circuit-switched era. Carriers implement the spec loosely, so to get auth right I couldn't just read the RFCs; I had to capture what a real handset does. A friend's iPhone 12 doing VoWiFi gave me the ground truth. Handily, Xcode can read an iPhone's packets over USB even inside the ePDG tunnel, so once I had the right headers for auth and call setup it wasn't that bad, and I got IMS-Py talking to Verizon's ePDG and IMS core in about four or five days.
The hardware also got in the way. The ThinkPad T540p won't even POST with a non-approved WWAN card, thanks to Lenovo's infamous 1802 whitelist, so before any of the software mattered I had to physically reflash the BIOS over SPI to strip that whitelist out. I followed this whitelist-removal guide from notthebe.ee to do it.
§5 · The outcome
It places calls
IMS-Py now runs on my ThinkPad T540p with a Sierra Wireless EM7455 modem, registers to the IMS core, and carries a call out to BareSIP. Along the way I also wrote a small PC/SC smart card driver that sends raw APDUs to the SIM with AT+CSIM over the modem's AT command channel, so you don't need a separate card reader at all; the SIM already sitting in the modem is enough.
A working IMS-Py demo, placing a real carrier call from a plain SIP softphone.
Watch the IMS-Py demo on X →
§6 · ECE skills gained
What this taught me
This project pushed me across a bunch of ECE areas at once, most of them squarely in the telecom and embedded space I want to work in.
Cellular architecture
LTE EPC and IMS internals: VoLTE/VoWiFi, the ePDG, P-CSCF/S-CSCF, and how SIP and RTP actually carry a modern call.
Security & crypto protocols
IPsec and IKEv2 over the SWu interface, and EAP-AKA authentication driven by the SIM's keys.
Smart-card / embedded interfacing
ISO 7816 APDUs over PC/SC, and writing a driver that tunnels them through the modem via AT+CSIM (3GPP 27.007).
Hardware bring-up
SPI-flashing a laptop BIOS to lift a WWAN whitelist, and integrating a real LTE modem end to end.
Protocol reverse engineering
Capturing and reading live signaling, including traffic inside an IPsec tunnel, to reconstruct the correct IMS headers.
Systems software
Building a SIP server and RTP media relay in Python that translates carrier IMS into something standard clients understand.
§7 · Final thoughts
Where it goes next
Coming in I already loved legacy GSM and CDMA work, and IMS-Py pulled me toward modern LTE and IMS too. It's made the telecom thread feel like the right one for me. I want to keep building on it; the goal I'd love to hit is Linux phone vendors using IMS-Py to bring VoWiFi and even VoLTE to modems newer and harder to support than the Snapdragon 845, where the closed baseband path runs out.
More than any single result, the project confirmed the kind of engineering I want to do: taking a closed, invisible piece of infrastructure and making it something you can open up, understand, and reuse.
Addendum
Someone else went and did it too
About a month after I posted my demo, someone built basically the same thing in C++, aimed at Linux phones. I don't know whether it was inspired by IMS-Py, but either way it's great to see the idea moving in that direction, which is exactly where I wanted it to go. You can find their post here on ani.social.