Files
smpp-js/interop-tests/research/smsc-simulators.md
T

31 KiB
Raw Blame History

SMPP SMSC-side test targets for @larvit/smpp

Research date 2026-09-05. All claims cite the URL they came from; anything not confirmed by a primary source is marked unverified.

Quick comparison

Candidate Language License Maintained? Docker tag (pinned) SMPP port SMPP versions
SMPPSim (Selenium Software) Java GPLv2 sourceforge Stalled — homepage seleniumsoftware.com returns Cloudflare 522 as of this research; last SourceForge file 2015-05-22; community fork last touched 2024-01-09 none published — build your own 2775 3.3/3.4 implied, not confirmed
Jasmin SMS Gateway Python/Twisted ISC-style (see repo) github Source active (last push 2026-04-26), last tagged release 0.11.0 (2023-11-10) jookies/jasmin:0.11.0 dockerhub 2775 3.4
Kannel + opensmppbox C BSD-style (Kannel) Kannel core: last stable 1.4.5, 2018-06-19 kannel.org; opensmppbox (pruiz fork): last commit 2014-04-22 github none — build from source 2345 (configurable) 3.3/3.4/5.0
Kannel fakesmsc C BSD-style same as Kannel n/a configurable (e.g. 10000) none — not SMPP at all
Melrose Labs SMSC Simulator (hosted) closed-source proprietary Actively run (commercial service) n/a — hosted 2775 (8775 TLS) 3.3/3.4/5
Melrose Labs SMSC Simulator (OSS, old code) C++ MIT github Dormant, last push 2023-07-15, explicitly "old version" none published 2775 subset of 3.4
ukarim/smscsim Go MIT github Source active (last push 2025-12-12); Docker tags stop at 0.2.0 ukarim/smscsim:0.2.0 (no newer semver tag) dockerhub 2775 (env SMSC_PORT) subset of 3.4
mdouchement/smsc3 Go MIT github Last push 2024-05-09, small project none published — Dockerfile in repo 20001 3.4
K2InformaticsGmbH/smsc_simulator Erlang Apache-2.0 github Abandoned, last commit 2018-08-31 none configurable SMPP + UCP
MavoCz/smscsim (cloudhopper-based) Java unverified unverified last-commit date none configurable (CLI -p) 3.3/3.4/5.0 (via cloudhopper)
fizzed/cloudhopper-smpp Java Apache-2.0 github Last push 2020-10-12 none — library + demo, not a packaged sim demo-configurable 3.3/3.4/most of 5.0
jsmpp SMPPServerSimulator example Java Apache-2.0 github jsmpp itself very active (last push 2026-06-17); the example is a demo class, not a packaged tool none — sample code example-configurable 3.4/3.3
node-smpp JS MIT github Last push 2023-12-28 none — library, build your own server n/a 5.0 (back-compat with 3.4)
MikeSafonov/smpp-server-mock Java (JUnit ext.) MIT github Last push 2023-03-10 none — embedded-in-test only, not standalone n/a unverified
Restcomm/TeleStax SMSC Gateway simulator Java/JSLEE unverified project largely dormant post-TeleStax none published 2776 (sample) unverified, full carrier-grade stack
OsmoMSC SMPP interface C AGPL (Osmocom) Actively maintained as part of Osmocom NITB/MSC, but it's a client interface for external ESMEs bound to a live MSC core, not a standalone SMSC simulator you spin up in Docker none configurable unverified
smscsim.smpp.org (public) closed n/a unverified, listed on smpp.org hosted 2775 unverified, 2 SMS/s cap

Ozeki NG SMS Gateway and NowSMS both ship free/trial tiers with an SMPP server mode, but are Windows-first, closed-source products; skipped per task scope beyond this line.


1. SMPPSim (Selenium Software)

  1. Source: originally seleniumsoftware.com/downloads.html; that domain currently returns an HTTP 522 (Cloudflare "origin unreachable") when fetched directly — confirmed via both WebFetch and a raw curl from this research session, so the vendor's own site is effectively down right now. SourceForge mirror: sourceforge.net/projects/smppsim — license GPLv2, "Currently hosted by Selenium Software", last file dated 2015-05-22. A community fork with docs/props preserved: komuw/smpp_server_docker (last push 2019-06-04), user-guide mirrored at user-guide.htm. Not actively maintained by any single fork; version history in the mirrored guide references up to v2.6.6.
  2. Docker: no maintainer-published image with a pinned version tag exists. Two build-yourself Dockerfiles found:
    • kwahome/smpp-sim-docker (repo last pushed 2024-01-09) — its own Dockerfile builds openjdk:7-jre-alpine + bundled SMPPSim/, but its docker-compose.yml instead pulls a pre-built blackorder/smppsim:latestonly a latest tag exists on that Docker Hub repo (pushed ~2 years ago, single tag) dockerhub. Since no full-patch-version tag is published anywhere, to comply with "never floating tags" you must build the image yourself from the Dockerfile and apply your own version tag.
    • bitsensedev/smpp-sim on Docker Hub: single latest tag, pushed 9+ years ago — effectively abandoned, do not use.
    • Ports (from the Dockerfile env defaults): SMPP 2775, HTTP admin 8884 (some older docs say port 88 — verify against the image you build).
    • Default credentials (env SYSTEM_IDS / PASSWORDS): smppclient1,smppclient2,smppclient3 / password,password,password Dockerfile.
  3. SMPP versions: not explicitly stated in any surviving doc; behavior suggests 3.3/3.4-era PDU set. Whether it validates interface_version at bind — unverified, no mention in the mirrored user guide.
  4. Delivery receipts: yes, when registered_delivery_flag is set on submit_sm. Controlled by percentage knobs: PERCENTAGE_DELIVERED, PERCENTAGE_UNDELIVERABLE, PERCENTAGE_ACCEPTED, PERCENTAGE_REJECTED, plus PERCENTAGE_THAT_TRANSITION (chance of an intermediate state before final), DELAY_DELIVERY_RECEIPTS_BY (delayed DLR, ms), MAX_TIME_ENROUTE. TLV vs text-body format not documented; message-id format documented only as "randomised … with configurable prefix" — hex/decimal notation unverified.
  5. Long messages: UDH/sar_*/message_payload handling not documented in any surviving guide fragment — unverified, treat as untested.
  6. Encodings: only one hard fact recovered — binary MO messages (hex-prefixed with 0x in the inject form) get data_coding auto-set to 4. GSM7 packed-vs-unpacked, Latin-1, UCS-2 behavior — unverified.
  7. MO injection: three documented methods — (a) web form /inject_mo.htm, (b) "loopback" mode that turns a submit_sm back into a deliver_sm, (c) MO service reading a deliver_messages.csv file. Also supports SMSC-initiated outbind (OUTBIND_ENABLED=true + OUTBIND_ESME_* env vars) to test your library's outbind handling.
  8. Fault injection: queue-full simulation via INBOUND_QUEUE_MAX_SIZE/OUTBOUND_QUEUE_MAX_SIZE and DELAYED_INBOUND_QUEUE_MAX_ATTEMPTS; on ESME_RMSGQFUL the mirrored guide says SMPPSim "will attempt to deliver the MO message again, after a delay" (v2.6.0 note). MO_DELIVERY_MESSAGES_PER_MINUTE/DELIVERY_MESSAGES_PER_MINUTE throttles delivery rate. Explicit ESME_RTHROTTLED triggering — unverified.
  9. TLS: not mentioned anywhere in the surviving docs — treat as unsupported.
  10. Minimal run (build-yourself, since no pinned image exists):
    git clone https://github.com/kwahome/smpp-sim-docker
    cd smpp-sim-docker
    docker build -t local/smppsim:<your-tag> .
    docker run -p 2775:2775 -p 8884:8884 local/smppsim:<your-tag>
    
    Bind with system_id=smppclient1, password=password, port 2775.
  11. Quirks: primary vendor site down (522) at research time; ecosystem is a scatter of unofficial Docker forks with inconsistent port numbers (88 vs 8884) between older and newer docs — verify against whichever build you actually use.

