Merges #34 Major redesign of Tuner, Channel and Alias management.

Changes to model, view and controller components and updates all gui
editors.  Removes the configuration panel and tree and replaces with 3
new panels.  Updates playlist.xml to a new playlist_v2.xml format.
This commit is contained in:
denny
2016-04-01 08:23:49 -04:00
450 changed files with 19560 additions and 22805 deletions

View File

@@ -9,25 +9,20 @@ import instrument.tap.stream.FloatTap;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sample.Listener;
import sample.real.RealBuffer;
import sample.real.RealSampleListener;
import sample.real.RealSampleProvider;
import source.tuner.frequency.FrequencyCorrectionControl;
import source.tuner.frequency.FrequencyCorrectionControl.FrequencyCorrectionResetListener;
import source.tuner.frequency.FrequencyChangeEvent;
import source.tuner.frequency.FrequencyChangeEvent.Event;
import source.tuner.frequency.IFrequencyChangeListener;
import dsp.gain.DirectGainControl;
public class C4FMSymbolFilter implements FrequencyCorrectionResetListener,
Listener<RealBuffer>,
public class C4FMSymbolFilter implements Listener<RealBuffer>,
IFrequencyChangeListener,
RealSampleProvider,
Instrumentable
{
private final static Logger mLog =
LoggerFactory.getLogger( C4FMSymbolFilter.class );
private static final float TAPS[][] =
{
{ 0.00000e+00f, 0.00000e+00f, 0.00000e+00f, 0.00000e+00f, 1.00000e+00f, 0.00000e+00f, 0.00000e+00f, 0.00000e+00f }, // 0/128
@@ -201,15 +196,17 @@ public class C4FMSymbolFilter implements FrequencyCorrectionResetListener,
private float mHistory[] = new float[ NUMBER_FILTER_TAPS ];
private int mHistoryLast = 0;
private boolean mResetFrequencyTracker = false;
private RealSampleListener mListener;
private DirectGainControl mGainController =
new DirectGainControl( 15.0f, 0.1f, 35.0f, 0.3f );
private FrequencyCorrectionControl mFrequencyCorrectionControl;
private int mFrequencyAdjustmentRequested = 0;
private int mFrequencyCorrection = 0;
private int mFrequencyCorrectionMaximum = 3000;
private boolean mResetFrequencyTracker = false;
private FrequencyCorrectionProcessor mFrequencyCorrectionProcessor;
private Listener<FrequencyChangeEvent> mFrequencyChangeListener;
/**
* C4FM Symbol Filter
@@ -224,18 +221,15 @@ public class C4FMSymbolFilter implements FrequencyCorrectionResetListener,
* setting for this filter is 15.4 and that yields a symbol spread that
* is centered on 2.0, ranging 1.92 to 2.08.
*/
public C4FMSymbolFilter( FrequencyCorrectionControl frequencyControl )
public C4FMSymbolFilter( int frequencyCorrectionMaximum )
{
mFrequencyCorrectionControl = frequencyControl;
/* Register for reset events, so we can reset internal frequency tracking */
mFrequencyCorrectionControl.setListener( this );
mFrequencyCorrectionMaximum = frequencyCorrectionMaximum;
}
public void dispose()
{
mGainController = null;
mFrequencyCorrectionControl = null;
// mFrequencyCorrectionControl = null;
mListener = null;
}
@@ -253,13 +247,21 @@ public class C4FMSymbolFilter implements FrequencyCorrectionResetListener,
* the internal frequency correction tracker */
if( mFrequencyAdjustmentRequested != 0 )
{
mFrequencyCorrectionControl.adjust( mFrequencyAdjustmentRequested );
int correction = mFrequencyCorrection + mFrequencyAdjustmentRequested;
if( correction > mFrequencyCorrectionMaximum )
{
correction = mFrequencyCorrectionMaximum;
}
else if( correction < -mFrequencyCorrectionMaximum )
{
correction = -mFrequencyCorrectionMaximum;
}
broadcast( new FrequencyChangeEvent(
Event.REQUEST_CHANNEL_FREQUENCY_CORRECTION_CHANGE, correction ) );
mFrequencyAdjustmentRequested = 0;
//Reset internal frequency tracking
mCoarseFrequencyCorrection = 0.0f;
mFineFrequencyCorrection = 0.0f;
}
}
@@ -272,7 +274,8 @@ public class C4FMSymbolFilter implements FrequencyCorrectionResetListener,
mCoarseFrequencyCorrection = 0.0f;
mFineFrequencyCorrection = 0.0f;
mFrequencyCorrectionControl.setFrequencyCorrection( 0 );
broadcast( new FrequencyChangeEvent(
Event.REQUEST_CHANNEL_FREQUENCY_CORRECTION_CHANGE, 0 ));
mResetFrequencyTracker = false;
}
@@ -397,17 +400,6 @@ public class C4FMSymbolFilter implements FrequencyCorrectionResetListener,
}
}
/**
* Listener interface for frequency correction reset events. We reset the
* coarse and fine frequency control values when the tuner channel source
* has changed frequency (PPM) or sample rate
*/
@Override
public void resetFrequencyCorrection()
{
mResetFrequencyTracker = true;
}
@Override
public void setListener( RealSampleListener listener )
{
@@ -459,4 +451,56 @@ public class C4FMSymbolFilter implements FrequencyCorrectionResetListener,
mSymbolSpreadTap = null;
}
}
public void broadcast( FrequencyChangeEvent event )
{
if( mFrequencyChangeListener != null )
{
mFrequencyChangeListener.receive( event );
}
}
public void setFrequencyChangeListener( Listener<FrequencyChangeEvent> listener )
{
mFrequencyChangeListener = listener;
}
@Override
public Listener<FrequencyChangeEvent> getFrequencyChangeListener()
{
if( mFrequencyCorrectionProcessor == null )
{
mFrequencyCorrectionProcessor = new FrequencyCorrectionProcessor();
}
return mFrequencyCorrectionProcessor;
}
/**
* Receives notifications that the channel frequency correction has been
* applied and updates internal tracking value.
*/
public class FrequencyCorrectionProcessor implements Listener<FrequencyChangeEvent>
{
@Override
public void receive( FrequencyChangeEvent event )
{
switch( event.getEvent() )
{
case NOTIFICATION_CHANNEL_FREQUENCY_CORRECTION_CHANGE:
mFrequencyCorrection = event.getValue().intValue();
//Reset internal frequency tracking
mCoarseFrequencyCorrection = 0.0f;
mFineFrequencyCorrection = 0.0f;
break;
case NOTIFICATION_FREQUENCY_CORRECTION_CHANGE:
case NOTIFICATION_SAMPLE_RATE_CHANGE:
mResetFrequencyTracker = true;
break;
default:
break;
}
}
}
}

View File

