REPRODUCIBILITY: 100 %
OS VERSION: 5.1.0.11 (Pispala); hw release 1.1.0.12; ofono 1.29+git12-1.16.4.jolla, ofono-binder-plugin 1.1.25-1.12.2.jolla, libgbinder 1.1.45-1.15.1.jolla, libgbinder-radio 1.6.1-1.9.2.jolla, mms-engine 1.0.83
HARDWARE: Jolla C2 (Reeder s19mps)
UI LANGUAGE: Norwegian (bokmål)
REGRESSION: Unknown — issue present since first setup of this device; no earlier release tested on it
DESCRIPTION:
MMS sending and receiving fail with a deterministic 60-second timeout when the operator uses a separate MMS APN (tested with Happybytes, an MVNO on Telenor Norway: MMS APN mms, MMSC http://mms.media, no proxy — the exact settings published by the operator). Ordinary internet over the internet APN works fine throughout.
Root cause, verified live on the device: when mms-engine activates the MMS context, oFono’s binder plugin reports the data call settings (address, DNS) but no kernel route is ever installed via the MMS interface (seth_lte1). The data call reports gateways=0.0.0.0, and because the MMS context is not managed by connman (it is activated standalone by mms-engine via oFono D-Bus), it — unlike the internet context — receives neither a prefix route nor an on-link default route.
mms-engine binds its HTTP session to the MMS interface address (SOUP_SESSION_LOCAL_ADDRESS in mms_task_http.c), but routing is destination-based: the TCP packets leave via the internet APN’s default route (default dev seth_lte0 scope link) with a source address from the MMS pool, and the operator’s ingress filtering drops them. libsoup’s default 60 s session timeout then surfaces as HTTP status 7 (Connection terminated unexpectedly).
Proof: with a host route via seth_lte1 forced in as root, the MMSC answers immediately — curl from the MMS source IP gets HTTP/1.1 405 Method Not Allowed, Allow: POST,OPTIONS (the expected MMSC reply to a GET) — and a real MMS sent from the Messages app succeeds, including reception of the MMS notification. Network, provisioning, APN settings, MMSC and mms-engine are all fine; the only missing piece is a route via the MMS interface.
PRECONDITIONS:
- A SIM from an operator that uses a separate MMS APN (Telenor Norway and its MVNOs qualify: APN
mms, MMSChttp://mms.media, no proxy). - MMS access point configured per the operator’s instructions (Settings → System → Mobile network → MMS access point).
- Mobile data working normally on the
internetAPN; WiFi switched off (not required for the bug, but keeps the analysis clean). - For observing the internals: developer mode enabled, SSH over USB.
STEPS TO REPRODUCE:
-
Insert the SIM, configure the MMS access point as above (APN
mms, MMSChttp://mms.media, MMS proxy empty). -
SSH in over USB and watch interfaces and the routing table:
while true; do ip -4 addr show seth_lte1 2>/dev/null; ip -4 route show; sleep 1; done -
From the Messages app, share a small picture to your own number.
-
Observe that
seth_lte1comes up with a 10.120.x.x address — and that the routing table never gains any route viaseth_lte1. -
Wait ~60 s and watch the message fail. mms-engine retries roughly every 76 s, ~11 attempts total, then the message is permanently failed.
-
Optional counter-proof, as root:
dbus-send --system --print-reply --dest=org.ofono /ril_0/context2 \ org.ofono.ConnectionContext.SetProperty string:Active variant:boolean:true ip route replace 148.122.173.15/32 dev seth_lte1 ip route replace 148.122.173.79/32 dev seth_lte1 curl -4 -v --interface 10.120.95.111 http://mms.media/ # → 405, Allow: POST,OPTIONSResend the MMS from the app while those routes exist → it succeeds and the MMS notification arrives.
EXPECTED RESULT:
When the MMS context is activated, a usable route via the MMS interface (seth_lte1) is installed (on-link default route or equivalent source-based routing), so that the MMS POST bound to the MMS source address reaches the MMSC. The MMS is delivered and the incoming MMS notification/content is retrieved — as it does on Android handsets with the same SIM and the same operator settings.
ACTUAL RESULT:
seth_lte1 comes up (e.g. inet 10.120.95.111/32) but no route referencing seth_lte1 is ever created. Routing table captured live while the MMS context was UP:
$ ip -4 route show
0.0.0.0 dev seth_lte0 scope link
default dev seth_lte0 scope link
10.0.0.0/8 dev seth_lte0 proto kernel scope link src 10.8.167.111
10.8.167.0/24 dev seth_lte0 proto kernel scope link src 10.8.167.111
192.168.2.0/24 dev usb0 proto kernel scope link src 192.168.2.15
Consequently every MMS send fails after exactly 60 s. mms-engine log (identical for every attempt, 30+ attempts across all configuration variants):
[mms-task-http] MMS interface address 10.120.105.253
[mms-task-http] m-send.req (261475 bytes) -> http://mms.media -> m-send.conf
... exactly 60 s later ...
[mms-task-http] HTTP status 7 (Connection terminated unexpectedly)
m-send.conf is 0 bytes — the MMSC never answered, because the SYNs went out the internet APN with a foreign source address and were dropped by the operator. MMS reception (notification content retrieval) fails for the same reason.
MODIFICATIONS:
- OpenRepos packages installed for diagnostics: MMS Logger 1.0.20, oFono/sailfish-log-viewer.
- Developer mode + SSH enabled.
- After diagnosing, a workaround systemd service (
mms-route-fix.service, runs a small script that adds host routes to the MMSC viaseth_lte1whenever that interface is up) was installed — with it, MMS works flawlessly. All attached logs were captured before the workaround was installed. - No other patches, no WayDroid, no alternative repositories.
ADDITIONAL INFORMATION:
oFono activates the MMS context without any error (ofono.log):
binder_data_call_new_aidl() [status=0,retry=-1,cid=2,active=2,type=0,
ifname=seth_lte1,mtu=0,address=10.120.105.253,
dns=148.122.173.7 148.122.173.77,gateways=0.0.0.0,pcscf=]
setting up data call
mtu_limit_apply() seth_lte1 mtu 1500 => 1280
pri_update_mms_context_settings() proxy mms.media port 80
Counter-proof with forced routes (context up, root):
# ping -c2 148.122.173.7 # MMS-APN DNS via seth_lte1
64 bytes from 148.122.173.7: seq=0 ttl=60 time=88.668 ms
# curl -4 -v --interface 10.120.95.111 http://mms.media/
* Established connection to mms.media (148.122.173.15 port 80) from 10.120.95.111
> GET / HTTP/1.1
< HTTP/1.1 405 Method Not Allowed
< Server: nginx/1.29.3
< Allow: POST,OPTIONS ← MMSC alive and reachable
End-to-end success with routes held in place — journal:
Sep 30 00:38:04 JollaC2 ofonod[1479]: 2f 6d 6d 73 2e 6d 65 64 69 61 2f ... /mms.media/3ePw3...
Sep 30 00:38:04 JollaC2 ofonod[1479]: plugins/sailfish_pushforwarder.c:
pf_handle_datagram() content type application/vnd.wap.mms-message
Workaround in use (systemd watchdog; MMS then works fully automatically):
#!/bin/sh
IP=/usr/sbin/ip
IFACE=seth_lte1
MMSC_IPS="148.122.173.15 148.122.173.79" # mms.media (Telenor NO)
while true; do
if "$IP" -4 addr show "$IFACE" 2>/dev/null | grep -q "inet "; then
for ip_ in $MMSC_IPS; do
"$IP" route replace "${ip_}/32" dev "$IFACE" 2>/dev/null
done
fi
sleep 1
done
Suggested proper fix (source level): install source-policy routing for MMS contexts — e.g. in oFono core (src/gprs.c) when a context of type MMS is activated with IPv4 gateway 0.0.0.0/unset, add (and remove on deactivation):
ip rule add pref 100 from <mms_ipv4> lookup <table>
ip route add default dev <mms_ifname> table <table> # on-link default
This mirrors Android’s per-network routing tables and cannot interfere with the default internet route. Alternatives: synthesize a usable gateway in binder_gprs_context_set_gateway() when the data call reports 0.0.0.0, or let mms-engine (mms-connman-nemo) manage the route for its own connection (grant CAP_NET_ADMIN). Regression criteria: MMS works with separate-MMS-APN operators and with proxy-based MMSCs; ordinary traffic still uses the internet APN during transfers; no routes/rules leak after context release.
rename “workaround.targz” to “workaround.tar.gz”, unzip and follow instructions in readme or setup manually.
workaround.targz (3.4 KB)