Also known as: vendor MAC opcode, manufacturer-specific MAC PDU, Motorola MAC opcode, Harris MAC opcode
Vendor MAC opcodes are the manufacturer-specific MAC PDUs that P25
Phase 2 systems emit outside the standard opcode set.1 The standard reserves an opcode range
(0x80–0xBF) in which each manufacturer defines its own messages, and a PDU with such an opcode carries
an MFID (Manufacturer ID) byte right after the opcode so the same numeric opcode can mean different
things per vendor.2 GopherTrunk decodes the two vendors that dominate deployed P25 —
Motorola (MFID 0x90) and Harris (MFID 0xA4) — dispatching on the (MFID, Opcode) pair.
Because TIA-102 vendor extensions are not in the project’s spec PDFs, these layouts are a working model
reverse-engineered against SDRTrunk, and are confined to one file so a correction stays local.
The vendor opcode set
| Opcode | MFID | Decodes as |
|---|---|---|
| 0x81 | 0x90 (Motorola) | Group-regroup / patch group (super-group + up to 3 members) |
| 0x81 | 0xA4 (Harris) | Regroup (regroup talkgroup → target unit ID) |
| 0x82 | 0x90 / 0xA4 | Talker-alias (speculative plain-ASCII model — never matches real air) |
| 0x83 | 0x90 (Motorola) | Patch-delete (cancels a super-group established by 0x81) |
| 0x91 | 0x90 (Motorola) | Talker-alias HEADER (FACCH-S) |
| 0x95 | 0x90 (Motorola) | Talker-alias DATA (FACCH-S) |
The patch / regroup opcode (0x81) is the clearest example of MFID disambiguation: under Motorola it
aggregates member talkgroups under one super-group so a patched call is heard on every member (a
channel-grant-adjacent construct), while under Harris the identical opcode
points a single regroup talkgroup at a target unit. AsMotorolaPatchGroup and AsHarrisRegroup each
guard on both the opcode and the MFID before unpacking, so a Harris regroup is never mis-parsed as a
Motorola patch.
The FACCH-S talker alias
The most important vendor path is the Motorola talker alias — the radio’s display name. An early working
model assumed a single plain-ASCII opcode (0x82), but that never matched on-air traffic. SDRTrunk ground
truth (from Victorian MMR) showed the real form rides on FACCH-S during hangtime as a HEADER PDU
(opcode 0x91) followed by one or more DATA PDUs (opcode 0x95), both under MFID 0x90. The fragments
are not ASCII: they reassemble into the same Motorola message framing as Phase 1 —
WACN | System | RadioID | cipher-alias | CRC-16 — so the alias is deciphered through the shared
Motorola alias cipher and validated by a trailing
CRC-16 rather than read literally. A subtlety that cost time: the
data fragment is nibble-aligned, with the first cipher nibble in the low nibble of a payload byte, so
reassembly concatenates a nibble stream, not whole bytes. An assembler collects the header and data
blocks for one call and emits the finished alias once the CRC validates. The 0x82 opcode is retained only
as a dead reference the dispatch still names; the real alias is the 0x91/0x95 path.
Relevance to SDR
internal/radio/p25/phase2/mac_vendor.go holds the MFID constants, the vendor opcode enum, and the
(MFID, Opcode) accessors, with the alias reassembly in talker_alias.go. Decoding these is what lets
GopherTrunk report a patch super-group or a caller’s alias on a Motorola or Harris Phase 2 system —
information the standard opcodes alone do not carry. All of it is a working model against SDRTrunk, not a
published spec, and is deliberately isolated so a future correction is one local edit.
Sources
-
Project 25 — Wikipedia, on P25 and its manufacturer extensions. ↩
-
Protocol data unit — Wikipedia, on the PDU as a self-contained protocol message. ↩