#90 [WIP] on redesigning the channel processing gui components and backing model. Simplifies channel state by introducing a new Metadata class that tracks all metadata for all decoders.

This commit is contained in:
Denny
2017-01-14 11:21:53 -05:00
parent 6a9e522d77
commit 7115b4feb1
57 changed files with 1534 additions and 298 deletions

View File

@@ -92,10 +92,10 @@ import module.decode.passport.PassportDecoderEditor;
import module.decode.passport.PassportDecoderPanel;
import module.decode.passport.PassportDecoderState;
import module.decode.passport.PassportMessageFilter;
import module.decode.state.AlwaysUnsquelchedDecoderState;
import module.decode.state.DecoderPanel;
import module.decode.state.DecoderState;
import module.decode.state.TrafficChannelManager;
import channel.state.AlwaysUnsquelchedDecoderState;
import channel.state.DecoderPanel;
import channel.state.DecoderState;
import channel.traffic.TrafficChannelManager;
import module.decode.tait.Tait1200Decoder;
import module.decode.tait.Tait1200DecoderPanel;
import module.decode.tait.Tait1200DecoderState;

View File

@@ -19,9 +19,9 @@
package module.decode.am;
import icon.IconManager;
import module.decode.state.ChangedAttribute;
import module.decode.state.DecoderPanel;
import module.decode.state.DecoderState;
import channel.metadata.Attribute;
import channel.state.DecoderPanel;
import channel.state.DecoderState;
import net.miginfocom.swing.MigLayout;
import settings.ColorSetting;
import settings.Setting;
@@ -55,7 +55,7 @@ public class AMDecoderPanel extends DecoderPanel
}
@Override
public void receive(final ChangedAttribute changedAttribute)
public void receive(final Attribute attribute)
{
}

View File

