diff --git a/src/main/java/io/github/dsheirer/filter/FilterSet.java b/src/main/java/io/github/dsheirer/filter/FilterSet.java index e5ecbd9b..ef8a1f63 100644 --- a/src/main/java/io/github/dsheirer/filter/FilterSet.java +++ b/src/main/java/io/github/dsheirer/filter/FilterSet.java @@ -46,13 +46,14 @@ public class FilterSet implements IFilter { for( IFilter filter: mFilters ) { - if( filter.canProcess( t ) ) + // Make sure to loop through all filters. + // Only return if true or all filters have been evaluated. + if( filter.canProcess( t ) && filter.passes( t )) { - return filter.passes( t ); + return true; } } } - return false; } diff --git a/src/main/java/io/github/dsheirer/module/decode/event/DecodeEvent.java b/src/main/java/io/github/dsheirer/module/decode/event/DecodeEvent.java index 0321032e..ae4fa9ed 100644 --- a/src/main/java/io/github/dsheirer/module/decode/event/DecodeEvent.java +++ b/src/main/java/io/github/dsheirer/module/decode/event/DecodeEvent.java @@ -33,6 +33,7 @@ public class DecodeEvent implements IDecodeEvent private long mTimeStart; private long mTimeEnd; private String mEventDescription; + private DecodeEventType mDecodeEventType; private IdentifierCollection mIdentifierCollection; private IChannelDescriptor mChannelDescriptor; private String mDetails; @@ -131,6 +132,21 @@ public class DecodeEvent implements IDecodeEvent mEventDescription = description; } + /** + * {@link DecodeEventType} + */ + @Override + public DecodeEventType getEventType() { + return mDecodeEventType; + } + + /** + * Sets the {@link DecodeEventType} + */ + public void setEventType(DecodeEventType eventType) { + this.mDecodeEventType = eventType; + } + /** * Identifier collection for this event. */ @@ -252,6 +268,7 @@ public class DecodeEvent implements IDecodeEvent protected long mTimeStart; protected long mDuration; protected String mEventDescription; + protected DecodeEventType mDecodeEventType; protected IdentifierCollection mIdentifierCollection; protected IChannelDescriptor mChannelDescriptor; protected String mDetails; @@ -296,6 +313,11 @@ public class DecodeEvent implements IDecodeEvent return this; } + public DecodeEventBuilder eventType(DecodeEventType eventType) { + mDecodeEventType = eventType; + return this; + } + /** * Sets the event description text * @param description of the event diff --git a/src/main/java/io/github/dsheirer/module/decode/event/DecodeEventModel.java b/src/main/java/io/github/dsheirer/module/decode/event/DecodeEventModel.java index d2c360a9..99524dc5 100644 --- a/src/main/java/io/github/dsheirer/module/decode/event/DecodeEventModel.java +++ b/src/main/java/io/github/dsheirer/module/decode/event/DecodeEventModel.java @@ -24,7 +24,10 @@ package io.github.dsheirer.module.decode.event; import com.google.common.eventbus.Subscribe; import io.github.dsheirer.channel.IChannelDescriptor; import io.github.dsheirer.eventbus.MyEventBus; +import io.github.dsheirer.filter.FilterSet; import io.github.dsheirer.identifier.IdentifierCollection; +import io.github.dsheirer.module.decode.event.filter.DecodeEventFilterSet; +import io.github.dsheirer.module.decode.event.filter.EventFilterProvider; import io.github.dsheirer.preference.PreferenceType; import io.github.dsheirer.sample.Listener; import org.slf4j.Logger; @@ -35,7 +38,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; -public class DecodeEventModel extends AbstractTableModel implements Listener +public class DecodeEventModel extends AbstractTableModel implements Listener, EventFilterProvider { private static final long serialVersionUID = 1L; private final static Logger mLog = LoggerFactory.getLogger(DecodeEventModel.class); @@ -54,6 +57,7 @@ public class DecodeEventModel extends AbstractTableModel implements Listener mEvents = new ArrayList<>(); + protected FilterSet mEventFilterSet = new DecodeEventFilterSet(); protected String[] mHeaders = new String[]{"Time", "Duration", "Event", "From", "Alias", "To", "Alias", "Channel", "Frequency", "Details"}; @@ -105,6 +109,12 @@ public class DecodeEventModel extends AbstractTableModel implements Listener getFilterSet() { + return mEventFilterSet; + } + + @Override + public void setFilterSet(FilterSet filterSet) { + this.mEventFilterSet = filterSet; + } + @Override public int getRowCount() { diff --git a/src/main/java/io/github/dsheirer/module/decode/event/DecodeEventPanel.java b/src/main/java/io/github/dsheirer/module/decode/event/DecodeEventPanel.java index ac7b74fa..a0233dfb 100644 --- a/src/main/java/io/github/dsheirer/module/decode/event/DecodeEventPanel.java +++ b/src/main/java/io/github/dsheirer/module/decode/event/DecodeEventPanel.java @@ -28,12 +28,18 @@ import io.github.dsheirer.alias.AliasList; import io.github.dsheirer.alias.AliasModel; import io.github.dsheirer.channel.IChannelDescriptor; import io.github.dsheirer.eventbus.MyEventBus; +import io.github.dsheirer.filter.AllPassFilter; +import io.github.dsheirer.filter.FilterSet; import io.github.dsheirer.icon.IconModel; import io.github.dsheirer.identifier.Form; import io.github.dsheirer.identifier.Identifier; import io.github.dsheirer.identifier.IdentifierCollection; import io.github.dsheirer.identifier.Role; import io.github.dsheirer.module.ProcessingChain; +import io.github.dsheirer.module.decode.event.filter.EventClearButton; +import io.github.dsheirer.module.decode.event.filter.EventClearHandler; +import io.github.dsheirer.module.decode.event.filter.EventFilterButton; +import io.github.dsheirer.module.decode.event.filter.EventFilterProvider; import io.github.dsheirer.preference.PreferenceType; import io.github.dsheirer.preference.UserPreferences; import io.github.dsheirer.preference.swing.JTableColumnWidthMonitor; @@ -42,15 +48,9 @@ import net.miginfocom.swing.MigLayout; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.swing.ImageIcon; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTable; +import javax.swing.*; import javax.swing.table.DefaultTableCellRenderer; -import java.awt.Color; -import java.awt.Component; -import java.awt.EventQueue; +import java.awt.*; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.Collections; @@ -72,6 +72,7 @@ public class DecodeEventPanel extends JPanel implements Listener mFilterButton; + private EventClearButton mEventClearButton; + + public EventManagementPanel() + { + setLayout(new MigLayout("insets 2 2 5 5", "[]5[left,grow]", "")); + + initializeFilterButton(); + initializeClearButton(); + disableButtons(); + + add(mFilterButton); + add(mEventClearButton); + } + + public void enableButtons() + { + mFilterButton.setEnabled(true); + mEventClearButton.setEnabled(true); + } + + public void disableButtons() + { + mFilterButton.setEnabled(false); + mEventClearButton.setEnabled(false); + } + + private void initializeFilterButton() + { + EventFilterProvider filterProvider = (EventFilterProvider) mTable.getModel(); + FilterSet filterSet = new FilterSet<>(new AllPassFilter<>()); + if (filterProvider != null) { + filterSet = filterProvider.getFilterSet(); + } + mFilterButton = new EventFilterButton<>("Message Filter Editor", filterSet); + } + + private void initializeClearButton() { + mEventClearButton = new EventClearButton( + ((DecodeEventModel) mTable.getModel()).getMaxMessageCount() + ); + mEventClearButton.setEventClearHandler(new EventClearHandler() { + @Override + public void onHistoryLimitChanged(int newHistoryLimit) { + ((DecodeEventModel) mTable.getModel()).setMaxMessageCount(newHistoryLimit); + } + + @Override + public void onClearHistoryClicked() { + ((DecodeEventModel) mTable.getModel()).clear(); + } + }); + } + } + /** * Custom cell renderer for displaying identifiers from an identifier collection */ diff --git a/src/main/java/io/github/dsheirer/module/decode/event/IDecodeEvent.java b/src/main/java/io/github/dsheirer/module/decode/event/IDecodeEvent.java index 8fb84d6b..ea3da208 100644 --- a/src/main/java/io/github/dsheirer/module/decode/event/IDecodeEvent.java +++ b/src/main/java/io/github/dsheirer/module/decode/event/IDecodeEvent.java @@ -77,6 +77,11 @@ public interface IDecodeEvent */ Protocol getProtocol(); + /** + * {@link DecodeEventType} for the event produced + */ + DecodeEventType getEventType(); + /** * Timeslot for the event. * @return timeslot or default of 0 diff --git a/src/main/java/io/github/dsheirer/module/decode/event/filter/DecodeEventFilterSet.java b/src/main/java/io/github/dsheirer/module/decode/event/filter/DecodeEventFilterSet.java new file mode 100644 index 00000000..ed2a8302 --- /dev/null +++ b/src/main/java/io/github/dsheirer/module/decode/event/filter/DecodeEventFilterSet.java @@ -0,0 +1,16 @@ +package io.github.dsheirer.module.decode.event.filter; + +import io.github.dsheirer.filter.FilterSet; +import io.github.dsheirer.module.decode.event.IDecodeEvent; + +public class DecodeEventFilterSet extends FilterSet { + public DecodeEventFilterSet() { + super ("All Messages"); + + addFilter(new DecodedCallEventFilter()); + addFilter(new DecodedCallEncryptedEventFilter()); + addFilter(new DecodedDataEventFilter()); + addFilter(new DecodedCommandEventFilter()); + addFilter(new DecodedRegistrationEventFilter()); + } +} diff --git a/src/main/java/io/github/dsheirer/module/decode/event/filter/DecodedCallEncryptedEventFilter.java b/src/main/java/io/github/dsheirer/module/decode/event/filter/DecodedCallEncryptedEventFilter.java new file mode 100644 index 00000000..3afc588a --- /dev/null +++ b/src/main/java/io/github/dsheirer/module/decode/event/filter/DecodedCallEncryptedEventFilter.java @@ -0,0 +1,19 @@ +package io.github.dsheirer.module.decode.event.filter; + +import io.github.dsheirer.module.decode.event.DecodeEventType; + +import java.util.Arrays; + +public class DecodedCallEncryptedEventFilter extends EventFilter +{ + public DecodedCallEncryptedEventFilter() + { + super("Voice Calls - Encrypted", Arrays.asList( + DecodeEventType.CALL_ENCRYPTED, + DecodeEventType.CALL_GROUP_ENCRYPTED, + DecodeEventType.CALL_PATCH_GROUP_ENCRYPTED, + DecodeEventType.CALL_INTERCONNECT_ENCRYPTED, + DecodeEventType.CALL_UNIT_TO_UNIT_ENCRYPTED + )); + } +} diff --git a/src/main/java/io/github/dsheirer/module/decode/event/filter/DecodedCallEventFilter.java b/src/main/java/io/github/dsheirer/module/decode/event/filter/DecodedCallEventFilter.java new file mode 100644 index 00000000..930e52a2 --- /dev/null +++ b/src/main/java/io/github/dsheirer/module/decode/event/filter/DecodedCallEventFilter.java @@ -0,0 +1,25 @@ +package io.github.dsheirer.module.decode.event.filter; + +import io.github.dsheirer.module.decode.event.DecodeEventType; + +import java.util.Arrays; + +public class DecodedCallEventFilter extends EventFilter +{ + public DecodedCallEventFilter() + { + super("Voice Calls", Arrays.asList( + DecodeEventType.CALL_GROUP, + DecodeEventType.CALL_PATCH_GROUP, + DecodeEventType.CALL_ALERT, + DecodeEventType.CALL_DETECT, + DecodeEventType.CALL_DO_NOT_MONITOR, + DecodeEventType.CALL_END, + DecodeEventType.CALL_INTERCONNECT, + DecodeEventType.CALL_UNIQUE_ID, + DecodeEventType.CALL_UNIT_TO_UNIT, + DecodeEventType.CALL_NO_TUNER, + DecodeEventType.CALL_TIMEOUT + )); + } +} diff --git a/src/main/java/io/github/dsheirer/module/decode/event/filter/DecodedCommandEventFilter.java b/src/main/java/io/github/dsheirer/module/decode/event/filter/DecodedCommandEventFilter.java new file mode 100644 index 00000000..8eb385e2 --- /dev/null +++ b/src/main/java/io/github/dsheirer/module/decode/event/filter/DecodedCommandEventFilter.java @@ -0,0 +1,24 @@ +package io.github.dsheirer.module.decode.event.filter; + +import io.github.dsheirer.module.decode.event.DecodeEventType; + +import java.util.Arrays; + +public class DecodedCommandEventFilter extends EventFilter +{ + public DecodedCommandEventFilter() + { + super("Commands", Arrays.asList( + DecodeEventType.ANNOUNCEMENT, + DecodeEventType.STATION_ID, + DecodeEventType.PAGE, + DecodeEventType.QUERY, + DecodeEventType.RADIO_CHECK, + DecodeEventType.STATUS, + DecodeEventType.COMMAND, + DecodeEventType.EMERGENCY, + DecodeEventType.NOTIFICATION, + DecodeEventType.FUNCTION + )); + } +} diff --git a/src/main/java/io/github/dsheirer/module/decode/event/filter/DecodedDataEventFilter.java b/src/main/java/io/github/dsheirer/module/decode/event/filter/DecodedDataEventFilter.java new file mode 100644 index 00000000..5b8ea00d --- /dev/null +++ b/src/main/java/io/github/dsheirer/module/decode/event/filter/DecodedDataEventFilter.java @@ -0,0 +1,23 @@ +package io.github.dsheirer.module.decode.event.filter; + +import io.github.dsheirer.module.decode.event.DecodeEventType; + +import java.util.Arrays; + +public class DecodedDataEventFilter extends EventFilter +{ + public DecodedDataEventFilter() + { + super("Data Calls", Arrays.asList( + DecodeEventType.DATA_CALL, + DecodeEventType.DATA_CALL_ENCRYPTED, + DecodeEventType.DATA_PACKET, + DecodeEventType.GPS, + DecodeEventType.IP_PACKET, + DecodeEventType.UDP_PACKET, + DecodeEventType.SDM, + DecodeEventType.ID_ANI, + DecodeEventType.ID_UNIQUE + )); + } +} diff --git a/src/main/java/io/github/dsheirer/module/decode/event/filter/DecodedRegistrationEventFilter.java b/src/main/java/io/github/dsheirer/module/decode/event/filter/DecodedRegistrationEventFilter.java new file mode 100644 index 00000000..d316b671 --- /dev/null +++ b/src/main/java/io/github/dsheirer/module/decode/event/filter/DecodedRegistrationEventFilter.java @@ -0,0 +1,22 @@ +package io.github.dsheirer.module.decode.event.filter; + +import io.github.dsheirer.module.decode.event.DecodeEventType; + +import java.util.Arrays; + +public class DecodedRegistrationEventFilter extends EventFilter +{ + public DecodedRegistrationEventFilter() + { + super("Registrations", Arrays.asList( + DecodeEventType.AFFILIATE, + DecodeEventType.AUTOMATIC_REGISTRATION_SERVICE, + DecodeEventType.REGISTER, + DecodeEventType.REGISTER_ESN, + DecodeEventType.DEREGISTER, + DecodeEventType.REQUEST, + DecodeEventType.RESPONSE, + DecodeEventType.RESPONSE_PACKET + )); + } +} diff --git a/src/main/java/io/github/dsheirer/module/decode/event/filter/EventClearButton.java b/src/main/java/io/github/dsheirer/module/decode/event/filter/EventClearButton.java new file mode 100644 index 00000000..8dba214e --- /dev/null +++ b/src/main/java/io/github/dsheirer/module/decode/event/filter/EventClearButton.java @@ -0,0 +1,101 @@ +package io.github.dsheirer.module.decode.event.filter; + +import com.jidesoft.swing.JideSplitButton; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; + +public class EventClearButton extends JideSplitButton + { + private static final long serialVersionUID = 1L; + private EventClearHandler mEventClearHandler; + + public EventClearButton(int maxHistoryCount) + { + super("Clear"); + + JPanel historyPanel = new JPanel(); + + historyPanel.add(new JLabel("History Entries:")); + + final JSlider historySlider = initializeHistorySlider(); + + historySlider.setValue(maxHistoryCount); + historySlider.addChangeListener(new ChangeListener() + { + @Override + public void stateChanged(ChangeEvent arg0) + { + if (mEventClearHandler != null) + { + mEventClearHandler.onHistoryLimitChanged(historySlider.getValue()); + } + } + }); + + historyPanel.add(historySlider); + + add(historyPanel); + + /* This handles the click action on the main button. Clear messages */ + addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + if (mEventClearHandler != null) + { + mEventClearHandler.onClearHistoryClicked(); + } + } + }); + } + + public void setEventClearHandler(EventClearHandler eventClearHandler) { + this.mEventClearHandler = eventClearHandler; + } + + private JSlider initializeHistorySlider() + { + final JSlider slider = new JSlider(); + slider.setMinimum(0); + slider.setMaximum(2000); + slider.setMajorTickSpacing(500); + slider.setPaintTicks(true); + slider.setPaintLabels(true); + + slider.addMouseListener(new MouseListener() + { + @Override + public void mouseClicked(MouseEvent arg0) + { + if(SwingUtilities.isLeftMouseButton(arg0) && arg0.getClickCount() == 2) + { + slider.setValue(500); //default + } + } + + public void mouseEntered(MouseEvent arg0) + { + } + + public void mouseExited(MouseEvent arg0) + { + } + + public void mousePressed(MouseEvent arg0) + { + } + + public void mouseReleased(MouseEvent arg0) + { + } + }); + return slider; + } + } \ No newline at end of file diff --git a/src/main/java/io/github/dsheirer/module/decode/event/filter/EventClearHandler.java b/src/main/java/io/github/dsheirer/module/decode/event/filter/EventClearHandler.java new file mode 100644 index 00000000..badfd817 --- /dev/null +++ b/src/main/java/io/github/dsheirer/module/decode/event/filter/EventClearHandler.java @@ -0,0 +1,6 @@ +package io.github.dsheirer.module.decode.event.filter; + +public interface EventClearHandler { + void onHistoryLimitChanged(int newHistoryLimit); + void onClearHistoryClicked(); +} diff --git a/src/main/java/io/github/dsheirer/module/decode/event/filter/EventFilter.java b/src/main/java/io/github/dsheirer/module/decode/event/filter/EventFilter.java new file mode 100644 index 00000000..53508930 --- /dev/null +++ b/src/main/java/io/github/dsheirer/module/decode/event/filter/EventFilter.java @@ -0,0 +1,56 @@ +package io.github.dsheirer.module.decode.event.filter; + +import io.github.dsheirer.filter.Filter; +import io.github.dsheirer.filter.FilterElement; +import io.github.dsheirer.module.decode.event.DecodeEventType; +import io.github.dsheirer.module.decode.event.IDecodeEvent; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +/** + * This is used as a base for {@link IDecodeEvent} types. + * This will take a list of {@link IDecodeEvent}s and generate filters for the list. + * This will default canProcess to TRUE. Override if other value or evaluation is needed. + * + */ +public class EventFilter extends Filter +{ + private Map> mElements = new EnumMap<>(DecodeEventType.class); + + public EventFilter(String name, List eventTypes) + { + super(name); + + for (DecodeEventType eventType : eventTypes) { + mElements.put(eventType, new FilterElement<>(eventType)); + } + } + + @Override + public boolean passes(IDecodeEvent iDecodeEvent) + { + if (mEnabled && canProcess(iDecodeEvent)) + { + if (mElements.containsKey(iDecodeEvent.getEventType())) + { + return mElements.get(iDecodeEvent.getEventType()).isEnabled(); + } + } + return false; + } + + @Override + public boolean canProcess(IDecodeEvent iDecodeEvent) + { + return true; + } + + @Override + public List> getFilterElements() + { + return new ArrayList<>(mElements.values()); + } +} diff --git a/src/main/java/io/github/dsheirer/module/decode/event/filter/EventFilterButton.java b/src/main/java/io/github/dsheirer/module/decode/event/filter/EventFilterButton.java new file mode 100644 index 00000000..235aa1be --- /dev/null +++ b/src/main/java/io/github/dsheirer/module/decode/event/filter/EventFilterButton.java @@ -0,0 +1,84 @@ +package io.github.dsheirer.module.decode.event.filter; + +import com.jidesoft.swing.JideButton; +import io.github.dsheirer.filter.FilterEditorPanel; +import io.github.dsheirer.filter.FilterSet; +import net.miginfocom.swing.MigLayout; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class EventFilterButton extends JideButton +{ + private static final long serialVersionUID = 1L; + + public EventFilterButton(String dialogTitle, FilterSet filterSet) + { + this("Filter", dialogTitle, filterSet); + } + + public EventFilterButton(String buttonLabel, String dialogTitle, FilterSet filterSet) + { + super(buttonLabel); + + addActionListener( + new EventFilterActionHandler(dialogTitle, filterSet) + ); + } + + public class EventFilterActionHandler implements ActionListener + { + private String title; + private FilterSet filterSet; + + public EventFilterActionHandler( String title, FilterSet filterSet) + { + this.title = title; + this.filterSet = filterSet; + } + + @Override + public void actionPerformed(ActionEvent e) + { + final JFrame editor = new JFrame(); + + editor.setTitle(title); + editor.setLocationRelativeTo(EventFilterButton.this); + editor.setSize(600, 400); + editor.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + editor.setLayout(new MigLayout("", "[grow,fill]", + "[grow,fill][][]")); + + FilterEditorPanel panel = new FilterEditorPanel(filterSet); + + JScrollPane scroller = new JScrollPane(panel); + scroller.setViewportView(panel); + + editor.add(scroller, "wrap"); + + editor.add(new JLabel("Right-click to select/deselect all nodes"), "wrap"); + + JButton close = new JButton("Close"); + close.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + editor.dispose(); + } + }); + + editor.add(close); + + EventQueue.invokeLater(new Runnable() + { + public void run() + { + editor.setVisible(true); + } + }); + } + } +} \ No newline at end of file diff --git a/src/main/java/io/github/dsheirer/module/decode/event/filter/EventFilterProvider.java b/src/main/java/io/github/dsheirer/module/decode/event/filter/EventFilterProvider.java new file mode 100644 index 00000000..d0981010 --- /dev/null +++ b/src/main/java/io/github/dsheirer/module/decode/event/filter/EventFilterProvider.java @@ -0,0 +1,8 @@ +package io.github.dsheirer.module.decode.event.filter; + +import io.github.dsheirer.filter.FilterSet; + +public interface EventFilterProvider { + FilterSet getFilterSet(); + void setFilterSet(FilterSet filterSet); +} diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/P25ChannelGrantEvent.java b/src/main/java/io/github/dsheirer/module/decode/p25/P25ChannelGrantEvent.java index 377fdcd2..d6f55655 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/P25ChannelGrantEvent.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/P25ChannelGrantEvent.java @@ -21,6 +21,7 @@ package io.github.dsheirer.module.decode.p25; import io.github.dsheirer.channel.IChannelDescriptor; import io.github.dsheirer.identifier.IdentifierCollection; +import io.github.dsheirer.module.decode.event.DecodeEventType; import io.github.dsheirer.module.decode.p25.reference.ServiceOptions; import io.github.dsheirer.protocol.Protocol; @@ -76,6 +77,7 @@ public class P25ChannelGrantEvent extends P25DecodeEvent protected long mTimeStart; protected long mDuration; protected String mEventDescription; + protected DecodeEventType mDecodeEventType; protected IdentifierCollection mIdentifierCollection; protected IChannelDescriptor mChannelDescriptor; protected String mDetails; @@ -132,6 +134,16 @@ public class P25ChannelGrantEvent extends P25DecodeEvent return this; } + /** + * Sets the {@link DecodeEventType} + * @param decodeEventType of the event + */ + public P25ChannelGrantDecodeEventBuilder eventType(DecodeEventType decodeEventType) + { + mDecodeEventType = decodeEventType; + return this; + } + /** * Sets the identifier collection. * @param identifierCollection containing optional identifiers like TO, FROM, frequency and @@ -163,6 +175,7 @@ public class P25ChannelGrantEvent extends P25DecodeEvent decodeEvent.setChannelDescriptor(mChannelDescriptor); decodeEvent.setDetails(mDetails); decodeEvent.setDuration(mDuration); + decodeEvent.setEventType(mDecodeEventType); decodeEvent.setEventDescription(mEventDescription); decodeEvent.setIdentifierCollection(mIdentifierCollection); decodeEvent.setServiceOptions(mServiceOptions); diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/P25TrafficChannelManager.java b/src/main/java/io/github/dsheirer/module/decode/p25/P25TrafficChannelManager.java index 737c542c..af735bb8 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/P25TrafficChannelManager.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/P25TrafficChannelManager.java @@ -268,6 +268,7 @@ public class P25TrafficChannelManager extends TrafficChannelManager implements I { long frequency = apco25Channel.getDownlinkFrequency(); + DecodeEventType decodeEventType = getEventType(opcode, serviceOptions); P25ChannelGrantEvent event = mTS0ChannelGrantEventMap.get(frequency); if(event != null && isSameCall(identifierCollection, event.getIdentifierCollection())) @@ -283,7 +284,8 @@ public class P25TrafficChannelManager extends TrafficChannelManager implements I P25ChannelGrantEvent continuationGrantEvent = P25ChannelGrantEvent.builder(timestamp, serviceOptions) .channel(apco25Channel) - .eventDescription(getEventType(opcode, serviceOptions).toString() + " - Continue") + .eventType(decodeEventType) + .eventDescription(decodeEventType.toString() + " - Continue") .details("PHASE 1 CHANNEL GRANT " + (serviceOptions != null ? serviceOptions : "")) .identifiers(identifierCollection) .build(); @@ -305,7 +307,7 @@ public class P25TrafficChannelManager extends TrafficChannelManager implements I if(trafficChannel != null) { - event.setEventDescription(getEventType(opcode, serviceOptions).toString()); + event.setEventDescription(decodeEventType.toString()); event.setDetails("PHASE 1 CHANNEL GRANT " + (serviceOptions != null ? serviceOptions : "")); event.setChannelDescriptor(apco25Channel); broadcast(event); @@ -328,7 +330,8 @@ public class P25TrafficChannelManager extends TrafficChannelManager implements I { P25ChannelGrantEvent channelGrantEvent = P25ChannelGrantEvent.builder(timestamp, serviceOptions) .channel(apco25Channel) - .eventDescription(getEventType(opcode, serviceOptions).toString() + " - Ignored") + .eventType(decodeEventType) + .eventDescription(decodeEventType.toString() + " - Ignored") .details("DATA CALL IGNORED: " + (serviceOptions != null ? serviceOptions : "")) .identifiers(identifierCollection) .build(); @@ -340,7 +343,8 @@ public class P25TrafficChannelManager extends TrafficChannelManager implements I P25ChannelGrantEvent channelGrantEvent = P25ChannelGrantEvent.builder(timestamp, serviceOptions) .channel(apco25Channel) - .eventDescription(getEventType(opcode, serviceOptions).toString()) + .eventType(decodeEventType) + .eventDescription(decodeEventType.toString()) .details("PHASE 1 CHANNEL GRANT " + (serviceOptions != null ? serviceOptions : "")) .identifiers(identifierCollection) .build(); @@ -411,6 +415,7 @@ public class P25TrafficChannelManager extends TrafficChannelManager implements I } identifierCollection.setTimeslot(timeslot); + DecodeEventType decodeEventType = getEventType(opcode, serviceOptions); if(event != null && isSameCall(identifierCollection, event.getIdentifierCollection())) { @@ -425,7 +430,8 @@ public class P25TrafficChannelManager extends TrafficChannelManager implements I P25ChannelGrantEvent continuationGrantEvent = P25ChannelGrantEvent.builder(timestamp, serviceOptions) .channel(apco25Channel) - .eventDescription(getEventType(opcode, serviceOptions).toString() + " - Continue") + .eventType(decodeEventType) + .eventDescription(decodeEventType.toString() + " - Continue") .details("PHASE 2 CHANNEL GRANT " + (serviceOptions != null ? serviceOptions : "")) .identifiers(identifierCollection) .build(); @@ -455,7 +461,7 @@ public class P25TrafficChannelManager extends TrafficChannelManager implements I if(trafficChannel != null) { - event.setEventDescription(getEventType(opcode, serviceOptions).toString()); + event.setEventDescription(decodeEventType.toString()); event.setDetails("PHASE 2 CHANNEL GRANT " + (serviceOptions != null ? serviceOptions : "")); event.setChannelDescriptor(apco25Channel); broadcast(event); @@ -485,7 +491,8 @@ public class P25TrafficChannelManager extends TrafficChannelManager implements I { P25ChannelGrantEvent channelGrantEvent = P25ChannelGrantEvent.builder(timestamp, serviceOptions) .channel(apco25Channel) - .eventDescription(getEventType(opcode, serviceOptions).toString() + " - Ignored") + .eventType(decodeEventType) + .eventDescription(decodeEventType.toString() + " - Ignored") .details("PHASE 2 DATA CALL IGNORED: " + (serviceOptions != null ? serviceOptions : "")) .identifiers(identifierCollection) .build(); @@ -498,7 +505,8 @@ public class P25TrafficChannelManager extends TrafficChannelManager implements I P25ChannelGrantEvent channelGrantEvent = P25ChannelGrantEvent.builder(timestamp, serviceOptions) .channel(apco25Channel) - .eventDescription(getEventType(opcode, serviceOptions).toString()) + .eventType(decodeEventType) + .eventDescription(decodeEventType.toString()) .details("PHASE 2 CHANNEL GRANT " + (serviceOptions != null ? serviceOptions : "")) .identifiers(identifierCollection) .build(); diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1DecoderState.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1DecoderState.java index bcf50f27..20c00c46 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1DecoderState.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1DecoderState.java @@ -502,17 +502,8 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(ambtc instanceof AMBTCStatusUpdate) { AMBTCStatusUpdate su = (AMBTCStatusUpdate)ambtc; - - MutableIdentifierCollection icStatusUpdate = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icStatusUpdate.remove(IdentifierClass.USER); - icStatusUpdate.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.STATUS.toString()) - .details("UNIT:" + su.getUnitStatus() + " USER:" + su.getUserStatus()) - .identifiers(icStatusUpdate) - .build()); + processBroadcast(ambtc, DecodeEventType.STATUS, + "UNIT:" + su.getUnitStatus() + " USER:" + su.getUserStatus()); } } @@ -520,19 +511,9 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(ambtc instanceof AMBTCProtectionParameterBroadcast) { AMBTCProtectionParameterBroadcast ppb = (AMBTCProtectionParameterBroadcast)ambtc; - - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("USE ENCRYPTION " + ppb.getEncryptionKey() + + processBroadcast(ambtc, DecodeEventType.RESPONSE, "USE ENCRYPTION " + ppb.getEncryptionKey() + " OUTBOUND MI:" + ppb.getOutboundMessageIndicator() + - " INBOUND MI:" + ppb.getInboundMessageIndicator()) - .identifiers(ic) - .build()); + " INBOUND MI:" + ppb.getInboundMessageIndicator()); } } @@ -540,18 +521,8 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(ambtc instanceof AMBTCGroupAffiliationResponse) { AMBTCGroupAffiliationResponse gar = (AMBTCGroupAffiliationResponse)ambtc; - - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("AFFILIATION GROUP:" + gar.getGroupId() + - " ANNOUNCEMENT GROUP:" + gar.getAnnouncementGroupId()) - .identifiers(ic) - .build()); + processBroadcast(ambtc, DecodeEventType.RESPONSE, "AFFILIATION GROUP:" + gar.getGroupId() + + " ANNOUNCEMENT GROUP:" + gar.getAnnouncementGroupId()); } } @@ -560,9 +531,7 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList { AMBTCUnitToUnitVoiceServiceChannelGrantUpdate uuvscgu = (AMBTCUnitToUnitVoiceServiceChannelGrantUpdate)ambtc; - MutableIdentifierCollection identifierCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifierCollection.remove(IdentifierClass.USER); - identifierCollection.update(uuvscgu.getIdentifiers()); + MutableIdentifierCollection identifierCollection = getMutableIdentifierCollection(uuvscgu.getIdentifiers()); processChannelGrant(uuvscgu.getChannel(), uuvscgu.getVoiceServiceOptions(), identifierCollection, ambtc.getHeader().getOpcode(), @@ -575,9 +544,7 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList { AMBTCUnitToUnitVoiceServiceChannelGrant uuvscg = (AMBTCUnitToUnitVoiceServiceChannelGrant)ambtc; - MutableIdentifierCollection identifierCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifierCollection.remove(IdentifierClass.USER); - identifierCollection.update(uuvscg.getIdentifiers()); + MutableIdentifierCollection identifierCollection = getMutableIdentifierCollection(uuvscg.getIdentifiers()); processChannelGrant(uuvscg.getChannel(), uuvscg.getVoiceServiceOptions(), identifierCollection, ambtc.getHeader().getOpcode(), @@ -590,9 +557,7 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList { AMBTCTelephoneInterconnectChannelGrantUpdate ticgu = (AMBTCTelephoneInterconnectChannelGrantUpdate)ambtc; - MutableIdentifierCollection identifierCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifierCollection.remove(IdentifierClass.USER); - identifierCollection.update(ticgu.getIdentifiers()); + MutableIdentifierCollection identifierCollection = getMutableIdentifierCollection(ticgu.getIdentifiers()); processChannelGrant(ticgu.getChannel(), ticgu.getVoiceServiceOptions(), identifierCollection, ambtc.getHeader().getOpcode(), @@ -605,9 +570,7 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList { AMBTCTelephoneInterconnectChannelGrant ticg = (AMBTCTelephoneInterconnectChannelGrant)ambtc; - MutableIdentifierCollection identifierCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifierCollection.remove(IdentifierClass.USER); - identifierCollection.update(ticg.getIdentifiers()); + MutableIdentifierCollection identifierCollection = getMutableIdentifierCollection(ticg.getIdentifiers()); processChannelGrant(ticg.getChannel(), ticg.getVoiceServiceOptions(), identifierCollection, ambtc.getHeader().getOpcode(), @@ -620,9 +583,7 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList { AMBTCIndividualDataChannelGrant idcg = (AMBTCIndividualDataChannelGrant)ambtc; - MutableIdentifierCollection identifierCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifierCollection.remove(IdentifierClass.USER); - identifierCollection.update(idcg.getIdentifiers()); + MutableIdentifierCollection identifierCollection = getMutableIdentifierCollection(idcg.getIdentifiers()); processChannelGrant(idcg.getChannel(), idcg.getDataServiceOptions(), identifierCollection, ambtc.getHeader().getOpcode(), @@ -635,9 +596,7 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList { AMBTCGroupVoiceChannelGrant gvcg = (AMBTCGroupVoiceChannelGrant)ambtc; - MutableIdentifierCollection identifierCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifierCollection.remove(IdentifierClass.USER); - identifierCollection.update(gvcg.getIdentifiers()); + MutableIdentifierCollection identifierCollection = getMutableIdentifierCollection(gvcg.getIdentifiers()); processChannelGrant(gvcg.getChannel(), gvcg.getVoiceServiceOptions(), identifierCollection, ambtc.getHeader().getOpcode(), @@ -650,9 +609,7 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList { AMBTCGroupDataChannelGrant gdcg = (AMBTCGroupDataChannelGrant)ambtc; - MutableIdentifierCollection identifierCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifierCollection.remove(IdentifierClass.USER); - identifierCollection.update(gdcg.getIdentifiers()); + MutableIdentifierCollection identifierCollection = getMutableIdentifierCollection(gdcg.getIdentifiers()); processChannelGrant(gdcg.getChannel(), gdcg.getDataServiceOptions(), identifierCollection, ambtc.getHeader().getOpcode(), ambtc.getTimestamp()); @@ -663,18 +620,8 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(ambtc instanceof AMBTCUnitToUnitVoiceServiceAnswerResponse) { AMBTCUnitToUnitVoiceServiceAnswerResponse uuvsar = (AMBTCUnitToUnitVoiceServiceAnswerResponse)ambtc; - - MutableIdentifierCollection icUnitAnswerResponse = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icUnitAnswerResponse.remove(IdentifierClass.USER); - icUnitAnswerResponse.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details(uuvsar.getAnswerResponse() + " UNIT-2-UNIT VOICE SERVICE " + - uuvsar.getVoiceServiceOptions()) - .identifiers(icUnitAnswerResponse) - .build()); + processBroadcast(ambtc, DecodeEventType.RESPONSE, + uuvsar.getAnswerResponse() + " UNIT-2-UNIT VOICE SERVICE " + uuvsar.getVoiceServiceOptions()); } } @@ -682,56 +629,52 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(ambtc instanceof AMBTCStatusUpdateRequest) { AMBTCStatusUpdateRequest sur = (AMBTCStatusUpdateRequest)ambtc; - - MutableIdentifierCollection icStatusUpdateRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icStatusUpdateRequest.remove(IdentifierClass.USER); - icStatusUpdateRequest.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.STATUS.toString()) - .details("UNIT:" + sur.getUnitStatus() + " USER:" + sur.getUserStatus()) - .identifiers(icStatusUpdateRequest) - .build()); + processBroadcast(ambtc, DecodeEventType.STATUS, + "UNIT:" + sur.getUnitStatus() + " USER:" + sur.getUserStatus()); } } private void processAMBTCStatusQueryResponse(AMBTCMessage ambtc) { if(ambtc instanceof AMBTCStatusQueryResponse) { - MutableIdentifierCollection icStatusQueryResponse = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icStatusQueryResponse.remove(IdentifierClass.USER); - icStatusQueryResponse.update(ambtc.getIdentifiers()); - AMBTCStatusQueryResponse sqr = (AMBTCStatusQueryResponse)ambtc; - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.STATUS.toString()) - .details("UNIT:" + sqr.getUnitStatus() + " USER:" + sqr.getUserStatus()) - .identifiers(icStatusQueryResponse) - .build()); + processBroadcast(ambtc, DecodeEventType.STATUS, + "UNIT:" + sqr.getUnitStatus() + " USER:" + sqr.getUserStatus()); } } + private void processBroadcast(AMBTCMessage ambtcMessage, DecodeEventType request, String details) { + processBroadcast(ambtcMessage.getIdentifiers(), ambtcMessage.getTimestamp(), request, details); + } + + private void processBroadcast(TSBKMessage tsbkMessage, DecodeEventType request, String details) { + processBroadcast(tsbkMessage.getIdentifiers(), tsbkMessage.getTimestamp(), request, details); + } + private void processBroadcast(List identifiers, long timestamp, DecodeEventType request, String s) { - MutableIdentifierCollection requestCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - requestCollection.remove(IdentifierClass.USER); - requestCollection.update(identifiers); + MutableIdentifierCollection requestCollection = getMutableIdentifierCollection(identifiers); broadcast(P25DecodeEvent.builder(timestamp) .channel(getCurrentChannel()) + .eventType(request) .eventDescription(request.toString()) .details(s) .identifiers(requestCollection) .build()); } + private MutableIdentifierCollection getMutableIdentifierCollection(List identifiers) { + MutableIdentifierCollection requestCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + requestCollection.remove(IdentifierClass.USER); + requestCollection.update(identifiers); + return requestCollection; + } + private void processAMBTCIspAuthenticationResponse(P25Message message, AMBTCMessage ambtc) { if(message instanceof AMBTCAuthenticationResponse) { AMBTCAuthenticationResponse ar = (AMBTCAuthenticationResponse)ambtc; - - processBroadcast(ambtc.getIdentifiers(), ambtc.getTimestamp(), DecodeEventType.RESPONSE, "AUTHENTICATION:" + ar.getAuthenticationValue()); + processBroadcast(ambtc, DecodeEventType.RESPONSE, "AUTHENTICATION:" + ar.getAuthenticationValue()); } } @@ -1061,67 +1004,37 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList SNDCPMessage sndcpMessage = sndcpPacket.getSNDCPMessage(); - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(sndcpPacket.getIdentifiers()); + MutableIdentifierCollection ic = getMutableIdentifierCollection(sndcpPacket.getIdentifiers()); switch(sndcpPacket.getSNDCPPacketHeader().getPDUType()) { case OUTBOUND_SNDCP_ACTIVATE_TDS_CONTEXT_ACCEPT: - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("SNDCP ACTIVATE TDS CONTEXT ACCEPT") - .identifiers(ic) - .build()); + processBroadcast(sndcpPacket.getIdentifiers(), message.getTimestamp(), + DecodeEventType.RESPONSE, "SNDCP ACTIVATE TDS CONTEXT ACCEPT"); break; case OUTBOUND_SNDCP_DEACTIVATE_TDS_CONTEXT_ACCEPT: - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("SNDCP DEACTIVATE TDS CONTEXT ACCEPT") - .identifiers(ic) - .build()); + processBroadcast(sndcpPacket.getIdentifiers(), message.getTimestamp(), + DecodeEventType.RESPONSE, "SNDCP DEACTIVATE TDS CONTEXT ACCEPT"); break; case OUTBOUND_SNDCP_DEACTIVATE_TDS_CONTEXT_REQUEST: - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("SNDCP DEACTIVATE TDS CONTEXT") - .identifiers(ic) - .build()); + processBroadcast(sndcpPacket.getIdentifiers(), message.getTimestamp(), + DecodeEventType.REQUEST, "SNDCP DEACTIVATE TDS CONTEXT"); break; case OUTBOUND_SNDCP_ACTIVATE_TDS_CONTEXT_REJECT: - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("SNDCP ACTIVATE TDS CONTEXT REJECT") - .identifiers(ic) - .build()); + processBroadcast(sndcpPacket.getIdentifiers(), message.getTimestamp(), + DecodeEventType.RESPONSE, "SNDCP ACTIVATE TDS CONTEXT REJECT"); break; case INBOUND_SNDCP_ACTIVATE_TDS_CONTEXT_REQUEST: - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("SNDCP ACTIVATE TDS CONTEXT") - .identifiers(ic) - .build()); + processBroadcast(sndcpPacket.getIdentifiers(), message.getTimestamp(), + DecodeEventType.REQUEST, "SNDCP ACTIVATE TDS CONTEXT"); break; case INBOUND_SNDCP_DEACTIVATE_TDS_CONTEXT_ACCEPT: - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("SNDCP DEACTIVATE TDS CONTEXT ACCEPT") - .identifiers(ic) - .build()); + processBroadcast(sndcpPacket.getIdentifiers(), message.getTimestamp(), + DecodeEventType.RESPONSE, "SNDCP DEACTIVATE TDS CONTEXT ACCEPT"); break; case INBOUND_SNDCP_DEACTIVATE_TDS_CONTEXT_REQUEST: - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("SNDCP DEACTIVATE TDS CONTEXT") - .identifiers(ic) - .build()); + processBroadcast(sndcpPacket.getIdentifiers(), message.getTimestamp(), + DecodeEventType.REQUEST, "SNDCP DEACTIVATE TDS CONTEXT"); break; } } @@ -1408,49 +1321,30 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(tsbk instanceof MotorolaDenyResponse) { MotorolaDenyResponse dr = (MotorolaDenyResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("DENY: " + dr.getDeniedServiceType().getDescription() + - " REASON: " + dr.getDenyReason() + " - INFO: " + dr.getAdditionalInfo()) - .identifiers(ic) - .build()); + processBroadcast(tsbk, DecodeEventType.RESPONSE, + "DENY: " + dr.getDeniedServiceType().getDescription() + + " REASON: " + dr.getDenyReason() + " - INFO: " + dr.getAdditionalInfo()); } } private void processTSBKRoamingAddressRequest(TSBKMessage tsbk) { - MutableIdentifierCollection icRoamingRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icRoamingRequest.remove(IdentifierClass.USER); - icRoamingRequest.update(tsbk.getIdentifiers()); - + //TODO: not sure if this should be used or not. broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) .channel(getCurrentChannel()) .eventDescription(DecodeEventType.REQUEST.toString()) .details("ROAMING ADDRESS") + // TODO: This identifierCollection is different from all the others. .identifiers(new IdentifierCollection(tsbk.getIdentifiers())) .build()); - return; } private void processTSBKLocationRegistrationRequest(TSBKMessage tsbk) { if(tsbk instanceof LocationRegistrationRequest) { LocationRegistrationRequest lrr = (LocationRegistrationRequest)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REGISTER.toString()) - .details((lrr.isEmergency() ? "EMERGENCY " : "") + - "LOCATION REGISTRATION REQUEST - CAPABILITY:" + lrr.getCapability()) - .identifiers(ic) - .build()); + processBroadcast(tsbk, DecodeEventType.REGISTER, + (lrr.isEmergency() ? "EMERGENCY " : "") + + "LOCATION REGISTRATION REQUEST - CAPABILITY:" + lrr.getCapability()); } } @@ -1458,17 +1352,9 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(tsbk instanceof UnitRegistrationRequest) { UnitRegistrationRequest urr = (UnitRegistrationRequest)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REGISTER.toString()) - .details((urr.isEmergency() ? "EMERGENCY " : "") + - "UNIT REGISTRATION REQUEST - CAPABILITY:" + urr.getCapability()) - .identifiers(ic) - .build()); + processBroadcast(tsbk, DecodeEventType.REGISTER, + (urr.isEmergency() ? "EMERGENCY " : "") + + "UNIT REGISTRATION REQUEST - CAPABILITY:" + urr.getCapability()); } } @@ -1476,17 +1362,9 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(tsbk instanceof GroupAffiliationQueryResponse) { GroupAffiliationQueryResponse gaqr = (GroupAffiliationQueryResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("AFFILIATION - GROUP:" + gaqr.getGroupAddress() + - " ANNOUNCEMENT GROUP:" + gaqr.getAnnouncementGroupAddress()) - .identifiers(ic) - .build()); + processBroadcast(tsbk, DecodeEventType.RESPONSE, + "AFFILIATION - GROUP:" + gaqr.getGroupAddress() + + " ANNOUNCEMENT GROUP:" + gaqr.getAnnouncementGroupAddress()); } } @@ -1494,17 +1372,9 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(tsbk instanceof ExtendedFunctionResponse) { ExtendedFunctionResponse efr = (ExtendedFunctionResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("EXTENDED FUNCTION:" + efr.getExtendedFunction() + - " ARGUMENTS:" + efr.getArguments()) - .identifiers(ic) - .build()); + processBroadcast(tsbk, DecodeEventType.RESPONSE, + "EXTENDED FUNCTION:" + efr.getExtendedFunction() + + " ARGUMENTS:" + efr.getArguments()); } } @@ -1512,18 +1382,10 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(tsbk instanceof CancelServiceRequest) { CancelServiceRequest csr = (CancelServiceRequest)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("CANCEL SERVICE:" + csr.getServiceType() + + processBroadcast(tsbk, DecodeEventType.REQUEST, + "CANCEL SERVICE:" + csr.getServiceType() + " REASON:" + csr.getCancelReason() + (csr.hasAdditionalInformation() ? - " INFO:" + csr.getAdditionalInformation() : "")) - .identifiers(ic) - .build()); + " INFO:" + csr.getAdditionalInformation() : "")); } } @@ -1531,16 +1393,8 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(tsbk instanceof StatusQueryResponse) { StatusQueryResponse sqr = (StatusQueryResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.STATUS.toString()) - .details("UNIT:" + sqr.getUnitStatus() + " USER:" + sqr.getUserStatus()) - .identifiers(ic) - .build()); + processBroadcast(tsbk, DecodeEventType.STATUS, + "UNIT:" + sqr.getUnitStatus() + " USER:" + sqr.getUserStatus()); } } @@ -1548,16 +1402,8 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(tsbk instanceof StatusUpdateRequest) { StatusUpdateRequest sur = (StatusUpdateRequest)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.STATUS.toString()) - .details("UNIT:" + sur.getUnitStatus() + " USER:" + sur.getUserStatus()) - .identifiers(ic) - .build()); + processBroadcast(tsbk, DecodeEventType.STATUS, + "UNIT:" + sur.getUnitStatus() + " USER:" + sur.getUserStatus()); } } @@ -1565,17 +1411,10 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(tsbk instanceof SNDCPReconnectRequest) { SNDCPReconnectRequest srr = (SNDCPReconnectRequest)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("SNDCP RECONNECT " + (srr.hasDataToSend() ? "- DATA TO SEND " : "") + processBroadcast(tsbk, DecodeEventType.REQUEST, + "SNDCP RECONNECT " + (srr.hasDataToSend() ? "- DATA TO SEND " : "") + srr.getDataServiceOptions()) - .identifiers(ic) - .build()); +; } } @@ -1583,16 +1422,8 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(tsbk instanceof SNDCPDataPageResponse) { SNDCPDataPageResponse sdpr = (SNDCPDataPageResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details(sdpr.getAnswerResponse() + " SNDCP DATA " + sdpr.getDataServiceOptions()) - .identifiers(ic) - .build()); + processBroadcast(tsbk, DecodeEventType.RESPONSE, + sdpr.getAnswerResponse() + " SNDCP DATA " + sdpr.getDataServiceOptions()); } } @@ -1600,16 +1431,8 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(tsbk instanceof TelephoneInterconnectAnswerResponse) { TelephoneInterconnectAnswerResponse tiar = (TelephoneInterconnectAnswerResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details(tiar.getAnswerResponse() + " TELEPHONE INTERCONNECT " + tiar.getVoiceServiceOptions()) - .identifiers(ic) - .build()); + processBroadcast(tsbk, DecodeEventType.RESPONSE, + tiar.getAnswerResponse() + " TELEPHONE INTERCONNECT " + tiar.getVoiceServiceOptions()); } } @@ -1617,16 +1440,8 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(tsbk instanceof UnitToUnitVoiceServiceAnswerResponse) { UnitToUnitVoiceServiceAnswerResponse uuvsar = (UnitToUnitVoiceServiceAnswerResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details(uuvsar.getAnswerResponse() + " UNIT-2-UNIT VOICE SERVICE " + uuvsar.getVoiceServiceOptions()) - .identifiers(ic) - .build()); + processBroadcast(tsbk, DecodeEventType.RESPONSE, + uuvsar.getAnswerResponse() + " UNIT-2-UNIT VOICE SERVICE " + uuvsar.getVoiceServiceOptions()); } } @@ -1634,16 +1449,8 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(tsbk instanceof UnitRegistrationResponse) { UnitRegistrationResponse urr = (UnitRegistrationResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REGISTER.toString()) - .details(urr.getResponse() + " UNIT REGISTRATION - UNIT ID:" + urr.getTargetUniqueId()) - .identifiers(ic) - .build()); + processBroadcast(tsbk, DecodeEventType.REGISTER, + urr.getResponse() + " UNIT REGISTRATION - UNIT ID:" + urr.getTargetUniqueId()); } } @@ -1651,16 +1458,8 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(tsbk instanceof LocationRegistrationResponse) { LocationRegistrationResponse lrr = (LocationRegistrationResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REGISTER.toString()) - .details(lrr.getResponse() + " LOCATION REGISTRATION - GROUP:" + lrr.getGroupAddress()) - .identifiers(ic) - .build()); + processBroadcast(tsbk, DecodeEventType.REGISTER, + lrr.getResponse() + " LOCATION REGISTRATION - GROUP:" + lrr.getGroupAddress()); } } @@ -1668,19 +1467,10 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(tsbk instanceof GroupAffiliationResponse) { GroupAffiliationResponse gar = (GroupAffiliationResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details(gar.getAffiliationResponse() + + processBroadcast(tsbk, DecodeEventType.RESPONSE, gar.getAffiliationResponse() + " AFFILIATION GROUP: " + gar.getGroupAddress() + (gar.isGlobalAffiliation() ? " (GLOBAL)" : " (LOCAL)") + - " ANNOUNCEMENT GROUP:" + gar.getAnnouncementGroupAddress()) - .identifiers(ic) - .build()); + " ANNOUNCEMENT GROUP:" + gar.getAnnouncementGroupAddress()); } } @@ -1688,35 +1478,19 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(tsbk instanceof DenyResponse) { DenyResponse dr = (DenyResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("DENY: " + dr.getDeniedServiceType().getDescription() + - " REASON: " + dr.getDenyReason() + " - INFO: " + dr.getAdditionalInfo()) - .identifiers(ic) - .build()); + processBroadcast(tsbk, DecodeEventType.RESPONSE, + "DENY: " + dr.getDeniedServiceType().getDescription() + + " REASON: " + dr.getDenyReason() + " - INFO: " + dr.getAdditionalInfo()); } } private void processTSBKExtendedFunctionCommand(TSBKMessage tsbk) { if(tsbk instanceof ExtendedFunctionCommand) { - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - ExtendedFunctionCommand efc = (ExtendedFunctionCommand)tsbk; - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.COMMAND.toString()) - .details("EXTENDED FUNCTION: " + efc.getExtendedFunction() + - " ARGUMENTS:" + efc.getArguments()) - .identifiers(ic) - .build()); + processBroadcast(tsbk, DecodeEventType.COMMAND, + "EXTENDED FUNCTION: " + efc.getExtendedFunction() + + " ARGUMENTS:" + efc.getArguments()); } } @@ -1724,35 +1498,19 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(tsbk instanceof QueuedResponse) { QueuedResponse qr = (QueuedResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("QUEUED: " + qr.getQueuedResponseServiceType().getDescription() + + processBroadcast(tsbk, DecodeEventType.RESPONSE, + "QUEUED: " + qr.getQueuedResponseServiceType().getDescription() + " REASON: " + qr.getQueuedResponseReason() + - " INFO: " + qr.getAdditionalInfo()) - .identifiers(ic) - .build()); + " INFO: " + qr.getAdditionalInfo()); } } private void processTSBKAcknowledgeResponse(TSBKMessage tsbk) { if(tsbk instanceof AcknowledgeResponse) { - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - AcknowledgeResponse ar = (AcknowledgeResponse)tsbk; - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("ACKNOWLEDGE " + ar.getAcknowledgedServiceType().getDescription()) - .identifiers(ic) - .build()); + processBroadcast(tsbk, DecodeEventType.RESPONSE, + "ACKNOWLEDGE " + ar.getAcknowledgedServiceType().getDescription()); } } @@ -1760,34 +1518,17 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(tsbk instanceof StatusUpdate) { StatusUpdate su = (StatusUpdate)tsbk; - - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.STATUS.toString()) - .details("UNIT:" + su.getUnitStatus() + " USER:" + su.getUserStatus()) - .identifiers(ic) - .build()); + processBroadcast(tsbk, DecodeEventType.STATUS, + "UNIT:" + su.getUnitStatus() + " USER:" + su.getUserStatus()); } } private void processTSBKTelephoneInterconnectAnswerRequest(TSBKMessage tsbk) { if(tsbk instanceof TelephoneInterconnectAnswerRequest) { - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - TelephoneInterconnectAnswerRequest tiar = (TelephoneInterconnectAnswerRequest)tsbk; - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.PAGE.toString()) - .details("TELEPHONE ANSWER REQUEST: " + tiar.getTelephoneNumber()) - .identifiers(ic) - .build()); + processBroadcast(tsbk, DecodeEventType.PAGE, + "TELEPHONE ANSWER REQUEST: " + tiar.getTelephoneNumber()); } } @@ -1841,9 +1582,7 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList TelephoneInterconnectVoiceChannelGrantUpdate tivcgu = (TelephoneInterconnectVoiceChannelGrantUpdate)tsbk; //Make a copy of current identifiers and remove current user identifiers and replace from message - MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifiers.remove(IdentifierClass.USER); - identifiers.update(tivcgu.getIdentifiers()); + MutableIdentifierCollection identifiers = getMutableIdentifierCollection(tivcgu.getIdentifiers()); processChannelGrant(tivcgu.getChannel(), tivcgu.getVoiceServiceOptions(), identifiers, tsbk.getOpcode(), tivcgu.getTimestamp()); @@ -1856,9 +1595,7 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList SNDCPDataChannelGrant dcg = (SNDCPDataChannelGrant)tsbk; //Make a copy of current identifiers and remove current user identifiers and replace from message - MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifiers.remove(IdentifierClass.USER); - identifiers.update(dcg.getIdentifiers()); + MutableIdentifierCollection identifiers = getMutableIdentifierCollection(dcg.getIdentifiers()); processChannelGrant(dcg.getChannel(), dcg.getServiceOptions(), identifiers, tsbk.getOpcode(), dcg.getTimestamp()); @@ -1871,9 +1608,7 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList TelephoneInterconnectVoiceChannelGrant tivcg = (TelephoneInterconnectVoiceChannelGrant)tsbk; //Make a copy of current identifiers and remove current user identifiers and replace from message - MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifiers.remove(IdentifierClass.USER); - identifiers.update(tivcg.getIdentifiers()); + MutableIdentifierCollection identifiers = getMutableIdentifierCollection(tivcg.getIdentifiers()); processChannelGrant(tivcg.getChannel(), tivcg.getVoiceServiceOptions(), identifiers, tsbk.getOpcode(), tivcg.getTimestamp()); @@ -1886,9 +1621,7 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList UnitToUnitVoiceChannelGrantUpdate uuvcgu = (UnitToUnitVoiceChannelGrantUpdate)tsbk; //Make a copy of current identifiers and remove current user identifiers and replace from message - MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifiers.remove(IdentifierClass.USER); - identifiers.update(uuvcgu.getIdentifiers()); + MutableIdentifierCollection identifiers = getMutableIdentifierCollection(uuvcgu.getIdentifiers()); processChannelGrant(uuvcgu.getChannel(), null, identifiers, tsbk.getOpcode(), uuvcgu.getTimestamp()); @@ -1901,9 +1634,7 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList UnitToUnitVoiceChannelGrant uuvcg = (UnitToUnitVoiceChannelGrant)tsbk; //Make a copy of current identifiers and remove current user identifiers and replace from message - MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifiers.remove(IdentifierClass.USER); - identifiers.update(uuvcg.getIdentifiers()); + MutableIdentifierCollection identifiers = getMutableIdentifierCollection(uuvcg.getIdentifiers()); processChannelGrant(uuvcg.getChannel(), null, identifiers, tsbk.getOpcode(), uuvcg.getTimestamp()); @@ -2080,18 +1811,9 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(lcw instanceof LCExtendedFunctionCommand) { LCExtendedFunctionCommand efc = (LCExtendedFunctionCommand)lcw; - - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(lcw.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(timestamp) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.COMMAND.toString()) - .details("Extended Function: " + efc.getExtendedFunction() + - " Arguments:" + efc.getExtendedFunctionArguments()) - .identifiers(ic) - .build()); + processBroadcast(lcw.getIdentifiers(), timestamp, DecodeEventType.COMMAND, + "Extended Function: " + efc.getExtendedFunction() + + " Arguments:" + efc.getExtendedFunctionArguments()); } break; case GROUP_AFFILIATION_QUERY: @@ -2100,17 +1822,9 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList case MESSAGE_UPDATE: if(lcw instanceof LCMessageUpdate) { - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(lcw.getIdentifiers()); - LCMessageUpdate mu = (LCMessageUpdate)lcw; - broadcast(P25DecodeEvent.builder(timestamp) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.SDM.toString()) - .details("MSG:" + mu.getShortDataMessage()) - .identifiers(ic) - .build()); + processBroadcast(lcw.getIdentifiers(), timestamp, DecodeEventType.SDM, + "MSG:" + mu.getShortDataMessage()); } break; case STATUS_QUERY: @@ -2120,17 +1834,8 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(lcw instanceof LCStatusUpdate) { LCStatusUpdate su = (LCStatusUpdate)lcw; - - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(lcw.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(timestamp) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.STATUS.toString()) - .details("UNIT:" + su.getUnitStatus() + " USER:" + su.getUserStatus()) - .identifiers(ic) - .build()); + processBroadcast(lcw.getIdentifiers(), timestamp, DecodeEventType.STATUS, + "UNIT:" + su.getUnitStatus() + " USER:" + su.getUserStatus()); } break; case TELEPHONE_INTERCONNECT_ANSWER_REQUEST: