Qualcomm DIAG protocol parser: anatomy of a mobile diagnostic protocol
Deep dive into the Qualcomm DIAG protocol: HDLC framing, CRC-16, log codes, event dispatch. How to build or integrate a production-ready parser for mobile network diagnostics.
Every Qualcomm Snapdragon chipset exposes a diagnostic interface known as the DIAG protocol. This interface is the foundation of all professional mobile network diagnostic tools β TEMS, Nemo, Actix, and now HiCellTek all rely on it to capture raw modem data. Yet the protocol itself is largely undocumented outside of Qualcommβs internal engineering resources.
This article dissects the anatomy of the Qualcomm DIAG protocol: how it frames data, how it identifies message types, and what it takes to build a reliable parser.
What the DIAG interface provides
The DIAG port is a serial-like interface exposed by the Qualcomm modem subsystem. On Android devices, it is typically accessible via /dev/diag (with root privileges). Through this interface, an application can:
- Receive log packets: continuous stream of modem telemetry, including RF measurements, RRC messages, NAS signaling, MAC scheduler data, and physical layer statistics
- Receive event reports: discrete notifications of modem events (cell reselection, handover, RLF, attach, detach)
- Send commands: configure which log codes to enable, request modem state information, trigger diagnostic actions
- Capture raw protocol data: L1, L2, and L3 messages exactly as the modem processes them, before any abstraction by the Android telephony framework
This is fundamentally different from what the Android API provides. The standard TelephonyManager gives you a high-level summary (signal strength, cell ID, network type). The DIAG interface gives you the raw protocol stack: every RRC message, every measurement report, every scheduler decision.
HDLC framing
DIAG data is transmitted using a modified HDLC (High-Level Data Link Control) framing protocol. Each DIAG frame is structured as follows:
[0x7E] [Payload] [CRC-16] [0x7E]
0x7E: frame delimiter byte, marking the start and end of each frame- Payload: the actual DIAG message, with byte-stuffing applied (any
0x7Eor0x7Dwithin the payload is escaped) - CRC-16: a 16-bit CRC computed over the payload using the CRC-CCITT polynomial
Byte-stuffing rules
When the payload contains a byte equal to 0x7E (the delimiter) or 0x7D (the escape character), it must be escaped:
0x7Ein payload becomes0x7D 0x5E0x7Din payload becomes0x7D 0x5D
The parser must reverse this escaping before processing the payload. Failure to handle byte-stuffing correctly is one of the most common bugs in custom DIAG parsers β it causes frame misalignment and cascading parse failures.
CRC-16 validation
After un-stuffing the payload, the parser must validate the CRC-16 checksum. The CRC covers the entire un-stuffed payload (excluding the delimiter bytes and the CRC itself). The polynomial used is CRC-CCITT (0x8408, reflected).
Frames that fail CRC validation must be discarded. On a busy modem with high log code density, CRC failures can indicate:
- USB buffer overflows (the host is not reading fast enough)
- Modem firmware bugs (rare but not unheard of)
- Incorrect byte-stuffing reversal in the parser
A production-quality parser must track CRC failure rates and alert when they exceed a threshold, as this indicates data loss.
Message identification: log codes and subsystem IDs
Once a valid frame is extracted, the first byte of the payload identifies the message category:
| Command code | Category | Description |
|---|---|---|
0x10 | Log packet | Modem telemetry log (RF, RRC, NAS, MAC) |
0x60 | Event report | Discrete modem event notification |
0x73 | Extended message | Debug/printf from modem firmware |
0x4B | Subsystem dispatch | Command/response for subsystem queries |
Log codes
For log packets (0x10), the payload contains a 16-bit log code that identifies the specific measurement or message type. Examples:
| Log code | Description |
|---|---|
0xB0C0 | LTE RRC OTA message (contains ASN.1-encoded RRC PDU) |
0xB0EC | LTE NAS ESM/EMM message |
0xB821 | NR RRC OTA message |
0xB97F | LTE MAC UL transport block |
0xB060 | LTE ML1 serving cell measurement (RSRP, RSRQ, SINR) |
There are hundreds of defined log codes across LTE, NR, WCDMA, GSM, and IMS subsystems. A comprehensive parser must recognize and dispatch each log code to the appropriate handler.
Event IDs
For event reports (0x60), a 16-bit event ID identifies the event type:
| Event ID | Description |
|---|---|
0x0911 | LTE RRC state change |
0x0B28 | NR RRC state change |
0x074D | LTE handover success |
0x074E | LTE handover failure |
Building a DIAG parser: the engineering challenge
A functional DIAG parser requires several layers of engineering:
1. Transport layer
Reading from /dev/diag on Android requires root access and correct ioctl configuration. The device operates in a streaming mode β data arrives continuously as a byte stream, and the parser must buffer, scan for delimiters, and extract frames in real time.
2. Frame extraction
The HDLC de-framing engine must handle:
- Partial frames (data split across read() calls)
- Back-to-back frames with no gap
- Corrupted frames (CRC failure, truncated data)
- High throughput: on a busy modem, hundreds of frames per second
3. Log code dispatch
Each log code requires a dedicated handler that knows the internal structure of that packet type. For example, log code 0xB0C0 (LTE RRC OTA) contains:
- A header with version, radio bearer ID, and SFN
- An ASN.1 UPER-encoded RRC PDU that must be decoded using the full TS 36.331 grammar
The handler must parse the header, extract the ASN.1 payload, and pass it to the ASN.1 decoder.
4. Multi-radio support
Modern Qualcomm chipsets run multiple radio stacks (LTE + NR in NSA, dual-SIM DSDA). The DIAG stream interleaves frames from all active radios. The parser must:
- Identify which radio stack each frame belongs to
- Maintain separate state models for each stack
- Handle log code version differences between chipset generations
5. Chipset compatibility
Qualcomm changes log code formats between chipset generations. A log code that uses version 24 on Snapdragon 888 may use version 26 on Snapdragon 8 Gen 2, with different field layouts. A production parser must support multiple versions of each log code.
The maintenance burden
Even after building a working parser, the ongoing maintenance is substantial:
- New chipsets: each Snapdragon generation may introduce new log codes or change existing formats
- New 3GPP releases: NR features added in Release 17/18 require new log code handlers
- New radio technologies: RedCap, NTN (non-terrestrial networks), and sidelink introduce entirely new subsystems
- Bug fixes: edge cases in HDLC framing, CRC, and byte-stuffing surface over months of field deployment
Teams that maintain in-house DIAG parsers typically dedicate 1-2 engineers full-time to this work.
The SDK alternative: HiCellTek DiagClient
HiCellTekβs DiagClient SDK provides a production-ready Qualcomm DIAG parser as a compiled library for ARM64/Android, with the following components:
- HDLC de-framer: handles byte-stuffing, CRC-16, partial frames, and error recovery
- Log code dispatcher: recognizes 200+ LTE and NR log codes with multi-version support
- Event handler: processes modem events with structured output
- HLOG writer: writes parsed data to HiCellTekβs encrypted HLOG format for post-processing
- Multi-radio support: correct demultiplexing for NSA, SA, and dual-SIM configurations
- Chipset compatibility: tested across Snapdragon 6/7/8 series, updated with each new chipset release
The SDK abstracts the entire DIAG parsing pipeline, exposing a high-level callback API: register for the log codes you need, receive structured data objects, and focus your engineering effort on your application logic rather than protocol plumbing.
Conclusion
The Qualcomm DIAG protocol is the gateway to deep mobile network diagnostics, but it is also a significant engineering challenge. HDLC framing, CRC validation, log code dispatch, multi-radio support, and chipset compatibility require specialized expertise and ongoing maintenance.
For teams building diagnostic tools, drive test applications, or network monitoring solutions, integrating a proven DIAG parser SDK eliminates months of development and years of maintenance burden. HiCellTekβs DiagClient SDK is available at 5,990 EUR/year with full ARM64 and Windows support. Review the SDK details on the product page or explore licensing on the pricing page. The Android drive test tool and Layer 3 decoder pages show what is built on top of this DIAG stack.
Founder of HiCellTek. 15+ years in telecom, operator side, vendor side, field side. Building the field tool RF engineers deserve.
Request a personalized demo of HiCellTek β 2G/3G/4G/5G network diagnostics on Android.