@@ -19,8 +19,8 @@
package module.decode.fleetsync2;
import icon.IconManager;
import module.decode.state.ChangedAttribute;
import module.decode.state.DecoderPanel;
import channel.metadata.Attribute;
import channel.state.DecoderPanel;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -116,14 +116,14 @@ public class Fleetsync2DecoderPanel extends DecoderPanel
}
@Override
public void receive(final ChangedAttribute changedAttribute)
public void receive(final Attribute attribute)
{
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
switch(changedAttribute)
switch(attribute)
{
case FROM_TALKGROUP:
String from = getDecoderState().getFromID();

View File

@@ -23,11 +23,11 @@ import java.util.concurrent.ScheduledExecutorService;
import message.Message;
import module.decode.DecoderType;
import module.decode.state.ChangedAttribute;
import module.decode.state.DecoderState;
import module.decode.state.DecoderStateEvent;
import module.decode.state.DecoderStateEvent.Event;
import module.decode.state.State;
import channel.metadata.Attribute;
import channel.state.DecoderState;
import channel.state.DecoderStateEvent;
import channel.state.DecoderStateEvent.Event;
import channel.state.State;
import alias.Alias;
import alias.AliasList;
@@ -182,7 +182,7 @@ public class Fleetsync2DecoderState extends DecoderState
public void setFromID( String from )
{
mFrom = from;
broadcast( ChangedAttribute.FROM_TALKGROUP );
broadcast( Attribute.FROM_TALKGROUP );
}
public Alias getFromIDAlias()
@@ -193,7 +193,7 @@ public class Fleetsync2DecoderState extends DecoderState
public void setFromIDAlias( Alias alias )
{
mFromAlias = alias;
broadcast( ChangedAttribute.FROM_TALKGROUP_ALIAS );
broadcast( Attribute.FROM_TALKGROUP_ALIAS );
}
public String getToID()
@@ -204,7 +204,7 @@ public class Fleetsync2DecoderState extends DecoderState
public void setToID( String to )
{
mTo = to;
broadcast( ChangedAttribute.TO_TALKGROUP );
broadcast( Attribute.TO_TALKGROUP );
}
public Alias getToIDAlias()
@@ -215,7 +215,7 @@ public class Fleetsync2DecoderState extends DecoderState
public void setToIDAlias( Alias alias )
{
mToAlias = alias;
broadcast( ChangedAttribute.TO_TALKGROUP_ALIAS );
broadcast( Attribute.TO_TALKGROUP_ALIAS );
}
public String getMessage()
@@ -226,7 +226,7 @@ public class Fleetsync2DecoderState extends DecoderState
public void setMessage( String message )
{
mMessage = message;
broadcast( ChangedAttribute.MESSAGE );
broadcast( Attribute.MESSAGE );
}
public String getMessageType()
@@ -237,7 +237,7 @@ public class Fleetsync2DecoderState extends DecoderState
public void setMessageType( String type )
{
mMessageType = type;
broadcast( ChangedAttribute.MESSAGE_TYPE );
broadcast( Attribute.MESSAGE_TYPE );
}
/**

View File

@@ -20,8 +20,8 @@ package module.decode.lj1200;
import alias.Alias;
import icon.IconManager;
import module.decode.state.ChangedAttribute;
import module.decode.state.DecoderPanel;
import channel.metadata.Attribute;
import channel.state.DecoderPanel;
import net.miginfocom.swing.MigLayout;
import settings.ColorSetting;
import settings.ColorSetting.ColorSettingName;
@@ -79,9 +79,9 @@ public class LJ1200DecoderPanel extends DecoderPanel
}
@Override
public void receive(final ChangedAttribute changedAttribute)
public void receive(final Attribute attribute)
{
switch(changedAttribute)
switch(attribute)
{
case TO_TALKGROUP:
mTo.setText(getDecoderState().getAddress());

View File

@@ -26,11 +26,11 @@ import java.util.concurrent.ScheduledExecutorService;
import message.Message;
import module.decode.DecoderType;
import module.decode.state.ChangedAttribute;
import module.decode.state.DecoderState;
import module.decode.state.DecoderStateEvent;
import module.decode.state.DecoderStateEvent.Event;
import module.decode.state.State;
import channel.metadata.Attribute;
import channel.state.DecoderState;
import channel.state.DecoderStateEvent;
import channel.state.DecoderStateEvent.Event;
import channel.state.State;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -106,13 +106,13 @@ public class LJ1200DecoderState extends DecoderState
private void setAddress( String address )
{
mAddress = address;
broadcast( ChangedAttribute.TO_TALKGROUP );
broadcast( Attribute.TO_TALKGROUP );
}
private void setAddressAlias( Alias alias )
{
mAddressAlias = alias;
broadcast( ChangedAttribute.TO_TALKGROUP_ALIAS );
broadcast( Attribute.TO_TALKGROUP_ALIAS );
}
@Override
@@ -160,9 +160,9 @@ public class LJ1200DecoderState extends DecoderState
private void resetState()
{
setAddress( null );
broadcast( ChangedAttribute.TO_TALKGROUP );
broadcast( Attribute.TO_TALKGROUP );
setAddressAlias( null );
broadcast( ChangedAttribute.TO_TALKGROUP_ALIAS );
broadcast( Attribute.TO_TALKGROUP_ALIAS );
}
@Override

View File

@@ -20,8 +20,8 @@ package module.decode.ltrnet;
import alias.Alias;
import icon.IconManager;
import module.decode.state.ChangedAttribute;
import module.decode.state.DecoderPanel;
import channel.metadata.Attribute;
import channel.state.DecoderPanel;
import net.miginfocom.swing.MigLayout;
import settings.ColorSetting;
import settings.Setting;
@@ -83,7 +83,7 @@ public class LTRNetDecoderPanel extends DecoderPanel
}
@Override
public void receive(final ChangedAttribute changedAttribute)
public void receive(final Attribute attribute)
{
EventQueue.invokeLater(new Runnable()
{
@@ -92,7 +92,7 @@ public class LTRNetDecoderPanel extends DecoderPanel
{
LTRNetDecoderState state = getDecoderState();
switch(changedAttribute)
switch(attribute)
{
case TO_TALKGROUP:
mTalkgroup.setText(state.getToTalkgroup());

View File

@@ -27,11 +27,11 @@ import message.Message;
import module.decode.DecoderType;
import module.decode.event.CallEvent;
import module.decode.event.CallEvent.CallEventType;
import module.decode.state.ChangedAttribute;
import module.decode.state.DecoderState;
import module.decode.state.DecoderStateEvent;
import module.decode.state.DecoderStateEvent.Event;
import module.decode.state.State;
import channel.metadata.Attribute;
import channel.state.DecoderState;
import channel.state.DecoderStateEvent;
import channel.state.DecoderStateEvent.Event;
import channel.state.State;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -93,7 +93,7 @@ public class LTRNetDecoderState extends DecoderState
if (mChannelNumber == 0)
{
mChannelNumber = ltr.getChannel();
broadcast(ChangedAttribute.CHANNEL_NUMBER);
broadcast(Attribute.CHANNEL_NUMBER);
}
/* Process FCC Station ID Events */
@@ -131,7 +131,7 @@ public class LTRNetDecoderState extends DecoderState
if (mChannelNumber == 0)
{
mChannelNumber = ltr.getChannel();
broadcast(ChangedAttribute.CHANNEL_NUMBER);
broadcast(Attribute.CHANNEL_NUMBER);
}
/* If the call event channel matches our current channel
@@ -150,7 +150,7 @@ public class LTRNetDecoderState extends DecoderState
if (mChannelNumber != ltr.getChannel())
{
mChannelNumber = ltr.getChannel();
broadcast(ChangedAttribute.CHANNEL_NUMBER);
broadcast(Attribute.CHANNEL_NUMBER);
}
break;
case MA_CHNH:
@@ -211,10 +211,10 @@ public class LTRNetDecoderState extends DecoderState
}
mTalkgroup = String.valueOf(uniqueID);
broadcast(ChangedAttribute.TO_TALKGROUP);
broadcast(Attribute.TO_TALKGROUP);
mTalkgroupAlias = ltr.getRadioUniqueIDAlias();
broadcast(ChangedAttribute.TO_TALKGROUP_ALIAS);
broadcast(Attribute.TO_TALKGROUP_ALIAS);
break;
case ID_SITE:
String siteID = ltr.getSiteID();
@@ -252,13 +252,13 @@ public class LTRNetDecoderState extends DecoderState
}
mDescription = "ESN";
broadcast(ChangedAttribute.DESCRIPTION);
broadcast(Attribute.DESCRIPTION);
mTalkgroup = ltr.getESN();
broadcast(ChangedAttribute.TO_TALKGROUP);
broadcast(Attribute.TO_TALKGROUP);
mTalkgroupAlias = ltr.getESNAlias();
broadcast(ChangedAttribute.TO_TALKGROUP_ALIAS);
broadcast(Attribute.TO_TALKGROUP_ALIAS);
broadcast(new DecoderStateEvent(this, Event.DECODE, State.DATA));
@@ -286,13 +286,13 @@ public class LTRNetDecoderState extends DecoderState
mUniqueIDs.add(uniqueid);
mDescription = "REGISTER UID";
broadcast(ChangedAttribute.DESCRIPTION);
broadcast(Attribute.DESCRIPTION);
mTalkgroup = String.valueOf(uniqueid);
broadcast(ChangedAttribute.TO_TALKGROUP);
broadcast(Attribute.TO_TALKGROUP);
mTalkgroupAlias = ltr.getRadioUniqueIDAlias();
broadcast(ChangedAttribute.TO_TALKGROUP_ALIAS);
broadcast(Attribute.TO_TALKGROUP_ALIAS);
if (getCurrentLTRCallEvent() == null)
{
@@ -620,7 +620,7 @@ public class LTRNetDecoderState extends DecoderState
{
broadcast(new DecoderStateEvent(this, Event.START, State.DATA));
mDescription = "REGISTER";
broadcast(ChangedAttribute.DESCRIPTION);
broadcast(Attribute.DESCRIPTION);
}
/* Process call */
else
@@ -643,7 +643,7 @@ public class LTRNetDecoderState extends DecoderState
}
mTalkgroup = message.getTalkgroupID();
broadcast(ChangedAttribute.TO_TALKGROUP);
broadcast(Attribute.TO_TALKGROUP);
/* A talkgroup must be seen at least once before it will be added
* to the mTalkgroups list that is used in the activity summary,
@@ -658,7 +658,7 @@ public class LTRNetDecoderState extends DecoderState
}
mTalkgroupAlias = message.getTalkgroupIDAlias();
broadcast(ChangedAttribute.TO_TALKGROUP_ALIAS);
broadcast(Attribute.TO_TALKGROUP_ALIAS);
CallEvent callEvent = new LTRCallEvent.Builder(DecoderType.LTR_NET, CallEventType.CALL)
.aliasList(getAliasList())
@@ -729,13 +729,13 @@ public class LTRNetDecoderState extends DecoderState
mCurrentCallEvent = null;
mTalkgroup = null;
broadcast(ChangedAttribute.TO_TALKGROUP);
broadcast(Attribute.TO_TALKGROUP);
mTalkgroupAlias = null;
broadcast(ChangedAttribute.TO_TALKGROUP_ALIAS);
broadcast(Attribute.TO_TALKGROUP_ALIAS);
mDescription = null;
broadcast(ChangedAttribute.DESCRIPTION);
broadcast(Attribute.DESCRIPTION);
}
public String getToTalkgroup()

View File

@@ -20,8 +20,8 @@ package module.decode.ltrstandard;
import alias.Alias;
import icon.IconManager;
import module.decode.state.ChangedAttribute;
import module.decode.state.DecoderPanel;
import channel.metadata.Attribute;
import channel.state.DecoderPanel;
import net.miginfocom.swing.MigLayout;
import settings.ColorSetting;
import settings.Setting;
@@ -84,7 +84,7 @@ public class LTRStandardDecoderPanel extends DecoderPanel
}
@Override
public void receive(final ChangedAttribute attribute)
public void receive(final Attribute attribute)
{
EventQueue.invokeLater(new Runnable()
{

View File

@@ -34,11 +34,11 @@ import module.decode.ltrstandard.message.CallEndMessage;
import module.decode.ltrstandard.message.CallMessage;
import module.decode.ltrstandard.message.IdleMessage;
import module.decode.ltrstandard.message.LTRStandardMessage;
import module.decode.state.ChangedAttribute;
import module.decode.state.DecoderState;
import module.decode.state.DecoderStateEvent;
import module.decode.state.DecoderStateEvent.Event;
import module.decode.state.State;
import channel.metadata.Attribute;
import channel.state.DecoderState;
import channel.state.DecoderStateEvent;
import channel.state.DecoderStateEvent.Event;
import channel.state.State;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -137,12 +137,12 @@ public class LTRStandardDecoderState extends DecoderState
if( mLCNTracker.isCurrentChannel( channel ) )
{
mTalkgroup = start.getToID();
broadcast( ChangedAttribute.TO_TALKGROUP );
broadcast( Attribute.TO_TALKGROUP );
processTalkgroup( mTalkgroup );
mTalkgroupAlias = start.getToIDAlias();
broadcast( ChangedAttribute.TO_TALKGROUP_ALIAS );
broadcast( Attribute.TO_TALKGROUP_ALIAS );
broadcast( new Metadata( MetadataType.TO,
mTalkgroup, mTalkgroupAlias, true ) );
@@ -165,12 +165,12 @@ public class LTRStandardDecoderState extends DecoderState
if( mLCNTracker.isCurrentChannel( repeater ) )
{
mTalkgroup = end.getToID();
broadcast( ChangedAttribute.TO_TALKGROUP );
broadcast( Attribute.TO_TALKGROUP );
processTalkgroup( mTalkgroup );
mTalkgroupAlias = end.getToIDAlias();
broadcast( ChangedAttribute.TO_TALKGROUP_ALIAS );
broadcast( Attribute.TO_TALKGROUP_ALIAS );
LTRCallEvent event = mActiveCalls.remove( repeater );
@@ -242,10 +242,10 @@ public class LTRStandardDecoderState extends DecoderState
mActiveCalls.clear();
mTalkgroup = null;
broadcast( ChangedAttribute.TO_TALKGROUP );
broadcast( Attribute.TO_TALKGROUP );
mTalkgroupAlias = null;
broadcast( ChangedAttribute.TO_TALKGROUP_ALIAS );
broadcast( Attribute.TO_TALKGROUP_ALIAS );
}
public String getTalkgroup()
@@ -453,7 +453,7 @@ public class LTRStandardDecoderState extends DecoderState
mCallHighestCount = mCallLCNCounts[ channel ];
mCurrentLCN = channel;
broadcast( ChangedAttribute.CHANNEL_NUMBER );
broadcast( Attribute.CHANNEL_NUMBER );
}
}
}

View File

@@ -20,8 +20,8 @@ package module.decode.mdc1200;
import alias.Alias;
import icon.IconManager;
import module.decode.state.ChangedAttribute;
import module.decode.state.DecoderPanel;
import channel.metadata.Attribute;
import channel.state.DecoderPanel;
import net.miginfocom.swing.MigLayout;
import settings.ColorSetting;
import settings.ColorSetting.ColorSettingName;
@@ -82,14 +82,14 @@ public class MDCDecoderPanel extends DecoderPanel
}
@Override
public void receive(final ChangedAttribute changedAttribute)
public void receive(final Attribute attribute)
{
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
switch(changedAttribute)
switch(attribute)
{
case FROM_TALKGROUP:
String from = getDecoderState().getFrom();

View File

@@ -23,11 +23,11 @@ import java.util.concurrent.ScheduledExecutorService;
import message.Message;
import module.decode.DecoderType;
import module.decode.state.ChangedAttribute;
import module.decode.state.DecoderState;
import module.decode.state.DecoderStateEvent;
import module.decode.state.State;
import module.decode.state.DecoderStateEvent.Event;
import channel.metadata.Attribute;
import channel.state.DecoderState;
import channel.state.DecoderStateEvent;
import channel.state.State;
import channel.state.DecoderStateEvent.Event;
import alias.Alias;
import alias.AliasList;
@@ -150,7 +150,7 @@ public class MDCDecoderState extends DecoderState
public void setFrom( String from )
{
mFrom = from;
broadcast( ChangedAttribute.FROM_TALKGROUP );
broadcast( Attribute.FROM_TALKGROUP );
}
public Alias getFromAlias()
@@ -161,7 +161,7 @@ public class MDCDecoderState extends DecoderState
public void setFromAlias( Alias alias )
{
mFromAlias = alias;
broadcast( ChangedAttribute.FROM_TALKGROUP_ALIAS );
broadcast( Attribute.FROM_TALKGROUP_ALIAS );
}
public String getTo()
@@ -172,7 +172,7 @@ public class MDCDecoderState extends DecoderState
public void setTo( String to )
{
mTo = to;
broadcast( ChangedAttribute.TO_TALKGROUP );
broadcast( Attribute.TO_TALKGROUP );
}
public Alias getToAlias()
@@ -183,7 +183,7 @@ public class MDCDecoderState extends DecoderState
public void setToAlias( Alias alias )
{
mToAlias = alias;
broadcast( ChangedAttribute.TO_TALKGROUP_ALIAS );
broadcast( Attribute.TO_TALKGROUP_ALIAS );
}
public String getMessage()
@@ -194,7 +194,7 @@ public class MDCDecoderState extends DecoderState
public void setMessage( String message )
{
mMessage = message;
broadcast( ChangedAttribute.MESSAGE );
broadcast( Attribute.MESSAGE );
}
public String getMessageType()
@@ -205,7 +205,7 @@ public class MDCDecoderState extends DecoderState
public void setMessageType( String type )
{
mMessageType = type;
broadcast( ChangedAttribute.MESSAGE_TYPE );
broadcast( Attribute.MESSAGE_TYPE );
}
@Override

View File

@@ -20,8 +20,8 @@ package module.decode.mpt1327;
import controller.channel.Channel.ChannelType;
import icon.IconManager;
import module.decode.state.ChangedAttribute;
import module.decode.state.DecoderPanel;
import channel.metadata.Attribute;
import channel.state.DecoderPanel;
import net.miginfocom.swing.MigLayout;
import settings.ColorSetting;
import settings.Setting;
@@ -120,7 +120,7 @@ public class MPT1327DecoderPanel extends DecoderPanel
}
@Override
public void receive(final ChangedAttribute changedAttribute)
public void receive(final Attribute attribute)
{
final MPT1327DecoderState state = getDecoderState();
@@ -129,7 +129,7 @@ public class MPT1327DecoderPanel extends DecoderPanel
@Override
public void run()
{
switch(changedAttribute)
switch(attribute)
{
case CHANNEL_SITE_NUMBER:
mSiteOrToTalkgroup.setText(String.valueOf(state.getSite()));

View File

@@ -31,13 +31,13 @@ import module.decode.config.DecodeConfiguration;
import module.decode.event.CallEvent;
import module.decode.event.CallEvent.CallEventType;
import module.decode.mpt1327.MPT1327Message.IdentType;
import module.decode.state.ChangeChannelTimeoutEvent;
import module.decode.state.ChangedAttribute;
import module.decode.state.DecoderState;
import module.decode.state.DecoderStateEvent;
import module.decode.state.DecoderStateEvent.Event;
import module.decode.state.State;
import module.decode.state.TrafficChannelAllocationEvent;
import channel.state.ChangeChannelTimeoutEvent;
import channel.metadata.Attribute;
import channel.state.DecoderState;
import channel.state.DecoderStateEvent;
import channel.state.DecoderStateEvent.Event;
import channel.state.State;
import channel.traffic.TrafficChannelAllocationEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -184,7 +184,7 @@ public class MPT1327DecoderState extends DecoderState
if( site != null && ( mSite == null || !site.contentEquals( mSite ) ) )
{
mSite = site;
broadcast( ChangedAttribute.CHANNEL_SITE_NUMBER );
broadcast( Attribute.CHANNEL_SITE_NUMBER );
}
mSite = mpt.getSiteID();
@@ -314,10 +314,10 @@ public class MPT1327DecoderState extends DecoderState
private void resetState()
{
mFromTalkgroup = null;
broadcast( ChangedAttribute.FROM_TALKGROUP );
broadcast( Attribute.FROM_TALKGROUP );
mToTalkgroup = null;
broadcast( ChangedAttribute.TO_TALKGROUP );
broadcast( Attribute.TO_TALKGROUP );
/**
* If this is a standard channel, reset the fade timeout to the default
@@ -378,7 +378,7 @@ public class MPT1327DecoderState extends DecoderState
{
mFromTalkgroup = fromTalkgroup;
broadcast( ChangedAttribute.FROM_TALKGROUP );
broadcast( Attribute.FROM_TALKGROUP );
}
public Alias getFromTalkgroupAlias()
@@ -405,7 +405,7 @@ public class MPT1327DecoderState extends DecoderState
{
mToTalkgroup = toTalkgroup;
broadcast( ChangedAttribute.TO_TALKGROUP );
broadcast( Attribute.TO_TALKGROUP );
}
public Alias getToTalkgroupAlias()
@@ -432,7 +432,7 @@ public class MPT1327DecoderState extends DecoderState
{
mChannelNumber = channel;
broadcast( ChangedAttribute.CHANNEL_NUMBER );
broadcast( Attribute.CHANNEL_NUMBER );
}
@Override
@@ -590,7 +590,7 @@ public class MPT1327DecoderState extends DecoderState
try
{
mChannelNumber = Integer.valueOf( channel );
broadcast( ChangedAttribute.CHANNEL_NUMBER );
broadcast( Attribute.CHANNEL_NUMBER );
}
catch( Exception e )
{
@@ -599,13 +599,13 @@ public class MPT1327DecoderState extends DecoderState
}
mFrequency = allocationEvent.getCallEvent().getFrequency();
broadcast( ChangedAttribute.SOURCE );
broadcast( Attribute.SOURCE );
mFromTalkgroup = allocationEvent.getCallEvent().getFromID();
broadcast( ChangedAttribute.FROM_TALKGROUP );
broadcast( Attribute.FROM_TALKGROUP );
mToTalkgroup = allocationEvent.getCallEvent().getToID();
broadcast( ChangedAttribute.TO_TALKGROUP );
broadcast( Attribute.TO_TALKGROUP );
}
}
break;

View File

@@ -20,8 +20,8 @@ package module.decode.mpt1327;
import alias.Alias;
import icon.IconManager;
import module.decode.state.ChangedAttribute;
import module.decode.state.DecoderPanel;
import channel.metadata.Attribute;
import channel.state.DecoderPanel;
import settings.ColorSetting;
import settings.Setting;
import settings.SettingsManager;
@@ -95,7 +95,7 @@ public class MPT1327TrafficPanel extends DecoderPanel
}
@Override
public void receive(final ChangedAttribute changedAttribute)
public void receive(final Attribute attribute)
{
final MPT1327DecoderState state = getDecoderState();
@@ -104,7 +104,7 @@ public class MPT1327TrafficPanel extends DecoderPanel
@Override
public void run()
{
switch(changedAttribute)
switch(attribute)
{
case FROM_TALKGROUP:
String talkgroup = state.getFromTalkgroup();

View File

@@ -19,9 +19,9 @@
package module.decode.nbfm;
import icon.IconManager;
import module.decode.state.ChangedAttribute;
import module.decode.state.DecoderPanel;
import module.decode.state.DecoderState;
import channel.metadata.Attribute;
import channel.state.DecoderPanel;
import channel.state.DecoderState;
import net.miginfocom.swing.MigLayout;
import settings.ColorSetting;
import settings.ColorSetting.ColorSettingName;
@@ -56,7 +56,7 @@ public class NBFMDecoderPanel extends DecoderPanel
}
@Override
public void receive(ChangedAttribute t)
public void receive(Attribute t)
{
/* Not implemented */
}

View File

@@ -20,8 +20,8 @@ package module.decode.p25;
import alias.Alias;
import icon.IconManager;
import module.decode.state.ChangedAttribute;
import module.decode.state.DecoderPanel;
import channel.metadata.Attribute;
import channel.state.DecoderPanel;
import net.miginfocom.swing.MigLayout;
import settings.ColorSetting;
import settings.Setting;
@@ -108,7 +108,7 @@ public class P25DecoderPanel extends DecoderPanel
}
@Override
public void receive(final ChangedAttribute changedAttribute)
public void receive(final Attribute attribute)
{
final P25DecoderState state = getDecoderState();
@@ -118,7 +118,7 @@ public class P25DecoderPanel extends DecoderPanel
public void run()
{
switch(changedAttribute)
switch(attribute)
{
case NAC:
mNAC.setText("NAC:" + state.getNAC());

View File

@@ -123,13 +123,13 @@ 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;
import module.decode.state.DecoderStateEvent.Event;
import module.decode.state.State;
import module.decode.state.TrafficChannelAllocationEvent;
import channel.state.ChangeChannelTimeoutEvent;
import channel.metadata.Attribute;
import channel.state.DecoderState;
import channel.state.DecoderStateEvent;
import channel.state.DecoderStateEvent.Event;
import channel.state.State;
import channel.traffic.TrafficChannelAllocationEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -236,16 +236,16 @@ public class P25DecoderState extends DecoderState
private void resetState()
{
mFromTalkgroup = null;
broadcast(ChangedAttribute.FROM_TALKGROUP);
broadcast(Attribute.FROM_TALKGROUP);
mFromAlias = null;
broadcast(ChangedAttribute.FROM_TALKGROUP_ALIAS);
broadcast(Attribute.FROM_TALKGROUP_ALIAS);
mToTalkgroup = null;
broadcast(ChangedAttribute.TO_TALKGROUP);
broadcast(Attribute.TO_TALKGROUP);
mToAlias = null;
broadcast(ChangedAttribute.TO_TALKGROUP_ALIAS);
broadcast(Attribute.TO_TALKGROUP_ALIAS);
mCallDetectTalkgroups.clear();
@@ -3372,7 +3372,7 @@ public class P25DecoderState extends DecoderState
{
mToTalkgroup = to;
broadcast(ChangedAttribute.TO_TALKGROUP);
broadcast(Attribute.TO_TALKGROUP);
if(hasAliasList())
{
@@ -3383,7 +3383,7 @@ public class P25DecoderState extends DecoderState
mToAlias = null;
}
broadcast(ChangedAttribute.TO_TALKGROUP_ALIAS);
broadcast(Attribute.TO_TALKGROUP_ALIAS);
/* Send audio metadata update */
broadcast(new Metadata(MetadataType.TO, mToTalkgroup, mToAlias, true));
@@ -3409,7 +3409,7 @@ public class P25DecoderState extends DecoderState
if(mFromTalkgroup == null || !mFromTalkgroup.contentEquals(from))
{
mFromTalkgroup = from;
broadcast(ChangedAttribute.FROM_TALKGROUP);
broadcast(Attribute.FROM_TALKGROUP);
if(hasAliasList())
{
@@ -3420,7 +3420,7 @@ public class P25DecoderState extends DecoderState
mFromAlias = null;
}
broadcast(ChangedAttribute.FROM_TALKGROUP_ALIAS);
broadcast(Attribute.FROM_TALKGROUP_ALIAS);
/* Send audio metadata update */
broadcast(new Metadata(MetadataType.FROM, mFromTalkgroup, mFromAlias, true));
@@ -3446,7 +3446,7 @@ public class P25DecoderState extends DecoderState
{
mNAC = nac;
broadcast(ChangedAttribute.NAC);
broadcast(Attribute.NAC);
}
}
@@ -3459,7 +3459,7 @@ public class P25DecoderState extends DecoderState
{
mSite = site;
broadcast(ChangedAttribute.SITE);
broadcast(Attribute.SITE);
if(hasAliasList())
{
@@ -3475,7 +3475,7 @@ public class P25DecoderState extends DecoderState
}
}
broadcast(ChangedAttribute.SITE_ALIAS);
broadcast(Attribute.SITE_ALIAS);
}
}
@@ -3485,7 +3485,7 @@ public class P25DecoderState extends DecoderState
{
mSystem = system;
broadcast(ChangedAttribute.SYSTEM);
broadcast(Attribute.SYSTEM);
}
}
@@ -3816,26 +3816,26 @@ public class P25DecoderState extends DecoderState
mCurrentCallEvent = (P25CallEvent) allocationEvent.getCallEvent();
mCurrentChannel = allocationEvent.getCallEvent().getChannel();
broadcast(ChangedAttribute.CHANNEL_NUMBER);
broadcast(Attribute.CHANNEL_NUMBER);
mCurrentChannelFrequency = allocationEvent.getCallEvent().getFrequency();
broadcast(ChangedAttribute.SOURCE);
broadcast(Attribute.SOURCE);
mFromTalkgroup = allocationEvent.getCallEvent().getFromID();
broadcast(ChangedAttribute.FROM_TALKGROUP);
broadcast(Attribute.FROM_TALKGROUP);
mToTalkgroup = allocationEvent.getCallEvent().getToID();
broadcast(ChangedAttribute.TO_TALKGROUP);
broadcast(Attribute.TO_TALKGROUP);
if(allocationEvent.getCallEvent().hasAliasList())
{
AliasList aliasList = allocationEvent.getCallEvent().getAliasList();
mFromAlias = aliasList.getTalkgroupAlias(mFromTalkgroup);
broadcast(ChangedAttribute.FROM_TALKGROUP_ALIAS);
broadcast(Attribute.FROM_TALKGROUP_ALIAS);
mToAlias = aliasList.getTalkgroupAlias(mToTalkgroup);
broadcast(ChangedAttribute.TO_TALKGROUP_ALIAS);
broadcast(Attribute.TO_TALKGROUP_ALIAS);
}
}
}

View File

@@ -20,8 +20,8 @@ package module.decode.passport;
import alias.Alias;
import icon.IconManager;
import module.decode.state.ChangedAttribute;
import module.decode.state.DecoderPanel;
import channel.metadata.Attribute;
import channel.state.DecoderPanel;
import net.miginfocom.swing.MigLayout;
import settings.ColorSetting;
import settings.Setting;
@@ -93,7 +93,7 @@ public class PassportDecoderPanel extends DecoderPanel
}
@Override
public void receive(final ChangedAttribute changedAttribute)
public void receive(final Attribute attribute)
{
EventQueue.invokeLater(new Runnable()
{
@@ -102,7 +102,7 @@ public class PassportDecoderPanel extends DecoderPanel
{
PassportDecoderState state = getDecoderState();
switch(changedAttribute)
switch(attribute)
{
case TO_TALKGROUP:
String tg = state.getTalkgroup();

View File

@@ -29,11 +29,11 @@ import message.Message;
import module.decode.DecoderType;
import module.decode.event.CallEvent;
import module.decode.event.CallEvent.CallEventType;
import module.decode.state.ChangedAttribute;
import module.decode.state.DecoderState;
import module.decode.state.DecoderStateEvent;
import module.decode.state.DecoderStateEvent.Event;
import module.decode.state.State;
import channel.metadata.Attribute;
import channel.state.DecoderState;
import channel.state.DecoderStateEvent;
import channel.state.DecoderStateEvent.Event;
import channel.state.State;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -390,7 +390,7 @@ public class PassportDecoderState extends DecoderState
mChannelNumber = mSiteBand.getChannel( mFrequency );
broadcast( ChangedAttribute.CHANNEL_NUMBER );
broadcast( Attribute.CHANNEL_NUMBER );
}
break;
default:
@@ -570,7 +570,7 @@ public class PassportDecoderState extends DecoderState
public void setTalkgroup( String talkgroup )
{
mTalkgroup = talkgroup;
broadcast( ChangedAttribute.TO_TALKGROUP );
broadcast( Attribute.TO_TALKGROUP );
}
public Alias getTalkgroupAlias()
@@ -581,7 +581,7 @@ public class PassportDecoderState extends DecoderState
public void setTalkgroupAlias( Alias alias )
{
mTalkgroupAlias = alias;
broadcast( ChangedAttribute.TO_TALKGROUP_ALIAS );
broadcast( Attribute.TO_TALKGROUP_ALIAS );
}
public String getMobileID()
@@ -592,7 +592,7 @@ public class PassportDecoderState extends DecoderState
public void setMobileID( String id )
{
mMobileID = id;
broadcast( ChangedAttribute.FROM_TALKGROUP );
broadcast( Attribute.FROM_TALKGROUP );
}
public Alias getMobileIDAlias()
@@ -603,7 +603,7 @@ public class PassportDecoderState extends DecoderState
public void setMobileIDAlias( Alias alias )
{
mMobileIDAlias = alias;
broadcast( ChangedAttribute.FROM_TALKGROUP_ALIAS );
broadcast( Attribute.FROM_TALKGROUP_ALIAS );
}
@Override

View File

@@ -1,98 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014,2015 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.state;
import java.util.concurrent.ScheduledExecutorService;
import message.Message;
import module.decode.DecoderType;
import module.decode.state.DecoderStateEvent.Event;
import audio.metadata.Metadata;
import audio.metadata.MetadataType;
/**
* Basic decoder channel state - provides the minimum channel state functionality
* to support an always un-squelched audio decoder.
*/
public class AlwaysUnsquelchedDecoderState extends DecoderState
{
private DecoderType mDecoderType;
private String mChannelName;
public AlwaysUnsquelchedDecoderState( DecoderType decoderType, String channelName )
{
super( null );
mDecoderType = decoderType;
mChannelName = channelName;
}
@Override
public void init()
{
}
@Override
public void reset()
{
/* No reset actions needed */
}
@Override
public String getActivitySummary()
{
StringBuilder sb = new StringBuilder();
sb.append( "Activity Summary\n" );
sb.append( "\tDecoder:\t" );
sb.append( mDecoderType );
sb.append( "\n\n" );
return sb.toString();
}
@Override
public void receive( Message t )
{
/* Not implemented */
}
@Override
public void receiveDecoderStateEvent( DecoderStateEvent event )
{
/* Not implemented */
}
@Override
public DecoderType getDecoderType()
{
return mDecoderType;
}
@Override
public void start( ScheduledExecutorService executor )
{
broadcast( new Metadata( MetadataType.TO, mChannelName, false ) );
broadcast( new DecoderStateEvent( this, Event.ALWAYS_UNSQUELCH, State.IDLE ) );
}
@Override
public void stop()
{
}
}

View File

@@ -1,29 +0,0 @@
package module.decode.state;
import controller.channel.Channel.ChannelType;
/**
* Allows decoders to change the call timeout setting in the channel state
*/
public class ChangeChannelTimeoutEvent extends DecoderStateEvent
{
private ChannelType mChannelType;
private long mCallTimeout;
public ChangeChannelTimeoutEvent( Object source, ChannelType channelType, long timeout )
{
super( source, Event.CHANGE_CALL_TIMEOUT, State.IDLE );
mChannelType = channelType;
mCallTimeout = timeout;
}
public ChannelType getChannelType()
{
return mChannelType;
}
public long getCallTimeout()
{
return mCallTimeout;
}
}

View File

@@ -1,29 +0,0 @@
package module.decode.state;
public enum ChangedAttribute
{
AUDIO_TYPE,
CHANNEL_NUMBER,
CHANNEL_NAME,
CHANNEL_SITE_NUMBER,
CHANNEL_SITE_NUMBER_ALIAS,
CHANNEL_STATE,
DESCRIPTION,
FROM_TALKGROUP,
FROM_TALKGROUP_ALIAS,
FROM_TALKGROUP_TYPE,
MESSAGE,
MESSAGE_TYPE,
NAC,
SITE,
SITE_ALIAS,
SITE_NAME,
SOURCE,
SYSTEM,
SYSTEM_NAME,
SQUELCH,
TO_TALKGROUP,
TO_TALKGROUP_ALIAS,
TO_TALKGROUP_TYPE,
WACN;
}

View File

@@ -1,317 +0,0 @@
/*******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2017 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.state;
import audio.AudioPanel;
import controller.channel.Channel;
import controller.channel.ChannelEvent;
import controller.channel.ChannelEvent.Event;
import controller.channel.ChannelEventListener;
import controller.channel.ChannelModel;
import controller.channel.ChannelProcessingManager;
import icon.IconManager;
import net.miginfocom.swing.MigLayout;
import settings.ColorSetting.ColorSettingName;
import settings.ColorSettingMenuItem;
import settings.ColorSettingResetMenuItem;
import settings.SettingsManager;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Gui wrapper for the list of currently processing primary channels
*/
public class ChannelList extends JPanel implements ChannelEventListener
{
private static final long serialVersionUID = 1L;
private Map<Channel, ChannelPanel> mDisplayedPanels = new ConcurrentHashMap<>();
private ChannelModel mChannelModel;
private ChannelProcessingManager mChannelProcessingManager;
private IconManager mIconManager;
private SettingsManager mSettingsManager;
private AudioPanel mAudioPanel;
public ChannelList(ChannelModel channelModel,
ChannelProcessingManager channelProcessingManager,
IconManager iconManager,
SettingsManager settingsManager,
AudioPanel audioPanel)
{
mChannelModel = channelModel;
mChannelProcessingManager = channelProcessingManager;
mIconManager = iconManager;
mSettingsManager = settingsManager;
mAudioPanel = audioPanel;
init();
}
private void init()
{
setLayout(new MigLayout("insets 0 0 0 0,wrap 1", "[grow,fill]", "[]0[]"));
setBackground(Color.BLACK);
addMouseListener(new ListSelectionListener());
add(mAudioPanel);
JSeparator separator = new JSeparator(JSeparator.HORIZONTAL);
add(separator);
}
@Override
public void channelChanged(ChannelEvent event)
{
switch(event.getEvent())
{
case NOTIFICATION_PROCESSING_START:
addChannelPanel(event.getChannel());
break;
case NOTIFICATION_PROCESSING_STOP:
removeChannelPanel(event.getChannel());
break;
default:
break;
}
}
private void addChannelPanel(Channel channel)
{
if(!mDisplayedPanels.containsKey(channel))
{
ChannelPanel channelPanel = new ChannelPanel(mChannelModel,
mChannelProcessingManager, mIconManager, mSettingsManager, channel);
add(channelPanel);
mDisplayedPanels.put(channel, channelPanel);
revalidate();
repaint();
}
}
public void removeChannelPanel(Channel channel)
{
if(mDisplayedPanels.containsKey(channel))
{
ChannelPanel panel = mDisplayedPanels.remove(channel);
if(panel != null)
{
remove(panel);
panel.dispose();
}
revalidate();
repaint();
}
}
public class ListSelectionListener implements MouseListener
{
@Override
public void mouseClicked(MouseEvent e)
{
Component component = getComponentAt(e.getPoint());
if(component instanceof ChannelPanel)
{
ChannelPanel panel = (ChannelPanel) component;
Channel channel = panel.getChannel();
if(e.getButton() == MouseEvent.BUTTON1)
{
if(channel.isSelected())
{
mChannelModel.broadcast(new ChannelEvent(channel, Event.REQUEST_DESELECT));
}
else
{
mChannelModel.broadcast(new ChannelEvent(channel, Event.REQUEST_SELECT));
}
}
else if(e.getButton() == MouseEvent.BUTTON3)
{
JPopupMenu popupMenu = new JPopupMenu();
JMenu menu = panel.getContextMenu();
if(menu != null)
{
popupMenu.add(menu);
}
JMenu colorMenu = new JMenu("Color");
popupMenu.add(colorMenu);
JMenu backgroundMenu = new JMenu("Background");
colorMenu.add(backgroundMenu);
backgroundMenu.add(new ColorSettingMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_BACKGROUND));
backgroundMenu.add(new ColorSettingResetMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_BACKGROUND));
JMenu channelsMenu = new JMenu("Channel State");
colorMenu.add(channelsMenu);
JMenu callMenu = new JMenu("Call");
channelsMenu.add(callMenu);
callMenu.add(new ColorSettingMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_MIDDLE_CALL));
callMenu.add(new ColorSettingResetMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_MIDDLE_CALL));
callMenu.add(new JSeparator());
callMenu.add(new ColorSettingMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_TOP_CALL));
callMenu.add(new ColorSettingResetMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_TOP_CALL));
JMenu controlMenu = new JMenu("Control");
channelsMenu.add(controlMenu);
controlMenu.add(new ColorSettingMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_MIDDLE_CONTROL));
controlMenu.add(new ColorSettingResetMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_MIDDLE_CONTROL));
controlMenu.add(new JSeparator());
controlMenu.add(new ColorSettingMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_TOP_CONTROL));
controlMenu.add(new ColorSettingResetMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_TOP_CONTROL));
JMenu dataMenu = new JMenu("Data");
channelsMenu.add(dataMenu);
dataMenu.add(new ColorSettingMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_MIDDLE_DATA));
dataMenu.add(new ColorSettingResetMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_MIDDLE_DATA));
dataMenu.add(new JSeparator());
dataMenu.add(new ColorSettingMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_TOP_DATA));
dataMenu.add(new ColorSettingResetMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_TOP_DATA));
JMenu fadeMenu = new JMenu("Fade");
channelsMenu.add(fadeMenu);
fadeMenu.add(new ColorSettingMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_MIDDLE_FADE));
fadeMenu.add(new ColorSettingResetMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_MIDDLE_FADE));
fadeMenu.add(new JSeparator());
fadeMenu.add(new ColorSettingMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_TOP_FADE));
fadeMenu.add(new ColorSettingResetMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_TOP_FADE));
JMenu idleMenu = new JMenu("Idle");
channelsMenu.add(idleMenu);
idleMenu.add(new ColorSettingMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_MIDDLE_IDLE));
idleMenu.add(new ColorSettingResetMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_MIDDLE_IDLE));
idleMenu.add(new JSeparator());
idleMenu.add(new ColorSettingMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_TOP_IDLE));
idleMenu.add(new ColorSettingResetMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_TOP_IDLE));
JMenu noTunerMenu = new JMenu("No Tuner");
channelsMenu.add(noTunerMenu);
noTunerMenu.add(new ColorSettingMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_MIDDLE_NO_TUNER));
noTunerMenu.add(new ColorSettingResetMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_MIDDLE_NO_TUNER));
noTunerMenu.add(new JSeparator());
noTunerMenu.add(new ColorSettingMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_TOP_NO_TUNER));
noTunerMenu.add(new ColorSettingResetMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_GRADIENT_TOP_NO_TUNER));
JMenu labelMenu = new JMenu("Labels");
colorMenu.add(labelMenu);
labelMenu.add(new ColorSettingMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_LABEL_AUX_DECODER));
labelMenu.add(new ColorSettingResetMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_LABEL_AUX_DECODER));
labelMenu.add(new JSeparator());
labelMenu.add(new ColorSettingMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_LABEL_DECODER));
labelMenu.add(new ColorSettingResetMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_LABEL_DECODER));
labelMenu.add(new JSeparator());
labelMenu.add(new ColorSettingMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_LABEL_DETAILS));
labelMenu.add(new ColorSettingResetMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_LABEL_DETAILS));
JMenu selectedMenu = new JMenu("Selected");
colorMenu.add(selectedMenu);
selectedMenu.add(new ColorSettingMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_SELECTED_CHANNEL));
selectedMenu.add(new ColorSettingResetMenuItem(mSettingsManager,
ColorSettingName.CHANNEL_STATE_SELECTED_CHANNEL));
popupMenu.show(ChannelList.this, e.getX(), e.getY());
}
}
}
public void mousePressed(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
}
}

View File

@@ -1,465 +0,0 @@
/*******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2017 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.state;
import controller.channel.Channel;
import controller.channel.ChannelEvent;
import controller.channel.ChannelEvent.Event;
import controller.channel.ChannelEventListener;
import controller.channel.ChannelModel;
import controller.channel.ChannelProcessingManager;
import controller.channel.ChannelUtils;
import icon.IconManager;
import module.ProcessingChain;
import module.decode.DecoderFactory;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import record.RecorderType;
import record.config.RecordConfiguration;
import sample.Listener;
import settings.ColorSetting;
import settings.ColorSetting.ColorSettingName;
import settings.Setting;
import settings.SettingChangeListener;
import settings.SettingsManager;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
public class ChannelPanel extends JPanel
implements Listener<ChangedAttribute>,
SettingChangeListener,
ChannelEventListener
{
private static final long serialVersionUID = 1L;
private final static Logger mLog = LoggerFactory.getLogger(ChannelPanel.class);
private Font mFontDetails = new Font(Font.MONOSPACED, Font.PLAIN, 12);
private Font mFontDecoder = new Font(Font.MONOSPACED, Font.PLAIN, 12);
protected Color mColorChannelBackground;
protected Color mColorChannelSelected;
protected Color mColorTopCall;
protected Color mColorMiddleCall;
protected Color mColorTopControl;
protected Color mColorMiddleControl;
protected Color mColorTopData;
protected Color mColorMiddleData;
protected Color mColorTopFade;
protected Color mColorMiddleFade;
protected Color mColorTopIdle;
protected Color mColorMiddleIdle;
protected Color mColorTopNoTuner;
protected Color mColorMiddleNoTuner;
protected Color mColorLabelDetails;
protected Color mColorLabelDecoder;
protected Color mColorLabelAuxDecoder;
private JLabel mStateLabel;
private JLabel mSourceLabel;
private JLabel mOptionsLabel;
private JLabel mSystemLabel;
private JLabel mSiteLabel;
private JLabel mChannelLabel;
protected SettingsManager mSettingsManager;
protected IconManager mIconManager;
private Channel mChannel;
private ChannelState mChannelState;
private List<DecoderPanel> mDecoderPanels = new ArrayList<>();
private ChannelModel mChannelModel;
private ChannelProcessingManager mChannelProcessingManager;
/**
* Gui component to a channel state. Provides System, Site and channel
* name, source and channel state visualization.
*
* Updates color background according to current channel state.
*/
public ChannelPanel(ChannelModel channelModel,
ChannelProcessingManager channelProcessingManager,
IconManager iconManager,
SettingsManager settingsManager,
Channel channel)
{
mChannelModel = channelModel;
mChannelProcessingManager = channelProcessingManager;
mIconManager = iconManager;
mSettingsManager = settingsManager;
mChannel = channel;
ProcessingChain processingChain =
channelProcessingManager.getProcessingChain(mChannel);
if(processingChain != null)
{
mChannelState = processingChain.getChannelState();
init();
for(DecoderState decoderState : processingChain.getDecoderStates())
{
DecoderPanel panel = DecoderFactory.getDecoderPanel(mIconManager, mSettingsManager, decoderState);
mDecoderPanels.add(panel);
add(panel, "grow,span");
}
mChannelState.setChangedAttributeListener(this);
mChannelModel.addListener(this);
mSettingsManager.addListener(this);
}
else
{
mLog.error("Processing Chain was null!");
}
}
private void init()
{
getColors();
setLayout(new MigLayout("insets 1 1 1 1", "[grow,fill]", "[]0[]0[]"));
mSystemLabel = new JLabel(mChannel.getSystem());
mSystemLabel.setFont(mFontDetails);
mSystemLabel.setForeground(mColorLabelDetails);
add(mSystemLabel);
mSiteLabel = new JLabel(mChannel.getSite());
mSiteLabel.setFont(mFontDetails);
mSiteLabel.setForeground(mColorLabelDetails);
add(mSiteLabel);
mChannelLabel = new JLabel(mChannel.getName());
mChannelLabel.setFont(mFontDetails);
mChannelLabel.setForeground(mColorLabelDetails);
add(mChannelLabel, "wrap");
mStateLabel = new JLabel(mChannelState.getState().getDisplayValue());
mStateLabel.setFont(mFontDecoder);
mStateLabel.setForeground(mColorLabelDecoder);
add(mStateLabel);
mSourceLabel = new JLabel(mChannel.getSourceConfiguration().getDescription());
mSourceLabel.setFont(mFontDetails);
mSourceLabel.setForeground(mColorLabelDetails);
add(mSourceLabel);
StringBuilder sb = new StringBuilder();
if(!mChannel.getEventLogConfiguration().getLoggers().isEmpty())
{
sb.append("LOG ");
}
RecordConfiguration recordConfig = mChannel.getRecordConfiguration();
if(recordConfig.getRecorders().contains(RecorderType.AUDIO))
{
sb.append("AUDIO ");
}
if(recordConfig.getRecorders().contains(RecorderType.BASEBAND) ||
recordConfig.getRecorders().contains(RecorderType.TRAFFIC_BASEBAND))
{
sb.append("BASEBAND");
}
mOptionsLabel = new JLabel(sb.toString());
mOptionsLabel.setFont(mFontDetails);
mOptionsLabel.setForeground(mColorLabelAuxDecoder);
add(mOptionsLabel, "wrap");
}
public Channel getChannel()
{
return mChannel;
}
public void dispose()
{
mChannelModel.removeListener(this);
mChannelModel = null;
mChannelProcessingManager = null;
mSettingsManager.removeListener(this);
mSettingsManager = null;
mChannelState.removeChangedAttributeListener();
mChannelState = null;
mChannel = null;
for(DecoderPanel panel : mDecoderPanels)
{
panel.dispose();
remove(panel);
}
mDecoderPanels.clear();
}
@Override
public void receive(final ChangedAttribute changedAttribute)
{
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
switch(changedAttribute)
{
case CHANNEL_STATE:
if(mChannelState != null && mChannelState.getState() != null)
{
mStateLabel.setText(mChannelState.getState().getDisplayValue());
}
break;
case SOURCE:
mSourceLabel.setText(mChannel.getSourceConfiguration()
.getDescription());
break;
case CHANNEL_NAME:
case SITE_NAME:
case SYSTEM_NAME:
mChannelLabel.setText(mChannel.toString());
break;
default:
break;
}
repaint();
}
});
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
setBackground(mColorChannelBackground);
Graphics2D g2 = (Graphics2D) g.create();
Paint p = null;
final Channel channel = mChannel;
if(mChannelState != null)
{
switch(mChannelState.getState())
{
case CALL:
p = getGradient(mColorTopCall, mColorMiddleCall);
break;
case CONTROL:
p = getGradient(mColorTopControl, mColorMiddleControl);
break;
case DATA:
p = getGradient(mColorTopData, mColorMiddleData);
break;
case FADE:
p = getGradient(mColorTopFade, mColorMiddleFade);
break;
case IDLE:
default:
p = getGradient(mColorTopIdle, mColorMiddleIdle);
break;
}
}
if(p == null)
{
p = getGradient(mColorTopIdle, mColorMiddleIdle);
}
g2.setPaint(p);
g2.fillRect(0, 0, getWidth(), getHeight());
/* Draw bottom separator line */
g2.setColor(Color.LIGHT_GRAY);
g2.drawLine(0, getHeight() - 1, getWidth(), getHeight() - 1);
/* Draw channel selected box */
if(getChannel() != null && getChannel().isSelected())
{
g2.setColor(mColorChannelSelected);
g2.drawRect(1, 1, getWidth() - 2, getHeight() - 2);
}
g2.dispose();
}
private void getColors()
{
mColorChannelBackground = mSettingsManager.getColorSetting(
ColorSettingName.CHANNEL_STATE_BACKGROUND).getColor();
mColorChannelSelected = mSettingsManager.getColorSetting(
ColorSettingName.CHANNEL_STATE_SELECTED_CHANNEL).getColor();
mColorTopCall = mSettingsManager.getColorSetting(
ColorSettingName.CHANNEL_STATE_GRADIENT_TOP_CALL).getColor();
mColorMiddleCall = mSettingsManager.getColorSetting(
ColorSettingName.CHANNEL_STATE_GRADIENT_MIDDLE_CALL).getColor();
mColorTopControl = mSettingsManager.getColorSetting(
ColorSettingName.CHANNEL_STATE_GRADIENT_TOP_CONTROL).getColor();
mColorMiddleControl = mSettingsManager.getColorSetting(
ColorSettingName.CHANNEL_STATE_GRADIENT_MIDDLE_CONTROL).getColor();
mColorTopData = mSettingsManager.getColorSetting(
ColorSettingName.CHANNEL_STATE_GRADIENT_TOP_DATA).getColor();
mColorMiddleData = mSettingsManager.getColorSetting(
ColorSettingName.CHANNEL_STATE_GRADIENT_MIDDLE_DATA).getColor();
mColorTopFade = mSettingsManager.getColorSetting(
ColorSettingName.CHANNEL_STATE_GRADIENT_TOP_FADE).getColor();
mColorMiddleFade = mSettingsManager.getColorSetting(
ColorSettingName.CHANNEL_STATE_GRADIENT_MIDDLE_FADE).getColor();
mColorTopIdle = mSettingsManager.getColorSetting(
ColorSettingName.CHANNEL_STATE_GRADIENT_TOP_IDLE).getColor();
mColorMiddleIdle = mSettingsManager.getColorSetting(
ColorSettingName.CHANNEL_STATE_GRADIENT_MIDDLE_IDLE).getColor();
mColorTopNoTuner = mSettingsManager.getColorSetting(
ColorSettingName.CHANNEL_STATE_GRADIENT_TOP_NO_TUNER).getColor();
mColorMiddleNoTuner = mSettingsManager.getColorSetting(
ColorSettingName.CHANNEL_STATE_GRADIENT_MIDDLE_NO_TUNER).getColor();
mColorLabelDetails = mSettingsManager.getColorSetting(
ColorSettingName.CHANNEL_STATE_LABEL_DETAILS).getColor();
mColorLabelDecoder = mSettingsManager.getColorSetting(
ColorSettingName.CHANNEL_STATE_LABEL_DECODER).getColor();
mColorLabelAuxDecoder = mSettingsManager.getColorSetting(
ColorSettingName.CHANNEL_STATE_LABEL_AUX_DECODER).getColor();
}
private GradientPaint getGradient(Color top, Color middle)
{
return new GradientPaint(0f, -50.0f, top,
0f, (float) getHeight() / 2.2f, middle, true);
}
@Override
public void settingChanged(Setting setting)
{
if(setting instanceof ColorSetting)
{
ColorSetting colorSetting = (ColorSetting) setting;
switch(colorSetting.getColorSettingName())
{
case CHANNEL_STATE_BACKGROUND:
mColorChannelBackground = colorSetting.getColor();
repaint();
break;
case CHANNEL_STATE_GRADIENT_MIDDLE_CALL:
mColorMiddleCall = colorSetting.getColor();
repaint();
break;
case CHANNEL_STATE_GRADIENT_TOP_CALL:
mColorTopCall = colorSetting.getColor();
repaint();
break;
case CHANNEL_STATE_GRADIENT_MIDDLE_CONTROL:
mColorMiddleControl = colorSetting.getColor();
repaint();
break;
case CHANNEL_STATE_GRADIENT_TOP_CONTROL:
mColorTopControl = colorSetting.getColor();
repaint();
break;
case CHANNEL_STATE_GRADIENT_MIDDLE_DATA:
mColorMiddleData = colorSetting.getColor();
repaint();
break;
case CHANNEL_STATE_GRADIENT_TOP_DATA:
mColorTopData = colorSetting.getColor();
repaint();
break;
case CHANNEL_STATE_GRADIENT_MIDDLE_FADE:
mColorMiddleFade = colorSetting.getColor();
repaint();
break;
case CHANNEL_STATE_GRADIENT_TOP_FADE:
mColorTopFade = colorSetting.getColor();
repaint();
break;
case CHANNEL_STATE_GRADIENT_MIDDLE_IDLE:
mColorMiddleIdle = colorSetting.getColor();
repaint();
break;
case CHANNEL_STATE_GRADIENT_TOP_IDLE:
mColorTopIdle = colorSetting.getColor();
repaint();
break;
case CHANNEL_STATE_GRADIENT_MIDDLE_NO_TUNER:
mColorMiddleNoTuner = colorSetting.getColor();
repaint();
break;
case CHANNEL_STATE_GRADIENT_TOP_NO_TUNER:
mColorTopNoTuner = colorSetting.getColor();
repaint();
break;
case CHANNEL_STATE_LABEL_AUX_DECODER:
mColorLabelAuxDecoder = colorSetting.getColor();
repaint();
break;
case CHANNEL_STATE_LABEL_DECODER:
mColorLabelDecoder = colorSetting.getColor();
repaint();
break;
case CHANNEL_STATE_LABEL_DETAILS:
mColorLabelDetails = colorSetting.getColor();
repaint();
break;
case CHANNEL_STATE_SELECTED_CHANNEL:
mColorChannelSelected = colorSetting.getColor();
repaint();
break;
default:
break;
}
}
}
@Override
public void settingDeleted(Setting setting)
{
}
public JMenu getContextMenu()
{
return ChannelUtils.getContextMenu(mChannelModel, mChannelProcessingManager,
mChannel, ChannelPanel.this);
}
@Override
public void channelChanged(ChannelEvent event)
{
if(event.getEvent() == Event.NOTIFICATION_SELECTION_CHANGE &&
event.getChannel() == mChannel)
{
repaint();
}
}
}

View File

