µBSS¶
A convergent Business Support System and Online Charging System for telecommunications operators. The platform handles real-time prepaid charging over DIAMETER (RFC 4006), offline postpaid billing from CDR files, monthly bill-cycle batch processing, PDF invoice rendering, and a gRPC management surface consumed by the crm2.micro.bss PHP frontend. It is implemented in C++20 on the ACE Reactor framework, with MySQL X DevAPI as the persistence layer.
High-Level Architecture¶
graph LR
subgraph Network["Telco network"]
NE["GGSN / PGW / MSC<br/>(DIAMETER peer)"]
Mediation["Mediation system<br/>(CDR files)"]
end
subgraph CRM["crm2.micro.bss (PHP)"]
UI["Web dashboard"]
end
subgraph Server["server.micro.bss (C++ / ACE)"]
Prepaid["Prepaid<br/>(DIAMETER server)"]
CDRLoader["CDR Loader<br/>(timer)"]
Billing["Billing<br/>(per bill-cycle)"]
BillFmt["Bill Formatter<br/>(PDF)"]
Stats["Stats handler<br/>(timer)"]
CRMSrv["CRM gRPC server<br/>(JWT + TLS)"]
Refdata["Refdata<br/>(in-memory cache)"]
Lic["License validator<br/>(Ed25519)"]
end
DB[("MySQL 8<br/>X DevAPI")]
PDF[("./invoices/<y>/<m>/<br/>bc_<n>/*.pdf")]
LicFile[("license/platform.lic")]
NE -- "DIAMETER CCR/CCA<br/>(TCP, RFC 4006)" --> Prepaid
Mediation -- "*.cdr files" --> CDRLoader
UI -- "gRPC + JWT (TLS)" --> CRMSrv
Prepaid --> DB
CDRLoader --> DB
Billing --> DB
BillFmt --> DB
BillFmt --> PDF
Stats --> DB
CRMSrv --> DB
CRMSrv -. "queues activities" .-> Billing
Refdata --> DB
Lic -- "verifies" --> LicFile
Prepaid -.-> Refdata
CDRLoader -.-> Refdata
Billing -.-> Refdata
CRMSrv -.-> Refdata
Subsystems¶
Convergent rating engine¶
A single Rater class rates both prepaid Charge / Balance_reserve events and postpaid CDR records against the same REF_Price_plan reference data, applying free-units allowance per service per month. Both paths converge on identical price-plan tables and identical service codes, yielding consistent unit pricing across the prepaid and postpaid customer lifecycle. See Convergent Rating.
Prepaid charging¶
A DIAMETER Credit-Control Application server implementing RFC 6733 (base) and RFC 4006 (Gy). The Acceptor listens on a configured TCP port; each accepted connection runs in a detached ACE_Svc_Handler thread that decodes CCR messages, performs BalanceReserve for INITIAL_REQUEST / UPDATE_REQUEST and Charge for TERMINATION_REQUEST / EVENT_REQUEST, and replies with a CCA carrying granted units and a validity time. See Prepaid Charging.
Postpaid billing¶
BillingHandler is a timer-driven ACE_Event_Handler that polls an activities queue table for work items and dispatches each through a thread pool. It supports on-demand single-subscriber billing (SINGLE_BILLING), full bill-cycle runs (FULL_BILLRUN), and a developer-only mass prepaid rating mode. The platform is launched with one process per bill-cycle, each instance filtering activities by its configured billing.billcycle. See Postpaid Billing.
CDR loader¶
CDRLoader polls a configured directory for protobuf-serialized CDR files, validates each record, rates it via Rater, persists it through DB_layer::insert(), and moves the source file to either processed/ (with .done suffix) or error/ (with .error suffix). Files are processed in a single background thread guarded by an atomic flag, preventing overlapping cycles. See Postpaid Billing.
Bill formatter¶
BillFormatterHandler polls for bills with BILL_STATUS_NEW, locks each one, renders the appropriate Inja template (prepaid.html or postpaid.html) with bill data and call/balance history, and produces a PDF via plutobook. The output is written to invoices/<year>/<month>/bc_<billcycle>/<billing_id>.pdf and the bill row is transitioned to BILL_STATUS_PAID (prepaid) or BILL_STATUS_UNPAID (postpaid). See Invoicing.
CRM gRPC service¶
CRMServer builds a grpc::Server and registers CRMServiceImpl, exposing the full management surface — subscribers (including lifecycle Suspend / Reactivate / Terminate), usage, bills (including the ReformatBill re-issue path), vouchers, notifications, statistics, reference data, and on-demand billing. Every call is gated by an AuthInterceptor that validates HS256 JWTs against the configured issuer and audience. Transport is TLS by default. See CRM.
Licensing¶
LicenseValidator enforces an offline Ed25519-signed license file before any module starts. Validation binds the license to /etc/machine-id, checks the expiry timestamp, and detects clock rollback via an HMAC-protected Last-Known-Good-Time (LKGT) state file. The 32-bit feature mask gates per-module runtime enablement (PREPAID, CDR_LOADER, STATS, BILLING, BILL_FMT, CRM, DIAMETER). See Licensing.
Technology Stack¶
| Layer | Component |
|---|---|
| Language | C++20 (clang or gcc) |
| Build | CMake (>= 3.10), Make, custom shell wrappers |
| Foundation framework | ACE (DOC Group) — Reactor, Acceptor, Svc_Handler, Singleton, Signal, Time_Value |
| RPC | gRPC C++ + Protocol Buffers (proto3) |
| Real-time charging | DIAMETER over TCP — RFC 6733 base, RFC 4006 Credit-Control |
| Persistence | MySQL 8 via the official mysqlcppconnx X DevAPI connector |
| Configuration | TOML via tomlplusplus |
| Templating | Inja (Jinja2-style) for HTML bill templates |
| PDF rendering | plutobook |
| Cryptography | OpenSSL — Ed25519 license signatures, HMAC-SHA256 LKGT, HS256 JWT |
| Logging | ACE ACE_LOG_MSG with optional JSON callback (JsonLogCallback) |
| Frontend | crm2.micro.bss — PHP, gRPC client (separate repository) |