2. Jasmin SMS Gateway

  1. jookies/jasmin, license per repo (ISC-style, see LICENSE), Python/Twisted. Repo actively committed (last push 2026-04-26) but last tagged release is 0.11.0, 2023-11-10 releases. Docs: docs.jasminsms.com.
  2. Docker: jookies/jasmin:0.11.0 (full patch tag exists and matches the GitHub release) dockerhub tags. Needs RabbitMQ + Redis as separate containers — not standalone.
    docker run -d -p 1401:1401 -p 2775:2775 -p 8990:8990 jookies/jasmin:0.11.0
    
    Ports: 2775 SMPP server, 1401 HTTP API/panel, 8990 jcli telnet console docker/README.md. No default smpp-server credentials are pre-provisioned — you create a system_id/password via jcli (smppccm/user -a commands) after startup.
  3. SMPP version: 3.4 SMPP Server API docs. interface_version enforcement at bind — not documented; unverified.
  4. Delivery receipts: yes. Jasmin's DLR pipeline (DLRLookup/DLRThrower) tracks the message in Redis and, when the original submission came in over smpps, pushes the receipt back as a deliver_sm/data_sm on the same bind messaging flows. Whether it's TLV (receipted_message_id/message_state) or text-body — not confirmed from docs; a dlr_msgid connector setting (0/1/2) exists specifically to reconcile hex-vs-decimal message-id mismatches between submit_sm_resp and deliver_sm — but that knob lives on outbound SMPP client connectors (Jasmin acting as ESME to an upstream real SMSC), not on the smpps server your library binds to Google Groups thread. When Jasmin itself is the SMSC (your library binds to its smpps), the message id it generates is its own internal UUID-based id Google Groups and should therefore be self-consistent between submit_sm_resp and the DLR — good for testing your library's "normalise across submit_sm_resp vs receipt" logic in the opposite direction (assert it does NOT need to normalise when ids already match).
  5. Long messages: two segmentation strategies documented for MT — SAR (sar_msg_ref_num/sar_total_segments/sar_segment_seqnum, "preferred by most SMSCs") and UDH (prepended header + UDHI_INDICATOR_SET in esm_class, "for older system compatibility") DeepWiki summary of Jasmin SMPP protocol support (secondary source — treat as indicative, not primary).
  6. Encodings: capacity figures imply packed GSM7 (160 chars / 153 segmented = the standard packed math), 8-bit binary 140/134 bytes, UCS-2 70/67 chars [same DeepWiki page]. Not a primary source — verify empirically before relying on it.
  7. MO injection: bind your library as receiver/transceiver on smpps; anything Jasmin routes to that connector arrives as deliver_sm. Separately, Jasmin's HTTP API/interceptor stack can push MO content to an HTTP webhook (deliverSmHttpThrower) instead — not needed for SMSC-side ESME testing, only relevant if you want Jasmin to also fan MO out to HTTP interception docs.
  8. Fault injection: submit_throughput exists as a per-connector throttling parameter but its exact unit/effect and how to disable it are not resolved even in the project's own issue tracker — issue #913 is open/stale with no documented answer. No documented way to force ESME_RTHROTTLED/ESME_RMSGQFUL, refuse binds, or drop the TCP connection on demand — unverified/likely absent.
  9. TLS: the [smpp-server] config section in the shipped jasmin.cfg has no TLS/SSL directives at all jasmin.cfg — the SMPP server role does not support TLS. (An outbound SMPP client connector does have useSSL/SSLCertificateFile options, irrelevant here.)
  10. Minimal config[smpp-server] section, defaults: port 2775, sessionInitTimerSecs=30, enquireLinkTimerSecs=30, inactivityTimerSecs=300, responseTimerSecs=60, pduReadTimerSecs=10, dlr_expiry=86400 jasmin.cfg. After boot, create a user via jcli:
    jcli -h 127.0.0.1 -p 8990   # telnet console
    > user -a
    > uid myesme
    > gid mygroup
    > username myesme
    > password mypassword
    > ok
    
  11. Quirks: no packaged Docker Compose bundling RabbitMQ+Redis is officially shipped — you must wire those yourself. No release/Docker tag newer than late 2023 despite ongoing source commits — verify current master behavior differs from 0.11.0 before trusting docs literally.