@@ -1,676 +0,0 @@
/*******************************************************************************
* 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.state;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import module.Module;
import module.decode.config.DecodeConfiguration;
import module.decode.event.CallEvent;
import module.decode.event.ICallEventProvider;
import module.decode.state.DecoderStateEvent.Event;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sample.Listener;
import audio.metadata.IMetadataProvider;
import audio.metadata.Metadata;
import audio.metadata.MetadataReset;
import audio.metadata.MetadataType;
import audio.squelch.ISquelchStateProvider;
import audio.squelch.SquelchState;
import controller.channel.Channel.ChannelType;
public class ChannelState extends Module implements ICallEventProvider, IChangedAttributeProvider,
IDecoderStateEventListener, IDecoderStateEventProvider, IMetadataProvider, ISquelchStateProvider
{
private final static Logger mLog =
LoggerFactory.getLogger( ChannelState.class );
public static final long FADE_TIMEOUT_DELAY = 1200;
public static final long RESET_TIMEOUT_DELAY = 2000;
private State mState = State.IDLE;
private Listener<CallEvent> mCallEventListener;
private Listener<ChangedAttribute> mChangedAttributeListener;
private Listener<DecoderStateEvent> mDecoderStateListener;
private Listener<Metadata> mMetadataListener;
private Listener<SquelchState> mSquelchStateListener;
private DecoderStateEventReceiver mDecoderStateEventReceiver =
new DecoderStateEventReceiver();
private boolean mSquelchLocked = false;
private boolean mSelected = false;
private long mStandardChannelFadeTimeout = FADE_TIMEOUT_DELAY;
private long mTrafficChannelFadeTimeout = DecodeConfiguration.DEFAULT_CALL_TIMEOUT_SECONDS * 1000;
private long mFadeTimeout;
private long mEndTimeout;
private StateMonitor mStateMonitor = new StateMonitor();
private ScheduledFuture<?> mStateMonitorFuture;
private ChannelType mChannelType;
private TrafficChannelManager mTrafficChannelEndListener;
private CallEvent mTrafficChannelCallEvent;
/**
* Channel state tracks the overall state of all processing modules and decoders
* configured for the channel and provides squelch control and decoder state
* reset events.
*
* Uses a state enumeration that defines allowable channel state transitions in
* order to track a call or data decode event from start to finish. Uses a
* timer to monitor for inactivity and to provide a FADE period that indicates
* to the user that the activity has stopped while continuing to provide details
* about the call, before the state is reset to IDLE.
*
* Since this class is multi-threaded between decoder events and the internal
* timer that monitors for inactivity, this class uses the mState object for
* thread synchronization.
*
* State Descriptions:
* IDLE Normal state. No voice or data call activity
* CALL/DATA/ENCRYPTED/CONTROL
* Decoding states.
* FADE The phase after a voice or data call when either an explicit
* call end has been received, or when no new signalling updates
* have been received, and the fade timer has expired. This phase
* allows for gui updates to signal to the user that the call is
* ended, while continuing to display the call details for the user
* TEARDOWN Indicates a traffic channel that will be torn down for reuse.
*/
public ChannelState( ChannelType channelType )
{
mChannelType = channelType;
}
/**
* Resets this channel state and prepares it for reuse.
*/
@Override
public void reset()
{
broadcast( new DecoderStateEvent( this, Event.RESET, State.IDLE ) );
broadcast( new MetadataReset() );
mState = State.IDLE;
broadcast( ChangedAttribute.CHANNEL_STATE );
}
@Override
public void start( ScheduledExecutorService executor )
{
if( mStateMonitorFuture == null && mStateMonitor != null )
{
if( mTrafficChannelEndListener != null )
{
setState( State.CALL );
}
try
{
mStateMonitorFuture = executor.scheduleAtFixedRate( mStateMonitor, 0, 20, TimeUnit.MILLISECONDS );
}
catch( RejectedExecutionException ree )
{
mLog.error( "state monitor scheduled task rejected", ree );
}
}
}
@Override
public void stop()
{
if( mStateMonitorFuture != null )
{
boolean success = mStateMonitorFuture.cancel( true );
if( !success )
{
mLog.error("Couldn't stop monitoring scheduled future" );
}
}
mTrafficChannelEndListener = null;
if( mTrafficChannelCallEvent != null )
{
mTrafficChannelCallEvent.end();
broadcast( mTrafficChannelCallEvent );
}
mTrafficChannelCallEvent = null;
mStateMonitorFuture = null;
mSquelchLocked = false;
}
public void dispose()
{
mCallEventListener = null;
mChangedAttributeListener = null;
mDecoderStateListener = null;
mSquelchStateListener = null;
mStateMonitor = null;
}
private boolean isStandardChannel()
{
return mChannelType == ChannelType.STANDARD;
}
private boolean isTrafficChannel()
{
return mChannelType == ChannelType.TRAFFIC;
}
public void setStandardChannelTimeout( long milliseconds )
{
mStandardChannelFadeTimeout = milliseconds;
if( mChannelType == ChannelType.STANDARD )
{
mFadeTimeout = mStandardChannelFadeTimeout;
}
}
public void setTrafficChannelTimeout( long milliseconds )
{
mTrafficChannelFadeTimeout = milliseconds;
if( mChannelType == ChannelType.TRAFFIC )
{
mFadeTimeout = System.currentTimeMillis() + mTrafficChannelFadeTimeout;
}
}
public void setSelected( boolean selected )
{
mSelected = selected;
}
public boolean isSelected()
{
return mSelected;
}
public State getState()
{
return mState;
}
/**
* Updates the fade timeout threshold to the current time plus delay
*/
private void updateFadeTimeout()
{
if( isTrafficChannel() )
{
mFadeTimeout = System.currentTimeMillis() + mTrafficChannelFadeTimeout;
}
else
{
mFadeTimeout = System.currentTimeMillis() + mStandardChannelFadeTimeout;
}
}
/**
* Updates the reset timeout threshold to the current time plus delay
*/
private void updateResetTimeout()
{
if( isTrafficChannel() )
{
mEndTimeout = System.currentTimeMillis();
}
else
{
mEndTimeout = System.currentTimeMillis() + RESET_TIMEOUT_DELAY;
}
}
/**
* Broadcasts the squelch state to the registered listener
*/
protected void broadcast( SquelchState state )
{
if( mSquelchStateListener != null && !mSquelchLocked )
{
mSquelchStateListener.receive( state );
}
}
/**
* Sets the squelch state listener
*/
@Override
public void setSquelchStateListener( Listener<SquelchState> listener )
{
mSquelchStateListener = listener;
}
/**
* Removes the squelch state listener
*/
@Override
public void removeSquelchStateListener()
{
mSquelchStateListener = null;
}
/**
* Sets the channel state to the specified state, or updates the timeout
* values so that the state monitor will not change state. Broadcasts a
* squelch event when the state changes and the audio squelch state should
* change. Also broadcasts changed attribute and decoder state events so
* that external processes can maintain sync with this channel state.
*/
protected void setState( State state )
{
synchronized( mState )
{
if( state == mState )
{
if( State.CALL_STATES.contains( state ) )
{
updateFadeTimeout();
}
}
else if( state != mState && mState.canChangeTo( state ) )
{
switch( state )
{
case CONTROL:
//Don't allow traffic channels to be control channels,
//otherwise they can't transition to call tear down
if( isStandardChannel() )
{
broadcast( SquelchState.SQUELCH );
updateFadeTimeout();
mState = state;
broadcast( ChangedAttribute.CHANNEL_STATE );
}
break;
case DATA:
case ENCRYPTED:
broadcast( SquelchState.SQUELCH );
updateFadeTimeout();
mState = state;
broadcast( ChangedAttribute.CHANNEL_STATE );
break;
case CALL:
broadcast( SquelchState.UNSQUELCH );
updateFadeTimeout();
mState = state;
broadcast( ChangedAttribute.CHANNEL_STATE );
break;
case FADE:
processFadeState();
break;
case IDLE:
processIdleState();
break;
case TEARDOWN:
processTeardownState();
break;
case RESET:
mState = State.IDLE;
break;
default:
break;
}
}
else
{
// mLog.debug( "Can't change from [" + mState + "] to [" + state + "]" );
}
}
}
/**
* Sets the state and processes related actions
*/
private void processFadeState()
{
updateResetTimeout();
mState = State.FADE;
broadcast( SquelchState.SQUELCH );
broadcast( ChangedAttribute.CHANNEL_STATE );
}
private void processIdleState()
{
broadcast( SquelchState.SQUELCH );
if( mState == State.FADE )
{
broadcast( new DecoderStateEvent( this, Event.RESET, State.IDLE ) );
broadcast( new MetadataReset() );
}
mState = State.IDLE;
broadcast( ChangedAttribute.CHANNEL_STATE );
}
private void processTeardownState()
{
broadcast( SquelchState.SQUELCH );
broadcast( new MetadataReset() );
mState = State.TEARDOWN;
broadcast( ChangedAttribute.CHANNEL_STATE );
if( mTrafficChannelEndListener != null )
{
mTrafficChannelEndListener.callEnd( mTrafficChannelCallEvent.getChannel() );
}
}
/**
* Broadcasts the call event to the registered listener
*/
protected void broadcast( CallEvent event )
{
if( mCallEventListener != null )
{
mCallEventListener.receive( event );
}
}
@Override
public void addCallEventListener( Listener<CallEvent> listener )
{
mCallEventListener = listener;
}
@Override
public void removeCallEventListener( Listener<CallEvent> listener )
{
mCallEventListener = null;
}
/**
* Broadcasts the channel state attribute change event to all registered
* listeners
*/
protected void broadcast( ChangedAttribute attribute )
{
if( mChangedAttributeListener != null )
{
mChangedAttributeListener.receive( attribute );
}
}
/**
* Adds the listener to receive channel state attribute change events
*/
@Override
public void setChangedAttributeListener( Listener<ChangedAttribute> listener )
{
mChangedAttributeListener = listener;
}
/**
* Removes the listener to receive channel state attribute change events
*/
@Override
public void removeChangedAttributeListener()
{
mChangedAttributeListener = null;
}
/**
* Broadcasts a channel state event to any registered listeners
*/
protected void broadcast( DecoderStateEvent event )
{
if( mDecoderStateListener != null )
{
mDecoderStateListener.receive( event );
}
}
/**
* Adds a decoder state event listener
*/
@Override
public void setDecoderStateListener( Listener<DecoderStateEvent> listener )
{
mDecoderStateListener = listener;
}
/**
* Removes the decoder state event listener
*/
@Override
public void removeDecoderStateListener()
{
mDecoderStateListener = null;
}
@Override
public Listener<DecoderStateEvent> getDecoderStateListener()
{
return mDecoderStateEventReceiver;
}
/**
* Broadcasts metadata to the registered listener
*/
protected void broadcast( Metadata metadata )
{
if( mMetadataListener != null )
{
mMetadataListener.receive( metadata );
}
}
/**
* Adds a metadata listener
*/
@Override
public void setMetadataListener( Listener<Metadata> listener )
{
mMetadataListener = listener;
}
/**
* Removes the decoder state event listener
*/
@Override
public void removeMetadataListener()
{
mMetadataListener = null;
}
/**
* Registers a listener to be notified when a traffic channel call event is
* completed, so that the listener can perform call tear-down
*/
public void configureAsTrafficChannel( TrafficChannelManager manager, CallEvent callEvent )
{
mTrafficChannelEndListener = manager;
mTrafficChannelCallEvent = callEvent;
/* Broadcast the call event details as metadata for the audio manager */
String channel = mTrafficChannelCallEvent.getChannel();
if( channel != null )
{
broadcast( new Metadata( MetadataType.CHANNEL_NUMBER, channel, true ) );
}
broadcast( new Metadata( MetadataType.PROTOCOL,
mTrafficChannelCallEvent.getDecoderType().getDisplayString(), true ) );
String details = mTrafficChannelCallEvent.getDetails();
if( details != null )
{
broadcast( new Metadata( MetadataType.DETAILS, details, true ) );
}
String from = mTrafficChannelCallEvent.getFromID();
if( from != null )
{
broadcast( new Metadata( mTrafficChannelCallEvent.getFromIDType(),
from, mTrafficChannelCallEvent.getFromIDAlias(), true ) );
}
String to = mTrafficChannelCallEvent.getToID();
if( to != null )
{
broadcast( new Metadata( mTrafficChannelCallEvent.getToIDType(), to,
mTrafficChannelCallEvent.getToIDAlias(), true ) );
}
long frequency = mTrafficChannelCallEvent.getFrequency();
if( frequency > 0 )
{
broadcast( new Metadata( MetadataType.FREQUENCY, String.valueOf( frequency ), true ) );
}
/* Rebroadcast the allocation event so that the internal decoder states
* can self-configure with the call event details */
broadcast( mTrafficChannelCallEvent );
}
/**
* DecoderStateEvent receiver wrapper
*/
public class DecoderStateEventReceiver implements Listener<DecoderStateEvent>
{
@Override
public void receive( DecoderStateEvent event )
{
if( event.getSource() != this )
{
switch( event.getEvent() )
{
case ALWAYS_UNSQUELCH:
broadcast( SquelchState.UNSQUELCH );
mSquelchLocked = true;
break;
case CHANGE_CALL_TIMEOUT:
if( event instanceof ChangeChannelTimeoutEvent )
{
ChangeChannelTimeoutEvent timeout = (ChangeChannelTimeoutEvent)event;
if( timeout.getChannelType() == ChannelType.STANDARD )
{
setStandardChannelTimeout( timeout.getCallTimeout() );
}
else
{
setTrafficChannelTimeout( timeout.getCallTimeout() );
}
}
case CONTINUATION:
case DECODE:
case START:
if( State.CALL_STATES.contains( event.getState() ) )
{
setState( event.getState() );
}
break;
case END:
if( isTrafficChannel() )
{
setState( State.TEARDOWN );
}
else
{
setState( State.FADE );
}
break;
case RESET:
/* Channel State does not respond to reset events */
break;
default:
break;
}
}
}
}
/**
* Monitors decoder state events to automatically transition the channel
* state to IDLE (standard channel) or to TEARDOWN (traffic channel) when
* decoding stops or the monitored channel returns to a no signal state.
*
* Provides a FADE transition state to allow for momentary decoding dropouts
* and to allow the user access to call details for a fade period upon
* call end.
*/
public class StateMonitor implements Runnable
{
@Override
public void run()
{
try
{
synchronized( mState )
{
if( State.CALL_STATES.contains( mState ) &&
mFadeTimeout <= System.currentTimeMillis() )
{
processFadeState();
}
else if( mState == State.FADE &&
mEndTimeout <= System.currentTimeMillis() )
{
if( isTrafficChannel() )
{
processTeardownState();
}
else
{
processIdleState();
}
}
}
}
catch( Exception e )
{
mLog.error( "Exception thrown while state monitor is running " +
"- state [" + getState() +
"] current [" + System.currentTimeMillis() +
"] mResetTimeout [" + mEndTimeout +
"] mFadeTimeout [" + mFadeTimeout +
"]", e );
}
}
}
}

View File

@@ -1,24 +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.state;
public interface ChannelStateSelectionListener
{
public void selected( ChannelState channelState );
}

View File

