mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-13 09:07:27 -05:00
P25P1: decode unconfirmed data PDUs with a packet data SAP as IP packets (#2506)
PDU header format 0x15 is the generic unconfirmed data header; unconfirmed multi-block trunking control (UMBTC) is only its trunking control SAP (61/63) use. PDUHeaderFactory built a plain PDUHeader for every 0x15 header and PDUMessageFactory sent every such sequence to createUMBTC(), so outbound unconfirmed IP data (SNDCP RF UNCONFIRMED DATA with SAP 0, 4 or 6) was logged raw as PDU HEADER FORMAT:UNCONFIRMED MBTC UNCONFIRMED VENDOR:STANDARD TO LLID:n DATA BLOCKS:4 MSG:4100450000... while the confirmed equivalent (format 0x16) was decoded as IPPKT with its LRRP / ARS payload. - PDUHeaderFactory: build a PacketHeader for a 0x15 header whose SAP is UNENCRYPTED_USER_DATA, PACKET_DATA or SNDCP_PACKET_DATA_CONTROL. Other SAPs, including trunking control 61/63, keep the plain PDUHeader. - PDUMessageFactory: route a 0x15 sequence whose header is a PacketHeader through createPacketData(); everything else stays on the UMBTC path. No payload changes are needed: PacketMessage already sizes unconfirmed data blocks at 12 octets, and the header fields it uses (SAP, pad octet count, data header offset) sit at the same bit positions in the confirmed and unconfirmed headers. The ARS RegistrationAcknowledgement parser only reads the extension octet, so the 5-octet trailer (0x04 + 32-bit time) some systems append does not affect it. Adds PDUMessageFactoryTest, built from two unconfirmed PDUs captured on a Motorola P25 Phase 1 system (ARS registration acknowledgements to UDP port 4005, one with the trailer), plus header routing checks for SAP 0/4/6, SAP 61/63 and the confirmed 0x16 header. Co-authored-by: csmith_ai <carrottop@gmail.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
committed by
GitHub
parent
fbc54a38dd
commit
1a90eaf6c6
@@ -24,6 +24,7 @@ import io.github.dsheirer.module.decode.p25.phase1.message.pdu.ambtc.AMBTCHeader
|
||||
import io.github.dsheirer.module.decode.p25.phase1.message.pdu.packet.PacketHeader;
|
||||
import io.github.dsheirer.module.decode.p25.phase1.message.pdu.response.ResponseHeader;
|
||||
import io.github.dsheirer.module.decode.p25.reference.PDUFormat;
|
||||
import io.github.dsheirer.module.decode.p25.reference.ServiceAccessPoint;
|
||||
|
||||
public class PDUHeaderFactory
|
||||
{
|
||||
@@ -41,8 +42,41 @@ public class PDUHeaderFactory
|
||||
case RESPONSE_PACKET_HEADER_FORMAT:
|
||||
return new ResponseHeader(correctedBinaryMessage, passesCRC);
|
||||
case UNCONFIRMED_MULTI_BLOCK_TRUNKING_CONTROL:
|
||||
//Format 0x15 is the generic unconfirmed data header. Unconfirmed multi-block trunking control is
|
||||
//only the trunking control SAP (61/63) use of it. With a packet data SAP the header has the same
|
||||
//field layout as the confirmed packet data header and the data blocks carry an (IP) packet.
|
||||
if(isPacketData(getServiceAccessPoint(correctedBinaryMessage)))
|
||||
{
|
||||
return new PacketHeader(correctedBinaryMessage, passesCRC);
|
||||
}
|
||||
|
||||
return new PDUHeader(correctedBinaryMessage, passesCRC);
|
||||
default:
|
||||
return new PDUHeader(correctedBinaryMessage, passesCRC);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Service Access Point (SAP) from a packet data or unconfirmed data header message.
|
||||
*/
|
||||
public static ServiceAccessPoint getServiceAccessPoint(CorrectedBinaryMessage correctedBinaryMessage)
|
||||
{
|
||||
return ServiceAccessPoint.fromValue(correctedBinaryMessage.getInt(PacketHeader.SAP_ID));
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if the SAP identifies packet data that is processed by the PDUMessageFactory as a packet message.
|
||||
*/
|
||||
public static boolean isPacketData(ServiceAccessPoint sap)
|
||||
{
|
||||
switch(sap)
|
||||
{
|
||||
case UNENCRYPTED_USER_DATA:
|
||||
case PACKET_DATA:
|
||||
case SNDCP_PACKET_DATA_CONTROL:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,6 +173,13 @@ public class PDUMessageFactory
|
||||
case RESPONSE_PACKET_HEADER_FORMAT:
|
||||
return new ResponseMessage(pduSequence, nac, timestamp);
|
||||
case UNCONFIRMED_MULTI_BLOCK_TRUNKING_CONTROL:
|
||||
//The header factory creates a packet header when the unconfirmed data header carries a packet data
|
||||
//SAP, so that unconfirmed IP packets are processed the same as confirmed (PACKET_DATA) packets.
|
||||
if(pduSequence.getHeader() instanceof PacketHeader)
|
||||
{
|
||||
return createPacketData(pduSequence, nac, timestamp);
|
||||
}
|
||||
|
||||
return createUMBTC(pduSequence, nac, timestamp);
|
||||
default:
|
||||
return new PDUSequenceMessage(pduSequence, nac, timestamp);
|
||||
@@ -229,7 +236,7 @@ public class PDUMessageFactory
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a packet data message
|
||||
* Creates a packet data message from a confirmed or unconfirmed packet data sequence.
|
||||
*
|
||||
* @param pduSequence containing a packet data header and zero or more data blocks
|
||||
* @param nac network access code
|
||||
|
||||
Reference in New Issue
Block a user