Watch
1
0
Fork
You've already forked SouveraineOS
0
SouveraineOS/saf/device/mms.md
Fimeg bde961c6f2 saf: one spine — device, state, and work under the index
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
2026-08-18 09:47:30 -04:00

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:

  1. No auto-start / lifecycle for the daemon. mmsd-tng has 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.
  2. 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.ModemManager D-Bus interface (only org.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/mms already reads MMS_APN=netsvcs, CarrierMMSC=http://mms.fido.ca, CarrierMMSProxy=205.151.11.13:80 (all correct).

THE WORKING RECIPE (proven live 2026-07-15)

  1. APN = netsvcs (NOT mms.fido.ca). Patched into the carrier database at rootfs-overlay/usr/share/mobile-broadband-provider-info/serviceproviders.xml (Fido entry, <apn value="netsvcs">, mmsc http://mms.fido.ca, proxy 205.151.11.13:80). mmsd-tng re-reads that DB and writes the right values into ~/.mms/modemmanager/mms — BUT only re-looks-up when its current MMSC is the placeholder http://mms.invalid, so to force a refresh you must rm ~/.mms/modemmanager/mms before restarting the daemon.
  2. The netsvcs bearer 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 on qmapmux0.X, the proxy becomes reachable and mmsd-tng's SO_BINDTODEVICE binds sends to it correctly.
  3. With both in place, mmsd-tng POSTs queued messages through the proxy and they send. AutoProcessOnConnection=true means 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:

  1. The tower sends you a tiny SMS that secretly means "there's a picture waiting for you."
  2. Your phone then has to open a special little internet connection and go download the picture from the carrier's own server (the "MMSC").
  3. 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.ca209.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.apn is 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. netsvcs is 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:

  1. 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/28 onto the interface, plus routes to the proxy through the carrier gateway) — the proxy answered. Reliably, every time. That was the real unlock.

  2. 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. Only mmsd-tng speaks 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 netsvcs MMS connection, apply its IP + routes to the interface, and hand it to mmsd-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 wrong mms.fido.ca APN, so editing its local config by hand gets overwritten. Fixing the phone book entry is the durable path (started: patched to netsvcs in rootfs-overlay/usr/share/ mobile-broadband-provider-info/serviceproviders.xml), but mmsd-tng's lookup only matches an entry when the active bearer's APN equals the entry's value=, 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.)