mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 16:47:31 -05:00
#1607 Add support for L3Harris dynamic regroup/patch messages and events. Includes parsing for L3Harris unknown opcodes 10, 42 and 43.
This commit is contained in:
@@ -1,69 +1,161 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2023 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2019 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/>
|
||||
* * *****************************************************************************
|
||||
* 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 io.github.dsheirer.identifier.patch;
|
||||
|
||||
import io.github.dsheirer.identifier.radio.RadioIdentifier;
|
||||
import io.github.dsheirer.identifier.talkgroup.TalkgroupIdentifier;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Temporary grouping or regrouping of talkgroups or individual radios.
|
||||
*/
|
||||
public class PatchGroup
|
||||
{
|
||||
// private final static Logger mLog = LoggerFactory.getLogger(PatchGroup.class);
|
||||
|
||||
private TalkgroupIdentifier mPatchGroupIdentifier;
|
||||
private List<TalkgroupIdentifier> mPatchedGroupIdentifiers = new ArrayList<>();
|
||||
private List<TalkgroupIdentifier> mPatchedTalkgroupIdentifiers = new ArrayList<>();
|
||||
private List<RadioIdentifier> mPatchedRadioIdentifiers = new ArrayList<>();
|
||||
private int mVersion;
|
||||
|
||||
public PatchGroup(TalkgroupIdentifier patchGroupIdentifier)
|
||||
/**
|
||||
* Constructs an instance
|
||||
* @param patchGroupIdentifier for the patch group
|
||||
* @param version for this patch group identifier. Note: if the patch group identifier is frequently reused, a
|
||||
* new version number will indicate a new instance of the patch group.
|
||||
*/
|
||||
public PatchGroup(TalkgroupIdentifier patchGroupIdentifier, int version)
|
||||
{
|
||||
mPatchGroupIdentifier = patchGroupIdentifier;
|
||||
mVersion = version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
* @param patchGroupIdentifier that is the overall identifier for this temporary grouping.
|
||||
*/
|
||||
public PatchGroup(TalkgroupIdentifier patchGroupIdentifier)
|
||||
{
|
||||
this(patchGroupIdentifier, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Version number for this patch group used to differentiate frequently reused patch group identifiers.
|
||||
* @return version number (aka super group sequence number).
|
||||
*/
|
||||
public int getVersion()
|
||||
{
|
||||
return mVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch group identifier.
|
||||
* @return identifier
|
||||
*/
|
||||
public TalkgroupIdentifier getPatchGroup()
|
||||
{
|
||||
return mPatchGroupIdentifier;
|
||||
}
|
||||
|
||||
public void addPatchedGroup(TalkgroupIdentifier patchedGroupIdentifier)
|
||||
/**
|
||||
* Indicates if this patch group contains any patched talkgroups.
|
||||
* @return true if there are patched talkgroups.
|
||||
*/
|
||||
public boolean hasPatchedTalkgroups()
|
||||
{
|
||||
if(!mPatchedGroupIdentifiers.contains(patchedGroupIdentifier))
|
||||
return !getPatchedTalkgroupIdentifiers().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this patch group contains any patched radio identifiers.
|
||||
* @return true if there are patched radios.
|
||||
*/
|
||||
public boolean hasPatchedRadios()
|
||||
{
|
||||
return !getPatchedRadioIdentifiers().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the talkgroup identifier to this patched group.
|
||||
* @param patchedGroupIdentifier to add
|
||||
*/
|
||||
public void addPatchedTalkgroup(TalkgroupIdentifier patchedGroupIdentifier)
|
||||
{
|
||||
if(!mPatchedTalkgroupIdentifiers.contains(patchedGroupIdentifier))
|
||||
{
|
||||
mPatchedGroupIdentifiers.add(patchedGroupIdentifier);
|
||||
mPatchedTalkgroupIdentifiers.add(patchedGroupIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
public void addPatchedGroups(List<TalkgroupIdentifier> patchedGroupIdentifiers)
|
||||
/**
|
||||
* Adds a list of talkgroup identifiers to this patched group.
|
||||
* @param patchedGroupIdentifiers to add
|
||||
*/
|
||||
public void addPatchedTalkgroups(List<TalkgroupIdentifier> patchedGroupIdentifiers)
|
||||
{
|
||||
for(TalkgroupIdentifier identifier : patchedGroupIdentifiers)
|
||||
{
|
||||
addPatchedGroup(identifier);
|
||||
addPatchedTalkgroup(identifier);
|
||||
}
|
||||
}
|
||||
|
||||
public List<TalkgroupIdentifier> getPatchedGroupIdentifiers()
|
||||
/**
|
||||
* List of patched group identifiers that are part of this patch group.
|
||||
* @return patched talkgroups.
|
||||
*/
|
||||
public List<TalkgroupIdentifier> getPatchedTalkgroupIdentifiers()
|
||||
{
|
||||
return mPatchedGroupIdentifiers;
|
||||
return mPatchedTalkgroupIdentifiers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the radio identifier to this patched group.
|
||||
* @param patchedRadioIdentifier to add
|
||||
*/
|
||||
public void addPatchedRadio(RadioIdentifier patchedRadioIdentifier)
|
||||
{
|
||||
if(!mPatchedRadioIdentifiers.contains(patchedRadioIdentifier))
|
||||
{
|
||||
mPatchedRadioIdentifiers.add(patchedRadioIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a list of radio identifiers to this patched group.
|
||||
* @param patchedRadioIdentifiers to add
|
||||
*/
|
||||
public void addPatchedRadios(List<RadioIdentifier> patchedRadioIdentifiers)
|
||||
{
|
||||
for(RadioIdentifier identifier : patchedRadioIdentifiers)
|
||||
{
|
||||
addPatchedRadio(identifier);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List of patched radio identifiers that are part of this patch group.
|
||||
* @return patched radios.
|
||||
*/
|
||||
public List<RadioIdentifier> getPatchedRadioIdentifiers()
|
||||
{
|
||||
return mPatchedRadioIdentifiers;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -72,9 +164,14 @@ public class PatchGroup
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("P:").append(getPatchGroup());
|
||||
|
||||
if(!getPatchedGroupIdentifiers().isEmpty())
|
||||
if(hasPatchedTalkgroups())
|
||||
{
|
||||
sb.append(" ").append(getPatchedGroupIdentifiers());
|
||||
sb.append(" TG").append(getPatchedTalkgroupIdentifiers());
|
||||
}
|
||||
|
||||
if(hasPatchedRadios())
|
||||
{
|
||||
sb.append(" RA").append(getPatchedRadioIdentifiers());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -22,27 +22,23 @@ package io.github.dsheirer.identifier.patch;
|
||||
import io.github.dsheirer.identifier.Identifier;
|
||||
import io.github.dsheirer.identifier.IdentifierClass;
|
||||
import io.github.dsheirer.identifier.Role;
|
||||
|
||||
import io.github.dsheirer.identifier.talkgroup.TalkgroupIdentifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Manager for (temporary) patch groups and related identifiers.
|
||||
* Manager for (temporary) patch groups aka super groups. This manager monitors patch group additions and deletions and
|
||||
* maintains a map of the current state of each patch group active in the system.
|
||||
*
|
||||
* Patch groups are primarily used on Motorola P25 systems. This manager monitors patch group additions and deletions
|
||||
* and maintains a map of the current patch groups.
|
||||
*
|
||||
* Traffic channel calls will sometimes reference a patch group by simply using the patch group identifier. This
|
||||
* manager will replace that reference with the full patch group so that the call event has the full patch group
|
||||
* including all of the patched groups, which may not have been included in the patch group reference on the
|
||||
* traffic channel.
|
||||
* Traffic channel calls will reference a patch group by simply using the patch group identifier. This
|
||||
* manager will replace that reference with the current state of the full patch group so that the call event has the
|
||||
* full patch group including all patched talkgroups or individual radios, which may not have been included in the
|
||||
* patch group reference on the control or traffic channel.
|
||||
*/
|
||||
public class PatchGroupManager
|
||||
{
|
||||
// private final static Logger mLog = LoggerFactory.getLogger(PatchGroupManager.class);
|
||||
private Map<Integer,Long> mPatchGroupLastUpdatedMap = new HashMap<>();
|
||||
private Map<Integer,PatchGroupIdentifier> mPatchGroupMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
@@ -58,13 +54,13 @@ public class PatchGroupManager
|
||||
public void clear()
|
||||
{
|
||||
mPatchGroupMap.clear();
|
||||
mPatchGroupLastUpdatedMap.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the patch group identifier to the set of managed patch groups. If the patch group is already being
|
||||
* managed, the new identifier is checked for additional patched talkgroups and they are added to the existing
|
||||
* managed patch group.
|
||||
* managed, the new patch group argument is checked for additional patched talkgroups and they are added to the
|
||||
* existing managed patch group. Where the patch group version (super group sequence number) is different, the
|
||||
* existing patch group is discarded and replaced with the updated version of the patch group.
|
||||
*
|
||||
* @param patchGroupIdentifier to add or update
|
||||
*/
|
||||
@@ -76,8 +72,19 @@ public class PatchGroupManager
|
||||
{
|
||||
if(mPatchGroupMap.containsKey(update.getPatchGroup().getValue()))
|
||||
{
|
||||
PatchGroup current = mPatchGroupMap.get(update.getPatchGroup().getValue()).getValue();
|
||||
current.addPatchedGroups(update.getPatchedGroupIdentifiers());
|
||||
PatchGroup existingPatchGroup = mPatchGroupMap.get(update.getPatchGroup().getValue()).getValue();
|
||||
|
||||
//If the patch group version number is the same, this is an update
|
||||
if(existingPatchGroup.getVersion() == update.getVersion())
|
||||
{
|
||||
existingPatchGroup.addPatchedTalkgroups(update.getPatchedTalkgroupIdentifiers());
|
||||
existingPatchGroup.addPatchedRadios(update.getPatchedRadioIdentifiers());
|
||||
}
|
||||
//Otherwise, this is a replace operation.
|
||||
else
|
||||
{
|
||||
mPatchGroupMap.put(update.getPatchGroup().getValue(), patchGroupIdentifier);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -109,7 +116,6 @@ public class PatchGroupManager
|
||||
{
|
||||
int id = patchGroupIdentifier.getValue().getPatchGroup().getValue();
|
||||
mPatchGroupMap.remove(id);
|
||||
mPatchGroupLastUpdatedMap.remove(id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,23 +159,28 @@ public class PatchGroupManager
|
||||
*/
|
||||
public Identifier update(Identifier identifier)
|
||||
{
|
||||
if(identifier == null)
|
||||
{
|
||||
return identifier;
|
||||
}
|
||||
|
||||
if(identifier.getIdentifierClass() == IdentifierClass.USER && identifier.getRole() == Role.TO)
|
||||
if(identifier != null && identifier.getIdentifierClass() == IdentifierClass.USER && identifier.getRole() == Role.TO)
|
||||
{
|
||||
switch(identifier.getForm())
|
||||
{
|
||||
case PATCH_GROUP:
|
||||
if(identifier instanceof PatchGroupIdentifier)
|
||||
case TALKGROUP:
|
||||
if(identifier instanceof TalkgroupIdentifier talkgroupIdentifier)
|
||||
{
|
||||
Identifier mapValue = mPatchGroupMap.get(talkgroupIdentifier.getValue());
|
||||
if (mapValue != null)
|
||||
{
|
||||
return mapValue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PATCH_GROUP:
|
||||
if(identifier instanceof PatchGroupIdentifier patchGroupIdentifier)
|
||||
{
|
||||
PatchGroupIdentifier patchGroupIdentifier = (PatchGroupIdentifier)identifier;
|
||||
int patchGroupId = patchGroupIdentifier.getValue().getPatchGroup().getValue();
|
||||
|
||||
Identifier mapValue = mPatchGroupMap.get(patchGroupId);
|
||||
if (mapValue != null) {
|
||||
if (mapValue != null)
|
||||
{
|
||||
return mapValue;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user