diff --git a/src/main/java/io/github/dsheirer/channel/state/AbstractDecoderState.java b/src/main/java/io/github/dsheirer/channel/state/AbstractDecoderState.java
index 2ec19bedd..198421013 100644
--- a/src/main/java/io/github/dsheirer/channel/state/AbstractDecoderState.java
+++ b/src/main/java/io/github/dsheirer/channel/state/AbstractDecoderState.java
@@ -1,23 +1,20 @@
/*
+ * *****************************************************************************
+ * Copyright (C) 2014-2024 Dennis Sheirer
*
- * * ******************************************************************************
- * * Copyright (C) 2014-2019 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
- * * *****************************************************************************
+ * 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
+ * ****************************************************************************
*/
package io.github.dsheirer.channel.state;
@@ -47,9 +44,37 @@ public abstract class AbstractDecoderState extends Module implements ActivitySum
protected Broadcaster mDecodeEventBroadcaster = new Broadcaster<>();
protected Listener mDecoderStateListener;
private DecoderStateEventListener mDecoderStateEventListener = new DecoderStateEventListener();
+ private boolean mRunning;
public abstract DecoderType getDecoderType();
+ /**
+ * Implements module start and sets the mRunning flag to true so that messages can be processed.
+ */
+ @Override
+ public void start()
+ {
+ mRunning = true;
+ }
+
+ /**
+ * Implements the module stop and sets the mRunning flag to false to stop message processing
+ */
+ @Override
+ public void stop()
+ {
+ mRunning = false;
+ }
+
+ /**
+ * Indicates if this module is running and can process/pass messages down to sub-class implementations.
+ * @return true if running
+ */
+ public boolean isRunning()
+ {
+ return mRunning;
+ }
+
/**
* Provides subclass reference to the decode event broadcaster
*/
@@ -145,4 +170,22 @@ public void receive(DecoderStateEvent event)
}
}
+ /**
+ * Message listener that only passes messages while we're running. This is important because each of the decoders
+ * can process blocks of samples and that can result in additional messages being generated even after shutdown
+ * and so we shut off the processing of decoded messages when we're commanded to stop. The sample processing thread
+ * cannot be shutdown or forcefully interrupted because downstream decoder and channel states may have acquired
+ * locks that have to be properly released.
+ */
+ private class MessageListener implements Listener
+ {
+ @Override
+ public void receive(IMessage message)
+ {
+ if(isRunning())
+ {
+ receive(message);
+ }
+ }
+ }
}
diff --git a/src/main/java/io/github/dsheirer/channel/state/AlwaysUnsquelchedDecoderState.java b/src/main/java/io/github/dsheirer/channel/state/AlwaysUnsquelchedDecoderState.java
deleted file mode 100644
index 4a0f933cb..000000000
--- a/src/main/java/io/github/dsheirer/channel/state/AlwaysUnsquelchedDecoderState.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * *****************************************************************************
- * Copyright (C) 2014-2020 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
- * ****************************************************************************
- */
-package io.github.dsheirer.channel.state;
-
-import io.github.dsheirer.channel.state.DecoderStateEvent.Event;
-import io.github.dsheirer.identifier.Form;
-import io.github.dsheirer.identifier.Identifier;
-import io.github.dsheirer.identifier.IdentifierClass;
-import io.github.dsheirer.identifier.Role;
-import io.github.dsheirer.identifier.string.SimpleStringIdentifier;
-import io.github.dsheirer.message.IMessage;
-import io.github.dsheirer.module.decode.DecoderType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Basic decoder channel state - provides the minimum channel state functionality
- * to support an always un-squelched audio decoder.
- */
-public class AlwaysUnsquelchedDecoderState extends DecoderState
-{
- private final static Logger mLog = LoggerFactory.getLogger(AlwaysUnsquelchedDecoderState.class);
- private static final String NO_SQUELCH = "No Squelch";
- private Identifier mChannelNameIdentifier;
-
- private DecoderType mDecoderType;
- private String mChannelName;
-
- public AlwaysUnsquelchedDecoderState(DecoderType decoderType, String channelName)
- {
- mDecoderType = decoderType;
- mChannelName = (channelName != null && !channelName.isEmpty()) ? channelName : decoderType.name() + " CHANNEL";
- mChannelNameIdentifier = new SimpleStringIdentifier(mChannelName, IdentifierClass.USER, Form.CHANNEL_NAME, Role.TO);
- }
-
- @Override
- public void init()
- {
- }
-
- @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(IMessage t)
- {
- /* Not implemented */
- }
-
- @Override
- public void receiveDecoderStateEvent(DecoderStateEvent event)
- {
- if(event.getEvent() == Event.REQUEST_RESET)
- {
- getIdentifierCollection().update(mChannelNameIdentifier);
- }
- }
-
- @Override
- public DecoderType getDecoderType()
- {
- return mDecoderType;
- }
-
- @Override
- public void start()
- {
- broadcast(new DecoderStateEvent(this, Event.REQUEST_ALWAYS_UNSQUELCH, State.IDLE));
- getIdentifierCollection().update(mChannelNameIdentifier);
- }
-
- @Override
- public void stop()
- {
- }
-}
diff --git a/src/main/java/io/github/dsheirer/channel/state/DecoderState.java b/src/main/java/io/github/dsheirer/channel/state/DecoderState.java
index dfae0cfad..f6fe14a6b 100644
--- a/src/main/java/io/github/dsheirer/channel/state/DecoderState.java
+++ b/src/main/java/io/github/dsheirer/channel/state/DecoderState.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * Copyright (C) 2014-2024 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
@@ -54,6 +54,7 @@ public DecoderState()
@Override
public void start()
{
+ super.start();
//Broadcast the existing identifiers (as add events) so that they can be received by external listeners
mIdentifierCollection.broadcastIdentifiers();
}
diff --git a/src/main/java/io/github/dsheirer/module/decode/analog/AnalogDecoderState.java b/src/main/java/io/github/dsheirer/module/decode/analog/AnalogDecoderState.java
index c2bb750a0..b1d579c82 100644
--- a/src/main/java/io/github/dsheirer/module/decode/analog/AnalogDecoderState.java
+++ b/src/main/java/io/github/dsheirer/module/decode/analog/AnalogDecoderState.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2023 Dennis Sheirer
+ * Copyright (C) 2014-2024 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
@@ -145,11 +145,10 @@ private void endCallEvent()
@Override
public void start()
{
+ super.start();
getIdentifierCollection().update(getChannelNameIdentifier());
}
- @Override
- public void stop() {}
@Override
public void init() {}
@Override
diff --git a/src/main/java/io/github/dsheirer/module/decode/dcs/DCSDecoderState.java b/src/main/java/io/github/dsheirer/module/decode/dcs/DCSDecoderState.java
index 763fca019..0fe3e639c 100644
--- a/src/main/java/io/github/dsheirer/module/decode/dcs/DCSDecoderState.java
+++ b/src/main/java/io/github/dsheirer/module/decode/dcs/DCSDecoderState.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2023 Dennis Sheirer
+ * Copyright (C) 2014-2024 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
@@ -115,9 +115,4 @@ public String getActivitySummary()
public void init()
{
}
-
- @Override
- public void stop()
- {
- }
}
diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/DMRDecoderState.java b/src/main/java/io/github/dsheirer/module/decode/dmr/DMRDecoderState.java
index 73e0b3289..dd088695a 100644
--- a/src/main/java/io/github/dsheirer/module/decode/dmr/DMRDecoderState.java
+++ b/src/main/java/io/github/dsheirer/module/decode/dmr/DMRDecoderState.java
@@ -1472,6 +1472,8 @@ public void receiveDecoderStateEvent(DecoderStateEvent event)
@Override
public void start()
{
+ super.start();
+
//Change the default (45-second) traffic channel timeout to 1 second
if(mChannel.isTrafficChannel())
{
@@ -1483,9 +1485,4 @@ public void start()
public void init()
{
}
-
- @Override
- public void stop()
- {
- }
}
diff --git a/src/main/java/io/github/dsheirer/module/decode/fleetsync2/Fleetsync2DecoderState.java b/src/main/java/io/github/dsheirer/module/decode/fleetsync2/Fleetsync2DecoderState.java
index 70817ff13..ba4fb8ee4 100644
--- a/src/main/java/io/github/dsheirer/module/decode/fleetsync2/Fleetsync2DecoderState.java
+++ b/src/main/java/io/github/dsheirer/module/decode/fleetsync2/Fleetsync2DecoderState.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2023 Dennis Sheirer
+ * Copyright (C) 2014-2024 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
@@ -53,20 +53,7 @@ public DecoderType getDecoderType()
}
@Override
- public void start()
- {
- }
-
- @Override
- public void stop()
- {
- }
-
- @Override
- public void init()
- {
-
- }
+ public void init() {}
@Override
public void receive(IMessage message)
diff --git a/src/main/java/io/github/dsheirer/module/decode/lj1200/LJ1200DecoderState.java b/src/main/java/io/github/dsheirer/module/decode/lj1200/LJ1200DecoderState.java
index bc54188eb..8a945a915 100644
--- a/src/main/java/io/github/dsheirer/module/decode/lj1200/LJ1200DecoderState.java
+++ b/src/main/java/io/github/dsheirer/module/decode/lj1200/LJ1200DecoderState.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2023 Dennis Sheirer
+ * Copyright (C) 2014-2024 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
@@ -150,20 +150,5 @@ public void reset()
}
@Override
- public void start()
- {
-
- }
-
- @Override
- public void stop()
- {
-
- }
-
- @Override
- public void init()
- {
-
- }
+ public void init() {}
}
diff --git a/src/main/java/io/github/dsheirer/module/decode/ltrnet/LTRNetDecoderState.java b/src/main/java/io/github/dsheirer/module/decode/ltrnet/LTRNetDecoderState.java
index e3bba893d..dff9f5211 100644
--- a/src/main/java/io/github/dsheirer/module/decode/ltrnet/LTRNetDecoderState.java
+++ b/src/main/java/io/github/dsheirer/module/decode/ltrnet/LTRNetDecoderState.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2023 Dennis Sheirer
+ * Copyright (C) 2014-2024 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
@@ -586,19 +586,7 @@ public String getActivitySummary()
}
@Override
- public void start()
- {
- }
-
- @Override
- public void stop()
- {
- }
-
- @Override
- public void init()
- {
- }
+ public void init() {}
/**
* Resets the decoder state after a call or other decode event
diff --git a/src/main/java/io/github/dsheirer/module/decode/ltrstandard/LTRStandardDecoderState.java b/src/main/java/io/github/dsheirer/module/decode/ltrstandard/LTRStandardDecoderState.java
index a28aa6dae..2664735e9 100644
--- a/src/main/java/io/github/dsheirer/module/decode/ltrstandard/LTRStandardDecoderState.java
+++ b/src/main/java/io/github/dsheirer/module/decode/ltrstandard/LTRStandardDecoderState.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2023 Dennis Sheirer
+ * Copyright (C) 2014-2024 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
@@ -153,19 +153,7 @@ public void reset()
}
@Override
- public void start()
- {
- }
-
- @Override
- public void stop()
- {
- }
-
- @Override
- public void init()
- {
- }
+ public void init() {}
/**
* Performs a temporal reset following a call or other decode event
diff --git a/src/main/java/io/github/dsheirer/module/decode/mdc1200/MDCDecoderState.java b/src/main/java/io/github/dsheirer/module/decode/mdc1200/MDCDecoderState.java
index f9a079053..db1c678da 100644
--- a/src/main/java/io/github/dsheirer/module/decode/mdc1200/MDCDecoderState.java
+++ b/src/main/java/io/github/dsheirer/module/decode/mdc1200/MDCDecoderState.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2023 Dennis Sheirer
+ * Copyright (C) 2014-2024 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
@@ -58,22 +58,7 @@ public void reset()
}
@Override
- public void start()
- {
-
- }
-
- @Override
- public void stop()
- {
-
- }
-
- @Override
- public void init()
- {
-
- }
+ public void init() {}
@Override
public void receive(IMessage message)
diff --git a/src/main/java/io/github/dsheirer/module/decode/mpt1327/MPT1327DecoderState.java b/src/main/java/io/github/dsheirer/module/decode/mpt1327/MPT1327DecoderState.java
index 95b1fc63b..67fa409b7 100644
--- a/src/main/java/io/github/dsheirer/module/decode/mpt1327/MPT1327DecoderState.java
+++ b/src/main/java/io/github/dsheirer/module/decode/mpt1327/MPT1327DecoderState.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2023 Dennis Sheirer
+ * Copyright (C) 2014-2024 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
@@ -220,6 +220,7 @@ public void reset()
@Override
public void start()
{
+ super.start();
//Send call start event for traffic channels to unsquelch the audio. Decoded return to channel message
//or fade timeout expire will end the call event.
if(mChannelType == ChannelType.TRAFFIC)
@@ -228,18 +229,8 @@ public void start()
broadcast(new DecoderStateEvent(this, Event.START, State.CALL));
}
}
-
@Override
- public void stop()
- {
-
- }
-
- @Override
- public void init()
- {
-
- }
+ public void init() {}
protected void resetState()
{
diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1DecoderState.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1DecoderState.java
index 4587c3b9e..5a53fd279 100644
--- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1DecoderState.java
+++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1DecoderState.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2023 Dennis Sheirer
+ * Copyright (C) 2014-2024 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
@@ -1948,6 +1948,7 @@ public void receiveDecoderStateEvent(DecoderStateEvent event)
@Override
public void start()
{
+ super.start();
mPatchGroupManager.clear();
//Change the default (45-second) traffic channel timeout to 1 second
@@ -1965,6 +1966,7 @@ public void init()
@Override
public void stop()
{
+ super.stop();
mPatchGroupManager.clear();
}
}
diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase2/P25P2DecoderState.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase2/P25P2DecoderState.java
index d1b88213a..8c47c1132 100644
--- a/src/main/java/io/github/dsheirer/module/decode/p25/phase2/P25P2DecoderState.java
+++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase2/P25P2DecoderState.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2023 Dennis Sheirer
+ * Copyright (C) 2014-2024 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
@@ -1161,6 +1161,7 @@ public void receiveDecoderStateEvent(DecoderStateEvent event)
@Override
public void start()
{
+ super.start();
mPatchGroupManager.clear();
//Change the default (45-second) traffic channel timeout to 1 second
@@ -1178,6 +1179,7 @@ public void init()
@Override
public void stop()
{
+ super.stop();
mPatchGroupManager.clear();
}
}
diff --git a/src/main/java/io/github/dsheirer/module/decode/passport/PassportDecoderState.java b/src/main/java/io/github/dsheirer/module/decode/passport/PassportDecoderState.java
index d792d398f..346e73dea 100644
--- a/src/main/java/io/github/dsheirer/module/decode/passport/PassportDecoderState.java
+++ b/src/main/java/io/github/dsheirer/module/decode/passport/PassportDecoderState.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2023 Dennis Sheirer
+ * Copyright (C) 2014-2024 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
@@ -327,22 +327,7 @@ public void reset()
}
@Override
- public void start()
- {
-
- }
-
- @Override
- public void stop()
- {
-
- }
-
- @Override
- public void init()
- {
-
- }
+ public void init() {}
protected void resetState()
{
diff --git a/src/main/java/io/github/dsheirer/module/decode/tait/Tait1200DecoderState.java b/src/main/java/io/github/dsheirer/module/decode/tait/Tait1200DecoderState.java
index 6bdddec04..dedfb343c 100644
--- a/src/main/java/io/github/dsheirer/module/decode/tait/Tait1200DecoderState.java
+++ b/src/main/java/io/github/dsheirer/module/decode/tait/Tait1200DecoderState.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2023 Dennis Sheirer
+ * Copyright (C) 2014-2024 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
@@ -58,22 +58,7 @@ public void reset()
}
@Override
- public void start()
- {
-
- }
-
- @Override
- public void stop()
- {
-
- }
-
- @Override
- public void init()
- {
-
- }
+ public void init() {}
@Override
public void receive(IMessage message)
diff --git a/src/main/java/io/github/dsheirer/util/Dispatcher.java b/src/main/java/io/github/dsheirer/util/Dispatcher.java
index f26cb783d..295984ac9 100644
--- a/src/main/java/io/github/dsheirer/util/Dispatcher.java
+++ b/src/main/java/io/github/dsheirer/util/Dispatcher.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2023 Dennis Sheirer
+ * Copyright (C) 2014-2024 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
@@ -106,7 +106,9 @@ public void start()
{
if(mScheduledFuture != null)
{
- mScheduledFuture.cancel(true);
+ //Note: this has to be false because downstream implementations may have acquired locks and they must
+ //be able to release those locks or we'll get a deadlock situation.
+ mScheduledFuture.cancel(false);
}
if(mExecutorService != null)
@@ -132,7 +134,9 @@ public void stop()
{
if(mScheduledFuture != null)
{
- mScheduledFuture.cancel(true);
+ //Note: this has to be false because downstream implementations may have acquired locks and they must
+ //be able to release those locks or we'll get a deadlock situation.
+ mScheduledFuture.cancel(false);
mScheduledFuture = null;
mQueue.clear();
}