wmbus

package
v0.725.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 21, 2026 License: AGPL-3.0 Imports: 3 Imported by: 0

Documentation

Overview

Package wmbus decodes the Wireless M-Bus (wM-Bus, EN 13757-4) radio link layer — the 868 MHz over-the-air framing that smart water / heat / gas / electricity meters broadcast and that a Flipper Sub-GHz (or SDR) capture lifts off the air. The wired M-Bus decoder (internal/mbus) already handles the shared application layer; this package adds the radio-specific frame: the length / control fields, the manufacturer + meter address, and the per-block CRC-16 that the wired bus does not use. Reading these telegrams enumerates the meters in radio range and validates frame integrity — the passive-recon start of a smart-meter RF assessment.

Wrap-vs-native judgement

Native. The wM-Bus radio frame (EN 13757-4 Format A) is a fixed
public structure: an L (length) field, then block 1 = C (control)
+ M (2-byte manufacturer) + A (6-byte address: 4-byte BCD ID +
version + device type) protected by a CRC-16, then 16-byte data
blocks each protected by their own CRC-16. The CRC is the EN 13757
polynomial 0x3D65 (init 0, final XOR 0xFFFF). All of that is
byte-field extraction plus that one CRC, reimplemented from the
standard — no new dependency, no shell-out.

What this covers

  • The L field and the Format-A block layout, with EVERY block's CRC-16 recomputed and reported valid / invalid.
  • Block 1: the C field (+ name: SND-NR / SND-IR / …), the manufacturer (FLAG 3-letter code from the M field), and the address — the BCD meter ID, the version, and the device/medium type (+ name: water / gas / heat / electricity / …).
  • The transport-protocol-layer (TPL) header after the CI field (EN 13757-3): short (CI 0x7A) / long (0x72) / none (0x78), the access number and status byte, and — the headline — the ENCRYPTION MODE from the configuration word (plaintext vs AES-128-CBC mode 5/7, with the encrypted-block count and the bidirectional / accessibility / synchronous flags). Whether the meter's data is readable or AES-encrypted is the first thing a smart-meter assessment needs to know.
  • The de-chunked application payload (the blocks with their CRCs stripped and concatenated) and its leading CI field — ready to feed into mbus_decode for the full Variable-Data-Structure read.

Deliberately deferred

Format B framing (a single trailing CRC instead of per-block CRCs)
is detected by CRC mismatch and noted rather than mis-parsed. The
3-of-6 (mode T) / Manchester (mode S) line coding is upstream — feed
the line-decoded bytes. AES decryption of an encrypted payload needs
the meter key (not carried in the frame). Application-layer (DIF/VIF)
decode is mbus_decode's job; the de-chunked payload is surfaced for it.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Result

type Result struct {
	Length         int        `json:"length_field"`
	Format         string     `json:"format"`
	CField         string     `json:"c_field"`
	CFieldName     string     `json:"c_field_name"`
	Manufacturer   string     `json:"manufacturer"`
	ManufacturerID string     `json:"manufacturer_id"`
	MeterID        string     `json:"meter_id"`
	Version        int        `json:"version"`
	DeviceType     string     `json:"device_type"`
	DeviceTypeName string     `json:"device_type_name"`
	BlocksValid    bool       `json:"all_blocks_crc_valid"`
	BlockCount     int        `json:"block_count"`
	CIField        string     `json:"ci_field,omitempty"`
	Transport      *TPLHeader `json:"transport_header,omitempty"`
	PayloadHex     string     `json:"application_payload_hex,omitempty"`
	Notes          []string   `json:"notes,omitempty"`
}

Result is the decoded wM-Bus radio frame.

func Decode

func Decode(hexStr string) (*Result, error)

Decode parses a Wireless M-Bus radio frame (Format A) from hex. The bytes must already be line-decoded (3-of-6 / Manchester removed).

type TPLHeader added in v0.540.0

type TPLHeader struct {
	HeaderType      string `json:"header_type"` // short / long / none
	AccessNumber    *int   `json:"access_number,omitempty"`
	Status          string `json:"status,omitempty"`
	ConfigWord      string `json:"config_word,omitempty"`
	EncryptionMode  int    `json:"encryption_mode"`
	EncryptionName  string `json:"encryption_name"`
	Encrypted       bool   `json:"encrypted"`
	EncryptedBlocks int    `json:"encrypted_blocks,omitempty"`
	Bidirectional   bool   `json:"bidirectional,omitempty"`
	Accessibility   bool   `json:"accessibility,omitempty"`
	Synchronous     bool   `json:"synchronous,omitempty"`
	// Long-header (CI 0x72) embedded address (may differ from the link layer).
	EmbeddedID           string `json:"embedded_id,omitempty"`
	EmbeddedManufacturer string `json:"embedded_manufacturer,omitempty"`
	EmbeddedVersion      *int   `json:"embedded_version,omitempty"`
	EmbeddedDeviceType   string `json:"embedded_device_type,omitempty"`
}

TPLHeader is the decoded transport-protocol-layer header (EN 13757-3) that follows the CI field. Its headline field is the encryption mode — whether the meter's data is plaintext or AES-encrypted.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL