GNU Radio M17 protocol implementation
 
 
 
 
 
Go to file
Wojciech Kaczmarski f7731a06d5 fixed how silence is produced with codec2 2026-11-02 18:47:09 +01:00
.github chore(github): add funding configuration 2025-10-28 10:27:00 -05:00
apps
…
cmake
…
codec2-mod@7c33428379 submodules update and cleanups 2026-10-02 20:02:49 +03:00
docs submodules update and cleanups 2026-10-02 20:02:49 +03:00
examples example readme update 2026-10-03 21:48:29 +03:00
grc multi-block Text Data 2026-10-03 21:37:01 +03:00
include/gnuradio/m17 Decoder updates 2026-10-03 17:19:30 +03:00
lib fixed how silence is produced with codec2 2026-11-02 18:47:09 +01:00
libm17@3684edce08 licensing cleanups and submodule updates 2026-11-02 14:17:19 +01:00
micro-ecc@67c81076b3 micro-ecc update 2026-11-02 18:25:55 +01:00
python/m17 multi-block Text Data 2026-10-03 21:37:01 +03:00
tinier-aes@8cff8da24d
…
.gitignore
…
.gitmodules submodules update and cleanups 2026-10-02 20:02:49 +03:00
CMakeLists.txt CMake fix 2026-10-02 20:05:51 +03:00
LICENSE licensing cleanups and submodule updates 2026-11-02 14:17:19 +01:00
MANIFEST.md
…
README.md licensing cleanups and submodule updates 2026-11-02 14:17:19 +01:00

README.md

Compiling for GNU Radio

The default targeted version is GNU Radio 3.10 (main branch). Tested on Debian/GNU Linux sid with GNU Radio 3.10.10.0 (Python 3.11.9), Ubuntu 24.04 LTS with GNU Radio 3.10.9.2, and Xubuntu 26.04 with GNU Radio 3.10.12.0 (Python 3.14.4), assuming the following dependencies are installed:

sudo apt install git cmake build-essential doxygen gnuradio gnuradio-dev

For compiling gr-m17:

git clone --recursive https://github.com/M17-Project/gr-m17
cd gr-m17
mkdir build
cd build
cmake ..
make -j`nproc`
sudo make install
sudo ldconfig

The sudo make install step will finish with a statement such as

-- Set runtime path of "/usr/local/lib/python3.11/dist-packages/gnuradio/m17/m17_python.cpython-311-x86_64-linux-gnu.so" to ""

If the repository was cloned without --recursive, fetch the submodules with git submodule update --init --recursive before running cmake.

If GNU Radio Companion then reports ImportError: libgnuradio-m17.so.1.0.0: cannot open shared object file, make sure sudo ldconfig was run after sudo make install. Depending on Linux distribution (needed with Debian/sid, but not with Ubuntu 24.04 LTS), the library and Python paths might also have to be set for GNU Radio Companion:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/x86_64-linux-gnu/
export PYTHONPATH=/usr/local/lib/python3.11/dist-packages/

where the LD_LIBRARY_PATH setting results from

find /usr/local/ -name libgnuradio-m17.so.1.0.0 -print

Running the loopback example from the build directory with gnuradio-companion ../examples/m17_loopback.grc and executing it displays:

See examples/README.md for the expected output and unit testing examples.

Using the blocks

  • Transmission control (M17 Encoder): in Messages mode, a stream is started and ended with SOT and EOT messages on the transmission_control port, and SMS messages (e.g. from a QT GUI Msg Push Button, property name SMS, value = text, up to 821 bytes) send a text message. In Continuous mode, the stream starts with the flowgraph and ends when the input ends.
  • META (M17 Encoder, Meta tab, no encryption only): text (up to 52 bytes, UTF-8, sent as up to 4 blocks, one per superframe), GNSS position, extended callsign data, or raw bytes (hex), selected with Meta type. With AES, META carries the nonce.
  • Keys and seeds are entered as hex strings (spaces allowed): AES key 32/48/64 hex digits, scrambler seed 2/4/6 hex digits (= 8/16/24-bit), ECDSA private key (encoder) 64 hex digits, public key (decoder) 128 hex digits. With Debug enabled, the encoder prints the public key derived from the private key.
  • M17 Decoder: the encryption type and key size are taken from the received stream; enter the AES key and/or scrambler seed needed. Frames over the Viterbi threshold are output as Codec2 encoded silence; frames that cannot be decrypted and signature frames are output as Codec2 silence, zeros or nothing (selectable).
  • Console output: one line per event, HH:MM:SS.mmm [TAG] message, with TAG being M17_ENC/M17_DEC (or the block alias, if set). Debug data/Debug control add per-frame details.

Developer notes

In case of error related to Python bindings for m17_decoder.h are out of sync after changing header files in include/gnuradio/m17, make sure that

md5sum include/gnuradio/m17/m17_decoder.h

matches the information in python/m17/bindings/*cc. Same goes for the encoder.

Rather than manually changing the md5sum, the proper way of handling bindings in the Python directory is to execute

gr_modtool bind m17_decoder
gr_modtool bind m17_coder

from the gr-m17 directory, assuming gr_modtool bind works, otherwise check https://github.com/gnuradio/gnuradio/issues/6477

A note on output generation

The coder block is an interpolating block outputting 12 times more symbols than input bytes (16 bytes per frame become 192 symbols). The (well named) noutput_items is the output buffer size which fills much faster than the input stream so we fill out until noutput_items are reached, then send this to the GNU Radio scheduler, and consume the few input samples needed to fill the output buffer. The ring buffer mechanism of GNU Radio makes sure the dataflow is consistent.

License

gr-m17 is licensed under the GNU General Public License v3.0 or later (GPL-3.0-or-later), see LICENSE.

The bundled submodules keep their own licenses:

Submodule License
libm17 GPL-2.0-or-later
micro-ecc BSD-2-Clause
tinier-aes Public domain (Unlicense)
Codec2-mod LGPL-2.1

All of them are compatible with GPL-3.0, and the combined module is distributed under GPL-3.0-or-later.