Add P25 Call Alert (TSBK 0x1F) decoding#1126
Conversation
Decodes Call Alert messages from the P25 control channel: - Extracts source unit ID (bits 16-39) and target unit ID (bits 40-63) - Sets message_type = CALL_ALERT and populates source/talkgroup fields - Logs at info level: tsbk1f\tCall Alert\tSource Unit: X\tTarget Unit: Y - Adds CALL_ALERT case to monitor_systems.cc message dispatch switch Includes Dockerfile and patch script for building against a pinned upstream commit to maintain plugin ABI compatibility. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Someone who actually codes will need to review this, all of the code is AI generated. Worked with what I found on the web about how Call Alerts are formatted to guide it. This PR only shows the CA in the log info level. |
Publishes directed unit-to-unit page events to MQTT when trunk-recorder
decodes a Call Alert (TSBK opcode 0x1F). Call Alerts contain only source
and target unit IDs — no audio, no talkgroup.
Topic: topic_unit/<shortname>/call_alert
Payload:
{
"sys_num": 1,
"sys_name": "pscsite4",
"unit": 4810011,
"unit_alpha_tag": "",
"target_unit": 4811289,
"target_unit_alpha_tag": ""
}
Requires the CALL_ALERT message type added to trunk-recorder core:
TrunkRecorder/trunk-recorder#1126
Verified on a live P25 system — call_alert events fire correctly and
are received by downstream consumers (tr-engine).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
⚠️ DEPENDS ON TWO UPSTREAM PRs — DO NOT MERGE UNTIL BOTH ARE IN: 1. TrunkRecorder/trunk-recorder#1126 — decodes TSBK 0x1F into CALL_ALERT message type and dispatches via plugin API 2. TrunkRecorder/tr-plugin-mqtt#8 — implements unit_call_alert() in mqtt_status plugin, publishes to tr/units/{sys}/call_alert Without those two PRs, trunk-recorder will never emit call_alert MQTT messages and this handler will never fire. --- Ingest (internal/ingest/): - router.go: routes tr/units/{sys}/call_alert → unit_event handler - messages.go: adds TargetUnit/TargetUnitAlphaTag fields to UnitEventData - handler_units.go: handles call_alert subtype — upserts both source and target units, stores target_unit in metadata_json, publishes SSE as unit_event:call_alert with target_unit/target_unit_alpha_tag fields - router_test.go, handler_units_test.go: full test coverage for routing, payload parsing, and round-trip API (openapi.yaml): - Adds call_alert to EventType enum - Documents target_unit/target_unit_alpha_tag SSE payload fields Web UI: - events.html: red bold CALL ALERT badge, Unit A → Unit B detail, dedicated filter checkbox - index.html (Event Horizon): call alert row in rate meter (red), red streak in background canvas - omnitrunker.html: red CALL ALERT badge, target unit in TG columns, Call Alert filter option - omnitrunker-classic.html: same as omnitrunker - irc-radio-live.html: 🚨 CALL ALERT: UnitA → UnitB posted to *status (no talkgroup affiliation, so it goes to the system status channel) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Cool - This general approach makes sense! Let me see if I can clean up this PR a little this weekend and then merge it in. The overall intent seems pretty straightforward and would be great to add. |
|
I have a cleaned up version of this on #1143 |
Summary
Decodes P25 Call Alert messages (TSBK opcode 0x1F) from the control channel. Previously this was a stub that only logged a debug message and discarded the message.
message_type = CALL_ALERT,message.source, andmessage.talkgrouptsbk1f\tCall Alert\tSource Unit: X\tTarget Unit: YCALL_ALERT = 18to theMessageTypeenum inparser.hcase CALL_ALERT:to the message dispatch switch inmonitor_systems.ccBit layout
From the P25 spec (confirmed via OP25 reference implementation):
Test
Verified on a live P25 system — Call Alerts appear correctly in logs with accurate source and target unit IDs.
🤖 Generated with Claude Code