@@ -1,147 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package module.decode.p25;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import module.decode.DecodeEditor;
import module.decode.config.DecodeConfiguration;
import module.decode.p25.P25Decoder.Modulation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import source.SourceEditor;
import source.tuner.TunerEditor;
import controller.Editor;
import controller.channel.ChannelValidationException;
public class P25DecodeEditor extends DecodeEditor
{
private final static Logger mLog = LoggerFactory.getLogger( P25DecodeEditor.class );
private static final long serialVersionUID = 1L;
private JComboBox<P25_LSMDecoder.Modulation> mComboModulation;
private JCheckBox mIgnoreDataCalls;
private JLabel mTrafficChannelPoolSizeLabel;
private JSlider mTrafficChannelPoolSize;
public P25DecodeEditor( DecodeConfiguration config )
{
super( config );
initGUI();
}
private void initGUI()
{
final DecodeConfigP25Phase1 config = (DecodeConfigP25Phase1)mConfig;
mComboModulation = new JComboBox<P25_LSMDecoder.Modulation>();
mComboModulation.setModel( new DefaultComboBoxModel<P25_LSMDecoder.Modulation>(
P25_LSMDecoder.Modulation.values() ) );
mComboModulation.setSelectedItem( config.getModulation() );
add( new JLabel( "Modulation:" ) );
add( mComboModulation, "wrap" );
mTrafficChannelPoolSize = new JSlider( JSlider.HORIZONTAL,
DecodeConfiguration.TRAFFIC_CHANNEL_LIMIT_MINIMUM,
DecodeConfiguration.TRAFFIC_CHANNEL_LIMIT_MAXIMUM,
config.getTrafficChannelPoolSize() );
mTrafficChannelPoolSize.setMajorTickSpacing( 10 );
mTrafficChannelPoolSize.setMinorTickSpacing( 1 );
mTrafficChannelPoolSize.setPaintTicks( true );
mTrafficChannelPoolSize.setLabelTable( mTrafficChannelPoolSize.createStandardLabels( 10, 10 ) );
mTrafficChannelPoolSize.setPaintLabels( true );
mTrafficChannelPoolSizeLabel = new JLabel( "Traffic Channel Pool: " + mTrafficChannelPoolSize.getValue() + " " );
mTrafficChannelPoolSize.addChangeListener( new ChangeListener()
{
@Override
public void stateChanged( ChangeEvent e )
{
mTrafficChannelPoolSizeLabel.setText( "Traffic Channel Pool: " + mTrafficChannelPoolSize.getValue() );
}
} );
add( mTrafficChannelPoolSizeLabel );
add( mTrafficChannelPoolSize, "wrap,grow" );
mIgnoreDataCalls = new JCheckBox();
mIgnoreDataCalls.setSelected( config.getIgnoreDataCalls() );
add( new JLabel( "Ignore Data Calls" ) );
add( mIgnoreDataCalls, "wrap,grow" );
reset();
}
/**
* Enforce source=tuner for CQPSK modulation
*/
@Override
public void validate( Editor editor ) throws ChannelValidationException
{
if( editor instanceof SourceEditor &&
((DecodeConfigP25Phase1)mConfig).getModulation() == Modulation.CQPSK )
{
if( !( editor instanceof TunerEditor ) )
{
throw new ChannelValidationException(
"<html><body width='175'><h1>LSM Simulcast</h1>"
+ "<p>P25 LSM Simulcast decoder can only be used with "
+ "a tuner source. Please change the Source to use a tuner"
+ " or change the P25 Decoder to C4FM modulation" );
}
}
}
@Override
public void save()
{
DecodeConfigP25Phase1 config = (DecodeConfigP25Phase1)mConfig;
config.setModulation( (Modulation)mComboModulation.getSelectedItem() );
config.setIgnoreDataCalls( mIgnoreDataCalls.isSelected() );
config.setTrafficChannelPoolSize( mTrafficChannelPoolSize.getValue() );
}
@Override
public void reset()
{
DecodeConfigP25Phase1 config = (DecodeConfigP25Phase1)mConfig;
mComboModulation.setSelectedItem( config.getModulation() );
mIgnoreDataCalls.setSelected( config.getIgnoreDataCalls() );
mTrafficChannelPoolSize.setValue( config.getTrafficChannelPoolSize() );
}
}

View File

@@ -1,20 +1,18 @@
package module.decode.p25;
import alias.AliasList;
import instrument.Instrumentable;
import module.decode.Decoder;
import module.decode.DecoderType;
import source.tuner.frequency.IFrequencyCorrectionController;
import alias.AliasList;
public abstract class P25Decoder extends Decoder
implements IFrequencyCorrectionController, Instrumentable
public abstract class P25Decoder extends Decoder implements Instrumentable
{
private P25MessageProcessor mMessageProcessor;
public P25Decoder( AliasList aliasList )
{
mMessageProcessor = new P25MessageProcessor( aliasList );
mMessageProcessor.setMessageListener( mMessageBroadcaster );
mMessageProcessor.setMessageListener( this );
}
public void dispose()

View File

@@ -0,0 +1,226 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014-2016 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package module.decode.p25;
import gui.editor.Editor;
import gui.editor.EditorValidationException;
import gui.editor.ValidatingEditor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import module.decode.AuxDecodeConfigurationEditor;
import module.decode.config.AuxDecodeConfiguration;
import module.decode.config.DecodeConfiguration;
import module.decode.p25.P25Decoder.Modulation;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import source.SourceConfigurationEditor;
import source.config.SourceConfigTuner;
import source.config.SourceConfiguration;
import controller.channel.Channel;
public class P25DecoderEditor extends ValidatingEditor<Channel>
{
private final static Logger mLog = LoggerFactory.getLogger( P25DecoderEditor.class );
private static final long serialVersionUID = 1L;
private JComboBox<P25_LSMDecoder.Modulation> mComboModulation;
private JCheckBox mIgnoreDataCalls;
private JLabel mTrafficChannelPoolSizeLabel;
private JSlider mTrafficChannelPoolSize;
public P25DecoderEditor()
{
init();
}
private void init()
{
setLayout( new MigLayout( "insets 0 0 0 0,wrap 3", "[right][grow,fill][]", "" ) );
mComboModulation = new JComboBox<P25_LSMDecoder.Modulation>();
mComboModulation.setModel( new DefaultComboBoxModel<P25_LSMDecoder.Modulation>(
P25_LSMDecoder.Modulation.values() ) );
mComboModulation.setEnabled( false );
mComboModulation.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
setModified( true );
}
} );
add( new JLabel( "Modulation:" ) );
add( mComboModulation );
mIgnoreDataCalls = new JCheckBox( "Ignore Data Calls" );
mIgnoreDataCalls.setEnabled( false );
mIgnoreDataCalls.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
setModified( true );
}
} );
add( mIgnoreDataCalls );
mTrafficChannelPoolSize = new JSlider( JSlider.HORIZONTAL, DecodeConfiguration.TRAFFIC_CHANNEL_LIMIT_MINIMUM,
DecodeConfiguration.TRAFFIC_CHANNEL_LIMIT_MAXIMUM, DecodeConfiguration.TRAFFIC_CHANNEL_LIMIT_DEFAULT );
mTrafficChannelPoolSize.setEnabled( false );
mTrafficChannelPoolSize.setMajorTickSpacing( 10 );
mTrafficChannelPoolSize.setMinorTickSpacing( 5 );
mTrafficChannelPoolSize.setPaintTicks( true );
mTrafficChannelPoolSize.addChangeListener( new ChangeListener()
{
@Override
public void stateChanged( ChangeEvent e )
{
mTrafficChannelPoolSizeLabel.setText( "Traffic Pool: " + mTrafficChannelPoolSize.getValue() );
setModified( true );
}
} );
mTrafficChannelPoolSizeLabel = new JLabel( "Traffic Pool: " + mTrafficChannelPoolSize.getValue() + " " );
add( mTrafficChannelPoolSizeLabel );
add( mTrafficChannelPoolSize );
}
@Override
public void save()
{
if( hasItem() && isModified() )
{
DecodeConfigP25Phase1 p25 = new DecodeConfigP25Phase1();
p25.setModulation( (Modulation)mComboModulation.getSelectedItem() );
p25.setIgnoreDataCalls( mIgnoreDataCalls.isSelected() );
p25.setTrafficChannelPoolSize( mTrafficChannelPoolSize.getValue() );
getItem().setDecodeConfiguration( p25 );
}
setModified( false );
}
@Override
public void validate( Editor<Channel> editor ) throws EditorValidationException
{
mLog.debug( "Validating editor:" + editor.getClass() );
/**
* Enforce CQPSK modulation uses a Tuner Source for I/Q sample data
*/
if( editor instanceof SourceConfigurationEditor &&
((Modulation)mComboModulation.getSelectedItem()) == Modulation.CQPSK )
{
SourceConfiguration config = ((SourceConfigurationEditor)editor).getSourceConfiguration();
if( config != null && !( config instanceof SourceConfigTuner ) )
{
throw new EditorValidationException( editor,
"<html><body width='175'><h3>LSM Simulcast</h3>"
+ "<p>P25 LSM Simulcast decoder can only be used with "
+ "a tuner source. Please change the Source to use a tuner"
+ " or change the P25 Decoder to C4FM modulation</p>" );
}
}
if( editor instanceof AuxDecodeConfigurationEditor )
{
AuxDecodeConfiguration config = ((AuxDecodeConfigurationEditor)editor).getConfiguration();
if( config != null && !config.getAuxDecoders().isEmpty() )
{
throw new EditorValidationException( editor,
"<html><body width='175'><h3>Auxilary Decoders</h3>"
+ "<p>The auxiliary decoders work with analog audio and are not "
+ "compatible with the P25 Decoder. Please uncheck any auxiliary "
+ "decoders that you have selected for this channel</p>" );
}
}
}
private void setControlsEnabled( boolean enabled )
{
if( mComboModulation.isEnabled() != enabled )
{
mComboModulation.setEnabled( enabled );
}
if( mTrafficChannelPoolSize.isEnabled() != enabled )
{
mTrafficChannelPoolSize.setEnabled( enabled );
}
if( mIgnoreDataCalls.isEnabled() != enabled )
{
mIgnoreDataCalls.setEnabled( enabled );
}
}
@Override
public void setItem( Channel item )
{
super.setItem( item );
if( hasItem() )
{
setControlsEnabled( true );
DecodeConfiguration config = getItem().getDecodeConfiguration();
if( config instanceof DecodeConfigP25Phase1 )
{
DecodeConfigP25Phase1 p25 = (DecodeConfigP25Phase1)config;
mComboModulation.setSelectedItem( p25.getModulation() );
mIgnoreDataCalls.setSelected( p25.getIgnoreDataCalls() );
mTrafficChannelPoolSize.setValue( p25.getTrafficChannelPoolSize() );
setModified( false );
}
else
{
mComboModulation.setSelectedItem( Modulation.C4FM );
mIgnoreDataCalls.setSelected( false );
mTrafficChannelPoolSize.setValue( DecodeConfiguration.TRAFFIC_CHANNEL_LIMIT_DEFAULT );
setModified( true );
}
}
else
{
setControlsEnabled( false );
setModified( false );
}
}
}

View File

@@ -25,10 +25,10 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.ScheduledExecutorService;
import message.Message;
import module.decode.DecoderType;
import module.decode.event.CallEvent;
import module.decode.event.CallEvent.CallEventType;
import module.decode.p25.P25Decoder.Modulation;
import module.decode.p25.message.IAdjacentSite;
@@ -121,6 +121,7 @@ import module.decode.p25.reference.IPProtocol;
import module.decode.p25.reference.LinkControlOpcode;
import module.decode.p25.reference.Response;
import module.decode.p25.reference.Vendor;
import module.decode.state.ChangeChannelTimeoutEvent;
import module.decode.state.ChangedAttribute;
import module.decode.state.DecoderState;
import module.decode.state.DecoderStateEvent;
@@ -204,11 +205,6 @@ public class P25DecoderState extends DecoderState
return DecoderType.P25_PHASE1;
}
@Override
public void start()
{
}
@Override
public void stop()
{
@@ -1668,7 +1664,7 @@ public class P25DecoderState extends DecoderState
.to( satcr.getLogicalLinkID() )
.build() );
break;
case SN_ACTIVATE_TDS_CONTEXT_REQUEST:
case SNDCP_ACTIVATE_TDS_CONTEXT_REQUEST:
SNDCPActivateTDSContextRequest satcreq =
(SNDCPActivateTDSContextRequest)pduc;
@@ -2292,6 +2288,8 @@ public class P25DecoderState extends DecoderState
logAlternateVendorMessage( pdu );
}
break;
default:
break;
}
}
@@ -2437,8 +2435,6 @@ public class P25DecoderState extends DecoderState
private void processTSBKResponse( TSBKMessage message )
{
CallEvent event = null;
switch( message.getOpcode() )
{
case ACKNOWLEDGE_RESPONSE:
@@ -3560,4 +3556,14 @@ public class P25DecoderState extends DecoderState
break;
}
}
@Override
public void start( ScheduledExecutorService executor )
{
//Change the default (45-second) traffic channel timeout to 1 second
if( mChannelType == ChannelType.TRAFFIC )
{
broadcast( new ChangeChannelTimeoutEvent( this, ChannelType.TRAFFIC, 1000 ) );
}
}
}

View File

@@ -17,6 +17,8 @@ import module.decode.p25.message.tdu.lc.TDULCMessageFactory;
import module.decode.p25.message.tdu.lc.TDULinkControlMessage;
import module.decode.p25.message.tsbk.TSBKMessage;
import module.decode.p25.message.tsbk.TSBKMessageFactory;
import module.decode.p25.message.vselp.VSELP1Message;
import module.decode.p25.message.vselp.VSELP2Message;
import module.decode.p25.reference.DataUnitID;
import org.slf4j.Logger;
@@ -129,7 +131,7 @@ public class P25MessageFramer implements Listener<Dibit>
if( demodulator != null )
{
/* For CQPSK, we include 3 additional sync detectors to watch for and
* correction +/-90 and 180 degree costas loop phase lock errors */
* correct +/-90 and 180 degree costas loop phase lock errors */
mMatcher.add( new CostasPhaseErrorDetector( FrameSync.P25_PHASE1_ERROR_90_CCW,
demodulator, PHASE_CORRECTION_90_DEGREES ) );
@@ -289,7 +291,7 @@ public class P25MessageFramer implements Listener<Dibit>
else
{
mComplete = true;
dispatch( new P25Message( mMessage.copy(), duid, mAliasList ) );
dispatch( new P25Message( mMessage.copy(), mDUID, mAliasList ) );
}
}
else
@@ -631,6 +633,14 @@ public class P25MessageFramer implements Listener<Dibit>
mComplete = true;
break;
case VSELP1:
mComplete = true;
dispatch( new VSELP1Message( mMessage.copy(), mDUID, mAliasList ) );
break;
case VSELP2:
mComplete = true;
dispatch( new VSELP2Message( mMessage.copy(), mDUID, mAliasList ) );
break;
case UNKN:
mComplete = true;
dispatch( new P25Message( mMessage.copy(), mDUID, mAliasList ) );

View File

