diff --git a/src/controller/ConfigurationTreePanel.java b/src/controller/ConfigurationTreePanel.java index 329de155..9644f1b8 100644 --- a/src/controller/ConfigurationTreePanel.java +++ b/src/controller/ConfigurationTreePanel.java @@ -52,7 +52,7 @@ public class ConfigurationTreePanel extends JPanel mSystemTree.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION ); mSystemTree.setShowsRootHandles( true ); - mSystemTree.addMouseListener( new Handler() ); + mSystemTree.addMouseListener( new MouseHandler() ); mSystemTree.setCellRenderer( new ControllerTreeCellRenderer() ); //Give the model a reference to the tree, so that it can force newly @@ -68,9 +68,9 @@ public class ConfigurationTreePanel extends JPanel mSystemTree.addTreeSelectionListener( listener ); } - public class Handler implements MouseListener + public class MouseHandler implements MouseListener { - public Handler() + public MouseHandler() { } diff --git a/src/controller/ControllerPanel.java b/src/controller/ControllerPanel.java index a0eaf0a2..145e5271 100644 --- a/src/controller/ControllerPanel.java +++ b/src/controller/ControllerPanel.java @@ -21,6 +21,7 @@ import java.awt.Color; import java.awt.Component; import java.awt.Dimension; +import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; @@ -131,7 +132,7 @@ public class ControllerPanel extends JPanel MapPanel mapPanel = new MapPanel( mResourceManager ); mTabbedPane.addTab( "Map", mapPanel ); - + /* Channel state list */ mChannelStateList = new ChannelStateList( mResourceManager.getSettingsManager() ); diff --git a/src/controller/activity/ActivitySummaryFrame.java b/src/controller/activity/ActivitySummaryFrame.java index c4d7bbaf..8541ccb5 100644 --- a/src/controller/activity/ActivitySummaryFrame.java +++ b/src/controller/activity/ActivitySummaryFrame.java @@ -18,8 +18,10 @@ package controller.activity; import java.awt.Component; +import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.lang.reflect.InvocationTargetException; import javax.swing.JButton; import javax.swing.JFrame; @@ -63,7 +65,13 @@ public class ActivitySummaryFrame extends JFrame } ); add( close ); - - setVisible( true ); + + EventQueue.invokeLater( new Runnable() + { + public void run() + { + setVisible( true ); + } + } ); } } diff --git a/src/controller/activity/MessageActivityModel.java b/src/controller/activity/MessageActivityModel.java index cfb5ea54..40a134bd 100644 --- a/src/controller/activity/MessageActivityModel.java +++ b/src/controller/activity/MessageActivityModel.java @@ -25,6 +25,7 @@ import javax.swing.table.AbstractTableModel; import message.Message; import sample.Listener; +import filter.FilterSet; public class MessageActivityModel extends AbstractTableModel implements Listener @@ -51,10 +52,41 @@ public class MessageActivityModel extends AbstractTableModel private boolean mNewMessagesFirst = true; + private FilterSet mMessageFilter; + + public MessageActivityModel( FilterSet messageFilter ) + { + mMessageFilter = messageFilter; + } + public MessageActivityModel() { } + /** + * Clears all messages from history + */ + public void clear() + { + EventQueue.invokeLater( new Runnable() + { + @Override + public void run() + { + int messageCount = mMessages.size(); + + mMessages.clear(); + + fireTableRowsDeleted( 0, messageCount - 1 ); + } + }); + } + + public FilterSet getMessageFilter() + { + return mMessageFilter; + } + public void dispose() { mMessages.clear(); @@ -90,18 +122,21 @@ public class MessageActivityModel extends AbstractTableModel public void receive( final Message message ) { - EventQueue.invokeLater( new Runnable() + if( mMessageFilter.passes( message ) ) { - @Override - public void run() - { - mMessages.addFirst( message ); + EventQueue.invokeLater( new Runnable() + { + @Override + public void run() + { + mMessages.addFirst( message ); - MessageActivityModel.this.fireTableRowsInserted( 0, 0 ); + MessageActivityModel.this.fireTableRowsInserted( 0, 0 ); - prune(); - } - } ); + prune(); + } + } ); + } } private void prune() diff --git a/src/controller/activity/MessageActivityPanel.java b/src/controller/activity/MessageActivityPanel.java index 6be195de..8ce74cb2 100644 --- a/src/controller/activity/MessageActivityPanel.java +++ b/src/controller/activity/MessageActivityPanel.java @@ -17,11 +17,37 @@ ******************************************************************************/ package controller.activity; +import filter.FilterEditorPanel; +import filter.FilterSet; +import gui.SDRTrunk; + +import java.awt.EventQueue; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; +import javax.swing.JSlider; import javax.swing.JTable; +import javax.swing.SwingUtilities; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import message.Message; import net.miginfocom.swing.MigLayout; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.jidesoft.swing.JideButton; +import com.jidesoft.swing.JideSplitButton; + import controller.channel.Channel; import controller.channel.ChannelEvent; import controller.channel.ChannelEvent.Event; @@ -30,23 +56,33 @@ import controller.channel.ChannelEventListener; public class MessageActivityPanel extends JPanel implements ChannelEventListener { private static final long serialVersionUID = 1L; + + private final static Logger mLog = LoggerFactory.getLogger( SDRTrunk.class ); + + private static MessageActivityModel EMPTY_MODEL = new MessageActivityModel(); + + private JTable mMessageTable; - private JScrollPane mEmptyScrollPane; private Channel mDisplayedChannel; + + private MessageManagementPanel mManagementPanel = new MessageManagementPanel(); public MessageActivityPanel() { - setLayout( new MigLayout("insets 0 0 0 0 ", "[grow,fill]", "[grow,fill]") ); + setLayout( new MigLayout("insets 0 0 0 0", "[][grow,fill]", "[]0[grow,fill]") ); - mEmptyScrollPane = - new JScrollPane( new JTable( new MessageActivityModel() ) ); + add( mManagementPanel, "span,growx" ); + + mMessageTable = new JTable( EMPTY_MODEL ); - add( mEmptyScrollPane ); + add( new JScrollPane( mMessageTable ), "span,grow" ); } @Override public void channelChanged( ChannelEvent event ) { + boolean changed = false; + if( event.getEvent() == Event.CHANGE_SELECTED && event.getChannel().isSelected() ) { @@ -54,18 +90,21 @@ public class MessageActivityPanel extends JPanel implements ChannelEventListener ( mDisplayedChannel != null && mDisplayedChannel != event.getChannel() ) ) { - removeAll(); - - JScrollPane scroll = - new JScrollPane( event.getChannel().getProcessingChain() - .getChannelState().getMessageActivityTable() ); - - add( scroll ); - mDisplayedChannel = event.getChannel(); + + mMessageTable.setModel( event.getChannel().getProcessingChain() + .getChannelState().getMessageActivityModel() ); + + if( mDisplayedChannel != null ) + { + mManagementPanel.enable(); + } + else + { + mManagementPanel.disable(); + } - revalidate(); - repaint(); + changed = true; } } else if( event.getEvent() == Event.PROCESSING_STOPPED || @@ -75,12 +114,203 @@ public class MessageActivityPanel extends JPanel implements ChannelEventListener mDisplayedChannel == event.getChannel() ) { mDisplayedChannel = null; - removeAll(); - add( mEmptyScrollPane ); - revalidate(); - repaint(); + mMessageTable.setModel( EMPTY_MODEL ); + + mManagementPanel.disable(); + + changed = true; } } + + if( changed ) + { + revalidate(); + repaint(); + } } + + public class MessageManagementPanel extends JPanel + { + private static final long serialVersionUID = 1L; + + private MessageHistoryButton mHistoryButton = new MessageHistoryButton(); + private MessageFilterButton mFilterButton = new MessageFilterButton(); + + public MessageManagementPanel() + { + setLayout( new MigLayout("insets 2 2 5 5", "[]5[left,grow]", "") ); + + disable(); + + add( mFilterButton ); + add( mHistoryButton ); + } + + public void enable() + { + mHistoryButton.setEnabled( true ); + mFilterButton.setEnabled( true ); + } + + public void disable() + { + mHistoryButton.setEnabled( false ); + mFilterButton.setEnabled( false ); + } + } + + public class MessageHistoryButton extends JideSplitButton + { + private static final long serialVersionUID = 1L; + + public MessageHistoryButton() + { + super( "Clear" ); + + JPanel historyPanel = new JPanel(); + + historyPanel.add( new JLabel( "Message History:" ) ); + + 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 ) {} + } ); + + if( mDisplayedChannel != null ) + { + slider.setValue( mDisplayedChannel.getProcessingChain() + .getChannelState().getMessageActivityModel() + .getMaxMessageCount() ); + } + else + { + slider.setValue( 500 ); + } + + slider.addChangeListener( new ChangeListener() + { + @Override + public void stateChanged( ChangeEvent arg0 ) + { + if( mDisplayedChannel != null ) + { + mDisplayedChannel.getProcessingChain().getChannelState() + .getMessageActivityModel() + .setMaxMessageCount( slider.getValue() ); + } + } + }); + + historyPanel.add( slider ); + + add( historyPanel ); + + /* Clear messages */ + addActionListener( new ActionListener() + { + @Override + public void actionPerformed( ActionEvent e ) + { + if( mDisplayedChannel != null ) + { + mDisplayedChannel.getProcessingChain().getChannelState() + .getMessageActivityModel().clear(); + } + } + } ); + } + } + + public class MessageFilterButton extends JideButton + { + private static final long serialVersionUID = 1L; + + public MessageFilterButton() + { + super( "Filter" ); + + addActionListener( new ActionListener() + { + @Override + public void actionPerformed( ActionEvent arg0 ) + { + if( mDisplayedChannel == null ) + { + JOptionPane.showMessageDialog( MessageFilterButton.this, + "Please enable and select a decoding channel to " + + "adjust the channel's message display filter" ); + } + else + { + final JFrame editor = new JFrame(); + + editor.setTitle( "Message Filter Editor" ); + editor.setSize( 600, 400 ); + editor.setLocationRelativeTo( MessageFilterButton.this ); + editor.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE ); + editor.setLayout( new MigLayout( "", "[grow,fill]", + "[grow,fill][][]" ) ); + + @SuppressWarnings( "unchecked" ) + FilterSet filter = + mDisplayedChannel + .getProcessingChain().getChannelState() + .getMessageActivityModel().getMessageFilter(); + + FilterEditorPanel panel = + new FilterEditorPanel( filter ); + + 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 ); + } + } ); + } + } + } ); + } + } } diff --git a/src/controller/state/ChannelState.java b/src/controller/state/ChannelState.java index 26d1f384..0bf97e1b 100644 --- a/src/controller/state/ChannelState.java +++ b/src/controller/state/ChannelState.java @@ -26,6 +26,7 @@ import java.util.concurrent.TimeUnit; import javax.swing.JTable; import message.Message; +import message.MessageFilterFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,6 +46,7 @@ import controller.activity.CallEventModel; import controller.activity.MessageActivityModel; import controller.channel.Channel.ChannelType; import controller.channel.ProcessingChain; +import filter.FilterSet; /** * ChannelState provides a state machine for tracking a voice or data call @@ -108,8 +110,7 @@ public abstract class ChannelState implements Listener protected JTable mCallEventTable; - protected MessageActivityModel mMessageActivityModel = - new MessageActivityModel(); + protected MessageActivityModel mMessageActivityModel; protected JTable mMessageActivityTable; protected ProcessingChain mProcessingChain; @@ -130,6 +131,12 @@ public abstract class ChannelState implements Listener SystemProperties props = SystemProperties.getInstance(); mCallFadeTimeout = props.get( "call.fade.timeout", 2000 ); mCallResetTimeout = props.get( "call.reset.timeout", 4000 ); + + /* Get a message filter for the primary decoder and aux decoders */ + FilterSet messageFilter = MessageFilterFactory + .getMessageFilter( mProcessingChain.getChannel() ); + + mMessageActivityModel = new MessageActivityModel( messageFilter ); } public void setCurrentCallEvent( CallEvent callEvent ) @@ -240,20 +247,11 @@ public abstract class ChannelState implements Listener } /** - * Returns the message activity model wrapped in a JTable. Although this - * may seem to violate separation between model and view, it simplifies - * retaining the JTable state for each channel by keeping a local reference - * to reuse + * Returns the message activity model. */ - public JTable getMessageActivityTable() + public MessageActivityModel getMessageActivityModel() { - if( mMessageActivityTable == null ) - { - mMessageActivityTable = new JTable( mMessageActivityModel ); - mMessageActivityTable.setAutoResizeMode( JTable.AUTO_RESIZE_LAST_COLUMN ); - } - - return mMessageActivityTable; + return mMessageActivityModel; } public void addAuxChannelState( AuxChannelState state ) diff --git a/src/decode/DecoderType.java b/src/decode/DecoderType.java index f6013176..c300b6e2 100644 --- a/src/decode/DecoderType.java +++ b/src/decode/DecoderType.java @@ -67,7 +67,7 @@ public enum DecoderType DecoderType.LTR_STANDARD, DecoderType.MPT1327, DecoderType.NBFM, - DecoderType.P25_PHASE1, +// DecoderType.P25_PHASE1, DecoderType.PASSPORT ); } diff --git a/src/decode/fleetsync2/FleetsyncMessageFilter.java b/src/decode/fleetsync2/FleetsyncMessageFilter.java new file mode 100644 index 00000000..8c04a308 --- /dev/null +++ b/src/decode/fleetsync2/FleetsyncMessageFilter.java @@ -0,0 +1,56 @@ +package decode.fleetsync2; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import message.Message; +import filter.Filter; +import filter.FilterElement; + +public class FleetsyncMessageFilter extends Filter +{ + private HashMap> mElements = + new HashMap>(); + + public FleetsyncMessageFilter() + { + super( "Fleetsync Message Filter" ); + + for( FleetsyncMessageType type: FleetsyncMessageType.values() ) + { + if( type != FleetsyncMessageType.UNKNOWN ) + { + mElements.put( type, new FilterElement( type ) ); + } + } + } + + @Override + public boolean passes( Message message ) + { + if( mEnabled && canProcess( message ) ) + { + FleetsyncMessage fleet = (FleetsyncMessage)message; + + if( mElements.containsKey( fleet.getMessageType() ) ) + { + return mElements.get( fleet.getMessageType() ).isEnabled(); + } + } + + return false; + } + + @Override + public boolean canProcess( Message message ) + { + return message instanceof FleetsyncMessage; + } + + @Override + public List> getFilterElements() + { + return new ArrayList>( mElements.values() ); + } +} diff --git a/src/decode/lj1200/LJ1200MessageFilter.java b/src/decode/lj1200/LJ1200MessageFilter.java new file mode 100644 index 00000000..bd71f5ec --- /dev/null +++ b/src/decode/lj1200/LJ1200MessageFilter.java @@ -0,0 +1,35 @@ +package decode.lj1200; + +import java.util.Collections; +import java.util.List; + +import message.Message; +import filter.Filter; +import filter.FilterElement; + +public class LJ1200MessageFilter extends Filter +{ + + public LJ1200MessageFilter() + { + super( "LJ-1200 Message Filter" ); + } + + @Override + public boolean passes( Message message ) + { + return mEnabled && canProcess( message ); + } + + @Override + public boolean canProcess( Message message ) + { + return message instanceof LJ1200Message; + } + + @Override + public List> getFilterElements() + { + return Collections.EMPTY_LIST; + } +} diff --git a/src/decode/ltrnet/LTRNetMessageFilter.java b/src/decode/ltrnet/LTRNetMessageFilter.java new file mode 100644 index 00000000..1f5a0f02 --- /dev/null +++ b/src/decode/ltrnet/LTRNetMessageFilter.java @@ -0,0 +1,80 @@ +package decode.ltrnet; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import message.Message; +import message.MessageType; +import filter.Filter; +import filter.FilterElement; + +public class LTRNetMessageFilter extends Filter +{ + private HashMap> mElements = + new HashMap>(); + + public LTRNetMessageFilter() + { + super( "LTR-Net Message Filter" ); + + mElements.put( MessageType.CA_STRT, + new FilterElement( MessageType.CA_STRT ) ); + mElements.put( MessageType.CA_ENDD, + new FilterElement( MessageType.CA_ENDD ) ); + mElements.put( MessageType.SY_IDLE, + new FilterElement( MessageType.SY_IDLE ) ); + mElements.put( MessageType.ID_UNIQ, + new FilterElement( MessageType.ID_UNIQ ) ); + mElements.put( MessageType.ID_ESNH, + new FilterElement( MessageType.ID_ESNH ) ); + mElements.put( MessageType.ID_ESNL, + new FilterElement( MessageType.ID_ESNL ) ); + mElements.put( MessageType.RQ_ACCE, + new FilterElement( MessageType.RQ_ACCE ) ); + mElements.put( MessageType.ID_SITE, + new FilterElement( MessageType.ID_SITE ) ); + mElements.put( MessageType.FQ_RXHI, + new FilterElement( MessageType.FQ_RXHI ) ); + mElements.put( MessageType.FQ_RXLO, + new FilterElement( MessageType.FQ_RXLO ) ); + mElements.put( MessageType.FQ_TXHI, + new FilterElement( MessageType.FQ_TXHI ) ); + mElements.put( MessageType.FQ_TXLO, + new FilterElement( MessageType.FQ_TXLO ) ); + mElements.put( MessageType.ID_NBOR, + new FilterElement( MessageType.ID_NBOR ) ); + mElements.put( MessageType.MA_CHNH, + new FilterElement( MessageType.MA_CHNH ) ); + mElements.put( MessageType.MA_CHNL, + new FilterElement( MessageType.MA_CHNL ) ); + } + + @Override + public boolean passes( Message message ) + { + if( mEnabled && canProcess( message ) ) + { + LTRNetMessage ltr = (LTRNetMessage)message; + + if( mElements.containsKey( ltr.getMessageType() ) ) + { + return mElements.get( ltr.getMessageType() ).isEnabled(); + } + } + + return false; + } + + @Override + public boolean canProcess( Message message ) + { + return message instanceof LTRNetMessage; + } + + @Override + public List> getFilterElements() + { + return new ArrayList>( mElements.values() ); + } +} diff --git a/src/decode/ltrstandard/LTRStandardMessageFilter.java b/src/decode/ltrstandard/LTRStandardMessageFilter.java new file mode 100644 index 00000000..8054fd3a --- /dev/null +++ b/src/decode/ltrstandard/LTRStandardMessageFilter.java @@ -0,0 +1,56 @@ +package decode.ltrstandard; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import message.Message; +import message.MessageType; +import filter.Filter; +import filter.FilterElement; + +public class LTRStandardMessageFilter extends Filter +{ + private HashMap> mElements = + new HashMap>(); + + public LTRStandardMessageFilter() + { + super( "LTR Message Filter" ); + + mElements.put( MessageType.CA_STRT, + new FilterElement( MessageType.CA_STRT ) ); + mElements.put( MessageType.CA_ENDD, + new FilterElement( MessageType.CA_ENDD ) ); + mElements.put( MessageType.SY_IDLE, + new FilterElement( MessageType.SY_IDLE ) ); + } + + @Override + public boolean passes( Message message ) + { + if( mEnabled && canProcess( message ) ) + { + LTRStandardMessage ltr = (LTRStandardMessage)message; + + if( mElements.containsKey( ltr.getMessageType() ) ) + { + return mElements.get( ltr.getMessageType() ).isEnabled(); + } + } + + return false; + } + + @Override + public boolean canProcess( Message message ) + { + return message instanceof LTRStandardMessage; + } + + @Override + public List> getFilterElements() + { + return new ArrayList>( mElements.values() ); + } +} diff --git a/src/decode/mdc1200/MDCMessageFilter.java b/src/decode/mdc1200/MDCMessageFilter.java new file mode 100644 index 00000000..729c7756 --- /dev/null +++ b/src/decode/mdc1200/MDCMessageFilter.java @@ -0,0 +1,56 @@ +package decode.mdc1200; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import message.Message; +import filter.Filter; +import filter.FilterElement; + +public class MDCMessageFilter extends Filter +{ + private HashMap> mElements = + new HashMap>(); + + public MDCMessageFilter() + { + super( "MDC-1200 Message Filter" ); + + for( MDCMessageType type: MDCMessageType.values() ) + { + if( type != MDCMessageType.UNKNOWN ) + { + mElements.put( type, new FilterElement( type ) ); + } + } + } + + @Override + public boolean passes( Message message ) + { + if( mEnabled && canProcess( message ) ) + { + MDCMessage mdc = (MDCMessage)message; + + if( mElements.containsKey( mdc.getMessageType() ) ) + { + return mElements.get( mdc.getMessageType() ).isEnabled(); + } + } + + return false; + } + + @Override + public boolean canProcess( Message message ) + { + return message instanceof MDCMessage; + } + + @Override + public List> getFilterElements() + { + return new ArrayList>( mElements.values() ); + } +} diff --git a/src/decode/mpt1327/MPT1327Message.java b/src/decode/mpt1327/MPT1327Message.java index 64884144..947b29bd 100644 --- a/src/decode/mpt1327/MPT1327Message.java +++ b/src/decode/mpt1327/MPT1327Message.java @@ -1930,6 +1930,11 @@ public class MPT1327Message extends Message { return mDescription; } + + public String toString() + { + return getDescription(); + } public static MPTMessageType fromNumber( int number ) { diff --git a/src/decode/mpt1327/MPT1327MessageFilter.java b/src/decode/mpt1327/MPT1327MessageFilter.java new file mode 100644 index 00000000..e98f89b9 --- /dev/null +++ b/src/decode/mpt1327/MPT1327MessageFilter.java @@ -0,0 +1,62 @@ +package decode.mpt1327; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import message.Message; +import decode.mpt1327.MPT1327Message.MPTMessageType; +import filter.Filter; +import filter.FilterElement; + +public class MPT1327MessageFilter extends Filter +{ + private HashMap> mFilterElements = + new HashMap>(); + + public MPT1327MessageFilter() + { + super( "MPT1327 Message Type Filter" ); + + for( MPTMessageType type: MPT1327Message.MPTMessageType.values() ) + { + if( type != MPTMessageType.UNKN ) + { + mFilterElements.put( type, + new FilterElement( type ) ); + } + } + } + + @Override + public boolean passes( Message message ) + { + if( mEnabled && canProcess( message ) ) + { + MPT1327Message mpt = (MPT1327Message)message; + + FilterElement element = + mFilterElements.get( mpt.getMessageType() ); + + if( element != null ) + { + return element.isEnabled(); + } + } + + return false; + } + + @Override + public boolean canProcess( Message message ) + { + return message instanceof MPT1327Message; + } + + @Override + public List> getFilterElements() + { + return new ArrayList>( mFilterElements.values() ); + } +} + diff --git a/src/decode/p25/P25MessageProcessor.java b/src/decode/p25/P25MessageProcessor.java index 0f534a8f..89665319 100644 --- a/src/decode/p25/P25MessageProcessor.java +++ b/src/decode/p25/P25MessageProcessor.java @@ -1,6 +1,5 @@ package decode.p25; -import java.util.Arrays; import java.util.HashMap; import message.Message; @@ -8,12 +7,9 @@ import message.Message; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import bits.BitSetBuffer; import sample.Broadcaster; import sample.Listener; import alias.AliasList; -import decode.mpt1327.MPT1327Message; -import decode.p25.message.tsbk.TSBKMessage; import decode.p25.message.tsbk.osp.control.IdentifierUpdate; import decode.p25.message.tsbk.osp.control.IdentifierUpdateReceiver; diff --git a/src/decode/p25/message/filter/P25MessageFilterSet.java b/src/decode/p25/message/filter/P25MessageFilterSet.java new file mode 100644 index 00000000..86178ffe --- /dev/null +++ b/src/decode/p25/message/filter/P25MessageFilterSet.java @@ -0,0 +1,23 @@ +package decode.p25.message.filter; + +import message.Message; +import decode.p25.message.P25Message; +import filter.FilterSet; + +public class P25MessageFilterSet extends FilterSet +{ + public P25MessageFilterSet() + { + super( "P25 Message Filter" ); + + addFilter( new PDUMessageFilter() ); + addFilter( new TDUMessageFilter() ); + addFilter( new TSBKMessageFilter() ); + } + + @Override + public boolean canProcess( Message message ) + { + return message instanceof P25Message; + } +} diff --git a/src/decode/p25/message/filter/PDUMessageFilter.java b/src/decode/p25/message/filter/PDUMessageFilter.java new file mode 100644 index 00000000..42fdd002 --- /dev/null +++ b/src/decode/p25/message/filter/PDUMessageFilter.java @@ -0,0 +1,54 @@ +package decode.p25.message.filter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import message.Message; +import decode.p25.message.pdu.PDUMessage; +import decode.p25.reference.Opcode; +import filter.Filter; +import filter.FilterElement; + +public class PDUMessageFilter extends Filter +{ + private HashMap> mOpcodeFilterElements = + new HashMap>(); + + public PDUMessageFilter() + { + super( "PDU - Packet Data Unit" ); + + for( Opcode opcode: Opcode.values() ) + { + mOpcodeFilterElements.put( opcode, new FilterElement( opcode ) ); + } + } + + @Override + public boolean passes( Message message ) + { + if( mEnabled && message instanceof PDUMessage ) + { + PDUMessage pdu = (PDUMessage)message; + + Opcode opcode = pdu.getOpcode(); + + return mOpcodeFilterElements.get( opcode ).isEnabled(); + } + + return false; + } + + @Override + public boolean canProcess( Message message ) + { + return message instanceof PDUMessage; + } + + @Override + public List> getFilterElements() + { + return new ArrayList>( mOpcodeFilterElements.values() ); + } +} diff --git a/src/decode/p25/message/filter/TDUMessageFilter.java b/src/decode/p25/message/filter/TDUMessageFilter.java new file mode 100644 index 00000000..d7f2a20b --- /dev/null +++ b/src/decode/p25/message/filter/TDUMessageFilter.java @@ -0,0 +1,35 @@ +package decode.p25.message.filter; + +import java.util.Collections; +import java.util.List; + +import message.Message; +import decode.p25.message.tdu.TDUMessage; +import filter.Filter; +import filter.FilterElement; + +public class TDUMessageFilter extends Filter +{ + public TDUMessageFilter() + { + super( "TDU Terminator Data Unit" ); + } + + @Override + public boolean passes( Message message ) + { + return mEnabled && canProcess( message ); + } + + @Override + public boolean canProcess( Message message ) + { + return message instanceof TDUMessage; + } + + @Override + public List> getFilterElements() + { + return Collections.EMPTY_LIST; + } +} diff --git a/src/decode/p25/message/filter/TSBKMessageFilter.java b/src/decode/p25/message/filter/TSBKMessageFilter.java new file mode 100644 index 00000000..1aef2724 --- /dev/null +++ b/src/decode/p25/message/filter/TSBKMessageFilter.java @@ -0,0 +1,54 @@ +package decode.p25.message.filter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import message.Message; +import decode.p25.message.tsbk.TSBKMessage; +import decode.p25.reference.Opcode; +import filter.Filter; +import filter.FilterElement; + +public class TSBKMessageFilter extends Filter +{ + private HashMap> mFilterElements = + new HashMap>(); + + public TSBKMessageFilter() + { + super( "TSBK Trunking Signalling Block" ); + + for( Opcode opcode: Opcode.values() ) + { + mFilterElements.put( opcode, new FilterElement( opcode ) ); + } + } + + @Override + public boolean passes( Message message ) + { + if( mEnabled && canProcess( message ) ) + { + TSBKMessage tsbk = (TSBKMessage)message; + + Opcode opcode = tsbk.getOpcode(); + + return mFilterElements.get( opcode ).isEnabled(); + } + + return false; + } + + @Override + public boolean canProcess( Message message ) + { + return message instanceof TSBKMessage; + } + + @Override + public List> getFilterElements() + { + return new ArrayList>( mFilterElements.values() ); + } +} diff --git a/src/decode/passport/PassportMessageFilter.java b/src/decode/passport/PassportMessageFilter.java new file mode 100644 index 00000000..f4026101 --- /dev/null +++ b/src/decode/passport/PassportMessageFilter.java @@ -0,0 +1,68 @@ +package decode.passport; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import message.Message; +import message.MessageType; +import filter.Filter; +import filter.FilterElement; + +public class PassportMessageFilter extends Filter +{ + private HashMap> mElements = + new HashMap>(); + + public PassportMessageFilter() + { + super( "Passport Message Filter" ); + + mElements.put( MessageType.CA_STRT, + new FilterElement( MessageType.CA_STRT ) ); + mElements.put( MessageType.CA_ENDD, + new FilterElement( MessageType.CA_ENDD ) ); + mElements.put( MessageType.SY_IDLE, + new FilterElement( MessageType.SY_IDLE ) ); + mElements.put( MessageType.ID_TGAS, + new FilterElement( MessageType.ID_TGAS ) ); + mElements.put( MessageType.ID_ESNH, + new FilterElement( MessageType.ID_ESNH ) ); + mElements.put( MessageType.CA_PAGE, + new FilterElement( MessageType.CA_PAGE ) ); + mElements.put( MessageType.ID_RDIO, + new FilterElement( MessageType.ID_RDIO ) ); + mElements.put( MessageType.DA_STRT, + new FilterElement( MessageType.DA_STRT ) ); + mElements.put( MessageType.RA_REGI, + new FilterElement( MessageType.RA_REGI ) ); + } + + @Override + public boolean passes( Message message ) + { + if( mEnabled && canProcess( message ) ) + { + PassportMessage passport = (PassportMessage)message; + + if( mElements.containsKey( passport.getMessageType() ) ) + { + return mElements.get( passport.getMessageType() ).isEnabled(); + } + } + + return false; + } + + @Override + public boolean canProcess( Message message ) + { + return message instanceof PassportMessage; + } + + @Override + public List> getFilterElements() + { + return new ArrayList>( mElements.values() ); + } +} diff --git a/src/filter/AllPassFilter.java b/src/filter/AllPassFilter.java new file mode 100644 index 00000000..89ccf6f4 --- /dev/null +++ b/src/filter/AllPassFilter.java @@ -0,0 +1,35 @@ +package filter; + +import java.util.Collections; +import java.util.List; + +/** + * Implements a message filter that passes (true) all messages + */ +@SuppressWarnings( "rawtypes" ) +public class AllPassFilter extends Filter +{ + public AllPassFilter() + { + super( "Allow All Messages" ); + } + + @Override + public boolean passes( T t ) + { + return true; + } + + @Override + public boolean canProcess( T t ) + { + return true; + } + + @Override + @SuppressWarnings( "unchecked" ) + public List getFilterElements() + { + return Collections.EMPTY_LIST; + } +} diff --git a/src/filter/Filter.java b/src/filter/Filter.java new file mode 100644 index 00000000..173b0c50 --- /dev/null +++ b/src/filter/Filter.java @@ -0,0 +1,55 @@ +package filter; + +import java.util.List; + +public abstract class Filter implements IFilter +{ + protected String mName; + protected boolean mEnabled = true; + + public Filter( String name ) + { + mName = name; + } + + /** + * Indicates if this filter is enabled or disabled + */ + public boolean isEnabled() + { + return mEnabled; + } + + /** + * Enables (true) or disables (false) this filter. An enabled filter will + * evaluate messages and a disabled filter will return false on all message + * test methods. + */ + public void setEnabled( boolean enabled ) + { + mEnabled = enabled; + } + + /** + * List of filter elements managed by this filter + */ + public abstract List> getFilterElements(); + + /** + * Name of this filter + */ + public String getName() + { + return mName; + } + + public void setName( String name ) + { + mName = name; + } + + public String toString() + { + return mName; + } +} diff --git a/src/filter/FilterEditorPanel.java b/src/filter/FilterEditorPanel.java new file mode 100644 index 00000000..ce4b31ba --- /dev/null +++ b/src/filter/FilterEditorPanel.java @@ -0,0 +1,400 @@ +package filter; + +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.Collections; +import java.util.Comparator; +import java.util.Enumeration; +import java.util.EventObject; +import java.util.List; + +import javax.swing.JCheckBox; +import javax.swing.JLabel; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JTree; +import javax.swing.SwingUtilities; +import javax.swing.event.CellEditorListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeCellEditor; +import javax.swing.tree.TreeSelectionModel; + +import net.miginfocom.swing.MigLayout; + +public class FilterEditorPanel extends JPanel +{ + private static final long serialVersionUID = 1L; + + private JTree mTree; + private DefaultTreeModel mModel; + private FilterSet mFilterSet; + + public FilterEditorPanel( FilterSet filterSet ) + { + setLayout( new MigLayout("insets 0 0 0 0", "[grow,fill]", "[grow,fill]") ); + + mFilterSet = filterSet; + + init(); + } + + private void init() + { + DefaultMutableTreeNode root = new DefaultMutableTreeNode( mFilterSet ); + + mModel = new DefaultTreeModel( root ); + + addFilterSet( mFilterSet, root ); + + mTree = new JTree( mModel ); + mTree.setShowsRootHandles( true ); + + mTree.addMouseListener( new MouseHandler() ); + + mTree.getSelectionModel().setSelectionMode( + TreeSelectionModel.SINGLE_TREE_SELECTION ); + + mTree.setCellRenderer( new EditorTreeCellRenderer() ); + + mTree.setCellEditor( new FilterTreeNodeEditor() ); + + mTree.setEditable( true ); + + add( mTree ); + } + + private void addFilterSet( FilterSet filterSet, DefaultMutableTreeNode parent ) + { + List> filters = filterSet.getFilters(); + + /* sort the filters in alphabetical order by name */ + Collections.sort( filters, new Comparator>() + { + @Override + public int compare( IFilter first, IFilter second ) + { + return first.getName().compareTo( second.getName() ); + } + }); + + for( IFilter filter: filters ) + { + DefaultMutableTreeNode child = new DefaultMutableTreeNode( filter ); + + mModel.insertNodeInto( child, parent, parent.getChildCount() ); + + if( filter instanceof FilterSet ) + { + addFilterSet( (FilterSet)filter, child ); + } + else if( filter instanceof Filter ) + { + addFilter( (Filter)filter, child ); + } + } + } + + private void addFilter( Filter filter, DefaultMutableTreeNode parent ) + { + List> elements = filter.getFilterElements(); + + Collections.sort( elements ); + + for( FilterElement element: elements ) + { + DefaultMutableTreeNode child = new DefaultMutableTreeNode( element ); + + mModel.insertNodeInto( child, parent, parent.getChildCount() ); + } + } + + public class MouseHandler implements MouseListener + { + public MouseHandler() + { + } + + @Override + public void mouseClicked( MouseEvent event ) + { + if( SwingUtilities.isRightMouseButton( event ) ) + { + int row = mTree.getRowForLocation( event.getX(), + event.getY() ); + + if( row != -1 ) + { + mTree.setSelectionRow( row ); + + Object selectedNode = + mTree.getLastSelectedPathComponent(); + + if( selectedNode instanceof DefaultMutableTreeNode ) + { + final DefaultMutableTreeNode node = + (DefaultMutableTreeNode)selectedNode; + + if( node.getChildCount() > 0 ) + { + JPopupMenu selectionMenu = new JPopupMenu(); + + JMenuItem selectAll = new JMenuItem( "Select All" ); + selectAll.addActionListener( new ActionListener() + { + @Override + public void actionPerformed( ActionEvent arg0 ) + { + setFilterEnabled( mModel, node, true ); + } + }); + + selectionMenu.add( selectAll ); + + JMenuItem deselectAll = new JMenuItem( "Deselect All" ); + deselectAll.addActionListener( new ActionListener() + { + @Override + public void actionPerformed( ActionEvent arg0 ) + { + setFilterEnabled( mModel, node, false ); + } + }); + + selectionMenu.add( deselectAll ); + + selectionMenu.show( mTree, + event.getX(), + event.getY() ); + } + } + } + } + } + + @Override + public void mousePressed( MouseEvent e ){} + @Override + public void mouseReleased( MouseEvent e ){} + @Override + public void mouseEntered( MouseEvent e ){} + @Override + public void mouseExited( MouseEvent e ){} + } + + /** + * Recursively sets the enabled state on all filter node children below the + * specified parent node. + * + * @param model - model containing the tree nodes + * @param node - parent node + * @param enabled - true or false to enable or disable the filters + */ + private void setFilterEnabled( DefaultTreeModel model, + DefaultMutableTreeNode node, + boolean enabled ) + { + Object obj = node.getUserObject(); + + if( obj instanceof FilterSet ) + { + ((FilterSet)obj).setEnabled( enabled ); + } + else if( obj instanceof Filter ) + { + ((Filter)obj).setEnabled( enabled ); + } + else if( obj instanceof FilterElement ) + { + ((FilterElement)obj).setEnabled( enabled ); + } + + model.nodeChanged( node ); + + /* Recursively set the children of this node */ + Enumeration children = node.children(); + + while( children.hasMoreElements() ) + { + Object child = children.nextElement(); + + if( child instanceof DefaultMutableTreeNode ) + { + setFilterEnabled( model, (DefaultMutableTreeNode)child, enabled ); + } + } + } + + public class EditorTreeCellRenderer extends DefaultTreeCellRenderer + { + private static final long serialVersionUID = 1L; + + public Component getTreeCellRendererComponent( JTree tree, + Object treeNode, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus ) + { + if( treeNode instanceof DefaultMutableTreeNode ) + { + Object userObject = ((DefaultMutableTreeNode)treeNode).getUserObject(); + + JCheckBox checkBox = null; + + if( userObject instanceof IFilter ) + { + IFilter filter = (IFilter)userObject; + + checkBox = new JCheckBox( filter.getName() ); + checkBox.setSelected( filter.isEnabled() ); + } + else if( userObject instanceof FilterElement ) + { + FilterElement element = (FilterElement)userObject; + + checkBox = new JCheckBox( element.getName() ); + checkBox.setSelected( element.isEnabled() ); + } + + if( checkBox != null ) + { + if( selected ) + { + checkBox.setForeground( getTextSelectionColor() ); + checkBox.setBackground( getBackgroundSelectionColor() ); + } + else + { + checkBox.setForeground( getTextNonSelectionColor() ); + checkBox.setBackground( getBackgroundNonSelectionColor() ); + } + + return checkBox; + } + } + + return super.getTreeCellRendererComponent( tree, treeNode, selected, + expanded, leaf, row, hasFocus ); + } + } + + public class FilterCheckBox extends JCheckBox + { + private static final long serialVersionUID = 1L; + + private IFilter mFilter; + + public FilterCheckBox( IFilter filter ) + { + super( filter.getName() ); + + mFilter = filter; + + setSelected( mFilter.isEnabled() ); + + addItemListener( new ItemListener() + { + @Override + public void itemStateChanged( ItemEvent e ) + { + mFilter.setEnabled( FilterCheckBox.this.isSelected() ); + } + } ); + } + } + + public class FilterElementCheckBox extends JCheckBox + { + private static final long serialVersionUID = 1L; + + private FilterElement mFilter; + + public FilterElementCheckBox( FilterElement filter ) + { + super( filter.getName() ); + + mFilter = filter; + + setSelected( mFilter.isEnabled() ); + + addItemListener( new ItemListener() + { + @Override + public void itemStateChanged( ItemEvent arg0 ) + { + mFilter.setEnabled( FilterElementCheckBox.this.isSelected() ); + } + } ); + } + } + + public class FilterTreeNodeEditor implements TreeCellEditor + { + @Override + @SuppressWarnings( { "rawtypes", "unchecked" } ) + public Component getTreeCellEditorComponent( JTree tree, Object node, + boolean isSelected, boolean expanded, boolean leaf, int row ) + { + if( node instanceof DefaultMutableTreeNode ) + { + Object userObject = ((DefaultMutableTreeNode)node).getUserObject(); + + if( userObject instanceof IFilter ) + { + return new FilterCheckBox( (IFilter)userObject ); + } + else if( userObject instanceof FilterElement ) + { + return new FilterElementCheckBox( (FilterElement)userObject ); + } + } + + return new JLabel( node.toString() ); + } + + @Override + public void addCellEditorListener( CellEditorListener l ) {} + + @Override + public void cancelCellEditing() + { + + } + + @Override + public Object getCellEditorValue() + { + return null; + } + + @Override + public boolean isCellEditable( EventObject anEvent ) + { + return true; + } + + @Override + public void removeCellEditorListener( CellEditorListener l ) {} + + @Override + public boolean shouldSelectCell( EventObject anEvent ) + { + return false; + } + + @Override + public boolean stopCellEditing() + { + return false; + } + } +} diff --git a/src/filter/FilterElement.java b/src/filter/FilterElement.java new file mode 100644 index 00000000..ce6bfa75 --- /dev/null +++ b/src/filter/FilterElement.java @@ -0,0 +1,49 @@ +package filter; + +public class FilterElement implements Comparable> +{ + private boolean mEnabled; + private T mElement; + + public FilterElement( T element, boolean enabled ) + { + mElement = element; + mEnabled = enabled; + } + + public FilterElement( T t ) + { + this( t, true ); + } + + public T getElement() + { + return mElement; + } + + public String toString() + { + return getName(); + } + + public boolean isEnabled() + { + return mEnabled; + } + + public void setEnabled( boolean enabled ) + { + mEnabled = enabled; + } + + public String getName() + { + return mElement.toString(); + } + + @Override + public int compareTo( FilterElement other ) + { + return toString().compareTo( other.toString() ); + } +} diff --git a/src/filter/FilterSet.java b/src/filter/FilterSet.java new file mode 100644 index 00000000..eba21694 --- /dev/null +++ b/src/filter/FilterSet.java @@ -0,0 +1,97 @@ +package filter; + +import java.util.ArrayList; +import java.util.List; + +public class FilterSet implements IFilter +{ + protected List> mFilters = new ArrayList>(); + protected boolean mEnabled = true; + protected String mName; + + public FilterSet( String name ) + { + mName = name; + } + + public String getName() + { + return mName; + } + + public void setName( String name ) + { + mName = name; + } + + public String toString() + { + return getName(); + } + + @Override + public boolean passes( T t ) + { + if( mEnabled ) + { + for( IFilter filter: mFilters ) + { + if( filter.canProcess( t ) ) + { + return filter.passes( t ); + } + } + } + + return false; + } + + @Override + public boolean canProcess( T t ) + { + if( mEnabled ) + { + for( IFilter filter: mFilters ) + { + if( filter.canProcess( t ) ) + { + return true; + } + } + } + + return false; + } + + public List> getFilters() + { + return mFilters; + } + + public void addFilters( List> filters ) + { + mFilters.addAll( filters ); + } + + public void addFilter( IFilter filter ) + { + mFilters.add( filter ); + } + + public void removeFilter( IFilter filter ) + { + mFilters.remove( filter ); + } + + @Override + public boolean isEnabled() + { + return mEnabled; + } + + @Override + public void setEnabled( boolean enabled ) + { + mEnabled = enabled; + } +} diff --git a/src/filter/IFilter.java b/src/filter/IFilter.java new file mode 100644 index 00000000..fbb7226f --- /dev/null +++ b/src/filter/IFilter.java @@ -0,0 +1,36 @@ +package filter; + +public interface IFilter +{ + /** + * Generic filter method. + * + * @param message - message to filter + * @return - true if the message passes the filter + */ + public boolean passes( T t ); + + /** + * Indicates if the filter can process (filter) the object + * + * @param message - candidate message for filtering + * + * @return - true if the filter is capable of filtering the message + */ + public boolean canProcess( T t ); + + /** + * Indicates if this filter is enabled to evaluate messages + */ + public boolean isEnabled(); + + /** + * Sets the enabled state of the filter + */ + public void setEnabled( boolean enabled ); + + /** + * Display name for the filter + */ + public String getName(); +} diff --git a/src/message/MessageFilterFactory.java b/src/message/MessageFilterFactory.java new file mode 100644 index 00000000..36f8c63a --- /dev/null +++ b/src/message/MessageFilterFactory.java @@ -0,0 +1,111 @@ +package message; + +import java.util.ArrayList; +import java.util.List; + +import controller.channel.Channel; +import decode.DecoderType; +import decode.config.AuxDecodeConfiguration; +import decode.fleetsync2.FleetsyncMessageFilter; +import decode.lj1200.LJ1200MessageFilter; +import decode.ltrnet.LTRNetMessageFilter; +import decode.ltrstandard.LTRStandardMessageFilter; +import decode.mdc1200.MDCMessageFilter; +import decode.mpt1327.MPT1327MessageFilter; +import decode.p25.message.filter.P25MessageFilterSet; +import decode.passport.PassportMessageFilter; +import filter.AllPassFilter; +import filter.FilterSet; +import filter.IFilter; + +/** + * Constructs message filters for each of the decoder types + */ +public class MessageFilterFactory +{ + /** + * Assembles a filter set containing filters for the primary channel + * decoder and each of the auxiliary decoders + */ + public static FilterSet getMessageFilter( Channel channel ) + { + FilterSet filterSet = new FilterSet( + "Message Filter: " + channel.getChannelDisplayName() ); + + filterSet.addFilters( getMessageFilters( + channel.getDecodeConfiguration().getDecoderType() ) ); + + AuxDecodeConfiguration auxConfig = channel.getAuxDecodeConfiguration(); + + for( DecoderType decoderType: auxConfig.getAuxDecoders() ) + { + filterSet.addFilters( getMessageFilters( decoderType ) ); + } + + /* If we don't have any filters, add an ALL-PASS filter */ + if( filterSet.getFilters().isEmpty() ) + { + filterSet.addFilter( new AllPassFilter() ); + } + + return filterSet; + } + + /** + * Returns a set of IMessageFilter objects (FilterSets or Filters) that + * can process all of the messages produced by the specified decoder type. + */ + public static List> getMessageFilters( DecoderType decoder ) + { + ArrayList> filters = new ArrayList>(); + + switch( decoder ) + { + case ACARS: + break; + case AIS: + break; + case AM: + break; + case APRS: + break; + case DMR: + break; + case FLEETSYNC2: + filters.add( new FleetsyncMessageFilter() ); + break; + case LJ_1200: + filters.add( new LJ1200MessageFilter() ); + break; + case LTR_NET: + filters.add( new LTRNetMessageFilter() ); + break; + case LTR_STANDARD: + filters.add( new LTRStandardMessageFilter() ); + break; + case MDC1200: + filters.add( new MDCMessageFilter() ); + break; + case MOTOROLA_TYPE_2: + break; + case MPT1327: + filters.add( new MPT1327MessageFilter() ); + break; + case NBFM: + break; + case NXDN: + break; + case P25_PHASE1: + case P25_PHASE2: + filters.add( new P25MessageFilterSet() ); + break; + case PASSPORT: + filters.add( new PassportMessageFilter() ); + break; + default: + break; + } + + return filters; + } +} diff --git a/src/message/MessageType.java b/src/message/MessageType.java index 25672de5..6b046efb 100644 --- a/src/message/MessageType.java +++ b/src/message/MessageType.java @@ -71,4 +71,9 @@ public enum MessageType { return mDisplayText; } + + public String toString() + { + return getDisplayText(); + } }