Merge pull request #418 from DSheirer/417-channel-overflow-zombie-state

417 Traffic Channels in Buffer Overflow state do not tear down correctly
This commit is contained in:
Denny Sheirer
2018-09-16 05:23:05 -04:00
committed by GitHub
9 changed files with 70 additions and 101 deletions

View File

@@ -20,6 +20,7 @@ package io.github.dsheirer.channel.metadata;
public enum Attribute
{
BUFFER_OVERFLOW,
CHANNEL_CONFIGURATION_NAME,
CHANNEL_CONFIGURATION_SITE,
CHANNEL_CONFIGURATION_SYSTEM,

View File

@@ -116,6 +116,16 @@ public class AttributeChangeRequest<T>
return null;
}
public Boolean getBooleanValue()
{
if(mValue instanceof Boolean)
{
return (Boolean)mValue;
}
return false;
}
/**
* Returns the value as a DecoderType or null if the value is not a DecoderType instance.
*/

View File

@@ -1,19 +1,16 @@
/*******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2017 Dennis Sheirer
* sdr-trunk
* Copyright (C) 2014-2018 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 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.
* 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/>
* 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 io.github.dsheirer.channel.metadata;
@@ -23,7 +20,7 @@ import io.github.dsheirer.controller.channel.Channel;
import io.github.dsheirer.sample.Listener;
import javax.swing.table.AbstractTableModel;
import java.awt.*;
import java.awt.EventQueue;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
@@ -45,7 +42,7 @@ public class ChannelMetadataModel extends AbstractTableModel implements Listener
public static final int COLUMN_CONFIGURATION_NAME = 8;
public static final int COLUMN_MESSAGE = 9;
private static final String[] COLUMNS = {"State", "Decoder", "Channel", "Frequency", "Primary From", "Primary To",
private static final String[] COLUMNS = {"Status", "Decoder", "Channel", "Frequency", "Primary From", "Primary To",
"Secondary From", "Secondary To", "Channel Name", "Message"};
private List<MutableMetadata> mChannelMetadata = new ArrayList();
@@ -166,7 +163,14 @@ public class ChannelMetadataModel extends AbstractTableModel implements Listener
switch(columnIndex)
{
case COLUMN_STATE:
return metadata.getState();
if(metadata.isBufferOverflow())
{
return metadata.getState() + " *OVERFLOW*";
}
else
{
return metadata.getState();
}
case COLUMN_DECODER:
if(metadata.hasPrimaryDecoderType())
{

View File

@@ -120,8 +120,6 @@ public class ChannelMetadataPanel extends JPanel implements ListSelectionListene
mForegroundColors.put(State.FADE, Color.DARK_GRAY);
mBackgroundColors.put(State.IDLE, Color.WHITE);
mForegroundColors.put(State.IDLE, Color.DARK_GRAY);
mBackgroundColors.put(State.OVERFLOW, Color.RED);
mForegroundColors.put(State.OVERFLOW, Color.YELLOW);
mBackgroundColors.put(State.RESET, Color.PINK);
mForegroundColors.put(State.RESET, Color.YELLOW);
mBackgroundColors.put(State.TEARDOWN, Color.DARK_GRAY);

View File

@@ -41,6 +41,7 @@ public class Metadata
protected boolean mUpdated;
protected DecoderType mPrimaryDecoderType;
protected boolean mSelected;
protected boolean mBufferOverflow;
protected State mState = State.IDLE;
protected String mChannelConfigurationSystem;
protected String mChannelConfigurationSite;
@@ -173,6 +174,14 @@ public class Metadata
return mSelected;
}
/**
* Indicates if the channel for this metadata is in a buffer overflow state.
*/
public boolean isBufferOverflow()
{
return mBufferOverflow;
}
/**
* List of de-duplicated broadcast channels aggregated from the primary and secondary TO/FROM aliases.
*/

View File

