Skip to content

Releases

diagmunge 2026.11.8

Choose a tag to compare

@lukejenkins lukejenkins released this 08 Nov 23:50

diagmunge 2026.11.8, the first release on PyPI: pip install diagmunge (extras: serial, libusb, decode, munge). The PyPI version is the same code as this tag.

Packaging

  • The decode and munge extras depend on diaggrok>=2026.11.8 from PyPI instead of a pinned git URL. Mixed installs no longer fail with ResolutionImpossible.
  • The PyPI page carries the README, license and project links.

Changes

  • DiagClient.unlock_spc() sends DIAG_SPC_F (0x41). It used to send DIAG_PASSWORD_F (0x46), which answers success to any body, so a True meant nothing. 0x41 checks the code: True now means the modem accepted it.
  • diagmunge-capture-dlf runs under the read-only request guard after its SPC step, so the capture itself cannot send a write-class request.
  • GSMTAP and EARFCNs of 16384 and up. GSMTAP v2's arfcn field is 14 bits with two flag bits above it. Band 41 EARFCNs used to set the PCS flag, and band 66/71 EARFCNs became channel 0. The header now gets 0 for any EARFCN of 16384+, and the full value rides on GsmtapFrame.earfcn.
  • diagmunge-dlf-to-pcap writes pcapng when the output path ends in .pcapng, with a per-packet earfcn=<n> comment that Wireshark shows and filters on. Classic .pcap output is unchanged.
  • diagmunge-dlf-to-pcap says when timestamps are synthetic: one stderr line when the capture holds no usable GNSS time anchor, instead of a pcap that looks calibrated.
  • One warning per DGE1 sequence gap per ingest, not one per stream-walking pass.

diagmunge 2026.10.31

Choose a tag to compare

@lukejenkins lukejenkins released this 01 Nov 16:08

diagmunge 2026.10.31. The decode and munge extras now pin diaggrok v2026.10.31.

New

  • diagmunge.diag_source, a pcap-native DIAG record source: open_diag_source, iter_dge1_payloads, open_f3_source and iter_packets_from_source. It reads DGE1-over-UDP pcap / pcapng captures (optionally .zst, single file or an ordered multi-part set) and yields DIAG records carrying both the modem clock and the host wire-arrival time. It moved here from diaggrok, because it is built on diagmunge's DGE1 transport, so diaggrok no longer depends on diagmunge at all. It needs diaggrok (the decode / munge extra), and reads capture files with diaggulp's container reader. It is what diaggulp --pcap replay uses.
  • Opt-in read-only request guard. DiagClient(..., guard="read_only") (or setting client.guard after a factory built the client) checks every request before a byte reaches the modem, and refuses write-class requests (memory poke, password, EFS write sub-commands and other write subsystems) with DiagRequestRefused. Survey, NV-scan and dump tools can make "read-only" a property of the transport.

Fixes

  • DiagClient.from_libusb reattaches the kernel driver it detached when the client closes, so a modem that also has a working tty keeps it after a libusb session.
  • F3 runtime-mask readback understands the 3-byte-header GET_RT_MASK reply some SDX72 / SDX62 parts send. Read with the long header it lost the range's first SSID and read a single-SSID range as empty, so a mask restore drifted.
  • diagmunge-hdlc-to-dlf names an F3 extractor only when one is installed; otherwise it says to keep the raw HDLC capture.
  • diagmunge-dlf-to-pcap gets GNSS-calibrated frame timestamps from the capture's own 0x1476 fixes, now that diaggrok v2026.10.31 ships ts64_cal. A capture with no valid fix still falls back to a synthetic clock.

Install

pip install "diagmunge @ git+https://github.com/lukejenkins/diagmunge@v2026.10.31"
pip install "diagmunge[munge] @ git+https://github.com/lukejenkins/diagmunge@v2026.10.31"

Install at a tag, not @main: pip compares direct-URL requirements by string, so @main in the same command as a tool pinning @v2026.10.31 fails to resolve. The README explains this.