#1746 DMR Decoder now supports simplex repeater and DMDC modes of operation.

This commit is contained in:
Dennis Sheirer
2023-12-01 02:58:27 -05:00
parent d2580f8a99
commit 834846d339
7 changed files with 110 additions and 25 deletions

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2020 Dennis Sheirer
* Copyright (C) 2014-2023 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -284,11 +284,27 @@ public class DMRBurstFramer implements Listener<Dibit>
}
else
{
//When we don't have sufficient timeslot tracking data, dump the messages to timeslot 0 so that they
//don't corrupt the decoder states for either timeslot, until we positively regain timeslot tracking
//When we don't have sufficient timeslot tracking data, we either have misaligned timeslots from a
//repeater or we have some form of mobile burst. If mobile, process to the correct timeslto, otherwise
//dump the messages to timeslot 0 so that the burst doesn't corrupt the decoder states for either
// timeslot, until we positively regain timeslot tracking
if(burst1 != null)
{
mBurstDetectListener.burstDetected(burst1, mSyncTrackerTimeslot1.getSyncPattern(), 0);
DMRSyncPattern sync1 = mSyncTrackerTimeslot1.getSyncPattern();
if(sync1.isMobileStationSyncPattern() || sync1.isDirectModeTS1())
{
mBurstDetectListener.burstDetected(burst1, sync1, 1);
}
else if(sync1.isDirectModeTS2())
{
mBurstDetectListener.burstDetected(burst1, sync1, 2);
}
else
{
mBurstDetectListener.burstDetected(burst1, sync1, 0);
}
mDibitCounter -= BURST_DIBIT_LENGTH;
}
else
@@ -298,7 +314,21 @@ public class DMRBurstFramer implements Listener<Dibit>
if(burst2 != null)
{
mBurstDetectListener.burstDetected(burst2, mSyncTrackerTimeslot2.getSyncPattern(), 0);
DMRSyncPattern sync2 = mSyncTrackerTimeslot2.getSyncPattern();
if(sync2.isMobileStationSyncPattern() || sync2.isDirectModeTS1())
{
mBurstDetectListener.burstDetected(burst2, sync2, 1);
}
else if(sync2.isDirectModeTS2())
{
mBurstDetectListener.burstDetected(burst2, sync2, 2);
}
else
{
mBurstDetectListener.burstDetected(burst2, sync2, 0);
}
mDibitCounter -= BURST_DIBIT_LENGTH;
}
else

View File

@@ -445,11 +445,18 @@ public class DMRDecoderState extends TimeslotDecoderState
*/
private void processVoice(VoiceMessage message)
{
if(message.getSyncPattern().isDirectMode())
if(message.getSyncPattern().isMobileSyncPattern())
{
updateCurrentCall(DecodeEventType.CALL, "DIRECT MODE", message.getTimestamp());
if(message.getSyncPattern().isDirectMode())
{
updateCurrentCall(DecodeEventType.CALL, "DIRECT MODE", message.getTimestamp());
}
else
{
updateCurrentCall(DecodeEventType.CALL, "REPEATER", message.getTimestamp());
}
//Use the timeslot as the talkgroup identifier since DCDM mode doesn't use talkgroups
//Use the timeslot as the talkgroup identifier since DCDM & simple repeater modes don't use talkgroups
getIdentifierCollection().update(DMRTalkgroup.create(getTimeslot()));
}
else

View File

@@ -153,10 +153,8 @@ public class DMRMessageProcessor implements Listener<IMessage>
dispatch(message);
//Extract the Full Link Control message fragment from the Voice with embedded signalling message
if(message instanceof VoiceEMBMessage)
if(message instanceof VoiceEMBMessage voice)
{
VoiceEMBMessage voice = (VoiceEMBMessage)message;
if(message.getTimeslot() == 1)
{
FullLCMessage flco = mFLCAssemblerTimeslot1.process(voice.getEMB().getLCSS(),

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2022 Dennis Sheirer
* Copyright (C) 2014-2023 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -91,9 +91,17 @@ public enum DMRSyncPattern
private static final EnumSet<DMRSyncPattern> CACH_PATTERNS = EnumSet.of(BASE_STATION_DATA, BASE_STATION_VOICE,
BS_VOICE_FRAME_B, BS_VOICE_FRAME_C, BS_VOICE_FRAME_D, BS_VOICE_FRAME_E, BS_VOICE_FRAME_F);
//Direct Mode Sync Patterns
private static final EnumSet<DMRSyncPattern> DIRECT_MODE_PATTERNS = EnumSet.of(DIRECT_MODE_DATA_TIMESLOT_1,
DIRECT_MODE_DATA_TIMESLOT_2, DIRECT_MODE_VOICE_TIMESLOT_1, DIRECT_MODE_VOICE_TIMESLOT_2);
//Direct Mode TS 1 Sync Patterns
private static final EnumSet<DMRSyncPattern> DIRECT_MODE_TS1_PATTERNS = EnumSet.of(DIRECT_MODE_VOICE_TIMESLOT_1,
DIRECT_MODE_DATA_TIMESLOT_1);
//Direct Mode TS 2 Sync Patterns
private static final EnumSet<DMRSyncPattern> DIRECT_MODE_TS2_PATTERNS = EnumSet.of(DIRECT_MODE_VOICE_TIMESLOT_2,
DIRECT_MODE_DATA_TIMESLOT_2);
//Mobile Station Sync Patterns
private static final EnumSet<DMRSyncPattern> MOBILE_STATION_PATTERNS = EnumSet.of(MOBILE_STATION_DATA,
MOBILE_STATION_VOICE, MS_VOICE_FRAME_B, MS_VOICE_FRAME_C, MS_VOICE_FRAME_D, MS_VOICE_FRAME_E, MS_VOICE_FRAME_F);
/**
* Pattern that represents the enum entry
@@ -140,7 +148,43 @@ public enum DMRSyncPattern
*/
public boolean isDirectMode()
{
return DIRECT_MODE_PATTERNS.contains(this);
return isDirectModeTS1() || isDirectModeTS2();
}
/**
* Indicates if this is Direct Mode sync pattern for timestot 1
* @return true if DMTS1
*/
public boolean isDirectModeTS1()
{
return DIRECT_MODE_TS1_PATTERNS.contains(this);
}
/**
* Indicates if this is Direct Mode sync pattern for timestot 2
* @return true if DMTS2
*/
public boolean isDirectModeTS2()
{
return DIRECT_MODE_TS2_PATTERNS.contains(this);
}
/**
* Indicates if this is a mobile station sync pattern
* @return true if a mobile station sync pattern.
*/
public boolean isMobileStationSyncPattern()
{
return MOBILE_STATION_PATTERNS.contains(this);
}
/**
* Indicates if this is a mobile sync pattern, either mobile station or direct mode.
* @return true if a mobile sync pattern.
*/
public boolean isMobileSyncPattern()
{
return isMobileStationSyncPattern() || isDirectMode();
}
/**

View File

@@ -48,15 +48,13 @@ public class VoiceAMessage extends VoiceMessage
{
StringBuilder sb = new StringBuilder();
if(getSyncPattern().isDirectMode())
if(!getSyncPattern().isMobileSyncPattern())
{
sb.append(getSyncPattern());
}
else
{
sb.append("CC:- ").append(getSyncPattern());
sb.append("CC:- ");
}
sb.append(getSyncPattern());
return sb.toString();
}

View File

@@ -56,7 +56,7 @@ public class VoiceEMBMessage extends VoiceMessage
{
StringBuilder sb = new StringBuilder();
if(getEMB().isValid())
if(!getSyncPattern().isMobileSyncPattern() && getEMB().isValid())
{
sb.append("CC:").append(getEMB().getColorCode()).append(" ");
}