Files
sdrtrunk/src/decode/mpt1327/MPT1327ChannelState.java
dennis.sheirer ad456d81a3 Updated Call Event handling/display for all decoders and updated channel display values for all decoders.
- Call events now show start-stop timestamps.  (or START-In Progress if call is ongoing )
 - Call start/stop events are now on the same event line.
 - Channel panels now display site and/or channel info
 - LTR call events are limited to CALLs on the current LCN, in order to cut down on false call events resulting from noise.
 - Passport display channels now show site/channel.
 - Changed default window used by the DFTProcessor to Cosine, which doesn't have as much FFT bin leakage.
2014-09-15 00:42:20 +00:00

412 lines
11 KiB
Java

/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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 decode.mpt1327;
import message.Message;
import sample.Listener;
import source.config.SourceConfigTuner;
import alias.AliasList;
import audio.SquelchListener;
import audio.SquelchListener.SquelchState;
import controller.activity.CallEvent;
import controller.activity.CallEvent.CallEventType;
import controller.channel.Channel;
import controller.channel.Channel.ChannelType;
import controller.channel.ChannelMap;
import controller.channel.ProcessingChain;
import controller.state.AuxChannelState;
import controller.state.ChannelState;
import decode.config.DecodeConfigMPT1327;
import decode.mpt1327.MPT1327Message.IdentType;
public class MPT1327ChannelState extends ChannelState
{
private int mSite;
private String mFromTalkgroup;
private String mToTalkgroup;
private int mChannelNumber;
private ChannelType mChannelType;
private ChannelMap mChannelMap;
private MPT1327ActivitySummary mActivitySummary;
public MPT1327ChannelState( ProcessingChain processingChain,
AliasList aliasList,
ChannelMap channelMap )
{
super( processingChain, aliasList );
mActivitySummary = new MPT1327ActivitySummary( aliasList );
mChannelMap = channelMap;
mChannelType = processingChain.getChannel().getChannelType();
}
public void dispose()
{
super.dispose();
mActivitySummary.dispose();
mActivitySummary = null;
mCurrentCallEvent = null;
}
public void setCurrentCall( MPT1327CallEvent event )
{
mCurrentCallEvent = event;
}
@Override
public String getActivitySummary()
{
StringBuilder sb = new StringBuilder();
sb.append( mActivitySummary.getSummary() );
for( AuxChannelState state: mAuxChannelStates )
{
sb.append( state.getActivitySummary() );
sb.append( "\n\n" );
}
return sb.toString();
}
@Override
public void receive( Message message )
{
super.receive( message );
if( message instanceof MPT1327Message )
{
mActivitySummary.receive( message );
MPT1327Message mpt = (MPT1327Message)message;
if( mpt.isValid() )
{
switch( mpt.getMessageType() )
{
case ACK:
IdentType identType = ( (MPT1327Message) message ).getIdent1Type();
if( identType == IdentType.REGI )
{
mCallEventModel.add(
new MPT1327CallEvent.Builder( CallEventType.REGISTER )
.aliasList( getProcessingChain().getAliasList() )
.channel( mChannelNumber )
.details( "REGISTERED ON NETWORK" )
.frequency( mChannelMap.getFrequency( mChannelNumber ) )
.from( mpt.getToID() )
.to( mpt.getFromID() )
.build() );
}
else
{
mCallEventModel.add(
new MPT1327CallEvent.Builder( CallEventType.ACKNOWLEDGE )
.aliasList( getProcessingChain().getAliasList() )
.channel( mChannelNumber )
.details( "ACK " + identType.getLabel() )
.frequency( mChannelMap.getFrequency( mChannelNumber ) )
.from( mpt.getFromID() )
.to( mpt.getToID() )
.build() );
}
break;
case AHYC:
mCallEventModel.add(
new MPT1327CallEvent.Builder( CallEventType.REQUEST )
.aliasList( getProcessingChain().getAliasList() )
.channel( mChannelNumber )
.details( ( (MPT1327Message) message ).getRequestString() )
.frequency( mChannelMap.getFrequency( mChannelNumber ) )
.from( mpt.getFromID() )
.to( mpt.getToID() )
.build() );
break;
case AHYQ:
mCallEventModel.add(
new MPT1327CallEvent.Builder( CallEventType.STATUS )
.aliasList( getProcessingChain().getAliasList() )
.channel( mChannelNumber )
.details( mpt.getStatusMessage() )
.frequency( mChannelMap.getFrequency( mChannelNumber ) )
.from( mpt.getFromID() )
.to( mpt.getToID() )
.build() );
break;
case ALH:
int sys = mpt.getSiteID();
if( sys != 0 && sys != mSite )
{
mSite = sys;
broadcastChange( ChangedAttribute.CHANNEL_SITE_NUMBER );
}
setState( State.CONTROL );
break;
case GTC:
if( mpt.isValidCall() )
{
int channelNumber = mpt.getChannel();
if( !getProcessingChain().getChannel()
.hasTrafficChannel( channelNumber ) )
{
String aliasListName = mProcessingChain
.getChannel().getAliasListName();
Channel traffic = getTrafficChannel( channelNumber,
aliasListName );
/* Set the system and site to same as control channel */
traffic.setSystem( getProcessingChain().getChannel()
.getSystem(), false );
traffic.setSite( getProcessingChain().getChannel()
.getSite(), false );
/* Add the traffic channel to the parent control channel */
getProcessingChain().getChannel()
.addTrafficChannel( channelNumber, traffic );
/* Start the traffic channel */
traffic.setEnabled( true );
/* Set traffic channel state info */
MPT1327ChannelState trafficState =
(MPT1327ChannelState)traffic
.getProcessingChain().getChannelState();
MPT1327ChannelState controlState =
(MPT1327ChannelState)getProcessingChain()
.getChannelState();
trafficState.setChannelMap( controlState.getChannelMap() );
trafficState.setChannelNumber( channelNumber );
trafficState.setFromTalkgroup( mpt.getFromID() );
trafficState.setToTalkgroup( mpt.getToID() );
/* Add this control channel as message listener on the
* traffic channel so we can receive call tear-down
* messages */
traffic.addListener( (Listener<Message>)this );
CallEventType type = traffic.isProcessing() ?
CallEventType.CALL :
CallEventType.CALL_NO_TUNER;
/*
* Set the traffic channel's call event model to
* share the control channel's call event model
*/
traffic.getProcessingChain().getChannelState()
.setCallEventModel( mCallEventModel );
MPT1327CallEvent callStartEvent =
new MPT1327CallEvent.Builder( type )
.aliasList( traffic.getProcessingChain().getAliasList() )
.channel( channelNumber )
.frequency( mChannelMap.getFrequency( channelNumber ) )
.from( mpt.getFromID() )
.to( mpt.getToID() )
.build();
traffic.getProcessingChain().getChannelState()
.setCurrentCallEvent( callStartEvent );
mCallEventModel.add( callStartEvent );
}
}
break;
case CLEAR:
case MAINT:
if( mChannelType == ChannelType.TRAFFIC )
{
fade( CallEventType.CALL_END );
}
break;
case HEAD_PLUS1:
case HEAD_PLUS2:
case HEAD_PLUS3:
case HEAD_PLUS4:
mCallEventModel.add(
new MPT1327CallEvent.Builder( CallEventType.SDM )
.aliasList( mAliasList )
.details( mpt.getMessage() )
.from( mpt.getFromID() )
.to( mpt.getToID() )
.build() );
break;
}
}
}
}
/**
* Intercept the fade event so that we can generate a call end event
*/
@Override
public void fade( final CallEventType type )
{
/*
* We can receive multiple call tear-down messages -- only post a call
* end event for the one that can change the state to fade
*/
if( getState().canChangeTo( State.FADE ) )
{
CallEvent current = getCurrentCallEvent();
if( current != null )
{
mCallEventModel.setEnd( current );
}
else
{
mCallEventModel.add(
new MPT1327CallEvent.Builder( type )
.aliasList( getAliasList() )
.channel( mChannelNumber )
.frequency( mChannelMap.getFrequency( mChannelNumber ) )
.from( mFromTalkgroup )
.to( mToTalkgroup )
.build() );
}
setCurrentCall( null );
}
super.fade( type );
}
/**
* Make the ConventionalChannelState always unsquelched
*/
public void addListener( SquelchListener listener )
{
super.addListener( listener );
super.setSquelchState( SquelchState.UNSQUELCH );
}
public void reset()
{
mFromTalkgroup = null;
broadcastChange( ChangedAttribute.FROM_TALKGROUP );
mToTalkgroup = null;
broadcastChange( ChangedAttribute.TO_TALKGROUP );
super.reset();
}
public int getSite()
{
return mSite;
}
public ChannelMap getChannelMap()
{
return mChannelMap;
}
public void setChannelMap( ChannelMap channelMap )
{
mChannelMap = channelMap;
}
public String getFromTalkgroup()
{
return mFromTalkgroup;
}
/**
* Set the talkgroup. This is used primarily for traffic channels since
* the talkgroup will already have been identified prior to the traffic
* channel being created.
*/
public void setFromTalkgroup( String fromTalkgroup )
{
mFromTalkgroup = fromTalkgroup;
broadcastChange( ChangedAttribute.FROM_TALKGROUP );
}
public String getToTalkgroup()
{
return mToTalkgroup;
}
/**
* Set the talkgroup. This is used primarily for traffic channels since
* the talkgroup will already have been identified prior to the traffic
* channel being created.
*/
public void setToTalkgroup( String toTalkgroup )
{
mToTalkgroup = toTalkgroup;
broadcastChange( ChangedAttribute.TO_TALKGROUP );
}
public int getChannelNumber()
{
return mChannelNumber;
}
/**
* Set the channel number. This is used primarily for traffic channels since
* the channel will already have been identified prior to the traffic
* channel being created.
*/
public void setChannelNumber( int channel )
{
mChannelNumber = channel;
broadcastChange( ChangedAttribute.CHANNEL_NUMBER );
}
public String getAliasListName()
{
return mProcessingChain.getChannel().getAliasListName();
}
private Channel getTrafficChannel( int channelNumber, String aliasListName )
{
Channel traffic = new Channel( "Traffic Channel " + channelNumber,
ChannelType.TRAFFIC );
traffic.setResourceManager( getProcessingChain().getResourceManager() );
SourceConfigTuner source = new SourceConfigTuner();
long frequency = mChannelMap.getFrequency( channelNumber );
source.setFrequency( frequency );
traffic.setSourceConfiguration( source );
DecodeConfigMPT1327 decode = new DecodeConfigMPT1327();
traffic.setDecodeConfiguration( decode );
traffic.setAliasListName( aliasListName );
return traffic;
}
}