mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 08:37:25 -05:00
Performance improvements (#746)
* Misc minor performance improvements * Use more concise loop syntax * Use more concise Collection sort syntax * Use StringUtils pad methods * Optimize some loops and double-map-lookups * Optimize array instantiation There are two styles to convert a collection to an array: either using a pre-sized array (like c.toArray(new String[c.size()])) or using an empty array (like c.toArray(new String[0]). In older Java versions using pre-sized array was recommended, as the reflection call which is necessary to create an array of proper size was quite slow. However since late updates of OpenJDK 6 this call was intrinsified, making the performance of the empty array version the same and sometimes even better, compared to the pre-sized version. Also passing pre-sized array is dangerous for a concurrent or synchronized collection as a data race is possible between the size and toArray call which may result in extra nulls at the end of the array, if the collection was concurrently shrunk during the operation. * Cleanup string concatenation * Use EnumMap where possible * Use FastMath instead of Math * Initialize complex things only once * Reduce method size to aloow more JIT inlining * remove map of short->float * Move field to local variable * Cleanup Map lookup Co-authored-by: Rob Ekl <xwq876@zebra.com>
This commit is contained in:
@@ -143,146 +143,28 @@ public class DecoderFactory
|
||||
switch(decodeConfig.getDecoderType())
|
||||
{
|
||||
case AM:
|
||||
modules.add(new AMDecoder(decodeConfig));
|
||||
modules.add(new AlwaysUnsquelchedDecoderState(DecoderType.AM, channel.getName()));
|
||||
|
||||
AudioModule audioModuleAM = new AudioModule(aliasList);
|
||||
modules.add(audioModuleAM);
|
||||
|
||||
//Check if the user wants all audio recorded ..
|
||||
if(((DecodeConfigAM)decodeConfig).getRecordAudio())
|
||||
{
|
||||
audioModuleAM.setRecordAudio(true);
|
||||
}
|
||||
|
||||
if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER)
|
||||
{
|
||||
modules.add(new AMDemodulatorModule(AM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
|
||||
}
|
||||
processAM(channel, modules, aliasList, decodeConfig);
|
||||
break;
|
||||
case NBFM:
|
||||
modules.add(new NBFMDecoder(decodeConfig));
|
||||
modules.add(new AlwaysUnsquelchedDecoderState(DecoderType.NBFM, channel.getName()));
|
||||
AudioModule audioModuleFM = new AudioModule(aliasList);
|
||||
|
||||
//Check if the user wants all audio recorded ..
|
||||
if(((DecodeConfigNBFM)decodeConfig).getRecordAudio())
|
||||
{
|
||||
audioModuleFM.setRecordAudio(true);
|
||||
}
|
||||
modules.add(audioModuleFM);
|
||||
if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER)
|
||||
{
|
||||
modules.add(new FMDemodulatorModule(FM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
|
||||
}
|
||||
processNBFM(channel, modules, aliasList, decodeConfig);
|
||||
break;
|
||||
case LTR_STANDARD:
|
||||
MessageDirection direction = ((DecodeConfigLTRStandard)decodeConfig).getMessageDirection();
|
||||
modules.add(new LTRStandardDecoder(null, direction));
|
||||
modules.add(new LTRStandardDecoderState());
|
||||
modules.add(new AudioModule(aliasList));
|
||||
if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER)
|
||||
{
|
||||
modules.add(new FMDemodulatorModule(FM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
|
||||
}
|
||||
processLTRStandard(channel, modules, aliasList, (DecodeConfigLTRStandard) decodeConfig);
|
||||
break;
|
||||
case LTR_NET:
|
||||
modules.add(new LTRNetDecoder((DecodeConfigLTRNet)decodeConfig));
|
||||
modules.add(new LTRNetDecoderState());
|
||||
modules.add(new AudioModule(aliasList));
|
||||
if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER)
|
||||
{
|
||||
modules.add(new FMDemodulatorModule(FM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
|
||||
}
|
||||
processLTRNet(channel, modules, aliasList, (DecodeConfigLTRNet) decodeConfig);
|
||||
break;
|
||||
case MPT1327:
|
||||
DecodeConfigMPT1327 mptConfig = (DecodeConfigMPT1327)decodeConfig;
|
||||
ChannelMap channelMap = channelMapModel.getChannelMap(mptConfig.getChannelMapName());
|
||||
Sync sync = mptConfig.getSync();
|
||||
modules.add(new MPT1327Decoder(sync));
|
||||
modules.add(new AudioModule(aliasList));
|
||||
SourceType sourceType = channel.getSourceConfiguration().getSourceType();
|
||||
if(sourceType == SourceType.TUNER || sourceType == SourceType.TUNER_MULTIPLE_FREQUENCIES)
|
||||
{
|
||||
modules.add(new FMDemodulatorModule(FM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
|
||||
}
|
||||
|
||||
long timeout = mptConfig.getCallTimeout() * 1000;
|
||||
|
||||
if(channelType == ChannelType.STANDARD)
|
||||
{
|
||||
MPT1327TrafficChannelManager trafficChannelManager = new MPT1327TrafficChannelManager(channel, channelMap);
|
||||
modules.add(trafficChannelManager);
|
||||
modules.add(new MPT1327DecoderState(trafficChannelManager, channelType, timeout));
|
||||
}
|
||||
else
|
||||
{
|
||||
modules.add(new MPT1327DecoderState(channelType, timeout));
|
||||
}
|
||||
|
||||
//Add a channel rotation monitor when we have multiple control channel frequencies specified
|
||||
if(channel.getSourceConfiguration() instanceof SourceConfigTunerMultipleFrequency &&
|
||||
((SourceConfigTunerMultipleFrequency)channel.getSourceConfiguration()).hasMultipleFrequencies())
|
||||
{
|
||||
List<State> activeStates = new ArrayList<>();
|
||||
activeStates.add(State.CONTROL);
|
||||
modules.add(new ChannelRotationMonitor(activeStates, userPreferences));
|
||||
}
|
||||
processMPT1327(channelMapModel, channel, userPreferences, modules, aliasList, channelType, (DecodeConfigMPT1327) decodeConfig);
|
||||
break;
|
||||
case PASSPORT:
|
||||
modules.add(new PassportDecoder(decodeConfig));
|
||||
modules.add(new PassportDecoderState());
|
||||
modules.add(new AudioModule(aliasList));
|
||||
if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER)
|
||||
{
|
||||
modules.add(new FMDemodulatorModule(FM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
|
||||
}
|
||||
processPassport(channel, modules, aliasList, decodeConfig);
|
||||
break;
|
||||
case P25_PHASE1:
|
||||
DecodeConfigP25Phase1 p25Config = (DecodeConfigP25Phase1)decodeConfig;
|
||||
|
||||
switch(p25Config.getModulation())
|
||||
{
|
||||
case C4FM:
|
||||
modules.add(new P25P1DecoderC4FM());
|
||||
break;
|
||||
case CQPSK:
|
||||
modules.add(new P25P1DecoderLSM());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unrecognized P25 Phase 1 Modulation [" +
|
||||
p25Config.getModulation() + "]");
|
||||
}
|
||||
|
||||
if(channelType == ChannelType.STANDARD)
|
||||
{
|
||||
P25TrafficChannelManager trafficChannelManager = new P25TrafficChannelManager(channel);
|
||||
modules.add(trafficChannelManager);
|
||||
modules.add(new P25P1DecoderState(channel, trafficChannelManager));
|
||||
}
|
||||
else
|
||||
{
|
||||
modules.add(new P25P1DecoderState(channel));
|
||||
}
|
||||
|
||||
modules.add(new P25P1AudioModule(userPreferences, aliasList));
|
||||
|
||||
//Add a channel rotation monitor when we have multiple control channel frequencies specified
|
||||
if(channel.getSourceConfiguration() instanceof SourceConfigTunerMultipleFrequency &&
|
||||
((SourceConfigTunerMultipleFrequency)channel.getSourceConfiguration()).hasMultipleFrequencies())
|
||||
{
|
||||
List<State> activeStates = new ArrayList<>();
|
||||
activeStates.add(State.CONTROL);
|
||||
modules.add(new ChannelRotationMonitor(activeStates, userPreferences));
|
||||
}
|
||||
processP25Phase1(channel, userPreferences, modules, aliasList, channelType, (DecodeConfigP25Phase1) decodeConfig);
|
||||
break;
|
||||
case P25_PHASE2:
|
||||
modules.add(new P25P2DecoderHDQPSK((DecodeConfigP25Phase2)channel.getDecodeConfiguration()));
|
||||
|
||||
modules.add(new P25P2DecoderState(channel, 0));
|
||||
modules.add(new P25P2DecoderState(channel, 1));
|
||||
modules.add(new P25P2AudioModule(userPreferences, 0, aliasList));
|
||||
modules.add(new P25P2AudioModule(userPreferences, 1, aliasList));
|
||||
processP25Phase2(channel, userPreferences, modules, aliasList);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown decoder type [" + decodeConfig.getDecoderType().toString() + "]");
|
||||
@@ -291,6 +173,156 @@ public class DecoderFactory
|
||||
return modules;
|
||||
}
|
||||
|
||||
private static void processP25Phase2(Channel channel, UserPreferences userPreferences, List<Module> modules, AliasList aliasList) {
|
||||
modules.add(new P25P2DecoderHDQPSK((DecodeConfigP25Phase2)channel.getDecodeConfiguration()));
|
||||
|
||||
modules.add(new P25P2DecoderState(channel, 0));
|
||||
modules.add(new P25P2DecoderState(channel, 1));
|
||||
modules.add(new P25P2AudioModule(userPreferences, 0, aliasList));
|
||||
modules.add(new P25P2AudioModule(userPreferences, 1, aliasList));
|
||||
}
|
||||
|
||||
private static void processP25Phase1(Channel channel, UserPreferences userPreferences, List<Module> modules, AliasList aliasList, ChannelType channelType, DecodeConfigP25Phase1 decodeConfig) {
|
||||
DecodeConfigP25Phase1 p25Config = decodeConfig;
|
||||
|
||||
switch(p25Config.getModulation())
|
||||
{
|
||||
case C4FM:
|
||||
modules.add(new P25P1DecoderC4FM());
|
||||
break;
|
||||
case CQPSK:
|
||||
modules.add(new P25P1DecoderLSM());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unrecognized P25 Phase 1 Modulation [" +
|
||||
p25Config.getModulation() + "]");
|
||||
}
|
||||
|
||||
if(channelType == ChannelType.STANDARD)
|
||||
{
|
||||
P25TrafficChannelManager trafficChannelManager = new P25TrafficChannelManager(channel);
|
||||
modules.add(trafficChannelManager);
|
||||
modules.add(new P25P1DecoderState(channel, trafficChannelManager));
|
||||
}
|
||||
else
|
||||
{
|
||||
modules.add(new P25P1DecoderState(channel));
|
||||
}
|
||||
|
||||
modules.add(new P25P1AudioModule(userPreferences, aliasList));
|
||||
|
||||
//Add a channel rotation monitor when we have multiple control channel frequencies specified
|
||||
if(channel.getSourceConfiguration() instanceof SourceConfigTunerMultipleFrequency &&
|
||||
((SourceConfigTunerMultipleFrequency)channel.getSourceConfiguration()).hasMultipleFrequencies())
|
||||
{
|
||||
List<State> activeStates = new ArrayList<>();
|
||||
activeStates.add(State.CONTROL);
|
||||
modules.add(new ChannelRotationMonitor(activeStates, userPreferences));
|
||||
}
|
||||
}
|
||||
|
||||
private static void processPassport(Channel channel, List<Module> modules, AliasList aliasList, DecodeConfiguration decodeConfig) {
|
||||
modules.add(new PassportDecoder(decodeConfig));
|
||||
modules.add(new PassportDecoderState());
|
||||
modules.add(new AudioModule(aliasList));
|
||||
if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER)
|
||||
{
|
||||
modules.add(new FMDemodulatorModule(FM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
|
||||
}
|
||||
}
|
||||
|
||||
private static void processMPT1327(ChannelMapModel channelMapModel, Channel channel, UserPreferences userPreferences, List<Module> modules, AliasList aliasList, ChannelType channelType, DecodeConfigMPT1327 decodeConfig) {
|
||||
DecodeConfigMPT1327 mptConfig = decodeConfig;
|
||||
ChannelMap channelMap = channelMapModel.getChannelMap(mptConfig.getChannelMapName());
|
||||
Sync sync = mptConfig.getSync();
|
||||
modules.add(new MPT1327Decoder(sync));
|
||||
modules.add(new AudioModule(aliasList));
|
||||
SourceType sourceType = channel.getSourceConfiguration().getSourceType();
|
||||
if(sourceType == SourceType.TUNER || sourceType == SourceType.TUNER_MULTIPLE_FREQUENCIES)
|
||||
{
|
||||
modules.add(new FMDemodulatorModule(FM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
|
||||
}
|
||||
|
||||
long timeout = mptConfig.getCallTimeout() * 1000;
|
||||
|
||||
if(channelType == ChannelType.STANDARD)
|
||||
{
|
||||
MPT1327TrafficChannelManager trafficChannelManager = new MPT1327TrafficChannelManager(channel, channelMap);
|
||||
modules.add(trafficChannelManager);
|
||||
modules.add(new MPT1327DecoderState(trafficChannelManager, channelType, timeout));
|
||||
}
|
||||
else
|
||||
{
|
||||
modules.add(new MPT1327DecoderState(channelType, timeout));
|
||||
}
|
||||
|
||||
//Add a channel rotation monitor when we have multiple control channel frequencies specified
|
||||
if(channel.getSourceConfiguration() instanceof SourceConfigTunerMultipleFrequency &&
|
||||
((SourceConfigTunerMultipleFrequency)channel.getSourceConfiguration()).hasMultipleFrequencies())
|
||||
{
|
||||
List<State> activeStates = new ArrayList<>();
|
||||
activeStates.add(State.CONTROL);
|
||||
modules.add(new ChannelRotationMonitor(activeStates, userPreferences));
|
||||
}
|
||||
}
|
||||
|
||||
private static void processLTRNet(Channel channel, List<Module> modules, AliasList aliasList, DecodeConfigLTRNet decodeConfig) {
|
||||
modules.add(new LTRNetDecoder(decodeConfig));
|
||||
modules.add(new LTRNetDecoderState());
|
||||
modules.add(new AudioModule(aliasList));
|
||||
if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER)
|
||||
{
|
||||
modules.add(new FMDemodulatorModule(FM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
|
||||
}
|
||||
}
|
||||
|
||||
private static void processLTRStandard(Channel channel, List<Module> modules, AliasList aliasList, DecodeConfigLTRStandard decodeConfig) {
|
||||
MessageDirection direction = decodeConfig.getMessageDirection();
|
||||
modules.add(new LTRStandardDecoder(null, direction));
|
||||
modules.add(new LTRStandardDecoderState());
|
||||
modules.add(new AudioModule(aliasList));
|
||||
if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER)
|
||||
{
|
||||
modules.add(new FMDemodulatorModule(FM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
|
||||
}
|
||||
}
|
||||
|
||||
private static void processNBFM(Channel channel, List<Module> modules, AliasList aliasList, DecodeConfiguration decodeConfig) {
|
||||
modules.add(new NBFMDecoder(decodeConfig));
|
||||
modules.add(new AlwaysUnsquelchedDecoderState(DecoderType.NBFM, channel.getName()));
|
||||
AudioModule audioModuleFM = new AudioModule(aliasList);
|
||||
|
||||
//Check if the user wants all audio recorded ..
|
||||
if(((DecodeConfigNBFM)decodeConfig).getRecordAudio())
|
||||
{
|
||||
audioModuleFM.setRecordAudio(true);
|
||||
}
|
||||
modules.add(audioModuleFM);
|
||||
if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER)
|
||||
{
|
||||
modules.add(new FMDemodulatorModule(FM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
|
||||
}
|
||||
}
|
||||
|
||||
private static void processAM(Channel channel, List<Module> modules, AliasList aliasList, DecodeConfiguration decodeConfig) {
|
||||
modules.add(new AMDecoder(decodeConfig));
|
||||
modules.add(new AlwaysUnsquelchedDecoderState(DecoderType.AM, channel.getName()));
|
||||
|
||||
AudioModule audioModuleAM = new AudioModule(aliasList);
|
||||
modules.add(audioModuleAM);
|
||||
|
||||
//Check if the user wants all audio recorded ..
|
||||
if(((DecodeConfigAM)decodeConfig).getRecordAudio())
|
||||
{
|
||||
audioModuleAM.setRecordAudio(true);
|
||||
}
|
||||
|
||||
if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER)
|
||||
{
|
||||
modules.add(new AMDemodulatorModule(AM_CHANNEL_BANDWIDTH, DEMODULATED_AUDIO_SAMPLE_RATE));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a list of auxiliary decoders, as specified in the configuration
|
||||
*
|
||||
|
||||
@@ -167,11 +167,9 @@ public class Fleetsync2DecoderState extends DecoderState
|
||||
}
|
||||
else
|
||||
{
|
||||
Iterator<FleetsyncIdentifier> it = mIdents.iterator();
|
||||
|
||||
while(it.hasNext())
|
||||
{
|
||||
sb.append(" ").append(it.next().formatted()).append("\n");
|
||||
for (FleetsyncIdentifier mIdent : mIdents) {
|
||||
sb.append(" ").append(mIdent.formatted()).append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,15 +24,13 @@ import io.github.dsheirer.filter.Filter;
|
||||
import io.github.dsheirer.filter.FilterElement;
|
||||
import io.github.dsheirer.message.IMessage;
|
||||
import io.github.dsheirer.module.decode.fleetsync2.message.Fleetsync2Message;
|
||||
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
public class FleetsyncMessageFilter extends Filter<IMessage>
|
||||
{
|
||||
private HashMap<FleetsyncMessageType,FilterElement<FleetsyncMessageType>> mElements =
|
||||
new HashMap<FleetsyncMessageType,FilterElement<FleetsyncMessageType>>();
|
||||
private Map<FleetsyncMessageType,FilterElement<FleetsyncMessageType>> mElements = new EnumMap<>(FleetsyncMessageType.class);
|
||||
|
||||
public FleetsyncMessageFilter()
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@ import io.github.dsheirer.identifier.Role;
|
||||
import io.github.dsheirer.identifier.esn.ESNIdentifier;
|
||||
import io.github.dsheirer.message.Message;
|
||||
import io.github.dsheirer.protocol.Protocol;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -183,9 +184,9 @@ public class LJ1200Message extends Message
|
||||
|
||||
sb.append("] ADDRESS [");
|
||||
sb.append(getAddress());
|
||||
sb.append("] VRC [" + getVRC());
|
||||
sb.append("] LRC [" + getLRC());
|
||||
sb.append("] CRC [" + getCRC());
|
||||
sb.append("] VRC [").append(getVRC());
|
||||
sb.append("] LRC [").append(getLRC());
|
||||
sb.append("] CRC [").append(getCRC());
|
||||
sb.append("]");
|
||||
|
||||
return sb.toString();
|
||||
@@ -196,16 +197,7 @@ public class LJ1200Message extends Message
|
||||
*/
|
||||
public String pad(String value, int places, String padCharacter)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append(value);
|
||||
|
||||
while(sb.length() < places)
|
||||
{
|
||||
sb.append(padCharacter);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
return StringUtils.rightPad(value, places, padCharacter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -213,18 +205,7 @@ public class LJ1200Message extends Message
|
||||
*/
|
||||
public String format(int number, int decimalPlaces)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int paddingRequired = decimalPlaces - (String.valueOf(number).length());
|
||||
|
||||
for(int x = 0; x < paddingRequired; x++)
|
||||
{
|
||||
sb.append("0");
|
||||
}
|
||||
|
||||
sb.append(number);
|
||||
|
||||
return sb.toString();
|
||||
return StringUtils.leftPad(Integer.valueOf(number).toString(), decimalPlaces, '0');
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -22,6 +22,7 @@ import io.github.dsheirer.edac.CRC;
|
||||
import io.github.dsheirer.identifier.Identifier;
|
||||
import io.github.dsheirer.message.Message;
|
||||
import io.github.dsheirer.protocol.Protocol;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -100,16 +101,7 @@ public class LJ1200TransponderMessage extends Message
|
||||
*/
|
||||
public String pad(String value, int places, String padCharacter)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append(value);
|
||||
|
||||
while(sb.length() < places)
|
||||
{
|
||||
sb.append(padCharacter);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
return StringUtils.rightPad(value, places, padCharacter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,18 +109,7 @@ public class LJ1200TransponderMessage extends Message
|
||||
*/
|
||||
public String format(int number, int decimalPlaces)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int paddingRequired = decimalPlaces - (String.valueOf(number).length());
|
||||
|
||||
for(int x = 0; x < paddingRequired; x++)
|
||||
{
|
||||
sb.append("0");
|
||||
}
|
||||
|
||||
sb.append(number);
|
||||
|
||||
return sb.toString();
|
||||
return StringUtils.leftPad(Integer.valueOf(number).toString(), decimalPlaces, '0');
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -573,7 +573,7 @@ public class LTRNetDecoderState extends DecoderState
|
||||
else
|
||||
{
|
||||
List<LTRTalkgroup> talkgroups = new ArrayList<>(mTalkgroups);
|
||||
Collections.sort(talkgroups, Comparator.comparingInt(Identifier::getValue));
|
||||
talkgroups.sort(Comparator.comparingInt(Identifier::getValue));
|
||||
|
||||
for(LTRTalkgroup talkgroup: talkgroups)
|
||||
{
|
||||
@@ -590,7 +590,7 @@ public class LTRNetDecoderState extends DecoderState
|
||||
else
|
||||
{
|
||||
List<LtrNetRadioIdentifier> ltrNetRadioIdentifiers = new ArrayList<>(mLtrNetRadioIdentifiers);
|
||||
Collections.sort(ltrNetRadioIdentifiers, Comparator.comparingInt(Identifier::getValue));
|
||||
ltrNetRadioIdentifiers.sort(Comparator.comparingInt(Identifier::getValue));
|
||||
|
||||
for(LtrNetRadioIdentifier ltrNetRadioIdentifier : ltrNetRadioIdentifiers)
|
||||
{
|
||||
|
||||
@@ -4,15 +4,13 @@ import io.github.dsheirer.filter.Filter;
|
||||
import io.github.dsheirer.filter.FilterElement;
|
||||
import io.github.dsheirer.message.IMessage;
|
||||
import io.github.dsheirer.module.decode.ltrnet.message.LtrNetMessage;
|
||||
import io.github.dsheirer.module.decode.ltrstandard.LtrStandardMessageType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public class LTRNetMessageFilter extends Filter<IMessage>
|
||||
{
|
||||
private Map<LtrNetMessageType, FilterElement<LtrNetMessageType>> mElements = new HashMap<>();
|
||||
private Map<LtrNetMessageType, FilterElement<LtrNetMessageType>> mElements = new EnumMap<>(LtrNetMessageType.class);
|
||||
|
||||
public LTRNetMessageFilter()
|
||||
{
|
||||
|
||||
@@ -24,15 +24,13 @@ import io.github.dsheirer.filter.Filter;
|
||||
import io.github.dsheirer.filter.FilterElement;
|
||||
import io.github.dsheirer.message.IMessage;
|
||||
import io.github.dsheirer.module.decode.ltrstandard.message.LTRStandardMessage;
|
||||
import io.github.dsheirer.module.decode.mdc1200.MDCMessageType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public class LTRStandardMessageFilter extends Filter<IMessage>
|
||||
{
|
||||
private Map<LtrStandardMessageType,FilterElement<LtrStandardMessageType>> mElements = new HashMap<>();
|
||||
private Map<LtrStandardMessageType,FilterElement<LtrStandardMessageType>> mElements = new EnumMap<>(LtrStandardMessageType.class);
|
||||
|
||||
public LTRStandardMessageFilter()
|
||||
{
|
||||
|
||||
@@ -152,11 +152,9 @@ public class MDCDecoderState extends DecoderState
|
||||
}
|
||||
else
|
||||
{
|
||||
Iterator<MDC1200Identifier> it = mIdents.iterator();
|
||||
|
||||
while(it.hasNext())
|
||||
{
|
||||
sb.append(" ").append(it.next()).append("\n");
|
||||
for (MDC1200Identifier mIdent : mIdents) {
|
||||
sb.append(" ").append(mIdent).append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,11 +170,9 @@ public class MDCDecoderState extends DecoderState
|
||||
|
||||
while(it.hasNext())
|
||||
{
|
||||
Iterator<MDC1200Identifier> it2 = mIdents.iterator();
|
||||
|
||||
while(it2.hasNext())
|
||||
{
|
||||
sb.append(" ").append(it2.next()).append("\n");
|
||||
for (MDC1200Identifier mIdent : mIdents) {
|
||||
sb.append(" ").append(mIdent).append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import io.github.dsheirer.identifier.Identifier;
|
||||
import io.github.dsheirer.message.Message;
|
||||
import io.github.dsheirer.module.decode.mdc1200.identifier.MDC1200Identifier;
|
||||
import io.github.dsheirer.protocol.Protocol;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -177,16 +178,7 @@ public class MDCMessage extends Message
|
||||
*/
|
||||
public String pad(String value, int places, String padCharacter)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append(value);
|
||||
|
||||
while(sb.length() < places)
|
||||
{
|
||||
sb.append(padCharacter);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
return StringUtils.rightPad(value, places, padCharacter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -194,18 +186,7 @@ public class MDCMessage extends Message
|
||||
*/
|
||||
public String format(int number, int decimalPlaces)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int paddingRequired = decimalPlaces - (String.valueOf(number).length());
|
||||
|
||||
for(int x = 0; x < paddingRequired; x++)
|
||||
{
|
||||
sb.append("0");
|
||||
}
|
||||
|
||||
sb.append(number);
|
||||
|
||||
return sb.toString();
|
||||
return StringUtils.leftPad(Integer.valueOf(number).toString(), decimalPlaces, '0');
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -219,7 +200,7 @@ public class MDCMessage extends Message
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append("MDC1200 UNIT:" + getFromIdentifier());
|
||||
sb.append("MDC1200 UNIT:").append(getFromIdentifier());
|
||||
if(isEmergency())
|
||||
{
|
||||
sb.append(" **EMERGENCY**");
|
||||
@@ -235,11 +216,11 @@ public class MDCMessage extends Message
|
||||
sb.append(" EOT");
|
||||
}
|
||||
|
||||
sb.append(" OPCODE:" + format(getOpcode(), 2));
|
||||
sb.append(" ARG:" + format(getArgument(), 3));
|
||||
sb.append(" TYPE:" + getPacketType().toString());
|
||||
sb.append(" ACK:" + getResponse().toString());
|
||||
sb.append(" DIR:" + pad(getDirection().toString(), 3, " "));
|
||||
sb.append(" OPCODE:").append(format(getOpcode(), 2));
|
||||
sb.append(" ARG:").append(format(getArgument(), 3));
|
||||
sb.append(" TYPE:").append(getPacketType().toString());
|
||||
sb.append(" ACK:").append(getResponse().toString());
|
||||
sb.append(" DIR:").append(pad(getDirection().toString(), 3, " "));
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -4,15 +4,13 @@ import io.github.dsheirer.filter.Filter;
|
||||
import io.github.dsheirer.filter.FilterElement;
|
||||
import io.github.dsheirer.message.IMessage;
|
||||
import io.github.dsheirer.message.Message;
|
||||
import io.github.dsheirer.module.decode.mpt1327.MPT1327Message;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public class MDCMessageFilter extends Filter<IMessage>
|
||||
{
|
||||
private Map<MDCMessageType, FilterElement<MDCMessageType>> mElements = new HashMap<MDCMessageType, FilterElement<MDCMessageType>>();
|
||||
private Map<MDCMessageType, FilterElement<MDCMessageType>> mElements = new EnumMap<>(MDCMessageType.class);
|
||||
|
||||
public MDCMessageFilter()
|
||||
{
|
||||
|
||||
@@ -411,12 +411,7 @@ public class MPT1327DecoderState extends DecoderState
|
||||
{
|
||||
sb.append("\n");
|
||||
|
||||
Iterator<String> it = mIdents.iterator();
|
||||
|
||||
while(it.hasNext())
|
||||
{
|
||||
String ident = it.next();
|
||||
|
||||
for (String ident : mIdents) {
|
||||
sb.append(ident);
|
||||
sb.append("\n");
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import io.github.dsheirer.identifier.Identifier;
|
||||
import io.github.dsheirer.message.Message;
|
||||
import io.github.dsheirer.module.decode.mpt1327.identifier.MPT1327Talkgroup;
|
||||
import io.github.dsheirer.protocol.Protocol;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
@@ -466,16 +467,7 @@ public class MPT1327Message extends Message
|
||||
*/
|
||||
public String pad(String value, int places, String padCharacter)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append(value);
|
||||
|
||||
while(sb.length() < places)
|
||||
{
|
||||
sb.append(padCharacter);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
return StringUtils.rightPad(value, places, padCharacter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -483,18 +475,7 @@ public class MPT1327Message extends Message
|
||||
*/
|
||||
public String format(int number, int decimalPlaces)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int paddingRequired = decimalPlaces - (String.valueOf(number).length());
|
||||
|
||||
for(int x = 0; x < paddingRequired; x++)
|
||||
{
|
||||
sb.append("0");
|
||||
}
|
||||
|
||||
sb.append(number);
|
||||
|
||||
return sb.toString();
|
||||
return StringUtils.leftPad(Integer.valueOf(number).toString(), decimalPlaces, '0');
|
||||
}
|
||||
|
||||
public String getMessage()
|
||||
|
||||
@@ -23,15 +23,13 @@ package io.github.dsheirer.module.decode.mpt1327;
|
||||
import io.github.dsheirer.filter.Filter;
|
||||
import io.github.dsheirer.filter.FilterElement;
|
||||
import io.github.dsheirer.message.IMessage;
|
||||
import io.github.dsheirer.message.MessageType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public class MPT1327MessageFilter extends Filter<IMessage>
|
||||
{
|
||||
private Map<MPT1327Message.MPTMessageType, FilterElement<MPT1327Message.MPTMessageType>> mFilterElements = new HashMap<>();
|
||||
private Map<MPT1327Message.MPTMessageType, FilterElement<MPT1327Message.MPTMessageType>> mFilterElements = new EnumMap<>(MPT1327Message.MPTMessageType.class);
|
||||
|
||||
public MPT1327MessageFilter()
|
||||
{
|
||||
|
||||
@@ -67,6 +67,7 @@ import java.util.Objects;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Monitors channel grant and channel grant update messages to allocate traffic channels to capture
|
||||
@@ -780,37 +781,12 @@ public class P25TrafficChannelManager extends Module implements IDecodeEventProv
|
||||
|
||||
if(channel.getDecodeConfiguration().getDecoderType() == DecoderType.P25_PHASE1)
|
||||
{
|
||||
List<APCO25Channel> channels = new ArrayList<>(mPhase1ChannelGrantEventMap.keySet());
|
||||
|
||||
for(APCO25Channel p25Channel: channels)
|
||||
{
|
||||
if(p25Channel.getDownlinkFrequency() == frequency)
|
||||
{
|
||||
mPhase1ChannelGrantEventMap.remove(p25Channel);
|
||||
}
|
||||
}
|
||||
mPhase1ChannelGrantEventMap.entrySet().removeIf(entry -> entry.getKey().getDownlinkFrequency() == frequency);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<APCO25Channel> channels = new ArrayList<>(mPhase2TS0ChannelGrantEventMap.keySet());
|
||||
|
||||
for(APCO25Channel p25Channel: channels)
|
||||
{
|
||||
if(p25Channel.getDownlinkFrequency() == frequency)
|
||||
{
|
||||
mPhase2TS0ChannelGrantEventMap.remove(p25Channel);
|
||||
}
|
||||
}
|
||||
|
||||
channels = new ArrayList<>(mPhase2TS1ChannelGrantEventMap.keySet());
|
||||
|
||||
for(APCO25Channel p25Channel: channels)
|
||||
{
|
||||
if(p25Channel.getDownlinkFrequency() == frequency)
|
||||
{
|
||||
mPhase2TS1ChannelGrantEventMap.remove(p25Channel);
|
||||
}
|
||||
}
|
||||
mPhase2TS0ChannelGrantEventMap.entrySet().removeIf(entry -> entry.getKey().getDownlinkFrequency() == frequency);
|
||||
mPhase2TS1ChannelGrantEventMap.entrySet().removeIf(entry -> entry.getKey().getDownlinkFrequency() == frequency);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -824,82 +800,56 @@ public class P25TrafficChannelManager extends Module implements IDecodeEventProv
|
||||
{
|
||||
boolean isPhase1 = channel.getDecodeConfiguration().getDecoderType() == DecoderType.P25_PHASE1;
|
||||
|
||||
if((isPhase1 && mManagedPhase1TrafficChannels.contains(channel)) ||
|
||||
(!isPhase1 && mManagedPhase2TrafficChannels.contains(channel)))
|
||||
if(isPhase1 ? mManagedPhase1TrafficChannels.contains(channel) : mManagedPhase2TrafficChannels.contains(channel))
|
||||
{
|
||||
switch(channelEvent.getEvent())
|
||||
{
|
||||
case NOTIFICATION_PROCESSING_STOP:
|
||||
APCO25Channel toRemove = null;
|
||||
mAllocatedTrafficChannelMap.entrySet()
|
||||
.stream()
|
||||
.filter(entry -> entry.getValue() == channel)
|
||||
.map(Map.Entry::getKey)
|
||||
.findFirst()
|
||||
.ifPresent(toRemove -> {
|
||||
mAllocatedTrafficChannelMap.remove(toRemove);
|
||||
|
||||
for(Map.Entry<APCO25Channel,Channel> entry: mAllocatedTrafficChannelMap.entrySet())
|
||||
{
|
||||
if(entry.getValue() == channel)
|
||||
{
|
||||
toRemove = entry.getKey();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(toRemove != null)
|
||||
{
|
||||
mAllocatedTrafficChannelMap.remove(toRemove);
|
||||
|
||||
if(isPhase1)
|
||||
{
|
||||
mAvailablePhase1TrafficChannelQueue.add(channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
mAvailablePhase2TrafficChannelQueue.add(channel);
|
||||
}
|
||||
}
|
||||
if (isPhase1) {
|
||||
mAvailablePhase1TrafficChannelQueue.add(channel);
|
||||
} else {
|
||||
mAvailablePhase2TrafficChannelQueue.add(channel);
|
||||
}
|
||||
});
|
||||
|
||||
cleanupCallEvents(channel);
|
||||
break;
|
||||
case NOTIFICATION_PROCESSING_START_REJECTED:
|
||||
APCO25Channel rejected = null;
|
||||
mAllocatedTrafficChannelMap.entrySet().stream()
|
||||
.filter(entry -> entry.getValue() == channel)
|
||||
.map(Map.Entry::getKey)
|
||||
.findFirst()
|
||||
.ifPresent(rejected -> {
|
||||
mAllocatedTrafficChannelMap.remove(rejected);
|
||||
|
||||
for(Map.Entry<APCO25Channel,Channel> entry: mAllocatedTrafficChannelMap.entrySet())
|
||||
{
|
||||
if(entry.getValue() == channel)
|
||||
{
|
||||
rejected = entry.getKey();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (isPhase1) {
|
||||
mAvailablePhase1TrafficChannelQueue.add(channel);
|
||||
} else {
|
||||
mAvailablePhase2TrafficChannelQueue.add(channel);
|
||||
}
|
||||
|
||||
if(rejected != null)
|
||||
{
|
||||
mAllocatedTrafficChannelMap.remove(rejected);
|
||||
P25ChannelGrantEvent event = mPhase1ChannelGrantEventMap.get(rejected);
|
||||
|
||||
if(isPhase1)
|
||||
{
|
||||
mAvailablePhase1TrafficChannelQueue.add(channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
mAvailablePhase2TrafficChannelQueue.add(channel);
|
||||
}
|
||||
if (event != null) {
|
||||
event.setEventDescription(event.getEventDescription() + " - Rejected");
|
||||
|
||||
P25ChannelGrantEvent event = mPhase1ChannelGrantEventMap.get(rejected);
|
||||
if (channelEvent.getDescription() != null) {
|
||||
event.setDetails(channelEvent.getDescription() + " - " + event.getDetails());
|
||||
} else {
|
||||
event.setDetails(CHANNEL_START_REJECTED + " - " + event.getDetails());
|
||||
}
|
||||
|
||||
if(event != null)
|
||||
{
|
||||
event.setEventDescription(event.getEventDescription() + " - Rejected");
|
||||
|
||||
if(channelEvent.getDescription() != null)
|
||||
{
|
||||
event.setDetails(channelEvent.getDescription() + " - " + event.getDetails());
|
||||
}
|
||||
else
|
||||
{
|
||||
event.setDetails(CHANNEL_START_REJECTED + " - " + event.getDetails());
|
||||
}
|
||||
|
||||
broadcast(event);
|
||||
}
|
||||
}
|
||||
broadcast(event);
|
||||
}
|
||||
});
|
||||
|
||||
cleanupCallEvents(channel);
|
||||
break;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package io.github.dsheirer.module.decode.p25;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class P25Utils
|
||||
{
|
||||
/**
|
||||
@@ -20,20 +22,7 @@ public class P25Utils
|
||||
*/
|
||||
public static String formatHex(int value, int places)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String formatted = Integer.toHexString(value).toUpperCase();
|
||||
|
||||
if(formatted.length() < places)
|
||||
{
|
||||
for(int x = 0; x < (places - formatted.length()); x++)
|
||||
{
|
||||
sb.append("0");
|
||||
}
|
||||
}
|
||||
|
||||
sb.append(formatted);
|
||||
|
||||
return sb.toString();
|
||||
return StringUtils.leftPad(Integer.toHexString(value).toUpperCase(), places, '0');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -219,131 +219,25 @@ public class P25P2CallSequenceRecorder extends MBECallSequenceRecorder
|
||||
switch(mac.getOpcode())
|
||||
{
|
||||
case PUSH_TO_TALK:
|
||||
if(mac instanceof PushToTalk)
|
||||
{
|
||||
PushToTalk ptt = (PushToTalk)mac;
|
||||
|
||||
if(mCallSequence == null)
|
||||
{
|
||||
mCallSequence = new MBECallSequence(PROTOCOL);
|
||||
}
|
||||
mCallSequence.setFromIdentifier(ptt.getSourceAddress().toString());
|
||||
mCallSequence.setToIdentifier(ptt.getGroupAddress().toString());
|
||||
|
||||
if(ptt.isEncrypted())
|
||||
{
|
||||
mCallSequence.setEncrypted(true);
|
||||
mCallSequence.setEncryptionSyncParameters(ptt.getEncryptionSyncParameters());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.warn("Expected push-to-talk structure but found: " + mac.getClass());
|
||||
}
|
||||
processPTT(mac);
|
||||
break;
|
||||
case END_PUSH_TO_TALK:
|
||||
if(mac instanceof EndPushToTalk)
|
||||
{
|
||||
EndPushToTalk eptt = (EndPushToTalk)mac;
|
||||
|
||||
String source = eptt.getSourceAddress().toString();
|
||||
|
||||
if(source != null && !source.contentEquals("16777215"))
|
||||
{
|
||||
mCallSequence.setFromIdentifier(source);
|
||||
}
|
||||
mCallSequence.setToIdentifier(eptt.getGroupAddress().toString());
|
||||
writeCallSequence(mCallSequence, "TS" + getTimeslot());
|
||||
mCallSequence = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.warn("Expected End push-to-talk structure but found: " + mac.getClass());
|
||||
}
|
||||
processEndPTT(mac);
|
||||
break;
|
||||
case TDMA_1_GROUP_VOICE_CHANNEL_USER_ABBREVIATED:
|
||||
if(mac instanceof GroupVoiceChannelUserAbbreviated)
|
||||
{
|
||||
GroupVoiceChannelUserAbbreviated gvcua = (GroupVoiceChannelUserAbbreviated)mac;
|
||||
mCallSequence.setFromIdentifier(gvcua.getSourceAddress().toString());
|
||||
mCallSequence.setToIdentifier(gvcua.getGroupAddress().toString());
|
||||
mCallSequence.setCallType(CALL_TYPE_GROUP);
|
||||
if(gvcua.getServiceOptions().isEncrypted())
|
||||
{
|
||||
mCallSequence.setEncrypted(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.warn("Expected group voice channel user abbreviated but found: " + mac.getClass());
|
||||
}
|
||||
processGVCUA(mac);
|
||||
break;
|
||||
case TDMA_2_UNIT_TO_UNIT_VOICE_CHANNEL_USER:
|
||||
if(mac instanceof UnitToUnitVoiceChannelUserAbbreviated)
|
||||
{
|
||||
UnitToUnitVoiceChannelUserAbbreviated uuvcua = (UnitToUnitVoiceChannelUserAbbreviated)mac;
|
||||
mCallSequence.setFromIdentifier(uuvcua.getSourceAddress().toString());
|
||||
mCallSequence.setToIdentifier(uuvcua.getTargetAddress().toString());
|
||||
mCallSequence.setCallType(CALL_TYPE_INDIVIDUAL);
|
||||
if(uuvcua.getServiceOptions().isEncrypted())
|
||||
{
|
||||
mCallSequence.setEncrypted(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.warn("Expected unit-2-unit voice channel user abbreviated but found: " + mac.getClass());
|
||||
}
|
||||
processUTUVCU(mac);
|
||||
break;
|
||||
case TDMA_3_TELEPHONE_INTERCONNECT_VOICE_CHANNEL_USER:
|
||||
if(mac instanceof TelephoneInterconnectVoiceChannelUser)
|
||||
{
|
||||
TelephoneInterconnectVoiceChannelUser tivcu = (TelephoneInterconnectVoiceChannelUser)mac;
|
||||
mCallSequence.setToIdentifier(tivcu.getToOrFromAddress().toString());
|
||||
mCallSequence.setCallType(CALL_TYPE_TELEPHONE_INTERCONNECT);
|
||||
if(tivcu.getServiceOptions().isEncrypted())
|
||||
{
|
||||
mCallSequence.setEncrypted(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.warn("Expected telephone interconnect voice channel user abbreviated but found: " + mac.getClass());
|
||||
}
|
||||
processTIVCU(mac);
|
||||
break;
|
||||
case TDMA_33_GROUP_VOICE_CHANNEL_USER_EXTENDED:
|
||||
if(mac instanceof GroupVoiceChannelUserExtended)
|
||||
{
|
||||
GroupVoiceChannelUserExtended gvcue = (GroupVoiceChannelUserExtended)mac;
|
||||
mCallSequence.setFromIdentifier(gvcue.getSourceAddress().toString());
|
||||
mCallSequence.setToIdentifier(gvcue.getGroupAddress().toString());
|
||||
mCallSequence.setCallType(CALL_TYPE_GROUP);
|
||||
if(gvcue.getServiceOptions().isEncrypted())
|
||||
{
|
||||
mCallSequence.setEncrypted(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.warn("Expected group voice channel user extended but found: " + mac.getClass());
|
||||
}
|
||||
processGVCUE(mac);
|
||||
break;
|
||||
case TDMA_34_UNIT_TO_UNIT_VOICE_CHANNEL_USER_EXTENDED:
|
||||
if(mac instanceof UnitToUnitVoiceChannelUserExtended)
|
||||
{
|
||||
UnitToUnitVoiceChannelUserExtended uuvcue = (UnitToUnitVoiceChannelUserExtended)mac;
|
||||
mCallSequence.setFromIdentifier(uuvcue.getSourceAddress().toString());
|
||||
mCallSequence.setToIdentifier(uuvcue.getTargetAddress().toString());
|
||||
mCallSequence.setCallType(CALL_TYPE_INDIVIDUAL);
|
||||
if(uuvcue.getServiceOptions().isEncrypted())
|
||||
{
|
||||
mCallSequence.setEncrypted(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.warn("Expected unit-2-unit voice channel user extended but found: " + mac.getClass());
|
||||
}
|
||||
processUTUVCUE(mac);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -354,5 +248,139 @@ public class P25P2CallSequenceRecorder extends MBECallSequenceRecorder
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processUTUVCUE(MacStructure mac) {
|
||||
if(mac instanceof UnitToUnitVoiceChannelUserExtended)
|
||||
{
|
||||
UnitToUnitVoiceChannelUserExtended uuvcue = (UnitToUnitVoiceChannelUserExtended)mac;
|
||||
mCallSequence.setFromIdentifier(uuvcue.getSourceAddress().toString());
|
||||
mCallSequence.setToIdentifier(uuvcue.getTargetAddress().toString());
|
||||
mCallSequence.setCallType(CALL_TYPE_INDIVIDUAL);
|
||||
if(uuvcue.getServiceOptions().isEncrypted())
|
||||
{
|
||||
mCallSequence.setEncrypted(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.warn("Expected unit-2-unit voice channel user extended but found: " + mac.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
private void processGVCUE(MacStructure mac) {
|
||||
if(mac instanceof GroupVoiceChannelUserExtended)
|
||||
{
|
||||
GroupVoiceChannelUserExtended gvcue = (GroupVoiceChannelUserExtended)mac;
|
||||
mCallSequence.setFromIdentifier(gvcue.getSourceAddress().toString());
|
||||
mCallSequence.setToIdentifier(gvcue.getGroupAddress().toString());
|
||||
mCallSequence.setCallType(CALL_TYPE_GROUP);
|
||||
if(gvcue.getServiceOptions().isEncrypted())
|
||||
{
|
||||
mCallSequence.setEncrypted(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.warn("Expected group voice channel user extended but found: " + mac.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
private void processTIVCU(MacStructure mac) {
|
||||
if(mac instanceof TelephoneInterconnectVoiceChannelUser)
|
||||
{
|
||||
TelephoneInterconnectVoiceChannelUser tivcu = (TelephoneInterconnectVoiceChannelUser)mac;
|
||||
mCallSequence.setToIdentifier(tivcu.getToOrFromAddress().toString());
|
||||
mCallSequence.setCallType(CALL_TYPE_TELEPHONE_INTERCONNECT);
|
||||
if(tivcu.getServiceOptions().isEncrypted())
|
||||
{
|
||||
mCallSequence.setEncrypted(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.warn("Expected telephone interconnect voice channel user abbreviated but found: " + mac.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
private void processUTUVCU(MacStructure mac) {
|
||||
if(mac instanceof UnitToUnitVoiceChannelUserAbbreviated)
|
||||
{
|
||||
UnitToUnitVoiceChannelUserAbbreviated uuvcua = (UnitToUnitVoiceChannelUserAbbreviated)mac;
|
||||
mCallSequence.setFromIdentifier(uuvcua.getSourceAddress().toString());
|
||||
mCallSequence.setToIdentifier(uuvcua.getTargetAddress().toString());
|
||||
mCallSequence.setCallType(CALL_TYPE_INDIVIDUAL);
|
||||
if(uuvcua.getServiceOptions().isEncrypted())
|
||||
{
|
||||
mCallSequence.setEncrypted(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.warn("Expected unit-2-unit voice channel user abbreviated but found: " + mac.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
private void processGVCUA(MacStructure mac) {
|
||||
if(mac instanceof GroupVoiceChannelUserAbbreviated)
|
||||
{
|
||||
GroupVoiceChannelUserAbbreviated gvcua = (GroupVoiceChannelUserAbbreviated)mac;
|
||||
mCallSequence.setFromIdentifier(gvcua.getSourceAddress().toString());
|
||||
mCallSequence.setToIdentifier(gvcua.getGroupAddress().toString());
|
||||
mCallSequence.setCallType(CALL_TYPE_GROUP);
|
||||
if(gvcua.getServiceOptions().isEncrypted())
|
||||
{
|
||||
mCallSequence.setEncrypted(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.warn("Expected group voice channel user abbreviated but found: " + mac.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
private void processEndPTT(MacStructure mac) {
|
||||
if(mac instanceof EndPushToTalk)
|
||||
{
|
||||
EndPushToTalk eptt = (EndPushToTalk)mac;
|
||||
|
||||
String source = eptt.getSourceAddress().toString();
|
||||
|
||||
if(source != null && !source.contentEquals("16777215"))
|
||||
{
|
||||
mCallSequence.setFromIdentifier(source);
|
||||
}
|
||||
mCallSequence.setToIdentifier(eptt.getGroupAddress().toString());
|
||||
writeCallSequence(mCallSequence, "TS" + getTimeslot());
|
||||
mCallSequence = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.warn("Expected End push-to-talk structure but found: " + mac.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
private void processPTT(MacStructure mac) {
|
||||
if(mac instanceof PushToTalk)
|
||||
{
|
||||
PushToTalk ptt = (PushToTalk)mac;
|
||||
|
||||
if(mCallSequence == null)
|
||||
{
|
||||
mCallSequence = new MBECallSequence(PROTOCOL);
|
||||
}
|
||||
mCallSequence.setFromIdentifier(ptt.getSourceAddress().toString());
|
||||
mCallSequence.setToIdentifier(ptt.getGroupAddress().toString());
|
||||
|
||||
if(ptt.isEncrypted())
|
||||
{
|
||||
mCallSequence.setEncrypted(true);
|
||||
mCallSequence.setEncryptionSyncParameters(ptt.getEncryptionSyncParameters());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.warn("Expected push-to-talk structure but found: " + mac.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import io.github.dsheirer.sample.real.RealSampleListener;
|
||||
import io.github.dsheirer.sample.real.RealSampleProvider;
|
||||
import io.github.dsheirer.source.ISourceEventListener;
|
||||
import io.github.dsheirer.source.SourceEvent;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
public class C4FMSymbolFilter implements Listener<ReusableFloatBuffer>, ISourceEventListener, RealSampleProvider
|
||||
{
|
||||
@@ -289,7 +290,7 @@ public class C4FMSymbolFilter implements Listener<ReusableFloatBuffer>, ISourceE
|
||||
{
|
||||
mSymbolClock -= 1.0f;
|
||||
|
||||
int imu = (int)Math.floor(0.5 +
|
||||
int imu = (int) FastMath.floor(0.5 +
|
||||
((float)NUMBER_FILTER_STEPS * (mSymbolClock / mSymbolTime)));
|
||||
|
||||
if(imu >= NUMBER_FILTER_STEPS)
|
||||
@@ -380,7 +381,7 @@ public class C4FMSymbolFilter implements Listener<ReusableFloatBuffer>, ISourceE
|
||||
mFineFrequencyCorrection += (symbolError * K_FINE_FREQUENCY);
|
||||
|
||||
/* Queue a frequency adjustment (once per buffer) as needed */
|
||||
if(Math.abs(mCoarseFrequencyCorrection) > COARSE_FREQUENCY_THRESHOLD)
|
||||
if(FastMath.abs(mCoarseFrequencyCorrection) > COARSE_FREQUENCY_THRESHOLD)
|
||||
{
|
||||
mFrequencyAdjustmentRequested =
|
||||
500 * (mCoarseFrequencyCorrection > 0 ? 1 : -1);
|
||||
|
||||
@@ -436,11 +436,11 @@ public class P25P1DataUnitDetector implements Listener<Dibit>, ISyncDetectListen
|
||||
|
||||
if(this instanceof NIDDelayBuffer)
|
||||
{
|
||||
mLog.debug("NIDBUF: " + sb.toString() + " Length:" + mBuffer.length);
|
||||
mLog.debug("NIDBUF: " + sb + " Length:" + mBuffer.length);
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.debug("SYNBUF: " + sb.toString() + " Length:" + mBuffer.length);
|
||||
mLog.debug("SYNBUF: " + sb + " Length:" + mBuffer.length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -535,11 +535,11 @@ public class P25P1DataUnitDetector implements Listener<Dibit>, ISyncDetectListen
|
||||
|
||||
if(corrected)
|
||||
{
|
||||
mLog.debug("C* NID: " + sb.toString());
|
||||
mLog.debug("C* NID: " + sb);
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.debug(" NID: " + sb.toString());
|
||||
mLog.debug(" NID: " + sb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -48,17 +48,12 @@ import io.github.dsheirer.module.decode.p25.phase1.message.tsbk.standard.osp.SND
|
||||
import io.github.dsheirer.module.decode.p25.phase1.message.tsbk.standard.osp.SecondaryControlChannelBroadcast;
|
||||
import io.github.dsheirer.module.decode.p25.phase1.message.tsbk.standard.osp.SecondaryControlChannelBroadcastExplicit;
|
||||
import io.github.dsheirer.module.decode.p25.phase1.message.tsbk.standard.osp.SystemServiceBroadcast;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
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.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Tracks the network configuration details of a P25 Phase 1 network from the broadcast messages
|
||||
@@ -334,12 +329,7 @@ public class P25P1NetworkConfigurationMonitor
|
||||
{
|
||||
if(identifier.getValue() instanceof Integer)
|
||||
{
|
||||
String hex = Integer.toHexString((Integer)identifier.getValue());
|
||||
|
||||
while(hex.length() < width)
|
||||
{
|
||||
hex = "0" + hex;
|
||||
}
|
||||
String hex = StringUtils.leftPad(Integer.toHexString((Integer)identifier.getValue()), width, '0');
|
||||
|
||||
return hex.toUpperCase() + "[" + identifier.getValue() + "]";
|
||||
}
|
||||
@@ -438,20 +428,16 @@ public class P25P1NetworkConfigurationMonitor
|
||||
|
||||
if(!mSecondaryControlChannels.isEmpty())
|
||||
{
|
||||
List<String> channels = new ArrayList<>(mSecondaryControlChannels.keySet());
|
||||
Collections.sort(channels);
|
||||
|
||||
for(String channel : channels)
|
||||
{
|
||||
IChannelDescriptor secondaryControlChannel = mSecondaryControlChannels.get(channel);
|
||||
|
||||
if(secondaryControlChannel != null)
|
||||
{
|
||||
sb.append(" SEC CONTROL CHANNEL:").append(secondaryControlChannel);
|
||||
sb.append(" DOWNLINK:").append(secondaryControlChannel.getDownlinkFrequency());
|
||||
sb.append(" UPLINK:").append(secondaryControlChannel.getUplinkFrequency()).append("\n");
|
||||
}
|
||||
}
|
||||
mSecondaryControlChannels
|
||||
.entrySet()
|
||||
.stream()
|
||||
.sorted(Map.Entry.comparingByKey())
|
||||
.filter(Objects::nonNull)
|
||||
.forEach(entry -> {
|
||||
sb.append(" SEC CONTROL CHANNEL:").append(entry.getValue());
|
||||
sb.append(" DOWNLINK:").append(entry.getValue().getDownlinkFrequency());
|
||||
sb.append(" UPLINK:").append(entry.getValue().getUplinkFrequency()).append("\n");
|
||||
});
|
||||
}
|
||||
|
||||
if(mSNDCPDataChannel != null)
|
||||
@@ -463,7 +449,7 @@ public class P25P1NetworkConfigurationMonitor
|
||||
|
||||
if(mMotorolaBaseStationId != null)
|
||||
{
|
||||
sb.append(" STATION ID/LICENSE: " + mMotorolaBaseStationId.getCWID()).append("\n");
|
||||
sb.append(" STATION ID/LICENSE: ").append(mMotorolaBaseStationId.getCWID()).append("\n");
|
||||
}
|
||||
|
||||
if(mTSBKSystemServiceBroadcast != null)
|
||||
@@ -490,60 +476,59 @@ public class P25P1NetworkConfigurationMonitor
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Integer> sitesSorted = new ArrayList<>(sites);
|
||||
Collections.sort(sitesSorted);
|
||||
sites
|
||||
.stream()
|
||||
.sorted()
|
||||
.forEach(site -> {
|
||||
if(mAMBTCNeighborSites.containsKey(site))
|
||||
{
|
||||
AMBTCAdjacentStatusBroadcast ambtc = mAMBTCNeighborSites.get(site);
|
||||
sb.append(" SYSTEM:").append(format(ambtc.getSystem(), 3));
|
||||
sb.append(" NAC:").append(format(ambtc.getNAC(), 3));
|
||||
sb.append(" RFSS:").append(format(ambtc.getRfss(), 2));
|
||||
sb.append(" SITE:").append(format(ambtc.getSite(), 2));
|
||||
sb.append(" LRA:").append(format(ambtc.getLocationRegistrationArea(), 2));
|
||||
sb.append(" CHANNEL:").append(ambtc.getChannel());
|
||||
sb.append(" DOWNLINK:").append(ambtc.getChannel().getDownlinkFrequency());
|
||||
sb.append(" UPLINK:").append(ambtc.getChannel().getUplinkFrequency()).append("\n");
|
||||
}
|
||||
if(mLCNeighborSites.containsKey(site))
|
||||
{
|
||||
LCAdjacentSiteStatusBroadcast lc = mLCNeighborSites.get(site);
|
||||
sb.append(" SYSTEM:").append(format(lc.getSystem(), 3));
|
||||
sb.append(" RFSS:").append(format(lc.getRfss(), 2));
|
||||
sb.append(" SITE:").append(format(lc.getSite(), 2));
|
||||
sb.append(" LRA:").append(format(lc.getLocationRegistrationArea(), 2));
|
||||
sb.append(" CHANNEL:").append(lc.getChannel());
|
||||
sb.append(" DOWNLINK:").append(lc.getChannel().getDownlinkFrequency());
|
||||
sb.append(" UPLINK:").append(lc.getChannel().getUplinkFrequency()).append("\n");
|
||||
|
||||
for(Integer site : sitesSorted)
|
||||
{
|
||||
if(mAMBTCNeighborSites.containsKey(site))
|
||||
{
|
||||
AMBTCAdjacentStatusBroadcast ambtc = mAMBTCNeighborSites.get(site);
|
||||
sb.append(" SYSTEM:").append(format(ambtc.getSystem(), 3));
|
||||
sb.append(" NAC:").append(format(ambtc.getNAC(), 3));
|
||||
sb.append(" RFSS:").append(format(ambtc.getRfss(), 2));
|
||||
sb.append(" SITE:").append(format(ambtc.getSite(), 2));
|
||||
sb.append(" LRA:").append(format(ambtc.getLocationRegistrationArea(), 2));
|
||||
sb.append(" CHANNEL:").append(ambtc.getChannel());
|
||||
sb.append(" DOWNLINK:").append(ambtc.getChannel().getDownlinkFrequency());
|
||||
sb.append(" UPLINK:").append(ambtc.getChannel().getUplinkFrequency()).append("\n");
|
||||
}
|
||||
if(mLCNeighborSites.containsKey(site))
|
||||
{
|
||||
LCAdjacentSiteStatusBroadcast lc = mLCNeighborSites.get(site);
|
||||
sb.append(" SYSTEM:").append(format(lc.getSystem(), 3));
|
||||
sb.append(" RFSS:").append(format(lc.getRfss(), 2));
|
||||
sb.append(" SITE:").append(format(lc.getSite(), 2));
|
||||
sb.append(" LRA:").append(format(lc.getLocationRegistrationArea(), 2));
|
||||
sb.append(" CHANNEL:").append(lc.getChannel());
|
||||
sb.append(" DOWNLINK:").append(lc.getChannel().getDownlinkFrequency());
|
||||
sb.append(" UPLINK:").append(lc.getChannel().getUplinkFrequency()).append("\n");
|
||||
|
||||
}
|
||||
if(mLCNeighborSitesExplicit.containsKey(site))
|
||||
{
|
||||
LCAdjacentSiteStatusBroadcastExplicit lce = mLCNeighborSitesExplicit.get(site);
|
||||
sb.append(" SYSTEM:---");
|
||||
sb.append(" RFSS:").append(format(lce.getRfss(), 2));
|
||||
sb.append(" SITE:").append(format(lce.getSite(), 2));
|
||||
sb.append(" LRA:").append(format(lce.getLocationRegistrationArea(), 2));
|
||||
sb.append(" CHANNEL:").append(lce.getChannel());
|
||||
sb.append(" DOWNLINK:").append(lce.getChannel().getDownlinkFrequency());
|
||||
sb.append(" UPLINK:").append(lce.getChannel().getUplinkFrequency()).append("\n");
|
||||
}
|
||||
if(mTSBKNeighborSites.containsKey(site))
|
||||
{
|
||||
AdjacentStatusBroadcast asb = mTSBKNeighborSites.get(site);
|
||||
sb.append(" SYSTEM:").append(format(asb.getSystem(), 3));
|
||||
sb.append(" NAC:").append(format(asb.getNAC(), 3));
|
||||
sb.append(" RFSS:").append(format(asb.getRfss(), 2));
|
||||
sb.append(" SITE:").append(format(asb.getSite(), 2));
|
||||
sb.append(" LRA:").append(format(asb.getLocationRegistrationArea(), 2));
|
||||
sb.append(" CHANNEL:").append(asb.getChannel());
|
||||
sb.append(" DOWNLINK:").append(asb.getChannel().getDownlinkFrequency());
|
||||
sb.append(" UPLINK:").append(asb.getChannel().getUplinkFrequency());
|
||||
sb.append(" STATUS:").append(asb.getSiteFlags()).append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if(mLCNeighborSitesExplicit.containsKey(site))
|
||||
{
|
||||
LCAdjacentSiteStatusBroadcastExplicit lce = mLCNeighborSitesExplicit.get(site);
|
||||
sb.append(" SYSTEM:---");
|
||||
sb.append(" RFSS:").append(format(lce.getRfss(), 2));
|
||||
sb.append(" SITE:").append(format(lce.getSite(), 2));
|
||||
sb.append(" LRA:").append(format(lce.getLocationRegistrationArea(), 2));
|
||||
sb.append(" CHANNEL:").append(lce.getChannel());
|
||||
sb.append(" DOWNLINK:").append(lce.getChannel().getDownlinkFrequency());
|
||||
sb.append(" UPLINK:").append(lce.getChannel().getUplinkFrequency()).append("\n");
|
||||
}
|
||||
if(mTSBKNeighborSites.containsKey(site))
|
||||
{
|
||||
AdjacentStatusBroadcast asb = mTSBKNeighborSites.get(site);
|
||||
sb.append(" SYSTEM:").append(format(asb.getSystem(), 3));
|
||||
sb.append(" NAC:").append(format(asb.getNAC(), 3));
|
||||
sb.append(" RFSS:").append(format(asb.getRfss(), 2));
|
||||
sb.append(" SITE:").append(format(asb.getSite(), 2));
|
||||
sb.append(" LRA:").append(format(asb.getLocationRegistrationArea(), 2));
|
||||
sb.append(" CHANNEL:").append(asb.getChannel());
|
||||
sb.append(" DOWNLINK:").append(asb.getChannel().getDownlinkFrequency());
|
||||
sb.append(" UPLINK:").append(asb.getChannel().getUplinkFrequency());
|
||||
sb.append(" STATUS:").append(asb.getSiteFlags()).append("\n");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
sb.append("\nFrequency Bands\n");
|
||||
@@ -553,14 +538,10 @@ public class P25P1NetworkConfigurationMonitor
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Integer> ids = new ArrayList<>(mFrequencyBandMap.keySet());
|
||||
Collections.sort(ids);
|
||||
{
|
||||
for(Integer id : ids)
|
||||
{
|
||||
sb.append(" ").append(formatFrequencyBand(mFrequencyBandMap.get(id))).append("\n");
|
||||
}
|
||||
}
|
||||
mFrequencyBandMap.entrySet()
|
||||
.stream()
|
||||
.sorted(Map.Entry.comparingByKey())
|
||||
.forEach(entry -> sb.append(" ").append(formatFrequencyBand(entry.getValue())).append("\n"));
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
|
||||
@@ -29,6 +29,7 @@ import io.github.dsheirer.dsp.symbol.Dibit;
|
||||
import io.github.dsheirer.dsp.symbol.FrameSync;
|
||||
import io.github.dsheirer.dsp.symbol.ISyncDetectListener;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
public class P25P1SyncDetector implements Listener<Dibit>
|
||||
{
|
||||
@@ -163,7 +164,7 @@ public class P25P1SyncDetector implements Listener<Dibit>
|
||||
public void setSampleRate(double sampleRate)
|
||||
{
|
||||
mSampleRate = sampleRate;
|
||||
mPllCorrection = 2.0 * Math.PI * mFrequencyCorrection / mSampleRate;
|
||||
mPllCorrection = 2.0 * FastMath.PI * mFrequencyCorrection / mSampleRate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,15 +25,13 @@ import io.github.dsheirer.filter.FilterElement;
|
||||
import io.github.dsheirer.message.IMessage;
|
||||
import io.github.dsheirer.module.decode.p25.phase1.message.pdu.PDUMessage;
|
||||
import io.github.dsheirer.module.decode.p25.phase1.message.tsbk.Opcode;
|
||||
import io.github.dsheirer.protocol.Protocol;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public class PDUMessageFilter extends Filter<IMessage>
|
||||
{
|
||||
private Map<Opcode, FilterElement<Opcode>> mOpcodeFilterElements = new HashMap<Opcode, FilterElement<Opcode>>();
|
||||
private Map<Opcode, FilterElement<Opcode>> mOpcodeFilterElements = new EnumMap<>(Opcode.class);
|
||||
|
||||
public PDUMessageFilter()
|
||||
{
|
||||
|
||||
@@ -28,9 +28,7 @@ import io.github.dsheirer.module.decode.p25.phase1.message.tsbk.Opcode;
|
||||
import io.github.dsheirer.module.decode.p25.phase1.message.tsbk.TSBKMessage;
|
||||
import io.github.dsheirer.module.decode.p25.reference.Vendor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
public class TSBKMessageFilterSet extends FilterSet<IMessage>
|
||||
{
|
||||
@@ -69,8 +67,7 @@ public class TSBKMessageFilterSet extends FilterSet<IMessage>
|
||||
|
||||
public class StandardOpcodeFilter extends Filter<IMessage>
|
||||
{
|
||||
private HashMap<Opcode, FilterElement<Opcode>> mStandardElements =
|
||||
new HashMap<Opcode, FilterElement<Opcode>>();
|
||||
private Map<Opcode, FilterElement<Opcode>> mStandardElements = new EnumMap<>(Opcode.class);
|
||||
|
||||
public StandardOpcodeFilter()
|
||||
{
|
||||
|
||||
@@ -77,6 +77,9 @@ public class HDUMessage extends P25Message
|
||||
private static final int[] RS_HEX_14 = {612, 613, 614, 615, 616, 617};
|
||||
private static final int[] RS_HEX_15 = {630, 631, 632, 633, 634, 635};
|
||||
|
||||
//Reed-Solomon(36,20,17) code protects the header word. Maximum correctable errors are: 8
|
||||
private static final ReedSolomon_63_47_17 reedSolomon_63_47_17 = new ReedSolomon_63_47_17(8);
|
||||
|
||||
private HeaderData mHeaderData;
|
||||
|
||||
public HDUMessage(CorrectedBinaryMessage message, int nac, long timestamp)
|
||||
@@ -157,9 +160,6 @@ public class HDUMessage extends P25Message
|
||||
input[35] = getMessage().getInt(CW_HEX_0);
|
||||
/* indexes 36 - 62 are defaulted to zero */
|
||||
|
||||
//Reed-Solomon(36,20,17) code protects the header word. Maximum correctable errors are: 8
|
||||
ReedSolomon_63_47_17 reedSolomon_63_47_17 = new ReedSolomon_63_47_17(8);
|
||||
|
||||
boolean irrecoverableErrors;
|
||||
|
||||
try
|
||||
|
||||
@@ -70,7 +70,7 @@ public class HeaderData
|
||||
|
||||
if(isValid())
|
||||
{
|
||||
sb.append("TALKGROUP:" + getTalkgroup());
|
||||
sb.append("TALKGROUP:").append(getTalkgroup());
|
||||
|
||||
Vendor vendor = getVendor();
|
||||
|
||||
|
||||
@@ -72,11 +72,11 @@ public class LCAdjacentSiteStatusBroadcast extends LinkControlWord implements IF
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(getMessageStub());
|
||||
sb.append(" RFSS:" + getRfss());
|
||||
sb.append(" SITE:" + getSite());
|
||||
sb.append(" RFSS:").append(getRfss());
|
||||
sb.append(" SITE:").append(getSite());
|
||||
sb.append(" SYSTEM:").append(getSystem());
|
||||
sb.append(" LRA:").append(getLocationRegistrationArea());
|
||||
sb.append(" CHAN:" + getChannel());
|
||||
sb.append(" CHAN:").append(getChannel());
|
||||
sb.append(" SERVICE OPTIONS:").append(getSystemServiceClass());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -71,10 +71,10 @@ public class LCAdjacentSiteStatusBroadcastExplicit extends LinkControlWord imple
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(getMessageStub());
|
||||
sb.append(" RFSS:" + getRfss());
|
||||
sb.append(" SITE:" + getSite());
|
||||
sb.append(" RFSS:").append(getRfss());
|
||||
sb.append(" SITE:").append(getSite());
|
||||
sb.append(" LRA:").append(getLocationRegistrationArea());
|
||||
sb.append(" CHAN:" + getChannel());
|
||||
sb.append(" CHAN:").append(getChannel());
|
||||
sb.append(" SERVICE OPTIONS:").append(getSystemServiceClass());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -69,8 +69,8 @@ public class LCNetworkStatusBroadcast extends LinkControlWord implements IFreque
|
||||
sb.append(getMessageStub());
|
||||
sb.append(" WACN:").append(getWACN());
|
||||
sb.append(" SYSTEM:").append(getSystem());
|
||||
sb.append(" CHAN:" + getChannel());
|
||||
sb.append(" SERVICE OPTIONS:" + getSystemServiceClass());
|
||||
sb.append(" CHAN:").append(getChannel());
|
||||
sb.append(" SERVICE OPTIONS:").append(getSystemServiceClass());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ public class LCNetworkStatusBroadcastExplicit extends LinkControlWord implements
|
||||
sb.append(getMessageStub());
|
||||
sb.append(" WACN:").append(getWACN());
|
||||
sb.append(" SYSTEM:").append(getSystem());
|
||||
sb.append(" CHAN:" + getChannel());
|
||||
sb.append(" CHAN:").append(getChannel());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -74,9 +74,9 @@ public class LCRFSSStatusBroadcast extends LinkControlWord implements IFrequency
|
||||
sb.append(getMessageStub());
|
||||
sb.append(" LRA:").append(getLocationRegistrationArea());
|
||||
sb.append(" SYSTEM:").append(getSystem());
|
||||
sb.append(" SITE:" + getRfss() + "-" + getSite());
|
||||
sb.append(" CHAN:" + getChannel());
|
||||
sb.append(" SERVICE OPTIONS:" + getSystemServiceClass());
|
||||
sb.append(" SITE:").append(getRfss()).append("-").append(getSite());
|
||||
sb.append(" CHAN:").append(getChannel());
|
||||
sb.append(" SERVICE OPTIONS:").append(getSystemServiceClass());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -72,9 +72,9 @@ public class LCRFSSStatusBroadcastExplicit extends LinkControlWord implements IF
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(getMessageStub());
|
||||
sb.append(" LRA:").append(getLocationRegistrationArea());
|
||||
sb.append(" SITE:" + getRfss() + "-" + getSite());
|
||||
sb.append(" CHAN:" + getChannel());
|
||||
sb.append(" SERVICE OPTIONS:" + getSystemServiceClass());
|
||||
sb.append(" SITE:").append(getRfss()).append("-").append(getSite());
|
||||
sb.append(" CHAN:").append(getChannel());
|
||||
sb.append(" SERVICE OPTIONS:").append(getSystemServiceClass());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -71,14 +71,14 @@ public class LCSecondaryControlChannelBroadcast extends LinkControlWord implemen
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(getMessageStub());
|
||||
sb.append(" SITE:" + getRFSS() + "-" + getSite());
|
||||
sb.append(" CHAN A:" + getChannelA());
|
||||
sb.append(" SERVICE CLASS:" + getSystemServiceClassA());
|
||||
sb.append(" SITE:").append(getRFSS()).append("-").append(getSite());
|
||||
sb.append(" CHAN A:").append(getChannelA());
|
||||
sb.append(" SERVICE CLASS:").append(getSystemServiceClassA());
|
||||
|
||||
if(hasChannelB())
|
||||
{
|
||||
sb.append(" CHAN B:" + getChannelB());
|
||||
sb.append(" SERVICE CLASS:" + getSystemServiceClassB());
|
||||
sb.append(" CHAN B:").append(getChannelB());
|
||||
sb.append(" SERVICE CLASS:").append(getSystemServiceClassB());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -69,8 +69,8 @@ public class LCSecondaryControlChannelBroadcastExplicit extends LinkControlWord
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(getMessageStub());
|
||||
sb.append(" SITE:" + getRFSS() + "-" + getSite());
|
||||
sb.append(" CHAN:" + getChannel());
|
||||
sb.append(" SITE:").append(getRFSS()).append("-").append(getSite());
|
||||
sb.append(" CHAN:").append(getChannel());
|
||||
sb.append(" SERVICE CLASS:").append(getSystemServiceClass());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -89,6 +89,9 @@ public class LDU1Message extends LDUMessage implements IFrequencyBandReceiver
|
||||
private static final int[] RS_HEX_10 = {1228, 1229, 1230, 1231, 1232, 1233};
|
||||
private static final int[] RS_HEX_11 = {1238, 1239, 1240, 1241, 1242, 1243};
|
||||
|
||||
//Reed-Solomon(24,12,13) code protects the link control word. Maximum correctable errors are: 6
|
||||
private static final ReedSolomon_63_47_17 reedSolomon_63_47_17 = new ReedSolomon_63_47_17(6);
|
||||
|
||||
private LinkControlWord mLinkControlWord;
|
||||
private List<Identifier> mIdentifiers;
|
||||
|
||||
@@ -174,8 +177,6 @@ public class LDU1Message extends LDUMessage implements IFrequencyBandReceiver
|
||||
input[23] = getMessage().getInt(CW_HEX_0);
|
||||
/* indexes 24 - 62 are defaulted to zero */
|
||||
|
||||
//Reed-Solomon(24,12,13) code protects the link control word. Maximum correctable errors are: 6
|
||||
ReedSolomon_63_47_17 reedSolomon_63_47_17 = new ReedSolomon_63_47_17(6);
|
||||
boolean irrecoverableErrors = reedSolomon_63_47_17.decode(input, output);
|
||||
|
||||
//Transfer error corrected output to a new binary message
|
||||
|
||||
@@ -63,6 +63,9 @@ public class LDU2Message extends LDUMessage
|
||||
private static final int[] RS_HEX_6 = {1228, 1229, 1230, 1231, 1232, 1233};
|
||||
private static final int[] RS_HEX_7 = {1238, 1239, 1240, 1241, 1242, 1243};
|
||||
|
||||
//Reed-Solomon(24,16,9) code protects the encryption sync word. Maximum correctable errors are: 4
|
||||
private static final ReedSolomon_63_47_17 reedSolomon_63_47_17 = new ReedSolomon_63_47_17(4);
|
||||
|
||||
private EncryptionSyncParameters mEncryptionSyncParameters;
|
||||
private List<Identifier> mIdentifiers;
|
||||
|
||||
@@ -137,8 +140,6 @@ public class LDU2Message extends LDUMessage
|
||||
input[23] = getMessage().getInt(CW_HEX_0);
|
||||
/* indexes 24 - 62 are defaulted to zero */
|
||||
|
||||
//Reed-Solomon(24,16,9) code protects the encryption sync word. Maximum correctable errors are: 4
|
||||
ReedSolomon_63_47_17 reedSolomon_63_47_17 = new ReedSolomon_63_47_17(4);
|
||||
boolean irrecoverableErrors = reedSolomon_63_47_17.decode(input, output);
|
||||
|
||||
BinaryMessage binaryMessage = new BinaryMessage(96);
|
||||
|
||||
@@ -186,7 +186,7 @@ public class PDUHeader implements IBitErrorProvider
|
||||
sb.append("PDU HEADER FORMAT:");
|
||||
sb.append(getFormat().getLabel());
|
||||
sb.append(isConfirmationRequired() ? " CONFIRMED" : " UNCONFIRMED");
|
||||
sb.append(" VENDOR:" + getVendor().getLabel());
|
||||
sb.append(" VENDOR:").append(getVendor().getLabel());
|
||||
sb.append(isOutbound() ? "TO" : "FROM").append(" LLID").append(getLLID());
|
||||
|
||||
return sb.toString();
|
||||
|
||||
@@ -117,8 +117,8 @@ public class PDUMessage extends P25Message
|
||||
case ALTERNATE_MULTI_BLOCK_TRUNKING_CONTROL:
|
||||
break;
|
||||
case UNCONFIRMED_MULTI_BLOCK_TRUNKING_CONTROL:
|
||||
sb.append(" PAD OCTETS:" + getPadOctetCount());
|
||||
sb.append(" DATA HDR OFFSET:" + getDataHeaderOffset());
|
||||
sb.append(" PAD OCTETS:").append(getPadOctetCount());
|
||||
sb.append(" DATA HDR OFFSET:").append(getDataHeaderOffset());
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
@@ -61,6 +61,9 @@ public class TDULinkControlMessage extends P25Message implements IFrequencyBandR
|
||||
public static final int[] RS_HEX_10 = {264, 265, 266, 267, 268, 269};
|
||||
public static final int[] RS_HEX_11 = {270, 271, 272, 273, 274, 275};
|
||||
|
||||
//Reed-Solomon(24,12,13) code protects the link control word. Maximum correctable errors are: 6
|
||||
private static final ReedSolomon_63_47_17 reedSolomon_63_47_17 = new ReedSolomon_63_47_17(6);
|
||||
|
||||
private LinkControlWord mLinkControlWord;
|
||||
|
||||
public TDULinkControlMessage(CorrectedBinaryMessage message, int nac, long timestamp)
|
||||
@@ -143,9 +146,6 @@ public class TDULinkControlMessage extends P25Message implements IFrequencyBandR
|
||||
input[23] = getMessage().getInt(LC_HEX_0);
|
||||
/* indexes 24 - 62 are defaulted to zero */
|
||||
|
||||
//Reed-Solomon(24,12,13) code protects the link control word. Maximum correctable errors are: 6
|
||||
ReedSolomon_63_47_17 reedSolomon_63_47_17 = new ReedSolomon_63_47_17(6);
|
||||
|
||||
boolean irrecoverableErrors = reedSolomon_63_47_17.decode(input, output);
|
||||
|
||||
//Transfer error corrected output to a new binary message
|
||||
|
||||
@@ -62,8 +62,8 @@ public class MotorolaBaseStationId extends OSPMessage implements IFrequencyBandR
|
||||
|
||||
if(hasChannel())
|
||||
{
|
||||
sb.append(" CHAN:" + getChannel());
|
||||
sb.append(" CWID:" + getCWID());
|
||||
sb.append(" CHAN:").append(getChannel());
|
||||
sb.append(" CWID:").append(getCWID());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -28,6 +28,7 @@ import io.github.dsheirer.module.decode.p25.phase1.P25P1DataUnitID;
|
||||
import io.github.dsheirer.module.decode.p25.phase1.message.IFrequencyBand;
|
||||
import io.github.dsheirer.module.decode.p25.phase1.message.tsbk.OSPMessage;
|
||||
import io.github.dsheirer.module.decode.p25.reference.ChannelType;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -125,7 +126,7 @@ public class FrequencyBandUpdateTDMA extends OSPMessage implements IFrequencyBan
|
||||
@Override
|
||||
public long getDownlinkFrequency(int channelNumber)
|
||||
{
|
||||
return getBaseFrequency() + (getChannelSpacing() * (int)(Math.floor(channelNumber / getTimeslotCount())));
|
||||
return getBaseFrequency() + (getChannelSpacing() * (int)(FastMath.floor(channelNumber / getTimeslotCount())));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -76,8 +76,8 @@ public class SyncBroadcast extends OSPMessage
|
||||
}
|
||||
sb.append(":");
|
||||
TIME_FORMATTER.setTimeZone(getTimeZone());
|
||||
sb.append(" " + TIME_FORMATTER.format(new Date(getSystemTime())));
|
||||
sb.append(" LEAP-SECOND CORRECTION:" + getLeapSecondCorrection() + "mS");
|
||||
sb.append(" ").append(TIME_FORMATTER.format(new Date(getSystemTime())));
|
||||
sb.append(" LEAP-SECOND CORRECTION:").append(getLeapSecondCorrection()).append("mS");
|
||||
if(isMicroslotsLockedToMinuteRollover())
|
||||
{
|
||||
sb.append(" MICROSLOT-MINUTE ROLLOVER:SLOW");
|
||||
|
||||
@@ -197,7 +197,7 @@ public class DibitDelayBuffer
|
||||
|
||||
counter++;
|
||||
}
|
||||
mLog.debug("BUFFER: " + sb.toString() + " Length:" + mBuffer.length);
|
||||
mLog.debug("BUFFER: " + sb + " Length:" + mBuffer.length);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -39,17 +39,13 @@ import io.github.dsheirer.module.decode.p25.phase2.message.mac.structure.RfssSta
|
||||
import io.github.dsheirer.module.decode.p25.phase2.message.mac.structure.SecondaryControlChannelBroadcastAbbreviated;
|
||||
import io.github.dsheirer.module.decode.p25.phase2.message.mac.structure.SecondaryControlChannelBroadcastExplicit;
|
||||
import io.github.dsheirer.module.decode.p25.phase2.message.mac.structure.SystemServiceBroadcast;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
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.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Tracks the network configuration details of a P25 Phase 2 network from the broadcast messages
|
||||
@@ -95,12 +91,7 @@ public class P25P2NetworkConfigurationMonitor
|
||||
{
|
||||
if(identifier.getValue() instanceof Integer)
|
||||
{
|
||||
String hex = Integer.toHexString((Integer)identifier.getValue());
|
||||
|
||||
while(hex.length() < width)
|
||||
{
|
||||
hex = "0" + hex;
|
||||
}
|
||||
String hex = StringUtils.leftPad(Integer.toHexString((Integer)identifier.getValue()), width, '0');
|
||||
|
||||
return hex.toUpperCase() + "[" + identifier.getValue() + "]";
|
||||
}
|
||||
@@ -278,20 +269,15 @@ public class P25P2NetworkConfigurationMonitor
|
||||
|
||||
if(!mSecondaryControlChannels.isEmpty())
|
||||
{
|
||||
List<String> channels = new ArrayList<>(mSecondaryControlChannels.keySet());
|
||||
Collections.sort(channels);
|
||||
|
||||
for(String channel : channels)
|
||||
{
|
||||
IChannelDescriptor secondaryControlChannel = mSecondaryControlChannels.get(channel);
|
||||
|
||||
if(secondaryControlChannel != null)
|
||||
{
|
||||
sb.append(" SEC CONTROL CHANNEL:").append(secondaryControlChannel);
|
||||
sb.append(" DOWNLINK:").append(secondaryControlChannel.getDownlinkFrequency());
|
||||
sb.append(" UPLINK:").append(secondaryControlChannel.getUplinkFrequency()).append("\n");
|
||||
}
|
||||
}
|
||||
mSecondaryControlChannels.entrySet()
|
||||
.stream()
|
||||
.sorted(Map.Entry.comparingByKey())
|
||||
.filter(Objects::nonNull)
|
||||
.forEach(entry -> {
|
||||
sb.append(" SEC CONTROL CHANNEL:").append(entry.getValue());
|
||||
sb.append(" DOWNLINK:").append(entry.getValue().getDownlinkFrequency());
|
||||
sb.append(" UPLINK:").append(entry.getValue().getUplinkFrequency()).append("\n");
|
||||
});
|
||||
}
|
||||
|
||||
if(mSystemServiceBroadcast != null)
|
||||
@@ -312,40 +298,38 @@ public class P25P2NetworkConfigurationMonitor
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Integer> sitesSorted = new ArrayList<>(sites);
|
||||
Collections.sort(sitesSorted);
|
||||
|
||||
for(Integer site : sitesSorted)
|
||||
{
|
||||
if(mNeighborSitesAbbreviated.containsKey(site))
|
||||
{
|
||||
AdjacentStatusBroadcastAbbreviated asb = mNeighborSitesAbbreviated.get(site);
|
||||
sb.append(" SYSTEM:").append(format(asb.getSystem(), 3));
|
||||
sb.append(" RFSS:").append(format(asb.getRFSS(), 2));
|
||||
sb.append(" SITE:").append(format(asb.getSite(), 2));
|
||||
sb.append(" LRA:").append(format(asb.getLRA(), 2));
|
||||
sb.append(" CHANNEL:").append(asb.getChannel());
|
||||
sb.append(" DOWNLINK:").append(asb.getChannel().getDownlinkFrequency());
|
||||
sb.append(" UPLINK:").append(asb.getChannel().getUplinkFrequency());
|
||||
sb.append(" STATUS:").append(asb.getSiteFlags()).append("\n");
|
||||
}
|
||||
else if(mNeighborSitesAbbreviated.containsKey(site))
|
||||
{
|
||||
AdjacentStatusBroadcastAbbreviated asb = mNeighborSitesAbbreviated.get(site);
|
||||
sb.append(" SYSTEM:").append(format(asb.getSystem(), 3));
|
||||
sb.append(" RFSS:").append(format(asb.getRFSS(), 2));
|
||||
sb.append(" SITE:").append(format(asb.getSite(), 2));
|
||||
sb.append(" LRA:").append(format(asb.getLRA(), 2));
|
||||
sb.append(" CHANNEL:").append(asb.getChannel());
|
||||
sb.append(" DOWNLINK:").append(asb.getChannel().getDownlinkFrequency());
|
||||
sb.append(" UPLINK:").append(asb.getChannel().getUplinkFrequency());
|
||||
sb.append(" STATUS:").append(asb.getSiteFlags()).append("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append(" SITE:").append(site).append(" NOT FOUND IN NEIGHBOR SITE MAPS\n");
|
||||
}
|
||||
}
|
||||
sites.stream()
|
||||
.sorted()
|
||||
.forEach(site -> {
|
||||
if(mNeighborSitesAbbreviated.containsKey(site))
|
||||
{
|
||||
AdjacentStatusBroadcastAbbreviated asb = mNeighborSitesAbbreviated.get(site);
|
||||
sb.append(" SYSTEM:").append(format(asb.getSystem(), 3));
|
||||
sb.append(" RFSS:").append(format(asb.getRFSS(), 2));
|
||||
sb.append(" SITE:").append(format(asb.getSite(), 2));
|
||||
sb.append(" LRA:").append(format(asb.getLRA(), 2));
|
||||
sb.append(" CHANNEL:").append(asb.getChannel());
|
||||
sb.append(" DOWNLINK:").append(asb.getChannel().getDownlinkFrequency());
|
||||
sb.append(" UPLINK:").append(asb.getChannel().getUplinkFrequency());
|
||||
sb.append(" STATUS:").append(asb.getSiteFlags()).append("\n");
|
||||
}
|
||||
else if(mNeighborSitesExtended.containsKey(site))
|
||||
{
|
||||
AdjacentStatusBroadcastExtended asb = mNeighborSitesExtended.get(site);
|
||||
sb.append(" SYSTEM:").append(format(asb.getSystem(), 3));
|
||||
sb.append(" RFSS:").append(format(asb.getRFSS(), 2));
|
||||
sb.append(" SITE:").append(format(asb.getSite(), 2));
|
||||
sb.append(" LRA:").append(format(asb.getLRA(), 2));
|
||||
sb.append(" CHANNEL:").append(asb.getChannel());
|
||||
sb.append(" DOWNLINK:").append(asb.getChannel().getDownlinkFrequency());
|
||||
sb.append(" UPLINK:").append(asb.getChannel().getUplinkFrequency());
|
||||
sb.append(" STATUS:").append(asb.getSiteFlags()).append("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append(" SITE:").append(site).append(" NOT FOUND IN NEIGHBOR SITE MAPS\n");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
sb.append("\nFrequency Bands\n");
|
||||
@@ -355,14 +339,10 @@ public class P25P2NetworkConfigurationMonitor
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Integer> ids = new ArrayList<>(mFrequencyBandMap.keySet());
|
||||
Collections.sort(ids);
|
||||
{
|
||||
for(Integer id : ids)
|
||||
{
|
||||
sb.append(" ").append(formatFrequencyBand(mFrequencyBandMap.get(id))).append("\n");
|
||||
}
|
||||
}
|
||||
mFrequencyBandMap.entrySet()
|
||||
.stream()
|
||||
.sorted(Map.Entry.comparingByKey())
|
||||
.forEach(entry -> sb.append(" ").append(formatFrequencyBand(entry.getValue())).append("\n"));
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
|
||||
@@ -29,6 +29,7 @@ import io.github.dsheirer.dsp.symbol.Dibit;
|
||||
import io.github.dsheirer.dsp.symbol.FrameSync;
|
||||
import io.github.dsheirer.dsp.symbol.ISyncDetectListener;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -169,7 +170,7 @@ public class P25P2SyncDetector implements Listener<Dibit>
|
||||
public void setSampleRate(double sampleRate)
|
||||
{
|
||||
mSampleRate = sampleRate;
|
||||
mPllCorrection = 2.0 * Math.PI * mFrequencyCorrection / mSampleRate;
|
||||
mPllCorrection = 2.0 * FastMath.PI * mFrequencyCorrection / mSampleRate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import io.github.dsheirer.module.decode.p25.phase2.enumeration.ISCHSequence;
|
||||
import io.github.dsheirer.module.decode.p25.phase2.enumeration.SuperframeSequence;
|
||||
import org.apache.commons.math3.linear.MatrixUtils;
|
||||
import org.apache.commons.math3.linear.RealMatrix;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -231,7 +232,7 @@ public class InterSlotSignallingChannel
|
||||
double[] values = new double[9];
|
||||
for(int x = 0; x < 7; x++)
|
||||
{
|
||||
int mask = (int)Math.pow(2, x);
|
||||
int mask = (int) FastMath.pow(2, x);
|
||||
if((value & mask) == mask)
|
||||
{
|
||||
values[8 - x] = 1;
|
||||
@@ -257,7 +258,7 @@ public class InterSlotSignallingChannel
|
||||
|
||||
if((value & 1) == 1)
|
||||
{
|
||||
decoded += (long)Math.pow(2, x);
|
||||
decoded += (long)FastMath.pow(2, x);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -159,9 +159,10 @@ public enum MacOpcode
|
||||
*/
|
||||
public static MacOpcode fromValue(int value)
|
||||
{
|
||||
if(LOOKUP_MAP.containsKey(value))
|
||||
MacOpcode mapValue = LOOKUP_MAP.get(value);
|
||||
if (mapValue != null)
|
||||
{
|
||||
return LOOKUP_MAP.get(value);
|
||||
return mapValue;
|
||||
}
|
||||
|
||||
if(0 <= value && value <= 63)
|
||||
|
||||
@@ -27,6 +27,7 @@ import io.github.dsheirer.identifier.Identifier;
|
||||
import io.github.dsheirer.module.decode.p25.phase1.message.IFrequencyBand;
|
||||
import io.github.dsheirer.module.decode.p25.phase2.message.mac.MacStructure;
|
||||
import io.github.dsheirer.module.decode.p25.reference.ChannelType;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -130,7 +131,7 @@ public class FrequencyBandUpdateTDMA extends MacStructure implements IFrequencyB
|
||||
@Override
|
||||
public long getDownlinkFrequency(int channelNumber)
|
||||
{
|
||||
return getBaseFrequency() + (getChannelSpacing() * (int)(Math.floor(channelNumber / getTimeslotCount())));
|
||||
return getBaseFrequency() + (getChannelSpacing() * (int)(FastMath.floor(channelNumber / getTimeslotCount())));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -59,15 +59,15 @@ public enum ChannelType
|
||||
{
|
||||
sb.append(" H-D8PSK");
|
||||
}
|
||||
sb.append(" BW:" + mBandwidth);
|
||||
sb.append(" TIMESLOTS:" + mSlotsPerCarrier);
|
||||
sb.append(" VOCODER:" + mVocoder.name());
|
||||
sb.append(" BW:").append(mBandwidth);
|
||||
sb.append(" TIMESLOTS:").append(mSlotsPerCarrier);
|
||||
sb.append(" VOCODER:").append(mVocoder.name());
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append("FDMA");
|
||||
sb.append(" BW:" + mBandwidth);
|
||||
sb.append(" VOCODER:" + mVocoder.name());
|
||||
sb.append(" BW:").append(mBandwidth);
|
||||
sb.append(" VOCODER:").append(mVocoder.name());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
package io.github.dsheirer.module.decode.passport;
|
||||
|
||||
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
public enum PassportBand
|
||||
{
|
||||
BAND_800( "800", 800000000 ),
|
||||
@@ -69,7 +71,7 @@ public enum PassportBand
|
||||
|
||||
public int getChannel( long frequency )
|
||||
{
|
||||
return Math.round( (float)( frequency - mBase ) /
|
||||
return FastMath.round( (float)( frequency - mBase ) /
|
||||
(float)CHANNEL_BANDWIDTH );
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class PassportDecoderState extends DecoderState
|
||||
{
|
||||
@@ -260,15 +261,14 @@ public class PassportDecoderState extends DecoderState
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Integer> channels = new ArrayList<>(mSiteLCNs.keySet());
|
||||
Collections.sort(channels);
|
||||
|
||||
for(Integer channel : channels)
|
||||
{
|
||||
sb.append(" " + channel);
|
||||
sb.append("\t" + mSiteLCNs.get(channel));
|
||||
sb.append("\n");
|
||||
}
|
||||
mSiteLCNs.entrySet()
|
||||
.stream()
|
||||
.sorted(Map.Entry.comparingByKey())
|
||||
.forEach(entry -> {
|
||||
sb.append(" " + entry.getKey());
|
||||
sb.append("\t" + entry.getValue());
|
||||
sb.append("\n");
|
||||
});
|
||||
}
|
||||
|
||||
sb.append("\nNeighbor Channels\n");
|
||||
@@ -279,15 +279,14 @@ public class PassportDecoderState extends DecoderState
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Integer> channels = new ArrayList<>(mNeighborLCNs.keySet());
|
||||
Collections.sort(channels);
|
||||
|
||||
for(Integer channel : channels)
|
||||
{
|
||||
sb.append(" " + channel);
|
||||
sb.append("\t" + mNeighborLCNs.get(channel));
|
||||
sb.append("\n");
|
||||
}
|
||||
mNeighborLCNs.entrySet()
|
||||
.stream()
|
||||
.sorted(Map.Entry.comparingByKey())
|
||||
.forEach(entry -> {
|
||||
sb.append(" " + entry.getKey());
|
||||
sb.append("\t" + entry.getValue());
|
||||
sb.append("\n");
|
||||
});
|
||||
}
|
||||
|
||||
sb.append("\nTalkgroups\n");
|
||||
@@ -298,11 +297,9 @@ public class PassportDecoderState extends DecoderState
|
||||
}
|
||||
else
|
||||
{
|
||||
Iterator<PassportTalkgroup> it = mTalkgroups.iterator();
|
||||
|
||||
while(it.hasNext())
|
||||
{
|
||||
sb.append(" ").append(it.next()).append("\n");
|
||||
for (PassportTalkgroup mTalkgroup : mTalkgroups) {
|
||||
sb.append(" ").append(mTalkgroup).append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,11 +311,9 @@ public class PassportDecoderState extends DecoderState
|
||||
}
|
||||
else
|
||||
{
|
||||
Iterator<PassportTalkgroup> it = mMobileIDs.iterator();
|
||||
|
||||
while(it.hasNext())
|
||||
{
|
||||
sb.append(" ").append(it.next()).append("\n");
|
||||
for (PassportTalkgroup mMobileID : mMobileIDs) {
|
||||
sb.append(" ").append(mMobileID).append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import io.github.dsheirer.message.Message;
|
||||
import io.github.dsheirer.message.MessageType;
|
||||
import io.github.dsheirer.module.decode.passport.identifier.PassportTalkgroup;
|
||||
import io.github.dsheirer.protocol.Protocol;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -257,32 +258,12 @@ public class PassportMessage extends Message
|
||||
*/
|
||||
public String format(int number, int decimalPlaces)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int paddingRequired = decimalPlaces - (String.valueOf(number).length());
|
||||
|
||||
for(int x = 0; x < paddingRequired; x++)
|
||||
{
|
||||
sb.append("0");
|
||||
}
|
||||
|
||||
sb.append(number);
|
||||
|
||||
return sb.toString();
|
||||
return StringUtils.leftPad(Integer.valueOf(number).toString(), decimalPlaces, '0');
|
||||
}
|
||||
|
||||
public String format(String val, int places)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append(val);
|
||||
|
||||
while(sb.length() < places)
|
||||
{
|
||||
sb.append(" ");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
return StringUtils.leftPad(val, places);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -4,15 +4,13 @@ import io.github.dsheirer.filter.Filter;
|
||||
import io.github.dsheirer.filter.FilterElement;
|
||||
import io.github.dsheirer.message.IMessage;
|
||||
import io.github.dsheirer.message.MessageType;
|
||||
import io.github.dsheirer.protocol.Protocol;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public class PassportMessageFilter extends Filter<IMessage>
|
||||
{
|
||||
private Map<MessageType, FilterElement<MessageType>> mElements = new HashMap<MessageType, FilterElement<MessageType>>();
|
||||
private Map<MessageType, FilterElement<MessageType>> mElements = new EnumMap<>(MessageType.class);
|
||||
|
||||
public PassportMessageFilter()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user