mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-15 01:57:39 -05:00
Updated LTR Standard decoder state to new architecture to support
per-call recording and accurate state tracking. Resolved issue with ThreadPoolManager limiting total number of scheduled tasks (removed limiter - original intent is now OBE) Updated ChannelState to better handle auxiliary decoder decode events, so that when a fleetsync ident is at the end of the transmission, the decode doesn't kick the channel back into a call state after it has faded, causing static bursts and additional empty recordings. Updated recording file name to include millisecond level precision, to further avoid duplicate recording names
This commit is contained in:
@@ -32,7 +32,6 @@ public class ThreadPoolManager
|
|||||||
private final static Logger mLog = LoggerFactory.getLogger( ThreadPoolManager.class );
|
private final static Logger mLog = LoggerFactory.getLogger( ThreadPoolManager.class );
|
||||||
|
|
||||||
private int THREAD_POOL_SIZE = 2;
|
private int THREAD_POOL_SIZE = 2;
|
||||||
private int MAX_TASK_COUNT = 24;
|
|
||||||
|
|
||||||
private HashMap<ScheduledFuture<?>,ThreadType> mTasks =
|
private HashMap<ScheduledFuture<?>,ThreadType> mTasks =
|
||||||
new HashMap<ScheduledFuture<?>,ThreadType>();
|
new HashMap<ScheduledFuture<?>,ThreadType>();
|
||||||
@@ -55,21 +54,12 @@ public class ThreadPoolManager
|
|||||||
new NamingThreadFactory( "sdrtrunk" ) );
|
new NamingThreadFactory( "sdrtrunk" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( mTasks.size() <= MAX_TASK_COUNT )
|
ScheduledFuture<?> task =
|
||||||
{
|
mExecutor.scheduleAtFixedRate( command, 0, period, unit );
|
||||||
ScheduledFuture<?> task =
|
|
||||||
mExecutor.scheduleAtFixedRate( command, 0, period, unit );
|
|
||||||
|
|
||||||
mTasks.put( task, type );
|
mTasks.put( task, type );
|
||||||
|
|
||||||
return task;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new RejectedExecutionException( "Cannot schedule task - at "
|
|
||||||
+ "max task count [" + mTasks.size() + "]" );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void scheduleOnce( Runnable command, long delay, TimeUnit unit )
|
public void scheduleOnce( Runnable command, long delay, TimeUnit unit )
|
||||||
@@ -81,22 +71,14 @@ public class ThreadPoolManager
|
|||||||
new NamingThreadFactory( "sdrtrunk" ) );
|
new NamingThreadFactory( "sdrtrunk" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( mTasks.size() <= MAX_TASK_COUNT )
|
mExecutor.schedule( command, delay, unit );
|
||||||
{
|
|
||||||
mExecutor.schedule( command, delay, unit );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new RejectedExecutionException( "Cannot schedule task - at "
|
|
||||||
+ "max task count [" + mTasks.size() + "]" );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cancel( ScheduledFuture<?> task )
|
public void cancel( ScheduledFuture<?> task )
|
||||||
{
|
{
|
||||||
task.cancel( true );
|
task.cancel( true );
|
||||||
|
|
||||||
ThreadType type = mTasks.remove( task );
|
mTasks.remove( task );
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTaskCount( ThreadType type )
|
public int getTaskCount( ThreadType type )
|
||||||
|
|||||||
@@ -66,8 +66,6 @@ public class CallEventModel extends AbstractTableModel implements Listener<CallE
|
|||||||
|
|
||||||
private SimpleDateFormat mSDFTime = new SimpleDateFormat( "HH:mm:ss" );
|
private SimpleDateFormat mSDFTime = new SimpleDateFormat( "HH:mm:ss" );
|
||||||
|
|
||||||
private boolean mNewMessagesFirst = true;
|
|
||||||
|
|
||||||
public CallEventModel()
|
public CallEventModel()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -102,10 +100,6 @@ public class CallEventModel extends AbstractTableModel implements Listener<CallE
|
|||||||
*/
|
*/
|
||||||
public void receive( final CallEvent event )
|
public void receive( final CallEvent event )
|
||||||
{
|
{
|
||||||
//TODO: reverse this so that the new events go to the end and the oldest
|
|
||||||
//events are at the beginning ... use the getObjectAt() to control
|
|
||||||
//correct access to the ordering imposed.
|
|
||||||
|
|
||||||
if( event.isValid() )
|
if( event.isValid() )
|
||||||
{
|
{
|
||||||
if( !mEvents.contains( event ) )
|
if( !mEvents.contains( event ) )
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ public class Fleetsync2DecoderState extends DecoderState
|
|||||||
private String mMessage;
|
private String mMessage;
|
||||||
private String mMessageType;
|
private String mMessageType;
|
||||||
|
|
||||||
|
private long mFrequency;
|
||||||
|
|
||||||
public Fleetsync2DecoderState( AliasList aliasList )
|
public Fleetsync2DecoderState( AliasList aliasList )
|
||||||
{
|
{
|
||||||
super( aliasList );
|
super( aliasList );
|
||||||
@@ -158,14 +160,14 @@ public class Fleetsync2DecoderState extends DecoderState
|
|||||||
}
|
}
|
||||||
|
|
||||||
FleetsyncCallEvent fsCallEvent =
|
FleetsyncCallEvent fsCallEvent =
|
||||||
FleetsyncCallEvent.getFleetsync2Event( fleetsync );
|
FleetsyncCallEvent.getFleetsync2Event( fleetsync, mFrequency );
|
||||||
|
|
||||||
fsCallEvent.setAliasList( getAliasList() );
|
fsCallEvent.setAliasList( getAliasList() );
|
||||||
|
|
||||||
broadcast( fsCallEvent );
|
broadcast( fsCallEvent );
|
||||||
|
|
||||||
/* Broadcast decode event so that the channel state will
|
/* Broadcast decode event so that the channel state will
|
||||||
* kick in and reset everything */
|
* kick in and reset everything after a short delay */
|
||||||
broadcast( new DecoderStateEvent( this, Event.DECODE, state ) );
|
broadcast( new DecoderStateEvent( this, Event.DECODE, state ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -248,6 +250,9 @@ public class Fleetsync2DecoderState extends DecoderState
|
|||||||
case RESET:
|
case RESET:
|
||||||
resetState();
|
resetState();
|
||||||
break;
|
break;
|
||||||
|
case SOURCE_FREQUENCY:
|
||||||
|
mFrequency = event.getFrequency();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,14 +24,19 @@ import alias.AliasList;
|
|||||||
|
|
||||||
public class FleetsyncCallEvent extends CallEvent
|
public class FleetsyncCallEvent extends CallEvent
|
||||||
{
|
{
|
||||||
|
private long mFrequency = 0;
|
||||||
|
|
||||||
public FleetsyncCallEvent( CallEventType callEventType,
|
public FleetsyncCallEvent( CallEventType callEventType,
|
||||||
AliasList aliasList,
|
AliasList aliasList,
|
||||||
String fromID,
|
String fromID,
|
||||||
String toID,
|
String toID,
|
||||||
String details )
|
String details,
|
||||||
|
long frequency )
|
||||||
{
|
{
|
||||||
super( DecoderType.FLEETSYNC2, callEventType,
|
super( DecoderType.FLEETSYNC2, callEventType,
|
||||||
aliasList, fromID, toID, details );
|
aliasList, fromID, toID, details );
|
||||||
|
|
||||||
|
mFrequency = frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Alias getAlias( String ident )
|
private Alias getAlias( String ident )
|
||||||
@@ -65,7 +70,7 @@ public class FleetsyncCallEvent extends CallEvent
|
|||||||
@Override
|
@Override
|
||||||
public long getFrequency()
|
public long getFrequency()
|
||||||
{
|
{
|
||||||
return 0;
|
return mFrequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder
|
public static class Builder
|
||||||
@@ -78,6 +83,7 @@ public class FleetsyncCallEvent extends CallEvent
|
|||||||
private String mFromID;
|
private String mFromID;
|
||||||
private String mToID;
|
private String mToID;
|
||||||
private String mDetails;
|
private String mDetails;
|
||||||
|
private long mFrequency;
|
||||||
|
|
||||||
public Builder( CallEventType callEventType )
|
public Builder( CallEventType callEventType )
|
||||||
{
|
{
|
||||||
@@ -90,6 +96,12 @@ public class FleetsyncCallEvent extends CallEvent
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder frequency( long frequency )
|
||||||
|
{
|
||||||
|
mFrequency = frequency;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder from( String val )
|
public Builder from( String val )
|
||||||
{
|
{
|
||||||
mFromID = val;
|
mFromID = val;
|
||||||
@@ -123,11 +135,12 @@ public class FleetsyncCallEvent extends CallEvent
|
|||||||
builder.mAliasList,
|
builder.mAliasList,
|
||||||
builder.mFromID,
|
builder.mFromID,
|
||||||
builder.mToID,
|
builder.mToID,
|
||||||
builder.mDetails );
|
builder.mDetails,
|
||||||
|
builder.mFrequency );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FleetsyncCallEvent
|
public static FleetsyncCallEvent getFleetsync2Event(
|
||||||
getFleetsync2Event( FleetsyncMessage message )
|
FleetsyncMessage message, long frequency )
|
||||||
{
|
{
|
||||||
CallEventType type = CallEventType.UNKNOWN;
|
CallEventType type = CallEventType.UNKNOWN;
|
||||||
StringBuilder sbDetails = new StringBuilder();
|
StringBuilder sbDetails = new StringBuilder();
|
||||||
@@ -176,6 +189,7 @@ public class FleetsyncCallEvent extends CallEvent
|
|||||||
{
|
{
|
||||||
return new FleetsyncCallEvent.Builder( type )
|
return new FleetsyncCallEvent.Builder( type )
|
||||||
.details( sbDetails.toString() )
|
.details( sbDetails.toString() )
|
||||||
|
.frequency( frequency )
|
||||||
.from( message.getFromID() )
|
.from( message.getFromID() )
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
@@ -183,6 +197,7 @@ public class FleetsyncCallEvent extends CallEvent
|
|||||||
{
|
{
|
||||||
return new FleetsyncCallEvent.Builder( type )
|
return new FleetsyncCallEvent.Builder( type )
|
||||||
.details( sbDetails.toString() )
|
.details( sbDetails.toString() )
|
||||||
|
.frequency( frequency )
|
||||||
.from( message.getFromID() )
|
.from( message.getFromID() )
|
||||||
.to( message.getToID() )
|
.to( message.getToID() )
|
||||||
.build();
|
.build();
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ public class LTRCallEvent extends CallEvent
|
|||||||
{
|
{
|
||||||
private String mChannel;
|
private String mChannel;
|
||||||
private long mFrequency;
|
private long mFrequency;
|
||||||
private int mValidCallMessages = 1;
|
|
||||||
|
|
||||||
public LTRCallEvent( DecoderType type,
|
public LTRCallEvent( DecoderType type,
|
||||||
CallEventType callEventType,
|
CallEventType callEventType,
|
||||||
@@ -44,26 +43,6 @@ public class LTRCallEvent extends CallEvent
|
|||||||
mFrequency = frequency;
|
mFrequency = frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* LTR sends multiple CALL messages during a call. In order to detect noise
|
|
||||||
* bursts from valid calls, send every valid call message to this method
|
|
||||||
* and the event will keep a tally of valid call messages in order to
|
|
||||||
* determine if the call was a valid (and loggable) call event.
|
|
||||||
*/
|
|
||||||
public boolean addMessage( LTRStandardMessage message )
|
|
||||||
{
|
|
||||||
String talkgroup = message.getTalkgroupID();
|
|
||||||
|
|
||||||
if( talkgroup.contentEquals( getToID() ) )
|
|
||||||
{
|
|
||||||
mValidCallMessages++;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the message's talkgroup matches this call event. Counts the
|
* Checks if the message's talkgroup matches this call event. Counts the
|
||||||
* number of messages that match this call event to use in determining if
|
* number of messages that match this call event to use in determining if
|
||||||
@@ -78,24 +57,12 @@ public class LTRCallEvent extends CallEvent
|
|||||||
if( talkgroup != null && getToID() != null &&
|
if( talkgroup != null && getToID() != null &&
|
||||||
talkgroup.contentEquals( getToID() ) )
|
talkgroup.contentEquals( getToID() ) )
|
||||||
{
|
{
|
||||||
mValidCallMessages++;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isValid()
|
|
||||||
{
|
|
||||||
if( getCallEventType() == CallEventType.CALL )
|
|
||||||
{
|
|
||||||
return mValidCallMessages > 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Alias getAlias( String talkgroup )
|
private Alias getAlias( String talkgroup )
|
||||||
{
|
{
|
||||||
if( hasAliasList() )
|
if( hasAliasList() )
|
||||||
|
|||||||
@@ -675,7 +675,7 @@ public class LTRNetDecoderState extends DecoderState
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the decoder state for re-use on another channel
|
* Performs a full reset
|
||||||
*/
|
*/
|
||||||
public void reset()
|
public void reset()
|
||||||
{
|
{
|
||||||
@@ -694,7 +694,7 @@ public class LTRNetDecoderState extends DecoderState
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the decoder state after a call event
|
* Resets the decoder state after a call or other decode event
|
||||||
*/
|
*/
|
||||||
private void resetState()
|
private void resetState()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import java.awt.EventQueue;
|
|||||||
|
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
|
|
||||||
|
import net.miginfocom.swing.MigLayout;
|
||||||
import module.decode.state.ChangedAttribute;
|
import module.decode.state.ChangedAttribute;
|
||||||
import module.decode.state.DecoderPanel;
|
import module.decode.state.DecoderPanel;
|
||||||
import settings.ColorSetting;
|
import settings.ColorSetting;
|
||||||
@@ -53,7 +54,11 @@ public class LTRStandardDecoderPanel extends DecoderPanel
|
|||||||
|
|
||||||
public void init()
|
public void init()
|
||||||
{
|
{
|
||||||
mProtocol.setFont( mFontDecoder );
|
super.init();
|
||||||
|
|
||||||
|
setLayout( new MigLayout( "insets 0 0 0 0", "[grow,fill]", "[]0[]0[]") );
|
||||||
|
|
||||||
|
mProtocol.setFont( mFontDecoder );
|
||||||
mProtocol.setForeground( mColorLabelDecoder );
|
mProtocol.setForeground( mColorLabelDecoder );
|
||||||
|
|
||||||
mTalkgroup.setFont( mFontDecoder );
|
mTalkgroup.setFont( mFontDecoder );
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* SDR Trunk
|
* SDR Trunk
|
||||||
* Copyright (C) 2014 Dennis Sheirer
|
* Copyright (C) 2014,2015 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -17,7 +17,6 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package module.decode.ltrstandard;
|
package module.decode.ltrstandard;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@@ -35,22 +34,19 @@ import module.decode.state.DecoderStateEvent.Event;
|
|||||||
import module.decode.state.State;
|
import module.decode.state.State;
|
||||||
import alias.Alias;
|
import alias.Alias;
|
||||||
import alias.AliasList;
|
import alias.AliasList;
|
||||||
|
import audio.metadata.Metadata;
|
||||||
|
import audio.metadata.MetadataType;
|
||||||
|
|
||||||
public class LTRStandardDecoderState extends DecoderState
|
public class LTRStandardDecoderState extends DecoderState
|
||||||
{
|
{
|
||||||
private static final int sINT_NULL_VALUE = -1;
|
|
||||||
private DecimalFormat mDecimalFormatter = new DecimalFormat("0.00000");
|
|
||||||
|
|
||||||
private HashMap<Integer,String> mActiveCalls = new HashMap<Integer,String>();
|
private HashMap<Integer,String> mActiveCalls = new HashMap<Integer,String>();
|
||||||
private HashSet<String> mTalkgroupsFirstHeard = new HashSet<String>();
|
private HashSet<String> mTalkgroupsFirstHeard = new HashSet<String>();
|
||||||
private TreeSet<String> mTalkgroups = new TreeSet<String>();
|
private TreeSet<String> mTalkgroups = new TreeSet<String>();
|
||||||
private TreeSet<Integer> mActiveLCNs = new TreeSet<Integer>();
|
private TreeSet<Integer> mActiveLCNs = new TreeSet<Integer>();
|
||||||
private int mMonitoredLCN;
|
|
||||||
|
|
||||||
private String mTalkgroup;
|
private String mTalkgroup;
|
||||||
private Alias mTalkgroupAlias;
|
private Alias mTalkgroupAlias;
|
||||||
private int mChannelNumber;
|
private int mChannelNumber;
|
||||||
|
|
||||||
private long mFrequency;
|
private long mFrequency;
|
||||||
|
|
||||||
public LTRStandardDecoderState( AliasList aliasList )
|
public LTRStandardDecoderState( AliasList aliasList )
|
||||||
@@ -112,13 +108,12 @@ public class LTRStandardDecoderState extends DecoderState
|
|||||||
|
|
||||||
LTRCallEvent current = getCurrentCallEvent();
|
LTRCallEvent current = getCurrentCallEvent();
|
||||||
|
|
||||||
/* If we have an ongoing call, then add this message
|
/* Detect when we haven't reset from the previous
|
||||||
* to the current event - if addMessage returns
|
* call and now have a new call coming in with
|
||||||
* false, then we have a different talkgroup and a
|
* a different talkgroup */
|
||||||
* new call event, so close out the old one. */
|
if( current != null && isDifferentTalkgroup( mTalkgroup ) )
|
||||||
if( current != null && !current.addMessage( ltr ) )
|
|
||||||
{
|
{
|
||||||
mCurrentCallEvent.setEnd( System.currentTimeMillis() );
|
mCurrentCallEvent.end();
|
||||||
broadcast( mCurrentCallEvent );
|
broadcast( mCurrentCallEvent );
|
||||||
mCurrentCallEvent = null;
|
mCurrentCallEvent = null;
|
||||||
}
|
}
|
||||||
@@ -136,25 +131,30 @@ public class LTRStandardDecoderState extends DecoderState
|
|||||||
|
|
||||||
broadcast( mCurrentCallEvent );
|
broadcast( mCurrentCallEvent );
|
||||||
|
|
||||||
broadcast( new DecoderStateEvent( this, Event.START, State.CALL ) );
|
broadcast( new Metadata( MetadataType.TO,
|
||||||
|
mTalkgroup, mTalkgroupAlias, true ) );
|
||||||
|
|
||||||
|
broadcast( new DecoderStateEvent( this,
|
||||||
|
Event.START, State.CALL ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
broadcast( new DecoderStateEvent( this, Event.CONTINUATION, State.CALL ) );
|
broadcast( new DecoderStateEvent( this,
|
||||||
|
Event.CONTINUATION, State.CALL ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CA_ENDD:
|
case CA_ENDD:
|
||||||
mTalkgroup = ltr.getTalkgroupID();
|
mTalkgroup = ltr.getTalkgroupID();
|
||||||
broadcast( ChangedAttribute.FROM_TALKGROUP );
|
broadcast( ChangedAttribute.TO_TALKGROUP );
|
||||||
|
|
||||||
mTalkgroupAlias = ltr.getTalkgroupIDAlias();
|
mTalkgroupAlias = ltr.getTalkgroupIDAlias();
|
||||||
broadcast( ChangedAttribute.FROM_TALKGROUP_ALIAS );
|
broadcast( ChangedAttribute.TO_TALKGROUP_ALIAS );
|
||||||
|
|
||||||
if( mCurrentCallEvent != null )
|
if( mCurrentCallEvent != null )
|
||||||
{
|
{
|
||||||
mCurrentCallEvent.setEnd( System.currentTimeMillis() );
|
mCurrentCallEvent.end();
|
||||||
broadcast( mCurrentCallEvent );
|
broadcast( mCurrentCallEvent );
|
||||||
broadcast( new DecoderStateEvent( this, Event.END, State.FADE ) );
|
broadcast( new DecoderStateEvent( this, Event.END, State.FADE ) );
|
||||||
mCurrentCallEvent = null;
|
mCurrentCallEvent = null;
|
||||||
@@ -182,9 +182,9 @@ public class LTRStandardDecoderState extends DecoderState
|
|||||||
{
|
{
|
||||||
if( channel == home )
|
if( channel == home )
|
||||||
{
|
{
|
||||||
if( mMonitoredLCN != channel )
|
if( mChannelNumber != channel )
|
||||||
{
|
{
|
||||||
mMonitoredLCN = channel;
|
mChannelNumber = channel;
|
||||||
broadcast( ChangedAttribute.CHANNEL_NUMBER );
|
broadcast( ChangedAttribute.CHANNEL_NUMBER );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,15 +206,16 @@ public class LTRStandardDecoderState extends DecoderState
|
|||||||
if( idleChannel == ltr.getHomeRepeater() &&
|
if( idleChannel == ltr.getHomeRepeater() &&
|
||||||
idleChannel == ltr.getFree() )
|
idleChannel == ltr.getFree() )
|
||||||
{
|
{
|
||||||
if( mMonitoredLCN != idleChannel )
|
if( mChannelNumber != idleChannel )
|
||||||
{
|
{
|
||||||
mMonitoredLCN = idleChannel;
|
mChannelNumber = idleChannel;
|
||||||
broadcast( ChangedAttribute.CHANNEL_NUMBER );
|
broadcast( ChangedAttribute.CHANNEL_NUMBER );
|
||||||
}
|
}
|
||||||
|
|
||||||
mActiveLCNs.add( idleChannel );
|
mActiveLCNs.add( idleChannel );
|
||||||
}
|
}
|
||||||
broadcast( new DecoderStateEvent( this, Event.CONTINUATION, State.IDLE ) );
|
broadcast( new DecoderStateEvent( this,
|
||||||
|
Event.CONTINUATION, State.IDLE ) );
|
||||||
break;
|
break;
|
||||||
case UN_KNWN:
|
case UN_KNWN:
|
||||||
default:
|
default:
|
||||||
@@ -224,44 +225,37 @@ public class LTRStandardDecoderState extends DecoderState
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * Intercept the fade event so that we can generate a call end event
|
* Indicates if the talkgroup is different than the talkgroup specified in
|
||||||
// */
|
* the current call event
|
||||||
// @Override
|
*/
|
||||||
// public void fade( final CallEventType type )
|
private boolean isDifferentTalkgroup( String talkgroup )
|
||||||
// {
|
{
|
||||||
// /* We can receive multiple call tear-down messages -- only respond to
|
return talkgroup != null &&
|
||||||
// * the message that can change the state to fade */
|
mCurrentCallEvent != null &&
|
||||||
// if( getState().canChangeTo( State.FADE ) )
|
mCurrentCallEvent.getToID() != null &&
|
||||||
// {
|
!mCurrentCallEvent.getToID().contentEquals( talkgroup );
|
||||||
// mActiveCalls.clear();
|
}
|
||||||
//
|
|
||||||
// LTRCallEvent current = getCurrentLTRCallEvent();
|
|
||||||
//
|
|
||||||
// if( current != null )
|
|
||||||
// {
|
|
||||||
// /* Close out the call event. If we only received 1 call
|
|
||||||
// * message, then flag it as noise and remove the call event */
|
|
||||||
// if( current.isValid() )
|
|
||||||
// {
|
|
||||||
// mCallEventModel.setEnd( current );
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// mCallEventModel.remove( current );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// setCurrentCallEvent( null );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// super.fade( type );
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a full reset
|
||||||
|
*/
|
||||||
public void reset()
|
public void reset()
|
||||||
{
|
{
|
||||||
resetState();
|
mActiveCalls.clear();
|
||||||
|
mTalkgroupsFirstHeard.clear();
|
||||||
|
mTalkgroups.clear();
|
||||||
|
mActiveLCNs.clear();
|
||||||
|
mChannelNumber = 0;
|
||||||
|
|
||||||
|
resetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a temporal reset following a call or other decode event
|
||||||
|
*/
|
||||||
|
private void resetState()
|
||||||
|
{
|
||||||
if( mCurrentCallEvent != null )
|
if( mCurrentCallEvent != null )
|
||||||
{
|
{
|
||||||
mCurrentCallEvent.setEnd( System.currentTimeMillis() );
|
mCurrentCallEvent.setEnd( System.currentTimeMillis() );
|
||||||
@@ -269,15 +263,11 @@ public class LTRStandardDecoderState extends DecoderState
|
|||||||
mCurrentCallEvent = null;
|
mCurrentCallEvent = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resetState()
|
|
||||||
{
|
|
||||||
mTalkgroup = null;
|
mTalkgroup = null;
|
||||||
broadcast( ChangedAttribute.FROM_TALKGROUP );
|
broadcast( ChangedAttribute.TO_TALKGROUP );
|
||||||
|
|
||||||
mTalkgroupAlias = null;
|
mTalkgroupAlias = null;
|
||||||
broadcast( ChangedAttribute.FROM_TALKGROUP_ALIAS );
|
broadcast( ChangedAttribute.TO_TALKGROUP_ALIAS );
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTalkgroup()
|
public String getTalkgroup()
|
||||||
@@ -303,7 +293,6 @@ public class LTRStandardDecoderState extends DecoderState
|
|||||||
@Override
|
@Override
|
||||||
public void init()
|
public void init()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -333,9 +322,9 @@ public class LTRStandardDecoderState extends DecoderState
|
|||||||
|
|
||||||
sb.append( "Monitored LCN: " );
|
sb.append( "Monitored LCN: " );
|
||||||
|
|
||||||
if( mMonitoredLCN > 0 )
|
if( mChannelNumber > 0 )
|
||||||
{
|
{
|
||||||
sb.append( mMonitoredLCN );
|
sb.append( mChannelNumber );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -568,7 +568,6 @@ public class ChannelState extends Module implements ICallEventProvider,
|
|||||||
mSquelchLocked = true;
|
mSquelchLocked = true;
|
||||||
break;
|
break;
|
||||||
case CONTINUATION:
|
case CONTINUATION:
|
||||||
case DECODE:
|
|
||||||
if( isEndingState() )
|
if( isEndingState() )
|
||||||
{
|
{
|
||||||
setState( event.getState() );
|
setState( event.getState() );
|
||||||
@@ -578,6 +577,12 @@ public class ChannelState extends Module implements ICallEventProvider,
|
|||||||
updateFadeTimeout();
|
updateFadeTimeout();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case DECODE:
|
||||||
|
if( getState() == State.IDLE )
|
||||||
|
{
|
||||||
|
setState( event.getState() );
|
||||||
|
}
|
||||||
|
break;
|
||||||
case END:
|
case END:
|
||||||
setState( State.FADE );
|
setState( State.FADE );
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ public class RealBufferWaveRecorder extends Module
|
|||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append( mFilePrefix );
|
sb.append( mFilePrefix );
|
||||||
sb.append( "_" );
|
sb.append( "_" );
|
||||||
sb.append( TimeStamp.getTimeStamp( "_" ) );
|
sb.append( TimeStamp.getLongTimeStamp( "_" ) );
|
||||||
sb.append( ".wav" );
|
sb.append( ".wav" );
|
||||||
|
|
||||||
mFile = Paths.get( sb.toString() );
|
mFile = Paths.get( sb.toString() );
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ public class TimeStamp
|
|||||||
{
|
{
|
||||||
private static SimpleDateFormat mSDFDate = new SimpleDateFormat( "yyyyMMdd" );
|
private static SimpleDateFormat mSDFDate = new SimpleDateFormat( "yyyyMMdd" );
|
||||||
private static SimpleDateFormat mSDFTime = new SimpleDateFormat( "HHmmss" );
|
private static SimpleDateFormat mSDFTime = new SimpleDateFormat( "HHmmss" );
|
||||||
|
private static SimpleDateFormat mSDFTimeWithMilliseconds = new SimpleDateFormat( "HHmmss.SSS" );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current system date formatted as yyyy-MM-dd
|
* Returns the current system date formatted as yyyy-MM-dd
|
||||||
@@ -57,6 +58,14 @@ public class TimeStamp
|
|||||||
return mSDFTime.format( new Date( timestamp ) );
|
return mSDFTime.format( new Date( timestamp ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the timestamp formatted as a time of HH:mm:ss
|
||||||
|
*/
|
||||||
|
public static String getFormattedTimeWithMilliseconds( long timestamp )
|
||||||
|
{
|
||||||
|
return mSDFTime.format( new Date( timestamp ) );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns current system time formatted as yyyy-MM-dd*HH:mm:ss
|
* Returns current system time formatted as yyyy-MM-dd*HH:mm:ss
|
||||||
* with the * representing the separator attribute
|
* with the * representing the separator attribute
|
||||||
@@ -80,5 +89,30 @@ public class TimeStamp
|
|||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns current system time formatted as yyyy-MM-dd*HH:mm:ss.SSS
|
||||||
|
* with the * representing the separator attribute
|
||||||
|
*/
|
||||||
|
public static String getLongTimeStamp( String separator )
|
||||||
|
{
|
||||||
|
return getLongTimeStamp( System.currentTimeMillis(), separator );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns timestamp formatted as yyyy-MM-dd*HH:mm:ss.SSS
|
||||||
|
* with the * representing the separator attribute
|
||||||
|
*/
|
||||||
|
public static String getLongTimeStamp( long timestamp, String separator )
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
sb.append( getFormattedDate( timestamp ) );
|
||||||
|
sb.append( separator );
|
||||||
|
sb.append( getFormattedTimeWithMilliseconds( timestamp ) );
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user