Skip to content

Commit

Permalink
#1994 P25 Phase1 missing subsequent calls audio when multiple convers…
Browse files Browse the repository at this point in the history
…ations on the same traffic channel. (#1995)

Fixed issue where sdrtrunk was not checking HDU and LDU2 encryption sequences as valid before assessing the encryption state of a call.  Updated P25P1 audio module to check the valid flag for both the HDU and the LDU2 encryption segment before assigning encryption state.  Now caches all LDU messages until encryption state is determined.

Co-authored-by: Dennis Sheirer <[email protected]>
  • Loading branch information
DSheirer and Dennis Sheirer authored Sep 29, 2024
1 parent 32ce79b commit 0ecdf4d
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 40 deletions.
34 changes: 33 additions & 1 deletion src/main/java/io/github/dsheirer/gui/viewer/MessagePackage.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@

package io.github.dsheirer.gui.viewer;

import io.github.dsheirer.audio.AudioSegment;
import io.github.dsheirer.channel.state.DecoderStateEvent;
import io.github.dsheirer.controller.channel.event.ChannelStartProcessingRequest;
import io.github.dsheirer.message.IMessage;
import io.github.dsheirer.module.decode.event.DecodeEventSnapshot;
import io.github.dsheirer.module.decode.event.IDecodeEvent;
import java.util.ArrayList;
import java.util.List;

Expand All @@ -37,6 +37,7 @@ public class MessagePackage
private List<DecoderStateEvent> mDecoderStateEvents = new ArrayList<>();
private List<DecodeEventSnapshot> mDecodeEvents = new ArrayList<>();
private ChannelStartProcessingRequest mChannelStartProcessingRequest;
private AudioSegment mAudioSegment;

/**
* Constructs an instance
Expand Down Expand Up @@ -152,8 +153,39 @@ public int getChannelStartProcessingRequestCount()
return mChannelStartProcessingRequest == null ? 0 : 1;
}

/**
* Count (0 or 1) of audio segment.
*/
public int getAudioSegmentCount()
{
return mAudioSegment == null ? 0 : 1;
}

public ChannelStartProcessingRequest getChannelStartProcessingRequest()
{
return mChannelStartProcessingRequest;
}

/**
* Generated audio segment.
* @return segment or null.
*/
public AudioSegment getAudioSegment()
{
return mAudioSegment;
}

/**
* Adds the audio segment to the package
* @param audioSegment to add
*/
public void add(AudioSegment audioSegment)
{
if(mAudioSegment != null)
{
throw new IllegalStateException("AudioSegment already set");
}

mAudioSegment = audioSegment;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import io.github.dsheirer.channel.state.DecoderStateEvent;
import io.github.dsheirer.module.decode.event.DecodeEventSnapshot;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
Expand All @@ -38,6 +40,7 @@ public class MessagePackageViewer extends VBox
private TableView<DecoderStateEvent> mDecoderStateEventTableView;
private TableView<DecodeEventSnapshot> mDecodeEventTableView;
private IdentifierCollectionViewer mIdentifierCollectionViewer;
private IdentifierCollectionViewer mAudioSegmentIdCollectionViewer;
private ChannelStartProcessingRequestViewer mChannelStartProcessingRequestViewer;

/**
Expand All @@ -63,8 +66,14 @@ public MessagePackageViewer()
GridPane.setHgrow(getDecodeEventTableView(), Priority.ALWAYS);
gridPane.add(getDecodeEventTableView(), 1, 2);

gridPane.add(new Label("Channel Start Processing Request"), 0, 3);
gridPane.add(getChannelStartProcessingRequestViewer(), 0, 4);
TabPane tabPane = new TabPane();
Tab startTab = new Tab("Channel Start Processing Request");
startTab.setContent(getChannelStartProcessingRequestViewer());
Tab audioTab = new Tab("Audio Segment");
audioTab.setContent(getAudioSegmentIdCollectionViewer());
tabPane.getTabs().addAll(audioTab, startTab);

gridPane.add(tabPane, 0, 4);

getIdentifierCollectionViewer().setPrefHeight(120);
gridPane.add(new Label("Selected Decode Event Identifiers"), 1, 3);
Expand Down Expand Up @@ -96,6 +105,15 @@ public void set(MessagePackage messagePackage)
{
getDecodeEventTableView().getSelectionModel().select(0);
}

if(messagePackage.getAudioSegment() != null)
{
getAudioSegmentIdCollectionViewer().set(messagePackage.getAudioSegment().getIdentifierCollection());
}
else
{
getAudioSegmentIdCollectionViewer().set(null);
}
}
}

Expand All @@ -109,6 +127,16 @@ private IdentifierCollectionViewer getIdentifierCollectionViewer()
return mIdentifierCollectionViewer;
}

private IdentifierCollectionViewer getAudioSegmentIdCollectionViewer()
{
if(mAudioSegmentIdCollectionViewer == null)
{
mAudioSegmentIdCollectionViewer = new IdentifierCollectionViewer();
}

return mAudioSegmentIdCollectionViewer;
}

private Label getMessageLabel()
{
if(mMessageLabel == null)
Expand Down
14 changes: 13 additions & 1 deletion src/main/java/io/github/dsheirer/gui/viewer/MessagePackager.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@
package io.github.dsheirer.gui.viewer;

import com.google.common.eventbus.Subscribe;
import io.github.dsheirer.audio.AudioSegment;
import io.github.dsheirer.channel.state.DecoderStateEvent;
import io.github.dsheirer.controller.channel.event.ChannelStartProcessingRequest;
import io.github.dsheirer.message.IMessage;
import io.github.dsheirer.module.decode.event.DecodeEvent;
import io.github.dsheirer.module.decode.event.DecodeEventSnapshot;
import io.github.dsheirer.module.decode.event.IDecodeEvent;
import io.github.dsheirer.module.decode.event.IDecodeEventListener;

/**
* Utility for combining a message and decoder state events.
Expand All @@ -42,6 +42,18 @@ public MessagePackager()
{
}

/**
* Adds an audio segment.
* @param audioSegment to add
*/
public void add(AudioSegment audioSegment)
{
if(mMessagePackage != null)
{
mMessagePackage.add(audioSegment);
}
}

/**
* Adds the message and creates a new MessageWithEvents instance, wrapping the message, ready to also receive any
* decode events and decoder state events. The previous message with events is overwritten.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

package io.github.dsheirer.gui.viewer;

import io.github.dsheirer.preference.UserPreferences;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Node;
Expand Down Expand Up @@ -51,6 +52,7 @@ public class MessageRecordingViewer extends VBox
private int mTabCounterDmr = 1;
private int mTabCounterP25P1 = 1;
private int mTabCounterP25P2 = 1;
private UserPreferences mUserPreferences = new UserPreferences();

/**
* Constructs an instance
Expand All @@ -77,7 +79,7 @@ public MenuBar getMenuBar()
});
MenuItem p25p1MenuItem = new MenuItem("P25 Phase 1");
p25p1MenuItem.onActionProperty().set(event -> {
Tab tab = new LabeledTab("P25P1-" + mTabCounterP25P1++, new P25P1Viewer());
Tab tab = new LabeledTab("P25P1-" + mTabCounterP25P1++, new P25P1Viewer(mUserPreferences));
getTabPane().getTabs().add(tab);
getTabPane().getSelectionModel().select(tab);
});
Expand Down Expand Up @@ -108,7 +110,7 @@ public TabPane getTabPane()
mTabPane = new TabPane();
mTabPane.setMaxHeight(Double.MAX_VALUE);
mTabPane.getTabs().add(new LabeledTab("DMR-" + mTabCounterDmr++, new DmrViewer()));
mTabPane.getTabs().add(new LabeledTab("P25P1-" + mTabCounterP25P1++, new P25P1Viewer()));
mTabPane.getTabs().add(new LabeledTab("P25P1-" + mTabCounterP25P1++, new P25P1Viewer(mUserPreferences)));
mTabPane.getTabs().add(new LabeledTab("P25P2-" + mTabCounterP25P2++, new P25P2Viewer()));
}

Expand Down
47 changes: 41 additions & 6 deletions src/main/java/io/github/dsheirer/gui/viewer/P25P1Viewer.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,24 @@
package io.github.dsheirer.gui.viewer;

import com.google.common.eventbus.EventBus;
import io.github.dsheirer.alias.AliasList;
import io.github.dsheirer.alias.AliasModel;
import io.github.dsheirer.channel.state.DecoderStateEvent;
import io.github.dsheirer.channel.state.SingleChannelState;
import io.github.dsheirer.controller.channel.Channel;
import io.github.dsheirer.identifier.IdentifierUpdateNotification;
import io.github.dsheirer.identifier.configuration.FrequencyConfigurationIdentifier;
import io.github.dsheirer.message.IMessage;
import io.github.dsheirer.message.StuffBitsMessage;
import io.github.dsheirer.module.decode.p25.P25TrafficChannelManager;
import io.github.dsheirer.module.decode.p25.audio.P25P1AudioModule;
import io.github.dsheirer.module.decode.p25.phase1.DecodeConfigP25Phase1;
import io.github.dsheirer.module.decode.p25.phase1.P25P1DecoderState;
import io.github.dsheirer.module.decode.p25.phase1.P25P1MessageFramer;
import io.github.dsheirer.module.decode.p25.phase1.P25P1MessageProcessor;
import io.github.dsheirer.preference.UserPreferences;
import io.github.dsheirer.record.binary.BinaryReader;
import io.github.dsheirer.sample.Broadcaster;
import io.github.dsheirer.util.ThreadPool;
import java.io.File;
import java.nio.ByteBuffer;
Expand Down Expand Up @@ -94,9 +102,11 @@ public class P25P1Viewer extends VBox
private ProgressIndicator mLoadingIndicator;
private MessagePackageViewer mMessagePackageViewer;
private StringProperty mLoadedFile = new SimpleStringProperty();
private UserPreferences mUserPreferences;

public P25P1Viewer()
public P25P1Viewer(UserPreferences userPreferences)
{
mUserPreferences = userPreferences;
setPadding(new Insets(5));
setSpacing(5);

Expand Down Expand Up @@ -155,7 +165,9 @@ private void load(File file)
List<MessagePackage> messagePackages = new ArrayList<>();
P25P1MessageFramer messageFramer = new P25P1MessageFramer(null, 9600);
P25P1MessageProcessor messageProcessor = new P25P1MessageProcessor();
messageFramer.setListener(messageProcessor);
Broadcaster<IMessage> messageBroadcaster = new Broadcaster<>();
messageFramer.setListener(messageBroadcaster);
messageBroadcaster.addListener(messageProcessor);

Channel empty = new Channel("Empty");
empty.setDecodeConfiguration(new DecodeConfigP25Phase1());
Expand All @@ -169,10 +181,14 @@ private void load(File file)
trafficChannelManager.setInterModuleEventBus(eventBus);

//Register to receive events
trafficChannelManager.addDecodeEventListener(decodeEvent -> messagePackager.add(decodeEvent));
trafficChannelManager.addDecodeEventListener(messagePackager::add);
P25P1DecoderState decoderState = new P25P1DecoderState(empty, trafficChannelManager);
decoderState.setDecoderStateListener(decoderStateEvent -> messagePackager.add(decoderStateEvent));
decoderState.addDecodeEventListener(decodeEvent -> messagePackager.add(decodeEvent));

Broadcaster<DecoderStateEvent> decoderStateEventBroadcaster = new Broadcaster<>();
decoderState.setDecoderStateListener(decoderStateEventBroadcaster);

decoderStateEventBroadcaster.addListener(messagePackager::add);
decoderState.addDecodeEventListener(messagePackager::add);
decoderState.start();

long frequency = getFrequencyFromFile(mLoadedFile.get());
Expand All @@ -197,6 +213,16 @@ private void load(File file)
}
});

P25P1AudioModule audioModule = new P25P1AudioModule(mUserPreferences, new AliasList("debug"));
decoderState.setIdentifierUpdateListener(audioModule.getIdentifierUpdateListener());
audioModule.setAudioSegmentListener(messagePackager::add);
messageBroadcaster.addListener(audioModule);
audioModule.start();
SingleChannelState singleChannelState = new SingleChannelState(empty, new AliasModel());
singleChannelState.setSquelchStateListener(squelchStateEvent -> audioModule.getSquelchStateListener().receive(squelchStateEvent));
decoderStateEventBroadcaster.addListener(singleChannelState.getDecoderStateListener());
singleChannelState.start();

try(BinaryReader reader = new BinaryReader(file.toPath(), 200))
{
while(reader.hasNext())
Expand All @@ -210,6 +236,10 @@ private void load(File file)
ioe.printStackTrace();
}

audioModule.stop();
decoderState.stop();
singleChannelState.stop();

Platform.runLater(() -> {
getLoadingIndicator().setVisible(false);
getSelectedFileLabel().setText(file.getName());
Expand Down Expand Up @@ -444,8 +474,13 @@ private TableView<MessagePackage> getMessagePackageTableView()
channelStartCountColumn.setText("Starts");
channelStartCountColumn.setCellValueFactory(new PropertyValueFactory<>("channelStartProcessingRequestCount"));

TableColumn audioSegmentCountColumn = new TableColumn();
audioSegmentCountColumn.setPrefWidth(50);
audioSegmentCountColumn.setText("Audio");
audioSegmentCountColumn.setCellValueFactory(new PropertyValueFactory<>("audioSegmentCount"));

mMessagePackageTableView.getColumns().addAll(timestampColumn, validColumn, timeslotColumn, messageColumn,
decodeEventCountColumn, decoderStateEventCountColumn, channelStartCountColumn);
decodeEventCountColumn, decoderStateEventCountColumn, channelStartCountColumn, audioSegmentCountColumn);
}

return mMessagePackageTableView;
Expand Down
Loading

0 comments on commit 0ecdf4d

Please sign in to comment.