From 39f6d6c831de437a572a811e2da4cf268f18e7da Mon Sep 17 00:00:00 2001 From: robekl Date: Sat, 25 Apr 2020 06:57:56 -0500 Subject: [PATCH] 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 --- .../io/github/dsheirer/alias/AliasList.java | 44 +- .../io/github/dsheirer/alias/AliasModel.java | 6 +- .../dsheirer/alias/AliasNameEditor.java | 6 +- .../dsheirer/alias/MultipleAliasEditor.java | 10 +- .../alias/action/AliasActionEditor.java | 9 +- .../alias/id/AliasIdentifierEditor.java | 9 +- .../github/dsheirer/alias/id/WildcardID.java | 5 +- .../id/broadcast/BroadcastChannelEditor.java | 2 +- .../alias/id/radio/RadioFormatter.java | 3 +- .../id/talkgroup/TalkgroupFormatter.java | 3 +- .../github/dsheirer/audio/AudioSegment.java | 5 +- .../audio/broadcast/AudioBroadcaster.java | 3 +- .../broadcastify/UserFeedSelectionDialog.java | 2 +- .../v2/ShoutcastV2AudioBroadcaster.java | 5 +- .../audio/convert/MP3AudioConverter.java | 9 +- .../audio/playback/AudioPlaybackManager.java | 11 +- .../github/dsheirer/bits/BinaryMessage.java | 7 +- .../github/dsheirer/bits/MessageFramer.java | 5 +- .../bits/MultiSyncPatternMatcher.java | 3 +- .../dsheirer/bits/SyncPatternMatcher.java | 4 +- .../buffer/BooleanAveragingBuffer.java | 6 +- .../metadata/ChannelMetadataPanel.java | 5 +- .../channel/state/DecoderStateEvent.java | 10 +- .../controller/channel/ChannelModel.java | 28 +- .../channel/NameConfigurationEditor.java | 8 +- .../controller/channel/map/ChannelRange.java | 4 +- .../dsheirer/dsp/afsk/AFSK1200Decoder.java | 3 +- .../io/github/dsheirer/dsp/afsk/AFSKTest.java | 5 +- .../github/dsheirer/dsp/am/AMDemodulator.java | 3 +- .../dsheirer/dsp/filter/FilterFactory.java | 67 +- .../dsheirer/dsp/filter/FloatFIRFilter.java | 2 +- .../dsheirer/dsp/filter/GoertzelFilter.java | 25 +- .../dsp/filter/IIRBiQuadraticFilter.java | 18 +- .../io/github/dsheirer/dsp/filter/Window.java | 67 +- .../filter/channelizer/ChannelCalculator.java | 3 +- .../ComplexPolyphaseChannelizerM2.java | 53 +- .../channelizer/PolyphaseChannelManager.java | 3 +- .../channelizer/PolyphaseChannelSource.java | 5 +- .../channelizer/TwoChannelSynthesizerM2.java | 21 +- .../filter/cic/ComplexPrimeCICDecimate.java | 70 +- .../dsp/filter/cic/RealPrimeCICDecimate.java | 44 +- .../dsp/filter/dc/BufferDCFilter.java | 5 +- .../dsp/filter/design/FilterView.java | 5 +- .../filter/fir/FIRFilterSpecification.java | 27 +- .../dsheirer/dsp/filter/fir/remez/Grid.java | 5 +- .../PolyphaseChannelizerFilterFactory.java | 5 +- .../fir/remez/RemezFIRFilterDesigner.java | 37 +- .../fir/remez/RemezFIRFilterDesigner2.java | 37 +- .../RemezFIRFilterDesignerWithLagrange.java | 35 +- .../dsp/filter/hilbert/HilbertTransform.java | 5 +- .../dsp/filter/iir/DeemphasisFilter.java | 11 +- .../filter/interpolator/RealInterpolator.java | 5 +- .../github/dsheirer/dsp/fm/FMDemodulator.java | 5 +- .../github/dsheirer/dsp/fsk/SampleBuffer.java | 3 +- .../dsp/fsk/ZeroCrossingErrorDetector.java | 6 +- .../dsp/gain/AutomaticGainControl.java | 19 +- .../dsp/gain/ComplexAutomaticGainControl.java | 22 +- .../dsp/mixer/LowPhaseNoiseOscillator.java | 7 +- .../github/dsheirer/dsp/mixer/Oscillator.java | 3 +- ...cisionDirectedDemodulatorInstrumented.java | 3 +- .../DQPSKDecisionDirectedSymbolEvaluator.java | 9 +- .../DQPSKGardnerDemodulatorInstrumented.java | 3 +- .../dsp/psk/DQPSKGardnerSymbolEvaluator.java | 9 +- .../dsheirer/dsp/psk/GardnerDetector.java | 5 +- .../dsp/psk/InterpolatingSampleBuffer.java | 7 +- ...InterpolatingSampleBufferInstrumented.java | 3 +- .../dsheirer/dsp/psk/QPSKSymbolDecoder.java | 3 +- .../psk/QPSKSymbolPhaseErrorCalculator.java | 3 +- .../dsheirer/dsp/psk/SymbolDecisionData.java | 3 +- .../dsheirer/dsp/psk/SymbolInversion.java | 8 +- .../dsheirer/dsp/psk/pll/CostasLoop.java | 5 +- .../dsheirer/dsp/psk/pll/PLLBandwidth.java | 6 +- .../psk/pll/QPSKPhaseInversionCalculator.java | 6 +- .../dsheirer/edac/BerlekempMassey_63.java | 15 +- .../java/io/github/dsheirer/edac/CRC.java | 12 +- .../dsheirer/edac/trellis/ViterbiDecoder.java | 6 +- .../dsheirer/filter/FilterEditorPanel.java | 18 +- .../dsheirer/gui/ChannelMemoryLogger.java | 14 +- .../gui/control/ConstellationViewer.java | 3 +- .../gui/control/JFrequencyControl.java | 7 +- .../gui/control/MultipleFrequencyEditor.java | 3 +- .../chart/ComplexPhaseLineChart.java | 5 +- .../gui/instrument/chart/EyeDiagramChart.java | 7 +- .../gui/instrument/chart/SampleXYChart.java | 4 +- .../gui/preference/PreferencesEditor.java | 20 +- .../io/github/dsheirer/icon/IconManager.java | 6 +- .../github/dsheirer/icon/IconTableModel.java | 2 +- .../identifier/IdentifierCollection.java | 2 +- .../identifier/patch/PatchGroupManager.java | 10 +- .../github/dsheirer/map/SelectionAdapter.java | 9 +- .../module/decode/DecoderFactory.java | 284 ++- .../fleetsync2/Fleetsync2DecoderState.java | 6 +- .../fleetsync2/FleetsyncMessageFilter.java | 8 +- .../module/decode/lj1200/LJ1200Message.java | 31 +- .../lj1200/LJ1200TransponderMessage.java | 25 +- .../decode/ltrnet/LTRNetDecoderState.java | 4 +- .../decode/ltrnet/LTRNetMessageFilter.java | 8 +- .../ltrstandard/LTRStandardMessageFilter.java | 8 +- .../decode/mdc1200/MDCDecoderState.java | 12 +- .../module/decode/mdc1200/MDCMessage.java | 37 +- .../decode/mdc1200/MDCMessageFilter.java | 8 +- .../decode/mpt1327/MPT1327DecoderState.java | 7 +- .../module/decode/mpt1327/MPT1327Message.java | 25 +- .../decode/mpt1327/MPT1327MessageFilter.java | 8 +- .../decode/p25/P25TrafficChannelManager.java | 130 +- .../dsheirer/module/decode/p25/P25Utils.java | 17 +- .../p25/audio/P25P2CallSequenceRecorder.java | 254 +- .../decode/p25/phase1/C4FMSymbolFilter.java | 5 +- .../p25/phase1/P25P1DataUnitDetector.java | 8 +- .../decode/p25/phase1/P25P1DecoderState.java | 2137 +++++++---------- .../P25P1NetworkConfigurationMonitor.java | 161 +- .../decode/p25/phase1/P25P1SyncDetector.java | 3 +- .../message/filter/PDUMessageFilter.java | 8 +- .../message/filter/TSBKMessageFilterSet.java | 7 +- .../p25/phase1/message/hdu/HDUMessage.java | 6 +- .../p25/phase1/message/hdu/HeaderData.java | 2 +- .../LCAdjacentSiteStatusBroadcast.java | 6 +- ...LCAdjacentSiteStatusBroadcastExplicit.java | 6 +- .../lc/standard/LCNetworkStatusBroadcast.java | 4 +- .../LCNetworkStatusBroadcastExplicit.java | 2 +- .../lc/standard/LCRFSSStatusBroadcast.java | 6 +- .../LCRFSSStatusBroadcastExplicit.java | 6 +- .../LCSecondaryControlChannelBroadcast.java | 10 +- ...ondaryControlChannelBroadcastExplicit.java | 4 +- .../p25/phase1/message/ldu/LDU1Message.java | 5 +- .../p25/phase1/message/ldu/LDU2Message.java | 5 +- .../p25/phase1/message/pdu/PDUHeader.java | 2 +- .../p25/phase1/message/pdu/PDUMessage.java | 4 +- .../message/tdu/TDULinkControlMessage.java | 6 +- .../motorola/osp/MotorolaBaseStationId.java | 4 +- .../standard/osp/FrequencyBandUpdateTDMA.java | 3 +- .../tsbk/standard/osp/SyncBroadcast.java | 4 +- .../decode/p25/phase2/DibitDelayBuffer.java | 2 +- .../decode/p25/phase2/P25P2DecoderState.java | 1363 ++++++----- .../P25P2NetworkConfigurationMonitor.java | 120 +- .../decode/p25/phase2/P25P2SyncDetector.java | 3 +- .../message/InterSlotSignallingChannel.java | 5 +- .../p25/phase2/message/mac/MacOpcode.java | 5 +- .../structure/FrequencyBandUpdateTDMA.java | 3 +- .../decode/p25/reference/ChannelType.java | 10 +- .../module/decode/passport/PassportBand.java | 4 +- .../decode/passport/PassportDecoderState.java | 47 +- .../decode/passport/PassportMessage.java | 25 +- .../passport/PassportMessageFilter.java | 8 +- .../identifier/TalkgroupFormatPreference.java | 11 +- .../record/wave/AudioMetadataUtils.java | 30 +- .../github/dsheirer/sample/Broadcaster.java | 2 +- .../sample/adapter/ComplexShortAdapter.java | 3 +- .../adapter/RealChannelShortAdapter.java | 5 +- .../sample/adapter/RealShortAdapter.java | 3 +- .../sample/adapter/ShortToFloatMap.java | 19 - .../dsheirer/sample/complex/Complex.java | 44 +- .../sample/complex/ComplexSampleUtils.java | 4 +- .../dsheirer/source/mixer/MixerManager.java | 26 +- .../source/mixer/MixerSourceEditor.java | 4 +- .../source/mixer/SystemMixerDevices.java | 26 +- .../dsheirer/source/tuner/TunerManager.java | 2 +- .../source/tuner/TunerSourceEditor.java | 6 +- .../TunerSourceMultipleFrequencyEditor.java | 6 +- .../tuner/airspy/AirspyTunerEditor.java | 2 +- .../tuner/hackrf/HackRFTunerEditor.java | 2 +- .../PolyphaseChannelSourceManager.java | 7 +- .../source/tuner/test/SampleGenerator.java | 3 +- .../dsheirer/source/tuner/usb/USBUtils.java | 34 +- .../source/wave/ComplexWaveSource.java | 3 +- .../dsheirer/spectrum/DFTProcessor.java | 6 +- .../dsheirer/spectrum/OverlayPanel.java | 15 +- .../spectrum/SpectralDisplayPanel.java | 3 +- .../dsheirer/spectrum/SpectrumPanel.java | 5 +- .../dsheirer/spectrum/WaterfallPanel.java | 3 +- .../converter/ComplexDecibelConverter.java | 4 +- .../converter/RealDecibelConverter.java | 3 +- .../java/io/github/dsheirer/util/Angle.java | 6 +- .../io/github/dsheirer/util/ArcTangent.java | 9 +- .../io/github/dsheirer/util/ThreadPool.java | 3 +- .../java/org/jdesktop/swingx/JXMapViewer.java | 5 +- .../swingx/mapviewer/AbstractTileFactory.java | 3 +- .../jdesktop/swingx/mapviewer/GeoBounds.java | 10 +- .../swingx/mapviewer/TileFactoryInfo.java | 4 +- .../CylindricalProjectionTileFactory.java | 3 +- .../mapviewer/bmng/SLMapServerInfo.java | 3 +- .../swingx/mapviewer/util/GeoUtil.java | 7 +- .../swingx/mapviewer/util/MercatorUtils.java | 16 +- .../swingx/mapviewer/wms/WMSService.java | 5 +- .../swingx/mapviewer/wms/WMSTileFactory.java | 3 +- .../org/jdesktop/swingx/util/ShapeUtils.java | 6 +- 186 files changed, 2840 insertions(+), 3464 deletions(-) delete mode 100644 src/main/java/io/github/dsheirer/sample/adapter/ShortToFloatMap.java diff --git a/src/main/java/io/github/dsheirer/alias/AliasList.java b/src/main/java/io/github/dsheirer/alias/AliasList.java index b1793997..36e4b5d6 100644 --- a/src/main/java/io/github/dsheirer/alias/AliasList.java +++ b/src/main/java/io/github/dsheirer/alias/AliasList.java @@ -45,13 +45,7 @@ import io.github.dsheirer.sample.Listener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; +import java.util.*; /** * List of aliases that share the same alias list name and provides convenient methods for looking up alias @@ -60,8 +54,8 @@ import java.util.TreeMap; public class AliasList implements Listener { private final static Logger mLog = LoggerFactory.getLogger(AliasList.class); - private Map mTalkgroupProtocolMap = new HashMap<>(); - private Map mRadioProtocolMap = new HashMap<>(); + private Map mTalkgroupProtocolMap = new EnumMap<>(Protocol.class); + private Map mRadioProtocolMap = new EnumMap<>(Protocol.class); private Map mESNMap = new HashMap<>(); private Map mStatusMap = new HashMap<>(); private boolean mHasAliasActions = false; @@ -487,15 +481,7 @@ public class AliasList implements Listener */ public static void remove(Alias alias, Map map) { - Iterator it = map.entrySet().iterator(); - - while(it.hasNext()) - { - if(it.next().getValue().equals(alias)) - { - it.remove(); - } - } + map.entrySet().removeIf(entry -> alias.equals(((Map.Entry)entry).getValue())); } @@ -515,16 +501,17 @@ public class AliasList implements Listener { int value = identifier.getValue(); - if(mTalkgroupAliasMap.containsKey(value)) + Alias mapValue = mTalkgroupAliasMap.get(value); + if (mapValue != null) { - return mTalkgroupAliasMap.get(value); + return mapValue; } - for(TalkgroupRange talkgroupRange: mTalkgroupRangeAliasMap.keySet()) + for(Map.Entry entry : mTalkgroupRangeAliasMap.entrySet()) { - if(talkgroupRange.contains(value)) + if(entry.getKey().contains(value)) { - return mTalkgroupRangeAliasMap.get(talkgroupRange); + return entry.getValue(); } } @@ -601,16 +588,17 @@ public class AliasList implements Listener { int value = identifier.getValue(); - if(mRadioAliasMap.containsKey(value)) + Alias mapValue = mRadioAliasMap.get(value); + if(mapValue != null) { - return mRadioAliasMap.get(value); + return mapValue; } - for(RadioRange radioRange: mRadioRangeAliasMap.keySet()) + for(Map.Entry entry : mRadioRangeAliasMap.entrySet()) { - if(radioRange.contains(value)) + if(entry.getKey().contains(value)) { - return mRadioRangeAliasMap.get(radioRange); + return entry.getValue(); } } diff --git a/src/main/java/io/github/dsheirer/alias/AliasModel.java b/src/main/java/io/github/dsheirer/alias/AliasModel.java index daba8830..9b990173 100644 --- a/src/main/java/io/github/dsheirer/alias/AliasModel.java +++ b/src/main/java/io/github/dsheirer/alias/AliasModel.java @@ -117,9 +117,9 @@ public class AliasModel extends AbstractTableModel return new AliasList(name); } - if(mAliasListMap.containsKey(name)) - { - return mAliasListMap.get(name); + AliasList mapValue = mAliasListMap.get(name); + if (mapValue != null) { + return mapValue; } AliasList aliasList = new AliasList(name); diff --git a/src/main/java/io/github/dsheirer/alias/AliasNameEditor.java b/src/main/java/io/github/dsheirer/alias/AliasNameEditor.java index 6fcc06aa..c0c2f74d 100644 --- a/src/main/java/io/github/dsheirer/alias/AliasNameEditor.java +++ b/src/main/java/io/github/dsheirer/alias/AliasNameEditor.java @@ -115,7 +115,7 @@ public class AliasNameEditor extends Editor else { mGroupCombo.setModel(new DefaultComboBoxModel( - groups.toArray(new String[groups.size()]))); + groups.toArray(new String[0]))); ; } } @@ -243,7 +243,7 @@ public class AliasNameEditor extends Editor else { mListCombo.setModel(new DefaultComboBoxModel( - listNames.toArray(new String[listNames.size()]))); + listNames.toArray(new String[0]))); ; } @@ -258,7 +258,7 @@ public class AliasNameEditor extends Editor else { mGroupCombo.setModel(new DefaultComboBoxModel( - groupNames.toArray(new String[groupNames.size()]))); + groupNames.toArray(new String[0]))); ; } diff --git a/src/main/java/io/github/dsheirer/alias/MultipleAliasEditor.java b/src/main/java/io/github/dsheirer/alias/MultipleAliasEditor.java index 472911fc..d2d9c655 100644 --- a/src/main/java/io/github/dsheirer/alias/MultipleAliasEditor.java +++ b/src/main/java/io/github/dsheirer/alias/MultipleAliasEditor.java @@ -266,15 +266,15 @@ public class MultipleAliasEditor extends Editor> List listNames = mAliasModel.getListNames(); listNames.add(0, ""); mListCombo.setModel(new DefaultComboBoxModel( - listNames.toArray(new String[listNames.size()]))); + listNames.toArray(new String[0]))); List groupNames = mAliasModel.getGroupNames(); groupNames.add(0, ""); mGroupCombo.setModel(new DefaultComboBoxModel( - groupNames.toArray(new String[groupNames.size()]))); + groupNames.toArray(new String[0]))); List streamNames = mBroadcastModel.getBroadcastConfigurationNames(); - mStreamCombo.setModel(new DefaultComboBoxModel(streamNames.toArray(new String[streamNames.size()]))); + mStreamCombo.setModel(new DefaultComboBoxModel(streamNames.toArray(new String[0]))); mIconCombo.setModel(new DefaultComboBoxModel<>(mIconManager.getIcons())); @@ -300,12 +300,12 @@ public class MultipleAliasEditor extends Editor> List listNames = mAliasModel.getListNames(); listNames.add(0, ""); mListCombo.setModel(new DefaultComboBoxModel( - listNames.toArray(new String[listNames.size()]))); + listNames.toArray(new String[0]))); List groupNames = mAliasModel.getGroupNames(); groupNames.add(0, ""); mGroupCombo.setModel(new DefaultComboBoxModel( - groupNames.toArray(new String[groupNames.size()]))); + groupNames.toArray(new String[0]))); mButtonColor.setForeground(getForeground()); mButtonColor.setBackground(getBackground()); diff --git a/src/main/java/io/github/dsheirer/alias/action/AliasActionEditor.java b/src/main/java/io/github/dsheirer/alias/action/AliasActionEditor.java index 388a5ea9..b6cce86a 100644 --- a/src/main/java/io/github/dsheirer/alias/action/AliasActionEditor.java +++ b/src/main/java/io/github/dsheirer/alias/action/AliasActionEditor.java @@ -188,14 +188,7 @@ public class AliasActionEditor extends Editor List actions = alias.getAction(); - Collections.sort( actions, new Comparator() - { - @Override - public int compare( AliasAction o1, AliasAction o2 ) - { - return o1.toString().compareTo( o2.toString() ); - } - } ); + actions.sort(Comparator.comparing(Object::toString)); for( AliasAction action: actions ) { diff --git a/src/main/java/io/github/dsheirer/alias/id/AliasIdentifierEditor.java b/src/main/java/io/github/dsheirer/alias/id/AliasIdentifierEditor.java index e9a6a86e..22687145 100644 --- a/src/main/java/io/github/dsheirer/alias/id/AliasIdentifierEditor.java +++ b/src/main/java/io/github/dsheirer/alias/id/AliasIdentifierEditor.java @@ -227,14 +227,7 @@ public class AliasIdentifierEditor extends Editor List ids = alias.getId(); - Collections.sort(ids, new Comparator() - { - @Override - public int compare(AliasID o1, AliasID o2) - { - return o1.toString().compareTo(o2.toString()); - } - }); + ids.sort(Comparator.comparing(Object::toString)); for(AliasID id : ids) { diff --git a/src/main/java/io/github/dsheirer/alias/id/WildcardID.java b/src/main/java/io/github/dsheirer/alias/id/WildcardID.java index 2ce8c6da..2b9b0afd 100644 --- a/src/main/java/io/github/dsheirer/alias/id/WildcardID.java +++ b/src/main/java/io/github/dsheirer/alias/id/WildcardID.java @@ -19,6 +19,7 @@ package io.github.dsheirer.alias.id; import org.apache.commons.lang3.Validate; +import org.apache.commons.math3.util.FastMath; import java.util.regex.Pattern; @@ -95,12 +96,12 @@ public class WildcardID implements Comparable { if(mValue.substring(x, x + 1).equals(WILDCARD)) { - weight += (int)(Math.pow(2, mValue.length() - x - 1)); //Position weight + weight += (int)(FastMath.pow(2, mValue.length() - x - 1)); //Position weight characterCount++; } } - weight += (int)(Math.pow(2, characterCount)) * 1000; //Character count weight + weight += (int)(FastMath.pow(2, characterCount)) * 1000; //Character count weight return weight; } diff --git a/src/main/java/io/github/dsheirer/alias/id/broadcast/BroadcastChannelEditor.java b/src/main/java/io/github/dsheirer/alias/id/broadcast/BroadcastChannelEditor.java index 8b025d94..cd4ebc3d 100644 --- a/src/main/java/io/github/dsheirer/alias/id/broadcast/BroadcastChannelEditor.java +++ b/src/main/java/io/github/dsheirer/alias/id/broadcast/BroadcastChannelEditor.java @@ -61,7 +61,7 @@ public class BroadcastChannelEditor extends DocumentListenerEditor List channelNames = mBroadcastModel.getBroadcastConfigurationNames(); - mBroadcastConfigurations = new JComboBox(channelNames.toArray(new String[channelNames.size()])); + mBroadcastConfigurations = new JComboBox(channelNames.toArray(new String[0])); mBroadcastConfigurations.addActionListener(new ActionListener() { @Override diff --git a/src/main/java/io/github/dsheirer/alias/id/radio/RadioFormatter.java b/src/main/java/io/github/dsheirer/alias/id/radio/RadioFormatter.java index 77127bfe..1d542e9e 100644 --- a/src/main/java/io/github/dsheirer/alias/id/radio/RadioFormatter.java +++ b/src/main/java/io/github/dsheirer/alias/id/radio/RadioFormatter.java @@ -29,6 +29,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.text.ParseException; +import java.util.EnumMap; import java.util.HashMap; import java.util.Map; @@ -38,7 +39,7 @@ import java.util.Map; public class RadioFormatter { private final static Logger mLog = LoggerFactory.getLogger(RadioFormatter.class); - private static Map mFormatterMap = new HashMap<>(); + private static Map mFormatterMap = new EnumMap<>(Protocol.class); static { diff --git a/src/main/java/io/github/dsheirer/alias/id/talkgroup/TalkgroupFormatter.java b/src/main/java/io/github/dsheirer/alias/id/talkgroup/TalkgroupFormatter.java index 20cd88b0..46c964e5 100644 --- a/src/main/java/io/github/dsheirer/alias/id/talkgroup/TalkgroupFormatter.java +++ b/src/main/java/io/github/dsheirer/alias/id/talkgroup/TalkgroupFormatter.java @@ -32,6 +32,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.text.ParseException; +import java.util.EnumMap; import java.util.HashMap; import java.util.Map; @@ -41,7 +42,7 @@ import java.util.Map; public class TalkgroupFormatter { private final static Logger mLog = LoggerFactory.getLogger(TalkgroupFormatter.class); - private static Map mFormatterMap = new HashMap<>(); + private static Map mFormatterMap = new EnumMap<>(Protocol.class); static { diff --git a/src/main/java/io/github/dsheirer/audio/AudioSegment.java b/src/main/java/io/github/dsheirer/audio/AudioSegment.java index 1d605bbd..5fd20ef7 100644 --- a/src/main/java/io/github/dsheirer/audio/AudioSegment.java +++ b/src/main/java/io/github/dsheirer/audio/AudioSegment.java @@ -384,10 +384,7 @@ public class AudioSegment implements Listener } //Add all broadcast channels for the alias ... let the set handle duplication. - for(BroadcastChannel broadcastChannel: alias.getBroadcastChannels()) - { - mBroadcastChannels.add(broadcastChannel); - } + mBroadcastChannels.addAll(alias.getBroadcastChannels()); //Only assign a playback priority if it is lower priority than the current setting. int playbackPriority = alias.getPlaybackPriority(); diff --git a/src/main/java/io/github/dsheirer/audio/broadcast/AudioBroadcaster.java b/src/main/java/io/github/dsheirer/audio/broadcast/AudioBroadcaster.java index cb50878d..59770cb5 100644 --- a/src/main/java/io/github/dsheirer/audio/broadcast/AudioBroadcaster.java +++ b/src/main/java/io/github/dsheirer/audio/broadcast/AudioBroadcaster.java @@ -25,6 +25,7 @@ import io.github.dsheirer.audio.convert.ISilenceGenerator; import io.github.dsheirer.identifier.IdentifierCollection; import io.github.dsheirer.sample.Listener; import io.github.dsheirer.util.ThreadPool; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -360,7 +361,7 @@ public abstract class AudioBroadcaster implements Listener //Trim length to whole-frame intervals (144 byte frame) bytesToStream -= (bytesToStream % 144); - int length = Math.min(bytesToStream, mInputStream.available()); + int length = FastMath.min(bytesToStream, mInputStream.available()); byte[] audio = new byte[length]; diff --git a/src/main/java/io/github/dsheirer/audio/broadcast/broadcastify/UserFeedSelectionDialog.java b/src/main/java/io/github/dsheirer/audio/broadcast/broadcastify/UserFeedSelectionDialog.java index 24e56907..c6cc6d68 100644 --- a/src/main/java/io/github/dsheirer/audio/broadcast/broadcastify/UserFeedSelectionDialog.java +++ b/src/main/java/io/github/dsheirer/audio/broadcast/broadcastify/UserFeedSelectionDialog.java @@ -174,7 +174,7 @@ public class UserFeedSelectionDialog extends JDialog implements DocumentListener mLog.info("RR User:" + userInfo.getUserName() + " Expiration Date:" + userInfo.getExpirationDate()); List feeds = service.getUserFeeds(); - mUserFeedBroadcastList.setListData(feeds.toArray(new UserFeedBroadcast[feeds.size()])); + mUserFeedBroadcastList.setListData(feeds.toArray(new UserFeedBroadcast[0])); } catch(RadioReferenceException rre) { diff --git a/src/main/java/io/github/dsheirer/audio/broadcast/shoutcast/v2/ShoutcastV2AudioBroadcaster.java b/src/main/java/io/github/dsheirer/audio/broadcast/shoutcast/v2/ShoutcastV2AudioBroadcaster.java index 37f78165..28f6a291 100644 --- a/src/main/java/io/github/dsheirer/audio/broadcast/shoutcast/v2/ShoutcastV2AudioBroadcaster.java +++ b/src/main/java/io/github/dsheirer/audio/broadcast/shoutcast/v2/ShoutcastV2AudioBroadcaster.java @@ -50,6 +50,7 @@ import io.github.dsheirer.identifier.IdentifierCollection; import io.github.dsheirer.identifier.Role; import io.github.dsheirer.properties.SystemProperties; import io.github.dsheirer.util.ThreadPool; +import org.apache.commons.math3.util.FastMath; import org.apache.mina.core.RuntimeIoException; import org.apache.mina.core.future.ConnectFuture; import org.apache.mina.core.service.IoHandlerAdapter; @@ -363,7 +364,7 @@ public class ShoutcastV2AudioBroadcaster extends AudioBroadcaster implements IBr int pointer = 0; int messageCounter = 1; - int messageCount = (int) Math.ceil((double) xml.length / (double) (mMaxPayloadSize - 6)); + int messageCount = (int) FastMath.ceil((double) xml.length / (double) (mMaxPayloadSize - 6)); if(messageCount > 32) { @@ -375,7 +376,7 @@ public class ShoutcastV2AudioBroadcaster extends AudioBroadcaster implements IBr while(pointer < xml.length && messageCounter <= messageCount) { - int payloadSize = Math.min(mMaxPayloadSize - 6, xml.length - pointer); + int payloadSize = FastMath.min(mMaxPayloadSize - 6, xml.length - pointer); byte[] payload = new byte[payloadSize + 6]; diff --git a/src/main/java/io/github/dsheirer/audio/convert/MP3AudioConverter.java b/src/main/java/io/github/dsheirer/audio/convert/MP3AudioConverter.java index 176bc1aa..d90d71a1 100644 --- a/src/main/java/io/github/dsheirer/audio/convert/MP3AudioConverter.java +++ b/src/main/java/io/github/dsheirer/audio/convert/MP3AudioConverter.java @@ -23,6 +23,7 @@ import io.github.dsheirer.audio.AudioUtils; import net.sourceforge.lame.lowlevel.LameEncoder; import net.sourceforge.lame.mp3.Lame; import net.sourceforge.lame.mp3.MPEGMode; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -59,7 +60,7 @@ public class MP3AudioConverter implements IAudioConverter byte[] pcmBytes = AudioUtils.convertTo16BitSamples(audioPackets); - int pcmBufferSize = Math.min(mMP3Buffer.length, pcmBytes.length); + int pcmBufferSize = FastMath.min(mMP3Buffer.length, pcmBytes.length); int mp3BufferSize = 0; @@ -70,7 +71,7 @@ public class MP3AudioConverter implements IAudioConverter while (0 < (mp3BufferSize = mEncoder.encodeBuffer(pcmBytes, pcmBytesPosition, pcmBufferSize, mMP3Buffer))) { pcmBytesPosition += pcmBufferSize; - pcmBufferSize = Math.min(mMP3Buffer.length, pcmBytes.length - pcmBytesPosition); + pcmBufferSize = FastMath.min(mMP3Buffer.length, pcmBytes.length - pcmBytesPosition); mMP3Stream.write(mMP3Buffer, 0, mp3BufferSize); } @@ -89,7 +90,7 @@ public class MP3AudioConverter implements IAudioConverter byte[] pcmBytes = AudioUtils.convert(audioBuffers); - int pcmBufferSize = Math.min(mMP3Buffer.length, pcmBytes.length); + int pcmBufferSize = FastMath.min(mMP3Buffer.length, pcmBytes.length); int mp3BufferSize = 0; @@ -100,7 +101,7 @@ public class MP3AudioConverter implements IAudioConverter while (0 < (mp3BufferSize = mEncoder.encodeBuffer(pcmBytes, pcmBytesPosition, pcmBufferSize, mMP3Buffer))) { pcmBytesPosition += pcmBufferSize; - pcmBufferSize = Math.min(mMP3Buffer.length, pcmBytes.length - pcmBytesPosition); + pcmBufferSize = FastMath.min(mMP3Buffer.length, pcmBytes.length - pcmBytesPosition); mMP3Stream.write(mMP3Buffer, 0, mp3BufferSize); } diff --git a/src/main/java/io/github/dsheirer/audio/playback/AudioPlaybackManager.java b/src/main/java/io/github/dsheirer/audio/playback/AudioPlaybackManager.java index 35d2af58..8052b5fc 100644 --- a/src/main/java/io/github/dsheirer/audio/playback/AudioPlaybackManager.java +++ b/src/main/java/io/github/dsheirer/audio/playback/AudioPlaybackManager.java @@ -195,7 +195,7 @@ public class AudioPlaybackManager implements Listener, IAudioContr //Sort audio segments by playback priority and assign to empty audio outputs if(!mAudioSegments.isEmpty()) { - Collections.sort(mAudioSegments, Comparator.comparingInt(o -> o.monitorPriorityProperty().get())); + mAudioSegments.sort(Comparator.comparingInt(o -> o.monitorPriorityProperty().get())); //Assign empty audio outputs first for(AudioOutput audioOutput: mAudioOutputs) @@ -347,14 +347,7 @@ public class AudioPlaybackManager implements Listener, IAudioContr { List outputs = new ArrayList<>(mAudioOutputs); - Collections.sort(outputs, new Comparator() - { - @Override - public int compare(AudioOutput first, AudioOutput second) - { - return first.getChannelName().compareTo(second.getChannelName()); - } - }); + outputs.sort(Comparator.comparing(AudioOutput::getChannelName)); return outputs; } diff --git a/src/main/java/io/github/dsheirer/bits/BinaryMessage.java b/src/main/java/io/github/dsheirer/bits/BinaryMessage.java index 7e59046e..1b9acb83 100644 --- a/src/main/java/io/github/dsheirer/bits/BinaryMessage.java +++ b/src/main/java/io/github/dsheirer/bits/BinaryMessage.java @@ -23,6 +23,7 @@ package io.github.dsheirer.bits; import io.github.dsheirer.edac.CRC; import org.apache.commons.lang3.Validate; +import org.apache.commons.math3.util.FastMath; import java.util.BitSet; @@ -593,7 +594,7 @@ public class BinaryMessage extends BitSet */ public byte[] getBytes() { - byte[] bytes = new byte[(int)Math.ceil((double)size() / 8.0)]; + byte[] bytes = new byte[(int)FastMath.ceil((double)size() / 8.0)]; for(int x = 0; x < bytes.length; x++) { @@ -795,7 +796,7 @@ public class BinaryMessage extends BitSet */ public int getInt(int start, int end) { - if(Math.abs(end - start) > 32) + if(FastMath.abs(end - start) > 32) { throw new IllegalArgumentException("Overflow - must be 32 bits " + "or less to fit into a primitive integer value"); @@ -847,7 +848,7 @@ public class BinaryMessage extends BitSet */ public long getLong(int start, int end) { - if(Math.abs(end - start) > 64) + if(FastMath.abs(end - start) > 64) { throw new IllegalArgumentException("Overflow - must be 64 bits " + "or less to fit into a primitive long value"); diff --git a/src/main/java/io/github/dsheirer/bits/MessageFramer.java b/src/main/java/io/github/dsheirer/bits/MessageFramer.java index 97fb43e4..935e8f77 100644 --- a/src/main/java/io/github/dsheirer/bits/MessageFramer.java +++ b/src/main/java/io/github/dsheirer/bits/MessageFramer.java @@ -171,9 +171,8 @@ public class MessageFramer implements IBinarySymbolProcessor, Listener, this(messageLength); /* Pre-load the message with the sync pattern */ - for(int x = 0; x < initialFill.length; x++) - { - receive(initialFill[x]); + for (boolean b : initialFill) { + receive(b); } } diff --git a/src/main/java/io/github/dsheirer/bits/MultiSyncPatternMatcher.java b/src/main/java/io/github/dsheirer/bits/MultiSyncPatternMatcher.java index cd4cd25c..e3a58008 100644 --- a/src/main/java/io/github/dsheirer/bits/MultiSyncPatternMatcher.java +++ b/src/main/java/io/github/dsheirer/bits/MultiSyncPatternMatcher.java @@ -23,6 +23,7 @@ package io.github.dsheirer.bits; import io.github.dsheirer.dsp.symbol.ISyncDetectListener; import org.apache.commons.lang3.Validate; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,7 +58,7 @@ public class MultiSyncPatternMatcher Validate.isTrue(syncSize < 64); //Setup a bit mask of all ones the length of the sync pattern - mMask = (long)((Math.pow(2, syncSize)) - 1); + mMask = (long)((FastMath.pow(2, syncSize)) - 1); } public void dispose() diff --git a/src/main/java/io/github/dsheirer/bits/SyncPatternMatcher.java b/src/main/java/io/github/dsheirer/bits/SyncPatternMatcher.java index 7adf426f..3d3c12bd 100644 --- a/src/main/java/io/github/dsheirer/bits/SyncPatternMatcher.java +++ b/src/main/java/io/github/dsheirer/bits/SyncPatternMatcher.java @@ -18,6 +18,8 @@ package io.github.dsheirer.bits; +import org.apache.commons.math3.util.FastMath; + /** * Sync pattern matcher. * @@ -37,7 +39,7 @@ public class SyncPatternMatcher public SyncPatternMatcher(boolean[] syncPattern) { //Setup a bit mask of all ones the length of the sync pattern - mMask = (long)((Math.pow(2, syncPattern.length)) - 1); + mMask = (long)((FastMath.pow(2, syncPattern.length)) - 1); //Convert the sync bits into a long value for comparison for(int x = 0; x < syncPattern.length; x++) diff --git a/src/main/java/io/github/dsheirer/buffer/BooleanAveragingBuffer.java b/src/main/java/io/github/dsheirer/buffer/BooleanAveragingBuffer.java index 9d37d2e3..2c6f0e04 100644 --- a/src/main/java/io/github/dsheirer/buffer/BooleanAveragingBuffer.java +++ b/src/main/java/io/github/dsheirer/buffer/BooleanAveragingBuffer.java @@ -76,10 +76,8 @@ public class BooleanAveragingBuffer mTrueCount = 0; - for(int x = 0; x < mBuffer.length; x++) - { - if(mBuffer[x]) - { + for (boolean b : mBuffer) { + if (b) { mTrueCount++; } } diff --git a/src/main/java/io/github/dsheirer/channel/metadata/ChannelMetadataPanel.java b/src/main/java/io/github/dsheirer/channel/metadata/ChannelMetadataPanel.java index 13fc3f12..784589c6 100644 --- a/src/main/java/io/github/dsheirer/channel/metadata/ChannelMetadataPanel.java +++ b/src/main/java/io/github/dsheirer/channel/metadata/ChannelMetadataPanel.java @@ -55,6 +55,7 @@ import java.awt.Component; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.text.DecimalFormat; +import java.util.EnumMap; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -68,8 +69,8 @@ public class ChannelMetadataPanel extends JPanel implements ListSelectionListene private UserPreferences mUserPreferences; private JTable mTable; private Broadcaster mSelectedProcessingChainBroadcaster = new Broadcaster<>(); - private Map mBackgroundColors = new HashMap<>(); - private Map mForegroundColors = new HashMap<>(); + private Map mBackgroundColors = new EnumMap<>(State.class); + private Map mForegroundColors = new EnumMap<>(State.class); private JTableColumnWidthMonitor mTableColumnMonitor; /** diff --git a/src/main/java/io/github/dsheirer/channel/state/DecoderStateEvent.java b/src/main/java/io/github/dsheirer/channel/state/DecoderStateEvent.java index e724ce99..2edb5ff5 100644 --- a/src/main/java/io/github/dsheirer/channel/state/DecoderStateEvent.java +++ b/src/main/java/io/github/dsheirer/channel/state/DecoderStateEvent.java @@ -128,11 +128,11 @@ public class DecoderStateEvent { StringBuilder sb = new StringBuilder(); - sb.append("Decoder State Event - source[" + mSource.getClass() + - "] event[" + mEvent.toString() + - "] state[" + mState.toString() + - "] timeslot[" + mTimeslot + - "] frequency [" + mFrequency + "]"); + sb.append("Decoder State Event - source[").append(mSource.getClass()) + .append("] event[").append(mEvent) + .append("] state[").append(mState) + .append("] timeslot[").append(mTimeslot) + .append("] frequency [").append(mFrequency).append("]"); return sb.toString(); } diff --git a/src/main/java/io/github/dsheirer/controller/channel/ChannelModel.java b/src/main/java/io/github/dsheirer/controller/channel/ChannelModel.java index 3dedb42a..31c48b89 100644 --- a/src/main/java/io/github/dsheirer/controller/channel/ChannelModel.java +++ b/src/main/java/io/github/dsheirer/controller/channel/ChannelModel.java @@ -251,26 +251,16 @@ public class ChannelModel extends AbstractTableModel implements Listener() - { - @Override - public int compare(Channel channel1, Channel channel2) - { - if(channel1.hasAutoStartOrder() && channel2.hasAutoStartOrder()) - { - return Integer.compare(channel1.getAutoStartOrder(), channel2.getAutoStartOrder()); - } - else if(channel1.hasAutoStartOrder()) - { - return -1; - } - else if(channel2.hasAutoStartOrder()) - { - return 1; - } - - return 0; + autoStartChannels.sort((channel1, channel2) -> { + if (channel1.hasAutoStartOrder() && channel2.hasAutoStartOrder()) { + return Integer.compare(channel1.getAutoStartOrder(), channel2.getAutoStartOrder()); + } else if (channel1.hasAutoStartOrder()) { + return -1; + } else if (channel2.hasAutoStartOrder()) { + return 1; } + + return 0; }); return autoStartChannels; diff --git a/src/main/java/io/github/dsheirer/controller/channel/NameConfigurationEditor.java b/src/main/java/io/github/dsheirer/controller/channel/NameConfigurationEditor.java index 6699e177..199cfa92 100644 --- a/src/main/java/io/github/dsheirer/controller/channel/NameConfigurationEditor.java +++ b/src/main/java/io/github/dsheirer/controller/channel/NameConfigurationEditor.java @@ -110,7 +110,7 @@ public class NameConfigurationEditor extends Editor implements Document else { mSiteNameCombo.setModel(new DefaultComboBoxModel( - sites.toArray(new String[sites.size()]))); + sites.toArray(new String[0]))); ; } @@ -267,7 +267,7 @@ public class NameConfigurationEditor extends Editor implements Document else { mSystemNameCombo.setModel(new DefaultComboBoxModel( - systems.toArray(new String[systems.size()]))); + systems.toArray(new String[0]))); ; } @@ -282,7 +282,7 @@ public class NameConfigurationEditor extends Editor implements Document else { mSiteNameCombo.setModel(new DefaultComboBoxModel( - sites.toArray(new String[sites.size()]))); + sites.toArray(new String[0]))); ; } @@ -294,7 +294,7 @@ public class NameConfigurationEditor extends Editor implements Document List lists = mAliasModel.getListNames(); Collections.sort(lists); mAliasListCombo.setModel(new DefaultComboBoxModel( - lists.toArray(new String[lists.size()]))); + lists.toArray(new String[0]))); if(channel.getAliasListName() != null) { diff --git a/src/main/java/io/github/dsheirer/controller/channel/map/ChannelRange.java b/src/main/java/io/github/dsheirer/controller/channel/map/ChannelRange.java index 35ba0440..f87e1686 100644 --- a/src/main/java/io/github/dsheirer/controller/channel/map/ChannelRange.java +++ b/src/main/java/io/github/dsheirer/controller/channel/map/ChannelRange.java @@ -60,13 +60,13 @@ public class ChannelRange if(isValid()) { sb.append("First: "); - sb.append(mFirst + "="); + sb.append(mFirst).append("="); long frequency = getFrequency(mFirst); sb.append(FREQUENCY_FORMATTER.format((double)frequency / 1E6D)); sb.append(" Last: "); - sb.append(mLast + "="); + sb.append(mLast).append("="); frequency = getFrequency(mLast); sb.append(FREQUENCY_FORMATTER.format((double)frequency / 1E6D)); diff --git a/src/main/java/io/github/dsheirer/dsp/afsk/AFSK1200Decoder.java b/src/main/java/io/github/dsheirer/dsp/afsk/AFSK1200Decoder.java index f2ca56bc..f2b76925 100644 --- a/src/main/java/io/github/dsheirer/dsp/afsk/AFSK1200Decoder.java +++ b/src/main/java/io/github/dsheirer/dsp/afsk/AFSK1200Decoder.java @@ -26,6 +26,7 @@ import io.github.dsheirer.dsp.mixer.IOscillator; import io.github.dsheirer.dsp.mixer.Oscillator; import io.github.dsheirer.sample.Listener; import io.github.dsheirer.sample.buffer.ReusableFloatBuffer; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -247,7 +248,7 @@ public class AFSK1200Decoder implements Listener //Add the absolute value of correlation accumulator value to the averaging buffer and store the current //average as the correlation value for this sample. We use absolute value because we don't care if the //signal is out of phase with the reference samples - mCorrelationValues[x] = mAveragingBuffer.get(Math.abs(mCorrelationAccumulator)); + mCorrelationValues[x] = mAveragingBuffer.get(FastMath.abs(mCorrelationAccumulator)); } return mCorrelationValues; diff --git a/src/main/java/io/github/dsheirer/dsp/afsk/AFSKTest.java b/src/main/java/io/github/dsheirer/dsp/afsk/AFSKTest.java index 3e215f0c..8c44b959 100644 --- a/src/main/java/io/github/dsheirer/dsp/afsk/AFSKTest.java +++ b/src/main/java/io/github/dsheirer/dsp/afsk/AFSKTest.java @@ -19,6 +19,7 @@ import io.github.dsheirer.buffer.FloatAveragingBuffer; import io.github.dsheirer.dsp.mixer.IOscillator; import io.github.dsheirer.dsp.mixer.Oscillator; import io.github.dsheirer.sample.complex.Complex; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -110,8 +111,8 @@ public class AFSKTest correlation1800 += reference1800[x] * samples[x + offset]; } - correlation1200 = avg1200.get(Math.abs(correlation1200)); - correlation1800 = avg1800.get(Math.abs(correlation1800)); + correlation1200 = avg1200.get(FastMath.abs(correlation1200)); + correlation1800 = avg1800.get(FastMath.abs(correlation1800)); mLog.debug(offset + " 1200:" + format(correlation1200) + " 1800:" + format(correlation1800) + " Decision: " + (correlation1200 > correlation1800 ? "0" : "1")); diff --git a/src/main/java/io/github/dsheirer/dsp/am/AMDemodulator.java b/src/main/java/io/github/dsheirer/dsp/am/AMDemodulator.java index bec59588..7e540441 100644 --- a/src/main/java/io/github/dsheirer/dsp/am/AMDemodulator.java +++ b/src/main/java/io/github/dsheirer/dsp/am/AMDemodulator.java @@ -18,6 +18,7 @@ package io.github.dsheirer.dsp.am; import io.github.dsheirer.sample.buffer.ReusableBufferQueue; import io.github.dsheirer.sample.buffer.ReusableComplexBuffer; import io.github.dsheirer.sample.buffer.ReusableFloatBuffer; +import org.apache.commons.math3.util.FastMath; /** * Performs AM demodulation on baseband I/Q samples to produce demodulated float output. @@ -55,7 +56,7 @@ public class AMDemodulator */ public float demodulate(float inphase, float quadrature) { - return (float)Math.sqrt((inphase * inphase) + (quadrature * quadrature)) * mGain; + return (float) FastMath.sqrt((inphase * inphase) + (quadrature * quadrature)) * mGain; } /** diff --git a/src/main/java/io/github/dsheirer/dsp/filter/FilterFactory.java b/src/main/java/io/github/dsheirer/dsp/filter/FilterFactory.java index cab8d1b7..a3897c40 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/FilterFactory.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/FilterFactory.java @@ -26,6 +26,7 @@ import io.github.dsheirer.dsp.filter.design.FilterDesignException; import io.github.dsheirer.dsp.filter.fir.FIRFilterSpecification; import io.github.dsheirer.dsp.filter.fir.remez.RemezFIRFilterDesigner; import io.github.dsheirer.dsp.filter.fir.remez.RemezFIRFilterDesignerWithLagrange; +import org.apache.commons.math3.util.FastMath; import org.jtransforms.fft.FloatFFT_1D; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -109,9 +110,8 @@ public class FilterFactory { float accumulator = 0; - for(int x = 0; x < coefficients.length; x++) - { - accumulator += Math.abs(coefficients[x]); + for (float coefficient : coefficients) { + accumulator += FastMath.abs(coefficient); } for(int x = 0; x < coefficients.length; x++) @@ -133,9 +133,8 @@ public class FilterFactory { float accumulator = 0; - for(int x = 0; x < coefficients.length; x++) - { - accumulator += Math.abs(coefficients[x]); + for (float coefficient : coefficients) { + accumulator += FastMath.abs(coefficient); } accumulator /= objective; @@ -171,7 +170,7 @@ public class FilterFactory if(length % 2 == 0) //even length { - int binCount = (int)((Math.round((float)frequency / (float)sampleRate * (float)length))); + int binCount = (int)((FastMath.round((float)frequency / (float)sampleRate * (float)length))); for(int x = 0; x < binCount; x++) { @@ -181,7 +180,7 @@ public class FilterFactory } else //odd length { - int binCount = (int)((Math.round((float)frequency / (float)sampleRate * (float)length + 0.5))); + int binCount = (int)((FastMath.round((float)frequency / (float)sampleRate * (float)length + 0.5))); unityArray[0] = 1.0f; @@ -316,7 +315,7 @@ public class FilterFactory StringBuilder sb = new StringBuilder(); for(int x = 0; x < array.length; x++) { - sb.append(x + ": " + array[x]); + sb.append(x).append(": ").append(array[x]); if(breaks) { @@ -354,7 +353,7 @@ public class FilterFactory { double frequency = ((double)stop - (double)pass) / sampleRate; - return (int)(Math.round((double)attenuation / (22.0d * frequency))); + return (int)(FastMath.round((double)attenuation / (22.0d * frequency))); } /** @@ -431,7 +430,7 @@ public class FilterFactory for(Integer factor : factors) { - int testDelta = Math.abs(desiredFactor - factor); + int testDelta = FastMath.abs(desiredFactor - factor); if(testDelta < bestDelta) { @@ -484,7 +483,7 @@ public class FilterFactory { double ratio = getBandwidthRatio(passFrequency, stopFrequency); - double numerator = 1.0d - (Math.sqrt((double)decimation * ratio / (2.0d - ratio))); + double numerator = 1.0d - (FastMath.sqrt((double)decimation * ratio / (2.0d - ratio))); double denominator = 2.0d - (ratio * (decimation + 1.0d)); @@ -559,18 +558,18 @@ public class FilterFactory { float[] cicArray = new float[length * 2]; - int binCount = (int)((Math.round( + int binCount = (int)((FastMath.round( (double)frequency / (double)sampleRate * 2.0d * (double)length))); cicArray[0] = 1.0f; - float unityResponse = (float)(Math.sin(1.0d / (double)length) / + float unityResponse = (float)(FastMath.sin(1.0d / (double)length) / (1.0d / (double)length)); for(int x = 1; x <= binCount; x++) { /* Calculate unity response plus amplification for droop */ - float compensated = 1.0f + (unityResponse - (float)(Math.sin((double)x / (double)length) / ((double)x / (double)length))); + float compensated = 1.0f + (unityResponse - (float)(FastMath.sin((double)x / (double)length) / ((double)x / (double)length))); cicArray[x] = compensated; cicArray[length - x] = compensated; @@ -612,25 +611,25 @@ public class FilterFactory { float index = (float)x - ((float)taps / 2.0f); - float x1 = (float)Math.PI * index / (float)samplesPerSymbol; + float x1 = (float)FastMath.PI * index / (float)samplesPerSymbol; float x2 = 4.0f * alpha * index / (float)samplesPerSymbol; float x3 = x2 * x2 - 1.0f; float numerator, denominator; - if(Math.abs(x3) >= 0.000001) + if(FastMath.abs(x3) >= 0.000001) { if(x != taps / 2) { - numerator = (float)Math.cos((1.0 + alpha) * x1) + - (float)Math.sin((1.0f - alpha) * x1) / (4.0f * alpha * index / (float)samplesPerSymbol); + numerator = (float)FastMath.cos((1.0 + alpha) * x1) + + (float)FastMath.sin((1.0f - alpha) * x1) / (4.0f * alpha * index / (float)samplesPerSymbol); } else { - numerator = (float)Math.cos((1.0f + alpha) * x1) + (1.0f - alpha) * (float)Math.PI / (4.0f * alpha); + numerator = (float)FastMath.cos((1.0f + alpha) * x1) + (1.0f - alpha) * (float)FastMath.PI / (4.0f * alpha); } - denominator = x3 * (float)Math.PI; + denominator = x3 * (float)FastMath.PI; } else { @@ -643,11 +642,11 @@ public class FilterFactory x3 = (1.0f - alpha) * x1; x2 = (1.0f + alpha) * x1; - numerator = (float)(Math.sin(x2) * (1.0f + alpha) * Math.PI - Math.cos(x3) * ((1.0 - alpha) * Math.PI * - (double)samplesPerSymbol) / (4.0 * alpha * index) + Math.sin(x3) * (double)samplesPerSymbol * + numerator = (float)(FastMath.sin(x2) * (1.0f + alpha) * FastMath.PI - FastMath.cos(x3) * ((1.0 - alpha) * FastMath.PI * + (double)samplesPerSymbol) / (4.0 * alpha * index) + FastMath.sin(x3) * (double)samplesPerSymbol * (double)samplesPerSymbol / (4.0 * alpha * index * index)); - denominator = (float)(-32.0 * Math.PI * alpha * alpha * index / (double)samplesPerSymbol); + denominator = (float)(-32.0 * FastMath.PI * alpha * alpha * index / (double)samplesPerSymbol); } coefficients[x] = 4.0f * alpha * numerator / denominator; @@ -699,8 +698,8 @@ public class FilterFactory for(int x = 0; x < filter.length; x++) { - real += filter[x] * Math.cos(Math.PI * frequency * (double)x); - imag += filter[x] * Math.sin(Math.PI * frequency * (double)x); + real += filter[x] * FastMath.cos(FastMath.PI * frequency * (double)x); + imag += filter[x] * FastMath.sin(FastMath.PI * frequency * (double)x); } return decibel(real, imag); @@ -715,7 +714,7 @@ public class FilterFactory */ public static double decibel(double real, double imag) { - return (float)(10.0 * Math.log10(Math.pow(real, 2.0) + Math.pow(imag, 2.0))); + return (float)(10.0 * FastMath.log10(FastMath.pow(real, 2.0) + FastMath.pow(imag, 2.0))); } @@ -738,9 +737,9 @@ public class FilterFactory double bandEdgeFrequency = (double)channelBandwidth / (double)(channels * channelBandwidth * 2); - double response = decibel(designer.getFrequencyResponse(Math.cos(bandEdgeFrequency * Math.PI)), 0.0); + double response = decibel(designer.getFrequencyResponse(FastMath.cos(bandEdgeFrequency * FastMath.PI)), 0.0); mLog.debug("Frequency Response at 1.0: " + response); - response = decibel(designer.getFrequencyResponse(Math.cos(bandEdgeFrequency * Math.PI * 2.0)), 0.0); + response = decibel(designer.getFrequencyResponse(FastMath.cos(bandEdgeFrequency * FastMath.PI * 2.0)), 0.0); mLog.debug("Frequency Response at 2.0: " + response); return taps; @@ -946,14 +945,14 @@ public class FilterFactory double[] window = Window.getWindow(windowType, length); double scalor = 2.0 * cutoff; - double piScalor = Math.PI * scalor; + double piScalor = FastMath.PI * scalor; coefficients[half] = (float)(1.0 * scalor * window[half]); for(int x = 1; x <= half; x++) { double a = piScalor * x; - double coefficient = scalor * Math.sin(a) / a; + double coefficient = scalor * FastMath.sin(a) / a; coefficient *= window[half + x]; coefficients[half + x] = (float)coefficient; @@ -985,14 +984,14 @@ public class FilterFactory double[] window = Window.getKaiser(length, attenuation); double scalor = 2.0 * cutoff; - double piScalor = Math.PI * scalor; + double piScalor = FastMath.PI * scalor; coefficients[half] = (float)(1.0 * scalor * window[half]); for(int x = 1; x <= half; x++) { double a = piScalor * x; - double coefficient = scalor * Math.sin(a) / a; + double coefficient = scalor * FastMath.sin(a) / a; coefficient *= window[half + x]; coefficients[half + x] = (float)coefficient; @@ -1011,7 +1010,7 @@ public class FilterFactory */ private static boolean matchesObjective(double a, double objective, double marginOfError) { - return Math.abs(a - objective) <= marginOfError; + return FastMath.abs(a - objective) <= marginOfError; } public static void main(String[] args) diff --git a/src/main/java/io/github/dsheirer/dsp/filter/FloatFIRFilter.java b/src/main/java/io/github/dsheirer/dsp/filter/FloatFIRFilter.java index c712d238..2eac14dc 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/FloatFIRFilter.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/FloatFIRFilter.java @@ -126,7 +126,7 @@ public class FloatFIRFilter implements RealSampleListener { for( int y = 0; y < mCoefficients.length; y++ ) { - sb.append( mIndexMap[ x ][ y ] + " " ); + sb.append(mIndexMap[x][y]).append(" "); } sb.append( "\n" ); } diff --git a/src/main/java/io/github/dsheirer/dsp/filter/GoertzelFilter.java b/src/main/java/io/github/dsheirer/dsp/filter/GoertzelFilter.java index 6bbb0997..6cb112e8 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/GoertzelFilter.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/GoertzelFilter.java @@ -18,6 +18,7 @@ package io.github.dsheirer.dsp.filter; import io.github.dsheirer.dsp.filter.Window.WindowType; +import org.apache.commons.math3.util.FastMath; /** @@ -68,7 +69,7 @@ public class GoertzelFilter private void init() { double normalizedFrequency = (double) mTargetFrequency / mSampleRate; - mCoefficient = 2.0D * Math.cos( 2 * Math.PI * normalizedFrequency ); + mCoefficient = 2.0D * FastMath.cos( 2 * FastMath.PI * normalizedFrequency ); } @@ -101,20 +102,19 @@ public class GoertzelFilter double s = 0.0D; double s_prev = 0.0D; double s_prev2 = 0.0D; - - for ( int x = 0; x < samples.length; x++ ) - { - s = samples[x] + ( mCoefficient * s_prev ) - s_prev2; - s_prev2 = s_prev; - s_prev = s; - } + + for (float sample : samples) { + s = sample + (mCoefficient * s_prev) - s_prev2; + s_prev2 = s_prev; + s_prev = s; + } //power = s_prev2 * s_prev2 + s_prev * s_prev - coeff * s_prev * s_prev2 ; double magnitude = ( s_prev2 * s_prev2 ) + ( s_prev * s_prev) - (mCoefficient * s_prev * s_prev2); int binZero = getBinZeroPower( samples ); - int power = (int) (20 * Math.log10( magnitude / binZero ) ); + int power = (int) (20 * FastMath.log10( magnitude / binZero ) ); return power; } @@ -125,10 +125,9 @@ public class GoertzelFilter private int getBinZeroPower( float[] samples ) { int retVal = 0; - - for( int x = 0; x < samples.length; x++ ) - { - retVal += samples[ x ]; + + for (float sample : samples) { + retVal += sample; } return retVal; diff --git a/src/main/java/io/github/dsheirer/dsp/filter/IIRBiQuadraticFilter.java b/src/main/java/io/github/dsheirer/dsp/filter/IIRBiQuadraticFilter.java index 6ab72dfc..fe93fb7e 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/IIRBiQuadraticFilter.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/IIRBiQuadraticFilter.java @@ -17,6 +17,8 @@ ******************************************************************************/ package io.github.dsheirer.dsp.filter; +import org.apache.commons.math3.util.FastMath; + /*************************************************************************** * Copyright (C) 2011 by Paul Lutus * * lutusp@arachnoid.com * @@ -93,12 +95,12 @@ final public class IIRBiQuadraticFilter { public void reconfigure(double cf) { center_freq = cf; // only used for peaking and shelving filters - gain_abs = Math.pow(10, gainDB / 40); - double omega = 2 * Math.PI * cf / sample_rate; - double sn = Math.sin(omega); - double cs = Math.cos(omega); + gain_abs = FastMath.pow(10, gainDB / 40); + double omega = 2 * FastMath.PI * cf / sample_rate; + double sn = FastMath.sin(omega); + double cs = FastMath.cos(omega); double alpha = sn / (2 * Q); - double beta = Math.sqrt(gain_abs + gain_abs); + double beta = FastMath.sqrt(gain_abs + gain_abs); switch (type) { case BANDPASS: b0 = alpha; @@ -167,8 +169,8 @@ final public class IIRBiQuadraticFilter { // provide a static amplitude result for testing public double result(double f) { - double phi = Math.pow((Math.sin(2.0 * Math.PI * f / (2.0 * sample_rate))), 2.0); - return (Math.pow(b0 + b1 + b2, 2.0) - 4.0 * (b0 * b1 + 4.0 * b0 * b2 + b1 * b2) * phi + 16.0 * b0 * b2 * phi * phi) / (Math.pow(1.0 + a1 + a2, 2.0) - 4.0 * (a1 + 4.0 * a2 + a1 * a2) * phi + 16.0 * a2 * phi * phi); + double phi = FastMath.pow((FastMath.sin(2.0 * FastMath.PI * f / (2.0 * sample_rate))), 2.0); + return (FastMath.pow(b0 + b1 + b2, 2.0) - 4.0 * (b0 * b1 + 4.0 * b0 * b2 + b1 * b2) * phi + 16.0 * b0 * b2 * phi * phi) / (FastMath.pow(1.0 + a1 + a2, 2.0) - 4.0 * (a1 + 4.0 * a2 + a1 * a2) * phi + 16.0 * a2 * phi * phi); } // provide a static decibel result for testing @@ -176,7 +178,7 @@ final public class IIRBiQuadraticFilter { { double r; try { - r = 10 * Math.log10(result(f)); + r = 10 * FastMath.log10(result(f)); } catch (Exception e) { r = -100; } diff --git a/src/main/java/io/github/dsheirer/dsp/filter/Window.java b/src/main/java/io/github/dsheirer/dsp/filter/Window.java index a97f1453..b67b459a 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/Window.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/Window.java @@ -36,6 +36,7 @@ */ package io.github.dsheirer.dsp.filter; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,10 +49,10 @@ public class Window { private final static Logger mLog = LoggerFactory.getLogger(Window.class); - private static final double TWO_PI = Math.PI * 2.0d; - private static final double FOUR_PI = Math.PI * 4.0d; - private static final double SIX_PI = Math.PI * 6.0d; - private static final double EIGHT_PI = Math.PI * 8.0d; + private static final double TWO_PI = FastMath.PI * 2.0d; + private static final double FOUR_PI = FastMath.PI * 4.0d; + private static final double SIX_PI = FastMath.PI * 6.0d; + private static final double EIGHT_PI = FastMath.PI * 8.0d; /** * Creates a window of the specified type and length. @@ -121,8 +122,8 @@ public class Window for(int x = -half; x < length / 2 + 1; x++) { - coefficients[x + half] = Math.cos( - ((double)x * Math.PI) / ((double)length + 1.0d)); + coefficients[x + half] = FastMath.cos( + ((double)x * FastMath.PI) / ((double)length + 1.0d)); } } else //Odd length @@ -131,8 +132,8 @@ public class Window for(int x = -half; x < half + 1; x++) { - coefficients[x + half] = Math.cos( - ((double)x * Math.PI) / ((double)length + 1.0d)); + coefficients[x + half] = FastMath.cos( + ((double)x * FastMath.PI) / ((double)length + 1.0d)); } } @@ -158,8 +159,8 @@ public class Window for(int x = 0; x < length; x++) { coefficients[x] = a0 - - (a1 * Math.cos((TWO_PI * (double)x) / denominator)) + - (a2 * Math.cos((FOUR_PI * (double)x) / denominator)); + (a1 * FastMath.cos((TWO_PI * (double)x) / denominator)) + + (a2 * FastMath.cos((FOUR_PI * (double)x) / denominator)); } return coefficients; @@ -184,9 +185,9 @@ public class Window for(int x = 0; x < length; x++) { coefficients[x] = a0 - - (a1 * Math.cos(TWO_PI * (double)x / denominator)) + - (a2 * Math.cos(FOUR_PI * (double)x / denominator)) - - (a3 * Math.cos(SIX_PI * (double)x / denominator)); + (a1 * FastMath.cos(TWO_PI * (double)x / denominator)) + + (a2 * FastMath.cos(FOUR_PI * (double)x / denominator)) - + (a3 * FastMath.cos(SIX_PI * (double)x / denominator)); } return coefficients; @@ -211,9 +212,9 @@ public class Window for(int x = 0; x < length; x++) { coefficients[x] = a0 - - (a1 * Math.cos(TWO_PI * (double)x / denominator)) + - (a2 * Math.cos(FOUR_PI * (double)x / denominator)) - - (a3 * Math.cos(SIX_PI * (double)x / denominator)); + (a1 * FastMath.cos(TWO_PI * (double)x / denominator)) + + (a2 * FastMath.cos(FOUR_PI * (double)x / denominator)) - + (a3 * FastMath.cos(SIX_PI * (double)x / denominator)); } return coefficients; @@ -238,9 +239,9 @@ public class Window for(int x = 0; x < length; x++) { coefficients[x] = a0 - - (a1 * Math.cos(TWO_PI * (double)x / denominator)) + - (a2 * Math.cos(FOUR_PI * (double)x / denominator)) - - (a3 * Math.cos(SIX_PI * (double)x / denominator)); + (a1 * FastMath.cos(TWO_PI * (double)x / denominator)) + + (a2 * FastMath.cos(FOUR_PI * (double)x / denominator)) - + (a3 * FastMath.cos(SIX_PI * (double)x / denominator)); } return coefficients; @@ -272,12 +273,12 @@ public class Window double w = TWO_PI * (double)x / denominator; coefficients[x] = a0 - - (a1 * Math.cos(w)) + - (a2 * Math.cos(2.0 * w)) - - (a3 * Math.cos(3.0 * w)) + - (a4 * Math.cos(4.0 * w)) - - (a5 * Math.cos(5.0 * w)) + - (a6 * Math.cos(6.0 * w)); + (a1 * FastMath.cos(w)) + + (a2 * FastMath.cos(2.0 * w)) - + (a3 * FastMath.cos(3.0 * w)) + + (a4 * FastMath.cos(4.0 * w)) - + (a5 * FastMath.cos(5.0 * w)) + + (a6 * FastMath.cos(6.0 * w)); } return coefficients; @@ -299,7 +300,7 @@ public class Window for(int x = 0; x < length; x++) { - coefficients[x] = a0 - (a1 * Math.cos(TWO_PI * (double)x / denominator)); + coefficients[x] = a0 - (a1 * FastMath.cos(TWO_PI * (double)x / denominator)); } return coefficients; @@ -321,7 +322,7 @@ public class Window for(int x = 0; x < length; x++) { - coefficients[x] = a0 - (a1 * Math.cos(TWO_PI * (double)x / denominator)); + coefficients[x] = a0 - (a1 * FastMath.cos(TWO_PI * (double)x / denominator)); } return coefficients; @@ -348,10 +349,10 @@ public class Window for(int x = 0; x < length; x++) { coefficients[x] = a0 - - (a1 * Math.cos(TWO_PI * (double)x / denominator)) + - (a2 * Math.cos(FOUR_PI * (double)x / denominator)) - - (a3 * Math.cos(SIX_PI * (double)x / denominator)) + - (a4 * Math.cos(EIGHT_PI * (double)x / denominator)); + (a1 * FastMath.cos(TWO_PI * (double)x / denominator)) + + (a2 * FastMath.cos(FOUR_PI * (double)x / denominator)) - + (a3 * FastMath.cos(SIX_PI * (double)x / denominator)) + + (a4 * FastMath.cos(EIGHT_PI * (double)x / denominator)); } return coefficients; @@ -371,7 +372,7 @@ public class Window } else if(attenuation >= 21.0) { - return (0.5842 * Math.pow(attenuation - 21.0, 0.4)) + (0.07886 * (attenuation - 21.0)); + return (0.5842 * FastMath.pow(attenuation - 21.0, 0.4)) + (0.07886 * (attenuation - 21.0)); } else { @@ -398,7 +399,7 @@ public class Window for(int x = 0; x < coefficients.length; x++) { - temp = beta * Math.sqrt(1.0 - Math.pow(2.0 * x / (length - 1) - 1.0, 2)); + temp = beta * FastMath.sqrt(1.0 - FastMath.pow(2.0 * x / (length - 1) - 1.0, 2)); coefficients[x] = getBesselZerothOrder(temp) / betaBesselZerothOrder; } diff --git a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ChannelCalculator.java b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ChannelCalculator.java index db76ab0d..8b5b0189 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ChannelCalculator.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ChannelCalculator.java @@ -17,6 +17,7 @@ package io.github.dsheirer.dsp.filter.channelizer; import io.github.dsheirer.source.tuner.channel.TunerChannel; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -293,7 +294,7 @@ public class ChannelCalculator { double offset = frequency - getCenterFrequency(); - if(Math.abs(offset) < getHalfChannelBandwidth()) + if(FastMath.abs(offset) < getHalfChannelBandwidth()) { return 0; //Center index } diff --git a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ComplexPolyphaseChannelizerM2.java b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ComplexPolyphaseChannelizerM2.java index 5a41e15e..c8f797e3 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ComplexPolyphaseChannelizerM2.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/ComplexPolyphaseChannelizerM2.java @@ -24,6 +24,7 @@ import io.github.dsheirer.sample.IOverflowListener; import io.github.dsheirer.sample.Listener; import io.github.dsheirer.sample.buffer.ReusableChannelResultsBuffer; import io.github.dsheirer.sample.buffer.ReusableComplexBuffer; +import org.apache.commons.math3.util.FastMath; import org.jtransforms.fft.FloatFFT_1D; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -71,8 +72,6 @@ public class ComplexPolyphaseChannelizerM2 extends AbstractComplexPolyphaseChann private FloatFFT_1D mFFT; private float[] mInlineSamples; private float[] mInlineFilter; - private float[] mInlineInterimOutput; - private float[] mFilterAccumulator; private boolean mTopBlockIndicator = true; private int[] mTopBlockMap; private int[] mMiddleBlockMap; @@ -100,7 +99,7 @@ public class ComplexPolyphaseChannelizerM2 extends AbstractComplexPolyphaseChann throw new IllegalArgumentException("Channel count must be an even multiple of the over-sample rate (2x)"); } - mTapsPerChannel = (int)Math.ceil((double)taps.length / (double)channelCount); + mTapsPerChannel = (int) FastMath.ceil((double)taps.length / (double)channelCount); init(taps); } @@ -204,9 +203,10 @@ public class ComplexPolyphaseChannelizerM2 extends AbstractComplexPolyphaseChann { samplesToCopy = mSamplesPerBlock - mSampleBufferPointer; - if((samples.length - samplesPointer) < samplesToCopy) + int samplesDiff = samples.length - samplesPointer; + if(samplesDiff < samplesToCopy) { - samplesToCopy = (samples.length - samplesPointer); + samplesToCopy = samplesDiff; } System.arraycopy(samples, samplesPointer, mInlineSamples, mSampleBufferPointer, samplesToCopy); @@ -336,13 +336,16 @@ public class ComplexPolyphaseChannelizerM2 extends AbstractComplexPolyphaseChann */ private void process(ReusableChannelResultsBuffer channelResultsBuffer) { + int bufferLength = getSubChannelCount() * mTapsPerChannel; + float[] inlineInterimOutput = new float[bufferLength]; + //Multiply each of the samples by the corresponding filter tap for(int x = 0; x < mInlineSamples.length; x++) { - mInlineInterimOutput[x] = mInlineSamples[x] * mInlineFilter[x]; + inlineInterimOutput[x] = mInlineSamples[x] * mInlineFilter[x]; } - Arrays.fill(mFilterAccumulator, 0.0f); + float[] filterAccumulator = new float[getSubChannelCount()]; int tapOffset = 0; @@ -353,7 +356,7 @@ public class ComplexPolyphaseChannelizerM2 extends AbstractComplexPolyphaseChann for(int channel = 0; channel < getSubChannelCount(); channel++) { - mFilterAccumulator[channel] += mInlineInterimOutput[tapOffset + channel]; + filterAccumulator[channel] += inlineInterimOutput[tapOffset + channel]; } } @@ -363,14 +366,14 @@ public class ComplexPolyphaseChannelizerM2 extends AbstractComplexPolyphaseChann { for(int x = 0; x < getSubChannelCount(); x++) { - processed[x] = mFilterAccumulator[mTopBlockMap[x]]; + processed[x] = filterAccumulator[mTopBlockMap[x]]; } } else { for(int x = 0; x < getSubChannelCount(); x++) { - processed[x] = mFilterAccumulator[mMiddleBlockMap[x]]; + processed[x] = filterAccumulator[mMiddleBlockMap[x]]; } } @@ -394,8 +397,6 @@ public class ComplexPolyphaseChannelizerM2 extends AbstractComplexPolyphaseChann mMiddleBlockMap = getMiddleBlockMap(channelCount); mInlineFilter = getAlignedFilter(coefficients, channelCount, mTapsPerChannel); mInlineSamples = new float[bufferLength]; - mInlineInterimOutput = new float[bufferLength]; - mFilterAccumulator = new float[getSubChannelCount()]; } /** @@ -413,32 +414,20 @@ public class ComplexPolyphaseChannelizerM2 extends AbstractComplexPolyphaseChann //dispatcher thread that is part of this continuous buffer processor. We perform an IFFT on each //channel results array contained in each results buffer and then dispatch the buffer //so that it can be distributed to each channel listener. - setListener(new Listener>() - { - @Override - public void receive(List buffers) + setListener(buffers -> { + for(ReusableChannelResultsBuffer buffer: buffers) { - for(ReusableChannelResultsBuffer buffer: buffers) + for(float[] channelResults: buffer.getChannelResults()) { - for(float[] channelResults: buffer.getChannelResults()) - { - //Rotate each of the channels to the correct phase using the IFFT - mFFT.complexInverse(channelResults, true); - } - - dispatch(buffer); + //Rotate each of the channels to the correct phase using the IFFT + mFFT.complexInverse(channelResults, true); } + + dispatch(buffer); } }); - setOverflowListener(new IOverflowListener() - { - @Override - public void sourceOverflow(boolean overflow) - { - mLog.debug("IFFTProcessor overflow changed - overflow:" + overflow); - } - }); + setOverflowListener(overflow -> mLog.debug("IFFTProcessor overflow changed - overflow:" + overflow)); } /** diff --git a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelManager.java b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelManager.java index 92da1704..6f0499a7 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelManager.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelManager.java @@ -38,6 +38,7 @@ import io.github.dsheirer.source.tuner.TunerController; import io.github.dsheirer.source.tuner.channel.ChannelSpecification; import io.github.dsheirer.source.tuner.channel.TunerChannel; import io.github.dsheirer.source.tuner.channel.TunerChannelSource; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -339,7 +340,7 @@ public class PolyphaseChannelManager implements ISourceEventProcessor double tunerSampleRate = mChannelCalculator.getSampleRate(); //If the channelizer is not setup, or setup to the wrong sample rate, recreate it - if(mPolyphaseChannelizer == null || Math.abs(mPolyphaseChannelizer.getSampleRate() - tunerSampleRate) > 0.5) + if(mPolyphaseChannelizer == null || FastMath.abs(mPolyphaseChannelizer.getSampleRate() - tunerSampleRate) > 0.5) { if(mPolyphaseChannelizer != null && mPolyphaseChannelizer.getRegisteredChannelCount() > 0) { diff --git a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelSource.java b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelSource.java index de590798..8aee60f4 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelSource.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelSource.java @@ -286,9 +286,10 @@ public class PolyphaseChannelSource extends TunerChannelSource private float[] getLowPassFilter(double sampleRate, double passFrequency, double stopFrequency) throws FilterDesignException { //Use existing filter if we've already designed one - if(sLowPassFilters.containsKey((int)sampleRate)) + float[] filter = sLowPassFilters.get((int) sampleRate); + if(filter != null) { - return sLowPassFilters.get((int)sampleRate); + return filter; } FIRFilterSpecification specification = FIRFilterSpecification.lowPassBuilder() diff --git a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/TwoChannelSynthesizerM2.java b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/TwoChannelSynthesizerM2.java index a8bbc02c..2ba55d27 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/TwoChannelSynthesizerM2.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/TwoChannelSynthesizerM2.java @@ -17,6 +17,7 @@ package io.github.dsheirer.dsp.filter.channelizer; import io.github.dsheirer.sample.buffer.ReusableComplexBuffer; import io.github.dsheirer.sample.buffer.ReusableComplexBufferQueue; +import org.apache.commons.math3.util.FastMath; import org.jtransforms.fft.FloatFFT_1D; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,7 +50,6 @@ public class TwoChannelSynthesizerM2 private float[] mSerpentineDataBuffer; private float[] mIQInterleavedFilter; private float[] mFilterVectorProduct; - private float[] mIFFTBuffer = new float[4]; private float mIAccumulator; private float mQAccumulator; private FloatFFT_1D mFFT = new FloatFFT_1D(2); @@ -72,7 +72,7 @@ public class TwoChannelSynthesizerM2 */ private void init(float[] filter) { - int tapsPerChannel = (int)Math.ceil(filter.length / 2); + int tapsPerChannel = (int) FastMath.ceil(filter.length / 2); mIQInterleavedFilter = getInterleavedFilter(filter, tapsPerChannel); mSerpentineDataBuffer = new float[mIQInterleavedFilter.length]; @@ -100,17 +100,18 @@ public class TwoChannelSynthesizerM2 ReusableComplexBuffer synthesizedComplexBuffer = mReusableComplexBufferQueue.getBuffer(channel1.length); float[] output = synthesizedComplexBuffer.getSamples(); + float[] IFFTBuffer = new float[4]; for(int x = 0; x < channel1.length; x += 2) { //Load samples from each channel into buffer for IFFT - mIFFTBuffer[0] = channel1[x]; //i - mIFFTBuffer[1] = channel1[x + 1]; //q - mIFFTBuffer[2] = channel2[x]; //i - mIFFTBuffer[3] = channel2[x + 1]; //q + IFFTBuffer[0] = channel1[x]; //i + IFFTBuffer[1] = channel1[x + 1]; //q + IFFTBuffer[2] = channel2[x]; //i + IFFTBuffer[3] = channel2[x + 1]; //q //Perform Inverse FFT (IFFT) - mFFT.complexInverse(mIFFTBuffer, true); + mFFT.complexInverse(IFFTBuffer, true); //Perform serpentine shift of data blocks in the data buffer - make room for 4 new samples System.arraycopy(mSerpentineDataBuffer, 0, mSerpentineDataBuffer, 4, mSerpentineDataBuffer.length - 4); @@ -118,13 +119,13 @@ public class TwoChannelSynthesizerM2 //Top Block - load samples into data buffer in normal order if(mTopBlockFlag) { - System.arraycopy(mIFFTBuffer, 0, mSerpentineDataBuffer, 0, mIFFTBuffer.length); + System.arraycopy(IFFTBuffer, 0, mSerpentineDataBuffer, 0, IFFTBuffer.length); } //Bottom Block - swap samples via data loading to account for phase shift else { - System.arraycopy(mIFFTBuffer, 0, mSerpentineDataBuffer, 2, 2); - System.arraycopy(mIFFTBuffer, 2, mSerpentineDataBuffer, 0, 2); + System.arraycopy(IFFTBuffer, 0, mSerpentineDataBuffer, 2, 2); + System.arraycopy(IFFTBuffer, 2, mSerpentineDataBuffer, 0, 2); } //Note: in order to use Java's ability to leverage SIMD intrinsics, we perform filtering in two steps diff --git a/src/main/java/io/github/dsheirer/dsp/filter/cic/ComplexPrimeCICDecimate.java b/src/main/java/io/github/dsheirer/dsp/filter/cic/ComplexPrimeCICDecimate.java index d49929bb..7093b939 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/cic/ComplexPrimeCICDecimate.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/cic/ComplexPrimeCICDecimate.java @@ -29,6 +29,7 @@ import io.github.dsheirer.sample.buffer.ReusableComplexBufferAssembler; import io.github.dsheirer.sample.complex.ComplexSampleListener; import io.github.dsheirer.sample.decimator.ComplexDecimator; import org.apache.commons.lang3.Validate; +import org.apache.commons.math3.primes.Primes; import java.util.ArrayList; import java.util.HashMap; @@ -49,38 +50,6 @@ public class ComplexPrimeCICDecimate implements Listener { // private final static Logger mLog = LoggerFactory.getLogger(ComplexPrimeCICDecimate.class); - /** - * PRIME numbers to use for decimation stage sizing. This list contains values that should - * support input sample rates up to 70 MHz with an output channel rate of at least 25 kHz. - */ - public static int[] PRIMES = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, - 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, - 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, - 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, - 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, - 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, - 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, - 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, - 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, - 967, 971, 977, 983, 991, 997, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, - 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, - 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, - 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, - 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, - 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, - 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, - 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, - 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, - 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, - 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, - 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297, - 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399, - 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, - 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, - 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, - 2767, 2777, 2789, 2791, 2797, 2801 - }; - private static Map sLowPassFilters = new HashMap(); private static Map> sPrimeFactors = new HashMap(); @@ -111,8 +80,6 @@ public class ComplexPrimeCICDecimate implements Listener public ComplexPrimeCICDecimate(double sampleRate, int decimation, double passFrequency, double stopFrequency) throws FilterDesignException { - Validate.isTrue(decimation <= PRIMES[PRIMES.length - 1]); - List stageSizes = getPrimeFactors(decimation); for(int x = 0; x < stageSizes.size(); x++) @@ -180,35 +147,13 @@ public class ComplexPrimeCICDecimate implements Listener */ public static List getPrimeFactors(int decimation) { - if(decimation > PRIMES[PRIMES.length - 1]) + List primeFactors = sPrimeFactors.get(decimation); + if(primeFactors != null) { - throw new IllegalArgumentException("Decimation rates higher than [" + PRIMES[PRIMES.length - 1] + - "] are not supported. Update the PRIMES array to add support for higher decimation rates"); + return primeFactors; } - if(sPrimeFactors.containsKey(decimation)) - { - return sPrimeFactors.get(decimation); - } - - List primeFactors = new ArrayList(); - - int pointer = 0; - - while(decimation > 0 && pointer < PRIMES.length) - { - int prime = PRIMES[pointer]; - - if(decimation % prime == 0) - { - primeFactors.add(prime); - decimation /= prime; - } - else - { - pointer++; - } - } + primeFactors = Primes.primeFactors(decimation); sPrimeFactors.put(decimation, primeFactors); @@ -481,9 +426,10 @@ public class ComplexPrimeCICDecimate implements Listener private float[] getLowPassFilter(double sampleRate, double passFrequency, double stopFrequency) throws FilterDesignException { //Use existing filter if we've already designed one - if(sLowPassFilters.containsKey((int)sampleRate)) + float[] existingFilter = sLowPassFilters.get((int) sampleRate); + if(existingFilter != null) { - return sLowPassFilters.get((int)sampleRate); + return existingFilter; } FIRFilterSpecification specification = FIRFilterSpecification.lowPassBuilder() diff --git a/src/main/java/io/github/dsheirer/dsp/filter/cic/RealPrimeCICDecimate.java b/src/main/java/io/github/dsheirer/dsp/filter/cic/RealPrimeCICDecimate.java index 07c5c8ee..1acd545d 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/cic/RealPrimeCICDecimate.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/cic/RealPrimeCICDecimate.java @@ -28,6 +28,7 @@ import io.github.dsheirer.sample.buffer.ReusableFloatBuffer; import io.github.dsheirer.sample.decimator.RealDecimator; import io.github.dsheirer.sample.real.RealSampleListener; import org.apache.commons.lang3.Validate; +import org.apache.commons.math3.primes.Primes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,14 +39,6 @@ public class RealPrimeCICDecimate { private final static Logger mLog = LoggerFactory.getLogger(RealPrimeCICDecimate.class); - public static int[] PRIMES = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, - 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, - 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, - 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, - 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, - 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, - 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691}; - private List mDecimatingStages = new ArrayList(); private DecimatingStage mFirstDecimatingStage; private Output mOutput; @@ -79,7 +72,7 @@ public class RealPrimeCICDecimate mOutputBufferSize = outputBufferSize; - List stageSizes = getPrimeFactors(decimation); + List stageSizes = Primes.primeFactors(decimation); for(int x = 0; x < stageSizes.size(); x++) { @@ -137,39 +130,6 @@ public class RealPrimeCICDecimate mOutput.removeListener(); } - /** - * Calculates the prime factors of the decimation rate up to a maximum - * decimation rate of 700. If you wish to have decimation rates higher - * than 700, then add additional prime factors to the PRIMES array. - * - * @param decimation - integral decimation rate - * @return - ordered list (smallest to largest) of prime factors - */ - public static List getPrimeFactors(int decimation) - { - ArrayList stages = new ArrayList(); - - int pointer = 0; - - while(decimation > 0 && pointer < PRIMES.length) - { - int prime = PRIMES[pointer]; - - if(decimation % prime == 0) - { - stages.add(prime); - - decimation /= prime; - } - else - { - pointer++; - } - } - - return stages; - } - /** * Primary input method for receiving real buffers. */ diff --git a/src/main/java/io/github/dsheirer/dsp/filter/dc/BufferDCFilter.java b/src/main/java/io/github/dsheirer/dsp/filter/dc/BufferDCFilter.java index 8d8c997a..9d12e45d 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/dc/BufferDCFilter.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/dc/BufferDCFilter.java @@ -43,9 +43,8 @@ public class BufferDCFilter { mAccumulator = 0.0; - for(int x = 0; x < samples.length; x++) - { - mAccumulator += samples[x]; + for (float sample : samples) { + mAccumulator += sample; } return (float)(mAccumulator / (double)samples.length); diff --git a/src/main/java/io/github/dsheirer/dsp/filter/design/FilterView.java b/src/main/java/io/github/dsheirer/dsp/filter/design/FilterView.java index f0ee3b78..8d6046c9 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/design/FilterView.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/design/FilterView.java @@ -23,6 +23,7 @@ import javafx.scene.chart.XYChart.Series; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; +import org.apache.commons.math3.util.FastMath; import org.jtransforms.fft.FloatFFT_1D; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -140,7 +141,7 @@ public class FilterView extends BorderPane mImpulseXAxis.setUpperBound(taps.length - 1); mImpulseXAxis.setTickUnit(1.0); - double padding = Math.abs(largest - smallest) * .1; + double padding = FastMath.abs(largest - smallest) * .1; mImpulseYAxis.setLowerBound(smallest - padding); mImpulseYAxis.setUpperBound(largest + padding); @@ -180,7 +181,7 @@ public class FilterView extends BorderPane { index = x * 2; - decibels[x] = 20.0f * (float)Math.log10(((dft[index] * dft[index]) + + decibels[x] = 20.0f * (float)FastMath.log10(((dft[index] * dft[index]) + (dft[index + 1] * dft[index + 1]))); } diff --git a/src/main/java/io/github/dsheirer/dsp/filter/fir/FIRFilterSpecification.java b/src/main/java/io/github/dsheirer/dsp/filter/fir/FIRFilterSpecification.java index e60716e1..3872a8ce 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/fir/FIRFilterSpecification.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/fir/FIRFilterSpecification.java @@ -2,6 +2,7 @@ package io.github.dsheirer.dsp.filter.fir; import io.github.dsheirer.dsp.filter.fir.remez.FIRLinearPhaseFilterType; import org.apache.commons.lang3.Validate; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -887,7 +888,7 @@ public class FIRFilterSpecification */ private static int getFilterOrder(double length) { - return (int)(Math.ceil(length) - 1); + return (int)(FastMath.ceil(length) - 1); } /** @@ -908,10 +909,10 @@ public class FIRFilterSpecification public static int estimateFilterOrder(double sampleRate, double frequency1, double frequency2, double passBandRipple, double stopBandRipple) { - double df = Math.abs(frequency2 - frequency1) / sampleRate; + double df = FastMath.abs(frequency2 - frequency1) / sampleRate; - double ddp = Math.log10(stopBandRipple <= passBandRipple ? passBandRipple : stopBandRipple); - double dds = Math.log10(stopBandRipple <= passBandRipple ? stopBandRipple : passBandRipple); + double ddp = FastMath.log10(FastMath.max(stopBandRipple, passBandRipple)); + double dds = FastMath.log10(FastMath.min(stopBandRipple, passBandRipple)); double a1 = 5.309e-3; double a2 = 7.114e-2; @@ -932,7 +933,7 @@ public class FIRFilterSpecification double ff = b1 + b2 * (ddp - dds); double n = dinf / df - ff * df + 1.0; - return (int)Math.ceil(n); + return (int)FastMath.ceil(n); } /** @@ -946,9 +947,9 @@ public class FIRFilterSpecification public static int estimateBandPassOrder(double sampleRate, int passBandStart, int passBandEnd, double passBandRippleDb, double stopBandRippleDb) { - double df = (double)Math.abs(passBandEnd - passBandStart) / sampleRate; - double ddp = Math.log10(passBandRippleDb); - double dds = Math.log10(stopBandRippleDb); + double df = (double)FastMath.abs(passBandEnd - passBandStart) / sampleRate; + double ddp = FastMath.log10(passBandRippleDb); + double dds = FastMath.log10(stopBandRippleDb); double a1 = 0.01201; double a2 = 0.09664; @@ -963,10 +964,10 @@ public class FIRFilterSpecification double t4 = a5 * ddp; double cinf = dds * (t1 + t2 + a3) + t3 + t4 + a6; - double ginf = -14.6f * (double)Math.log10(passBandRippleDb / stopBandRippleDb) - 16.9; + double ginf = -14.6f * (double)FastMath.log10(passBandRippleDb / stopBandRippleDb) - 16.9; double n = cinf / df + ginf * df + 1.0; - return (int)Math.ceil(n); + return (int)FastMath.ceil(n); } /** @@ -1040,7 +1041,7 @@ public class FIRFilterSpecification public void setGridSize(int totalGridSize, double totalBandwidth) { - mGridSize = Math.max(1, (int)Math.ceil((double)totalGridSize * (getBandWidth() / totalBandwidth))); + mGridSize = FastMath.max(1, (int)FastMath.ceil((double)totalGridSize * (getBandWidth() / totalBandwidth))); } public String toString() @@ -1104,8 +1105,8 @@ public class FIRFilterSpecification */ public double getRippleAmplitude() { - return (Math.pow(10.0, (mRippleDB / 20)) - 1) - / (Math.pow(10.0, (mRippleDB / 20)) + 1); + return (FastMath.pow(10.0, (mRippleDB / 20)) - 1) + / (FastMath.pow(10.0, (mRippleDB / 20)) + 1); } /** diff --git a/src/main/java/io/github/dsheirer/dsp/filter/fir/remez/Grid.java b/src/main/java/io/github/dsheirer/dsp/filter/fir/remez/Grid.java index 302202d1..c9241c42 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/fir/remez/Grid.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/fir/remez/Grid.java @@ -1,10 +1,11 @@ package io.github.dsheirer.dsp.filter.fir.remez; import io.github.dsheirer.dsp.filter.fir.FIRFilterSpecification; +import org.apache.commons.math3.util.FastMath; public class Grid { - public static final double TWO_PI = 2.0 * Math.PI; + public static final double TWO_PI = 2.0 * FastMath.PI; private double[] mFrequencyGrid; private double[] mCosineOfFrequencyGrid; @@ -59,7 +60,7 @@ public class Grid //gridFrequencyInterval increments mFrequencyGrid[ j ] = lowFrequency; - mCosineOfFrequencyGrid[ j ] = Math.cos( TWO_PI * mFrequencyGrid[ j ] ); + mCosineOfFrequencyGrid[ j ] = FastMath.cos( TWO_PI * mFrequencyGrid[ j ] ); lowFrequency += gridFrequencyInterval; diff --git a/src/main/java/io/github/dsheirer/dsp/filter/fir/remez/PolyphaseChannelizerFilterFactory.java b/src/main/java/io/github/dsheirer/dsp/filter/fir/remez/PolyphaseChannelizerFilterFactory.java index 9cad5751..7d273914 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/fir/remez/PolyphaseChannelizerFilterFactory.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/fir/remez/PolyphaseChannelizerFilterFactory.java @@ -19,6 +19,7 @@ package io.github.dsheirer.dsp.filter.fir.remez; import io.github.dsheirer.dsp.filter.fir.FIRFilterSpecification; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -26,7 +27,7 @@ public class PolyphaseChannelizerFilterFactory { private final static Logger mLog = LoggerFactory.getLogger(PolyphaseChannelizerFilterFactory.class); - private static final double OBJECTIVE_BAND_EDGE_COEFFICIENT_AMPLITUDE = Math.sqrt(2.0) / 2.0; //.707xxx + private static final double OBJECTIVE_BAND_EDGE_COEFFICIENT_AMPLITUDE = FastMath.sqrt(2.0) / 2.0; //.707xxx public static float[] getFilter(int sampleRate, int channelBandwidth, double alpha) { @@ -77,7 +78,7 @@ public class PolyphaseChannelizerFilterFactory specification.addFrequencyBand(transitionBand); specification.addFrequencyBand(stopBand); - double bandEdgeFrequency = Math.cos(Math.PI * (double)channelBandwidth / (double)(sampleRate / 2)); + double bandEdgeFrequency = FastMath.cos(FastMath.PI * (double)channelBandwidth / (double)(sampleRate / 2)); float[] filter = null; try diff --git a/src/main/java/io/github/dsheirer/dsp/filter/fir/remez/RemezFIRFilterDesigner.java b/src/main/java/io/github/dsheirer/dsp/filter/fir/remez/RemezFIRFilterDesigner.java index bbfbf209..e813764a 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/fir/remez/RemezFIRFilterDesigner.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/fir/remez/RemezFIRFilterDesigner.java @@ -2,6 +2,7 @@ package io.github.dsheirer.dsp.filter.fir.remez; import io.github.dsheirer.dsp.filter.design.FilterDesignException; import io.github.dsheirer.dsp.filter.fir.FIRFilterSpecification; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -16,7 +17,7 @@ public class RemezFIRFilterDesigner private static final double CONVERGENCE_THRESHOLD = 0.0001; public static final int MAXIMUM_ITERATION_COUNT = 40; - public static final double TWO_PI = 2.0 * Math.PI; + public static final double TWO_PI = 2.0 * FastMath.PI; private static final DecimalFormat DECIMAL_FORMATTER = new DecimalFormat( "0.00000000" ); @@ -164,7 +165,7 @@ public class RemezFIRFilterDesigner for( int k = 1; k <= M; k++ ) { - accumulator += 2.0 * frequencyResponse[ k ] * Math.cos( frequency * (double)k ); + accumulator += 2.0 * frequencyResponse[ k ] * FastMath.cos( frequency * (double)k ); } impulseResponse[ n ] = accumulator / (double)length; @@ -181,7 +182,7 @@ public class RemezFIRFilterDesigner for( int k = 1; k < frequencyResponse.length; k++ ) { - accumulator += 2.0 * frequencyResponse[ k ] * Math.cos( frequency * (double)k ); + accumulator += 2.0 * frequencyResponse[ k ] * FastMath.cos( frequency * (double)k ); } impulseResponse[ n ] = accumulator / (double)length; @@ -214,7 +215,7 @@ public class RemezFIRFilterDesigner double cosineDelta = cosineOfFrequency - mGrid.getCosineFrequencyGrid()[ mExtremalIndices.get( k ) ]; //If this frequency is close to one of the polynomial points, use the polynomial point for the response - if( Math.abs( cosineDelta ) < 1.0e-7 ) + if( FastMath.abs( cosineDelta ) < 1.0e-7 ) { return mIdealFrequencyResponse[ k ]; } @@ -319,7 +320,7 @@ public class RemezFIRFilterDesigner double denominator = xk - xi; - if( Math.abs( denominator ) < 0.00001 ) + if( FastMath.abs( denominator ) < 0.00001 ) { denominator = 0.00001; } @@ -496,7 +497,7 @@ public class RemezFIRFilterDesigner //Check for consecutive (redundant) indices on same side of zero axis - retain largest if( !( positiveAxis ^ ( mGridErrors[ next ] > 0.0 ) ) ) { - if( Math.abs( mGridErrors[ next ] ) <= Math.abs( mGridErrors[ current ] )) + if( FastMath.abs( mGridErrors[ next ] ) <= FastMath.abs( mGridErrors[ current ] )) { //Remove next error index that is less than current index and on it.remove(); @@ -530,8 +531,8 @@ public class RemezFIRFilterDesigner { int lastIndex = mExtremalIndices.size() - 1; - if( Math.abs( mGridErrors[ mExtremalIndices.get( 0 )] ) > - Math.abs( mGridErrors[ mExtremalIndices.get( lastIndex )] ) ) + if( FastMath.abs( mGridErrors[ mExtremalIndices.get( 0 )] ) > + FastMath.abs( mGridErrors[ mExtremalIndices.get( lastIndex )] ) ) { mExtremalIndices.remove( lastIndex ); } @@ -560,7 +561,7 @@ public class RemezFIRFilterDesigner */ private boolean isGTEDelta( double value ) { - return Math.abs( value ) - Math.abs( mDelta ) > -1.0e-5; + return FastMath.abs( value ) - FastMath.abs( mDelta ) > -1.0e-5; } /** @@ -570,11 +571,11 @@ public class RemezFIRFilterDesigner */ public void checkConvergence() { - double maximum = Math.abs( mGridErrors[ mExtremalIndices.get( 0 ) ] ); + double maximum = FastMath.abs( mGridErrors[ mExtremalIndices.get( 0 ) ] ); for( int i = 1; i < mExtremalIndices.size(); i++ ) { - double current = Math.abs( mGridErrors[ mExtremalIndices.get( i ) ] ); + double current = FastMath.abs( mGridErrors[ mExtremalIndices.get( i ) ] ); if( current > maximum ) { @@ -582,7 +583,7 @@ public class RemezFIRFilterDesigner } } - double convergence = maximum - Math.abs( mDelta ); + double convergence = maximum - FastMath.abs( mDelta ); mConverged = convergence < CONVERGENCE_THRESHOLD; } @@ -619,11 +620,11 @@ public class RemezFIRFilterDesigner double half = (double)length / 2.0; - double[] resampled = new double[ (int)Math.ceil( half ) ] ; + double[] resampled = new double[ (int)FastMath.ceil( half ) ] ; for( int x = 0; x < resampled.length; x++ ) { - resampled[ x ] = getFrequencyResponse( Math.cos( Math.PI * (double)x / half ) ); + resampled[ x ] = getFrequencyResponse( FastMath.cos( FastMath.PI * (double)x / half ) ); } return resampled; @@ -651,15 +652,15 @@ public class RemezFIRFilterDesigner case TYPE_3_ODD_LENGTH_EVEN_ORDER_ANTI_SYMMETRICAL: for( int x = 0; x < frequencyResponse.length; x++ ) { - double frequencyRadians = Math.PI * ( ( (double)x ) / filterLength ); - frequencyResponse[ x ] *= Math.sin( TWO_PI * frequencyRadians ); + double frequencyRadians = FastMath.PI * ( ( (double)x ) / filterLength ); + frequencyResponse[ x ] *= FastMath.sin( TWO_PI * frequencyRadians ); } break; case TYPE_4_EVEN_LENGTH_ODD_ORDER_ANTI_SYMMETRICAL: for( int x = 0; x < frequencyResponse.length; x++ ) { - double frequencyRadians = Math.PI * ( ( (double)x ) / filterLength ); - frequencyResponse[ x ] *= Math.sin( Math.PI * frequencyRadians ); + double frequencyRadians = FastMath.PI * ( ( (double)x ) / filterLength ); + frequencyResponse[ x ] *= FastMath.sin( FastMath.PI * frequencyRadians ); } break; default: diff --git a/src/main/java/io/github/dsheirer/dsp/filter/fir/remez/RemezFIRFilterDesigner2.java b/src/main/java/io/github/dsheirer/dsp/filter/fir/remez/RemezFIRFilterDesigner2.java index 42c4c6d5..08443b48 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/fir/remez/RemezFIRFilterDesigner2.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/fir/remez/RemezFIRFilterDesigner2.java @@ -20,6 +20,7 @@ package io.github.dsheirer.dsp.filter.fir.remez; import io.github.dsheirer.dsp.filter.design.FilterDesignException; import io.github.dsheirer.dsp.filter.fir.FIRFilterSpecification; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,7 +36,7 @@ public class RemezFIRFilterDesigner2 private static final double CONVERGENCE_THRESHOLD = 0.0001; public static final int MAXIMUM_ITERATION_COUNT = 40; - public static final double TWO_PI = 2.0 * Math.PI; + public static final double TWO_PI = 2.0 * FastMath.PI; public static final double FREQUENCY_PROXIMITY_THRESHOLD = 1.0e-7; private FIRFilterSpecification mSpecification; @@ -189,7 +190,7 @@ public class RemezFIRFilterDesigner2 for(int k = 1; k <= M; k++) { - accumulator += 2.0 * frequencyResponse[k] * Math.cos(frequency * (double)k); + accumulator += 2.0 * frequencyResponse[k] * FastMath.cos(frequency * (double)k); } impulseResponse[n] = accumulator / (double)length; @@ -206,7 +207,7 @@ public class RemezFIRFilterDesigner2 for(int k = 1; k < frequencyResponse.length; k++) { - accumulator += 2.0 * frequencyResponse[k] * Math.cos(frequency * (double)k); + accumulator += 2.0 * frequencyResponse[k] * FastMath.cos(frequency * (double)k); } impulseResponse[n] = accumulator / (double)length; @@ -238,7 +239,7 @@ public class RemezFIRFilterDesigner2 double cosineDelta = cosineOfFrequency - mGrid.getCosineFrequencyGrid()[mExtremalIndices.get(k)]; //If this frequency is close to one of the polynomial points, use the point as the response value - if(Math.abs(cosineDelta) < FREQUENCY_PROXIMITY_THRESHOLD) + if(FastMath.abs(cosineDelta) < FREQUENCY_PROXIMITY_THRESHOLD) { return mIdealFrequencyResponse[k]; } @@ -360,7 +361,7 @@ public class RemezFIRFilterDesigner2 double denominator = xk - xi; - if(Math.abs(denominator) < 0.00001) + if(FastMath.abs(denominator) < 0.00001) { denominator = 0.00001; } @@ -537,7 +538,7 @@ public class RemezFIRFilterDesigner2 //Check for consecutive (redundant) indices on same side of zero axis - retain largest if(!(positiveAxis ^ (mGridErrors[next] > 0.0))) { - if(Math.abs(mGridErrors[next]) <= Math.abs(mGridErrors[current])) + if(FastMath.abs(mGridErrors[next]) <= FastMath.abs(mGridErrors[current])) { //Remove next error index that is less than current index and on it.remove(); @@ -571,8 +572,8 @@ public class RemezFIRFilterDesigner2 { int lastIndex = mExtremalIndices.size() - 1; - if(Math.abs(mGridErrors[mExtremalIndices.get(0)]) > - Math.abs(mGridErrors[mExtremalIndices.get(lastIndex)])) + if(FastMath.abs(mGridErrors[mExtremalIndices.get(0)]) > + FastMath.abs(mGridErrors[mExtremalIndices.get(lastIndex)])) { mExtremalIndices.remove(lastIndex); } @@ -600,7 +601,7 @@ public class RemezFIRFilterDesigner2 */ private boolean isGTEDelta(double value) { - return Math.abs(value) - Math.abs(mDelta) > -1.0e-5; + return FastMath.abs(value) - FastMath.abs(mDelta) > -1.0e-5; } /** @@ -610,11 +611,11 @@ public class RemezFIRFilterDesigner2 */ public void checkConvergence() { - double maximum = Math.abs(mGridErrors[mExtremalIndices.get(0)]); + double maximum = FastMath.abs(mGridErrors[mExtremalIndices.get(0)]); for(int i = 1; i < mExtremalIndices.size(); i++) { - double current = Math.abs(mGridErrors[mExtremalIndices.get(i)]); + double current = FastMath.abs(mGridErrors[mExtremalIndices.get(i)]); if(current > maximum) { @@ -622,7 +623,7 @@ public class RemezFIRFilterDesigner2 } } - double convergence = maximum - Math.abs(mDelta); + double convergence = maximum - FastMath.abs(mDelta); mConverged = convergence < CONVERGENCE_THRESHOLD; } @@ -659,11 +660,11 @@ public class RemezFIRFilterDesigner2 double half = (double)length / 2.0; - double[] resampled = new double[(int)Math.ceil(half)]; + double[] resampled = new double[(int)FastMath.ceil(half)]; for(int x = 0; x < resampled.length; x++) { - resampled[x] = getFrequencyResponse(Math.cos(Math.PI * (double)x / half)); + resampled[x] = getFrequencyResponse(FastMath.cos(FastMath.PI * (double)x / half)); } return resampled; @@ -690,15 +691,15 @@ public class RemezFIRFilterDesigner2 case TYPE_3_ODD_LENGTH_EVEN_ORDER_ANTI_SYMMETRICAL: for(int x = 0; x < frequencyResponse.length; x++) { - double frequencyRadians = Math.PI * (((double)x) / filterLength); - frequencyResponse[x] *= Math.sin(TWO_PI * frequencyRadians); + double frequencyRadians = FastMath.PI * (((double)x) / filterLength); + frequencyResponse[x] *= FastMath.sin(TWO_PI * frequencyRadians); } break; case TYPE_4_EVEN_LENGTH_ODD_ORDER_ANTI_SYMMETRICAL: for(int x = 0; x < frequencyResponse.length; x++) { - double frequencyRadians = Math.PI * (((double)x) / filterLength); - frequencyResponse[x] *= Math.sin(Math.PI * frequencyRadians); + double frequencyRadians = FastMath.PI * (((double)x) / filterLength); + frequencyResponse[x] *= FastMath.sin(FastMath.PI * frequencyRadians); } break; default: diff --git a/src/main/java/io/github/dsheirer/dsp/filter/fir/remez/RemezFIRFilterDesignerWithLagrange.java b/src/main/java/io/github/dsheirer/dsp/filter/fir/remez/RemezFIRFilterDesignerWithLagrange.java index 07765625..0f8cb796 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/fir/remez/RemezFIRFilterDesignerWithLagrange.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/fir/remez/RemezFIRFilterDesignerWithLagrange.java @@ -21,6 +21,7 @@ package io.github.dsheirer.dsp.filter.fir.remez; import io.github.dsheirer.dsp.filter.design.FilterDesignException; import io.github.dsheirer.dsp.filter.fir.FIRFilterSpecification; import org.apache.commons.math3.analysis.polynomials.PolynomialFunctionLagrangeForm; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,7 +37,7 @@ public class RemezFIRFilterDesignerWithLagrange private static final double CONVERGENCE_THRESHOLD = 0.0001; public static final int MAXIMUM_ITERATION_COUNT = 40; - public static final double TWO_PI = 2.0 * Math.PI; + public static final double TWO_PI = 2.0 * FastMath.PI; private static final DecimalFormat DECIMAL_FORMATTER = new DecimalFormat("0.00000000"); @@ -178,7 +179,7 @@ public class RemezFIRFilterDesignerWithLagrange for(int k = 1; k <= M; k++) { - accumulator += 2.0 * frequencyResponse[k] * Math.cos(frequency * (double)k); + accumulator += 2.0 * frequencyResponse[k] * FastMath.cos(frequency * (double)k); } impulseResponse[n] = accumulator / (double)length; @@ -195,7 +196,7 @@ public class RemezFIRFilterDesignerWithLagrange for(int k = 1; k < frequencyResponse.length; k++) { - accumulator += 2.0 * frequencyResponse[k] * Math.cos(frequency * (double)k); + accumulator += 2.0 * frequencyResponse[k] * FastMath.cos(frequency * (double)k); } impulseResponse[n] = accumulator / (double)length; @@ -351,7 +352,7 @@ public class RemezFIRFilterDesignerWithLagrange double denominator = xk - xi; - if(Math.abs(denominator) < 0.00001) + if(FastMath.abs(denominator) < 0.00001) { denominator = 0.00001; } @@ -511,7 +512,7 @@ public class RemezFIRFilterDesignerWithLagrange //Check for consecutive (redundant) indices on same side of zero axis - retain largest if(!(positiveAxis ^ (mGridErrors[next] > 0.0))) { - if(Math.abs(mGridErrors[next]) <= Math.abs(mGridErrors[current])) + if(FastMath.abs(mGridErrors[next]) <= FastMath.abs(mGridErrors[current])) { //Remove next error index that is less than current index and on it.remove(); @@ -545,8 +546,8 @@ public class RemezFIRFilterDesignerWithLagrange { int lastIndex = mExtremalIndices.size() - 1; - if(Math.abs(mGridErrors[mExtremalIndices.get(0)]) > - Math.abs(mGridErrors[mExtremalIndices.get(lastIndex)])) + if(FastMath.abs(mGridErrors[mExtremalIndices.get(0)]) > + FastMath.abs(mGridErrors[mExtremalIndices.get(lastIndex)])) { mExtremalIndices.remove(lastIndex); } @@ -574,7 +575,7 @@ public class RemezFIRFilterDesignerWithLagrange */ private boolean isGTEDelta(double value) { - return Math.abs(value) - Math.abs(mDelta) > -1.0e-5; + return FastMath.abs(value) - FastMath.abs(mDelta) > -1.0e-5; } /** @@ -584,11 +585,11 @@ public class RemezFIRFilterDesignerWithLagrange */ public void checkConvergence() { - double maximum = Math.abs(mGridErrors[mExtremalIndices.get(0)]); + double maximum = FastMath.abs(mGridErrors[mExtremalIndices.get(0)]); for(int i = 1; i < mExtremalIndices.size(); i++) { - double current = Math.abs(mGridErrors[mExtremalIndices.get(i)]); + double current = FastMath.abs(mGridErrors[mExtremalIndices.get(i)]); if(current > maximum) { @@ -596,7 +597,7 @@ public class RemezFIRFilterDesignerWithLagrange } } - double convergence = maximum - Math.abs(mDelta); + double convergence = maximum - FastMath.abs(mDelta); mLog.debug("Convergence: " + convergence); @@ -635,11 +636,11 @@ public class RemezFIRFilterDesignerWithLagrange double half = (double)length / 2.0; - double[] resampled = new double[(int)Math.ceil(half)]; + double[] resampled = new double[(int)FastMath.ceil(half)]; for(int x = 0; x < resampled.length; x++) { - resampled[x] = getFrequencyResponse(Math.cos(Math.PI * (double)x / half)); + resampled[x] = getFrequencyResponse(FastMath.cos(FastMath.PI * (double)x / half)); } return resampled; @@ -666,15 +667,15 @@ public class RemezFIRFilterDesignerWithLagrange case TYPE_3_ODD_LENGTH_EVEN_ORDER_ANTI_SYMMETRICAL: for(int x = 0; x < frequencyResponse.length; x++) { - double frequencyRadians = Math.PI * (((double)x) / filterLength); - frequencyResponse[x] *= Math.sin(TWO_PI * frequencyRadians); + double frequencyRadians = FastMath.PI * (((double)x) / filterLength); + frequencyResponse[x] *= FastMath.sin(TWO_PI * frequencyRadians); } break; case TYPE_4_EVEN_LENGTH_ODD_ORDER_ANTI_SYMMETRICAL: for(int x = 0; x < frequencyResponse.length; x++) { - double frequencyRadians = Math.PI * (((double)x) / filterLength); - frequencyResponse[x] *= Math.sin(Math.PI * frequencyRadians); + double frequencyRadians = FastMath.PI * (((double)x) / filterLength); + frequencyResponse[x] *= FastMath.sin(FastMath.PI * frequencyRadians); } break; default: diff --git a/src/main/java/io/github/dsheirer/dsp/filter/hilbert/HilbertTransform.java b/src/main/java/io/github/dsheirer/dsp/filter/hilbert/HilbertTransform.java index 98894616..32de3ee0 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/hilbert/HilbertTransform.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/hilbert/HilbertTransform.java @@ -16,6 +16,7 @@ package io.github.dsheirer.dsp.filter.hilbert; import io.github.dsheirer.dsp.filter.Filters; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -230,11 +231,11 @@ public class HilbertTransform { if(x < middle) { - mHilbertFilter[x] = 2.0f * -Math.abs(coefficients[x]); + mHilbertFilter[x] = 2.0f * -FastMath.abs(coefficients[x]); } else if(x > middle) { - mHilbertFilter[x] = 2.0f * Math.abs(coefficients[x]); + mHilbertFilter[x] = 2.0f * FastMath.abs(coefficients[x]); } else { diff --git a/src/main/java/io/github/dsheirer/dsp/filter/iir/DeemphasisFilter.java b/src/main/java/io/github/dsheirer/dsp/filter/iir/DeemphasisFilter.java index 601f4a38..0de85846 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/iir/DeemphasisFilter.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/iir/DeemphasisFilter.java @@ -15,6 +15,8 @@ ******************************************************************************/ package io.github.dsheirer.dsp.filter.iir; +import org.apache.commons.math3.util.FastMath; + public class DeemphasisFilter { private static final float MAX_SAMPLE_VALUE = 0.95f; @@ -24,7 +26,7 @@ public class DeemphasisFilter public DeemphasisFilter( float sampleRate, float cutoff, float gain ) { - mAlpha = (float)Math.exp( -2.0 * Math.PI * cutoff * ( 1.0 / sampleRate ) ); + mAlpha = (float)FastMath.exp( -2.0 * FastMath.PI * cutoff * ( 1.0 / sampleRate ) ); mGain = gain; } @@ -41,12 +43,7 @@ public class DeemphasisFilter { return MAX_SAMPLE_VALUE; } - else if( value < -MAX_SAMPLE_VALUE ) - { - return -MAX_SAMPLE_VALUE; - } - - else return value; + else return FastMath.max(value, -MAX_SAMPLE_VALUE); } public float[] filter( float[] samples ) diff --git a/src/main/java/io/github/dsheirer/dsp/filter/interpolator/RealInterpolator.java b/src/main/java/io/github/dsheirer/dsp/filter/interpolator/RealInterpolator.java index ff933ed1..00a64f80 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/interpolator/RealInterpolator.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/interpolator/RealInterpolator.java @@ -2,6 +2,7 @@ package io.github.dsheirer.dsp.filter.interpolator; import io.github.dsheirer.sample.complex.Complex; import org.apache.commons.lang3.Validate; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -70,13 +71,13 @@ public class RealInterpolator extends Interpolator RealInterpolator interpolator = new RealInterpolator(1.0f); DecimalFormat decimalFormat = new DecimalFormat("0.0000"); - double TWO_PI = Math.PI * 2.0; + double TWO_PI = FastMath.PI * 2.0; float[] samples = new float[16]; for(int x = 0; x < 16; x++) { - samples[x] = (float)Math.sin(TWO_PI * (double)x / 8.0); + samples[x] = (float) FastMath.sin(TWO_PI * (double)x / 8.0); } mLog.debug("Samples: " + Arrays.toString(samples)); diff --git a/src/main/java/io/github/dsheirer/dsp/fm/FMDemodulator.java b/src/main/java/io/github/dsheirer/dsp/fm/FMDemodulator.java index 2dd550ea..34421994 100644 --- a/src/main/java/io/github/dsheirer/dsp/fm/FMDemodulator.java +++ b/src/main/java/io/github/dsheirer/dsp/fm/FMDemodulator.java @@ -21,6 +21,7 @@ import io.github.dsheirer.sample.buffer.ReusableBufferQueue; import io.github.dsheirer.sample.buffer.ReusableComplexBuffer; import io.github.dsheirer.sample.buffer.ReusableFloatBuffer; import io.github.dsheirer.sample.complex.Complex; +import org.apache.commons.math3.util.FastMath; /** * FM Demodulator for demodulating complex samples and producing demodulated floating point samples. @@ -81,7 +82,7 @@ public class FMDemodulator * serves as the instantaneous amplitude of the demodulated signal */ double denominator = 1.0d / inphase; - angle = Math.atan((double)quadrature * denominator); + angle = FastMath.atan((double)quadrature * denominator); } /** @@ -116,7 +117,7 @@ public class FMDemodulator * serves as the instantaneous amplitude of the demodulated signal */ double denominator = 1.0d / inphase; - angle = Math.atan((double)quadrature * denominator); + angle = FastMath.atan((double)quadrature * denominator); } return angle; diff --git a/src/main/java/io/github/dsheirer/dsp/fsk/SampleBuffer.java b/src/main/java/io/github/dsheirer/dsp/fsk/SampleBuffer.java index 5a264320..602d016b 100644 --- a/src/main/java/io/github/dsheirer/dsp/fsk/SampleBuffer.java +++ b/src/main/java/io/github/dsheirer/dsp/fsk/SampleBuffer.java @@ -15,6 +15,7 @@ ******************************************************************************/ package io.github.dsheirer.dsp.fsk; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,7 +48,7 @@ public class SampleBuffer mIntegerSamplesPerSymbol = (int)(samplesPerSymbol + 0.5f); mHalfIntegerSamplesPerSymbol = (int)(samplesPerSymbol / 2.0f + 0.5f); mMidSymbolSamplingPoint = samplesPerSymbol + mHalfIntegerSamplesPerSymbol; - mTwiceSamplesPerSymbol = (int)Math.floor(2.0 * samplesPerSymbol); + mTwiceSamplesPerSymbol = (int) FastMath.floor(2.0 * samplesPerSymbol); mDelayLine = new boolean[2 * mTwiceSamplesPerSymbol]; } diff --git a/src/main/java/io/github/dsheirer/dsp/fsk/ZeroCrossingErrorDetector.java b/src/main/java/io/github/dsheirer/dsp/fsk/ZeroCrossingErrorDetector.java index ded627d8..2bbe4c5b 100644 --- a/src/main/java/io/github/dsheirer/dsp/fsk/ZeroCrossingErrorDetector.java +++ b/src/main/java/io/github/dsheirer/dsp/fsk/ZeroCrossingErrorDetector.java @@ -15,6 +15,8 @@ ******************************************************************************/ package io.github.dsheirer.dsp.fsk; +import org.apache.commons.math3.util.FastMath; + /** * Zero crossing error detector. Provides symbol timing error correction values by detecting zero-crossings within * each symbol period. Ideally there should be only 0 or 1 zero crossings within each symbol period. However, when @@ -45,7 +47,7 @@ public class ZeroCrossingErrorDetector */ public ZeroCrossingErrorDetector(float samplesPerSymbol) { - mBuffer = new boolean[(int)Math.ceil(samplesPerSymbol)]; + mBuffer = new boolean[(int)FastMath.ceil(samplesPerSymbol)]; // mZeroCrossingIdeal = mBuffer.length - 1.5f - (samplesPerSymbol / 2.0f); //Preserve this for LTR mZeroCrossingIdeal = (samplesPerSymbol / 2.0f); } @@ -108,7 +110,7 @@ public class ZeroCrossingErrorDetector float errorDistanceOne = mZeroCrossingIdeal - mZeroCrossingOne; float errorDistanceTwo = mZeroCrossingCount - mZeroCrossingTwo; - if(Math.abs(errorDistanceOne) < Math.abs(errorDistanceTwo)) + if(FastMath.abs(errorDistanceOne) < FastMath.abs(errorDistanceTwo)) { mDetectedZeroCrossing = mZeroCrossingOne; } diff --git a/src/main/java/io/github/dsheirer/dsp/gain/AutomaticGainControl.java b/src/main/java/io/github/dsheirer/dsp/gain/AutomaticGainControl.java index a8533d97..ff5269c1 100644 --- a/src/main/java/io/github/dsheirer/dsp/gain/AutomaticGainControl.java +++ b/src/main/java/io/github/dsheirer/dsp/gain/AutomaticGainControl.java @@ -4,6 +4,7 @@ import io.github.dsheirer.buffer.DoubleCircularBuffer; import io.github.dsheirer.buffer.RealCircularBuffer; import io.github.dsheirer.sample.buffer.ReusableBufferQueue; import io.github.dsheirer.sample.buffer.ReusableFloatBuffer; +import org.apache.commons.math3.util.FastMath; /******************************************************************************* * SDR Trunk @@ -74,10 +75,10 @@ public class AutomaticGainControl private static final double ATTACK_FALL_TIME_CONSTANT = 0.005; private static final double ATTACK_RISE_ALPHA = 1.0 - - Math.exp(-1.0 / SAMPLE_RATE * ATTACK_RISE_TIME_CONSTANT); + FastMath.exp(-1.0 / SAMPLE_RATE * ATTACK_RISE_TIME_CONSTANT); private static final double ATTACK_FALL_ALPHA = 1.0 - - Math.exp(-1.0 / SAMPLE_RATE * ATTACK_FALL_TIME_CONSTANT); + FastMath.exp(-1.0 / SAMPLE_RATE * ATTACK_FALL_TIME_CONSTANT); /* AGC decay value in milliseconds (20 to 5000) */ private static final double DECAY = 200; @@ -87,10 +88,10 @@ public class AutomaticGainControl private static final double DECAY_RISEFALL_RATIO = 0.3; private static final double DECAY_RISE_ALPHA = 1.0 - - Math.exp(-1.0 / (SAMPLE_RATE * DECAY * .001 * DECAY_RISEFALL_RATIO)); + FastMath.exp(-1.0 / (SAMPLE_RATE * DECAY * .001 * DECAY_RISEFALL_RATIO)); private static final double DECAY_FALL_ALPHA = 1.0 - - Math.exp(-1.0 / (SAMPLE_RATE * DECAY * .001)); + FastMath.exp(-1.0 / (SAMPLE_RATE * DECAY * .001)); /* Hang timer release decay time constant in seconds */ @SuppressWarnings("unused") @@ -110,7 +111,7 @@ public class AutomaticGainControl private static final double MANUAL_GAIN = 0.0; private static final double MANUAL_AGC_GAIN = MAX_MANUAL_AMPLITUDE * - Math.pow(10.0, MANUAL_GAIN / 20.0); + FastMath.pow(10.0, MANUAL_GAIN / 20.0); /* Specifies dB reduction in output at knee from max output level (0 - 10dB) */ private static final double SLOPE_FACTOR = 2.0; @@ -120,7 +121,7 @@ public class AutomaticGainControl private static final double GAIN_SLOPE = SLOPE_FACTOR / 100.0; private static final double FIXED_GAIN = AGC_OUT_SCALE * - Math.pow(10.0, KNEE * (GAIN_SLOPE - 1.0)); + FastMath.pow(10.0, KNEE * (GAIN_SLOPE - 1.0)); /* Constant for calc log() so that a value of 0 magnitude = -8 */ private static final double MIN_CONSTANT = 3.2767E-4; @@ -178,7 +179,7 @@ public class AutomaticGainControl if(mAGCEnabled) { - double currentMagnitude = Math.log10(Math.abs(currentSample) + MIN_CONSTANT) - Math.log10(MAX_AMPLITUDE); + double currentMagnitude = FastMath.log10(FastMath.abs(currentSample) + MIN_CONSTANT) - FastMath.log10(MAX_AMPLITUDE); double delayedMagnitude = mMagnitudeBuffer.get(currentMagnitude); @@ -212,7 +213,7 @@ public class AutomaticGainControl mDecayAverage = ((1.0 - DECAY_FALL_ALPHA) * mDecayAverage) + (DECAY_RISE_ALPHA * mPeakMagnitude); } - double magnitude = (mAttackAverage > mDecayAverage) ? mAttackAverage : mDecayAverage; + double magnitude = FastMath.max(mAttackAverage, mDecayAverage); if(magnitude < KNEE) { @@ -220,7 +221,7 @@ public class AutomaticGainControl } else { - gain = AGC_OUT_SCALE * Math.pow(10.0, magnitude * (GAIN_SLOPE - 1.0)); + gain = AGC_OUT_SCALE * FastMath.pow(10.0, magnitude * (GAIN_SLOPE - 1.0)); } } diff --git a/src/main/java/io/github/dsheirer/dsp/gain/ComplexAutomaticGainControl.java b/src/main/java/io/github/dsheirer/dsp/gain/ComplexAutomaticGainControl.java index a3431f6d..83de223d 100644 --- a/src/main/java/io/github/dsheirer/dsp/gain/ComplexAutomaticGainControl.java +++ b/src/main/java/io/github/dsheirer/dsp/gain/ComplexAutomaticGainControl.java @@ -5,6 +5,7 @@ import io.github.dsheirer.buffer.DoubleCircularBuffer; import io.github.dsheirer.sample.Listener; import io.github.dsheirer.sample.Provider; import io.github.dsheirer.sample.complex.Complex; +import org.apache.commons.math3.util.FastMath; import java.util.concurrent.atomic.AtomicBoolean; @@ -77,10 +78,10 @@ public class ComplexAutomaticGainControl implements Listener, private static final double ATTACK_FALL_TIME_CONSTANT = 0.005; private static final double ATTACK_RISE_ALPHA = 1.0 - - Math.exp( -1.0 / SAMPLE_RATE * ATTACK_RISE_TIME_CONSTANT ); + FastMath.exp( -1.0 / SAMPLE_RATE * ATTACK_RISE_TIME_CONSTANT ); private static final double ATTACK_FALL_ALPHA = 1.0 - - Math.exp( -1.0 / SAMPLE_RATE * ATTACK_FALL_TIME_CONSTANT ); + FastMath.exp( -1.0 / SAMPLE_RATE * ATTACK_FALL_TIME_CONSTANT ); /* AGC decay value in milliseconds (20 to 5000) */ private static final double DECAY = 200; @@ -90,10 +91,10 @@ public class ComplexAutomaticGainControl implements Listener, private static final double DECAY_RISEFALL_RATIO = 0.3; private static final double DECAY_RISE_ALPHA = 1.0 - - Math.exp( -1.0 / ( SAMPLE_RATE * DECAY * .001 * DECAY_RISEFALL_RATIO ) ); + FastMath.exp( -1.0 / ( SAMPLE_RATE * DECAY * .001 * DECAY_RISEFALL_RATIO ) ); private static final double DECAY_FALL_ALPHA = 1.0 - - Math.exp( -1.0 / ( SAMPLE_RATE * DECAY * .001 ) ); + FastMath.exp( -1.0 / ( SAMPLE_RATE * DECAY * .001 ) ); /* Hang timer release decay time constant in seconds */ @SuppressWarnings( "unused" ) @@ -113,7 +114,7 @@ public class ComplexAutomaticGainControl implements Listener, private static final double MANUAL_GAIN = 0.0; private static final double MANUAL_AGC_GAIN = MAX_MANUAL_AMPLITUDE * - Math.pow( 10.0, MANUAL_GAIN / 20.0 ); + FastMath.pow( 10.0, MANUAL_GAIN / 20.0 ); /* Specifies dB reduction in output at knee from max output level (0 - 10dB) */ private static final double SLOPE_FACTOR = 2.0; @@ -123,7 +124,7 @@ public class ComplexAutomaticGainControl implements Listener, private static final double GAIN_SLOPE = SLOPE_FACTOR / 100.0; private static final double FIXED_GAIN = AGC_OUT_SCALE * - Math.pow( 10.0, KNEE * ( GAIN_SLOPE - 1.0 ) ); + FastMath.pow( 10.0, KNEE * ( GAIN_SLOPE - 1.0 ) ); /* Constant for calc log() so that a value of 0 magnitude = -8 */ private static final double MIN_CONSTANT = 3.2767E-4; @@ -156,8 +157,8 @@ public class ComplexAutomaticGainControl implements Listener, { float max = currentSample.maximumAbsolute(); - double currentMagnitude = Math.log10( max + MIN_CONSTANT ) - - Math.log10( MAX_AMPLITUDE ); + double currentMagnitude = FastMath.log10( max + MIN_CONSTANT ) - + FastMath.log10( MAX_AMPLITUDE ); double delayedMagnitude = mMagnitudeBuffer.get( currentMagnitude ); @@ -195,8 +196,7 @@ public class ComplexAutomaticGainControl implements Listener, ( DECAY_RISE_ALPHA * mPeakMagnitude ); } - double magnitude = ( mAttackAverage > mDecayAverage ) ? - mAttackAverage : mDecayAverage; + double magnitude = FastMath.max(mAttackAverage, mDecayAverage); if( magnitude < KNEE ) { @@ -204,7 +204,7 @@ public class ComplexAutomaticGainControl implements Listener, } else { - gain = AGC_OUT_SCALE * Math.pow( 10.0, + gain = AGC_OUT_SCALE * FastMath.pow( 10.0, magnitude * ( GAIN_SLOPE - 1.0 ) ); } diff --git a/src/main/java/io/github/dsheirer/dsp/mixer/LowPhaseNoiseOscillator.java b/src/main/java/io/github/dsheirer/dsp/mixer/LowPhaseNoiseOscillator.java index 7ae6e9dc..9b46665f 100644 --- a/src/main/java/io/github/dsheirer/dsp/mixer/LowPhaseNoiseOscillator.java +++ b/src/main/java/io/github/dsheirer/dsp/mixer/LowPhaseNoiseOscillator.java @@ -15,6 +15,7 @@ ******************************************************************************/ package io.github.dsheirer.dsp.mixer; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -26,7 +27,7 @@ public class LowPhaseNoiseOscillator extends AbstractOscillator { private final static Logger mLog = LoggerFactory.getLogger(LowPhaseNoiseOscillator.class); - private static final double TWO_PI = 2.0 * Math.PI; + private static final double TWO_PI = 2.0 * FastMath.PI; private static final double THREE_HALVES = 3.0 / 2.0; private double mInphase = 1.0; private double mQuadrature = 0.0; @@ -68,8 +69,8 @@ public class LowPhaseNoiseOscillator extends AbstractOscillator { double anglePerSample = TWO_PI * getFrequency() / getSampleRate(); - mCosineAngle = Math.cos(anglePerSample); - mSineAngle = Math.sin(anglePerSample); + mCosineAngle = FastMath.cos(anglePerSample); + mSineAngle = FastMath.sin(anglePerSample); } /** diff --git a/src/main/java/io/github/dsheirer/dsp/mixer/Oscillator.java b/src/main/java/io/github/dsheirer/dsp/mixer/Oscillator.java index 3e87a0ba..825c5e76 100644 --- a/src/main/java/io/github/dsheirer/dsp/mixer/Oscillator.java +++ b/src/main/java/io/github/dsheirer/dsp/mixer/Oscillator.java @@ -16,6 +16,7 @@ package io.github.dsheirer.dsp.mixer; import io.github.dsheirer.sample.complex.Complex; +import org.apache.commons.math3.util.FastMath; public class Oscillator extends AbstractOscillator { @@ -62,7 +63,7 @@ public class Oscillator extends AbstractOscillator @Override protected void update() { - float anglePerSample = (float)(2.0d * Math.PI * getFrequency() / getSampleRate()); + float anglePerSample = (float)(2.0d * FastMath.PI * getFrequency() / getSampleRate()); mAnglePerSample = Complex.fromAngle(anglePerSample); } } diff --git a/src/main/java/io/github/dsheirer/dsp/psk/DQPSKDecisionDirectedDemodulatorInstrumented.java b/src/main/java/io/github/dsheirer/dsp/psk/DQPSKDecisionDirectedDemodulatorInstrumented.java index 4543f0d6..5bec6eb5 100644 --- a/src/main/java/io/github/dsheirer/dsp/psk/DQPSKDecisionDirectedDemodulatorInstrumented.java +++ b/src/main/java/io/github/dsheirer/dsp/psk/DQPSKDecisionDirectedDemodulatorInstrumented.java @@ -26,6 +26,7 @@ import io.github.dsheirer.dsp.psk.pll.IPhaseLockedLoop; import io.github.dsheirer.sample.Listener; import io.github.dsheirer.sample.buffer.ReusableComplexBuffer; import io.github.dsheirer.sample.complex.Complex; +import org.apache.commons.math3.util.FastMath; public class DQPSKDecisionDirectedDemodulatorInstrumented extends DQPSKDecisionDirectedDemodulator { @@ -102,7 +103,7 @@ public class DQPSKDecisionDirectedDemodulatorInstrumented extends DQPSKDecisionD { double loopFrequency = ((CostasLoop)getPLL()).getLoopFrequency(); - loopFrequency *= mSampleRate / (2.0 * Math.PI); + loopFrequency *= mSampleRate / (2.0 * FastMath.PI); mPLLFrequencyListener.receive(loopFrequency); } diff --git a/src/main/java/io/github/dsheirer/dsp/psk/DQPSKDecisionDirectedSymbolEvaluator.java b/src/main/java/io/github/dsheirer/dsp/psk/DQPSKDecisionDirectedSymbolEvaluator.java index ead3c1ed..35a08c2d 100644 --- a/src/main/java/io/github/dsheirer/dsp/psk/DQPSKDecisionDirectedSymbolEvaluator.java +++ b/src/main/java/io/github/dsheirer/dsp/psk/DQPSKDecisionDirectedSymbolEvaluator.java @@ -17,13 +17,14 @@ package io.github.dsheirer.dsp.psk; import io.github.dsheirer.dsp.symbol.Dibit; import io.github.dsheirer.sample.complex.Complex; +import org.apache.commons.math3.util.FastMath; public class DQPSKDecisionDirectedSymbolEvaluator implements IPSKSymbolEvaluator { - private static final Complex ROTATE_FROM_PLUS_135 = Complex.fromAngle(-3.0 * Math.PI / 4.0); - private static final Complex ROTATE_FROM_PLUS_45 = Complex.fromAngle(-1.0 * Math.PI / 4.0); - private static final Complex ROTATE_FROM_MINUS_45 = Complex.fromAngle(1.0 * Math.PI / 4.0); - private static final Complex ROTATE_FROM_MINUS_135 = Complex.fromAngle(3.0 * Math.PI / 4.0); + private static final Complex ROTATE_FROM_PLUS_135 = Complex.fromAngle(-3.0 * FastMath.PI / 4.0); + private static final Complex ROTATE_FROM_PLUS_45 = Complex.fromAngle(-1.0 * FastMath.PI / 4.0); + private static final Complex ROTATE_FROM_MINUS_45 = Complex.fromAngle(1.0 * FastMath.PI / 4.0); + private static final Complex ROTATE_FROM_MINUS_135 = Complex.fromAngle(3.0 * FastMath.PI / 4.0); private Complex mEvaluationSymbol = new Complex(0, 0); private float mPhaseError = 0.0f; diff --git a/src/main/java/io/github/dsheirer/dsp/psk/DQPSKGardnerDemodulatorInstrumented.java b/src/main/java/io/github/dsheirer/dsp/psk/DQPSKGardnerDemodulatorInstrumented.java index 2e739914..6b77c083 100644 --- a/src/main/java/io/github/dsheirer/dsp/psk/DQPSKGardnerDemodulatorInstrumented.java +++ b/src/main/java/io/github/dsheirer/dsp/psk/DQPSKGardnerDemodulatorInstrumented.java @@ -26,6 +26,7 @@ import io.github.dsheirer.dsp.psk.pll.IPhaseLockedLoop; import io.github.dsheirer.sample.Listener; import io.github.dsheirer.sample.buffer.ReusableComplexBuffer; import io.github.dsheirer.sample.complex.Complex; +import org.apache.commons.math3.util.FastMath; public class DQPSKGardnerDemodulatorInstrumented extends DQPSKGardnerDemodulator { @@ -99,7 +100,7 @@ public class DQPSKGardnerDemodulatorInstrumented extends DQPSKGardnerDemodulator { double loopFrequency = ((CostasLoop)getPLL()).getLoopFrequency(); - loopFrequency *= mSampleRate / (2.0 * Math.PI); + loopFrequency *= mSampleRate / (2.0 * FastMath.PI); mPLLFrequencyListener.receive(loopFrequency); } diff --git a/src/main/java/io/github/dsheirer/dsp/psk/DQPSKGardnerSymbolEvaluator.java b/src/main/java/io/github/dsheirer/dsp/psk/DQPSKGardnerSymbolEvaluator.java index 1ccfbf25..ba700bb2 100644 --- a/src/main/java/io/github/dsheirer/dsp/psk/DQPSKGardnerSymbolEvaluator.java +++ b/src/main/java/io/github/dsheirer/dsp/psk/DQPSKGardnerSymbolEvaluator.java @@ -17,13 +17,14 @@ package io.github.dsheirer.dsp.psk; import io.github.dsheirer.dsp.symbol.Dibit; import io.github.dsheirer.sample.complex.Complex; +import org.apache.commons.math3.util.FastMath; public class DQPSKGardnerSymbolEvaluator implements IPSKSymbolEvaluator { - private static final Complex ROTATE_FROM_PLUS_135 = Complex.fromAngle(-3.0 * Math.PI / 4.0); - private static final Complex ROTATE_FROM_PLUS_45 = Complex.fromAngle(-1.0 * Math.PI / 4.0); - private static final Complex ROTATE_FROM_MINUS_45 = Complex.fromAngle(1.0 * Math.PI / 4.0); - private static final Complex ROTATE_FROM_MINUS_135 = Complex.fromAngle(3.0 * Math.PI / 4.0); + private static final Complex ROTATE_FROM_PLUS_135 = Complex.fromAngle(-3.0 * FastMath.PI / 4.0); + private static final Complex ROTATE_FROM_PLUS_45 = Complex.fromAngle(-1.0 * FastMath.PI / 4.0); + private static final Complex ROTATE_FROM_MINUS_45 = Complex.fromAngle(1.0 * FastMath.PI / 4.0); + private static final Complex ROTATE_FROM_MINUS_135 = Complex.fromAngle(3.0 * FastMath.PI / 4.0); private float mPhaseError = 0.0f; private float mTimingError = 0.0f; diff --git a/src/main/java/io/github/dsheirer/dsp/psk/GardnerDetector.java b/src/main/java/io/github/dsheirer/dsp/psk/GardnerDetector.java index 9b338e97..af0197de 100644 --- a/src/main/java/io/github/dsheirer/dsp/psk/GardnerDetector.java +++ b/src/main/java/io/github/dsheirer/dsp/psk/GardnerDetector.java @@ -16,6 +16,7 @@ package io.github.dsheirer.dsp.psk; import io.github.dsheirer.sample.complex.Complex; +import org.apache.commons.math3.util.FastMath; public class GardnerDetector { @@ -41,8 +42,8 @@ public class GardnerDetector */ public float getError(Complex previous, Complex middle, Complex current) { - mErrorInphase = (Math.abs(previous.inphase()) - Math.abs(current.inphase())) * Math.abs(middle.inphase()); - mErrorQuadrature = (Math.abs(previous.quadrature()) - Math.abs(current.quadrature())) * Math.abs(middle.quadrature()); + mErrorInphase = (FastMath.abs(previous.inphase()) - FastMath.abs(current.inphase())) * FastMath.abs(middle.inphase()); + mErrorQuadrature = (FastMath.abs(previous.quadrature()) - FastMath.abs(current.quadrature())) * FastMath.abs(middle.quadrature()); mError = normalize(mErrorInphase + mErrorQuadrature, 1.0f); return mError; diff --git a/src/main/java/io/github/dsheirer/dsp/psk/InterpolatingSampleBuffer.java b/src/main/java/io/github/dsheirer/dsp/psk/InterpolatingSampleBuffer.java index bdf6e817..196fa6a4 100644 --- a/src/main/java/io/github/dsheirer/dsp/psk/InterpolatingSampleBuffer.java +++ b/src/main/java/io/github/dsheirer/dsp/psk/InterpolatingSampleBuffer.java @@ -23,6 +23,7 @@ package io.github.dsheirer.dsp.psk; import io.github.dsheirer.dsp.filter.interpolator.RealInterpolator; import io.github.dsheirer.sample.complex.Complex; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,7 +61,7 @@ public class InterpolatingSampleBuffer mDetectedSamplesPerSymbol = samplesPerSymbol; mMaximumSamplesPerSymbol = samplesPerSymbol * (1.0f + MAXIMUM_DEVIATION_SAMPLES_PER_SYMBOL); mMinimumSamplesPerSymbol = samplesPerSymbol * (1.0f - MAXIMUM_DEVIATION_SAMPLES_PER_SYMBOL); - mTwiceSamplesPerSymbol = (int)Math.floor(2.0 * samplesPerSymbol); + mTwiceSamplesPerSymbol = (int) FastMath.floor(2.0 * samplesPerSymbol); mDelayLineInphase = new float[2 * mTwiceSamplesPerSymbol]; mDelayLineQuadrature = new float[2 * mTwiceSamplesPerSymbol]; @@ -190,7 +191,7 @@ public class InterpolatingSampleBuffer } else { - int offset = (int)Math.floor(interpolation); + int offset = (int)FastMath.floor(interpolation); return mInterpolator.filter(mDelayLineInphase, mDelayLinePointer + offset, interpolation - offset); } } @@ -208,7 +209,7 @@ public class InterpolatingSampleBuffer } else { - int offset = (int)Math.floor(interpolation); + int offset = (int)FastMath.floor(interpolation); return mInterpolator.filter(mDelayLineQuadrature, mDelayLinePointer + offset, interpolation - offset); } } diff --git a/src/main/java/io/github/dsheirer/dsp/psk/InterpolatingSampleBufferInstrumented.java b/src/main/java/io/github/dsheirer/dsp/psk/InterpolatingSampleBufferInstrumented.java index 610e9ac0..ecb08166 100644 --- a/src/main/java/io/github/dsheirer/dsp/psk/InterpolatingSampleBufferInstrumented.java +++ b/src/main/java/io/github/dsheirer/dsp/psk/InterpolatingSampleBufferInstrumented.java @@ -23,6 +23,7 @@ package io.github.dsheirer.dsp.psk; import io.github.dsheirer.sample.complex.Complex; import io.github.dsheirer.sample.complex.ComplexSampleListener; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,7 +37,7 @@ public class InterpolatingSampleBufferInstrumented extends InterpolatingSampleBu public InterpolatingSampleBufferInstrumented(float samplesPerSymbol, float symbolTimingGain) { super(samplesPerSymbol, symbolTimingGain); - mBufferLength = (int)Math.ceil(samplesPerSymbol); + mBufferLength = (int) FastMath.ceil(samplesPerSymbol); mSymbolDecisionData = new SymbolDecisionData(mBufferLength); } diff --git a/src/main/java/io/github/dsheirer/dsp/psk/QPSKSymbolDecoder.java b/src/main/java/io/github/dsheirer/dsp/psk/QPSKSymbolDecoder.java index 42a97b6c..d4dcfa6a 100644 --- a/src/main/java/io/github/dsheirer/dsp/psk/QPSKSymbolDecoder.java +++ b/src/main/java/io/github/dsheirer/dsp/psk/QPSKSymbolDecoder.java @@ -19,6 +19,7 @@ import io.github.dsheirer.dsp.symbol.Dibit; import io.github.dsheirer.sample.Broadcaster; import io.github.dsheirer.sample.Listener; import io.github.dsheirer.sample.complex.Complex; +import org.apache.commons.math3.util.FastMath; public class QPSKSymbolDecoder implements Listener, IQPSKSymbolDecoder { @@ -63,7 +64,7 @@ public class QPSKSymbolDecoder implements Listener, IQPSKSymbolDecoder public Dibit decode(Complex complex ) { - if( Math.abs( complex.inphase() ) > Math.abs( complex.quadrature() ) ) + if( FastMath.abs( complex.inphase() ) > FastMath.abs( complex.quadrature() ) ) { if( complex.inphase() > 0 ) { diff --git a/src/main/java/io/github/dsheirer/dsp/psk/QPSKSymbolPhaseErrorCalculator.java b/src/main/java/io/github/dsheirer/dsp/psk/QPSKSymbolPhaseErrorCalculator.java index fed580ce..0fe1d5f8 100644 --- a/src/main/java/io/github/dsheirer/dsp/psk/QPSKSymbolPhaseErrorCalculator.java +++ b/src/main/java/io/github/dsheirer/dsp/psk/QPSKSymbolPhaseErrorCalculator.java @@ -16,6 +16,7 @@ package io.github.dsheirer.dsp.psk; import io.github.dsheirer.sample.complex.Complex; +import org.apache.commons.math3.util.FastMath; /** * Calculates the phase error for a QPSK polar-orientation constellation @@ -29,7 +30,7 @@ public class QPSKSymbolPhaseErrorCalculator implements ISymbolPhaseErrorCalculat { mPhaseError = 0.0f; - if(Math.abs(symbol.inphase()) > Math.abs(symbol.quadrature())) + if(FastMath.abs(symbol.inphase()) > FastMath.abs(symbol.quadrature())) { if(symbol.inphase() > 0) { diff --git a/src/main/java/io/github/dsheirer/dsp/psk/SymbolDecisionData.java b/src/main/java/io/github/dsheirer/dsp/psk/SymbolDecisionData.java index b2dd87f2..327fde75 100644 --- a/src/main/java/io/github/dsheirer/dsp/psk/SymbolDecisionData.java +++ b/src/main/java/io/github/dsheirer/dsp/psk/SymbolDecisionData.java @@ -23,11 +23,12 @@ package io.github.dsheirer.dsp.psk; import io.github.dsheirer.buffer.ComplexCircularBuffer; import io.github.dsheirer.sample.complex.Complex; +import org.apache.commons.math3.util.FastMath; public class SymbolDecisionData { //45 degrees rotation to orient the symbol to a polar axis to make error calculation easy/efficient - public static final Complex DIFFERENTIAL_OFFSET = Complex.fromAngle(Math.PI / 4.0d); + public static final Complex DIFFERENTIAL_OFFSET = Complex.fromAngle(FastMath.PI / 4.0d); private ComplexCircularBuffer mBuffer; private float mSamplingPoint; diff --git a/src/main/java/io/github/dsheirer/dsp/psk/SymbolInversion.java b/src/main/java/io/github/dsheirer/dsp/psk/SymbolInversion.java index 0b7431c9..22d55f37 100644 --- a/src/main/java/io/github/dsheirer/dsp/psk/SymbolInversion.java +++ b/src/main/java/io/github/dsheirer/dsp/psk/SymbolInversion.java @@ -15,11 +15,13 @@ ******************************************************************************/ package io.github.dsheirer.dsp.psk; +import org.apache.commons.math3.util.FastMath; + public enum SymbolInversion { - DEGREES_90_PLUS(Math.PI / 2.0), - DEGREES_90_MINUS(Math.PI / -2.0), - DEGREES_180(Math.PI); + DEGREES_90_PLUS(FastMath.PI / 2.0), + DEGREES_90_MINUS(FastMath.PI / -2.0), + DEGREES_180(FastMath.PI); private double mAngleRadians; diff --git a/src/main/java/io/github/dsheirer/dsp/psk/pll/CostasLoop.java b/src/main/java/io/github/dsheirer/dsp/psk/pll/CostasLoop.java index 117fa908..cf166894 100644 --- a/src/main/java/io/github/dsheirer/dsp/psk/pll/CostasLoop.java +++ b/src/main/java/io/github/dsheirer/dsp/psk/pll/CostasLoop.java @@ -22,6 +22,7 @@ package io.github.dsheirer.dsp.psk.pll; import io.github.dsheirer.sample.complex.Complex; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,13 +39,13 @@ public class CostasLoop implements IPhaseLockedLoop { private final static Logger mLog = LoggerFactory.getLogger(CostasLoop.class); - public static final double TWO_PI = 2.0 * Math.PI; + public static final double TWO_PI = 2.0 * FastMath.PI; private Complex mCurrentVector = new Complex(0, 0); private double mLoopPhase = 0.0; private double mLoopFrequency = 0.0; private double mMaximumLoopFrequency; - private double mDamping = Math.sqrt(2.0) / 2.0; + private double mDamping = FastMath.sqrt(2.0) / 2.0; private double mAlphaGain; private double mBetaGain; private PLLBandwidth mPLLBandwidth = PLLBandwidth.BW_400; diff --git a/src/main/java/io/github/dsheirer/dsp/psk/pll/PLLBandwidth.java b/src/main/java/io/github/dsheirer/dsp/psk/pll/PLLBandwidth.java index 8c6fd8f1..8d71352f 100644 --- a/src/main/java/io/github/dsheirer/dsp/psk/pll/PLLBandwidth.java +++ b/src/main/java/io/github/dsheirer/dsp/psk/pll/PLLBandwidth.java @@ -86,9 +86,9 @@ public enum PLLBandwidth */ public static PLLBandwidth fromSyncCount(int syncCount) { - if(LOOKUP_MAP.containsKey(syncCount)) - { - return LOOKUP_MAP.get(syncCount); + PLLBandwidth mapValue = LOOKUP_MAP.get(syncCount); + if (mapValue != null) { + return mapValue; } return BW_200; diff --git a/src/main/java/io/github/dsheirer/dsp/psk/pll/QPSKPhaseInversionCalculator.java b/src/main/java/io/github/dsheirer/dsp/psk/pll/QPSKPhaseInversionCalculator.java index 8a3fdbed..58ce1688 100644 --- a/src/main/java/io/github/dsheirer/dsp/psk/pll/QPSKPhaseInversionCalculator.java +++ b/src/main/java/io/github/dsheirer/dsp/psk/pll/QPSKPhaseInversionCalculator.java @@ -70,9 +70,9 @@ public class QPSKPhaseInversionCalculator } System.out.println("NORMAL: " + sync); - System.out.println(" +90: " + sbP90.toString()); - System.out.println(" -90: " + sbM90.toString()); - System.out.println(" 180: " + sb180.toString()); + System.out.println(" +90: " + sbP90); + System.out.println(" -90: " + sbM90); + System.out.println(" 180: " + sb180); } } diff --git a/src/main/java/io/github/dsheirer/edac/BerlekempMassey_63.java b/src/main/java/io/github/dsheirer/edac/BerlekempMassey_63.java index 300147c6..6ab364ea 100644 --- a/src/main/java/io/github/dsheirer/edac/BerlekempMassey_63.java +++ b/src/main/java/io/github/dsheirer/edac/BerlekempMassey_63.java @@ -22,6 +22,7 @@ package io.github.dsheirer.edac; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -304,14 +305,7 @@ public class BerlekempMassey_63 /* have now found q such that d[u]!=0 and u_lu[q] is maximum */ /* store degree of new elp polynomial */ - if( l[ u ] > l[ q ] + u - q ) - { - l[ u + 1 ] = l[ u ]; - } - else - { - l[ u + 1 ] = l[ q ] + u - q; - } + l[u + 1] = FastMath.max(l[u], l[q] + u - q); /* form new elp(x) */ for( int i = 0; i < NN - KK; i++ ) @@ -373,10 +367,7 @@ public class BerlekempMassey_63 } /* find roots of the error location polynomial */ - for( int i = 1; i <= l[u]; i++ ) - { - reg[ i ] = elp[ u ][ i ]; - } + if (l[u] >= 0) System.arraycopy(elp[u], 1, reg, 1, l[u]); count = 0; diff --git a/src/main/java/io/github/dsheirer/edac/CRC.java b/src/main/java/io/github/dsheirer/edac/CRC.java index 15c22cb1..732a8889 100644 --- a/src/main/java/io/github/dsheirer/edac/CRC.java +++ b/src/main/java/io/github/dsheirer/edac/CRC.java @@ -63,16 +63,10 @@ public enum CRC StringBuilder sb = new StringBuilder(); - for(int x = 0; x < checks.length; x++) - { - CRC check = checks[x]; - - if(check != null) - { + for (CRC check : checks) { + if (check != null) { sb.append(check.getAbbreviation()); - } - else - { + } else { sb.append(CRC.UNKNOWN.getAbbreviation()); } } diff --git a/src/main/java/io/github/dsheirer/edac/trellis/ViterbiDecoder.java b/src/main/java/io/github/dsheirer/edac/trellis/ViterbiDecoder.java index 48c7bc86..5a30881b 100644 --- a/src/main/java/io/github/dsheirer/edac/trellis/ViterbiDecoder.java +++ b/src/main/java/io/github/dsheirer/edac/trellis/ViterbiDecoder.java @@ -18,6 +18,8 @@ ******************************************************************************/ package io.github.dsheirer.edac.trellis; +import org.apache.commons.math3.util.FastMath; + import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -41,8 +43,8 @@ public abstract class ViterbiDecoder mInputBitLength = inputBitLength; mOutputBitLength = outputBitLength; - mInputValueCount = (int)Math.pow(2.0, mInputBitLength); - mOutputValueCount = (int)Math.pow(2.0, mOutputBitLength); + mInputValueCount = (int) FastMath.pow(2.0, mInputBitLength); + mOutputValueCount = (int)FastMath.pow(2.0, mOutputBitLength); } /** diff --git a/src/main/java/io/github/dsheirer/filter/FilterEditorPanel.java b/src/main/java/io/github/dsheirer/filter/FilterEditorPanel.java index 009d1db7..0ea5cc49 100644 --- a/src/main/java/io/github/dsheirer/filter/FilterEditorPanel.java +++ b/src/main/java/io/github/dsheirer/filter/FilterEditorPanel.java @@ -75,14 +75,7 @@ public class FilterEditorPanel extends JPanel List> filters = filterSet.getFilters(); /* sort the filters in alphabetical order by name */ - Collections.sort(filters, new Comparator>() - { - @Override - public int compare(IFilter first, IFilter second) - { - return first.getName().compareTo(second.getName()); - } - }); + filters.sort((Comparator>) (first, second) -> first.getName().compareTo(second.getName())); for(IFilter filter : filters) { @@ -105,14 +98,7 @@ public class FilterEditorPanel extends JPanel { List> elements = filter.getFilterElements(); - Collections.sort(elements, new Comparator>() - { - @Override - public int compare(FilterElement o1, FilterElement o2) - { - return o1.toString().compareTo(o2.toString()); - } - }); + elements.sort(Comparator.comparing(FilterElement::toString)); for(FilterElement element : elements) { diff --git a/src/main/java/io/github/dsheirer/gui/ChannelMemoryLogger.java b/src/main/java/io/github/dsheirer/gui/ChannelMemoryLogger.java index b36112d1..0677331f 100644 --- a/src/main/java/io/github/dsheirer/gui/ChannelMemoryLogger.java +++ b/src/main/java/io/github/dsheirer/gui/ChannelMemoryLogger.java @@ -25,18 +25,18 @@ public class ChannelMemoryLogger implements Runnable, ChannelEventListener StringBuilder sb = new StringBuilder(); - sb.append( "CHAN TOT:" + mChannelCount ); - sb.append( " TRFC:" + mTrafficChannelCount ); - sb.append( " PROC:" + mChannelProcessingCount ); + sb.append("CHAN TOT:").append(mChannelCount); + sb.append(" TRFC:").append(mTrafficChannelCount); + sb.append(" PROC:").append(mChannelProcessingCount); long maxMemory = runtime.maxMemory(); long allocatedMemory = runtime.totalMemory(); long freeMemory = runtime.freeMemory(); - sb.append(" MEM FREE: " + format.format(freeMemory / 1024) ); - sb.append(" ALLOC: " + format.format(allocatedMemory / 1024) ); - sb.append(" MAX: " + format.format(maxMemory / 1024) ); - sb.append(" TOTAL: " + format.format((freeMemory + (maxMemory - allocatedMemory)) / 1024) ); + sb.append(" MEM FREE: ").append(format.format(freeMemory / 1024)); + sb.append(" ALLOC: ").append(format.format(allocatedMemory / 1024)); + sb.append(" MAX: ").append(format.format(maxMemory / 1024)); + sb.append(" TOTAL: ").append(format.format((freeMemory + (maxMemory - allocatedMemory)) / 1024)); mLog.debug( sb.toString() ); } diff --git a/src/main/java/io/github/dsheirer/gui/control/ConstellationViewer.java b/src/main/java/io/github/dsheirer/gui/control/ConstellationViewer.java index cf51c81a..92d237c7 100644 --- a/src/main/java/io/github/dsheirer/gui/control/ConstellationViewer.java +++ b/src/main/java/io/github/dsheirer/gui/control/ConstellationViewer.java @@ -3,6 +3,7 @@ package io.github.dsheirer.gui.control; import io.github.dsheirer.buffer.CircularBuffer; import io.github.dsheirer.sample.Listener; import io.github.dsheirer.sample.complex.Complex; +import org.apache.commons.math3.util.FastMath; import javax.swing.*; import javax.swing.event.ChangeEvent; @@ -135,7 +136,7 @@ public class ConstellationViewer extends JPanel implements Listener * serves as the instantaneous amplitude of the demodulated signal */ double denominator = 1.0d / i; - angle = Math.atan( (double)q * denominator ); + angle = FastMath.atan( (double)q * denominator ); } Ellipse2D.Double ellipse = diff --git a/src/main/java/io/github/dsheirer/gui/control/JFrequencyControl.java b/src/main/java/io/github/dsheirer/gui/control/JFrequencyControl.java index e0e7cc9b..402d4813 100644 --- a/src/main/java/io/github/dsheirer/gui/control/JFrequencyControl.java +++ b/src/main/java/io/github/dsheirer/gui/control/JFrequencyControl.java @@ -22,6 +22,7 @@ import io.github.dsheirer.source.InvalidFrequencyException; import io.github.dsheirer.source.SourceEvent; import io.github.dsheirer.source.SourceException; import net.miginfocom.swing.MigLayout; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -287,17 +288,17 @@ public class JFrequencyControl extends JPanel implements ISourceEventProcessor public void setFrequency(long frequency, boolean fireChangeEvent) { //Strip the digits higher than this one - long lower = frequency % (long)(Math.pow(10, mPower + 1)); + long lower = frequency % (long)(FastMath.pow(10, mPower + 1)); //Set the value to int value of dividing by 10 to this power - long value = (long)(lower / (long)(Math.pow(10, mPower))); + long value = (long)(lower / (long)(FastMath.pow(10, mPower))); set(value, fireChangeEvent); } public long getFrequency() { - return mValue * (long)Math.pow(10, mPower); + return mValue * (long)FastMath.pow(10, mPower); } public void increment() diff --git a/src/main/java/io/github/dsheirer/gui/control/MultipleFrequencyEditor.java b/src/main/java/io/github/dsheirer/gui/control/MultipleFrequencyEditor.java index 3bac4fab..d75b30ee 100644 --- a/src/main/java/io/github/dsheirer/gui/control/MultipleFrequencyEditor.java +++ b/src/main/java/io/github/dsheirer/gui/control/MultipleFrequencyEditor.java @@ -337,8 +337,7 @@ public class MultipleFrequencyEditor extends JPanel */ public List getFrequencies() { - List frequencies = new ArrayList<>(); - frequencies.addAll(mFrequencies); + List frequencies = new ArrayList<>(mFrequencies); return frequencies; } } diff --git a/src/main/java/io/github/dsheirer/gui/instrument/chart/ComplexPhaseLineChart.java b/src/main/java/io/github/dsheirer/gui/instrument/chart/ComplexPhaseLineChart.java index fb03391b..0d6a15c6 100644 --- a/src/main/java/io/github/dsheirer/gui/instrument/chart/ComplexPhaseLineChart.java +++ b/src/main/java/io/github/dsheirer/gui/instrument/chart/ComplexPhaseLineChart.java @@ -28,6 +28,7 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.scene.chart.LineChart; import javafx.scene.chart.NumberAxis; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,7 +36,7 @@ public class ComplexPhaseLineChart extends LineChart implements Listener> mPhaseValues = FXCollections.observableArrayList(); @@ -44,7 +45,7 @@ public class ComplexPhaseLineChart extends LineChart implements Listener phaseSeries = new Series<>("Phase", mPhaseValues); ObservableList> observableList = FXCollections.observableArrayList(phaseSeries); diff --git a/src/main/java/io/github/dsheirer/gui/instrument/chart/EyeDiagramChart.java b/src/main/java/io/github/dsheirer/gui/instrument/chart/EyeDiagramChart.java index cede2e58..bc12a22b 100644 --- a/src/main/java/io/github/dsheirer/gui/instrument/chart/EyeDiagramChart.java +++ b/src/main/java/io/github/dsheirer/gui/instrument/chart/EyeDiagramChart.java @@ -28,6 +28,7 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.scene.chart.LineChart; import javafx.scene.chart.NumberAxis; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -97,7 +98,7 @@ public class EyeDiagramChart extends LineChart implements Listener 0 && (Math.abs(corrected[x] - corrected[x - 1]) > Math.PI)) + if(x > 0 && (FastMath.abs(corrected[x] - corrected[x - 1]) > FastMath.PI)) { phaseRolloverIndex = x; } @@ -109,11 +110,11 @@ public class EyeDiagramChart extends LineChart implements Listener 0) { - corrected[x] -= 2 * Math.PI; + corrected[x] -= 2 * FastMath.PI; } else { - corrected[x] += 2 * Math.PI; + corrected[x] += 2 * FastMath.PI; } } } diff --git a/src/main/java/io/github/dsheirer/gui/instrument/chart/SampleXYChart.java b/src/main/java/io/github/dsheirer/gui/instrument/chart/SampleXYChart.java index 1dc19166..6dc963c8 100644 --- a/src/main/java/io/github/dsheirer/gui/instrument/chart/SampleXYChart.java +++ b/src/main/java/io/github/dsheirer/gui/instrument/chart/SampleXYChart.java @@ -85,9 +85,7 @@ public class SampleXYChart extends PolarChart implements Listener mEditors = new HashMap<>(); + private Map mEditors = new EnumMap<>(PreferenceEditorType.class); private UserPreferences mUserPreferences; private HBox mParentBox; private TreeView mEditorSelectionTreeView; @@ -118,22 +120,14 @@ public class PreferencesEditor extends Application private TreeItem recursivelyFindEditorType(TreeItem parent, PreferenceEditorType type) { - ListIterator li = parent.getChildren().listIterator(); - while(li.hasNext()) - { - TreeItem treeItem = li.next(); - - if(treeItem.getValue() instanceof PreferenceEditorType && (treeItem.getValue()).equals(type)) - { + for (TreeItem treeItem : (Iterable) parent.getChildren()) { + if (treeItem.getValue() instanceof PreferenceEditorType && (treeItem.getValue()).equals(type)) { return treeItem; - } - else - { + } else { TreeItem item = recursivelyFindEditorType(treeItem, type); - if(item != null) - { + if (item != null) { return item; } } diff --git a/src/main/java/io/github/dsheirer/icon/IconManager.java b/src/main/java/io/github/dsheirer/icon/IconManager.java index d821efcd..425a1a6d 100644 --- a/src/main/java/io/github/dsheirer/icon/IconManager.java +++ b/src/main/java/io/github/dsheirer/icon/IconManager.java @@ -151,9 +151,9 @@ public class IconManager String scaledIconName = name + height; - if(mResizedIcons.containsKey(scaledIconName)) - { - return mResizedIcons.get(scaledIconName); + ImageIcon mapValue = mResizedIcons.get(scaledIconName); + if (mapValue != null) { + return mapValue; } Icon icon = getModel().getIcon(name); diff --git a/src/main/java/io/github/dsheirer/icon/IconTableModel.java b/src/main/java/io/github/dsheirer/icon/IconTableModel.java index a58c8be1..c1ee256a 100644 --- a/src/main/java/io/github/dsheirer/icon/IconTableModel.java +++ b/src/main/java/io/github/dsheirer/icon/IconTableModel.java @@ -168,7 +168,7 @@ public class IconTableModel extends AbstractTableModel Collections.sort(icons); - return icons.toArray(new Icon[icons.size()]); + return icons.toArray(new Icon[0]); } /** diff --git a/src/main/java/io/github/dsheirer/identifier/IdentifierCollection.java b/src/main/java/io/github/dsheirer/identifier/IdentifierCollection.java index 673046ed..9d7a168e 100644 --- a/src/main/java/io/github/dsheirer/identifier/IdentifierCollection.java +++ b/src/main/java/io/github/dsheirer/identifier/IdentifierCollection.java @@ -198,7 +198,7 @@ public class IdentifierCollection sb.append("Identifier: ").append(i).append(" Class:").append(i.getClass()).append("\n"); } } - mLog.warn("An identifier in a collection is somehow null ...\n" + sb.toString()); + mLog.warn("An identifier in a collection is somehow null ...\n" + sb); } } diff --git a/src/main/java/io/github/dsheirer/identifier/patch/PatchGroupManager.java b/src/main/java/io/github/dsheirer/identifier/patch/PatchGroupManager.java index 67e0a6af..cd8337a7 100644 --- a/src/main/java/io/github/dsheirer/identifier/patch/PatchGroupManager.java +++ b/src/main/java/io/github/dsheirer/identifier/patch/PatchGroupManager.java @@ -157,13 +157,9 @@ public class PatchGroupManager PatchGroupIdentifier patchGroupIdentifier = (PatchGroupIdentifier)identifier; int patchGroupId = patchGroupIdentifier.getValue().getPatchGroup().getValue(); - if(mPatchGroupMap.containsKey(patchGroupId)) - { - return mPatchGroupMap.get(patchGroupId); - } - else - { - addPatchGroup(patchGroupIdentifier); + Identifier mapValue = mPatchGroupMap.get(patchGroupId); + if (mapValue != null) { + return mapValue; } } break; diff --git a/src/main/java/io/github/dsheirer/map/SelectionAdapter.java b/src/main/java/io/github/dsheirer/map/SelectionAdapter.java index 6c38cf31..6647356f 100644 --- a/src/main/java/io/github/dsheirer/map/SelectionAdapter.java +++ b/src/main/java/io/github/dsheirer/map/SelectionAdapter.java @@ -17,6 +17,7 @@ ******************************************************************************/ package io.github.dsheirer.map; +import org.apache.commons.math3.util.FastMath; import org.jdesktop.swingx.JXMapViewer; import java.awt.*; @@ -89,10 +90,10 @@ public class SelectionAdapter extends MouseAdapter { if (dragging) { - int x1 = (int) Math.min(startPos.getX(), endPos.getX()); - int y1 = (int) Math.min(startPos.getY(), endPos.getY()); - int x2 = (int) Math.max(startPos.getX(), endPos.getX()); - int y2 = (int) Math.max(startPos.getY(), endPos.getY()); + int x1 = (int) FastMath.min(startPos.getX(), endPos.getX()); + int y1 = (int) FastMath.min(startPos.getY(), endPos.getY()); + int x2 = (int) FastMath.max(startPos.getX(), endPos.getX()); + int y2 = (int) FastMath.max(startPos.getY(), endPos.getY()); return new Rectangle(x1, y1, x2-x1, y2-y1); } diff --git a/src/main/java/io/github/dsheirer/module/decode/DecoderFactory.java b/src/main/java/io/github/dsheirer/module/decode/DecoderFactory.java index 81408711..bfb3f013 100644 --- a/src/main/java/io/github/dsheirer/module/decode/DecoderFactory.java +++ b/src/main/java/io/github/dsheirer/module/decode/DecoderFactory.java @@ -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 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 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 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 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 activeStates = new ArrayList<>(); + activeStates.add(State.CONTROL); + modules.add(new ChannelRotationMonitor(activeStates, userPreferences)); + } + } + + private static void processPassport(Channel channel, List 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 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 activeStates = new ArrayList<>(); + activeStates.add(State.CONTROL); + modules.add(new ChannelRotationMonitor(activeStates, userPreferences)); + } + } + + private static void processLTRNet(Channel channel, List 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 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 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 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 * diff --git a/src/main/java/io/github/dsheirer/module/decode/fleetsync2/Fleetsync2DecoderState.java b/src/main/java/io/github/dsheirer/module/decode/fleetsync2/Fleetsync2DecoderState.java index 00a05455..9e76369c 100644 --- a/src/main/java/io/github/dsheirer/module/decode/fleetsync2/Fleetsync2DecoderState.java +++ b/src/main/java/io/github/dsheirer/module/decode/fleetsync2/Fleetsync2DecoderState.java @@ -167,11 +167,9 @@ public class Fleetsync2DecoderState extends DecoderState } else { - Iterator 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"); } } diff --git a/src/main/java/io/github/dsheirer/module/decode/fleetsync2/FleetsyncMessageFilter.java b/src/main/java/io/github/dsheirer/module/decode/fleetsync2/FleetsyncMessageFilter.java index c40039bd..c2b75b0b 100644 --- a/src/main/java/io/github/dsheirer/module/decode/fleetsync2/FleetsyncMessageFilter.java +++ b/src/main/java/io/github/dsheirer/module/decode/fleetsync2/FleetsyncMessageFilter.java @@ -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 { - private HashMap> mElements = - new HashMap>(); + private Map> mElements = new EnumMap<>(FleetsyncMessageType.class); public FleetsyncMessageFilter() { diff --git a/src/main/java/io/github/dsheirer/module/decode/lj1200/LJ1200Message.java b/src/main/java/io/github/dsheirer/module/decode/lj1200/LJ1200Message.java index 607894ec..62708210 100644 --- a/src/main/java/io/github/dsheirer/module/decode/lj1200/LJ1200Message.java +++ b/src/main/java/io/github/dsheirer/module/decode/lj1200/LJ1200Message.java @@ -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 diff --git a/src/main/java/io/github/dsheirer/module/decode/lj1200/LJ1200TransponderMessage.java b/src/main/java/io/github/dsheirer/module/decode/lj1200/LJ1200TransponderMessage.java index 33654be2..ea6f5b09 100644 --- a/src/main/java/io/github/dsheirer/module/decode/lj1200/LJ1200TransponderMessage.java +++ b/src/main/java/io/github/dsheirer/module/decode/lj1200/LJ1200TransponderMessage.java @@ -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 diff --git a/src/main/java/io/github/dsheirer/module/decode/ltrnet/LTRNetDecoderState.java b/src/main/java/io/github/dsheirer/module/decode/ltrnet/LTRNetDecoderState.java index a3bde96c..34c82147 100644 --- a/src/main/java/io/github/dsheirer/module/decode/ltrnet/LTRNetDecoderState.java +++ b/src/main/java/io/github/dsheirer/module/decode/ltrnet/LTRNetDecoderState.java @@ -573,7 +573,7 @@ public class LTRNetDecoderState extends DecoderState else { List 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 ltrNetRadioIdentifiers = new ArrayList<>(mLtrNetRadioIdentifiers); - Collections.sort(ltrNetRadioIdentifiers, Comparator.comparingInt(Identifier::getValue)); + ltrNetRadioIdentifiers.sort(Comparator.comparingInt(Identifier::getValue)); for(LtrNetRadioIdentifier ltrNetRadioIdentifier : ltrNetRadioIdentifiers) { diff --git a/src/main/java/io/github/dsheirer/module/decode/ltrnet/LTRNetMessageFilter.java b/src/main/java/io/github/dsheirer/module/decode/ltrnet/LTRNetMessageFilter.java index 9b8d1ed9..ab9182bc 100644 --- a/src/main/java/io/github/dsheirer/module/decode/ltrnet/LTRNetMessageFilter.java +++ b/src/main/java/io/github/dsheirer/module/decode/ltrnet/LTRNetMessageFilter.java @@ -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 { - private Map> mElements = new HashMap<>(); + private Map> mElements = new EnumMap<>(LtrNetMessageType.class); public LTRNetMessageFilter() { diff --git a/src/main/java/io/github/dsheirer/module/decode/ltrstandard/LTRStandardMessageFilter.java b/src/main/java/io/github/dsheirer/module/decode/ltrstandard/LTRStandardMessageFilter.java index 17530372..78f20f50 100644 --- a/src/main/java/io/github/dsheirer/module/decode/ltrstandard/LTRStandardMessageFilter.java +++ b/src/main/java/io/github/dsheirer/module/decode/ltrstandard/LTRStandardMessageFilter.java @@ -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 { - private Map> mElements = new HashMap<>(); + private Map> mElements = new EnumMap<>(LtrStandardMessageType.class); public LTRStandardMessageFilter() { diff --git a/src/main/java/io/github/dsheirer/module/decode/mdc1200/MDCDecoderState.java b/src/main/java/io/github/dsheirer/module/decode/mdc1200/MDCDecoderState.java index ae4d5505..7875de83 100644 --- a/src/main/java/io/github/dsheirer/module/decode/mdc1200/MDCDecoderState.java +++ b/src/main/java/io/github/dsheirer/module/decode/mdc1200/MDCDecoderState.java @@ -152,11 +152,9 @@ public class MDCDecoderState extends DecoderState } else { - Iterator 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 it2 = mIdents.iterator(); - while(it2.hasNext()) - { - sb.append(" ").append(it2.next()).append("\n"); + for (MDC1200Identifier mIdent : mIdents) { + sb.append(" ").append(mIdent).append("\n"); } } } diff --git a/src/main/java/io/github/dsheirer/module/decode/mdc1200/MDCMessage.java b/src/main/java/io/github/dsheirer/module/decode/mdc1200/MDCMessage.java index 1dfcaa88..34cda27b 100644 --- a/src/main/java/io/github/dsheirer/module/decode/mdc1200/MDCMessage.java +++ b/src/main/java/io/github/dsheirer/module/decode/mdc1200/MDCMessage.java @@ -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(); } diff --git a/src/main/java/io/github/dsheirer/module/decode/mdc1200/MDCMessageFilter.java b/src/main/java/io/github/dsheirer/module/decode/mdc1200/MDCMessageFilter.java index 8a49cb46..45b4d3af 100644 --- a/src/main/java/io/github/dsheirer/module/decode/mdc1200/MDCMessageFilter.java +++ b/src/main/java/io/github/dsheirer/module/decode/mdc1200/MDCMessageFilter.java @@ -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 { - private Map> mElements = new HashMap>(); + private Map> mElements = new EnumMap<>(MDCMessageType.class); public MDCMessageFilter() { diff --git a/src/main/java/io/github/dsheirer/module/decode/mpt1327/MPT1327DecoderState.java b/src/main/java/io/github/dsheirer/module/decode/mpt1327/MPT1327DecoderState.java index 83b040d2..9ac05217 100644 --- a/src/main/java/io/github/dsheirer/module/decode/mpt1327/MPT1327DecoderState.java +++ b/src/main/java/io/github/dsheirer/module/decode/mpt1327/MPT1327DecoderState.java @@ -411,12 +411,7 @@ public class MPT1327DecoderState extends DecoderState { sb.append("\n"); - Iterator it = mIdents.iterator(); - - while(it.hasNext()) - { - String ident = it.next(); - + for (String ident : mIdents) { sb.append(ident); sb.append("\n"); } diff --git a/src/main/java/io/github/dsheirer/module/decode/mpt1327/MPT1327Message.java b/src/main/java/io/github/dsheirer/module/decode/mpt1327/MPT1327Message.java index be682c93..687cb88e 100644 --- a/src/main/java/io/github/dsheirer/module/decode/mpt1327/MPT1327Message.java +++ b/src/main/java/io/github/dsheirer/module/decode/mpt1327/MPT1327Message.java @@ -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() diff --git a/src/main/java/io/github/dsheirer/module/decode/mpt1327/MPT1327MessageFilter.java b/src/main/java/io/github/dsheirer/module/decode/mpt1327/MPT1327MessageFilter.java index c5f2c2c0..bfd596aa 100644 --- a/src/main/java/io/github/dsheirer/module/decode/mpt1327/MPT1327MessageFilter.java +++ b/src/main/java/io/github/dsheirer/module/decode/mpt1327/MPT1327MessageFilter.java @@ -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 { - private Map> mFilterElements = new HashMap<>(); + private Map> mFilterElements = new EnumMap<>(MPT1327Message.MPTMessageType.class); public MPT1327MessageFilter() { diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/P25TrafficChannelManager.java b/src/main/java/io/github/dsheirer/module/decode/p25/P25TrafficChannelManager.java index bddc36b0..1c21630a 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/P25TrafficChannelManager.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/P25TrafficChannelManager.java @@ -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 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 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 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 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; diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/P25Utils.java b/src/main/java/io/github/dsheirer/module/decode/p25/P25Utils.java index 62c0c296..42aff213 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/P25Utils.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/P25Utils.java @@ -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'); } /** diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/audio/P25P2CallSequenceRecorder.java b/src/main/java/io/github/dsheirer/module/decode/p25/audio/P25P2CallSequenceRecorder.java index 3d7ea882..aba52e0a 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/audio/P25P2CallSequenceRecorder.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/audio/P25P2CallSequenceRecorder.java @@ -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()); + } + } } } diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/C4FMSymbolFilter.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/C4FMSymbolFilter.java index 992294af..a3e46de5 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/C4FMSymbolFilter.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/C4FMSymbolFilter.java @@ -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, ISourceEventListener, RealSampleProvider { @@ -289,7 +290,7 @@ public class C4FMSymbolFilter implements Listener, 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, 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); diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1DataUnitDetector.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1DataUnitDetector.java index 32ffcb99..274e0cd5 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1DataUnitDetector.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1DataUnitDetector.java @@ -436,11 +436,11 @@ public class P25P1DataUnitDetector implements Listener, 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, ISyncDetectListen if(corrected) { - mLog.debug("C* NID: " + sb.toString()); + mLog.debug("C* NID: " + sb); } else { - mLog.debug(" NID: " + sb.toString()); + mLog.debug(" NID: " + sb); } } diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1DecoderState.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1DecoderState.java index 0c136392..c5ab733c 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1DecoderState.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1DecoderState.java @@ -137,6 +137,8 @@ import io.github.dsheirer.sample.Listener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.List; + /** * Decoder state for an APCO25 channel. Maintains the call/data/idle state of the channel and produces events by * monitoring the decoded message stream. @@ -325,61 +327,20 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList switch(ambtc.getHeader().getOpcode()) { case ISP_AUTHENTICATION_RESPONSE: - if(message instanceof AMBTCAuthenticationResponse) - { - AMBTCAuthenticationResponse ar = (AMBTCAuthenticationResponse)ambtc; - - MutableIdentifierCollection icAuthenticationResponse = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icAuthenticationResponse.remove(IdentifierClass.USER); - icAuthenticationResponse.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("AUTHENTICATION:" + ar.getAuthenticationValue()) - .identifiers(icAuthenticationResponse) - .build()); - } + processAMBTCIspAuthenticationResponse(message, ambtc); break; case ISP_CALL_ALERT_REQUEST: - MutableIdentifierCollection icCallAlertRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icCallAlertRequest.remove(IdentifierClass.USER); - icCallAlertRequest.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("CALL ALERT") - .identifiers(icCallAlertRequest) - .build()); + processBroadcast(ambtc.getIdentifiers(), ambtc.getTimestamp(), DecodeEventType.REQUEST, "CALL ALERT"); break; case ISP_GROUP_AFFILIATION_REQUEST: - MutableIdentifierCollection icGroupAffiliationRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icGroupAffiliationRequest.remove(IdentifierClass.USER); - icGroupAffiliationRequest.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("GROUP AFFILIATION") - .identifiers(icGroupAffiliationRequest) - .build()); + processBroadcast(ambtc.getIdentifiers(), ambtc.getTimestamp(), DecodeEventType.REQUEST, "GROUP AFFILIATION"); break; case ISP_INDIVIDUAL_DATA_SERVICE_REQUEST: if(ambtc instanceof AMBTCIndividualDataServiceRequest) { AMBTCIndividualDataServiceRequest idsr = (AMBTCIndividualDataServiceRequest)ambtc; - MutableIdentifierCollection icDataRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icDataRequest.remove(IdentifierClass.USER); - icDataRequest.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("INDIVIDUAL DATA SERVICE " + idsr.getDataServiceOptions()) - .identifiers(icDataRequest) - .build()); + processBroadcast(ambtc.getIdentifiers(), ambtc.getTimestamp(), DecodeEventType.REQUEST, "INDIVIDUAL DATA SERVICE " + idsr.getDataServiceOptions()); } break; case ISP_LOCATION_REGISTRATION_REQUEST: @@ -387,16 +348,7 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList { AMBTCLocationRegistrationRequest lrr = (AMBTCLocationRegistrationRequest)ambtc; - MutableIdentifierCollection icLocationRegistrationRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icLocationRegistrationRequest.remove(IdentifierClass.USER); - icLocationRegistrationRequest.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("LOCATION REGISTRATION - UNIQUE ID:" + lrr.getSourceId()) - .identifiers(icLocationRegistrationRequest) - .build()); + processBroadcast(ambtc.getIdentifiers(), ambtc.getTimestamp(), DecodeEventType.REQUEST, "LOCATION REGISTRATION - UNIQUE ID:" + lrr.getSourceId()); } break; case ISP_MESSAGE_UPDATE_REQUEST: @@ -404,90 +356,27 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList { AMBTCMessageUpdateRequest mur = (AMBTCMessageUpdateRequest)ambtc; - MutableIdentifierCollection icMessageUpdateRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icMessageUpdateRequest.remove(IdentifierClass.USER); - icMessageUpdateRequest.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.SDM.toString()) - .details("MESSAGE:" + mur.getShortDataMessage()) - .identifiers(icMessageUpdateRequest) - .build()); + processBroadcast(ambtc.getIdentifiers(), ambtc.getTimestamp(), DecodeEventType.SDM, "MESSAGE:" + mur.getShortDataMessage()); } break; case ISP_ROAMING_ADDRESS_REQUEST: - MutableIdentifierCollection icRoamingAddressRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icRoamingAddressRequest.remove(IdentifierClass.USER); - icRoamingAddressRequest.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("ROAMING ADDRESS") - .identifiers(icRoamingAddressRequest) - .build()); + processBroadcast(ambtc.getIdentifiers(), ambtc.getTimestamp(), DecodeEventType.REQUEST, "ROAMING ADDRESS"); break; case ISP_STATUS_QUERY_REQUEST: - MutableIdentifierCollection icStatusQuery = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icStatusQuery.remove(IdentifierClass.USER); - icStatusQuery.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("STATUS QUERY") - .identifiers(icStatusQuery) - .build()); + processBroadcast(ambtc.getIdentifiers(), ambtc.getTimestamp(), DecodeEventType.REQUEST, "STATUS QUERY"); break; case ISP_STATUS_QUERY_RESPONSE: - if(ambtc instanceof AMBTCStatusQueryResponse) - { - MutableIdentifierCollection icStatusQueryResponse = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icStatusQueryResponse.remove(IdentifierClass.USER); - icStatusQueryResponse.update(ambtc.getIdentifiers()); - - AMBTCStatusQueryResponse sqr = (AMBTCStatusQueryResponse)ambtc; - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.STATUS.toString()) - .details("UNIT:" + sqr.getUnitStatus() + " USER:" + sqr.getUserStatus()) - .identifiers(icStatusQueryResponse) - .build()); - } + processAMBTCStatusQueryResponse(ambtc); break; case ISP_STATUS_UPDATE_REQUEST: - if(ambtc instanceof AMBTCStatusUpdateRequest) - { - AMBTCStatusUpdateRequest sur = (AMBTCStatusUpdateRequest)ambtc; - - MutableIdentifierCollection icStatusUpdateRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icStatusUpdateRequest.remove(IdentifierClass.USER); - icStatusUpdateRequest.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.STATUS.toString()) - .details("UNIT:" + sur.getUnitStatus() + " USER:" + sur.getUserStatus()) - .identifiers(icStatusUpdateRequest) - .build()); - } + processAMBTCStatusUpdateRequest(ambtc); break; case ISP_UNIT_ACKNOWLEDGE_RESPONSE: if(ambtc instanceof AMBTCUnitAcknowledgeResponse) { AMBTCUnitAcknowledgeResponse uar = (AMBTCUnitAcknowledgeResponse)ambtc; - MutableIdentifierCollection icUnitAcknowledge = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icUnitAcknowledge.remove(IdentifierClass.USER); - icUnitAcknowledge.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("ACKNOWLEDGE:" + uar.getAcknowledgedService()) - .identifiers(icUnitAcknowledge) - .build()); + processBroadcast(ambtc.getIdentifiers(), ambtc.getTimestamp(), DecodeEventType.RESPONSE, "ACKNOWLEDGE:" + uar.getAcknowledgedService()); } break; case ISP_UNIT_TO_UNIT_VOICE_SERVICE_REQUEST: @@ -495,35 +384,11 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList { AMBTCUnitToUnitVoiceServiceRequest uuvsr = (AMBTCUnitToUnitVoiceServiceRequest)ambtc; - MutableIdentifierCollection icUnitVoiceService = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icUnitVoiceService.remove(IdentifierClass.USER); - icUnitVoiceService.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("UNIT-2-UNIT VOICE SERVICE " + uuvsr.getVoiceServiceOptions()) - .identifiers(icUnitVoiceService) - .build()); + processBroadcast(ambtc.getIdentifiers(), ambtc.getTimestamp(), DecodeEventType.REQUEST, "UNIT-2-UNIT VOICE SERVICE " + uuvsr.getVoiceServiceOptions()); } break; case ISP_UNIT_TO_UNIT_ANSWER_RESPONSE: - if(ambtc instanceof AMBTCUnitToUnitVoiceServiceAnswerResponse) - { - AMBTCUnitToUnitVoiceServiceAnswerResponse uuvsar = (AMBTCUnitToUnitVoiceServiceAnswerResponse)ambtc; - - MutableIdentifierCollection icUnitAnswerResponse = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icUnitAnswerResponse.remove(IdentifierClass.USER); - icUnitAnswerResponse.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details(uuvsar.getAnswerResponse() + " UNIT-2-UNIT VOICE SERVICE " + - uuvsar.getVoiceServiceOptions()) - .identifiers(icUnitAnswerResponse) - .build()); - } + processAMBTCUnitToUnitAnswerResponse(ambtc); break; //Network configuration messages @@ -539,260 +404,67 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList //Channel grants case OSP_GROUP_DATA_CHANNEL_GRANT: - if(ambtc instanceof AMBTCGroupDataChannelGrant) - { - AMBTCGroupDataChannelGrant gdcg = (AMBTCGroupDataChannelGrant)ambtc; - - MutableIdentifierCollection identifierCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifierCollection.remove(IdentifierClass.USER); - identifierCollection.update(gdcg.getIdentifiers()); - processChannelGrant(gdcg.getChannel(), gdcg.getDataServiceOptions(), - identifierCollection, ambtc.getHeader().getOpcode(), - ambtc.getTimestamp()); - } + processAMBTCGroupDataChannelGrant(ambtc); break; case OSP_GROUP_VOICE_CHANNEL_GRANT: - if(ambtc instanceof AMBTCGroupVoiceChannelGrant) - { - AMBTCGroupVoiceChannelGrant gvcg = (AMBTCGroupVoiceChannelGrant)ambtc; - - MutableIdentifierCollection identifierCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifierCollection.remove(IdentifierClass.USER); - identifierCollection.update(gvcg.getIdentifiers()); - - processChannelGrant(gvcg.getChannel(), gvcg.getVoiceServiceOptions(), - identifierCollection, ambtc.getHeader().getOpcode(), - ambtc.getTimestamp()); - } + processAMBTCGroupVoiceChannelGrant(ambtc); break; case OSP_INDIVIDUAL_DATA_CHANNEL_GRANT: - if(ambtc instanceof AMBTCIndividualDataChannelGrant) - { - AMBTCIndividualDataChannelGrant idcg = (AMBTCIndividualDataChannelGrant)ambtc; - - MutableIdentifierCollection identifierCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifierCollection.remove(IdentifierClass.USER); - identifierCollection.update(idcg.getIdentifiers()); - - processChannelGrant(idcg.getChannel(), idcg.getDataServiceOptions(), - identifierCollection, ambtc.getHeader().getOpcode(), - ambtc.getTimestamp()); - } + processAMBTCIndividualDataChannelGrant(ambtc); break; case OSP_TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT: - if(ambtc instanceof AMBTCTelephoneInterconnectChannelGrant) - { - AMBTCTelephoneInterconnectChannelGrant ticg = (AMBTCTelephoneInterconnectChannelGrant)ambtc; - - MutableIdentifierCollection identifierCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifierCollection.remove(IdentifierClass.USER); - identifierCollection.update(ticg.getIdentifiers()); - - processChannelGrant(ticg.getChannel(), ticg.getVoiceServiceOptions(), - identifierCollection, ambtc.getHeader().getOpcode(), - ambtc.getTimestamp()); - } + processAMBTCTelephoneInterconnectVoiceChannelGrant(ambtc); break; case OSP_TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT_UPDATE: - if(ambtc instanceof AMBTCTelephoneInterconnectChannelGrantUpdate) - { - AMBTCTelephoneInterconnectChannelGrantUpdate ticgu = (AMBTCTelephoneInterconnectChannelGrantUpdate)ambtc; - - MutableIdentifierCollection identifierCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifierCollection.remove(IdentifierClass.USER); - identifierCollection.update(ticgu.getIdentifiers()); - - processChannelGrant(ticgu.getChannel(), ticgu.getVoiceServiceOptions(), - identifierCollection, ambtc.getHeader().getOpcode(), - ambtc.getTimestamp()); - } + processAMBTCTelephoneInterconnectVoiceChannelGrantUpdate(ambtc); break; case OSP_UNIT_TO_UNIT_VOICE_CHANNEL_GRANT: - if(ambtc instanceof AMBTCUnitToUnitVoiceServiceChannelGrant) - { - AMBTCUnitToUnitVoiceServiceChannelGrant uuvscg = (AMBTCUnitToUnitVoiceServiceChannelGrant)ambtc; - - MutableIdentifierCollection identifierCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifierCollection.remove(IdentifierClass.USER); - identifierCollection.update(uuvscg.getIdentifiers()); - - processChannelGrant(uuvscg.getChannel(), uuvscg.getVoiceServiceOptions(), - identifierCollection, ambtc.getHeader().getOpcode(), - ambtc.getTimestamp()); - } + processAMBTCUnitToUnitVoiceChannelGrant(ambtc); break; case OSP_UNIT_TO_UNIT_VOICE_CHANNEL_GRANT_UPDATE: - if(ambtc instanceof AMBTCUnitToUnitVoiceServiceChannelGrantUpdate) - { - AMBTCUnitToUnitVoiceServiceChannelGrantUpdate uuvscgu = (AMBTCUnitToUnitVoiceServiceChannelGrantUpdate)ambtc; - - MutableIdentifierCollection identifierCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifierCollection.remove(IdentifierClass.USER); - identifierCollection.update(uuvscgu.getIdentifiers()); - - processChannelGrant(uuvscgu.getChannel(), uuvscgu.getVoiceServiceOptions(), - identifierCollection, ambtc.getHeader().getOpcode(), - ambtc.getTimestamp()); - } + processAMBTCUnitToUnitVoiceChannelGrantUpdate(ambtc); break; case OSP_UNIT_TO_UNIT_ANSWER_REQUEST: - MutableIdentifierCollection icUUAnswerRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icUUAnswerRequest.remove(IdentifierClass.USER); - icUUAnswerRequest.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.PAGE.toString()) - .details("ANSWER REQUEST") - .identifiers(icUUAnswerRequest) - .build()); + processBroadcast(ambtc.getIdentifiers(), ambtc.getTimestamp(), DecodeEventType.PAGE, "ANSWER REQUEST"); break; case OSP_CALL_ALERT: - MutableIdentifierCollection icCallAlert = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icCallAlert.remove(IdentifierClass.USER); - icCallAlert.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.PAGE.toString()) - .details("CALL ALERT") - .identifiers(icCallAlert) - .build()); + processBroadcast(ambtc.getIdentifiers(), ambtc.getTimestamp(), DecodeEventType.PAGE, "CALL ALERT"); break; case OSP_GROUP_AFFILIATION_QUERY: - MutableIdentifierCollection icGroupAffiliationQuery = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icGroupAffiliationQuery.remove(IdentifierClass.USER); - icGroupAffiliationQuery.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.QUERY.toString()) - .details("GROUP AFFILIATION") - .identifiers(icGroupAffiliationQuery) - .build()); + processBroadcast(ambtc.getIdentifiers(), ambtc.getTimestamp(), DecodeEventType.QUERY, "GROUP AFFILIATION"); break; case OSP_GROUP_AFFILIATION_RESPONSE: - if(ambtc instanceof AMBTCGroupAffiliationResponse) - { - AMBTCGroupAffiliationResponse gar = (AMBTCGroupAffiliationResponse)ambtc; - - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("AFFILIATION GROUP:" + gar.getGroupId() + - " ANNOUNCEMENT GROUP:" + gar.getAnnouncementGroupId()) - .identifiers(ic) - .build()); - } + processAMBTCGroupAffiliationResponse(ambtc); break; case OSP_MESSAGE_UPDATE: if(ambtc instanceof AMBTCMessageUpdate) { AMBTCMessageUpdate mu = (AMBTCMessageUpdate)ambtc; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.SDM.toString()) - .details("MESSAGE:" + mu.getShortDataMessage()) - .identifiers(ic) - .build()); + processBroadcast(ambtc.getIdentifiers(), ambtc.getTimestamp(), DecodeEventType.SDM, "MESSAGE:" + mu.getShortDataMessage()); } break; case OSP_PROTECTION_PARAMETER_BROADCAST: - if(ambtc instanceof AMBTCProtectionParameterBroadcast) - { - AMBTCProtectionParameterBroadcast ppb = (AMBTCProtectionParameterBroadcast)ambtc; - - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("USE ENCRYPTION " + ppb.getEncryptionKey() + - " OUTBOUND MI:" + ppb.getOutboundMessageIndicator() + - " INBOUND MI:" + ppb.getInboundMessageIndicator()) - .identifiers(ic) - .build()); - } + processAMBTCProtectionParameterBroadcast(ambtc); break; case OSP_ROAMING_ADDRESS_UPDATE: - MutableIdentifierCollection icRoamingAddressUpdate = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icRoamingAddressUpdate.remove(IdentifierClass.USER); - icRoamingAddressUpdate.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("ROAMING ADDRESS UPDATE") - .identifiers(icRoamingAddressUpdate) - .build()); + processBroadcast(ambtc.getIdentifiers(), ambtc.getTimestamp(), DecodeEventType.RESPONSE, "ROAMING ADDRESS UPDATE"); break; case OSP_ROAMING_ADDRESS_COMMAND: - MutableIdentifierCollection icRoamingAddressCommand = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icRoamingAddressCommand.remove(IdentifierClass.USER); - icRoamingAddressCommand.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.COMMAND.toString()) - .details("ROAMING ADDRESS") - .identifiers(icRoamingAddressCommand) - .build()); + processBroadcast(ambtc.getIdentifiers(), ambtc.getTimestamp(), DecodeEventType.COMMAND, "ROAMING ADDRESS"); break; case OSP_STATUS_QUERY: - MutableIdentifierCollection icOStatusQuery = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icOStatusQuery.remove(IdentifierClass.USER); - icOStatusQuery.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.QUERY.toString()) - .details("STATUS") - .identifiers(icOStatusQuery) - .build()); + processBroadcast(ambtc.getIdentifiers(), ambtc.getTimestamp(), DecodeEventType.QUERY, "STATUS"); break; case OSP_STATUS_UPDATE: - if(ambtc instanceof AMBTCStatusUpdate) - { - AMBTCStatusUpdate su = (AMBTCStatusUpdate)ambtc; - - MutableIdentifierCollection icStatusUpdate = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icStatusUpdate.remove(IdentifierClass.USER); - icStatusUpdate.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.STATUS.toString()) - .details("UNIT:" + su.getUnitStatus() + " USER:" + su.getUserStatus()) - .identifiers(icStatusUpdate) - .build()); - } + processAMBTCStatusUpdate(ambtc); break; case OSP_UNIT_REGISTRATION_RESPONSE: if(ambtc instanceof AMBTCUnitRegistrationResponse) { AMBTCUnitRegistrationResponse urr = (AMBTCUnitRegistrationResponse)ambtc; - MutableIdentifierCollection icUnitRegistrationResponse = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icUnitRegistrationResponse.remove(IdentifierClass.USER); - icUnitRegistrationResponse.update(ambtc.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REGISTER.toString()) - .details(urr.getResponse() + " UNIT REGISTRATION") - .identifiers(icUnitRegistrationResponse) - .build()); + processBroadcast(ambtc.getIdentifiers(), ambtc.getTimestamp(), DecodeEventType.REGISTER, urr.getResponse() + " UNIT REGISTRATION"); } break; default: @@ -804,6 +476,243 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList broadcast(new DecoderStateEvent(this, Event.DECODE, State.CONTROL)); } + private void processAMBTCStatusUpdate(AMBTCMessage ambtc) { + if(ambtc instanceof AMBTCStatusUpdate) + { + AMBTCStatusUpdate su = (AMBTCStatusUpdate)ambtc; + + MutableIdentifierCollection icStatusUpdate = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + icStatusUpdate.remove(IdentifierClass.USER); + icStatusUpdate.update(ambtc.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.STATUS.toString()) + .details("UNIT:" + su.getUnitStatus() + " USER:" + su.getUserStatus()) + .identifiers(icStatusUpdate) + .build()); + } + } + + private void processAMBTCProtectionParameterBroadcast(AMBTCMessage ambtc) { + if(ambtc instanceof AMBTCProtectionParameterBroadcast) + { + AMBTCProtectionParameterBroadcast ppb = (AMBTCProtectionParameterBroadcast)ambtc; + + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(ambtc.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.RESPONSE.toString()) + .details("USE ENCRYPTION " + ppb.getEncryptionKey() + + " OUTBOUND MI:" + ppb.getOutboundMessageIndicator() + + " INBOUND MI:" + ppb.getInboundMessageIndicator()) + .identifiers(ic) + .build()); + } + } + + private void processAMBTCGroupAffiliationResponse(AMBTCMessage ambtc) { + if(ambtc instanceof AMBTCGroupAffiliationResponse) + { + AMBTCGroupAffiliationResponse gar = (AMBTCGroupAffiliationResponse)ambtc; + + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(ambtc.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.RESPONSE.toString()) + .details("AFFILIATION GROUP:" + gar.getGroupId() + + " ANNOUNCEMENT GROUP:" + gar.getAnnouncementGroupId()) + .identifiers(ic) + .build()); + } + } + + private void processAMBTCUnitToUnitVoiceChannelGrantUpdate(AMBTCMessage ambtc) { + if(ambtc instanceof AMBTCUnitToUnitVoiceServiceChannelGrantUpdate) + { + AMBTCUnitToUnitVoiceServiceChannelGrantUpdate uuvscgu = (AMBTCUnitToUnitVoiceServiceChannelGrantUpdate)ambtc; + + MutableIdentifierCollection identifierCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + identifierCollection.remove(IdentifierClass.USER); + identifierCollection.update(uuvscgu.getIdentifiers()); + + processChannelGrant(uuvscgu.getChannel(), uuvscgu.getVoiceServiceOptions(), + identifierCollection, ambtc.getHeader().getOpcode(), + ambtc.getTimestamp()); + } + } + + private void processAMBTCUnitToUnitVoiceChannelGrant(AMBTCMessage ambtc) { + if(ambtc instanceof AMBTCUnitToUnitVoiceServiceChannelGrant) + { + AMBTCUnitToUnitVoiceServiceChannelGrant uuvscg = (AMBTCUnitToUnitVoiceServiceChannelGrant)ambtc; + + MutableIdentifierCollection identifierCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + identifierCollection.remove(IdentifierClass.USER); + identifierCollection.update(uuvscg.getIdentifiers()); + + processChannelGrant(uuvscg.getChannel(), uuvscg.getVoiceServiceOptions(), + identifierCollection, ambtc.getHeader().getOpcode(), + ambtc.getTimestamp()); + } + } + + private void processAMBTCTelephoneInterconnectVoiceChannelGrantUpdate(AMBTCMessage ambtc) { + if(ambtc instanceof AMBTCTelephoneInterconnectChannelGrantUpdate) + { + AMBTCTelephoneInterconnectChannelGrantUpdate ticgu = (AMBTCTelephoneInterconnectChannelGrantUpdate)ambtc; + + MutableIdentifierCollection identifierCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + identifierCollection.remove(IdentifierClass.USER); + identifierCollection.update(ticgu.getIdentifiers()); + + processChannelGrant(ticgu.getChannel(), ticgu.getVoiceServiceOptions(), + identifierCollection, ambtc.getHeader().getOpcode(), + ambtc.getTimestamp()); + } + } + + private void processAMBTCTelephoneInterconnectVoiceChannelGrant(AMBTCMessage ambtc) { + if(ambtc instanceof AMBTCTelephoneInterconnectChannelGrant) + { + AMBTCTelephoneInterconnectChannelGrant ticg = (AMBTCTelephoneInterconnectChannelGrant)ambtc; + + MutableIdentifierCollection identifierCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + identifierCollection.remove(IdentifierClass.USER); + identifierCollection.update(ticg.getIdentifiers()); + + processChannelGrant(ticg.getChannel(), ticg.getVoiceServiceOptions(), + identifierCollection, ambtc.getHeader().getOpcode(), + ambtc.getTimestamp()); + } + } + + private void processAMBTCIndividualDataChannelGrant(AMBTCMessage ambtc) { + if(ambtc instanceof AMBTCIndividualDataChannelGrant) + { + AMBTCIndividualDataChannelGrant idcg = (AMBTCIndividualDataChannelGrant)ambtc; + + MutableIdentifierCollection identifierCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + identifierCollection.remove(IdentifierClass.USER); + identifierCollection.update(idcg.getIdentifiers()); + + processChannelGrant(idcg.getChannel(), idcg.getDataServiceOptions(), + identifierCollection, ambtc.getHeader().getOpcode(), + ambtc.getTimestamp()); + } + } + + private void processAMBTCGroupVoiceChannelGrant(AMBTCMessage ambtc) { + if(ambtc instanceof AMBTCGroupVoiceChannelGrant) + { + AMBTCGroupVoiceChannelGrant gvcg = (AMBTCGroupVoiceChannelGrant)ambtc; + + MutableIdentifierCollection identifierCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + identifierCollection.remove(IdentifierClass.USER); + identifierCollection.update(gvcg.getIdentifiers()); + + processChannelGrant(gvcg.getChannel(), gvcg.getVoiceServiceOptions(), + identifierCollection, ambtc.getHeader().getOpcode(), + ambtc.getTimestamp()); + } + } + + private void processAMBTCGroupDataChannelGrant(AMBTCMessage ambtc) { + if(ambtc instanceof AMBTCGroupDataChannelGrant) + { + AMBTCGroupDataChannelGrant gdcg = (AMBTCGroupDataChannelGrant)ambtc; + + MutableIdentifierCollection identifierCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + identifierCollection.remove(IdentifierClass.USER); + identifierCollection.update(gdcg.getIdentifiers()); + processChannelGrant(gdcg.getChannel(), gdcg.getDataServiceOptions(), + identifierCollection, ambtc.getHeader().getOpcode(), + ambtc.getTimestamp()); + } + } + + private void processAMBTCUnitToUnitAnswerResponse(AMBTCMessage ambtc) { + if(ambtc instanceof AMBTCUnitToUnitVoiceServiceAnswerResponse) + { + AMBTCUnitToUnitVoiceServiceAnswerResponse uuvsar = (AMBTCUnitToUnitVoiceServiceAnswerResponse)ambtc; + + MutableIdentifierCollection icUnitAnswerResponse = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + icUnitAnswerResponse.remove(IdentifierClass.USER); + icUnitAnswerResponse.update(ambtc.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.RESPONSE.toString()) + .details(uuvsar.getAnswerResponse() + " UNIT-2-UNIT VOICE SERVICE " + + uuvsar.getVoiceServiceOptions()) + .identifiers(icUnitAnswerResponse) + .build()); + } + } + + private void processAMBTCStatusUpdateRequest(AMBTCMessage ambtc) { + if(ambtc instanceof AMBTCStatusUpdateRequest) + { + AMBTCStatusUpdateRequest sur = (AMBTCStatusUpdateRequest)ambtc; + + MutableIdentifierCollection icStatusUpdateRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + icStatusUpdateRequest.remove(IdentifierClass.USER); + icStatusUpdateRequest.update(ambtc.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.STATUS.toString()) + .details("UNIT:" + sur.getUnitStatus() + " USER:" + sur.getUserStatus()) + .identifiers(icStatusUpdateRequest) + .build()); + } + } + + private void processAMBTCStatusQueryResponse(AMBTCMessage ambtc) { + if(ambtc instanceof AMBTCStatusQueryResponse) + { + MutableIdentifierCollection icStatusQueryResponse = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + icStatusQueryResponse.remove(IdentifierClass.USER); + icStatusQueryResponse.update(ambtc.getIdentifiers()); + + AMBTCStatusQueryResponse sqr = (AMBTCStatusQueryResponse)ambtc; + broadcast(P25DecodeEvent.builder(ambtc.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.STATUS.toString()) + .details("UNIT:" + sqr.getUnitStatus() + " USER:" + sqr.getUserStatus()) + .identifiers(icStatusQueryResponse) + .build()); + } + } + + private void processBroadcast(List identifiers, long timestamp, DecodeEventType request, String s) { + MutableIdentifierCollection requestCollection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + requestCollection.remove(IdentifierClass.USER); + requestCollection.update(identifiers); + + broadcast(P25DecodeEvent.builder(timestamp) + .channel(getCurrentChannel()) + .eventDescription(request.toString()) + .details(s) + .identifiers(requestCollection) + .build()); + } + + private void processAMBTCIspAuthenticationResponse(P25Message message, AMBTCMessage ambtc) { + if(message instanceof AMBTCAuthenticationResponse) + { + AMBTCAuthenticationResponse ar = (AMBTCAuthenticationResponse)ambtc; + + processBroadcast(ambtc.getIdentifiers(), ambtc.getTimestamp(), DecodeEventType.RESPONSE, "AUTHENTICATION:" + ar.getAuthenticationValue()); + } + } + /** * Processes a Header Data Unit message and starts a new call event. */ @@ -963,16 +872,7 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList { PDUMessage pdu = (PDUMessage)message; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(pdu.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.DATA_PACKET.toString()) - .details(pdu.toString()) - .identifiers(ic) - .build()); + processBroadcast(pdu.getIdentifiers(), message.getTimestamp(), DecodeEventType.DATA_PACKET, pdu.toString()); } @@ -990,16 +890,7 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList { UMBTCTelephoneInterconnectRequestExplicitDialing tired = (UMBTCTelephoneInterconnectRequestExplicitDialing)message; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tired.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tired.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("TELEPHONE INTERCONNECT:" + tired.getTelephoneNumber()) - .identifiers(ic) - .build()); + processBroadcast(tired.getIdentifiers(), tired.getTimestamp(), DecodeEventType.REQUEST, "TELEPHONE INTERCONNECT:" + tired.getTelephoneNumber()); } broadcast(new DecoderStateEvent(this, Event.DECODE, State.CONTROL)); @@ -1170,189 +1061,37 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList { //Channel Grant messages case OSP_GROUP_DATA_CHANNEL_GRANT: - if(tsbk instanceof GroupDataChannelGrant) - { - GroupDataChannelGrant gdcg = (GroupDataChannelGrant)tsbk; - - //Make a copy of current identifiers and remove current user identifiers and replace from message - MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifiers.remove(IdentifierClass.USER); - for(Identifier identifier : gdcg.getIdentifiers()) - { - identifiers.update(mPatchGroupManager.update(identifier)); - } - - processChannelGrant(gdcg.getChannel(), gdcg.getDataServiceOptions(), - identifiers, tsbk.getOpcode(), gdcg.getTimestamp()); - } + processTSBKDataChannelGrant(tsbk); break; case OSP_GROUP_VOICE_CHANNEL_GRANT: - if(tsbk instanceof GroupVoiceChannelGrant) - { - GroupVoiceChannelGrant gvcg = (GroupVoiceChannelGrant)tsbk; - - //Make a copy of current identifiers and remove current user identifiers and replace from message - MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifiers.remove(IdentifierClass.USER); - for(Identifier identifier : gvcg.getIdentifiers()) - { - identifiers.update(mPatchGroupManager.update(identifier)); - } - - processChannelGrant(gvcg.getChannel(), gvcg.getVoiceServiceOptions(), - identifiers, tsbk.getOpcode(), gvcg.getTimestamp()); - } + processTSBKGroupVoiceChannelGrant(tsbk); break; case OSP_GROUP_VOICE_CHANNEL_GRANT_UPDATE: - if(tsbk instanceof GroupVoiceChannelGrantUpdate) - { - GroupVoiceChannelGrantUpdate gvcgu = (GroupVoiceChannelGrantUpdate)tsbk; - - //Make a copy of current identifiers and remove current user identifiers and replace from message - MutableIdentifierCollection identifiersA = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifiersA.remove(IdentifierClass.USER); - identifiersA.update(mPatchGroupManager.update(gvcgu.getGroupAddressA())); - - processChannelGrant(gvcgu.getChannelA(), null, identifiersA, - tsbk.getOpcode(), gvcgu.getTimestamp()); - - if(gvcgu.hasGroupB()) - { - //Make a copy of current identifiers and remove current user identifiers and replace from message - MutableIdentifierCollection identifiersB = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifiersB.remove(IdentifierClass.USER); - identifiersB.update(mPatchGroupManager.update(gvcgu.getGroupAddressB())); - - processChannelGrant(gvcgu.getChannelB(), null, identifiersB, - tsbk.getOpcode(), gvcgu.getTimestamp()); - } - } + processTSBKGroupVoiceChannelGrantUpdate(tsbk); break; case OSP_GROUP_VOICE_CHANNEL_GRANT_UPDATE_EXPLICIT: - if(tsbk instanceof GroupVoiceChannelGrantUpdateExplicit) - { - GroupVoiceChannelGrantUpdateExplicit gvcgue = (GroupVoiceChannelGrantUpdateExplicit)tsbk; - - //Make a copy of current identifiers and remove current user identifiers and replace from message - MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifiers.remove(IdentifierClass.USER); - identifiers.update(mPatchGroupManager.update(gvcgue.getGroupAddress())); - - processChannelGrant(gvcgue.getChannel(), gvcgue.getVoiceServiceOptions(), - identifiers, tsbk.getOpcode(), gvcgue.getTimestamp()); - } + processTSBKGroupVoiceChannelGrantUpdateExplicit(tsbk); break; case OSP_UNIT_TO_UNIT_VOICE_CHANNEL_GRANT: - if(tsbk instanceof UnitToUnitVoiceChannelGrant) - { - UnitToUnitVoiceChannelGrant uuvcg = (UnitToUnitVoiceChannelGrant)tsbk; - - //Make a copy of current identifiers and remove current user identifiers and replace from message - MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifiers.remove(IdentifierClass.USER); - identifiers.update(uuvcg.getIdentifiers()); - - processChannelGrant(uuvcg.getChannel(), null, identifiers, - tsbk.getOpcode(), uuvcg.getTimestamp()); - } + processTSBKUnitToUnitVoiceChannelGrant(tsbk); break; case OSP_UNIT_TO_UNIT_VOICE_CHANNEL_GRANT_UPDATE: - if(tsbk instanceof UnitToUnitVoiceChannelGrantUpdate) - { - UnitToUnitVoiceChannelGrantUpdate uuvcgu = (UnitToUnitVoiceChannelGrantUpdate)tsbk; - - //Make a copy of current identifiers and remove current user identifiers and replace from message - MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifiers.remove(IdentifierClass.USER); - identifiers.update(uuvcgu.getIdentifiers()); - - processChannelGrant(uuvcgu.getChannel(), null, identifiers, - tsbk.getOpcode(), uuvcgu.getTimestamp()); - } + processTSBKUnitToUnitVoiceChannelGrantUpdate(tsbk); break; case OSP_TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT: - if(tsbk instanceof TelephoneInterconnectVoiceChannelGrant) - { - TelephoneInterconnectVoiceChannelGrant tivcg = (TelephoneInterconnectVoiceChannelGrant)tsbk; - - //Make a copy of current identifiers and remove current user identifiers and replace from message - MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifiers.remove(IdentifierClass.USER); - identifiers.update(tivcg.getIdentifiers()); - - processChannelGrant(tivcg.getChannel(), tivcg.getVoiceServiceOptions(), - identifiers, tsbk.getOpcode(), tivcg.getTimestamp()); - } + processTSBKTelephoneInterconnectVoiceChannelGrant(tsbk); break; case OSP_TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT_UPDATE: - if(tsbk instanceof TelephoneInterconnectVoiceChannelGrantUpdate) - { - TelephoneInterconnectVoiceChannelGrantUpdate tivcgu = (TelephoneInterconnectVoiceChannelGrantUpdate)tsbk; - - //Make a copy of current identifiers and remove current user identifiers and replace from message - MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifiers.remove(IdentifierClass.USER); - identifiers.update(tivcgu.getIdentifiers()); - - processChannelGrant(tivcgu.getChannel(), tivcgu.getVoiceServiceOptions(), - identifiers, tsbk.getOpcode(), tivcgu.getTimestamp()); - } + processTSBKTelephoneInterconnectVoiceChannelGrantUpdate(tsbk); break; case OSP_SNDCP_DATA_CHANNEL_GRANT: - if(tsbk instanceof SNDCPDataChannelGrant) - { - SNDCPDataChannelGrant dcg = (SNDCPDataChannelGrant)tsbk; - - //Make a copy of current identifiers and remove current user identifiers and replace from message - MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifiers.remove(IdentifierClass.USER); - identifiers.update(dcg.getIdentifiers()); - - processChannelGrant(dcg.getChannel(), dcg.getServiceOptions(), - identifiers, tsbk.getOpcode(), dcg.getTimestamp()); - } + processTSBKSndcpDataChannelGrant(tsbk); break; case MOTOROLA_OSP_PATCH_GROUP_CHANNEL_GRANT: - if(tsbk instanceof PatchGroupVoiceChannelGrant) - { - PatchGroupVoiceChannelGrant pgvcg = (PatchGroupVoiceChannelGrant)tsbk; - - //Make a copy of current identifiers and remove current user identifiers and replace from message - MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifiers.remove(IdentifierClass.USER); - for(Identifier identifier : pgvcg.getIdentifiers()) - { - identifiers.update(mPatchGroupManager.update(identifier)); - } - - processChannelGrant(pgvcg.getChannel(), pgvcg.getVoiceServiceOptions(), - identifiers, tsbk.getOpcode(), pgvcg.getTimestamp()); - } + processTSBKMotorolaOspPatchGroupChannelGrant(tsbk); break; case MOTOROLA_OSP_PATCH_GROUP_CHANNEL_GRANT_UPDATE: - if(tsbk instanceof PatchGroupVoiceChannelGrantUpdate) - { - PatchGroupVoiceChannelGrantUpdate pgvcgu = (PatchGroupVoiceChannelGrantUpdate)tsbk; - - //Make a copy of current identifiers and remove current user identifiers and replace from message - MutableIdentifierCollection identifiersPG1 = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifiersPG1.remove(IdentifierClass.USER); - identifiersPG1.update(mPatchGroupManager.update(pgvcgu.getPatchGroup1())); - - processChannelGrant(pgvcgu.getChannel1(), null, identifiersPG1, - tsbk.getOpcode(), pgvcgu.getTimestamp()); - - if(pgvcgu.hasPatchGroup2()) - { - //Make a copy of current identifiers and remove current user identifiers and replace from message - MutableIdentifierCollection identifiersPG2 = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - identifiersPG2.remove(IdentifierClass.USER); - identifiersPG2.update(mPatchGroupManager.update(pgvcgu.getPatchGroup2())); - - processChannelGrant(pgvcgu.getChannel2(), null, - identifiersPG2, tsbk.getOpcode(), pgvcgu.getTimestamp()); - } - } + processTSBKMotorolaOspPatchGroupChannelGrantUpdate(tsbk); break; //Network Configuration Messages @@ -1378,296 +1117,72 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList break; case OSP_UNIT_TO_UNIT_ANSWER_REQUEST: - MutableIdentifierCollection icUnitAnswerRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icUnitAnswerRequest.remove(IdentifierClass.USER); - icUnitAnswerRequest.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.PAGE.toString()) - .details("UNIT-TO-UNIT ANSWER REQUEST") - .identifiers(icUnitAnswerRequest) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.PAGE, "UNIT-TO-UNIT ANSWER REQUEST"); break; case OSP_TELEPHONE_INTERCONNECT_ANSWER_REQUEST: - if(tsbk instanceof TelephoneInterconnectAnswerRequest) - { - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - TelephoneInterconnectAnswerRequest tiar = (TelephoneInterconnectAnswerRequest)tsbk; - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.PAGE.toString()) - .details("TELEPHONE ANSWER REQUEST: " + tiar.getTelephoneNumber()) - .identifiers(ic) - .build()); - } + processTSBKTelephoneInterconnectAnswerRequest(tsbk); break; case OSP_SNDCP_DATA_PAGE_REQUEST: - MutableIdentifierCollection icDataPage = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icDataPage.remove(IdentifierClass.USER); - icDataPage.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.PAGE.toString()) - .details("SNDCP DATA PAGE REQUEST") - .identifiers(icDataPage) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.PAGE, "SNDCP DATA PAGE REQUEST"); break; case OSP_STATUS_UPDATE: - if(tsbk instanceof StatusUpdate) - { - StatusUpdate su = (StatusUpdate)tsbk; - - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.STATUS.toString()) - .details("UNIT:" + su.getUnitStatus() + " USER:" + su.getUserStatus()) - .identifiers(ic) - .build()); - } + processTSBKStatusUpdate(tsbk); break; case OSP_STATUS_QUERY: - MutableIdentifierCollection icStatusQuery = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icStatusQuery.remove(IdentifierClass.USER); - icStatusQuery.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.QUERY.toString()) - .details("STATUS") - .identifiers(icStatusQuery) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.QUERY, "STATUS"); break; case OSP_MESSAGE_UPDATE: if(tsbk instanceof MessageUpdate) { MessageUpdate mu = (MessageUpdate)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.SDM.toString()) - .details("MSG:" + mu.getShortDataMessage()) - .identifiers(ic) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.SDM, "MSG:" + mu.getShortDataMessage()); } break; case OSP_RADIO_UNIT_MONITOR_COMMAND: - MutableIdentifierCollection icUnitMonitor = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icUnitMonitor.remove(IdentifierClass.USER); - icUnitMonitor.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.COMMAND.toString()) - .details("RADIO UNIT MONITOR") - .identifiers(icUnitMonitor) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.COMMAND, "RADIO UNIT MONITOR"); break; case OSP_CALL_ALERT: - MutableIdentifierCollection icCallAlert = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icCallAlert.remove(IdentifierClass.USER); - icCallAlert.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.PAGE.toString()) - .details("CALL ALERT") - .identifiers(icCallAlert) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.PAGE, "CALL ALERT"); break; case OSP_ACKNOWLEDGE_RESPONSE: - if(tsbk instanceof AcknowledgeResponse) - { - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - AcknowledgeResponse ar = (AcknowledgeResponse)tsbk; - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("ACKNOWLEDGE " + ar.getAcknowledgedServiceType().getDescription()) - .identifiers(ic) - .build()); - } + processTSBKAcknowledgeResponse(tsbk); break; case OSP_QUEUED_RESPONSE: - if(tsbk instanceof QueuedResponse) - { - QueuedResponse qr = (QueuedResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("QUEUED: " + qr.getQueuedResponseServiceType().getDescription() + - " REASON: " + qr.getQueuedResponseReason() + - " INFO: " + qr.getAdditionalInfo()) - .identifiers(ic) - .build()); - } + processTSBKQueuedResponse(tsbk); break; case OSP_EXTENDED_FUNCTION_COMMAND: - if(tsbk instanceof ExtendedFunctionCommand) - { - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - ExtendedFunctionCommand efc = (ExtendedFunctionCommand)tsbk; - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.COMMAND.toString()) - .details("EXTENDED FUNCTION: " + efc.getExtendedFunction() + - " ARGUMENTS:" + efc.getArguments()) - .identifiers(ic) - .build()); - } + processTSBKExtendedFunctionCommand(tsbk); break; case OSP_DENY_RESPONSE: - if(tsbk instanceof DenyResponse) - { - DenyResponse dr = (DenyResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("DENY: " + dr.getDeniedServiceType().getDescription() + - " REASON: " + dr.getDenyReason() + " - INFO: " + dr.getAdditionalInfo()) - .identifiers(ic) - .build()); - } + processTSBKDenyResponse(tsbk); break; case OSP_GROUP_AFFILIATION_RESPONSE: - if(tsbk instanceof GroupAffiliationResponse) - { - GroupAffiliationResponse gar = (GroupAffiliationResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details(gar.getAffiliationResponse() + - " AFFILIATION GROUP: " + gar.getGroupAddress() + - (gar.isGlobalAffiliation() ? " (GLOBAL)" : " (LOCAL)") + - " ANNOUNCEMENT GROUP:" + gar.getAnnouncementGroupAddress()) - .identifiers(ic) - .build()); - } + processTSBKGroupAffiliationResponse(tsbk); break; case OSP_GROUP_AFFILIATION_QUERY: - MutableIdentifierCollection icGroupAffiliationQuery = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icGroupAffiliationQuery.remove(IdentifierClass.USER); - icGroupAffiliationQuery.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.QUERY.toString()) - .details("GROUP AFFILIATION") - .identifiers(icGroupAffiliationQuery) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.QUERY, "GROUP AFFILIATION"); break; case OSP_LOCATION_REGISTRATION_RESPONSE: - if(tsbk instanceof LocationRegistrationResponse) - { - LocationRegistrationResponse lrr = (LocationRegistrationResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REGISTER.toString()) - .details(lrr.getResponse() + " LOCATION REGISTRATION - GROUP:" + lrr.getGroupAddress()) - .identifiers(ic) - .build()); - } + processTSBKLocationRegistrationResponse(tsbk); break; case OSP_UNIT_REGISTRATION_RESPONSE: - if(tsbk instanceof UnitRegistrationResponse) - { - UnitRegistrationResponse urr = (UnitRegistrationResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REGISTER.toString()) - .details(urr.getResponse() + " UNIT REGISTRATION - UNIT ID:" + urr.getTargetUniqueId()) - .identifiers(ic) - .build()); - } + processTSBKUnitRegistrationResponse(tsbk); break; case OSP_UNIT_REGISTRATION_COMMAND: - MutableIdentifierCollection icUnitRegistration = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icUnitRegistration.remove(IdentifierClass.USER); - icUnitRegistration.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.COMMAND.toString()) - .details("UNIT REGISTRATION") - .identifiers(icUnitRegistration) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.COMMAND, "UNIT REGISTRATION"); break; case OSP_AUTHENTICATION_COMMAND: - MutableIdentifierCollection icAuthenticationCommand = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icAuthenticationCommand.remove(IdentifierClass.USER); - icAuthenticationCommand.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.COMMAND.toString()) - .details("AUTHENTICATE") - .identifiers(icAuthenticationCommand) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.COMMAND, "AUTHENTICATE"); break; case OSP_UNIT_DEREGISTRATION_ACKNOWLEDGE: - MutableIdentifierCollection icUnitDeregistration = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icUnitDeregistration.remove(IdentifierClass.USER); - icUnitDeregistration.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.DEREGISTER.toString()) - .details("ACKNOWLEDGE UNIT DE-REGISTRATION") - .identifiers(icUnitDeregistration) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.DEREGISTER, "ACKNOWLEDGE UNIT DE-REGISTRATION"); break; case OSP_ROAMING_ADDRESS_COMMAND: if(tsbk instanceof RoamingAddressCommand) { RoamingAddressCommand rac = (RoamingAddressCommand)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.COMMAND.toString()) - .details(rac.getStackOperation() + " ROAMING ADDRESS") - .identifiers(ic) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.COMMAND, rac.getStackOperation() + " ROAMING ADDRESS"); } break; @@ -1684,445 +1199,119 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList if(tsbk instanceof GroupVoiceServiceRequest) { GroupVoiceServiceRequest gvsr = (GroupVoiceServiceRequest)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("GROUP VOICE SERVICE " + gvsr.getVoiceServiceOptions()) - .identifiers(ic) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.REQUEST, "GROUP VOICE SERVICE " + gvsr.getVoiceServiceOptions()); } break; case ISP_UNIT_TO_UNIT_VOICE_SERVICE_REQUEST: if(tsbk instanceof UnitToUnitVoiceServiceRequest) { UnitToUnitVoiceServiceRequest uuvsr = (UnitToUnitVoiceServiceRequest)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("UNIT-2-UNIT VOICE SERVICE " + uuvsr.getVoiceServiceOptions()) - .identifiers(ic) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.REQUEST, "UNIT-2-UNIT VOICE SERVICE " + uuvsr.getVoiceServiceOptions()); } break; case ISP_UNIT_TO_UNIT_ANSWER_RESPONSE: - if(tsbk instanceof UnitToUnitVoiceServiceAnswerResponse) - { - UnitToUnitVoiceServiceAnswerResponse uuvsar = (UnitToUnitVoiceServiceAnswerResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details(uuvsar.getAnswerResponse() + " UNIT-2-UNIT VOICE SERVICE " + uuvsar.getVoiceServiceOptions()) - .identifiers(ic) - .build()); - } + processTSBKUnitToUnitAnswerResponse(tsbk); break; case ISP_TELEPHONE_INTERCONNECT_PSTN_REQUEST: - MutableIdentifierCollection icInterconnect = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icInterconnect.remove(IdentifierClass.USER); - icInterconnect.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("TELEPHONE INTERCONNECT") - .identifiers(icInterconnect) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.REQUEST, "TELEPHONE INTERCONNECT"); break; case ISP_TELEPHONE_INTERCONNECT_ANSWER_RESPONSE: - if(tsbk instanceof TelephoneInterconnectAnswerResponse) - { - TelephoneInterconnectAnswerResponse tiar = (TelephoneInterconnectAnswerResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details(tiar.getAnswerResponse() + " TELEPHONE INTERCONNECT " + tiar.getVoiceServiceOptions()) - .identifiers(ic) - .build()); - } + processTSBKTelephoneInterconnectAnswerResponse(tsbk); break; case ISP_INDIVIDUAL_DATA_SERVICE_REQUEST: if(tsbk instanceof IndividualDataServiceRequest) { IndividualDataServiceRequest idsr = (IndividualDataServiceRequest)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("INDIVIDUAL DATA SERVICE " + idsr.getVoiceServiceOptions()) - .identifiers(ic) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.REQUEST, "INDIVIDUAL DATA SERVICE " + idsr.getVoiceServiceOptions()); } break; case ISP_GROUP_DATA_SERVICE_REQUEST: if(tsbk instanceof GroupDataServiceRequest) { GroupDataServiceRequest gdsr = (GroupDataServiceRequest)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("GROUP DATA SERVICE " + gdsr.getVoiceServiceOptions()) - .identifiers(ic) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.REQUEST, "GROUP DATA SERVICE " + gdsr.getVoiceServiceOptions()); } break; case ISP_SNDCP_DATA_CHANNEL_REQUEST: if(tsbk instanceof SNDCPDataChannelRequest) { SNDCPDataChannelRequest sdcr = (SNDCPDataChannelRequest)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("SNDCP DATA CHANNEL " + sdcr.getDataServiceOptions()) - .identifiers(ic) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.REQUEST, "SNDCP DATA CHANNEL " + sdcr.getDataServiceOptions()); } break; case ISP_SNDCP_DATA_PAGE_RESPONSE: - if(tsbk instanceof SNDCPDataPageResponse) - { - SNDCPDataPageResponse sdpr = (SNDCPDataPageResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details(sdpr.getAnswerResponse() + " SNDCP DATA " + sdpr.getDataServiceOptions()) - .identifiers(ic) - .build()); - } + processTSBKSndcpDataPageResponse(tsbk); break; case ISP_SNDCP_RECONNECT_REQUEST: - if(tsbk instanceof SNDCPReconnectRequest) - { - SNDCPReconnectRequest srr = (SNDCPReconnectRequest)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("SNDCP RECONNECT " + (srr.hasDataToSend() ? "- DATA TO SEND " : "") - + srr.getDataServiceOptions()) - .identifiers(ic) - .build()); - } + processTSBKSndcpReconnectRequest(tsbk); break; case ISP_STATUS_UPDATE_REQUEST: - if(tsbk instanceof StatusUpdateRequest) - { - StatusUpdateRequest sur = (StatusUpdateRequest)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.STATUS.toString()) - .details("UNIT:" + sur.getUnitStatus() + " USER:" + sur.getUserStatus()) - .identifiers(ic) - .build()); - } + processTSBKStatusUpdateRequest(tsbk); break; case ISP_STATUS_QUERY_RESPONSE: - if(tsbk instanceof StatusQueryResponse) - { - StatusQueryResponse sqr = (StatusQueryResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.STATUS.toString()) - .details("UNIT:" + sqr.getUnitStatus() + " USER:" + sqr.getUserStatus()) - .identifiers(ic) - .build()); - } + processTSBKStatusQueryResponse(tsbk); break; case ISP_STATUS_QUERY_REQUEST: - MutableIdentifierCollection icStatusQueryRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icStatusQueryRequest.remove(IdentifierClass.USER); - icStatusQueryRequest.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.QUERY.toString()) - .details("UNIT AND USER STATUS") - .identifiers(icStatusQueryRequest) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.QUERY, "UNIT AND USER STATUS"); break; case ISP_MESSAGE_UPDATE_REQUEST: if(tsbk instanceof MessageUpdateRequest) { MessageUpdateRequest mur = (MessageUpdateRequest)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.SDM.toString()) - .details("MESSAGE:" + mur.getShortDataMessage()) - .identifiers(ic) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.SDM, "MESSAGE:" + mur.getShortDataMessage()); } break; case ISP_RADIO_UNIT_MONITOR_REQUEST: - MutableIdentifierCollection icUnitMonitorRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icUnitMonitorRequest.remove(IdentifierClass.USER); - icUnitMonitorRequest.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("RADIO UNIT MONITOR") - .identifiers(icUnitMonitorRequest) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.REQUEST, "RADIO UNIT MONITOR"); break; case ISP_CALL_ALERT_REQUEST: - MutableIdentifierCollection icCallAlertRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icCallAlertRequest.remove(IdentifierClass.USER); - icCallAlertRequest.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("CALL ALERT") - .identifiers(icCallAlertRequest) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.REQUEST, "CALL ALERT"); break; case ISP_UNIT_ACKNOWLEDGE_RESPONSE: if(tsbk instanceof UnitAcknowledgeResponse) { UnitAcknowledgeResponse uar = (UnitAcknowledgeResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("UNIT ACKNOWLEDGE:" + uar.getAcknowledgedServiceType().getDescription()) - .identifiers(ic) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.RESPONSE, "UNIT ACKNOWLEDGE:" + uar.getAcknowledgedServiceType().getDescription()); } break; case ISP_CANCEL_SERVICE_REQUEST: - if(tsbk instanceof CancelServiceRequest) - { - CancelServiceRequest csr = (CancelServiceRequest)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("CANCEL SERVICE:" + csr.getServiceType() + - " REASON:" + csr.getCancelReason() + (csr.hasAdditionalInformation() ? - " INFO:" + csr.getAdditionalInformation() : "")) - .identifiers(ic) - .build()); - } + processTSBKCancelServiceRequest(tsbk); break; case ISP_EXTENDED_FUNCTION_RESPONSE: - if(tsbk instanceof ExtendedFunctionResponse) - { - ExtendedFunctionResponse efr = (ExtendedFunctionResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("EXTENDED FUNCTION:" + efr.getExtendedFunction() + - " ARGUMENTS:" + efr.getArguments()) - .identifiers(ic) - .build()); - } + processTSBKExtendedFunctionResponse(tsbk); break; case ISP_EMERGENCY_ALARM_REQUEST: - MutableIdentifierCollection icAlarm = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icAlarm.remove(IdentifierClass.USER); - icAlarm.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("EMERGENCY ALARM") - .identifiers(icAlarm) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.REQUEST, "EMERGENCY ALARM"); break; case ISP_GROUP_AFFILIATION_REQUEST: - MutableIdentifierCollection icGroupAffiliationRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icGroupAffiliationRequest.remove(IdentifierClass.USER); - icGroupAffiliationRequest.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("GROUP AFFILIATION") - .identifiers(icGroupAffiliationRequest) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.REQUEST, "GROUP AFFILIATION"); break; case ISP_GROUP_AFFILIATION_QUERY_RESPONSE: - if(tsbk instanceof GroupAffiliationQueryResponse) - { - GroupAffiliationQueryResponse gaqr = (GroupAffiliationQueryResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("AFFILIATION - GROUP:" + gaqr.getGroupAddress() + - " ANNOUNCEMENT GROUP:" + gaqr.getAnnouncementGroupAddress()) - .identifiers(ic) - .build()); - } + processTSBKGroupAffiliationQueryResponse(tsbk); break; case ISP_UNIT_DE_REGISTRATION_REQUEST: - MutableIdentifierCollection icDeregistrationRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icDeregistrationRequest.remove(IdentifierClass.USER); - icDeregistrationRequest.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.DEREGISTER.toString()) - .details("UNIT DE-REGISTRATION REQUEST") - .identifiers(icDeregistrationRequest) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.DEREGISTER, "UNIT DE-REGISTRATION REQUEST"); break; case ISP_UNIT_REGISTRATION_REQUEST: - if(tsbk instanceof UnitRegistrationRequest) - { - UnitRegistrationRequest urr = (UnitRegistrationRequest)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REGISTER.toString()) - .details((urr.isEmergency() ? "EMERGENCY " : "") + - "UNIT REGISTRATION REQUEST - CAPABILITY:" + urr.getCapability()) - .identifiers(ic) - .build()); - } + processTSBKUnitRegistrationRequest(tsbk); break; case ISP_LOCATION_REGISTRATION_REQUEST: - if(tsbk instanceof LocationRegistrationRequest) - { - LocationRegistrationRequest lrr = (LocationRegistrationRequest)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REGISTER.toString()) - .details((lrr.isEmergency() ? "EMERGENCY " : "") + - "LOCATION REGISTRATION REQUEST - CAPABILITY:" + lrr.getCapability()) - .identifiers(ic) - .build()); - } + processTSBKLocationRegistrationRequest(tsbk); break; case ISP_PROTECTION_PARAMETER_REQUEST: - MutableIdentifierCollection icProtection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icProtection.remove(IdentifierClass.USER); - icProtection.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("ENCRYPTION PARAMETERS") - .identifiers(icProtection) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.REQUEST, "ENCRYPTION PARAMETERS"); break; case ISP_IDENTIFIER_UPDATE_REQUEST: - MutableIdentifierCollection icIdentifierUpdate = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icIdentifierUpdate.remove(IdentifierClass.USER); - icIdentifierUpdate.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("FREQUENCY BAND DETAILS") - .identifiers(icIdentifierUpdate) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.REQUEST, "FREQUENCY BAND DETAILS"); break; case ISP_ROAMING_ADDRESS_REQUEST: - MutableIdentifierCollection icRoamingRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icRoamingRequest.remove(IdentifierClass.USER); - icRoamingRequest.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("ROAMING ADDRESS") - .identifiers(new IdentifierCollection(tsbk.getIdentifiers())) - .build()); + processTSBKRoamingAddressRequest(tsbk); break; case ISP_ROAMING_ADDRESS_RESPONSE: - MutableIdentifierCollection icRoaming = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icRoaming.remove(IdentifierClass.USER); - icRoaming.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("ROAMING ADDRESS") - .identifiers(icRoaming) - .build()); + processBroadcast(tsbk.getIdentifiers(), tsbk.getTimestamp(), DecodeEventType.RESPONSE, "ROAMING ADDRESS"); break; case MOTOROLA_OSP_DENY_RESPONSE: - if(tsbk instanceof MotorolaDenyResponse) - { - MotorolaDenyResponse dr = (MotorolaDenyResponse)tsbk; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(tsbk.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("DENY: " + dr.getDeniedServiceType().getDescription() + - " REASON: " + dr.getDenyReason() + " - INFO: " + dr.getAdditionalInfo()) - .identifiers(ic) - .build()); - } + processTSBKMotorolaOspDenyResponse(tsbk); break; default: // mLog.debug("Unrecognized TSBK Opcode: " + tsbk.getOpcode().name() + " VENDOR:" + tsbk.getVendor() + @@ -2132,6 +1321,589 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList } } + private void processTSBKMotorolaOspDenyResponse(TSBKMessage tsbk) { + if(tsbk instanceof MotorolaDenyResponse) + { + MotorolaDenyResponse dr = (MotorolaDenyResponse)tsbk; + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(tsbk.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.RESPONSE.toString()) + .details("DENY: " + dr.getDeniedServiceType().getDescription() + + " REASON: " + dr.getDenyReason() + " - INFO: " + dr.getAdditionalInfo()) + .identifiers(ic) + .build()); + } + } + + private void processTSBKRoamingAddressRequest(TSBKMessage tsbk) { + MutableIdentifierCollection icRoamingRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + icRoamingRequest.remove(IdentifierClass.USER); + icRoamingRequest.update(tsbk.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.REQUEST.toString()) + .details("ROAMING ADDRESS") + .identifiers(new IdentifierCollection(tsbk.getIdentifiers())) + .build()); + return; + } + + private void processTSBKLocationRegistrationRequest(TSBKMessage tsbk) { + if(tsbk instanceof LocationRegistrationRequest) + { + LocationRegistrationRequest lrr = (LocationRegistrationRequest)tsbk; + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(tsbk.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.REGISTER.toString()) + .details((lrr.isEmergency() ? "EMERGENCY " : "") + + "LOCATION REGISTRATION REQUEST - CAPABILITY:" + lrr.getCapability()) + .identifiers(ic) + .build()); + } + } + + private void processTSBKUnitRegistrationRequest(TSBKMessage tsbk) { + if(tsbk instanceof UnitRegistrationRequest) + { + UnitRegistrationRequest urr = (UnitRegistrationRequest)tsbk; + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(tsbk.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.REGISTER.toString()) + .details((urr.isEmergency() ? "EMERGENCY " : "") + + "UNIT REGISTRATION REQUEST - CAPABILITY:" + urr.getCapability()) + .identifiers(ic) + .build()); + } + } + + private void processTSBKGroupAffiliationQueryResponse(TSBKMessage tsbk) { + if(tsbk instanceof GroupAffiliationQueryResponse) + { + GroupAffiliationQueryResponse gaqr = (GroupAffiliationQueryResponse)tsbk; + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(tsbk.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.RESPONSE.toString()) + .details("AFFILIATION - GROUP:" + gaqr.getGroupAddress() + + " ANNOUNCEMENT GROUP:" + gaqr.getAnnouncementGroupAddress()) + .identifiers(ic) + .build()); + } + } + + private void processTSBKExtendedFunctionResponse(TSBKMessage tsbk) { + if(tsbk instanceof ExtendedFunctionResponse) + { + ExtendedFunctionResponse efr = (ExtendedFunctionResponse)tsbk; + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(tsbk.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.RESPONSE.toString()) + .details("EXTENDED FUNCTION:" + efr.getExtendedFunction() + + " ARGUMENTS:" + efr.getArguments()) + .identifiers(ic) + .build()); + } + } + + private void processTSBKCancelServiceRequest(TSBKMessage tsbk) { + if(tsbk instanceof CancelServiceRequest) + { + CancelServiceRequest csr = (CancelServiceRequest)tsbk; + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(tsbk.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.REQUEST.toString()) + .details("CANCEL SERVICE:" + csr.getServiceType() + + " REASON:" + csr.getCancelReason() + (csr.hasAdditionalInformation() ? + " INFO:" + csr.getAdditionalInformation() : "")) + .identifiers(ic) + .build()); + } + } + + private void processTSBKStatusQueryResponse(TSBKMessage tsbk) { + if(tsbk instanceof StatusQueryResponse) + { + StatusQueryResponse sqr = (StatusQueryResponse)tsbk; + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(tsbk.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.STATUS.toString()) + .details("UNIT:" + sqr.getUnitStatus() + " USER:" + sqr.getUserStatus()) + .identifiers(ic) + .build()); + } + } + + private void processTSBKStatusUpdateRequest(TSBKMessage tsbk) { + if(tsbk instanceof StatusUpdateRequest) + { + StatusUpdateRequest sur = (StatusUpdateRequest)tsbk; + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(tsbk.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.STATUS.toString()) + .details("UNIT:" + sur.getUnitStatus() + " USER:" + sur.getUserStatus()) + .identifiers(ic) + .build()); + } + } + + private void processTSBKSndcpReconnectRequest(TSBKMessage tsbk) { + if(tsbk instanceof SNDCPReconnectRequest) + { + SNDCPReconnectRequest srr = (SNDCPReconnectRequest)tsbk; + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(tsbk.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.REQUEST.toString()) + .details("SNDCP RECONNECT " + (srr.hasDataToSend() ? "- DATA TO SEND " : "") + + srr.getDataServiceOptions()) + .identifiers(ic) + .build()); + } + } + + private void processTSBKSndcpDataPageResponse(TSBKMessage tsbk) { + if(tsbk instanceof SNDCPDataPageResponse) + { + SNDCPDataPageResponse sdpr = (SNDCPDataPageResponse)tsbk; + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(tsbk.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.RESPONSE.toString()) + .details(sdpr.getAnswerResponse() + " SNDCP DATA " + sdpr.getDataServiceOptions()) + .identifiers(ic) + .build()); + } + } + + private void processTSBKTelephoneInterconnectAnswerResponse(TSBKMessage tsbk) { + if(tsbk instanceof TelephoneInterconnectAnswerResponse) + { + TelephoneInterconnectAnswerResponse tiar = (TelephoneInterconnectAnswerResponse)tsbk; + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(tsbk.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.RESPONSE.toString()) + .details(tiar.getAnswerResponse() + " TELEPHONE INTERCONNECT " + tiar.getVoiceServiceOptions()) + .identifiers(ic) + .build()); + } + } + + private void processTSBKUnitToUnitAnswerResponse(TSBKMessage tsbk) { + if(tsbk instanceof UnitToUnitVoiceServiceAnswerResponse) + { + UnitToUnitVoiceServiceAnswerResponse uuvsar = (UnitToUnitVoiceServiceAnswerResponse)tsbk; + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(tsbk.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.RESPONSE.toString()) + .details(uuvsar.getAnswerResponse() + " UNIT-2-UNIT VOICE SERVICE " + uuvsar.getVoiceServiceOptions()) + .identifiers(ic) + .build()); + } + } + + private void processTSBKUnitRegistrationResponse(TSBKMessage tsbk) { + if(tsbk instanceof UnitRegistrationResponse) + { + UnitRegistrationResponse urr = (UnitRegistrationResponse)tsbk; + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(tsbk.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.REGISTER.toString()) + .details(urr.getResponse() + " UNIT REGISTRATION - UNIT ID:" + urr.getTargetUniqueId()) + .identifiers(ic) + .build()); + } + } + + private void processTSBKLocationRegistrationResponse(TSBKMessage tsbk) { + if(tsbk instanceof LocationRegistrationResponse) + { + LocationRegistrationResponse lrr = (LocationRegistrationResponse)tsbk; + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(tsbk.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.REGISTER.toString()) + .details(lrr.getResponse() + " LOCATION REGISTRATION - GROUP:" + lrr.getGroupAddress()) + .identifiers(ic) + .build()); + } + } + + private void processTSBKGroupAffiliationResponse(TSBKMessage tsbk) { + if(tsbk instanceof GroupAffiliationResponse) + { + GroupAffiliationResponse gar = (GroupAffiliationResponse)tsbk; + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(tsbk.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.RESPONSE.toString()) + .details(gar.getAffiliationResponse() + + " AFFILIATION GROUP: " + gar.getGroupAddress() + + (gar.isGlobalAffiliation() ? " (GLOBAL)" : " (LOCAL)") + + " ANNOUNCEMENT GROUP:" + gar.getAnnouncementGroupAddress()) + .identifiers(ic) + .build()); + } + } + + private void processTSBKDenyResponse(TSBKMessage tsbk) { + if(tsbk instanceof DenyResponse) + { + DenyResponse dr = (DenyResponse)tsbk; + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(tsbk.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.RESPONSE.toString()) + .details("DENY: " + dr.getDeniedServiceType().getDescription() + + " REASON: " + dr.getDenyReason() + " - INFO: " + dr.getAdditionalInfo()) + .identifiers(ic) + .build()); + } + } + + private void processTSBKExtendedFunctionCommand(TSBKMessage tsbk) { + if(tsbk instanceof ExtendedFunctionCommand) + { + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(tsbk.getIdentifiers()); + + ExtendedFunctionCommand efc = (ExtendedFunctionCommand)tsbk; + broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.COMMAND.toString()) + .details("EXTENDED FUNCTION: " + efc.getExtendedFunction() + + " ARGUMENTS:" + efc.getArguments()) + .identifiers(ic) + .build()); + } + } + + private void processTSBKQueuedResponse(TSBKMessage tsbk) { + if(tsbk instanceof QueuedResponse) + { + QueuedResponse qr = (QueuedResponse)tsbk; + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(tsbk.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.RESPONSE.toString()) + .details("QUEUED: " + qr.getQueuedResponseServiceType().getDescription() + + " REASON: " + qr.getQueuedResponseReason() + + " INFO: " + qr.getAdditionalInfo()) + .identifiers(ic) + .build()); + } + } + + private void processTSBKAcknowledgeResponse(TSBKMessage tsbk) { + if(tsbk instanceof AcknowledgeResponse) + { + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(tsbk.getIdentifiers()); + + AcknowledgeResponse ar = (AcknowledgeResponse)tsbk; + broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.RESPONSE.toString()) + .details("ACKNOWLEDGE " + ar.getAcknowledgedServiceType().getDescription()) + .identifiers(ic) + .build()); + } + } + + private void processTSBKStatusUpdate(TSBKMessage tsbk) { + if(tsbk instanceof StatusUpdate) + { + StatusUpdate su = (StatusUpdate)tsbk; + + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(tsbk.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.STATUS.toString()) + .details("UNIT:" + su.getUnitStatus() + " USER:" + su.getUserStatus()) + .identifiers(ic) + .build()); + } + } + + private void processTSBKTelephoneInterconnectAnswerRequest(TSBKMessage tsbk) { + if(tsbk instanceof TelephoneInterconnectAnswerRequest) + { + MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + ic.remove(IdentifierClass.USER); + ic.update(tsbk.getIdentifiers()); + + TelephoneInterconnectAnswerRequest tiar = (TelephoneInterconnectAnswerRequest)tsbk; + broadcast(P25DecodeEvent.builder(tsbk.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.PAGE.toString()) + .details("TELEPHONE ANSWER REQUEST: " + tiar.getTelephoneNumber()) + .identifiers(ic) + .build()); + } + } + + private void processTSBKMotorolaOspPatchGroupChannelGrantUpdate(TSBKMessage tsbk) { + if(tsbk instanceof PatchGroupVoiceChannelGrantUpdate) + { + PatchGroupVoiceChannelGrantUpdate pgvcgu = (PatchGroupVoiceChannelGrantUpdate)tsbk; + + //Make a copy of current identifiers and remove current user identifiers and replace from message + MutableIdentifierCollection identifiersPG1 = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + identifiersPG1.remove(IdentifierClass.USER); + identifiersPG1.update(mPatchGroupManager.update(pgvcgu.getPatchGroup1())); + + processChannelGrant(pgvcgu.getChannel1(), null, identifiersPG1, + tsbk.getOpcode(), pgvcgu.getTimestamp()); + + if(pgvcgu.hasPatchGroup2()) + { + //Make a copy of current identifiers and remove current user identifiers and replace from message + MutableIdentifierCollection identifiersPG2 = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + identifiersPG2.remove(IdentifierClass.USER); + identifiersPG2.update(mPatchGroupManager.update(pgvcgu.getPatchGroup2())); + + processChannelGrant(pgvcgu.getChannel2(), null, + identifiersPG2, tsbk.getOpcode(), pgvcgu.getTimestamp()); + } + } + } + + private void processTSBKMotorolaOspPatchGroupChannelGrant(TSBKMessage tsbk) { + if(tsbk instanceof PatchGroupVoiceChannelGrant) + { + PatchGroupVoiceChannelGrant pgvcg = (PatchGroupVoiceChannelGrant)tsbk; + + //Make a copy of current identifiers and remove current user identifiers and replace from message + MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + identifiers.remove(IdentifierClass.USER); + for(Identifier identifier : pgvcg.getIdentifiers()) + { + identifiers.update(mPatchGroupManager.update(identifier)); + } + + processChannelGrant(pgvcg.getChannel(), pgvcg.getVoiceServiceOptions(), + identifiers, tsbk.getOpcode(), pgvcg.getTimestamp()); + } + } + + private void processTSBKTelephoneInterconnectVoiceChannelGrantUpdate(TSBKMessage tsbk) { + if(tsbk instanceof TelephoneInterconnectVoiceChannelGrantUpdate) + { + TelephoneInterconnectVoiceChannelGrantUpdate tivcgu = (TelephoneInterconnectVoiceChannelGrantUpdate)tsbk; + + //Make a copy of current identifiers and remove current user identifiers and replace from message + MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + identifiers.remove(IdentifierClass.USER); + identifiers.update(tivcgu.getIdentifiers()); + + processChannelGrant(tivcgu.getChannel(), tivcgu.getVoiceServiceOptions(), + identifiers, tsbk.getOpcode(), tivcgu.getTimestamp()); + } + } + + private void processTSBKSndcpDataChannelGrant(TSBKMessage tsbk) { + if(tsbk instanceof SNDCPDataChannelGrant) + { + SNDCPDataChannelGrant dcg = (SNDCPDataChannelGrant)tsbk; + + //Make a copy of current identifiers and remove current user identifiers and replace from message + MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + identifiers.remove(IdentifierClass.USER); + identifiers.update(dcg.getIdentifiers()); + + processChannelGrant(dcg.getChannel(), dcg.getServiceOptions(), + identifiers, tsbk.getOpcode(), dcg.getTimestamp()); + } + } + + private void processTSBKTelephoneInterconnectVoiceChannelGrant(TSBKMessage tsbk) { + if(tsbk instanceof TelephoneInterconnectVoiceChannelGrant) + { + TelephoneInterconnectVoiceChannelGrant tivcg = (TelephoneInterconnectVoiceChannelGrant)tsbk; + + //Make a copy of current identifiers and remove current user identifiers and replace from message + MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + identifiers.remove(IdentifierClass.USER); + identifiers.update(tivcg.getIdentifiers()); + + processChannelGrant(tivcg.getChannel(), tivcg.getVoiceServiceOptions(), + identifiers, tsbk.getOpcode(), tivcg.getTimestamp()); + } + } + + private void processTSBKUnitToUnitVoiceChannelGrantUpdate(TSBKMessage tsbk) { + if(tsbk instanceof UnitToUnitVoiceChannelGrantUpdate) + { + UnitToUnitVoiceChannelGrantUpdate uuvcgu = (UnitToUnitVoiceChannelGrantUpdate)tsbk; + + //Make a copy of current identifiers and remove current user identifiers and replace from message + MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + identifiers.remove(IdentifierClass.USER); + identifiers.update(uuvcgu.getIdentifiers()); + + processChannelGrant(uuvcgu.getChannel(), null, identifiers, + tsbk.getOpcode(), uuvcgu.getTimestamp()); + } + } + + private void processTSBKUnitToUnitVoiceChannelGrant(TSBKMessage tsbk) { + if(tsbk instanceof UnitToUnitVoiceChannelGrant) + { + UnitToUnitVoiceChannelGrant uuvcg = (UnitToUnitVoiceChannelGrant)tsbk; + + //Make a copy of current identifiers and remove current user identifiers and replace from message + MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + identifiers.remove(IdentifierClass.USER); + identifiers.update(uuvcg.getIdentifiers()); + + processChannelGrant(uuvcg.getChannel(), null, identifiers, + tsbk.getOpcode(), uuvcg.getTimestamp()); + } + } + + private void processTSBKGroupVoiceChannelGrantUpdateExplicit(TSBKMessage tsbk) { + if(tsbk instanceof GroupVoiceChannelGrantUpdateExplicit) + { + GroupVoiceChannelGrantUpdateExplicit gvcgue = (GroupVoiceChannelGrantUpdateExplicit)tsbk; + + //Make a copy of current identifiers and remove current user identifiers and replace from message + MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + identifiers.remove(IdentifierClass.USER); + identifiers.update(mPatchGroupManager.update(gvcgue.getGroupAddress())); + + processChannelGrant(gvcgue.getChannel(), gvcgue.getVoiceServiceOptions(), + identifiers, tsbk.getOpcode(), gvcgue.getTimestamp()); + } + } + + private void processTSBKGroupVoiceChannelGrantUpdate(TSBKMessage tsbk) { + if(tsbk instanceof GroupVoiceChannelGrantUpdate) + { + GroupVoiceChannelGrantUpdate gvcgu = (GroupVoiceChannelGrantUpdate)tsbk; + + //Make a copy of current identifiers and remove current user identifiers and replace from message + MutableIdentifierCollection identifiersA = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + identifiersA.remove(IdentifierClass.USER); + identifiersA.update(mPatchGroupManager.update(gvcgu.getGroupAddressA())); + + processChannelGrant(gvcgu.getChannelA(), null, identifiersA, + tsbk.getOpcode(), gvcgu.getTimestamp()); + + if(gvcgu.hasGroupB()) + { + //Make a copy of current identifiers and remove current user identifiers and replace from message + MutableIdentifierCollection identifiersB = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + identifiersB.remove(IdentifierClass.USER); + identifiersB.update(mPatchGroupManager.update(gvcgu.getGroupAddressB())); + + processChannelGrant(gvcgu.getChannelB(), null, identifiersB, + tsbk.getOpcode(), gvcgu.getTimestamp()); + } + } + } + + private void processTSBKGroupVoiceChannelGrant(TSBKMessage tsbk) { + if(tsbk instanceof GroupVoiceChannelGrant) + { + GroupVoiceChannelGrant gvcg = (GroupVoiceChannelGrant)tsbk; + + //Make a copy of current identifiers and remove current user identifiers and replace from message + MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + identifiers.remove(IdentifierClass.USER); + for(Identifier identifier : gvcg.getIdentifiers()) + { + identifiers.update(mPatchGroupManager.update(identifier)); + } + + processChannelGrant(gvcg.getChannel(), gvcg.getVoiceServiceOptions(), + identifiers, tsbk.getOpcode(), gvcg.getTimestamp()); + } + } + + private void processTSBKDataChannelGrant(TSBKMessage tsbk) { + if(tsbk instanceof GroupDataChannelGrant) + { + GroupDataChannelGrant gdcg = (GroupDataChannelGrant)tsbk; + + //Make a copy of current identifiers and remove current user identifiers and replace from message + MutableIdentifierCollection identifiers = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + identifiers.remove(IdentifierClass.USER); + for(Identifier identifier : gdcg.getIdentifiers()) + { + identifiers.update(mPatchGroupManager.update(identifier)); + } + + processChannelGrant(gdcg.getChannel(), gdcg.getDataServiceOptions(), + identifiers, tsbk.getOpcode(), gdcg.getTimestamp()); + } + } + /** * Processes encryption sync parameters carried by an LDU2 message * @@ -2219,16 +1991,7 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList //Other events case CALL_ALERT: - MutableIdentifierCollection icCallAlert = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icCallAlert.remove(IdentifierClass.USER); - icCallAlert.update(lcw.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(timestamp) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.PAGE.toString()) - .details("Call Alert") - .identifiers(icCallAlert) - .build()); + processBroadcast(lcw.getIdentifiers(), timestamp, DecodeEventType.PAGE, "Call Alert"); break; case EXTENDED_FUNCTION_COMMAND: if(lcw instanceof LCExtendedFunctionCommand) @@ -2249,16 +2012,7 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList } break; case GROUP_AFFILIATION_QUERY: - MutableIdentifierCollection icGroupAffiliation = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icGroupAffiliation.remove(IdentifierClass.USER); - icGroupAffiliation.update(lcw.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(timestamp) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.QUERY.toString()) - .details("Group Affiliation") - .identifiers(icGroupAffiliation) - .build()); + processBroadcast(lcw.getIdentifiers(), timestamp, DecodeEventType.QUERY, "Group Affiliation"); break; case MESSAGE_UPDATE: if(lcw instanceof LCMessageUpdate) @@ -2277,16 +2031,7 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList } break; case STATUS_QUERY: - MutableIdentifierCollection icStatusQuery = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icStatusQuery.remove(IdentifierClass.USER); - icStatusQuery.update(lcw.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(timestamp) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.QUERY.toString()) - .details("Status") - .identifiers(icStatusQuery) - .build()); + processBroadcast(lcw.getIdentifiers(), timestamp, DecodeEventType.QUERY, "Status"); break; case STATUS_UPDATE: if(lcw instanceof LCStatusUpdate) @@ -2310,53 +2055,17 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList { LCTelephoneInterconnectAnswerRequest tiar = (LCTelephoneInterconnectAnswerRequest)lcw; - MutableIdentifierCollection ic = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - ic.remove(IdentifierClass.USER); - ic.update(lcw.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(timestamp) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.PAGE.toString()) - .details("Telephone Call:" + tiar.getTelephoneNumber()) - .identifiers(ic) - .build()); + processBroadcast(lcw.getIdentifiers(), timestamp, DecodeEventType.PAGE, "Telephone Call:" + tiar.getTelephoneNumber()); } break; case UNIT_AUTHENTICATION_COMMAND: - MutableIdentifierCollection icAuthenticationCommand = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icAuthenticationCommand.remove(IdentifierClass.USER); - icAuthenticationCommand.update(lcw.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(timestamp) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.COMMAND.toString()) - .details("Authenticate Unit") - .identifiers(icAuthenticationCommand) - .build()); + processBroadcast(lcw.getIdentifiers(), timestamp, DecodeEventType.COMMAND, "Authenticate Unit"); break; case UNIT_REGISTRATION_COMMAND: - MutableIdentifierCollection icUnitRegistrationCommand = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icUnitRegistrationCommand.remove(IdentifierClass.USER); - icUnitRegistrationCommand.update(lcw.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(timestamp) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.COMMAND.toString()) - .details("Unit Registration") - .identifiers(icUnitRegistrationCommand) - .build()); + processBroadcast(lcw.getIdentifiers(), timestamp, DecodeEventType.COMMAND, "Unit Registration"); break; case UNIT_TO_UNIT_ANSWER_REQUEST: - MutableIdentifierCollection icUnitAnswerRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icUnitAnswerRequest.remove(IdentifierClass.USER); - icUnitAnswerRequest.update(lcw.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(timestamp) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.PAGE.toString()) - .details("Unit-to-Unit Answer Request") - .identifiers(icUnitAnswerRequest) - .build()); + processBroadcast(lcw.getIdentifiers(), timestamp, DecodeEventType.PAGE, "Unit-to-Unit Answer Request"); break; default: // mLog.debug("Unrecognized LCW Opcode: " + lcw.getOpcode().name() + " VENDOR:" + lcw.getVendor() + diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1NetworkConfigurationMonitor.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1NetworkConfigurationMonitor.java index 50868c7d..6515b9a5 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1NetworkConfigurationMonitor.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1NetworkConfigurationMonitor.java @@ -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 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 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 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(); diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1SyncDetector.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1SyncDetector.java index db95ed74..b1b26301 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1SyncDetector.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/P25P1SyncDetector.java @@ -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 { @@ -163,7 +164,7 @@ public class P25P1SyncDetector implements Listener public void setSampleRate(double sampleRate) { mSampleRate = sampleRate; - mPllCorrection = 2.0 * Math.PI * mFrequencyCorrection / mSampleRate; + mPllCorrection = 2.0 * FastMath.PI * mFrequencyCorrection / mSampleRate; } } } diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/filter/PDUMessageFilter.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/filter/PDUMessageFilter.java index 67bb287c..1f447070 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/filter/PDUMessageFilter.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/filter/PDUMessageFilter.java @@ -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 { - private Map> mOpcodeFilterElements = new HashMap>(); + private Map> mOpcodeFilterElements = new EnumMap<>(Opcode.class); public PDUMessageFilter() { diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/filter/TSBKMessageFilterSet.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/filter/TSBKMessageFilterSet.java index 132a4014..2efe15ce 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/filter/TSBKMessageFilterSet.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/filter/TSBKMessageFilterSet.java @@ -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 { @@ -69,8 +67,7 @@ public class TSBKMessageFilterSet extends FilterSet public class StandardOpcodeFilter extends Filter { - private HashMap> mStandardElements = - new HashMap>(); + private Map> mStandardElements = new EnumMap<>(Opcode.class); public StandardOpcodeFilter() { diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/hdu/HDUMessage.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/hdu/HDUMessage.java index 8043950b..889b1ccc 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/hdu/HDUMessage.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/hdu/HDUMessage.java @@ -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 diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/hdu/HeaderData.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/hdu/HeaderData.java index 167f0c47..67f6fdbc 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/hdu/HeaderData.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/hdu/HeaderData.java @@ -70,7 +70,7 @@ public class HeaderData if(isValid()) { - sb.append("TALKGROUP:" + getTalkgroup()); + sb.append("TALKGROUP:").append(getTalkgroup()); Vendor vendor = getVendor(); diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCAdjacentSiteStatusBroadcast.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCAdjacentSiteStatusBroadcast.java index eaa92b16..b856f68b 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCAdjacentSiteStatusBroadcast.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCAdjacentSiteStatusBroadcast.java @@ -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(); } diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCAdjacentSiteStatusBroadcastExplicit.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCAdjacentSiteStatusBroadcastExplicit.java index 86623c11..186081e2 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCAdjacentSiteStatusBroadcastExplicit.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCAdjacentSiteStatusBroadcastExplicit.java @@ -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(); } diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCNetworkStatusBroadcast.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCNetworkStatusBroadcast.java index 03415a40..e11051d4 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCNetworkStatusBroadcast.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCNetworkStatusBroadcast.java @@ -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(); } diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCNetworkStatusBroadcastExplicit.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCNetworkStatusBroadcastExplicit.java index 6bdd2246..d94992f0 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCNetworkStatusBroadcastExplicit.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCNetworkStatusBroadcastExplicit.java @@ -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(); } diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCRFSSStatusBroadcast.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCRFSSStatusBroadcast.java index 8c58c9b3..44620080 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCRFSSStatusBroadcast.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCRFSSStatusBroadcast.java @@ -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(); } diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCRFSSStatusBroadcastExplicit.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCRFSSStatusBroadcastExplicit.java index a818e007..8e37b0b2 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCRFSSStatusBroadcastExplicit.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCRFSSStatusBroadcastExplicit.java @@ -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(); } diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCSecondaryControlChannelBroadcast.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCSecondaryControlChannelBroadcast.java index 24a72010..76240daa 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCSecondaryControlChannelBroadcast.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCSecondaryControlChannelBroadcast.java @@ -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(); } diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCSecondaryControlChannelBroadcastExplicit.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCSecondaryControlChannelBroadcastExplicit.java index 9bfe29f8..d8536f04 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCSecondaryControlChannelBroadcastExplicit.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/standard/LCSecondaryControlChannelBroadcastExplicit.java @@ -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(); } diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/ldu/LDU1Message.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/ldu/LDU1Message.java index b9efcdf6..5ebaf524 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/ldu/LDU1Message.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/ldu/LDU1Message.java @@ -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 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 diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/ldu/LDU2Message.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/ldu/LDU2Message.java index 4a5ef493..311d0c60 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/ldu/LDU2Message.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/ldu/LDU2Message.java @@ -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 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); diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/pdu/PDUHeader.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/pdu/PDUHeader.java index 675a57d5..7b7a4cce 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/pdu/PDUHeader.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/pdu/PDUHeader.java @@ -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(); diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/pdu/PDUMessage.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/pdu/PDUMessage.java index 9954ec0f..83416948 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/pdu/PDUMessage.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/pdu/PDUMessage.java @@ -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: } diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/tdu/TDULinkControlMessage.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/tdu/TDULinkControlMessage.java index b19bd41c..efcf04d6 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/tdu/TDULinkControlMessage.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/tdu/TDULinkControlMessage.java @@ -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 diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/tsbk/motorola/osp/MotorolaBaseStationId.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/tsbk/motorola/osp/MotorolaBaseStationId.java index fee7f988..cd288aec 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/tsbk/motorola/osp/MotorolaBaseStationId.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/tsbk/motorola/osp/MotorolaBaseStationId.java @@ -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 { diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/tsbk/standard/osp/FrequencyBandUpdateTDMA.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/tsbk/standard/osp/FrequencyBandUpdateTDMA.java index 01cc6df2..4703e477 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/tsbk/standard/osp/FrequencyBandUpdateTDMA.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/tsbk/standard/osp/FrequencyBandUpdateTDMA.java @@ -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 diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/tsbk/standard/osp/SyncBroadcast.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/tsbk/standard/osp/SyncBroadcast.java index d7184741..44959758 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/tsbk/standard/osp/SyncBroadcast.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/tsbk/standard/osp/SyncBroadcast.java @@ -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"); diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase2/DibitDelayBuffer.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase2/DibitDelayBuffer.java index 29c89fb6..00db784b 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase2/DibitDelayBuffer.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase2/DibitDelayBuffer.java @@ -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) diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase2/P25P2DecoderState.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase2/P25P2DecoderState.java index 658ade5b..d3b4acbe 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase2/P25P2DecoderState.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase2/P25P2DecoderState.java @@ -21,6 +21,7 @@ */ package io.github.dsheirer.module.decode.p25.phase2; +import io.github.dsheirer.channel.IChannelDescriptor; import io.github.dsheirer.channel.state.ChangeChannelTimeoutEvent; import io.github.dsheirer.channel.state.DecoderStateEvent; import io.github.dsheirer.channel.state.DecoderStateEvent.Event; @@ -236,90 +237,10 @@ public class P25P2DecoderState extends TimeslotDecoderState implements Identifie switch((mac.getOpcode())) { case PUSH_TO_TALK: - for(Identifier identifier : mac.getIdentifiers()) - { - //Add to the identifier collection after filtering through the patch group manager - getIdentifierCollection().update(mPatchGroupManager.update(identifier)); - } - - PushToTalk ptt = (PushToTalk)mac; - - if(ptt.isEncrypted()) - { - updateCurrentCall(DecodeEventType.CALL_ENCRYPTED, ptt.getEncryptionKey().toString(), message.getTimestamp()); - } - else - { - updateCurrentCall(DecodeEventType.CALL, null, message.getTimestamp()); - } + processPushToTalk(message, mac); break; case END_PUSH_TO_TALK: - if(mac instanceof EndPushToTalk) - { - //Add the set of identifiers before we close out the call event to ensure they're captured in - //the closing event. - if(mCurrentCallEvent != null) - { - for(Identifier identifier : mac.getIdentifiers()) - { - if(identifier.getRole() == Role.FROM) - { - if(identifier instanceof APCO25RadioIdentifier) - { - int value = ((APCO25RadioIdentifier)identifier).getValue(); - - //Group call End PTT uses a FROM value of 0xFFFFFF - don't overwrite the correct id - if(value != SYSTEM_CONTROLLER) - { - getIdentifierCollection().update(mPatchGroupManager.update(identifier)); - } - } - } - else if(identifier.getRole() == Role.TO) - { - if(identifier instanceof APCO25Talkgroup) - { - int value = ((APCO25Talkgroup)identifier).getValue(); - - //Individual call End PTT uses a TO value of 0 - don't overwrite the correct id - if(value != 0) - { - getIdentifierCollection().update(mPatchGroupManager.update(identifier)); - } - } - } - else - { - getIdentifierCollection().update(mPatchGroupManager.update(identifier)); - } - } - } - - if(message.getDataUnitID().isFACCH()) - { - mEndPttOnFacchCounter++; - - //FNE sending 2 or more End PTT in FACCH timeslots indicates a channel teardown event. - if(mEndPttOnFacchCounter > 1) - { - if(mChannelType == ChannelType.TRAFFIC) - { - closeCurrentCallEvent(message.getTimestamp(), true, MacPduType.MAC_2_END_PTT); - //Don't send a continue state here ... the close() method will send the TEARDOWN state - } - //Otherwise the channel state is set to ACTIVE in anticipation of further call activity - else - { - closeCurrentCallEvent(message.getTimestamp(), true, MacPduType.MAC_4_ACTIVE); - continueState(State.RESET); - } - } - } - else - { - closeCurrentCallEvent(message.getTimestamp(), true, MacPduType.MAC_4_ACTIVE); - } - } + processEndPushToTalk(message, mac); break; case TDMA_0_NULL_INFORMATION_MESSAGE: MacPduType type = message.getMacPduType(); @@ -330,743 +251,176 @@ public class P25P2DecoderState extends TimeslotDecoderState implements Identifie } break; case TDMA_1_GROUP_VOICE_CHANNEL_USER_ABBREVIATED: - if(message.getMacPduType() == MacPduType.MAC_6_HANGTIME) - { - closeCurrentCallEvent(message.getTimestamp(), false, MacPduType.MAC_6_HANGTIME); - - for(Identifier identifier : mac.getIdentifiers()) - { - //Add to the identifier collection after filtering through the patch group manager - getIdentifierCollection().update(mPatchGroupManager.update(identifier)); - } - } - else - { - for(Identifier identifier : mac.getIdentifiers()) - { - //Add to the identifier collection after filtering through the patch group manager - getIdentifierCollection().update(mPatchGroupManager.update(identifier)); - } - - if(mac instanceof GroupVoiceChannelUserAbbreviated) - { - GroupVoiceChannelUserAbbreviated gvcua = (GroupVoiceChannelUserAbbreviated)mac; - - if(gvcua.getServiceOptions().isEncrypted()) - { - updateCurrentCall(DecodeEventType.CALL_GROUP_ENCRYPTED, null, message.getTimestamp()); - } - else - { - updateCurrentCall(DecodeEventType.CALL_GROUP, null, message.getTimestamp()); - } - } - } + processGVCUAbbreviated(message, mac); break; case TDMA_33_GROUP_VOICE_CHANNEL_USER_EXTENDED: - if(message.getMacPduType() == MacPduType.MAC_6_HANGTIME) - { - closeCurrentCallEvent(message.getTimestamp(), false, MacPduType.MAC_6_HANGTIME); - - for(Identifier identifier : mac.getIdentifiers()) - { - //Add to the identifier collection after filtering through the patch group manager - getIdentifierCollection().update(mPatchGroupManager.update(identifier)); - } - } - else - { - for(Identifier identifier : mac.getIdentifiers()) - { - //Add to the identifier collection after filtering through the patch group manager - getIdentifierCollection().update(mPatchGroupManager.update(identifier)); - } - - if(mac instanceof GroupVoiceChannelUserExtended) - { - GroupVoiceChannelUserExtended gvcue = (GroupVoiceChannelUserExtended)mac; - - if(gvcue.getServiceOptions().isEncrypted()) - { - updateCurrentCall(DecodeEventType.CALL_GROUP_ENCRYPTED, null, message.getTimestamp()); - } - else - { - updateCurrentCall(DecodeEventType.CALL_GROUP, null, message.getTimestamp()); - } - } - } + processGVCUExtended(message, mac); break; case TDMA_2_UNIT_TO_UNIT_VOICE_CHANNEL_USER: - if(message.getMacPduType() == MacPduType.MAC_6_HANGTIME) - { - closeCurrentCallEvent(message.getTimestamp(), false, MacPduType.MAC_6_HANGTIME); - - for(Identifier identifier : mac.getIdentifiers()) - { - //Add to the identifier collection after filtering through the patch group manager - getIdentifierCollection().update(mPatchGroupManager.update(identifier)); - } - } - else - { - for(Identifier identifier : mac.getIdentifiers()) - { - //Add to the identifier collection after filtering through the patch group manager - getIdentifierCollection().update(mPatchGroupManager.update(identifier)); - } - - if(mac instanceof UnitToUnitVoiceChannelUserAbbreviated) - { - UnitToUnitVoiceChannelUserAbbreviated uuvcua = (UnitToUnitVoiceChannelUserAbbreviated)mac; - - if(uuvcua.getServiceOptions().isEncrypted()) - { - updateCurrentCall(DecodeEventType.CALL_UNIT_TO_UNIT_ENCRYPTED, null, message.getTimestamp()); - } - else - { - updateCurrentCall(DecodeEventType.CALL_UNIT_TO_UNIT, null, message.getTimestamp()); - } - } - } + processUTUVCU(message, mac); break; case TDMA_34_UNIT_TO_UNIT_VOICE_CHANNEL_USER_EXTENDED: - if(message.getMacPduType() == MacPduType.MAC_6_HANGTIME) - { - closeCurrentCallEvent(message.getTimestamp(), false, MacPduType.MAC_6_HANGTIME); - - for(Identifier identifier : mac.getIdentifiers()) - { - //Add to the identifier collection after filtering through the patch group manager - getIdentifierCollection().update(mPatchGroupManager.update(identifier)); - } - } - else - { - for(Identifier identifier : mac.getIdentifiers()) - { - //Add to the identifier collection after filtering through the patch group manager - getIdentifierCollection().update(mPatchGroupManager.update(identifier)); - } - - if(mac instanceof UnitToUnitVoiceChannelUserExtended) - { - UnitToUnitVoiceChannelUserExtended uuvcue = (UnitToUnitVoiceChannelUserExtended)mac; - - if(uuvcue.getServiceOptions().isEncrypted()) - { - updateCurrentCall(DecodeEventType.CALL_UNIT_TO_UNIT_ENCRYPTED, null, message.getTimestamp()); - } - else - { - updateCurrentCall(DecodeEventType.CALL_UNIT_TO_UNIT, null, message.getTimestamp()); - } - } - } + processUTUVCUExtended(message, mac); break; case TDMA_3_TELEPHONE_INTERCONNECT_VOICE_CHANNEL_USER: - if(message.getMacPduType() == MacPduType.MAC_6_HANGTIME) - { - closeCurrentCallEvent(message.getTimestamp(), false, MacPduType.MAC_6_HANGTIME); - - for(Identifier identifier : mac.getIdentifiers()) - { - //Add to the identifier collection after filtering through the patch group manager - getIdentifierCollection().update(mPatchGroupManager.update(identifier)); - } - } - else - { - for(Identifier identifier : mac.getIdentifiers()) - { - //Add to the identifier collection after filtering through the patch group manager - getIdentifierCollection().update(mPatchGroupManager.update(identifier)); - } - - if(mac instanceof TelephoneInterconnectVoiceChannelUser) - { - TelephoneInterconnectVoiceChannelUser tivcu = (TelephoneInterconnectVoiceChannelUser)mac; - - if(tivcu.getServiceOptions().isEncrypted()) - { - updateCurrentCall(DecodeEventType.CALL_INTERCONNECT_ENCRYPTED, null, message.getTimestamp()); - } - else - { - updateCurrentCall(DecodeEventType.CALL_INTERCONNECT, null, message.getTimestamp()); - } - } - } + processTIVCU(message, mac); break; case TDMA_5_GROUP_VOICE_CHANNEL_GRANT_UPDATE_MULTIPLE: - if(getCurrentChannel() == null && mac instanceof GroupVoiceChannelGrantUpdateMultiple) - { - GroupVoiceChannelGrantUpdateMultiple gvcgum = (GroupVoiceChannelGrantUpdateMultiple)mac; - - if(isCurrentGroup(gvcgum.getGroupAddressA())) - { - broadcastCurrentChannel(gvcgum.getChannelA()); - } - - if(getCurrentChannel() == null && gvcgum.hasGroupB() && isCurrentGroup(gvcgum.getGroupAddressB())) - { - broadcastCurrentChannel(gvcgum.getChannelB()); - } - - if(getCurrentChannel() == null && gvcgum.hasGroupC() && isCurrentGroup(gvcgum.getGroupAddressC())) - { - broadcastCurrentChannel(gvcgum.getChannelC()); - } - } + processGVCGUM(mac); break; case TDMA_37_GROUP_VOICE_CHANNEL_GRANT_UPDATE_MULTIPLE_EXPLICIT: - if(getCurrentChannel() == null && mac instanceof GroupVoiceChannelGrantUpdateMultipleExplicit) - { - GroupVoiceChannelGrantUpdateMultipleExplicit gvcgume = (GroupVoiceChannelGrantUpdateMultipleExplicit)mac; - - if(isCurrentGroup(gvcgume.getGroupAddressA())) - { - broadcastCurrentChannel(gvcgume.getChannelA()); - } - - if(getCurrentChannel() == null && isCurrentGroup(gvcgume.getGroupAddressB())) - { - broadcastCurrentChannel(gvcgume.getChannelB()); - } - } + processGVCGUMExplicit(mac); break; case PHASE1_64_GROUP_VOICE_CHANNEL_GRANT_ABBREVIATED: - if(getCurrentChannel() == null && mac instanceof GroupVoiceChannelGrantAbbreviated) - { - GroupVoiceChannelGrantAbbreviated gvcga = (GroupVoiceChannelGrantAbbreviated)mac; - - if(isCurrentGroup(gvcga.getGroupAddress())) - { - broadcastCurrentChannel(gvcga.getChannel()); - } - } + processGVCGAbbreviated(mac); break; case PHASE1_66_GROUP_VOICE_CHANNEL_GRANT_UPDATE: - if(getCurrentChannel() == null && mac instanceof GroupVoiceChannelGrantUpdate) - { - GroupVoiceChannelGrantUpdate gvcgu = (GroupVoiceChannelGrantUpdate)mac; - - if(isCurrentGroup(gvcgu.getGroupAddressA())) - { - broadcastCurrentChannel(gvcgu.getChannelA()); - } - - if(getCurrentChannel() == null && isCurrentGroup(gvcgu.getGroupAddressB())) - { - broadcastCurrentChannel(gvcgu.getChannelB()); - } - } + processGVCGUpdate(mac); break; case PHASE1_70_UNIT_TO_UNIT_VOICE_CHANNEL_GRANT_UPDATE_ABBREVIATED: - if(getCurrentChannel() == null && mac instanceof UnitToUnitVoiceChannelGrantAbbreviated) - { - UnitToUnitVoiceChannelGrantAbbreviated uuvcga = (UnitToUnitVoiceChannelGrantAbbreviated)mac; - - if(isCurrentGroup(uuvcga.getSourceAddress()) || isCurrentGroup(uuvcga.getTargetAddress())) - { - broadcastCurrentChannel(uuvcga.getChannel()); - } - } + processUTUVCGUAbbreviated(mac); break; case PHASE1_195_GROUP_VOICE_CHANNEL_GRANT_UPDATE_EXPLICIT: - if(getCurrentChannel() == null && mac instanceof GroupVoiceChannelGrantUpdateExplicit) - { - GroupVoiceChannelGrantUpdateExplicit gvcgue = (GroupVoiceChannelGrantUpdateExplicit)mac; - - if(isCurrentGroup(gvcgue.getGroupAddress())) - { - broadcastCurrentChannel(gvcgue.getChannel()); - } - } + processGVCGUExplicit(mac); break; case PHASE1_198_UNIT_TO_UNIT_VOICE_CHANNEL_GRANT_UPDATE_EXTENDED: - if(getCurrentChannel() == null && mac instanceof UnitToUnitVoiceChannelGrantUpdateExtended) - { - UnitToUnitVoiceChannelGrantUpdateExtended uuvcgue = (UnitToUnitVoiceChannelGrantUpdateExtended)mac; - - if(isCurrentGroup(uuvcgue.getTargetAddress())) - { - broadcastCurrentChannel(uuvcgue.getChannel()); - } - } + processUTUVCGUExtended(mac); break; case TDMA_17_INDIRECT_GROUP_PAGING: - MutableIdentifierCollection icGroupPaging = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icGroupPaging.remove(IdentifierClass.USER); - icGroupPaging.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.PAGE.toString()) - .details("GROUP PAGE") - .identifiers(icGroupPaging) - .build()); + broadcast(message, mac, getCurrentChannel(), DecodeEventType.PAGE, "GROUP PAGE"); break; case TDMA_18_INDIVIDUAL_PAGING_MESSAGE_WITH_PRIORITY: - if(mac instanceof IndividualPagingMessage) - { - IndividualPagingMessage ipm = (IndividualPagingMessage)mac; - MutableIdentifierCollection icIndividualPaging = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icIndividualPaging.remove(IdentifierClass.USER); - icIndividualPaging.update(mac.getIdentifiers()); - boolean priority = ipm.isTalkgroupPriority1() || ipm.isTalkgroupPriority2() || - ipm.isTalkgroupPriority3() || ipm.isTalkgroupPriority4(); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.PAGE.toString()) - .details((priority ? "PRIORITY " : "") + "USER PAGE") - .identifiers(icIndividualPaging) - .build()); - } + processIPMWP(message, mac); break; case TDMA_48_POWER_CONTROL_SIGNAL_QUALITY: - if(mac instanceof PowerControlSignalQuality) - { - PowerControlSignalQuality pcsq = (PowerControlSignalQuality)mac; - - MutableIdentifierCollection icPowerControl = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icPowerControl.remove(IdentifierClass.USER); - icPowerControl.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.COMMAND.toString()) - .details("ADJUST TRANSMIT POWER - RF:" + pcsq.getRFLevel() + " BER:" + pcsq.getBitErrorRate()) - .identifiers(icPowerControl) - .build()); - } + processPCSQ(message, mac); break; case TDMA_49_MAC_RELEASE: - if(mac instanceof MacRelease) - { - MacRelease mr = (MacRelease)mac; - - MutableIdentifierCollection icMacRelease = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icMacRelease.remove(IdentifierClass.USER); - icMacRelease.update(mac.getIdentifiers()); - - closeCurrentCallEvent(message.getTimestamp(), true, message.getMacPduType()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.COMMAND.toString()) - .details((mr.isForcedPreemption() ? "FORCED " : "") + "CALL PREEMPTION" + (mr.isTalkerPreemption() ? " BY USER" : "")) - .identifiers(icMacRelease) - .build()); - } + processMacRelease(message, mac); break; case PHASE1_65_GROUP_VOICE_SERVICE_REQUEST: if(mac instanceof GroupVoiceServiceRequest) { GroupVoiceServiceRequest gvsr = (GroupVoiceServiceRequest)mac; - MutableIdentifierCollection icMacRelease = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icMacRelease.remove(IdentifierClass.USER); - icMacRelease.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("GROUP VOICE SERVICE " + gvsr.getServiceOptions()) - .identifiers(icMacRelease) - .build()); + broadcast(message, mac, getCurrentChannel(), DecodeEventType.REQUEST, "GROUP VOICE SERVICE " + gvsr.getServiceOptions()); } break; case PHASE1_68_UNIT_TO_UNIT_VOICE_CHANNEL_GRANT_ABBREVIATED: if(mac instanceof UnitToUnitVoiceChannelGrantAbbreviated) { UnitToUnitVoiceChannelGrantAbbreviated uuvcga = (UnitToUnitVoiceChannelGrantAbbreviated)mac; - MutableIdentifierCollection icGrant = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icGrant.remove(IdentifierClass.USER); - icGrant.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(uuvcga.getChannel()) - .eventDescription(DecodeEventType.CALL_UNIT_TO_UNIT.toString()) - .details("VOICE CHANNEL GRANT") - .identifiers(icGrant) - .build()); + broadcast(message, mac, uuvcga.getChannel(), DecodeEventType.CALL_UNIT_TO_UNIT, "VOICE CHANNEL GRANT"); } break; case PHASE1_69_UNIT_TO_UNIT_ANSWER_REQUEST_ABBREVIATED: if(mac instanceof UnitToUnitAnswerRequestAbbreviated) { UnitToUnitAnswerRequestAbbreviated uuara = (UnitToUnitAnswerRequestAbbreviated)mac; - MutableIdentifierCollection icRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icRequest.remove(IdentifierClass.USER); - icRequest.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("UNIT-TO-UNIT ANSWER REQUEST - " + uuara.getServiceOptions()) - .identifiers(icRequest) - .build()); + broadcast(message, mac, getCurrentChannel(), DecodeEventType.REQUEST, "UNIT-TO-UNIT ANSWER REQUEST - " + uuara.getServiceOptions()); } break; case PHASE1_74_TELEPHONE_INTERCONNECT_ANSWER_REQUEST: if(mac instanceof TelephoneInterconnectAnswerRequest) { TelephoneInterconnectAnswerRequest tiar = (TelephoneInterconnectAnswerRequest)mac; - MutableIdentifierCollection icRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icRequest.remove(IdentifierClass.USER); - icRequest.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("TELEPHONE INTERCONNECT ANSWER REQUEST") - .identifiers(icRequest) - .build()); + broadcast(message, mac, getCurrentChannel(), DecodeEventType.REQUEST, "TELEPHONE INTERCONNECT ANSWER REQUEST"); } break; case PHASE1_76_RADIO_UNIT_MONITOR_COMMAND_ABBREVIATED: - if(mac instanceof RadioUnitMonitorCommand) - { - RadioUnitMonitorCommand rumc = (RadioUnitMonitorCommand)mac; - MutableIdentifierCollection icRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icRequest.remove(IdentifierClass.USER); - icRequest.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.COMMAND.toString()) - .details("RADIO UNIT MONITOR" + (rumc.isSilentMonitor() ? " (STEALTH)" : "") + - " TIME:" + rumc.getTransmitTime() + " MULTIPLIER:" + rumc.getTransmitMultiplier()) - .identifiers(icRequest) - .build()); - } + processRUMCA(message, mac); break; case PHASE1_84_SNDCP_DATA_CHANNEL_GRANT: - if(mac instanceof SNDCPDataChannelGrant) - { - SNDCPDataChannelGrant sdcg = (SNDCPDataChannelGrant)mac; - MutableIdentifierCollection icGrant = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icGrant.remove(IdentifierClass.USER); - icGrant.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(sdcg.getChannel()) - .eventDescription(sdcg.getServiceOptions().isEncrypted() ? DecodeEventType.DATA_CALL_ENCRYPTED.toString() : DecodeEventType.DATA_CALL.toString()) - .details("SNDCP CHANNEL GRANT " + sdcg.getServiceOptions()) - .identifiers(icGrant) - .build()); - } + processSDCG(message, mac); break; case PHASE1_85_SNDCP_DATA_PAGE_REQUEST: if(mac instanceof SNDCPDataPageRequest) { SNDCPDataPageRequest sdpr = (SNDCPDataPageRequest)mac; - MutableIdentifierCollection icPage = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icPage.remove(IdentifierClass.USER); - icPage.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.PAGE.toString()) - .details("SNDCP DATA PAGE " + sdpr.getServiceOptions()) - .identifiers(icPage) - .build()); + broadcast(message, mac, getCurrentChannel(), DecodeEventType.PAGE, "SNDCP DATA PAGE " + sdpr.getServiceOptions()); } break; case PHASE1_88_STATUS_UPDATE_ABBREVIATED: - if(mac instanceof StatusUpdateAbbreviated) - { - StatusUpdateAbbreviated sua = (StatusUpdateAbbreviated)mac; - MutableIdentifierCollection icStatusUpdate = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icStatusUpdate.remove(IdentifierClass.USER); - icStatusUpdate.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.STATUS.toString()) - .details("STATUS UPDATE - UNIT:" + sua.getUnitStatus() + " USER:" + sua.getUserStatus()) - .identifiers(icStatusUpdate) - .build()); - } + processSUA(message, mac); break; case PHASE1_90_STATUS_QUERY_ABBREVIATED: if(mac instanceof StatusQueryAbbreviated) { - MutableIdentifierCollection icStatusUpdate = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icStatusUpdate.remove(IdentifierClass.USER); - icStatusUpdate.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.STATUS.toString()) - .details("STATUS QUERY") - .identifiers(icStatusUpdate) - .build()); + broadcast(message, mac, getCurrentChannel(), DecodeEventType.STATUS, "STATUS QUERY"); } break; case PHASE1_92_MESSAGE_UPDATE_ABBREVIATED: if(mac instanceof MessageUpdateAbbreviated) { MessageUpdateAbbreviated mua = (MessageUpdateAbbreviated)mac; - MutableIdentifierCollection icStatusUpdate = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icStatusUpdate.remove(IdentifierClass.USER); - icStatusUpdate.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.SDM.toString()) - .details("MESSAGE UPDATE - " + mua.getShortDataMessage()) - .identifiers(icStatusUpdate) - .build()); + broadcast(message, mac, getCurrentChannel(), DecodeEventType.SDM, "MESSAGE UPDATE - " + mua.getShortDataMessage()); } break; case PHASE1_94_RADIO_UNIT_MONITOR_COMMAND_ENHANCED: - if(mac instanceof RadioUnitMonitorCommandEnhanced) - { - RadioUnitMonitorCommandEnhanced rumc = (RadioUnitMonitorCommandEnhanced)mac; - MutableIdentifierCollection icRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icRequest.remove(IdentifierClass.USER); - icRequest.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.COMMAND.toString()) - .details("RADIO UNIT MONITOR" + (rumc.isStealthMode() ? " (STEALTH)" : "") + - " ENCRYPTION:" + rumc.getEncryption() + - " TIME:" + rumc.getTransmitTime()) - .identifiers(icRequest) - .build()); - } + processRUMCE(message, mac); break; case PHASE1_95_CALL_ALERT_ABBREVIATED: - MutableIdentifierCollection icCallAlert = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icCallAlert.remove(IdentifierClass.USER); - icCallAlert.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.CALL_ALERT.toString()) - .identifiers(icCallAlert) - .build()); + processCallAlert(message, mac); break; case PHASE1_96_ACK_RESPONSE: if(mac instanceof AcknowledgeResponse) { AcknowledgeResponse ar = (AcknowledgeResponse)mac; - MutableIdentifierCollection icAckResponse = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icAckResponse.remove(IdentifierClass.USER); - icAckResponse.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("ACKNOWLEDGE: " + ar.getServiceType()) - .identifiers(icAckResponse) - .build()); + broadcast(message, mac, getCurrentChannel(), DecodeEventType.RESPONSE, "ACKNOWLEDGE: " + ar.getServiceType()); } break; case PHASE1_97_QUEUED_RESPONSE: - if(mac instanceof QueuedResponse) - { - QueuedResponse qr = (QueuedResponse)mac; - - MutableIdentifierCollection icQueuedResponse = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icQueuedResponse.remove(IdentifierClass.USER); - icQueuedResponse.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("QUEUED - " + qr.getQueuedResponseServiceType() + - " REASON:" + qr.getQueuedResponseReason() + " ADDL:" + qr.getAdditionalInfo()) - .identifiers(icQueuedResponse) - .build()); - } + processQueuedResponse(message, mac); break; case PHASE1_100_EXTENDED_FUNCTION_COMMAND_ABBREVIATED: - if(mac instanceof ExtendedFunctionCommand) - { - ExtendedFunctionCommand efc = (ExtendedFunctionCommand)mac; - - MutableIdentifierCollection icExtendedFunction = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icExtendedFunction.remove(IdentifierClass.USER); - icExtendedFunction.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.COMMAND.toString()) - .details("EXTENDED FUNCTION: " + efc.getExtendedFunction() + " ARGUMENTS:" + efc.getArguments()) - .identifiers(icExtendedFunction) - .build()); - } + processEFCA(message, mac); break; case PHASE1_103_DENY_RESPONSE: - if(mac instanceof DenyResponse) - { - DenyResponse dr = (DenyResponse)mac; - MutableIdentifierCollection icDenyResponse = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icDenyResponse.remove(IdentifierClass.USER); - icDenyResponse.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.RESPONSE.toString()) - .details("DENY: " + dr.getDeniedServiceType() + " REASON:" + dr.getDenyReason() + " ADDL:" + dr.getAdditionalInfo()) - .identifiers(icDenyResponse) - .build()); - } + processDenyResponse(message, mac); break; case PHASE1_106_GROUP_AFFILIATION_QUERY_ABBREVIATED: - MutableIdentifierCollection icGroupAffiliationQuery = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icGroupAffiliationQuery.remove(IdentifierClass.USER); - icGroupAffiliationQuery.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.QUERY.toString()) - .details("GROUP AFFILIATION") - .identifiers(icGroupAffiliationQuery) - .build()); + broadcast(message, mac, getCurrentChannel(), DecodeEventType.QUERY, "GROUP AFFILIATION"); break; case PHASE1_109_UNIT_REGISTRATION_COMMAND_ABBREVIATED: - MutableIdentifierCollection icUnitRegisterCommand = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icUnitRegisterCommand.remove(IdentifierClass.USER); - icUnitRegisterCommand.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.COMMAND.toString()) - .details("UNIT REGISTRATION") - .identifiers(icUnitRegisterCommand) - .build()); + broadcast(message, mac, getCurrentChannel(), DecodeEventType.COMMAND, "UNIT REGISTRATION"); break; case PHASE1_197_UNIT_TO_UNIT_ANSWER_REQUEST_EXTENDED: if(mac instanceof UnitToUnitAnswerRequestExtended) { UnitToUnitAnswerRequestExtended uuare = (UnitToUnitAnswerRequestExtended)mac; - MutableIdentifierCollection icUnitAnswerRequestExtended = - new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icUnitAnswerRequestExtended.remove(IdentifierClass.USER); - icUnitAnswerRequestExtended.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.REQUEST.toString()) - .details("UNIT-TO-UNIT ANSWER REQUEST " + uuare.getServiceOptions()) - .identifiers(icUnitAnswerRequestExtended) - .build()); + broadcast(message, mac, getCurrentChannel(), DecodeEventType.REQUEST, "UNIT-TO-UNIT ANSWER REQUEST " + uuare.getServiceOptions()); } break; case PHASE1_204_RADIO_UNIT_MONITOR_COMMAND_EXTENDED: - if(mac instanceof RadioUnitMonitorCommandExtended) - { - RadioUnitMonitorCommandExtended rumce = (RadioUnitMonitorCommandExtended)mac; - MutableIdentifierCollection icRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icRequest.remove(IdentifierClass.USER); - icRequest.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.COMMAND.toString()) - .details("RADIO UNIT MONITOR" + (rumce.isSilentMonitor() ? " (STEALTH)" : "") + - " TIME:" + rumce.getTransmitTime() + "MULTIPLIER:" + rumce.getTransmitMultiplier()) - .identifiers(icRequest) - .build()); - } + processRUMCExtended(message, mac); break; case PHASE1_216_STATUS_UPDATE_EXTENDED: - if(mac instanceof StatusUpdateExtended) - { - StatusUpdateExtended sue = (StatusUpdateExtended)mac; - MutableIdentifierCollection icStatusUpdate = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icStatusUpdate.remove(IdentifierClass.USER); - icStatusUpdate.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.STATUS.toString()) - .details("STATUS UPDATE - UNIT:" + sue.getUnitStatus() + " USER:" + sue.getUserStatus()) - .identifiers(icStatusUpdate) - .build()); - } + processSUE(message, mac); break; case PHASE1_218_STATUS_QUERY_EXTENDED: - MutableIdentifierCollection icStatusQueryExtended = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icStatusQueryExtended.remove(IdentifierClass.USER); - icStatusQueryExtended.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.STATUS.toString()) - .details("STATUS QUERY") - .identifiers(icStatusQueryExtended) - .build()); + broadcast(message, mac, getCurrentChannel(), DecodeEventType.STATUS, "STATUS QUERY"); break; case PHASE1_220_MESSAGE_UPDATE_EXTENDED: if(mac instanceof MessageUpdateExtended) { MessageUpdateExtended mue = (MessageUpdateExtended)mac; - MutableIdentifierCollection icStatusUpdate = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icStatusUpdate.remove(IdentifierClass.USER); - icStatusUpdate.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.SDM.toString()) - .details("MESSAGE UPDATE - " + mue.getShortDataMessage()) - .identifiers(icStatusUpdate) - .build()); + broadcast(message, mac, getCurrentChannel(), DecodeEventType.SDM, "MESSAGE UPDATE - " + mue.getShortDataMessage()); } break; case PHASE1_223_CALL_ALERT_EXTENDED: if(mac instanceof CallAlertExtended) { - MutableIdentifierCollection icCallAlertExtended = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icCallAlertExtended.remove(IdentifierClass.USER); - icCallAlertExtended.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.CALL_ALERT.toString()) - .identifiers(icCallAlertExtended) - .build()); + processCallAlert(message, mac); } break; case PHASE1_228_EXTENDED_FUNCTION_COMMAND_EXTENDED: - if(mac instanceof ExtendedFunctionCommandExtended) - { - ExtendedFunctionCommandExtended efce = (ExtendedFunctionCommandExtended)mac; - - MutableIdentifierCollection icExtendedFunction = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icExtendedFunction.remove(IdentifierClass.USER); - icExtendedFunction.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.COMMAND.toString()) - .details("EXTENDED FUNCTION: " + efce.getExtendedFunction() + " ARGUMENTS:" + efce.getArguments()) - .identifiers(icExtendedFunction) - .build()); - } + processEFCE(message, mac); break; case PHASE1_234_GROUP_AFFILIATION_QUERY_EXTENDED: if(mac instanceof GroupAffiliationQueryExtended) { - MutableIdentifierCollection icGroupAffiliationQueryExtended = - new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); - icGroupAffiliationQueryExtended.remove(IdentifierClass.USER); - icGroupAffiliationQueryExtended.update(mac.getIdentifiers()); - - broadcast(P25DecodeEvent.builder(message.getTimestamp()) - .channel(getCurrentChannel()) - .eventDescription(DecodeEventType.QUERY.toString()) - .details("GROUP AFFILIATION") - .identifiers(icGroupAffiliationQueryExtended) - .build()); + broadcast(message, mac, getCurrentChannel(), DecodeEventType.QUERY, "GROUP AFFILIATION"); } break; @@ -1097,6 +451,633 @@ public class P25P2DecoderState extends TimeslotDecoderState implements Identifie } } + private void processQueuedResponse(MacMessage message, MacStructure mac) { + if(mac instanceof QueuedResponse) + { + QueuedResponse qr = (QueuedResponse)mac; + + MutableIdentifierCollection icQueuedResponse = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + icQueuedResponse.remove(IdentifierClass.USER); + icQueuedResponse.update(mac.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(message.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.RESPONSE.toString()) + .details("QUEUED - " + qr.getQueuedResponseServiceType() + + " REASON:" + qr.getQueuedResponseReason() + " ADDL:" + qr.getAdditionalInfo()) + .identifiers(icQueuedResponse) + .build()); + } + } + + private void processEFCA(MacMessage message, MacStructure mac) { + if(mac instanceof ExtendedFunctionCommand) + { + ExtendedFunctionCommand efc = (ExtendedFunctionCommand)mac; + + MutableIdentifierCollection icExtendedFunction = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + icExtendedFunction.remove(IdentifierClass.USER); + icExtendedFunction.update(mac.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(message.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.COMMAND.toString()) + .details("EXTENDED FUNCTION: " + efc.getExtendedFunction() + " ARGUMENTS:" + efc.getArguments()) + .identifiers(icExtendedFunction) + .build()); + } + } + + private void processDenyResponse(MacMessage message, MacStructure mac) { + if(mac instanceof DenyResponse) + { + DenyResponse dr = (DenyResponse)mac; + MutableIdentifierCollection icDenyResponse = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + icDenyResponse.remove(IdentifierClass.USER); + icDenyResponse.update(mac.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(message.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.RESPONSE.toString()) + .details("DENY: " + dr.getDeniedServiceType() + " REASON:" + dr.getDenyReason() + " ADDL:" + dr.getAdditionalInfo()) + .identifiers(icDenyResponse) + .build()); + } + } + + private void processRUMCExtended(MacMessage message, MacStructure mac) { + if(mac instanceof RadioUnitMonitorCommandExtended) + { + RadioUnitMonitorCommandExtended rumce = (RadioUnitMonitorCommandExtended)mac; + MutableIdentifierCollection icRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + icRequest.remove(IdentifierClass.USER); + icRequest.update(mac.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(message.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.COMMAND.toString()) + .details("RADIO UNIT MONITOR" + (rumce.isSilentMonitor() ? " (STEALTH)" : "") + + " TIME:" + rumce.getTransmitTime() + "MULTIPLIER:" + rumce.getTransmitMultiplier()) + .identifiers(icRequest) + .build()); + } + } + + private void processSUE(MacMessage message, MacStructure mac) { + if(mac instanceof StatusUpdateExtended) + { + StatusUpdateExtended sue = (StatusUpdateExtended)mac; + MutableIdentifierCollection icStatusUpdate = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + icStatusUpdate.remove(IdentifierClass.USER); + icStatusUpdate.update(mac.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(message.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.STATUS.toString()) + .details("STATUS UPDATE - UNIT:" + sue.getUnitStatus() + " USER:" + sue.getUserStatus()) + .identifiers(icStatusUpdate) + .build()); + } + } + + private void processEFCE(MacMessage message, MacStructure mac) { + if(mac instanceof ExtendedFunctionCommandExtended) + { + ExtendedFunctionCommandExtended efce = (ExtendedFunctionCommandExtended)mac; + + MutableIdentifierCollection icExtendedFunction = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + icExtendedFunction.remove(IdentifierClass.USER); + icExtendedFunction.update(mac.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(message.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.COMMAND.toString()) + .details("EXTENDED FUNCTION: " + efce.getExtendedFunction() + " ARGUMENTS:" + efce.getArguments()) + .identifiers(icExtendedFunction) + .build()); + } + } + + private void processCallAlert(MacMessage message, MacStructure mac) { + MutableIdentifierCollection icCallAlert = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + icCallAlert.remove(IdentifierClass.USER); + icCallAlert.update(mac.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(message.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.CALL_ALERT.toString()) + .identifiers(icCallAlert) + .build()); + } + + private void processRUMCE(MacMessage message, MacStructure mac) { + if(mac instanceof RadioUnitMonitorCommandEnhanced) + { + RadioUnitMonitorCommandEnhanced rumc = (RadioUnitMonitorCommandEnhanced)mac; + MutableIdentifierCollection icRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + icRequest.remove(IdentifierClass.USER); + icRequest.update(mac.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(message.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.COMMAND.toString()) + .details("RADIO UNIT MONITOR" + (rumc.isStealthMode() ? " (STEALTH)" : "") + + " ENCRYPTION:" + rumc.getEncryption() + + " TIME:" + rumc.getTransmitTime()) + .identifiers(icRequest) + .build()); + } + } + + private void processSUA(MacMessage message, MacStructure mac) { + if(mac instanceof StatusUpdateAbbreviated) + { + StatusUpdateAbbreviated sua = (StatusUpdateAbbreviated)mac; + MutableIdentifierCollection icStatusUpdate = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + icStatusUpdate.remove(IdentifierClass.USER); + icStatusUpdate.update(mac.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(message.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.STATUS.toString()) + .details("STATUS UPDATE - UNIT:" + sua.getUnitStatus() + " USER:" + sua.getUserStatus()) + .identifiers(icStatusUpdate) + .build()); + } + } + + private void processSDCG(MacMessage message, MacStructure mac) { + if(mac instanceof SNDCPDataChannelGrant) + { + SNDCPDataChannelGrant sdcg = (SNDCPDataChannelGrant)mac; + MutableIdentifierCollection icGrant = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + icGrant.remove(IdentifierClass.USER); + icGrant.update(mac.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(message.getTimestamp()) + .channel(sdcg.getChannel()) + .eventDescription(sdcg.getServiceOptions().isEncrypted() ? DecodeEventType.DATA_CALL_ENCRYPTED.toString() : DecodeEventType.DATA_CALL.toString()) + .details("SNDCP CHANNEL GRANT " + sdcg.getServiceOptions()) + .identifiers(icGrant) + .build()); + } + } + + private void processRUMCA(MacMessage message, MacStructure mac) { + if(mac instanceof RadioUnitMonitorCommand) + { + RadioUnitMonitorCommand rumc = (RadioUnitMonitorCommand)mac; + MutableIdentifierCollection icRequest = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + icRequest.remove(IdentifierClass.USER); + icRequest.update(mac.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(message.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.COMMAND.toString()) + .details("RADIO UNIT MONITOR" + (rumc.isSilentMonitor() ? " (STEALTH)" : "") + + " TIME:" + rumc.getTransmitTime() + " MULTIPLIER:" + rumc.getTransmitMultiplier()) + .identifiers(icRequest) + .build()); + } + } + + private void processMacRelease(MacMessage message, MacStructure mac) { + if(mac instanceof MacRelease) + { + MacRelease mr = (MacRelease)mac; + + MutableIdentifierCollection icMacRelease = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + icMacRelease.remove(IdentifierClass.USER); + icMacRelease.update(mac.getIdentifiers()); + + closeCurrentCallEvent(message.getTimestamp(), true, message.getMacPduType()); + + broadcast(P25DecodeEvent.builder(message.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.COMMAND.toString()) + .details((mr.isForcedPreemption() ? "FORCED " : "") + "CALL PREEMPTION" + (mr.isTalkerPreemption() ? " BY USER" : "")) + .identifiers(icMacRelease) + .build()); + } + } + + private void processPCSQ(MacMessage message, MacStructure mac) { + if(mac instanceof PowerControlSignalQuality) + { + PowerControlSignalQuality pcsq = (PowerControlSignalQuality)mac; + + MutableIdentifierCollection icPowerControl = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + icPowerControl.remove(IdentifierClass.USER); + icPowerControl.update(mac.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(message.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.COMMAND.toString()) + .details("ADJUST TRANSMIT POWER - RF:" + pcsq.getRFLevel() + " BER:" + pcsq.getBitErrorRate()) + .identifiers(icPowerControl) + .build()); + } + } + + private void processIPMWP(MacMessage message, MacStructure mac) { + if(mac instanceof IndividualPagingMessage) + { + IndividualPagingMessage ipm = (IndividualPagingMessage)mac; + MutableIdentifierCollection icIndividualPaging = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + icIndividualPaging.remove(IdentifierClass.USER); + icIndividualPaging.update(mac.getIdentifiers()); + boolean priority = ipm.isTalkgroupPriority1() || ipm.isTalkgroupPriority2() || + ipm.isTalkgroupPriority3() || ipm.isTalkgroupPriority4(); + + broadcast(P25DecodeEvent.builder(message.getTimestamp()) + .channel(getCurrentChannel()) + .eventDescription(DecodeEventType.PAGE.toString()) + .details((priority ? "PRIORITY " : "") + "USER PAGE") + .identifiers(icIndividualPaging) + .build()); + } + } + + private void broadcast(MacMessage message, MacStructure mac, IChannelDescriptor currentChannel, DecodeEventType page, String s) { + MutableIdentifierCollection collection = new MutableIdentifierCollection(getIdentifierCollection().getIdentifiers()); + collection.remove(IdentifierClass.USER); + collection.update(mac.getIdentifiers()); + + broadcast(P25DecodeEvent.builder(message.getTimestamp()) + .channel(currentChannel) + .eventDescription(page.toString()) + .details(s) + .identifiers(collection) + .build()); + } + + private void processUTUVCGUExtended(MacStructure mac) { + if(getCurrentChannel() == null && mac instanceof UnitToUnitVoiceChannelGrantUpdateExtended) + { + UnitToUnitVoiceChannelGrantUpdateExtended uuvcgue = (UnitToUnitVoiceChannelGrantUpdateExtended)mac; + + if(isCurrentGroup(uuvcgue.getTargetAddress())) + { + broadcastCurrentChannel(uuvcgue.getChannel()); + } + } + } + + private void processGVCGUExplicit(MacStructure mac) { + if(getCurrentChannel() == null && mac instanceof GroupVoiceChannelGrantUpdateExplicit) + { + GroupVoiceChannelGrantUpdateExplicit gvcgue = (GroupVoiceChannelGrantUpdateExplicit)mac; + + if(isCurrentGroup(gvcgue.getGroupAddress())) + { + broadcastCurrentChannel(gvcgue.getChannel()); + } + } + } + + private void processUTUVCGUAbbreviated(MacStructure mac) { + if(getCurrentChannel() == null && mac instanceof UnitToUnitVoiceChannelGrantAbbreviated) + { + UnitToUnitVoiceChannelGrantAbbreviated uuvcga = (UnitToUnitVoiceChannelGrantAbbreviated)mac; + + if(isCurrentGroup(uuvcga.getSourceAddress()) || isCurrentGroup(uuvcga.getTargetAddress())) + { + broadcastCurrentChannel(uuvcga.getChannel()); + } + } + } + + private void processGVCGUpdate(MacStructure mac) { + if(getCurrentChannel() == null && mac instanceof GroupVoiceChannelGrantUpdate) + { + GroupVoiceChannelGrantUpdate gvcgu = (GroupVoiceChannelGrantUpdate)mac; + + if(isCurrentGroup(gvcgu.getGroupAddressA())) + { + broadcastCurrentChannel(gvcgu.getChannelA()); + } + + if(getCurrentChannel() == null && isCurrentGroup(gvcgu.getGroupAddressB())) + { + broadcastCurrentChannel(gvcgu.getChannelB()); + } + } + } + + private void processGVCGAbbreviated(MacStructure mac) { + if(getCurrentChannel() == null && mac instanceof GroupVoiceChannelGrantAbbreviated) + { + GroupVoiceChannelGrantAbbreviated gvcga = (GroupVoiceChannelGrantAbbreviated)mac; + + if(isCurrentGroup(gvcga.getGroupAddress())) + { + broadcastCurrentChannel(gvcga.getChannel()); + } + } + } + + private void processGVCGUMExplicit(MacStructure mac) { + if(getCurrentChannel() == null && mac instanceof GroupVoiceChannelGrantUpdateMultipleExplicit) + { + GroupVoiceChannelGrantUpdateMultipleExplicit gvcgume = (GroupVoiceChannelGrantUpdateMultipleExplicit)mac; + + if(isCurrentGroup(gvcgume.getGroupAddressA())) + { + broadcastCurrentChannel(gvcgume.getChannelA()); + } + + if(getCurrentChannel() == null && isCurrentGroup(gvcgume.getGroupAddressB())) + { + broadcastCurrentChannel(gvcgume.getChannelB()); + } + } + } + + private void processGVCGUM(MacStructure mac) { + if(getCurrentChannel() == null && mac instanceof GroupVoiceChannelGrantUpdateMultiple) + { + GroupVoiceChannelGrantUpdateMultiple gvcgum = (GroupVoiceChannelGrantUpdateMultiple)mac; + + if(isCurrentGroup(gvcgum.getGroupAddressA())) + { + broadcastCurrentChannel(gvcgum.getChannelA()); + } + + if(getCurrentChannel() == null && gvcgum.hasGroupB() && isCurrentGroup(gvcgum.getGroupAddressB())) + { + broadcastCurrentChannel(gvcgum.getChannelB()); + } + + if(getCurrentChannel() == null && gvcgum.hasGroupC() && isCurrentGroup(gvcgum.getGroupAddressC())) + { + broadcastCurrentChannel(gvcgum.getChannelC()); + } + } + } + + private void processTIVCU(MacMessage message, MacStructure mac) { + if(message.getMacPduType() == MacPduType.MAC_6_HANGTIME) + { + closeCurrentCallEvent(message.getTimestamp(), false, MacPduType.MAC_6_HANGTIME); + + for(Identifier identifier : mac.getIdentifiers()) + { + //Add to the identifier collection after filtering through the patch group manager + getIdentifierCollection().update(mPatchGroupManager.update(identifier)); + } + } + else + { + for(Identifier identifier : mac.getIdentifiers()) + { + //Add to the identifier collection after filtering through the patch group manager + getIdentifierCollection().update(mPatchGroupManager.update(identifier)); + } + + if(mac instanceof TelephoneInterconnectVoiceChannelUser) + { + TelephoneInterconnectVoiceChannelUser tivcu = (TelephoneInterconnectVoiceChannelUser)mac; + + if(tivcu.getServiceOptions().isEncrypted()) + { + updateCurrentCall(DecodeEventType.CALL_INTERCONNECT_ENCRYPTED, null, message.getTimestamp()); + } + else + { + updateCurrentCall(DecodeEventType.CALL_INTERCONNECT, null, message.getTimestamp()); + } + } + } + } + + private void processUTUVCUExtended(MacMessage message, MacStructure mac) { + if(message.getMacPduType() == MacPduType.MAC_6_HANGTIME) + { + closeCurrentCallEvent(message.getTimestamp(), false, MacPduType.MAC_6_HANGTIME); + + for(Identifier identifier : mac.getIdentifiers()) + { + //Add to the identifier collection after filtering through the patch group manager + getIdentifierCollection().update(mPatchGroupManager.update(identifier)); + } + } + else + { + for(Identifier identifier : mac.getIdentifiers()) + { + //Add to the identifier collection after filtering through the patch group manager + getIdentifierCollection().update(mPatchGroupManager.update(identifier)); + } + + if(mac instanceof UnitToUnitVoiceChannelUserExtended) + { + UnitToUnitVoiceChannelUserExtended uuvcue = (UnitToUnitVoiceChannelUserExtended)mac; + + if(uuvcue.getServiceOptions().isEncrypted()) + { + updateCurrentCall(DecodeEventType.CALL_UNIT_TO_UNIT_ENCRYPTED, null, message.getTimestamp()); + } + else + { + updateCurrentCall(DecodeEventType.CALL_UNIT_TO_UNIT, null, message.getTimestamp()); + } + } + } + } + + private void processUTUVCU(MacMessage message, MacStructure mac) { + if(message.getMacPduType() == MacPduType.MAC_6_HANGTIME) + { + closeCurrentCallEvent(message.getTimestamp(), false, MacPduType.MAC_6_HANGTIME); + + for(Identifier identifier : mac.getIdentifiers()) + { + //Add to the identifier collection after filtering through the patch group manager + getIdentifierCollection().update(mPatchGroupManager.update(identifier)); + } + } + else + { + for(Identifier identifier : mac.getIdentifiers()) + { + //Add to the identifier collection after filtering through the patch group manager + getIdentifierCollection().update(mPatchGroupManager.update(identifier)); + } + + if(mac instanceof UnitToUnitVoiceChannelUserAbbreviated) + { + UnitToUnitVoiceChannelUserAbbreviated uuvcua = (UnitToUnitVoiceChannelUserAbbreviated)mac; + + if(uuvcua.getServiceOptions().isEncrypted()) + { + updateCurrentCall(DecodeEventType.CALL_UNIT_TO_UNIT_ENCRYPTED, null, message.getTimestamp()); + } + else + { + updateCurrentCall(DecodeEventType.CALL_UNIT_TO_UNIT, null, message.getTimestamp()); + } + } + } + } + + private void processGVCUExtended(MacMessage message, MacStructure mac) { + if(message.getMacPduType() == MacPduType.MAC_6_HANGTIME) + { + closeCurrentCallEvent(message.getTimestamp(), false, MacPduType.MAC_6_HANGTIME); + + for(Identifier identifier : mac.getIdentifiers()) + { + //Add to the identifier collection after filtering through the patch group manager + getIdentifierCollection().update(mPatchGroupManager.update(identifier)); + } + } + else + { + for(Identifier identifier : mac.getIdentifiers()) + { + //Add to the identifier collection after filtering through the patch group manager + getIdentifierCollection().update(mPatchGroupManager.update(identifier)); + } + + if(mac instanceof GroupVoiceChannelUserExtended) + { + GroupVoiceChannelUserExtended gvcue = (GroupVoiceChannelUserExtended)mac; + + if(gvcue.getServiceOptions().isEncrypted()) + { + updateCurrentCall(DecodeEventType.CALL_GROUP_ENCRYPTED, null, message.getTimestamp()); + } + else + { + updateCurrentCall(DecodeEventType.CALL_GROUP, null, message.getTimestamp()); + } + } + } + } + + private void processGVCUAbbreviated(MacMessage message, MacStructure mac) { + if(message.getMacPduType() == MacPduType.MAC_6_HANGTIME) + { + closeCurrentCallEvent(message.getTimestamp(), false, MacPduType.MAC_6_HANGTIME); + + for(Identifier identifier : mac.getIdentifiers()) + { + //Add to the identifier collection after filtering through the patch group manager + getIdentifierCollection().update(mPatchGroupManager.update(identifier)); + } + } + else + { + for(Identifier identifier : mac.getIdentifiers()) + { + //Add to the identifier collection after filtering through the patch group manager + getIdentifierCollection().update(mPatchGroupManager.update(identifier)); + } + + if(mac instanceof GroupVoiceChannelUserAbbreviated) + { + GroupVoiceChannelUserAbbreviated gvcua = (GroupVoiceChannelUserAbbreviated)mac; + + if(gvcua.getServiceOptions().isEncrypted()) + { + updateCurrentCall(DecodeEventType.CALL_GROUP_ENCRYPTED, null, message.getTimestamp()); + } + else + { + updateCurrentCall(DecodeEventType.CALL_GROUP, null, message.getTimestamp()); + } + } + } + } + + private void processEndPushToTalk(MacMessage message, MacStructure mac) { + if(mac instanceof EndPushToTalk) + { + //Add the set of identifiers before we close out the call event to ensure they're captured in + //the closing event. + if(mCurrentCallEvent != null) + { + for(Identifier identifier : mac.getIdentifiers()) + { + if(identifier.getRole() == Role.FROM) + { + if(identifier instanceof APCO25RadioIdentifier) + { + int value = ((APCO25RadioIdentifier)identifier).getValue(); + + //Group call End PTT uses a FROM value of 0xFFFFFF - don't overwrite the correct id + if(value != SYSTEM_CONTROLLER) + { + getIdentifierCollection().update(mPatchGroupManager.update(identifier)); + } + } + } + else if(identifier.getRole() == Role.TO) + { + if(identifier instanceof APCO25Talkgroup) + { + int value = ((APCO25Talkgroup)identifier).getValue(); + + //Individual call End PTT uses a TO value of 0 - don't overwrite the correct id + if(value != 0) + { + getIdentifierCollection().update(mPatchGroupManager.update(identifier)); + } + } + } + else + { + getIdentifierCollection().update(mPatchGroupManager.update(identifier)); + } + } + } + + if(message.getDataUnitID().isFACCH()) + { + mEndPttOnFacchCounter++; + + //FNE sending 2 or more End PTT in FACCH timeslots indicates a channel teardown event. + if(mEndPttOnFacchCounter > 1) + { + if(mChannelType == ChannelType.TRAFFIC) + { + closeCurrentCallEvent(message.getTimestamp(), true, MacPduType.MAC_2_END_PTT); + //Don't send a continue state here ... the close() method will send the TEARDOWN state + } + //Otherwise the channel state is set to ACTIVE in anticipation of further call activity + else + { + closeCurrentCallEvent(message.getTimestamp(), true, MacPduType.MAC_4_ACTIVE); + continueState(State.RESET); + } + } + } + else + { + closeCurrentCallEvent(message.getTimestamp(), true, MacPduType.MAC_4_ACTIVE); + } + } + } + + private void processPushToTalk(MacMessage message, MacStructure mac) { + for(Identifier identifier : mac.getIdentifiers()) + { + //Add to the identifier collection after filtering through the patch group manager + getIdentifierCollection().update(mPatchGroupManager.update(identifier)); + } + + PushToTalk ptt = (PushToTalk)mac; + + if(ptt.isEncrypted()) + { + updateCurrentCall(DecodeEventType.CALL_ENCRYPTED, ptt.getEncryptionKey().toString(), message.getTimestamp()); + } + else + { + updateCurrentCall(DecodeEventType.CALL, null, message.getTimestamp()); + } + } + /** * Indicates if the identifier argument matches the current (TO) talkgroup for this channel and timeslot * @param identifier to match diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase2/P25P2NetworkConfigurationMonitor.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase2/P25P2NetworkConfigurationMonitor.java index 1fb24a87..37ac78ad 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase2/P25P2NetworkConfigurationMonitor.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase2/P25P2NetworkConfigurationMonitor.java @@ -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 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 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 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(); diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase2/P25P2SyncDetector.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase2/P25P2SyncDetector.java index 96823702..d609d9c4 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase2/P25P2SyncDetector.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase2/P25P2SyncDetector.java @@ -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 public void setSampleRate(double sampleRate) { mSampleRate = sampleRate; - mPllCorrection = 2.0 * Math.PI * mFrequencyCorrection / mSampleRate; + mPllCorrection = 2.0 * FastMath.PI * mFrequencyCorrection / mSampleRate; } } } diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase2/message/InterSlotSignallingChannel.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase2/message/InterSlotSignallingChannel.java index 289d4f33..64f79131 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase2/message/InterSlotSignallingChannel.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase2/message/InterSlotSignallingChannel.java @@ -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); } } diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase2/message/mac/MacOpcode.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase2/message/mac/MacOpcode.java index ca91fd61..e80c927a 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase2/message/mac/MacOpcode.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase2/message/mac/MacOpcode.java @@ -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) diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase2/message/mac/structure/FrequencyBandUpdateTDMA.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase2/message/mac/structure/FrequencyBandUpdateTDMA.java index 86914512..fde26820 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase2/message/mac/structure/FrequencyBandUpdateTDMA.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase2/message/mac/structure/FrequencyBandUpdateTDMA.java @@ -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 diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/reference/ChannelType.java b/src/main/java/io/github/dsheirer/module/decode/p25/reference/ChannelType.java index ca8ce3f3..33d67fbd 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/reference/ChannelType.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/reference/ChannelType.java @@ -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(); diff --git a/src/main/java/io/github/dsheirer/module/decode/passport/PassportBand.java b/src/main/java/io/github/dsheirer/module/decode/passport/PassportBand.java index f855ff63..7bfcb44a 100644 --- a/src/main/java/io/github/dsheirer/module/decode/passport/PassportBand.java +++ b/src/main/java/io/github/dsheirer/module/decode/passport/PassportBand.java @@ -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 ); } diff --git a/src/main/java/io/github/dsheirer/module/decode/passport/PassportDecoderState.java b/src/main/java/io/github/dsheirer/module/decode/passport/PassportDecoderState.java index 6f9d55cc..beedce88 100644 --- a/src/main/java/io/github/dsheirer/module/decode/passport/PassportDecoderState.java +++ b/src/main/java/io/github/dsheirer/module/decode/passport/PassportDecoderState.java @@ -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 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 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 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 it = mMobileIDs.iterator(); - while(it.hasNext()) - { - sb.append(" ").append(it.next()).append("\n"); + for (PassportTalkgroup mMobileID : mMobileIDs) { + sb.append(" ").append(mMobileID).append("\n"); } } diff --git a/src/main/java/io/github/dsheirer/module/decode/passport/PassportMessage.java b/src/main/java/io/github/dsheirer/module/decode/passport/PassportMessage.java index f67c6520..4466bb33 100644 --- a/src/main/java/io/github/dsheirer/module/decode/passport/PassportMessage.java +++ b/src/main/java/io/github/dsheirer/module/decode/passport/PassportMessage.java @@ -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 diff --git a/src/main/java/io/github/dsheirer/module/decode/passport/PassportMessageFilter.java b/src/main/java/io/github/dsheirer/module/decode/passport/PassportMessageFilter.java index f58b086f..f4ea669b 100644 --- a/src/main/java/io/github/dsheirer/module/decode/passport/PassportMessageFilter.java +++ b/src/main/java/io/github/dsheirer/module/decode/passport/PassportMessageFilter.java @@ -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 { - private Map> mElements = new HashMap>(); + private Map> mElements = new EnumMap<>(MessageType.class); public PassportMessageFilter() { diff --git a/src/main/java/io/github/dsheirer/preference/identifier/TalkgroupFormatPreference.java b/src/main/java/io/github/dsheirer/preference/identifier/TalkgroupFormatPreference.java index 489a4c6c..af8f07e9 100644 --- a/src/main/java/io/github/dsheirer/preference/identifier/TalkgroupFormatPreference.java +++ b/src/main/java/io/github/dsheirer/preference/identifier/TalkgroupFormatPreference.java @@ -39,6 +39,7 @@ import io.github.dsheirer.sample.Listener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.EnumMap; import java.util.HashMap; import java.util.Map; import java.util.prefs.Preferences; @@ -54,8 +55,8 @@ public class TalkgroupFormatPreference extends Preference public static final String TALKGROUP_FORMAT_PROPERTY = "talkgroup.format."; public static final String TALKGROUP_FIXED_WIDTH_PROPERTY = "talkgroup.fixed.width."; - private Map mTalkgroupFormatProtocolMap = new HashMap<>(); - private Map mTalkgroupFixedWidthProtocolMap = new HashMap<>(); + private Map mTalkgroupFormatProtocolMap = new EnumMap<>(Protocol.class); + private Map mTalkgroupFixedWidthProtocolMap = new EnumMap<>(Protocol.class); /** * Constructs an instance of identifier formatting preference. @@ -214,9 +215,9 @@ public class TalkgroupFormatPreference extends Preference */ public IntegerFormat getTalkgroupFormat(Protocol protocol) { - if(mTalkgroupFormatProtocolMap.containsKey(protocol)) - { - return mTalkgroupFormatProtocolMap.get(protocol); + IntegerFormat mapValue = mTalkgroupFormatProtocolMap.get(protocol); + if (mapValue != null) { + return mapValue; } return IntegerFormat.DECIMAL; diff --git a/src/main/java/io/github/dsheirer/record/wave/AudioMetadataUtils.java b/src/main/java/io/github/dsheirer/record/wave/AudioMetadataUtils.java index 3f834609..6da95f9f 100644 --- a/src/main/java/io/github/dsheirer/record/wave/AudioMetadataUtils.java +++ b/src/main/java/io/github/dsheirer/record/wave/AudioMetadataUtils.java @@ -43,11 +43,7 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.charset.Charset; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public class AudioMetadataUtils { @@ -79,7 +75,7 @@ public class AudioMetadataUtils */ public static Map getMetadataMap(IdentifierCollection identifierCollection, AliasList aliasList) { - Map audioMetadata = new HashMap<>(); + Map audioMetadata = new EnumMap<>(AudioMetadata.class); StringBuilder comments = new StringBuilder(); audioMetadata.put(AudioMetadata.COMPOSER, SystemProperties.getInstance().getApplicationName()); String dateCreated = SDF.format(new Date(System.currentTimeMillis())); @@ -186,36 +182,36 @@ public class AudioMetadataUtils { ID3v24Tag tag = new ID3v24Tag(); - for(AudioMetadata metadata: metadataMap.keySet()) + for(Map.Entry entry : metadataMap.entrySet()) { - switch(metadata) + switch(entry.getKey()) { case ALBUM_TITLE: - tag.setAlbum(metadataMap.get(metadata)); + tag.setAlbum(entry.getValue()); break; case ARTIST_NAME: - tag.setArtist(metadataMap.get(metadata)); + tag.setArtist(entry.getValue()); break; case COMMENTS: - tag.setComment(metadataMap.get(metadata)); + tag.setComment(entry.getValue()); break; case COMPOSER: - tag.setComposer(metadataMap.get(metadata)); + tag.setComposer(entry.getValue()); break; case DATE_CREATED: - tag.setDate(metadataMap.get(metadata)); + tag.setDate(entry.getValue()); break; case GENRE: - tag.setGenreDescription(metadataMap.get(metadata)); + tag.setGenreDescription(entry.getValue()); break; case GROUPING: - tag.setGrouping(metadataMap.get(metadata)); + tag.setGrouping(entry.getValue()); break; case TRACK_TITLE: - tag.setTitle(metadataMap.get(metadata)); + tag.setTitle(entry.getValue()); break; case YEAR: - tag.setYear(metadataMap.get(metadata)); + tag.setYear(entry.getValue()); break; } } diff --git a/src/main/java/io/github/dsheirer/sample/Broadcaster.java b/src/main/java/io/github/dsheirer/sample/Broadcaster.java index 5605a00f..5ed2569d 100644 --- a/src/main/java/io/github/dsheirer/sample/Broadcaster.java +++ b/src/main/java/io/github/dsheirer/sample/Broadcaster.java @@ -117,7 +117,7 @@ public class Broadcaster implements Listener */ public void removeListener(Listener listener) { - if(listener != null && mListeners.contains(listener)) + if(listener != null) { mListeners.remove(listener); } diff --git a/src/main/java/io/github/dsheirer/sample/adapter/ComplexShortAdapter.java b/src/main/java/io/github/dsheirer/sample/adapter/ComplexShortAdapter.java index 6530694d..2b39e9c2 100644 --- a/src/main/java/io/github/dsheirer/sample/adapter/ComplexShortAdapter.java +++ b/src/main/java/io/github/dsheirer/sample/adapter/ComplexShortAdapter.java @@ -28,7 +28,6 @@ import java.nio.ByteOrder; public class ComplexShortAdapter extends ComplexSampleAdapter { private final static Logger mLog = LoggerFactory.getLogger(ComplexShortAdapter.class); - private ShortToFloatMap mMap = new ShortToFloatMap(); private ByteOrder mByteOrder = ByteOrder.LITTLE_ENDIAN; private ByteBuffer mByteBuffer; @@ -57,7 +56,7 @@ public class ComplexShortAdapter extends ComplexSampleAdapter while(mByteBuffer.hasRemaining()) { - convertedSamples[pointer] = mMap.get(mByteBuffer.getShort()); + convertedSamples[pointer] = (float) mByteBuffer.getShort() / 32768.0f; pointer++; } diff --git a/src/main/java/io/github/dsheirer/sample/adapter/RealChannelShortAdapter.java b/src/main/java/io/github/dsheirer/sample/adapter/RealChannelShortAdapter.java index 522fd879..fd1f5180 100644 --- a/src/main/java/io/github/dsheirer/sample/adapter/RealChannelShortAdapter.java +++ b/src/main/java/io/github/dsheirer/sample/adapter/RealChannelShortAdapter.java @@ -30,7 +30,6 @@ import java.nio.ByteOrder; public class RealChannelShortAdapter extends RealSampleAdapter { private final static Logger mLog = LoggerFactory.getLogger(RealChannelShortAdapter.class); - private ShortToFloatMap mMap = new ShortToFloatMap(); private ByteOrder mByteOrder = ByteOrder.LITTLE_ENDIAN; private MixerChannel mMixerChannel; private ByteBuffer mByteBuffer; @@ -62,7 +61,7 @@ public class RealChannelShortAdapter extends RealSampleAdapter { if(mMixerChannel == MixerChannel.LEFT) { - convertedSamples[pointer++] = mMap.get(mByteBuffer.getShort()); + convertedSamples[pointer++] = (float) mByteBuffer.getShort() / 32768.0f; //Throw away the right channel mByteBuffer.getShort(); @@ -72,7 +71,7 @@ public class RealChannelShortAdapter extends RealSampleAdapter //Throw away the left channel mByteBuffer.getShort(); - convertedSamples[pointer++] = mMap.get(mByteBuffer.getShort()); + convertedSamples[pointer++] = (float) mByteBuffer.getShort() / 32768.0f; } } diff --git a/src/main/java/io/github/dsheirer/sample/adapter/RealShortAdapter.java b/src/main/java/io/github/dsheirer/sample/adapter/RealShortAdapter.java index 04670d5a..683c04d1 100644 --- a/src/main/java/io/github/dsheirer/sample/adapter/RealShortAdapter.java +++ b/src/main/java/io/github/dsheirer/sample/adapter/RealShortAdapter.java @@ -26,7 +26,6 @@ import java.nio.ByteOrder; public class RealShortAdapter extends RealSampleAdapter { private ByteBuffer mByteBuffer; - private ShortToFloatMap mMap = new ShortToFloatMap(); private ByteOrder mByteOrder = ByteOrder.LITTLE_ENDIAN; /** @@ -54,7 +53,7 @@ public class RealShortAdapter extends RealSampleAdapter while(mByteBuffer.hasRemaining()) { - convertedSamples[pointer] = mMap.get(mByteBuffer.getShort()); + convertedSamples[pointer] = (float) mByteBuffer.getShort() / 32768.0f; pointer++; } diff --git a/src/main/java/io/github/dsheirer/sample/adapter/ShortToFloatMap.java b/src/main/java/io/github/dsheirer/sample/adapter/ShortToFloatMap.java deleted file mode 100644 index b95f7b03..00000000 --- a/src/main/java/io/github/dsheirer/sample/adapter/ShortToFloatMap.java +++ /dev/null @@ -1,19 +0,0 @@ -package io.github.dsheirer.sample.adapter; - -public class ShortToFloatMap -{ - private static float[] MAP = new float[ 65536 ]; - - static - { - for( int x = 0; x < 65536; x++ ) - { - MAP[ x] = (float)( x - 32768 ) / 32768.0f; - } - } - - public float get( short value ) - { - return MAP[ 32768 + value ]; - } -} diff --git a/src/main/java/io/github/dsheirer/sample/complex/Complex.java b/src/main/java/io/github/dsheirer/sample/complex/Complex.java index 06234564..977cbfc8 100644 --- a/src/main/java/io/github/dsheirer/sample/complex/Complex.java +++ b/src/main/java/io/github/dsheirer/sample/complex/Complex.java @@ -21,6 +21,7 @@ */ package io.github.dsheirer.sample.complex; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -213,12 +214,12 @@ public class Complex implements Serializable */ public float magnitude() { - return (float)Math.sqrt(magnitudeSquared()); + return (float)FastMath.sqrt(magnitudeSquared()); } public static float magnitude(float inphase, float quadrature) { - return (float)Math.sqrt((inphase * inphase) + (quadrature * quadrature)); + return (float) FastMath.sqrt((inphase * inphase) + (quadrature * quadrature)); } /** @@ -266,8 +267,8 @@ public class Complex implements Serializable */ public void normalizeFast() { - float inphaseAbsolute = Math.abs(inphase()); - float quadratureAbsolute = Math.abs(quadrature()); + float inphaseAbsolute = FastMath.abs(inphase()); + float quadratureAbsolute = FastMath.abs(quadrature()); float gain; @@ -303,7 +304,7 @@ public class Complex implements Serializable */ public float inPhaseAbsolute() { - return Math.abs(mLeft); + return FastMath.abs(mLeft); } public float quadrature() @@ -316,7 +317,7 @@ public class Complex implements Serializable */ public float quadratureAbsolute() { - return Math.abs(mRight); + return FastMath.abs(mRight); } public float x() @@ -339,7 +340,7 @@ public class Complex implements Serializable */ public float realAbsolute() { - return Math.abs(mLeft); + return FastMath.abs(mLeft); } public float imaginary() @@ -352,7 +353,7 @@ public class Complex implements Serializable */ public float imaginaryAbsolute() { - return Math.abs(mRight); + return FastMath.abs(mRight); } /** @@ -360,14 +361,7 @@ public class Complex implements Serializable */ public float maximumAbsolute() { - if(Math.abs(mLeft) > Math.abs(mRight)) - { - return Math.abs(mLeft); - } - else - { - return Math.abs(mRight); - } + return FastMath.max(FastMath.abs(mLeft), FastMath.abs(mRight)); } /** @@ -379,7 +373,7 @@ public class Complex implements Serializable */ public static Complex fromAngle(double angle) { - return new Complex((float)Math.cos(angle), (float)Math.sin(angle)); + return new Complex((float)FastMath.cos(angle), (float)FastMath.sin(angle)); } /** @@ -388,8 +382,8 @@ public class Complex implements Serializable */ public void setAngle(double angle) { - setInphase((float)Math.cos(angle)); - setQuadrature((float)Math.sin(angle)); + setInphase((float)FastMath.cos(angle)); + setQuadrature((float)FastMath.sin(angle)); } /** @@ -397,7 +391,7 @@ public class Complex implements Serializable */ public float angle() { - return (float)Math.atan2(y(), x()); + return (float)FastMath.atan2(y(), x()); } /** @@ -406,7 +400,7 @@ public class Complex implements Serializable */ public double angleDegrees() { - return Math.toDegrees(Math.atan2(y(), x())); + return FastMath.toDegrees(FastMath.atan2(y(), x())); } /** @@ -414,7 +408,7 @@ public class Complex implements Serializable */ public double polarAngleDegrees() { - double angle = Math.toDegrees(Math.atan2(y(), x())); + double angle = FastMath.toDegrees(FastMath.atan2(y(), x())); return (450.0 - angle) % 360.0; } @@ -449,7 +443,7 @@ public class Complex implements Serializable */ public float polarAngle() { - return (float)Math.toDegrees(angle()); + return (float)FastMath.toDegrees(angle()); } /** @@ -462,8 +456,8 @@ public class Complex implements Serializable public static float envelope(float inphase, float quadrature) { - float inphaseAbsolute = Math.abs(inphase); - float quadratureAbsolute = Math.abs(quadrature); + float inphaseAbsolute = FastMath.abs(inphase); + float quadratureAbsolute = FastMath.abs(quadrature); if(inphaseAbsolute > quadratureAbsolute) { diff --git a/src/main/java/io/github/dsheirer/sample/complex/ComplexSampleUtils.java b/src/main/java/io/github/dsheirer/sample/complex/ComplexSampleUtils.java index 2cada398..63e5a8ab 100644 --- a/src/main/java/io/github/dsheirer/sample/complex/ComplexSampleUtils.java +++ b/src/main/java/io/github/dsheirer/sample/complex/ComplexSampleUtils.java @@ -18,6 +18,8 @@ package io.github.dsheirer.sample.complex; +import org.apache.commons.math3.util.FastMath; + public class ComplexSampleUtils { @@ -37,7 +39,7 @@ public class ComplexSampleUtils public static double magnitude( Complex sample ) { - return Math.sqrt( magnitudeSquared( sample ) ); + return FastMath.sqrt( magnitudeSquared( sample ) ); } public static int magnitudeSquared( Complex sample ) diff --git a/src/main/java/io/github/dsheirer/source/mixer/MixerManager.java b/src/main/java/io/github/dsheirer/source/mixer/MixerManager.java index 6673921e..d674afc3 100644 --- a/src/main/java/io/github/dsheirer/source/mixer/MixerManager.java +++ b/src/main/java/io/github/dsheirer/source/mixer/MixerManager.java @@ -311,11 +311,11 @@ public class MixerManager for(Mixer.Info mixerInfo : AudioSystem.getMixerInfo()) { sb.append("\n--------------------------------------------------"); - sb.append("\nMIXER name:" + mixerInfo.getName() + - "\n desc:" + mixerInfo.getDescription() + - "\n vendor:" + mixerInfo.getVendor() + - "\n version:" + mixerInfo.getVersion() + - "\n"); + sb.append("\nMIXER name:").append(mixerInfo.getName()) + .append("\n desc:").append(mixerInfo.getDescription()) + .append("\n vendor:").append(mixerInfo.getVendor()) + .append("\n version:").append(mixerInfo.getVersion()) + .append("\n"); Mixer mixer = AudioSystem.getMixer(mixerInfo); @@ -323,20 +323,20 @@ public class MixerManager for(Line.Info lineInfo : sourceLines) { - sb.append(" SOURCE LINE desc:" + lineInfo.toString() + - "\n class:" + lineInfo.getClass() + - "\n lineclass:" + lineInfo.getLineClass() + - "\n"); + sb.append(" SOURCE LINE desc:").append(lineInfo) + .append("\n class:").append(lineInfo.getClass()) + .append("\n lineclass:").append(lineInfo.getLineClass()) + .append("\n"); } Line.Info[] targetLines = mixer.getTargetLineInfo(); for(Line.Info lineInfo : targetLines) { - sb.append(" TARGET LINE desc:" + lineInfo.toString() + - "\n class:" + lineInfo.getClass() + - "\n lineclass:" + lineInfo.getLineClass() + - "\n"); + sb.append(" TARGET LINE desc:").append(lineInfo) + .append("\n class:").append(lineInfo.getClass()) + .append("\n lineclass:").append(lineInfo.getLineClass()) + .append("\n"); } Line.Info portInfo = new Line.Info(Port.class); diff --git a/src/main/java/io/github/dsheirer/source/mixer/MixerSourceEditor.java b/src/main/java/io/github/dsheirer/source/mixer/MixerSourceEditor.java index 213beca2..9958376e 100644 --- a/src/main/java/io/github/dsheirer/source/mixer/MixerSourceEditor.java +++ b/src/main/java/io/github/dsheirer/source/mixer/MixerSourceEditor.java @@ -64,7 +64,7 @@ public class MixerSourceEditor extends Editor EnumSet channels = selected.getChannels(); mComboChannels.setModel(new DefaultComboBoxModel( - channels.toArray(new MixerChannel[channels.size()]))); + channels.toArray(new MixerChannel[0]))); repaint(); @@ -84,7 +84,7 @@ public class MixerSourceEditor extends Editor EnumSet channels = selected.getChannels(); mComboChannels.setModel(new DefaultComboBoxModel( - channels.toArray(new MixerChannel[channels.size()]))); + channels.toArray(new MixerChannel[0]))); } mComboChannels.setEnabled(false); diff --git a/src/main/java/io/github/dsheirer/source/mixer/SystemMixerDevices.java b/src/main/java/io/github/dsheirer/source/mixer/SystemMixerDevices.java index 84523ef2..2642a6a4 100644 --- a/src/main/java/io/github/dsheirer/source/mixer/SystemMixerDevices.java +++ b/src/main/java/io/github/dsheirer/source/mixer/SystemMixerDevices.java @@ -81,11 +81,11 @@ public class SystemMixerDevices { for( Mixer.Info mixerInfo: AudioSystem.getMixerInfo() ) { sb.append( "\n--------------------------------------------------" ); - sb.append( "\nMIXER name:" + mixerInfo.getName() + - "\n desc:" + mixerInfo.getDescription() + - "\n vendor:" + mixerInfo.getVendor() + - "\n version:" + mixerInfo.getVersion() + - "\n" ); + sb.append("\nMIXER name:").append(mixerInfo.getName()) + .append("\n desc:").append(mixerInfo.getDescription()) + .append("\n vendor:").append(mixerInfo.getVendor()) + .append("\n version:").append(mixerInfo.getVersion()) + .append("\n"); Mixer mixer = AudioSystem.getMixer( mixerInfo ); @@ -93,20 +93,20 @@ public class SystemMixerDevices { for( Line.Info lineInfo: sourceLines ) { - sb.append( " SOURCE LINE desc:" + lineInfo.toString() + - "\n class:" + lineInfo.getClass() + - "\n lineclass:" + lineInfo.getLineClass() + - "\n" ); + sb.append(" SOURCE LINE desc:").append(lineInfo) + .append("\n class:").append(lineInfo.getClass()) + .append("\n lineclass:").append(lineInfo.getLineClass()) + .append("\n"); } Line.Info[] targetLines = mixer.getTargetLineInfo(); for( Line.Info lineInfo: targetLines ) { - sb.append( " TARGET LINE desc:" + lineInfo.toString() + - "\n class:" + lineInfo.getClass() + - "\n lineclass:" + lineInfo.getLineClass() + - "\n" ); + sb.append(" TARGET LINE desc:").append(lineInfo) + .append("\n class:").append(lineInfo.getClass()) + .append("\n lineclass:").append(lineInfo.getLineClass()) + .append("\n"); } } diff --git a/src/main/java/io/github/dsheirer/source/tuner/TunerManager.java b/src/main/java/io/github/dsheirer/source/tuner/TunerManager.java index f4995975..494140ab 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/TunerManager.java +++ b/src/main/java/io/github/dsheirer/source/tuner/TunerManager.java @@ -173,7 +173,7 @@ public class TunerManager { sb.append(" NOT LOADED: "); sb.append(status.getInfo()); - sb.append(" Error:" + e.getMessage()); + sb.append(" Error:").append(e.getMessage()); } } else diff --git a/src/main/java/io/github/dsheirer/source/tuner/TunerSourceEditor.java b/src/main/java/io/github/dsheirer/source/tuner/TunerSourceEditor.java index b0fb0e3b..309f111b 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/TunerSourceEditor.java +++ b/src/main/java/io/github/dsheirer/source/tuner/TunerSourceEditor.java @@ -69,7 +69,7 @@ public class TunerSourceEditor extends Editor }); add(mFrequencyControl); - mTunerNameComboBox = new JComboBox<>(mCurrentTunerNames.toArray(new String[mCurrentTunerNames.size()])); + mTunerNameComboBox = new JComboBox<>(mCurrentTunerNames.toArray(new String[0])); mTunerNameComboBox.addActionListener(new ActionListener() { @Override @@ -103,13 +103,13 @@ public class TunerSourceEditor extends Editor List updatedTunerNameList = new ArrayList<>(mCurrentTunerNames); String unavailableTuner = preferredTuner + UNAVAILABLE_TUNER; updatedTunerNameList.add(unavailableTuner); - String[] tunerNameArray = updatedTunerNameList.toArray(new String[updatedTunerNameList.size()]); + String[] tunerNameArray = updatedTunerNameList.toArray(new String[0]); mTunerNameComboBox.setModel(new DefaultComboBoxModel<>(tunerNameArray)); mTunerNameComboBox.setSelectedItem(unavailableTuner); } else { - String[] tunerNameArray = mCurrentTunerNames.toArray(new String[mCurrentTunerNames.size()]); + String[] tunerNameArray = mCurrentTunerNames.toArray(new String[0]); mTunerNameComboBox.setModel(new DefaultComboBoxModel<>(tunerNameArray)); if(preferredTuner == null) diff --git a/src/main/java/io/github/dsheirer/source/tuner/TunerSourceMultipleFrequencyEditor.java b/src/main/java/io/github/dsheirer/source/tuner/TunerSourceMultipleFrequencyEditor.java index 068b3a84..fc594952 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/TunerSourceMultipleFrequencyEditor.java +++ b/src/main/java/io/github/dsheirer/source/tuner/TunerSourceMultipleFrequencyEditor.java @@ -71,7 +71,7 @@ public class TunerSourceMultipleFrequencyEditor extends Editor // mFrequencyEditor.setSize(new Dimension(100, 30)); add(mFrequencyEditor, "span 2 2"); - mTunerNameComboBox = new JComboBox<>(mCurrentTunerNames.toArray(new String[mCurrentTunerNames.size()])); + mTunerNameComboBox = new JComboBox<>(mCurrentTunerNames.toArray(new String[0])); mTunerNameComboBox.addActionListener(new ActionListener() { @Override @@ -105,13 +105,13 @@ public class TunerSourceMultipleFrequencyEditor extends Editor List updatedTunerNameList = new ArrayList<>(mCurrentTunerNames); String unavailableTuner = preferredTuner + UNAVAILABLE_TUNER; updatedTunerNameList.add(unavailableTuner); - String[] tunerNameArray = updatedTunerNameList.toArray(new String[updatedTunerNameList.size()]); + String[] tunerNameArray = updatedTunerNameList.toArray(new String[0]); mTunerNameComboBox.setModel(new DefaultComboBoxModel<>(tunerNameArray)); mTunerNameComboBox.setSelectedItem(unavailableTuner); } else { - String[] tunerNameArray = mCurrentTunerNames.toArray(new String[mCurrentTunerNames.size()]); + String[] tunerNameArray = mCurrentTunerNames.toArray(new String[0]); mTunerNameComboBox.setModel(new DefaultComboBoxModel<>(tunerNameArray)); if(preferredTuner == null) diff --git a/src/main/java/io/github/dsheirer/source/tuner/airspy/AirspyTunerEditor.java b/src/main/java/io/github/dsheirer/source/tuner/airspy/AirspyTunerEditor.java index c5ef8437..342e4e87 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/airspy/AirspyTunerEditor.java +++ b/src/main/java/io/github/dsheirer/source/tuner/airspy/AirspyTunerEditor.java @@ -150,7 +150,7 @@ public class AirspyTunerEditor extends TunerConfigurationEditor mSampleRateCombo = new JComboBox( new DefaultComboBoxModel(rates.toArray( - new AirspySampleRate[rates.size()]))); + new AirspySampleRate[0]))); mSampleRateCombo.setEnabled(false); mSampleRateCombo.addActionListener(new ActionListener() { diff --git a/src/main/java/io/github/dsheirer/source/tuner/hackrf/HackRFTunerEditor.java b/src/main/java/io/github/dsheirer/source/tuner/hackrf/HackRFTunerEditor.java index 80abb013..629bf648 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/hackrf/HackRFTunerEditor.java +++ b/src/main/java/io/github/dsheirer/source/tuner/hackrf/HackRFTunerEditor.java @@ -125,7 +125,7 @@ public class HackRFTunerEditor extends TunerConfigurationEditor HackRFSampleRate[] validRates = HackRFSampleRate.VALID_SAMPLE_RATES - .toArray(new HackRFSampleRate[HackRFSampleRate.VALID_SAMPLE_RATES.size()]); + .toArray(new HackRFSampleRate[0]); mComboSampleRate = new JComboBox<>(validRates); mComboSampleRate.setEnabled(false); mComboSampleRate.addActionListener(new ActionListener() diff --git a/src/main/java/io/github/dsheirer/source/tuner/manager/PolyphaseChannelSourceManager.java b/src/main/java/io/github/dsheirer/source/tuner/manager/PolyphaseChannelSourceManager.java index 680f01a3..151f88ca 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/manager/PolyphaseChannelSourceManager.java +++ b/src/main/java/io/github/dsheirer/source/tuner/manager/PolyphaseChannelSourceManager.java @@ -28,6 +28,7 @@ import io.github.dsheirer.source.tuner.TunerController; import io.github.dsheirer.source.tuner.channel.ChannelSpecification; import io.github.dsheirer.source.tuner.channel.TunerChannel; import io.github.dsheirer.source.tuner.channel.TunerChannelSource; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -215,7 +216,7 @@ public class PolyphaseChannelSourceManager extends ChannelSourceManager //Align the test frequency to the next greater integral frequency placing the first channel at the // minimum extreme of the available bandwidth as a starting location - double delta = Math.abs(startFrequency - bestIntegralFrequency); + double delta = FastMath.abs(startFrequency - bestIntegralFrequency); double adjustment = delta % mPolyphaseChannelManager.getChannelBandwidth(); startFrequency += adjustment; @@ -329,7 +330,7 @@ public class PolyphaseChannelSourceManager extends ChannelSourceManager */ private boolean isIntegralSpacing(long frequencyA, long frequencyB) { - double delta = Math.abs(frequencyA - frequencyB); + double delta = FastMath.abs(frequencyA - frequencyB); return delta % mPolyphaseChannelManager.getChannelBandwidth() <= 1.0; } @@ -364,7 +365,7 @@ public class PolyphaseChannelSourceManager extends ChannelSourceManager { if(firstChannel != secondChannel) { - double delta = Math.abs(firstChannel.getFrequency() - secondChannel.getFrequency()) % + double delta = FastMath.abs(firstChannel.getFrequency() - secondChannel.getFrequency()) % mPolyphaseChannelManager.getChannelBandwidth(); score += delta; diff --git a/src/main/java/io/github/dsheirer/source/tuner/test/SampleGenerator.java b/src/main/java/io/github/dsheirer/source/tuner/test/SampleGenerator.java index 37d352bd..0e5cdab6 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/test/SampleGenerator.java +++ b/src/main/java/io/github/dsheirer/source/tuner/test/SampleGenerator.java @@ -22,6 +22,7 @@ import io.github.dsheirer.sample.buffer.ReusableBufferBroadcaster; import io.github.dsheirer.sample.buffer.ReusableComplexBuffer; import io.github.dsheirer.sample.buffer.ReusableComplexBufferQueue; import io.github.dsheirer.util.ThreadPool; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,7 +54,7 @@ public class SampleGenerator */ public SampleGenerator(int sampleRate, long frequency, long interval, int sweepUpdateRate) { - if(Math.abs(sweepUpdateRate) >= sampleRate) + if(FastMath.abs(sweepUpdateRate) >= sampleRate) { throw new IllegalArgumentException("Sweep update rate cannot be greater than sample rate"); } diff --git a/src/main/java/io/github/dsheirer/source/tuner/usb/USBUtils.java b/src/main/java/io/github/dsheirer/source/tuner/usb/USBUtils.java index bb57c599..89a982aa 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/usb/USBUtils.java +++ b/src/main/java/io/github/dsheirer/source/tuner/usb/USBUtils.java @@ -39,13 +39,11 @@ public class USBUtils public static List getDevices() throws SecurityException, UsbException, UnsupportedEncodingException { - ArrayList devices = new ArrayList(); - UsbServices services = UsbHostManager.getUsbServices(); UsbHub root = services.getRootUsbHub(); - - devices.addAll( getHubDevices( root ) ); + + ArrayList devices = new ArrayList(getHubDevices(root)); return devices; } @@ -60,20 +58,12 @@ public class USBUtils @SuppressWarnings( "unchecked" ) List children = hub.getAttachedUsbDevices(); - - Iterator it = children.iterator(); - - while( it.hasNext() ) - { - UsbDevice child = it.next(); - - if( child.isUsbHub() ) - { - devices.addAll( getHubDevices( (UsbHub)child ) ); - } - else - { - devices.add( child ); + + for (UsbDevice child : children) { + if (child.isUsbHub()) { + devices.addAll(getHubDevices((UsbHub) child)); + } else { + devices.add(child); } } @@ -85,25 +75,25 @@ public class USBUtils { StringBuilder sb = new StringBuilder(); - sb.append( device.getUsbDeviceDescriptor().toString() + "\n\n" ); + sb.append(device.getUsbDeviceDescriptor().toString()).append("\n\n"); for( Object configObject: device.getUsbConfigurations() ) { UsbConfiguration config = (UsbConfiguration)configObject; - sb.append( config.getUsbConfigurationDescriptor().toString() + "\n\n" ); + sb.append(config.getUsbConfigurationDescriptor().toString()).append("\n\n"); for( Object interfaceObject: config.getUsbInterfaces() ) { UsbInterface iface = (UsbInterface)interfaceObject; - sb.append( iface.getUsbInterfaceDescriptor().toString() + "\n\n" ); + sb.append(iface.getUsbInterfaceDescriptor().toString()).append("\n\n"); for( Object endpointObject: iface.getUsbEndpoints() ) { UsbEndpoint endpoint = (UsbEndpoint)endpointObject; - sb.append( endpoint.getUsbEndpointDescriptor().toString() + "\n\n" ); + sb.append(endpoint.getUsbEndpointDescriptor().toString()).append("\n\n"); } } } diff --git a/src/main/java/io/github/dsheirer/source/wave/ComplexWaveSource.java b/src/main/java/io/github/dsheirer/source/wave/ComplexWaveSource.java index cf8bb760..c011a416 100644 --- a/src/main/java/io/github/dsheirer/source/wave/ComplexWaveSource.java +++ b/src/main/java/io/github/dsheirer/source/wave/ComplexWaveSource.java @@ -30,6 +30,7 @@ import io.github.dsheirer.source.IControllableFileSource; import io.github.dsheirer.source.IFrameLocationListener; import io.github.dsheirer.source.SourceEvent; import io.github.dsheirer.util.ThreadPool; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -367,7 +368,7 @@ public class ComplexWaveSource extends ComplexSource implements IControllableFil public void run() { mIntervals++; - int framesToRead = (int)Math.floor((mIntervals * mFramesPerInterval) - mFramesRead); + int framesToRead = (int) FastMath.floor((mIntervals * mFramesPerInterval) - mFramesRead); try { diff --git a/src/main/java/io/github/dsheirer/spectrum/DFTProcessor.java b/src/main/java/io/github/dsheirer/spectrum/DFTProcessor.java index 3429195f..c1b5bb95 100644 --- a/src/main/java/io/github/dsheirer/spectrum/DFTProcessor.java +++ b/src/main/java/io/github/dsheirer/spectrum/DFTProcessor.java @@ -264,11 +264,9 @@ public class DFTProcessor implements Listener, ISourceEve */ private void dispatch(float[] results) { - Iterator it = mListeners.iterator(); - while(it.hasNext()) - { - it.next().receive(results); + for (DFTResultsConverter mListener : mListeners) { + mListener.receive(results); } } diff --git a/src/main/java/io/github/dsheirer/spectrum/OverlayPanel.java b/src/main/java/io/github/dsheirer/spectrum/OverlayPanel.java index 0e49da2f..173a12f1 100644 --- a/src/main/java/io/github/dsheirer/spectrum/OverlayPanel.java +++ b/src/main/java/io/github/dsheirer/spectrum/OverlayPanel.java @@ -33,6 +33,7 @@ import io.github.dsheirer.settings.SettingsManager; import io.github.dsheirer.source.ISourceEventProcessor; import io.github.dsheirer.source.SourceEvent; import io.github.dsheirer.source.tuner.channel.TunerChannel; +import org.apache.commons.math3.util.FastMath; import javax.swing.JPanel; import java.awt.BasicStroke; @@ -326,7 +327,7 @@ public class OverlayPanel extends JPanel implements Listener, ISou if(mZoom != 0) { - graphics.drawString("Zoom: " + (int)Math.pow(2.0, mZoom) + "x", mCursorLocation.x + 17, + graphics.drawString("Zoom: " + (int)FastMath.pow(2.0, mZoom) + "x", mCursorLocation.x + 17, mCursorLocation.y + 11); } } @@ -504,7 +505,7 @@ public class OverlayPanel extends JPanel implements Listener, ISou double offset = xAxis / width; - long frequency = getMinDisplayFrequency() + Math.round((double)getDisplayBandwidth() * offset); + long frequency = getMinDisplayFrequency() + FastMath.round((double)getDisplayBandwidth() * offset); if(frequency > (getMaxFrequency())) { @@ -761,7 +762,7 @@ public class OverlayPanel extends JPanel implements Listener, ISou public boolean containsFrequency(long frequency) { - return Math.abs(mFrequency - frequency) <= (mBandwidth / 2); + return FastMath.abs(mFrequency - frequency) <= (mBandwidth / 2); } private long getMinDisplayFrequency() @@ -780,7 +781,7 @@ public class OverlayPanel extends JPanel implements Listener, ISou { if(mZoom != 0) { - return mBandwidth / (int)Math.pow(2.0, mZoom); + return mBandwidth / (int)FastMath.pow(2.0, mZoom); } return mBandwidth; @@ -862,14 +863,14 @@ public class OverlayPanel extends JPanel implements Listener, ISou double maxLabels = ((double)OverlayPanel.this.getWidth() * LABEL_FILL_THRESHOLD) / (double)maxLabelWidth; //Calculate the next smallest base 10 value for the major increment - int power = (int)Math.log10((double)getDisplayBandwidth() / maxLabels); + int power = (int)FastMath.log10((double)getDisplayBandwidth() / maxLabels); //Set the number of decimal places to display in frequency labels int precision = 5 - power; - int start = (int)Math.pow(10.0, power + 1); + int start = (int)FastMath.pow(10.0, power + 1); - int minimum = (int)Math.pow(10.0, power); + int minimum = (int)FastMath.pow(10.0, power); int labelIncrement = start; diff --git a/src/main/java/io/github/dsheirer/spectrum/SpectralDisplayPanel.java b/src/main/java/io/github/dsheirer/spectrum/SpectralDisplayPanel.java index 35a9a507..8a64f6d4 100644 --- a/src/main/java/io/github/dsheirer/spectrum/SpectralDisplayPanel.java +++ b/src/main/java/io/github/dsheirer/spectrum/SpectralDisplayPanel.java @@ -49,6 +49,7 @@ import io.github.dsheirer.spectrum.menu.FrameRateItem; import io.github.dsheirer.spectrum.menu.SmoothingItem; import io.github.dsheirer.spectrum.menu.SmoothingTypeItem; import net.miginfocom.swing.MigLayout; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -312,7 +313,7 @@ public class SpectralDisplayPanel extends JPanel implements Listener= 0.0 ) { diff --git a/src/main/java/io/github/dsheirer/util/ThreadPool.java b/src/main/java/io/github/dsheirer/util/ThreadPool.java index 833533bb..3458263e 100644 --- a/src/main/java/io/github/dsheirer/util/ThreadPool.java +++ b/src/main/java/io/github/dsheirer/util/ThreadPool.java @@ -19,6 +19,7 @@ package io.github.dsheirer.util; import io.github.dsheirer.controller.NamingThreadFactory; +import org.apache.commons.math3.util.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,7 +36,7 @@ public class ThreadPool static { //Create a scheduled thread pool sized according to the available processors/cores, minimum 2 - CORES = (CORES < 2 ? 2 : CORES); + CORES = (FastMath.max(CORES, 2)); SCHEDULED = Executors.newScheduledThreadPool(CORES, new NamingThreadFactory("sdrtrunk")); } diff --git a/src/main/java/org/jdesktop/swingx/JXMapViewer.java b/src/main/java/org/jdesktop/swingx/JXMapViewer.java index e61f43e5..6a174b7c 100644 --- a/src/main/java/org/jdesktop/swingx/JXMapViewer.java +++ b/src/main/java/org/jdesktop/swingx/JXMapViewer.java @@ -33,6 +33,7 @@ package org.jdesktop.swingx; import jiconfont.icons.font_awesome.FontAwesome; import jiconfont.swing.IconFontSwing; +import org.apache.commons.math3.util.FastMath; import org.jdesktop.swingx.mapviewer.GeoPosition; import org.jdesktop.swingx.mapviewer.Tile; import org.jdesktop.swingx.mapviewer.TileFactory; @@ -233,8 +234,8 @@ public class JXMapViewer extends JPanel implements DesignMode // TilePoint topLeftTile = getTileFactory().getTileCoordinate( // new Point2D.Double(viewportBounds.x, viewportBounds.y)); TileFactoryInfo info = getTileFactory().getInfo(); - int tpx = (int) Math.floor(viewportBounds.getX() / info.getTileSize(0)); - int tpy = (int) Math.floor(viewportBounds.getY() / info.getTileSize(0)); + int tpx = (int) FastMath.floor(viewportBounds.getX() / info.getTileSize(0)); + int tpy = (int) FastMath.floor(viewportBounds.getY() / info.getTileSize(0)); // TilePoint topLeftTile = new TilePoint(tpx, tpy); // p("top tile = " + topLeftTile); diff --git a/src/main/java/org/jdesktop/swingx/mapviewer/AbstractTileFactory.java b/src/main/java/org/jdesktop/swingx/mapviewer/AbstractTileFactory.java index f94ca983..8dc588cd 100644 --- a/src/main/java/org/jdesktop/swingx/mapviewer/AbstractTileFactory.java +++ b/src/main/java/org/jdesktop/swingx/mapviewer/AbstractTileFactory.java @@ -21,6 +21,7 @@ */ package org.jdesktop.swingx.mapviewer; +import org.apache.commons.math3.util.FastMath; import org.jdesktop.swingx.mapviewer.util.GeoUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -101,7 +102,7 @@ public abstract class AbstractTileFactory extends TileFactory int numTilesWide = (int) getMapSize(zoom).getWidth(); if (tileX < 0) { - tileX = numTilesWide - (Math.abs(tileX) % numTilesWide); + tileX = numTilesWide - (FastMath.abs(tileX) % numTilesWide); } tileX = tileX % numTilesWide; diff --git a/src/main/java/org/jdesktop/swingx/mapviewer/GeoBounds.java b/src/main/java/org/jdesktop/swingx/mapviewer/GeoBounds.java index f7a74eb9..3f76c4c5 100644 --- a/src/main/java/org/jdesktop/swingx/mapviewer/GeoBounds.java +++ b/src/main/java/org/jdesktop/swingx/mapviewer/GeoBounds.java @@ -17,6 +17,8 @@ ******************************************************************************/ package org.jdesktop.swingx.mapviewer; +import org.apache.commons.math3.util.FastMath; + import java.awt.geom.Rectangle2D; import java.util.Set; @@ -60,10 +62,10 @@ public class GeoBounds double maxLng = Integer.MIN_VALUE; for (GeoPosition position : geoPositions) { - minLat = Math.min(minLat, position.getLatitude()); - minLng = Math.min(minLng, position.getLongitude()); - maxLat = Math.max(maxLat, position.getLatitude()); - maxLng = Math.max(maxLng, position.getLongitude()); + minLat = FastMath.min(minLat, position.getLatitude()); + minLng = FastMath.min(minLng, position.getLongitude()); + maxLat = FastMath.max(maxLat, position.getLatitude()); + maxLng = FastMath.max(maxLng, position.getLongitude()); } setRect(minLat, minLng, maxLat, maxLng); } diff --git a/src/main/java/org/jdesktop/swingx/mapviewer/TileFactoryInfo.java b/src/main/java/org/jdesktop/swingx/mapviewer/TileFactoryInfo.java index 3fb97564..41b50f91 100644 --- a/src/main/java/org/jdesktop/swingx/mapviewer/TileFactoryInfo.java +++ b/src/main/java/org/jdesktop/swingx/mapviewer/TileFactoryInfo.java @@ -9,6 +9,8 @@ package org.jdesktop.swingx.mapviewer; +import org.apache.commons.math3.util.FastMath; + import java.awt.geom.Point2D; /** @@ -140,7 +142,7 @@ public class TileFactoryInfo // how wide is each degree of longitude in pixels longitudeDegreeWidthInPixels[z] = tilesize / 360.0; // how wide is each radian of longitude in pixels - longitudeRadianWidthInPixels[z] = tilesize / (2.0 * Math.PI); + longitudeRadianWidthInPixels[z] = tilesize / (2.0 * FastMath.PI); int t2 = tilesize / 2; mapCenterInPixelsAtZoom[z] = new Point2D.Double(t2, t2); mapWidthInTilesAtZoom[z] = tilesize / this.getTileSize(0); diff --git a/src/main/java/org/jdesktop/swingx/mapviewer/bmng/CylindricalProjectionTileFactory.java b/src/main/java/org/jdesktop/swingx/mapviewer/bmng/CylindricalProjectionTileFactory.java index 8d10f153..4ecf7e8c 100644 --- a/src/main/java/org/jdesktop/swingx/mapviewer/bmng/CylindricalProjectionTileFactory.java +++ b/src/main/java/org/jdesktop/swingx/mapviewer/bmng/CylindricalProjectionTileFactory.java @@ -17,6 +17,7 @@ ******************************************************************************/ package org.jdesktop.swingx.mapviewer.bmng; +import org.apache.commons.math3.util.FastMath; import org.jdesktop.swingx.mapviewer.DefaultTileFactory; import org.jdesktop.swingx.mapviewer.GeoPosition; @@ -50,7 +51,7 @@ public class CylindricalProjectionTileFactory extends DefaultTileFactory int midpoint = ((SLMapServerInfo) getInfo()).getMidpoint(); if (zoom < midpoint) { - int w = (int) Math.pow(2, midpoint - zoom); + int w = (int) FastMath.pow(2, midpoint - zoom); return new Dimension(w, w / 2); // return super.getMapSize(zoom); } diff --git a/src/main/java/org/jdesktop/swingx/mapviewer/bmng/SLMapServerInfo.java b/src/main/java/org/jdesktop/swingx/mapviewer/bmng/SLMapServerInfo.java index 6b3ed54a..47849cab 100644 --- a/src/main/java/org/jdesktop/swingx/mapviewer/bmng/SLMapServerInfo.java +++ b/src/main/java/org/jdesktop/swingx/mapviewer/bmng/SLMapServerInfo.java @@ -17,6 +17,7 @@ ******************************************************************************/ package org.jdesktop.swingx.mapviewer.bmng; +import org.apache.commons.math3.util.FastMath; import org.jdesktop.swingx.mapviewer.TileFactoryInfo; /** @@ -85,7 +86,7 @@ public class SLMapServerInfo extends TileFactoryInfo { if (zoom < midpoint) { - return (int) Math.pow(2, midpoint - zoom); + return (int) FastMath.pow(2, midpoint - zoom); } else { diff --git a/src/main/java/org/jdesktop/swingx/mapviewer/util/GeoUtil.java b/src/main/java/org/jdesktop/swingx/mapviewer/util/GeoUtil.java index 36dbf53f..c3e819c1 100644 --- a/src/main/java/org/jdesktop/swingx/mapviewer/util/GeoUtil.java +++ b/src/main/java/org/jdesktop/swingx/mapviewer/util/GeoUtil.java @@ -9,6 +9,7 @@ package org.jdesktop.swingx.mapviewer.util; +import org.apache.commons.math3.util.FastMath; import org.jdesktop.swingx.JXMapViewer; import org.jdesktop.swingx.mapviewer.GeoBounds; import org.jdesktop.swingx.mapviewer.GeoPosition; @@ -99,7 +100,7 @@ public final class GeoUtil { double x = info.getMapCenterInPixelsAtZoom(zoomLevel).getX() + longitude * info.getLongitudeDegreeWidthInPixels(zoomLevel); - double e = Math.sin(latitude * (Math.PI / 180.0)); + double e = FastMath.sin(latitude * (FastMath.PI / 180.0)); if (e > 0.9999) { e = 0.9999; @@ -108,7 +109,7 @@ public final class GeoUtil { e = -0.9999; } - double y = info.getMapCenterInPixelsAtZoom(zoomLevel).getY() + 0.5 * Math.log((1 + e) / (1 - e)) * -1 + double y = info.getMapCenterInPixelsAtZoom(zoomLevel).getY() + 0.5 * FastMath.log((1 + e) / (1 - e)) * -1 * (info.getLongitudeRadianWidthInPixels(zoomLevel)); return new Point2D.Double(x, y); } @@ -129,7 +130,7 @@ public final class GeoUtil double flon = (wx - info.getMapCenterInPixelsAtZoom(zoom).getX()) / info.getLongitudeDegreeWidthInPixels(zoom); double e1 = (wy - info.getMapCenterInPixelsAtZoom(zoom).getY()) / (-1 * info.getLongitudeRadianWidthInPixels(zoom)); - double e2 = (2 * Math.atan(Math.exp(e1)) - Math.PI / 2) / (Math.PI / 180.0); + double e2 = (2 * FastMath.atan(FastMath.exp(e1)) - FastMath.PI / 2) / (FastMath.PI / 180.0); double flat = e2; GeoPosition wc = new GeoPosition(flat, flon); return wc; diff --git a/src/main/java/org/jdesktop/swingx/mapviewer/util/MercatorUtils.java b/src/main/java/org/jdesktop/swingx/mapviewer/util/MercatorUtils.java index e9eb5f52..f4caa9a2 100644 --- a/src/main/java/org/jdesktop/swingx/mapviewer/util/MercatorUtils.java +++ b/src/main/java/org/jdesktop/swingx/mapviewer/util/MercatorUtils.java @@ -9,6 +9,8 @@ package org.jdesktop.swingx.mapviewer.util; +import org.apache.commons.math3.util.FastMath; + /** * A utility class of methods that help when * dealing with standard Mercator projections. @@ -31,7 +33,7 @@ public final class MercatorUtils */ public static int longToX(double longitudeDegrees, double radius) { - double longitude = Math.toRadians(longitudeDegrees); + double longitude = FastMath.toRadians(longitudeDegrees); return (int) (radius * longitude); } @@ -42,8 +44,8 @@ public final class MercatorUtils */ public static int latToY(double latitudeDegrees, double radius) { - double latitude = Math.toRadians(latitudeDegrees); - double y = radius / 2.0 * Math.log((1.0 + Math.sin(latitude)) / (1.0 - Math.sin(latitude))); + double latitude = FastMath.toRadians(latitudeDegrees); + double y = radius / 2.0 * FastMath.log((1.0 + FastMath.sin(latitude)) / (1.0 - FastMath.sin(latitude))); return (int) y; } @@ -55,12 +57,12 @@ public final class MercatorUtils public static double xToLong(int x, double radius) { double longRadians = x / radius; - double longDegrees = Math.toDegrees(longRadians); + double longDegrees = FastMath.toDegrees(longRadians); /* * The user could have panned around the world a lot of times. Lat long goes from -180 to 180. So every time a * user gets to 181 we want to subtract 360 degrees. Every time a user gets to -181 we want to add 360 degrees. */ - int rotations = (int) Math.floor((longDegrees + 180) / 360); + int rotations = (int) FastMath.floor((longDegrees + 180) / 360); double longitude = longDegrees - (rotations * 360); return longitude; } @@ -72,7 +74,7 @@ public final class MercatorUtils */ public static double yToLat(int y, double radius) { - double latitude = (Math.PI / 2) - (2 * Math.atan(Math.exp(-1.0 * y / radius))); - return Math.toDegrees(latitude); + double latitude = (FastMath.PI / 2) - (2 * FastMath.atan(FastMath.exp(-1.0 * y / radius))); + return FastMath.toDegrees(latitude); } } diff --git a/src/main/java/org/jdesktop/swingx/mapviewer/wms/WMSService.java b/src/main/java/org/jdesktop/swingx/mapviewer/wms/WMSService.java index b74f9201..3ab61cc7 100644 --- a/src/main/java/org/jdesktop/swingx/mapviewer/wms/WMSService.java +++ b/src/main/java/org/jdesktop/swingx/mapviewer/wms/WMSService.java @@ -9,6 +9,7 @@ package org.jdesktop.swingx.mapviewer.wms; +import org.apache.commons.math3.util.FastMath; import org.jdesktop.swingx.mapviewer.util.MercatorUtils; /** @@ -57,7 +58,7 @@ public class WMSService String srs = "EPSG:4326"; int ts = tileSize; int circumference = widthOfWorldInPixels(zoom, tileSize); - double radius = circumference / (2 * Math.PI); + double radius = circumference / (2 * FastMath.PI); double ulx = MercatorUtils.xToLong(x * ts, radius); double uly = MercatorUtils.yToLat(y * ts, radius); double lrx = MercatorUtils.xToLong((x + 1) * ts, radius); @@ -73,7 +74,7 @@ public class WMSService private int widthOfWorldInPixels(int zoom, int TILE_SIZE) { // int TILE_SIZE = 256; - int tiles = (int) Math.pow(2, zoom); + int tiles = (int) FastMath.pow(2, zoom); int circumference = TILE_SIZE * tiles; return circumference; } diff --git a/src/main/java/org/jdesktop/swingx/mapviewer/wms/WMSTileFactory.java b/src/main/java/org/jdesktop/swingx/mapviewer/wms/WMSTileFactory.java index dd3a6f99..6641bf4a 100644 --- a/src/main/java/org/jdesktop/swingx/mapviewer/wms/WMSTileFactory.java +++ b/src/main/java/org/jdesktop/swingx/mapviewer/wms/WMSTileFactory.java @@ -9,6 +9,7 @@ package org.jdesktop.swingx.mapviewer.wms; +import org.apache.commons.math3.util.FastMath; import org.jdesktop.swingx.mapviewer.DefaultTileFactory; import org.jdesktop.swingx.mapviewer.TileFactoryInfo; @@ -32,7 +33,7 @@ public class WMSTileFactory extends DefaultTileFactory { int zz = 17 - zoom; int z = 4; - z = (int) Math.pow(2, (double) zz - 1); + z = (int) FastMath.pow(2, (double) zz - 1); return wms.toWMSURL(x - z, z - 1 - y, zz, getTileSize(zoom)); } diff --git a/src/main/java/org/jdesktop/swingx/util/ShapeUtils.java b/src/main/java/org/jdesktop/swingx/util/ShapeUtils.java index 96b7b149..480d6224 100644 --- a/src/main/java/org/jdesktop/swingx/util/ShapeUtils.java +++ b/src/main/java/org/jdesktop/swingx/util/ShapeUtils.java @@ -20,6 +20,8 @@ */ package org.jdesktop.swingx.util; +import org.apache.commons.math3.util.FastMath; + import java.awt.*; import java.awt.font.GlyphVector; import java.awt.geom.AffineTransform; @@ -86,10 +88,10 @@ public final class ShapeUtils { AffineTransform trans = new AffineTransform(); Polygon poly = new Polygon(); for (int i = 0; i < sides; i++) { - trans.rotate(Math.PI * 2 / sides / 2); + trans.rotate(FastMath.PI * 2 / sides / 2); Point2D out = trans.transform(new Point2D.Float(0, outsideRadius), null); poly.addPoint((int) out.getX(), (int) out.getY()); - trans.rotate(Math.PI * 2 / sides / 2); + trans.rotate(FastMath.PI * 2 / sides / 2); if (insideRadius > 0) { Point2D in = trans.transform(new Point2D.Float(0, insideRadius), null); poly.addPoint((int) in.getX(), (int) in.getY());