@@ -1,162 +0,0 @@
/*******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2017 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.state;
import alias.Alias;
import icon.IconManager;
import sample.Listener;
import settings.ColorSetting;
import settings.ColorSetting.ColorSettingName;
import settings.Setting;
import settings.SettingChangeListener;
import settings.SettingsManager;
import javax.swing.*;
import java.awt.*;
public abstract class DecoderPanel extends JPanel
implements Listener<ChangedAttribute>, SettingChangeListener
{
private static final long serialVersionUID = 1L;
protected Font mFontDetails = new Font(Font.MONOSPACED, Font.PLAIN, 12);
protected Font mFontDecoder = new Font(Font.MONOSPACED, Font.PLAIN, 12);
protected Font mFontAuxDecoder = new Font(Font.MONOSPACED, Font.PLAIN, 10);
public static final int ICON_SIZE = 12;
protected Color mColorLabelDetails;
protected Color mColorLabelDecoder;
protected Color mColorLabelAuxDecoder;
protected IconManager mIconManager;
protected SettingsManager mSettingsManager;
protected DecoderState mDecoderState;
public DecoderPanel(IconManager iconManager, SettingsManager settingsManager, DecoderState decoderState)
{
mIconManager = iconManager;
mSettingsManager = settingsManager;
mSettingsManager.addListener(this);
mDecoderState = decoderState;
mDecoderState.setChangedAttributeListener(this);
}
public void dispose()
{
mSettingsManager.removeListener(this);
mSettingsManager = null;
mDecoderState.removeChangedAttributeListener();
mDecoderState = null;
}
public DecoderState getDecoderState()
{
return mDecoderState;
}
protected void init()
{
getColors();
setOpaque(false); //Use the parent panel's background color
}
private void getColors()
{
mColorLabelDetails = mSettingsManager.getColorSetting(
ColorSettingName.CHANNEL_STATE_LABEL_DETAILS).getColor();
mColorLabelDecoder = mSettingsManager.getColorSetting(
ColorSettingName.CHANNEL_STATE_LABEL_DECODER).getColor();
mColorLabelAuxDecoder = mSettingsManager.getColorSetting(
ColorSettingName.CHANNEL_STATE_LABEL_AUX_DECODER).getColor();
}
@Override
public void settingChanged(Setting setting)
{
if(setting instanceof ColorSetting)
{
ColorSetting colorSetting = (ColorSetting) setting;
switch(colorSetting.getColorSettingName())
{
case CHANNEL_STATE_LABEL_AUX_DECODER:
mColorLabelAuxDecoder = colorSetting.getColor();
repaint();
break;
case CHANNEL_STATE_LABEL_DECODER:
mColorLabelDecoder = colorSetting.getColor();
repaint();
break;
case CHANNEL_STATE_LABEL_DETAILS:
mColorLabelDetails = colorSetting.getColor();
repaint();
break;
default:
break;
}
}
}
@Override
public void settingDeleted(Setting setting)
{
}
protected void setAliasLabel(final JLabel label, final Alias alias)
{
setAliasLabel(label, alias, true);
}
protected void setAliasLabel(final JLabel label, final Alias alias, boolean includeIcon)
{
if(alias != null)
{
label.setText(alias.getName());
if(includeIcon)
{
String iconName = alias.getIconName();
if(iconName != null)
{
label.setIcon(mIconManager.getIcon(iconName, IconManager.DEFAULT_ICON_SIZE));
}
else
{
label.setIcon(null);
}
}
else
{
label.setIcon(null);
}
}
else
{
label.setText("");
label.setIcon(null);
}
}
}

View File

@@ -1,227 +0,0 @@
package module.decode.state;
import message.IMessageListener;
import message.Message;
import module.Module;
import module.decode.DecoderType;
import module.decode.event.ActivitySummaryProvider;
import module.decode.event.CallEvent;
import module.decode.event.ICallEventProvider;
import sample.Broadcaster;
import sample.Listener;
import alias.AliasList;
import audio.metadata.IMetadataProvider;
import audio.metadata.Metadata;
/**
* Channel state monitors the stream of decoded messages produced by the
* decoder and broadcasts call events as they occur within the decoded message activity.
*
* Provides access to a textual activity summary of events observed.
*/
public abstract class DecoderState extends Module
implements ActivitySummaryProvider,
Listener<Message>,
ICallEventProvider,
IChangedAttributeProvider,
IDecoderStateEventListener,
IDecoderStateEventProvider,
IMessageListener,
IMetadataProvider
{
/* This has to be a broadcaster in order for references to persist */
private Broadcaster<CallEvent> mCallEventBroadcaster = new Broadcaster<>();
private Listener<ChangedAttribute> mChangedAttributeListener;
private Listener<DecoderStateEvent> mDecoderStateListener;
private Listener<Metadata> mMetadataListener;
private DecoderStateEventListener mDecoderStateEventListener =
new DecoderStateEventListener();
protected CallEvent mCurrentCallEvent;
private AliasList mAliasList;
public DecoderState( AliasList aliasList )
{
mAliasList = aliasList;
}
public abstract DecoderType getDecoderType();
public AliasList getAliasList()
{
return mAliasList;
}
public boolean hasAliasList()
{
return mAliasList != null;
}
/**
* Reset the decoder state to prepare for processing a different sample
* source
*/
public abstract void reset();
/**
* Allow the decoder to perform any setup actions
*/
public abstract void init();
/**
* Implements the IDecoderStateEventListener interface to receive state
* reset events.
*/
public abstract void receiveDecoderStateEvent( DecoderStateEvent event );
/**
* Disposes any resources or pointers held by this instance to prepare for
* garbage collection
*/
public void dispose()
{
mCallEventBroadcaster.dispose();
mCallEventBroadcaster = null;
mChangedAttributeListener = null;
mDecoderStateListener = null;
mMetadataListener = null;
mAliasList = null;
}
/**
* Activity Summary - textual summary of activity observed by the channel state.
*/
public abstract String getActivitySummary();
/**
* Broadcasts a call event to any registered listeners
*/
protected void broadcast( CallEvent event )
{
mCallEventBroadcaster.broadcast( event );
}
/**
* Adds a call event listener
*/
@Override
public void addCallEventListener( Listener<CallEvent> listener )
{
mCallEventBroadcaster.addListener( listener );
}
/**
* Removes the call event listener
*/
@Override
public void removeCallEventListener( Listener<CallEvent> listener )
{
mCallEventBroadcaster.removeListener( listener );
}
@Override
public Listener<DecoderStateEvent> getDecoderStateListener()
{
return mDecoderStateEventListener;
}
private class DecoderStateEventListener implements Listener<DecoderStateEvent>
{
@Override
public void receive( DecoderStateEvent event )
{
receiveDecoderStateEvent( event );
}
}
/**
* Broadcasts the channel state attribute change event to all registered
* listeners
*/
protected void broadcast( ChangedAttribute attribute )
{
if( mChangedAttributeListener != null )
{
mChangedAttributeListener.receive( attribute );
}
}
/**
* Adds the listener to receive channel state attribute change events
*/
@Override
public void setChangedAttributeListener( Listener<ChangedAttribute> listener )
{
mChangedAttributeListener = listener;
}
/**
* Removes the listener to receive channel state attribute change events
*/
@Override
public void removeChangedAttributeListener()
{
mChangedAttributeListener = null;
}
/**
* Broadcasts a channel state event to any registered listeners
*/
protected void broadcast( DecoderStateEvent event )
{
if( mDecoderStateListener != null )
{
mDecoderStateListener.receive( event );
}
}
/**
* Adds a decoder state event listener
*/
@Override
public void setDecoderStateListener( Listener<DecoderStateEvent> listener )
{
mDecoderStateListener = listener;
}
/**
* Removes the decoder state event listener
*/
@Override
public void removeDecoderStateListener()
{
mDecoderStateListener = null;
}
/**
* Broadcasts metadata to a registered listener
*/
protected void broadcast( Metadata metadata )
{
if( mMetadataListener != null )
{
mMetadataListener.receive( metadata );
}
}
@Override
public void setMetadataListener( Listener<Metadata> listener )
{
mMetadataListener = listener;
}
@Override
public void removeMetadataListener()
{
mMetadataListener = null;
}
@Override
public Listener<Message> getMessageListener()
{
return this;
}
}

View File

@@ -1,68 +0,0 @@
package module.decode.state;
public class DecoderStateEvent
{
private Object mSource;
private Event mEvent;
private State mState;
private long mFrequency;
public DecoderStateEvent( Object source, Event event, State state )
{
mSource = source;
mEvent = event;
mState = state;
}
public DecoderStateEvent( Object source, Event event, State state, long frequency )
{
this( source, event, state );
mFrequency = frequency;
}
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append( "Decoder State Event - source[" + mSource.getClass() +
"] event[" + mEvent.toString() +
"] state[" + mState.toString() +
"] frequency [" + mFrequency + "]" );
return sb.toString();
}
public Object getSource()
{
return mSource;
}
public Event getEvent()
{
return mEvent;
}
public State getState()
{
return mState;
}
public long getFrequency()
{
return mFrequency;
}
public enum Event
{
ALWAYS_UNSQUELCH,
CHANGE_CALL_TIMEOUT,
CONTINUATION,
DECODE,
END,
RESET,
SOURCE_FREQUENCY,
START,
TRAFFIC_CHANNEL_ALLOCATION;
}
}

View File

@@ -1,8 +0,0 @@
package module.decode.state;
import sample.Listener;
public interface IChangedAttributeListener
{
public Listener<ChangedAttribute> getChangedAttributeListener();
}

View File

@@ -1,9 +0,0 @@
package module.decode.state;
import sample.Listener;
public interface IChangedAttributeProvider
{
public void setChangedAttributeListener( Listener<ChangedAttribute> listener );
public void removeChangedAttributeListener();
}

View File

@@ -1,8 +0,0 @@
package module.decode.state;
import sample.Listener;
public interface IDecoderStateEventListener
{
public Listener<DecoderStateEvent> getDecoderStateListener();
}

View File

@@ -1,9 +0,0 @@
package module.decode.state;
import sample.Listener;
public interface IDecoderStateEventProvider
{
public void setDecoderStateListener( Listener<DecoderStateEvent> listener );
public void removeDecoderStateListener();
}

View File

@@ -1,120 +0,0 @@
/*******************************************************************************
* 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.state;
import java.util.EnumSet;
/**
* Details the set of states for a channel and the allowable transition states
*/
public enum State
{
IDLE( "IDLE" )
{
@Override
public boolean canChangeTo( State state )
{
return state != TEARDOWN &&
state != RESET;
}
},
CALL( "CALL" )
{
@Override
public boolean canChangeTo( State state )
{
return state == CONTROL ||
state == DATA ||
state == ENCRYPTED ||
state == FADE ||
state == TEARDOWN;
}
},
DATA( "DATA" )
{
@Override
public boolean canChangeTo( State state )
{
return state == CALL ||
state == CONTROL ||
state == ENCRYPTED ||
state == FADE ||
state == TEARDOWN;
}
},
ENCRYPTED( "ENCRYPTED" )
{
@Override
public boolean canChangeTo( State state )
{
return state == FADE || state == TEARDOWN;
}
},
CONTROL( "CONTROL" )
{
@Override
public boolean canChangeTo( State state )
{
return state == IDLE ||
state == FADE;
}
},
FADE( "FADE" )
{
@Override
public boolean canChangeTo( State state )
{
return state != FADE &&
state != RESET;
}
},
RESET( "RESET" )
{
@Override
public boolean canChangeTo(State state)
{
return state == IDLE;
}
},
TEARDOWN( "TEARDOWN" )
{
@Override
public boolean canChangeTo(State state)
{
return state == RESET;
}
};
private String mDisplayValue;
public static final EnumSet<State> CALL_STATES = EnumSet.of( CALL, CONTROL, DATA, ENCRYPTED );
public static final EnumSet<State> IDLE_STATES = EnumSet.of( IDLE, FADE );
private State( String displayValue )
{
mDisplayValue = displayValue;
}
public abstract boolean canChangeTo( State state );
public String getDisplayValue()
{
return mDisplayValue;
}
}

View File

@@ -1,25 +0,0 @@
package module.decode.state;
import module.decode.event.CallEvent;
/**
* Traffic channel allocation event wraps a call event indicating the channel
* and frequency for a traffic channel allocation event, so that the traffic
* channel manager can respond and allocate a decoder channel and source if
* available, or change the wrapped call event to a call detect event and log it.
*/
public class TrafficChannelAllocationEvent extends DecoderStateEvent
{
private CallEvent mCallEvent;
public TrafficChannelAllocationEvent( Object source, CallEvent callEvent )
{
super( source, Event.TRAFFIC_CHANNEL_ALLOCATION, State.CALL );
mCallEvent = callEvent;
}
public CallEvent getCallEvent()
{
return mCallEvent;
}
}

View File

