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(); }