MMS Centre (MMSc)
← Back to Documentation Index | Configuration Reference | API Reference
Overview
OmniMessage includes an MMS Centre (MMSc) that handles the receipt, storage, and delivery notification of multimedia messages. The MMSc supports the two primary MMS inter-working interfaces defined by 3GPP TS 23.140: MM1 for direct handset communication and MM4 for inter-carrier relay.
When a subscriber sends or receives an MMS, the MMSc stores the message content locally and injects an MMS notification SMS into the OmniMessage message queue via the standard REST API. The receiving handset retrieves the MMS by making an HTTP GET directly to the MMSc.
Relevant Specifications
| Specification | Title |
|---|---|
| 3GPP TS 23.140 | Multimedia Messaging Service (MMS) — functional description |
| 3GPP TS 26.140 | MMS — media formats and codecs |
| OMA MMS Encapsulation Protocol | MM1 WAP binary encoding specification |
Architecture
The MMSc sits alongside OmniMessage and interfaces with it exclusively through the REST API. No direct database access to the message store occurs.
MMS Delivery Flow
On-Net Delivery (MM1)
A subscriber sends an MMS to another subscriber on the same network.
Off-Net Delivery (MM4)
A subscriber sends an MMS to a subscriber on a different carrier.
Inbound MM4 (from Peer Carrier)
A subscriber on another network sends an MMS to an on-net subscriber.
MMS Notification SMS
The MMS Notify SMS is a binary SMS (DCS 0x44, 8-bit data) containing a WSP-encoded m-notification-ind PDU. It is split into 64-byte segments, each wrapped with a concatenated SMS UDH, and submitted to OmniMessage as individual messages via POST /api/messages.
The notification payload encodes the MMS content location as an HTTP URL pointing to the MMSc:
http://<mmsc.mms_domain>/<mms_message_id>.00
The receiving handset uses this URL to retrieve the MMS directly from the MMSc over MM1.
On/Off-Net Determination
The MMSc uses ENUM DNS (NAPTR lookups) to determine whether a destination subscriber is on-net or off-net before deciding whether to send an MMS Notify SMS or relay via MM4.
| Result | Action |
|---|---|
NAPTR record matches a configured enum_routing entry with on_net: true | MMS stored locally; notify SMS injected into OmniMessage queue |
NAPTR record matches an entry with on_net: false | MMS stored locally; forwarded to peer via MM4 SMTP relay |
| No NAPTR record or ENUM timeout | Treated as off-net; MM4 relay attempted |
Configuration
The MMSc is configured via MMSc/config.yaml.
Configuration Example
log_prefix: 'MMSc'
smsc_api:
url: 'https://10.4.10.215:8443'
mmsc:
host: 0.0.0.0
port: 8080
location: 'mmsc01.mnc001.mcc001.3gppnetwork.org'
mms_domain: "mms.example.com"
remote_mmsc_ip:
- 10.101.2.150
mm4_peers:
sinch:
- mm4_destination_host: mm4.sinch.com
mm4_destination_port: 25
mms_domain: mms1.mmsnni.carrier.net
database:
mysql:
server: 127.0.0.1
username: mmsc
password: changeme
database: mmsc
ping_before_query: true
prometheus:
listen_port: 8083
number_routing:
enum_domain: e164.arpa
enum_timeout_seconds: 1
enum_servers:
- 10.4.10.80
enum_routing:
- domain: 'mobile.example.local'
operator: 'ExampleMNO'
on_net: true
next_hop: 'internal'
destination_rewriting:
- regex_match: "^1(\d{10}$)"
regex_replace: "\1"
description: Strip leading 1 from 11-digit NANP number
default_route_mm4: 'sinch'
smsc_api Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
url | String | Yes | — | Base URL of the OmniMessage REST API. Used to submit MMS Notify SMS messages. |
api_key | String | No | — | Bearer token for API authentication, if required. Omit if the API has no authentication configured. |
hss_url | String | No | — | Base URL of an HSS/PCRF API for resolving client IP addresses to MSISDNs on the MM1 interface. When omitted, IP-to-MSISDN resolution is unavailable and requests from non-localhost IPs will be rejected. |
mmsc Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
host | String | No | 0.0.0.0 | Interface address to bind the MM1 HTTP server. |
port | Integer | No | 8080 | TCP port for the MM1 HTTP server. |
location | String | Yes | — | Node identity string for this MMSc, used as the source_mmsc recorded against delivered messages. |
mms_domain | String | Yes | — | Domain name of this MMSc. Encoded into the MMS content location URL sent in Notify SMS messages (e.g. mms.example.com). |
remote_mmsc_ip | List | No | [] | IP addresses of peer MMScs. Requests from these IPs on the retrieval endpoint are not recursively forwarded, preventing loops. Also used as fallback sources on a local cache-miss. |
mm4_peers | Map | No | — | Named groups of MM4 relay targets. Each key is a peer group name; each entry is a list of SMTP endpoint definitions. See MM4 Peer Parameters below. |
MM4 Peer Parameters
Each entry under mmsc.mm4_peers.<name> is a list. When multiple entries are present, one is selected at random per relay attempt.
| Parameter | Type | Required | Description |
|---|---|---|---|
mm4_destination_host | String | Yes | Hostname or IP of the peer carrier's MM4 SMTP server. |
mm4_destination_port | Integer | Yes | SMTP port on the peer MMSc. Typically 25. |
mms_domain | String | Yes | MMS domain of the peer carrier. Used in SMTP To headers and message addressing. |
database.mysql Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
server | String | Yes | — | MySQL server hostname or IP. |
username | String | Yes | — | Database username. |
password | String | Yes | — | Database password. |
database | String | Yes | — | Database name. Must match the schema created from MMSc/schema.sql. |
ping_before_query | Boolean | No | false | Reconnect to MySQL before each query. Recommended for long-running processes to recover from server-side connection timeouts. |
number_routing Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
enum_domain | String | Yes | — | Root DNS zone for ENUM NAPTR lookups (e.g. e164.arpa). |
enum_timeout_seconds | Integer | No | 1 | DNS query timeout in seconds. Set to 0 to disable ENUM and treat all destinations as off-net. |
enum_servers | List | No | System DNS | DNS resolver addresses to use for ENUM queries. |
enum_routing | List | No | — | Ordered list of NAPTR domain-to-route mappings. See ENUM Routing Parameters below. |
destination_rewriting | List | No | — | Ordered list of regex rewrite rules applied to destination MSISDNs before ENUM lookup and MM4 relay. First matching rule wins. |
default_route_mm4 | String | Yes | — | Key of the MM4 peer group (from mmsc.mm4_peers) to use when no other route applies. |
ENUM Routing Parameters
| Parameter | Type | Description |
|---|---|---|
domain | String | NAPTR replacement domain string to match against (substring match). |
operator | String | Human-readable operator name for logging. |
on_net | Boolean | true — subscriber is on-net; inject notify SMS. false — relay via MM4. |
next_hop | String | Optional. Informational label recorded in logs; not used for routing. |
prometheus Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
listen_port | Integer | No | 8083 | Port on which Prometheus metrics are exposed. Choose a port that does not conflict with the OmniMessage core metrics port (default 9568). |
Database Schema
The MMSc maintains its own MySQL database for MMS metadata and delivery state. The schema is defined in MMSc/schema.sql and consists of a single table.
mms_message_queue
| Column | Type | Description |
|---|---|---|
id | INT UNSIGNED | Auto-increment primary key. |
unique_id | VARCHAR(64) | MMSc-assigned message identifier. Also used as the retrieval URL path segment. |
send_time | DATETIME | Timestamp when the MMS was received by this MMSc. |
expires | DATETIME | Message expiry time, after which it will not be delivered. |
source_msisdn | VARCHAR(32) | Sending subscriber's MSISDN. |
destination_msisdn_unique | VARCHAR(32) | Primary recipient MSISDN. |
mms_destinatination_msisdn_list | TEXT | Comma-separated list of all recipient MSISDNs (for group MMS). |
mms_subject | VARCHAR(255) | MMS subject line. |
mms_file_path | VARCHAR(512) | Path to the stored MMS content file (stored_mms/<id>.mms). |
source_mmsc | VARCHAR(128) | Identity of the MMSc or MM4 peer that originated the message. |
dest_mmsc | VARCHAR(128) | Set to MM4_<peer> after outbound MM4 relay, or to the retrieving MMSc location after local delivery. |
mms_notify_time | DATETIME | Timestamp when the MMS Notify SMS was submitted to OmniMessage. |
mms_retrive_time | DATETIME | Timestamp when the subscriber retrieved the MMS. |
Processes
The MMSc runs as two independent processes.
MM1 HTTP Frontend
Handles WAP MMS submissions (m-send-req) and retrievals (GET /<id>) from handsets. Run via gunicorn:
gunicorn --bind 0.0.0.0:8080 MMSc:app
The MM1 frontend should sit behind a reverse proxy (nginx, HAProxy) for TLS termination. Handsets typically connect to the MMSc APN using the carrier's MMS proxy settings.
MM4 SMTP Server
Listens for inbound MM4_forward.REQ messages from peer carrier MMScs. Run directly:
python smtp_server.py
Port 25 requires either root privileges or CAP_NET_BIND_SERVICE. Outbound MM4 relay uses Python's built-in smtplib and does not require a separate MTA.
Metrics
The MMSc exposes Prometheus metrics on the port configured under prometheus.listen_port.
MMS Operations
Metric: prom_mms_operations_count_total
Type: Counter
Description: Count of MMS operations processed.
Labels:
method— Operation type:HTTP_POST,m-send-req,m-notifyresp-ind,m-acknowledge-ind,InsertMMS,GetMMS,UpdateMMS,MMS_Get,MMS_Get_Fail,SMTP_Start,SMTP_Complete
Example queries:
# MMS submit rate
rate(prom_mms_operations_count_total{method="m-send-req"}[5m])
# MM4 inbound completion rate
rate(prom_mms_operations_count_total{method="SMTP_Complete"}[5m])
API Response Times
Metric: prom_mms_api_response_time
Type: Histogram
Description: MM1 HTTP handler latency in seconds.
Labels:
result— HTTP status code:200,404,500function— Handler:m-send-req,m-notifyresp-ind,m-acknowledge-ind,GET MMS,GET MMS Remote,unknown
Example queries:
# 95th percentile retrieval latency
histogram_quantile(0.95,
rate(prom_mms_api_response_time_bucket{function="GET MMS"}[5m]))
MM4 Relay Times
Metric: prom_mm4_response_time
Type: Histogram
Description: MM4 SMTP relay latency in seconds.
Labels:
result—200(success) or000(failure)direction—in(inbound from peer) orout(outbound to peer)peer— MM4 peer group name
Example queries:
# MM4 outbound error rate
sum(rate(prom_mm4_response_time_count{direction="out",result="000"}[5m]))
/ sum(rate(prom_mm4_response_time_count{direction="out"}[5m]))
DNS Response Times
Metric: prom_dns_response_time
Type: Histogram
Description: ENUM DNS query latency in seconds. A spike here will delay MMS delivery decisions.