Skip to content

µ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/&lt;y&gt;/&lt;m&gt;/<br/>bc_&lt;n&gt;/*.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)