mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 08:37:25 -05:00
* #6 DMR decoder feature - work in progress * #6 DMR Decoder. * #6 DMR Decoder. Code review updates. Co-authored-by: Zhenyu Mao <maozhenyu@foxmail.com> Co-authored-by: Denny <denny@denny-desktop>
This commit is contained in:
@@ -21,12 +21,13 @@
|
||||
*/
|
||||
package io.github.dsheirer.channel.state;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import io.github.dsheirer.alias.AliasModel;
|
||||
import io.github.dsheirer.audio.squelch.SquelchStateEvent;
|
||||
import io.github.dsheirer.channel.metadata.ChannelMetadata;
|
||||
import io.github.dsheirer.channel.state.DecoderStateEvent.Event;
|
||||
import io.github.dsheirer.controller.channel.Channel;
|
||||
import io.github.dsheirer.controller.channel.Channel.ChannelType;
|
||||
import io.github.dsheirer.controller.channel.ChannelConfigurationChangeNotification;
|
||||
import io.github.dsheirer.controller.channel.ChannelEvent;
|
||||
import io.github.dsheirer.identifier.IdentifierClass;
|
||||
import io.github.dsheirer.identifier.IdentifierUpdateListener;
|
||||
@@ -51,7 +52,6 @@ import io.github.dsheirer.source.config.SourceConfigTunerMultipleFrequency;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -97,6 +97,7 @@ public class SingleChannelState extends AbstractChannelState implements IDecoder
|
||||
private ChannelMetadata mChannelMetadata;
|
||||
private StateMachine mStateMachine = new StateMachine(0, State.SINGLE_CHANNEL_ACTIVE_STATES);
|
||||
private StateMonitoringSquelchController mSquelchController = new StateMonitoringSquelchController(0);
|
||||
private DecoderStateNotificationEventCache mStateNotificationCache = new DecoderStateNotificationEventCache();
|
||||
|
||||
public SingleChannelState(Channel channel, AliasModel aliasModel)
|
||||
{
|
||||
@@ -107,10 +108,21 @@ public class SingleChannelState extends AbstractChannelState implements IDecoder
|
||||
|
||||
mStateMachine.addListener(this);
|
||||
mStateMachine.addListener(mSquelchController);
|
||||
mStateMachine.setChannelType(mChannel.getChannelType());
|
||||
mStateMachine.setIdentifierUpdateListener(mIdentifierCollection);
|
||||
mStateMachine.setEndTimeoutBufferMilliseconds(RESET_TIMEOUT_DELAY);
|
||||
if(channel.getChannelType() == ChannelType.STANDARD)
|
||||
|
||||
configureChannelType(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure items according to channel type
|
||||
* @param channel configuration
|
||||
*/
|
||||
private void configureChannelType(Channel channel)
|
||||
{
|
||||
mStateMachine.setChannelType(getChannel().getChannelType());
|
||||
|
||||
if(channel.isStandardChannel())
|
||||
{
|
||||
mStateMachine.setFadeTimeoutBufferMilliseconds(FADE_TIMEOUT_DELAY);
|
||||
}
|
||||
@@ -125,36 +137,38 @@ public class SingleChannelState extends AbstractChannelState implements IDecoder
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive notification that the underlying channel configuration has changed.
|
||||
* @param notification
|
||||
*/
|
||||
@Subscribe
|
||||
public void channelConfigurationChanged(ChannelConfigurationChangeNotification notification)
|
||||
{
|
||||
updateChannelConfiguration(notification.getChannel());
|
||||
configureChannelType(notification.getChannel());
|
||||
createConfigurationIdentifiers(notification.getChannel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateChanged(State state, int timeslot)
|
||||
{
|
||||
//Broadcast current channel state so that channel rotation monitor can track
|
||||
if(State.SINGLE_CHANNEL_ACTIVE_STATES.contains(state))
|
||||
{
|
||||
broadcast(DecoderStateEvent.activeState(timeslot));
|
||||
}
|
||||
else
|
||||
{
|
||||
broadcast(DecoderStateEvent.inactiveState(timeslot));
|
||||
}
|
||||
|
||||
ChannelStateIdentifier stateIdentifier = ChannelStateIdentifier.create(state);
|
||||
ChannelStateIdentifier stateIdentifier = ChannelStateIdentifier.get(state);
|
||||
mIdentifierCollection.update(stateIdentifier);
|
||||
mChannelMetadata.receive(new IdentifierUpdateNotification(stateIdentifier, IdentifierUpdateNotification.Operation.ADD, timeslot));
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case IDLE:
|
||||
broadcast(new DecoderStateEvent(this, Event.RESET, State.IDLE));
|
||||
broadcast(new DecoderStateEvent(this, Event.REQUEST_RESET, State.IDLE));
|
||||
break;
|
||||
case RESET:
|
||||
reset();
|
||||
mStateMachine.setState(State.IDLE);
|
||||
break;
|
||||
case TEARDOWN:
|
||||
if(mChannel.isTrafficChannel())
|
||||
if(getChannel().isTrafficChannel())
|
||||
{
|
||||
broadcast(new ChannelEvent(mChannel, ChannelEvent.Event.REQUEST_DISABLE));
|
||||
broadcast(new ChannelEvent(getChannel(), ChannelEvent.Event.REQUEST_DISABLE));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -258,7 +272,7 @@ public class SingleChannelState extends AbstractChannelState implements IDecoder
|
||||
/**
|
||||
* Channel metadata for this channel.
|
||||
*/
|
||||
public Collection<ChannelMetadata> getChannelMetadata()
|
||||
public List<ChannelMetadata> getChannelMetadata()
|
||||
{
|
||||
return Collections.singletonList(mChannelMetadata);
|
||||
}
|
||||
@@ -270,7 +284,7 @@ public class SingleChannelState extends AbstractChannelState implements IDecoder
|
||||
public void reset()
|
||||
{
|
||||
mStateMachine.setState(State.RESET);
|
||||
broadcast(new DecoderStateEvent(this, Event.RESET, State.IDLE));
|
||||
broadcast(new DecoderStateEvent(this, Event.REQUEST_RESET, State.IDLE));
|
||||
mIdentifierCollection.remove(IdentifierClass.USER);
|
||||
sourceOverflow(false);
|
||||
}
|
||||
@@ -280,7 +294,7 @@ public class SingleChannelState extends AbstractChannelState implements IDecoder
|
||||
{
|
||||
mIdentifierCollection.broadcastIdentifiers();
|
||||
|
||||
if(mChannel.getChannelType() == ChannelType.TRAFFIC)
|
||||
if(getChannel().isTrafficChannel())
|
||||
{
|
||||
mStateMachine.setState(State.ACTIVE);
|
||||
}
|
||||
@@ -292,12 +306,6 @@ public class SingleChannelState extends AbstractChannelState implements IDecoder
|
||||
mSquelchController.setSquelchLock(false);
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
mDecodeEventListener = null;
|
||||
mDecoderStateListener = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Listener<SourceEvent> getSourceEventListener()
|
||||
{
|
||||
@@ -372,7 +380,7 @@ public class SingleChannelState extends AbstractChannelState implements IDecoder
|
||||
case NOTIFICATION_FREQUENCY_CHANGE:
|
||||
//Rebroadcast source frequency change events for the decoder(s) to process
|
||||
long frequency = sourceEvent.getValue().longValue();
|
||||
broadcast(new DecoderStateEvent(this, Event.SOURCE_FREQUENCY, mStateMachine.getState(), frequency));
|
||||
broadcast(new DecoderStateEvent(this, Event.NOTIFICATION_SOURCE_FREQUENCY, mStateMachine.getState(), frequency));
|
||||
|
||||
//Create a new frequency configuration identifier so that downstream consumers receive the change
|
||||
//via channel metadata and audio packet updates - this is a silent add that is sent as a notification
|
||||
@@ -386,7 +394,7 @@ public class SingleChannelState extends AbstractChannelState implements IDecoder
|
||||
if(State.SINGLE_CHANNEL_ACTIVE_STATES.contains(mStateMachine.getState()))
|
||||
{
|
||||
broadcast(SourceEvent.frequencyErrorMeasurementSyncLocked(sourceEvent.getValue().longValue(),
|
||||
mChannel.getChannelType().name()));
|
||||
getChannel().getChannelType().name()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -405,10 +413,10 @@ public class SingleChannelState extends AbstractChannelState implements IDecoder
|
||||
{
|
||||
switch(event.getEvent())
|
||||
{
|
||||
case ALWAYS_UNSQUELCH:
|
||||
case REQUEST_ALWAYS_UNSQUELCH:
|
||||
mSquelchController.setSquelchLock(true);
|
||||
break;
|
||||
case CHANGE_CALL_TIMEOUT:
|
||||
case REQUEST_CHANGE_CALL_TIMEOUT:
|
||||
if(event instanceof ChangeChannelTimeoutEvent)
|
||||
{
|
||||
ChangeChannelTimeoutEvent timeout = (ChangeChannelTimeoutEvent)event;
|
||||
@@ -420,19 +428,28 @@ public class SingleChannelState extends AbstractChannelState implements IDecoder
|
||||
if(State.SINGLE_CHANNEL_ACTIVE_STATES.contains(event.getState()))
|
||||
{
|
||||
mStateMachine.setState(event.getState());
|
||||
|
||||
//Broadcast state so channel rotation manager can track
|
||||
broadcast(mStateNotificationCache.getStateNotificationEvent(event.getState(), event.getTimeslot()));
|
||||
}
|
||||
break;
|
||||
case END:
|
||||
if(mChannel.isTrafficChannel())
|
||||
if(getChannel().isTrafficChannel())
|
||||
{
|
||||
mStateMachine.setState(State.TEARDOWN);
|
||||
|
||||
//Broadcast state so channel rotation manager can track
|
||||
broadcast(mStateNotificationCache.getStateNotificationEvent(State.TEARDOWN, event.getTimeslot()));
|
||||
}
|
||||
else
|
||||
{
|
||||
mStateMachine.setState(State.FADE);
|
||||
|
||||
//Broadcast state so channel rotation manager can track
|
||||
broadcast(mStateNotificationCache.getStateNotificationEvent(State.FADE, event.getTimeslot()));
|
||||
}
|
||||
break;
|
||||
case RESET:
|
||||
case REQUEST_RESET:
|
||||
/* Channel State does not respond to reset events */
|
||||
break;
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user