Skip to content

About

GSM Layer 3 Signalling Library - Parse, Build, and Frame L3 Messages for Software BTS. Fast, memory-efficient, and optimized for telecom systems.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

libgsml3parser

GSM Layer 3 Protocol Stack — Parse, Build, and Run a Software BTS in C++20

License: MIT C++20 Build Version

A type-safe, zero-allocation C++20 library with no external dependencies, spanning the full GSM signalling chain of a software Base Transceiver Station: 216 L3 message classes across 13 PD domains — typed fields for RR/SM/CC/GMM/MM/SS and the SMS CP/RP/TP layers; the BCC/GCC/LS blocks have no normative reference templates, so they are parsed best-effort as opaque bodies and bit-level conformance is not claimed for them — plus passthrough for the PDSS1/PDSS2 and Test-Procedure PDs, the complete LAPDm (L2) entity and A-bis RSL interface, per-subscriber state (context, FSMs, timers, transactions) and ten spec-based protocol procedures — from raw radio bytes up to working MO/MT call flows.

Why This Library?

Building a software BTS means implementing the entire Layer-3 signalling stack: parsing hundreds of binary messages, driving protocol state machines, tracking timers, correlating request-response transactions, and generating correct responses at real-time speed. The existing solutions each leave a gap:

  • Hand-written C BTS stacks — hand-coded parsers per message type, no builder API, implicit FSMs scattered across handler code;
  • Ad-hoc C++ stacks — custom structs with manual byte construction and limited coverage;
  • TTCN-3 conformance suites — excellent for validation, unusable as a production protocol stack.

libgsml3parser closes the gap: one type-safe C++20 package that provides everything from raw parse/serialize to per-subscriber procedure state machines — ready to connect to any SDR backend or a BSC over A-bis RSL, with zero third-party dependencies to carry.

What You Save

Without libgsml3parser With libgsml3parser
Hand-roll binary parsers for 200+ message types parseL3Hex("060D41") — one call, typed result
Manual byte construction for responses Fluent builder: .addTMSI(0x12345678, SDCCHType).build()
Scatter/gather FSM logic across handlers Pre-built ProcedureOrchestrator auto-chains Location Update, Auth, Call Setup
Track timers with raw std::map + cron jobs TimerManager — fixed 32-slot arrays, zero allocation; built-in default durations for the 19 named GSM/GPRS timers (T3101, T3102, T3103, T3106, T3108, T3109, T3111, T3112, T3113, T3310, T3311, T3312, T3314, T3315, T3320, T3321, T3322, T3334, T3395); other timer IDs accept a custom duration
Correlate request/response with custom TI tables TransactionManager — O(1) TI lookup, 0.004 µs per match
Debug hex dumps by eye std::format specializations for protocol enums, Expected<T> with bit-position errors

Who Is This For?

Audience What You Get
Software BTS developers Drop-in L3 layer for a software BTS: parse, build, FSMs, timers, procedures, LAPDm — link gsml3parser and go
Protocol testers & fuzzers Bidirectional binary↔typed API, golden vectors pinned to the normative TS wire layouts, libFuzzer targets for every major entry point
SDR / radio hobbyists Complete L2 (LAPDm) + L3 stack for the Um interface plus A-bis RSL — no networking or SIP dependencies

What You Get

Four layers, from raw bits to protocol state:

  1. L3 Parser & Serializer — hex/bytes ↔ typed std::variant objects; compile-time tryGet<T>(); a fluent builder() for every message type; zero heap on the hot path (sizeof(ParsedMessage) = 400 B).
  2. LAPDm Protocol Entity — GSM 04.06 / TS 44.064 state machine (SABME/UA/DISC), I-frame segmentation with k=1 and T200 retransmission, contention resolution, 4 KB-bounded reassembly.
  3. BTS Stack Modules — MSContext, TimerManager (fixed 32-slot arrays, zero allocation; built-in default durations for the 19 named GSM/GPRS timers (T3101, T3102, T3103, T3106, T3108, T3109, T3111, T3112, T3113, T3310, T3311, T3312, T3314, T3315, T3320, T3321, T3322, T3334, T3395); other timer IDs accept a custom duration; O(active) tick), TransactionManager (O(1) TI index), RR/MM/CC state machines, ChannelPool / ShardedChannelPool, SubscriberRegistry — sizeof(SubscriberSession) = 2056 B (10K sessions ≈ 20 MB).
  4. Procedure Framework — ProcedureRunner + ProcedureOrchestrator auto-chain ten spec-based procedures (Location Update, Authentication, Call Setup MO/MT, Channel Assignment, Ciphering, Paging, Handover, Release, IMSI Detach) through a zero-heap ResponseToken → ResponseBuilder pattern; plus A-bis RSL parsing and 14 frame builders for BSC integration.
