Skip to content

Add P25 Call Alert (TSBK 0x1F) decoding#1126

Open
hoosierscanner wants to merge 1 commit intoTrunkRecorder:masterfrom
hoosierscanner:feature/call-alert
Open

Add P25 Call Alert (TSBK 0x1F) decoding#1126
hoosierscanner wants to merge 1 commit intoTrunkRecorder:masterfrom
hoosierscanner:feature/call-alert

Conversation

@hoosierscanner
Copy link
Copy Markdown

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.

  • Extracts source unit ID from bits 16–39 and target unit ID from bits 40–63
  • Sets message_type = CALL_ALERT, message.source, and message.talkgroup
  • Logs at info level: tsbk1f\tCall Alert\tSource Unit: X\tTarget Unit: Y
  • Adds CALL_ALERT = 18 to the MessageType enum in parser.h
  • Adds case CALL_ALERT: to the message dispatch switch in monitor_systems.cc

Bit layout

From the P25 spec (confirmed via OP25 reference implementation):

args = dst << 24 | src   →   bits[16:39] = src, bits[40:63] = dst

Test

Verified on a live P25 system — Call Alerts appear correctly in logs with accurate source and target unit IDs.

🤖 Generated with Claude Code

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>
@hoosierscanner
Copy link
Copy Markdown
Author

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.
Background, call alerts are sent over the system to alert another radio. On my local system they are used to activate relays on a base radio as a poor-man's firehouse alerting system. I have also seen them used on systems to alert ERs to incoming patient reports, or from dispatch to raise units.
The next goal would be to send these through the MQTT feed so something can be done with the data.

hoosierscanner added a commit to hoosierscanner/tr-plugin-mqtt that referenced this pull request Apr 11, 2026
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>
hoosierscanner added a commit to hoosierscanner/tr-engine that referenced this pull request Apr 11, 2026
⚠️  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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant