gsm_map
GSM MAP — the Mobile Application Part of the SS7 protocol suite
(3GPP TS 29.002) — as a set of rasn-derived ASN.1 types you can
BER-encode and -decode, from Rust or Python.
Each MAP operation is an ordinary Rust struct or enum that round-trips through
rasn::ber; the TCAP layer above and the SCCP/M3UA/MTP3 transports below are
somebody else's job. Pure and I/O-free: no sockets, no async runtime — so it
drops into an SMSC, HLR, VLR, MSC, STP, or gsmSCF and stays unit-testable.
The same codec ships two ways from one source tree, one version: the Rust
crate (cargo add gsm_map, pyo3-free) and a Rust-backed Python wheel
(pip install gsm_map) exposing the SMS operation set.
use RoutingInfoForSmArg;
use *;
// SMS-SC asks the HLR to route a message to a subscriber (sendRoutingInfoForSM).
// Addresses are TBCD in an OCTET STRING: byte 0 is TON/NPI, the rest are the
// swapped-nibble digits. This one is the fictional +1 555 0100 999.
let arg = RoutingInfoForSmArg ;
// Encode to BER for the TCAP Invoke parameter …
let ber = encode.unwrap;
// … and the peer decodes it straight back into the typed struct.
let decoded: RoutingInfoForSmArg = decode.unwrap;
assert_eq!;
What's covered
Every operation below is a BER-codable argument/result type (see
src/operations/):
| Group | Operations |
|---|---|
| SMS | sendRoutingInfoForSM, mo-ForwardSM, mt-ForwardSM, reportSM-DeliveryStatus, alertServiceCentre, informServiceCentre, readyForSM |
| Mobility | updateLocation, cancelLocation, purgeMS, sendIdentification, updateGprsLocation, sendRoutingInfoForGprs |
| Authentication | sendAuthenticationInfo (GSM triplets + UMTS quintuplets) |
| Subscriber data | insertSubscriberData, deleteSubscriberData |
| Subscriber info | provideSubscriberInfo, anyTimeInterrogation, anyTimeModification |
| Call handling | sendRoutingInfo, provideRoamingNumber |
| Supplementary services | registerSS, eraseSS, activateSS, deactivateSS, interrogateSS |
| USSD | processUnstructuredSS-Request, unstructuredSS-Request, unstructuredSS-Notify |
| Fault recovery | reset, restoreData |
| Handover / IMEI / LCS / OAM | prepareHandover, checkIMEI, provideSubscriberLocation, activateTraceMode, … |
Plus the connective tissue a stack needs:
op_codesandoperation_name()— the MAP operation-code registry.operations::errors— MAP error codes anderror_name().application_context— the MAP application-context OIDs (v1/v2/v3) for TCAP dialogue negotiation.dialogue— builds the TCAP dialogue portion (AARQ/AARE) that carries the application context, so a decoder can pick the right ASN.1 module.MapError— the crate error type (wrapstcap::TcapError).
Where it fits
TCAP dialogue + components (the `tcap` crate)
▲
MAP / CAP operation types (this crate; pure, I/O-free)
▼
SCCP ▸ M3UA / MTP3 ▸ SCTP (transport; separate crates)
More: docs/OVERVIEW.md.
Python
pip install gsm_map gives a Rust-backed wheel exposing the SMS operation set.
Each operation has .encode() -> bytes (the BER Invoke parameter) and a
.decode(bytes) classmethod; addresses/identities cross the boundary as bytes
(TBCD in an OCTET STRING). All examples use synthetic +1 555 01xx numbers and
the reserved test PLMN 001/01.
# SMS-GMSC asks the HLR to route a message (sendRoutingInfoForSM, op 45).
=
= # → the TCAP Invoke parameter
=
assert ==
# mo-ForwardSM (op 46): the SM-RP-DA / -OA are CHOICEs.
=
The wheel is built for regular CPython 3.9+ (abi3) and, version-specific, for
free-threaded (3.13t/3.14t) CPython — the module is gil_used = false, so it
loads without re-enabling the GIL.
Performance
cargo bench runs two suites (criterion):
codec— BER encode/decode of the core SMS ops. Indicative (x86-64, release): SRI-SM arg ~99 ns encode / ~72 ns decode; MO-ForwardSM ~147 ns / ~120 ns.integration— the full SS7 stack, end to end: it assembles a real connectionless message — MAP op arg → TCAPInvokein aBegin→ SCCPUDTwith GT/SSN addresses → wire bytes — and measures both directions at volume (encodeMAP → TCAP → SCCP, decodeSCCP → TCAP → MAP), reporting messages/sec. Indicative: SRI-SM ~1.7 M msg/s encode, ~2.9 M msg/s decode; MO-ForwardSM ~1.4 M msg/s encode, ~2.8 M msg/s decode.
MAP operation arg (gsm_map — BER-encode the typed struct)
│
TCAP Invoke in a Begin (tcap)
│
SCCP UnitData (UDT) (sccp — GT/SSN addresses, TCAP as user data)
▼
wire bytes
scripts/mem_leak_test.sh runs examples/leak_check.rs: a counting global
allocator asserts live bytes stay flat across codec and full-stack churn.
Development
# Rust
# Python wheel
&&
License
MIT — see LICENSE.