auto msg = gsml3parser::parseL3Hex("060D41");            // RR Channel Release
if (msg) std::cout << gsml3parser::messageName(*msg);    // "ChannelRelease"

auto paging = L3PagingRequestType2::builder()
    .addTMSI(0x12345678, ChannelType::SDCCHType).build();// fluent construction

Supported Messages Summary

All 13 protocol domains — RR 98 · SM 24 · CC 21 · GMM 23 · MM 21 · SMS 5 · BCC 8 · GCC 8 · SS 3 · LS 2 · PDSS1 + PDSS2 (Extended) + Test PDs 3: 216 message types in total, with Information Elements and enums defined per domain.

Full catalog (MTIs, directions, IEs, dispatch edge cases such as TIF=1 short messages and build-only types): doc/messages.md.

Wire Format Conformance

All parse/build paths for RR/SM/CC/GMM/MM/SS and the SMS CP/RP/TP layers follow the normative 3GPP TS wire layouts; golden vectors are pinned in the test suite. The BCC/GCC/LS blocks have no normative reference templates, so they are parsed best-effort as opaque bodies and bit-level conformance is not claimed for them. Highlights of the non-obvious encodings:

Identities (TS 24.008) — LAI/RAI pack the PLMN as [MCC2|MCC1][MNC3/F|MCC3][MNC2|MNC1] BCD octets plus a 16-bit LAC (plus one RAC octet for RAI); mcc()/mnc() return the digits in natural order. The mobile identity value starts with [first digit(4)|odd-count(1)|type(3)] and encodes digit pairs as [next digit or F fill|current digit]; a TMSI starts with the spare 'F' nibble, a zero bit and type '100'B (first octet 0xF4).

MM (TS 24.008) — in a sequence of half-octet information elements the first element occupies the low half-octet (bits 1-4). CM Service Request body starts with one octet: CM service type (four bits) in the low half-octet and CKSN(3)|reserved(1) in the high; Location Updating Request starts with [spare(1)|CKSN(3)] + [FOR(1)|spare(1)|LUtype(2)]; Authentication Request and CM Re-establishment Request carry the CKSN (three bits plus one spare) in the low half-octet with the high half-octet spare. Authentication Failure (0x1C) is a bare reject-cause octet plus, for the "Synch failure" cause, the optional AUTS TLV 0x22; CM Service Prompt (0x25) is one spare(2)|SAPI(2)|PD(4) octet — both present per TS 24.008 Table 10.2. TMSI Reallocation Command body is exactly the LAI (five octets, not length-prefixed) followed by the new mobile identity in LV form (TS 24.008 section 9.2.17). Optional IEs after the mandatory part are preserved opaquely and re-emitted verbatim.

GMM / SM (TS 44.068) — Attach/RAU Request pack the type (three bits plus the forL3 indicator) in the low half-octet and the GPRS CKSN (three bits plus one reserved) in the high half-octet; the DRX parameter is two value octets without an identifier and the MS radio access capability is a mandatory LV. Reject/failure/status messages start with a single bare cause value octet; RAU Reject appends one force-to-standby octet after the cause, and Detach Accept is that one octet alone (the low bit is force-to-standby). Attach Accept leads with [forceToStandby(4)][attachResult(4)] (result: 1 = GPRS attach, 3 = combined IMSI+GPRS), then the periodic RA update timer octet [units(3)][value(5)] and the radio-priority octet [radioPrioritySMS(4)][radioPriorityTOM8(4)], then the RAI (six raw PLMN/LAC/RAC octets) and, when a new P-TMSI is allocated, the P-TMSI signature (TV 0x19, three octets) and the allocated P-TMSI (TLV 0x18, MI form 0xF4 + TMSI); remaining IEs are preserved opaquely. RAU Accept leads with [spare(4)][updateResult(3)][forceToStandby(1)], then the same timer octet and the RAI in octets 2–7, then the optional P-TMSI signature / allocated P-TMSI / MS identity / ready-timer IEs and, when included by the network, the PDP context status (TLV 0x32, two-octet value). P-TMSI Reallocation Command is positional: allocated P-TMSI LV (length 5, MI form), RAI, one force-to-standby octet, optional P-TMSI signature. Service Request starts with one octet — GPRS CKSN(3) in the low bits, service type(3) in the high half-octet — followed by the P-TMSI LV; further IEs (a conforming MS appends the PDP context status TLV 0x32) are preserved opaquely. GMM Identity Request is a single [spare(3)|forceToStandby(1)|type(3)] octet. SM ACTIVATE PDP CONTEXT REQUEST carries the NSAPI and the negotiated LLC SAPI as two octets with the value in the low four bits and the high nibble zero, the requested QoS profile (three mandatory octets — delay/reliability class, peak/precedence, mean throughput — plus any optional characteristics, preserved opaquely) and the requested PDP address as positional LVs, the APN as TLV 0x28 when present, PCO as TLV 0x27 and an optional request type 0xAx; DEACTIVATE PDP CONTEXT REQUEST starts with the SM cause octet followed by an optional tear-down indicator octet (0x90, flag in bit 0). The PDP type-and-address value is [type organization(4) = 0x01 IETF | spare(4)][type number(8)] plus, for a static address only, the address octets — type numbers 0x21 (IPv4) and 0x53 (IPv6), four / sixteen address octets; a dynamic address carries no address octets, so the LV length is 2 (dynamic), 6 (static IPv4) or 18 (static IPv6). SM MTI 0x50-0x54 are reserved and not assigned to message classes (Table 10.4a).

CC / SMS — CC message types per TS 24.008 Table 10.3 (no unit-data messages); the Cause IE (IEI 0x08, length 2) value is [0x60|location][0x80|cause] (TS 24.008 section 10.5.1.2), CC PROGRESS carries the progress indicator as an LV ([0x02][0xE0|location][0x80|progress]), structured 0xDx IEs are single-octet and Facility is LV. The SMS PD carries CP-DATA/CP-ACK/CP-ERROR plus CP-STATUS/CP-SUBMIT (TS 24.011); the RP header octet is [reserved(5)=0][RP-MTI(3)] and the MTI is direction dependent (TS 24.079 section 7.2.1, Table 8.3): uplink Data/Ack/Error/SMMA = 0/2/4/6, downlink = the uplink value plus one; the TP-DU header octet is [TP-MTI(2)|MMS/RD(1)|VPF(2)|SRI/SRR(1)|UDHI(1)|RP(1)] (bit positions in the octet value; TP-MTI 2 = status report network→mobile / command mobile→network), addresses carry the digit count as length followed by TON/NPI and BCD digits, and the user-data length counts septets for GSM 7-bit text (TS 23.040 section 9).

SS (TS 24.078) — the SS-Data body is a TCAP-style component container [component tag(1)][component length(1)][component] with tags Invoke=0xA1, ReturnResult=0xA2, ReturnError=0xA3 and Reject=0xA4; an invoke component is [02 01 invokeId][02 01 operationCode] [30 len {parameters}], and every component form re-emits losslessly.

