Motorola LRRP request tokens that carry an integer (trigger interval 0x31, trigger distance 0x78 and the unknown parameters 0x42 / 0x44) encode it as a 7-bit variable length integer: each byte holds seven value bits, most significant group first, and the high bit of a byte flags a continuation byte. The parser read a single byte, so a real triggered location start request 09 11 22 03 FF FF EE 52 44 64 42 9C 10 62 57 34 31 84 58 was logged as ID:15663103 TRIGGER ON GPIO TRIGGER EVERY:132 SECS REQUESTED TOKENS [TIME,REQUEST-64,REQUEST-62,HORIZONTAL DIRECTION,TIMESTAMP, UNRECOGNIZED(10,44,58,9C)] and now decodes to ID:FFFFEE PERIODIC INTERVAL:600 SECS PARAM-42:3600 PARAM-44:100 REQUESTED TOKENS [TIME,HORIZONTAL SPEED,HORIZONTAL DIRECTION] The encoding and the token names follow node-dmr-lib (LRRP.js parseLRRPInt/toLRRPInt and its quoted TRBONet captures, DMRConst.js) and Moto.Net (LRRPPacket.cs "using VLQ for most of the fields"). - Add VarInt, a shared 7-bit varint reader, and VarIntToken, a token base class whose byte length is measured from the value and bounded by the remaining payload. Use them for 0x31, 0x78, 0x42 and 0x44. - Add TokenType.fromRequestValue(): 0x34 is the periodic trigger flag in a request and the timestamp in a response. TokenFactory accepts the resolved TokenType so the request path is not re-resolved. - Rename request tokens: 0x31 TRIGGER_INTERVAL (TriggerInterval), 0x4A TRIGGER_CONDITION (TriggerCondition: 02 emergency, 42 pin status change, 50 PTT, 51 PTT emergency), 0x78 TRIGGER_DISTANCE (TriggerDistance), 0x62 HORIZONTAL_SPEED. 0x42 and 0x44 become REQUEST_PARAMETER_42/44 (RequestParameter) with an optional varint value; their meaning is unknown (observed 3600 and 100). Remove TriggerGpio and TriggerOnMove. - Identity: assemble the request id big-endian (it was accumulated LSB-first), render it in hex, and clamp the read to the message. - RequestedTokens: keep a list that holds only unrecognized ids; add getters for the recognized and unrecognized lists. - Remove leftover debug locals from LRRPPacket.parseTokens(). - Add LRRPPacketTest (both captured bodies plus two copies with a corrupted type byte) and VarIntTest. Built with the project's Gradle build (JDK 27 toolchain, in Docker); compileJava, compileTestJava and the 9 new tests pass. Co-authored-by: csmith_ai <carrottop@gmail.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
MacOS Tahoe 26.1 Users - Attention:
Changes to USB support in Tahoe version 26.x cause sdrtrunk to fail to launch. Do the following to install the latest libusb and create a symbolic link and then use the nightly build which includes an updated usb4java native library for Tahoe with ARM processor. There may still be issue(s) with MacOS accessing your USB SDR tuners.
brew install libusb --HEAD
cd /opt
sudo mkdir local
cd local
sudo mkdir lib
Next, find where brew installed the libusb library, for example: /opt/homebrew/Cellar/libusb/HEAD-9ceaa52/lib/libusb-1.0.0.dylib Note: the folder "HEAD-9ceaa52" is the version stamp for HEAD when you installed from it.
Finally, create a symbolic link from the installed library to the place where usb4java is expecting to find libusb (/opt/local/lib/libusb-1.0.0.dylib)
sudo ln -s /opt/homebrew/Cellar/libusb/HEAD-9ceaa52/lib/libusb-1.0.0.dylib /opt/local/lib/libusb-1.0.0.dylib
sdrtrunk
A cross-platform java application for decoding, monitoring, recording and streaming trunked mobile and related radio protocols using Software Defined Radios (SDR).
Figure 1: sdrtrunk Application Screenshot
Download the Latest Release
All release versions of sdrtrunk are available from the releases tab.
- (alpha) These versions are under development feature previews and likely to contain bugs and unexpected behavior.
- (beta) These versions are currently being tested for bugs and functionality prior to final release.
- (final) These versions have been tested and are the current release version.
Download Nightly Software Build
The nightly release contains current builds of the software for all supported operating systems. This version of the software may contain bugs and may not run correctly. However, it let's you preview the most recent changes and fixes before the next software release. Always backup your playlist(s) before you use the nightly builds. Note: the nightly release is updated each time code changes are committed to the code base, so it's not really 'nightly' as much as it is 'current'.
Minimum System Requirements
- Operating System: Windows (
32 or64-bit), Linux (32 or64-bit) or Mac (64-bit, 12.x or higher) - CPU: 4-core
- RAM: 8GB or more (preferred). Depending on usage, 4GB may be sufficient.
Creating a Release (Maintainers)
Releases are built and published automatically by the Release GitHub workflow whenever a version tag is pushed to the repository.
- Update
projectVersioningradle.propertiesto the new version, following the naming convention described in that file (e.g.0.6.2-alpha-1,0.6.2-beta-1or0.6.2). - Commit and push the change to
master. - Create and push a tag that matches the version with a leading
v:
git tag v0.6.2-beta-1
git push origin v0.6.2-beta-1
The workflow then:
- Verifies that the tag matches
projectVersioningradle.propertiesand fails if it does not. - Builds and tests the code, then creates the release zips for Linux, Mac and Windows (x86-64 and aarch64).
- Creates a GitHub release titled
Version <version>with auto-generated release notes (a "What's Changed" list of the PRs merged since the previous version tag), and attaches the six zip files plus aSHA256SUMSchecksum file. - Marks tags containing a dash (alpha and beta versions) as pre-releases. Tags without a dash become full releases.
If the workflow fails part way through, fix the problem and re-run it from the Actions tab. It resumes from the draft release left behind. It won't modify a release that has already been published. To rebuild a published release, delete the release and the tag on GitHub, then push the tag again.