diff --git a/src/alias/AliasList.java b/src/alias/AliasList.java index 493e051a..8c9afa98 100644 --- a/src/alias/AliasList.java +++ b/src/alias/AliasList.java @@ -48,16 +48,16 @@ public class AliasList implements Listener public static final String WILDCARD = "*"; public static final String REGEX_WILDCARD = "."; - private Map mESN = new HashMap<>(); - private Map mFleetsync = new HashMap<>(); - private Map mLoJack = new HashMap<>(); - private Map mMDC1200 = new HashMap<>(); - private Map mMobileID = new HashMap<>(); - private Map mMPT1327 = new HashMap<>(); - private Map mSiteID = new HashMap<>(); - private Map mStatus = new HashMap<>(); - private Map mTalkgroup = new HashMap<>(); - private Map mUniqueID = new HashMap<>(); + private Map mESN = new HashMap<>(); + private Map mFleetsync = new HashMap<>(); + private Map mLoJack = new HashMap<>(); + private Map mMDC1200 = new HashMap<>(); + private Map mMobileID = new HashMap<>(); + private Map mMPT1327 = new HashMap<>(); + private Map mSiteID = new HashMap<>(); + private Map mStatus = new HashMap<>(); + private Map mTalkgroup = new HashMap<>(); + private Map mUniqueID = new HashMap<>(); private List mESNWildcards = new ArrayList<>(); private List mMobileIDWildcards = new ArrayList<>(); @@ -124,7 +124,7 @@ public class AliasList implements Listener if(fleetsync != null) { - if (fleetsync.contains(WILDCARD)) + if(fleetsync.contains(WILDCARD)) { mFleetsyncWildcards.add(new WildcardID(fleetsync)); Collections.sort(mFleetsyncWildcards); @@ -137,11 +137,11 @@ public class AliasList implements Listener mLoJack.put((LoJackFunctionAndID) id, alias); break; case MDC1200: - String mdc = ((MDC1200ID)id).getIdent(); + String mdc = ((MDC1200ID) id).getIdent(); if(mdc != null) { - if (mdc.contains(WILDCARD)) + if(mdc.contains(WILDCARD)) { mMDC1200Wildcards.add(new WildcardID(mdc)); Collections.sort(mMDC1200Wildcards); @@ -151,11 +151,11 @@ public class AliasList implements Listener } break; case MPT1327: - String mpt = ((MPT1327ID)id).getIdent(); + String mpt = ((MPT1327ID) id).getIdent(); if(mpt != null) { - if (mpt.contains(WILDCARD)) + if(mpt.contains(WILDCARD)) { mMPT1327Wildcards.add(new WildcardID(mpt)); Collections.sort(mMPT1327Wildcards); @@ -165,11 +165,11 @@ public class AliasList implements Listener } break; case MIN: - String min = ((Min)id).getMin(); + String min = ((Min) id).getMin(); if(min != null) { - if (min.contains(WILDCARD)) + if(min.contains(WILDCARD)) { mMobileIDWildcards.add(new WildcardID(min)); Collections.sort(mMobileIDWildcards); @@ -179,14 +179,14 @@ public class AliasList implements Listener } break; case LTR_NET_UID: - mUniqueID.put(((UniqueID)id).getUid(), alias); + mUniqueID.put(((UniqueID) id).getUid(), alias); break; case SITE: - String siteID = ((SiteID)id).getSite(); + String siteID = ((SiteID) id).getSite(); if(siteID != null) { - if (siteID.contains(WILDCARD)) + if(siteID.contains(WILDCARD)) { mSiteWildcards.add(new WildcardID(siteID)); Collections.sort(mSiteWildcards); @@ -199,11 +199,11 @@ public class AliasList implements Listener mStatus.put(((StatusID) id).getStatus(), alias); break; case TALKGROUP: - String tgid = ((TalkgroupID)id).getTalkgroup(); + String tgid = ((TalkgroupID) id).getTalkgroup(); if(tgid != null) { - if (tgid.contains(WILDCARD)) + if(tgid.contains(WILDCARD)) { mTalkgroupWildcards.add(new WildcardID(tgid)); Collections.sort(mTalkgroupWildcards); @@ -222,7 +222,7 @@ public class AliasList implements Listener break; } } - catch (Exception e) + catch(Exception e) { mLog.error("Couldn't add alias ID " + id + " for alias " + alias); } @@ -234,9 +234,9 @@ public class AliasList implements Listener */ public void removeAlias(Alias alias) { - if (alias != null) + if(alias != null) { - for (AliasID aliasID : alias.getId()) + for(AliasID aliasID : alias.getId()) { removeAliasID(aliasID, alias); } @@ -247,7 +247,7 @@ public class AliasList implements Listener { if(value != null) { - for(WildcardID wildcardID: wildcards) + for(WildcardID wildcardID : wildcards) { if(wildcardID.value().equals(value)) { @@ -262,12 +262,12 @@ public class AliasList implements Listener */ private void removeAliasID(AliasID id, Alias alias) { - if (id.isValid()) + if(id.isValid()) { - switch (id.getType()) + switch(id.getType()) { case ESN: - String esn = ((Esn)id).getEsn(); + String esn = ((Esn) id).getEsn(); if(esn != null) { @@ -280,13 +280,13 @@ public class AliasList implements Listener mESN.remove(esn); break; case FLEETSYNC: - String fleetsync = ((FleetsyncID)id).getIdent(); + String fleetsync = ((FleetsyncID) id).getIdent(); if(fleetsync != null) { if(fleetsync.contains(WILDCARD)) { - removeWildcard(fleetsync,mFleetsyncWildcards); + removeWildcard(fleetsync, mFleetsyncWildcards); } mFleetsync.remove(fleetsync); @@ -296,7 +296,7 @@ public class AliasList implements Listener mLoJack.remove((LoJackFunctionAndID) id); break; case MDC1200: - String mdc = ((MDC1200ID)id).getIdent(); + String mdc = ((MDC1200ID) id).getIdent(); if(mdc != null) { @@ -309,7 +309,7 @@ public class AliasList implements Listener } break; case MPT1327: - String mpt = ((MPT1327ID)id).getIdent(); + String mpt = ((MPT1327ID) id).getIdent(); if(mpt != null) { @@ -322,7 +322,7 @@ public class AliasList implements Listener } break; case MIN: - String min = ((Min)id).getMin(); + String min = ((Min) id).getMin(); if(min != null) { @@ -344,7 +344,7 @@ public class AliasList implements Listener mStatus.remove(((StatusID) id).getStatus()); break; case TALKGROUP: - String tgid = ((TalkgroupID)id).getTalkgroup(); + String tgid = ((TalkgroupID) id).getTalkgroup(); if(tgid != null) { @@ -378,11 +378,11 @@ public class AliasList implements Listener */ private String getWildcardMatch(String id, List wildcards) { - if (id != null) + if(id != null) { - for (WildcardID wildcard : wildcards) + for(WildcardID wildcard : wildcards) { - if (wildcard.matches(id)) + if(wildcard.matches(id)) { return wildcard.value(); } @@ -399,15 +399,15 @@ public class AliasList implements Listener { Alias alias = null; - if (siteID != null) + if(siteID != null) { alias = mSiteID.get(siteID); - if (alias == null) + if(alias == null) { String wildcard = getWildcardMatch(siteID, mSiteWildcards); - if (wildcard != null) + if(wildcard != null) { alias = mSiteID.get(wildcard); } @@ -440,15 +440,15 @@ public class AliasList implements Listener { Alias alias = null; - if (esn != null) + if(esn != null) { alias = mESN.get(esn); - if (alias == null) + if(alias == null) { String wildcard = getWildcardMatch(esn, mESNWildcards); - if (wildcard != null) + if(wildcard != null) { alias = mESN.get(wildcard); } @@ -465,15 +465,15 @@ public class AliasList implements Listener { Alias alias = null; - if (ident != null) + if(ident != null) { alias = mFleetsync.get(ident); - if (alias == null) + if(alias == null) { String wildcard = getWildcardMatch(ident, mFleetsyncWildcards); - if (wildcard != null) + if(wildcard != null) { alias = mFleetsync.get(wildcard); } @@ -488,11 +488,11 @@ public class AliasList implements Listener */ public Alias getLoJackAlias(Function function, String id) { - if (id != null) + if(id != null) { - for (LoJackFunctionAndID lojack : mLoJack.keySet()) + for(LoJackFunctionAndID lojack : mLoJack.keySet()) { - if (lojack.matches(function, id)) + if(lojack.matches(function, id)) { return mLoJack.get(lojack); } @@ -509,15 +509,15 @@ public class AliasList implements Listener { Alias alias = null; - if (ident != null) + if(ident != null) { alias = mMDC1200.get(ident); - if (alias == null) + if(alias == null) { String wildcard = getWildcardMatch(ident, mMDC1200Wildcards); - if (wildcard != null) + if(wildcard != null) { alias = mMDC1200.get(wildcard); } @@ -534,15 +534,15 @@ public class AliasList implements Listener { Alias alias = null; - if (ident != null) + if(ident != null) { alias = mMPT1327.get(ident); - if (alias == null) + if(alias == null) { String wildcard = getWildcardMatch(ident, mMPT1327Wildcards); - if (wildcard != null) + if(wildcard != null) { alias = mMPT1327.get(wildcard); } @@ -559,15 +559,15 @@ public class AliasList implements Listener { Alias alias = null; - if (ident != null) + if(ident != null) { alias = mMobileID.get(ident); - if (alias == null) + if(alias == null) { String wildcard = getWildcardMatch(ident, mMobileIDWildcards); - if (wildcard != null) + if(wildcard != null) { alias = mMobileID.get(wildcard); } @@ -588,15 +588,15 @@ public class AliasList implements Listener { Alias alias = null; - if (tgid != null) + if(tgid != null) { alias = mTalkgroup.get(tgid); - if (alias == null && includeWildcards) + if(alias == null && includeWildcards) { String wildcard = getWildcardMatch(tgid, mTalkgroupWildcards); - if (wildcard != null) + if(wildcard != null) { alias = mTalkgroup.get(wildcard); } @@ -614,9 +614,9 @@ public class AliasList implements Listener return getTalkgroupAlias(tgid, true); } - /** - * Alias list name - */ + /** + * Alias list name + */ public String toString() { return mName; @@ -639,22 +639,22 @@ public class AliasList implements Listener { Alias alias = event.getAlias(); - switch (event.getEvent()) + switch(event.getEvent()) { case ADD: - if (alias.getList() != null && getName().equalsIgnoreCase(alias.getList())) + if(alias.getList() != null && getName().equalsIgnoreCase(alias.getList())) { addAlias(alias); } break; case CHANGE: - if (alias.getList() != null && getName().equalsIgnoreCase(alias.getList())) + if(alias.getList() != null && getName().equalsIgnoreCase(alias.getList())) { addAlias(alias); } break; case DELETE: - if (alias.getList() != null && getName().equalsIgnoreCase(alias.getList())) + if(alias.getList() != null && getName().equalsIgnoreCase(alias.getList())) { removeAlias(alias); } diff --git a/src/channel/metadata/AliasedStringAttributeMonitor.java b/src/channel/metadata/AliasedStringAttributeMonitor.java new file mode 100644 index 00000000..216653e5 --- /dev/null +++ b/src/channel/metadata/AliasedStringAttributeMonitor.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 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 channel.metadata; + +import alias.Alias; +import alias.AliasList; +import alias.id.AliasIDType; +import sample.Listener; + +import static alias.id.AliasIDType.*; + +public class AliasedStringAttributeMonitor extends AttributeMonitor +{ + private static final AliasIDType[] VALID_ID_TYPES = {ESN, FLEETSYNC, MDC1200, MIN, MPT1327, SITE, TALKGROUP}; + + private AliasList mAliasList; + private AliasIDType mAliasIDType; + + /** + * Provides monitoring of a String attribute's values with occurrence heuristics enabled and alias lookup with each + * change in the attribute's value. + * + * @param attribute to monitor + * @param listener to receive change requests + * @param aliasList to lookup alias from + * @param aliasIDType to determine correct alias lookup method in alias list + */ + public AliasedStringAttributeMonitor(Attribute attribute, Listener listener, AliasList aliasList, + AliasIDType aliasIDType) + { + super(attribute, listener); + + if(!isValidIDType(aliasIDType)) + { + throw new IllegalArgumentException("Alias ID Type [" + aliasIDType.name() + "] is not supported"); + } + mAliasList = aliasList; + mAliasIDType = aliasIDType; + } + + /** + * Indicates if the alias ID type is a supported/valid type for this monitor. + */ + public static boolean isValidIDType(AliasIDType type) + { + for(AliasIDType validType: VALID_ID_TYPES) + { + if(type == validType) + { + return true; + } + } + + return false; + } + + /** + * Lookup of the alias that corresponds to the value's alias ID type + */ + @Override + protected Alias getAlias() + { + Alias alias = null; + + if(mAliasList != null) + { + if(hasValue()) + { + switch(mAliasIDType) + { + case ESN: + alias = mAliasList.getESNAlias(getValue()); + break; + case FLEETSYNC: + alias = mAliasList.getFleetsyncAlias(getValue()); + break; + case MDC1200: + alias = mAliasList.getMDC1200Alias(getValue()); + break; + case MIN: + alias = mAliasList.getMobileIDNumberAlias(getValue()); + break; + case MPT1327: + alias = mAliasList.getMPT1327Alias(getValue()); + break; + case SITE: + alias = mAliasList.getSiteID(getValue()); + break; + case TALKGROUP: + alias = mAliasList.getTalkgroupAlias(getValue()); + break; + } + } + } + + return alias; + } +} diff --git a/src/channel/metadata/AttributeMonitor.java b/src/channel/metadata/AttributeMonitor.java new file mode 100644 index 00000000..74bfd281 --- /dev/null +++ b/src/channel/metadata/AttributeMonitor.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 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 channel.metadata; + +import alias.Alias; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import sample.Listener; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class AttributeMonitor +{ + private final static Logger mLog = LoggerFactory.getLogger(AttributeMonitor.class); + + private Attribute mAttribute; + private Listener mListener; + private boolean mHeuristicsEnabled = true; + private Map mOccurrenceCounts = new HashMap<>(); + private T mCurrentValue; + private List mIllegalValues = new ArrayList<>(); + + public AttributeMonitor(Attribute attribute, Listener listener) + { + mAttribute = attribute; + mListener = listener; + } + + /** + * Processes the value and emits a change request if the value needs to be changed. If heuristics are enabled, + * an internal mapping of values to occurrence counts is updated and a change is emitted once a value that is + * different from the current value, has a higher occurrence count than the current value. If heuristics are + * disabled, then a change is emitted at each change in the value. + * @param t + */ + public void process(T t) + { + if(t != null && !mIllegalValues.contains(t)) + { + boolean changed = false; + + if(mHeuristicsEnabled) + { + if(mOccurrenceCounts.containsKey(t)) + { + mOccurrenceCounts.put(t, mOccurrenceCounts.get(t) + 1); + } + else + { + mOccurrenceCounts.put(t, 1); + } + } + + if(mCurrentValue == null) + { + mCurrentValue = t; + changed = true; + } + else if(!mCurrentValue.equals(t)) + { + if(mHeuristicsEnabled) + { + int count = mOccurrenceCounts.get(mCurrentValue); + + for(Map.Entry entry: mOccurrenceCounts.entrySet()) + { + if(entry.getValue() > count) + { + count = entry.getValue(); + mCurrentValue = entry.getKey(); + changed = true; + } + } + } + else + { + mCurrentValue = t; + changed = true; + } + } + + if(changed && mListener != null) + { + mListener.receive(new AttributeChangeRequest(mAttribute, getValue(), getAlias())); + } + } + } + + /** + * Alias for the current value. This class does not return an alias, but subclasses can return an alias that + * is appropriate for the monitored attribute value. + * + * @return an optional alias for the current value + */ + protected Alias getAlias() + { + return null; + } + + /** + * Resets the attribute value to null and resets occurrence heuristics. + */ + public void reset() + { + mCurrentValue = null; + mOccurrenceCounts.clear(); + } + + /** + * Adds a value to the internal list of illegal values. The monitor will not allow the attribute to be changed to + * any values contained in this list. + * + * @param illegalValue to prevent for the monitored alias + */ + public void addIllegalValue(T illegalValue) + { + mIllegalValues.add(illegalValue); + } + + /** + * Returns the current value or null if the monitor is newly started or reset. + */ + public T getValue() + { + return mCurrentValue; + } + + /** + * Indicates if the current value is non-null + */ + public boolean hasValue() + { + return mCurrentValue != null; + } + + public static void main(String[] args) + { + AttributeMonitor monitor = new AttributeMonitor<>(Attribute.PRIMARY_ADDRESS_TO, new Listener() + { + @Override + public void receive(AttributeChangeRequest attributeChangeRequest) + { + mLog.debug("Attribute Changed - value:" + attributeChangeRequest.getValue()); + } + }); + monitor.addIllegalValue("0000"); + monitor.addIllegalValue("000000"); + + monitor.process("ABCD"); + monitor.process("EFGH"); + monitor.process("0000"); + monitor.process("0000"); + monitor.process("ABCD"); + monitor.reset(); + + monitor.process("EFGH"); + monitor.process("ABCD"); + monitor.process("ABCD"); + monitor.process("EFGH"); + monitor.process("EFGH"); + monitor.process("000000"); + monitor.process("000000"); + monitor.process("000000"); + monitor.process("000000"); + } +} diff --git a/src/channel/metadata/IAttributeChangeRequestProvider.java b/src/channel/metadata/IAttributeChangeRequestProvider.java index 7be76f95..c9b78cd1 100644 --- a/src/channel/metadata/IAttributeChangeRequestProvider.java +++ b/src/channel/metadata/IAttributeChangeRequestProvider.java @@ -24,5 +24,5 @@ public interface IAttributeChangeRequestProvider { public void setAttributeChangeRequestListener(Listener listener); - public void removeAttributeChangeRequestListener(); + public void removeAttributeChangeRequestListener(Listener listener); } diff --git a/src/channel/state/DecoderState.java b/src/channel/state/DecoderState.java index a1780e0d..a27dd7be 100644 --- a/src/channel/state/DecoderState.java +++ b/src/channel/state/DecoderState.java @@ -25,7 +25,7 @@ public abstract class DecoderState extends Module implements ActivitySummaryProv { /* This has to be a broadcaster in order for references to persist */ private Broadcaster mCallEventBroadcaster = new Broadcaster<>(); - private Listener mAttributeChangeRequestListener; + private Broadcaster mAttributeChangeRequestBroadcaster = new Broadcaster<>(); private Listener mDecoderStateListener; private DecoderStateEventListener mDecoderStateEventListener = new DecoderStateEventListener(); @@ -167,10 +167,7 @@ public abstract class DecoderState extends Module implements ActivitySummaryProv */ protected void broadcast(AttributeChangeRequest request) { - if(mAttributeChangeRequestListener != null) - { - mAttributeChangeRequestListener.receive(request); - } + mAttributeChangeRequestBroadcaster.broadcast(request); } /** @@ -179,16 +176,23 @@ public abstract class DecoderState extends Module implements ActivitySummaryProv @Override public void setAttributeChangeRequestListener(Listener listener) { - mAttributeChangeRequestListener = listener; + mAttributeChangeRequestBroadcaster.addListener(listener); } /** * Removes any listener from receiving attribute change requests */ @Override - public void removeAttributeChangeRequestListener() + public void removeAttributeChangeRequestListener(Listener listener) { - mAttributeChangeRequestListener = null; + mAttributeChangeRequestBroadcaster.removeListener(listener); } + /** + * Broadaster so that Attribute monitors can broadcast attribute change requests + */ + protected Listener getAttributeChangeRequestListener() + { + return mAttributeChangeRequestBroadcaster; + } } diff --git a/src/module/decode/p25/P25DecoderState.java b/src/module/decode/p25/P25DecoderState.java index 6e05a5e7..ce636cab 100644 --- a/src/module/decode/p25/P25DecoderState.java +++ b/src/module/decode/p25/P25DecoderState.java @@ -20,7 +20,9 @@ package module.decode.p25; import alias.Alias; import alias.AliasList; import alias.PatchGroupAlias; +import alias.id.AliasIDType; import alias.id.talkgroup.TalkgroupID; +import channel.metadata.AliasedStringAttributeMonitor; import channel.metadata.Attribute; import channel.metadata.AttributeChangeRequest; import channel.state.ChangeChannelTimeoutEvent; @@ -169,14 +171,12 @@ public class P25DecoderState extends DecoderState private String mLastRegistrationEventID; private String mLastResponseEventID; + //TODO: create multi-attribute monitor for NAC and System private String mNAC; private String mSystem; - private String mSite; - private String mSiteAlias; - private String mFromTalkgroup; - private Alias mFromAlias; - private String mToTalkgroup; - private Alias mToAlias; + private AliasedStringAttributeMonitor mSiteAttributeMonitor; + private AliasedStringAttributeMonitor mFromTalkgroupMonitor; + private AliasedStringAttributeMonitor mToTalkgroupMonitor; private String mCurrentChannel = "CURRENT"; private long mCurrentChannelFrequency = 0; @@ -198,6 +198,13 @@ public class P25DecoderState extends DecoderState mChannelType = channelType; mModulation = modulation; mIgnoreDataCalls = ignoreDataCalls; + + mSiteAttributeMonitor = new AliasedStringAttributeMonitor(Attribute.NETWORK_ID_2, + getAttributeChangeRequestListener(), getAliasList(), AliasIDType.SITE); + mFromTalkgroupMonitor = new AliasedStringAttributeMonitor(Attribute.PRIMARY_ADDRESS_FROM, + getAttributeChangeRequestListener(), getAliasList(), AliasIDType.TALKGROUP); + mToTalkgroupMonitor = new AliasedStringAttributeMonitor(Attribute.PRIMARY_ADDRESS_TO, + getAttributeChangeRequestListener(), getAliasList(), AliasIDType.TALKGROUP); } public Modulation getModulation() @@ -225,8 +232,7 @@ public class P25DecoderState extends DecoderState resetState(); mNAC = null; - mSite = null; - mSiteAlias = null; + mSiteAttributeMonitor.reset(); mSystem = null; } @@ -235,10 +241,8 @@ public class P25DecoderState extends DecoderState */ private void resetState() { - mFromTalkgroup = null; - mFromAlias = null; - mToTalkgroup = null; - mToAlias = null; + mFromTalkgroupMonitor.reset(); + mToTalkgroupMonitor.reset(); mCallDetectTalkgroups.clear(); @@ -405,7 +409,7 @@ public class P25DecoderState extends DecoderState String to = hdu.getToID(); - updateTo(to); + mToTalkgroupMonitor.process(to); if(mCurrentCallEvent == null) { @@ -495,7 +499,7 @@ public class P25DecoderState extends DecoderState //TODO: does the activity summary need this message? /* This message is handled by the P25MessageProcessor and - * inserted into any channels needing frequency band info */ + * inserted into any channels needing frequency band info */ break; case CHANNEL_IDENTIFIER_UPDATE_EXPLICIT: //TODO: does the activity summary need this message? @@ -614,8 +618,8 @@ public class P25DecoderState extends DecoderState String from = gvcuser.getSourceAddress(); String to = gvcuser.getGroupAddress(); - updateFrom(from); - updateTo(to); + mFromTalkgroupMonitor.process(from); + mToTalkgroupMonitor.process(to); if(mCurrentCallEvent == null) { @@ -702,7 +706,7 @@ public class P25DecoderState extends DecoderState String site = rfsssb.getRFSubsystemID() + "-" + rfsssb.getSiteID(); - updateSite(site); + mSiteAttributeMonitor.process(site); if(mCurrentChannel == null || !mCurrentChannel.contentEquals(rfsssb.getChannel())) @@ -725,7 +729,7 @@ public class P25DecoderState extends DecoderState String site = rfsssbe.getRFSubsystemID() + "-" + rfsssbe.getSiteID(); - updateSite(site); + mSiteAttributeMonitor.process(site); if(mCurrentChannel == null || !mCurrentChannel.contentEquals(rfsssbe.getTransmitChannel())) @@ -748,7 +752,7 @@ public class P25DecoderState extends DecoderState String site = sccb.getRFSubsystemID() + "-" + sccb.getSiteID(); - updateSite(site); + mSiteAttributeMonitor.process(site); } else { @@ -764,7 +768,7 @@ public class P25DecoderState extends DecoderState String site = sccb.getRFSubsystemID() + "-" + sccb.getSiteID(); - updateSite(site); + mSiteAttributeMonitor.process(site); } else { @@ -838,7 +842,7 @@ public class P25DecoderState extends DecoderState String to = tivcu.getAddress(); - updateTo(to); + mToTalkgroupMonitor.process(to); if(mCurrentCallEvent == null) { @@ -915,10 +919,10 @@ public class P25DecoderState extends DecoderState (module.decode.p25.message.tdu.lc.UnitToUnitVoiceChannelUser) tdulc; String from = uuvcu.getSourceAddress(); - updateFrom(from); + mFromTalkgroupMonitor.process(from); String to = uuvcu.getTargetAddress(); - updateTo(to); + mToTalkgroupMonitor.process(to); if(mCurrentCallEvent != null) { @@ -1163,9 +1167,9 @@ public class P25DecoderState extends DecoderState module.decode.p25.message.ldu.lc.GroupVoiceChannelUser gvcuser = (module.decode.p25.message.ldu.lc.GroupVoiceChannelUser) ldu; - updateFrom(gvcuser.getSourceAddress()); + mFromTalkgroupMonitor.process(gvcuser.getSourceAddress()); - updateTo(gvcuser.getGroupAddress()); + mToTalkgroupMonitor.process(gvcuser.getGroupAddress()); if(mChannelType == ChannelType.STANDARD) { @@ -1258,7 +1262,7 @@ public class P25DecoderState extends DecoderState String site = rfsssb.getRFSubsystemID() + "-" + rfsssb.getSiteID(); - updateSite(site); + mSiteAttributeMonitor.process(site); } else { @@ -1274,7 +1278,7 @@ public class P25DecoderState extends DecoderState String site = rfsssbe.getRFSubsystemID() + "-" + rfsssbe.getSiteID(); - updateSite(site); + mSiteAttributeMonitor.process(site); } else { @@ -1290,7 +1294,7 @@ public class P25DecoderState extends DecoderState String site = sccb.getRFSubsystemID() + "-" + sccb.getSiteID(); - updateSite(site); + mSiteAttributeMonitor.process(site); } else { @@ -1306,7 +1310,7 @@ public class P25DecoderState extends DecoderState String site = sccb.getRFSubsystemID() + "-" + sccb.getSiteID(); - updateSite(site); + mSiteAttributeMonitor.process(site); } else { @@ -1379,7 +1383,7 @@ public class P25DecoderState extends DecoderState TelephoneInterconnectVoiceChannelUser tivcu = (TelephoneInterconnectVoiceChannelUser) ldu; - updateTo(tivcu.getAddress()); + mToTalkgroupMonitor.process(tivcu.getAddress()); if(mCurrentCallEvent.getCallEventType() != CallEventType.TELEPHONE_INTERCONNECT) { @@ -1460,9 +1464,9 @@ public class P25DecoderState extends DecoderState UnitToUnitVoiceChannelUser uuvcu = (UnitToUnitVoiceChannelUser) ldu; - updateFrom(uuvcu.getSourceAddress()); + mFromTalkgroupMonitor.process(uuvcu.getSourceAddress()); - updateTo(uuvcu.getTargetAddress()); + mToTalkgroupMonitor.process(uuvcu.getTargetAddress()); if(mCurrentCallEvent.getCallEventType() != CallEventType.UNIT_TO_UNIT_CALL) { @@ -1877,7 +1881,7 @@ public class P25DecoderState extends DecoderState updateNAC(mRFSSStatusMessageExtended.getNAC()); updateSystem(mRFSSStatusMessageExtended.getSystemID()); - updateSite(mRFSSStatusMessageExtended.getRFSubsystemID() + + mSiteAttributeMonitor.process(mRFSSStatusMessageExtended.getRFSubsystemID() + "-" + mRFSSStatusMessageExtended.getSiteID()); } else @@ -2651,7 +2655,7 @@ public class P25DecoderState extends DecoderState updateSystem(message.getSystemID()); - updateSite(message.getRFSubsystemID() + "-" + message.getSiteID()); + mSiteAttributeMonitor.process(message.getRFSubsystemID() + "-" + message.getSiteID()); } private void processTSBKDataChannelAnnouncement(TSBKMessage message) @@ -3354,99 +3358,6 @@ public class P25DecoderState extends DecoderState } } - /** - * Broadcasts an update for the TO group or unit address - */ - private void updateTo(final String to) - { - if(to != null && !to.contentEquals("0000") && !to.contentEquals("000000")) - { - if(mToTalkgroup == null || !mToTalkgroup.contentEquals(to)) - { - mToTalkgroup = to; - - if(hasAliasList()) - { - mToAlias = getAliasList().getTalkgroupAlias(mToTalkgroup); - } - else - { - mToAlias = null; - } - - broadcast(new AttributeChangeRequest(Attribute.PRIMARY_ADDRESS_TO, mToTalkgroup, mToAlias)); - - if(mCurrentCallEvent != null && - (mCurrentCallEvent.getToID() == null || !mCurrentCallEvent.getToID().contentEquals(to))) - { - mCurrentCallEvent.setToID(to); - broadcast(mCurrentCallEvent); - } - } - } - } - - /** - * Broadcasts an update for the FROM group or unit address - */ - private void updateFrom(final String from) - { - if(from != null && !from.contentEquals("0000") && !from.contentEquals("000000")) - { - if(mFromTalkgroup == null || !mFromTalkgroup.contentEquals(from)) - { - mFromTalkgroup = from; - - if(hasAliasList()) - { - mFromAlias = getAliasList().getTalkgroupAlias(mFromTalkgroup); - } - else - { - mFromAlias = null; - } - - broadcast(new AttributeChangeRequest(Attribute.PRIMARY_ADDRESS_FROM, mFromTalkgroup, - mFromAlias)); - - if(mCurrentCallEvent != null && - (mCurrentCallEvent.getFromID() == null || !mCurrentCallEvent.getFromID().contentEquals(from))) - { - mCurrentCallEvent.setFromID(from); - broadcast(mCurrentCallEvent); - } - } - - } - } - - /** - * Updates the site information - */ - private void updateSite(String site) - { - if(mSite == null || (site != null && !mSite.contentEquals(site))) - { - mSite = site; - - if(hasAliasList()) - { - Alias alias = getAliasList().getSiteID(mSite); - - if(alias != null) - { - mSiteAlias = alias.getName(); - } - else - { - mSiteAlias = null; - } - } - - - } - } - private void updateSystem(String system) { if(mSystem == null || (system != null && !mSystem.contentEquals(system))) @@ -3739,46 +3650,6 @@ public class P25DecoderState extends DecoderState return sb.toString(); } - public String getNAC() - { - return mNAC; - } - - public String getSystem() - { - return mSystem; - } - - public String getSiteAlias() - { - return mSiteAlias; - } - - public String getSite() - { - return mSite; - } - - public String getFromTalkgroup() - { - return mFromTalkgroup; - } - - public Alias getFromAlias() - { - return mFromAlias; - } - - public String getToTalkgroup() - { - return mToTalkgroup; - } - - public Alias getToAlias() - { - return mToAlias; - } - @Override public void receiveDecoderStateEvent(DecoderStateEvent event) { @@ -3806,19 +3677,11 @@ public class P25DecoderState extends DecoderState mCurrentChannelFrequency = allocationEvent.getCallEvent().getFrequency(); broadcast(new AttributeChangeRequest(Attribute.CHANNEL_FREQUENCY, mCurrentChannelFrequency)); - mFromTalkgroup = allocationEvent.getCallEvent().getFromID(); - mToTalkgroup = allocationEvent.getCallEvent().getToID(); + mFromTalkgroupMonitor.reset(); + mFromTalkgroupMonitor.process(allocationEvent.getCallEvent().getFromID()); - if(allocationEvent.getCallEvent().hasAliasList()) - { - AliasList aliasList = allocationEvent.getCallEvent().getAliasList(); - - mFromAlias = aliasList.getTalkgroupAlias(mFromTalkgroup); - mToAlias = aliasList.getTalkgroupAlias(mToTalkgroup); - } - - broadcast(new AttributeChangeRequest(Attribute.PRIMARY_ADDRESS_FROM, mFromTalkgroup, mFromAlias)); - broadcast(new AttributeChangeRequest(Attribute.PRIMARY_ADDRESS_TO, mToTalkgroup, mToAlias)); + mToTalkgroupMonitor.reset(); + mToTalkgroupMonitor.process(allocationEvent.getCallEvent().getToID()); } } break;