Skip to content

Commit

Permalink
Merge pull request #1755 from DSheirer/1746-dmr-simplex-repeater
Browse files Browse the repository at this point in the history
#1746 DMR Decoder - Simplex Repeater and DCDM Calls
  • Loading branch information
DSheirer authored Dec 1, 2023
2 parents d2580f8 + 834846d commit a7c89b5
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 25 deletions.
12 changes: 10 additions & 2 deletions src/main/java/io/github/dsheirer/gui/viewer/RecordingViewer.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,17 @@ public MenuBar getMenuBar()

Menu createNewViewerMenu = new Menu("New Viewer ...");
MenuItem dmrMenuItem = new MenuItem("DMR");
dmrMenuItem.onActionProperty().set(event -> getTabPane().getTabs().add(new LabeledTab("DMR-" + mTabCounterDmr++, new DmrViewer())));
dmrMenuItem.onActionProperty().set(event -> {
Tab tab = new LabeledTab("DMR-" + mTabCounterDmr++, new DmrViewer());
getTabPane().getTabs().add(tab);
getTabPane().getSelectionModel().select(tab);
});
MenuItem p25p1MenuItem = new MenuItem("P25P1");
p25p1MenuItem.onActionProperty().set(event -> getTabPane().getTabs().add(new LabeledTab("P25P1-" + mTabCounterP25P1++, new P25P1Viewer())));
p25p1MenuItem.onActionProperty().set(event -> {
Tab tab = new LabeledTab("P25P1-" + mTabCounterP25P1++, new P25P1Viewer());
getTabPane().getTabs().add(tab);
getTabPane().getSelectionModel().select(tab);
});
createNewViewerMenu.getItems().addAll(dmrMenuItem, p25p1MenuItem);

MenuItem exitMenu = new MenuItem("Exit");
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -284,11 +284,27 @@ private void dispatch()
}
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
Expand All @@ -298,7 +314,21 @@ private void dispatch()

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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -445,11 +445,18 @@ else if(packet.getPacket() instanceof XCMPPacket xcmp)
*/
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,8 @@ else if(message instanceof DMRBurst dmrBurst && dmrBurst.isValid())
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(),
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -140,7 +148,43 @@ public boolean hasCACH()
*/
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();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,13 @@ public String toString()
{
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();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public String toString()
{
StringBuilder sb = new StringBuilder();

if(getEMB().isValid())
if(!getSyncPattern().isMobileSyncPattern() && getEMB().isValid())
{
sb.append("CC:").append(getEMB().getColorCode()).append(" ");
}
Expand Down

0 comments on commit a7c89b5

Please sign in to comment.