PAF becomes saf/device (history kept), STATE.md dissolves into saf/state.md with the dated era archived, the substrate SAF moves up from souveraine, and every agreement points at saf/INDEX.md and nowhere else. one map, nothing to remember
9.4 KiB
PAF · MMS (picture messaging)
STATUS (2026-07-15): MMS SEND WORKS end-to-end. Two loose ends remain.
A real picture message sent successfully today — image to +12897767709, 508 KB, POSTed through Fido's MMS proxy and cleared from the queue. The core problem (reaching Fido's MMS servers with the right APN) is SOLVED. See "THE WORKING RECIPE" below.
Two things still not fully nailed:
- No auto-start / lifecycle for the daemon.
mmsd-tnghas no D-Bus auto-spawn or systemd service — it only runs when launched by hand. When it isn't running, sends silently pile up in the queue (that's how 4 messages got stuck). Needs a proper service unit. - Chatty says "MMSC is not configured." The daemon's internal config is
correct and it sends fine, but it does NOT expose the
org.ofono.mms.ModemManagerD-Bus interface (onlyorg.ofono.mms.Service), which is what Chatty's settings menu reads. So Chatty can't see the MMSC even though sending works. Setting values in Chatty's own menu did NOT bring that interface up. Daemon-side interface-registration issue, not a wrong-value issue — the file~/.mms/modemmanager/mmsalready readsMMS_APN=netsvcs,CarrierMMSC=http://mms.fido.ca,CarrierMMSProxy=205.151.11.13:80(all correct).
THE WORKING RECIPE (proven live 2026-07-15)
- APN =
netsvcs(NOTmms.fido.ca). Patched into the carrier database atrootfs-overlay/usr/share/mobile-broadband-provider-info/serviceproviders.xml(Fido entry,<apn value="netsvcs">, mmschttp://mms.fido.ca, proxy205.151.11.13:80).mmsd-tngre-reads that DB and writes the right values into~/.mms/modemmanager/mms— BUT only re-looks-up when its current MMSC is the placeholderhttp://mms.invalid, so to force a refresh you mustrm ~/.mms/modemmanager/mmsbefore restarting the daemon. - The
netsvcsbearer must be connected AND have its IPv4 applied to the netdev. ModemManager reports the IP but nothing installs it — apply manually (see cheat-sheet). Once the IP is onqmapmux0.X, the proxy becomes reachable andmmsd-tng'sSO_BINDTODEVICEbinds sends to it correctly. - With both in place,
mmsd-tngPOSTs queued messages through the proxy and they send.AutoProcessOnConnection=truemeans it auto-flushes the queue when a usable bearer appears.
To reproduce a send right now: ensure the netsvcs bearer is up with its IP
applied, rm ~/.mms/modemmanager/mms, then
mmsdtng --debug — it re-looks-up netsvcs from the DB and flushes the queue.
Texting (SMS) already works. This doc is about MMS — the picture/group messages. They still don't send/receive on their own yet, but today we found why, and proved the hard part (reaching Fido's MMS servers) actually works.
ELI5 — what MMS even is, and why it's fussy
A plain text (SMS) is tiny, so it rides along on the same signaling channel the phone uses to talk to the tower — no internet needed. A picture message (MMS) is too big for that. So MMS actually works like this:
- The tower sends you a tiny SMS that secretly means "there's a picture waiting for you."
- Your phone then has to open a special little internet connection and go download the picture from the carrier's own server (the "MMSC").
- To send a picture, your phone uploads it to that same server the same way.
The catch: that "special little internet connection" is not your normal data or WiFi. Carriers put their MMS server on a private, members-only road that only exists inside their own cellular network. You can't get to it from WiFi, and you can't get to it from the normal data connection either. You have to dial a second, separate connection specifically for MMS.
Every piece of confusion we hit came from that one fact: MMS needs its own special door, and we kept knocking on the wrong ones.
The pieces (and the plain-English name for each)
| Thing | What it really is | Value for this SIM |
|---|---|---|
| APN | The name of the door you dial for a given service | netsvcs (NOT mms.fido.ca) |
| MMSC | The server that actually holds the pictures | http://mms.fido.ca → 209.4.229.111 |
| MMS proxy | A doorman you must go through to reach the MMSC | 205.151.11.13:80 |
| The daemon | mmsd-tng, the background program that does all this for you |
already installed |
| The phone book | serviceproviders.xml, a big list of carrier settings the daemon trusts |
had the WRONG APN |
What we got wrong (and how we found the right answer)
Wrong door #1: mms.fido.ca
Every website, and the settings file already on the phone, said Fido's MMS APN is
mms.fido.ca. We dialed it. The network slammed the door:
ServiceOptionNotSubscribed — "you're not signed up for that."
That error sounds like an account/billing problem, but it wasn't. It just means that door name doesn't exist on this SIM. The public instructions are for manually typing settings into an Android phone; they don't necessarily match what the SIM is actually provisioned for underneath.
How we found the truth: we asked the modem to list the doors it actually
knows about (mmcli -m 0 --3gpp-profile-manager-list). It answered with a real
list, and there it was:
profile 4: apn: netsvcs apn type: mms
The real MMS door on this SIM is called netsvcs, not mms.fido.ca. Dialed
netsvcs → it connected immediately. (Confirmed the same name shows up in the
raw Android radio logs from this same SIM, so it's genuinely the carrier's name
for it, not a fluke.)
Gotcha:
ltemobile.apnis the generic Rogers-family internet door (Rogers/Fido/Chatr all share it). Some guides say "just use that for MMS too." It's a red herring here — it's not Fido-specific, and it came up IPv6-only, which can't even reach the IPv4 MMS server.netsvcsis the right door.
Wrong door #2: trying to reach the server the normal way
Once netsvcs connected, we tried to reach the MMS proxy (205.151.11.13) — and
it hung, dead silence.
Two reasons, both now understood:
-
The connection was "connected" but had no address actually plugged in. The modem dialed the door and the carrier handed us an address (
10.145.x.x) — but nothing put that address onto the network card. It's like being handed the keys to a car that nobody parked in your driveway. On the normal data connection, a program called NetworkManager does this parking step automatically. For our hand-dialed MMS connection, nobody did it. The interface had no IPv4 address at all.The moment we manually "parked the car" (
ip addr add 10.145.146.168/28onto the interface, plus routes to the proxy through the carrier gateway) — the proxy answered. Reliably, every time. That was the real unlock. -
The proxy only speaks "MMS language." After it started answering, a plain web request (
curl) to it still got silence. That's expected: Fido's proxy is a WAP proxy — it only understands the special MMS protocol (WSP), and ignores normal web traffic. So a normal browser test will always look like a failure even when the path is perfectly open. Onlymmsd-tngspeaks the right language to it.
Where it actually stands right now
PROVEN working:
- The correct APN is
netsvcs, and it connects. - Once its IP is applied to the interface, Fido's MMS proxy is reachable (TCP handshake succeeds every time, from the bearer's own address).
Still missing (the automation):
- Nothing yet automatically does the "park the car" step — dial the
netsvcsMMS connection, apply its IP + routes to the interface, and hand it tommsd-tng— at the moment a picture needs to go out, then tear it down after. mmsd-tng's own config keeps regenerating from the carrier phone book (serviceproviders.xml) with the wrongmms.fido.caAPN, so editing its local config by hand gets overwritten. Fixing the phone book entry is the durable path (started: patched tonetsvcsinrootfs-overlay/usr/share/ mobile-broadband-provider-info/serviceproviders.xml), butmmsd-tng's lookup only matches an entry when the active bearer's APN equals the entry'svalue=, so the exact match behavior still needs verifying against the real code path before calling it solved.
Next step: re-test mmsd-tng end-to-end now that the network road is
manually open (send one real MMS), to confirm the daemon itself works, before
building the automation that opens the road on its own.
Cheat-sheet: manually open the MMS road (for testing)
# 1. dial the real MMS door, IPv4
mmcli -m 0 --create-bearer="apn=netsvcs,apn-type=mms,ip-type=ipv4"
mmcli -m 0 -b <N> --connect # note the interface (qmapmux0.X) + address
# 2. "park the car": put the handed-out IP onto the interface
sudo ip addr add <address>/<prefix> dev qmapmux0.X
# 3. lay down the private road to the proxy + MMSC via the carrier gateway
sudo ip route add 205.151.11.13/32 via <gateway> dev qmapmux0.X # proxy
sudo ip route add 209.4.229.111/32 via <gateway> dev qmapmux0.X # MMSC
# 4. proof the road is open (TCP handshake to the proxy should succeed):
python3 -c "import socket;s=socket.socket();s.bind(('<address>',0));s.connect(('205.151.11.13',80));print('proxy OPEN')"
(A plain curl through the proxy will still hang — that's normal, it only
speaks MMS, not web. Real proof is mmsd-tng sending a message.)