P25 and Airspy work in progress

Updated p25 decoder state to better track calls and call detects from
a trunked channel

Fixed issue with false detects on LDU2 encrypted call messages

Fixed Airspy channel allocation ... will allocate channels across the
entire bandwidth, minus 50 kHz on either end, and will not adjust the
center frequency if it's not needed.

Fixed traffic channel teardown -- traffic channels are immediately 
removed now, without a fade delay.

AudioMetadata - updated flag is now reset upon copying the metadata
This commit is contained in:
denny
2015-11-21 17:40:59 -05:00
parent a6c7c4f5d1
commit 4025f88951
11 changed files with 629 additions and 241 deletions

View File

@@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
@@ -177,6 +178,7 @@ public class P25DecoderState extends DecoderState
private P25CallEvent mCurrentCallEvent;
private List<String> mCallDetectTalkgroups = new ArrayList<>();
private Map<String,P25CallEvent> mChannelCallMap = new HashMap<>();
public P25DecoderState( AliasList aliasList,
ChannelType channelType,
@@ -256,6 +258,90 @@ public class P25DecoderState extends DecoderState
{
}
/**
* Indicates if there a call event exists for the specified channel and
* from and to talkgroup identifiers.
*
* @param channel - channel number
* @param from user id
* @param to talkgroup or user id
* @param time current in millis
* @return true if there is a call event
*/
public boolean hasCallEvent( String channel, String from, String to )
{
boolean hasEvent = false;
if( mChannelCallMap.containsKey( channel ) )
{
P25CallEvent event = mChannelCallMap.get( channel );
if( to != null &&
event.getToID() != null &&
to.contentEquals( event.getToID() ) )
{
if( from != null )
{
if( event.getFromID() == null )
{
hasEvent = true;
}
else if( from.contentEquals( event.getFromID() ) )
{
hasEvent = true;
}
}
else if( event.getFromID() == null )
{
hasEvent = true;
}
}
}
return hasEvent;
}
/**
* Adds the channel and event to the current channel call map. If an entry
* already exists, terminates the event and broadcasts the update.
*
* @param channel for the call
* @param event to place in the map
*/
public void registerCallEvent( P25CallEvent event )
{
if( mChannelCallMap.containsKey( event.getChannel() ) )
{
P25CallEvent previousEvent = mChannelCallMap.remove( event.getChannel() );
previousEvent.end();
broadcast( previousEvent );
}
mChannelCallMap.put( event.getChannel(), event );
}
public void updateCallEvent( String channel, String from, String to )
{
P25CallEvent event = mChannelCallMap.get( channel );
if( event != null &&
to != null &&
event.getToID() != null &&
event.getToID().contentEquals( to ) )
{
if( event.getFromID() == null &&
from != null &&
!from.contentEquals( "0000" ) &&
!from.contentEquals( "000000" ) )
{
event.setFromID( from );
broadcast( event );
}
}
}
/**
* Primary message processing method.
*/
@@ -1937,12 +2023,10 @@ public class P25DecoderState extends DecoderState
TelephoneInterconnectChannelGrantExplicit ticge =
(TelephoneInterconnectChannelGrantExplicit)pdu;
CallEvent callEvent = new P25CallEvent.Builder( CallEventType.CALL )
CallEvent callEvent = new P25CallEvent.Builder( CallEventType.TELEPHONE_INTERCONNECT )
.aliasList( getAliasList() )
.channel( ticge.getTransmitChannel() )
.details( "Trigger: PDU-TEL_INT_V_CH_GRNT " +
"TELEPHONE CALL " +
( ticge.isEncrypted() ? "ENCRYPTED" : "" ) +
.details( ( ticge.isEncrypted() ? "ENCRYPTED" : "" ) +
( ticge.isEmergency() ? " EMERGENCY" : "") +
" CALL TIMER:" + ticge.getCallTimer() )
.frequency( ticge.getDownlinkFrequency() )
@@ -2017,11 +2101,10 @@ public class P25DecoderState extends DecoderState
UnitToUnitVoiceChannelGrantExtended uuvcge =
(UnitToUnitVoiceChannelGrantExtended)pdu;
CallEvent uuCallEvent = new P25CallEvent.Builder( CallEventType.CALL )
CallEvent uuCallEvent = new P25CallEvent.Builder( CallEventType.UNIT_TO_UNIT_CALL )
.aliasList( getAliasList() )
.channel( uuvcge.getTransmitChannel() )
.details( "Trigger:PDU-U2U_V-CH_GRNT " +
( uuvcge.isEncrypted() ? "ENCRYPTED" : "" ) +
.details( ( uuvcge.isEncrypted() ? "ENCRYPTED" : "" ) +
( uuvcge.isEmergency() ? " EMERGENCY" : "") )
.frequency( uuvcge.getDownlinkFrequency() )
.from( uuvcge.getSourceWACN() + "-" +
@@ -2043,11 +2126,10 @@ public class P25DecoderState extends DecoderState
UnitToUnitVoiceChannelGrantUpdateExtended uuvcgue =
(UnitToUnitVoiceChannelGrantUpdateExtended)pdu;
broadcast( new P25CallEvent.Builder( CallEventType.CALL )
broadcast( new P25CallEvent.Builder( CallEventType.UNIT_TO_UNIT_CALL )
.aliasList( getAliasList() )
.channel( uuvcgue.getTransmitChannel() )
.details( "Trigger: PDU-U2U_V_CH_G_U " +
( uuvcgue.isEncrypted() ? "ENCRYPTED" : "" ) +
.details( ( uuvcgue.isEncrypted() ? "ENCRYPTED" : "" ) +
( uuvcgue.isEmergency() ? " EMERGENCY" : "") )
.frequency( uuvcgue.getDownlinkFrequency() )
.from( uuvcgue.getSourceWACN() + "-" +
@@ -2479,178 +2561,362 @@ public class P25DecoderState extends DecoderState
*/
private void processTSBKChannelGrant( TSBKMessage message )
{
P25CallEvent event = null;
String channel = null;
String from = null;
String to = null;
switch( message.getOpcode() )
{
case GROUP_DATA_CHANNEL_GRANT:
GroupDataChannelGrant gdcg = (GroupDataChannelGrant)message;
event = new P25CallEvent.Builder( CallEventType.DATA_CALL )
.aliasList( getAliasList() )
.channel( gdcg.getChannel() )
.details( ( gdcg.isEncrypted() ? "ENCRYPTED" : "" ) +
( gdcg.isEmergency() ? " EMERGENCY" : "") )
.frequency( gdcg.getDownlinkFrequency() )
.from( gdcg.getSourceAddress() )
.to( gdcg.getGroupAddress() )
.build();
channel = gdcg.getChannel();
from = gdcg.getSourceAddress();
to = gdcg.getGroupAddress();
if( hasCallEvent( channel, from, to ) )
{
updateCallEvent( channel, from, to );
}
else
{
P25CallEvent event = new P25CallEvent.Builder( CallEventType.DATA_CALL )
.aliasList( getAliasList() )
.channel( channel )
.details( ( gdcg.isEncrypted() ? "ENCRYPTED" : "" ) +
( gdcg.isEmergency() ? " EMERGENCY" : "") )
.frequency( gdcg.getDownlinkFrequency() )
.from( from )
.to( to )
.build();
registerCallEvent( event );
broadcast( event );
}
/* We don't allocate traffic channels for data */
break;
case GROUP_VOICE_CHANNEL_GRANT:
GroupVoiceChannelGrant gvcg = (GroupVoiceChannelGrant)message;
event = new P25CallEvent.Builder( CallEventType.GROUP_CALL )
.aliasList( getAliasList() )
.channel( gvcg.getChannel() )
.details( "Trigger: TSBK-G_V_CH_GRNT " +
( gvcg.isEncrypted() ? "ENCRYPTED" : "" ) +
( gvcg.isEmergency() ? " EMERGENCY" : "") )
.frequency( gvcg.getDownlinkFrequency() )
.from( gvcg.getSourceAddress() )
.to( gvcg.getGroupAddress() )
.build();
channel = gvcg.getChannel();
from = gvcg.getSourceAddress();
to = gvcg.getGroupAddress();
if( hasCallEvent( channel, from, to ) )
{
updateCallEvent( channel, from, to );
}
else
{
P25CallEvent event = new P25CallEvent.Builder( CallEventType.GROUP_CALL )
.aliasList( getAliasList() )
.channel( channel )
.details( ( gvcg.isEncrypted() ? "ENCRYPTED" : "" ) +
( gvcg.isEmergency() ? " EMERGENCY" : "") )
.frequency( gvcg.getDownlinkFrequency() )
.from( from )
.to( to )
.build();
registerCallEvent( event );
broadcast( event );
}
broadcast( new TrafficChannelAllocationEvent( this,
mChannelCallMap.get( channel ) ) );
break;
case GROUP_VOICE_CHANNEL_GRANT_UPDATE:
GroupVoiceChannelGrantUpdate gvcgu =
(GroupVoiceChannelGrantUpdate)message;
channel = gvcgu.getChannel1();
from = null;
to = gvcgu.getGroupAddress1();
event = new P25CallEvent.Builder( CallEventType.GROUP_CALL )
.aliasList( getAliasList() )
.channel( gvcgu.getChannel1() )
.details( "Trigger: TSBK-G_V_CH_GRNT_UP " +
( gvcgu.isEncrypted() ? "ENCRYPTED" : "" ) +
( gvcgu.isEmergency() ? " EMERGENCY" : "") )
.frequency( gvcgu.getDownlinkFrequency1() )
.to( gvcgu.getGroupAddress1() )
.build();
if( hasCallEvent( channel, from, to ) )
{
updateCallEvent( channel, from, to );
}
else
{
P25CallEvent event = new P25CallEvent.Builder( CallEventType.GROUP_CALL )
.aliasList( getAliasList() )
.channel( channel )
.channel( gvcgu.getChannel1() )
.details( ( gvcgu.isEncrypted() ? "ENCRYPTED" : "" ) +
( gvcgu.isEmergency() ? " EMERGENCY" : "") )
.frequency( gvcgu.getDownlinkFrequency1() )
.from( from )
.to( to )
.build();
registerCallEvent( event );
broadcast( event );
}
broadcast( new TrafficChannelAllocationEvent( this,
mChannelCallMap.get( channel ) ) );
if( gvcgu.hasChannelNumber2() )
{
/* We handle this channel grant independent of the first event */
P25CallEvent event2 = new P25CallEvent.Builder( CallEventType.GROUP_CALL )
.aliasList( getAliasList() )
.channel( gvcgu.getChannel2() )
.details( "Trigger: TSBK-G_V_CH_GRNT_UP#2 " +
( gvcgu.isEncrypted() ? "ENCRYPTED" : "" ) +
( gvcgu.isEmergency() ? " EMERGENCY" : "") )
.frequency( gvcgu.getDownlinkFrequency2() )
.to( gvcgu.getGroupAddress2() )
.build();
broadcast( new TrafficChannelAllocationEvent( this, event2 ) );
channel = gvcgu.getChannel2();
to = gvcgu.getGroupAddress2();
if( hasCallEvent( channel, from, to ) )
{
updateCallEvent( channel, from, to );
}
else
{
P25CallEvent event2 = new P25CallEvent.Builder( CallEventType.GROUP_CALL )
.aliasList( getAliasList() )
.channel( gvcgu.getChannel2() )
.details( ( gvcgu.isEncrypted() ? "ENCRYPTED" : "" ) +
( gvcgu.isEmergency() ? " EMERGENCY" : "") )
.frequency( gvcgu.getDownlinkFrequency2() )
.to( gvcgu.getGroupAddress2() )
.build();
registerCallEvent( event2 );
broadcast( event2 );
}
broadcast( new TrafficChannelAllocationEvent( this,
mChannelCallMap.get( channel ) ) );
}
break;
case GROUP_VOICE_CHANNEL_GRANT_UPDATE_EXPLICIT:
GroupVoiceChannelGrantUpdateExplicit gvcgue =
(GroupVoiceChannelGrantUpdateExplicit)message;
event = new P25CallEvent.Builder( CallEventType.GROUP_CALL )
.aliasList( getAliasList() )
.channel( gvcgue.getTransmitChannelIdentifier() + "-" +
gvcgue.getTransmitChannelNumber() )
.details( "Trigger: TSBK-G_V_CH_GRNT_U_E " +
( gvcgue.isEncrypted() ? "ENCRYPTED" : "" ) +
( gvcgue.isEmergency() ? " EMERGENCY" : "") )
.frequency( gvcgue.getDownlinkFrequency() )
.to( gvcgue.getGroupAddress() )
.build();
channel = gvcgue.getTransmitChannelIdentifier() + "-" +
gvcgue.getTransmitChannelNumber();
from = null;
to = gvcgue.getGroupAddress();
if( hasCallEvent( channel, from, to ) )
{
updateCallEvent( channel, from, to );
}
else
{
P25CallEvent event = new P25CallEvent.Builder( CallEventType.GROUP_CALL )
.aliasList( getAliasList() )
.channel( channel )
.details( ( gvcgue.isEncrypted() ? "ENCRYPTED" : "" ) +
( gvcgue.isEmergency() ? " EMERGENCY" : "") )
.frequency( gvcgue.getDownlinkFrequency() )
.from( from )
.to( to )
.build();
registerCallEvent( event );
broadcast( event );
}
broadcast( new TrafficChannelAllocationEvent( this,
mChannelCallMap.get( channel ) ) );
break;
case INDIVIDUAL_DATA_CHANNEL_GRANT:
IndividualDataChannelGrant idcg = (IndividualDataChannelGrant)message;
event = new P25CallEvent.Builder( CallEventType.DATA_CALL )
.aliasList( getAliasList() )
.channel( idcg.getChannel() )
.details( "Trigger: TSBK-IND_D_CH_GRNT " +
( idcg.isEncrypted() ? "ENCRYPTED" : "" ) +
( idcg.isEmergency() ? " EMERGENCY" : "") )
.frequency( idcg.getDownlinkFrequency() )
.from( idcg.getSourceAddress() )
.to( idcg.getTargetAddress() )
.build();
channel = idcg.getChannel();
from = idcg.getSourceAddress();
to = idcg.getTargetAddress();
if( hasCallEvent( channel, from, to ) )
{
updateCallEvent( channel, from, to );
}
else
{
P25CallEvent event = new P25CallEvent.Builder( CallEventType.DATA_CALL )
.aliasList( getAliasList() )
.channel( channel )
.details( ( idcg.isEncrypted() ? "ENCRYPTED" : "" ) +
( idcg.isEmergency() ? " EMERGENCY" : "") )
.frequency( idcg.getDownlinkFrequency() )
.from( from )
.to( to )
.build();
registerCallEvent( event );
broadcast( event );
}
/* We don't allocate a traffic channel for data */
break;
case SNDCP_DATA_CHANNEL_GRANT:
SNDCPDataChannelGrant sdcg = (SNDCPDataChannelGrant)message;
event = new P25CallEvent.Builder( CallEventType.DATA_CALL )
.aliasList( getAliasList() )
.channel( sdcg.getTransmitChannel() )
.details( "Trigger: TSBK-SN_D_CH_GRNT " +
"SNDCP DATA NSAPI:" + sdcg.getNSAPI() )
.frequency( sdcg.getDownlinkFrequency() )
.to( sdcg.getTargetAddress() )
.build();
channel = sdcg.getTransmitChannel();
from = null;
to = sdcg.getTargetAddress();
if( hasCallEvent( channel, from, to ) )
{
updateCallEvent( channel, from, to );
}
else
{
P25CallEvent event = new P25CallEvent.Builder( CallEventType.DATA_CALL )
.aliasList( getAliasList() )
.channel( channel )
.details( ( sdcg.isEncrypted() ? "ENCRYPTED" : "" ) +
( sdcg.isEmergency() ? " EMERGENCY" : "") )
.frequency( sdcg.getDownlinkFrequency() )
.from( from )
.to( to )
.build();
registerCallEvent( event );
broadcast( event );
}
/* We don't allocate a traffic channel for data */
break;
case TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT:
TelephoneInterconnectVoiceChannelGrant tivcg =
(TelephoneInterconnectVoiceChannelGrant)message;
event = new P25CallEvent.Builder( CallEventType.TELEPHONE_INTERCONNECT )
.aliasList( getAliasList() )
.channel( tivcg.getChannel() )
.details( "Trigger: TSBK-T_INT_V_CH_GRNT " +
( tivcg.isEncrypted() ? "ENCRYPTED" : "" ) +
( tivcg.isEmergency() ? " EMERGENCY" : "") +
" CALL TIMER:" + tivcg.getCallTimer() )
.frequency( tivcg.getDownlinkFrequency() )
.from( tivcg.getAddress() )
.build();
channel = tivcg.getChannel();
from = null;
/* Address is ambiguous and could mean either source or target,
* so we'll place the value in the to field */
to = tivcg.getAddress();
if( hasCallEvent( channel, from, to ) )
{
updateCallEvent( channel, from, to );
}
else
{
P25CallEvent event = new P25CallEvent.Builder(
CallEventType.TELEPHONE_INTERCONNECT )
.aliasList( getAliasList() )
.channel( channel )
.details( ( tivcg.isEncrypted() ? "ENCRYPTED " : "" ) +
( tivcg.isEmergency() ? "EMERGENCY " : "") +
"CALL TIMER:" + tivcg.getCallTimer() )
.frequency( tivcg.getDownlinkFrequency() )
.from( from )
.to( to )
.build();
registerCallEvent( event );
broadcast( event );
}
broadcast( new TrafficChannelAllocationEvent( this,
mChannelCallMap.get( channel ) ) );
break;
case TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT_UPDATE:
TelephoneInterconnectVoiceChannelGrantUpdate tivcgu =
(TelephoneInterconnectVoiceChannelGrantUpdate)message;
event = new P25CallEvent.Builder( CallEventType.TELEPHONE_INTERCONNECT )
.aliasList( getAliasList() )
.channel( tivcgu.getChannelIdentifier() + "-" +
tivcgu.getChannelNumber() )
.details( "Trigger: TSBK-T_INT_V_CH_G_UP " +
( tivcgu.isEncrypted() ? "ENCRYPTED" : "" ) +
( tivcgu.isEmergency() ? " EMERGENCY" : "") )
.frequency( tivcgu.getDownlinkFrequency() )
.from( tivcgu.getAddress() )
.build();
channel = tivcgu.getChannelIdentifier() + "-" +
tivcgu.getChannelNumber();
from = null;
/* Address is ambiguous and could mean either source or target,
* so we'll place the value in the to field */
to = tivcgu.getAddress();
if( hasCallEvent( channel, from, to ) )
{
updateCallEvent( channel, from, to );
}
else
{
P25CallEvent event = new P25CallEvent.Builder(
CallEventType.TELEPHONE_INTERCONNECT )
.aliasList( getAliasList() )
.channel( channel )
.details( ( tivcgu.isEncrypted() ? "ENCRYPTED " : "" ) +
( tivcgu.isEmergency() ? "EMERGENCY " : "") +
"CALL TIMER:" + tivcgu.getCallTimer() )
.frequency( tivcgu.getDownlinkFrequency() )
.from( from )
.to( to )
.build();
registerCallEvent( event );
broadcast( event );
}
broadcast( new TrafficChannelAllocationEvent( this,
mChannelCallMap.get( channel ) ) );
break;
case UNIT_TO_UNIT_VOICE_CHANNEL_GRANT:
UnitToUnitVoiceChannelGrant uuvcg =
(UnitToUnitVoiceChannelGrant)message;
channel = uuvcg.getChannelIdentifier() + "-" +
uuvcg.getChannelNumber();
from = uuvcg.getSourceAddress();
to = uuvcg.getTargetAddress();
event = new P25CallEvent.Builder( CallEventType.UNIT_TO_UNIT_CALL )
.aliasList( getAliasList() )
.channel( uuvcg.getChannelIdentifier() + "-" +
uuvcg.getChannelNumber() )
.details( "Trigger: TSBK-U2U_V_CH_GRNT " +
( uuvcg.isEncrypted() ? "ENCRYPTED" : "" ) +
( uuvcg.isEmergency() ? " EMERGENCY" : "") )
.frequency( uuvcg.getDownlinkFrequency() )
.from( uuvcg.getSourceAddress() )
.to( uuvcg.getTargetAddress() )
.build();
if( hasCallEvent( channel, from, to ) )
{
updateCallEvent( channel, from, to );
}
else
{
P25CallEvent event = new P25CallEvent.Builder(
CallEventType.UNIT_TO_UNIT_CALL )
.aliasList( getAliasList() )
.channel( channel )
.details( ( uuvcg.isEncrypted() ? "ENCRYPTED " : "" ) +
( uuvcg.isEmergency() ? "EMERGENCY " : "") )
.frequency( uuvcg.getDownlinkFrequency() )
.from( from )
.to( to )
.build();
registerCallEvent( event );
broadcast( event );
}
broadcast( new TrafficChannelAllocationEvent( this,
mChannelCallMap.get( channel ) ) );
break;
case UNIT_TO_UNIT_VOICE_CHANNEL_GRANT_UPDATE:
UnitToUnitVoiceChannelGrantUpdate uuvcgu =
(UnitToUnitVoiceChannelGrantUpdate)message;
event = new P25CallEvent.Builder( CallEventType.UNIT_TO_UNIT_CALL )
.aliasList( getAliasList() )
.channel( uuvcgu.getChannelIdentifier() + "-" +
uuvcgu.getChannelNumber() )
.details( "Trigger: TSBK-U2U_V_CH_G_UP " +
( uuvcgu.isEncrypted() ? "ENCRYPTED" : "" ) +
( uuvcgu.isEmergency() ? " EMERGENCY" : "") )
.frequency( uuvcgu.getDownlinkFrequency() )
.from( uuvcgu.getSourceAddress() )
.to( uuvcgu.getTargetAddress() )
.build();
channel = uuvcgu.getChannelIdentifier() + "-" +
uuvcgu.getChannelNumber();
from = uuvcgu.getSourceAddress();
to = uuvcgu.getTargetAddress();
if( hasCallEvent( channel, from, to ) )
{
updateCallEvent( channel, from, to );
}
else
{
P25CallEvent event = new P25CallEvent.Builder(
CallEventType.UNIT_TO_UNIT_CALL )
.aliasList( getAliasList() )
.channel( channel )
.details( ( uuvcgu.isEncrypted() ? "ENCRYPTED " : "" ) +
( uuvcgu.isEmergency() ? "EMERGENCY " : "") )
.frequency( uuvcgu.getDownlinkFrequency() )
.from( from )
.to( to )
.build();
registerCallEvent( event );
broadcast( event );
}
broadcast( new TrafficChannelAllocationEvent( this,
mChannelCallMap.get( channel ) ) );
break;
default:
break;
}
if( event != null && event.getCallEventType() != CallEventType.DATA_CALL )
{
broadcast( new TrafficChannelAllocationEvent( this, event ) );
}
}
/**
@@ -2658,38 +2924,35 @@ public class P25DecoderState extends DecoderState
*/
private void updateTo( String to )
{
mLog.debug( "Updating to [" + to + "]" );
if( to != null &&
!to.contentEquals( "0000" ) &&
!to.contentEquals( "000000" ) &&
( mToTalkgroup == null || !mToTalkgroup.contentEquals( to ) ) )
if( to != null && !to.contentEquals( "0000" ) && !to.contentEquals( "000000" ) )
{
mToTalkgroup = to;
broadcast( ChangedAttribute.TO_TALKGROUP );
if( mToTalkgroup == null || !mToTalkgroup.contentEquals( to ) )
{
mToTalkgroup = to;
broadcast( ChangedAttribute.TO_TALKGROUP );
if( mCurrentCallEvent != null &&
( mCurrentCallEvent.getToID() == null ||
!mCurrentCallEvent.getToID().contentEquals( to ) ) )
{
mCurrentCallEvent.setToID( to );
broadcast( mCurrentCallEvent );
}
if( mCurrentCallEvent != null &&
( mCurrentCallEvent.getToID() == null ||
!mCurrentCallEvent.getToID().contentEquals( to ) ) )
{
mCurrentCallEvent.setToID( to );
broadcast( mCurrentCallEvent );
}
if( hasAliasList() )
{
mToAlias = getAliasList().getTalkgroupAlias( mToTalkgroup );
mLog.debug( "To Alias: " + mToAlias );
if( hasAliasList() )
{
mToAlias = getAliasList().getTalkgroupAlias( mToTalkgroup );
}
else
{
mToAlias = null;
}
broadcast( ChangedAttribute.TO_TALKGROUP_ALIAS );
}
else
{
mLog.debug( "To Alias: no alias list" );
mToAlias = null;
}
broadcast( ChangedAttribute.TO_TALKGROUP_ALIAS );
/* Send audio metadata update */
broadcast( new Metadata( MetadataType.TO, to, mToAlias, true ) );
broadcast( new Metadata( MetadataType.TO, mToTalkgroup, mToAlias, true ) );
}
}
@@ -2698,35 +2961,35 @@ public class P25DecoderState extends DecoderState
*/
private void updateFrom( String from )
{
if( from != null &&
!from.contentEquals( "0000" ) &&
!from.contentEquals( "000000" ) &&
( mFromTalkgroup == null || !mFromTalkgroup.contentEquals( from ) ) )
if( from != null && !from.contentEquals( "0000" ) && !from.contentEquals( "000000" ) )
{
mFromTalkgroup = from;
broadcast( ChangedAttribute.FROM_TALKGROUP );
if( mCurrentCallEvent != null &&
mCurrentCallEvent.getFromID() == null ||
!mCurrentCallEvent.getFromID().contentEquals( from ) )
if( mFromTalkgroup == null || !mFromTalkgroup.contentEquals( from ))
{
mCurrentCallEvent.setFromID( from );
broadcast( mCurrentCallEvent );
mFromTalkgroup = from;
broadcast( ChangedAttribute.FROM_TALKGROUP );
if( mCurrentCallEvent != null &&
mCurrentCallEvent.getFromID() == null ||
!mCurrentCallEvent.getFromID().contentEquals( from ) )
{
mCurrentCallEvent.setFromID( from );
broadcast( mCurrentCallEvent );
}
if( hasAliasList() )
{
mFromAlias = getAliasList().getTalkgroupAlias( mFromTalkgroup );
}
else
{
mFromAlias = null;
}
broadcast( ChangedAttribute.FROM_TALKGROUP_ALIAS );
}
if( hasAliasList() )
{
mFromAlias = getAliasList().getTalkgroupAlias( mFromTalkgroup );
}
else
{
mFromAlias = null;
}
broadcast( ChangedAttribute.FROM_TALKGROUP_ALIAS );
/* Send audio metadata update */
broadcast( new Metadata( MetadataType.FROM, from, mFromAlias, true ) );
broadcast( new Metadata( MetadataType.FROM, mFromTalkgroup, mFromAlias, true ) );
}
}