@@ -1,457 +0,0 @@
package module.decode.state;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import module.Module;
import module.decode.config.DecodeConfiguration;
import module.decode.event.CallEvent;
import module.decode.event.CallEvent.CallEventType;
import module.decode.event.ICallEventProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import record.config.RecordConfiguration;
import sample.Listener;
import source.config.SourceConfigTuner;
import source.tuner.TunerChannel;
import source.tuner.TunerChannel.Type;
import alias.Alias;
import alias.id.priority.Priority;
import controller.channel.Channel;
import controller.channel.Channel.ChannelType;
import controller.channel.ChannelEvent;
import controller.channel.ChannelEvent.Event;
import controller.channel.ChannelModel;
import controller.channel.ChannelProcessingManager;
import controller.channel.TrafficChannelEvent;
public class TrafficChannelManager extends Module
implements ICallEventProvider, IDecoderStateEventListener
{
private final static Logger mLog = LoggerFactory.getLogger( TrafficChannelManager.class );
public static final String CHANNEL_START_REJECTED = "CHANNEL START REJECTED";
public static final String NO_TUNER_AVAILABLE = "NO TUNER AVAILABLE";
public static final String UNKNOWN_FREQUENCY = "UNKNOWN FREQUENCY";
private int mTrafficChannelPoolMaximumSize =
DecodeConfiguration.TRAFFIC_CHANNEL_LIMIT_DEFAULT;
private List<Channel> mTrafficChannelPool = new ArrayList<Channel>();
private Map<String,Channel> mTrafficChannelsInUse = new ConcurrentHashMap<String,Channel>();
private DecoderStateEventListener mEventListener = new DecoderStateEventListener();
private Listener<CallEvent> mCallEventListener;
private ChannelModel mChannelModel;
private ChannelProcessingManager mChannelProcessingManager;
private DecodeConfiguration mDecodeConfiguration;
private RecordConfiguration mRecordConfiguration;
private String mSystem;
private String mSite;
private String mAliasListName;
private CallEvent mPreviousDoNotMonitorCallEvent;
/**
* Monitors call events and allocates traffic decoder channels in response
* to traffic channel allocation call events. Manages a pool of reusable
* traffic channel allocations.
*
* @param channelModel containing channels currently in use
*
* @param channelProcessingManager
*
* @param decodeConfiguration - decoder configuration to use for each
* traffic channel allocation.
*
* @param recordConfiguration - recording options for each traffic channel
*
* @param system label to use to describe the system
*
* @param site label to use to describe the site
*
* @param aliasListName designated for the channel
*
* @param trafficChannelTimeout - millisecond call timer limit used when an
* end of call signalling event is not decoded.
*
* @param trafficChannelPoolSize - maximum number of allocated traffic channels
* in the pool
*/
public TrafficChannelManager( ChannelModel channelModel,
ChannelProcessingManager channelProcessingManager,
DecodeConfiguration decodeConfiguration,
RecordConfiguration recordConfiguration,
String system,
String site,
String aliasListName,
long trafficChannelTimeout,
int trafficChannelPoolSize )
{
mChannelModel = channelModel;
mChannelProcessingManager = channelProcessingManager;
mDecodeConfiguration = decodeConfiguration;
mRecordConfiguration = recordConfiguration;
mSystem = system;
mSite = site;
mAliasListName = aliasListName;
mTrafficChannelPoolMaximumSize = trafficChannelPoolSize;
}
@Override
public void dispose()
{
for( Channel trafficChannel: mTrafficChannelPool )
{
mChannelModel.broadcast( new ChannelEvent( trafficChannel, Event.REQUEST_DISABLE ) );
}
mTrafficChannelPool.clear();
mTrafficChannelsInUse.clear();
mCallEventListener = null;
mDecodeConfiguration = null;
mPreviousDoNotMonitorCallEvent = null;
}
/**
* Provides a channel by either reusing an existing channel or constructing
* a new one, limited by the total number of constructed channels allowed.
*
* Note: you must enforce thread safety on the mTrafficChannelsInUse
* external to this method.
*
* @param channelNumber
* @param tunerChannel
* @return
*/
private Channel getChannel( String channelNumber, TunerChannel tunerChannel )
{
Channel channel = null;
if( !mTrafficChannelsInUse.containsKey( channelNumber ) )
{
for( Channel configuredChannel: mTrafficChannelPool )
{
if( !configuredChannel.getEnabled() )
{
channel = configuredChannel;
break;
}
}
if( channel == null && mTrafficChannelPool.size() < mTrafficChannelPoolMaximumSize )
{
channel = new Channel( "Traffic", ChannelType.TRAFFIC );
channel.setDecodeConfiguration( mDecodeConfiguration );
channel.setRecordConfiguration( mRecordConfiguration );
channel.setAliasListName( mAliasListName );
mChannelModel.addChannel( channel );
mTrafficChannelPool.add( channel );
}
/* If we have a configured channel, update metadata */
if( channel != null )
{
channel.setSourceConfiguration( new SourceConfigTuner( tunerChannel ) );
channel.setSystem( mSystem );
channel.setSite( mSite );
channel.setName( channelNumber );
mChannelModel.broadcast( new ChannelEvent( channel, Event.NOTIFICATION_CONFIGURATION_CHANGE ) );
}
}
return channel;
}
/**
* Processes the event and creates a traffic channel is resources are
* available
*/
private void process( TrafficChannelAllocationEvent event )
{
CallEvent callEvent = event.getCallEvent();
/* Check for duplicate events and suppress */
synchronized( mTrafficChannelsInUse )
{
if( mTrafficChannelsInUse.containsKey( callEvent.getChannel() ) )
{
return;
}
long frequency = callEvent.getFrequency();
/* Check the from/to aliases for do not monitor priority */
if( isDoNotMonitor( callEvent ) )
{
callEvent.setCallEventType( CallEventType.CALL_DO_NOT_MONITOR );
if( isSameCallEvent( mPreviousDoNotMonitorCallEvent, callEvent ) )
{
return;
}
else
{
mPreviousDoNotMonitorCallEvent = callEvent;
}
}
else if( frequency > 0 )
{
Channel channel = getChannel( callEvent.getChannel(), new TunerChannel( Type.TRAFFIC,
frequency, mDecodeConfiguration.getDecoderType().getChannelBandwidth() ) );
if( channel != null )
{
TrafficChannelEvent trafficChannelEvent =
new TrafficChannelEvent( this, channel, Event.REQUEST_ENABLE, callEvent );
//Request to enable the channel
mChannelModel.broadcast( trafficChannelEvent );
if( channel.getEnabled() )
{
mTrafficChannelsInUse.put( callEvent.getChannel(), channel );
}
else
{
callEvent.setCallEventType( CallEventType.CALL_DETECT );
String details = callEvent.getDetails();
if(details == null || details.isEmpty())
{
callEvent.setDetails(CHANNEL_START_REJECTED);
}
else if(!details.contains(CHANNEL_START_REJECTED))
{
callEvent.setDetails(new StringBuilder(CHANNEL_START_REJECTED)
.append(" : ")
.append(callEvent.getDetails()).toString());
}
}
}
else
{
callEvent.setCallEventType( CallEventType.CALL_DETECT );
String details = callEvent.getDetails();
if(details == null || details.isEmpty())
{
callEvent.setDetails(NO_TUNER_AVAILABLE);
}
else if(!details.contains(NO_TUNER_AVAILABLE))
{
callEvent.setDetails(new StringBuilder(NO_TUNER_AVAILABLE)
.append(" : ")
.append(callEvent.getDetails()).toString());
}
}
}
else
{
callEvent.setCallEventType( CallEventType.CALL_DETECT );
String details = callEvent.getDetails();
if(details == null || details.isEmpty())
{
callEvent.setDetails(UNKNOWN_FREQUENCY);
}
else if(!details.contains(UNKNOWN_FREQUENCY))
{
callEvent.setDetails(new StringBuilder(UNKNOWN_FREQUENCY)
.append(" : ")
.append(callEvent.getDetails()).toString());
}
}
final Listener<CallEvent> listener = mCallEventListener;
if( listener != null )
{
listener.receive( callEvent );
}
}
}
/**
* Compares the call type, channel and to fields for equivalence and the
* from field for either both null, or equivalence.
*
* @param e1
* @param e2
* @return
*/
public static boolean isSameCallEvent( CallEvent e1, CallEvent e2 )
{
if( e1 == null || e2 == null )
{
return false;
}
if( e1.getCallEventType() != e2.getCallEventType() )
{
return false;
}
if( e1.getChannel() == null ||
e2.getChannel() == null ||
!e1.getChannel().contentEquals( e2.getChannel() ) )
{
return false;
}
if( e1.getToID() == null ||
e2.getToID() == null ||
!e1.getToID().contentEquals( e2.getToID() ) )
{
return false;
}
if( e1.getFromID() == null || e2.getFromID() == null )
{
if( e1.getFromID() == null && e2.getFromID() == null )
{
return true;
}
else
{
return false;
}
}
else if( e1.getFromID().contentEquals( e2.getFromID() ) )
{
return true;
}
return false;
}
/**
* Checks for aliases that contain a do not follow/process priority.
*
* @param event
* @return - true if there is an alias that has a do not process alias id
*/
private boolean isDoNotMonitor( CallEvent event )
{
Alias to = event.getToIDAlias();
if( to != null &&
to.hasCallPriority() &&
to.getCallPriority() == Priority.DO_NOT_MONITOR )
{
return true;
}
Alias from = event.getFromIDAlias();
if( from != null &&
from.hasCallPriority() &&
from.getCallPriority() == Priority.DO_NOT_MONITOR )
{
return true;
}
return false;
}
@Override
public Listener<DecoderStateEvent> getDecoderStateListener()
{
return mEventListener;
}
@Override
public void addCallEventListener( Listener<CallEvent> listener )
{
mCallEventListener = listener;
}
@Override
public void removeCallEventListener( Listener<CallEvent> listener )
{
mCallEventListener = null;
}
@Override
public void reset()
{
}
@Override
public void start( ScheduledExecutorService executor )
{
}
@Override
public void stop()
{
if( !mTrafficChannelsInUse.isEmpty() )
{
List<String> channels = new ArrayList<>();
/* Copy the keyset so we don't get concurrent modification of the map */
channels.addAll( mTrafficChannelsInUse.keySet() );
for( String channel: channels )
{
callEnd( channel );
}
}
}
/**
* Callback used by the TrafficChannelStatusListener class to signal the
* end of a an allocated traffic channel call event
*
* @param channelNumber - channel number from the call event that signaled
* the start of a traffic channel allocation
*/
public void callEnd( String channelNumber )
{
synchronized( mTrafficChannelsInUse )
{
if( channelNumber != null && mTrafficChannelsInUse.containsKey( channelNumber ) )
{
Channel channel = mTrafficChannelsInUse.get( channelNumber );
mChannelModel.broadcast( new ChannelEvent( channel, Event.REQUEST_DISABLE ) );
mTrafficChannelsInUse.remove( channelNumber );
}
}
}
/**
* Wrapper class for the decoder state event listener interface to catch
* traffic channel allocation requests
*/
public class DecoderStateEventListener implements Listener<DecoderStateEvent>
{
@Override
public void receive( DecoderStateEvent event )
{
switch( event.getEvent() )
{
case TRAFFIC_CHANNEL_ALLOCATION:
process( (TrafficChannelAllocationEvent)event );
break;
default:
break;
}
}
}
}

View File

@@ -20,8 +20,8 @@ package module.decode.tait;
import alias.Alias;
import icon.IconManager;
import module.decode.state.ChangedAttribute;
import module.decode.state.DecoderPanel;
import channel.metadata.Attribute;
import channel.state.DecoderPanel;
import net.miginfocom.swing.MigLayout;
import settings.ColorSetting;
import settings.ColorSetting.ColorSettingName;
@@ -87,14 +87,14 @@ public class Tait1200DecoderPanel extends DecoderPanel
}
@Override
public void receive(final ChangedAttribute changedAttribute)
public void receive(final Attribute attribute)
{
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
switch(changedAttribute)
switch(attribute)
{
case FROM_TALKGROUP:
String from = getDecoderState().getFromID();

View File

@@ -28,11 +28,11 @@ import org.jdesktop.swingx.mapviewer.GeoPosition;
import message.Message;
import module.decode.DecoderType;
import module.decode.event.CallEvent.CallEventType;
import module.decode.state.ChangedAttribute;
import module.decode.state.DecoderState;
import module.decode.state.DecoderStateEvent;
import module.decode.state.State;
import module.decode.state.DecoderStateEvent.Event;
import channel.metadata.Attribute;
import channel.state.DecoderState;
import channel.state.DecoderStateEvent;
import channel.state.State;
import channel.state.DecoderStateEvent.Event;
import alias.Alias;
import alias.AliasList;
@@ -208,7 +208,7 @@ public class Tait1200DecoderState extends DecoderState
public void setFromID( String from )
{
mFrom = from;
broadcast( ChangedAttribute.FROM_TALKGROUP );
broadcast( Attribute.FROM_TALKGROUP );
}
public Alias getFromIDAlias()
@@ -219,7 +219,7 @@ public class Tait1200DecoderState extends DecoderState
public void setFromIDAlias( Alias alias )
{
mFromAlias = alias;
broadcast( ChangedAttribute.FROM_TALKGROUP_ALIAS );
broadcast( Attribute.FROM_TALKGROUP_ALIAS );
}
public String getToID()
@@ -230,7 +230,7 @@ public class Tait1200DecoderState extends DecoderState
public void setToID( String to )
{
mTo = to;
broadcast( ChangedAttribute.TO_TALKGROUP );
broadcast( Attribute.TO_TALKGROUP );
}
public Alias getToIDAlias()
@@ -241,7 +241,7 @@ public class Tait1200DecoderState extends DecoderState
public void setToIDAlias( Alias alias )
{
mToAlias = alias;
broadcast( ChangedAttribute.TO_TALKGROUP_ALIAS );
broadcast( Attribute.TO_TALKGROUP_ALIAS );
}
public String getMessage()
@@ -252,7 +252,7 @@ public class Tait1200DecoderState extends DecoderState
public void setMessage( String message )
{
mMessage = message;
broadcast( ChangedAttribute.MESSAGE );
broadcast( Attribute.MESSAGE );
}
public String getMessageType()
@@ -263,6 +263,6 @@ public class Tait1200DecoderState extends DecoderState
public void setMessageType( String type )
{
mMessageType = type;
broadcast( ChangedAttribute.MESSAGE_TYPE );
broadcast( Attribute.MESSAGE_TYPE );
}
}