@@ -10,8 +10,8 @@ import module.decode.p25.message.ldu.LDUMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sample.Listener;
import alias.AliasList;
import sample.Listener;
public class P25MessageProcessor implements Listener<Message>
{

View File

@@ -24,22 +24,25 @@ import instrument.tap.stream.FloatBufferTap;
import instrument.tap.stream.FloatTap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sample.Listener;
import sample.real.IRealBufferListener;
import sample.real.RealBuffer;
import source.tuner.frequency.FrequencyCorrectionControl;
import alias.AliasList;
import sample.Listener;
import sample.real.IFilteredRealBufferListener;
import sample.real.RealBuffer;
import source.tuner.frequency.FrequencyChangeEvent;
import source.tuner.frequency.IFrequencyChangeListener;
import source.tuner.frequency.IFrequencyChangeProvider;
import dsp.filter.FilterFactory;
import dsp.filter.Window.WindowType;
import dsp.filter.fir.real.RealFIRFilter_RB_RB;
public class P25_C4FMDecoder extends P25Decoder implements IRealBufferListener
public class P25_C4FMDecoder extends P25Decoder
implements IFrequencyChangeListener, IFrequencyChangeProvider,IFilteredRealBufferListener
{
private final static Logger mLog = LoggerFactory.getLogger( P25_C4FMDecoder.class );
@@ -48,11 +51,8 @@ public class P25_C4FMDecoder extends P25Decoder implements IRealBufferListener
private static final String INSTRUMENT_C4FM_SYMBOL_FILTER_OUTPUT = "Tap Point: Symbol Filter Output";
private static final String INSTRUMENT_C4FM_SLICER_OUTPUT = "Tap Point: C4FM Slicer Output";
private final static int MAXIMUM_FREQUENCY_CORRECTION = 3000; //Hertz, +/-
private List<TapGroup> mAvailableTaps;
private RealFIRFilter_RB_RB mC4FMPreFilter;
private FrequencyCorrectionControl mFrequencyCorrectionControl;
private C4FMSymbolFilter mSymbolFilter;
private C4FMSlicer mC4FMSlicer;
private P25MessageFramer mMessageFramer;
@@ -70,7 +70,7 @@ public class P25_C4FMDecoder extends P25Decoder implements IRealBufferListener
* infrastructure and subscriber identities that will be included in each
* decoded message
*/
public P25_C4FMDecoder( AliasList aliasList )
public P25_C4FMDecoder( AliasList aliasList, int frequencyCorrectionMaximum )
{
super( aliasList );
@@ -79,13 +79,8 @@ public class P25_C4FMDecoder extends P25Decoder implements IRealBufferListener
mC4FMPreFilter = new RealFIRFilter_RB_RB( filter, 1.0f );
/* Issue tuned frequency correction commands, remotely controlled by the
* downstream symbol filter */
mFrequencyCorrectionControl = new FrequencyCorrectionControl(
MAXIMUM_FREQUENCY_CORRECTION );
/* Shape gain and frequency offsets to optimize sample stream */
mSymbolFilter = new C4FMSymbolFilter( mFrequencyCorrectionControl );
mSymbolFilter = new C4FMSymbolFilter( frequencyCorrectionMaximum );
mC4FMPreFilter.setListener( mSymbolFilter );
/* Convert samples to symbols */
@@ -108,9 +103,6 @@ public class P25_C4FMDecoder extends P25Decoder implements IRealBufferListener
mC4FMPreFilter.dispose();
mC4FMPreFilter = null;
mFrequencyCorrectionControl.dispose();
mFrequencyCorrectionControl = null;
mSymbolFilter.dispose();
mSymbolFilter = null;
@@ -127,19 +119,7 @@ public class P25_C4FMDecoder extends P25Decoder implements IRealBufferListener
}
@Override
public boolean hasFrequencyCorrectionControl()
{
return mFrequencyCorrectionControl != null;
}
@Override
public FrequencyCorrectionControl getFrequencyCorrectionControl()
{
return mFrequencyCorrectionControl;
}
@Override
public Listener<RealBuffer> getRealBufferListener()
public Listener<RealBuffer> getFilteredRealBufferListener()
{
return mC4FMPreFilter;
}
@@ -249,7 +229,7 @@ public class P25_C4FMDecoder extends P25Decoder implements IRealBufferListener
}
@Override
public void start()
public void start( ScheduledExecutorService executor )
{
// TODO Auto-generated method stub
@@ -261,4 +241,33 @@ public class P25_C4FMDecoder extends P25Decoder implements IRealBufferListener
// TODO Auto-generated method stub
}
@Override
public void setFrequencyChangeListener( Listener<FrequencyChangeEvent> listener )
{
if( mSymbolFilter != null )
{
mSymbolFilter.setFrequencyChangeListener( listener );
}
}
@Override
public void removeFrequencyChangeListener()
{
if( mSymbolFilter != null )
{
mSymbolFilter.setFrequencyChangeListener( null );
}
}
@Override
public Listener<FrequencyChangeEvent> getFrequencyChangeListener()
{
if( mSymbolFilter != null )
{
return mSymbolFilter.getFrequencyChangeListener();
}
return null;
}
}

View File