@@ -80,6 +80,10 @@ public class MutableMetadata extends Metadata implements Listener<AttributeChang
{
switch(request.getAttribute())
{
case BUFFER_OVERFLOW:
mBufferOverflow = request.getBooleanValue();
broadcast(Attribute.BUFFER_OVERFLOW);
break;
case CHANNEL_CONFIGURATION_SYSTEM:
mChannelConfigurationSystem = request.getStringValue();
broadcast(Attribute.CHANNEL_CONFIGURATION_SYSTEM);

View File

@@ -346,8 +346,7 @@ public class ChannelState extends Module implements ICallEventProvider, IDecoder
break;
}
mMutableMetadata.receive(new AttributeChangeRequest<State>(Attribute.CHANNEL_STATE,
mSourceOverflow ? State.OVERFLOW : mState));
mMutableMetadata.receive(new AttributeChangeRequest<State>(Attribute.CHANNEL_STATE, mState));
}
}
@@ -370,8 +369,19 @@ public class ChannelState extends Module implements ICallEventProvider, IDecoder
{
mSourceOverflow = overflow;
mMutableMetadata.receive(new AttributeChangeRequest<State>(Attribute.CHANNEL_STATE,
mSourceOverflow ? State.OVERFLOW : mState));
mMutableMetadata.receive(new AttributeChangeRequest<Boolean>(Attribute.BUFFER_OVERFLOW, mSourceOverflow));
}
/**
* Indicates if this channel's sample buffer is in overflow state, meaning that the inbound sample
* stream is not being processed fast enough and samples are being thrown away until the processing can
* catch up.
*
* @return true if the channel is in overflow state.
*/
public boolean isOverflow()
{
return mSourceOverflow;
}
/**

View File

@@ -34,7 +34,7 @@ public enum State
@Override
public boolean canChangeTo(State state)
{
return state == CALL |
return state == CALL ||
state == CONTROL ||
state == DATA ||
state == ENCRYPTED ||
@@ -108,8 +108,7 @@ public enum State
public boolean canChangeTo(State state)
{
return state != FADE &&
state != RESET &&
state != OVERFLOW;
state != RESET;
}
},
/**
@@ -121,25 +120,10 @@ public enum State
public boolean canChangeTo(State state)
{
return state != TEARDOWN &&
state != RESET &&
state != OVERFLOW;
}
},
/**
* Indicates that the channel's sample buffer has overflowed and new buffer samples are no longer being
* delivered to the channel. This state persists until the processing catches up and reduces the number
* of samples in the input buffer below a threshold value. Transition to and from this state is exclusively
* managed by the Channel State and no other channel states can be processed from the channel decoders
* until the channel state is taken out of overflow.
*/
OVERFLOW("OVERFLOW")
{
@Override
public boolean canChangeTo(State state)
{
return false;
state != RESET;
}
},
/**
* Indicates that the channel has been reset and is ready to use for a new decoding session.
*/

View File

@@ -30,10 +30,17 @@ import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
@@ -86,64 +93,6 @@ public class MessageActivityPanel extends JPanel implements Listener<ProcessingC
});
}
// @Override
// public void channelChanged(ChannelEvent event)
// {
// boolean changed = false;
//
// if(event.getEvent() == Event.NOTIFICATION_SELECTION_CHANGE &&
// event.getChannel().isSelected())
// {
// if(mDisplayedChannel == null || (mDisplayedChannel != null && mDisplayedChannel != event.getChannel()))
// {
// mDisplayedChannel = event.getChannel();
//
// ProcessingChain chain = mChannelProcessingManager.getProcessingChain(mDisplayedChannel);
//
// if(chain != null)
// {
// mDisplayedModel = chain.getMessageActivityModel();
// }
// else
// {
// mDisplayedModel = EMPTY_MODEL;
// }
//
// mMessageTable.setModel(mDisplayedModel);
//
// if(mDisplayedChannel != null)
// {
// mManagementPanel.enableButtons();
// }
// else
// {
// mManagementPanel.disableButtons();
// }
//
// changed = true;
// }
// }
// else if(event.getEvent() == Event.NOTIFICATION_PROCESSING_STOP || event.getEvent() == Event.REQUEST_DISABLE)
// {
// if(mDisplayedChannel != null && mDisplayedChannel == event.getChannel())
// {
// mDisplayedChannel = null;
//
// mMessageTable.setModel(EMPTY_MODEL);
//
// mManagementPanel.disableButtons();
//
// changed = true;
// }
// }
//
// if(changed)
// {
// revalidate();
// repaint();
// }
// }
public class MessageManagementPanel extends JPanel
{
private static final long serialVersionUID = 1L;