RR (TS 44.018) — Ciphering Mode Command is exactly one body octet with sC in the low bit: [sC(1)|algorithm(3)][cR(1)|spare(3)] (section 9.2.24); Power Command is one octet [reserved(3)=0][msPowerLevel(5)] (section 10.5.2.6) and Power Command And Access Type adds the aTC, ePC_Mode and fPC_EP bits above the power level (section 10.5.2.7); SI1 carries the cell channel description in the sixteen-octet variable-length BCCH frequency list form — seven-bit header, ten-bit base ARFCN and a 111-bit presence map (section 10.5.2.1b) — plus RACH control parameters (three octets) and at most one rest octet (body 19–20 octets); SI2/SI2bis/SI2ter and the SI5/SI5bis/SI5ter frequency lists use the same sixteen-octet bitmap form (any seven-bit header is accepted on parse, raw sixteen octets kept for lossless re-emit); the access-class bitmap is a 16-bit value written low byte first (AC i ↔ bit i); a set bit bars the class (emergency = class 10); Paging Request Type 1/2/3 start with the octet [channelNeeded(4)][pageMode(4)] (channel needed packed as second|first two-bit fields) followed by the identities — two raw TMSIs plus an optional third identity (TLV 0x17) for Type 2, four raw TMSIs for Type 3 — and Paging Response starts with [spare(4)][CKSN(4)]; the Immediate Assignment start time (IEI 0x7C) is two value octets packing T1(5)/T3(6)/T2(5); channel numbers use the five-bit type-and-offset codes ('00001'B Bm ACCH … '10000'B BCCH, '10001'B RACH, '10010'B PCH+AGCH, PDCH/CBCH/VAMOS extensions) with channelCodeLm/Sdcch4/Sdcch8 helpers. SI3/SI4 rest octets carry the selection parameters, power offset, scheduling-if/where, GPRS indicator, UMTS early-CM and SI2quater indicators; a rest region made purely of the 0x2B padding pattern means no rest octets are present, and sub-octet alignment is padded with that pattern on emit (sections 10.5.2.35/10.5.2.37); SI4 optionally carries the CBCH mobile allocation (TLV 0x72) after the CBCH channel description (TV 0x64); SI4 rest octets are optional (zero or more on emit), SI2bis/SI2ter accept at most one / four rest octets respectively, and SI13 rest octets carry the typed GPRS cell options, mobile allocation and power-control parameters, padded to the octet boundary.

LAPDm (GSM 04.06 / TS 51.010-1) — a SABME command with the P/F bit cleared is ignored; an initial SABME command is accepted on any SAPI: with a payload it is answered by a UA echoing that payload, and the link enters the contention-resolution state on SAPI 0 but is established directly on every other SAPI; without a payload the link is established with a plain UA. Every UA and DM we send mirrors the P/F of the received command, and a UA or DM response with F cleared is ignored; a DM while awaiting establishment restarts T200 without releasing the link; the retransmission budget allows N200+1 frames before abnormal release; a T200-expired I-frame is retransmitted with P/F set and the current V(R) in N(R).

A-bis RSL (TS 48.058) — the Channel Mode IE (0x06) value is exactly four octets: [reserved(6)|DTX_d(1)|DTX_u(1)], speed indicator (Speech=0x01, Data=0x02, Signalling=0x03), channel rate type (Sdcch=0x01, TchF=0x08, TchH=0x09, …, VAMOS extensions 0x88/0x89) and a union octet (speech algorithm / opaque data rate / 0x00 for signalling). Error causes use the canonical section 9.3.26 values (RadioLinkFail=0x01, ResUnavail=0x2F, Proto=0x6F, Interworking=0x7F, …) and reserved gaps are rejected on emit. The Uplink Measurements IE (0x19) is three value octets — [RFU|DTX_d|rxlev_full(6)], [res(2)|rxlev_sub(6)], [res(2)|rxq_full(3)|rxq_sub(3)] — with any vendor supplementary bytes preserved verbatim. The Frame Number IE (0x08) packs t1p(5), t3(6) and t2(5) derived from an absolute TDMA frame number (t1p=(fn/1326)%32, t3=fn%51, t2=fn%26). The RACH Load IE (0x12) is LV-encoded with an explicit length octet (0x06) and three big-endian u16 counters (total/busy/access); CCCH LOAD INDICATION comes in two channel-number variants — PCH+AGCH tn 0 (0x90) with the Paging Load IE (TV, two-octet value) and RACH tn 0 (0x88) with the RACH Load IE (LV) — and RF RESOURCE INDICATION / SACCH FILLING / OVERLOAD INDICATION / ERROR REPORT belong to the TRX MANAGEMENT group (discriminator 0x08) while LOCATION INFORMATION belongs to the LCS group (0x10). The IE catalog covers the full section 9 set (0x01–0x3C; 0x1D is not allocated) plus vendor extensions 0x60–0x63 (Osmo) and the ip.access group 0xE0–0xFE, in which the IEs with a defined value size — Remote/Local IP (four octets), Remote/Local port and Connection ID (two octets), RTP payload type(s), speech mode and RTP CSD format (one octet) — are TV-encoded, connection statistics is LV-encoded (length octet 0x1C, seven big-endian u32 counters) and the remaining codes have no defined size and decode as LV; TL16V for L3Info (0x0B) only, and LV for everything else — including Full BCCH Info (0x27). The channel number codes include the VAMOS Lm sub-slot extensions (30/31); MEASUREMENT RESULT carries the always-present BS_POWER TV IE between Uplink Measurements and L1 Information.

Quick Start

cmake -S . -B build -DBUILD_TESTS=ON -DBUILD_EXAMPLES=ON
cmake --build build --config Release --parallel
ctest --test-dir build --output-on-failure     # 2100+ tests

Requirements: C++20 (MSVC 2022 17.x, GCC 13+, or Clang with a std::format-capable stdlib) and CMake 3.20. All build options (BUILD_SHARED_LIBS, ENABLE_FUZZING, ENABLE_ASAN, …), the find_package() consumer pattern, the error-handling model, and the full API tour: doc/API.md.

Performance

Numbers that matter for a real-time radio stack (Release, single core):

Metric Result
L3 parse throughput (per message type) 7.7 – 26.5 M msg/s
Mixed-domain stream (all 13 PDs) / zero-copy 10.8 / 9.7 M msg/s
Full BTS stack dispatch (1K MS: timers, FSMs, correlation) ~66 – 86 M msg/s
TimerManager tick / Transaction match 42.6 M ticks/s / 0.004 µs per match
1M and 2M sessions (create / TMSI lookup / tick 10K active) 1195 / 127 / 1.4 ms and 1096 / 258 / 1.4 ms
example_rt_scale: 1M sessions, real-time event loop 6.2 M msg/s aggregate, 0 overruns / 1000 ticks, 2.0 GB peak

Every benchmark and stress test prints the dynamically detected hardware ID (CPU, caches, RAM, OS), so results are attributed to the machine that produced them; a full annotated run: benchmark_results.txt. Verify on your own machine with example_benchmark, example_benchmark_stack and example_rt_scale. Optimization techniques behind the numbers: doc/bts_architecture.md §6, doc/API.md §62.

How It Compares

Aspect Hand-written C stack Ad-hoc C++ stack libgsml3parser
Language C C++ (manual memory) C++20
Type safety enum + manual cast custom structs std::variant + tryGet<T>() — compile-time, no RTTI
Message types hand-coded per message partial coverage 216 typed messages, all 13 PD domains
Builder API none (manual struct) partial fluent builder for every type
FSM + timers + correlation implicit in handlers custom built-in stack modules + procedure framework
LAPDm / A-bis RSL separate library custom full LAPDm entity + RSL parse/build included
Dependencies external core library multiple zero (C++20 stdlib only)

Documentation — Start Here

Every detail lives in a dedicated guide; this README is the pitch and the index.

Document What It Covers
doc/API.md Full API reference (63 numbered sections): core types, bit I/O, streaming, parser/serializer, builders and IEs/enums of all 13 domains, LAPDm, dispatcher, arena, every stack module, RSL, all procedures, C ABI, FFI bindings + spec conformance notes
doc/bts_integration.md Primary guide for BTS developers: step-by-step event loop with ProcedureOrchestrator, full worked procedure chains (Location Update, Call Setup MO, Paging), AuC/VLR/BSC typed-data integration, LAPDm link management, L3 timer reference table, SI broadcast, production error handling
doc/bts_architecture.md Two usage modes (L3 Parser vs BTS Stack), component & data-flow diagrams, PHY/SDR integration points, thread-safety matrix, per-MS memory footprint, allocation-free hot paths, scaling guidelines to millions of sessions
doc/messages.md Complete message catalog: all 216 types with MTIs and directions, CC/GMM/SM IEs, SMS CP/RP/TP layers, dispatch edge cases (TIF=1 short messages, build-only types)
doc/boundaries.md What the library intentionally excludes — PHY/SDR, speech codecs, A5 ciphering, OML, SIP/media gateways, PS full stack, configuration, logging — and the exact integration point for each
examples/ 20 runnable demos (see below), incl. full BTS flows, benchmarks, and a 1M-session real-time loop
bindings/README.md FFI bindings (Python / Go / Rust) over the stable C ABI: unified quickstarts, ownership & threading model, callback safety rules, extension guide, test gate
bindings/python/README.md, bindings/go/README.md, bindings/rust/README.md Per-language binding guides with identical structure: layout, building & linking, quickstart, error model, ownership & callbacks, versioning

Examples

