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:
robekl
2020-04-25 07:57:56 -04:00
committed by GitHub
parent 649258bd2b
commit 39f6d6c831
186 changed files with 2840 additions and 3464 deletions

View File

@@ -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
*

View File

@@ -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");
}
}

View File

@@ -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()
{

View File

@@ -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

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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()
{

View File

@@ -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()
{

View File

@@ -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");
}
}
}

View File

@@ -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();
}

View File

@@ -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()
{

View File

@@ -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");
}

View File

@@ -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()

View File

@@ -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()
{

View File

@@ -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;

View File

@@ -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');
}
/**

View File

@@ -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());
}
}
}
}

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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();

View File

@@ -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;
}
}
}

View File

@@ -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()
{

View File

@@ -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()
{

View File

@@ -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

View File

@@ -70,7 +70,7 @@ public class HeaderData
if(isValid())
{
sb.append("TALKGROUP:" + getTalkgroup());
sb.append("TALKGROUP:").append(getTalkgroup());
Vendor vendor = getVendor();

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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);

View File

@@ -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();

View File

@@ -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:
}

View File

@@ -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

View File

@@ -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
{

View File

@@ -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

View File

@@ -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");

View File

@@ -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)

View File

@@ -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();

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}

View File

@@ -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)

View File

@@ -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

View File

@@ -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();

View File

@@ -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 );
}

View File

@@ -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");
}
}

View File

@@ -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

View File

@@ -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()
{