3. Kannel + opensmppbox (and why fakesmsc doesn't help)

  1. Kannel core: kannel.org, C, BSD-style license. Confirmed via the vendor's own homepage: last stable release 1.4.5, 2018-06-19; nothing newer since [kannel.org news list, fetched directly]. Effectively unmaintained upstream. opensmppbox (the actual SMPP-server add-on): canonical doc is the OpenSMPPBox User's Guide ("developed by Chimit Ltd, maintained by the Kannel Group"). The most complete GitHub mirror, pruiz/kannel-opensmppbox, has its last commit 2014-04-22 — 11+ years stale.
  2. Docker: no official image. Build from source against a Kannel bearerbox build; no maintained Dockerfile found. Default port 2345 (opensmppbox-port); credentials live in a flat file set via smpp-logins (username/password/system-type/IP-restriction per line).
  3. SMPP versions: "compliance to SMPP v3.3, SMPP v3.4 & SMPPv5.0" per the user guide. interface_version bind-time validation — not documented, unverified.
  4. Delivery receipts: opensmppbox stores/forwards DLRs from Kannel's bearerbox (multiple backends: internal, MySQL, PostgreSQL, Oracle, SQLite3, MS-SQL) and "rewrites [them] to appear that they originated from OpenSMPPBox" back to the bound ESME. TLV vs text, exact esm_class, intermediate/failure/delayed-DLR simulation — not documented in the guide; unverified.
  5. Long messages: supports message_payload TLV as an alternative to UDH concatenation when explicitly enabled; UDH re-splitting behavior on the MO side — unverified.
  6. Encodings: guide only states it can "define the data coding type of the short message" — packed vs unpacked GSM7 behavior unverified.
  7. MO injection: MO routing targets a specific bound ESME "based on shortcode, SMSC id, or randomly if unconfigured" — i.e. inbound traffic through Kannel's normal SMSC drivers gets forwarded to whichever ESME opensmppbox picks; no direct CLI/HTTP "inject one MO now" tool documented for opensmppbox itself (Kannel's own fakesmsc, see below, cannot fill this gap because it doesn't speak SMPP).
  8. Fault injection / TLS: not documented for opensmppbox in the guide; unverified — treat as unsupported until proven otherwise.
  9. fakesmsc clarification (important): Kannel ships a separate testing tool test/fakesmsc that connects to bearerbox's core smsc = fake group. Per Kannel's own 1.4.5 user guide (fetched directly from kannel.org): "Fake SMSC is a simple protocol to test out Kannel. It is not a real SMS center, and cannot be used to send or receive SMS messages from real phones. So, it is ONLY used for testing purposes." Its wire format is a trivial line-based text protocol (sender receiver type message...), confirmed from the fakesmsc.c usage text — it does not speak SMPP at all. It exists only to test Kannel's own HTTP sendsms interface end-to-end without a real carrier link. It is not usable to interoperability-test an external SMPP client library, despite superficially sounding like an SMSC simulator. Use opensmppbox for that instead.
  10. Minimal opensmppbox config (from the user guide):
    group = smpp-logins
    smpp-logins = /etc/opensmppbox/smpp-logins.txt
    opensmppbox-port = 2345
    
    and in smpp-logins.txt: myuser mypass VMA 0.0.0.0/0
  11. Quirks: Kannel's core smpp SMSC driver (Kannel acting as client connecting outbound to a real SMSC) is well documented and supports interface-version (hex string, default "34"), msg-id-type (bit-flags for hex/decimal submit_sm_resp vs deliver_sm), max-pending-submits (window, default 10), enquire-link-interval (default 30s), use-ssl/ssl-client-cert — but that's the wrong direction for this task (it's Kannel-as-ESME, not Kannel-as-SMSC). Given both Kannel and opensmppbox have had no significant commits in a decade, this path is the highest-effort, lowest-payoff of the "must include" list.

4. Melrose Labs SMSC Simulator

Two distinct things share the name:

  • Hosted public/commercial service at smscsim.melroselabs.com:2775 — closed-source, run by Melrose Labs.
  • Old open-source code at melroselabs/smpp-smsc-simulator, MIT license, C++11, single-file (smscsimulator.cpp) — repo explicitly says it "represents old version of existing SMSC Simulator service available online … newer version of code not published." Last push 2023-07-15.
  1. Homepages: melroselabs.com/services/smsc-simulator, technical details at smsc-simulator-technical-details, dedicated-instance doc at ssg docs / scrollhelp.
  2. Docker: OSS repo has a docker-compose.yml; no image tag confirmed (repo has only source + compose, no published registry tag found). Default port 2775 in both the OSS code and the hosted service.
  3. SMPP versions: "SMPP v3.3, v3.4 and v5" for the hosted service [technical details page]. submit_sm_resp message-id length differs by version: 8 characters for v3.3, 64 characters for v3.4 and v5 [same page] — hex/decimal notation not stated.
  4. Delivery receipts: hosted shared service — text short_message receipt plus TLVs receipted_message_id and message_state (value 2 = DELIVERED) [technical details page]; shared/free tier is "delivered" status only, <1s after submit_sm_resp. Dedicated instances are configurable via a dlr.conf: DELIVERED(2)/EXPIRED(3)/DELETED(4)/UNDELIVERABLE(5)/ACCEPTED(6)/UNKNOWN(7)/REJECTED(8) with percentages, plus --dlrlatency (default 3s) for delayed DLRs, and a per-ESME shouldReturnUndeliveredReceipts override dedicated simulator docs.
  5. Long messages: message_payload TLV (0x0424) supported on submit_sm/deliver_sm/data_sm [technical details page]. UDH / sar_* handling not documented — unverified.
  6. Encodings: not documented for either tier — unverified; test empirically.
  7. MO injection: on the shared simulator, MO is triggered by encoding the bound system_id's digits into the destination address (prepend/append ≥2 digits, min 8 chars total) [technical details page] — an unusual, non-obvious convention, worth automating carefully. Dedicated instances configure acceptable MSISDNs per-ESME via esme_<systemid>.config.
  8. Fault injection: dedicated instance's dlr.conf/shouldReturnUndeliveredReceipts cover DLR-level faults; explicit ESME_RTHROTTLED/ESME_RMSGQFUL/bind-refusal/connection-drop simulation not documented for either tier — unverified.
  9. TLS: shared service — "TLS 1.1 and up are supported for SMPP sessions. SSL and TLS 1.0 are not supported," on a separate port 8775 [main service page]. Dedicated instances also offer TLS as a paid option.
  10. Minimal use: bind to smscsim.melroselabs.com:2775 with credentials issued after signing up for a free developer account (python tutorial shows the PDU shape but not the signup flow itself).
  11. Quirks / limits: shared service capped at 100 SMS/sec; a separate, apparently-independent free public simulator is listed at smscsim.smpp.org:2775 (max 2 SMS/sec) via smpp.org's testing page — relationship to Melrose Labs unverified. Melrose Labs also offers standalone browser tools worth knowing about: an SMPP client (bind/submit without installing anything), SMPP Load Test, and an SMPP Analyser that captures a session to a downloadable pcap.

5. ukarim/smscsim — best lightweight OSS option

  1. github.com/ukarim/smscsim, Go, MIT, "Lightweight, zero-dependency and stupid SMSc simulator." GitHub push activity is current (last push 2025-12-12) — the most recently-touched OSS candidate found besides Jasmin/jsmpp.
  2. Docker: ukarim/smscsim on Docker Hub. Highest semver tag is 0.2.0 (pushed ~3 years ago per Docker Hub); newer builds exist only as commit-hash tags (e.g. a2c646d, ~2 years ago) with no semver — use ukarim/smscsim:0.2.0 for a reproducible pinned tag, or pin the specific commit-hash tag if you need the newer build and accept it's not semver.
    docker run -p 2775:2775 -p 12775:12775 ukarim/smscsim:0.2.0
    
    Ports: SMPP 2775 (env SMSC_PORT), web UI 12775 (env WEB_PORT). No auth/credentials required by default.
  3. SMPP version: implements "only a small subset of the SMPP3.4 specification." PDUs: bind_transmitter, bind_receiver, bind_transceiver, unbind, submit_sm, enquire_link, deliver_sm_resp. Explicitly: "simulator does not perform PDU validation" — so it will not reject a bad interface_version or malformed PDU; not useful for negative-path bind testing.
  4. Delivery receipts: fixed — DLR always returned ~2s after submit_sm with message_state always DELIVERED; no way to simulate other states except via the FAILED_SUBMITS fault-injection flag below. TLV vs text not detailed in the README.
  5. Long messages: not documented — given the minimal PDU set, treat UDH/sar_*/message_payload support as unverified/likely absent.
  6. Encodings: not documented — unverified.
  7. MO injection: web page at http://localhost:12775 sends a deliver_sm to the active session — simplest MO-injection UX of any candidate here.
  8. Fault injection: FAILED_SUBMITS=1 env var — even sequence numbers get a submit_sm system-error response, odd sequence numbers get an undeliverable DLR. No throttling, no bind refusal, no connection-drop simulation.
  9. TLS: not mentioned — unsupported.
  10. Minimal run: shown above; no config file, everything is env vars.
  11. Quirks: "does not perform PDU validation" is explicit in the README — good for happy-path/throughput testing, useless for asserting your library correctly handles a rejecting SMSC.

613. Other candidates (condensed)

Candidate Notes
mdouchement/smsc3 Go, MIT, SMPP3.4-based, port 20001 (SMPP)/6000 (HTTP). MO injection via POST /deliver with JSON {session, sender, recipient, message}. Has Dockerfile+compose but built around integrating with Kannel specifically. Last push 2024-05-09, low adoption (10 stars).
K2InformaticsGmbH/smsc_simulator Erlang, Apache-2.0, speaks both SMPP and UCP. Abandoned — last commit 2018-08-31. Configured/driven from the Erlang shell (smsc_simulator:start(smpp,10000)), no Docker. Skip unless you specifically need UCP too.
MavoCz/smscsim Java, built on cloudhopper-smpp, so inherits 3.3/3.4/5.0 support and real PDU validation. Multi-port CLI (-p 34567 34568 34569), sends DLRs after a configurable fixed/random delay round-robin to connected RX/TRX binds. No Docker; requires Maven build + editing Spring XML for anything beyond port/log-level. Last-commit date unverified.
fizzed/cloudhopper-smpp (successor to twitter-archive/cloudhopper-smpp, which is archived) Java library, Apache-2.0, not a packaged simulator — but ships runnable demo classes (make server, make server-echo, make simulator, make ssl-server) covering SSL and PDU-dump. Good as a base to write a custom fixture, not a drop-in server. Last push 2020-10-12.
jsmpp jsmpp-examples/.../SMPPServerSimulator.java Java, Apache-2.0. jsmpp itself is very actively maintained (last push 2026-06-17) — best-maintained library in this whole survey. The bundled SMPPServerSimulator example demonstrates DLR sending and SSL, but is example code, not a packaged/dockerized tool — expect to fork and extend it.
farhadi/node-smpp Node.js, MIT, implements SMPP v5 (backward compatible with 3.4), includes both client and server APIs, supports ssmpp:// TLS, UDH via message_payload, and encoding auto-detection (ASCII/Latin1/UCS2). No packaged simulator binary — you write ~30 lines of server code yourself. Last push 2023-12-28. Small existing forks built on it: tiltroom/fakesmpp, theodorosidmar/smpp-server-simulator (returns error on 1-in-10 submit_sm) — neither independently verified for maintenance/quality here.
MikeSafonov/smpp-server-mock Java, MIT, JUnit5-extension/Spring-Boot-starter mock server for your own test suite (assert on captured SubmitSms) — not a standalone server you point an arbitrary client at. Only useful if you also write JVM-side interop tests. Last push 2023-03-10.
Restcomm/TeleStax SMSC Gateway "SMPP Simulator" Bundled GUI test tool inside the RestComm SMSC Gateway product ($SMSC_HOME/tools/TelScale-smpp-simulator/bin/run.sh), default system_id=test/password=test, port 2776, transceiver bind, address range 6666 docs. This is really a load-test client for RestComm's own gateway, not an installable-alone SMSC simulator — and the whole product requires a JSLEE stack. High setup cost for low unique coverage; skip unless you're specifically validating against a carrier-grade SS7-adjacent stack.
OsmoMSC SMPP interface C, part of Osmocom's core-network stack (actively maintained as infrastructure, not as a "test double"). Its SMPP interface lets an ESME bind to a real (if simulated-radio) mobile-network MSC to send/receive SMS to subscribers — valuable only if you're also running an Osmocom test network; far too heavy just to test an SMPP library. Treat as out of scope for this project.
smscsim.smpp.org Free public SMSC simulator, host/port from smpp.org's testing page: smscsim.smpp.org:2775, capped at 2 SMS/sec, delivered-only DLRs, per-IP connection limits. Ownership/maintenance unverified — treat as a convenience fallback, not a primary target.
Ozeki NG SMS Gateway / NowSMS Both have a free/trial tier with SMPP server capability, both are closed-source and Windows-first (Ozeki explicitly; NowSMS also ships Linux/Docker in some tiers but is paid-oriented) — out of scope per task instructions beyond this line.

Recommendation — set these up first

  1. ukarim/smscsim (Docker ukarim/smscsim:0.2.0) — near-zero setup cost, fastest possible CI smoke test: bind, submit, get a DLR, inject an MO from the web UI. Its explicit "no PDU validation" and single fixed DLR state are limitations, not blockers, for a first pass.
  2. Jasmin SMS Gateway (Docker jookies/jasmin:0.11.0 + RabbitMQ + Redis) — the only candidate here that is a real, still-developed production SMS gateway with a proper SMPP server role, HTTP management, and a DLR pipeline distinct from a toy simulator. Exercises your library against genuinely different internals (Python/Twisted, AMQP-backed message routing) than the Go/Java toys.
  3. Melrose Labs hosted SMSC Simulator (smscsim.melroselabs.com:2775, free tier) — a public, independently-run, closed-box target you don't control, which is exactly the point: it validates your library against an implementation you cannot special-case for. Its TLS port (8775) also covers your TLS interop case for free without standing up your own CA. Follow up with a dedicated instance (paid) once you need to script specific DLR failure/latency states via dlr.conf.
  4. SMPPSim, built yourself from kwahome/smpp-sim-docker — despite the dead upstream site and lack of a pinned tag, it's the only candidate with rich, config-file-driven fault injection (percentage-based delivered/undeliverable/rejected/accepted, intermediate-state transition chance, delayed DLRs, outbind support, MO queue-full retry behavior). Worth the one-time cost of building and tagging your own image specifically to cover the failure- and delay-injection matrix nothing else here offers as cleanly.

Skip Kannel/opensmppbox and fakesmsc for now: both Kannel and opensmppbox have had no meaningful commits in a decade, opensmppbox's interop behavior (TLS, throttling, interface_version validation) is entirely undocumented, and fakesmsc — despite the name — doesn't speak SMPP at all, so it cannot test this library regardless of effort spent.