mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 08:37:25 -05:00
#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:
@@ -34,8 +34,10 @@ public class AliasedIdentifier
|
||||
|
||||
/**
|
||||
* Resets alias and value to null
|
||||
*
|
||||
* Package Private - should only be changed within MutableMetadata
|
||||
*/
|
||||
public void reset()
|
||||
void reset()
|
||||
{
|
||||
mIdentifier = null;
|
||||
mAlias = null;
|
||||
@@ -51,8 +53,10 @@ public class AliasedIdentifier
|
||||
|
||||
/**
|
||||
* Sets the identifier to the argument value
|
||||
*
|
||||
* Package Private - should only be changed within MutableMetadata
|
||||
*/
|
||||
public void setIdentifier(String identifier)
|
||||
void setIdentifier(String identifier)
|
||||
{
|
||||
mIdentifier = identifier;
|
||||
}
|
||||
@@ -75,8 +79,10 @@ public class AliasedIdentifier
|
||||
|
||||
/**
|
||||
* Sets the alias to the argument
|
||||
*
|
||||
* Package Private - should only be changed within MutableMetadata
|
||||
*/
|
||||
public void setAlias(Alias alias)
|
||||
void setAlias(Alias alias)
|
||||
{
|
||||
mAlias = alias;
|
||||
}
|
||||
@@ -88,4 +94,14 @@ public class AliasedIdentifier
|
||||
{
|
||||
return mAlias != null;
|
||||
}
|
||||
|
||||
public AliasedIdentifier copyOf()
|
||||
{
|
||||
AliasedIdentifier copy = new AliasedIdentifier();
|
||||
|
||||
copy.setAlias(mAlias);
|
||||
copy.setIdentifier(new String(mIdentifier));
|
||||
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ChannelMetadataModel extends AbstractTableModel implements Listener<MetadataChangeEvent>
|
||||
public class ChannelMetadataModel extends AbstractTableModel implements Listener<MutableMetadataChangeEvent>
|
||||
{
|
||||
public static final int COLUMN_STATE = 0;
|
||||
public static final int COLUMN_PRIMARY = 1;
|
||||
@@ -40,10 +40,10 @@ public class ChannelMetadataModel extends AbstractTableModel implements Listener
|
||||
private static final String[] COLUMNS =
|
||||
{"State", "Primary", "Secondary", "Message", "Network", "Frequency", "Configuration"};
|
||||
|
||||
private List<Metadata> mChannelMetadata = new ArrayList();
|
||||
private Map<Metadata,Channel> mMetadataChannelMap = new HashMap();
|
||||
private List<MutableMetadata> mChannelMetadata = new ArrayList();
|
||||
private Map<MutableMetadata,Channel> mMetadataChannelMap = new HashMap();
|
||||
|
||||
public void add(Metadata metadata, Channel channel)
|
||||
public void add(MutableMetadata metadata, Channel channel)
|
||||
{
|
||||
mChannelMetadata.add(metadata);
|
||||
mMetadataChannelMap.put(metadata, channel);
|
||||
@@ -55,7 +55,7 @@ public class ChannelMetadataModel extends AbstractTableModel implements Listener
|
||||
metadata.addListener(this);
|
||||
}
|
||||
|
||||
public void remove(Metadata metadata)
|
||||
public void remove(MutableMetadata metadata)
|
||||
{
|
||||
metadata.removeListener(this);
|
||||
|
||||
@@ -88,7 +88,7 @@ public class ChannelMetadataModel extends AbstractTableModel implements Listener
|
||||
@Override
|
||||
public Class<?> getColumnClass(int columnIndex)
|
||||
{
|
||||
return Metadata.class;
|
||||
return MutableMetadata.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,13 +98,13 @@ public class ChannelMetadataModel extends AbstractTableModel implements Listener
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(MetadataChangeEvent metadataChangeEvent)
|
||||
public void receive(MutableMetadataChangeEvent mutableMetadataChangeEvent)
|
||||
{
|
||||
int rowIndex = mChannelMetadata.indexOf(metadataChangeEvent.getMetadata());
|
||||
int rowIndex = mChannelMetadata.indexOf(mutableMetadataChangeEvent.getMetadata());
|
||||
|
||||
if(rowIndex >= 0)
|
||||
{
|
||||
switch(metadataChangeEvent.getAttribute())
|
||||
switch(mutableMetadataChangeEvent.getAttribute())
|
||||
{
|
||||
case CHANNEL_CONFIGURATION_LABEL_1:
|
||||
case CHANNEL_CONFIGURATION_LABEL_2:
|
||||
|
||||
@@ -24,7 +24,6 @@ import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import java.awt.*;
|
||||
import java.text.DecimalFormat;
|
||||
@@ -120,7 +119,7 @@ public class ChannelMetadataPanel extends JPanel
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
|
||||
int row, int column)
|
||||
{
|
||||
Metadata metadata = (Metadata)value;
|
||||
MutableMetadata metadata = (MutableMetadata)value;
|
||||
|
||||
if(mAttribute1 != null)
|
||||
{
|
||||
@@ -187,7 +186,7 @@ public class ChannelMetadataPanel extends JPanel
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
|
||||
int row, int column)
|
||||
{
|
||||
Metadata metadata = (Metadata)value;
|
||||
MutableMetadata metadata = (MutableMetadata)value;
|
||||
|
||||
if(metadata.hasChannelFrequency())
|
||||
{
|
||||
@@ -198,7 +197,7 @@ public class ChannelMetadataPanel extends JPanel
|
||||
mLabel1.setText(null);
|
||||
}
|
||||
|
||||
mLabel2.setText(metadata.getChannelID());
|
||||
mLabel2.setText(metadata.getChannelFrequencyLabel());
|
||||
|
||||
setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
|
||||
|
||||
@@ -224,7 +223,7 @@ public class ChannelMetadataPanel extends JPanel
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
|
||||
int row, int column)
|
||||
{
|
||||
Metadata metadata = (Metadata)value;
|
||||
MutableMetadata metadata = (MutableMetadata)value;
|
||||
|
||||
mLabel1.setText(metadata.getState().getDisplayValue());
|
||||
|
||||
|
||||
26
src/channel/metadata/IAttributeChangeRequestListener.java
Normal file
26
src/channel/metadata/IAttributeChangeRequestListener.java
Normal file
@@ -0,0 +1,26 @@
|
||||
/*******************************************************************************
|
||||
* 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 channel.metadata;
|
||||
|
||||
import sample.Listener;
|
||||
|
||||
public interface IAttributeChangeRequestListener
|
||||
{
|
||||
public Listener<AttributeChangeRequest> getAttributeChangeRequestListener();
|
||||
}
|
||||
28
src/channel/metadata/IAttributeChangeRequestProvider.java
Normal file
28
src/channel/metadata/IAttributeChangeRequestProvider.java
Normal file
@@ -0,0 +1,28 @@
|
||||
/*******************************************************************************
|
||||
* 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 channel.metadata;
|
||||
|
||||
import sample.Listener;
|
||||
|
||||
public interface IAttributeChangeRequestProvider
|
||||
{
|
||||
public void setAttributeChangeRequestListener(Listener<AttributeChangeRequest> listener);
|
||||
|
||||
public void removeAttributeChangeRequestListener();
|
||||
}
|
||||
@@ -19,234 +19,187 @@
|
||||
package channel.metadata;
|
||||
|
||||
import alias.Alias;
|
||||
import alias.id.broadcast.BroadcastChannel;
|
||||
import alias.id.priority.Priority;
|
||||
import channel.state.State;
|
||||
import sample.Broadcaster;
|
||||
import sample.Listener;
|
||||
import module.decode.DecoderType;
|
||||
|
||||
public class Metadata implements Listener<AttributeChangeRequest>
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Metadata
|
||||
{
|
||||
private State mState = State.IDLE;
|
||||
private String mChannelConfigurationLabel1;
|
||||
private String mChannelConfigurationLabel2;
|
||||
private String mChannelID;
|
||||
private long mChannelFrequency;
|
||||
private AliasedIdentifier mNetworkID1 = new AliasedIdentifier();
|
||||
private AliasedIdentifier mNetworkID2 = new AliasedIdentifier();
|
||||
// Static unique metadata identifier tracking
|
||||
private static int UNIQUE_METADATA_ID_GENERATOR = 0;
|
||||
|
||||
//Temporal attributes
|
||||
private String mMessage;
|
||||
private String mMessageType;
|
||||
private AliasedIdentifier mPrimaryAddressFrom = new AliasedIdentifier();
|
||||
private AliasedIdentifier mPrimaryAddressTo = new AliasedIdentifier();
|
||||
private AliasedIdentifier mSecondaryAddressFrom = new AliasedIdentifier();
|
||||
private AliasedIdentifier mSecondaryAddressTo = new AliasedIdentifier();
|
||||
private int mMetadataID;
|
||||
|
||||
private Broadcaster<MetadataChangeEvent> mMetadataChangeEventBroadcaster = new Broadcaster<>();
|
||||
protected boolean mUpdated;
|
||||
protected DecoderType mPrimaryDecoderType;
|
||||
protected boolean mSelected;
|
||||
protected State mState = State.IDLE;
|
||||
protected String mChannelConfigurationLabel1;
|
||||
protected String mChannelConfigurationLabel2;
|
||||
protected String mChannelFrequencyLabel;
|
||||
protected long mChannelFrequency;
|
||||
protected AliasedIdentifier mNetworkID1 = new AliasedIdentifier();
|
||||
protected AliasedIdentifier mNetworkID2 = new AliasedIdentifier();
|
||||
|
||||
protected String mMessage;
|
||||
protected String mMessageType;
|
||||
protected AliasedIdentifier mPrimaryAddressFrom = new AliasedIdentifier();
|
||||
protected AliasedIdentifier mPrimaryAddressTo = new AliasedIdentifier();
|
||||
protected AliasedIdentifier mSecondaryAddressFrom = new AliasedIdentifier();
|
||||
protected AliasedIdentifier mSecondaryAddressTo = new AliasedIdentifier();
|
||||
|
||||
//Lazily constructed member variables.
|
||||
private Integer mAudioPriority;
|
||||
private Boolean mRecordable;
|
||||
private List<BroadcastChannel> mBroadcastChannels;
|
||||
|
||||
|
||||
/**
|
||||
* Channel metadata. Contains all attributes that reflect the state and current attribute values for a channel
|
||||
* that is currently decoding. This metadata is intended to support any decoding channel gui components to
|
||||
* graphically convey the current state of a decoding channel.
|
||||
* graphically convey the current state of a decoding channel and to provide audio metadata
|
||||
*/
|
||||
public Metadata()
|
||||
{
|
||||
mMetadataID = UNIQUE_METADATA_ID_GENERATOR++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the state of this metadata
|
||||
* Protected constructor. Primarily used by the copyOf() method to create a metadata copy with the same ID
|
||||
*/
|
||||
public void setState(State state)
|
||||
protected Metadata(int metadataID)
|
||||
{
|
||||
mState = state;
|
||||
broadcast(Attribute.CHANNEL_STATE);
|
||||
mMetadataID = metadataID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request to change an attribute value for this metadata. This is the primary method for updating all attributes
|
||||
* in this metadata set.
|
||||
* Unique string identifier for this metadata that is comprised of the channel ID and the primary TO address.
|
||||
*
|
||||
* This identifier can be used to uniquely identify a channel audio stream and the primary communicant.
|
||||
*/
|
||||
@Override
|
||||
public void receive(AttributeChangeRequest request)
|
||||
public String getUniqueIdentifier()
|
||||
{
|
||||
switch(request.getAttribute())
|
||||
{
|
||||
case CHANNEL_CONFIGURATION_LABEL_1:
|
||||
mChannelConfigurationLabel1 = request.getStringValue();
|
||||
broadcast(Attribute.CHANNEL_CONFIGURATION_LABEL_1);
|
||||
break;
|
||||
case CHANNEL_CONFIGURATION_LABEL_2:
|
||||
mChannelConfigurationLabel2 = request.getStringValue();
|
||||
broadcast(Attribute.CHANNEL_CONFIGURATION_LABEL_2);
|
||||
break;
|
||||
case CHANNEL_FREQUENCY:
|
||||
if(request.hasValue())
|
||||
{
|
||||
mChannelFrequency = request.getLongValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
mChannelFrequency = 0;
|
||||
}
|
||||
broadcast(Attribute.CHANNEL_FREQUENCY);
|
||||
break;
|
||||
case CHANNEL_ID:
|
||||
mChannelID = request.getStringValue();
|
||||
broadcast(Attribute.CHANNEL_ID);
|
||||
break;
|
||||
case MESSAGE:
|
||||
mMessage = request.getStringValue();
|
||||
broadcast(Attribute.MESSAGE);
|
||||
break;
|
||||
case MESSAGE_TYPE:
|
||||
mMessageType = request.getStringValue();
|
||||
broadcast(Attribute.MESSAGE_TYPE);
|
||||
break;
|
||||
case NETWORK_ID_1:
|
||||
mNetworkID1.setIdentifier(request.getStringValue());
|
||||
mNetworkID1.setAlias(request.getAlias());
|
||||
broadcast(Attribute.NETWORK_ID_1);
|
||||
break;
|
||||
case NETWORK_ID_2:
|
||||
mNetworkID2.setIdentifier(request.getStringValue());
|
||||
mNetworkID2.setAlias(request.getAlias());
|
||||
broadcast(Attribute.NETWORK_ID_2);
|
||||
break;
|
||||
case PRIMARY_ADDRESS_FROM:
|
||||
mPrimaryAddressFrom.setIdentifier(request.getStringValue());
|
||||
mPrimaryAddressFrom.setAlias(request.getAlias());
|
||||
broadcast(Attribute.PRIMARY_ADDRESS_FROM);
|
||||
break;
|
||||
case PRIMARY_ADDRESS_TO:
|
||||
mPrimaryAddressTo.setIdentifier(request.getStringValue());
|
||||
mPrimaryAddressTo.setAlias(request.getAlias());
|
||||
broadcast(Attribute.PRIMARY_ADDRESS_TO);
|
||||
break;
|
||||
case SECONDARY_ADDRESS_FROM:
|
||||
mSecondaryAddressFrom.setIdentifier(request.getStringValue());
|
||||
mSecondaryAddressFrom.setAlias(request.getAlias());
|
||||
broadcast(Attribute.SECONDARY_ADDRESS_FROM);
|
||||
break;
|
||||
case SECONDARY_ADDRESS_TO:
|
||||
mSecondaryAddressTo.setIdentifier(request.getStringValue());
|
||||
mSecondaryAddressTo.setAlias(request.getAlias());
|
||||
broadcast(Attribute.SECONDARY_ADDRESS_TO);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unrecognized Metadata Attribute: " +
|
||||
request.getAttribute().name());
|
||||
}
|
||||
return "SRC:" + mMetadataID +
|
||||
" ID:" + (mPrimaryAddressTo.hasIdentifier() ? mPrimaryAddressTo.getIdentifier() : "UNKNOWN");
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts to registered listeners that an attribute has changed for this metadata
|
||||
* Indicates if any of the fields of this metadata have been updated since the last time a copy was made from this
|
||||
* metadata. This method is primarily used by downstream audio playback and audio recording to signal when changes
|
||||
* are made to the metadata that requires the downstream component to reinspect the metadata.
|
||||
*
|
||||
* This flag is reset to false immediately after a copy is made of this metadata via the copyOf() method.
|
||||
*/
|
||||
private void broadcast(Attribute attribute)
|
||||
public boolean isUpdated()
|
||||
{
|
||||
mMetadataChangeEventBroadcaster.broadcast(new MetadataChangeEvent(this, attribute));
|
||||
return mUpdated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the listener to receive metadata change events for this channel metadata
|
||||
* Audio Priority as the highest audio priority value from across the primary and secondary identifier aliases.
|
||||
*
|
||||
* A default priority will be used if there are no aliased values. If there is a conflict between audio priority
|
||||
* and 'Do Not Monitor' among the aliases, the highest audio priority will be used (prefer to monitor).
|
||||
*
|
||||
* -1 Do Not Monitor
|
||||
* 0 Channel Selected for immediate monitor
|
||||
* 1 Highest Priority
|
||||
* 100 Lowest Priority (default)
|
||||
*
|
||||
* @return audio priority
|
||||
*/
|
||||
public void addListener(Listener<MetadataChangeEvent> listener)
|
||||
public int getAudioPriority()
|
||||
{
|
||||
mMetadataChangeEventBroadcaster.addListener(listener);
|
||||
if(isSelected())
|
||||
{
|
||||
return Priority.SELECTED_PRIORITY;
|
||||
}
|
||||
|
||||
if(mAudioPriority == null)
|
||||
{
|
||||
determineAudioPriority();
|
||||
}
|
||||
|
||||
return mAudioPriority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the listener from receiving metadata change events for this channel metadata
|
||||
* Indicates if the audio priority is set to 'Do Not Monitor'
|
||||
*/
|
||||
public void removeListener(Listener<MetadataChangeEvent> listener)
|
||||
public boolean isDoNotMonitor()
|
||||
{
|
||||
mMetadataChangeEventBroadcaster.removeListener(listener);
|
||||
return getAudioPriority() == Priority.DO_NOT_MONITOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets temporal attributes to null value. This only resets attributes that have a non-ull value in order to
|
||||
* limit the number of change events that are produced.
|
||||
* Indicates if any of the primary or secondary TO/FROM aliases are identified as recordable
|
||||
*/
|
||||
public void resetTemporalAttributes()
|
||||
public boolean isRecordable()
|
||||
{
|
||||
if(hasMessage())
|
||||
if(mRecordable == null)
|
||||
{
|
||||
mMessage = null;
|
||||
broadcast(Attribute.MESSAGE);
|
||||
determineRecordable();
|
||||
}
|
||||
|
||||
if(hasMessageType())
|
||||
{
|
||||
mMessageType = null;
|
||||
broadcast(Attribute.MESSAGE_TYPE);
|
||||
}
|
||||
|
||||
if(mPrimaryAddressFrom.hasIdentifier())
|
||||
{
|
||||
mPrimaryAddressFrom.reset();
|
||||
broadcast(Attribute.PRIMARY_ADDRESS_FROM);
|
||||
}
|
||||
|
||||
if(mPrimaryAddressTo.hasIdentifier())
|
||||
{
|
||||
mPrimaryAddressTo.reset();
|
||||
broadcast(Attribute.PRIMARY_ADDRESS_TO);
|
||||
}
|
||||
|
||||
if(mSecondaryAddressFrom.hasIdentifier())
|
||||
{
|
||||
mSecondaryAddressFrom.reset();
|
||||
broadcast(Attribute.SECONDARY_ADDRESS_FROM);
|
||||
}
|
||||
|
||||
if(mSecondaryAddressTo.hasIdentifier())
|
||||
{
|
||||
mSecondaryAddressTo.reset();
|
||||
broadcast(Attribute.SECONDARY_ADDRESS_TO);
|
||||
}
|
||||
return mRecordable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all attributes to empty values
|
||||
* Indicates that this metadata has been selected by the user and any audio produced by this channel will be set
|
||||
* to the highest playback priority (immediate monitor).
|
||||
*/
|
||||
public void resetAllAttributes()
|
||||
public boolean isSelected()
|
||||
{
|
||||
resetTemporalAttributes();
|
||||
return mSelected;
|
||||
}
|
||||
|
||||
if(hasChannelConfigurationLabel1())
|
||||
/**
|
||||
* List of de-duplicated broadcast channels aggregated from the primary and secondary TO/FROM aliases.
|
||||
*/
|
||||
public List<BroadcastChannel> getBroadcastChannels()
|
||||
{
|
||||
if(mBroadcastChannels == null)
|
||||
{
|
||||
mChannelConfigurationLabel1 = null;
|
||||
broadcast(Attribute.CHANNEL_CONFIGURATION_LABEL_1);
|
||||
determineBroadcastChannels();
|
||||
}
|
||||
|
||||
if(hasChannelConfigurationLabel2())
|
||||
{
|
||||
mChannelConfigurationLabel2 = null;
|
||||
broadcast(Attribute.CHANNEL_CONFIGURATION_LABEL_2);
|
||||
}
|
||||
return mBroadcastChannels;
|
||||
}
|
||||
|
||||
if(hasChannelID())
|
||||
{
|
||||
mChannelID = null;
|
||||
broadcast(Attribute.CHANNEL_ID);
|
||||
}
|
||||
/**
|
||||
* Indicates if this metadata is streamable, meaning that it contains one ore more broadcast channels
|
||||
*/
|
||||
public boolean isStreamable()
|
||||
{
|
||||
return !getBroadcastChannels().isEmpty();
|
||||
}
|
||||
|
||||
if(hasChannelFrequency())
|
||||
{
|
||||
mChannelFrequency = 0;
|
||||
broadcast(Attribute.CHANNEL_FREQUENCY);
|
||||
}
|
||||
/**
|
||||
* Unique identifier for the source channel that produces this metadata
|
||||
*/
|
||||
public int getMetadataID()
|
||||
{
|
||||
return mMetadataID;
|
||||
}
|
||||
|
||||
if(mNetworkID1.hasIdentifier())
|
||||
{
|
||||
mNetworkID1.reset();
|
||||
broadcast(Attribute.NETWORK_ID_1);
|
||||
}
|
||||
/**
|
||||
* Decoder type (ie protocol) for the primary decoder
|
||||
*/
|
||||
public DecoderType getPrimaryDecoderType()
|
||||
{
|
||||
return mPrimaryDecoderType;
|
||||
}
|
||||
|
||||
if(mNetworkID2.hasIdentifier())
|
||||
{
|
||||
mNetworkID2.reset();
|
||||
broadcast(Attribute.NETWORK_ID_2);
|
||||
}
|
||||
/**
|
||||
* Indicates if this metadata has a primary decoder type defined
|
||||
*/
|
||||
public boolean hasPrimaryDecoderType()
|
||||
{
|
||||
return mPrimaryDecoderType != null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -285,7 +238,7 @@ public class Metadata implements Listener<AttributeChangeRequest>
|
||||
case CHANNEL_CONFIGURATION_LABEL_2:
|
||||
return mChannelConfigurationLabel2;
|
||||
case CHANNEL_ID:
|
||||
return mChannelID;
|
||||
return mChannelFrequencyLabel;
|
||||
case CHANNEL_STATE:
|
||||
return mState.getDisplayValue();
|
||||
case MESSAGE:
|
||||
@@ -352,17 +305,17 @@ public class Metadata implements Listener<AttributeChangeRequest>
|
||||
/**
|
||||
* Channel ID or Channel Number
|
||||
*/
|
||||
public String getChannelID()
|
||||
public String getChannelFrequencyLabel()
|
||||
{
|
||||
return mChannelID;
|
||||
return mChannelFrequencyLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if there is a non-null, non-empty channel identifier value
|
||||
*/
|
||||
public boolean hasChannelID()
|
||||
public boolean hasChannelFrequencyLabel()
|
||||
{
|
||||
return mChannelID != null && !mChannelID.isEmpty();
|
||||
return mChannelFrequencyLabel != null && !mChannelFrequencyLabel.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -460,4 +413,232 @@ public class Metadata implements Listener<AttributeChangeRequest>
|
||||
{
|
||||
return mSecondaryAddressTo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the audio priority from across the primary and secondary TO/FROM aliases when they exist
|
||||
*/
|
||||
private void determineAudioPriority()
|
||||
{
|
||||
int priority = Priority.DEFAULT_PRIORITY;
|
||||
|
||||
boolean doNotMonitorFound = false;
|
||||
boolean audioPriorityFound = false;
|
||||
|
||||
if(getPrimaryAddressTo().hasAlias())
|
||||
{
|
||||
Alias primaryTo = getPrimaryAddressTo().getAlias();
|
||||
|
||||
if(primaryTo.hasCallPriority())
|
||||
{
|
||||
if(primaryTo.getCallPriority() == Priority.DO_NOT_MONITOR)
|
||||
{
|
||||
doNotMonitorFound = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
audioPriorityFound = true;
|
||||
|
||||
if(primaryTo.getCallPriority() < priority)
|
||||
{
|
||||
priority = primaryTo.getCallPriority();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(getPrimaryAddressFrom().hasAlias())
|
||||
{
|
||||
Alias primaryFrom = getPrimaryAddressFrom().getAlias();
|
||||
|
||||
if(primaryFrom.hasCallPriority())
|
||||
{
|
||||
if(primaryFrom.getCallPriority() == Priority.DO_NOT_MONITOR)
|
||||
{
|
||||
doNotMonitorFound = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
audioPriorityFound = true;
|
||||
|
||||
if(primaryFrom.getCallPriority() < priority)
|
||||
{
|
||||
priority = primaryFrom.getCallPriority();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(getSecondaryAddressTo().hasAlias())
|
||||
{
|
||||
Alias secondaryTo = getSecondaryAddressTo().getAlias();
|
||||
|
||||
if(secondaryTo.hasCallPriority())
|
||||
{
|
||||
if(secondaryTo.getCallPriority() == Priority.DO_NOT_MONITOR)
|
||||
{
|
||||
doNotMonitorFound = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
audioPriorityFound = true;
|
||||
|
||||
if(secondaryTo.getCallPriority() < priority)
|
||||
{
|
||||
priority = secondaryTo.getCallPriority();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(getSecondaryAddressFrom().hasAlias())
|
||||
{
|
||||
Alias secondaryFrom = getSecondaryAddressFrom().getAlias();
|
||||
|
||||
if(secondaryFrom.hasCallPriority())
|
||||
{
|
||||
if(secondaryFrom.getCallPriority() == Priority.DO_NOT_MONITOR)
|
||||
{
|
||||
doNotMonitorFound = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
audioPriorityFound = true;
|
||||
|
||||
if(secondaryFrom.getCallPriority() < priority)
|
||||
{
|
||||
priority = secondaryFrom.getCallPriority();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//If we found a 'Do Not Monitor' and no other audio priority, then set to do not monitor
|
||||
if(doNotMonitorFound && !audioPriorityFound)
|
||||
{
|
||||
mAudioPriority = Priority.DO_NOT_MONITOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
mAudioPriority = priority;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if any of the primary or secondary to/from aliases are recordable.
|
||||
*/
|
||||
private void determineRecordable()
|
||||
{
|
||||
mRecordable = false;
|
||||
|
||||
if(mPrimaryAddressTo.hasAlias() && mPrimaryAddressTo.getAlias().isRecordable())
|
||||
{
|
||||
mRecordable = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if(mPrimaryAddressFrom.hasAlias() && mPrimaryAddressFrom.getAlias().isRecordable())
|
||||
{
|
||||
mRecordable = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if(mSecondaryAddressTo.hasAlias() && mSecondaryAddressTo.getAlias().isRecordable())
|
||||
{
|
||||
mRecordable = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if(mSecondaryAddressFrom.hasAlias() && mSecondaryAddressFrom.getAlias().isRecordable())
|
||||
{
|
||||
mRecordable = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Aggregates a de-duplicated list of broadcast channels from among the primary/secondary to/from aliases
|
||||
*/
|
||||
private void determineBroadcastChannels()
|
||||
{
|
||||
mBroadcastChannels = new ArrayList<>();
|
||||
|
||||
if(mPrimaryAddressTo.hasAlias() && mPrimaryAddressTo.getAlias().isStreamable())
|
||||
{
|
||||
for(BroadcastChannel broadcastChannel: mPrimaryAddressTo.getAlias().getBroadcastChannels())
|
||||
{
|
||||
if(!mBroadcastChannels.contains(broadcastChannel))
|
||||
{
|
||||
mBroadcastChannels.add(broadcastChannel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(mPrimaryAddressFrom.hasAlias() && mPrimaryAddressFrom.getAlias().isStreamable())
|
||||
{
|
||||
for(BroadcastChannel broadcastChannel: mPrimaryAddressFrom.getAlias().getBroadcastChannels())
|
||||
{
|
||||
if(!mBroadcastChannels.contains(broadcastChannel))
|
||||
{
|
||||
mBroadcastChannels.add(broadcastChannel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(mSecondaryAddressTo.hasAlias() && mSecondaryAddressTo.getAlias().isStreamable())
|
||||
{
|
||||
for(BroadcastChannel broadcastChannel: mSecondaryAddressTo.getAlias().getBroadcastChannels())
|
||||
{
|
||||
if(!mBroadcastChannels.contains(broadcastChannel))
|
||||
{
|
||||
mBroadcastChannels.add(broadcastChannel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(mSecondaryAddressFrom.hasAlias() && mSecondaryAddressFrom.getAlias().isStreamable())
|
||||
{
|
||||
for(BroadcastChannel broadcastChannel: mSecondaryAddressFrom.getAlias().getBroadcastChannels())
|
||||
{
|
||||
if(!mBroadcastChannels.contains(broadcastChannel))
|
||||
{
|
||||
mBroadcastChannels.add(broadcastChannel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deep/full snapshot copy of this metadata set.
|
||||
*
|
||||
* The streamable, recordable, audio priority and broadcast channels are not copied. These are lazily determined
|
||||
* when initially requested.
|
||||
*/
|
||||
public Metadata copyOf()
|
||||
{
|
||||
Metadata copy = new Metadata(mMetadataID);
|
||||
|
||||
copy.mState = mState;
|
||||
copy.mPrimaryDecoderType = mPrimaryDecoderType;
|
||||
copy.mChannelFrequency = mChannelFrequency;
|
||||
|
||||
copy.mChannelConfigurationLabel1 = hasChannelConfigurationLabel1() ? new String(mChannelConfigurationLabel1) : null;
|
||||
copy.mChannelConfigurationLabel2 = hasChannelConfigurationLabel2() ? new String(mChannelConfigurationLabel2) : null;
|
||||
copy.mChannelFrequencyLabel = hasChannelFrequencyLabel() ? new String(mChannelFrequencyLabel) : null;
|
||||
copy.mMessage = hasMessage() ? new String(mMessage) : null;
|
||||
copy.mMessageType = hasMessageType() ? new String(mMessageType) : null;
|
||||
|
||||
copy.mNetworkID1 = mNetworkID1.copyOf();
|
||||
copy.mNetworkID2 = mNetworkID2.copyOf();
|
||||
copy.mPrimaryAddressFrom = mPrimaryAddressFrom.copyOf();
|
||||
copy.mPrimaryAddressTo = mPrimaryAddressTo.copyOf();
|
||||
copy.mSecondaryAddressFrom = mSecondaryAddressFrom.copyOf();
|
||||
copy.mSecondaryAddressTo = mSecondaryAddressTo.copyOf();
|
||||
|
||||
copy.mUpdated = mUpdated;
|
||||
|
||||
//Reset the updated flag
|
||||
mUpdated = false;
|
||||
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
|
||||
251
src/channel/metadata/MutableMetadata.java
Normal file
251
src/channel/metadata/MutableMetadata.java
Normal file
@@ -0,0 +1,251 @@
|
||||
/*******************************************************************************
|
||||
* 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 channel.metadata;
|
||||
|
||||
import channel.state.State;
|
||||
import module.decode.DecoderType;
|
||||
import sample.Broadcaster;
|
||||
import sample.Listener;
|
||||
|
||||
public class MutableMetadata extends Metadata implements Listener<AttributeChangeRequest>
|
||||
{
|
||||
private Broadcaster<MutableMetadataChangeEvent> mMetadataChangeEventBroadcaster = new Broadcaster<>();
|
||||
|
||||
/**
|
||||
* Mutable channel metadata. Contains all attributes that reflect the state and current attribute values for a
|
||||
* channel that is currently decoding. This metadata is intended to support any decoding channel gui components to
|
||||
* graphically convey the current state of a decoding channel and to provide audio metadata
|
||||
*/
|
||||
public MutableMetadata()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the selected state for this metadata. Selected indicates that the user has selected this metadata for
|
||||
* immediate monitor in the audio panel. When true, this overrides the audio priority for any audio produced
|
||||
* by the channel and sets that audio to the highest priority.
|
||||
*
|
||||
* Any component that toggles the selected state for this metadata is also responsible for clearing the flag.
|
||||
*/
|
||||
public void setSelected(boolean selected)
|
||||
{
|
||||
mSelected = selected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the primary decoder type
|
||||
*/
|
||||
public void setPrimaryDecoderType(DecoderType decoderType)
|
||||
{
|
||||
mPrimaryDecoderType = decoderType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request to change an attribute value for this metadata. This is the primary method for updating all attributes
|
||||
* in this metadata set.
|
||||
*/
|
||||
@Override
|
||||
public void receive(AttributeChangeRequest request)
|
||||
{
|
||||
switch(request.getAttribute())
|
||||
{
|
||||
case CHANNEL_CONFIGURATION_LABEL_1:
|
||||
mChannelConfigurationLabel1 = request.getStringValue();
|
||||
broadcast(Attribute.CHANNEL_CONFIGURATION_LABEL_1);
|
||||
break;
|
||||
case CHANNEL_CONFIGURATION_LABEL_2:
|
||||
mChannelConfigurationLabel2 = request.getStringValue();
|
||||
broadcast(Attribute.CHANNEL_CONFIGURATION_LABEL_2);
|
||||
break;
|
||||
case CHANNEL_FREQUENCY:
|
||||
if(request.hasValue())
|
||||
{
|
||||
mChannelFrequency = request.getLongValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
mChannelFrequency = 0;
|
||||
}
|
||||
broadcast(Attribute.CHANNEL_FREQUENCY);
|
||||
break;
|
||||
case CHANNEL_ID:
|
||||
mChannelFrequencyLabel = request.getStringValue();
|
||||
broadcast(Attribute.CHANNEL_ID);
|
||||
break;
|
||||
case MESSAGE:
|
||||
mMessage = request.getStringValue();
|
||||
broadcast(Attribute.MESSAGE);
|
||||
break;
|
||||
case MESSAGE_TYPE:
|
||||
mMessageType = request.getStringValue();
|
||||
broadcast(Attribute.MESSAGE_TYPE);
|
||||
break;
|
||||
case NETWORK_ID_1:
|
||||
mNetworkID1.setIdentifier(request.getStringValue());
|
||||
mNetworkID1.setAlias(request.getAlias());
|
||||
broadcast(Attribute.NETWORK_ID_1);
|
||||
break;
|
||||
case NETWORK_ID_2:
|
||||
mNetworkID2.setIdentifier(request.getStringValue());
|
||||
mNetworkID2.setAlias(request.getAlias());
|
||||
broadcast(Attribute.NETWORK_ID_2);
|
||||
break;
|
||||
case PRIMARY_ADDRESS_FROM:
|
||||
mPrimaryAddressFrom.setIdentifier(request.getStringValue());
|
||||
mPrimaryAddressFrom.setAlias(request.getAlias());
|
||||
broadcast(Attribute.PRIMARY_ADDRESS_FROM);
|
||||
break;
|
||||
case PRIMARY_ADDRESS_TO:
|
||||
mPrimaryAddressTo.setIdentifier(request.getStringValue());
|
||||
mPrimaryAddressTo.setAlias(request.getAlias());
|
||||
broadcast(Attribute.PRIMARY_ADDRESS_TO);
|
||||
break;
|
||||
case SECONDARY_ADDRESS_FROM:
|
||||
mSecondaryAddressFrom.setIdentifier(request.getStringValue());
|
||||
mSecondaryAddressFrom.setAlias(request.getAlias());
|
||||
broadcast(Attribute.SECONDARY_ADDRESS_FROM);
|
||||
break;
|
||||
case SECONDARY_ADDRESS_TO:
|
||||
mSecondaryAddressTo.setIdentifier(request.getStringValue());
|
||||
mSecondaryAddressTo.setAlias(request.getAlias());
|
||||
broadcast(Attribute.SECONDARY_ADDRESS_TO);
|
||||
break;
|
||||
case CHANNEL_STATE:
|
||||
mState = (State)request.getValue();
|
||||
broadcast(Attribute.CHANNEL_STATE);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unrecognized Metadata Attribute: " +
|
||||
request.getAttribute().name());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets temporal attributes to null value. This only resets attributes that have a non-ull value in order to
|
||||
* limit the number of change events that are produced.
|
||||
*/
|
||||
public void resetTemporalAttributes()
|
||||
{
|
||||
if(hasMessage())
|
||||
{
|
||||
mMessage = null;
|
||||
broadcast(Attribute.MESSAGE);
|
||||
}
|
||||
|
||||
if(hasMessageType())
|
||||
{
|
||||
mMessageType = null;
|
||||
broadcast(Attribute.MESSAGE_TYPE);
|
||||
}
|
||||
|
||||
if(mPrimaryAddressFrom.hasIdentifier())
|
||||
{
|
||||
mPrimaryAddressFrom.reset();
|
||||
broadcast(Attribute.PRIMARY_ADDRESS_FROM);
|
||||
}
|
||||
|
||||
if(mPrimaryAddressTo.hasIdentifier())
|
||||
{
|
||||
mPrimaryAddressTo.reset();
|
||||
broadcast(Attribute.PRIMARY_ADDRESS_TO);
|
||||
}
|
||||
|
||||
if(mSecondaryAddressFrom.hasIdentifier())
|
||||
{
|
||||
mSecondaryAddressFrom.reset();
|
||||
broadcast(Attribute.SECONDARY_ADDRESS_FROM);
|
||||
}
|
||||
|
||||
if(mSecondaryAddressTo.hasIdentifier())
|
||||
{
|
||||
mSecondaryAddressTo.reset();
|
||||
broadcast(Attribute.SECONDARY_ADDRESS_TO);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all attributes to empty values
|
||||
*/
|
||||
public void resetAllAttributes()
|
||||
{
|
||||
resetTemporalAttributes();
|
||||
|
||||
if(hasChannelConfigurationLabel1())
|
||||
{
|
||||
mChannelConfigurationLabel1 = null;
|
||||
broadcast(Attribute.CHANNEL_CONFIGURATION_LABEL_1);
|
||||
}
|
||||
|
||||
if(hasChannelConfigurationLabel2())
|
||||
{
|
||||
mChannelConfigurationLabel2 = null;
|
||||
broadcast(Attribute.CHANNEL_CONFIGURATION_LABEL_2);
|
||||
}
|
||||
|
||||
if(hasChannelFrequencyLabel())
|
||||
{
|
||||
mChannelFrequencyLabel = null;
|
||||
broadcast(Attribute.CHANNEL_ID);
|
||||
}
|
||||
|
||||
if(hasChannelFrequency())
|
||||
{
|
||||
mChannelFrequency = 0;
|
||||
broadcast(Attribute.CHANNEL_FREQUENCY);
|
||||
}
|
||||
|
||||
if(mNetworkID1.hasIdentifier())
|
||||
{
|
||||
mNetworkID1.reset();
|
||||
broadcast(Attribute.NETWORK_ID_1);
|
||||
}
|
||||
|
||||
if(mNetworkID2.hasIdentifier())
|
||||
{
|
||||
mNetworkID2.reset();
|
||||
broadcast(Attribute.NETWORK_ID_2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Broadcasts to registered listeners that an attribute has changed for this metadata
|
||||
*/
|
||||
private void broadcast(Attribute attribute)
|
||||
{
|
||||
mMetadataChangeEventBroadcaster.broadcast(new MutableMetadataChangeEvent(this, attribute));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the listener to receive metadata change events for this channel metadata
|
||||
*/
|
||||
public void addListener(Listener<MutableMetadataChangeEvent> listener)
|
||||
{
|
||||
mMetadataChangeEventBroadcaster.addListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the listener from receiving metadata change events for this channel metadata
|
||||
*/
|
||||
public void removeListener(Listener<MutableMetadataChangeEvent> listener)
|
||||
{
|
||||
mMetadataChangeEventBroadcaster.removeListener(listener);
|
||||
}
|
||||
}
|
||||
@@ -18,9 +18,9 @@
|
||||
******************************************************************************/
|
||||
package channel.metadata;
|
||||
|
||||
public class MetadataChangeEvent
|
||||
public class MutableMetadataChangeEvent
|
||||
{
|
||||
private Metadata mMetadata;
|
||||
private MutableMetadata mMetadata;
|
||||
private Attribute mAttribute;
|
||||
|
||||
/**
|
||||
@@ -29,7 +29,7 @@ public class MetadataChangeEvent
|
||||
* @param metadata where the change occurred
|
||||
* @param attribute that changed
|
||||
*/
|
||||
public MetadataChangeEvent(Metadata metadata, Attribute attribute)
|
||||
public MutableMetadataChangeEvent(MutableMetadata metadata, Attribute attribute)
|
||||
{
|
||||
mMetadata = metadata;
|
||||
mAttribute = attribute;
|
||||
@@ -38,7 +38,7 @@ public class MetadataChangeEvent
|
||||
/**
|
||||
* Channel metadata where the change occurred
|
||||
*/
|
||||
public Metadata getMetadata()
|
||||
public MutableMetadata getMetadata()
|
||||
{
|
||||
return mMetadata;
|
||||
}
|
||||
@@ -1,29 +1,29 @@
|
||||
/*******************************************************************************
|
||||
* 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 channel.state;
|
||||
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import channel.metadata.Attribute;
|
||||
import channel.metadata.AttributeChangeRequest;
|
||||
import channel.state.DecoderStateEvent.Event;
|
||||
import message.Message;
|
||||
import module.decode.DecoderType;
|
||||
import channel.state.DecoderStateEvent.Event;
|
||||
import audio.metadata.Metadata;
|
||||
import audio.metadata.MetadataType;
|
||||
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
/**
|
||||
* Basic decoder channel state - provides the minimum channel state functionality
|
||||
@@ -31,68 +31,68 @@ import audio.metadata.MetadataType;
|
||||
*/
|
||||
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 */
|
||||
}
|
||||
private DecoderType mDecoderType;
|
||||
private String mChannelName;
|
||||
|
||||
@Override
|
||||
public String getActivitySummary()
|
||||
public AlwaysUnsquelchedDecoderState(DecoderType decoderType, String channelName)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append( "Activity Summary\n" );
|
||||
sb.append( "\tDecoder:\t" );
|
||||
sb.append( mDecoderType );
|
||||
sb.append( "\n\n" );
|
||||
|
||||
return sb.toString();
|
||||
super(null);
|
||||
|
||||
mDecoderType = decoderType;
|
||||
mChannelName = channelName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive( Message t )
|
||||
{
|
||||
@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 )
|
||||
{
|
||||
@Override
|
||||
public void receiveDecoderStateEvent(DecoderStateEvent event)
|
||||
{
|
||||
/* Not implemented */
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DecoderType getDecoderType()
|
||||
{
|
||||
return mDecoderType;
|
||||
}
|
||||
@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 start(ScheduledExecutorService executor)
|
||||
{
|
||||
broadcast(new AttributeChangeRequest<String>(Attribute.PRIMARY_ADDRESS_TO, mChannelName));
|
||||
broadcast(new DecoderStateEvent(this, Event.ALWAYS_UNSQUELCH, State.IDLE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop()
|
||||
{
|
||||
}
|
||||
@Override
|
||||
public void stop()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@ import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import channel.metadata.Attribute;
|
||||
import channel.metadata.AttributeChangeRequest;
|
||||
import channel.metadata.IAttributeChangeRequestListener;
|
||||
import channel.metadata.MutableMetadata;
|
||||
import channel.traffic.TrafficChannelManager;
|
||||
import module.Module;
|
||||
import module.decode.config.DecodeConfiguration;
|
||||
@@ -43,14 +46,16 @@ import audio.squelch.SquelchState;
|
||||
import controller.channel.Channel.ChannelType;
|
||||
|
||||
public class ChannelState extends Module implements ICallEventProvider, IChangedAttributeProvider,
|
||||
IDecoderStateEventListener, IDecoderStateEventProvider, IMetadataProvider, ISquelchStateProvider
|
||||
IDecoderStateEventListener, IDecoderStateEventProvider, IMetadataProvider, ISquelchStateProvider,
|
||||
IAttributeChangeRequestListener
|
||||
{
|
||||
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 MutableMetadata mMutableMetadata = new MutableMetadata();
|
||||
private State mState = State.IDLE;
|
||||
|
||||
private Listener<CallEvent> mCallEventListener;
|
||||
@@ -107,7 +112,19 @@ public class ChannelState extends Module implements ICallEventProvider, IChanged
|
||||
{
|
||||
mChannelType = channelType;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Metadata for this channel containing channel details, primary and secondary entities for call events and any
|
||||
* decoded messages. This metadata is primarily intended to be used by graphical components to convey the
|
||||
* details of the current channel state and to provide metadata backing any decoded audio packets produced by
|
||||
* any audio streams for this channel.
|
||||
*/
|
||||
public MutableMetadata getMutableMetadata()
|
||||
{
|
||||
return mMutableMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets this channel state and prepares it for reuse.
|
||||
*/
|
||||
@@ -115,8 +132,9 @@ public class ChannelState extends Module implements ICallEventProvider, IChanged
|
||||
public void reset()
|
||||
{
|
||||
broadcast( new DecoderStateEvent( this, Event.RESET, State.IDLE ) );
|
||||
broadcast( new MetadataReset() );
|
||||
|
||||
|
||||
mMutableMetadata.resetTemporalAttributes();
|
||||
|
||||
mState = State.IDLE;
|
||||
broadcast( Attribute.CHANNEL_STATE );
|
||||
}
|
||||
@@ -126,6 +144,8 @@ public class ChannelState extends Module implements ICallEventProvider, IChanged
|
||||
{
|
||||
if( mStateMonitorFuture == null && mStateMonitor != null )
|
||||
{
|
||||
mMutableMetadata.resetAllAttributes();
|
||||
|
||||
if( mTrafficChannelEndListener != null )
|
||||
{
|
||||
setState( State.CALL );
|
||||
@@ -419,7 +439,16 @@ public class ChannelState extends Module implements ICallEventProvider, IChanged
|
||||
mCallEventListener = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
|
||||
//NEW:
|
||||
@Override
|
||||
public Listener<AttributeChangeRequest> getAttributeChangeRequestListener()
|
||||
{
|
||||
return mMutableMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts the channel state attribute change event to all registered
|
||||
* listeners
|
||||
*/
|
||||
@@ -439,7 +468,7 @@ public class ChannelState extends Module implements ICallEventProvider, IChanged
|
||||
{
|
||||
mChangedAttributeListener = listener;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes the listener to receive channel state attribute change events
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
package channel.state;
|
||||
|
||||
import alias.AliasList;
|
||||
import audio.metadata.IMetadataProvider;
|
||||
import audio.metadata.Metadata;
|
||||
import channel.metadata.Attribute;
|
||||
import channel.metadata.AttributeChangeRequest;
|
||||
import channel.metadata.IAttributeChangeRequestProvider;
|
||||
import message.IMessageListener;
|
||||
import message.Message;
|
||||
import module.Module;
|
||||
@@ -10,219 +15,182 @@ 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
|
||||
* 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
|
||||
public abstract class DecoderState extends Module implements ActivitySummaryProvider, Listener<Message>,
|
||||
IAttributeChangeRequestProvider, ICallEventProvider, IDecoderStateEventListener,
|
||||
IDecoderStateEventProvider, IMessageListener
|
||||
{
|
||||
/* This has to be a broadcaster in order for references to persist */
|
||||
private Broadcaster<CallEvent> mCallEventBroadcaster = new Broadcaster<>();
|
||||
private Listener<Attribute> 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();
|
||||
/* This has to be a broadcaster in order for references to persist */
|
||||
private Broadcaster<CallEvent> mCallEventBroadcaster = new Broadcaster<>();
|
||||
private Listener<AttributeChangeRequest> mAttributeChangeRequestListener;
|
||||
private Listener<DecoderStateEvent> mDecoderStateListener;
|
||||
|
||||
/**
|
||||
* Allow the decoder to perform any setup actions
|
||||
*/
|
||||
public abstract void init();
|
||||
private DecoderStateEventListener mDecoderStateEventListener = new DecoderStateEventListener();
|
||||
|
||||
/**
|
||||
* 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;
|
||||
protected CallEvent mCurrentCallEvent;
|
||||
|
||||
mAliasList = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Activity Summary - textual summary of activity observed by the channel state.
|
||||
*/
|
||||
public abstract String getActivitySummary();
|
||||
private AliasList mAliasList;
|
||||
|
||||
/**
|
||||
* Broadcasts a call event to any registered listeners
|
||||
*/
|
||||
protected void broadcast( CallEvent event )
|
||||
{
|
||||
mCallEventBroadcaster.broadcast( event );
|
||||
}
|
||||
public DecoderState(AliasList aliasList)
|
||||
{
|
||||
mAliasList = aliasList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a call event listener
|
||||
*/
|
||||
@Override
|
||||
public void addCallEventListener( Listener<CallEvent> listener )
|
||||
{
|
||||
mCallEventBroadcaster.addListener( listener );
|
||||
}
|
||||
public abstract DecoderType getDecoderType();
|
||||
|
||||
/**
|
||||
* Removes the call event listener
|
||||
*/
|
||||
@Override
|
||||
public void removeCallEventListener( Listener<CallEvent> listener )
|
||||
{
|
||||
mCallEventBroadcaster.removeListener( listener );
|
||||
}
|
||||
public AliasList getAliasList()
|
||||
{
|
||||
return mAliasList;
|
||||
}
|
||||
|
||||
@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( Attribute attribute )
|
||||
{
|
||||
if( mChangedAttributeListener != null )
|
||||
{
|
||||
mChangedAttributeListener.receive( attribute );
|
||||
}
|
||||
}
|
||||
public boolean hasAliasList()
|
||||
{
|
||||
return mAliasList != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the listener to receive channel state attribute change events
|
||||
*/
|
||||
@Override
|
||||
public void setChangedAttributeListener( Listener<Attribute> listener )
|
||||
{
|
||||
mChangedAttributeListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the listener to receive channel state attribute change events
|
||||
*/
|
||||
@Override
|
||||
public void removeChangedAttributeListener()
|
||||
{
|
||||
mChangedAttributeListener = null;
|
||||
}
|
||||
/**
|
||||
* Reset the decoder state to prepare for processing a different sample
|
||||
* source
|
||||
*/
|
||||
public abstract void reset();
|
||||
|
||||
/**
|
||||
* Broadcasts a channel state event to any registered listeners
|
||||
*/
|
||||
protected void broadcast( DecoderStateEvent event )
|
||||
{
|
||||
if( mDecoderStateListener != null )
|
||||
{
|
||||
mDecoderStateListener.receive( event );
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Allow the decoder to perform any setup actions
|
||||
*/
|
||||
public abstract void init();
|
||||
|
||||
/**
|
||||
* Adds a decoder state event listener
|
||||
*/
|
||||
@Override
|
||||
public void setDecoderStateListener( Listener<DecoderStateEvent> listener )
|
||||
{
|
||||
mDecoderStateListener = listener;
|
||||
}
|
||||
/**
|
||||
* Implements the IDecoderStateEventListener interface to receive state
|
||||
* reset events.
|
||||
*/
|
||||
public abstract void receiveDecoderStateEvent(DecoderStateEvent event);
|
||||
|
||||
/**
|
||||
* Removes the decoder state event listener
|
||||
*/
|
||||
@Override
|
||||
public void removeDecoderStateListener()
|
||||
{
|
||||
mDecoderStateListener = null;
|
||||
}
|
||||
/**
|
||||
* Disposes any resources or pointers held by this instance to prepare for
|
||||
* garbage collection
|
||||
*/
|
||||
public void dispose()
|
||||
{
|
||||
mCallEventBroadcaster.dispose();
|
||||
mCallEventBroadcaster = null;
|
||||
mDecoderStateListener = null;
|
||||
|
||||
/**
|
||||
* Broadcasts metadata to a registered listener
|
||||
*/
|
||||
protected void broadcast( Metadata metadata )
|
||||
{
|
||||
if( mMetadataListener != null )
|
||||
{
|
||||
mMetadataListener.receive( metadata );
|
||||
}
|
||||
}
|
||||
mAliasList = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMetadataListener( Listener<Metadata> listener )
|
||||
{
|
||||
mMetadataListener = listener;
|
||||
}
|
||||
/**
|
||||
* Activity Summary - textual summary of activity observed by the channel state.
|
||||
*/
|
||||
public abstract String getActivitySummary();
|
||||
|
||||
@Override
|
||||
public void removeMetadataListener()
|
||||
{
|
||||
mMetadataListener = null;
|
||||
}
|
||||
/**
|
||||
* Broadcasts a call event to any registered listeners
|
||||
*/
|
||||
protected void broadcast(CallEvent event)
|
||||
{
|
||||
mCallEventBroadcaster.broadcast(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Listener<Message> getMessageListener()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* 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 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<Message> getMessageListener()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts the attribute change request to the registered listener
|
||||
*/
|
||||
protected void broadcast(AttributeChangeRequest<?> request)
|
||||
{
|
||||
if(mAttributeChangeRequestListener != null)
|
||||
{
|
||||
mAttributeChangeRequestListener.receive(request);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the listener to receive attribute change requests from this decoder state
|
||||
*/
|
||||
@Override
|
||||
public void setAttributeChangeRequestListener(Listener<AttributeChangeRequest> listener)
|
||||
{
|
||||
mAttributeChangeRequestListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes any listener from receiving attribute change requests
|
||||
*/
|
||||
@Override
|
||||
public void removeAttributeChangeRequestListener()
|
||||
{
|
||||
mAttributeChangeRequestListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,353 +1,354 @@
|
||||
/*******************************************************************************
|
||||
* 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.fleetsync2;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import message.Message;
|
||||
import module.decode.DecoderType;
|
||||
import alias.Alias;
|
||||
import alias.AliasList;
|
||||
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;
|
||||
import message.Message;
|
||||
import module.decode.DecoderType;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
public class Fleetsync2DecoderState extends DecoderState
|
||||
{
|
||||
private TreeSet<String> mIdents = new TreeSet<String>();
|
||||
private TreeSet<String> mEmergencyIdents = new TreeSet<String>();
|
||||
private TreeSet<String> mIdents = new TreeSet<String>();
|
||||
private TreeSet<String> mEmergencyIdents = new TreeSet<String>();
|
||||
|
||||
private String mFrom;
|
||||
private Alias mFromAlias;
|
||||
private String mFrom;
|
||||
private Alias mFromAlias;
|
||||
|
||||
private String mTo;
|
||||
private Alias mToAlias;
|
||||
private String mTo;
|
||||
private Alias mToAlias;
|
||||
|
||||
private String mMessage;
|
||||
private String mMessageType;
|
||||
|
||||
private long mFrequency;
|
||||
private String mMessage;
|
||||
private String mMessageType;
|
||||
|
||||
public Fleetsync2DecoderState( AliasList aliasList )
|
||||
{
|
||||
super( aliasList );
|
||||
}
|
||||
|
||||
@Override
|
||||
public DecoderType getDecoderType()
|
||||
{
|
||||
return DecoderType.FLEETSYNC2;
|
||||
}
|
||||
private long mFrequency;
|
||||
|
||||
@Override
|
||||
public void start( ScheduledExecutorService executor )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose()
|
||||
{
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the overall decoder state and clears any accumulated event details
|
||||
*/
|
||||
@Override
|
||||
public void reset()
|
||||
{
|
||||
mIdents.clear();
|
||||
mEmergencyIdents.clear();
|
||||
|
||||
resetState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets this decoder state
|
||||
*/
|
||||
public void resetState()
|
||||
{
|
||||
setFromID( null );
|
||||
setFromIDAlias( null );
|
||||
setToID( null );
|
||||
setToIDAlias( null );
|
||||
setMessage( null );
|
||||
setMessageType( null );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive( Message message )
|
||||
public Fleetsync2DecoderState(AliasList aliasList)
|
||||
{
|
||||
if( message instanceof FleetsyncMessage )
|
||||
{
|
||||
FleetsyncMessage fleetsync = (FleetsyncMessage)message;
|
||||
|
||||
if( fleetsync.isValid() )
|
||||
{
|
||||
State state = State.CALL;
|
||||
|
||||
setFromID( fleetsync.getFromID() );
|
||||
setFromIDAlias( fleetsync.getFromIDAlias() );
|
||||
mIdents.add( fleetsync.getFromID() );
|
||||
|
||||
FleetsyncMessageType type = fleetsync.getMessageType();
|
||||
super(aliasList);
|
||||
}
|
||||
|
||||
if( type != FleetsyncMessageType.ANI )
|
||||
{
|
||||
setToID( fleetsync.getToID() );
|
||||
setToIDAlias( fleetsync.getToIDAlias() );
|
||||
mIdents.add( fleetsync.getToID() );
|
||||
}
|
||||
|
||||
setMessageType( type.getLabel() );
|
||||
@Override
|
||||
public DecoderType getDecoderType()
|
||||
{
|
||||
return DecoderType.FLEETSYNC2;
|
||||
}
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case GPS:
|
||||
setMessage( fleetsync.getGPSLocation() );
|
||||
state = State.DATA;
|
||||
break;
|
||||
case STATUS:
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append( fleetsync.getStatus() );
|
||||
|
||||
Alias status = fleetsync.getStatusAlias();
|
||||
|
||||
if( status != null )
|
||||
{
|
||||
sb.append( "/" );
|
||||
sb.append( status.getName() );
|
||||
}
|
||||
@Override
|
||||
public void start(ScheduledExecutorService executor)
|
||||
{
|
||||
}
|
||||
|
||||
setMessage( sb.toString() );
|
||||
state = State.DATA;
|
||||
break;
|
||||
case EMERGENCY:
|
||||
case LONE_WORKER_EMERGENCY:
|
||||
mEmergencyIdents.add( fleetsync.getFromID() );
|
||||
state = State.DATA;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@Override
|
||||
public void stop()
|
||||
{
|
||||
}
|
||||
|
||||
FleetsyncCallEvent fsCallEvent =
|
||||
FleetsyncCallEvent.getFleetsync2Event( fleetsync, mFrequency );
|
||||
@Override
|
||||
public void dispose()
|
||||
{
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
fsCallEvent.setAliasList( getAliasList() );
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
}
|
||||
|
||||
broadcast( fsCallEvent );
|
||||
/**
|
||||
* Resets the overall decoder state and clears any accumulated event details
|
||||
*/
|
||||
@Override
|
||||
public void reset()
|
||||
{
|
||||
mIdents.clear();
|
||||
mEmergencyIdents.clear();
|
||||
|
||||
resetState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets this decoder state
|
||||
*/
|
||||
public void resetState()
|
||||
{
|
||||
mFrom = null;
|
||||
mFromAlias = null;
|
||||
mTo = null;
|
||||
mToAlias = null;
|
||||
mMessage = null;
|
||||
mMessageType = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(Message message)
|
||||
{
|
||||
if(message instanceof FleetsyncMessage)
|
||||
{
|
||||
FleetsyncMessage fleetsync = (FleetsyncMessage) message;
|
||||
|
||||
if(fleetsync.isValid())
|
||||
{
|
||||
State state = State.CALL;
|
||||
|
||||
setFromID(fleetsync.getFromID());
|
||||
setFromIDAlias(fleetsync.getFromIDAlias());
|
||||
mIdents.add(fleetsync.getFromID());
|
||||
|
||||
FleetsyncMessageType type = fleetsync.getMessageType();
|
||||
|
||||
if(type != FleetsyncMessageType.ANI)
|
||||
{
|
||||
setToID(fleetsync.getToID());
|
||||
setToIDAlias(fleetsync.getToIDAlias());
|
||||
mIdents.add(fleetsync.getToID());
|
||||
}
|
||||
|
||||
setMessageType(type.getLabel());
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case GPS:
|
||||
setMessage(fleetsync.getGPSLocation());
|
||||
state = State.DATA;
|
||||
break;
|
||||
case STATUS:
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(fleetsync.getStatus());
|
||||
|
||||
Alias status = fleetsync.getStatusAlias();
|
||||
|
||||
if(status != null)
|
||||
{
|
||||
sb.append("/");
|
||||
sb.append(status.getName());
|
||||
}
|
||||
|
||||
setMessage(sb.toString());
|
||||
state = State.DATA;
|
||||
break;
|
||||
case EMERGENCY:
|
||||
case LONE_WORKER_EMERGENCY:
|
||||
mEmergencyIdents.add(fleetsync.getFromID());
|
||||
state = State.DATA;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
FleetsyncCallEvent fsCallEvent =
|
||||
FleetsyncCallEvent.getFleetsync2Event(fleetsync, mFrequency);
|
||||
|
||||
fsCallEvent.setAliasList(getAliasList());
|
||||
|
||||
broadcast(fsCallEvent);
|
||||
|
||||
/* Broadcast decode event so that the channel state will
|
||||
* kick in and reset everything after a short delay */
|
||||
broadcast( new DecoderStateEvent( this, Event.DECODE, state ) );
|
||||
}
|
||||
}
|
||||
* kick in and reset everything after a short delay */
|
||||
broadcast(new DecoderStateEvent(this, Event.DECODE, state));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getFromID()
|
||||
{
|
||||
return mFrom;
|
||||
}
|
||||
|
||||
public void setFromID( String from )
|
||||
{
|
||||
mFrom = from;
|
||||
broadcast( Attribute.FROM_TALKGROUP );
|
||||
}
|
||||
|
||||
public Alias getFromIDAlias()
|
||||
{
|
||||
return mFromAlias;
|
||||
}
|
||||
|
||||
public void setFromIDAlias( Alias alias )
|
||||
{
|
||||
mFromAlias = alias;
|
||||
broadcast( Attribute.FROM_TALKGROUP_ALIAS );
|
||||
}
|
||||
|
||||
public String getToID()
|
||||
{
|
||||
return mTo;
|
||||
}
|
||||
|
||||
public void setToID( String to )
|
||||
{
|
||||
mTo = to;
|
||||
broadcast( Attribute.TO_TALKGROUP );
|
||||
}
|
||||
|
||||
public Alias getToIDAlias()
|
||||
{
|
||||
return mToAlias;
|
||||
}
|
||||
|
||||
public void setToIDAlias( Alias alias )
|
||||
{
|
||||
mToAlias = alias;
|
||||
broadcast( Attribute.TO_TALKGROUP_ALIAS );
|
||||
}
|
||||
|
||||
public String getMessage()
|
||||
{
|
||||
return mMessage;
|
||||
}
|
||||
public String getFromID()
|
||||
{
|
||||
return mFrom;
|
||||
}
|
||||
|
||||
public void setMessage( String message )
|
||||
{
|
||||
mMessage = message;
|
||||
broadcast( Attribute.MESSAGE );
|
||||
}
|
||||
|
||||
public String getMessageType()
|
||||
{
|
||||
return mMessageType;
|
||||
}
|
||||
public void setFromID(String from)
|
||||
{
|
||||
mFrom = from;
|
||||
|
||||
public void setMessageType( String type )
|
||||
{
|
||||
mMessageType = type;
|
||||
broadcast( Attribute.MESSAGE_TYPE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Responds to reset events issued by the channel state
|
||||
*/
|
||||
@Override
|
||||
public void receiveDecoderStateEvent( DecoderStateEvent event )
|
||||
{
|
||||
switch( event.getEvent() )
|
||||
{
|
||||
case RESET:
|
||||
resetState();
|
||||
break;
|
||||
case SOURCE_FREQUENCY:
|
||||
mFrequency = event.getFrequency();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
broadcast(Attribute.FROM_TALKGROUP);
|
||||
}
|
||||
|
||||
public Alias getFromIDAlias()
|
||||
{
|
||||
return mFromAlias;
|
||||
}
|
||||
|
||||
public void setFromIDAlias(Alias alias)
|
||||
{
|
||||
mFromAlias = alias;
|
||||
broadcast(Attribute.FROM_TALKGROUP_ALIAS);
|
||||
}
|
||||
|
||||
public String getToID()
|
||||
{
|
||||
return mTo;
|
||||
}
|
||||
|
||||
public void setToID(String to)
|
||||
{
|
||||
mTo = to;
|
||||
broadcast(Attribute.TO_TALKGROUP);
|
||||
}
|
||||
|
||||
public Alias getToIDAlias()
|
||||
{
|
||||
return mToAlias;
|
||||
}
|
||||
|
||||
public void setToIDAlias(Alias alias)
|
||||
{
|
||||
mToAlias = alias;
|
||||
broadcast(Attribute.TO_TALKGROUP_ALIAS);
|
||||
}
|
||||
|
||||
public String getMessage()
|
||||
{
|
||||
return mMessage;
|
||||
}
|
||||
|
||||
public void setMessage(String message)
|
||||
{
|
||||
mMessage = message;
|
||||
broadcast(Attribute.MESSAGE);
|
||||
}
|
||||
|
||||
public String getMessageType()
|
||||
{
|
||||
return mMessageType;
|
||||
}
|
||||
|
||||
public void setMessageType(String type)
|
||||
{
|
||||
mMessageType = type;
|
||||
broadcast(Attribute.MESSAGE_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Responds to reset events issued by the channel state
|
||||
*/
|
||||
@Override
|
||||
public void receiveDecoderStateEvent(DecoderStateEvent event)
|
||||
{
|
||||
switch(event.getEvent())
|
||||
{
|
||||
case RESET:
|
||||
resetState();
|
||||
break;
|
||||
case SOURCE_FREQUENCY:
|
||||
mFrequency = event.getFrequency();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActivitySummary()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append( "=============================\n" );
|
||||
sb.append( "Decoder:\tFleetsync II\n\n" );
|
||||
sb.append( "Fleetsync Idents\n" );
|
||||
sb.append("=============================\n");
|
||||
sb.append("Decoder:\tFleetsync II\n\n");
|
||||
sb.append("Fleetsync Idents\n");
|
||||
|
||||
if( mIdents.isEmpty() )
|
||||
{
|
||||
sb.append( " None\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
Iterator<String> it = mIdents.iterator();
|
||||
|
||||
while( it.hasNext() )
|
||||
{
|
||||
String ident = it.next();
|
||||
|
||||
sb.append( " " );
|
||||
sb.append( formatIdent( ident ) );
|
||||
if(mIdents.isEmpty())
|
||||
{
|
||||
sb.append(" None\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Iterator<String> it = mIdents.iterator();
|
||||
|
||||
if( hasAliasList() )
|
||||
{
|
||||
Alias alias = getAliasList().getFleetsyncAlias( ident );
|
||||
|
||||
if( alias != null )
|
||||
{
|
||||
sb.append( " " );
|
||||
sb.append( alias.getName() );
|
||||
}
|
||||
}
|
||||
|
||||
sb.append( "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
sb.append( "\nFleetsync Emergency Activations\n" );
|
||||
while(it.hasNext())
|
||||
{
|
||||
String ident = it.next();
|
||||
|
||||
if( mEmergencyIdents.isEmpty() )
|
||||
{
|
||||
sb.append( " None\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
Iterator<String> it = mEmergencyIdents.iterator();
|
||||
|
||||
while( it.hasNext() )
|
||||
{
|
||||
String ident = it.next();
|
||||
|
||||
sb.append( " " );
|
||||
sb.append( formatIdent( ident ) );
|
||||
sb.append(" ");
|
||||
sb.append(formatIdent(ident));
|
||||
|
||||
if( hasAliasList() )
|
||||
{
|
||||
Alias alias = getAliasList().getFleetsyncAlias( ident );
|
||||
|
||||
if( alias != null )
|
||||
{
|
||||
sb.append( " " );
|
||||
sb.append( alias.getName() );
|
||||
}
|
||||
|
||||
sb.append( "\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
if(hasAliasList())
|
||||
{
|
||||
Alias alias = getAliasList().getFleetsyncAlias(ident);
|
||||
|
||||
return sb.toString();
|
||||
if(alias != null)
|
||||
{
|
||||
sb.append(" ");
|
||||
sb.append(alias.getName());
|
||||
}
|
||||
}
|
||||
|
||||
sb.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
sb.append("\nFleetsync Emergency Activations\n");
|
||||
|
||||
if(mEmergencyIdents.isEmpty())
|
||||
{
|
||||
sb.append(" None\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Iterator<String> it = mEmergencyIdents.iterator();
|
||||
|
||||
while(it.hasNext())
|
||||
{
|
||||
String ident = it.next();
|
||||
|
||||
sb.append(" ");
|
||||
sb.append(formatIdent(ident));
|
||||
|
||||
if(hasAliasList())
|
||||
{
|
||||
Alias alias = getAliasList().getFleetsyncAlias(ident);
|
||||
|
||||
if(alias != null)
|
||||
{
|
||||
sb.append(" ");
|
||||
sb.append(alias.getName());
|
||||
}
|
||||
|
||||
sb.append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String formatIdent( String ident )
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if( ident.length() == 7 )
|
||||
{
|
||||
sb.append( ident.substring( 0, 3 ) );
|
||||
sb.append( "-" );
|
||||
sb.append( ident.substring( 3, 7 ) );
|
||||
public static String formatIdent(String ident)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return ident;
|
||||
}
|
||||
}
|
||||
if(ident.length() == 7)
|
||||
{
|
||||
sb.append(ident.substring(0, 3));
|
||||
sb.append("-");
|
||||
sb.append(ident.substring(3, 7));
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return ident;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user