diff --git a/src/alias/AliasList.java b/src/alias/AliasList.java index 8b5a6ff8..cc1c4662 100644 --- a/src/alias/AliasList.java +++ b/src/alias/AliasList.java @@ -218,7 +218,7 @@ public class AliasList implements Listener //We don't maintain lookups for these items break; default: - mLog.warn("Unrecognized Alias ID Type:" + id.getType().name()); + mLog.warn("Unrecognized Alias ID Type:" + id.getType().name() + " - can't ADD to lookup table"); break; } } @@ -358,10 +358,11 @@ public class AliasList implements Listener break; case NON_RECORDABLE: case PRIORITY: + case BROADCAST_CHANNEL: //We don't maintain lookups for these items break; default: - mLog.warn("Unrecognized Alias ID Type:" + id.getType().name()); + mLog.warn("Unrecognized Alias ID Type:" + id.getType().name() + " - can't REMOVE from lookup table"); break; } } diff --git a/src/alias/PatchGroupAlias.java b/src/alias/PatchGroupAlias.java index 6d5ddaa1..a83a6fd7 100644 --- a/src/alias/PatchGroupAlias.java +++ b/src/alias/PatchGroupAlias.java @@ -30,7 +30,9 @@ import java.util.List; public class PatchGroupAlias extends Alias { + private Alias mPatchGroupAlias; private List mPatchedAliases = new ArrayList<>(); + private List mPatchedTalkgroupIDs = new ArrayList<>(); /** * Patch group alias is a single alias for a group of aliases that are temporarily patched together. This will @@ -38,13 +40,37 @@ public class PatchGroupAlias extends Alias * temporarily joined to form a patch group. * * Alias properties such as recordable, streamable and call priority are an aggregation from the set of patched - * aliases contained in this patch group alias and where applicable, return the highest value/priority from the - * group of patched aliases. + * aliases contained in this patch group alias and the patch group ID alias and where applicable, return the highest + * value/priority from the group of patched aliases. */ public PatchGroupAlias() { } + /** + * Sets an alias for this patch group ID + */ + public void setPatchGroupAlias(Alias alias) + { + mPatchGroupAlias = alias; + } + + /** + * Alias for this patch group + */ + public Alias getPatchGroupAlias() + { + return mPatchGroupAlias; + } + + /** + * Indicates if this patch group has an alias + */ + public boolean hasPatchGroupAlias() + { + return mPatchGroupAlias != null; + } + /** * List of patched aliases contained in this patch group */ @@ -66,6 +92,11 @@ public class PatchGroupAlias extends Alias */ public void addPatchedAlias(Alias alias) { + if(alias == PatchGroupAlias.this) + { + throw new IllegalArgumentException("Can't add patch group alias to itself - would create an infinite loop"); + } + mPatchedAliases.add(alias); } @@ -77,16 +108,39 @@ public class PatchGroupAlias extends Alias mPatchedAliases.remove(alias); } + /** + * Sets the list of patched talkgroup IDs for this patch group + */ + public void setPatchedTalkgroupIDs(List talkgroupIDs) + { + mPatchedTalkgroupIDs = talkgroupIDs; + } + + /** + * List of patched talkgroup IDs for this patch group + */ + public List getPatchedTalkgroupIDs() + { + return mPatchedTalkgroupIDs; + } + @Override public String getName() { - if(getId().size() > 0) + if(hasPatchGroupAlias()) { - for(AliasID id: getId()) + return getPatchGroupAlias().getName(); + } + else + { + if(getId().size() > 0) { - if(id.getType() == AliasIDType.TALKGROUP) + for(AliasID id: getId()) { - return "PATCH:" + ((TalkgroupID)id).getTalkgroup(); + if(id.getType() == AliasIDType.TALKGROUP) + { + return "PATCH:" + ((TalkgroupID)id).getTalkgroup(); + } } } } @@ -104,6 +158,11 @@ public class PatchGroupAlias extends Alias aliasActions.addAll(alias.getAction()); } + if(hasPatchGroupAlias()) + { + aliasActions.addAll(getPatchGroupAlias().getAction()); + } + return aliasActions; } @@ -118,13 +177,13 @@ public class PatchGroupAlias extends Alias } } - return false; + return hasPatchGroupAlias() && getPatchGroupAlias().hasActions(); } @Override public int getCallPriority() { - int highestPriority = Priority.DEFAULT_PRIORITY; + int highestPriority = (hasPatchGroupAlias() ? getPatchGroupAlias().getCallPriority() : Priority.DEFAULT_PRIORITY); for(Alias alias: mPatchedAliases) { @@ -140,6 +199,11 @@ public class PatchGroupAlias extends Alias @Override public boolean hasCallPriority() { + if(hasPatchGroupAlias() && getPatchGroupAlias().hasCallPriority()) + { + return true; + } + for(Alias alias: mPatchedAliases) { if(alias.hasCallPriority()) @@ -154,6 +218,11 @@ public class PatchGroupAlias extends Alias @Override public boolean isRecordable() { + if(hasPatchGroupAlias() && getPatchGroupAlias().isRecordable()) + { + return true; + } + for(Alias alias: mPatchedAliases) { if(alias.isRecordable()) @@ -168,6 +237,11 @@ public class PatchGroupAlias extends Alias @Override public boolean isStreamable() { + if(hasPatchGroupAlias() && getPatchGroupAlias().isStreamable()) + { + return true; + } + for(Alias alias: mPatchedAliases) { if(alias.isStreamable()) @@ -184,6 +258,11 @@ public class PatchGroupAlias extends Alias { List broadcastChannels = new ArrayList<>(); + if(hasPatchGroupAlias()) + { + broadcastChannels.addAll(getPatchGroupAlias().getBroadcastChannels()); + } + for(Alias alias: mPatchedAliases) { for(BroadcastChannel broadcastChannel: alias.getBroadcastChannels()) @@ -201,6 +280,11 @@ public class PatchGroupAlias extends Alias @Override public boolean hasBroadcastChannel(String channel) { + if(hasPatchGroupAlias() && getPatchGroupAlias().hasBroadcastChannel(channel)) + { + return true; + } + for(Alias alias: mPatchedAliases) { if(alias.hasBroadcastChannel(channel)) diff --git a/src/module/decode/p25/P25DecoderState.java b/src/module/decode/p25/P25DecoderState.java index c597f598..0b17c870 100644 --- a/src/module/decode/p25/P25DecoderState.java +++ b/src/module/decode/p25/P25DecoderState.java @@ -2719,11 +2719,11 @@ public class P25DecoderState extends DecoderState switch(((MotorolaTSBKMessage) tsbk).getMotorolaOpcode()) { case PATCH_GROUP_CHANNEL_GRANT: - PatchGroupVoiceChannelGrant gvcg = (PatchGroupVoiceChannelGrant) tsbk; + PatchGroupVoiceChannelGrant pgvcg = (PatchGroupVoiceChannelGrant) tsbk; - channel = gvcg.getChannel(); - from = gvcg.getSourceAddress(); - to = gvcg.getPatchGroupAddress(); + channel = pgvcg.getChannel(); + from = pgvcg.getSourceAddress(); + to = pgvcg.getPatchGroupAddress(); if(hasCallEvent(channel, from, to)) { @@ -2734,10 +2734,10 @@ public class P25DecoderState extends DecoderState P25CallEvent event = new P25CallEvent.Builder(CallEventType.PATCH_GROUP_CALL) .aliasList(getAliasList()) .channel(channel) - .details((gvcg.isEncrypted() ? "ENCRYPTED " : "") + - (gvcg.isEmergency() ? " EMERGENCY " : "") + - "PATCH SESSION MODE:" + gvcg.getSessionMode().name()) - .frequency(gvcg.getDownlinkFrequency()) + .details((pgvcg.isEncrypted() ? "ENCRYPTED " : "") + + (pgvcg.isEmergency() ? " EMERGENCY " : "") + + "PATCH SESSION MODE:" + pgvcg.getSessionMode().name()) + .frequency(pgvcg.getDownlinkFrequency()) .from(from) .to(to) .build(); @@ -2845,6 +2845,13 @@ public class P25DecoderState extends DecoderState for(String talkgroupToAdd: talkgroupsToAdd) { + //Exclude the patch group ID if it is included in the patched talkgroup list so that we don't have + //an infinite loop situation + if(talkgroupToAdd.equals(patchGroupID)) + { + continue; + } + if(!patchedTalkgroups.contains(talkgroupToAdd)) { patchedTalkgroups.add(talkgroupToAdd); @@ -2906,7 +2913,9 @@ public class P25DecoderState extends DecoderState } /** - * Adds/updates a patch group alias to the alias list containing aliases for each of the patched talkgroups + * Adds/updates a patch group alias to the alias list containing aliases for each of the patched talkgroups. If the + * patch group alias already exists, any patched talkgroups will be removed from the existing patch group alias and + * replaced with the aliases corresponding to the patched talkgroup aliases. * * @param patchGroupID for the patch group * @param patchedTalkgroups containing the talkgroup IDs for each of the patched talkgroups @@ -2916,25 +2925,32 @@ public class P25DecoderState extends DecoderState PatchGroupAlias patchGroupAlias = null; //Check for an existing alias for the patch talkgroup - Alias alias = getAliasList().getTalkgroupAlias(patchGroupID); + Alias existingAlias = getAliasList().getTalkgroupAlias(patchGroupID); - if(alias instanceof PatchGroupAlias) + if(existingAlias instanceof PatchGroupAlias) { - patchGroupAlias = (PatchGroupAlias)alias; - } - else if(alias != null) - { - //If the talkgroup is already aliased to a non-patch group, do nothing + patchGroupAlias = (PatchGroupAlias)existingAlias; } else { patchGroupAlias = new PatchGroupAlias(); + + if(existingAlias != null) + { + getAliasList().removeAlias(existingAlias); + + patchGroupAlias.setPatchGroupAlias(existingAlias); + } + patchGroupAlias.addAliasID(new TalkgroupID(patchGroupID)); + getAliasList().addAlias(patchGroupAlias); } if(patchGroupAlias != null) { + patchGroupAlias.setPatchedTalkgroupIDs(patchedTalkgroups); + patchGroupAlias.clearPatchedAliases(); for(String patchedTalkgroup: patchedTalkgroups) @@ -2958,7 +2974,15 @@ public class P25DecoderState extends DecoderState if(alias instanceof PatchGroupAlias) { - getAliasList().removeAlias(alias); + PatchGroupAlias patchGroupAlias = (PatchGroupAlias)alias; + + getAliasList().removeAlias(patchGroupAlias); + + //Replace our temporary patch group alias with the original alias for the patch group ID + if(patchGroupAlias.hasPatchGroupAlias()) + { + getAliasList().addAlias(patchGroupAlias.getPatchGroupAlias()); + } } }