@@ -26,16 +26,16 @@ import instrument.tap.stream.QPSKTap;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import alias.AliasList;
import sample.Listener;
import sample.complex.ComplexBuffer;
import sample.complex.ComplexBufferToStreamConverter;
import sample.complex.IComplexBufferListener;
import source.tuner.frequency.FrequencyCorrectionControl;
import alias.AliasList;
import dsp.filter.FilterFactory;
import dsp.filter.Window.WindowType;
import dsp.filter.fir.complex.ComplexFIRFilter_CB_CB;
@@ -50,8 +50,8 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
/* Instrumentation Taps */
private static final String INSTRUMENT_BASEBAND_FILTER_OUTPUT = "Tap Point: Baseband Filter Output";
private static final String INSTRUMENT_AGC_OUTPUT = "Tap Point: AGC Output";
private static final String INSTRUMENT_QPSK_DEMODULATOR_OUTPUT = "Tap Point: CQPSK Demodulator Output";
private static final String INSTRUMENT_CQPSK_SLICER_OUTPUT = "Tap Point: CQPSK Slicer Output";
private static final String INSTRUMENT_LSM_DEMODULATOR_OUTPUT = "Tap Point: LSM Demodulator Output";
private static final String INSTRUMENT_QPSK_SLICER_OUTPUT = "Tap Point: QPSK Slicer Output";
private List<TapGroup> mAvailableTaps;
@@ -60,8 +60,8 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
new ComplexBufferToStreamConverter();
private ComplexFeedForwardGainControl mAGC =
new ComplexFeedForwardGainControl( 32 );
private LSMDemodulator mCQPSKDemodulator = new LSMDemodulator();
private QPSKPolarSlicer mCQPSKSlicer = new QPSKPolarSlicer();
private LSMDemodulator mLSMDemodulator = new LSMDemodulator();
private QPSKPolarSlicer mQPSKSlicer = new QPSKPolarSlicer();
private P25MessageFramer mMessageFramer;
public P25_LSMDecoder( AliasList aliasList )
@@ -75,12 +75,12 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
mStreamConverter.setListener( mAGC );
mAGC.setListener( mCQPSKDemodulator );
mAGC.setListener( mLSMDemodulator );
mCQPSKDemodulator.setSymbolListener( mCQPSKSlicer );
mLSMDemodulator.setSymbolListener( mQPSKSlicer );
mMessageFramer = new P25MessageFramer( aliasList, mCQPSKDemodulator );
mCQPSKSlicer.addListener( mMessageFramer );
mMessageFramer = new P25MessageFramer( aliasList, mLSMDemodulator );
mQPSKSlicer.addListener( mMessageFramer );
mMessageFramer.setListener( getMessageProcessor() );
}
@@ -98,11 +98,11 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
mAGC.dispose();
mAGC = null;
mCQPSKDemodulator.dispose();
mCQPSKDemodulator = null;
mLSMDemodulator.dispose();
mLSMDemodulator = null;
mCQPSKSlicer.dispose();
mCQPSKSlicer = null;
mQPSKSlicer.dispose();
mQPSKSlicer = null;
mMessageFramer.dispose();
mMessageFramer = null;
@@ -119,18 +119,6 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
return Modulation.CQPSK;
}
@Override
public boolean hasFrequencyCorrectionControl()
{
return false;
}
@Override
public FrequencyCorrectionControl getFrequencyCorrectionControl()
{
return null;
}
/**
* Provides a list of instrumentation taps for monitoring internal processing
*/
@@ -145,14 +133,14 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
group.add( new ComplexTap( INSTRUMENT_BASEBAND_FILTER_OUTPUT, 0, 1.0f ) );
group.add( new ComplexTap( INSTRUMENT_AGC_OUTPUT, 0, 1.0f ) );
group.add( new QPSKTap( INSTRUMENT_QPSK_DEMODULATOR_OUTPUT, 0, 1.0f ) );
group.add( new DibitTap( INSTRUMENT_CQPSK_SLICER_OUTPUT, 0, 0.1f ) );
group.add( new QPSKTap( INSTRUMENT_LSM_DEMODULATOR_OUTPUT, 0, 1.0f ) );
group.add( new DibitTap( INSTRUMENT_QPSK_SLICER_OUTPUT, 0, 0.1f ) );
mAvailableTaps.add( group );
if( mCQPSKDemodulator != null )
if( mLSMDemodulator != null )
{
mAvailableTaps.addAll( mCQPSKDemodulator.getTapGroups() );
mAvailableTaps.addAll( mLSMDemodulator.getTapGroups() );
}
}
@@ -165,9 +153,9 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
@Override
public void registerTap( Tap tap )
{
if( mCQPSKDemodulator != null )
if( mLSMDemodulator != null )
{
mCQPSKDemodulator.registerTap( tap );
mLSMDemodulator.registerTap( tap );
}
switch( tap.getName() )
@@ -180,15 +168,15 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
case INSTRUMENT_AGC_OUTPUT:
ComplexSampleTap agcSymbol = (ComplexSampleTap)tap;
mAGC.setListener( agcSymbol );
agcSymbol.setListener( mCQPSKDemodulator );
agcSymbol.setListener( mLSMDemodulator );
break;
case INSTRUMENT_QPSK_DEMODULATOR_OUTPUT:
case INSTRUMENT_LSM_DEMODULATOR_OUTPUT:
QPSKTap qpsk = (QPSKTap)tap;
mCQPSKDemodulator.setSymbolListener( qpsk );
qpsk.setListener( mCQPSKSlicer );
mLSMDemodulator.setSymbolListener( qpsk );
qpsk.setListener( mQPSKSlicer );
break;
case INSTRUMENT_CQPSK_SLICER_OUTPUT:
mCQPSKSlicer.addListener( (DibitTap)tap );
case INSTRUMENT_QPSK_SLICER_OUTPUT:
mQPSKSlicer.addListener( (DibitTap)tap );
break;
default:
throw new IllegalArgumentException( "Unrecognized tap: " +
@@ -202,9 +190,9 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
@Override
public void unregisterTap( Tap tap )
{
if( mCQPSKDemodulator != null )
if( mLSMDemodulator != null )
{
mCQPSKDemodulator.unregisterTap( tap );
mLSMDemodulator.unregisterTap( tap );
}
switch( tap.getName() )
@@ -213,13 +201,13 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
mStreamConverter.setListener( mAGC );
break;
case INSTRUMENT_AGC_OUTPUT:
mAGC.setListener( mCQPSKDemodulator );
mAGC.setListener( mLSMDemodulator );
break;
case INSTRUMENT_QPSK_DEMODULATOR_OUTPUT:
mCQPSKDemodulator.setSymbolListener( mCQPSKSlicer );
case INSTRUMENT_LSM_DEMODULATOR_OUTPUT:
mLSMDemodulator.setSymbolListener( mQPSKSlicer );
break;
case INSTRUMENT_CQPSK_SLICER_OUTPUT:
mCQPSKSlicer.removeListener( (DibitTap)tap );
case INSTRUMENT_QPSK_SLICER_OUTPUT:
mQPSKSlicer.removeListener( (DibitTap)tap );
break;
default:
throw new IllegalArgumentException( "Unrecognized tap: " +
@@ -235,7 +223,7 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
}
@Override
public void start()
public void start( ScheduledExecutorService executor )
{
// TODO Auto-generated method stub

View File

@@ -1,5 +1,7 @@
package module.decode.p25.audio;
import java.util.concurrent.ScheduledExecutorService;
import jmbe.iface.AudioConversionLibrary;
import jmbe.iface.AudioConverter;
import message.IMessageListener;
@@ -21,7 +23,6 @@ import audio.squelch.ISquelchStateListener;
import audio.squelch.SquelchState;
import controller.channel.ChannelEvent;
import controller.channel.IChannelEventListener;
import dsp.filter.iir.DeemphasisFilter;
import dsp.gain.NonClippingGain;
public class P25AudioModule extends Module implements Listener<Message>,
@@ -78,7 +79,7 @@ public class P25AudioModule extends Module implements Listener<Message>,
}
@Override
public void start()
public void start( ScheduledExecutorService executor )
{
}
@@ -232,10 +233,10 @@ public class P25AudioModule extends Module implements Listener<Message>,
{
switch( event.getEvent() )
{
case CHANNEL_STATE_RESET:
case NOTIFICATION_STATE_RESET:
mAudioMetadata.reset();
break;
case CHANGE_SELECTED:
case NOTIFICATION_SELECTION_CHANGE:
mAudioMetadata.setSelected( event.getChannel().isSelected() );
break;
default:

View File

@@ -86,7 +86,6 @@ public class P25Message extends Message
sb.append( getNAC() );
sb.append( " " );
sb.append( getDUID().getLabel() );
sb.append( " DATA UNIT ID:" + mMessage.getInt( DUID ) );
return sb.toString();

View File

@@ -7,15 +7,9 @@ import module.decode.p25.message.ldu.LDU1Message;
import module.decode.p25.message.tsbk.osp.control.SystemService;
import module.decode.p25.reference.LinkControlOpcode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AdjacentSiteStatusBroadcast extends LDU1Message
implements IdentifierReceiver, IAdjacentSite
{
private final static Logger mLog =
LoggerFactory.getLogger( AdjacentSiteStatusBroadcast.class );
public static final int[] LRA = { 364,365,366,367,372,373,374,375 };
public static final int[] SYSTEM_ID = { 384,385,386,387,536,537,538,539,540,
541,546,547 };

View File

@@ -6,15 +6,9 @@ import module.decode.p25.message.IdentifierReceiver;
import module.decode.p25.message.ldu.LDU1Message;
import module.decode.p25.reference.LinkControlOpcode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AdjacentSiteStatusBroadcastExplicit extends LDU1Message
implements IdentifierReceiver, IAdjacentSite
{
private final static Logger mLog =
LoggerFactory.getLogger( AdjacentSiteStatusBroadcastExplicit.class );
public static final int[] LRA = { 364,365,366,367,372,373,374,375 };
public static final int[] TRANSMIT_IDENTIFIER = { 376,377,382,383 };
public static final int[] TRANSMIT_CHANNEL = { 384,385,386,387,536,537,538,

View File

@@ -3,13 +3,8 @@ package module.decode.p25.message.ldu.lc;
import module.decode.p25.message.ldu.LDU1Message;
import module.decode.p25.reference.LinkControlOpcode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CallAlert extends LDU1Message
{
private final static Logger mLog =
LoggerFactory.getLogger( CallAlert.class );
public static final int[] TARGET_ADDRESS = { 536,537,538,539,540,541,546,
547,548,549,550,551,556,557,558,559,560,561,566,567,568,569,570,571 };
public static final int[] SOURCE_ADDRESS = { 720,721,722,723,724,725,730,

View File

@@ -3,13 +3,8 @@ package module.decode.p25.message.ldu.lc;
import module.decode.p25.message.ldu.LDU1Message;
import module.decode.p25.reference.LinkControlOpcode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CallTermination extends LDU1Message
{
private final static Logger mLog = LoggerFactory.getLogger( CallTermination.class );
public static final int[] SOURCE_ADDRESS = { 720,721,722,723,724,725,730,
731,732,733,734,735,740,741,742,743,744,745,750,751,752,753,754,755 };

View File

@@ -4,15 +4,9 @@ import module.decode.p25.message.IBandIdentifier;
import module.decode.p25.message.ldu.LDU1Message;
import module.decode.p25.reference.LinkControlOpcode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ChannelIdentifierUpdate extends LDU1Message
implements IBandIdentifier
{
private final static Logger mLog =
LoggerFactory.getLogger( ChannelIdentifierUpdate.class );
public static final int[] IDENTIFIER = { 364,365,366,367 };
public static final int[] BANDWIDTH = { 372,373,374,375,376,377,382,383,384 };
public static final int[] TRANSMIT_OFFSET = { 385,386,387,536,537,538,539,

View File

@@ -4,15 +4,9 @@ import module.decode.p25.message.IBandIdentifier;
import module.decode.p25.message.ldu.LDU1Message;
import module.decode.p25.reference.LinkControlOpcode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ChannelIdentifierUpdateExplicit extends LDU1Message
implements IBandIdentifier
{
private final static Logger mLog =
LoggerFactory.getLogger( ChannelIdentifierUpdateExplicit.class );
public static final int[] IDENTIFIER = { 364,365,366,367 };
public static final int[] BANDWIDTH = { 372,373,374,375 };
public static final int[] TRANSMIT_OFFSET = { 376,377,382,383,384,385,386,

View File

@@ -1,6 +1,5 @@
package module.decode.p25.message.pdu;
import module.decode.p25.message.pdu.confirmed.PacketData;
import module.decode.p25.message.pdu.osp.control.AdjacentStatusBroadcastExtended;
import module.decode.p25.message.pdu.osp.control.CallAlertExtended;
import module.decode.p25.message.pdu.osp.control.GroupAffiliationQueryExtended;
@@ -122,8 +121,7 @@ public class PDUMessageFactory
}
return new PDUMessage( message, duid, aliasList );
case PACKET_DATA:
return new PacketData( message, aliasList );
case UNCONFIRMED_MULTI_BLOCK_TRUNKING_CONTROL:
return new PDUMessage( message, duid, aliasList );
default:

View File

@@ -3,7 +3,6 @@ package module.decode.p25.message.pdu.confirmed;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PDUConfirmedMessageFactory
{
public final static Logger mLog =
@@ -52,7 +51,7 @@ public class PDUConfirmedMessageFactory
return new SNDCPActivateTDSContextAccept( message );
case SNDCP_ACTIVATE_TDS_CONTEXT_REJECT:
return new SNDCPActivateTDSContextReject( message );
case SN_ACTIVATE_TDS_CONTEXT_REQUEST:
case SNDCP_ACTIVATE_TDS_CONTEXT_REQUEST:
return new SNDCPActivateTDSContextRequest( message );
case SNDCP_DEACTIVATE_TDS_CONTEXT_ACCEPT:
case SNDCP_DEACTIVATE_TDS_CONTEXT_REQUEST:
@@ -61,14 +60,6 @@ public class PDUConfirmedMessageFactory
return new SNDCPUserData( message );
case SNDCP_RF_UNCONFIRMED_DATA:
break;
case PDU_TYPE_6:
case PDU_TYPE_7:
case PDU_TYPE_8:
case PDU_TYPE_9:
case PDU_TYPE_10:
case PDU_TYPE_11:
return new PDUTypeUnknown( message );
case UNKNOWN:
default:
break;
}

View File

@@ -1,3 +1,21 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014-2016 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package module.decode.p25.message.tdu;
import module.decode.p25.message.P25Message;
@@ -18,7 +36,7 @@ public class TDUMessage extends P25Message
mCRC = new CRC[ 1 ];
mCRC[ 0 ] = CRC.PASSED;
}
@Override
public String getMessage()
{

View File

@@ -5,17 +5,10 @@ import module.decode.p25.message.IBandIdentifier;
import module.decode.p25.message.IdentifierReceiver;
import module.decode.p25.message.tsbk.osp.control.SystemService;
import module.decode.p25.reference.LinkControlOpcode;
import module.decode.p25.reference.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AdjacentSiteStatusBroadcast extends TDULinkControlMessage
implements IdentifierReceiver, IAdjacentSite
{
private final static Logger mLog =
LoggerFactory.getLogger( AdjacentSiteStatusBroadcast.class );
public static final int[] LRA = { 72,73,74,75,88,89,90,91 };
public static final int[] SYSTEM_ID = { 96,97,98,99,112,113,114,115,
116,117,118,119 };

View File

@@ -5,15 +5,9 @@ import module.decode.p25.message.IBandIdentifier;
import module.decode.p25.message.IdentifierReceiver;
import module.decode.p25.reference.LinkControlOpcode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AdjacentSiteStatusBroadcastExplicit extends TDULinkControlMessage
implements IdentifierReceiver, IAdjacentSite
{
private final static Logger mLog =
LoggerFactory.getLogger( AdjacentSiteStatusBroadcastExplicit.class );
public static final int[] LRA = { 72,73,74,75,88,89,90,91 };
public static final int[] TRANSMIT_IDENTIFIER = { 92,93,94,95 };
public static final int[] TRANSMIT_CHANNEL = { 96,97,98,99,112,113,114,115,

View File

@@ -2,13 +2,8 @@ package module.decode.p25.message.tdu.lc;
import module.decode.p25.reference.LinkControlOpcode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CallAlert extends TDULinkControlMessage
{
private final static Logger mLog =
LoggerFactory.getLogger( CallAlert.class );
public static final int[] TARGET_ADDRESS = { 112,113,114,115,116,117,118,
119,120,121,122,123,136,137,138,139,140,141,142,143,144,145,146,147 };
public static final int[] SOURCE_ADDRESS = { 160,161,162,163,164,165,166,

View File

@@ -2,13 +2,8 @@ package module.decode.p25.message.tdu.lc;
import module.decode.p25.reference.LinkControlOpcode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CallTermination extends TDULinkControlMessage
{
private final static Logger mLog = LoggerFactory.getLogger( CallTermination.class );
public static final int[] SOURCE_ADDRESS = { 160,161,162,163,164,165,166,
167,168,169,170,171,184,185,186,187,188,189,190,191,192,193,194,195 };

View File

@@ -3,15 +3,9 @@ package module.decode.p25.message.tdu.lc;
import module.decode.p25.message.IBandIdentifier;
import module.decode.p25.reference.LinkControlOpcode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ChannelIdentifierUpdate extends TDULinkControlMessage
implements IBandIdentifier
{
private final static Logger mLog =
LoggerFactory.getLogger( ChannelIdentifierUpdate.class );
public static final int[] IDENTIFIER = { 72,73,74,75 };
public static final int[] BANDWIDTH = { 88,89,90,91,92,93,94,95,96 };
public static final int[] TRANSMIT_OFFSET = { 97,98,99,112,113,114,115,116,

View File

@@ -3,15 +3,9 @@ package module.decode.p25.message.tdu.lc;
import module.decode.p25.message.IBandIdentifier;
import module.decode.p25.reference.LinkControlOpcode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ChannelIdentifierUpdateExplicit extends TDULinkControlMessage
implements IBandIdentifier
{
private final static Logger mLog =
LoggerFactory.getLogger( ChannelIdentifierUpdateExplicit.class );
public static final int[] IDENTIFIER = { 72,73,74,75 };
public static final int[] BANDWIDTH = { 88,89,90,91 };
public static final int[] TRANSMIT_OFFSET = { 92,93,94,95,96,97,98,99,112,

View File

@@ -78,93 +78,67 @@ public class TSBKMessageFactory
switch( opcode )
{
case ACKNOWLEDGE_RESPONSE:
return new AcknowledgeResponse( message, duid,
aliasList );
return new AcknowledgeResponse( message, duid, aliasList );
case ADJACENT_STATUS_BROADCAST:
return new AdjacentStatusBroadcast( message, duid,
aliasList );
return new AdjacentStatusBroadcast( message, duid, aliasList );
case AUTHENTICATION_COMMAND:
return new AuthenticationCommand( message, duid,
aliasList );
return new AuthenticationCommand( message, duid, aliasList );
case CALL_ALERT:
return new CallAlert( message, duid, aliasList );
case DENY_RESPONSE:
return new DenyResponse( message, duid, aliasList );
case EXTENDED_FUNCTION_COMMAND:
return new ExtendedFunctionCommand( message, duid,
aliasList );
return new ExtendedFunctionCommand( message, duid, aliasList );
case GROUP_AFFILIATION_QUERY:
return new GroupAffiliationQuery( message, duid,
aliasList );
return new GroupAffiliationQuery( message, duid, aliasList );
case GROUP_AFFILIATION_RESPONSE:
return new GroupAffiliationResponse( message, duid,
aliasList );
return new GroupAffiliationResponse( message, duid, aliasList );
case GROUP_DATA_CHANNEL_ANNOUNCEMENT:
return new GroupDataChannelAnnouncement( message, duid,
aliasList );
return new GroupDataChannelAnnouncement( message, duid, aliasList );
case GROUP_DATA_CHANNEL_ANNOUNCEMENT_EXPLICIT:
return new GroupDataChannelAnnouncementExplicit(
message, duid, aliasList );
return new GroupDataChannelAnnouncementExplicit( message, duid, aliasList );
case GROUP_DATA_CHANNEL_GRANT:
return new GroupDataChannelGrant( message, duid,
aliasList );
return new GroupDataChannelGrant( message, duid, aliasList );
case GROUP_VOICE_CHANNEL_GRANT:
return new GroupVoiceChannelGrant( message, duid,
aliasList );
return new GroupVoiceChannelGrant( message, duid, aliasList );
case GROUP_VOICE_CHANNEL_GRANT_UPDATE:
return new GroupVoiceChannelGrantUpdate( message, duid,
aliasList );
return new GroupVoiceChannelGrantUpdate( message, duid, aliasList );
case GROUP_VOICE_CHANNEL_GRANT_UPDATE_EXPLICIT:
return new GroupVoiceChannelGrantUpdateExplicit( message,
duid, aliasList );
return new GroupVoiceChannelGrantUpdateExplicit( message, duid, aliasList );
case IDENTIFIER_UPDATE_NON_VUHF:
return new IdentifierUpdateNonVUHF( message, duid,
aliasList );
return new IdentifierUpdateNonVUHF( message, duid, aliasList );
case IDENTIFIER_UPDATE_TDMA:
return new IdentifierUpdateTDMA( message, duid, aliasList );
case IDENTIFIER_UPDATE_VHF_UHF_BANDS:
return new IdentifierUpdateVUHF( message, duid,
aliasList );
return new IdentifierUpdateVUHF( message, duid, aliasList );
case INDIVIDUAL_DATA_CHANNEL_GRANT:
return new IndividualDataChannelGrant( message, duid,
aliasList );
return new IndividualDataChannelGrant( message, duid, aliasList );
case LOCATION_REGISTRATION_RESPONSE:
return new LocationRegistrationResponse( message, duid,
aliasList );
return new LocationRegistrationResponse( message, duid, aliasList );
case MESSAGE_UPDATE:
return new MessageUpdate( message, duid, aliasList );
case NETWORK_STATUS_BROADCAST:
return new NetworkStatusBroadcast( message, duid,
aliasList );
return new NetworkStatusBroadcast( message, duid, aliasList );
case QUEUED_RESPONSE:
return new QueuedResponse( message, duid, aliasList );
case PROTECTION_PARAMETER_UPDATE:
return new ProtectionParameterUpdate( message, duid,
aliasList );
return new ProtectionParameterUpdate( message, duid, aliasList );
case RADIO_UNIT_MONITOR_COMMAND:
return new RadioUnitMonitorCommand( message, duid,
aliasList );
return new RadioUnitMonitorCommand( message, duid, aliasList );
case RFSS_STATUS_BROADCAST:
return new RFSSStatusBroadcast( message, duid,
aliasList );
return new RFSSStatusBroadcast( message, duid, aliasList );
case ROAMING_ADDRESS_COMMAND:
return new RoamingAddressCommand( message, duid,
aliasList );
return new RoamingAddressCommand( message, duid, aliasList );
case SECONDARY_CONTROL_CHANNEL_BROADCAST:
return new SecondaryControlChannelBroadcast( message,
duid, aliasList );
return new SecondaryControlChannelBroadcast( message, duid, aliasList );
case SECONDARY_CONTROL_CHANNEL_BROADCAST_EXPLICIT:
return new SecondaryControlChannelBroadcastExplicit(
message, duid, aliasList );
return new SecondaryControlChannelBroadcastExplicit( message, duid, aliasList );
case SNDCP_DATA_CHANNEL_GRANT:
return new SNDCPDataChannelGrant( message, duid,
aliasList );
return new SNDCPDataChannelGrant( message, duid, aliasList );
case SNDCP_DATA_CHANNEL_ANNOUNCEMENT_EXPLICIT:
return new SNDCPDataChannelAnnouncementExplicit(
message, duid, aliasList );
return new SNDCPDataChannelAnnouncementExplicit( message, duid, aliasList );
case SNDCP_DATA_PAGE_REQUEST:
return new SNDCPDataPageRequest( message, duid,
aliasList );
return new SNDCPDataPageRequest( message, duid, aliasList );
case STATUS_QUERY:
return new StatusQuery( message, duid, aliasList );
case STATUS_UPDATE:
@@ -172,35 +146,25 @@ public class TSBKMessageFactory
case TDMA_SYNC_BROADCAST:
return new SyncBroadcast( message, duid, aliasList );
case SYSTEM_SERVICE_BROADCAST:
return new SystemServiceBroadcast( message, duid,
aliasList );
return new SystemServiceBroadcast( message, duid, aliasList );
case TELEPHONE_INTERCONNECT_ANSWER_REQUEST:
return new TelephoneInterconnectAnswerRequest(
message, duid, aliasList );
return new TelephoneInterconnectAnswerRequest( message, duid, aliasList );
case TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT:
return new TelephoneInterconnectVoiceChannelGrant(
message, duid, aliasList );
return new TelephoneInterconnectVoiceChannelGrant( message, duid, aliasList );
case TIME_DATE_ANNOUNCEMENT:
return new TimeAndDateAnnouncement( message, duid,
aliasList );
return new TimeAndDateAnnouncement( message, duid, aliasList );
case UNIT_DEREGISTRATION_ACKNOWLEDGE:
return new UnitDeregistrationAcknowledge( message,
duid, aliasList );
return new UnitDeregistrationAcknowledge( message, duid, aliasList );
case UNIT_REGISTRATION_COMMAND:
return new UnitRegistrationCommand( message, duid,
aliasList );
return new UnitRegistrationCommand( message, duid, aliasList );
case UNIT_REGISTRATION_RESPONSE:
return new UnitRegistrationResponse( message, duid,
aliasList );
return new UnitRegistrationResponse( message, duid, aliasList );
case UNIT_TO_UNIT_ANSWER_REQUEST:
return new UnitToUnitAnswerRequest( message, duid,
aliasList );
return new UnitToUnitAnswerRequest( message, duid, aliasList );
case UNIT_TO_UNIT_VOICE_CHANNEL_GRANT:
return new UnitToUnitVoiceChannelGrant( message,
duid, aliasList );
return new UnitToUnitVoiceChannelGrant( message, duid, aliasList );
case UNIT_TO_UNIT_VOICE_CHANNEL_GRANT_UPDATE:
return new UnitToUnitVoiceChannelGrantUpdate( message,
duid, aliasList );
return new UnitToUnitVoiceChannelGrantUpdate( message, duid, aliasList );
default:
return new TSBKMessage( message, duid, aliasList );
}
@@ -235,4 +199,4 @@ public class TSBKMessageFactory
return new TSBKMessage( message, duid, aliasList );
}
}
}
}

View File

@@ -156,4 +156,4 @@ public class IdentifierUpdateTDMA extends IdentifierUpdate
{
HALF_RATE, FULL_RATE;
}
}
}

View File

@@ -271,4 +271,4 @@ public class SyncBroadcast extends TSBKMessage
{
return mMessage.getInt( MICRO_SLOTS );
}
}
}

View File

@@ -0,0 +1,42 @@
package module.decode.p25.message.vselp;
import module.decode.p25.message.P25Message;
import module.decode.p25.reference.DataUnitID;
import alias.AliasList;
import bits.BinaryMessage;
public class VSELP1Message extends P25Message
{
/**
* Motorola VSELP audio message 1.
*
* @param message
* @param duid
* @param aliasList
*/
public VSELP1Message( BinaryMessage message, DataUnitID duid, AliasList aliasList )
{
super( message, duid, aliasList );
}
@Override
public String getMessage()
{
StringBuilder sb = new StringBuilder();
sb.append( getMessageStub() );
sb.append( " " );
sb.append( mMessage.toString() );
return sb.toString();
}
public String getMessageStub()
{
StringBuilder sb = new StringBuilder();
sb.append( "VSELP 1 VOICE FRAME" );
return sb.toString();
}
}

View File

@@ -0,0 +1,42 @@
package module.decode.p25.message.vselp;
import alias.AliasList;
import bits.BinaryMessage;
import module.decode.p25.message.P25Message;
import module.decode.p25.reference.DataUnitID;
public class VSELP2Message extends P25Message
{
/**
* Motorola VSELP audio message 1.
*
* @param message
* @param duid
* @param aliasList
*/
public VSELP2Message( BinaryMessage message, DataUnitID duid, AliasList aliasList )
{
super( message, duid, aliasList );
}
@Override
public String getMessage()
{
StringBuilder sb = new StringBuilder();
sb.append( getMessageStub() );
sb.append( " " );
sb.append( mMessage.toString() );
return sb.toString();
}
public String getMessageStub()
{
StringBuilder sb = new StringBuilder();
sb.append( "VSELP 2 VOICE FRAME" );
return sb.toString();
}
}

View File

@@ -14,7 +14,7 @@ public enum DataUnitID
TSBK1( 7, 260, false, "TSBK1", "Trunking Signaling Block" ),
TSBK2( 7, 260, false, "TSBK2", "Trunking Signaling Block" ),
TSBK3( 7, 260, false, "TSBK3", "Trunking Signaling Block" ),
VSELP2( 9, 1680, false, "VSEL1", "Motorola VSELP Unit 1" ),
VSELP2( 9, 1680, false, "VSEL2", "Motorola VSELP Unit 2" ),
LDU2 ( 10, 1632, true, "LDU2 ", "Logical Link Data Unit 2" ),
PDU0 ( 12, 260, false, "PDU0 ", "Packet Header Data Unit" ),
PDU1 ( 12, 356, false, "PDU1 ", "Packet Data Unit-Unconfirmed" ),
@@ -75,8 +75,12 @@ public enum DataUnitID
return TDU;
case 5:
return LDU1;
case 6:
return VSELP1;
case 7:
return TSBK1;
case 9:
return VSELP2;
case 10:
return LDU2;
case 12:

View File

@@ -17,7 +17,7 @@ public enum PDUType
PDU_TYPE_11( "PDU TYPE 11 UNKNOWN", 11 ),
/* Inbound */
SN_ACTIVATE_TDS_CONTEXT_REQUEST( "SN-ACTIVATE TDS CONTEXT REQUEST", 0 ),
SNDCP_ACTIVATE_TDS_CONTEXT_REQUEST( "SNDCP-ACTIVATE TDS CONTEXT REQUEST", 0 ),
UNKNOWN( "UNKNOWN", -1 );
@@ -48,9 +48,9 @@ public enum PDUType
}
else if( value == 0 && !outbound )
{
return SN_ACTIVATE_TDS_CONTEXT_REQUEST;
return SNDCP_ACTIVATE_TDS_CONTEXT_REQUEST;
}
return UNKNOWN;
}
}
}

View File

@@ -2,7 +2,7 @@ package module.decode.p25.reference;
public enum ServiceAccessPoint
{
UNENCRYPTED_USER_DATA( "UNENCRYPTED USER DATA", 0 ),
UNENCRYPTED_USER_DATA( "USER DATA", 0 ),
ENCRYPTED_USER_DATA( "ENCRYPTED USER DATA", 1 ),
CIRCUIT_DATA( "CIRCUIT DATA", 2 ),
CIRCUIT_DATA_CONTROL( "CIRCUIT DATA CONTROL", 3 ),