Example Description
example_parse_file Parse L3 from hex strings/files, typed access via tryGet<>, round-trip serialization
example_streaming L3Framer + stream processing over SpanByteSource and a RingBuffer producer/consumer
example_multithread Concurrent parsing across all 13 PD domains with immutable configs (no mutex)
example_zero_copy InlineFramer + ZeroCopyStreamProcessor on a contiguous buffer (DMA/PCAP-style)
example_benchmark / example_benchmark_stack Component benchmarks with hardware-ID reporting
example_lapdm_entity Full LAPDm lifecycle: SABME/UA, UI + segmented I-frame data, T200 retransmission, DISC
example_bts_paging Paging cycle: Builder → L3 bytes → LAPDm UI frame → unwrap → parse → verify
example_bts_channel_assignment Channel Request on RACH → ImmediateAssignment response, full round-trip
example_bts_rach_assignment RACH → channel allocation → assignment → MS response using stack modules
example_bts_sysinfo System Information (SI1–SI4) construction for BCCH broadcast
example_bts_dispatcher ProtocolDispatcher routing: specific, domain fallback, TI-based handlers
example_bts_location_update Location updating flow: CM Service Request, identity verification, TMSI reallocation
example_bts_paging_call Paging → channel assignment → MM auth → CC call setup
example_subscriber_registry Registry workflow: create/assign/tick/remove subscriber sessions
example_rt_scale 1M sessions, 10 ms event-loop ticks, real-time overrun verification
example_procedure_location_update Full Location Update procedure via ProcedureRunner
example_procedure_call_setup Mobile-Originated Call Setup via ProcedureRunner
example_rsl_pipeline A-bis RSL in → L3 out (incl. TL16V L3Info wrapping) and RSL response out
example_reference_bts Location Update + MO Call Setup chains through ProcedureOrchestrator with ShardedSubscriberRegistry

FFI and Bindings

The full stack is also reachable through a stable C89 C ABI (include/gsml3parser/gsml3parser_c.h, contract in doc/API.md §63). Three first-party bindings share one set of semantics — RAII ownership, the borrowed-session rule, queue-model callbacks — and carry no third-party runtime dependencies:

Language Mechanism Coverage Runnable demo
Python ctypes, stdlib only entire C ABI: 238 functions, completeness pinned by test bts_simulation.py
Go cgo + cgo.Handle callback bridges (needs a C toolchain) v1 surface: 135 functions incl. typed L3 builders cmd/gsmexample
Rust handwritten sys crate + safe wrapper — Send, no bindgen/codegen same 135-function v1 surface; extern block checked at compile time bts_simulation.rs

All three run the same "MO call over SDCCH" scenario against the shared C core, and one unified gate (scripts/verify_bindings.ps1, CI on Linux + Windows) builds and tests them together. Per-language guides (quickstart, building & linking, error model, ownership & callbacks): bindings/README.md plus the README.md in each binding directory.

Testing & Fuzzing

Quality you can verify, not just trust:

  • GoogleTest suite: 2100+ tests — parse/golden-vector (normative TS wire layouts), round-trip, builders, LAPDm FSM, dispatcher, all procedures and orchestrator chains, RSL, C ABI + strict-C89 header check, high-load stress (1M/2M sessions) and concurrency tests.
  • ENABLE_FUZZING=ON (Clang/LLVM) builds eight libFuzzer targets (L3 parse, RSL parse, LAPDm frame decode, LAPDm entity, L3Framer, orchestrator, subscriber registry, C API) with ASan/UBSan; CI adds a ThreadSanitizer pass on Linux and attaches a prebuilt static+shared package to each GitHub Release.

Thread Safety

Parse/build/RSL entry points are stateless; per-session stack modules are single-thread by design (the one-instance-per-MS event-loop model keeps the hot path lock-free); ShardedSubscriberRegistry and ShardedChannelPool provide the thread-safe variants. Complete matrix: doc/bts_architecture.md §5.

License

MIT License. See COPYING for details. Golden test vectors are pinned to the normative 3GPP TS wire layouts (TS 24.008, TS 44.018, TS 44.064, TS 48.058 and friends). Copyright 2026 momentics <momentics@gmail.com> and libgsml3parser contributors.

About

GSM Layer 3 Signalling Library - Parse, Build, and Frame L3 Messages for Software BTS. Fast, memory-efficient, and optimized for telecom systems.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages