diagmunge
Part of the cellular
diag*toolkit: start there for how the capture/decode pieces fit together.
Shared Qualcomm DIAG transport core + offline format-munge tools: arm the DIAG log mask, pump raw HDLC frames over serial, raw-fd, TCP, or UDP, and munge DIAG capture formats (HDLC ↔ DLF ↔ JSONL) offline. It is the transport foundation shared by the capture/daemon siblings in this constellation, and stands on its own as a DIAG transport core you can build on.
Public API
import diagmunge
client = diagmunge.DiagClient.from_tcp_server(host, port) # or .from_serial(port)
for frame in client.iter_frames():
...
Re-exported at the top level: DiagClient, Dge1SeqTracker,
parse_dge1_header, and the DIAG_* opcode constants. Internal transport
classes live in diagmunge.transport.
The munge tools (diagmunge.munge)
Offline DIAG format converters, each a self-contained CLI:
| Tool | Purpose |
|---|---|
python -m diagmunge.munge.hdlc_to_dlf |
raw HDLC stream → DLF record format |
python -m diagmunge.munge.capture_dlf_from_diag |
subscribe to log codes on a live device, capture frames → DLF |
python -m diagmunge.munge.dlf_to_pcap |
DIAG capture → Wireshark pcap: GSMTAP/LTE on UDP/4729, plus a sibling .nr.pcap (Exported-PDU/NR signalling) |
diagmunge.munge.replay (library) |
offline DLF/HDLC replay core: replay_to_jsonl(dispatch=…, code_filter=…) with an injected dispatch |
diagmunge.gsmtap (library) |
GSMTAP v2 encoder for decoded LTE RRC/NAS records (encode), plus GSMTAP v3 parse/convert |
diagmunge.exported_pdu (library) |
Wireshark Exported-PDU framing for NR RRC/NAS (pcap link type 252) |
diagmunge.pcap (library) |
stdlib-only pcap/pcapng writer and a synthetic Eth/IPv4/UDP frame builder |
diagmunge.gsmtap_sink (library) |
GsmtapUdpSink: send GSMTAP frames live over UDP to a listening Wireshark |
Console entry points diagmunge-hdlc-to-dlf, diagmunge-capture-dlf, and
diagmunge-dlf-to-pcap are declared for installed use. The munge tools
decode via diaggrok (the munge extra); a bare import diagmunge never
pulls it in.
dlf_to_pcap: DIAG capture to a Wireshark pcap
Reads a DIAG/HDLC/DLF capture and encapsulates the signalling records into
a Wireshark-readable pcap. LTE RRC/NAS records become GSMTAP frames on
UDP/4729 in <capture>.diaggrok.pcap; NR RRC/NAS records become
Exported-PDU blocks in a sibling <capture>.diaggrok.nr.pcap (a separate
file because NR uses a different pcap link type). Frame timestamps come
from the capture's GNSS ts64→UTC calibration when the installed diaggrok
provides diaggrok.ts64_cal and the capture carries GNSS fixes. Otherwise
they use a synthetic monotonic clock, and the tool says so on stderr.
diagmunge-dlf-to-pcap capture.dlf
diagmunge-dlf-to-pcap capture.hdlc.zst -o out.pcap
diagmunge-dlf-to-pcap capture.dlf --log-code 0xB0C0
The encapsulation is clean-room, built on the public Osmocom GSMTAP and
Wireshark Exported-PDU header layouts; tshark is used only as an output
oracle in the tests, never as a source.
Installation
From PyPI:
pip install diagmunge
# with extras:
pip install "diagmunge[munge]"
Each PyPI version is the same code as the GitHub tag of the same number
(diagmunge==2026.11.8 is tag v2026.11.8). If you only want a tool
(diaggulp, diaggpsd), install the tool; it pulls diagmunge itself.
Dependencies
The core transport (TCP / UDP / raw-fd) is stdlib-only. Optional extras cover the lazy integrations:
| Extra | Pulls | Used by |
|---|---|---|
diagmunge[serial] |
pyserial |
DiagClient.from_serial() |
diagmunge[decode] |
diaggrok |
DiagClient.observe_codes() |
diagmunge[munge] |
diaggrok |
the diagmunge.munge CLI tools |
import diagmunge never requires any of them; all are imported lazily
at their call sites. The decode and munge extras pull diaggrok from
PyPI, at least the release this diagmunge was tested against.
diagmunge.diag_source (the pcap-native DIAG record source behind
diaggulp --pcap replay) needs diaggrok too, and reads capture files with
diaggulp's container reader, so install diaggulp to use it on a capture.
Constellation position
diaggrok (pure DECODE library; never depends on diagmunge)
▲ (lazy: observe_codes -> diaggrok.frame.parse_outer_frame)
│
diagmunge (this: shared DiagClient transport + munge tools)
▲ ▲ ▲
│ │ └── diaggpsd
│ └────── diaggulp (consumes diagmunge transport)
└────────── other tools/consumers
Dependency edges point inward. diagmunge -> diaggrok (lazy) is the only
cross-package edge; the reverse never exists.
Roadmap
The semantic/foreign-format converters belong here too; that is the
munge in diagmunge. GSMTAP pcap output has now landed (dlf_to_pcap,
above); the remaining converters (WiGLE, Kismet, RINEX) are still to
follow.
License
Apache License 2.0. See LICENSE and NOTICE.
The measured QSH-trace masksets
(src/diagmunge/data/) come with
no warranty. Read their document, which also says how they were measured,
before arming one.
Metadata
Release files for diagmunge 2026.11.8
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| diagmunge-2026.11.8.tar.gz | 171.2 kB | Without provenance | Details for diagmunge-2026.11.8.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| diagmunge-2026.11.8-py3-none-any.whl | Python 3 | none | any | Details for diagmunge-2026.11.8-py3-none-any.whl |
Total release size: 293.8 kB
Release files / diagmunge-2026.11.8.tar.gz
| Download URL | diagmunge-2026.11.8.tar.gz |
|---|---|
| Size | 171.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
de4cfdffac938656621861ab9664af2d0db65f55617ab40aa397026071da6181
|
|
BLAKE2b-256 checksum How to use checksums |
7a8a6ad71056d3a588774e0274b298aa45299d8ee49c489dff286badfd6a37d2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.10
|
Release files / diagmunge-2026.11.8-py3-none-any.whl
| Download URL | diagmunge-2026.11.8-py3-none-any.whl |
|---|---|
| Size | 122.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fffa28e173c292895c0939575ad0a756f00b6117c29d617947bb38e40c658fe5
|
|
BLAKE2b-256 checksum How to use checksums |
c9551ca93e5937e3737a5a5248b1a0a8e48de8e207f07970e6b560289a765220
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.10
|
Security for diagmunge 2026.11.8
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.