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