diff --git a/.idea/dictionaries/denny.xml b/.idea/dictionaries/denny.xml index 24e59925..223a1c26 100644 --- a/.idea/dictionaries/denny.xml +++ b/.idea/dictionaries/denny.xml @@ -7,6 +7,7 @@ fleetsync icecast ident + overflowable polyphase remez samplerate @@ -17,6 +18,7 @@ talkgroup tgid ultravox + wacn xtea diff --git a/.idea/libraries/imports.xml b/.idea/libraries/imports.xml index c2d94bbd..91ffaa83 100644 --- a/.idea/libraries/imports.xml +++ b/.idea/libraries/imports.xml @@ -27,39 +27,9 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/CHANGELOG b/CHANGELOG index b040d09a..7ab1b516 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,10 +1,10 @@ 0.3.0-beta1 20170129 + - REQUIRES: Java 8 (or newer) for compatibility and eventual changeover to JavaFX - FEATURE: audio streaming - adds capability to stream to multiple remote broadcast servers (Broadcastify, Icecast v2.3 and v2.4+, and Shoutcast V1 and V2). Each stream can be independently configured with a delay. Audio calls are directed to one or more streams by attaching one or more stream identifiers to each alias. - - Requires Java 8 (or newer) for compatibility and eventual changeover to JavaFX - Extensive GUI updates for tuner, channel and alias management. Includes new 'Now Playing' channel view and 'Detail' view. - Updated alias list management of alias id values and wildcards. Weighting is now @@ -17,7 +17,8 @@ - Implemented bounded queues for both tuner and individual channel IQ sample buffers. Bounded queues have ability to enter/exit overflow state when queue size reaches overflow threshold and reset when queue size falls below the reset - threshold. + threshold. Channel state will show OVERFLOW in red/yellow. + - Improves handling of P25 TDMA channels (NO Phase 2 decoder support yet) - Updated airspy controller for airspy-mini specific sample rate handling. - New developer remez filter designer tool and internal usage diff --git a/build/build.xml b/build/build.xml index 3f28086d..bce263e7 100644 --- a/build/build.xml +++ b/build/build.xml @@ -7,7 +7,7 @@ - + diff --git a/imports/libusb4java-1.2.0-linux-aarch64.jar b/imports/libusb4java-1.2.0-linux-aarch64.jar new file mode 100644 index 00000000..61a2e742 Binary files /dev/null and b/imports/libusb4java-1.2.0-linux-aarch64.jar differ diff --git a/src/alias/Alias.java b/src/alias/Alias.java index 0747e72d..8f8b5ba5 100644 --- a/src/alias/Alias.java +++ b/src/alias/Alias.java @@ -185,27 +185,6 @@ public class Alias */ public void validate() { - //Check for duplicate broadcast channels - List broadcastChannels = getBroadcastChannels(); - - if(broadcastChannels.size() > 0) - { - Set channelNames = new TreeSet<>(); - - for(BroadcastChannel broadcastChannel: broadcastChannels) - { - String channelName = broadcastChannel.getChannelName(); - - if(channelName == null || channelName.isEmpty() || channelNames.contains(channelName)) - { - removeAliasID(broadcastChannel); - } - else - { - channelNames.add(channelName); - } - } - } } /** * Returns the priority level of this alias, if defined, or the default priority @@ -336,9 +315,9 @@ public class Alias * List of broadcast channels specified for this alias. */ @XmlTransient - public List getBroadcastChannels() + public Set getBroadcastChannels() { - List broadcastChannels = new ArrayList<>(); + Set broadcastChannels = new TreeSet<>(); for(AliasID id: getId()) { diff --git a/src/alias/AliasList.java b/src/alias/AliasList.java index 8c9afa98..44a2b2e9 100644 --- a/src/alias/AliasList.java +++ b/src/alias/AliasList.java @@ -631,36 +631,47 @@ public class AliasList implements Listener return mName; } + /** + * Indicates if this alias list has a non-null, non-empty name + */ + private boolean hasName() + { + return mName != null && !mName.isEmpty(); + } + /** * Receive alias change event notifications and modify this list accordingly */ @Override public void receive(AliasEvent event) { - Alias alias = event.getAlias(); - - switch(event.getEvent()) + if(hasName()) { - case ADD: - if(alias.getList() != null && getName().equalsIgnoreCase(alias.getList())) - { - addAlias(alias); - } - break; - case CHANGE: - if(alias.getList() != null && getName().equalsIgnoreCase(alias.getList())) - { - addAlias(alias); - } - break; - case DELETE: - if(alias.getList() != null && getName().equalsIgnoreCase(alias.getList())) - { - removeAlias(alias); - } - break; - default: - break; + Alias alias = event.getAlias(); + + switch(event.getEvent()) + { + case ADD: + if(alias.getList() != null && getName().equalsIgnoreCase(alias.getList())) + { + addAlias(alias); + } + break; + case CHANGE: + if(alias.getList() != null && getName().equalsIgnoreCase(alias.getList())) + { + addAlias(alias); + } + break; + case DELETE: + if(alias.getList() != null && getName().equalsIgnoreCase(alias.getList())) + { + removeAlias(alias); + } + break; + default: + break; + } } } } diff --git a/src/alias/PatchGroupAlias.java b/src/alias/PatchGroupAlias.java index b4788a86..bb7e347a 100644 --- a/src/alias/PatchGroupAlias.java +++ b/src/alias/PatchGroupAlias.java @@ -24,12 +24,20 @@ import alias.id.AliasIDType; import alias.id.broadcast.BroadcastChannel; import alias.id.priority.Priority; import alias.id.talkgroup.TalkgroupID; +import gui.SDRTrunk; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import playlist.version1.System; import java.util.ArrayList; import java.util.List; +import java.util.Set; +import java.util.TreeSet; public class PatchGroupAlias extends Alias { + private final static Logger mLog = LoggerFactory.getLogger(PatchGroupAlias.class); + private Alias mPatchGroupAlias; private List mPatchedAliases = new ArrayList<>(); private List mPatchedTalkgroupIDs = new ArrayList<>(); @@ -168,11 +176,14 @@ public class PatchGroupAlias extends Alias for(Alias alias: mPatchedAliases) { - for(AliasAction action: alias.getAction()) + if(!(alias instanceof PatchGroupAlias)) { - if(!aliasActions.contains(action)) + for(AliasAction action: alias.getAction()) { - aliasActions.add(action); + if(!aliasActions.contains(action)) + { + aliasActions.add(action); + } } } } @@ -185,7 +196,7 @@ public class PatchGroupAlias extends Alias { for(Alias alias: mPatchedAliases) { - if(alias.hasActions()) + if(!(alias instanceof PatchGroupAlias) && alias.hasActions()) { return true; } @@ -194,20 +205,44 @@ public class PatchGroupAlias extends Alias return hasPatchGroupAlias() && getPatchGroupAlias().hasActions(); } + /** + * Returns the highest listenable audio priority defined among the aliases in the group, or returns 'Do Not Monitor' + * if that is the only priority defined. Otherwise, returns default (100) priority. + */ @Override public int getCallPriority() { - int highestPriority = (hasPatchGroupAlias() ? getPatchGroupAlias().getCallPriority() : Priority.DEFAULT_PRIORITY); + boolean hasDoNotMonitor = false; + + int highestPriority = (hasPatchGroupAlias() ? getPatchGroupAlias().getCallPriority() : Priority.DEFAULT_PRIORITY + 1); for(Alias alias: mPatchedAliases) { - if(alias.hasCallPriority() && alias.getCallPriority() < highestPriority) + if(!(alias instanceof PatchGroupAlias) && alias.hasCallPriority() && alias.getCallPriority() < highestPriority) { - highestPriority = alias.getCallPriority(); + if(alias.getCallPriority() == Priority.DO_NOT_MONITOR) + { + hasDoNotMonitor = true; + } + else + { + highestPriority = alias.getCallPriority(); + } } } - return highestPriority; + if(highestPriority <= Priority.DEFAULT_PRIORITY) + { + return highestPriority; + } + else if(hasDoNotMonitor) + { + return Priority.DO_NOT_MONITOR; + } + else + { + return Priority.DEFAULT_PRIORITY; + } } @Override @@ -220,7 +255,7 @@ public class PatchGroupAlias extends Alias for(Alias alias: mPatchedAliases) { - if(alias.hasCallPriority()) + if(!(alias instanceof PatchGroupAlias) && alias.hasCallPriority()) { return true; } @@ -239,7 +274,7 @@ public class PatchGroupAlias extends Alias for(Alias alias: mPatchedAliases) { - if(alias.isRecordable()) + if(!(alias instanceof PatchGroupAlias) && alias.isRecordable()) { return true; } @@ -258,7 +293,7 @@ public class PatchGroupAlias extends Alias for(Alias alias: mPatchedAliases) { - if(alias.isStreamable()) + if(!(alias instanceof PatchGroupAlias) && alias.isStreamable()) { return true; } @@ -268,9 +303,9 @@ public class PatchGroupAlias extends Alias } @Override - public List getBroadcastChannels() + public Set getBroadcastChannels() { - List broadcastChannels = new ArrayList<>(); + Set broadcastChannels = new TreeSet<>(); if(hasPatchGroupAlias()) { @@ -279,12 +314,9 @@ public class PatchGroupAlias extends Alias for(Alias alias: mPatchedAliases) { - for(BroadcastChannel broadcastChannel: alias.getBroadcastChannels()) + if(!(alias instanceof PatchGroupAlias)) { - if(!broadcastChannels.contains(broadcastChannel)) - { - broadcastChannels.add(broadcastChannel); - } + broadcastChannels.addAll(alias.getBroadcastChannels()); } } @@ -301,7 +333,7 @@ public class PatchGroupAlias extends Alias for(Alias alias: mPatchedAliases) { - if(alias.hasBroadcastChannel(channel)) + if(!(alias instanceof PatchGroupAlias) && alias.hasBroadcastChannel(channel)) { return true; } @@ -309,4 +341,41 @@ public class PatchGroupAlias extends Alias return false; } + + public static void main(String[] args) + { + Alias a1 = new Alias("Alias 1"); + a1.addAliasID(new BroadcastChannel("Channel 1")); + a1.addAliasID(new BroadcastChannel("Channel 2")); + a1.addAliasID(new BroadcastChannel("Channel 3")); + a1.addAliasID(new BroadcastChannel("Channel 4")); + + Alias a2 = new Alias("Alias 1"); + a1.addAliasID(new BroadcastChannel("Channel 1")); + a1.addAliasID(new BroadcastChannel("Channel 2")); + a1.addAliasID(new BroadcastChannel("Channel 3")); + a1.addAliasID(new BroadcastChannel("Channel 4")); + + Alias a3 = new Alias("Alias 1"); + a1.addAliasID(new BroadcastChannel("Channel 1")); + a1.addAliasID(new BroadcastChannel("Channel 2")); + a1.addAliasID(new BroadcastChannel("Channel 3")); + a1.addAliasID(new BroadcastChannel("Channel 4")); + + Alias a4 = new Alias("Alias 1"); + a1.addAliasID(new BroadcastChannel("Channel 1")); + a1.addAliasID(new BroadcastChannel("Channel 2")); + a1.addAliasID(new BroadcastChannel("Channel 3")); + a1.addAliasID(new BroadcastChannel("Channel 4")); + + PatchGroupAlias pga = new PatchGroupAlias(); + pga.setPatchGroupAlias(a1); + pga.addPatchedAlias(a2); + pga.addPatchedAlias(a3); + pga.addPatchedAlias(a4); + + Set bc = pga.getBroadcastChannels(); + + mLog.debug("Channels:" + bc); + } } diff --git a/src/alias/id/broadcast/BroadcastChannel.java b/src/alias/id/broadcast/BroadcastChannel.java index f0baf630..59a32090 100644 --- a/src/alias/id/broadcast/BroadcastChannel.java +++ b/src/alias/id/broadcast/BroadcastChannel.java @@ -25,76 +25,99 @@ import javax.xml.bind.annotation.XmlAttribute; public class BroadcastChannel extends AliasID implements Comparable { - private String mChannelName; + private String mChannelName; - public BroadcastChannel() - { - //JAXB Constructor - } + public BroadcastChannel() + { + //JAXB Constructor + } - @Override - public int compareTo(BroadcastChannel other) - { - if(mChannelName != null && other.getChannelName() != null) - { - return mChannelName.compareTo(other.getChannelName()); - } - else if(mChannelName != null) - { - return -1; - } - else - { - return 1; - } - } + @Override + public int compareTo(BroadcastChannel other) + { + if(mChannelName != null && other.getChannelName() != null) + { + return mChannelName.compareTo(other.getChannelName()); + } + else if(mChannelName != null) + { + return -1; + } + else + { + return 1; + } + } - /** - * Creates a named broadcast channel - */ - public BroadcastChannel(String channelName) - { - mChannelName = channelName; - } + @Override + public boolean equals(Object o) + { + if(this == o) + { + return true; + } + if(!(o instanceof BroadcastChannel)) + { + return false; + } - /** - * Name of the broadcastAudio channel configuration - */ - @XmlAttribute(name="channel") - public String getChannelName() - { - return mChannelName; - } + BroadcastChannel that = (BroadcastChannel)o; - /** - * Sets the name of the broadcastAudio channel configuration - */ - public void setChannelName(String channel) - { - mChannelName = channel; - } + return getChannelName() != null ? getChannelName().equals(that.getChannelName()) : that.getChannelName() == null; + } - @Override - public AliasIDType getType() - { - return AliasIDType.BROADCAST_CHANNEL; - } + @Override + public int hashCode() + { + return getChannelName() != null ? getChannelName().hashCode() : 0; + } - @Override - public boolean isValid() - { - return mChannelName != null; - } + /** + * Creates a named broadcast channel + */ + public BroadcastChannel(String channelName) + { + mChannelName = channelName; + } - @Override - public boolean matches( AliasID id ) - { - return false; - } - - @Override - public String toString() - { + /** + * Name of the broadcastAudio channel configuration + */ + @XmlAttribute(name = "channel") + public String getChannelName() + { + return mChannelName; + } + + /** + * Sets the name of the broadcastAudio channel configuration + */ + public void setChannelName(String channel) + { + mChannelName = channel; + } + + @Override + public AliasIDType getType() + { + return AliasIDType.BROADCAST_CHANNEL; + } + + @Override + public boolean isValid() + { + return mChannelName != null; + } + + @Override + public boolean matches(AliasID id) + { + return false; + } + + @Override + public String toString() + { if(isValid()) { return "Broadcast Channel: " + mChannelName; @@ -103,5 +126,5 @@ public class BroadcastChannel extends AliasID implements Comparable { setIcon(UNMUTED_ICON); setBorderPainted(false); + getAccessibleContext().setAccessibleName("Mute"); addActionListener(new ActionListener() { @@ -402,6 +403,7 @@ public class AudioPanel extends JPanel implements Listener public void run() { setIcon(mMuted ? MUTED_ICON : UNMUTED_ICON); + getAccessibleContext().setAccessibleName(mMuted ? "Unmute" : "Mute"); } }); } diff --git a/src/audio/broadcast/icecast/IcecastTCPAudioBroadcaster.java b/src/audio/broadcast/icecast/IcecastTCPAudioBroadcaster.java index 846bd92c..53f728c3 100644 --- a/src/audio/broadcast/icecast/IcecastTCPAudioBroadcaster.java +++ b/src/audio/broadcast/icecast/IcecastTCPAudioBroadcaster.java @@ -25,6 +25,7 @@ import org.apache.mina.core.RuntimeIoException; import org.apache.mina.core.future.ConnectFuture; import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IoSession; +import org.apache.mina.core.write.WriteTimeoutException; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.transport.socket.nio.NioSocketConnector; import org.slf4j.Logger; @@ -248,7 +249,13 @@ public class IcecastTCPAudioBroadcaster extends IcecastAudioBroadcaster { String reason = ioe.getMessage(); - if(reason.startsWith("Connection reset")) + if(connected()) + { + mLog.info("Streaming connection error detected - resetting connection - " + reason); + disconnect(); + connect(); + } + else if(reason.startsWith("Connection reset")) { mLog.info("Streaming connection reset by remote server - reestablishing connection"); disconnect(); @@ -264,14 +271,20 @@ public class IcecastTCPAudioBroadcaster extends IcecastAudioBroadcaster { setBroadcastState(BroadcastState.ERROR); disconnect(); - mLog.error("Unrecognized IO error: " + reason + ". Streaming halted."); + mLog.error("Unrecognized IO error: " + reason + ". Streaming halted.", cause); } } + else if(ioe instanceof WriteTimeoutException) + { + mLog.info("Network write timeout error - resetting connection"); + disconnect(); + connect(); + } else { setBroadcastState(BroadcastState.ERROR); disconnect(); - mLog.error("Unspecified IO error - streaming halted."); + mLog.error("Unspecified IO error - streaming halted.", cause); } } else diff --git a/src/audio/broadcast/shoutcast/v2/ShoutcastV2AudioBroadcaster.java b/src/audio/broadcast/shoutcast/v2/ShoutcastV2AudioBroadcaster.java index 786f6728..cd4cadaf 100644 --- a/src/audio/broadcast/shoutcast/v2/ShoutcastV2AudioBroadcaster.java +++ b/src/audio/broadcast/shoutcast/v2/ShoutcastV2AudioBroadcaster.java @@ -50,6 +50,7 @@ import properties.SystemProperties; import util.ThreadPool; import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.net.ConnectException; import java.net.InetSocketAddress; import java.util.ArrayList; @@ -244,43 +245,50 @@ public class ShoutcastV2AudioBroadcaster extends AudioBroadcaster implements IBr sb.append(""); - sb.append(UltravoxMetadata.ALBUM_TITLE.asXML(getConfiguration().getName())); - - sb.append(UltravoxMetadata.BROADCAST_CLIENT_APPLICATION.asXML(SystemProperties.getInstance().getApplicationName())); - - if(getConfiguration().hasGenre()) + try { - sb.append(UltravoxMetadata.GENRE.asXML(getConfiguration().getGenre())); - } + sb.append(UltravoxMetadata.ALBUM_TITLE.asXML(getConfiguration().getName())); - if(getConfiguration().hasURL()) - { - sb.append(UltravoxMetadata.URL.asXML(getConfiguration().getURL())); - } + sb.append(UltravoxMetadata.BROADCAST_CLIENT_APPLICATION.asXML(SystemProperties.getInstance().getApplicationName())); - if(metadata != null) - { - if(metadata.getPrimaryAddressTo().hasAlias()) + if(getConfiguration().hasGenre()) { - sb.append(UltravoxMetadata.TITLE_2.asXML(metadata.getPrimaryAddressTo().getAlias().getName())); - } - else if(metadata.getPrimaryAddressTo().hasIdentifier()) - { - sb.append(UltravoxMetadata.TITLE_2.asXML(metadata.getPrimaryAddressTo().getIdentifier())); + sb.append(UltravoxMetadata.GENRE.asXML(getConfiguration().getGenre())); } - if(metadata.getPrimaryAddressFrom().hasAlias()) + if(getConfiguration().hasURL()) { - sb.append(UltravoxMetadata.TITLE_3.asXML("From:" + metadata.getPrimaryAddressFrom().getAlias().getName())); + sb.append(UltravoxMetadata.URL.asXML(getConfiguration().getURL())); } - else if(metadata.getPrimaryAddressFrom().hasIdentifier()) + + if(metadata != null) { - sb.append(UltravoxMetadata.TITLE_3.asXML("From:" + metadata.getPrimaryAddressFrom().getIdentifier())); + if(metadata.getPrimaryAddressTo().hasAlias()) + { + sb.append(UltravoxMetadata.TITLE_2.asXML(metadata.getPrimaryAddressTo().getAlias().getName())); + } + else if(metadata.getPrimaryAddressTo().hasIdentifier()) + { + sb.append(UltravoxMetadata.TITLE_2.asXML(metadata.getPrimaryAddressTo().getIdentifier())); + } + + if(metadata.getPrimaryAddressFrom().hasAlias()) + { + sb.append(UltravoxMetadata.TITLE_3.asXML("From:" + metadata.getPrimaryAddressFrom().getAlias().getName())); + } + else if(metadata.getPrimaryAddressFrom().hasIdentifier()) + { + sb.append(UltravoxMetadata.TITLE_3.asXML("From:" + metadata.getPrimaryAddressFrom().getIdentifier())); + } + } + else + { + sb.append(UltravoxMetadata.TITLE_2.asXML("Scanning ...")); } } - else + catch(UnsupportedEncodingException uee) { - sb.append(UltravoxMetadata.TITLE_2.asXML("Scanning ...")); + mLog.error("UTF-8 Encoding is not supported - shoutcast/ultravox metadata will not be updated"); } sb.append(""); diff --git a/src/audio/broadcast/shoutcast/v2/ultravox/UltravoxMetadata.java b/src/audio/broadcast/shoutcast/v2/ultravox/UltravoxMetadata.java index 73d21cb3..6a124355 100644 --- a/src/audio/broadcast/shoutcast/v2/ultravox/UltravoxMetadata.java +++ b/src/audio/broadcast/shoutcast/v2/ultravox/UltravoxMetadata.java @@ -18,6 +18,9 @@ ******************************************************************************/ package audio.broadcast.shoutcast.v2.ultravox; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; + public enum UltravoxMetadata { ALBUM_TITLE("TALB"), @@ -58,11 +61,11 @@ public enum UltravoxMetadata * @param value to enclose in XML tags * @return xml tag wrapped value */ - public String asXML(String value) + public String asXML(String value) throws UnsupportedEncodingException { StringBuilder sb = new StringBuilder(); sb.append("<").append(getXMLTag()).append(">"); - sb.append(value); + sb.append(URLEncoder.encode(value, "UTF-8")); sb.append(""); return sb.toString(); diff --git a/src/channel/details/ChannelDetailPanel.java b/src/channel/details/ChannelDetailPanel.java index 3ed53b2f..4f41e267 100644 --- a/src/channel/details/ChannelDetailPanel.java +++ b/src/channel/details/ChannelDetailPanel.java @@ -38,7 +38,7 @@ public class ChannelDetailPanel extends JPanel implements Listener { - private final static Logger mLog = LoggerFactory.getLogger(AttributeMonitor.class); - private Attribute mAttribute; private Listener mListener; private boolean mHeuristicsEnabled = true; @@ -50,8 +46,8 @@ public class AttributeMonitor * an internal mapping of values to occurrence counts is updated and a change is emitted once a value that is * different from the current value, has a higher occurrence count than the current value. If heuristics are * disabled, then a change is emitted at each change in the value. - * @param t * + * @param t type * @return true if the value was changed after processing */ public boolean process(T t) @@ -83,7 +79,7 @@ public class AttributeMonitor { int count = mOccurrenceCounts.get(mCurrentValue); - for(Map.Entry entry: mOccurrenceCounts.entrySet()) + for(Map.Entry entry : mOccurrenceCounts.entrySet()) { if(entry.getValue() > count) { @@ -155,35 +151,4 @@ public class AttributeMonitor { return mCurrentValue != null; } - - public static void main(String[] args) - { - AttributeMonitor monitor = new AttributeMonitor<>(Attribute.PRIMARY_ADDRESS_TO, new Listener() - { - @Override - public void receive(AttributeChangeRequest attributeChangeRequest) - { - mLog.debug("Attribute Changed - value:" + attributeChangeRequest.getValue()); - } - }); - monitor.addIllegalValue("0000"); - monitor.addIllegalValue("000000"); - - monitor.process("ABCD"); - monitor.process("EFGH"); - monitor.process("0000"); - monitor.process("0000"); - monitor.process("ABCD"); - monitor.reset(); - - monitor.process("EFGH"); - monitor.process("ABCD"); - monitor.process("ABCD"); - monitor.process("EFGH"); - monitor.process("EFGH"); - monitor.process("000000"); - monitor.process("000000"); - monitor.process("000000"); - monitor.process("000000"); - } } diff --git a/src/channel/metadata/ChannelMetadataPanel.java b/src/channel/metadata/ChannelMetadataPanel.java index e9ecef00..5fa80231 100644 --- a/src/channel/metadata/ChannelMetadataPanel.java +++ b/src/channel/metadata/ChannelMetadataPanel.java @@ -210,6 +210,10 @@ public class ChannelMetadataPanel extends JPanel implements ListSelectionListene background = SystemProperties.getInstance().get(PROPERTY_PREFIX_BACKGROUND + "idle", Color.WHITE); foreground = SystemProperties.getInstance().get(PROPERTY_PREFIX_FOREGROUND + "idle", Color.BLUE); break; + case OVERFLOW: + background = SystemProperties.getInstance().get(PROPERTY_PREFIX_BACKGROUND + "overflow", Color.RED); + foreground = SystemProperties.getInstance().get(PROPERTY_PREFIX_FOREGROUND + "overflow", Color.YELLOW); + break; case RESET: background = SystemProperties.getInstance().get(PROPERTY_PREFIX_BACKGROUND + "reset", Color.PINK); foreground = SystemProperties.getInstance().get(PROPERTY_PREFIX_FOREGROUND + "reset", Color.YELLOW); diff --git a/src/channel/metadata/ChannelMetadataViewer.java b/src/channel/metadata/ChannelMetadataViewer.java index 53996650..e7efc2c2 100644 --- a/src/channel/metadata/ChannelMetadataViewer.java +++ b/src/channel/metadata/ChannelMetadataViewer.java @@ -51,7 +51,7 @@ public class ChannelMetadataViewer extends JPanel mChannelDetailPanel = new ChannelDetailPanel(channelProcessingManager); mCallEventPanel = new CallEventPanel(iconManager); mMessageActivityPanel = new MessageActivityPanel(channelProcessingManager); - mChannelSpectrumPanel = new ChannelSpectrumPanel(settingsManager, channelProcessingManager); +// mChannelSpectrumPanel = new ChannelSpectrumPanel(settingsManager, channelProcessingManager); mChannelMetadataPanel = new ChannelMetadataPanel(channelProcessingManager, iconManager); init(); diff --git a/src/channel/metadata/Metadata.java b/src/channel/metadata/Metadata.java index 5db7a40e..e3117dbf 100644 --- a/src/channel/metadata/Metadata.java +++ b/src/channel/metadata/Metadata.java @@ -28,6 +28,8 @@ import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; +import java.util.Set; +import java.util.TreeSet; public class Metadata { @@ -61,7 +63,7 @@ public class Metadata private Integer mAudioPriority; protected Boolean mRecordable = false; protected Boolean mDoNotRecord; - private List mBroadcastChannels; + private Set mBroadcastChannels; /** @@ -166,7 +168,7 @@ public class Metadata /** * List of de-duplicated broadcast channels aggregated from the primary and secondary TO/FROM aliases. */ - public List getBroadcastChannels() + public Set getBroadcastChannels() { if(mBroadcastChannels == null) { @@ -582,50 +584,26 @@ public class Metadata */ private void determineBroadcastChannels() { - mBroadcastChannels = new ArrayList<>(); + mBroadcastChannels = new TreeSet<>(); if(mPrimaryAddressTo.hasAlias() && mPrimaryAddressTo.getAlias().isStreamable()) { - for(BroadcastChannel broadcastChannel: mPrimaryAddressTo.getAlias().getBroadcastChannels()) - { - if(!mBroadcastChannels.contains(broadcastChannel)) - { - mBroadcastChannels.add(broadcastChannel); - } - } + mBroadcastChannels.addAll(mPrimaryAddressTo.getAlias().getBroadcastChannels()); } if(mPrimaryAddressFrom.hasAlias() && mPrimaryAddressFrom.getAlias().isStreamable()) { - for(BroadcastChannel broadcastChannel: mPrimaryAddressFrom.getAlias().getBroadcastChannels()) - { - if(!mBroadcastChannels.contains(broadcastChannel)) - { - mBroadcastChannels.add(broadcastChannel); - } - } + mBroadcastChannels.addAll(mPrimaryAddressFrom.getAlias().getBroadcastChannels()); } if(mSecondaryAddressTo.hasAlias() && mSecondaryAddressTo.getAlias().isStreamable()) { - for(BroadcastChannel broadcastChannel: mSecondaryAddressTo.getAlias().getBroadcastChannels()) - { - if(!mBroadcastChannels.contains(broadcastChannel)) - { - mBroadcastChannels.add(broadcastChannel); - } - } + mBroadcastChannels.addAll(mSecondaryAddressTo.getAlias().getBroadcastChannels()); } if(mSecondaryAddressFrom.hasAlias() && mSecondaryAddressFrom.getAlias().isStreamable()) { - for(BroadcastChannel broadcastChannel: mSecondaryAddressFrom.getAlias().getBroadcastChannels()) - { - if(!mBroadcastChannels.contains(broadcastChannel)) - { - mBroadcastChannels.add(broadcastChannel); - } - } + mBroadcastChannels.addAll(mSecondaryAddressFrom.getAlias().getBroadcastChannels()); } } diff --git a/src/channel/state/ChannelState.java b/src/channel/state/ChannelState.java index 66a22984..768c1062 100644 --- a/src/channel/state/ChannelState.java +++ b/src/channel/state/ChannelState.java @@ -35,6 +35,7 @@ import module.decode.event.ICallEventProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sample.Listener; +import sample.real.IOverflowListener; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.ScheduledExecutorService; @@ -42,7 +43,7 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; public class ChannelState extends Module implements ICallEventProvider, IDecoderStateEventListener, - IDecoderStateEventProvider, ISquelchStateProvider, IAttributeChangeRequestListener + IDecoderStateEventProvider, ISquelchStateProvider, IAttributeChangeRequestListener, IOverflowListener { private final static Logger mLog = LoggerFactory.getLogger(ChannelState.class); @@ -63,6 +64,7 @@ public class ChannelState extends Module implements ICallEventProvider, IDecoder private boolean mSquelchLocked = false; private boolean mSelected = false; + private boolean mSourceOverflow = false; private long mStandardChannelFadeTimeout = FADE_TIMEOUT_DELAY; private long mTrafficChannelFadeTimeout = DecodeConfiguration.DEFAULT_CALL_TIMEOUT_SECONDS * 1000; @@ -123,6 +125,7 @@ public class ChannelState extends Module implements ICallEventProvider, IDecoder mState = State.IDLE; mMutableMetadata.receive(new AttributeChangeRequest(Attribute.CHANNEL_STATE, mState)); + mSourceOverflow = false; } @Override @@ -350,15 +353,26 @@ public class ChannelState extends Module implements ICallEventProvider, IDecoder break; } - mMutableMetadata.receive(new AttributeChangeRequest(Attribute.CHANNEL_STATE, mState)); - } - else - { -// mLog.debug( "Can't change from [" + mState + "] to [" + state + "]" ); + mMutableMetadata.receive(new AttributeChangeRequest(Attribute.CHANNEL_STATE, + mSourceOverflow ? State.OVERFLOW : mState)); } } } + /** + * This method is invoked if the source buffer provider goes into overflow state. Since this is an external state, + * we use the mSourceOverflow variable to override the internal state reported to external listeners. + * @param overflow true to indicate an overflow state + */ + @Override + public void sourceOverflow(boolean overflow) + { + mSourceOverflow = overflow; + + mMutableMetadata.receive(new AttributeChangeRequest(Attribute.CHANNEL_STATE, + mSourceOverflow ? State.OVERFLOW : mState)); + } + /** * Sets the state and processes related actions */ diff --git a/src/channel/state/DecoderState.java b/src/channel/state/DecoderState.java index a27dd7be..4e68bb8f 100644 --- a/src/channel/state/DecoderState.java +++ b/src/channel/state/DecoderState.java @@ -23,6 +23,9 @@ public abstract class DecoderState extends Module implements ActivitySummaryProv IAttributeChangeRequestProvider, ICallEventProvider, IDecoderStateEventListener, IDecoderStateEventProvider, IMessageListener { + protected String DIVIDER1 = "======================================================\n"; + protected String DIVIDER2 = "------------------------------------------------------\n"; + /* This has to be a broadcaster in order for references to persist */ private Broadcaster mCallEventBroadcaster = new Broadcaster<>(); private Broadcaster mAttributeChangeRequestBroadcaster = new Broadcaster<>(); @@ -51,6 +54,14 @@ public abstract class DecoderState extends Module implements ActivitySummaryProv return mAliasList != null; } + /** + * Provides subclass reference to the call event broadcaster + */ + protected Broadcaster getCallEventBroadcaster() + { + return mCallEventBroadcaster; + } + /** * Reset the decoder state to prepare for processing a different sample * source diff --git a/src/channel/state/State.java b/src/channel/state/State.java index 83336d2c..f2c75767 100644 --- a/src/channel/state/State.java +++ b/src/channel/state/State.java @@ -1,17 +1,17 @@ /******************************************************************************* * SDR Trunk * Copyright (C) 2014-2016 Dennis Sheirer - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see ******************************************************************************/ @@ -23,98 +23,94 @@ import java.util.EnumSet; * Details the set of states for a channel and the allowable transition states */ public enum State -{ - IDLE( "IDLE" ) - { - @Override - public boolean canChangeTo( State state ) +{ + IDLE("IDLE") { - return state != TEARDOWN && - state != RESET; - } - }, - CALL( "CALL" ) - { - @Override - public boolean canChangeTo( State state ) + @Override + public boolean canChangeTo(State state) + { + return state != TEARDOWN && state != RESET && state != OVERFLOW; + } + }, + CALL("CALL") { - return state == CONTROL || - state == DATA || - state == ENCRYPTED || - state == FADE || - state == TEARDOWN; - } - }, - DATA( "DATA" ) - { - @Override - public boolean canChangeTo( State state ) + @Override + public boolean canChangeTo(State state) + { + return state == CONTROL || state == DATA || state == ENCRYPTED || state == FADE || state == TEARDOWN; + } + }, + DATA("DATA") { - return state == CALL || - state == CONTROL || - state == ENCRYPTED || - state == FADE || - state == TEARDOWN; - } - }, - ENCRYPTED( "ENCRYPTED" ) + @Override + public boolean canChangeTo(State state) + { + return state == CALL || state == CONTROL || state == ENCRYPTED || state == FADE || state == TEARDOWN; + } + }, + ENCRYPTED("ENCRYPTED") + { + @Override + public boolean canChangeTo(State state) + { + return state == FADE || state == TEARDOWN; + } + }, + CONTROL("CONTROL") + { + @Override + public boolean canChangeTo(State state) + { + return state == IDLE || state == FADE; + } + }, + FADE("FADE") + { + @Override + public boolean canChangeTo(State state) + { + return state != FADE && state != RESET && state != OVERFLOW; + } + }, + OVERFLOW("OVERFLOW") + { + @Override + public boolean canChangeTo(State state) + { + return false; + } + }, + RESET("RESET") + { + @Override + public boolean canChangeTo(State state) + { + return state == IDLE; + } + }, + TEARDOWN("TEARDOWN") + { + @Override + public boolean canChangeTo(State state) + { + return state == RESET; + } + }; + + private String mDisplayValue; + + public static final EnumSet CALL_STATES = EnumSet.of(CALL, CONTROL, DATA, ENCRYPTED); + public static final EnumSet IDLE_STATES = EnumSet.of(IDLE, FADE); + + private State(String displayValue) { - @Override - public boolean canChangeTo( State state ) - { - return state == FADE || state == TEARDOWN; - } - }, - CONTROL( "CONTROL" ) + mDisplayValue = displayValue; + } + + public abstract boolean canChangeTo(State state); + + public String getDisplayValue() { - @Override - public boolean canChangeTo( State state ) - { - return state == IDLE || - state == FADE; - } - }, - FADE( "FADE" ) - { - @Override - public boolean canChangeTo( State state ) - { - return state != FADE && - state != RESET; - } - }, - RESET( "RESET" ) - { - @Override - public boolean canChangeTo(State state) - { - return state == IDLE; - } - }, - - TEARDOWN( "TEARDOWN" ) - { - @Override - public boolean canChangeTo(State state) - { - return state == RESET; - } - }; - - private String mDisplayValue; - - public static final EnumSet CALL_STATES = EnumSet.of( CALL, CONTROL, DATA, ENCRYPTED ); - public static final EnumSet IDLE_STATES = EnumSet.of( IDLE, FADE ); - - private State( String displayValue ) - { - mDisplayValue = displayValue; - } - - public abstract boolean canChangeTo( State state ); - - public String getDisplayValue() - { - return mDisplayValue; - } + return mDisplayValue; + } } \ No newline at end of file diff --git a/src/channel/traffic/TrafficChannelManager.java b/src/channel/traffic/TrafficChannelManager.java index 1a706cf0..16cdec10 100644 --- a/src/channel/traffic/TrafficChannelManager.java +++ b/src/channel/traffic/TrafficChannelManager.java @@ -84,8 +84,6 @@ public class TrafficChannelManager extends Module implements ICallEventProvider, * @param system label to use to describe the system * @param site label to use to describe the site * @param aliasListName designated for the channel - * @param trafficChannelTimeout - millisecond call timer limit used when an - * end of call signalling event is not decoded. * @param trafficChannelPoolSize - maximum number of allocated traffic channels * in the pool */ @@ -96,7 +94,6 @@ public class TrafficChannelManager extends Module implements ICallEventProvider, String system, String site, String aliasListName, - long trafficChannelTimeout, int trafficChannelPoolSize) { mChannelModel = channelModel; diff --git a/src/controller/NamingThreadFactory.java b/src/controller/NamingThreadFactory.java index ae3302b1..ed7bd0dc 100644 --- a/src/controller/NamingThreadFactory.java +++ b/src/controller/NamingThreadFactory.java @@ -1,5 +1,9 @@ package controller; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import util.ThreadPool; + import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; @@ -8,24 +12,23 @@ import java.util.concurrent.atomic.AtomicInteger; */ public class NamingThreadFactory implements ThreadFactory { - static final AtomicInteger poolNumber = new AtomicInteger(1); + private final static Logger mLog = LoggerFactory.getLogger(ThreadPool.class); + + private static final AtomicInteger mPoolNumber = new AtomicInteger(1); - final ThreadGroup mThreadGroup; + private final ThreadGroup mThreadGroup; - final AtomicInteger mThreadNumber = new AtomicInteger(1); + private final AtomicInteger mThreadNumber = new AtomicInteger(1); - final String mNamePrefix; + private final String mNamePrefix; public NamingThreadFactory( String prefix ) { SecurityManager s = System.getSecurityManager(); - mThreadGroup = (s != null)? s.getThreadGroup() : - Thread.currentThread().getThreadGroup(); + mThreadGroup = (s != null)? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); - mNamePrefix = prefix + " pool-" + - poolNumber.getAndIncrement() + - "-thread-"; + mNamePrefix = prefix + " pool-" + mPoolNumber.getAndIncrement() + "-thread-"; } public Thread newThread( Runnable runnable ) @@ -42,7 +45,16 @@ public class NamingThreadFactory implements ThreadFactory { thread.setPriority( Thread.NORM_PRIORITY ); } - + + thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() + { + @Override + public void uncaughtException(Thread t, Throwable e) + { + mLog.error("Error while executing runnable in scheduled thread pool [" + t.getName() + "]", e); + } + }); + return thread; } } \ No newline at end of file diff --git a/src/module/ProcessingChain.java b/src/module/ProcessingChain.java index d8a13e9a..fdf60e86 100644 --- a/src/module/ProcessingChain.java +++ b/src/module/ProcessingChain.java @@ -538,6 +538,9 @@ public class ProcessingChain implements IChannelEventListener module.reset(); } + //Setup the channel state to monitor source overflow conditions + mSource.setOverflowListener(mChannelState); + /* Register with the source to receive sample data. Setup a * timer task to process the buffer queues 50 times a second * (every 20 ms) */ @@ -606,6 +609,7 @@ public class ProcessingChain implements IChannelEventListener if(mSource != null) { mSource.stop(); + mSource.setOverflowListener(null); switch(mSource.getSampleType()) { diff --git a/src/module/decode/DecoderFactory.java b/src/module/decode/DecoderFactory.java index 19471fe9..cce17e65 100644 --- a/src/module/decode/DecoderFactory.java +++ b/src/module/decode/DecoderFactory.java @@ -103,35 +103,35 @@ public class DecoderFactory //Low-pass filter with ~60 dB attenuation and 89 taps private static final FIRFilterSpecification MPT1327_FILTER_SPECIFICATION = FIRFilterSpecification.lowPassBuilder() - .sampleRate( 48000 ) - .gridDensity( 16 ) - .passBandCutoff( 3200 ) - .passBandAmplitude( 1.0 ) - .passBandRipple( 0.02 ) - .stopBandStart( 4000 ) - .stopBandAmplitude( 0.0 ) - .stopBandRipple( 0.03 ) - .build(); + .sampleRate( 48000 ).gridDensity( 16 ).passBandCutoff( 3200 ).passBandAmplitude( 1.0 ).passBandRipple( 0.02 ) + .stopBandStart( 4000 ).stopBandAmplitude( 0.0 ).stopBandRipple( 0.03 ).build(); + + private static final FIRFilterSpecification P25_C4FM_IQ_SPECIFICATION = FIRFilterSpecification.lowPassBuilder() + .sampleRate(48000).gridDensity(16).passBandCutoff(6750).passBandAmplitude(1.0).passBandRipple(0.01) + .stopBandStart(7000).stopBandAmplitude(0.0).stopBandRipple(0.008).build(); + + private static final FIRFilterSpecification P25_C4FM_DEMOD_SPECIFICATION = FIRFilterSpecification.lowPassBuilder() + .sampleRate(48000).gridDensity(16).passBandCutoff(2500).passBandAmplitude(1.0).passBandRipple(0.01) + .stopBandStart(4000).stopBandAmplitude(0.0).stopBandRipple(0.008).build(); private static float[] MPT1327_LOWPASS_FILTER; + private static float[] P25_C4FM_IQ_FILTER; + private static float[] P25_C4FM_DEMOD_FILTER; static { try { MPT1327_LOWPASS_FILTER = FilterFactory.getTaps(MPT1327_FILTER_SPECIFICATION); + P25_C4FM_IQ_FILTER = FilterFactory.getTaps(P25_C4FM_IQ_SPECIFICATION); + P25_C4FM_DEMOD_FILTER = FilterFactory.getTaps(P25_C4FM_DEMOD_SPECIFICATION); } catch(Exception e) { - mLog.error("Couldn't design MPT1327 bandpass filter"); + mLog.error("Couldn't design startup filter(s)"); } } - public static final boolean NO_REMOVE_DC = false; - public static final boolean REMOVE_DC = true; - - public static final int NO_FREQUENCY_CORRECTION = 0; - /** * Returns a list of one primary decoder and any auxiliary decoders, as * specified in the configurations. @@ -222,15 +222,13 @@ public class DecoderFactory if(channelType == ChannelType.STANDARD) { - long timeout = mptConfig.getCallTimeout() * 1000; //convert to milliseconds - modules.add(new TrafficChannelManager(channelModel, channelProcessingManager, decodeConfig, channel.getRecordConfiguration(), channel.getSystem(), channel.getSite(), - (aliasList != null ? aliasList.getName() : null), timeout, mptConfig.getTrafficChannelPoolSize())); + (aliasList != null ? aliasList.getName() : null), mptConfig.getTrafficChannelPoolSize())); } modules.add(new FMDemodulatorModule(iqPass, iqStop)); - modules.add(new DemodulatedAudioFilterModule(MPT1327_LOWPASS_FILTER, 1.0f)); + modules.add(new DemodulatedAudioFilterModule(P25_C4FM_DEMOD_FILTER, 1.0f)); modules.add(new AudioModule(metadata)); break; case PASSPORT: @@ -249,7 +247,8 @@ public class DecoderFactory switch(modulation) { case C4FM: - modules.add(new FMDemodulatorModule(6750, 7500)); + modules.add(new FMDemodulatorModule(P25_C4FM_IQ_FILTER)); + modules.add(new DemodulatedAudioFilterModule(P25_C4FM_DEMOD_FILTER, 1.0f)); modules.add(new P25_C4FMDecoder(aliasList, decodeConfig.getAFCMaximumCorrection())); modules.add(new P25DecoderState(aliasList, channelType, Modulation.C4FM, p25Config.getIgnoreDataCalls())); @@ -264,12 +263,9 @@ public class DecoderFactory if(channelType == ChannelType.STANDARD) { - //Set call timeout to 3 seconds for P25 traffic channels - long timeout = 3000; - modules.add(new TrafficChannelManager(channelModel, channelProcessingManager, decodeConfig, channel.getRecordConfiguration(), channel.getSystem(), channel.getSite(), - (aliasList != null ? aliasList.getName() : null), timeout, p25Config.getTrafficChannelPoolSize())); + (aliasList != null ? aliasList.getName() : null), p25Config.getTrafficChannelPoolSize())); } modules.add(new P25AudioModule(metadata)); diff --git a/src/module/decode/mpt1327/MPT1327DecoderState.java b/src/module/decode/mpt1327/MPT1327DecoderState.java index 00e85efe..a70b96fa 100644 --- a/src/module/decode/mpt1327/MPT1327DecoderState.java +++ b/src/module/decode/mpt1327/MPT1327DecoderState.java @@ -389,9 +389,9 @@ public class MPT1327DecoderState extends DecoderState { StringBuilder sb = new StringBuilder(); - sb.append("Activity Summary\n"); - sb.append("Decoder:\tMPT-1327\n"); - sb.append("Site:\t"); + sb.append("Activity Summary - Decoder: MPT-1327\n"); + sb.append(DIVIDER1); + sb.append("Site: "); if(mSite != null) { @@ -403,9 +403,7 @@ public class MPT1327DecoderState extends DecoderState if(siteAlias != null) { - sb.append(" "); - sb.append(siteAlias.getName()); - sb.append("\n"); + sb.append(" ").append(siteAlias.getName()).append("\n"); } } } @@ -414,13 +412,11 @@ public class MPT1327DecoderState extends DecoderState sb.append("Unknown\n"); } - sb.append("\n\n"); - - sb.append("Talkgroups\n\n"); + sb.append(DIVIDER2).append("Talkgroups: "); if(mGroups.isEmpty()) { - sb.append(" None\n"); + sb.append("None\n"); } else { @@ -429,8 +425,7 @@ public class MPT1327DecoderState extends DecoderState for(String talkgroup : talkgroups) { - sb.append(" "); - sb.append(talkgroup); + sb.append("\n ").append(talkgroup); if(hasAliasList()) { @@ -450,7 +445,7 @@ public class MPT1327DecoderState extends DecoderState for(String member : members) { - sb.append(" >"); + sb.append(" >"); sb.append(member); if(hasAliasList()) @@ -466,27 +461,26 @@ public class MPT1327DecoderState extends DecoderState sb.append("\n"); } - - sb.append("\n"); } } - sb.append("\n"); + sb.append(DIVIDER2).append("All Idents: "); - sb.append("Individual Idents\n"); if(mIdents.isEmpty()) { - sb.append(" None\n"); + sb.append("None\n"); } else { + sb.append("\n"); + Iterator it = mIdents.iterator(); while(it.hasNext()) { String ident = it.next(); - sb.append(" "); + sb.append(""); sb.append(ident); sb.append(" "); diff --git a/src/module/decode/p25/P25DecoderState.java b/src/module/decode/p25/P25DecoderState.java index 156c4fdd..dbd7e596 100644 --- a/src/module/decode/p25/P25DecoderState.java +++ b/src/module/decode/p25/P25DecoderState.java @@ -19,9 +19,7 @@ package module.decode.p25; import alias.Alias; import alias.AliasList; -import alias.PatchGroupAlias; import alias.id.AliasIDType; -import alias.id.talkgroup.TalkgroupID; import channel.metadata.AliasedStringAttributeMonitor; import channel.metadata.Attribute; import channel.metadata.AttributeChangeRequest; @@ -150,6 +148,7 @@ public class P25DecoderState extends DecoderState private static final DecimalFormat mFrequencyFormatter = new DecimalFormat("0.000000"); + private module.decode.p25.message.tsbk.osp.control.NetworkStatusBroadcast mNetworkStatus; private NetworkStatusBroadcastExtended mNetworkStatusExtended; private ProtectionParameterBroadcast mProtectionParameterBroadcast; @@ -163,7 +162,6 @@ public class P25DecoderState extends DecoderState private Map mBands = new HashMap<>(); private Map mRegistrations = new HashMap<>(); private Map mNeighborMap = new HashMap<>(); - private Map> mPatchGroupMap = new HashMap<>(); private String mLastCommandEventID; private String mLastPageEventID; @@ -188,6 +186,7 @@ public class P25DecoderState extends DecoderState private P25CallEvent mCurrentCallEvent; private List mCallDetectTalkgroups = new ArrayList<>(); private Map mChannelCallMap = new HashMap<>(); + private PatchGroupManager mPatchGroupManager; public P25DecoderState(AliasList aliasList, ChannelType channelType, @@ -199,6 +198,7 @@ public class P25DecoderState extends DecoderState mModulation = modulation; mIgnoreDataCalls = ignoreDataCalls; + mPatchGroupManager = new PatchGroupManager(aliasList, getCallEventBroadcaster()); mSiteAttributeMonitor = new AliasedStringAttributeMonitor(Attribute.NETWORK_ID_2, getAttributeChangeRequestListener(), getAliasList(), AliasIDType.SITE); mFromTalkgroupMonitor = new AliasedStringAttributeMonitor(Attribute.PRIMARY_ADDRESS_FROM, @@ -2719,6 +2719,9 @@ public class P25DecoderState extends DecoderState switch(((MotorolaTSBKMessage)tsbk).getMotorolaOpcode()) { case PATCH_GROUP_CHANNEL_GRANT: + //Cleanup patch groups - auto-expire any patch groups before we allocate a channel + mPatchGroupManager.cleanupPatchGroups(); + PatchGroupVoiceChannelGrant pgvcg = (PatchGroupVoiceChannelGrant)tsbk; channel = pgvcg.getChannel(); @@ -2739,7 +2742,7 @@ public class P25DecoderState extends DecoderState P25CallEvent event = new P25CallEvent.Builder(CallEventType.PATCH_GROUP_CALL) .aliasList(getAliasList()) - .channel(channel) + .channel(channel + (pgvcg.isTDMAChannel() ? " TDMA" : "")) .details(details.toString()) .frequency(pgvcg.getDownlinkFrequency()) .from(from) @@ -2750,10 +2753,15 @@ public class P25DecoderState extends DecoderState broadcast(event); } - broadcast(new TrafficChannelAllocationEvent(this, - mChannelCallMap.get(channel))); + if(!pgvcg.isTDMAChannel()) + { + broadcast(new TrafficChannelAllocationEvent(this, mChannelCallMap.get(channel))); + } break; case PATCH_GROUP_CHANNEL_GRANT_UPDATE: + //Cleanup patch groups - auto-expire any patch groups before we allocate a channel + mPatchGroupManager.cleanupPatchGroups(); + PatchGroupVoiceChannelGrantUpdate gvcgu = (PatchGroupVoiceChannelGrantUpdate)tsbk; channel = gvcgu.getChannel1(); @@ -2767,10 +2775,8 @@ public class P25DecoderState extends DecoderState { P25CallEvent event = new P25CallEvent.Builder(CallEventType.PATCH_GROUP_CALL) .aliasList(getAliasList()) - .channel(channel) - .details((gvcgu.isEncrypted() ? "ENCRYPTED " : "") + - "PATCH UPDATE - GROUP 2:" + gvcgu.getPatchGroupAddress2() + - " DN:" + gvcgu.getDownlinkFrequency2()) + .channel(channel + (gvcgu.isTDMAChannel1() ? " TDMA" : "")) + .details((gvcgu.isEncrypted() ? "ENCRYPTED " : "")) .frequency(gvcgu.getDownlinkFrequency1()) .to(to) .build(); @@ -2779,40 +2785,45 @@ public class P25DecoderState extends DecoderState broadcast(event); } - broadcast(new TrafficChannelAllocationEvent(this, - mChannelCallMap.get(channel))); + if(!gvcgu.isTDMAChannel1()) + { + broadcast(new TrafficChannelAllocationEvent(this, mChannelCallMap.get(channel))); + } + + String channel2 = gvcgu.getChannel2(); + String to2 = gvcgu.getPatchGroupAddress2(); + + if(hasCallEvent(channel2, null, to2)) + { + updateCallEvent(channel2, null, to2); + } + else + { + P25CallEvent event = new P25CallEvent.Builder(CallEventType.PATCH_GROUP_CALL) + .aliasList(getAliasList()) + .channel(channel2 + (gvcgu.isTDMAChannel2() ? " TDMA" : "")) + .details((gvcgu.isEncrypted() ? "ENCRYPTED " : "")) + .frequency(gvcgu.getDownlinkFrequency2()) + .to(to2) + .build(); + + registerCallEvent(event); + broadcast(event); + } + + if(!gvcgu.isTDMAChannel2()) + { + broadcast(new TrafficChannelAllocationEvent(this, mChannelCallMap.get(channel2))); + } + break; case PATCH_GROUP_ADD: PatchGroupAdd pga = (PatchGroupAdd)tsbk; - - if(addPatchGroup(pga.getPatchGroupAddress(), pga.getPatchedTalkgroups())) - { - StringBuilder sb = new StringBuilder(); - - sb.append("PATCH GROUP:").append(pga.getPatchGroupAddress()); - sb.append(" ").append(pga.getPatchedTalkgroups()); - - broadcast(new P25CallEvent.Builder(CallEventType.PATCH_GROUP_ADD) - .aliasList(getAliasList()) - .details(sb.toString()) - .build()); - } + mPatchGroupManager.updatePatchGroup(pga.getPatchGroupAddress(), pga.getPatchedTalkgroups()); break; case PATCH_GROUP_DELETE: PatchGroupDelete pgd = (PatchGroupDelete)tsbk; - - if(removePatchGroup(pgd.getPatchGroupAddress(), pgd.getPatchedTalkgroups())) - { - StringBuilder sbpgd = new StringBuilder(); - - sbpgd.append("PATCH GROUP:").append(pgd.getPatchGroupAddress()); - sbpgd.append(" ").append(pgd.getPatchedTalkgroups()); - - broadcast(new P25CallEvent.Builder(CallEventType.PATCH_GROUP_DELETE) - .aliasList(getAliasList()) - .details(sbpgd.toString()) - .build()); - } + mPatchGroupManager.removePatchGroup(pgd.getPatchGroupAddress()); break; case CCH_PLANNED_SHUTDOWN: if(!mControlChannelShutdownLogged) @@ -2827,174 +2838,14 @@ public class P25DecoderState extends DecoderState } } - /** - * Creates a new patch group or updates an existing patch group with the patched talkgroup entries. - * - * @param patchGroupID for the patch group - * @param talkgroupsToAdd to include in the patch group - * @return true if the patch group or the patch group map was updated - */ - private boolean addPatchGroup(String patchGroupID, List talkgroupsToAdd) - { - boolean updated = false; - - if(patchGroupID != null && !talkgroupsToAdd.isEmpty()) - { - List patchedTalkgroups = mPatchGroupMap.get(patchGroupID); - - if(patchedTalkgroups == null) - { - patchedTalkgroups = new ArrayList<>(); - } - - for(String talkgroupToAdd : talkgroupsToAdd) - { - //Exclude the patch group ID if it is included in the patched talkgroup list so that we don't have - //an infinite loop situation - if(talkgroupToAdd.equals(patchGroupID)) - { - continue; - } - - if(!patchedTalkgroups.contains(talkgroupToAdd)) - { - patchedTalkgroups.add(talkgroupToAdd); - updated = true; - } - } - - if(updated) - { - mPatchGroupMap.put(patchGroupID, patchedTalkgroups); - updatePatchAlias(patchGroupID, patchedTalkgroups); - } - } - - return updated; - } - - /** - * Removes the patched talkgroups from the patch group and removes the patch group from the patch group map if - * there are no more patched talkgroups in the patch group. - * - * @param patchGroupID for the patch group - * @param talkgroupsToRemove to remove from the patch group - * @return true if the patch group or the patch group map was updated - */ - private boolean removePatchGroup(String patchGroupID, List talkgroupsToRemove) - { - boolean updated = false; - - if(patchGroupID != null && !talkgroupsToRemove.isEmpty()) - { - List patchedTalkgroups = mPatchGroupMap.get(patchGroupID); - - if(patchedTalkgroups != null) - { - for(String talkgroupToRemove : talkgroupsToRemove) - { - if(patchedTalkgroups.contains(talkgroupToRemove)) - { - patchedTalkgroups.remove(talkgroupToRemove); - updated = true; - } - } - - if(patchedTalkgroups.isEmpty()) - { - mPatchGroupMap.remove(patchGroupID); - removePatchGroupAlias(patchGroupID); - updated = true; - } - else - { - updatePatchAlias(patchGroupID, patchedTalkgroups); - } - } - } - - return updated; - } - - /** - * Adds/updates a patch group alias to the alias list containing aliases for each of the patched talkgroups. If the - * patch group alias already exists, any patched talkgroups will be removed from the existing patch group alias and - * replaced with the aliases corresponding to the patched talkgroup aliases. - * - * @param patchGroupID for the patch group - * @param patchedTalkgroups containing the talkgroup IDs for each of the patched talkgroups - */ - private void updatePatchAlias(String patchGroupID, List patchedTalkgroups) - { - PatchGroupAlias patchGroupAlias = null; - - //Check for an existing alias for the patch talkgroup - do not include wildcard aliases - Alias existingAlias = getAliasList().getTalkgroupAlias(patchGroupID, false); - - if(existingAlias instanceof PatchGroupAlias) - { - patchGroupAlias = (PatchGroupAlias)existingAlias; - } - else - { - patchGroupAlias = new PatchGroupAlias(); - - patchGroupAlias.addAliasID(new TalkgroupID(patchGroupID)); - - if(existingAlias != null) - { - getAliasList().removeAlias(existingAlias); - - patchGroupAlias.setPatchGroupAlias(existingAlias); - } - - getAliasList().addAlias(patchGroupAlias); - } - - if(patchGroupAlias != null) - { - patchGroupAlias.setPatchedTalkgroupIDs(patchedTalkgroups); - - patchGroupAlias.clearPatchedAliases(); - - for(String patchedTalkgroup : patchedTalkgroups) - { - Alias patchedAlias = getAliasList().getTalkgroupAlias(patchedTalkgroup); - - if(patchedAlias != null) - { - patchGroupAlias.addPatchedAlias(patchedAlias); - } - } - } - } - - /** - * Removes the temporary patch group alias from the alias list - */ - private void removePatchGroupAlias(String patchGroupID) - { - Alias alias = getAliasList().getTalkgroupAlias(patchGroupID); - - if(alias instanceof PatchGroupAlias) - { - PatchGroupAlias patchGroupAlias = (PatchGroupAlias)alias; - - getAliasList().removeAlias(patchGroupAlias); - - //Replace our temporary patch group alias with the original alias for the patch group ID - if(patchGroupAlias.hasPatchGroupAlias()) - { - getAliasList().addAlias(patchGroupAlias.getPatchGroupAlias()); - } - } - } - /** * Process a traffic channel allocation message */ private void processTSBKChannelGrant(TSBKMessage message) { + //Cleanup patch groups - auto-expire any patch groups before we allocate a channel + mPatchGroupManager.cleanupPatchGroups(); + String channel = null; String from = null; String to = null; @@ -3022,7 +2873,7 @@ public class P25DecoderState extends DecoderState P25CallEvent event = new P25CallEvent.Builder(CallEventType.DATA_CALL) .aliasList(getAliasList()) - .channel(channel) + .channel(channel + (gdcg.isTDMAChannel() ? " TDMA" : "")) .details(details.toString()) .frequency(gdcg.getDownlinkFrequency()) .from(from) @@ -3033,7 +2884,7 @@ public class P25DecoderState extends DecoderState broadcast(event); } - if(!mIgnoreDataCalls) + if(!mIgnoreDataCalls && !gdcg.isTDMAChannel()) { broadcast(new TrafficChannelAllocationEvent(this, mChannelCallMap.get(channel))); @@ -3060,7 +2911,7 @@ public class P25DecoderState extends DecoderState P25CallEvent event = new P25CallEvent.Builder(CallEventType.GROUP_CALL) .aliasList(getAliasList()) - .channel(channel) + .channel(channel + (gvcg.isTDMAChannel() ? " TDMA" : "")) .details(details.toString()) .frequency(gvcg.getDownlinkFrequency()) .from(from) @@ -3071,8 +2922,10 @@ public class P25DecoderState extends DecoderState broadcast(event); } - broadcast(new TrafficChannelAllocationEvent(this, - mChannelCallMap.get(channel))); + if(!gvcg.isTDMAChannel()) + { + broadcast(new TrafficChannelAllocationEvent(this, mChannelCallMap.get(channel))); + } break; case GROUP_VOICE_CHANNEL_GRANT_UPDATE: GroupVoiceChannelGrantUpdate gvcgu = @@ -3096,8 +2949,7 @@ public class P25DecoderState extends DecoderState P25CallEvent event = new P25CallEvent.Builder(CallEventType.GROUP_CALL) .aliasList(getAliasList()) - .channel(channel) - .channel(gvcgu.getChannel1()) + .channel(gvcgu.getChannel1() + (gvcgu.isTDMAChannel1() ? " TDMA" : "")) .details(details.toString()) .frequency(gvcgu.getDownlinkFrequency1()) .from(from) @@ -3108,8 +2960,10 @@ public class P25DecoderState extends DecoderState broadcast(event); } - broadcast(new TrafficChannelAllocationEvent(this, - mChannelCallMap.get(channel))); + if(!gvcgu.isTDMAChannel1()) + { + broadcast(new TrafficChannelAllocationEvent(this, mChannelCallMap.get(channel))); + } if(gvcgu.hasChannelNumber2()) { @@ -3130,7 +2984,7 @@ public class P25DecoderState extends DecoderState P25CallEvent event2 = new P25CallEvent.Builder(CallEventType.GROUP_CALL) .aliasList(getAliasList()) - .channel(gvcgu.getChannel2()) + .channel(gvcgu.getChannel2() + (gvcgu.isTDMAChannel2() ? " TDMA" : "")) .details(details.toString()) .frequency(gvcgu.getDownlinkFrequency2()) .to(gvcgu.getGroupAddress2()) @@ -3140,8 +2994,10 @@ public class P25DecoderState extends DecoderState broadcast(event2); } - broadcast(new TrafficChannelAllocationEvent(this, - mChannelCallMap.get(channel))); + if(!gvcgu.isTDMAChannel2()) + { + broadcast(new TrafficChannelAllocationEvent(this, mChannelCallMap.get(channel))); + } } break; case GROUP_VOICE_CHANNEL_GRANT_UPDATE_EXPLICIT: @@ -3167,7 +3023,7 @@ public class P25DecoderState extends DecoderState P25CallEvent event = new P25CallEvent.Builder(CallEventType.GROUP_CALL) .aliasList(getAliasList()) - .channel(channel) + .channel(channel + (gvcgue.isTDMAChannel() ? " TDMA" : "")) .details(details.toString()) .frequency(gvcgue.getDownlinkFrequency()) .from(from) @@ -3178,8 +3034,10 @@ public class P25DecoderState extends DecoderState broadcast(event); } - broadcast(new TrafficChannelAllocationEvent(this, - mChannelCallMap.get(channel))); + if(!gvcgue.isTDMAChannel()) + { + broadcast(new TrafficChannelAllocationEvent(this, mChannelCallMap.get(channel))); + } break; case INDIVIDUAL_DATA_CHANNEL_GRANT: IndividualDataChannelGrant idcg = (IndividualDataChannelGrant)message; @@ -3202,7 +3060,7 @@ public class P25DecoderState extends DecoderState P25CallEvent event = new P25CallEvent.Builder(CallEventType.DATA_CALL) .aliasList(getAliasList()) - .channel(channel) + .channel(channel + (idcg.isTDMAChannel() ? " TDMA" : "")) .details(details.toString()) .frequency(idcg.getDownlinkFrequency()) .from(from) @@ -3213,10 +3071,9 @@ public class P25DecoderState extends DecoderState broadcast(event); } - if(!mIgnoreDataCalls) + if(!mIgnoreDataCalls && !idcg.isTDMAChannel()) { - broadcast(new TrafficChannelAllocationEvent(this, - mChannelCallMap.get(channel))); + broadcast(new TrafficChannelAllocationEvent(this, mChannelCallMap.get(channel))); } break; case SNDCP_DATA_CHANNEL_GRANT: @@ -3239,7 +3096,7 @@ public class P25DecoderState extends DecoderState P25CallEvent event = new P25CallEvent.Builder(CallEventType.DATA_CALL) .aliasList(getAliasList()) - .channel(channel) + .channel(channel + (sdcg.isTDMAChannel() ? " TDMA" : "")) .details(details.toString()) .frequency(sdcg.getDownlinkFrequency()) .from(from) @@ -3250,15 +3107,13 @@ public class P25DecoderState extends DecoderState broadcast(event); } - if(!mIgnoreDataCalls) + if(!mIgnoreDataCalls && !sdcg.isTDMAChannel()) { - broadcast(new TrafficChannelAllocationEvent(this, - mChannelCallMap.get(channel))); + broadcast(new TrafficChannelAllocationEvent(this, mChannelCallMap.get(channel))); } break; case TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT: - TelephoneInterconnectVoiceChannelGrant tivcg = - (TelephoneInterconnectVoiceChannelGrant)message; + TelephoneInterconnectVoiceChannelGrant tivcg = (TelephoneInterconnectVoiceChannelGrant)message; channel = tivcg.getChannel(); from = null; @@ -3282,7 +3137,7 @@ public class P25DecoderState extends DecoderState P25CallEvent event = new P25CallEvent.Builder( CallEventType.TELEPHONE_INTERCONNECT) .aliasList(getAliasList()) - .channel(channel) + .channel(channel + (tivcg.isTDMAChannel() ? " TDMA" : "")) .details(details.toString()) .frequency(tivcg.getDownlinkFrequency()) .from(from) @@ -3293,15 +3148,15 @@ public class P25DecoderState extends DecoderState broadcast(event); } - broadcast(new TrafficChannelAllocationEvent(this, - mChannelCallMap.get(channel))); + if(!tivcg.isTDMAChannel()) + { + broadcast(new TrafficChannelAllocationEvent(this, mChannelCallMap.get(channel))); + } break; case TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT_UPDATE: - TelephoneInterconnectVoiceChannelGrantUpdate tivcgu = - (TelephoneInterconnectVoiceChannelGrantUpdate)message; + TelephoneInterconnectVoiceChannelGrantUpdate tivcgu = (TelephoneInterconnectVoiceChannelGrantUpdate)message; - channel = tivcgu.getChannelIdentifier() + "-" + - tivcgu.getChannelNumber(); + channel = tivcgu.getChannelIdentifier() + "-" + tivcgu.getChannelNumber(); from = null; /* Address is ambiguous and could mean either source or target, @@ -3324,7 +3179,7 @@ public class P25DecoderState extends DecoderState P25CallEvent event = new P25CallEvent.Builder( CallEventType.TELEPHONE_INTERCONNECT) .aliasList(getAliasList()) - .channel(channel) + .channel(channel + (tivcgu.isTDMAChannel() ? " TDMA" : "")) .details(details.toString()) .frequency(tivcgu.getDownlinkFrequency()) .from(from) @@ -3335,15 +3190,15 @@ public class P25DecoderState extends DecoderState broadcast(event); } - broadcast(new TrafficChannelAllocationEvent(this, - mChannelCallMap.get(channel))); + if(!tivcgu.isTDMAChannel()) + { + broadcast(new TrafficChannelAllocationEvent(this, mChannelCallMap.get(channel))); + } break; case UNIT_TO_UNIT_VOICE_CHANNEL_GRANT: - UnitToUnitVoiceChannelGrant uuvcg = - (UnitToUnitVoiceChannelGrant)message; + UnitToUnitVoiceChannelGrant uuvcg = (UnitToUnitVoiceChannelGrant)message; - channel = uuvcg.getChannelIdentifier() + "-" + - uuvcg.getChannelNumber(); + channel = uuvcg.getChannelIdentifier() + "-" + uuvcg.getChannelNumber(); from = uuvcg.getSourceAddress(); to = uuvcg.getTargetAddress(); @@ -3362,7 +3217,7 @@ public class P25DecoderState extends DecoderState P25CallEvent event = new P25CallEvent.Builder( CallEventType.UNIT_TO_UNIT_CALL) .aliasList(getAliasList()) - .channel(channel) + .channel(channel + (uuvcg.isTDMAChannel() ? " TDMA" : "")) .details(details.toString()) .frequency(uuvcg.getDownlinkFrequency()) .from(from) @@ -3373,15 +3228,15 @@ public class P25DecoderState extends DecoderState broadcast(event); } - broadcast(new TrafficChannelAllocationEvent(this, - mChannelCallMap.get(channel))); + if(!uuvcg.isTDMAChannel()) + { + broadcast(new TrafficChannelAllocationEvent(this, mChannelCallMap.get(channel))); + } break; case UNIT_TO_UNIT_VOICE_CHANNEL_GRANT_UPDATE: - UnitToUnitVoiceChannelGrantUpdate uuvcgu = - (UnitToUnitVoiceChannelGrantUpdate)message; + UnitToUnitVoiceChannelGrantUpdate uuvcgu = (UnitToUnitVoiceChannelGrantUpdate)message; - channel = uuvcgu.getChannelIdentifier() + "-" + - uuvcgu.getChannelNumber(); + channel = uuvcgu.getChannelIdentifier() + "-" + uuvcgu.getChannelNumber(); from = uuvcgu.getSourceAddress(); to = uuvcgu.getTargetAddress(); @@ -3400,7 +3255,7 @@ public class P25DecoderState extends DecoderState P25CallEvent event = new P25CallEvent.Builder( CallEventType.UNIT_TO_UNIT_CALL) .aliasList(getAliasList()) - .channel(channel) + .channel(channel + (uuvcgu.isTDMAChannel() ? " TDMA" : "")) .details(details.toString()) .frequency(uuvcgu.getDownlinkFrequency()) .from(from) @@ -3411,8 +3266,10 @@ public class P25DecoderState extends DecoderState broadcast(event); } - broadcast(new TrafficChannelAllocationEvent(this, - mChannelCallMap.get(channel))); + if(!uuvcgu.isTDMAChannel()) + { + broadcast(new TrafficChannelAllocationEvent(this, mChannelCallMap.get(channel))); + } break; default: break; @@ -3522,29 +3379,25 @@ public class P25DecoderState extends DecoderState { StringBuilder sb = new StringBuilder(); - sb.append("Activity Summary\n"); - sb.append("Decoder:\tP25\n"); - sb.append("===================== THIS SITE ======================"); + sb.append("Activity Summary - Decoder:P25 ").append(getModulation().getLabel()).append("\n"); + sb.append(DIVIDER1); + sb.append("SITE "); if(mNetworkStatus != null) { - sb.append("\nNAC:\t" + mNetworkStatus.getNAC()); - sb.append("\nWACN-SYS:\t" + mNetworkStatus.getWACN()); - sb.append("-" + mNetworkStatus.getSystemID()); - sb.append(" ["); - sb.append(mNetworkStatus.getNetworkCallsign()); - sb.append("]"); - sb.append("\nLRA:\t" + mNetworkStatus.getLocationRegistrationArea()); + sb.append("NAC:" + mNetworkStatus.getNAC()); + sb.append("h WACN:" + mNetworkStatus.getWACN()); + sb.append("h SYS:" + mNetworkStatus.getSystemID()); + sb.append("h [").append(mNetworkStatus.getNetworkCallsign()).append("]"); + sb.append(" LRA:" + mNetworkStatus.getLocationRegistrationArea()); } else if(mNetworkStatusExtended != null) { - sb.append("\nNAC:\t" + mNetworkStatusExtended.getNAC()); - sb.append("\nWACN-SYS:\t" + mNetworkStatusExtended.getWACN()); - sb.append("-" + mNetworkStatusExtended.getSystemID()); - sb.append(" ["); - sb.append(mNetworkStatusExtended.getNetworkCallsign()); - sb.append("]"); - sb.append("\nLRA:\t" + mNetworkStatusExtended.getLocationRegistrationArea()); + sb.append("NAC:" + mNetworkStatusExtended.getNAC()); + sb.append("h WACN:" + mNetworkStatusExtended.getWACN()); + sb.append("h SYS:" + mNetworkStatusExtended.getSystemID()); + sb.append("h [").append(mNetworkStatusExtended.getNetworkCallsign()).append("]"); + sb.append(" LRA:" + mNetworkStatusExtended.getLocationRegistrationArea()); } String site = null; @@ -3555,11 +3408,10 @@ public class P25DecoderState extends DecoderState } else if(mRFSSStatusMessageExtended != null) { - site = mRFSSStatusMessageExtended.getRFSubsystemID() + "-" + - mRFSSStatusMessageExtended.getSiteID(); + site = mRFSSStatusMessageExtended.getRFSubsystemID() + "-" + mRFSSStatusMessageExtended.getSiteID(); } - sb.append("\nRFSS-SITE:\t" + site); + sb.append("h RFSS-SITE:").append(site).append("h"); if(hasAliasList()) { @@ -3571,121 +3423,120 @@ public class P25DecoderState extends DecoderState } } + sb.append("\n").append(DIVIDER2); + if(mNetworkStatus != null) { - sb.append("\nSERVICES:\t" + SystemService.toString( - mNetworkStatus.getSystemServiceClass())); - sb.append("\nPCCH:\tDNLINK " + mFrequencyFormatter.format( - (double)mNetworkStatus.getDownlinkFrequency() / 1E6d) + - " [" + mNetworkStatus.getIdentifier() + "-" + - mNetworkStatus.getChannel() + "]\n"); - sb.append("\tUPLINK " + mFrequencyFormatter.format( - (double)mNetworkStatus.getUplinkFrequency() / 1E6d) + " [" + - mNetworkStatus.getIdentifier() + "-" + - mNetworkStatus.getChannel() + "]\n"); + sb.append("SERVICES: " + SystemService.toString(mNetworkStatus.getSystemServiceClass())).append("\n"); + sb.append(DIVIDER2); + sb.append("PCCH DOWNLINK ") + .append(mFrequencyFormatter.format((double)mNetworkStatus.getDownlinkFrequency() / 1E6d)) + .append(" [").append(mNetworkStatus.getIdentifier()).append("-").append(mNetworkStatus.getChannel()) + .append("] UPLINK ") + .append(mFrequencyFormatter.format((double)mNetworkStatus.getUplinkFrequency() / 1E6d)) + .append(" [").append(mNetworkStatus.getIdentifier()).append("-").append(mNetworkStatus.getChannel()) + .append("]\n"); } else if(mNetworkStatusExtended != null) { - sb.append("\nSERVICES:\t" + SystemService.toString( - mNetworkStatusExtended.getSystemServiceClass())); - sb.append("\nPCCH:\tDNLINK " + mFrequencyFormatter.format( - (double)mNetworkStatusExtended.getDownlinkFrequency() / 1E6d) + - " [" + mNetworkStatusExtended.getTransmitIdentifier() + "-" + - mNetworkStatusExtended.getTransmitChannel() + "]\n"); - sb.append("\tUPLINK " + mFrequencyFormatter.format( - (double)mNetworkStatusExtended.getUplinkFrequency() / 1E6d) + - " [" + mNetworkStatusExtended.getReceiveIdentifier() + "-" + - mNetworkStatusExtended.getReceiveChannel() + "]"); + sb.append("\nSERVICES:").append(SystemService.toString(mNetworkStatusExtended.getSystemServiceClass())) + .append("\n"); + sb.append(DIVIDER2); + sb.append("PCCH DOWNLINK ") + .append(mFrequencyFormatter.format((double)mNetworkStatusExtended.getDownlinkFrequency() / 1E6d)) + .append(" [").append(mNetworkStatusExtended.getTransmitIdentifier()).append("-") + .append(mNetworkStatusExtended.getTransmitChannel()).append("] UPLINK ") + .append(mFrequencyFormatter.format((double)mNetworkStatusExtended.getUplinkFrequency() / 1E6d)) + .append(" [").append(mNetworkStatusExtended.getReceiveIdentifier()).append("-") + .append(mNetworkStatusExtended.getReceiveChannel()).append("]\n"); } if(mSecondaryControlChannels.isEmpty()) { - sb.append("\nSCCH:\tNONE"); + sb.append("SCCH: NONE\n"); } else { - for(module.decode.p25.message.tsbk.osp.control.SecondaryControlChannelBroadcast - sec : mSecondaryControlChannels) + for(module.decode.p25.message.tsbk.osp.control.SecondaryControlChannelBroadcast sec : mSecondaryControlChannels) { - sb.append("\nSCCH:\tDNLINK " + mFrequencyFormatter.format( - (double)sec.getDownlinkFrequency1() / 1E6d) + - " [" + sec.getIdentifier1() + "-" + sec.getChannel1() + "]\n"); - sb.append("\tUPLINK " + mFrequencyFormatter.format( - (double)sec.getUplinkFrequency1() / 1E6d) + " [" + - sec.getIdentifier1() + "-" + sec.getChannel1() + "]\n"); + sb.append("SCCH DOWNLINK ") + .append(mFrequencyFormatter.format((double)sec.getDownlinkFrequency1() / 1E6d)) + .append(" [").append(sec.getIdentifier1()).append("-").append(sec.getChannel1()).append("] UPLINK ") + .append(mFrequencyFormatter.format((double)sec.getUplinkFrequency1() / 1E6d)) + .append(" [").append(sec.getIdentifier1()).append("-").append(sec.getChannel1()).append("]"); if(sec.hasChannel2()) { - sb.append("\nSCCH:\tDNLINK " + mFrequencyFormatter.format( - (double)sec.getDownlinkFrequency2() / 1E6d) + - " [" + sec.getIdentifier2() + "-" + sec.getChannel2() + "]\n"); - sb.append("\tUPLINK " + mFrequencyFormatter.format( - (double)sec.getUplinkFrequency2() / 1E6d) + " [" + - sec.getIdentifier2() + "-" + sec.getChannel2() + "]"); + sb.append(" SCCH 2 DOWNLINK ") + .append(mFrequencyFormatter.format((double)sec.getDownlinkFrequency2() / 1E6d)) + .append(" [").append(sec.getIdentifier2()).append("-").append(sec.getChannel2()) + .append("] UPLINK ").append(mFrequencyFormatter.format((double)sec.getUplinkFrequency2() / 1E6d)) + .append(" [").append(sec.getIdentifier2()).append("-").append(sec.getChannel2()).append("]"); } + + sb.append("\n"); } } + if(mSNDCPDataChannel != null) { - sb.append("\nSNDCP:"); - sb.append("\tDNLINK " + mFrequencyFormatter.format( - (double)mSNDCPDataChannel.getDownlinkFrequency() / 1E6D) + - " [" + mSNDCPDataChannel.getTransmitChannel() + "]"); - sb.append("\tUPLINK " + mFrequencyFormatter.format( - (double)mSNDCPDataChannel.getUplinkFrequency() / 1E6D) + - " [" + mSNDCPDataChannel.getReceiveChannel() + "]"); + sb.append("SNDCP DOWNLINK ") + .append(mFrequencyFormatter.format((double)mSNDCPDataChannel.getDownlinkFrequency() / 1E6D)) + .append(" [").append(mSNDCPDataChannel.getTransmitChannel()).append("]").append(" UPLINK ") + .append(mFrequencyFormatter.format((double)mSNDCPDataChannel.getUplinkFrequency() / 1E6D)) + .append(" [").append(mSNDCPDataChannel.getReceiveChannel()).append("]\n"); } if(mProtectionParameterBroadcast != null) { - sb.append("\nENCRYPTION:"); - sb.append("\nTYPE:\t" + mProtectionParameterBroadcast - .getEncryptionType().name()); - sb.append("\nALGORITHM:\t" + mProtectionParameterBroadcast - .getAlgorithmID()); - sb.append("\nKEY:\t" + mProtectionParameterBroadcast.getKeyID()); - sb.append("\nINBOUND IV:\t" + mProtectionParameterBroadcast - .getInboundInitializationVector()); - sb.append("\nOUTBOUND IV:\t" + mProtectionParameterBroadcast - .getOutboundInitializationVector()); + sb.append(DIVIDER2); + sb.append("ENCRYPTION TYPE:").append(mProtectionParameterBroadcast.getEncryptionType().name()); + sb.append(" ALGORITHM:").append(mProtectionParameterBroadcast.getAlgorithmID()); + sb.append(" KEY:").append(mProtectionParameterBroadcast.getKeyID()); + sb.append(" INBOUND IV:").append(mProtectionParameterBroadcast.getInboundInitializationVector()); + sb.append(" OUTBOUND IV:").append(mProtectionParameterBroadcast.getOutboundInitializationVector()); + sb.append("\n"); } List identifiers = new ArrayList<>(mBands.keySet()); Collections.sort(identifiers); - sb.append("\nFREQUENCY BANDS:"); + sb.append(DIVIDER2).append("FREQUENCY BANDS:\n"); for(Integer id : identifiers) { IBandIdentifier band = mBands.get(id); - - sb.append("\n\t" + id); - sb.append("- BASE: " + mFrequencyFormatter.format( - (double)band.getBaseFrequency() / 1E6d)); - sb.append(" CHANNEL SIZE: " + mFrequencyFormatter.format( - (double)band.getChannelSpacing() / 1E6d)); - sb.append(" UPLINK OFFSET: " + mFrequencyFormatter.format( - (double)band.getTransmitOffset() / 1E6D)); + sb.append(band.toString()).append("\n"); +// sb.append(" ").append(id); +// sb.append(" - BASE: " + mFrequencyFormatter.format( +// (double)band.getBaseFrequency() / 1E6d)); +// sb.append(" CHANNEL SIZE: " + mFrequencyFormatter.format( +// (double)band.getChannelSpacing() / 1E6d)); +// sb.append(" UPLINK OFFSET: " + mFrequencyFormatter.format( +// (double)band.getTransmitOffset() / 1E6D)); +// sb.append("\n"); } - sb.append("\n\n=================== NEIGHBORS ======================"); + sb.append(DIVIDER2).append("NEIGHBOR SITES: "); if(mNeighborMap.isEmpty()) { - sb.append("\n\tNONE\n"); - sb.append("\n----------------------------------------------------"); + sb.append("NONE\n"); } else { for(IAdjacentSite neighbor : mNeighborMap.values()) { - sb.append("\nNAC:\t" + ((P25Message)neighbor).getNAC()); - sb.append("\nSYSTEM:\t" + neighbor.getSystemID()); - sb.append("\nLRA:\t" + neighbor.getLRA()); + sb.append("\n"); + sb.append("NAC:").append(((P25Message)neighbor).getNAC()); + sb.append("h SYSTEM:" + neighbor.getSystemID()); + sb.append("h LRA:" + neighbor.getLRA()); String neighborID = neighbor.getRFSS() + "-" + neighbor.getSiteID(); - sb.append("\nRFSS-SITE:\t" + neighborID); + sb.append("h RFSS-SITE:" + neighborID); + + sb.append("h "); if(hasAliasList()) { @@ -3693,18 +3544,16 @@ public class P25DecoderState extends DecoderState if(siteAlias != null) { - sb.append(" " + siteAlias.getName()); + sb.append(siteAlias.getName()); } } - sb.append("\nPCCH:\tDNLINK " + mFrequencyFormatter.format( - (double)neighbor.getDownlinkFrequency() / 1E6d) + - " [" + neighbor.getDownlinkChannel() + "]"); - sb.append("\n\tUPLINK:" + mFrequencyFormatter.format( - (double)neighbor.getUplinkFrequency() / 1E6d) + - " [" + neighbor.getDownlinkChannel() + "]\n"); - sb.append("\nSERVICES:\t" + neighbor.getSystemServiceClass()); - sb.append("\n----------------------------------------------------"); + sb.append("\n PCCH: DOWNLINK ") + .append(mFrequencyFormatter.format((double)neighbor.getDownlinkFrequency() / 1E6d)) + .append(" [").append(neighbor.getDownlinkChannel()).append("] UPLINK:") + .append(mFrequencyFormatter.format((double)neighbor.getUplinkFrequency() / 1E6d)) + .append(" [").append(neighbor.getDownlinkChannel()).append("] SERVICES: ") + .append(neighbor.getSystemServiceClass()); } } diff --git a/src/module/decode/p25/P25_C4FMDecoder.java b/src/module/decode/p25/P25_C4FMDecoder.java index 650c0cc2..94f2be56 100644 --- a/src/module/decode/p25/P25_C4FMDecoder.java +++ b/src/module/decode/p25/P25_C4FMDecoder.java @@ -47,12 +47,10 @@ public class P25_C4FMDecoder extends P25Decoder private final static Logger mLog = LoggerFactory.getLogger( P25_C4FMDecoder.class ); /* Instrumentation Taps */ - private static final String INSTRUMENT_FILTER_OUTPUT = "Tap Point: Pre-Filter Output"; private static final String INSTRUMENT_C4FM_SYMBOL_FILTER_OUTPUT = "Tap Point: Symbol Filter Output"; private static final String INSTRUMENT_C4FM_SLICER_OUTPUT = "Tap Point: C4FM Slicer Output"; private List mAvailableTaps; - private RealFIRFilter_RB_RB mC4FMPreFilter; private C4FMSymbolFilter mSymbolFilter; private C4FMSlicer mC4FMSlicer; private P25MessageFramer mMessageFramer; @@ -74,15 +72,9 @@ public class P25_C4FMDecoder extends P25Decoder { super( aliasList ); - /* Filter demodulated sample buffers */ - float[] filter = FilterFactory.getLowPass( 48000, 2500, 4000, 80, WindowType.HANNING, true ); - - mC4FMPreFilter = new RealFIRFilter_RB_RB( filter, 1.0f ); - /* Shape gain and frequency offsets to optimize sample stream */ mSymbolFilter = new C4FMSymbolFilter( frequencyCorrectionMaximum ); - mC4FMPreFilter.setListener( mSymbolFilter ); - + /* Convert samples to symbols */ mC4FMSlicer = new C4FMSlicer(); mSymbolFilter.setListener( mC4FMSlicer ); @@ -100,9 +92,6 @@ public class P25_C4FMDecoder extends P25Decoder { super.dispose(); - mC4FMPreFilter.dispose(); - mC4FMPreFilter = null; - mSymbolFilter.dispose(); mSymbolFilter = null; @@ -121,7 +110,7 @@ public class P25_C4FMDecoder extends P25Decoder @Override public Listener getFilteredRealBufferListener() { - return mC4FMPreFilter; + return mSymbolFilter; } /** @@ -136,8 +125,6 @@ public class P25_C4FMDecoder extends P25Decoder TapGroup group = new TapGroup( "P25 C4FM Decoder" ); - group.add( new FloatBufferTap( INSTRUMENT_FILTER_OUTPUT, 0, 1.0f ) ); - group.add( new FloatTap( INSTRUMENT_C4FM_SYMBOL_FILTER_OUTPUT, 0, 0.1f ) ); group.add( new DibitTap( INSTRUMENT_C4FM_SLICER_OUTPUT, 0, 0.1f ) ); @@ -165,11 +152,6 @@ public class P25_C4FMDecoder extends P25Decoder switch( tap.getName() ) { - case INSTRUMENT_FILTER_OUTPUT: - FloatBufferTap filterOutput = (FloatBufferTap)tap; - mC4FMPreFilter.setListener( filterOutput ); - filterOutput.setListener( mSymbolFilter ); - break; case INSTRUMENT_C4FM_SYMBOL_FILTER_OUTPUT: FloatTap symbolTap = (FloatTap)tap; mSymbolFilter.setListener( symbolTap ); @@ -201,9 +183,6 @@ public class P25_C4FMDecoder extends P25Decoder switch( tap.getName() ) { - case INSTRUMENT_FILTER_OUTPUT: - mC4FMPreFilter.setListener( mSymbolFilter ); - break; case INSTRUMENT_C4FM_SYMBOL_FILTER_OUTPUT: mSymbolFilter.setListener( mC4FMSlicer ); break; diff --git a/src/module/decode/p25/PatchGroup.java b/src/module/decode/p25/PatchGroup.java new file mode 100644 index 00000000..525602ad --- /dev/null +++ b/src/module/decode/p25/PatchGroup.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ +package module.decode.p25; + +import java.util.ArrayList; +import java.util.List; + +public class PatchGroup +{ + private long mExpireThreshold = 5000; //5 seconds + private long mLastUpdated; + private String mPatchGroupID; + private List mPatchedGroups = new ArrayList<>(); + + /** + * Constructs a patch group with the specified patch group ID + * @param patchGroupID that identifies this patch group + */ + public PatchGroup(String patchGroupID) + { + mPatchGroupID = patchGroupID; + mLastUpdated = System.currentTimeMillis(); + } + + /** + * Patch group ID for this patch group + */ + public String getPatchGroupID() + { + return mPatchGroupID; + } + + /** + * Adds the patched group to this patch group. Duplicate patched groups are ignored. + * + * Note: the patch group ID will not be added as a patched group, to avoid circular dependencies. + * + * @return true if the patched group was added to this patch group + */ + public boolean addPatchedGroup(String patchedGroup) + { + if(patchedGroup != null && !patchedGroup.equals(mPatchGroupID) && !mPatchedGroups.contains(patchedGroup)) + { + mPatchedGroups.add(patchedGroup); + return true; + } + + return false; + } + + /** + * Patched talkgroups that are part of this patch group. + */ + public List getPatchedGroups() + { + return mPatchedGroups; + } + + /** + * Updates the timestamp for this patch group. + */ + public void updateTimestamp() + { + mLastUpdated = System.currentTimeMillis(); + } + + /** + * Indicates if this patch group is expired, meaning that it hasn't been updated in the past (expire + * threshold) seconds. + */ + public boolean isExpired() + { + return System.currentTimeMillis() - mLastUpdated > mExpireThreshold; + } + + /** + * Sets the patch group expiration threshold (default = 5000 ms). A patch group is considered expired if + * no new updates have been received within the past (expire threshold) milliseconds + * + * @param expireThreshold in milliseconds + */ + public void setExpireThreshold(long expireThreshold) + { + mExpireThreshold = expireThreshold; + } +} diff --git a/src/module/decode/p25/PatchGroupManager.java b/src/module/decode/p25/PatchGroupManager.java new file mode 100644 index 00000000..8642923e --- /dev/null +++ b/src/module/decode/p25/PatchGroupManager.java @@ -0,0 +1,245 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ +package module.decode.p25; + +import alias.Alias; +import alias.AliasList; +import alias.PatchGroupAlias; +import alias.id.talkgroup.TalkgroupID; +import module.decode.event.CallEvent; +import sample.Broadcaster; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class PatchGroupManager +{ + private AliasList mAliasList; + private List mPatchGroups = new ArrayList<>(); + private Broadcaster mCallEventBroadcaster; + + /** + * Manages active P25 patch groups and auto-expires patch groups if not updated every 5 seconds. + * + * @param aliasList to keep updated with patch group changes + * @param broadcaster for rebroadcasting patch group related call events + */ + public PatchGroupManager(AliasList aliasList, Broadcaster broadcaster) + { + mAliasList = aliasList; + mCallEventBroadcaster = broadcaster; + } + + /** + * Removes the patch group. + * + * @param patchGroupID of the patch group to remove + */ + public void removePatchGroup(String patchGroupID) + { + removePatchGroup(patchGroupID, false); + } + + /** + * Removes the patch group. + * + * @param patchGroupID of the patch group to remove + * @param expired true if the patch group is being removed because it expired, false if we receive a + * message commanding commanding a patch group delete. + */ + private void removePatchGroup(String patchGroupID, boolean expired) + { + PatchGroup patchGroup = getPatchGroup(patchGroupID); + + if(patchGroup != null) + { + //Cleanup the alias list + if(mAliasList != null) + { + Alias alias = mAliasList.getTalkgroupAlias(patchGroupID); + + if(alias instanceof PatchGroupAlias) + { + PatchGroupAlias patchGroupAlias = (PatchGroupAlias)alias; + + mAliasList.removeAlias(patchGroupAlias); + + //Replace our temporary patch group alias with the original alias for the patch group ID + if(patchGroupAlias.hasPatchGroupAlias()) + { + mAliasList.addAlias(patchGroupAlias.getPatchGroupAlias()); + } + } + } + + mPatchGroups.remove(patchGroup); + + if(mCallEventBroadcaster != null) + { + StringBuilder sb = new StringBuilder(); + + sb.append((expired ? "EXPIRED " : "DELETED ")); + sb.append("PATCH GROUP:").append(patchGroup.getPatchGroupID()); + sb.append(" ").append(patchGroup.getPatchedGroups()); + + + mCallEventBroadcaster.broadcast(new P25CallEvent.Builder(CallEvent.CallEventType.PATCH_GROUP_DELETE) + .to(patchGroup.getPatchGroupID()) + .details(sb.toString()) + .build()); + } + } + } + + /** + * Adds/updates a patch group alias to the alias list containing aliases for each of the patched talkgroups. If the + * patch group alias already exists, any patched talkgroups will be removed from the existing patch group alias and + * replaced with the aliases corresponding to the patched talkgroup aliases. + * + * @param patchGroupID for the patch group + * @param patchedTalkgroups containing the talkgroup IDs for each of the patched talkgroups + */ + public void updatePatchGroup(String patchGroupID, List patchedTalkgroups) + { + boolean updated = false; + + PatchGroup patchGroup = getPatchGroup(patchGroupID); + + if(patchGroup == null) + { + //Remove any expired patch groups before we add a new one + cleanupPatchGroups(); + patchGroup = new PatchGroup(patchGroupID); + mPatchGroups.add(patchGroup); + updated = true; + } + else + { + patchGroup.updateTimestamp(); + } + + for(String patchedGroup : patchedTalkgroups) + { + if(patchGroup.addPatchedGroup(patchedGroup)) + { + updated = true; + } + } + + //If we make any changes to the patch group, update the patch group alias + if(updated) + { + PatchGroupAlias patchGroupAlias = null; + + //Check for an existing alias for the patch talkgroup - do not include wildcard aliases + if(mAliasList != null) + { + Alias existingAlias = mAliasList.getTalkgroupAlias(patchGroupID, false); + + if(existingAlias instanceof PatchGroupAlias) + { + patchGroupAlias = (PatchGroupAlias)existingAlias; + } + else + { + patchGroupAlias = new PatchGroupAlias(); + + patchGroupAlias.addAliasID(new TalkgroupID(patchGroupID)); + + if(existingAlias != null) + { + mAliasList.removeAlias(existingAlias); + + patchGroupAlias.setPatchGroupAlias(existingAlias); + } + + mAliasList.addAlias(patchGroupAlias); + } + + if(patchGroupAlias != null) + { + patchGroupAlias.setPatchedTalkgroupIDs(patchGroup.getPatchedGroups()); + + patchGroupAlias.clearPatchedAliases(); + + for(String patchedTalkgroup : patchGroup.getPatchedGroups()) + { + Alias patchedAlias = mAliasList.getTalkgroupAlias(patchedTalkgroup); + + if(patchedAlias != null) + { + patchGroupAlias.addPatchedAlias(patchedAlias); + } + } + } + } + + if(mCallEventBroadcaster != null) + { + StringBuilder sb = new StringBuilder(); + + sb.append("PATCH GROUP:").append(patchGroup.getPatchGroupID()); + sb.append(" ").append(patchGroup.getPatchedGroups()); + + mCallEventBroadcaster.broadcast(new P25CallEvent.Builder(CallEvent.CallEventType.PATCH_GROUP_ADD) + .aliasList(mAliasList) + .details(sb.toString()) + .build()); + } + } + } + + /** + * Returns the patch group matching the patch group ID or null + */ + private PatchGroup getPatchGroup(String patchGroupID) + { + for(PatchGroup patchGroup : mPatchGroups) + { + if(patchGroup.getPatchGroupID().equals(patchGroupID)) + { + return patchGroup; + } + } + + return null; + } + + /** + * Checks the last updated timestamp on all patch groups and removes any patch groups that have not been + * updated in the past 5 seconds + */ + public void cleanupPatchGroups() + { + Iterator it = mPatchGroups.iterator(); + + while(it.hasNext()) + { + PatchGroup patchGroup = it.next(); + + if(patchGroup.isExpired()) + { + it.remove(); + + removePatchGroup(patchGroup.getPatchGroupID(), true); + } + } + } +} diff --git a/src/module/decode/p25/message/IBandIdentifier.java b/src/module/decode/p25/message/IBandIdentifier.java index a2588c42..1f3524eb 100644 --- a/src/module/decode/p25/message/IBandIdentifier.java +++ b/src/module/decode/p25/message/IBandIdentifier.java @@ -1,3 +1,21 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message; public interface IBandIdentifier @@ -29,4 +47,18 @@ public interface IBandIdentifier */ public abstract long getTransmitOffset(); + /** + * Downlink (tower to mobile) Frequency for the specified channel + */ + public abstract long getDownlinkFrequency(int channelNumber); + + /** + * Uplink (mobile to tower) Frequency for the specified channel + */ + public abstract long getUplinkFrequency(int channelNumber); + + /** + * Indicates if this band is an FDMA (false) or TDMA (true) band + */ + public boolean isTDMA(); } \ No newline at end of file diff --git a/src/module/decode/p25/message/P25Message.java b/src/module/decode/p25/message/P25Message.java index e1e6fe29..730c8acf 100644 --- a/src/module/decode/p25/message/P25Message.java +++ b/src/module/decode/p25/message/P25Message.java @@ -1,214 +1,188 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message; -import java.text.SimpleDateFormat; - -import map.Plottable; -import message.Message; -import module.decode.p25.reference.DataUnitID; import alias.Alias; import alias.AliasList; import bits.BinaryMessage; import edac.CRC; +import map.Plottable; +import message.Message; +import module.decode.p25.reference.DataUnitID; + +import java.text.SimpleDateFormat; public class P25Message extends Message { - public enum DuplexMode { HALF, FULL }; - public enum SessionMode { PACKET, CIRCUIT }; - - public static final int[] NAC = { 0,1,2,3,4,5,6,7,8,9,10,11 }; - public static final int[] DUID = { 12,13,14,15 }; - public static final int[] BCH = { 16,17,18,19,20,21,22,23,24,25,26,27,28,29, - 30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53, - 54,55,56,57,58,59,60,61,62,63 }; - - protected SimpleDateFormat mTimeDurationFormat = - new SimpleDateFormat( "HH:mm:ss.SSS"); - - protected BinaryMessage mMessage; - protected DataUnitID mDUID; - protected AliasList mAliasList; - - protected CRC[] mCRC; - - public P25Message( BinaryMessage message, - DataUnitID duid, - AliasList aliasList ) - { - super(); - - mMessage = message; - mDUID = duid; - mAliasList = aliasList; - } - - public CRC[] getCRCResults() - { - return mCRC; - } - - public BinaryMessage getSourceMessage() - { - return mMessage; - } - - public AliasList getAliasList() - { - return mAliasList; - } - - public String getNAC() - { - return mMessage.getHex( NAC, 3 ); - } - - public DataUnitID getDUID() - { - return mDUID; - } - - @Override + public enum DuplexMode {HALF, FULL}; + public enum SessionMode {PACKET, CIRCUIT}; + + public static final int[] NAC = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + public static final int[] DUID = {12, 13, 14, 15}; + public static final int[] BCH = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63}; + + protected SimpleDateFormat mTimeDurationFormat = new SimpleDateFormat("HH:mm:ss.SSS"); + + protected BinaryMessage mMessage; + protected DataUnitID mDUID; + protected AliasList mAliasList; + + protected CRC[] mCRC; + + public P25Message(BinaryMessage message, DataUnitID duid, AliasList aliasList) + { + super(); + + mMessage = message; + mDUID = duid; + mAliasList = aliasList; + } + + public CRC[] getCRCResults() + { + return mCRC; + } + + public BinaryMessage getSourceMessage() + { + return mMessage; + } + + public AliasList getAliasList() + { + return mAliasList; + } + + public String getNAC() + { + return mMessage.getHex(NAC, 3); + } + + public DataUnitID getDUID() + { + return mDUID; + } + + @Override public String getErrorStatus() { - if( mCRC == null ) - { - return "UNKNOWN"; - } - - return CRC.format( mCRC ); + if(mCRC == null) + { + return "UNKNOWN"; + } + + return CRC.format(mCRC); } - @Override + @Override public String getMessage() { - StringBuilder sb = new StringBuilder(); - - sb.append( "NAC:" ); - sb.append( getNAC() ); - sb.append( " " ); - sb.append( getDUID().getLabel() ); - sb.append( " DATA UNIT ID:" + mMessage.getInt( DUID ) ); - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + + sb.append("NAC:"); + sb.append(getNAC()); + sb.append(" "); + sb.append(getDUID().getLabel()); + sb.append(" DATA UNIT ID:" + mMessage.getInt(DUID)); + + return sb.toString(); } - @Override + @Override public String getBinaryMessage() { - return mMessage.toString(); + return mMessage.toString(); } - @Override + @Override public String getProtocol() { - return "P25 Phase 1"; + return "P25 Phase 1"; } - @Override + @Override public String getEventType() { - return mDUID.name(); + return mDUID.name(); } - @Override + @Override public String getFromID() { - return null; - } - - @Override - public Alias getFromIDAlias() - { - if( mAliasList != null ) - { - return mAliasList.getTalkgroupAlias( getFromID() ); - } - return null; } - @Override + @Override + public Alias getFromIDAlias() + { + if(mAliasList != null) + { + return mAliasList.getTalkgroupAlias(getFromID()); + } + + return null; + } + + @Override public String getToID() { - return null; + return null; } - @Override + @Override public Alias getToIDAlias() { - if( mAliasList != null ) - { - return mAliasList.getTalkgroupAlias( getToID() ); - } - - return null; + if(mAliasList != null) + { + return mAliasList.getTalkgroupAlias(getToID()); + } + + return null; } - @Override + @Override public Plottable getPlottable() { - return null; + return null; } - @Override + @Override public String toString() { - return getMessage(); + return getMessage(); } - @Override + @Override public boolean isValid() { - if( mCRC != null ) - { - for( CRC crc: mCRC ) - { - if( crc == CRC.FAILED_CRC ) - { - return false; - } - } - } - - return true; - } + if(mCRC != null) + { + for(CRC crc : mCRC) + { + if(crc == CRC.FAILED_CRC) + { + return false; + } + } + } - /** - * Calculates the frequency of the uplink channel using the channel number - * and the IdentifierUpdate message. - * - * @param iden - Identifier Update message - * @param channel - channel number - * @return - frequency in Hertz - */ - protected static long calculateUplink( IBandIdentifier iden, int channel ) - { - long downlink = calculateDownlink( iden, channel ); - - if( downlink > 0 && iden != null ) - { - return downlink + iden.getTransmitOffset(); - } - - return 0; - } - - /** - * Calculates the frequency of the downlink channel using the channel number - * and the IdentifierUpdate message. - * - * @param iden - Identifier Update message - * @param channel - channel number - * @return - frequency in Hertz - */ - protected static long calculateDownlink( IBandIdentifier iden, int channel ) - { - if( iden != null ) - { - return iden.getBaseFrequency() + - ( channel * iden.getChannelSpacing() ); - } - - return 0; - } - + return true; + } } diff --git a/src/module/decode/p25/message/ldu/lc/AdjacentSiteStatusBroadcast.java b/src/module/decode/p25/message/ldu/lc/AdjacentSiteStatusBroadcast.java index 089912b8..a8dca0b9 100644 --- a/src/module/decode/p25/message/ldu/lc/AdjacentSiteStatusBroadcast.java +++ b/src/module/decode/p25/message/ldu/lc/AdjacentSiteStatusBroadcast.java @@ -1,3 +1,21 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.ldu.lc; import module.decode.p25.message.IAdjacentSite; @@ -7,142 +25,148 @@ import module.decode.p25.message.ldu.LDU1Message; import module.decode.p25.message.tsbk.osp.control.SystemService; import module.decode.p25.reference.LinkControlOpcode; -public class AdjacentSiteStatusBroadcast extends LDU1Message - implements IdentifierReceiver, IAdjacentSite +public class AdjacentSiteStatusBroadcast extends LDU1Message implements IdentifierReceiver, IAdjacentSite { - public static final int[] LRA = { 364,365,366,367,372,373,374,375 }; - public static final int[] SYSTEM_ID = { 384,385,386,387,536,537,538,539,540, - 541,546,547 }; - public static final int[] RFSS_ID = { 548,549,550,551,556,557,558,559 }; - public static final int[] SITE_ID = { 560,561,566,567,568,569,570,571 }; - public static final int[] IDENTIFIER = { 720,721,722,723 }; - public static final int[] CHANNEL = { 724,725,730,731,732,733,734,735,740, - 741,742,743 }; - public static final int[] SYSTEM_SERVICE_CLASS = { 744,745,750,751,752,753, - 754,755 }; - - private IBandIdentifier mIdentifierUpdate; - - public AdjacentSiteStatusBroadcast( LDU1Message message ) - { - super( message ); - } - + public static final int[] LRA = {364, 365, 366, 367, 372, 373, 374, 375}; + public static final int[] SYSTEM_ID = {384, 385, 386, 387, 536, 537, 538, 539, 540, 541, 546, 547}; + public static final int[] RFSS_ID = {548, 549, 550, 551, 556, 557, 558, 559}; + public static final int[] SITE_ID = {560, 561, 566, 567, 568, 569, 570, 571}; + public static final int[] IDENTIFIER = {720, 721, 722, 723}; + public static final int[] CHANNEL = {724, 725, 730, 731, 732, 733, 734, 735, 740, 741, 742, 743}; + public static final int[] SYSTEM_SERVICE_CLASS = {744, 745, 750, 751, 752, 753, 754, 755}; + + private IBandIdentifier mIdentifierUpdate; + + public AdjacentSiteStatusBroadcast(LDU1Message message) + { + super(message); + } + @Override public String getEventType() { return LinkControlOpcode.ADJACENT_SITE_STATUS_BROADCAST.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " LRA:" + getLRA() ); + @Override + public String getMessage() + { + StringBuilder sb = new StringBuilder(); - sb.append( " SYS:" + getSystemID() ); - - sb.append( " SITE:" + getRFSS() + "-" + getSiteID() ); - - sb.append( " CHAN:" + getChannel() ); + sb.append(getMessageStub()); + + sb.append(" LRA:" + getLRA()); + + sb.append(" SYS:" + getSystemID()); + + sb.append(" SITE:" + getRFSS() + "-" + getSiteID()); + + sb.append(" CHAN:" + getChannel()); + + sb.append(" " + getSystemServiceClass()); + + return sb.toString(); + } - sb.append( " " + getSystemServiceClass() ); - - return sb.toString(); - } - public String getUniqueID() { - StringBuilder sb = new StringBuilder(); - - sb.append( getSystemID() ); - sb.append( ":" ); - sb.append( getRFSS() ); - sb.append( ":" ); - sb.append( getSiteID() ); - - return sb.toString(); - } - - public String getLRA() - { - return mMessage.getHex( LRA, 2 ); - } - - public String getSystemID() - { - return mMessage.getHex( SYSTEM_ID, 3 ); - } - - public String getRFSS() - { - return mMessage.getHex( RFSS_ID, 2 ); - } - - public String getSiteID() - { - return mMessage.getHex( SITE_ID, 2 ); - } - - public int getIdentifier() - { - return mMessage.getInt( IDENTIFIER ); - } - - public String getChannel() - { - return getIdentifier() + "-" + getChannelNumber(); - } - - public int getChannelNumber() - { - return mMessage.getInt( CHANNEL ); - } - - public String getSystemServiceClass() - { - return SystemService.toString( mMessage.getInt( SYSTEM_SERVICE_CLASS ) ); - } + StringBuilder sb = new StringBuilder(); - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + sb.append(getSystemID()); + sb.append(":"); + sb.append(getRFSS()); + sb.append(":"); + sb.append(getSiteID()); + + return sb.toString(); + } + + public String getLRA() { - mIdentifierUpdate = message; + return mMessage.getHex(LRA, 2); } - @Override + public String getSystemID() + { + return mMessage.getHex(SYSTEM_ID, 3); + } + + public String getRFSS() + { + return mMessage.getHex(RFSS_ID, 2); + } + + public String getSiteID() + { + return mMessage.getHex(SITE_ID, 2); + } + + public int getIdentifier() + { + return mMessage.getInt(IDENTIFIER); + } + + public String getChannel() + { + return getIdentifier() + "-" + getChannelNumber(); + } + + public int getChannelNumber() + { + return mMessage.getInt(CHANNEL); + } + + public String getSystemServiceClass() + { + return SystemService.toString(mMessage.getInt(SYSTEM_SERVICE_CLASS)); + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + mIdentifierUpdate = message; + } + + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 1 ]; - - identifiers[ 0 ] = getIdentifier(); - - return identifiers; + int[] identifiers = new int[1]; + + identifiers[0] = getIdentifier(); + + return identifiers; } - + @Override - public String getDownlinkChannel() - { - return getChannel(); - } - - @Override - public String getUplinkChannel() - { - return getChannel(); - } - - public long getDownlinkFrequency() + public String getDownlinkChannel() { - return calculateDownlink( mIdentifierUpdate, getChannelNumber() ); + return getChannel(); } - + + @Override + public String getUplinkChannel() + { + return getChannel(); + } + + public long getDownlinkFrequency() + { + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.getDownlinkFrequency(getChannelNumber()); + } + + return 0; + } + public long getUplinkFrequency() { - return calculateUplink( mIdentifierUpdate, getChannelNumber() ); + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.getUplinkFrequency(getChannelNumber()); + } + + return 0; } } diff --git a/src/module/decode/p25/message/ldu/lc/AdjacentSiteStatusBroadcastExplicit.java b/src/module/decode/p25/message/ldu/lc/AdjacentSiteStatusBroadcastExplicit.java index 893c2e5c..c798598c 100644 --- a/src/module/decode/p25/message/ldu/lc/AdjacentSiteStatusBroadcastExplicit.java +++ b/src/module/decode/p25/message/ldu/lc/AdjacentSiteStatusBroadcastExplicit.java @@ -1,3 +1,21 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.ldu.lc; import module.decode.p25.message.IAdjacentSite; @@ -6,154 +24,160 @@ import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.message.ldu.LDU1Message; import module.decode.p25.reference.LinkControlOpcode; -public class AdjacentSiteStatusBroadcastExplicit extends LDU1Message - implements IdentifierReceiver, IAdjacentSite +public class AdjacentSiteStatusBroadcastExplicit extends LDU1Message implements IdentifierReceiver, IAdjacentSite { - public static final int[] LRA = { 364,365,366,367,372,373,374,375 }; - public static final int[] TRANSMIT_IDENTIFIER = { 376,377,382,383 }; - public static final int[] TRANSMIT_CHANNEL = { 384,385,386,387,536,537,538, - 539,540,541,546,547 }; - public static final int[] RFSS_ID = { 548,549,550,551,556,557,558,559 }; - public static final int[] SITE_ID = { 560,561,566,567,568,569,570,571 }; - - public static final int[] RECEIVE_IDENTIFIER = { 720,721,722,723 }; - public static final int[] RECEIVE_CHANNEL = { 724,725,730,731,732,733,734, - 735,740,741,742,743 }; - - private IBandIdentifier mTransmitBand; - private IBandIdentifier mReceiveBand; - - public AdjacentSiteStatusBroadcastExplicit( LDU1Message message ) - { - super( message ); - } - + public static final int[] LRA = {364, 365, 366, 367, 372, 373, 374, 375}; + public static final int[] TRANSMIT_IDENTIFIER = {376, 377, 382, 383}; + public static final int[] TRANSMIT_CHANNEL = {384, 385, 386, 387, 536, 537, 538, 539, 540, 541, 546, 547}; + public static final int[] RFSS_ID = {548, 549, 550, 551, 556, 557, 558, 559}; + public static final int[] SITE_ID = {560, 561, 566, 567, 568, 569, 570, 571}; + public static final int[] RECEIVE_IDENTIFIER = {720, 721, 722, 723}; + public static final int[] RECEIVE_CHANNEL = {724, 725, 730, 731, 732, 733, 734, 735, 740, 741, 742, 743}; + + private IBandIdentifier mTransmitBand; + private IBandIdentifier mReceiveBand; + + public AdjacentSiteStatusBroadcastExplicit(LDU1Message message) + { + super(message); + } + @Override public String getEventType() { return LinkControlOpcode.ADJACENT_SITE_STATUS_BROADCAST_EXPLICIT.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " LRA:" + getLRA() ); - - sb.append( " SITE:" + getRFSS() + "-" + getSiteID() ); - - sb.append( " DNLINK:" + getDownlinkChannel() ); - - sb.append( " UPLINK:" + getUplinkChannel() ); - - return sb.toString(); - } - + @Override + public String getMessage() + { + StringBuilder sb = new StringBuilder(); + + sb.append(getMessageStub()); + + sb.append(" LRA:" + getLRA()); + + sb.append(" SITE:" + getRFSS() + "-" + getSiteID()); + + sb.append(" DNLINK:" + getDownlinkChannel()); + + sb.append(" UPLINK:" + getUplinkChannel()); + + return sb.toString(); + } + public String getUniqueID() { - StringBuilder sb = new StringBuilder(); - - sb.append( getSystemID() ); - sb.append( ":" ); - sb.append( getRFSS() ); - sb.append( ":" ); - sb.append( getSiteID() ); - - return sb.toString(); - } - - public String getLRA() - { - return mMessage.getHex( LRA, 2 ); - } - - public String getRFSS() - { - return mMessage.getHex( RFSS_ID, 2 ); - } - - public String getSystemID() - { - return "***"; - } - - public String getSiteID() - { - return mMessage.getHex( SITE_ID, 2 ); - } - - public int getTransmitIdentifier() - { - return mMessage.getInt( TRANSMIT_IDENTIFIER ); - } - - public int getTransmitChannel() - { - return mMessage.getInt( TRANSMIT_CHANNEL ); - } - - public String getDownlinkChannel() - { - return getTransmitIdentifier() + "-" + getTransmitChannel(); - } - - public int getReceiveIdentifier() - { - return mMessage.getInt( RECEIVE_IDENTIFIER ); - } - - public int getReceiveChannel() - { - return mMessage.getInt( RECEIVE_CHANNEL ); - } - - public String getUplinkChannel() - { - return getReceiveIdentifier() + "-" + getReceiveChannel(); - } + StringBuilder sb = new StringBuilder(); - @Override - public String getSystemServiceClass() - { - return "[]"; - } + sb.append(getSystemID()); + sb.append(":"); + sb.append(getRFSS()); + sb.append(":"); + sb.append(getSiteID()); + + return sb.toString(); + } + + public String getLRA() + { + return mMessage.getHex(LRA, 2); + } + + public String getRFSS() + { + return mMessage.getHex(RFSS_ID, 2); + } + + public String getSystemID() + { + return "***"; + } + + public String getSiteID() + { + return mMessage.getHex(SITE_ID, 2); + } + + public int getTransmitIdentifier() + { + return mMessage.getInt(TRANSMIT_IDENTIFIER); + } + + public int getTransmitChannel() + { + return mMessage.getInt(TRANSMIT_CHANNEL); + } + + public String getDownlinkChannel() + { + return getTransmitIdentifier() + "-" + getTransmitChannel(); + } + + public int getReceiveIdentifier() + { + return mMessage.getInt(RECEIVE_IDENTIFIER); + } + + public int getReceiveChannel() + { + return mMessage.getInt(RECEIVE_CHANNEL); + } + + public String getUplinkChannel() + { + return getReceiveIdentifier() + "-" + getReceiveChannel(); + } + + @Override + public String getSystemServiceClass() + { + return "[]"; + } public long getDownlinkFrequency() { - return calculateDownlink( mTransmitBand, getTransmitChannel() ); + if(mTransmitBand != null) + { + return mTransmitBand.getDownlinkFrequency(getTransmitChannel()); + } + + return 0; } - + public long getUplinkFrequency() { - return calculateUplink( mReceiveBand, getReceiveChannel() ); + if(mReceiveBand != null) + { + return mReceiveBand.getUplinkFrequency(getReceiveChannel()); + } + + return 0; } - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) - { - if( identifier == getTransmitIdentifier() ) - { - mTransmitBand = message; - } - - if( identifier == getReceiveIdentifier() ) - { - mReceiveBand = message; - } - } + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getTransmitIdentifier()) + { + mTransmitBand = message; + } + + if(identifier == getReceiveIdentifier()) + { + mReceiveBand = message; + } + } + + @Override + public int[] getIdentifiers() + { + int[] identifiers = new int[2]; + + identifiers[0] = getTransmitIdentifier(); + identifiers[1] = getReceiveIdentifier(); + + return identifiers; + } - @Override - public int[] getIdentifiers() - { - int[] identifiers = new int[ 2 ]; - - identifiers[ 0 ] = getTransmitIdentifier(); - identifiers[ 1 ] = getReceiveIdentifier(); - - return identifiers; - } - } diff --git a/src/module/decode/p25/message/ldu/lc/ChannelIdentifierUpdate.java b/src/module/decode/p25/message/ldu/lc/ChannelIdentifierUpdate.java index 42cf0e78..9c8ef923 100644 --- a/src/module/decode/p25/message/ldu/lc/ChannelIdentifierUpdate.java +++ b/src/module/decode/p25/message/ldu/lc/ChannelIdentifierUpdate.java @@ -1,83 +1,118 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.ldu.lc; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.ldu.LDU1Message; import module.decode.p25.reference.LinkControlOpcode; -public class ChannelIdentifierUpdate extends LDU1Message - implements IBandIdentifier +public class ChannelIdentifierUpdate extends LDU1Message implements IBandIdentifier { - public static final int[] IDENTIFIER = { 364,365,366,367 }; - public static final int[] BANDWIDTH = { 372,373,374,375,376,377,382,383,384 }; - public static final int[] TRANSMIT_OFFSET = { 385,386,387,536,537,538,539, - 540,541 }; - public static final int[] CHANNEL_SPACING = { 546,547,548,549,550,551,556, - 557,558,559 }; - public static final int[] BASE_FREQUENCY = { 560,561,566,567,568,569,570, - 571,720,721,722,723,724,725,730,731,732,733,734,735,740,741,742,743,744, - 745,750,751,752,753,754,755 }; + public static final int[] IDENTIFIER = {364, 365, 366, 367}; + public static final int[] BANDWIDTH = {372, 373, 374, 375, 376, 377, 382, 383, 384}; + public static final int[] TRANSMIT_OFFSET = {385, 386, 387, 536, 537, 538, 539, + 540, 541}; + public static final int[] CHANNEL_SPACING = {546, 547, 548, 549, 550, 551, 556, + 557, 558, 559}; + public static final int[] BASE_FREQUENCY = {560, 561, 566, 567, 568, 569, 570, + 571, 720, 721, 722, 723, 724, 725, 730, 731, 732, 733, 734, 735, 740, 741, 742, 743, 744, + 745, 750, 751, 752, 753, 754, 755}; + + public ChannelIdentifierUpdate(LDU1Message message) + { + super(message); + } - public ChannelIdentifierUpdate( LDU1Message message ) - { - super( message ); - } - @Override public String getEventType() { return LinkControlOpcode.CHANNEL_IDENTIFIER_UPDATE.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " IDEN:" + getIdentifier() ); + @Override + public String getMessage() + { + StringBuilder sb = new StringBuilder(); - sb.append( " BASE:" + getBaseFrequency() ); - - sb.append( " BW:" + getBandwidth() ); - - sb.append( " SPACING:" + getChannelSpacing() ); - - sb.append( " OFFSET:" + getTransmitOffset() ); - - return sb.toString(); - } + sb.append(getMessageStub()); - @Override - public int getIdentifier() - { - return mMessage.getInt( IDENTIFIER ); - } + sb.append(" IDEN:" + getIdentifier()); - /** + sb.append(" BASE:" + getBaseFrequency()); + + sb.append(" BW:" + getBandwidth()); + + sb.append(" SPACING:" + getChannelSpacing()); + + sb.append(" OFFSET:" + getTransmitOffset()); + + return sb.toString(); + } + + @Override + public int getIdentifier() + { + return mMessage.getInt(IDENTIFIER); + } + + /** * Channel bandwidth in hertz */ @Override public int getBandwidth() { - return mMessage.getInt( BANDWIDTH ) * 125; + return mMessage.getInt(BANDWIDTH) * 125; } - + @Override public long getChannelSpacing() { - return mMessage.getLong( CHANNEL_SPACING ) * 125l; + return mMessage.getLong(CHANNEL_SPACING) * 125l; } @Override public long getBaseFrequency() { - return mMessage.getLong( BASE_FREQUENCY ) * 5l; + return mMessage.getLong(BASE_FREQUENCY) * 5l; } - @Override + @Override public long getTransmitOffset() { - return -1 * mMessage.getLong( TRANSMIT_OFFSET ) * 250000l; + return -1 * mMessage.getLong(TRANSMIT_OFFSET) * 250000l; + } + + @Override + public long getDownlinkFrequency(int channelNumber) + { + return getBaseFrequency() + (channelNumber * getChannelSpacing()); + } + + @Override + public long getUplinkFrequency(int channelNumber) + { + return getDownlinkFrequency(channelNumber) + getTransmitOffset(); + } + + @Override + public boolean isTDMA() + { + return false; } } diff --git a/src/module/decode/p25/message/ldu/lc/ChannelIdentifierUpdateExplicit.java b/src/module/decode/p25/message/ldu/lc/ChannelIdentifierUpdateExplicit.java index c857754f..a1532abf 100644 --- a/src/module/decode/p25/message/ldu/lc/ChannelIdentifierUpdateExplicit.java +++ b/src/module/decode/p25/message/ldu/lc/ChannelIdentifierUpdateExplicit.java @@ -4,8 +4,7 @@ import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.ldu.LDU1Message; import module.decode.p25.reference.LinkControlOpcode; -public class ChannelIdentifierUpdateExplicit extends LDU1Message - implements IBandIdentifier +public class ChannelIdentifierUpdateExplicit extends LDU1Message implements IBandIdentifier { public static final int[] IDENTIFIER = { 364,365,366,367 }; public static final int[] BANDWIDTH = { 372,373,374,375 }; @@ -80,4 +79,22 @@ public class ChannelIdentifierUpdateExplicit extends LDU1Message { return -1 * mMessage.getLong( TRANSMIT_OFFSET ) * 250000l; } + + @Override + public long getDownlinkFrequency(int channelNumber) + { + return getBaseFrequency() + ( channelNumber * getChannelSpacing() ); + } + + @Override + public long getUplinkFrequency(int channelNumber) + { + return getDownlinkFrequency(channelNumber) + getTransmitOffset(); + } + + @Override + public boolean isTDMA() + { + return false; + } } diff --git a/src/module/decode/p25/message/ldu/lc/GroupVoiceChannelUpdate.java b/src/module/decode/p25/message/ldu/lc/GroupVoiceChannelUpdate.java index 4091664b..d9b54839 100644 --- a/src/module/decode/p25/message/ldu/lc/GroupVoiceChannelUpdate.java +++ b/src/module/decode/p25/message/ldu/lc/GroupVoiceChannelUpdate.java @@ -1,3 +1,21 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.ldu.lc; import module.decode.p25.message.IBandIdentifier; @@ -5,156 +23,167 @@ import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.message.ldu.LDU1Message; import module.decode.p25.reference.LinkControlOpcode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class GroupVoiceChannelUpdate extends LDU1Message - implements IdentifierReceiver +public class GroupVoiceChannelUpdate extends LDU1Message implements IdentifierReceiver { - private final static Logger mLog = - LoggerFactory.getLogger( GroupVoiceChannelUpdate.class ); + public static final int[] IDENTIFIER_A = {364, 365, 366, 367}; + public static final int[] CHANNEL_A = {372, 373, 374, 375, 376, 377, 382, 383, 384, 385, 386, 387}; + public static final int[] GROUP_ADDRESS_A = {536, 537, 538, 539, 540, 541, 546, 547, 548, 549, 550, 551, 556, 557, + 558, 559}; + public static final int[] IDENTIFIER_B = {560, 561, 566, 567}; + public static final int[] CHANNEL_B = {568, 569, 570, 571, 720, 721, 722, 723, 724, 725, 730, 731}; + public static final int[] GROUP_ADDRESS_B = {732, 733, 734, 735, 740, 741, 742, 743, 744, 745, 750, 751, 752, 753, + 754, 755}; + + private IBandIdentifier mIdentifierUpdateA; + private IBandIdentifier mIdentifierUpdateB; + + public GroupVoiceChannelUpdate(LDU1Message message) + { + super(message); + } - public static final int[] IDENTIFIER_A = { 364,365,366,367 }; - public static final int[] CHANNEL_A = { 372,373,374,375,376,377,382,383,384, - 385,386,387 }; - public static final int[] GROUP_ADDRESS_A = { 536,537,538,539,540,541,546, - 547,548,549,550,551,556,557,558,559 }; - public static final int[] IDENTIFIER_B = { 560,561,566,567 }; - public static final int[] CHANNEL_B = { 568,569,570,571,720,721,722,723,724, - 725,730,731 }; - public static final int[] GROUP_ADDRESS_B = { 732,733,734,735,740,741,742, - 743,744,745,750,751,752,753,754,755 }; - - private IBandIdentifier mIdentifierUpdateA; - private IBandIdentifier mIdentifierUpdateB; - - public GroupVoiceChannelUpdate( LDU1Message message ) - { - super( message ); - } - @Override public String getEventType() { return LinkControlOpcode.GROUP_VOICE_CHANNEL_UPDATE.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " CHAN A:" + getChannelA() ); - - sb.append( " GRP A:" + getGroupAddressA() ); - - if( hasChannelB() ) - { - sb.append( " CHAN B:" + getChannelA() ); - - sb.append( " GRP B:" + getGroupAddressA() ); - } - - return sb.toString(); - } + @Override + public String getMessage() + { + StringBuilder sb = new StringBuilder(); + + sb.append(getMessageStub()); + + sb.append(" CHAN A:" + getChannelA()); + + sb.append(" GRP A:" + getGroupAddressA()); + + if(hasChannelB()) + { + sb.append(" CHAN B:" + getChannelA()); + + sb.append(" GRP B:" + getGroupAddressA()); + } + + return sb.toString(); + } + + public int getChannelIdentifierA() + { + return mMessage.getInt(IDENTIFIER_A); + } - public int getChannelIdentifierA() - { - return mMessage.getInt( IDENTIFIER_A ); - } - public int getChannelNumberA() { - return mMessage.getInt( CHANNEL_A ); + return mMessage.getInt(CHANNEL_A); } - + public String getChannelA() { - return getChannelIdentifierA() + "-" + getChannelNumberA(); + return getChannelIdentifierA() + "-" + getChannelNumberA(); } - - public int getChannelIdentifierB() - { - return mMessage.getInt( IDENTIFIER_B ); - } - + + public int getChannelIdentifierB() + { + return mMessage.getInt(IDENTIFIER_B); + } + public int getChannelNumberB() { - return mMessage.getInt( CHANNEL_B ); + return mMessage.getInt(CHANNEL_B); } - + public String getChannelB() { - return getChannelIdentifierB() + "-" + getChannelNumberB(); + return getChannelIdentifierB() + "-" + getChannelNumberB(); } - + public boolean hasChannelB() { - return getChannelNumberB() != 0; + return getChannelNumberB() != 0; } - + public String getGroupAddressA() { - return mMessage.getHex( GROUP_ADDRESS_A, 4 ); + return mMessage.getHex(GROUP_ADDRESS_A, 4); } public String getGroupAddressB() { - return mMessage.getHex( GROUP_ADDRESS_B, 4 ); + return mMessage.getHex(GROUP_ADDRESS_B, 4); } - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) { - if( identifier == getChannelIdentifierA() ) - { - mIdentifierUpdateA = message; - } - if( identifier == getChannelIdentifierB() ) - { - mIdentifierUpdateB = message; - } + if(identifier == getChannelIdentifierA()) + { + mIdentifierUpdateA = message; + } + if(identifier == getChannelIdentifierB()) + { + mIdentifierUpdateB = message; + } } - @Override + @Override public int[] getIdentifiers() { - if( hasChannelB() ) - { - int[] identifiers = new int[ 2 ]; - identifiers[ 0 ] = getChannelIdentifierA(); - identifiers[ 1 ] = getChannelIdentifierB(); - - return identifiers; - } - else - { - int[] identifiers = new int[ 1 ]; - identifiers[ 0 ] = getChannelIdentifierA(); - - return identifiers; - } + if(hasChannelB()) + { + int[] identifiers = new int[2]; + identifiers[0] = getChannelIdentifierA(); + identifiers[1] = getChannelIdentifierB(); + + return identifiers; + } + else + { + int[] identifiers = new int[1]; + identifiers[0] = getChannelIdentifierA(); + + return identifiers; + } } public long getDownlinkFrequencyA() { - return calculateDownlink( mIdentifierUpdateA, getChannelNumberA() ); + if(mIdentifierUpdateA != null) + { + return mIdentifierUpdateA.getDownlinkFrequency(getChannelNumberA()); + } + + return 0; } - + public long getUplinkFrequencyA() { - return calculateUplink( mIdentifierUpdateA, getChannelNumberA() ); + if(mIdentifierUpdateA != null) + { + return mIdentifierUpdateA.getUplinkFrequency(getChannelNumberA()); + } + + return 0; } public long getDownlinkFrequencyB() { - return calculateDownlink( mIdentifierUpdateB, getChannelNumberA() ); + if(mIdentifierUpdateB != null) + { + return mIdentifierUpdateB.getDownlinkFrequency(getChannelNumberB()); + } + + return 0; } - + public long getUplinkFrequencyB() { - return calculateUplink( mIdentifierUpdateB, getChannelNumberA() ); + if(mIdentifierUpdateB != null) + { + return mIdentifierUpdateB.getUplinkFrequency(getChannelNumberB()); + } + + return 0; } } diff --git a/src/module/decode/p25/message/ldu/lc/GroupVoiceChannelUpdateExplicit.java b/src/module/decode/p25/message/ldu/lc/GroupVoiceChannelUpdateExplicit.java index f3aa25f3..be2dfda5 100644 --- a/src/module/decode/p25/message/ldu/lc/GroupVoiceChannelUpdateExplicit.java +++ b/src/module/decode/p25/message/ldu/lc/GroupVoiceChannelUpdateExplicit.java @@ -1,3 +1,21 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.ldu.lc; import module.decode.p25.message.IBandIdentifier; @@ -5,151 +23,149 @@ import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.message.ldu.LDU1Message; import module.decode.p25.reference.LinkControlOpcode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class GroupVoiceChannelUpdateExplicit extends LDU1Message - implements IdentifierReceiver +public class GroupVoiceChannelUpdateExplicit extends LDU1Message implements IdentifierReceiver { - private final static Logger mLog = - LoggerFactory.getLogger( GroupVoiceChannelUpdateExplicit.class ); - public static final int EMERGENCY_FLAG = 376; public static final int ENCRYPTED_CHANNEL_FLAG = 377; public static final int DUPLEX_MODE = 382; public static final int SESSION_MODE = 383; - public static final int[] GROUP_ADDRESS = { 536,537,538,539,540,541,546,547, - 548,549,550,551,556,557,558,559 }; - public static final int[] TRANSMIT_IDENTIFIER = { 560,561,566,567 }; - public static final int[] TRANSMIT_CHANNEL = { 568,569,570,571,720,721,722, - 723,724,725,730,731 }; - public static final int[] RECEIVE_IDENTIFIER = { 732,733,734,735 }; - public static final int[] RECEIVE_CHANNEL = { 740,741,742,743,744,745,750, - 751,752,753,754,755 }; + public static final int[] GROUP_ADDRESS = {536, 537, 538, 539, 540, 541, 546, 547, 548, 549, 550, 551, 556, 557, 558, 559}; + public static final int[] TRANSMIT_IDENTIFIER = {560, 561, 566, 567}; + public static final int[] TRANSMIT_CHANNEL = {568, 569, 570, 571, 720, 721, 722, 723, 724, 725, 730, 731}; + public static final int[] RECEIVE_IDENTIFIER = {732, 733, 734, 735}; + public static final int[] RECEIVE_CHANNEL = {740, 741, 742, 743, 744, 745, 750, 751, 752, 753, 754, 755}; + + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; + + public GroupVoiceChannelUpdateExplicit(LDU1Message message) + { + super(message); + } - private IBandIdentifier mTransmitIdentifierUpdate; - private IBandIdentifier mReceiveIdentifierUpdate; - - public GroupVoiceChannelUpdateExplicit( LDU1Message message ) - { - super( message ); - } - @Override public String getEventType() { return LinkControlOpcode.GROUP_VOICE_CHANNEL_UPDATE_EXPLICIT.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - if( isEmergency() ) - { - sb.append( " EMERGENCY" ); - } - if( isEncryptedChannel() ) - { - sb.append( " ENCRYPTED CHANNEL" ); - } + @Override + public String getMessage() + { + StringBuilder sb = new StringBuilder(); - - return sb.toString(); - } + sb.append(getMessageStub()); + + if(isEmergency()) + { + sb.append(" EMERGENCY"); + } + if(isEncryptedChannel()) + { + sb.append(" ENCRYPTED CHANNEL"); + } + + + return sb.toString(); + } public boolean isEmergency() { - return mMessage.get( EMERGENCY_FLAG ); + return mMessage.get(EMERGENCY_FLAG); } - + public boolean isEncryptedChannel() { - return mMessage.get( ENCRYPTED_CHANNEL_FLAG ); + return mMessage.get(ENCRYPTED_CHANNEL_FLAG); } - + public DuplexMode getDuplexMode() { - return mMessage.get( DUPLEX_MODE ) ? DuplexMode.FULL : DuplexMode.HALF; + return mMessage.get(DUPLEX_MODE) ? DuplexMode.FULL : DuplexMode.HALF; } public SessionMode getSessionMode() { - return mMessage.get( SESSION_MODE ) ? - SessionMode.CIRCUIT : SessionMode.PACKET; + return mMessage.get(SESSION_MODE) ? + SessionMode.CIRCUIT : SessionMode.PACKET; } public int getTransmitChannelIdentifier() - { - return mMessage.getInt( TRANSMIT_IDENTIFIER ); - } - - public int getTransmitChannelNumber() { - return mMessage.getInt( TRANSMIT_CHANNEL ); - } - - public String getTransmitChannel() - { - return getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber(); - } - - public int getReceiveChannelIdentifier() - { - return mMessage.getInt( RECEIVE_IDENTIFIER ); - } - - public int getReceiveChannelNumber() - { - return mMessage.getInt( RECEIVE_CHANNEL ); - } - - public String getReceiveChannel() - { - return getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber(); - } - - public String getGroupAddress() - { - return mMessage.getHex( GROUP_ADDRESS, 4 ); - } - - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) - { - if( identifier == getTransmitChannelIdentifier() ) - { - mTransmitIdentifierUpdate = message; - } - if( identifier == getReceiveChannelIdentifier() ) - { - mReceiveIdentifierUpdate = message; - } + return mMessage.getInt(TRANSMIT_IDENTIFIER); } - @Override + public int getTransmitChannelNumber() + { + return mMessage.getInt(TRANSMIT_CHANNEL); + } + + public String getTransmitChannel() + { + return getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber(); + } + + public int getReceiveChannelIdentifier() + { + return mMessage.getInt(RECEIVE_IDENTIFIER); + } + + public int getReceiveChannelNumber() + { + return mMessage.getInt(RECEIVE_CHANNEL); + } + + public String getReceiveChannel() + { + return getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber(); + } + + public String getGroupAddress() + { + return mMessage.getHex(GROUP_ADDRESS, 4); + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getTransmitChannelIdentifier()) + { + mTransmitIdentifierUpdate = message; + } + if(identifier == getReceiveChannelIdentifier()) + { + mReceiveIdentifierUpdate = message; + } + } + + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 2 ]; - - identifiers[ 0 ] = getTransmitChannelIdentifier(); - identifiers[ 1 ] = getReceiveChannelIdentifier(); - - return identifiers; + int[] identifiers = new int[2]; + + identifiers[0] = getTransmitChannelIdentifier(); + identifiers[1] = getReceiveChannelIdentifier(); + + return identifiers; } public long getDownlinkFrequency() { - return calculateDownlink( mTransmitIdentifierUpdate, - getTransmitChannelNumber() ); + if(mTransmitIdentifierUpdate != null) + { + return mTransmitIdentifierUpdate.getDownlinkFrequency(getTransmitChannelNumber()); + } + + return 0; } - + public long getUplinkFrequency() { - return calculateUplink( mReceiveIdentifierUpdate, - getReceiveChannelNumber() ); + if(mReceiveIdentifierUpdate != null) + { + return mReceiveIdentifierUpdate.getUplinkFrequency(getReceiveChannelNumber()); + } + + return 0; } } diff --git a/src/module/decode/p25/message/ldu/lc/NetworkStatusBroadcast.java b/src/module/decode/p25/message/ldu/lc/NetworkStatusBroadcast.java index ec22b3ff..ae8091d9 100644 --- a/src/module/decode/p25/message/ldu/lc/NetworkStatusBroadcast.java +++ b/src/module/decode/p25/message/ldu/lc/NetworkStatusBroadcast.java @@ -1,3 +1,21 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.ldu.lc; import module.decode.p25.message.IBandIdentifier; @@ -6,105 +24,106 @@ import module.decode.p25.message.ldu.LDU1Message; import module.decode.p25.reference.LinkControlOpcode; import module.decode.p25.reference.Service; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class NetworkStatusBroadcast extends LDU1Message - implements IdentifierReceiver +public class NetworkStatusBroadcast extends LDU1Message implements IdentifierReceiver { - private final static Logger mLog = - LoggerFactory.getLogger( NetworkStatusBroadcast.class ); - public static final int[] NETWORK_ID = { 376,377,382,383,384,385,386,387, - 536,537,538,539,540,541,546,547,548,549,550,551 }; - public static final int[] SYSTEM_ID = { 556,557,558,559,560,561,566,567,568, - 569,570,571 }; - public static final int[] IDENTIFIER = { 720,721,722,723 }; - public static final int[] CHANNEL = { 724,725,730,731,732,733,734,735,740, - 741,742,743 }; - public static final int[] SYSTEM_SERVICE_CLASS = { 744,745,750,751,752,753, - 754,755 }; - - private IBandIdentifier mIdentifierUpdate; - - public NetworkStatusBroadcast( LDU1Message source ) - { - super( source ); - } - + public static final int[] NETWORK_ID = {376, 377, 382, 383, 384, 385, 386, 387, 536, 537, 538, 539, 540, 541, 546, + 547, 548, 549, 550, 551}; + public static final int[] SYSTEM_ID = {556, 557, 558, 559, 560, 561, 566, 567, 568, 569, 570, 571}; + public static final int[] IDENTIFIER = {720, 721, 722, 723}; + public static final int[] CHANNEL = {724, 725, 730, 731, 732, 733, 734, 735, 740, 741, 742, 743}; + public static final int[] SYSTEM_SERVICE_CLASS = {744, 745, 750, 751, 752, 753, 754, 755}; + + private IBandIdentifier mIdentifierUpdate; + + public NetworkStatusBroadcast(LDU1Message source) + { + super(source); + } + @Override public String getEventType() { return LinkControlOpcode.NETWORK_STATUS_BROADCAST.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " NETWORK:" + getNetworkID() ); - sb.append( " SYS:" + getSystem() ); - sb.append( " CHAN:" + getChannel() ); - sb.append( " " + Service.getServices( getSystemServiceClass() ).toString() ); - - return sb.toString(); - } - - public String getNetworkID() - { - return mMessage.getHex( NETWORK_ID, 5 ); - } - - public String getSystem() - { - return mMessage.getHex( SYSTEM_ID, 3 ); - } - - public int getIdentifier() - { - return mMessage.getInt( IDENTIFIER ); - } - - public int getChannelNumber() - { - return mMessage.getInt( CHANNEL ); - } - - public String getChannel() - { - return getIdentifier() + "-" + getChannelNumber(); - } - - public int getSystemServiceClass() - { - return mMessage.getInt( SYSTEM_SERVICE_CLASS ); - } - - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + @Override + public String getMessage() { - mIdentifierUpdate = message; + StringBuilder sb = new StringBuilder(); + + sb.append(getMessageStub()); + + sb.append(" NETWORK:" + getNetworkID()); + sb.append(" SYS:" + getSystem()); + sb.append(" CHAN:" + getChannel()); + sb.append(" " + Service.getServices(getSystemServiceClass()).toString()); + + return sb.toString(); } - @Override + public String getNetworkID() + { + return mMessage.getHex(NETWORK_ID, 5); + } + + public String getSystem() + { + return mMessage.getHex(SYSTEM_ID, 3); + } + + public int getIdentifier() + { + return mMessage.getInt(IDENTIFIER); + } + + public int getChannelNumber() + { + return mMessage.getInt(CHANNEL); + } + + public String getChannel() + { + return getIdentifier() + "-" + getChannelNumber(); + } + + public int getSystemServiceClass() + { + return mMessage.getInt(SYSTEM_SERVICE_CLASS); + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + mIdentifierUpdate = message; + } + + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 1 ]; - - identifiers[ 0 ] = getIdentifier(); - - return identifiers; + int[] identifiers = new int[1]; + + identifiers[0] = getIdentifier(); + + return identifiers; } - + public long getDownlinkFrequency() { - return calculateDownlink( mIdentifierUpdate, getChannelNumber() ); + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.getDownlinkFrequency(getChannelNumber()); + } + + return 0; } - + public long getUplinkFrequency() { - return calculateUplink( mIdentifierUpdate, getChannelNumber() ); + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.getUplinkFrequency(getChannelNumber()); + } + + return 0; } } diff --git a/src/module/decode/p25/message/ldu/lc/NetworkStatusBroadcastExplicit.java b/src/module/decode/p25/message/ldu/lc/NetworkStatusBroadcastExplicit.java index 682882ff..abfa7c92 100644 --- a/src/module/decode/p25/message/ldu/lc/NetworkStatusBroadcastExplicit.java +++ b/src/module/decode/p25/message/ldu/lc/NetworkStatusBroadcastExplicit.java @@ -1,131 +1,150 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.ldu.lc; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.message.ldu.LDU1Message; import module.decode.p25.reference.LinkControlOpcode; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class NetworkStatusBroadcastExplicit extends LDU1Message - implements IdentifierReceiver +public class NetworkStatusBroadcastExplicit extends LDU1Message implements IdentifierReceiver { - private final static Logger mLog = - LoggerFactory.getLogger( NetworkStatusBroadcastExplicit.class ); - public static final int[] NETWORK_ID = { 364,365,366,367,372,373,374,375, - 376,377,382,383,384,385,386,387,536,537,538,539 }; - public static final int[] SYSTEM_ID = { 540,541,546,547,548,549,550,551,556, - 557,558,559 }; - public static final int[] TRANSMIT_IDENTIFIER = { 560,561,566,567 }; - public static final int[] TRANSMIT_CHANNEL = { 568,569,570,571,720,721,722, - 723,724,725,730,731 }; - public static final int[] RECEIVE_IDENTIFIER = { 732,733,734,735 }; - public static final int[] RECEIVE_CHANNEL = { 740,741,742,743,744,745,750, - 751,752,753,754,755 }; - - private IBandIdentifier mTransmitIdentifierUpdate; - private IBandIdentifier mReceiveIdentifierUpdate; - - public NetworkStatusBroadcastExplicit( LDU1Message message ) - { - super( message ); - } - + public static final int[] NETWORK_ID = {364, 365, 366, 367, 372, 373, 374, 375, 376, 377, 382, 383, 384, 385, 386, + 387, 536, 537, 538, 539}; + public static final int[] SYSTEM_ID = {540, 541, 546, 547, 548, 549, 550, 551, 556, 557, 558, 559}; + public static final int[] TRANSMIT_IDENTIFIER = {560, 561, 566, 567}; + public static final int[] TRANSMIT_CHANNEL = {568, 569, 570, 571, 720, 721, 722, 723, 724, 725, 730, 731}; + public static final int[] RECEIVE_IDENTIFIER = {732, 733, 734, 735}; + public static final int[] RECEIVE_CHANNEL = {740, 741, 742, 743, 744, 745, 750, 751, 752, 753, 754, 755}; + + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; + + public NetworkStatusBroadcastExplicit(LDU1Message message) + { + super(message); + } + @Override public String getEventType() { return LinkControlOpcode.NETWORK_STATUS_BROADCAST_EXPLICIT.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " NETWORK:" + getNetworkID() ); - sb.append( " SYS:" + getSystem() ); - sb.append( " TRANSMIT:" + getTransmitChannel() ); - sb.append( " RECEIVE:" + getReceiveChannel() ); - - return sb.toString(); - } - - public String getNetworkID() - { - return mMessage.getHex( NETWORK_ID, 5 ); - } - - public String getSystem() - { - return mMessage.getHex( SYSTEM_ID, 3 ); - } - - public int getTransmitIdentifier() - { - return mMessage.getInt( TRANSMIT_IDENTIFIER ); - } - - public int getTransmitChannelNumber() - { - return mMessage.getInt( TRANSMIT_CHANNEL ); - } - - public String getTransmitChannel() - { - return getTransmitIdentifier() + "-" + getTransmitChannelNumber(); - } - - public int getReceiveIdentifier() - { - return mMessage.getInt( RECEIVE_IDENTIFIER ); - } - - public int getReceiveChannelNumber() - { - return mMessage.getInt( RECEIVE_CHANNEL ); - } - - public String getReceiveChannel() - { - return getReceiveIdentifier() + "-" + getReceiveChannelNumber(); - } - - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + @Override + public String getMessage() { - if( identifier == getTransmitIdentifier() ) - { - mTransmitIdentifierUpdate = message; - } - if( identifier == getReceiveIdentifier() ) - { - mReceiveIdentifierUpdate = message; - } + StringBuilder sb = new StringBuilder(); + + sb.append(getMessageStub()); + + sb.append(" NETWORK:" + getNetworkID()); + sb.append(" SYS:" + getSystem()); + sb.append(" TRANSMIT:" + getTransmitChannel()); + sb.append(" RECEIVE:" + getReceiveChannel()); + + return sb.toString(); } - @Override + public String getNetworkID() + { + return mMessage.getHex(NETWORK_ID, 5); + } + + public String getSystem() + { + return mMessage.getHex(SYSTEM_ID, 3); + } + + public int getTransmitIdentifier() + { + return mMessage.getInt(TRANSMIT_IDENTIFIER); + } + + public int getTransmitChannelNumber() + { + return mMessage.getInt(TRANSMIT_CHANNEL); + } + + public String getTransmitChannel() + { + return getTransmitIdentifier() + "-" + getTransmitChannelNumber(); + } + + public int getReceiveIdentifier() + { + return mMessage.getInt(RECEIVE_IDENTIFIER); + } + + public int getReceiveChannelNumber() + { + return mMessage.getInt(RECEIVE_CHANNEL); + } + + public String getReceiveChannel() + { + return getReceiveIdentifier() + "-" + getReceiveChannelNumber(); + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getTransmitIdentifier()) + { + mTransmitIdentifierUpdate = message; + } + if(identifier == getReceiveIdentifier()) + { + mReceiveIdentifierUpdate = message; + } + } + + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 2 ]; - - identifiers[ 0 ] = getTransmitIdentifier(); - identifiers[ 1 ] = getReceiveIdentifier(); - - return identifiers; + int[] identifiers = new int[2]; + + identifiers[0] = getTransmitIdentifier(); + identifiers[1] = getReceiveIdentifier(); + + return identifiers; } - + public long getDownlinkFrequency() { - return calculateDownlink( mTransmitIdentifierUpdate, - getTransmitChannelNumber() ); + if(mTransmitIdentifierUpdate != null) + { + return mTransmitIdentifierUpdate.getDownlinkFrequency(getTransmitChannelNumber()); + } + + return 0; } - + public long getUplinkFrequency() { - return calculateUplink( mReceiveIdentifierUpdate, - getReceiveChannelNumber() ); + if(mReceiveIdentifierUpdate != null) + { + return mReceiveIdentifierUpdate.getUplinkFrequency(getReceiveChannelNumber()); + } + + return 0; } } diff --git a/src/module/decode/p25/message/ldu/lc/RFSSStatusBroadcast.java b/src/module/decode/p25/message/ldu/lc/RFSSStatusBroadcast.java index 07edbef1..02b6017d 100644 --- a/src/module/decode/p25/message/ldu/lc/RFSSStatusBroadcast.java +++ b/src/module/decode/p25/message/ldu/lc/RFSSStatusBroadcast.java @@ -1,3 +1,21 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.ldu.lc; import module.decode.p25.message.IBandIdentifier; @@ -6,125 +24,124 @@ import module.decode.p25.message.ldu.LDU1Message; import module.decode.p25.message.tsbk.osp.control.SystemService; import module.decode.p25.reference.LinkControlOpcode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class RFSSStatusBroadcast extends LDU1Message - implements IdentifierReceiver +public class RFSSStatusBroadcast extends LDU1Message implements IdentifierReceiver { - private final static Logger mLog = - LoggerFactory.getLogger( RFSSStatusBroadcast.class ); + public static final int[] LRA = {364, 365, 366, 367, 372, 373, 374, 375}; + public static final int[] SYSTEM_ID = {384, 385, 386, 387, 536, 537, 538, 539, 540, 541, 546, 547}; + public static final int[] RFSS_ID = {548, 549, 550, 551, 556, 557, 558, 559}; + public static final int[] SITE_ID = {560, 561, 566, 567, 568, 569, 570, 571}; + public static final int[] IDENTIFIER = {720, 721, 722, 723}; + public static final int[] CHANNEL = {724, 725, 730, 731, 732, 733, 734, 735, 740, 741, 742, 743}; + public static final int[] SYSTEM_SERVICE_CLASS = {744, 745, 750, 751, 752, 753, 754, 755}; + + private IBandIdentifier mIdentifierUpdate; + + public RFSSStatusBroadcast(LDU1Message message) + { + super(message); + } - public static final int[] LRA = { 364,365,366,367,372,373,374,375 }; - public static final int[] SYSTEM_ID = { 384,385,386,387,536,537,538,539,540, - 541,546,547 }; - public static final int[] RFSS_ID = { 548,549,550,551,556,557,558,559 }; - public static final int[] SITE_ID = { 560,561,566,567,568,569,570,571 }; - public static final int[] IDENTIFIER = { 720,721,722,723 }; - public static final int[] CHANNEL = { 724,725,730,731,732,733,734,735,740, - 741,742,743 }; - public static final int[] SYSTEM_SERVICE_CLASS = { 744,745,750,751,752,753, - 754,755 }; - - private IBandIdentifier mIdentifierUpdate; - - public RFSSStatusBroadcast( LDU1Message message ) - { - super( message ); - } - @Override public String getEventType() { return LinkControlOpcode.RFSS_STATUS_BROADCAST.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " LRA:" + getLocationRegistrationArea() ); - - sb.append( " SYS:" + getSystem() ); - - sb.append( " SITE:" + getRFSubsystemID() + "-" + getSiteID() ); - - sb.append( " CHAN:" + getChannelNumber() ); - - sb.append( " " + SystemService.toString( getSystemServiceClass() ) ); - - sb.append( " " + mMessage.toString() ); - - return sb.toString(); - } - - public String getLocationRegistrationArea() - { - return mMessage.getHex( LRA, 2 ); - } - - public String getSystem() - { - return mMessage.getHex( SYSTEM_ID, 3 ); - } - - public String getRFSubsystemID() - { - return mMessage.getHex( RFSS_ID, 2 ); - } - - public String getSiteID() - { - return mMessage.getHex( SITE_ID, 2 ); - } - - public int getIdentifier() - { - return mMessage.getInt( IDENTIFIER ); - } - - public String getChannel() - { - return getIdentifier() + "-" + getChannelNumber(); - } - - public int getChannelNumber() - { - return mMessage.getInt( CHANNEL ); - } - - public int getSystemServiceClass() - { - return mMessage.getInt( SYSTEM_SERVICE_CLASS ); - } - - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + @Override + public String getMessage() { - mIdentifierUpdate = message; + StringBuilder sb = new StringBuilder(); + + sb.append(getMessageStub()); + + sb.append(" LRA:" + getLocationRegistrationArea()); + + sb.append(" SYS:" + getSystem()); + + sb.append(" SITE:" + getRFSubsystemID() + "-" + getSiteID()); + + sb.append(" CHAN:" + getChannelNumber()); + + sb.append(" " + SystemService.toString(getSystemServiceClass())); + + sb.append(" " + mMessage.toString()); + + return sb.toString(); } - @Override + public String getLocationRegistrationArea() + { + return mMessage.getHex(LRA, 2); + } + + public String getSystem() + { + return mMessage.getHex(SYSTEM_ID, 3); + } + + public String getRFSubsystemID() + { + return mMessage.getHex(RFSS_ID, 2); + } + + public String getSiteID() + { + return mMessage.getHex(SITE_ID, 2); + } + + public int getIdentifier() + { + return mMessage.getInt(IDENTIFIER); + } + + public String getChannel() + { + return getIdentifier() + "-" + getChannelNumber(); + } + + public int getChannelNumber() + { + return mMessage.getInt(CHANNEL); + } + + public int getSystemServiceClass() + { + return mMessage.getInt(SYSTEM_SERVICE_CLASS); + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + mIdentifierUpdate = message; + } + + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 1 ]; - - identifiers[ 0 ] = getIdentifier(); - - return identifiers; + int[] identifiers = new int[1]; + + identifiers[0] = getIdentifier(); + + return identifiers; } - + public long getDownlinkFrequency() { - return calculateDownlink( mIdentifierUpdate, getChannelNumber() ); + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.getDownlinkFrequency(getChannelNumber()); + } + + return 0; } - + public long getUplinkFrequency() { - return calculateUplink( mIdentifierUpdate, getChannelNumber() ); + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.getUplinkFrequency(getChannelNumber()); + } + + return 0; } - } diff --git a/src/module/decode/p25/message/ldu/lc/RFSSStatusBroadcastExplicit.java b/src/module/decode/p25/message/ldu/lc/RFSSStatusBroadcastExplicit.java index b3b7b7ec..54b813d5 100644 --- a/src/module/decode/p25/message/ldu/lc/RFSSStatusBroadcastExplicit.java +++ b/src/module/decode/p25/message/ldu/lc/RFSSStatusBroadcastExplicit.java @@ -1,3 +1,21 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.ldu.lc; import module.decode.p25.message.IBandIdentifier; @@ -5,146 +23,148 @@ import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.message.ldu.LDU1Message; import module.decode.p25.message.tsbk.osp.control.SystemService; import module.decode.p25.reference.LinkControlOpcode; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class RFSSStatusBroadcastExplicit extends LDU1Message - implements IdentifierReceiver +public class RFSSStatusBroadcastExplicit extends LDU1Message implements IdentifierReceiver { - private final static Logger mLog = - LoggerFactory.getLogger( RFSSStatusBroadcastExplicit.class ); + public static final int[] LRA = {364, 365, 366, 367, 372, 373, 374, 375}; + public static final int[] RECEIVE_IDENTIFIER = {376, 377, 382, 383}; + public static final int[] RECEIVE_CHANNEL = {384, 385, 386, 387, 536, 537, 538, 539, 540, 541, 546, 547}; + public static final int[] RFSS_ID = {548, 549, 550, 551, 556, 557, 558, 559}; + public static final int[] SITE_ID = {560, 561, 566, 567, 568, 569, 570, 571}; + public static final int[] TRANSMIT_IDENTIFIER = {720, 721, 722, 723}; + public static final int[] TRANSMIT_CHANNEL = {724, 725, 730, 731, 732, 733, 734, 735, 740, 741, 742, 743}; + public static final int[] SYSTEM_SERVICE_CLASS = {744, 745, 750, 751, 752, 753, 754, 755}; - public static final int[] LRA = { 364,365,366,367,372,373,374,375 }; - public static final int[] RECEIVE_IDENTIFIER = { 376,377,382,383 }; - public static final int[] RECEIVE_CHANNEL = { 384,385,386,387,536,537,538, - 539,540,541,546,547 }; - public static final int[] RFSS_ID = { 548,549,550,551,556,557,558,559 }; - public static final int[] SITE_ID = { 560,561,566,567,568,569,570,571 }; - public static final int[] TRANSMIT_IDENTIFIER = { 720,721,722,723 }; - public static final int[] TRANSMIT_CHANNEL = { 724,725,730,731,732,733,734, - 735,740,741,742,743 }; - public static final int[] SYSTEM_SERVICE_CLASS = { 744,745,750,751,752,753,754,755 }; + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; + + public RFSSStatusBroadcastExplicit(LDU1Message source) + { + super(source); + } - private IBandIdentifier mTransmitIdentifierUpdate; - private IBandIdentifier mReceiveIdentifierUpdate; - - public RFSSStatusBroadcastExplicit( LDU1Message source ) - { - super( source ); - } - @Override public String getEventType() { return LinkControlOpcode.RFSS_STATUS_BROADCAST_EXPLICIT.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " LRA:" + getLocationRegistrationArea() ); - - sb.append( " SITE:" + getRFSubsystemID() + "-" + getSiteID() ); - - sb.append( " TRANSMIT:" + getTransmitChannelNumber() ); - - sb.append( " RECEIVE:" + getReceiveChannelNumber() ); - - sb.append( " " + SystemService.toString( getSystemServiceClass() ) ); - - sb.append( " " + mMessage.toString() ); - - return sb.toString(); - } - - public String getLocationRegistrationArea() - { - return mMessage.getHex( LRA, 2 ); - } - - public String getRFSubsystemID() - { - return mMessage.getHex( RFSS_ID, 2 ); - } - - public String getSiteID() - { - return mMessage.getHex( SITE_ID, 2 ); - } - - public int getTransmitIdentifier() - { - return mMessage.getInt( TRANSMIT_IDENTIFIER ); - } - - public String getTransmitChannel() - { - return getTransmitIdentifier() + "-" + getTransmitChannelNumber(); - } - - public int getTransmitChannelNumber() - { - return mMessage.getInt( TRANSMIT_CHANNEL ); - } - - public int getReceiveIdentifier() - { - return mMessage.getInt( RECEIVE_IDENTIFIER ); - } - - public String getReceiveChannel() - { - return getReceiveIdentifier() + "-" + getReceiveChannelNumber(); - } - - public int getReceiveChannelNumber() - { - return mMessage.getInt( RECEIVE_CHANNEL ); - } - - public int getSystemServiceClass() - { - return mMessage.getInt( SYSTEM_SERVICE_CLASS ); - } - - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + @Override + public String getMessage() { - if( identifier == getTransmitIdentifier() ) - { - mTransmitIdentifierUpdate = message; - } - - if( identifier == getReceiveIdentifier() ) - { - mReceiveIdentifierUpdate = message; - } + StringBuilder sb = new StringBuilder(); + + sb.append(getMessageStub()); + + sb.append(" LRA:" + getLocationRegistrationArea()); + + sb.append(" SITE:" + getRFSubsystemID() + "-" + getSiteID()); + + sb.append(" TRANSMIT:" + getTransmitChannelNumber()); + + sb.append(" RECEIVE:" + getReceiveChannelNumber()); + + sb.append(" " + SystemService.toString(getSystemServiceClass())); + + sb.append(" " + mMessage.toString()); + + return sb.toString(); } - @Override + public String getLocationRegistrationArea() + { + return mMessage.getHex(LRA, 2); + } + + public String getRFSubsystemID() + { + return mMessage.getHex(RFSS_ID, 2); + } + + public String getSiteID() + { + return mMessage.getHex(SITE_ID, 2); + } + + public int getTransmitIdentifier() + { + return mMessage.getInt(TRANSMIT_IDENTIFIER); + } + + public String getTransmitChannel() + { + return getTransmitIdentifier() + "-" + getTransmitChannelNumber(); + } + + public int getTransmitChannelNumber() + { + return mMessage.getInt(TRANSMIT_CHANNEL); + } + + public int getReceiveIdentifier() + { + return mMessage.getInt(RECEIVE_IDENTIFIER); + } + + public String getReceiveChannel() + { + return getReceiveIdentifier() + "-" + getReceiveChannelNumber(); + } + + public int getReceiveChannelNumber() + { + return mMessage.getInt(RECEIVE_CHANNEL); + } + + public int getSystemServiceClass() + { + return mMessage.getInt(SYSTEM_SERVICE_CLASS); + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getTransmitIdentifier()) + { + mTransmitIdentifierUpdate = message; + } + + if(identifier == getReceiveIdentifier()) + { + mReceiveIdentifierUpdate = message; + } + } + + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 2 ]; - - identifiers[ 0 ] = getTransmitIdentifier(); - identifiers[ 1 ] = getReceiveIdentifier(); - - return identifiers; + int[] identifiers = new int[2]; + + identifiers[0] = getTransmitIdentifier(); + identifiers[1] = getReceiveIdentifier(); + + return identifiers; } - + public long getDownlinkFrequency() { - return calculateDownlink( mTransmitIdentifierUpdate, getTransmitChannelNumber() ); + if(mTransmitIdentifierUpdate != null) + { + return mTransmitIdentifierUpdate.getDownlinkFrequency(getTransmitChannelNumber()); + } + + return 0; } - + public long getUplinkFrequency() { - return calculateUplink( mReceiveIdentifierUpdate, getReceiveChannelNumber() ); + if(mReceiveIdentifierUpdate != null) + { + return mReceiveIdentifierUpdate.getUplinkFrequency(getReceiveChannelNumber()); + } + + return 0; } - } diff --git a/src/module/decode/p25/message/ldu/lc/SecondaryControlChannelBroadcast.java b/src/module/decode/p25/message/ldu/lc/SecondaryControlChannelBroadcast.java index e154f8d5..e275d0fa 100644 --- a/src/module/decode/p25/message/ldu/lc/SecondaryControlChannelBroadcast.java +++ b/src/module/decode/p25/message/ldu/lc/SecondaryControlChannelBroadcast.java @@ -1,3 +1,21 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.ldu.lc; import module.decode.p25.message.IBandIdentifier; @@ -6,151 +24,162 @@ import module.decode.p25.message.ldu.LDU1Message; import module.decode.p25.message.tsbk.osp.control.SystemService; import module.decode.p25.reference.LinkControlOpcode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SecondaryControlChannelBroadcast extends LDU1Message - implements IdentifierReceiver +public class SecondaryControlChannelBroadcast extends LDU1Message implements IdentifierReceiver { - private final static Logger mLog = - LoggerFactory.getLogger( SecondaryControlChannelBroadcast.class ); + public static final int[] RFSS_ID = {364, 365, 366, 367, 372, 373, 374, 375}; + public static final int[] SITE_ID = {376, 377, 382, 383, 384, 385, 386, 387}; + public static final int[] IDENTIFIER_A = {536, 537, 538, 539}; + public static final int[] CHANNEL_A = {540, 541, 546, 547, 548, 549, 550, 551, 556, 557, 558, 559}; + public static final int[] SYSTEM_SERVICE_CLASS_A = {560, 561, 566, 567, 568, 569, 570, 571}; + public static final int[] IDENTIFIER_B = {720, 721, 722, 723}; + public static final int[] CHANNEL_B = {724, 725, 730, 731, 732, 733, 734, 735, 740, 741, 742, 743}; + public static final int[] SYSTEM_SERVICE_CLASS_B = {744, 745, 750, 751, 752, 753, 754, 755}; - public static final int[] RFSS_ID = { 364,365,366,367,372,373,374,375 }; - public static final int[] SITE_ID = { 376,377,382,383,384,385,386,387 }; - public static final int[] IDENTIFIER_A = { 536,537,538,539 }; - public static final int[] CHANNEL_A = { 540,541,546,547,548,549,550,551, - 556,557,558,559 }; - public static final int[] SYSTEM_SERVICE_CLASS_A = { 560,561,566,567,568,569,570,571 }; - public static final int[] IDENTIFIER_B = { 720,721,722,723 }; - public static final int[] CHANNEL_B = { 724,725,730,731,732,733,734,735,740, - 741,742,743 }; - public static final int[] SYSTEM_SERVICE_CLASS_B = { 744,745,750,751,752,753,754,755 }; + private IBandIdentifier mIdentifierProviderA; + private IBandIdentifier mIdentifierProviderB; + + public SecondaryControlChannelBroadcast(LDU1Message message) + { + super(message); + } - private IBandIdentifier mIdentifierProviderA; - private IBandIdentifier mIdentifierProviderB; - - public SecondaryControlChannelBroadcast( LDU1Message message ) - { - super( message ); - } - @Override public String getEventType() { return LinkControlOpcode.SECONDARY_CONTROL_CHANNEL_BROADCAST.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " SITE:" + getRFSubsystemID() + "-" + getSiteID() ); - - sb.append( " CHAN A:" + getChannelA() ); - - sb.append( " " + SystemService.toString( getSystemServiceClassA() ) ); - - sb.append( " CHAN B:" + getChannelB() ); - - sb.append( " " + SystemService.toString( getSystemServiceClassB() ) ); - - return sb.toString(); - } - - public String getRFSubsystemID() - { - return mMessage.getHex( RFSS_ID, 2 ); - } - - public String getSiteID() - { - return mMessage.getHex( SITE_ID, 2 ); - } - - public int getIdentifierA() - { - return mMessage.getInt( IDENTIFIER_A ); - } - - public int getChannelA() - { - return mMessage.getInt( CHANNEL_A ); - } - - public String getChannelNumberA() - { - return getIdentifierA() + "-" + getChannelA(); - } - - public int getIdentifierB() - { - return mMessage.getInt( IDENTIFIER_B ); - } - - public int getChannelB() - { - return mMessage.getInt( CHANNEL_B ); - } - - public String getChannelNumberB() - { - return getIdentifierB() + "-" + getChannelB(); - } - - public int getSystemServiceClassA() - { - return mMessage.getInt( SYSTEM_SERVICE_CLASS_A ); - } - - public int getSystemServiceClassB() - { - return mMessage.getInt( SYSTEM_SERVICE_CLASS_B ); - } - - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + @Override + public String getMessage() { - if( identifier == getIdentifierA() ) - { - mIdentifierProviderA = message; - } - if( identifier == getIdentifierB() ) - { - mIdentifierProviderB = message; - } + StringBuilder sb = new StringBuilder(); + + sb.append(getMessageStub()); + + sb.append(" SITE:" + getRFSubsystemID() + "-" + getSiteID()); + + sb.append(" CHAN A:" + getChannelA()); + + sb.append(" " + SystemService.toString(getSystemServiceClassA())); + + sb.append(" CHAN B:" + getChannelB()); + + sb.append(" " + SystemService.toString(getSystemServiceClassB())); + + return sb.toString(); } - @Override + public String getRFSubsystemID() + { + return mMessage.getHex(RFSS_ID, 2); + } + + public String getSiteID() + { + return mMessage.getHex(SITE_ID, 2); + } + + public int getIdentifierA() + { + return mMessage.getInt(IDENTIFIER_A); + } + + public int getChannelA() + { + return mMessage.getInt(CHANNEL_A); + } + + public String getChannelNumberA() + { + return getIdentifierA() + "-" + getChannelA(); + } + + public int getIdentifierB() + { + return mMessage.getInt(IDENTIFIER_B); + } + + public int getChannelB() + { + return mMessage.getInt(CHANNEL_B); + } + + public String getChannelNumberB() + { + return getIdentifierB() + "-" + getChannelB(); + } + + public int getSystemServiceClassA() + { + return mMessage.getInt(SYSTEM_SERVICE_CLASS_A); + } + + public int getSystemServiceClassB() + { + return mMessage.getInt(SYSTEM_SERVICE_CLASS_B); + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getIdentifierA()) + { + mIdentifierProviderA = message; + } + if(identifier == getIdentifierB()) + { + mIdentifierProviderB = message; + } + } + + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 2 ]; - - identifiers[ 0 ] = getIdentifierA(); - identifiers[ 1 ] = getIdentifierB(); - - return identifiers; + int[] identifiers = new int[2]; + + identifiers[0] = getIdentifierA(); + identifiers[1] = getIdentifierB(); + + return identifiers; } - + public long getDownlinkFrequencyA() { - return calculateDownlink( mIdentifierProviderA, getChannelA() ); + if(mIdentifierProviderA != null) + { + return mIdentifierProviderA.getDownlinkFrequency(getChannelA()); + } + + return 0; } - + public long getUplinkFrequencyA() { - return calculateUplink( mIdentifierProviderA, getChannelA() ); + if(mIdentifierProviderA != null) + { + return mIdentifierProviderA.getUplinkFrequency(getChannelA()); + } + + return 0; } - + public long getDownlinkFrequencyB() { - return calculateDownlink( mIdentifierProviderB, getChannelB() ); + if(mIdentifierProviderB != null) + { + return mIdentifierProviderB.getDownlinkFrequency(getChannelB()); + } + + return 0; } - + public long getUplinkFrequencyB() { - return calculateUplink( mIdentifierProviderB, getChannelB() ); + if(mIdentifierProviderB != null) + { + return mIdentifierProviderB.getUplinkFrequency(getChannelB()); + } + + return 0; } } diff --git a/src/module/decode/p25/message/ldu/lc/SecondaryControlChannelBroadcastExplicit.java b/src/module/decode/p25/message/ldu/lc/SecondaryControlChannelBroadcastExplicit.java index 299531b2..00ae9b8c 100644 --- a/src/module/decode/p25/message/ldu/lc/SecondaryControlChannelBroadcastExplicit.java +++ b/src/module/decode/p25/message/ldu/lc/SecondaryControlChannelBroadcastExplicit.java @@ -1,3 +1,21 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.ldu.lc; import module.decode.p25.message.IBandIdentifier; @@ -6,136 +24,134 @@ import module.decode.p25.message.ldu.LDU1Message; import module.decode.p25.message.tsbk.osp.control.SystemService; import module.decode.p25.reference.LinkControlOpcode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SecondaryControlChannelBroadcastExplicit - extends LDU1Message implements IdentifierReceiver +public class SecondaryControlChannelBroadcastExplicit extends LDU1Message implements IdentifierReceiver { - private final static Logger mLog = - LoggerFactory.getLogger( SecondaryControlChannelBroadcastExplicit.class ); + public static final int[] RFSS_ID = {364, 365, 366, 367, 372, 373, 374, 375}; + public static final int[] SITE_ID = {376, 377, 382, 383, 384, 385, 386, 387}; + public static final int[] TRANSMIT_IDENTIFIER = {536, 537, 538, 539}; + public static final int[] TRANSMIT_CHANNEL = {540, 541, 546, 547, 548, 549, 550, 551, 556, 557, 558, 559}; + public static final int[] RECEIVE_IDENTIFIER = {560, 561, 566, 567}; + public static final int[] RECEIVE_CHANNEL = {568, 569, 570, 571, 720, 721, 722, 723, 724, 725, 730, 731}; + public static final int[] SYSTEM_SERVICE_CLASS = {732, 733, 734, 735, 740, 741, 742, 743}; + + private IBandIdentifier mTransmitIdentifierProvider; + private IBandIdentifier mReceiveIdentifierProvider; + + public SecondaryControlChannelBroadcastExplicit(LDU1Message message) + { + super(message); + } - public static final int[] RFSS_ID = { 364,365,366,367,372,373,374,375 }; - public static final int[] SITE_ID = { 376,377,382,383,384,385,386,387 }; - public static final int[] TRANSMIT_IDENTIFIER = { 536,537,538,539 }; - public static final int[] TRANSMIT_CHANNEL = { 540,541,546,547,548,549,550, - 551,556,557,558,559 }; - public static final int[] RECEIVE_IDENTIFIER = { 560,561,566,567 }; - public static final int[] RECEIVE_CHANNEL = { 568,569,570,571,720,721,722, - 723,724,725,730,731 }; - public static final int[] SYSTEM_SERVICE_CLASS = { 732,733,734,735,740,741, - 742,743 }; - - private IBandIdentifier mTransmitIdentifierProvider; - private IBandIdentifier mReceiveIdentifierProvider; - - public SecondaryControlChannelBroadcastExplicit( LDU1Message message ) - { - super( message ); - } - @Override public String getEventType() { return LinkControlOpcode.SECONDARY_CONTROL_CHANNEL_BROADCAST_EXPLICIT.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " SITE:" + getRFSubsystemID() + "-" + getSiteID() ); - - sb.append( " TRANSMIT:" + getTransmitChannel() ); - - sb.append( " RECEIVE:" + getReceiveChannel() ); - - sb.append( " " + SystemService.toString( getSystemServiceClass() ) ); - - return sb.toString(); - } - - public String getRFSubsystemID() - { - return mMessage.getHex( RFSS_ID, 2 ); - } - - public String getSiteID() - { - return mMessage.getHex( SITE_ID, 2 ); - } - - public int getTransmitIdentifier() - { - return mMessage.getInt( TRANSMIT_IDENTIFIER ); - } - - public int getTransmitChannelNumber() - { - return mMessage.getInt( TRANSMIT_CHANNEL ); - } - - public String getTransmitChannel() - { - return getTransmitIdentifier() + "-" + getTransmitChannelNumber(); - } - - public int getReceiveIdentifier() - { - return mMessage.getInt( RECEIVE_IDENTIFIER ); - } - - public int getReceiveChannelNumber() - { - return mMessage.getInt( RECEIVE_CHANNEL ); - } - - public String getReceiveChannel() - { - return getReceiveIdentifier() + "-" + getReceiveChannelNumber(); - } - - public int getSystemServiceClass() - { - return mMessage.getInt( SYSTEM_SERVICE_CLASS ); - } - - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + @Override + public String getMessage() { - if( identifier == getTransmitIdentifier() ) - { - mTransmitIdentifierProvider = message; - } - if( identifier == getReceiveIdentifier() ) - { - mReceiveIdentifierProvider = message; - } + StringBuilder sb = new StringBuilder(); + + sb.append(getMessageStub()); + + sb.append(" SITE:" + getRFSubsystemID() + "-" + getSiteID()); + + sb.append(" TRANSMIT:" + getTransmitChannel()); + + sb.append(" RECEIVE:" + getReceiveChannel()); + + sb.append(" " + SystemService.toString(getSystemServiceClass())); + + return sb.toString(); } - @Override + public String getRFSubsystemID() + { + return mMessage.getHex(RFSS_ID, 2); + } + + public String getSiteID() + { + return mMessage.getHex(SITE_ID, 2); + } + + public int getTransmitIdentifier() + { + return mMessage.getInt(TRANSMIT_IDENTIFIER); + } + + public int getTransmitChannelNumber() + { + return mMessage.getInt(TRANSMIT_CHANNEL); + } + + public String getTransmitChannel() + { + return getTransmitIdentifier() + "-" + getTransmitChannelNumber(); + } + + public int getReceiveIdentifier() + { + return mMessage.getInt(RECEIVE_IDENTIFIER); + } + + public int getReceiveChannelNumber() + { + return mMessage.getInt(RECEIVE_CHANNEL); + } + + public String getReceiveChannel() + { + return getReceiveIdentifier() + "-" + getReceiveChannelNumber(); + } + + public int getSystemServiceClass() + { + return mMessage.getInt(SYSTEM_SERVICE_CLASS); + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getTransmitIdentifier()) + { + mTransmitIdentifierProvider = message; + } + if(identifier == getReceiveIdentifier()) + { + mReceiveIdentifierProvider = message; + } + } + + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 2 ]; - - identifiers[ 0 ] = getTransmitIdentifier(); - identifiers[ 1 ] = getReceiveIdentifier(); - - return identifiers; + int[] identifiers = new int[2]; + + identifiers[0] = getTransmitIdentifier(); + identifiers[1] = getReceiveIdentifier(); + + return identifiers; } - + public long getDownlinkFrequency() { - return calculateDownlink( mTransmitIdentifierProvider, - getTransmitChannelNumber() ); + if(mTransmitIdentifierProvider != null) + { + return mTransmitIdentifierProvider.getDownlinkFrequency(getTransmitChannelNumber()); + } + + return 0; } - + public long getUplinkFrequency() { - return calculateUplink( mReceiveIdentifierProvider, - getReceiveChannelNumber() ); + if(mReceiveIdentifierProvider != null) + { + return mReceiveIdentifierProvider.getUplinkFrequency(getReceiveChannelNumber()); + } + + return 0; } } diff --git a/src/module/decode/p25/message/pdu/UnitToUnitChannelGrantExtended.java b/src/module/decode/p25/message/pdu/UnitToUnitChannelGrantExtended.java index ac8a1f30..29bd9bc4 100644 --- a/src/module/decode/p25/message/pdu/UnitToUnitChannelGrantExtended.java +++ b/src/module/decode/p25/message/pdu/UnitToUnitChannelGrantExtended.java @@ -1,199 +1,220 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.pdu; -import module.decode.p25.message.IBandIdentifier; -import module.decode.p25.message.IdentifierReceiver; -import module.decode.p25.reference.DataUnitID; import alias.AliasList; import bits.BinaryMessage; import edac.CRCP25; +import module.decode.p25.message.IBandIdentifier; +import module.decode.p25.message.IdentifierReceiver; +import module.decode.p25.reference.DataUnitID; -public abstract class UnitToUnitChannelGrantExtended extends PDUMessage - implements IdentifierReceiver +public abstract class UnitToUnitChannelGrantExtended extends PDUMessage implements IdentifierReceiver { /* Service Options */ public static final int EMERGENCY_FLAG = 128; public static final int ENCRYPTED_CHANNEL_FLAG = 129; public static final int DUPLEX_MODE = 130; public static final int SESSION_MODE = 131; - - public static final int[] SOURCE_ADDRESS = { 88,89,90,91,92,93,94,95,96,97, - 98,99,100,101,102,103,104,105,106,107,108,109,110,111 }; - public static final int[] SERVICE_OPTIONS = { 128,129,130,131,132,133,134, - 135 }; - public static final int[] SOURCE_WACN = { 160,161,162,163,164,165,166,167, - 168,169,170,171,172,173,174,175,176,177,178,179 }; - public static final int[] SOURCE_SYSTEM_ID = { 180,181,182,183,184,185,186, - 187,188,189,190,191 }; - public static final int[] SOURCE_ID = { 192,193,194,195,196,197,198,199,200, - 201,202,203,204,205,206,207,208,209,210,211,212,213,214,215 }; - public static final int[] TARGET_ADDRESS = { 216,217,218,219,220,221,222, - 223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239 }; - public static final int[] TRANSMIT_IDENTIFIER = { 240,241,242,243 }; - public static final int[] TRANSMIT_NUMBER = { 244,245,246,247,248,249,250, - 251,252,253,254,255 }; - public static final int[] RECEIVE_IDENTIFIER = { 256,257,258,259 }; - public static final int[] RECEIVE_NUMBER = { 260,261,262,263,264,265,266, - 267,268,269,270,271 }; - public static final int[] MULTIPLE_BLOCK_CRC = { 320,321,322,323,324,325, - 326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342, - 343,344,345,346,347,348,349,350,351 }; - - private IBandIdentifier mTransmitIdentifierUpdate; - private IBandIdentifier mReceiveIdentifierUpdate; - - public UnitToUnitChannelGrantExtended( BinaryMessage message, - DataUnitID duid, AliasList aliasList ) + + public static final int[] SOURCE_ADDRESS = {88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111}; + public static final int[] SERVICE_OPTIONS = {128, 129, 130, 131, 132, 133, 134, 135}; + public static final int[] SOURCE_WACN = {160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179}; + public static final int[] SOURCE_SYSTEM_ID = {180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191}; + public static final int[] SOURCE_ID = {192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215}; + public static final int[] TARGET_ADDRESS = {216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239}; + public static final int[] TRANSMIT_IDENTIFIER = {240, 241, 242, 243}; + public static final int[] TRANSMIT_NUMBER = {244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}; + public static final int[] RECEIVE_IDENTIFIER = {256, 257, 258, 259}; + public static final int[] RECEIVE_NUMBER = {260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271}; + public static final int[] MULTIPLE_BLOCK_CRC = {320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351}; + + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; + + public UnitToUnitChannelGrantExtended(BinaryMessage message, DataUnitID duid, AliasList aliasList) { - super( message, duid, aliasList ); + super(message, duid, aliasList); /* Header block is already error detected/corrected - perform error - * detection correction on the intermediate and final data blocks */ - mMessage = CRCP25.correctPDU2( mMessage ); - mCRC[ 1 ] = mMessage.getCRC(); + * detection correction on the intermediate and final data blocks */ + mMessage = CRCP25.correctPDU2(mMessage); + mCRC[1] = mMessage.getCRC(); } public String getMessage() { StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - if( isEmergency() ) + sb.append(getMessageStub()); + + if(isEmergency()) { - sb.append( " EMERGENCY" ); + sb.append(" EMERGENCY"); } - - sb.append( " FROM ADDR:" ); - sb.append( getSourceAddress() ); - - sb.append( " ID:" ); - sb.append( getSourceID() ); - - sb.append( " TO:" ); - sb.append( getTargetAddress() ); - - sb.append( " WACN:" ); - sb.append( getSourceWACN() ); - - sb.append( " SYS:" ); - sb.append( getSourceSystemID() ); - sb.append( " CHAN DN:" + getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber() ); - sb.append( " " + getDownlinkFrequency() ); - - sb.append( " CHAN UP:" + getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber() ); - sb.append( " " + getUplinkFrequency() ); - + sb.append(" FROM ADDR:"); + sb.append(getSourceAddress()); + + sb.append(" ID:"); + sb.append(getSourceID()); + + sb.append(" TO:"); + sb.append(getTargetAddress()); + + sb.append(" WACN:"); + sb.append(getSourceWACN()); + + sb.append(" SYS:"); + sb.append(getSourceSystemID()); + + sb.append(" CHAN DN:" + getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber()); + sb.append(" " + getDownlinkFrequency()); + + sb.append(" CHAN UP:" + getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber()); + sb.append(" " + getUplinkFrequency()); + return sb.toString(); } - + public boolean isEmergency() { - return mMessage.get( EMERGENCY_FLAG ); + return mMessage.get(EMERGENCY_FLAG); } - + public boolean isEncrypted() { - return mMessage.get( ENCRYPTED_CHANNEL_FLAG ); + return mMessage.get(ENCRYPTED_CHANNEL_FLAG); } - + public DuplexMode getDuplexMode() { - return mMessage.get( DUPLEX_MODE ) ? DuplexMode.FULL : DuplexMode.HALF; + return mMessage.get(DUPLEX_MODE) ? DuplexMode.FULL : DuplexMode.HALF; } public SessionMode getSessionMode() { - return mMessage.get( SESSION_MODE ) ? - SessionMode.CIRCUIT : SessionMode.PACKET; + return mMessage.get(SESSION_MODE) ? + SessionMode.CIRCUIT : SessionMode.PACKET; } public String getSourceAddress() { - return mMessage.getHex( SOURCE_ADDRESS, 6 ); - } - - public String getSourceID() - { - return mMessage.getHex( SOURCE_ID, 6 ); - } - - public String getSourceWACN() - { - return mMessage.getHex( SOURCE_WACN, 5 ); - } - - public String getSourceSystemID() - { - return mMessage.getHex( SOURCE_SYSTEM_ID, 3 ); - } - - public String getTargetAddress() - { - return mMessage.getHex( TARGET_ADDRESS, 6 ); - } - - public int getTransmitChannelIdentifier() - { - return mMessage.getInt( TRANSMIT_IDENTIFIER ); - } - - public int getTransmitChannelNumber() - { - return mMessage.getInt( TRANSMIT_NUMBER ); - } - - public String getTransmitChannel() - { - return getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber(); - } - - public int getReceiveChannelIdentifier() - { - return mMessage.getInt( RECEIVE_IDENTIFIER ); - } - - public int getReceiveChannelNumber() - { - return mMessage.getInt( RECEIVE_NUMBER ); - } - - public String getReceiveChannel() - { - return getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber(); - } - - public long getDownlinkFrequency() - { - return calculateDownlink( mTransmitIdentifierUpdate, getTransmitChannelNumber() ); - } - - public long getUplinkFrequency() - { - return calculateUplink( mReceiveIdentifierUpdate, getReceiveChannelNumber() ); + return mMessage.getHex(SOURCE_ADDRESS, 6); } - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + public String getSourceID() { - if( identifier == getTransmitChannelIdentifier() ) - { - mTransmitIdentifierUpdate = message; - } - - if( identifier == getReceiveChannelIdentifier() ) - { - mReceiveIdentifierUpdate = message; - } + return mMessage.getHex(SOURCE_ID, 6); + } + + public String getSourceWACN() + { + return mMessage.getHex(SOURCE_WACN, 5); + } + + public String getSourceSystemID() + { + return mMessage.getHex(SOURCE_SYSTEM_ID, 3); + } + + public String getTargetAddress() + { + return mMessage.getHex(TARGET_ADDRESS, 6); + } + + public int getTransmitChannelIdentifier() + { + return mMessage.getInt(TRANSMIT_IDENTIFIER); + } + + public int getTransmitChannelNumber() + { + return mMessage.getInt(TRANSMIT_NUMBER); + } + + public String getTransmitChannel() + { + return getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber(); + } + + public int getReceiveChannelIdentifier() + { + return mMessage.getInt(RECEIVE_IDENTIFIER); + } + + public int getReceiveChannelNumber() + { + return mMessage.getInt(RECEIVE_NUMBER); + } + + public String getReceiveChannel() + { + return getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber(); + } + + public long getDownlinkFrequency() + { + if(mTransmitIdentifierUpdate != null) + { + return mTransmitIdentifierUpdate.getDownlinkFrequency(getTransmitChannelNumber()); + } + + return 0; + } + + public long getUplinkFrequency() + { + if(mReceiveIdentifierUpdate != null) + { + return mReceiveIdentifierUpdate.getUplinkFrequency(getReceiveChannelNumber()); + } + + return 0; + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getTransmitChannelIdentifier()) + { + mTransmitIdentifierUpdate = message; + } + + if(identifier == getReceiveChannelIdentifier()) + { + mReceiveIdentifierUpdate = message; + } + } + + public int[] getIdentifiers() + { + int[] idens = new int[2]; + + idens[0] = getTransmitChannelIdentifier(); + idens[1] = getReceiveChannelIdentifier(); + + return idens; } - - public int[] getIdentifiers() - { - int[] idens = new int[ 2 ]; - - idens[ 0 ] = getTransmitChannelIdentifier(); - idens[ 1 ] = getReceiveChannelIdentifier(); - - return idens; - } } diff --git a/src/module/decode/p25/message/pdu/osp/control/AdjacentStatusBroadcastExtended.java b/src/module/decode/p25/message/pdu/osp/control/AdjacentStatusBroadcastExtended.java index de1183cd..3fd3dce1 100644 --- a/src/module/decode/p25/message/pdu/osp/control/AdjacentStatusBroadcastExtended.java +++ b/src/module/decode/p25/message/pdu/osp/control/AdjacentStatusBroadcastExtended.java @@ -1,5 +1,26 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.pdu.osp.control; +import alias.AliasList; +import bits.BinaryMessage; +import edac.CRCP25; import module.decode.p25.message.IAdjacentSite; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; @@ -7,43 +28,32 @@ import module.decode.p25.message.pdu.PDUMessage; import module.decode.p25.message.tsbk.osp.control.SystemService; import module.decode.p25.reference.DataUnitID; import module.decode.p25.reference.Opcode; -import alias.AliasList; -import bits.BinaryMessage; -import edac.CRCP25; -public class AdjacentStatusBroadcastExtended extends PDUMessage - implements IdentifierReceiver, IAdjacentSite +public class AdjacentStatusBroadcastExtended extends PDUMessage implements IdentifierReceiver, IAdjacentSite { - public static final int[] LRA = { 88,89,90,91,92,93,94,95 }; - public static final int[] SYSTEM_ID = { 100,101,102,103,104,105,106,107,108, - 109,110,111 }; - public static final int[] RF_SUBSYSTEM_ID = { 128,129,130,131,132,133,134, - 135 }; - public static final int[] SITE_ID = { 136,137,138,139,140,141,142,143 }; - public static final int[] TRANSMIT_IDENTIFIER = { 160,161,162,163 }; - public static final int[] TRANSMIT_CHANNEL = { 164,165,166,167,168,169,170, - 171,172,173,174,175 }; - public static final int[] RECEIVE_IDENTIFIER = { 176,177,178,179 }; - public static final int[] RECEIVE_CHANNEL = { 180,181,182,183,184,185,186, - 187,188,189,190,191 }; - public static final int[] SYSTEM_SERVICE_CLASS = { 192,193,194,195,196,197, - 198,199 }; - public static final int[] MULTIPLE_BLOCK_CRC = { 224,225,226,227,228,229, - 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247, - 248,249,250,251,252,253,254,255 }; - - private IBandIdentifier mTransmitIdentifierProvider; - private IBandIdentifier mReceiveIdentifierProvider; - - public AdjacentStatusBroadcastExtended( BinaryMessage message, - DataUnitID duid, AliasList aliasList ) + public static final int[] LRA = {88, 89, 90, 91, 92, 93, 94, 95}; + public static final int[] SYSTEM_ID = {100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111}; + public static final int[] RF_SUBSYSTEM_ID = {128, 129, 130, 131, 132, 133, 134, 135}; + public static final int[] SITE_ID = {136, 137, 138, 139, 140, 141, 142, 143}; + public static final int[] TRANSMIT_IDENTIFIER = {160, 161, 162, 163}; + public static final int[] TRANSMIT_CHANNEL = {164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175}; + public static final int[] RECEIVE_IDENTIFIER = {176, 177, 178, 179}; + public static final int[] RECEIVE_CHANNEL = {180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191}; + public static final int[] SYSTEM_SERVICE_CLASS = {192, 193, 194, 195, 196, 197, 198, 199}; + public static final int[] MULTIPLE_BLOCK_CRC = {224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}; + + private IBandIdentifier mTransmitIdentifierProvider; + private IBandIdentifier mReceiveIdentifierProvider; + + public AdjacentStatusBroadcastExtended(BinaryMessage message, DataUnitID duid, AliasList aliasList) { - super( message, duid, aliasList ); - + super(message, duid, aliasList); + /* Header block is already error detected/corrected - perform error - * detection correction on the intermediate and final data blocks */ - mMessage = CRCP25.correctPDU1( mMessage ); - mCRC[ 1 ] = mMessage.getCRC(); + * detection correction on the intermediate and final data blocks */ + mMessage = CRCP25.correctPDU1(mMessage); + mCRC[1] = mMessage.getCRC(); } @Override @@ -51,138 +61,148 @@ public class AdjacentStatusBroadcastExtended extends PDUMessage { return Opcode.ADJACENT_STATUS_BROADCAST.getDescription(); } - + public String getMessage() { StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - sb.append( " LRA:" + getLRA() ); - - sb.append( " SYS:" + getSystemID() ); - - sb.append( " RFSS:" + getRFSS() ); - - sb.append( " SITE:" + getSiteID() ); + sb.append(getMessageStub()); - sb.append( " CTRL CHAN:" + getTransmitIdentifier() + "-" + getTransmitChannel() ); + sb.append(" LRA:" + getLRA()); - sb.append( " DN:" + getDownlinkFrequency() ); + sb.append(" SYS:" + getSystemID()); - sb.append( " " + getReceiveIdentifier() + "-" + getReceiveChannel() ); + sb.append(" RFSS:" + getRFSS()); + + sb.append(" SITE:" + getSiteID()); + + sb.append(" CTRL CHAN:" + getTransmitIdentifier() + "-" + getTransmitChannel()); + + sb.append(" DN:" + getDownlinkFrequency()); + + sb.append(" " + getReceiveIdentifier() + "-" + getReceiveChannel()); + + sb.append(" UP:" + getUplinkFrequency()); + + sb.append(" SYS SVC CLASS:" + getSystemServiceClass()); - sb.append( " UP:" + getUplinkFrequency() ); - - sb.append( " SYS SVC CLASS:" + getSystemServiceClass() ); - return sb.toString(); } - + public String getUniqueID() { - StringBuilder sb = new StringBuilder(); - - sb.append( getSystemID() ); - sb.append( ":" ); - sb.append( getRFSS() ); - sb.append( ":" ); - sb.append( getSiteID() ); - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + + sb.append(getSystemID()); + sb.append(":"); + sb.append(getRFSS()); + sb.append(":"); + sb.append(getSiteID()); + + return sb.toString(); } - - public String getSystemID() - { - return mMessage.getHex( SYSTEM_ID, 3 ); - } - - public String getSiteID() - { - return mMessage.getHex( SITE_ID, 2 ); - } - - public int getTransmitIdentifier() - { - return mMessage.getInt( TRANSMIT_IDENTIFIER ); - } - - public int getTransmitChannel() - { - return mMessage.getInt( TRANSMIT_CHANNEL ); - } - - public int getReceiveIdentifier() - { - return mMessage.getInt( RECEIVE_IDENTIFIER ); - } - - public int getReceiveChannel() - { - return mMessage.getInt( RECEIVE_CHANNEL ); - } - + + public String getSystemID() + { + return mMessage.getHex(SYSTEM_ID, 3); + } + + public String getSiteID() + { + return mMessage.getHex(SITE_ID, 2); + } + + public int getTransmitIdentifier() + { + return mMessage.getInt(TRANSMIT_IDENTIFIER); + } + + public int getTransmitChannel() + { + return mMessage.getInt(TRANSMIT_CHANNEL); + } + + public int getReceiveIdentifier() + { + return mMessage.getInt(RECEIVE_IDENTIFIER); + } + + public int getReceiveChannel() + { + return mMessage.getInt(RECEIVE_CHANNEL); + } + public long getDownlinkFrequency() { - return calculateDownlink( mTransmitIdentifierProvider, getTransmitChannel() ); + if(mTransmitIdentifierProvider != null) + { + return mTransmitIdentifierProvider.getDownlinkFrequency(getTransmitChannel()); + } + + return 0; } - + public long getUplinkFrequency() { - return calculateUplink( mReceiveIdentifierProvider, getReceiveChannel() ); + if(mReceiveIdentifierProvider != null) + { + return mReceiveIdentifierProvider.getUplinkFrequency(getReceiveChannel()); + } + + return 0; } - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) { - if( identifier == getTransmitIdentifier() ) - { - mTransmitIdentifierProvider = message; - } - - if( identifier == getReceiveIdentifier() ) - { - mReceiveIdentifierProvider = message; - } + if(identifier == getTransmitIdentifier()) + { + mTransmitIdentifierProvider = message; + } + + if(identifier == getReceiveIdentifier()) + { + mReceiveIdentifierProvider = message; + } } - - public int[] getIdentifiers() - { - int[] idens = new int[ 2 ]; - - idens[ 0 ] = getTransmitIdentifier(); - idens[ 1 ] = getReceiveIdentifier(); - - return idens; - } - @Override - public String getRFSS() - { - return mMessage.getHex( RF_SUBSYSTEM_ID, 2 ); - } + public int[] getIdentifiers() + { + int[] idens = new int[2]; - @Override - public String getLRA() - { - return mMessage.getHex( LRA, 2 ); - } + idens[0] = getTransmitIdentifier(); + idens[1] = getReceiveIdentifier(); - @Override - public String getSystemServiceClass() - { - return SystemService.toString( mMessage.getInt( SYSTEM_SERVICE_CLASS ) ); - } + return idens; + } - @Override - public String getDownlinkChannel() - { - return getTransmitIdentifier() + "-" + getTransmitChannel(); - } + @Override + public String getRFSS() + { + return mMessage.getHex(RF_SUBSYSTEM_ID, 2); + } - @Override - public String getUplinkChannel() - { - return getReceiveIdentifier() + "-" + getReceiveChannel(); - } + @Override + public String getLRA() + { + return mMessage.getHex(LRA, 2); + } + + @Override + public String getSystemServiceClass() + { + return SystemService.toString(mMessage.getInt(SYSTEM_SERVICE_CLASS)); + } + + @Override + public String getDownlinkChannel() + { + return getTransmitIdentifier() + "-" + getTransmitChannel(); + } + + @Override + public String getUplinkChannel() + { + return getReceiveIdentifier() + "-" + getReceiveChannel(); + } } diff --git a/src/module/decode/p25/message/pdu/osp/control/NetworkStatusBroadcastExtended.java b/src/module/decode/p25/message/pdu/osp/control/NetworkStatusBroadcastExtended.java index f9f812a5..fb6b7fbf 100644 --- a/src/module/decode/p25/message/pdu/osp/control/NetworkStatusBroadcastExtended.java +++ b/src/module/decode/p25/message/pdu/osp/control/NetworkStatusBroadcastExtended.java @@ -1,5 +1,26 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.pdu.osp.control; +import alias.AliasList; +import bits.BinaryMessage; +import edac.CRCP25; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.message.pdu.PDUMessage; @@ -7,42 +28,32 @@ import module.decode.p25.message.tsbk.osp.control.SystemService; import module.decode.p25.reference.DataUnitID; import module.decode.p25.reference.Opcode; import module.decode.p25.reference.P25NetworkCallsign; -import alias.AliasList; -import bits.BinaryMessage; -import edac.CRCP25; -public class NetworkStatusBroadcastExtended extends PDUMessage - implements IdentifierReceiver +public class NetworkStatusBroadcastExtended extends PDUMessage implements IdentifierReceiver { - public static final int[] LRA = { 88,89,90,91,92,93,94,95 }; - public static final int[] SYSTEM_ID = { 100,101,102,103,104,105,106,107,108, - 109,110,111 }; - public static final int[] WACN = { 160,161,162,163,164,165,166,167,168,169, - 170,171,172,173,174,175,176,177,178,179 }; - public static final int[] TRANSMIT_IDENTIFIER = { 184,185,186,187 }; - public static final int[] TRANSMIT_CHANNEL = { 188,189,190,191,192,193,194, - 195,196,197,198,199 }; - public static final int[] RECEIVE_IDENTIFIER = { 200,201,202,203 }; - public static final int[] RECEIVE_CHANNEL = { 204,205,206,207,208,209,210, - 211,212,213,214,215 }; - public static final int[] SYSTEM_SERVICE_CLASS = { 216,217,218,219,220,221, - 222,223 }; - public static final int[] MULTIPLE_BLOCK_CRC = { 224,225,226,227,228,229, - 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247, - 248,249,250,251,252,253,254,255 }; - - private IBandIdentifier mTransmitIdentifierUpdate; - private IBandIdentifier mReceiveIdentifierUpdate; - - public NetworkStatusBroadcastExtended( BinaryMessage message, - DataUnitID duid, AliasList aliasList ) + public static final int[] LRA = {88, 89, 90, 91, 92, 93, 94, 95}; + public static final int[] SYSTEM_ID = {100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111}; + public static final int[] WACN = {160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179}; + public static final int[] TRANSMIT_IDENTIFIER = {184, 185, 186, 187}; + public static final int[] TRANSMIT_CHANNEL = {188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199}; + public static final int[] RECEIVE_IDENTIFIER = {200, 201, 202, 203}; + public static final int[] RECEIVE_CHANNEL = {204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215}; + public static final int[] SYSTEM_SERVICE_CLASS = {216, 217, 218, 219, 220, 221, 222, 223}; + public static final int[] MULTIPLE_BLOCK_CRC = {224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}; + + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; + + public NetworkStatusBroadcastExtended(BinaryMessage message, DataUnitID duid, AliasList aliasList) { - super( message, duid, aliasList ); - + super(message, duid, aliasList); + /* Header block is already error detected/corrected - perform error - * detection correction on the intermediate and final data blocks */ - mMessage = CRCP25.correctPDU1( mMessage ); - mCRC[ 1 ] = mMessage.getCRC(); + * detection correction on the intermediate and final data blocks */ + mMessage = CRCP25.correctPDU1(mMessage); + mCRC[1] = mMessage.getCRC(); } @Override @@ -50,111 +61,121 @@ public class NetworkStatusBroadcastExtended extends PDUMessage { return Opcode.NETWORK_STATUS_BROADCAST.getDescription(); } - + public String getMessage() { StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - sb.append( " LRA:" + getLocationRegistrationArea() ); - - sb.append( " WACN:" + getWACN() ); - - sb.append( " SYS:" + getSystemID() ); - - sb.append( " CTRL CHAN:" + getReceiveIdentifier() + "-" + getReceiveChannel() ); - - sb.append( " DN:" + getDownlinkFrequency() ); - - sb.append( " " + getTransmitIdentifier() + "-" + getTransmitChannel() ); - - sb.append( " UP:" + getUplinkFrequency() ); - - sb.append( " SYS SVC CLASS:" + - SystemService.toString( getSystemServiceClass() ) ); - + sb.append(getMessageStub()); + + sb.append(" LRA:" + getLocationRegistrationArea()); + + sb.append(" WACN:" + getWACN()); + + sb.append(" SYS:" + getSystemID()); + + sb.append(" CTRL CHAN:" + getReceiveIdentifier() + "-" + getReceiveChannel()); + + sb.append(" DN:" + getDownlinkFrequency()); + + sb.append(" " + getTransmitIdentifier() + "-" + getTransmitChannel()); + + sb.append(" UP:" + getUplinkFrequency()); + + sb.append(" SYS SVC CLASS:" + + SystemService.toString(getSystemServiceClass())); + return sb.toString(); } - - - public String getLocationRegistrationArea() - { - return mMessage.getHex( LRA, 2 ); - } - - public String getSystemID() - { - return mMessage.getHex( SYSTEM_ID, 3 ); - } - - public String getWACN() - { - return mMessage.getHex( WACN, 5 ); - } - - public String getNetworkCallsign() - { - return P25NetworkCallsign.getCallsign( mMessage.getInt( WACN ), - mMessage.getInt( SYSTEM_ID ) ); - } - - public int getTransmitIdentifier() - { - return mMessage.getInt( TRANSMIT_IDENTIFIER ); - } - - public int getTransmitChannel() - { - return mMessage.getInt( TRANSMIT_CHANNEL ); - } - - public int getReceiveIdentifier() - { - return mMessage.getInt( RECEIVE_IDENTIFIER ); - } - - public int getReceiveChannel() - { - return mMessage.getInt( RECEIVE_CHANNEL ); - } - - public int getSystemServiceClass() + + + public String getLocationRegistrationArea() { - return mMessage.getInt( SYSTEM_SERVICE_CLASS ); - } - - public long getDownlinkFrequency() - { - return calculateDownlink( mTransmitIdentifierUpdate, getTransmitChannel() ); - } - - public long getUplinkFrequency() - { - return calculateUplink( mReceiveIdentifierUpdate, getReceiveChannel() ); + return mMessage.getHex(LRA, 2); } - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + public String getSystemID() { - if( identifier == getTransmitIdentifier() ) - { - mTransmitIdentifierUpdate = message; - } - - if( identifier == getReceiveIdentifier() ) - { - mReceiveIdentifierUpdate = message; - } + return mMessage.getHex(SYSTEM_ID, 3); + } + + public String getWACN() + { + return mMessage.getHex(WACN, 5); + } + + public String getNetworkCallsign() + { + return P25NetworkCallsign.getCallsign(mMessage.getInt(WACN), + mMessage.getInt(SYSTEM_ID)); + } + + public int getTransmitIdentifier() + { + return mMessage.getInt(TRANSMIT_IDENTIFIER); + } + + public int getTransmitChannel() + { + return mMessage.getInt(TRANSMIT_CHANNEL); + } + + public int getReceiveIdentifier() + { + return mMessage.getInt(RECEIVE_IDENTIFIER); + } + + public int getReceiveChannel() + { + return mMessage.getInt(RECEIVE_CHANNEL); + } + + public int getSystemServiceClass() + { + return mMessage.getInt(SYSTEM_SERVICE_CLASS); + } + + public long getDownlinkFrequency() + { + if(mTransmitIdentifierUpdate != null) + { + return mTransmitIdentifierUpdate.getDownlinkFrequency(getTransmitChannel()); + } + + return 0; + } + + public long getUplinkFrequency() + { + if(mReceiveIdentifierUpdate != null) + { + return mReceiveIdentifierUpdate.getUplinkFrequency(getReceiveChannel()); + } + + return 0; + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getTransmitIdentifier()) + { + mTransmitIdentifierUpdate = message; + } + + if(identifier == getReceiveIdentifier()) + { + mReceiveIdentifierUpdate = message; + } + } + + public int[] getIdentifiers() + { + int[] idens = new int[2]; + + idens[0] = getTransmitIdentifier(); + idens[1] = getReceiveIdentifier(); + + return idens; } - - public int[] getIdentifiers() - { - int[] idens = new int[ 2 ]; - - idens[ 0 ] = getTransmitIdentifier(); - idens[ 1 ] = getReceiveIdentifier(); - - return idens; - } } diff --git a/src/module/decode/p25/message/pdu/osp/control/RFSSStatusBroadcastExtended.java b/src/module/decode/p25/message/pdu/osp/control/RFSSStatusBroadcastExtended.java index a8b6a03f..94ee8608 100644 --- a/src/module/decode/p25/message/pdu/osp/control/RFSSStatusBroadcastExtended.java +++ b/src/module/decode/p25/message/pdu/osp/control/RFSSStatusBroadcastExtended.java @@ -1,48 +1,59 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.pdu.osp.control; +import alias.AliasList; +import bits.BinaryMessage; +import edac.CRCP25; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.message.pdu.PDUMessage; import module.decode.p25.message.tsbk.osp.control.SystemService; import module.decode.p25.reference.DataUnitID; import module.decode.p25.reference.Opcode; -import alias.AliasList; -import bits.BinaryMessage; -import edac.CRCP25; -public class RFSSStatusBroadcastExtended extends PDUMessage - implements IdentifierReceiver +public class RFSSStatusBroadcastExtended extends PDUMessage implements IdentifierReceiver { - public static final int[] LRA = { 88,89,90,91,92,93,94,95 }; - public static final int ACTIVE_NETWORK_CONNECTION_INDICATOR = 99; - public static final int[] SYSTEM_ID = { 100,101,102,103,104,105,106,107,108, - 109,110,111 }; - public static final int[] RFSS_ID = { 160,161,162,163,164,165,166,167 }; - public static final int[] SITE_ID = { 168,169,170,171,172,173,174,175 }; - public static final int[] TRANSMIT_IDENTIFIER = { 184,185,186,187 }; - public static final int[] TRANSMIT_CHANNEL = { 188,189,190,191,192,193,194, - 195,196,197,198,199 }; - public static final int[] RECEIVE_IDENTIFIER = { 200,201,202,203 }; - public static final int[] RECEIVE_CHANNEL = { 204,205,206,207,208,209,210, - 211,212,213,214,215 }; - public static final int[] SYSTEM_SERVICE_CLASS = { 216,217,218,219,220,221, - 222,223 }; - public static final int[] MULTIPLE_BLOCK_CRC = { 224,225,226,227,228,229, - 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247, - 248,249,250,251,252,253,254,255 }; - - private IBandIdentifier mTransmitIdentifierUpdate; - private IBandIdentifier mReceiveIdentifierUpdate; - - public RFSSStatusBroadcastExtended( BinaryMessage message, - DataUnitID duid, AliasList aliasList ) + public static final int[] LRA = {88, 89, 90, 91, 92, 93, 94, 95}; + public static final int ACTIVE_NETWORK_CONNECTION_INDICATOR = 99; + public static final int[] SYSTEM_ID = {100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111}; + public static final int[] RFSS_ID = {160, 161, 162, 163, 164, 165, 166, 167}; + public static final int[] SITE_ID = {168, 169, 170, 171, 172, 173, 174, 175}; + public static final int[] TRANSMIT_IDENTIFIER = {184, 185, 186, 187}; + public static final int[] TRANSMIT_CHANNEL = {188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199}; + public static final int[] RECEIVE_IDENTIFIER = {200, 201, 202, 203}; + public static final int[] RECEIVE_CHANNEL = {204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215}; + public static final int[] SYSTEM_SERVICE_CLASS = {216, 217, 218, 219, 220, 221, 222, 223}; + public static final int[] MULTIPLE_BLOCK_CRC = {224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}; + + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; + + public RFSSStatusBroadcastExtended(BinaryMessage message, DataUnitID duid, AliasList aliasList) { - super( message, duid, aliasList ); - + super(message, duid, aliasList); + /* Header block is already error detected/corrected - perform error - * detection correction on the intermediate and final data blocks */ - mMessage = CRCP25.correctPDU1( mMessage ); - mCRC[ 1 ] = mMessage.getCRC(); + * detection correction on the intermediate and final data blocks */ + mMessage = CRCP25.correctPDU1(mMessage); + mCRC[1] = mMessage.getCRC(); } @Override @@ -50,115 +61,125 @@ public class RFSSStatusBroadcastExtended extends PDUMessage { return Opcode.NETWORK_STATUS_BROADCAST.getDescription(); } - + public String getMessage() { StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - sb.append( " LRA:" + getLocationRegistrationArea() ); - - sb.append( " SYS:" + getSystemID() ); - - sb.append( " SITE:" + getRFSubsystemID() + "-" + getSiteID() ); - - sb.append( " CTRL CHAN:" + getReceiveIdentifier() + "-" + getReceiveChannel() ); - - sb.append( " DN:" + getDownlinkFrequency() ); - - sb.append( " " + getTransmitIdentifier() + "-" + getTransmitChannel() ); - - sb.append( " UP:" + getUplinkFrequency() ); - - sb.append( " SYS SVC CLASS:" + - SystemService.toString( getSystemServiceClass() ) ); - + sb.append(getMessageStub()); + + sb.append(" LRA:" + getLocationRegistrationArea()); + + sb.append(" SYS:" + getSystemID()); + + sb.append(" SITE:" + getRFSubsystemID() + "-" + getSiteID()); + + sb.append(" CTRL CHAN:" + getReceiveIdentifier() + "-" + getReceiveChannel()); + + sb.append(" DN:" + getDownlinkFrequency()); + + sb.append(" " + getTransmitIdentifier() + "-" + getTransmitChannel()); + + sb.append(" UP:" + getUplinkFrequency()); + + sb.append(" SYS SVC CLASS:" + + SystemService.toString(getSystemServiceClass())); + return sb.toString(); } - - - public String getLocationRegistrationArea() - { - return mMessage.getHex( LRA, 2 ); - } - - public boolean hasActiveNetworkConnection() - { - return mMessage.get( ACTIVE_NETWORK_CONNECTION_INDICATOR ); - } - - public String getSystemID() - { - return mMessage.getHex( SYSTEM_ID, 3 ); - } - - public String getRFSubsystemID() - { - return mMessage.getHex( RFSS_ID, 2 ); - } - - public String getSiteID() - { - return mMessage.getHex( SITE_ID, 2 ); - } - - public int getTransmitIdentifier() - { - return mMessage.getInt( TRANSMIT_IDENTIFIER ); - } - - public int getTransmitChannel() - { - return mMessage.getInt( TRANSMIT_CHANNEL ); - } - - public int getReceiveIdentifier() - { - return mMessage.getInt( RECEIVE_IDENTIFIER ); - } - - public int getReceiveChannel() - { - return mMessage.getInt( RECEIVE_CHANNEL ); - } - - public int getSystemServiceClass() + + + public String getLocationRegistrationArea() { - return mMessage.getInt( SYSTEM_SERVICE_CLASS ); - } - - public long getDownlinkFrequency() - { - return calculateDownlink( mTransmitIdentifierUpdate, getTransmitChannel() ); - } - - public long getUplinkFrequency() - { - return calculateUplink( mReceiveIdentifierUpdate, getReceiveChannel() ); + return mMessage.getHex(LRA, 2); } - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + public boolean hasActiveNetworkConnection() { - if( identifier == getTransmitIdentifier() ) - { - mTransmitIdentifierUpdate = message; - } - - if( identifier == getReceiveIdentifier() ) - { - mReceiveIdentifierUpdate = message; - } + return mMessage.get(ACTIVE_NETWORK_CONNECTION_INDICATOR); + } + + public String getSystemID() + { + return mMessage.getHex(SYSTEM_ID, 3); + } + + public String getRFSubsystemID() + { + return mMessage.getHex(RFSS_ID, 2); + } + + public String getSiteID() + { + return mMessage.getHex(SITE_ID, 2); + } + + public int getTransmitIdentifier() + { + return mMessage.getInt(TRANSMIT_IDENTIFIER); + } + + public int getTransmitChannel() + { + return mMessage.getInt(TRANSMIT_CHANNEL); + } + + public int getReceiveIdentifier() + { + return mMessage.getInt(RECEIVE_IDENTIFIER); + } + + public int getReceiveChannel() + { + return mMessage.getInt(RECEIVE_CHANNEL); + } + + public int getSystemServiceClass() + { + return mMessage.getInt(SYSTEM_SERVICE_CLASS); + } + + public long getDownlinkFrequency() + { + if(mTransmitIdentifierUpdate != null) + { + return mTransmitIdentifierUpdate.getDownlinkFrequency(getTransmitChannel()); + } + + return 0; + } + + public long getUplinkFrequency() + { + if(mReceiveIdentifierUpdate != null) + { + return mReceiveIdentifierUpdate.getUplinkFrequency(getReceiveChannel()); + } + + return 0; + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getTransmitIdentifier()) + { + mTransmitIdentifierUpdate = message; + } + + if(identifier == getReceiveIdentifier()) + { + mReceiveIdentifierUpdate = message; + } + } + + public int[] getIdentifiers() + { + int[] idens = new int[2]; + + idens[0] = getTransmitIdentifier(); + idens[1] = getReceiveIdentifier(); + + return idens; } - - public int[] getIdentifiers() - { - int[] idens = new int[ 2 ]; - - idens[ 0 ] = getTransmitIdentifier(); - idens[ 1 ] = getReceiveIdentifier(); - - return idens; - } } diff --git a/src/module/decode/p25/message/pdu/osp/data/GroupDataChannelGrantExtended.java b/src/module/decode/p25/message/pdu/osp/data/GroupDataChannelGrantExtended.java index e196f10a..4ba2eef4 100644 --- a/src/module/decode/p25/message/pdu/osp/data/GroupDataChannelGrantExtended.java +++ b/src/module/decode/p25/message/pdu/osp/data/GroupDataChannelGrantExtended.java @@ -1,51 +1,63 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.pdu.osp.data; +import alias.AliasList; +import bits.BinaryMessage; +import edac.CRCP25; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.message.pdu.PDUMessage; import module.decode.p25.reference.DataUnitID; import module.decode.p25.reference.Opcode; -import alias.AliasList; -import bits.BinaryMessage; -import edac.CRCP25; -public class GroupDataChannelGrantExtended extends PDUMessage - implements IdentifierReceiver +public class GroupDataChannelGrantExtended extends PDUMessage implements IdentifierReceiver { /* Service Options */ public static final int EMERGENCY_FLAG = 128; public static final int ENCRYPTED_CHANNEL_FLAG = 129; public static final int DUPLEX_MODE = 130; public static final int SESSION_MODE = 131; - - public static final int[] SOURCE_ADDRESS = { 88,89,90,91,92,93,94,95,96,97, - 98,99,100,101,102,103,104,105,106,107,108,109,110,111 }; - public static final int[] SERVICE_OPTIONS = { 128,129,130,131,132,133,134, - 135 }; - public static final int[] TRANSMIT_IDENTIFIER = { 160,161,162,163 }; - public static final int[] TRANSMIT_NUMBER = { 164,165,166,167,168,169,170, - 171,172,173,174,175 }; - public static final int[] RECEIVE_IDENTIFIER = { 176,177,178,179 }; - public static final int[] RECEIVE_NUMBER = { 180,181,182,183,184,185,186, - 187,188,189,190,191 }; - public static final int[] GROUP_ADDRESS = { 192,193,194,195,196,197,198,199, - 200,201,202,203,204,205,206,207 }; - public static final int[] MULTIPLE_BLOCK_CRC = { 224,225,226,227,228,229, - 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247, - 248,249,250,251,252,253,254,255 }; - - private IBandIdentifier mTransmitIdentifierUpdate; - private IBandIdentifier mReceiveIdentifierUpdate; - - public GroupDataChannelGrantExtended( BinaryMessage message, - DataUnitID duid, AliasList aliasList ) + + public static final int[] SOURCE_ADDRESS = {88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111}; + public static final int[] SERVICE_OPTIONS = {128, 129, 130, 131, 132, 133, 134, 135}; + public static final int[] TRANSMIT_IDENTIFIER = {160, 161, 162, 163}; + public static final int[] TRANSMIT_NUMBER = {164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175}; + public static final int[] RECEIVE_IDENTIFIER = {176, 177, 178, 179}; + public static final int[] RECEIVE_NUMBER = {180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191}; + public static final int[] GROUP_ADDRESS = {192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, + 206, 207}; + public static final int[] MULTIPLE_BLOCK_CRC = {224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}; + + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; + + public GroupDataChannelGrantExtended(BinaryMessage message, DataUnitID duid, AliasList aliasList) { - super( message, duid, aliasList ); - + super(message, duid, aliasList); + /* Header block is already error detected/corrected - perform error - * detection correction on the intermediate and final data blocks */ - mMessage = CRCP25.correctPDU1( mMessage ); - mCRC[ 1 ] = mMessage.getCRC(); + * detection correction on the intermediate and final data blocks */ + mMessage = CRCP25.correctPDU1(mMessage); + mCRC[1] = mMessage.getCRC(); } @Override @@ -53,125 +65,135 @@ public class GroupDataChannelGrantExtended extends PDUMessage { return Opcode.TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT.getDescription(); } - + public String getMessage() { StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - if( isEmergency() ) + sb.append(getMessageStub()); + + if(isEmergency()) { - sb.append( " EMERGENCY" ); + sb.append(" EMERGENCY"); } - - sb.append( " FROM:" ); - sb.append( getSourceAddress() ); - - sb.append( " TO:" ); - sb.append( getGroupAddress() ); - - sb.append( " CHAN DN:" + getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber() ); - sb.append( " " + getDownlinkFrequency() ); - - sb.append( " CHAN UP:" + getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber() ); - sb.append( " " + getUplinkFrequency() ); - + + sb.append(" FROM:"); + sb.append(getSourceAddress()); + + sb.append(" TO:"); + sb.append(getGroupAddress()); + + sb.append(" CHAN DN:" + getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber()); + sb.append(" " + getDownlinkFrequency()); + + sb.append(" CHAN UP:" + getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber()); + sb.append(" " + getUplinkFrequency()); + return sb.toString(); } - + public boolean isEmergency() { - return mMessage.get( EMERGENCY_FLAG ); + return mMessage.get(EMERGENCY_FLAG); } - + public boolean isEncrypted() { - return mMessage.get( ENCRYPTED_CHANNEL_FLAG ); + return mMessage.get(ENCRYPTED_CHANNEL_FLAG); } - + public DuplexMode getDuplexMode() { - return mMessage.get( DUPLEX_MODE ) ? DuplexMode.FULL : DuplexMode.HALF; + return mMessage.get(DUPLEX_MODE) ? DuplexMode.FULL : DuplexMode.HALF; } public SessionMode getSessionMode() { - return mMessage.get( SESSION_MODE ) ? - SessionMode.CIRCUIT : SessionMode.PACKET; + return mMessage.get(SESSION_MODE) ? + SessionMode.CIRCUIT : SessionMode.PACKET; } public String getSourceAddress() { - return mMessage.getHex( SOURCE_ADDRESS, 6 ); + return mMessage.getHex(SOURCE_ADDRESS, 6); } public String getGroupAddress() { - return mMessage.getHex( GROUP_ADDRESS, 4 ); - } - - public int getTransmitChannelIdentifier() - { - return mMessage.getInt( TRANSMIT_IDENTIFIER ); - } - - public int getTransmitChannelNumber() - { - return mMessage.getInt( TRANSMIT_NUMBER ); - } - - public String getTransmitChannel() - { - return getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber(); - } - - public int getReceiveChannelIdentifier() - { - return mMessage.getInt( RECEIVE_IDENTIFIER ); - } - - public int getReceiveChannelNumber() - { - return mMessage.getInt( RECEIVE_NUMBER ); - } - - public String getReceiveChannel() - { - return getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber(); - } - - public long getDownlinkFrequency() - { - return calculateDownlink( mTransmitIdentifierUpdate, getTransmitChannelNumber() ); - } - - public long getUplinkFrequency() - { - return calculateUplink( mReceiveIdentifierUpdate, getReceiveChannelNumber() ); + return mMessage.getHex(GROUP_ADDRESS, 4); } - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + public int getTransmitChannelIdentifier() { - if( identifier == getTransmitChannelIdentifier() ) - { - mTransmitIdentifierUpdate = message; - } - - if( identifier == getReceiveChannelIdentifier() ) - { - mReceiveIdentifierUpdate = message; - } + return mMessage.getInt(TRANSMIT_IDENTIFIER); + } + + public int getTransmitChannelNumber() + { + return mMessage.getInt(TRANSMIT_NUMBER); + } + + public String getTransmitChannel() + { + return getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber(); + } + + public int getReceiveChannelIdentifier() + { + return mMessage.getInt(RECEIVE_IDENTIFIER); + } + + public int getReceiveChannelNumber() + { + return mMessage.getInt(RECEIVE_NUMBER); + } + + public String getReceiveChannel() + { + return getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber(); + } + + public long getDownlinkFrequency() + { + if(mTransmitIdentifierUpdate != null) + { + return mTransmitIdentifierUpdate.getDownlinkFrequency(getTransmitChannelNumber()); + } + + return 0; + } + + public long getUplinkFrequency() + { + if(mReceiveIdentifierUpdate != null) + { + return mReceiveIdentifierUpdate.getUplinkFrequency(getReceiveChannelNumber()); + } + + return 0; + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getTransmitChannelIdentifier()) + { + mTransmitIdentifierUpdate = message; + } + + if(identifier == getReceiveChannelIdentifier()) + { + mReceiveIdentifierUpdate = message; + } + } + + public int[] getIdentifiers() + { + int[] idens = new int[2]; + + idens[0] = getTransmitChannelIdentifier(); + idens[1] = getReceiveChannelIdentifier(); + + return idens; } - - public int[] getIdentifiers() - { - int[] idens = new int[ 2 ]; - - idens[ 0 ] = getTransmitChannelIdentifier(); - idens[ 1 ] = getReceiveChannelIdentifier(); - - return idens; - } } diff --git a/src/module/decode/p25/message/pdu/osp/voice/GroupVoiceChannelGrantExplicit.java b/src/module/decode/p25/message/pdu/osp/voice/GroupVoiceChannelGrantExplicit.java index 7b9105d7..d9f41c8a 100644 --- a/src/module/decode/p25/message/pdu/osp/voice/GroupVoiceChannelGrantExplicit.java +++ b/src/module/decode/p25/message/pdu/osp/voice/GroupVoiceChannelGrantExplicit.java @@ -1,51 +1,63 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.pdu.osp.voice; +import alias.AliasList; +import bits.BinaryMessage; +import edac.CRCP25; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.message.pdu.PDUMessage; import module.decode.p25.reference.DataUnitID; import module.decode.p25.reference.Opcode; -import alias.AliasList; -import bits.BinaryMessage; -import edac.CRCP25; -public class GroupVoiceChannelGrantExplicit extends PDUMessage - implements IdentifierReceiver +public class GroupVoiceChannelGrantExplicit extends PDUMessage implements IdentifierReceiver { /* Service Options */ public static final int EMERGENCY_FLAG = 128; public static final int ENCRYPTED_CHANNEL_FLAG = 129; public static final int DUPLEX_MODE = 130; public static final int SESSION_MODE = 131; - - public static final int[] SOURCE_ADDRESS = { 88,89,90,91,92,93,94,95,96,97, - 98,99,100,101,102,103,104,105,106,107,108,109,110,111 }; - public static final int[] SERVICE_OPTIONS = { 128,129,130,131,132,133,134, - 135 }; - public static final int[] TRANSMIT_IDENTIFIER = { 176,177,178,179 }; - public static final int[] TRANSMIT_NUMBER = { 180,181,182,183,184,185,186, - 187,188,189,190,191 }; - public static final int[] RECEIVE_IDENTIFIER = { 192,193,194,195 }; - public static final int[] RECEIVE_NUMBER = { 196,197,198,199,200,201,202, - 203,204,205,206,207 }; - public static final int[] GROUP_ADDRESS = { 208,209,210,211,212,213,214,215, - 216,217,218,219,220,221,222,223 }; - public static final int[] MULTIPLE_BLOCK_CRC = { 224,225,226,227,228,229, - 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247, - 248,249,250,251,252,253,254,255 }; - - private IBandIdentifier mTransmitIdentifierUpdate; - private IBandIdentifier mReceiveIdentifierUpdate; - - public GroupVoiceChannelGrantExplicit( BinaryMessage message, - DataUnitID duid, AliasList aliasList ) + + public static final int[] SOURCE_ADDRESS = {88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111}; + public static final int[] SERVICE_OPTIONS = {128, 129, 130, 131, 132, 133, 134, 135}; + public static final int[] TRANSMIT_IDENTIFIER = {176, 177, 178, 179}; + public static final int[] TRANSMIT_NUMBER = {180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191}; + public static final int[] RECEIVE_IDENTIFIER = {192, 193, 194, 195}; + public static final int[] RECEIVE_NUMBER = {196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207}; + public static final int[] GROUP_ADDRESS = {208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, + 222, 223}; + public static final int[] MULTIPLE_BLOCK_CRC = {224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}; + + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; + + public GroupVoiceChannelGrantExplicit(BinaryMessage message, DataUnitID duid, AliasList aliasList) { - super( message, duid, aliasList ); - + super(message, duid, aliasList); + /* Header block is already error detected/corrected - perform error - * detection correction on the intermediate and final data blocks */ - mMessage = CRCP25.correctPDU1( mMessage ); - mCRC[ 1 ] = mMessage.getCRC(); + * detection correction on the intermediate and final data blocks */ + mMessage = CRCP25.correctPDU1(mMessage); + mCRC[1] = mMessage.getCRC(); } @Override @@ -53,125 +65,135 @@ public class GroupVoiceChannelGrantExplicit extends PDUMessage { return Opcode.GROUP_VOICE_CHANNEL_GRANT.getDescription(); } - + public String getMessage() { StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - if( isEmergency() ) + sb.append(getMessageStub()); + + if(isEmergency()) { - sb.append( " EMERGENCY" ); + sb.append(" EMERGENCY"); } - - sb.append( " FROM:" ); - sb.append( getSourceAddress() ); - - sb.append( " GRP:" ); - sb.append( getGroupAddress() ); - sb.append( " CHAN DN:" + getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber() ); - sb.append( " " + getDownlinkFrequency() ); - - sb.append( " CHAN UP:" + getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber() ); - sb.append( " " + getUplinkFrequency() ); - + sb.append(" FROM:"); + sb.append(getSourceAddress()); + + sb.append(" GRP:"); + sb.append(getGroupAddress()); + + sb.append(" CHAN DN:" + getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber()); + sb.append(" " + getDownlinkFrequency()); + + sb.append(" CHAN UP:" + getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber()); + sb.append(" " + getUplinkFrequency()); + return sb.toString(); } - + public boolean isEmergency() { - return mMessage.get( EMERGENCY_FLAG ); + return mMessage.get(EMERGENCY_FLAG); } - + public boolean isEncrypted() { - return mMessage.get( ENCRYPTED_CHANNEL_FLAG ); + return mMessage.get(ENCRYPTED_CHANNEL_FLAG); } - + public DuplexMode getDuplexMode() { - return mMessage.get( DUPLEX_MODE ) ? DuplexMode.FULL : DuplexMode.HALF; + return mMessage.get(DUPLEX_MODE) ? DuplexMode.FULL : DuplexMode.HALF; } public SessionMode getSessionMode() { - return mMessage.get( SESSION_MODE ) ? - SessionMode.CIRCUIT : SessionMode.PACKET; + return mMessage.get(SESSION_MODE) ? + SessionMode.CIRCUIT : SessionMode.PACKET; } public String getSourceAddress() { - return mMessage.getHex( SOURCE_ADDRESS, 6 ); - } - - public String getGroupAddress() - { - return mMessage.getHex( GROUP_ADDRESS, 4 ); - } - - public int getTransmitChannelIdentifier() - { - return mMessage.getInt( TRANSMIT_IDENTIFIER ); - } - - public int getTransmitChannelNumber() - { - return mMessage.getInt( TRANSMIT_NUMBER ); - } - - public String getTransmitChannel() - { - return getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber(); - } - - public int getReceiveChannelIdentifier() - { - return mMessage.getInt( RECEIVE_IDENTIFIER ); - } - - public int getReceiveChannelNumber() - { - return mMessage.getInt( RECEIVE_NUMBER ); - } - - public String getReceiveChannel() - { - return getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber(); - } - - public long getDownlinkFrequency() - { - return calculateDownlink( mTransmitIdentifierUpdate, getTransmitChannelNumber() ); - } - - public long getUplinkFrequency() - { - return calculateUplink( mReceiveIdentifierUpdate, getReceiveChannelNumber() ); + return mMessage.getHex(SOURCE_ADDRESS, 6); } - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + public String getGroupAddress() { - if( identifier == getTransmitChannelIdentifier() ) - { - mTransmitIdentifierUpdate = message; - } - - if( identifier == getReceiveChannelIdentifier() ) - { - mReceiveIdentifierUpdate = message; - } + return mMessage.getHex(GROUP_ADDRESS, 4); + } + + public int getTransmitChannelIdentifier() + { + return mMessage.getInt(TRANSMIT_IDENTIFIER); + } + + public int getTransmitChannelNumber() + { + return mMessage.getInt(TRANSMIT_NUMBER); + } + + public String getTransmitChannel() + { + return getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber(); + } + + public int getReceiveChannelIdentifier() + { + return mMessage.getInt(RECEIVE_IDENTIFIER); + } + + public int getReceiveChannelNumber() + { + return mMessage.getInt(RECEIVE_NUMBER); + } + + public String getReceiveChannel() + { + return getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber(); + } + + public long getDownlinkFrequency() + { + if(mTransmitIdentifierUpdate != null) + { + return mTransmitIdentifierUpdate.getDownlinkFrequency(getTransmitChannelNumber()); + } + + return 0; + } + + public long getUplinkFrequency() + { + if(mReceiveIdentifierUpdate != null) + { + return mReceiveIdentifierUpdate.getUplinkFrequency(getReceiveChannelNumber()); + } + + return 0; + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getTransmitChannelIdentifier()) + { + mTransmitIdentifierUpdate = message; + } + + if(identifier == getReceiveChannelIdentifier()) + { + mReceiveIdentifierUpdate = message; + } + } + + public int[] getIdentifiers() + { + int[] idens = new int[2]; + + idens[0] = getTransmitChannelIdentifier(); + idens[1] = getReceiveChannelIdentifier(); + + return idens; } - - public int[] getIdentifiers() - { - int[] idens = new int[ 2 ]; - - idens[ 0 ] = getTransmitChannelIdentifier(); - idens[ 1 ] = getReceiveChannelIdentifier(); - - return idens; - } } diff --git a/src/module/decode/p25/message/pdu/osp/voice/TelephoneInterconnectChannelGrantExplicit.java b/src/module/decode/p25/message/pdu/osp/voice/TelephoneInterconnectChannelGrantExplicit.java index 48105b9a..0d06ad93 100644 --- a/src/module/decode/p25/message/pdu/osp/voice/TelephoneInterconnectChannelGrantExplicit.java +++ b/src/module/decode/p25/message/pdu/osp/voice/TelephoneInterconnectChannelGrantExplicit.java @@ -1,53 +1,64 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.pdu.osp.voice; -import java.util.Date; - +import alias.AliasList; +import bits.BinaryMessage; +import edac.CRCP25; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.message.pdu.PDUMessage; import module.decode.p25.reference.DataUnitID; import module.decode.p25.reference.Opcode; -import alias.AliasList; -import bits.BinaryMessage; -import edac.CRCP25; -public class TelephoneInterconnectChannelGrantExplicit extends PDUMessage - implements IdentifierReceiver +import java.util.Date; + +public class TelephoneInterconnectChannelGrantExplicit extends PDUMessage implements IdentifierReceiver { /* Service Options */ public static final int EMERGENCY_FLAG = 128; public static final int ENCRYPTED_CHANNEL_FLAG = 129; public static final int DUPLEX_MODE = 130; public static final int SESSION_MODE = 131; - - public static final int[] ADDRESS = { 88,89,90,91,92,93,94,95,96,97, - 98,99,100,101,102,103,104,105,106,107,108,109,110,111 }; - public static final int[] SERVICE_OPTIONS = { 128,129,130,131,132,133,134, - 135 }; - public static final int[] TRANSMIT_IDENTIFIER = { 160,161,162,163 }; - public static final int[] TRANSMIT_NUMBER = { 164,165,166,167,168,169,170, - 171,172,173,174,175 }; - public static final int[] RECEIVE_IDENTIFIER = { 176,177,178,179 }; - public static final int[] RECEIVE_NUMBER = { 180,181,182,183,184,185,186, - 187,188,189,190,191 }; - public static final int[] CALL_TIMER = { 192,193,194,195,196,197,198,199, - 200,201,202,203,204,205,206,207 }; - public static final int[] MULTIPLE_BLOCK_CRC = { 224,225,226,227,228,229, - 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247, - 248,249,250,251,252,253,254,255 }; - - private IBandIdentifier mTransmitIdentifierUpdate; - private IBandIdentifier mReceiveIdentifierUpdate; - - public TelephoneInterconnectChannelGrantExplicit( BinaryMessage message, - DataUnitID duid, AliasList aliasList ) + + public static final int[] ADDRESS = {88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111}; + public static final int[] SERVICE_OPTIONS = {128, 129, 130, 131, 132, 133, 134, 135}; + public static final int[] TRANSMIT_IDENTIFIER = {160, 161, 162, 163}; + public static final int[] TRANSMIT_NUMBER = {164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175}; + public static final int[] RECEIVE_IDENTIFIER = {176, 177, 178, 179}; + public static final int[] RECEIVE_NUMBER = {180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191}; + public static final int[] CALL_TIMER = {192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207}; + public static final int[] MULTIPLE_BLOCK_CRC = {224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}; + + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; + + public TelephoneInterconnectChannelGrantExplicit(BinaryMessage message, DataUnitID duid, AliasList aliasList) { - super( message, duid, aliasList ); - + super(message, duid, aliasList); + /* Header block is already error detected/corrected - perform error - * detection correction on the intermediate and final data blocks */ - mMessage = CRCP25.correctPDU1( mMessage ); - mCRC[ 1 ] = mMessage.getCRC(); + * detection correction on the intermediate and final data blocks */ + mMessage = CRCP25.correctPDU1(mMessage); + mCRC[1] = mMessage.getCRC(); } @Override @@ -55,57 +66,57 @@ public class TelephoneInterconnectChannelGrantExplicit extends PDUMessage { return Opcode.TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT.getDescription(); } - + public String getMessage() { StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - if( isEmergency() ) + sb.append(getMessageStub()); + + if(isEmergency()) { - sb.append( " EMERGENCY" ); + sb.append(" EMERGENCY"); } - - sb.append( " ADDR:" ); - sb.append( getAddress() ); - - sb.append( " CALL TIMER:" ); - sb.append( mTimeDurationFormat.format( new Date( getCallTimer() ) ) ); - - sb.append( " CHAN DN:" + getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber() ); - sb.append( " " + getDownlinkFrequency() ); - - sb.append( " CHAN UP:" + getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber() ); - sb.append( " " + getUplinkFrequency() ); - + + sb.append(" ADDR:"); + sb.append(getAddress()); + + sb.append(" CALL TIMER:"); + sb.append(mTimeDurationFormat.format(new Date(getCallTimer()))); + + sb.append(" CHAN DN:" + getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber()); + sb.append(" " + getDownlinkFrequency()); + + sb.append(" CHAN UP:" + getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber()); + sb.append(" " + getUplinkFrequency()); + return sb.toString(); } - + public boolean isEmergency() { - return mMessage.get( EMERGENCY_FLAG ); + return mMessage.get(EMERGENCY_FLAG); } - + public boolean isEncrypted() { - return mMessage.get( ENCRYPTED_CHANNEL_FLAG ); + return mMessage.get(ENCRYPTED_CHANNEL_FLAG); } - + public DuplexMode getDuplexMode() { - return mMessage.get( DUPLEX_MODE ) ? DuplexMode.FULL : DuplexMode.HALF; + return mMessage.get(DUPLEX_MODE) ? DuplexMode.FULL : DuplexMode.HALF; } public SessionMode getSessionMode() { - return mMessage.get( SESSION_MODE ) ? - SessionMode.CIRCUIT : SessionMode.PACKET; + return mMessage.get(SESSION_MODE) ? + SessionMode.CIRCUIT : SessionMode.PACKET; } public String getAddress() { - return mMessage.getHex( ADDRESS, 6 ); + return mMessage.getHex(ADDRESS, 6); } /* @@ -113,72 +124,82 @@ public class TelephoneInterconnectChannelGrantExplicit extends PDUMessage */ public long getCallTimer() { - int timer = mMessage.getInt( CALL_TIMER ); - - return timer / 100; - } - - public int getTransmitChannelIdentifier() - { - return mMessage.getInt( TRANSMIT_IDENTIFIER ); - } - - public int getTransmitChannelNumber() - { - return mMessage.getInt( TRANSMIT_NUMBER ); - } - - public String getTransmitChannel() - { - return getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber(); - } - - public int getReceiveChannelIdentifier() - { - return mMessage.getInt( RECEIVE_IDENTIFIER ); - } - - public int getReceiveChannelNumber() - { - return mMessage.getInt( RECEIVE_NUMBER ); - } - - public String getReceiveChannel() - { - return getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber(); - } - - public long getDownlinkFrequency() - { - return calculateDownlink( mTransmitIdentifierUpdate, getTransmitChannelNumber() ); - } - - public long getUplinkFrequency() - { - return calculateUplink( mReceiveIdentifierUpdate, getReceiveChannelNumber() ); + int timer = mMessage.getInt(CALL_TIMER); + + return timer / 100; } - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + public int getTransmitChannelIdentifier() { - if( identifier == getTransmitChannelIdentifier() ) - { - mTransmitIdentifierUpdate = message; - } - - if( identifier == getReceiveChannelIdentifier() ) - { - mReceiveIdentifierUpdate = message; - } + return mMessage.getInt(TRANSMIT_IDENTIFIER); + } + + public int getTransmitChannelNumber() + { + return mMessage.getInt(TRANSMIT_NUMBER); + } + + public String getTransmitChannel() + { + return getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber(); + } + + public int getReceiveChannelIdentifier() + { + return mMessage.getInt(RECEIVE_IDENTIFIER); + } + + public int getReceiveChannelNumber() + { + return mMessage.getInt(RECEIVE_NUMBER); + } + + public String getReceiveChannel() + { + return getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber(); + } + + public long getDownlinkFrequency() + { + if(mTransmitIdentifierUpdate != null) + { + return mTransmitIdentifierUpdate.getDownlinkFrequency(getTransmitChannelNumber()); + } + + return 0; + } + + public long getUplinkFrequency() + { + if(mReceiveIdentifierUpdate != null) + { + return mReceiveIdentifierUpdate.getUplinkFrequency(getReceiveChannelNumber()); + } + + return 0; + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getTransmitChannelIdentifier()) + { + mTransmitIdentifierUpdate = message; + } + + if(identifier == getReceiveChannelIdentifier()) + { + mReceiveIdentifierUpdate = message; + } + } + + public int[] getIdentifiers() + { + int[] idens = new int[2]; + + idens[0] = getTransmitChannelIdentifier(); + idens[1] = getReceiveChannelIdentifier(); + + return idens; } - - public int[] getIdentifiers() - { - int[] idens = new int[ 2 ]; - - idens[ 0 ] = getTransmitChannelIdentifier(); - idens[ 1 ] = getReceiveChannelIdentifier(); - - return idens; - } } diff --git a/src/module/decode/p25/message/pdu/osp/voice/UnitToUnitVoiceChannelGrantUpdateExtended.java b/src/module/decode/p25/message/pdu/osp/voice/UnitToUnitVoiceChannelGrantUpdateExtended.java index a6b3ff06..322cb003 100644 --- a/src/module/decode/p25/message/pdu/osp/voice/UnitToUnitVoiceChannelGrantUpdateExtended.java +++ b/src/module/decode/p25/message/pdu/osp/voice/UnitToUnitVoiceChannelGrantUpdateExtended.java @@ -1,57 +1,68 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.pdu.osp.voice; +import alias.AliasList; +import bits.BinaryMessage; +import edac.CRCP25; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.message.pdu.PDUMessage; import module.decode.p25.reference.DataUnitID; import module.decode.p25.reference.Opcode; -import alias.AliasList; -import bits.BinaryMessage; -import edac.CRCP25; -public class UnitToUnitVoiceChannelGrantUpdateExtended extends PDUMessage - implements IdentifierReceiver +public class UnitToUnitVoiceChannelGrantUpdateExtended extends PDUMessage implements IdentifierReceiver { /* Service Options */ public static final int EMERGENCY_FLAG = 128; public static final int ENCRYPTED_CHANNEL_FLAG = 129; public static final int DUPLEX_MODE = 130; public static final int SESSION_MODE = 131; - - public static final int[] SOURCE_ADDRESS = { 88,89,90,91,92,93,94,95,96,97, - 98,99,100,101,102,103,104,105,106,107,108,109,110,111 }; - public static final int[] SERVICE_OPTIONS = { 128,129,130,131,132,133,134, - 135 }; - public static final int[] SOURCE_WACN = { 160,161,162,163,164,165,166,167, - 168,169,170,171,172,173,174,175,176,177,178,179 }; - public static final int[] SOURCE_SYSTEM_ID = { 180,181,182,183,184,185,186, - 187,188,189,190,191 }; - public static final int[] SOURCE_ID = { 192,193,194,195,196,197,198,199,200, - 201,202,203,204,205,206,207,208,209,210,211,212,213,214,215 }; - public static final int[] TARGET_ADDRESS = { 216,217,218,219,220,221,222, - 223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239 }; - public static final int[] TRANSMIT_IDENTIFIER = { 240,241,242,243 }; - public static final int[] TRANSMIT_NUMBER = { 244,245,246,247,248,249,250, - 251,252,253,254,255 }; - public static final int[] RECEIVE_IDENTIFIER = { 256,257,258,259 }; - public static final int[] RECEIVE_NUMBER = { 260,261,262,263,264,265,266, - 267,268,269,270,271 }; - public static final int[] MULTIPLE_BLOCK_CRC = { 320,321,322,323,324,325, - 326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342, - 343,344,345,346,347,348,349,350,351 }; - - private IBandIdentifier mTransmitIdentifierUpdate; - private IBandIdentifier mReceiveIdentifierUpdate; - - public UnitToUnitVoiceChannelGrantUpdateExtended( BinaryMessage message, - DataUnitID duid, AliasList aliasList ) + + public static final int[] SOURCE_ADDRESS = {88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111}; + public static final int[] SERVICE_OPTIONS = {128, 129, 130, 131, 132, 133, 134, 135}; + public static final int[] SOURCE_WACN = {160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179}; + public static final int[] SOURCE_SYSTEM_ID = {180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191}; + public static final int[] SOURCE_ID = {192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215}; + public static final int[] TARGET_ADDRESS = {216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239}; + public static final int[] TRANSMIT_IDENTIFIER = {240, 241, 242, 243}; + public static final int[] TRANSMIT_NUMBER = {244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}; + public static final int[] RECEIVE_IDENTIFIER = {256, 257, 258, 259}; + public static final int[] RECEIVE_NUMBER = {260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271}; + public static final int[] MULTIPLE_BLOCK_CRC = {320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351}; + + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; + + public UnitToUnitVoiceChannelGrantUpdateExtended(BinaryMessage message, DataUnitID duid, AliasList aliasList) { - super( message, duid, aliasList ); - + super(message, duid, aliasList); + /* Header block is already error detected/corrected - perform error - * detection correction on the intermediate and final data blocks */ - mMessage = CRCP25.correctPDU2( mMessage ); - mCRC[ 1 ] = mMessage.getCRC(); + * detection correction on the intermediate and final data blocks */ + mMessage = CRCP25.correctPDU2(mMessage); + mCRC[1] = mMessage.getCRC(); } @Override @@ -59,149 +70,159 @@ public class UnitToUnitVoiceChannelGrantUpdateExtended extends PDUMessage { return Opcode.UNIT_TO_UNIT_VOICE_CHANNEL_GRANT_UPDATE.getDescription(); } - + public String getMessage() { StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - if( isEmergency() ) + sb.append(getMessageStub()); + + if(isEmergency()) { - sb.append( " EMERGENCY" ); + sb.append(" EMERGENCY"); } - - sb.append( " FROM ADDR:" ); - sb.append( getSourceAddress() ); - - sb.append( " ID:" ); - sb.append( getSourceID() ); - - sb.append( " TO:" ); - sb.append( getTargetAddress() ); - - sb.append( " WACN:" ); - sb.append( getSourceWACN() ); - - sb.append( " SYS:" ); - sb.append( getSourceSystemID() ); - sb.append( " CHAN DN:" + getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber() ); - sb.append( " " + getDownlinkFrequency() ); - - sb.append( " CHAN UP:" + getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber() ); - sb.append( " " + getUplinkFrequency() ); - + sb.append(" FROM ADDR:"); + sb.append(getSourceAddress()); + + sb.append(" ID:"); + sb.append(getSourceID()); + + sb.append(" TO:"); + sb.append(getTargetAddress()); + + sb.append(" WACN:"); + sb.append(getSourceWACN()); + + sb.append(" SYS:"); + sb.append(getSourceSystemID()); + + sb.append(" CHAN DN:" + getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber()); + sb.append(" " + getDownlinkFrequency()); + + sb.append(" CHAN UP:" + getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber()); + sb.append(" " + getUplinkFrequency()); + return sb.toString(); } - + public boolean isEmergency() { - return mMessage.get( EMERGENCY_FLAG ); + return mMessage.get(EMERGENCY_FLAG); } - + public boolean isEncrypted() { - return mMessage.get( ENCRYPTED_CHANNEL_FLAG ); + return mMessage.get(ENCRYPTED_CHANNEL_FLAG); } - + public DuplexMode getDuplexMode() { - return mMessage.get( DUPLEX_MODE ) ? DuplexMode.FULL : DuplexMode.HALF; + return mMessage.get(DUPLEX_MODE) ? DuplexMode.FULL : DuplexMode.HALF; } public SessionMode getSessionMode() { - return mMessage.get( SESSION_MODE ) ? - SessionMode.CIRCUIT : SessionMode.PACKET; + return mMessage.get(SESSION_MODE) ? + SessionMode.CIRCUIT : SessionMode.PACKET; } public String getSourceAddress() { - return mMessage.getHex( SOURCE_ADDRESS, 6 ); - } - - public String getSourceID() - { - return mMessage.getHex( SOURCE_ID, 6 ); - } - - public String getSourceWACN() - { - return mMessage.getHex( SOURCE_WACN, 5 ); - } - - public String getSourceSystemID() - { - return mMessage.getHex( SOURCE_SYSTEM_ID, 3 ); - } - - public String getTargetAddress() - { - return mMessage.getHex( TARGET_ADDRESS, 6 ); - } - - public int getTransmitChannelIdentifier() - { - return mMessage.getInt( TRANSMIT_IDENTIFIER ); - } - - public int getTransmitChannelNumber() - { - return mMessage.getInt( TRANSMIT_NUMBER ); - } - - public String getTransmitChannel() - { - return getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber(); - } - - public int getReceiveChannelIdentifier() - { - return mMessage.getInt( RECEIVE_IDENTIFIER ); - } - - public int getReceiveChannelNumber() - { - return mMessage.getInt( RECEIVE_NUMBER ); - } - - public String getReceiveChannel() - { - return getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber(); - } - - public long getDownlinkFrequency() - { - return calculateDownlink( mTransmitIdentifierUpdate, getTransmitChannelNumber() ); - } - - public long getUplinkFrequency() - { - return calculateUplink( mReceiveIdentifierUpdate, getReceiveChannelNumber() ); + return mMessage.getHex(SOURCE_ADDRESS, 6); } - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + public String getSourceID() { - if( identifier == getTransmitChannelIdentifier() ) - { - mTransmitIdentifierUpdate = message; - } - - if( identifier == getReceiveChannelIdentifier() ) - { - mReceiveIdentifierUpdate = message; - } + return mMessage.getHex(SOURCE_ID, 6); + } + + public String getSourceWACN() + { + return mMessage.getHex(SOURCE_WACN, 5); + } + + public String getSourceSystemID() + { + return mMessage.getHex(SOURCE_SYSTEM_ID, 3); + } + + public String getTargetAddress() + { + return mMessage.getHex(TARGET_ADDRESS, 6); + } + + public int getTransmitChannelIdentifier() + { + return mMessage.getInt(TRANSMIT_IDENTIFIER); + } + + public int getTransmitChannelNumber() + { + return mMessage.getInt(TRANSMIT_NUMBER); + } + + public String getTransmitChannel() + { + return getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber(); + } + + public int getReceiveChannelIdentifier() + { + return mMessage.getInt(RECEIVE_IDENTIFIER); + } + + public int getReceiveChannelNumber() + { + return mMessage.getInt(RECEIVE_NUMBER); + } + + public String getReceiveChannel() + { + return getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber(); + } + + public long getDownlinkFrequency() + { + if(mTransmitIdentifierUpdate != null) + { + return mTransmitIdentifierUpdate.getDownlinkFrequency(getTransmitChannelNumber()); + } + + return 0; + } + + public long getUplinkFrequency() + { + if(mReceiveIdentifierUpdate != null) + { + return mReceiveIdentifierUpdate.getUplinkFrequency(getReceiveChannelNumber()); + } + + return 0; + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getTransmitChannelIdentifier()) + { + mTransmitIdentifierUpdate = message; + } + + if(identifier == getReceiveChannelIdentifier()) + { + mReceiveIdentifierUpdate = message; + } + } + + public int[] getIdentifiers() + { + int[] idens = new int[2]; + + idens[0] = getTransmitChannelIdentifier(); + idens[1] = getReceiveChannelIdentifier(); + + return idens; } - - public int[] getIdentifiers() - { - int[] idens = new int[ 2 ]; - - idens[ 0 ] = getTransmitChannelIdentifier(); - idens[ 1 ] = getReceiveChannelIdentifier(); - - return idens; - } } diff --git a/src/module/decode/p25/message/tdu/lc/AdjacentSiteStatusBroadcast.java b/src/module/decode/p25/message/tdu/lc/AdjacentSiteStatusBroadcast.java index d14e03d6..2259c9d6 100644 --- a/src/module/decode/p25/message/tdu/lc/AdjacentSiteStatusBroadcast.java +++ b/src/module/decode/p25/message/tdu/lc/AdjacentSiteStatusBroadcast.java @@ -1,3 +1,21 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tdu.lc; import module.decode.p25.message.IAdjacentSite; @@ -6,141 +24,147 @@ import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.message.tsbk.osp.control.SystemService; import module.decode.p25.reference.LinkControlOpcode; -public class AdjacentSiteStatusBroadcast extends TDULinkControlMessage - implements IdentifierReceiver, IAdjacentSite +public class AdjacentSiteStatusBroadcast extends TDULinkControlMessage implements IdentifierReceiver, IAdjacentSite { - public static final int[] LRA = { 72,73,74,75,88,89,90,91 }; - public static final int[] SYSTEM_ID = { 96,97,98,99,112,113,114,115, - 116,117,118,119 }; - public static final int[] RFSS_ID = { 120,121,122,123,136,137,138,139 }; - public static final int[] SITE_ID = { 140,141,142,143,144,145,146,147 }; - public static final int[] IDENTIFIER = { 160,161,162,163 }; - public static final int[] CHANNEL = { 164,165,166,167,168,169,170, - 171,184,185,186,187 }; - public static final int[] SYSTEM_SERVICE_CLASS = { 188,189,190,191,192,193, - 194,195 }; - - private IBandIdentifier mIdentifierUpdate; - - public AdjacentSiteStatusBroadcast( TDULinkControlMessage source ) - { - super( source ); - } - + public static final int[] LRA = {72, 73, 74, 75, 88, 89, 90, 91}; + public static final int[] SYSTEM_ID = {96, 97, 98, 99, 112, 113, 114, 115, 116, 117, 118, 119}; + public static final int[] RFSS_ID = {120, 121, 122, 123, 136, 137, 138, 139}; + public static final int[] SITE_ID = {140, 141, 142, 143, 144, 145, 146, 147}; + public static final int[] IDENTIFIER = {160, 161, 162, 163}; + public static final int[] CHANNEL = {164, 165, 166, 167, 168, 169, 170, 171, 184, 185, 186, 187}; + public static final int[] SYSTEM_SERVICE_CLASS = {188, 189, 190, 191, 192, 193, 194, 195}; + + private IBandIdentifier mIdentifierUpdate; + + public AdjacentSiteStatusBroadcast(TDULinkControlMessage source) + { + super(source); + } + @Override public String getEventType() { return LinkControlOpcode.ADJACENT_SITE_STATUS_BROADCAST.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " LRA:" + getLRA() ); + @Override + public String getMessage() + { + StringBuilder sb = new StringBuilder(); - sb.append( " SYS:" + getSystemID() ); - - sb.append( " SITE:" + getRFSS() + "-" + getSiteID() ); - - sb.append( " CHAN:" + getChannel() ); + sb.append(getMessageStub()); + + sb.append(" LRA:" + getLRA()); + + sb.append(" SYS:" + getSystemID()); + + sb.append(" SITE:" + getRFSS() + "-" + getSiteID()); + + sb.append(" CHAN:" + getChannel()); + + sb.append(" " + getSystemServiceClass()); + + return sb.toString(); + } - sb.append( " " + getSystemServiceClass() ); - - return sb.toString(); - } - public String getUniqueID() { - StringBuilder sb = new StringBuilder(); - - sb.append( getSystemID() ); - sb.append( ":" ); - sb.append( getRFSS() ); - sb.append( ":" ); - sb.append( getSiteID() ); - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + + sb.append(getSystemID()); + sb.append(":"); + sb.append(getRFSS()); + sb.append(":"); + sb.append(getSiteID()); + + return sb.toString(); } - - public String getLRA() - { - return mMessage.getHex( LRA, 2 ); - } - - public String getSystemID() - { - return mMessage.getHex( SYSTEM_ID, 3 ); - } - - public String getRFSS() - { - return mMessage.getHex( RFSS_ID, 2 ); - } - - public String getSiteID() - { - return mMessage.getHex( SITE_ID, 2 ); - } - - public int getIdentifier() - { - return mMessage.getInt( IDENTIFIER ); - } - - public String getChannel() - { - return getIdentifier() + "-" + getChannelNumber(); - } - - @Override - public String getDownlinkChannel() - { - return getChannel(); - } - @Override - public String getUplinkChannel() - { - return getChannel(); - } - - public int getChannelNumber() - { - return mMessage.getInt( CHANNEL ); - } - - public String getSystemServiceClass() - { - return SystemService.toString( mMessage.getInt( SYSTEM_SERVICE_CLASS ) ); - } - - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + public String getLRA() { - mIdentifierUpdate = message; + return mMessage.getHex(LRA, 2); } - @Override + public String getSystemID() + { + return mMessage.getHex(SYSTEM_ID, 3); + } + + public String getRFSS() + { + return mMessage.getHex(RFSS_ID, 2); + } + + public String getSiteID() + { + return mMessage.getHex(SITE_ID, 2); + } + + public int getIdentifier() + { + return mMessage.getInt(IDENTIFIER); + } + + public String getChannel() + { + return getIdentifier() + "-" + getChannelNumber(); + } + + @Override + public String getDownlinkChannel() + { + return getChannel(); + } + + @Override + public String getUplinkChannel() + { + return getChannel(); + } + + public int getChannelNumber() + { + return mMessage.getInt(CHANNEL); + } + + public String getSystemServiceClass() + { + return SystemService.toString(mMessage.getInt(SYSTEM_SERVICE_CLASS)); + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + mIdentifierUpdate = message; + } + + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 1 ]; - - identifiers[ 0 ] = getIdentifier(); - - return identifiers; + int[] identifiers = new int[1]; + + identifiers[0] = getIdentifier(); + + return identifiers; } - + public long getDownlinkFrequency() { - return calculateDownlink( mIdentifierUpdate, getChannelNumber() ); + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.getDownlinkFrequency(getChannelNumber()); + } + + return 0; } - + public long getUplinkFrequency() { - return calculateUplink( mIdentifierUpdate, getChannelNumber() ); + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.getUplinkFrequency(getChannelNumber()); + } + + return 0; } } diff --git a/src/module/decode/p25/message/tdu/lc/AdjacentSiteStatusBroadcastExplicit.java b/src/module/decode/p25/message/tdu/lc/AdjacentSiteStatusBroadcastExplicit.java index da0c09d0..5be95844 100644 --- a/src/module/decode/p25/message/tdu/lc/AdjacentSiteStatusBroadcastExplicit.java +++ b/src/module/decode/p25/message/tdu/lc/AdjacentSiteStatusBroadcastExplicit.java @@ -1,3 +1,21 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tdu.lc; import module.decode.p25.message.IAdjacentSite; @@ -5,153 +23,162 @@ import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.reference.LinkControlOpcode; -public class AdjacentSiteStatusBroadcastExplicit extends TDULinkControlMessage - implements IdentifierReceiver, IAdjacentSite +public class AdjacentSiteStatusBroadcastExplicit extends TDULinkControlMessage implements IdentifierReceiver, IAdjacentSite { - public static final int[] LRA = { 72,73,74,75,88,89,90,91 }; - public static final int[] TRANSMIT_IDENTIFIER = { 92,93,94,95 }; - public static final int[] TRANSMIT_CHANNEL = { 96,97,98,99,112,113,114,115, - 116,117,118,119 }; - public static final int[] RFSS_ID = { 120,121,122,123,136,137,138,139 }; - public static final int[] SITE_ID = { 140,141,142,143,144,145,146,147 }; - - public static final int[] RECEIVE_IDENTIFIER = { 160,161,162,163 }; - public static final int[] RECEIVE_CHANNEL = { 164,165,166,167,168,169,170, - 171,184,185,186,187 }; - - private IBandIdentifier mTransmitBand; - private IBandIdentifier mReceiveBand; + public static final int[] LRA = {72, 73, 74, 75, 88, 89, 90, 91}; + public static final int[] TRANSMIT_IDENTIFIER = {92, 93, 94, 95}; + public static final int[] TRANSMIT_CHANNEL = {96, 97, 98, 99, 112, 113, 114, 115, + 116, 117, 118, 119}; + public static final int[] RFSS_ID = {120, 121, 122, 123, 136, 137, 138, 139}; + public static final int[] SITE_ID = {140, 141, 142, 143, 144, 145, 146, 147}; + + public static final int[] RECEIVE_IDENTIFIER = {160, 161, 162, 163}; + public static final int[] RECEIVE_CHANNEL = {164, 165, 166, 167, 168, 169, 170, + 171, 184, 185, 186, 187}; + + private IBandIdentifier mTransmitBand; + private IBandIdentifier mReceiveBand; + + public AdjacentSiteStatusBroadcastExplicit(TDULinkControlMessage source) + { + super(source); + } - public AdjacentSiteStatusBroadcastExplicit( TDULinkControlMessage source ) - { - super( source ); - } - @Override public String getEventType() { return LinkControlOpcode.ADJACENT_SITE_STATUS_BROADCAST_EXPLICIT.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " LRA:" + getLRA() ); - - sb.append( " SITE:" + getRFSS() + "-" + getSiteID() ); - - sb.append( " DNLINK:" + getDownlinkChannel() ); - - sb.append( " UPLINK:" + getUplinkChannel() ); - - return sb.toString(); - } - + @Override + public String getMessage() + { + StringBuilder sb = new StringBuilder(); + + sb.append(getMessageStub()); + + sb.append(" LRA:" + getLRA()); + + sb.append(" SITE:" + getRFSS() + "-" + getSiteID()); + + sb.append(" DNLINK:" + getDownlinkChannel()); + + sb.append(" UPLINK:" + getUplinkChannel()); + + return sb.toString(); + } + public String getUniqueID() { - StringBuilder sb = new StringBuilder(); - - sb.append( getSystemID() ); - sb.append( ":" ); - sb.append( getRFSS() ); - sb.append( ":" ); - sb.append( getSiteID() ); - - return sb.toString(); - } - - public String getLRA() - { - return mMessage.getHex( LRA, 2 ); - } - - public String getRFSS() - { - return mMessage.getHex( RFSS_ID, 2 ); - } - - public String getSystemID() - { - return "***"; - } - - public String getSiteID() - { - return mMessage.getHex( SITE_ID, 2 ); - } - - @Override - public String getSystemServiceClass() - { - return "[]"; - } + StringBuilder sb = new StringBuilder(); + + sb.append(getSystemID()); + sb.append(":"); + sb.append(getRFSS()); + sb.append(":"); + sb.append(getSiteID()); + + return sb.toString(); + } + + public String getLRA() + { + return mMessage.getHex(LRA, 2); + } + + public String getRFSS() + { + return mMessage.getHex(RFSS_ID, 2); + } + + public String getSystemID() + { + return "***"; + } + + public String getSiteID() + { + return mMessage.getHex(SITE_ID, 2); + } + + @Override + public String getSystemServiceClass() + { + return "[]"; + } + + public int getTransmitIdentifier() + { + return mMessage.getInt(TRANSMIT_IDENTIFIER); + } + + public int getTransmitChannel() + { + return mMessage.getInt(TRANSMIT_CHANNEL); + } + + public String getDownlinkChannel() + { + return getTransmitIdentifier() + "-" + getTransmitChannel(); + } + + public int getReceiveIdentifier() + { + return mMessage.getInt(RECEIVE_IDENTIFIER); + } + + public int getReceiveChannel() + { + return mMessage.getInt(RECEIVE_CHANNEL); + } + + public String getUplinkChannel() + { + return getReceiveIdentifier() + "-" + getReceiveChannel(); + } - public int getTransmitIdentifier() - { - return mMessage.getInt( TRANSMIT_IDENTIFIER ); - } - - public int getTransmitChannel() - { - return mMessage.getInt( TRANSMIT_CHANNEL ); - } - - public String getDownlinkChannel() - { - return getTransmitIdentifier() + "-" + getTransmitChannel(); - } - - public int getReceiveIdentifier() - { - return mMessage.getInt( RECEIVE_IDENTIFIER ); - } - - public int getReceiveChannel() - { - return mMessage.getInt( RECEIVE_CHANNEL ); - } - - public String getUplinkChannel() - { - return getReceiveIdentifier() + "-" + getReceiveChannel(); - } - public long getDownlinkFrequency() { - return calculateDownlink( mTransmitBand, getTransmitChannel() ); + if(mTransmitBand != null) + { + return mTransmitBand.getDownlinkFrequency(getTransmitChannel()); + } + + return 0; } - + public long getUplinkFrequency() { - return calculateUplink( mReceiveBand, getReceiveChannel() ); + if(mReceiveBand != null) + { + return mReceiveBand.getUplinkFrequency(getReceiveChannel()); + } + + return 0; } - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) - { - if( identifier == getTransmitIdentifier() ) - { - mTransmitBand = message; - } - - if( identifier == getReceiveIdentifier() ) - { - mReceiveBand = message; - } - } + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getTransmitIdentifier()) + { + mTransmitBand = message; + } - @Override - public int[] getIdentifiers() - { - int[] identifiers = new int[ 2 ]; - - identifiers[ 0 ] = getTransmitIdentifier(); - identifiers[ 1 ] = getReceiveIdentifier(); - - return identifiers; - } + if(identifier == getReceiveIdentifier()) + { + mReceiveBand = message; + } + } + + @Override + public int[] getIdentifiers() + { + int[] identifiers = new int[2]; + + identifiers[0] = getTransmitIdentifier(); + identifiers[1] = getReceiveIdentifier(); + + return identifiers; + } } diff --git a/src/module/decode/p25/message/tdu/lc/ChannelIdentifierUpdate.java b/src/module/decode/p25/message/tdu/lc/ChannelIdentifierUpdate.java index 75e725f8..63440320 100644 --- a/src/module/decode/p25/message/tdu/lc/ChannelIdentifierUpdate.java +++ b/src/module/decode/p25/message/tdu/lc/ChannelIdentifierUpdate.java @@ -1,82 +1,117 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tdu.lc; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.reference.LinkControlOpcode; -public class ChannelIdentifierUpdate extends TDULinkControlMessage - implements IBandIdentifier +public class ChannelIdentifierUpdate extends TDULinkControlMessage implements IBandIdentifier { - public static final int[] IDENTIFIER = { 72,73,74,75 }; - public static final int[] BANDWIDTH = { 88,89,90,91,92,93,94,95,96 }; - public static final int[] TRANSMIT_OFFSET = { 97,98,99,112,113,114,115,116, - 117 }; - public static final int[] CHANNEL_SPACING = { 118,119,120,121,122,123,136, - 137,138,139 }; - public static final int[] BASE_FREQUENCY = { 140,141,142,143,144,145,146, - 147,160,161,162,163,164,165,166,167,168,169,170,171,184,185,186, - 187,188,189,190,191,192,193,194,195 }; - - public ChannelIdentifierUpdate( TDULinkControlMessage source ) - { - super( source ); - } - + public static final int[] IDENTIFIER = {72, 73, 74, 75}; + public static final int[] BANDWIDTH = {88, 89, 90, 91, 92, 93, 94, 95, 96}; + public static final int[] TRANSMIT_OFFSET = {97, 98, 99, 112, 113, 114, 115, 116, + 117}; + public static final int[] CHANNEL_SPACING = {118, 119, 120, 121, 122, 123, 136, + 137, 138, 139}; + public static final int[] BASE_FREQUENCY = {140, 141, 142, 143, 144, 145, 146, + 147, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195}; + + public ChannelIdentifierUpdate(TDULinkControlMessage source) + { + super(source); + } + @Override public String getEventType() { return LinkControlOpcode.CHANNEL_IDENTIFIER_UPDATE.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " IDEN:" + getIdentifier() ); + @Override + public String getMessage() + { + StringBuilder sb = new StringBuilder(); - sb.append( " BASE:" + getBaseFrequency() ); - - sb.append( " BW:" + getBandwidth() ); - - sb.append( " SPACING:" + getChannelSpacing() ); - - sb.append( " OFFSET:" + getTransmitOffset() ); - - return sb.toString(); - } + sb.append(getMessageStub()); - @Override - public int getIdentifier() - { - return mMessage.getInt( IDENTIFIER ); - } + sb.append(" IDEN:" + getIdentifier()); - /** + sb.append(" BASE:" + getBaseFrequency()); + + sb.append(" BW:" + getBandwidth()); + + sb.append(" SPACING:" + getChannelSpacing()); + + sb.append(" OFFSET:" + getTransmitOffset()); + + return sb.toString(); + } + + @Override + public int getIdentifier() + { + return mMessage.getInt(IDENTIFIER); + } + + /** * Channel bandwidth in hertz */ @Override public int getBandwidth() { - return mMessage.getInt( BANDWIDTH ) * 125; + return mMessage.getInt(BANDWIDTH) * 125; } - + @Override public long getChannelSpacing() { - return mMessage.getLong( CHANNEL_SPACING ) * 125l; + return mMessage.getLong(CHANNEL_SPACING) * 125l; } @Override public long getBaseFrequency() { - return mMessage.getLong( BASE_FREQUENCY ) * 5l; + return mMessage.getLong(BASE_FREQUENCY) * 5l; } - @Override + @Override public long getTransmitOffset() { - return -1 * mMessage.getLong( TRANSMIT_OFFSET ) * 250000l; + return -1 * mMessage.getLong(TRANSMIT_OFFSET) * 250000l; + } + + @Override + public long getDownlinkFrequency(int channelNumber) + { + return getBaseFrequency() + (channelNumber * getChannelSpacing()); + } + + @Override + public long getUplinkFrequency(int channelNumber) + { + return getDownlinkFrequency(channelNumber) + getTransmitOffset(); + } + + @Override + public boolean isTDMA() + { + return false; } } diff --git a/src/module/decode/p25/message/tdu/lc/ChannelIdentifierUpdateExplicit.java b/src/module/decode/p25/message/tdu/lc/ChannelIdentifierUpdateExplicit.java index eb427fe3..a3be9821 100644 --- a/src/module/decode/p25/message/tdu/lc/ChannelIdentifierUpdateExplicit.java +++ b/src/module/decode/p25/message/tdu/lc/ChannelIdentifierUpdateExplicit.java @@ -1,82 +1,114 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tdu.lc; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.reference.LinkControlOpcode; -public class ChannelIdentifierUpdateExplicit extends TDULinkControlMessage - implements IBandIdentifier +public class ChannelIdentifierUpdateExplicit extends TDULinkControlMessage implements IBandIdentifier { - public static final int[] IDENTIFIER = { 72,73,74,75 }; - public static final int[] BANDWIDTH = { 88,89,90,91 }; - public static final int[] TRANSMIT_OFFSET = { 92,93,94,95,96,97,98,99,112, - 113,114,115,116,117 }; - public static final int[] CHANNEL_SPACING = { 118,119,120,121,122, - 123,136,137,138,139 }; - public static final int[] BASE_FREQUENCY = { 140,141,142,143,144,145,146, - 147,160,161,162,163,164,165,166,167,168,169,170,171,184,185,186, - 187,188,189,190,191,192,193,194,195 }; - - public ChannelIdentifierUpdateExplicit( TDULinkControlMessage source ) - { - super( source ); - } - + public static final int[] IDENTIFIER = {72, 73, 74, 75}; + public static final int[] BANDWIDTH = {88, 89, 90, 91}; + public static final int[] TRANSMIT_OFFSET = {92, 93, 94, 95, 96, 97, 98, 99, 112, 113, 114, 115, 116, 117}; + public static final int[] CHANNEL_SPACING = {118, 119, 120, 121, 122, 123, 136, 137, 138, 139}; + public static final int[] BASE_FREQUENCY = {140, 141, 142, 143, 144, 145, 146, 147, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195}; + + public ChannelIdentifierUpdateExplicit(TDULinkControlMessage source) + { + super(source); + } + @Override public String getEventType() { return LinkControlOpcode.CHANNEL_IDENTIFIER_UPDATE_EXPLICIT.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " IDEN:" + getIdentifier() ); + @Override + public String getMessage() + { + StringBuilder sb = new StringBuilder(); - sb.append( " BASE:" + getBaseFrequency() ); - - sb.append( " BW:" + getBandwidth() ); - - sb.append( " SPACING:" + getChannelSpacing() ); - - sb.append( " OFFSET:" + getTransmitOffset() ); - - return sb.toString(); - } + sb.append(getMessageStub()); - @Override - public int getIdentifier() - { - return mMessage.getInt( IDENTIFIER ); - } + sb.append(" IDEN:" + getIdentifier()); - /** + sb.append(" BASE:" + getBaseFrequency()); + + sb.append(" BW:" + getBandwidth()); + + sb.append(" SPACING:" + getChannelSpacing()); + + sb.append(" OFFSET:" + getTransmitOffset()); + + return sb.toString(); + } + + @Override + public int getIdentifier() + { + return mMessage.getInt(IDENTIFIER); + } + + /** * Channel bandwidth in hertz */ @Override public int getBandwidth() { - return mMessage.getInt( BANDWIDTH ) * 125; + return mMessage.getInt(BANDWIDTH) * 125; } - + @Override public long getChannelSpacing() { - return mMessage.getLong( CHANNEL_SPACING ) * 125l; + return mMessage.getLong(CHANNEL_SPACING) * 125l; } @Override public long getBaseFrequency() { - return mMessage.getLong( BASE_FREQUENCY ) * 5l; + return mMessage.getLong(BASE_FREQUENCY) * 5l; } - @Override + @Override public long getTransmitOffset() { - return -1 * mMessage.getLong( TRANSMIT_OFFSET ) * 250000l; + return -1 * mMessage.getLong(TRANSMIT_OFFSET) * 250000l; + } + + @Override + public long getDownlinkFrequency(int channelNumber) + { + return getBaseFrequency() + (channelNumber * getChannelSpacing()); + } + + @Override + public long getUplinkFrequency(int channelNumber) + { + return getDownlinkFrequency(channelNumber) + getTransmitOffset(); + } + + @Override + public boolean isTDMA() + { + return false; } } diff --git a/src/module/decode/p25/message/tdu/lc/GroupVoiceChannelUpdate.java b/src/module/decode/p25/message/tdu/lc/GroupVoiceChannelUpdate.java index 8f9521ef..3aa54dfc 100644 --- a/src/module/decode/p25/message/tdu/lc/GroupVoiceChannelUpdate.java +++ b/src/module/decode/p25/message/tdu/lc/GroupVoiceChannelUpdate.java @@ -1,176 +1,207 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tdu.lc; -import java.util.Set; -import java.util.TreeSet; - import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.reference.LinkControlOpcode; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class GroupVoiceChannelUpdate extends TDULinkControlMessage - implements IdentifierReceiver -{ - private final static Logger mLog = - LoggerFactory.getLogger( GroupVoiceChannelUpdate.class ); +import java.util.Set; +import java.util.TreeSet; + +public class GroupVoiceChannelUpdate extends TDULinkControlMessage implements IdentifierReceiver +{ + public static final int[] IDENTIFIER_A = {72, 73, 74, 75}; + public static final int[] CHANNEL_A = {88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99}; + public static final int[] GROUP_ADDRESS_A = {112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 136, 137, 138, 139}; + public static final int[] IDENTIFIER_B = {140, 141, 142, 143}; + public static final int[] CHANNEL_B = {144, 145, 146, 147, 160, 161, 162, 163, 164, 165, 166, 167}; + public static final int[] GROUP_ADDRESS_B = {168, 169, 170, 171, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195}; + + private IBandIdentifier mIdentifierUpdateA; + private IBandIdentifier mIdentifierUpdateB; + + public GroupVoiceChannelUpdate(TDULinkControlMessage source) + { + super(source); + } - public static final int[] IDENTIFIER_A = { 72,73,74,75 }; - public static final int[] CHANNEL_A = { 88,89,90,91,92,93,94,95,96,97,98,99 }; - public static final int[] GROUP_ADDRESS_A = { 112,113,114,115,116,117,118, - 119,120,121,122,123,136,137,138,139 }; - public static final int[] IDENTIFIER_B = { 140,141,142,143 }; - public static final int[] CHANNEL_B = { 144,145,146,147,160,161,162,163,164, - 165,166,167 }; - public static final int[] GROUP_ADDRESS_B = { 168,169,170,171,184,185,186, - 187,188,189,190,191,192,193,194,195 }; - - private IBandIdentifier mIdentifierUpdateA; - private IBandIdentifier mIdentifierUpdateB; - - public GroupVoiceChannelUpdate( TDULinkControlMessage source ) - { - super( source ); - } - @Override public String getEventType() { return LinkControlOpcode.GROUP_VOICE_CHANNEL_UPDATE.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " CHAN A:" + getChannelA() ); - - sb.append( " GRP A:" + getGroupAddressA() ); - - if( hasChannelB() ) - { - sb.append( " CHAN B:" + getChannelA() ); - - sb.append( " GRP B:" + getGroupAddressA() ); - } - - return sb.toString(); - } + @Override + public String getMessage() + { + StringBuilder sb = new StringBuilder(); + + sb.append(getMessageStub()); + + sb.append(" CHAN A:" + getChannelA()); + + sb.append(" GRP A:" + getGroupAddressA()); + + if(hasChannelB()) + { + sb.append(" CHAN B:" + getChannelA()); + + sb.append(" GRP B:" + getGroupAddressA()); + } + + return sb.toString(); + } + + public int getChannelIdentifierA() + { + return mMessage.getInt(IDENTIFIER_A); + } - public int getChannelIdentifierA() - { - return mMessage.getInt( IDENTIFIER_A ); - } - public int getChannelNumberA() { - return mMessage.getInt( CHANNEL_A ); + return mMessage.getInt(CHANNEL_A); } - + public String getChannelA() { - return getChannelIdentifierA() + "-" + getChannelNumberA(); + return getChannelIdentifierA() + "-" + getChannelNumberA(); } - - public int getChannelIdentifierB() - { - return mMessage.getInt( IDENTIFIER_B ); - } - + + public int getChannelIdentifierB() + { + return mMessage.getInt(IDENTIFIER_B); + } + public int getChannelNumberB() { - return mMessage.getInt( CHANNEL_B ); + return mMessage.getInt(CHANNEL_B); } - + public String getChannelB() { - return getChannelIdentifierB() + "-" + getChannelNumberB(); + return getChannelIdentifierB() + "-" + getChannelNumberB(); } - + public boolean hasChannelB() { - return getChannelNumberB() != 0; + return getChannelNumberB() != 0; } - + public String getGroupAddressA() { - return mMessage.getHex( GROUP_ADDRESS_A, 4 ); + return mMessage.getHex(GROUP_ADDRESS_A, 4); } public String getGroupAddressB() { - return mMessage.getHex( GROUP_ADDRESS_B, 4 ); + return mMessage.getHex(GROUP_ADDRESS_B, 4); } - /** - * Returns a sorted list of addresses contained in the A and B fields - * @return - */ - public Set getAddresses() - { - Set addresses = new TreeSet(); - - addresses.add( getGroupAddressA() ); - addresses.add( getGroupAddressB() ); - - return addresses; - } - - - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + /** + * Returns a sorted list of addresses contained in the A and B fields + * + * @return + */ + public Set getAddresses() { - if( identifier == getChannelIdentifierA() ) - { - mIdentifierUpdateA = message; - } - if( identifier == getChannelIdentifierB() ) - { - mIdentifierUpdateB = message; - } + Set addresses = new TreeSet(); + + addresses.add(getGroupAddressA()); + addresses.add(getGroupAddressB()); + + return addresses; } - @Override + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getChannelIdentifierA()) + { + mIdentifierUpdateA = message; + } + if(identifier == getChannelIdentifierB()) + { + mIdentifierUpdateB = message; + } + } + + @Override public int[] getIdentifiers() { - if( hasChannelB() ) - { - int[] identifiers = new int[ 2 ]; - identifiers[ 0 ] = getChannelIdentifierA(); - identifiers[ 1 ] = getChannelIdentifierB(); - - return identifiers; - } - else - { - int[] identifiers = new int[ 1 ]; - identifiers[ 0 ] = getChannelIdentifierA(); - - return identifiers; - } + if(hasChannelB()) + { + int[] identifiers = new int[2]; + identifiers[0] = getChannelIdentifierA(); + identifiers[1] = getChannelIdentifierB(); + + return identifiers; + } + else + { + int[] identifiers = new int[1]; + identifiers[0] = getChannelIdentifierA(); + + return identifiers; + } } public long getDownlinkFrequencyA() { - return calculateDownlink( mIdentifierUpdateA, getChannelNumberA() ); + if(mIdentifierUpdateA != null) + { + return mIdentifierUpdateA.getDownlinkFrequency(getChannelNumberA()); + } + + return 0; } - + public long getUplinkFrequencyA() { - return calculateUplink( mIdentifierUpdateA, getChannelNumberA() ); + if(mIdentifierUpdateA != null) + { + return mIdentifierUpdateA.getUplinkFrequency(getChannelNumberA()); + } + + return 0; } public long getDownlinkFrequencyB() { - return calculateDownlink( mIdentifierUpdateB, getChannelNumberA() ); + if(mIdentifierUpdateB != null) + { + return mIdentifierUpdateB.getDownlinkFrequency(getChannelNumberB()); + } + + return 0; } - + public long getUplinkFrequencyB() { - return calculateUplink( mIdentifierUpdateB, getChannelNumberA() ); + if(mIdentifierUpdateB != null) + { + return mIdentifierUpdateB.getUplinkFrequency(getChannelNumberB()); + } + + return 0; } } diff --git a/src/module/decode/p25/message/tdu/lc/GroupVoiceChannelUpdateExplicit.java b/src/module/decode/p25/message/tdu/lc/GroupVoiceChannelUpdateExplicit.java index 174f988f..72c35bcb 100644 --- a/src/module/decode/p25/message/tdu/lc/GroupVoiceChannelUpdateExplicit.java +++ b/src/module/decode/p25/message/tdu/lc/GroupVoiceChannelUpdateExplicit.java @@ -1,154 +1,176 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tdu.lc; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.reference.LinkControlOpcode; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class GroupVoiceChannelUpdateExplicit extends TDULinkControlMessage - implements IdentifierReceiver + implements IdentifierReceiver { - private final static Logger mLog = - LoggerFactory.getLogger( GroupVoiceChannelUpdateExplicit.class ); + private final static Logger mLog = + LoggerFactory.getLogger(GroupVoiceChannelUpdateExplicit.class); public static final int EMERGENCY_FLAG = 92; public static final int ENCRYPTED_CHANNEL_FLAG = 93; public static final int DUPLEX_MODE = 94; public static final int SESSION_MODE = 95; - public static final int[] GROUP_ADDRESS = { 112,113,114,115,116,117,118, - 119,120,121,122,123,136,137,138,139 }; - public static final int[] TRANSMIT_IDENTIFIER = { 140,141,142,143 }; - public static final int[] TRANSMIT_CHANNEL = { 144,145,146,147,160,161,162, - 163,164,165,166,167 }; - public static final int[] RECEIVE_IDENTIFIER = { 168,169,170,171 }; - public static final int[] RECEIVE_CHANNEL = { 184,185,186,187,188,189,190, - 191,192,193,194,195,196,197,198,199 }; - - private IBandIdentifier mTransmitIdentifierUpdate; - private IBandIdentifier mReceiveIdentifierUpdate; - - public GroupVoiceChannelUpdateExplicit( TDULinkControlMessage source ) - { - super( source ); - } - + public static final int[] GROUP_ADDRESS = {112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 136, 137, 138, 139}; + public static final int[] TRANSMIT_IDENTIFIER = {140, 141, 142, 143}; + public static final int[] TRANSMIT_CHANNEL = {144, 145, 146, 147, 160, 161, 162, 163, 164, 165, 166, 167}; + public static final int[] RECEIVE_IDENTIFIER = {168, 169, 170, 171}; + public static final int[] RECEIVE_CHANNEL = {184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199}; + + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; + + public GroupVoiceChannelUpdateExplicit(TDULinkControlMessage source) + { + super(source); + } + @Override public String getEventType() { return LinkControlOpcode.GROUP_VOICE_CHANNEL_UPDATE_EXPLICIT.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - if( isEmergency() ) - { - sb.append( " EMERGENCY" ); - } - if( isEncryptedChannel() ) - { - sb.append( " ENCRYPTED CHANNEL" ); - } + @Override + public String getMessage() + { + StringBuilder sb = new StringBuilder(); - - return sb.toString(); - } + sb.append(getMessageStub()); + + if(isEmergency()) + { + sb.append(" EMERGENCY"); + } + if(isEncryptedChannel()) + { + sb.append(" ENCRYPTED CHANNEL"); + } + + + return sb.toString(); + } public boolean isEmergency() { - return mMessage.get( EMERGENCY_FLAG ); + return mMessage.get(EMERGENCY_FLAG); } - + public boolean isEncryptedChannel() { - return mMessage.get( ENCRYPTED_CHANNEL_FLAG ); + return mMessage.get(ENCRYPTED_CHANNEL_FLAG); } - + public DuplexMode getDuplexMode() { - return mMessage.get( DUPLEX_MODE ) ? DuplexMode.FULL : DuplexMode.HALF; + return mMessage.get(DUPLEX_MODE) ? DuplexMode.FULL : DuplexMode.HALF; } public SessionMode getSessionMode() { - return mMessage.get( SESSION_MODE ) ? - SessionMode.CIRCUIT : SessionMode.PACKET; + return mMessage.get(SESSION_MODE) ? + SessionMode.CIRCUIT : SessionMode.PACKET; } public int getTransmitChannelIdentifier() - { - return mMessage.getInt( TRANSMIT_IDENTIFIER ); - } - - public int getTransmitChannelNumber() { - return mMessage.getInt( TRANSMIT_CHANNEL ); - } - - public String getTransmitChannel() - { - return getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber(); - } - - public int getReceiveChannelIdentifier() - { - return mMessage.getInt( RECEIVE_IDENTIFIER ); - } - - public int getReceiveChannelNumber() - { - return mMessage.getInt( RECEIVE_CHANNEL ); - } - - public String getReceiveChannel() - { - return getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber(); - } - - public String getGroupAddress() - { - return mMessage.getHex( GROUP_ADDRESS, 4 ); - } - - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) - { - if( identifier == getTransmitChannelIdentifier() ) - { - mTransmitIdentifierUpdate = message; - } - if( identifier == getReceiveChannelIdentifier() ) - { - mReceiveIdentifierUpdate = message; - } + return mMessage.getInt(TRANSMIT_IDENTIFIER); } - @Override + public int getTransmitChannelNumber() + { + return mMessage.getInt(TRANSMIT_CHANNEL); + } + + public String getTransmitChannel() + { + return getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber(); + } + + public int getReceiveChannelIdentifier() + { + return mMessage.getInt(RECEIVE_IDENTIFIER); + } + + public int getReceiveChannelNumber() + { + return mMessage.getInt(RECEIVE_CHANNEL); + } + + public String getReceiveChannel() + { + return getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber(); + } + + public String getGroupAddress() + { + return mMessage.getHex(GROUP_ADDRESS, 4); + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getTransmitChannelIdentifier()) + { + mTransmitIdentifierUpdate = message; + } + if(identifier == getReceiveChannelIdentifier()) + { + mReceiveIdentifierUpdate = message; + } + } + + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 2 ]; - - identifiers[ 0 ] = getTransmitChannelIdentifier(); - identifiers[ 1 ] = getReceiveChannelIdentifier(); - - return identifiers; + int[] identifiers = new int[2]; + + identifiers[0] = getTransmitChannelIdentifier(); + identifiers[1] = getReceiveChannelIdentifier(); + + return identifiers; } public long getDownlinkFrequency() { - return calculateDownlink( mTransmitIdentifierUpdate, - getTransmitChannelNumber() ); + if(mTransmitIdentifierUpdate != null) + { + return mTransmitIdentifierUpdate.getDownlinkFrequency(getTransmitChannelNumber()); + } + + return 0; } - + public long getUplinkFrequency() { - return calculateUplink( mReceiveIdentifierUpdate, - getReceiveChannelNumber() ); + if(mReceiveIdentifierUpdate != null) + { + return mReceiveIdentifierUpdate.getUplinkFrequency(getReceiveChannelNumber()); + } + + return 0; } } diff --git a/src/module/decode/p25/message/tdu/lc/NetworkStatusBroadcast.java b/src/module/decode/p25/message/tdu/lc/NetworkStatusBroadcast.java index b298fad6..db403f1c 100644 --- a/src/module/decode/p25/message/tdu/lc/NetworkStatusBroadcast.java +++ b/src/module/decode/p25/message/tdu/lc/NetworkStatusBroadcast.java @@ -1,3 +1,21 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tdu.lc; import module.decode.p25.message.IBandIdentifier; @@ -5,106 +23,106 @@ import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.reference.LinkControlOpcode; import module.decode.p25.reference.Service; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class NetworkStatusBroadcast extends TDULinkControlMessage - implements IdentifierReceiver +public class NetworkStatusBroadcast extends TDULinkControlMessage implements IdentifierReceiver { - private final static Logger mLog = - LoggerFactory.getLogger( NetworkStatusBroadcast.class ); - - public static final int[] WACN = { 72,73,74,75,88,89,90,91,92,93,94,95,96, - 97,98,99,112,113,114,115,116,117,118,119,120,121,122,123 }; - public static final int[] SYSTEM = { 136,137,138,139,140,141,142,143,144, - 145,146,147 }; - public static final int[] IDENTIFIER = { 160,161,162,163 }; - public static final int[] CHANNEL = { 164,165,166,167,168,169,170,171,184, - 185,186,187 }; - public static final int[] SYSTEM_SERVICE_CLASS = { 188,189,190,191,192,193, - 194,195 }; - - private IBandIdentifier mIdentifierUpdate; - - public NetworkStatusBroadcast( TDULinkControlMessage source ) - { - super( source ); - } - + public static final int[] WACN = {72, 73, 74, 75, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123}; + public static final int[] SYSTEM = {136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147}; + public static final int[] IDENTIFIER = {160, 161, 162, 163}; + public static final int[] CHANNEL = {164, 165, 166, 167, 168, 169, 170, 171, 184, 185, 186, 187}; + public static final int[] SYSTEM_SERVICE_CLASS = {188, 189, 190, 191, 192, 193, 194, 195}; + + private IBandIdentifier mIdentifierUpdate; + + public NetworkStatusBroadcast(TDULinkControlMessage source) + { + super(source); + } + @Override public String getEventType() { return LinkControlOpcode.NETWORK_STATUS_BROADCAST.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " NETWORK:" + getWACN() ); - sb.append( " SYS:" + getSystem() ); - sb.append( " CHAN:" + getChannel() ); - sb.append( " " + Service.getServices( getSystemServiceClass() ).toString() ); - - return sb.toString(); - } - - public String getWACN() - { - return mMessage.getHex( WACN, 5 ); - } - - public String getSystem() - { - return mMessage.getHex( SYSTEM, 3 ); - } - - public int getIdentifier() - { - return mMessage.getInt( IDENTIFIER ); - } - - public int getChannelNumber() - { - return mMessage.getInt( CHANNEL ); - } - - public String getChannel() - { - return getIdentifier() + "-" + getChannelNumber(); - } - - public int getSystemServiceClass() - { - return mMessage.getInt( SYSTEM_SERVICE_CLASS ); - } - - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + @Override + public String getMessage() { - mIdentifierUpdate = message; + StringBuilder sb = new StringBuilder(); + + sb.append(getMessageStub()); + + sb.append(" NETWORK:" + getWACN()); + sb.append(" SYS:" + getSystem()); + sb.append(" CHAN:" + getChannel()); + sb.append(" " + Service.getServices(getSystemServiceClass()).toString()); + + return sb.toString(); } - @Override + public String getWACN() + { + return mMessage.getHex(WACN, 5); + } + + public String getSystem() + { + return mMessage.getHex(SYSTEM, 3); + } + + public int getIdentifier() + { + return mMessage.getInt(IDENTIFIER); + } + + public int getChannelNumber() + { + return mMessage.getInt(CHANNEL); + } + + public String getChannel() + { + return getIdentifier() + "-" + getChannelNumber(); + } + + public int getSystemServiceClass() + { + return mMessage.getInt(SYSTEM_SERVICE_CLASS); + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + mIdentifierUpdate = message; + } + + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 1 ]; - - identifiers[ 0 ] = getIdentifier(); - - return identifiers; + int[] identifiers = new int[1]; + + identifiers[0] = getIdentifier(); + + return identifiers; } - + public long getDownlinkFrequency() { - return calculateDownlink( mIdentifierUpdate, getChannelNumber() ); + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.getDownlinkFrequency(getChannelNumber()); + } + + return 0; } - + public long getUplinkFrequency() { - return calculateUplink( mIdentifierUpdate, getChannelNumber() ); + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.getUplinkFrequency(getChannelNumber()); + } + + return 0; } } diff --git a/src/module/decode/p25/message/tdu/lc/NetworkStatusBroadcastExplicit.java b/src/module/decode/p25/message/tdu/lc/NetworkStatusBroadcastExplicit.java index d31b41ad..a88536ca 100644 --- a/src/module/decode/p25/message/tdu/lc/NetworkStatusBroadcastExplicit.java +++ b/src/module/decode/p25/message/tdu/lc/NetworkStatusBroadcastExplicit.java @@ -1,131 +1,146 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tdu.lc; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.reference.LinkControlOpcode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class NetworkStatusBroadcastExplicit extends TDULinkControlMessage - implements IdentifierReceiver +public class NetworkStatusBroadcastExplicit extends TDULinkControlMessage implements IdentifierReceiver { - private final static Logger mLog = - LoggerFactory.getLogger( NetworkStatusBroadcastExplicit.class ); + public static final int[] WACN = {72, 73, 74, 75, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 112, 113, 114, 115}; + public static final int[] SYSTEM = {116, 117, 118, 119, 120, 121, 122, 123, 136, 137, 138, 139}; + public static final int[] TRANSMIT_IDENTIFIER = {140, 141, 142, 143}; + public static final int[] TRANSMIT_CHANNEL = {144, 145, 146, 147, 160, 161, 162, 163, 164, 165, 166, 167}; + public static final int[] RECEIVE_IDENTIFIER = {168, 169, 170, 171}; + public static final int[] RECEIVE_CHANNEL = {184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195}; + + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; + + public NetworkStatusBroadcastExplicit(TDULinkControlMessage source) + { + super(source); + } - public static final int[] WACN = { 72,73,74,75,88,89,90,91,92,93,94,95,96, - 97,98,99,112,113,114,115 }; - public static final int[] SYSTEM = { 116,117,118,119,120,121,122,123,136, - 137,138,139 }; - public static final int[] TRANSMIT_IDENTIFIER = { 140,141,142,143 }; - public static final int[] TRANSMIT_CHANNEL = { 144,145,146,147,160,161,162, - 163,164,165,166,167 }; - public static final int[] RECEIVE_IDENTIFIER = { 168,169,170,171 }; - public static final int[] RECEIVE_CHANNEL = { 184,185,186,187,188,189,190, - 191,192,193,194,195 }; - - private IBandIdentifier mTransmitIdentifierUpdate; - private IBandIdentifier mReceiveIdentifierUpdate; - - public NetworkStatusBroadcastExplicit( TDULinkControlMessage source ) - { - super( source ); - } - @Override public String getEventType() { return LinkControlOpcode.NETWORK_STATUS_BROADCAST_EXPLICIT.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " NETWORK:" + getWACN() ); - sb.append( " SYS:" + getSystem() ); - sb.append( " TRANSMIT:" + getTransmitChannel() ); - sb.append( " RECEIVE:" + getReceiveChannel() ); - - return sb.toString(); - } - - public String getWACN() - { - return mMessage.getHex( WACN, 5 ); - } - - public String getSystem() - { - return mMessage.getHex( SYSTEM, 3 ); - } - - public int getTransmitIdentifier() - { - return mMessage.getInt( TRANSMIT_IDENTIFIER ); - } - - public int getTransmitChannelNumber() - { - return mMessage.getInt( TRANSMIT_CHANNEL ); - } - - public String getTransmitChannel() - { - return getTransmitIdentifier() + "-" + getTransmitChannelNumber(); - } - - public int getReceiveIdentifier() - { - return mMessage.getInt( RECEIVE_IDENTIFIER ); - } - - public int getReceiveChannelNumber() - { - return mMessage.getInt( RECEIVE_CHANNEL ); - } - - public String getReceiveChannel() - { - return getReceiveIdentifier() + "-" + getReceiveChannelNumber(); - } - - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + @Override + public String getMessage() { - if( identifier == getTransmitIdentifier() ) - { - mTransmitIdentifierUpdate = message; - } - if( identifier == getReceiveIdentifier() ) - { - mReceiveIdentifierUpdate = message; - } + StringBuilder sb = new StringBuilder(); + + sb.append(getMessageStub()); + + sb.append(" NETWORK:" + getWACN()); + sb.append(" SYS:" + getSystem()); + sb.append(" TRANSMIT:" + getTransmitChannel()); + sb.append(" RECEIVE:" + getReceiveChannel()); + + return sb.toString(); } - @Override + public String getWACN() + { + return mMessage.getHex(WACN, 5); + } + + public String getSystem() + { + return mMessage.getHex(SYSTEM, 3); + } + + public int getTransmitIdentifier() + { + return mMessage.getInt(TRANSMIT_IDENTIFIER); + } + + public int getTransmitChannelNumber() + { + return mMessage.getInt(TRANSMIT_CHANNEL); + } + + public String getTransmitChannel() + { + return getTransmitIdentifier() + "-" + getTransmitChannelNumber(); + } + + public int getReceiveIdentifier() + { + return mMessage.getInt(RECEIVE_IDENTIFIER); + } + + public int getReceiveChannelNumber() + { + return mMessage.getInt(RECEIVE_CHANNEL); + } + + public String getReceiveChannel() + { + return getReceiveIdentifier() + "-" + getReceiveChannelNumber(); + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getTransmitIdentifier()) + { + mTransmitIdentifierUpdate = message; + } + if(identifier == getReceiveIdentifier()) + { + mReceiveIdentifierUpdate = message; + } + } + + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 2 ]; - - identifiers[ 0 ] = getTransmitIdentifier(); - identifiers[ 1 ] = getReceiveIdentifier(); - - return identifiers; + int[] identifiers = new int[2]; + + identifiers[0] = getTransmitIdentifier(); + identifiers[1] = getReceiveIdentifier(); + + return identifiers; } - + public long getDownlinkFrequency() { - return calculateDownlink( mTransmitIdentifierUpdate, - getTransmitChannelNumber() ); + if(mTransmitIdentifierUpdate != null) + { + return mTransmitIdentifierUpdate.getDownlinkFrequency(getTransmitChannelNumber()); + } + + return 0; } - + public long getUplinkFrequency() { - return calculateUplink( mReceiveIdentifierUpdate, - getReceiveChannelNumber() ); + if(mReceiveIdentifierUpdate != null) + { + return mReceiveIdentifierUpdate.getUplinkFrequency(getReceiveChannelNumber()); + } + + return 0; } } diff --git a/src/module/decode/p25/message/tdu/lc/RFSSStatusBroadcast.java b/src/module/decode/p25/message/tdu/lc/RFSSStatusBroadcast.java index 7864b3c8..cc29771b 100644 --- a/src/module/decode/p25/message/tdu/lc/RFSSStatusBroadcast.java +++ b/src/module/decode/p25/message/tdu/lc/RFSSStatusBroadcast.java @@ -1,3 +1,21 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tdu.lc; import module.decode.p25.message.IBandIdentifier; @@ -5,128 +23,124 @@ import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.message.tsbk.osp.control.SystemService; import module.decode.p25.reference.LinkControlOpcode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class RFSSStatusBroadcast extends TDULinkControlMessage - implements IdentifierReceiver +public class RFSSStatusBroadcast extends TDULinkControlMessage implements IdentifierReceiver { - private final static Logger mLog = - LoggerFactory.getLogger( RFSSStatusBroadcast.class ); + public static final int[] LRA = {72, 73, 74, 75, 88, 89, 90, 91}; + public static final int[] SYSTEM_ID = {96, 97, 98, 99, 112, 113, 114, 115, 116, 117, 118, 119}; + public static final int[] RFSS_ID = {120, 121, 122, 123, 136, 137, 138, 139}; + public static final int[] SITE_ID = {140, 141, 142, 143, 144, 145, 146, 147}; + public static final int[] IDENTIFIER = {160, 161, 162, 163}; + public static final int[] CHANNEL = {164, 165, 166, 167, 168, 169, 170, 171, 184, 185, 186, 187}; + public static final int[] SYSTEM_SERVICE_CLASS = {188, 189, 190, 191, 192, 193, 194, 195}; + + private IBandIdentifier mIdentifierUpdate; + + public RFSSStatusBroadcast(TDULinkControlMessage source) + { + super(source); + } - public static final int[] LRA = { 72,73,74,75,88,89, - 90,91 }; - public static final int[] SYSTEM_ID = { 96,97,98,99,112,113,114,115,116,117, - 118,119 }; - public static final int[] RFSS_ID = { 120,121,122,123,136,137,138, - 139 }; - public static final int[] SITE_ID = { 140,141,142,143,144,145,146,147 }; - - public static final int[] IDENTIFIER = { 160,161,162,163 }; - public static final int[] CHANNEL = { 164,165,166,167,168,169,170, - 171,184,185,186,187 }; - public static final int[] SYSTEM_SERVICE_CLASS = { 188,189,190,191,192,193, - 194,195 }; - - private IBandIdentifier mIdentifierUpdate; - - public RFSSStatusBroadcast( TDULinkControlMessage source ) - { - super( source ); - } - @Override public String getEventType() { return LinkControlOpcode.RFSS_STATUS_BROADCAST.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " LRA:" + getLocationRegistrationArea() ); - - sb.append( " SYS:" + getSystem() ); - - sb.append( " SITE:" + getRFSubsystemID() + "-" + getSiteID() ); - - sb.append( " CHAN:" + getChannelNumber() ); - - sb.append( " " + SystemService.toString( getSystemServiceClass() ) ); - - sb.append( " " + mMessage.toString() ); - - return sb.toString(); - } - - public String getLocationRegistrationArea() - { - return mMessage.getHex( LRA, 2 ); - } - - public String getSystem() - { - return mMessage.getHex( SYSTEM_ID, 3 ); - } - - public String getRFSubsystemID() - { - return mMessage.getHex( RFSS_ID, 2 ); - } - - public String getSiteID() - { - return mMessage.getHex( SITE_ID, 2 ); - } - - public int getIdentifier() - { - return mMessage.getInt( IDENTIFIER ); - } - - public String getChannel() - { - return getIdentifier() + "-" + getChannelNumber(); - } - - public int getChannelNumber() - { - return mMessage.getInt( CHANNEL ); - } - - public int getSystemServiceClass() - { - return mMessage.getInt( SYSTEM_SERVICE_CLASS ); - } - - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + @Override + public String getMessage() { - mIdentifierUpdate = message; + StringBuilder sb = new StringBuilder(); + + sb.append(getMessageStub()); + + sb.append(" LRA:" + getLocationRegistrationArea()); + + sb.append(" SYS:" + getSystem()); + + sb.append(" SITE:" + getRFSubsystemID() + "-" + getSiteID()); + + sb.append(" CHAN:" + getChannelNumber()); + + sb.append(" " + SystemService.toString(getSystemServiceClass())); + + sb.append(" " + mMessage.toString()); + + return sb.toString(); } - @Override + public String getLocationRegistrationArea() + { + return mMessage.getHex(LRA, 2); + } + + public String getSystem() + { + return mMessage.getHex(SYSTEM_ID, 3); + } + + public String getRFSubsystemID() + { + return mMessage.getHex(RFSS_ID, 2); + } + + public String getSiteID() + { + return mMessage.getHex(SITE_ID, 2); + } + + public int getIdentifier() + { + return mMessage.getInt(IDENTIFIER); + } + + public String getChannel() + { + return getIdentifier() + "-" + getChannelNumber(); + } + + public int getChannelNumber() + { + return mMessage.getInt(CHANNEL); + } + + public int getSystemServiceClass() + { + return mMessage.getInt(SYSTEM_SERVICE_CLASS); + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + mIdentifierUpdate = message; + } + + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 1 ]; - - identifiers[ 0 ] = getIdentifier(); - - return identifiers; + int[] identifiers = new int[1]; + + identifiers[0] = getIdentifier(); + + return identifiers; } - + public long getDownlinkFrequency() { - return calculateDownlink( mIdentifierUpdate, getChannelNumber() ); + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.getDownlinkFrequency(getChannelNumber()); + } + + return 0; } - + public long getUplinkFrequency() { - return calculateUplink( mIdentifierUpdate, getChannelNumber() ); + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.getUplinkFrequency(getChannelNumber()); + } + + return 0; } - } diff --git a/src/module/decode/p25/message/tdu/lc/RFSSStatusBroadcastExplicit.java b/src/module/decode/p25/message/tdu/lc/RFSSStatusBroadcastExplicit.java index 452b3d51..0bec65c4 100644 --- a/src/module/decode/p25/message/tdu/lc/RFSSStatusBroadcastExplicit.java +++ b/src/module/decode/p25/message/tdu/lc/RFSSStatusBroadcastExplicit.java @@ -1,152 +1,171 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tdu.lc; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.message.tsbk.osp.control.SystemService; import module.decode.p25.reference.LinkControlOpcode; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class RFSSStatusBroadcastExplicit extends TDULinkControlMessage - implements IdentifierReceiver +public class RFSSStatusBroadcastExplicit extends TDULinkControlMessage implements IdentifierReceiver { - private final static Logger mLog = - LoggerFactory.getLogger( RFSSStatusBroadcastExplicit.class ); + private final static Logger mLog = LoggerFactory.getLogger(RFSSStatusBroadcastExplicit.class); + + public static final int[] LRA = {72, 73, 74, 75, 88, 89, 90, 91}; + public static final int[] RECEIVE_IDENTIFIER = {92, 93, 94, 95}; + public static final int[] RECEIVE_CHANNEL = {96, 97, 98, 99, 112, 113, 114, 115, 116, 117, 118, 119}; + public static final int[] RFSS_ID = {120, 121, 122, 123, 136, 137, 138, 139}; + public static final int[] SITE_ID = {140, 141, 142, 143, 144, 145, 146, 147}; + public static final int[] TRANSMIT_IDENTIFIER = {160, 161, 162, 163}; + public static final int[] TRANSMIT_CHANNEL = {164, 165, 166, 167, 168, 169, 170, 171, 184, 185, 186, 187}; + public static final int[] SYSTEM_SERVICE_CLASS = {188, 189, 190, 191, 192, 193, 194, 195}; + + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; + + public RFSSStatusBroadcastExplicit(TDULinkControlMessage source) + { + super(source); + } - public static final int[] LRA = { 72,73,74,75,88,89,90,91 }; - public static final int[] RECEIVE_IDENTIFIER = { 92,93,94,95 }; - public static final int[] RECEIVE_CHANNEL = { 96,97,98,99,112,113,114,115, - 116,117,118,119 }; - public static final int[] RFSS_ID = { 120,121,122,123,136,137,138, - 139 }; - public static final int[] SITE_ID = { 140,141,142,143,144,145,146,147 }; - - public static final int[] TRANSMIT_IDENTIFIER = { 160,161,162,163 }; - public static final int[] TRANSMIT_CHANNEL = { 164,165,166,167,168,169,170, - 171,184,185,186,187 }; - public static final int[] SYSTEM_SERVICE_CLASS = { 188,189,190,191,192,193, - 194,195 }; - - private IBandIdentifier mTransmitIdentifierUpdate; - private IBandIdentifier mReceiveIdentifierUpdate; - - public RFSSStatusBroadcastExplicit( TDULinkControlMessage source ) - { - super( source ); - } - @Override public String getEventType() { return LinkControlOpcode.RFSS_STATUS_BROADCAST_EXPLICIT.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " LRA:" + getLocationRegistrationArea() ); - - sb.append( " SITE:" + getRFSubsystemID() + "-" + getSiteID() ); - - sb.append( " TRANSMIT:" + getTransmitChannelNumber() ); - - sb.append( " RECEIVE:" + getReceiveChannelNumber() ); - - sb.append( " " + SystemService.toString( getSystemServiceClass() ) ); - - sb.append( " " + mMessage.toString() ); - - return sb.toString(); - } - - public String getLocationRegistrationArea() - { - return mMessage.getHex( LRA, 2 ); - } - - public String getRFSubsystemID() - { - return mMessage.getHex( RFSS_ID, 2 ); - } - - public String getSiteID() - { - return mMessage.getHex( SITE_ID, 2 ); - } - - public int getTransmitIdentifier() - { - return mMessage.getInt( TRANSMIT_IDENTIFIER ); - } - - public String getTransmitChannel() - { - return getTransmitIdentifier() + "-" + getTransmitChannelNumber(); - } - - public int getTransmitChannelNumber() - { - return mMessage.getInt( TRANSMIT_CHANNEL ); - } - - public int getReceiveIdentifier() - { - return mMessage.getInt( RECEIVE_IDENTIFIER ); - } - - public String getReceiveChannel() - { - return getReceiveIdentifier() + "-" + getReceiveChannelNumber(); - } - - public int getReceiveChannelNumber() - { - return mMessage.getInt( RECEIVE_CHANNEL ); - } - - public int getSystemServiceClass() - { - return mMessage.getInt( SYSTEM_SERVICE_CLASS ); - } - - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + @Override + public String getMessage() { - if( identifier == getTransmitIdentifier() ) - { - mTransmitIdentifierUpdate = message; - } - - if( identifier == getReceiveIdentifier() ) - { - mReceiveIdentifierUpdate = message; - } + StringBuilder sb = new StringBuilder(); + + sb.append(getMessageStub()); + + sb.append(" LRA:" + getLocationRegistrationArea()); + + sb.append(" SITE:" + getRFSubsystemID() + "-" + getSiteID()); + + sb.append(" TRANSMIT:" + getTransmitChannelNumber()); + + sb.append(" RECEIVE:" + getReceiveChannelNumber()); + + sb.append(" " + SystemService.toString(getSystemServiceClass())); + + sb.append(" " + mMessage.toString()); + + return sb.toString(); } - @Override + public String getLocationRegistrationArea() + { + return mMessage.getHex(LRA, 2); + } + + public String getRFSubsystemID() + { + return mMessage.getHex(RFSS_ID, 2); + } + + public String getSiteID() + { + return mMessage.getHex(SITE_ID, 2); + } + + public int getTransmitIdentifier() + { + return mMessage.getInt(TRANSMIT_IDENTIFIER); + } + + public String getTransmitChannel() + { + return getTransmitIdentifier() + "-" + getTransmitChannelNumber(); + } + + public int getTransmitChannelNumber() + { + return mMessage.getInt(TRANSMIT_CHANNEL); + } + + public int getReceiveIdentifier() + { + return mMessage.getInt(RECEIVE_IDENTIFIER); + } + + public String getReceiveChannel() + { + return getReceiveIdentifier() + "-" + getReceiveChannelNumber(); + } + + public int getReceiveChannelNumber() + { + return mMessage.getInt(RECEIVE_CHANNEL); + } + + public int getSystemServiceClass() + { + return mMessage.getInt(SYSTEM_SERVICE_CLASS); + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getTransmitIdentifier()) + { + mTransmitIdentifierUpdate = message; + } + + if(identifier == getReceiveIdentifier()) + { + mReceiveIdentifierUpdate = message; + } + } + + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 2 ]; - - identifiers[ 0 ] = getTransmitIdentifier(); - identifiers[ 1 ] = getReceiveIdentifier(); - - return identifiers; + int[] identifiers = new int[2]; + + identifiers[0] = getTransmitIdentifier(); + identifiers[1] = getReceiveIdentifier(); + + return identifiers; } - + public long getDownlinkFrequency() { - return calculateDownlink( mTransmitIdentifierUpdate, getTransmitChannelNumber() ); + if(mTransmitIdentifierUpdate != null) + { + return mTransmitIdentifierUpdate.getDownlinkFrequency(getTransmitChannelNumber()); + } + + return 0; } - + public long getUplinkFrequency() { - return calculateUplink( mReceiveIdentifierUpdate, getReceiveChannelNumber() ); + if(mReceiveIdentifierUpdate != null) + { + return mReceiveIdentifierUpdate.getUplinkFrequency(getReceiveChannelNumber()); + } + + return 0; } - } diff --git a/src/module/decode/p25/message/tdu/lc/SecondaryControlChannelBroadcast.java b/src/module/decode/p25/message/tdu/lc/SecondaryControlChannelBroadcast.java index 6a3587df..e1cf6342 100644 --- a/src/module/decode/p25/message/tdu/lc/SecondaryControlChannelBroadcast.java +++ b/src/module/decode/p25/message/tdu/lc/SecondaryControlChannelBroadcast.java @@ -1,3 +1,21 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tdu.lc; import module.decode.p25.message.IBandIdentifier; @@ -5,155 +23,162 @@ import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.message.tsbk.osp.control.SystemService; import module.decode.p25.reference.LinkControlOpcode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SecondaryControlChannelBroadcast extends TDULinkControlMessage - implements IdentifierReceiver +public class SecondaryControlChannelBroadcast extends TDULinkControlMessage implements IdentifierReceiver { - private final static Logger mLog = - LoggerFactory.getLogger( SecondaryControlChannelBroadcast.class ); + public static final int[] RFSS_ID = {72, 73, 74, 75, 88, 89, 90, 91}; + public static final int[] SITE_ID = {92, 93, 94, 95, 96, 97, 98, 99}; + public static final int[] IDENTIFIER_A = {112, 113, 114, 115}; + public static final int[] CHANNEL_A = {116, 117, 118, 119, 120, 121, 122, 123, 136, 137, 138, 139}; + public static final int[] SYSTEM_SERVICE_CLASS_A = {140, 141, 142, 143, 144, 145, 146, 147}; + public static final int[] IDENTIFIER_B = {160, 161, 162, 163}; + public static final int[] CHANNEL_B = {164, 165, 166, 167, 168, 169, 170, 171, 184, 185, 186, 187}; + public static final int[] SYSTEM_SERVICE_CLASS_B = {188, 189, 190, 191, 192, 193, 194, 195}; + + private IBandIdentifier mIdentifierProviderA; + private IBandIdentifier mIdentifierProviderB; + + public SecondaryControlChannelBroadcast(TDULinkControlMessage source) + { + super(source); + } - public static final int[] RFSS_ID = { 72,73,74,75,88,89,90,91 }; - public static final int[] SITE_ID = { 92,93,94,95,96,97,98,99 }; - public static final int[] IDENTIFIER_A = { 112,113,114,115 }; - public static final int[] CHANNEL_A = { 116,117,118,119,120,121,122, - 123,136,137,138,139 }; - - public static final int[] SYSTEM_SERVICE_CLASS_A = { 140,141,142,143,144, - 145,146,147 }; - - public static final int[] IDENTIFIER_B = { 160,161,162,163 }; - public static final int[] CHANNEL_B = { 164,165,166,167,168,169,170, - 171,184,185,186,187 }; - public static final int[] SYSTEM_SERVICE_CLASS_B = { 188,189,190,191,192, - 193,194,195 }; - - private IBandIdentifier mIdentifierProviderA; - private IBandIdentifier mIdentifierProviderB; - - public SecondaryControlChannelBroadcast( TDULinkControlMessage source ) - { - super( source ); - } - @Override public String getEventType() { return LinkControlOpcode.SECONDARY_CONTROL_CHANNEL_BROADCAST.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " SITE:" + getRFSubsystemID() + "-" + getSiteID() ); - - sb.append( " CHAN A:" + getChannelA() ); - - sb.append( " " + SystemService.toString( getSystemServiceClassA() ) ); - - sb.append( " CHAN B:" + getChannelB() ); - - sb.append( " " + SystemService.toString( getSystemServiceClassB() ) ); - - return sb.toString(); - } - - public String getRFSubsystemID() - { - return mMessage.getHex( RFSS_ID, 2 ); - } - - public String getSiteID() - { - return mMessage.getHex( SITE_ID, 2 ); - } - - public int getIdentifierA() - { - return mMessage.getInt( IDENTIFIER_A ); - } - - public int getChannelA() - { - return mMessage.getInt( CHANNEL_A ); - } - - public String getChannelNumberA() - { - return getIdentifierA() + "-" + getChannelA(); - } - - public int getIdentifierB() - { - return mMessage.getInt( IDENTIFIER_B ); - } - - public int getChannelB() - { - return mMessage.getInt( CHANNEL_B ); - } - - public String getChannelNumberB() - { - return getIdentifierB() + "-" + getChannelB(); - } - - public int getSystemServiceClassA() - { - return mMessage.getInt( SYSTEM_SERVICE_CLASS_A ); - } - - public int getSystemServiceClassB() - { - return mMessage.getInt( SYSTEM_SERVICE_CLASS_B ); - } - - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + @Override + public String getMessage() { - if( identifier == getIdentifierA() ) - { - mIdentifierProviderA = message; - } - if( identifier == getIdentifierB() ) - { - mIdentifierProviderB = message; - } + StringBuilder sb = new StringBuilder(); + + sb.append(getMessageStub()); + + sb.append(" SITE:" + getRFSubsystemID() + "-" + getSiteID()); + + sb.append(" CHAN A:" + getChannelA()); + + sb.append(" " + SystemService.toString(getSystemServiceClassA())); + + sb.append(" CHAN B:" + getChannelB()); + + sb.append(" " + SystemService.toString(getSystemServiceClassB())); + + return sb.toString(); } - @Override + public String getRFSubsystemID() + { + return mMessage.getHex(RFSS_ID, 2); + } + + public String getSiteID() + { + return mMessage.getHex(SITE_ID, 2); + } + + public int getIdentifierA() + { + return mMessage.getInt(IDENTIFIER_A); + } + + public int getChannelA() + { + return mMessage.getInt(CHANNEL_A); + } + + public String getChannelNumberA() + { + return getIdentifierA() + "-" + getChannelA(); + } + + public int getIdentifierB() + { + return mMessage.getInt(IDENTIFIER_B); + } + + public int getChannelB() + { + return mMessage.getInt(CHANNEL_B); + } + + public String getChannelNumberB() + { + return getIdentifierB() + "-" + getChannelB(); + } + + public int getSystemServiceClassA() + { + return mMessage.getInt(SYSTEM_SERVICE_CLASS_A); + } + + public int getSystemServiceClassB() + { + return mMessage.getInt(SYSTEM_SERVICE_CLASS_B); + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getIdentifierA()) + { + mIdentifierProviderA = message; + } + if(identifier == getIdentifierB()) + { + mIdentifierProviderB = message; + } + } + + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 2 ]; - - identifiers[ 0 ] = getIdentifierA(); - identifiers[ 1 ] = getIdentifierB(); - - return identifiers; + int[] identifiers = new int[2]; + + identifiers[0] = getIdentifierA(); + identifiers[1] = getIdentifierB(); + + return identifiers; } - + public long getDownlinkFrequencyA() { - return calculateDownlink( mIdentifierProviderA, getChannelA() ); + if(mIdentifierProviderA != null) + { + return mIdentifierProviderA.getDownlinkFrequency(getChannelA()); + } + + return 0; } - + public long getUplinkFrequencyA() { - return calculateUplink( mIdentifierProviderA, getChannelA() ); + if(mIdentifierProviderA != null) + { + return mIdentifierProviderA.getUplinkFrequency(getChannelA()); + } + + return 0; } - + public long getDownlinkFrequencyB() { - return calculateDownlink( mIdentifierProviderB, getChannelB() ); + if(mIdentifierProviderB != null) + { + return mIdentifierProviderB.getDownlinkFrequency(getChannelB()); + } + + return 0; } - + public long getUplinkFrequencyB() { - return calculateUplink( mIdentifierProviderB, getChannelB() ); + if(mIdentifierProviderB != null) + { + return mIdentifierProviderB.getUplinkFrequency(getChannelB()); + } + + return 0; } } diff --git a/src/module/decode/p25/message/tdu/lc/SecondaryControlChannelBroadcastExplicit.java b/src/module/decode/p25/message/tdu/lc/SecondaryControlChannelBroadcastExplicit.java index fb35f425..8032794d 100644 --- a/src/module/decode/p25/message/tdu/lc/SecondaryControlChannelBroadcastExplicit.java +++ b/src/module/decode/p25/message/tdu/lc/SecondaryControlChannelBroadcastExplicit.java @@ -1,3 +1,21 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tdu.lc; import module.decode.p25.message.IBandIdentifier; @@ -5,136 +23,134 @@ import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.message.tsbk.osp.control.SystemService; import module.decode.p25.reference.LinkControlOpcode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SecondaryControlChannelBroadcastExplicit - extends TDULinkControlMessage implements IdentifierReceiver +public class SecondaryControlChannelBroadcastExplicit extends TDULinkControlMessage implements IdentifierReceiver { - private final static Logger mLog = - LoggerFactory.getLogger( SecondaryControlChannelBroadcastExplicit.class ); + public static final int[] RFSS_ID = {72, 73, 74, 75, 88, 89, 90, 91}; + public static final int[] SITE_ID = {92, 93, 94, 95, 96, 97, 98, 99}; + public static final int[] TRANSMIT_IDENTIFIER = {112, 113, 114, 115}; + public static final int[] TRANSMIT_CHANNEL = {116, 117, 118, 119, 120, 121, 122, 123, 136, 137, 138, 139}; + public static final int[] RECEIVE_IDENTIFIER = {140, 141, 142, 143}; + public static final int[] RECEIVE_CHANNEL = {144, 145, 146, 147, 160, 161, 162, 163, 164, 165, 166, 167}; + public static final int[] SYSTEM_SERVICE_CLASS = {168, 169, 170, 171, 184, 185, 186, 187}; + + private IBandIdentifier mTransmitIdentifierProvider; + private IBandIdentifier mReceiveIdentifierProvider; + + public SecondaryControlChannelBroadcastExplicit(TDULinkControlMessage source) + { + super(source); + } - public static final int[] RFSS_ID = { 72,73,74,75,88,89,90,91 }; - public static final int[] SITE_ID = { 92,93,94,95,96,97,98,99 }; - public static final int[] TRANSMIT_IDENTIFIER = { 112,113,114,115 }; - public static final int[] TRANSMIT_CHANNEL = { 116,117,118,119,120,121,122, - 123,136,137,138,139 }; - public static final int[] RECEIVE_IDENTIFIER = { 140,141,142,143 }; - public static final int[] RECEIVE_CHANNEL = { 144,145,146,147,160,161,162, - 163,164,165,166,167 }; - public static final int[] SYSTEM_SERVICE_CLASS = { 168,169,170,171,184, - 185,186,187 }; - - private IBandIdentifier mTransmitIdentifierProvider; - private IBandIdentifier mReceiveIdentifierProvider; - - public SecondaryControlChannelBroadcastExplicit( TDULinkControlMessage source ) - { - super( source ); - } - @Override public String getEventType() { return LinkControlOpcode.SECONDARY_CONTROL_CHANNEL_BROADCAST_EXPLICIT.getDescription(); } - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " SITE:" + getRFSubsystemID() + "-" + getSiteID() ); - - sb.append( " TRANSMIT:" + getTransmitChannel() ); - - sb.append( " RECEIVE:" + getReceiveChannel() ); - - sb.append( " " + SystemService.toString( getSystemServiceClass() ) ); - - return sb.toString(); - } - - public String getRFSubsystemID() - { - return mMessage.getHex( RFSS_ID, 2 ); - } - - public String getSiteID() - { - return mMessage.getHex( SITE_ID, 2 ); - } - - public int getTransmitIdentifier() - { - return mMessage.getInt( TRANSMIT_IDENTIFIER ); - } - - public int getTransmitChannelNumber() - { - return mMessage.getInt( TRANSMIT_CHANNEL ); - } - - public String getTransmitChannel() - { - return getTransmitIdentifier() + "-" + getTransmitChannelNumber(); - } - - public int getReceiveIdentifier() - { - return mMessage.getInt( RECEIVE_IDENTIFIER ); - } - - public int getReceiveChannelNumber() - { - return mMessage.getInt( RECEIVE_CHANNEL ); - } - - public String getReceiveChannel() - { - return getReceiveIdentifier() + "-" + getReceiveChannelNumber(); - } - - public int getSystemServiceClass() - { - return mMessage.getInt( SYSTEM_SERVICE_CLASS ); - } - - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + @Override + public String getMessage() { - if( identifier == getTransmitIdentifier() ) - { - mTransmitIdentifierProvider = message; - } - if( identifier == getReceiveIdentifier() ) - { - mReceiveIdentifierProvider = message; - } + StringBuilder sb = new StringBuilder(); + + sb.append(getMessageStub()); + + sb.append(" SITE:" + getRFSubsystemID() + "-" + getSiteID()); + + sb.append(" TRANSMIT:" + getTransmitChannel()); + + sb.append(" RECEIVE:" + getReceiveChannel()); + + sb.append(" " + SystemService.toString(getSystemServiceClass())); + + return sb.toString(); } - @Override + public String getRFSubsystemID() + { + return mMessage.getHex(RFSS_ID, 2); + } + + public String getSiteID() + { + return mMessage.getHex(SITE_ID, 2); + } + + public int getTransmitIdentifier() + { + return mMessage.getInt(TRANSMIT_IDENTIFIER); + } + + public int getTransmitChannelNumber() + { + return mMessage.getInt(TRANSMIT_CHANNEL); + } + + public String getTransmitChannel() + { + return getTransmitIdentifier() + "-" + getTransmitChannelNumber(); + } + + public int getReceiveIdentifier() + { + return mMessage.getInt(RECEIVE_IDENTIFIER); + } + + public int getReceiveChannelNumber() + { + return mMessage.getInt(RECEIVE_CHANNEL); + } + + public String getReceiveChannel() + { + return getReceiveIdentifier() + "-" + getReceiveChannelNumber(); + } + + public int getSystemServiceClass() + { + return mMessage.getInt(SYSTEM_SERVICE_CLASS); + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getTransmitIdentifier()) + { + mTransmitIdentifierProvider = message; + } + if(identifier == getReceiveIdentifier()) + { + mReceiveIdentifierProvider = message; + } + } + + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 2 ]; - - identifiers[ 0 ] = getTransmitIdentifier(); - identifiers[ 1 ] = getReceiveIdentifier(); - - return identifiers; + int[] identifiers = new int[2]; + + identifiers[0] = getTransmitIdentifier(); + identifiers[1] = getReceiveIdentifier(); + + return identifiers; } - + public long getDownlinkFrequency() { - return calculateDownlink( mTransmitIdentifierProvider, - getTransmitChannelNumber() ); + if(mTransmitIdentifierProvider != null) + { + return mTransmitIdentifierProvider.getDownlinkFrequency(getTransmitChannelNumber()); + } + + return 0; } - + public long getUplinkFrequency() { - return calculateUplink( mReceiveIdentifierProvider, - getReceiveChannelNumber() ); + if(mReceiveIdentifierProvider != null) + { + return mReceiveIdentifierProvider.getUplinkFrequency(getReceiveChannelNumber()); + } + + return 0; } } diff --git a/src/module/decode/p25/message/tsbk/ChannelGrant.java b/src/module/decode/p25/message/tsbk/ChannelGrant.java index b0c81548..fa4893c7 100644 --- a/src/module/decode/p25/message/tsbk/ChannelGrant.java +++ b/src/module/decode/p25/message/tsbk/ChannelGrant.java @@ -1,26 +1,53 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tsbk; +import alias.AliasList; +import bits.BinaryMessage; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.reference.DataUnitID; -import alias.AliasList; -import bits.BinaryMessage; -public abstract class ChannelGrant extends ServiceMessage - implements IdentifierReceiver +public abstract class ChannelGrant extends ServiceMessage implements IdentifierReceiver { - public static final int[] PRIORITY = { 85,86,87 }; - public static final int[] CHANNEL_IDENTIFIER = { 88,89,90,91 }; - public static final int[] CHANNEL_NUMBER = { 92,93,94,95,96,97,98,99,100, - 101,102,103 }; - + public static final int[] PRIORITY = {85, 86, 87}; + public static final int[] CHANNEL_IDENTIFIER = {88, 89, 90, 91}; + public static final int[] CHANNEL_NUMBER = {92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103}; + private IBandIdentifier mIdentifierUpdate; - - public ChannelGrant( BinaryMessage message, - DataUnitID duid, - AliasList aliasList ) + + public ChannelGrant(BinaryMessage message, DataUnitID duid, AliasList aliasList) { - super( message, duid, aliasList ); + super(message, duid, aliasList); + } + + /** + * Indicates if this channel grant is for a TDMA channel + */ + public boolean isTDMAChannel() + { + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.isTDMA(); + } + + return false; } /** @@ -28,47 +55,56 @@ public abstract class ChannelGrant extends ServiceMessage */ public int getPriority() { - return mMessage.getInt( PRIORITY ); + return mMessage.getInt(PRIORITY); } - + public int getChannelIdentifier() { - return mMessage.getInt( CHANNEL_IDENTIFIER ); + return mMessage.getInt(CHANNEL_IDENTIFIER); } - + public int getChannelNumber() { - return mMessage.getInt( CHANNEL_NUMBER ); + return mMessage.getInt(CHANNEL_NUMBER); } public String getChannel() { - return getChannelIdentifier() + "-" + getChannelNumber(); + return getChannelIdentifier() + "-" + getChannelNumber(); } - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) { - mIdentifierUpdate = message; + mIdentifierUpdate = message; } - @Override + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 1 ]; - identifiers[ 0 ] = getChannelIdentifier(); - - return identifiers; - } - - public long getDownlinkFrequency() - { - return calculateDownlink( mIdentifierUpdate, getChannelNumber() ); - } - - public long getUplinkFrequency() - { - return calculateUplink( mIdentifierUpdate, getChannelNumber() ); + int[] identifiers = new int[1]; + identifiers[0] = getChannelIdentifier(); + + return identifiers; } + public long getDownlinkFrequency() + { + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.getDownlinkFrequency(getChannelNumber()); + } + + return 0; + } + + public long getUplinkFrequency() + { + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.getUplinkFrequency(getChannelNumber()); + } + + return 0; + } } diff --git a/src/module/decode/p25/message/tsbk/GroupChannelGrantExplicit.java b/src/module/decode/p25/message/tsbk/GroupChannelGrantExplicit.java index 5233162f..5a656706 100644 --- a/src/module/decode/p25/message/tsbk/GroupChannelGrantExplicit.java +++ b/src/module/decode/p25/message/tsbk/GroupChannelGrantExplicit.java @@ -1,120 +1,155 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tsbk; -import module.decode.p25.message.IBandIdentifier; -import module.decode.p25.reference.DataUnitID; import alias.AliasList; import bits.BinaryMessage; +import module.decode.p25.message.IBandIdentifier; +import module.decode.p25.reference.DataUnitID; public abstract class GroupChannelGrantExplicit extends ChannelGrant { - public static final int[] TRANSMIT_IDENTIFIER = { 96,97,98,99 }; - public static final int[] TRANSMIT_NUMBER = { 100,101,102,103, - 104,105,106,107,108,109,110,111 }; - public static final int[] RECEIVE_IDENTIFIER = { 112,113,114,115 }; - public static final int[] RECEIVE_NUMBER = { 116,117,118,119, - 120,121,122,123,124,125,126,127 }; - public static final int[] GROUP_ADDRESS = { 128,129,130,131,132,133,134,135, - 136,137,138,139,140,141,142,143 }; - + public static final int[] TRANSMIT_IDENTIFIER = {96, 97, 98, 99}; + public static final int[] TRANSMIT_NUMBER = {100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111}; + public static final int[] RECEIVE_IDENTIFIER = {112, 113, 114, 115}; + public static final int[] RECEIVE_NUMBER = {116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127}; + public static final int[] GROUP_ADDRESS = {128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143}; + private IBandIdentifier mTransmitIdentifierUpdate; private IBandIdentifier mReceiveIdentifierUpdate; - public GroupChannelGrantExplicit( BinaryMessage message, - DataUnitID duid, - AliasList aliasList ) + public GroupChannelGrantExplicit(BinaryMessage message, DataUnitID duid, AliasList aliasList) { - super( message, duid, aliasList ); + super(message, duid, aliasList); + } + + @Override + public boolean isTDMAChannel() + { + if(mTransmitIdentifierUpdate != null) + { + return mTransmitIdentifierUpdate.isTDMA(); + } + + return false; } public String getMessage() { StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - if( isEmergency() ) + + sb.append(getMessageStub()); + + if(isEmergency()) { - sb.append( " EMERGENCY" ); + sb.append(" EMERGENCY"); } - - sb.append( " XMIT:" ); - sb.append( getTransmitChannelIdentifier() + "/" + getTransmitChannelNumber() ); - - sb.append( " RCV:" ); - sb.append( getReceiveChannelIdentifier() + "/" + getReceiveChannelNumber() ); - - sb.append( " GRP:" ); - sb.append( getGroupAddress() ); - + + sb.append(" XMIT:"); + sb.append(getTransmitChannelIdentifier() + "/" + getTransmitChannelNumber()); + + sb.append(" RCV:"); + sb.append(getReceiveChannelIdentifier() + "/" + getReceiveChannelNumber()); + + sb.append(" GRP:"); + sb.append(getGroupAddress()); + return sb.toString(); } - + public int getTransmitChannelIdentifier() { - return mMessage.getInt( TRANSMIT_IDENTIFIER ); - } - - public int getTransmitChannelNumber() - { - return mMessage.getInt( TRANSMIT_NUMBER ); - } - - public String getTransmitChannel() - { - return getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber(); - } - - public int getReceiveChannelIdentifier() - { - return mMessage.getInt( RECEIVE_IDENTIFIER ); - } - - public int getReceiveChannelNumber() - { - return mMessage.getInt( RECEIVE_NUMBER ); - } - - public String getReceiveChannel() - { - return getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber(); - } - - public String getGroupAddress() - { - return mMessage.getHex( GROUP_ADDRESS, 4 ); - } - - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) - { - if( identifier == getTransmitChannelIdentifier() ) - { - mTransmitIdentifierUpdate = message; - } - - if( identifier == getReceiveChannelIdentifier() ) - { - mReceiveIdentifierUpdate = message; - } + return mMessage.getInt(TRANSMIT_IDENTIFIER); } - @Override + public int getTransmitChannelNumber() + { + return mMessage.getInt(TRANSMIT_NUMBER); + } + + public String getTransmitChannel() + { + return getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber(); + } + + public int getReceiveChannelIdentifier() + { + return mMessage.getInt(RECEIVE_IDENTIFIER); + } + + public int getReceiveChannelNumber() + { + return mMessage.getInt(RECEIVE_NUMBER); + } + + public String getReceiveChannel() + { + return getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber(); + } + + public String getGroupAddress() + { + return mMessage.getHex(GROUP_ADDRESS, 4); + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getTransmitChannelIdentifier()) + { + mTransmitIdentifierUpdate = message; + } + + if(identifier == getReceiveChannelIdentifier()) + { + mReceiveIdentifierUpdate = message; + } + } + + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 2 ]; - identifiers[ 0 ] = getTransmitChannelIdentifier(); - identifiers[ 1 ] = getReceiveChannelIdentifier(); - - return identifiers; + int[] identifiers = new int[2]; + identifiers[0] = getTransmitChannelIdentifier(); + identifiers[1] = getReceiveChannelIdentifier(); + + return identifiers; } - + public long getDownlinkFrequency() { - return calculateDownlink( mTransmitIdentifierUpdate, getTransmitChannelNumber() ); + if(mTransmitIdentifierUpdate != null) + { + return mTransmitIdentifierUpdate.getDownlinkFrequency(getTransmitChannelNumber()); + } + + return 0; } - + public long getUplinkFrequency() { - return calculateUplink( mReceiveIdentifierUpdate, getReceiveChannelNumber() ); + if(mReceiveIdentifierUpdate != null) + { + return mReceiveIdentifierUpdate.getUplinkFrequency(getReceiveChannelNumber()); + } + + return 0; } } diff --git a/src/module/decode/p25/message/tsbk/GroupMultiChannelGrant.java b/src/module/decode/p25/message/tsbk/GroupMultiChannelGrant.java index 90446323..8c2bf284 100644 --- a/src/module/decode/p25/message/tsbk/GroupMultiChannelGrant.java +++ b/src/module/decode/p25/message/tsbk/GroupMultiChannelGrant.java @@ -1,106 +1,116 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tsbk; +import alias.AliasList; +import bits.BinaryMessage; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.reference.DataUnitID; -import alias.AliasList; -import bits.BinaryMessage; -public abstract class GroupMultiChannelGrant extends ChannelGrant - implements IdentifierReceiver +public abstract class GroupMultiChannelGrant extends ChannelGrant implements IdentifierReceiver { - public static final int[] CHANNEL_IDENTIFIER_1 = { 80,81,82,83 }; - public static final int[] CHANNEL_NUMBER_1 = { 84,85,86,87, - 88,89,90,91,92,93,94,95 }; - public static final int[] GROUP_ADDRESS_1 = { 96,97,98,99,100,101,102,103, - 104,105,106,107,108,109,110,111 }; - - public static final int[] CHANNEL_IDENTIFIER_2 = { 112,113,114,115 }; - public static final int[] CHANNEL_NUMBER_2 = { 116,117,118,119,120,121,122, - 123,124,125,126,127 }; - public static final int[] GROUP_ADDRESS_2 = { 128,129,130,131,132,133,134, - 135,136,137,138,139,140,141,142,143 }; - + public static final int[] CHANNEL_IDENTIFIER_1 = {80, 81, 82, 83}; + public static final int[] CHANNEL_NUMBER_1 = {84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95}; + public static final int[] GROUP_ADDRESS_1 = {96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111}; + public static final int[] CHANNEL_IDENTIFIER_2 = {112, 113, 114, 115}; + public static final int[] CHANNEL_NUMBER_2 = {116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127}; + public static final int[] GROUP_ADDRESS_2 = {128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143}; + private IBandIdentifier mIdentifierUpdate1; private IBandIdentifier mIdentifierUpdate2; - public GroupMultiChannelGrant( BinaryMessage message, - DataUnitID duid, - AliasList aliasList ) + public GroupMultiChannelGrant(BinaryMessage message, DataUnitID duid, AliasList aliasList) { - super( message, duid, aliasList ); + super(message, duid, aliasList); } public String getMessage() { StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " CHAN1:" ); - sb.append( getChannelIdentifier1() + "/" + getChannelNumber1() ); - - sb.append( " GRP1:" ); - sb.append( getGroupAddress1() ); - - if( hasChannelNumber2() ) + + sb.append(getMessageStub()); + + sb.append(" CHAN1:"); + sb.append(getChannelIdentifier1() + "/" + getChannelNumber1()); + + sb.append(" GRP1:"); + sb.append(getGroupAddress1()); + + if(hasChannelNumber2()) { - sb.append( " CHAN2:" ); - sb.append( getChannelIdentifier2() + "/" + getChannelNumber2() ); - - sb.append( " GRP2:" ); - sb.append( getGroupAddress2() ); + sb.append(" CHAN2:"); + sb.append(getChannelIdentifier2() + "/" + getChannelNumber2()); + + sb.append(" GRP2:"); + sb.append(getGroupAddress2()); } - + return sb.toString(); } - + public int getChannelIdentifier1() { - return mMessage.getInt( CHANNEL_IDENTIFIER_1 ); + return mMessage.getInt(CHANNEL_IDENTIFIER_1); } - + public int getChannelNumber1() { - return mMessage.getInt( CHANNEL_NUMBER_1 ); + return mMessage.getInt(CHANNEL_NUMBER_1); } - + public String getChannel1() { - return getChannelIdentifier1() + "-" + getChannelNumber1(); + return getChannelIdentifier1() + "-" + getChannelNumber1(); } - + public String getGroupAddress1() { - return mMessage.getHex( GROUP_ADDRESS_1, 4 ); + return mMessage.getHex(GROUP_ADDRESS_1, 4); } - + public int getChannelIdentifier2() { - return mMessage.getInt( CHANNEL_IDENTIFIER_2 ); + return mMessage.getInt(CHANNEL_IDENTIFIER_2); } - + public int getChannelNumber2() { - return mMessage.getInt( CHANNEL_NUMBER_2 ); + return mMessage.getInt(CHANNEL_NUMBER_2); } - + public String getChannel2() { - return getChannelIdentifier2() + "-" + getChannelNumber2(); + return getChannelIdentifier2() + "-" + getChannelNumber2(); } - + public String getGroupAddress2() { - return mMessage.getHex( GROUP_ADDRESS_2, 4 ); + return mMessage.getHex(GROUP_ADDRESS_2, 4); } - + public boolean hasChannelNumber2() { - return mMessage.getInt( CHANNEL_NUMBER_2 ) != - mMessage.getInt( CHANNEL_NUMBER_1 ); + return mMessage.getInt(CHANNEL_NUMBER_2) != + mMessage.getInt(CHANNEL_NUMBER_1); } - + @Override public String getFromID() { @@ -112,59 +122,99 @@ public abstract class GroupMultiChannelGrant extends ChannelGrant { return getGroupAddress2(); } - - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) - { - if( identifier == getChannelIdentifier1() ) - { - mIdentifierUpdate1 = message; - } - if( hasChannelNumber2() && identifier == getChannelIdentifier2() ) - { - mIdentifierUpdate2 = message; - } + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getChannelIdentifier1()) + { + mIdentifierUpdate1 = message; + } + + if(hasChannelNumber2() && identifier == getChannelIdentifier2()) + { + mIdentifierUpdate2 = message; + } } - @Override + @Override public int[] getIdentifiers() { - int[] identifiers; - - if( hasChannelNumber2() ) - { - identifiers = new int[ 2 ]; - identifiers[ 0 ] = getChannelIdentifier1(); - identifiers[ 1 ] = getChannelIdentifier2(); - } - else - { - identifiers = new int[ 1 ]; - identifiers[ 0 ] = getChannelIdentifier1(); - } - - return identifiers; + int[] identifiers; + + if(hasChannelNumber2()) + { + identifiers = new int[2]; + identifiers[0] = getChannelIdentifier1(); + identifiers[1] = getChannelIdentifier2(); + } + else + { + identifiers = new int[1]; + identifiers[0] = getChannelIdentifier1(); + } + + return identifiers; } - + public long getDownlinkFrequency1() { - return calculateDownlink( mIdentifierUpdate1, getChannelNumber1() ); + if(mIdentifierUpdate1 != null) + { + return mIdentifierUpdate1.getDownlinkFrequency(getChannelNumber1()); + } + + return 0; } - + + public boolean isTDMAChannel1() + { + if(mIdentifierUpdate1 != null) + { + return mIdentifierUpdate1.isTDMA(); + } + + return false; + } + public long getUplinkFrequency1() { - return calculateUplink( mIdentifierUpdate1, getChannelNumber1() ); + if(mIdentifierUpdate1 != null) + { + return mIdentifierUpdate1.getUplinkFrequency(getChannelNumber1()); + } + + return 0; } - + public long getDownlinkFrequency2() { - return calculateDownlink( mIdentifierUpdate2, getChannelNumber2() ); + if(mIdentifierUpdate2 != null) + { + return mIdentifierUpdate2.getDownlinkFrequency(getChannelNumber2()); + } + + return 0; } - + + public boolean isTDMAChannel2() + { + if(mIdentifierUpdate2 != null) + { + return mIdentifierUpdate2.isTDMA(); + } + + return false; + } + public long getUplinkFrequency2() { - return calculateUplink( mIdentifierUpdate2, getChannelNumber2() ); + if(mIdentifierUpdate2 != null) + { + return mIdentifierUpdate2.getUplinkFrequency(getChannelNumber2()); + } + + return 0; } - + } diff --git a/src/module/decode/p25/message/tsbk/UnitChannelGrant.java b/src/module/decode/p25/message/tsbk/UnitChannelGrant.java index 5d49f4b7..90e8b476 100644 --- a/src/module/decode/p25/message/tsbk/UnitChannelGrant.java +++ b/src/module/decode/p25/message/tsbk/UnitChannelGrant.java @@ -1,55 +1,70 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tsbk; -import module.decode.p25.reference.DataUnitID; import alias.Alias; import alias.AliasList; import bits.BinaryMessage; +import module.decode.p25.reference.DataUnitID; public abstract class UnitChannelGrant extends ChannelGrant { - public static final int[] TARGET_ADDRESS = { 96,97,98,99,100,101,102,103, - 104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119 }; - - public static final int[] SOURCE_ADDRESS = { 120,121,122,123,124,125,126, - 127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143 }; - - public UnitChannelGrant( BinaryMessage message, - DataUnitID duid, - AliasList aliasList ) + public static final int[] TARGET_ADDRESS = {96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119}; + public static final int[] SOURCE_ADDRESS = {120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, 140, 141, 142, 143}; + + public UnitChannelGrant(BinaryMessage message, DataUnitID duid, AliasList aliasList) { - super( message, duid, aliasList ); + super(message, duid, aliasList); } public String getMessage() { StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - if( isEmergency() ) + + sb.append(getMessageStub()); + + if(isEmergency()) { - sb.append( " EMERGENCY" ); + sb.append(" EMERGENCY"); } - - sb.append( " FROM:" ); - sb.append( getSourceAddress() ); - - sb.append( " TO:" ); - sb.append( getTargetAddress() ); - + + sb.append(" FROM:"); + sb.append(getSourceAddress()); + + sb.append(" TO:"); + sb.append(getTargetAddress()); + return sb.toString(); } - + public String getTargetAddress() { - return mMessage.getHex( TARGET_ADDRESS, 6 ); + return mMessage.getHex(TARGET_ADDRESS, 6); } - + public String getSourceAddress() { - return mMessage.getHex( SOURCE_ADDRESS, 6 ); + return mMessage.getHex(SOURCE_ADDRESS, 6); } - + @Override public String getFromID() { @@ -59,11 +74,11 @@ public abstract class UnitChannelGrant extends ChannelGrant @Override public Alias getFromIDAlias() { - if( mAliasList != null ) + if(mAliasList != null) { - return mAliasList.getTalkgroupAlias( getFromID() ); + return mAliasList.getTalkgroupAlias(getFromID()); } - + return null; } diff --git a/src/module/decode/p25/message/tsbk/motorola/ControlChannelBaseStationIdentification.java b/src/module/decode/p25/message/tsbk/motorola/ControlChannelBaseStationIdentification.java index 987d84ad..be11983f 100644 --- a/src/module/decode/p25/message/tsbk/motorola/ControlChannelBaseStationIdentification.java +++ b/src/module/decode/p25/message/tsbk/motorola/ControlChannelBaseStationIdentification.java @@ -1,34 +1,48 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tsbk.motorola; +import alias.AliasList; +import bits.BinaryMessage; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.reference.DataUnitID; -import alias.AliasList; -import bits.BinaryMessage; -public class ControlChannelBaseStationIdentification extends MotorolaTSBKMessage - implements IdentifierReceiver +public class ControlChannelBaseStationIdentification extends MotorolaTSBKMessage implements IdentifierReceiver { - public static final int[] CHARACTER_1 = { 80,81,82,83,84,85 }; - public static final int[] CHARACTER_2 = { 86,87,88,89,90,91 }; - public static final int[] CHARACTER_3 = { 92,93,94,95,96,97 }; - public static final int[] CHARACTER_4 = { 98,99,100,101,102,103 }; - public static final int[] CHARACTER_5 = { 104,105,106,107,108,109 }; - public static final int[] CHARACTER_6 = { 110,111,112,113,114,115 }; - public static final int[] CHARACTER_7 = { 116,117,118,119,120,121 }; - public static final int[] CHARACTER_8 = { 122,123,124,125,126,127 }; - - public static final int[] IDENTIFIER = { 128,129,130,131 }; - public static final int[] CHANNEL = { 132,133,134,135,136,137,138,139,140, - 141,142,143 }; - + public static final int[] CHARACTER_1 = {80, 81, 82, 83, 84, 85}; + public static final int[] CHARACTER_2 = {86, 87, 88, 89, 90, 91}; + public static final int[] CHARACTER_3 = {92, 93, 94, 95, 96, 97}; + public static final int[] CHARACTER_4 = {98, 99, 100, 101, 102, 103}; + public static final int[] CHARACTER_5 = {104, 105, 106, 107, 108, 109}; + public static final int[] CHARACTER_6 = {110, 111, 112, 113, 114, 115}; + public static final int[] CHARACTER_7 = {116, 117, 118, 119, 120, 121}; + public static final int[] CHARACTER_8 = {122, 123, 124, 125, 126, 127}; + + public static final int[] IDENTIFIER = {128, 129, 130, 131}; + public static final int[] CHANNEL = {132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143}; + private IBandIdentifier mIdentifierUpdate; - - public ControlChannelBaseStationIdentification( BinaryMessage message, - DataUnitID duid, - AliasList aliasList ) + + public ControlChannelBaseStationIdentification(BinaryMessage message, DataUnitID duid, AliasList aliasList) { - super( message, duid, aliasList ); + super(message, duid, aliasList); } @Override @@ -36,86 +50,96 @@ public class ControlChannelBaseStationIdentification extends MotorolaTSBKMessage { return MotorolaOpcode.CONTROL_CHANNEL_ID.getDescription(); } - + public String getMessage() { StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - sb.append( " CHAN:" + getIdentifier() + "-" + getChannel() ); - - sb.append( " CWID:" + getCWID() ); - - sb.append( " DN:" + getDownlinkFrequency() ); - - sb.append( " UP:" + getUplinkFrequency() ); - + sb.append(getMessageStub()); + + sb.append(" CHAN:" + getIdentifier() + "-" + getChannel()); + + sb.append(" CWID:" + getCWID()); + + sb.append(" DN:" + getDownlinkFrequency()); + + sb.append(" UP:" + getUplinkFrequency()); + return sb.toString(); } - - + + public String getCWID() { - StringBuilder sb = new StringBuilder(); + StringBuilder sb = new StringBuilder(); - sb.append( getCharacter( CHARACTER_1 ) ); - sb.append( getCharacter( CHARACTER_2 ) ); - sb.append( getCharacter( CHARACTER_3 ) ); - sb.append( getCharacter( CHARACTER_4 ) ); - sb.append( getCharacter( CHARACTER_5 ) ); - sb.append( getCharacter( CHARACTER_6 ) ); - sb.append( getCharacter( CHARACTER_7 ) ); - sb.append( getCharacter( CHARACTER_8 ) ); - - return sb.toString(); + sb.append(getCharacter(CHARACTER_1)); + sb.append(getCharacter(CHARACTER_2)); + sb.append(getCharacter(CHARACTER_3)); + sb.append(getCharacter(CHARACTER_4)); + sb.append(getCharacter(CHARACTER_5)); + sb.append(getCharacter(CHARACTER_6)); + sb.append(getCharacter(CHARACTER_7)); + sb.append(getCharacter(CHARACTER_8)); + + return sb.toString(); } - - private String getCharacter( int[] field ) + + private String getCharacter(int[] field) { - int value = mMessage.getInt( field ); - - if( value != 0 ) - { - return String.valueOf( (char)( value + 43 ) ); - } - - return null; + int value = mMessage.getInt(field); + + if(value != 0) + { + return String.valueOf((char)(value + 43)); + } + + return null; } - + public int getIdentifier() { - return mMessage.getInt( IDENTIFIER ); + return mMessage.getInt(IDENTIFIER); } - + public int getChannel() { - return mMessage.getInt( CHANNEL ); + return mMessage.getInt(CHANNEL); } - + public long getUplinkFrequency() { - return calculateUplink( mIdentifierUpdate, getChannel() ); + if(mIdentifierUpdate != null) + { + mIdentifierUpdate.getUplinkFrequency(getChannel()); + } + + return 0; } - + public long getDownlinkFrequency() { - return calculateDownlink( mIdentifierUpdate, getChannel() ); + if(mIdentifierUpdate != null) + { + mIdentifierUpdate.getDownlinkFrequency(getChannel()); + } + + return 0; } - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) { - mIdentifierUpdate = message; + mIdentifierUpdate = message; } - @Override + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 1 ]; - - identifiers[ 0 ] = getIdentifier(); - - return identifiers; + int[] identifiers = new int[1]; + + identifiers[0] = getIdentifier(); + + return identifiers; } } diff --git a/src/module/decode/p25/message/tsbk/motorola/PatchGroupVoiceChannelGrant.java b/src/module/decode/p25/message/tsbk/motorola/PatchGroupVoiceChannelGrant.java index d760b2c9..54ab32c3 100644 --- a/src/module/decode/p25/message/tsbk/motorola/PatchGroupVoiceChannelGrant.java +++ b/src/module/decode/p25/message/tsbk/motorola/PatchGroupVoiceChannelGrant.java @@ -1,151 +1,187 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tsbk.motorola; +import alias.AliasList; +import bits.BinaryMessage; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.reference.DataUnitID; -import alias.AliasList; -import bits.BinaryMessage; -public class PatchGroupVoiceChannelGrant extends MotorolaTSBKMessage - implements IdentifierReceiver +public class PatchGroupVoiceChannelGrant extends MotorolaTSBKMessage implements IdentifierReceiver { /* Service Options */ public static final int EMERGENCY_FLAG = 80; public static final int ENCRYPTED_CHANNEL_FLAG = 81; public static final int DUPLEX_MODE = 82; public static final int SESSION_MODE = 83; - - public static final int[] PRIORITY = { 85,86,87 }; - public static final int[] IDENTIFIER = { 88,89,90,91 }; - public static final int[] CHANNEL = { 92,93,94,95,96,97,98,99,100,101,102,103 }; - public static final int[] PATCH_GROUP_ADDRESS = { 104,105,106,107,108,109, - 110,111,112,113,114,115,116,117,118,119 }; - public static final int[] SOURCE_ADDRESS = { 120,121,122,123,124,125,126, - 127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143 }; + + public static final int[] PRIORITY = {85, 86, 87}; + public static final int[] IDENTIFIER = {88, 89, 90, 91}; + public static final int[] CHANNEL = {92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103}; + public static final int[] PATCH_GROUP_ADDRESS = {104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119}; + public static final int[] SOURCE_ADDRESS = {120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, 140, 141, 142, 143}; private IBandIdentifier mIdentifierUpdate; - public PatchGroupVoiceChannelGrant( BinaryMessage message, DataUnitID duid, - AliasList aliasList ) + public PatchGroupVoiceChannelGrant(BinaryMessage message, DataUnitID duid, AliasList aliasList) { - super( message, duid, aliasList ); + super(message, duid, aliasList); } - @Override + public boolean isTDMAChannel() + { + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.isTDMA(); + } + + return false; + } + + @Override public String getEventType() { - return MotorolaOpcode.PATCH_GROUP_CHANNEL_GRANT.getLabel(); + return MotorolaOpcode.PATCH_GROUP_CHANNEL_GRANT.getLabel(); } - @Override + @Override public String getMessage() { - StringBuilder sb = new StringBuilder(); + StringBuilder sb = new StringBuilder(); - sb.append( getMessageStub() ); + sb.append(getMessageStub()); - if( isEmergency() ) - { - sb.append( " EMERGENCY" ); - } - - sb.append( " PATCH GROUP:" ); - sb.append( getPatchGroupAddress() ); - sb.append( " FROM:" ); - sb.append( getSourceAddress() ); - sb.append( " PRI:" ); - sb.append( getPriority() ); + if(isEmergency()) + { + sb.append(" EMERGENCY"); + } - sb.append( " CHAN:" ); - sb.append( getChannelIdentifier() + "-" + getChannelNumber() ); - - sb.append( " DN:" + getDownlinkFrequency() ); - - sb.append( " UP:" + getUplinkFrequency() ); + sb.append(" PATCH GROUP:"); + sb.append(getPatchGroupAddress()); + sb.append(" FROM:"); + sb.append(getSourceAddress()); + sb.append(" PRI:"); + sb.append(getPriority()); - sb.append( " SESSION MODE:"); - sb.append( getSessionMode().name() ); - - return sb.toString(); + sb.append(" CHAN:"); + sb.append(getChannelIdentifier() + "-" + getChannelNumber()); + + sb.append(" DN:" + getDownlinkFrequency()); + + sb.append(" UP:" + getUplinkFrequency()); + + sb.append(" SESSION MODE:"); + sb.append(getSessionMode().name()); + + return sb.toString(); } - + public String getPatchGroupAddress() { - return mMessage.getHex( PATCH_GROUP_ADDRESS, 4 ); + return mMessage.getHex(PATCH_GROUP_ADDRESS, 4); } - + public String getSourceAddress() { - return mMessage.getHex( SOURCE_ADDRESS, 6 ); + return mMessage.getHex(SOURCE_ADDRESS, 6); } - + public boolean isEmergency() { - return mMessage.get( EMERGENCY_FLAG ); + return mMessage.get(EMERGENCY_FLAG); } - + public boolean isEncryptedChannel() { - return mMessage.get( ENCRYPTED_CHANNEL_FLAG ); + return mMessage.get(ENCRYPTED_CHANNEL_FLAG); } - + public DuplexMode getDuplexMode() { - return mMessage.get( DUPLEX_MODE ) ? DuplexMode.FULL : DuplexMode.HALF; + return mMessage.get(DUPLEX_MODE) ? DuplexMode.FULL : DuplexMode.HALF; } public SessionMode getSessionMode() { - return mMessage.get( SESSION_MODE ) ? - SessionMode.CIRCUIT : SessionMode.PACKET; + return mMessage.get(SESSION_MODE) ? + SessionMode.CIRCUIT : SessionMode.PACKET; } - + /** * 1 = Lowest, 4 = Default, 7 = Highest */ public int getPriority() { - return mMessage.getInt( PRIORITY ); + return mMessage.getInt(PRIORITY); } - + public int getChannelIdentifier() { - return mMessage.getInt( IDENTIFIER ); + return mMessage.getInt(IDENTIFIER); } - + public int getChannelNumber() { - return mMessage.getInt( CHANNEL ); + return mMessage.getInt(CHANNEL); } public String getChannel() { - return getChannelIdentifier() + "-" + getChannelNumber(); + return getChannelIdentifier() + "-" + getChannelNumber(); } - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) { - mIdentifierUpdate = message; + mIdentifierUpdate = message; } - @Override + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 1 ]; - identifiers[ 0 ] = getChannelIdentifier(); - - return identifiers; + int[] identifiers = new int[1]; + identifiers[0] = getChannelIdentifier(); + + return identifiers; } - + public long getDownlinkFrequency() { - return calculateDownlink( mIdentifierUpdate, getChannelNumber() ); + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.getDownlinkFrequency(getChannelNumber()); + } + + return 0; } - + public long getUplinkFrequency() { - return calculateUplink( mIdentifierUpdate, getChannelNumber() ); + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.getUplinkFrequency(getChannelNumber()); + } + + return 0; } - + } diff --git a/src/module/decode/p25/message/tsbk/motorola/PatchGroupVoiceChannelGrantUpdate.java b/src/module/decode/p25/message/tsbk/motorola/PatchGroupVoiceChannelGrantUpdate.java index 0788c2ab..e1ee6556 100644 --- a/src/module/decode/p25/message/tsbk/motorola/PatchGroupVoiceChannelGrantUpdate.java +++ b/src/module/decode/p25/message/tsbk/motorola/PatchGroupVoiceChannelGrantUpdate.java @@ -1,146 +1,197 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tsbk.motorola; +import alias.AliasList; +import bits.BinaryMessage; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.reference.DataUnitID; -import alias.AliasList; -import bits.BinaryMessage; -public class PatchGroupVoiceChannelGrantUpdate extends MotorolaTSBKMessage - implements IdentifierReceiver +public class PatchGroupVoiceChannelGrantUpdate extends MotorolaTSBKMessage implements IdentifierReceiver { - public static final int[] IDENTIFIER_1 = { 80,81,82,83 }; - public static final int[] CHANNEL_1 = { 84,85,86,87,88,89,90,91,92,93,94, - 95 }; - public static final int[] PATCH_GROUP_ADDRESS_1 = { 96,97,98,99,100,101,102, - 103,104,105,106,107,108,109,110,111 }; - public static final int[] IDENTIFIER_2 = { 112,113,114,115 }; - public static final int[] CHANNEL_2 = { 116,117,118,119,120,121,122,123, - 124,125,126,127 }; - public static final int[] PATCH_GROUP_ADDRESS_2 = { 128,129,130,131,132,133, - 134,135,136,137,138,139,140,141,142,143 }; + public static final int[] IDENTIFIER_1 = {80, 81, 82, 83}; + public static final int[] CHANNEL_1 = {84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95}; + public static final int[] PATCH_GROUP_ADDRESS_1 = {96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111}; + public static final int[] IDENTIFIER_2 = {112, 113, 114, 115}; + public static final int[] CHANNEL_2 = {116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127}; + public static final int[] PATCH_GROUP_ADDRESS_2 = {128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143}; private IBandIdentifier mIdentifierUpdate1; private IBandIdentifier mIdentifierUpdate2; - public PatchGroupVoiceChannelGrantUpdate( BinaryMessage message, - DataUnitID duid, AliasList aliasList ) + public PatchGroupVoiceChannelGrantUpdate(BinaryMessage message, DataUnitID duid, AliasList aliasList) { - super( message, duid, aliasList ); + super(message, duid, aliasList); } - @Override + @Override public String getEventType() { - return MotorolaOpcode.PATCH_GROUP_CHANNEL_GRANT_UPDATE.getLabel(); + return MotorolaOpcode.PATCH_GROUP_CHANNEL_GRANT_UPDATE.getLabel(); } - @Override + @Override public String getMessage() { - StringBuilder sb = new StringBuilder(); + StringBuilder sb = new StringBuilder(); - sb.append( getMessageStub() ); + sb.append(getMessageStub()); - - sb.append( " PATCH GRP1:" ); - sb.append( getPatchGroupAddress1() ); - sb.append( " GRP2:" ); - sb.append( getPatchGroupAddress2() ); - sb.append( " CHAN 1:" ); - sb.append( getChannel1() ); - sb.append( " DN:" + getDownlinkFrequency1() ); - - sb.append( " CHAN 2:" ); - sb.append( getChannel2() ); - sb.append( " DN:" + getDownlinkFrequency2() ); - - return sb.toString(); + sb.append(" PATCH GRP1:"); + sb.append(getPatchGroupAddress1()); + sb.append(" GRP2:"); + sb.append(getPatchGroupAddress2()); + + sb.append(" CHAN 1:"); + sb.append(getChannel1()); + sb.append(" DN:" + getDownlinkFrequency1()); + + sb.append(" CHAN 2:"); + sb.append(getChannel2()); + sb.append(" DN:" + getDownlinkFrequency2()); + + return sb.toString(); } - + public String getPatchGroupAddress1() { - return mMessage.getHex( PATCH_GROUP_ADDRESS_1, 4 ); + return mMessage.getHex(PATCH_GROUP_ADDRESS_1, 4); } - + public String getPatchGroupAddress2() { - return mMessage.getHex( PATCH_GROUP_ADDRESS_2, 4 ); + return mMessage.getHex(PATCH_GROUP_ADDRESS_2, 4); } - + public int getChannelIdentifier1() { - return mMessage.getInt( IDENTIFIER_1 ); + return mMessage.getInt(IDENTIFIER_1); } - + public int getChannelNumber1() { - return mMessage.getInt( CHANNEL_1 ); + return mMessage.getInt(CHANNEL_1); } public String getChannel1() { - return getChannelIdentifier1() + "-" + getChannelNumber1(); + return getChannelIdentifier1() + "-" + getChannelNumber1(); } public int getChannelIdentifier2() { - return mMessage.getInt( IDENTIFIER_2 ); + return mMessage.getInt(IDENTIFIER_2); } - + public int getChannelNumber2() { - return mMessage.getInt( CHANNEL_2 ); + return mMessage.getInt(CHANNEL_2); } public String getChannel2() { - return getChannelIdentifier2() + "-" + getChannelNumber2(); + return getChannelIdentifier2() + "-" + getChannelNumber2(); } - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) { - if( identifier == getChannelIdentifier1() ) - { - mIdentifierUpdate1 = message; - } - - if( identifier == getChannelIdentifier2() ) - { - mIdentifierUpdate2 = message; - } + if(identifier == getChannelIdentifier1()) + { + mIdentifierUpdate1 = message; + } + + if(identifier == getChannelIdentifier2()) + { + mIdentifierUpdate2 = message; + } } - @Override + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 2 ]; - identifiers[ 0 ] = getChannelIdentifier1(); - identifiers[ 1 ] = getChannelIdentifier2(); - - return identifiers; + int[] identifiers = new int[2]; + identifiers[0] = getChannelIdentifier1(); + identifiers[1] = getChannelIdentifier2(); + + return identifiers; } - + public long getDownlinkFrequency1() { - return calculateDownlink( mIdentifierUpdate1, getChannelNumber1() ); + if(mIdentifierUpdate1 != null) + { + return mIdentifierUpdate1.getDownlinkFrequency(getChannelNumber1()); + } + + return 0; } - + + public boolean isTDMAChannel1() + { + if(mIdentifierUpdate1 != null) + { + return mIdentifierUpdate1.isTDMA(); + } + + return false; + } + public long getUplinkFrequency1() { - return calculateUplink( mIdentifierUpdate1, getChannelNumber1() ); + if(mIdentifierUpdate1 != null) + { + return mIdentifierUpdate1.getUplinkFrequency(getChannelNumber1()); + } + + return 0; } - + public long getDownlinkFrequency2() { - return calculateDownlink( mIdentifierUpdate2, getChannelNumber2() ); + if(mIdentifierUpdate2 != null) + { + return mIdentifierUpdate2.getDownlinkFrequency(getChannelNumber2()); + } + + return 0; } - + + public boolean isTDMAChannel2() + { + if(mIdentifierUpdate2 != null) + { + return mIdentifierUpdate2.isTDMA(); + } + + return false; + } + public long getUplinkFrequency2() { - return calculateUplink( mIdentifierUpdate2, getChannelNumber2() ); + if(mIdentifierUpdate2 != null) + { + return mIdentifierUpdate2.getUplinkFrequency(getChannelNumber2()); + } + + return 0; } - } diff --git a/src/module/decode/p25/message/tsbk/osp/control/AdjacentStatusBroadcast.java b/src/module/decode/p25/message/tsbk/osp/control/AdjacentStatusBroadcast.java index 49744f78..4ff1a876 100644 --- a/src/module/decode/p25/message/tsbk/osp/control/AdjacentStatusBroadcast.java +++ b/src/module/decode/p25/message/tsbk/osp/control/AdjacentStatusBroadcast.java @@ -1,40 +1,51 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tsbk.osp.control; +import alias.AliasList; +import bits.BinaryMessage; import module.decode.p25.message.IAdjacentSite; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.message.tsbk.TSBKMessage; import module.decode.p25.reference.DataUnitID; import module.decode.p25.reference.Opcode; -import alias.AliasList; -import bits.BinaryMessage; -public class AdjacentStatusBroadcast extends TSBKMessage - implements IdentifierReceiver, IAdjacentSite +public class AdjacentStatusBroadcast extends TSBKMessage implements IdentifierReceiver, IAdjacentSite { - public static final int[] LOCATION_REGISTRATION_AREA = { 80,81,82,83,84,85, - 86,87 }; + public static final int[] LOCATION_REGISTRATION_AREA = {80, 81, 82, 83, 84, 85, 86, 87}; public static final int CONVENTIONAL_CHANNEL_FLAG = 88; public static final int SITE_FAILURE_CONDITION_FLAG = 89; public static final int VALID_FLAG = 90; public static final int ACTIVE_NETWORK_CONNECTION_FLAG = 91; - public static final int[] SYSTEM_ID = { 92,93,94,95,96,97,98,99,100,101, - 102,103 }; - public static final int[] RFSS_ID = { 104,105,106,107,108,109,110,111 }; - public static final int[] SITE_ID = { 112,113,114,115,116,117,118,119 }; - public static final int[] IDENTIFIER = { 120,121,122,123 }; - public static final int[] CHANNEL = { 124,125,126,127,128,129,130,131,132, - 133,134,135 }; - public static final int[] SYSTEM_SERVICE_CLASS = { 136,137,138,139,140,141, - 142,143 }; - + public static final int[] SYSTEM_ID = {92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103}; + public static final int[] RFSS_ID = {104, 105, 106, 107, 108, 109, 110, 111}; + public static final int[] SITE_ID = {112, 113, 114, 115, 116, 117, 118, 119}; + public static final int[] IDENTIFIER = {120, 121, 122, 123}; + public static final int[] CHANNEL = {124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135}; + public static final int[] SYSTEM_SERVICE_CLASS = {136, 137, 138, 139, 140, 141, 142, 143}; + private IBandIdentifier mIdentifierUpdate; - - public AdjacentStatusBroadcast( BinaryMessage message, - DataUnitID duid, - AliasList aliasList ) + + public AdjacentStatusBroadcast(BinaryMessage message, DataUnitID duid, AliasList aliasList) { - super( message, duid, aliasList ); + super(message, duid, aliasList); } @Override @@ -42,154 +53,164 @@ public class AdjacentStatusBroadcast extends TSBKMessage { return Opcode.ADJACENT_STATUS_BROADCAST.getDescription(); } - + public String getMessage() { StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " LRA:" + getLRA() ); - sb.append( " SYS:" + getSystemID() ); + sb.append(getMessageStub()); - sb.append( " SITE:" + getRFSS() + "-" + getSiteID() ); - - sb.append( " CHAN:" + getIdentifier() + "-" + getChannel() ); + sb.append(" LRA:" + getLRA()); - sb.append( " DN:" + getDownlinkFrequency() ); + sb.append(" SYS:" + getSystemID()); - sb.append( " UP:" + getUplinkFrequency() ); - - if( isConventionalChannel() ) + sb.append(" SITE:" + getRFSS() + "-" + getSiteID()); + + sb.append(" CHAN:" + getIdentifier() + "-" + getChannel()); + + sb.append(" DN:" + getDownlinkFrequency()); + + sb.append(" UP:" + getUplinkFrequency()); + + if(isConventionalChannel()) { - sb.append( " CONVENTIONAL" ); + sb.append(" CONVENTIONAL"); } - - if( isSiteFailureCondition() ) + + if(isSiteFailureCondition()) { - sb.append( " FAILURE-CONDITION" ); + sb.append(" FAILURE-CONDITION"); } - - if( isValidSiteInformation() ) + + if(isValidSiteInformation()) { - sb.append( " VALID-INFO" ); + sb.append(" VALID-INFO"); } - - if( hasActiveNetworkConnection() ) + + if(hasActiveNetworkConnection()) { - sb.append( " ACTIVE-NETWORK-CONN" ); + sb.append(" ACTIVE-NETWORK-CONN"); } - - sb.append( getSystemServiceClass() ); - + + sb.append(getSystemServiceClass()); + return sb.toString(); } - + @Override - public String getDownlinkChannel() - { - return getIdentifier() + "-" + getChannel(); - } - - @Override - public String getUplinkChannel() - { - return getIdentifier() + "-" + getChannel(); - } - - public String getLRA() + public String getDownlinkChannel() { - return mMessage.getHex( LOCATION_REGISTRATION_AREA, 2 ); + return getIdentifier() + "-" + getChannel(); } - + + @Override + public String getUplinkChannel() + { + return getIdentifier() + "-" + getChannel(); + } + + public String getLRA() + { + return mMessage.getHex(LOCATION_REGISTRATION_AREA, 2); + } + public boolean isConventionalChannel() { - return mMessage.get( CONVENTIONAL_CHANNEL_FLAG ); + return mMessage.get(CONVENTIONAL_CHANNEL_FLAG); } - + public boolean isSiteFailureCondition() { - return mMessage.get( SITE_FAILURE_CONDITION_FLAG ); + return mMessage.get(SITE_FAILURE_CONDITION_FLAG); } - + public boolean isValidSiteInformation() { - return mMessage.get( VALID_FLAG ); + return mMessage.get(VALID_FLAG); } - + public boolean hasActiveNetworkConnection() { - return mMessage.get( ACTIVE_NETWORK_CONNECTION_FLAG ); + return mMessage.get(ACTIVE_NETWORK_CONNECTION_FLAG); } - + public String getUniqueID() { - StringBuilder sb = new StringBuilder(); - - sb.append( getSystemID() ); - sb.append( ":" ); - sb.append( getRFSS() ); - sb.append( ":" ); - sb.append( getSiteID() ); - - return sb.toString(); + StringBuilder sb = new StringBuilder(); + + sb.append(getSystemID()); + sb.append(":"); + sb.append(getRFSS()); + sb.append(":"); + sb.append(getSiteID()); + + return sb.toString(); } - + public String getSystemID() { - return mMessage.getHex( SYSTEM_ID, 3 ); + return mMessage.getHex(SYSTEM_ID, 3); } - + public String getRFSS() { - return mMessage.getHex( RFSS_ID, 2 ); + return mMessage.getHex(RFSS_ID, 2); } - + public String getSiteID() { - return mMessage.getHex( SITE_ID, 2 ); + return mMessage.getHex(SITE_ID, 2); } - + public int getChannel() { - return mMessage.getInt( CHANNEL ); + return mMessage.getInt(CHANNEL); } - + public int getIdentifier() { - return mMessage.getInt( IDENTIFIER ); + return mMessage.getInt(IDENTIFIER); } - + public String getSystemServiceClass() { - return SystemService.toString( mMessage.getInt( SYSTEM_SERVICE_CLASS ) ); + return SystemService.toString(mMessage.getInt(SYSTEM_SERVICE_CLASS)); } - + public long getDownlinkFrequency() { - return calculateDownlink( mIdentifierUpdate, getChannel() ); + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.getDownlinkFrequency(getChannel()); + } + + return 0; } - + public long getUplinkFrequency() { - return calculateUplink( mIdentifierUpdate, getChannel() ); - } - + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.getUplinkFrequency(getChannel()); + } - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) - { - /* we're only expecting 1 identifier, so use whatever is received */ - mIdentifierUpdate = message; + return 0; + } + + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + /* we're only expecting 1 identifier, so use whatever is received */ + mIdentifierUpdate = message; + } + + public int[] getIdentifiers() + { + int[] idens = new int[1]; + + idens[0] = getIdentifier(); + + return idens; } - - public int[] getIdentifiers() - { - int[] idens = new int[ 1 ]; - - idens[ 0 ] = getIdentifier(); - - return idens; - } } diff --git a/src/module/decode/p25/message/tsbk/osp/control/IdentifierUpdate.java b/src/module/decode/p25/message/tsbk/osp/control/IdentifierUpdate.java index 1f3e7e5e..d0b64617 100644 --- a/src/module/decode/p25/message/tsbk/osp/control/IdentifierUpdate.java +++ b/src/module/decode/p25/message/tsbk/osp/control/IdentifierUpdate.java @@ -1,3 +1,21 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tsbk.osp.control; import module.decode.p25.message.IBandIdentifier; @@ -6,8 +24,7 @@ import module.decode.p25.reference.DataUnitID; import alias.AliasList; import bits.BinaryMessage; -public abstract class IdentifierUpdate extends TSBKMessage - implements IBandIdentifier +public abstract class IdentifierUpdate extends TSBKMessage implements IBandIdentifier { public static final int[] IDENTIFIER = { 80,81,82,83 }; @@ -45,4 +62,22 @@ public abstract class IdentifierUpdate extends TSBKMessage @Override public abstract long getTransmitOffset(); + + @Override + public long getDownlinkFrequency(int channelNumber) + { + return getBaseFrequency() + ( channelNumber * getChannelSpacing() ); + } + + @Override + public long getUplinkFrequency(int channelNumber) + { + return getDownlinkFrequency(channelNumber) + getTransmitOffset(); + } + + @Override + public boolean isTDMA() + { + return false; + } } diff --git a/src/module/decode/p25/message/tsbk/osp/control/IdentifierUpdateNonVUHF.java b/src/module/decode/p25/message/tsbk/osp/control/IdentifierUpdateNonVUHF.java index e4719edb..0022f082 100644 --- a/src/module/decode/p25/message/tsbk/osp/control/IdentifierUpdateNonVUHF.java +++ b/src/module/decode/p25/message/tsbk/osp/control/IdentifierUpdateNonVUHF.java @@ -31,17 +31,21 @@ public class IdentifierUpdateNonVUHF extends IdentifierUpdate StringBuilder sb = new StringBuilder(); sb.append( getMessageStub() ); + sb.append(toString()); - sb.append( " IDEN:" + getIdentifier() ); + return sb.toString(); + } + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append( " ID:" + getIdentifier() ); sb.append( " BASE:" + getBaseFrequency() ); - - sb.append( " BW:" + getBandwidth() ); - + sb.append( " BANDWIDTH:" + getBandwidth() ); sb.append( " SPACING:" + getChannelSpacing() ); - sb.append( " OFFSET:" + getTransmitOffset() ); - + return sb.toString(); } diff --git a/src/module/decode/p25/message/tsbk/osp/control/IdentifierUpdateTDMA.java b/src/module/decode/p25/message/tsbk/osp/control/IdentifierUpdateTDMA.java index 4fb02ca0..5a4ab33d 100644 --- a/src/module/decode/p25/message/tsbk/osp/control/IdentifierUpdateTDMA.java +++ b/src/module/decode/p25/message/tsbk/osp/control/IdentifierUpdateTDMA.java @@ -30,18 +30,26 @@ public class IdentifierUpdateTDMA extends IdentifierUpdate StringBuilder sb = new StringBuilder(); sb.append( getMessageStub() ); + sb.append(toString()); - sb.append( " IDEN:" + getIdentifier() ); - sb.append( " BASE:" + getBaseFrequency() ); - sb.append( " BW:" + getBandwidth() ); - sb.append( " SPACING:" + getChannelSpacing() ); - sb.append( " OFFSET:" + getTransmitOffset() ); - sb.append( " TYPE:" + getChannelType().toString() ); - return sb.toString(); } - - public ChannelType getChannelType() + + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append( " ID:" + getIdentifier() ); + sb.append( " BASE:" + getBaseFrequency() ); + sb.append( " BW:" + getBandwidth() ); + sb.append( " SPACING:" + getChannelSpacing() ); + sb.append( " OFFSET:" + getTransmitOffset() ); + sb.append( " TYPE:" + getChannelType().toString() ); + + return sb.toString(); + } + + public ChannelType getChannelType() { return ChannelType.fromValue( mMessage.getInt( CHANNEL_TYPE) ); } @@ -72,7 +80,26 @@ public class IdentifierUpdateTDMA extends IdentifierUpdate return -offset; } } - + + @Override + public long getDownlinkFrequency(int channelNumber) + { + if(isTDMA()) + { + return getBaseFrequency() + ( (channelNumber / getChannelType().getSlotsPerCarrier()) * getChannelSpacing() ); + } + else + { + return super.getDownlinkFrequency(channelNumber); + } + } + + @Override + public boolean isTDMA() + { + return getChannelType().getAccessType() == AccessType.TDMA; + } + public enum ChannelType { TYPE_0( AccessType.FDMA, 12500, 1, Vocoder.HALF_RATE ), @@ -109,7 +136,7 @@ public class IdentifierUpdateTDMA extends IdentifierUpdate } sb.append( mAccessType.name() ); - sb.append( " BW:" + mBandwidth ); + sb.append( " BANDWIDTH:" + mBandwidth ); sb.append( " SLOT/CARRIER:" + mSlotsPerCarrier ); sb.append( " VOCODER:" + mVocoder.name() ); diff --git a/src/module/decode/p25/message/tsbk/osp/control/IdentifierUpdateVUHF.java b/src/module/decode/p25/message/tsbk/osp/control/IdentifierUpdateVUHF.java index 3dffa8cd..fb7c7098 100644 --- a/src/module/decode/p25/message/tsbk/osp/control/IdentifierUpdateVUHF.java +++ b/src/module/decode/p25/message/tsbk/osp/control/IdentifierUpdateVUHF.java @@ -32,17 +32,21 @@ public class IdentifierUpdateVUHF extends IdentifierUpdate StringBuilder sb = new StringBuilder(); sb.append( getMessageStub() ); + sb.append(toString()); - sb.append( " IDEN:" + getIdentifier() ); + return sb.toString(); + } + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append( " ID:" + getIdentifier() ); sb.append( " BASE:" + getBaseFrequency() ); - - sb.append( " BW:" + getBandwidth() ); - + sb.append( " BANDWIDTH:" + getBandwidth() ); sb.append( " SPACING:" + getChannelSpacing() ); - sb.append( " OFFSET:" + getTransmitOffset() ); - + return sb.toString(); } diff --git a/src/module/decode/p25/message/tsbk/osp/control/NetworkStatusBroadcast.java b/src/module/decode/p25/message/tsbk/osp/control/NetworkStatusBroadcast.java index 9acd5b99..a911693e 100644 --- a/src/module/decode/p25/message/tsbk/osp/control/NetworkStatusBroadcast.java +++ b/src/module/decode/p25/message/tsbk/osp/control/NetworkStatusBroadcast.java @@ -1,35 +1,46 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tsbk.osp.control; +import alias.AliasList; +import bits.BinaryMessage; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.message.tsbk.TSBKMessage; import module.decode.p25.reference.DataUnitID; import module.decode.p25.reference.Opcode; import module.decode.p25.reference.P25NetworkCallsign; -import alias.AliasList; -import bits.BinaryMessage; public class NetworkStatusBroadcast extends TSBKMessage implements IdentifierReceiver { - public static final int[] LOCATION_REGISTRATION_AREA = { 80,81,82,83,84,85, - 86,87 }; - public static final int[] WACN = { 88,89,90,91,92,93,94,95,96,97,98,99,100, - 101,102,103,104,105,106,107 }; - public static final int[] SYSTEM_ID = { 108,109,110,111,112,113,114,115,116, - 117,118,119 }; - public static final int[] IDENTIFIER = { 120,121,122,123 }; - public static final int[] CHANNEL = { 124,125,126,127,128,129,130,131,132, - 133,134,135 }; - public static final int[] SYSTEM_SERVICE_CLASS = { 136,137,138,139,140,141, - 142,143 }; - + public static final int[] LOCATION_REGISTRATION_AREA = {80, 81, 82, 83, 84, 85, 86, 87}; + public static final int[] WACN = {88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107}; + public static final int[] SYSTEM_ID = {108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119}; + public static final int[] IDENTIFIER = {120, 121, 122, 123}; + public static final int[] CHANNEL = {124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135}; + public static final int[] SYSTEM_SERVICE_CLASS = {136, 137, 138, 139, 140, 141, 142, 143}; + private IBandIdentifier mIdentifierUpdate; - - public NetworkStatusBroadcast( BinaryMessage message, - DataUnitID duid, - AliasList aliasList ) + + public NetworkStatusBroadcast(BinaryMessage message, DataUnitID duid, AliasList aliasList) { - super( message, duid, aliasList ); + super(message, duid, aliasList); } @Override @@ -37,90 +48,100 @@ public class NetworkStatusBroadcast extends TSBKMessage implements IdentifierRec { return Opcode.NETWORK_STATUS_BROADCAST.getDescription(); } - + public String getMessage() { StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - sb.append( " LRA:" + getLocationRegistrationArea() ); - - sb.append( " WACN:" + getWACN() ); - - sb.append( " SYS:" + getSystemID() ); - - sb.append( " CTRL CHAN:" + getIdentifier() + "-" + getChannel() ); - - sb.append( " DN:" + getDownlinkFrequency() ); - - sb.append( " UP:" + getUplinkFrequency() ); - - sb.append( " SYS SVC CLASS:" + - SystemService.toString( getSystemServiceClass() ) ); - + sb.append(getMessageStub()); + + sb.append(" LRA:" + getLocationRegistrationArea()); + + sb.append(" WACN:" + getWACN()); + + sb.append(" SYS:" + getSystemID()); + + sb.append(" CTRL CHAN:" + getIdentifier() + "-" + getChannel()); + + sb.append(" DN:" + getDownlinkFrequency()); + + sb.append(" UP:" + getUplinkFrequency()); + + sb.append(" SYS SVC CLASS:" + + SystemService.toString(getSystemServiceClass())); + return sb.toString(); } - + public String getLocationRegistrationArea() { - return mMessage.getHex( LOCATION_REGISTRATION_AREA, 2 ); + return mMessage.getHex(LOCATION_REGISTRATION_AREA, 2); } public String getWACN() { - return mMessage.getHex( WACN, 5 ); - } - - public String getSystemID() - { - return mMessage.getHex( SYSTEM_ID, 3 ); + return mMessage.getHex(WACN, 5); + } + + public String getSystemID() + { + return mMessage.getHex(SYSTEM_ID, 3); + } + + public String getNetworkCallsign() + { + return P25NetworkCallsign.getCallsign(mMessage.getInt(WACN), + mMessage.getInt(SYSTEM_ID)); } - public String getNetworkCallsign() - { - return P25NetworkCallsign.getCallsign( mMessage.getInt( WACN ), - mMessage.getInt( SYSTEM_ID ) ); - } - public int getIdentifier() { - return mMessage.getInt( IDENTIFIER ); + return mMessage.getInt(IDENTIFIER); } - + public int getChannel() { - return mMessage.getInt( CHANNEL ); + return mMessage.getInt(CHANNEL); } public int getSystemServiceClass() { - return mMessage.getInt( SYSTEM_SERVICE_CLASS ); + return mMessage.getInt(SYSTEM_SERVICE_CLASS); } public long getDownlinkFrequency() { - return calculateDownlink( mIdentifierUpdate, getChannel() ); - } - - public long getUplinkFrequency() - { - return calculateUplink( mIdentifierUpdate, getChannel() ); + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.getDownlinkFrequency(getChannel()); + } + + return 0; } - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + public long getUplinkFrequency() { - /* we're only expecting 1 identifier, so use whatever is received */ - mIdentifierUpdate = message; + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.getUplinkFrequency(getChannel()); + } + + return 0; + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + /* we're only expecting 1 identifier, so use whatever is received */ + mIdentifierUpdate = message; + } + + public int[] getIdentifiers() + { + int[] idens = new int[1]; + + idens[0] = getIdentifier(); + + return idens; } - - public int[] getIdentifiers() - { - int[] idens = new int[ 1 ]; - - idens[ 0 ] = getIdentifier(); - - return idens; - } } diff --git a/src/module/decode/p25/message/tsbk/osp/control/RFSSStatusBroadcast.java b/src/module/decode/p25/message/tsbk/osp/control/RFSSStatusBroadcast.java index b1f95c7a..8e5ed2d3 100644 --- a/src/module/decode/p25/message/tsbk/osp/control/RFSSStatusBroadcast.java +++ b/src/module/decode/p25/message/tsbk/osp/control/RFSSStatusBroadcast.java @@ -1,35 +1,47 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tsbk.osp.control; +import alias.AliasList; +import bits.BinaryMessage; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.message.tsbk.TSBKMessage; import module.decode.p25.reference.DataUnitID; import module.decode.p25.reference.Opcode; -import alias.AliasList; -import bits.BinaryMessage; public class RFSSStatusBroadcast extends TSBKMessage implements IdentifierReceiver { - public static final int[] LOCATION_REGISTRATION_AREA = { 80,81,82,83,84,85, - 86,87 }; + public static final int[] LOCATION_REGISTRATION_AREA = {80, 81, 82, 83, 84, 85, 86, 87}; public static final int ACTIVE_NETWORK_CONNECTION_FLAG = 91; - public static final int[] SYSTEM_ID = { 92,93,94,95,96,97,98,99,100,101, - 102,103 }; - public static final int[] RFSS_ID = { 104,105,106,107,108,109,110,111 }; - public static final int[] SITE_ID = { 112,113,114,115,116,117,118,119 }; - public static final int[] IDENTIFIER = { 120,121,122,123 }; - public static final int[] CHANNEL = { 124,125,126,127,128,129,130,131,132, - 133,134,135 }; - public static final int[] SYSTEM_SERVICE_CLASS = { 136,137,138,139,140,141, - 142,143 }; - + public static final int[] SYSTEM_ID = {92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103}; + public static final int[] RFSS_ID = {104, 105, 106, 107, 108, 109, 110, 111}; + public static final int[] SITE_ID = {112, 113, 114, 115, 116, 117, 118, 119}; + public static final int[] IDENTIFIER = {120, 121, 122, 123}; + public static final int[] CHANNEL = {124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135}; + public static final int[] SYSTEM_SERVICE_CLASS = {136, 137, 138, 139, 140, 141, 142, 143}; + private IBandIdentifier mIdentifierUpdate; - - public RFSSStatusBroadcast( BinaryMessage message, - DataUnitID duid, - AliasList aliasList ) + + public RFSSStatusBroadcast(BinaryMessage message, DataUnitID duid, AliasList aliasList) { - super( message, duid, aliasList ); + super(message, duid, aliasList); } @Override @@ -37,100 +49,110 @@ public class RFSSStatusBroadcast extends TSBKMessage implements IdentifierReceiv { return Opcode.RFSS_STATUS_BROADCAST.getDescription(); } - + public String getMessage() { StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " LRA:" + getLocationRegistrationArea() ); - sb.append( " SYSID:" + getSystemID() ); + sb.append(getMessageStub()); - sb.append( " RFSS:" + getRFSubsystemID() ); - - sb.append( " SITE:" + getSiteID() ); - - sb.append( " CHAN:" + getIdentifier() + "-" + getChannel() ); - - sb.append( " DN:" + getDownlinkFrequency() ); - - sb.append( " UP:" + getUplinkFrequency() ); + sb.append(" LRA:" + getLocationRegistrationArea()); - if( hasActiveNetworkConnection() ) + sb.append(" SYSID:" + getSystemID()); + + sb.append(" RFSS:" + getRFSubsystemID()); + + sb.append(" SITE:" + getSiteID()); + + sb.append(" CHAN:" + getIdentifier() + "-" + getChannel()); + + sb.append(" DN:" + getDownlinkFrequency()); + + sb.append(" UP:" + getUplinkFrequency()); + + if(hasActiveNetworkConnection()) { - sb.append( " ACTIVE-NETWORK-CONN" ); + sb.append(" ACTIVE-NETWORK-CONN"); } - - sb.append( SystemService.toString( getSystemServiceClass() ) ); - + + sb.append(SystemService.toString(getSystemServiceClass())); + return sb.toString(); } - + public String getLocationRegistrationArea() { - return mMessage.getHex( LOCATION_REGISTRATION_AREA, 2 ); + return mMessage.getHex(LOCATION_REGISTRATION_AREA, 2); } - + public boolean hasActiveNetworkConnection() { - return mMessage.get( ACTIVE_NETWORK_CONNECTION_FLAG ); + return mMessage.get(ACTIVE_NETWORK_CONNECTION_FLAG); } - + public String getSystemID() { - return mMessage.getHex( SYSTEM_ID, 3 ); + return mMessage.getHex(SYSTEM_ID, 3); } - + public String getRFSubsystemID() { - return mMessage.getHex( RFSS_ID, 2 ); + return mMessage.getHex(RFSS_ID, 2); } - + public String getSiteID() { - return mMessage.getHex( SITE_ID, 2 ); + return mMessage.getHex(SITE_ID, 2); } public int getIdentifier() { - return mMessage.getInt( IDENTIFIER ); - } - - public int getChannel() - { - return mMessage.getInt( CHANNEL ); - } - - public int getSystemServiceClass() - { - return mMessage.getInt( SYSTEM_SERVICE_CLASS ); - } - - public long getDownlinkFrequency() - { - return calculateDownlink( mIdentifierUpdate, getChannel() ); - } - - public long getUplinkFrequency() - { - return calculateUplink( mIdentifierUpdate, getChannel() ); + return mMessage.getInt(IDENTIFIER); } - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + public int getChannel() { - /* we're only expecting 1 identifier, so use whatever is received */ - mIdentifierUpdate = message; + return mMessage.getInt(CHANNEL); + } + + public int getSystemServiceClass() + { + return mMessage.getInt(SYSTEM_SERVICE_CLASS); + } + + public long getDownlinkFrequency() + { + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.getDownlinkFrequency(getChannel()); + } + + return 0; + } + + public long getUplinkFrequency() + { + if(mIdentifierUpdate != null) + { + return mIdentifierUpdate.getUplinkFrequency(getChannel()); + } + + return 0; + } + + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + /* we're only expecting 1 identifier, so use whatever is received */ + mIdentifierUpdate = message; + } + + public int[] getIdentifiers() + { + int[] idens = new int[1]; + + idens[0] = getIdentifier(); + + return idens; } - - public int[] getIdentifiers() - { - int[] idens = new int[ 1 ]; - - idens[ 0 ] = getIdentifier(); - - return idens; - } } diff --git a/src/module/decode/p25/message/tsbk/osp/control/SecondaryControlChannelBroadcast.java b/src/module/decode/p25/message/tsbk/osp/control/SecondaryControlChannelBroadcast.java index 48b61992..e120c785 100644 --- a/src/module/decode/p25/message/tsbk/osp/control/SecondaryControlChannelBroadcast.java +++ b/src/module/decode/p25/message/tsbk/osp/control/SecondaryControlChannelBroadcast.java @@ -1,44 +1,50 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tsbk.osp.control; +import alias.AliasList; +import bits.BinaryMessage; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.message.tsbk.TSBKMessage; import module.decode.p25.reference.DataUnitID; import module.decode.p25.reference.Opcode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import alias.AliasList; -import bits.BinaryMessage; - -public class SecondaryControlChannelBroadcast extends TSBKMessage - implements IdentifierReceiver, Comparable +public class SecondaryControlChannelBroadcast extends TSBKMessage implements IdentifierReceiver, Comparable { - private final static Logger mLog = - LoggerFactory.getLogger( SecondaryControlChannelBroadcast.class ); + public static final int[] RFSS_ID = {80, 81, 82, 83, 84, 85, 86, 87}; + public static final int[] SITE_ID = {88, 89, 90, 91, 92, 93, 94, 95}; + public static final int[] IDENTIFIER_1 = {96, 97, 98, 99}; + public static final int[] CHANNEL_1 = {100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111}; + public static final int[] SYSTEM_SERVICE_CLASS_1 = {112, 113, 114, 115, 116, 117, 118, 119}; + public static final int[] IDENTIFIER_2 = {120, 121, 122, 123}; + public static final int[] CHANNEL_2 = {124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135}; + public static final int[] SYSTEM_SERVICE_CLASS_2 = {136, 137, 138, 139, 140, 141, 142, 143}; - public static final int[] RFSS_ID = { 80,81,82,83,84,85,86,87 }; - public static final int[] SITE_ID = { 88,89,90,91,92,93,94,95 }; - public static final int[] IDENTIFIER_1 = { 96,97,98,99 }; - public static final int[] CHANNEL_1 = { 100,101,102,103,104,105,106,107,108, - 109,110,111 }; - public static final int[] SYSTEM_SERVICE_CLASS_1 = { 112,113,114,115,116, - 117,118,119 }; - public static final int[] IDENTIFIER_2 = { 120,121,122,123 }; - public static final int[] CHANNEL_2 = { 124,125,126,127,128,129,130,131,132, - 133,134,135 }; - public static final int[] SYSTEM_SERVICE_CLASS_2 = { 136,137,138,139,140, - 141,142,143 }; - private IBandIdentifier mIdentifierUpdate1; private IBandIdentifier mIdentifierUpdate2; - - public SecondaryControlChannelBroadcast( BinaryMessage message, - DataUnitID duid, - AliasList aliasList ) + + public SecondaryControlChannelBroadcast(BinaryMessage message, + DataUnitID duid, + AliasList aliasList) { - super( message, duid, aliasList ); + super(message, duid, aliasList); } @Override @@ -46,162 +52,215 @@ public class SecondaryControlChannelBroadcast extends TSBKMessage { return Opcode.SECONDARY_CONTROL_CHANNEL_BROADCAST.getDescription(); } - + public String getMessage() { StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - sb.append( " SITE:" + getRFSS() + "-" + getSiteID() ); - - sb.append( " CHAN1:" + getIdentifier1() + "-" + getChannel1() ); - - sb.append( " DN1:" + getDownlinkFrequency1() ); - - sb.append( " UP1:" + getUplinkFrequency1() ); - - sb.append( " SVC1:" + - SystemService.toString( getSystemServiceClass1() ) ); - if( hasChannel2() ) + sb.append(getMessageStub()); + + sb.append(" SITE:" + getRFSS() + "-" + getSiteID()); + + sb.append(" CHAN1:" + getIdentifier1() + "-" + getChannel1()); + + sb.append(" DN1:" + getDownlinkFrequency1()); + + sb.append(" UP1:" + getUplinkFrequency1()); + + sb.append(" SVC1:" + SystemService.toString(getSystemServiceClass1())); + + if(hasChannel2()) { - sb.append( " CHAN2:" + getIdentifier2() + "-" + getChannel2() ); - - sb.append( " DN2:" + getDownlinkFrequency2() ); - - sb.append( " UP2:" + getUplinkFrequency2() ); - - sb.append( " SVC2:" + - SystemService.toString( getSystemServiceClass2() ) ); + sb.append(" CHAN2:" + getIdentifier2() + "-" + getChannel2()); + + sb.append(" DN2:" + getDownlinkFrequency2()); + + sb.append(" UP2:" + getUplinkFrequency2()); + + sb.append(" SVC2:" + SystemService.toString(getSystemServiceClass2())); } - + return sb.toString(); } - + public String getRFSS() { - return mMessage.getHex( RFSS_ID, 2 ); + return mMessage.getHex(RFSS_ID, 2); } - + public String getSiteID() { - return mMessage.getHex( SITE_ID, 2 ); + return mMessage.getHex(SITE_ID, 2); } - + public int getIdentifier1() { - return mMessage.getInt( IDENTIFIER_1 ); + return mMessage.getInt(IDENTIFIER_1); } - + public int getChannel1() { - return mMessage.getInt( CHANNEL_1 ); + return mMessage.getInt(CHANNEL_1); } - + public int getSystemServiceClass1() { - return mMessage.getInt( SYSTEM_SERVICE_CLASS_1 ); + return mMessage.getInt(SYSTEM_SERVICE_CLASS_1); } public int getIdentifier2() { - return mMessage.getInt( IDENTIFIER_2 ); + return mMessage.getInt(IDENTIFIER_2); } - + public int getChannel2() { - return mMessage.getInt( CHANNEL_2 ); + return mMessage.getInt(CHANNEL_2); } - + public int getSystemServiceClass2() { - return mMessage.getInt( SYSTEM_SERVICE_CLASS_2 ); + return mMessage.getInt(SYSTEM_SERVICE_CLASS_2); } public boolean hasChannel2() { - return getSystemServiceClass2() != 0; + return getSystemServiceClass2() != 0; } - - + + public long getDownlinkFrequency1() { - return calculateDownlink( mIdentifierUpdate1, getChannel1() ); + if(mIdentifierUpdate1 != null) + { + return mIdentifierUpdate1.getDownlinkFrequency(getChannel1()); + } + + return 0; } - + public long getUplinkFrequency1() { - return calculateUplink( mIdentifierUpdate1, getChannel1() ); + if(mIdentifierUpdate1 != null) + { + return mIdentifierUpdate1.getUplinkFrequency(getChannel1()); + } + + return 0; } public long getDownlinkFrequency2() { - return calculateDownlink( mIdentifierUpdate2, getChannel2() ); + if(mIdentifierUpdate2 != null) + { + return mIdentifierUpdate2.getDownlinkFrequency(getChannel2()); + } + + return 0; } - + public long getUplinkFrequency2() { - return calculateUplink( mIdentifierUpdate2, getChannel2() ); + if(mIdentifierUpdate2 != null) + { + return mIdentifierUpdate2.getUplinkFrequency(getChannel2()); + } + + return 0; } - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) { - if( identifier == getIdentifier1() ) - { - mIdentifierUpdate1 = message; - } - - if( identifier == getIdentifier2() ) - { - mIdentifierUpdate2 = message; - } - } - - public int[] getIdentifiers() - { - int[] idens; - - if( hasChannel2() ) - { - idens = new int[ 2 ]; - - idens[ 0 ] = getIdentifier1(); - idens[ 1 ] = getIdentifier2(); - } - else - { - idens = new int[ 1 ]; - - idens[ 0 ] = getIdentifier1(); - } - - return idens; - } + if(identifier == getIdentifier1()) + { + mIdentifierUpdate1 = message; + } - @Override - public int compareTo( SecondaryControlChannelBroadcast other ) + if(identifier == getIdentifier2()) + { + mIdentifierUpdate2 = message; + } + } + + public int[] getIdentifiers() { - if( other.getSiteID().contentEquals( getSiteID() ) && - other.getIdentifier1() == getIdentifier1() && - other.getChannel1() == getChannel1() && - other.getChannel2() == getChannel2() && - other.getIdentifier2() == getIdentifier2() && - other.getDownlinkFrequency1() == getDownlinkFrequency1() && - other.getUplinkFrequency1() == getUplinkFrequency1() && - other.getDownlinkFrequency2() == getDownlinkFrequency2() && - other.getUplinkFrequency2() == getUplinkFrequency2() ) - { - return 0; - } - else if( other.getIdentifier1() < getIdentifier1() ) - { - return -1; - } - else - { - return 1; - } + int[] idens; + + if(hasChannel2()) + { + idens = new int[2]; + + idens[0] = getIdentifier1(); + idens[1] = getIdentifier2(); + } + else + { + idens = new int[1]; + + idens[0] = getIdentifier1(); + } + + return idens; + } + + @Override + public int compareTo(SecondaryControlChannelBroadcast other) + { + if(other.getRFSS().contentEquals(getRFSS()) && + other.getSiteID().contentEquals(getSiteID()) && + other.getIdentifier1() == getIdentifier1() && + other.getChannel1() == getChannel1()) + { + return 0; + } + else if(other.getIdentifier1() < getIdentifier1()) + { + return -1; + } + else + { + return 1; + } + } + + @Override + public boolean equals(Object o) + { + if(this == o) + { + return true; + } + if(!(o instanceof SecondaryControlChannelBroadcast)) + { + return false; + } + + SecondaryControlChannelBroadcast that = (SecondaryControlChannelBroadcast)o; + + if(getRFSS() != that.getRFSS()) + { + return false; + } + if(getSiteID() != that.getSiteID()) + { + return false; + } + if(getIdentifier1() != that.getIdentifier1()) + { + return false; + } + + return getChannel1() == that.getChannel1(); + } + + @Override + public int hashCode() + { + int result = getRFSS() != null ? getRFSS().hashCode() : 0; + result = 31 * result + getSiteID() != null ? getSiteID().hashCode() : 0; + result = 31 * result + getIdentifier1(); + result = 31 * result + getChannel1(); + return result; } } diff --git a/src/module/decode/p25/message/tsbk/osp/data/GroupDataChannelGrant.java b/src/module/decode/p25/message/tsbk/osp/data/GroupDataChannelGrant.java index 0873f1e9..42be5c6b 100644 --- a/src/module/decode/p25/message/tsbk/osp/data/GroupDataChannelGrant.java +++ b/src/module/decode/p25/message/tsbk/osp/data/GroupDataChannelGrant.java @@ -1,19 +1,35 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tsbk.osp.data; +import alias.AliasList; +import bits.BinaryMessage; import module.decode.p25.message.tsbk.GroupChannelGrant; import module.decode.p25.reference.DataUnitID; import module.decode.p25.reference.Opcode; -import alias.AliasList; -import bits.BinaryMessage; public class GroupDataChannelGrant extends GroupChannelGrant { - public GroupDataChannelGrant( BinaryMessage message, - DataUnitID duid, - AliasList aliasList ) + public GroupDataChannelGrant(BinaryMessage message, DataUnitID duid, AliasList aliasList) { - super( message, duid, aliasList ); + super(message, duid, aliasList); } @Override diff --git a/src/module/decode/p25/message/tsbk/osp/data/SNDCPDataChannelAnnouncementExplicit.java b/src/module/decode/p25/message/tsbk/osp/data/SNDCPDataChannelAnnouncementExplicit.java index e7a9f5c1..f8aec423 100644 --- a/src/module/decode/p25/message/tsbk/osp/data/SNDCPDataChannelAnnouncementExplicit.java +++ b/src/module/decode/p25/message/tsbk/osp/data/SNDCPDataChannelAnnouncementExplicit.java @@ -1,158 +1,178 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tsbk.osp.data; +import alias.AliasList; +import bits.BinaryMessage; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.reference.DataUnitID; -import alias.AliasList; -import bits.BinaryMessage; -public class SNDCPDataChannelAnnouncementExplicit extends SNDCPData - implements IdentifierReceiver +public class SNDCPDataChannelAnnouncementExplicit extends SNDCPData implements IdentifierReceiver { - public static final int AUTONOMOUS_ACCESS_AVAILABLE_INDICATOR = 88; - public static final int REQUESTED_ACCESS_AVAILABLE_INDICATOR = 89; - - public static final int[] TRANSMIT_IDENTIFIER = { 96,97,98,99 }; - public static final int[] TRANSMIT_NUMBER = { 100,101,102,103,104,105,106, - 107,108,109,110,111 }; - public static final int[] RECEIVE_IDENTIFIER = { 112,113,114,115 }; - public static final int[] RECEIVE_NUMBER = { 116,117,118,119,120,121,122, - 123,124,125,126,127 }; - - public static final int[] DATA_ACCESS_CONTROL = { 128,129,130,131,132,133, - 134,135,136,137,138,139,140,141,142,143 }; - + public static final int AUTONOMOUS_ACCESS_AVAILABLE_INDICATOR = 88; + public static final int REQUESTED_ACCESS_AVAILABLE_INDICATOR = 89; + public static final int[] TRANSMIT_IDENTIFIER = {96, 97, 98, 99}; + public static final int[] TRANSMIT_NUMBER = {100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111}; + public static final int[] RECEIVE_IDENTIFIER = {112, 113, 114, 115}; + public static final int[] RECEIVE_NUMBER = {116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127}; + public static final int[] DATA_ACCESS_CONTROL = {128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143}; + private IBandIdentifier mIdentifierUpdateTransmit; private IBandIdentifier mIdentifierUpdateReceive; - public SNDCPDataChannelAnnouncementExplicit( BinaryMessage message, - DataUnitID duid, - AliasList aliasList ) + public SNDCPDataChannelAnnouncementExplicit(BinaryMessage message, DataUnitID duid, AliasList aliasList) { - super( message, duid, aliasList ); + super(message, duid, aliasList); } - + public String getMessage() { StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - if( isEmergency() ) + + sb.append(getMessageStub()); + + if(isEmergency()) { - sb.append( " EMERGENCY" ); + sb.append(" EMERGENCY"); } - - if( isAutonomousAccessAvailable() ) + + if(isAutonomousAccessAvailable()) { - sb.append( " AUTONOMOUS ACCESS" ); + sb.append(" AUTONOMOUS ACCESS"); } - - if( isRequestedAccessAvailable() ) + + if(isRequestedAccessAvailable()) { - sb.append( " DOWNLINK:" ); - sb.append( getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber() ); - - sb.append( " " + getUplinkFrequency() ); - - sb.append( " UPLINK:" ); - sb.append( getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber() ); - - sb.append( " " + getDownlinkFrequency() ); - - sb.append( " DATA ACCESS CONTROL:" ); + sb.append(" DOWNLINK:"); + sb.append(getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber()); + + sb.append(" " + getUplinkFrequency()); + + sb.append(" UPLINK:"); + sb.append(getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber()); + + sb.append(" " + getDownlinkFrequency()); + + sb.append(" DATA ACCESS CONTROL:"); } else { - sb.append( " ACCESS DENIED TO DATA ACCESS CONTROL:" ); + sb.append(" ACCESS DENIED TO DATA ACCESS CONTROL:"); } - - sb.append( getDataAccessControl() ); - + + sb.append(getDataAccessControl()); + return sb.toString(); } - + public boolean isAutonomousAccessAvailable() { - return mMessage.get( AUTONOMOUS_ACCESS_AVAILABLE_INDICATOR ); + return mMessage.get(AUTONOMOUS_ACCESS_AVAILABLE_INDICATOR); } - + public boolean isRequestedAccessAvailable() { - return mMessage.get( REQUESTED_ACCESS_AVAILABLE_INDICATOR ); + return mMessage.get(REQUESTED_ACCESS_AVAILABLE_INDICATOR); } - + public int getTransmitChannelIdentifier() { - return mMessage.getInt( TRANSMIT_IDENTIFIER ); + return mMessage.getInt(TRANSMIT_IDENTIFIER); } - + public int getTransmitChannelNumber() { - return mMessage.getInt( TRANSMIT_NUMBER ); + return mMessage.getInt(TRANSMIT_NUMBER); } - + public String getTransmitChannel() { - return getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber(); + return getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber(); } - + public int getReceiveChannelIdentifier() { - return mMessage.getInt( RECEIVE_IDENTIFIER ); + return mMessage.getInt(RECEIVE_IDENTIFIER); } - + public int getReceiveChannelNumber() { - return mMessage.getInt( RECEIVE_NUMBER ); + return mMessage.getInt(RECEIVE_NUMBER); } - + public String getReceiveChannel() { - return getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber(); + return getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber(); } - + public String getDataAccessControl() { - return mMessage.getHex( DATA_ACCESS_CONTROL, 4 ); - } - - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) - { - if( identifier == getTransmitChannelIdentifier() ) - { - mIdentifierUpdateTransmit = message; - } - else if( identifier == getReceiveChannelIdentifier() ) - { - mIdentifierUpdateReceive = message; - } - else - { - throw new IllegalArgumentException( "unexpected channel band " - + "identifier [" + identifier + "]" ); - } + return mMessage.getHex(DATA_ACCESS_CONTROL, 4); } - @Override + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) + { + if(identifier == getTransmitChannelIdentifier()) + { + mIdentifierUpdateTransmit = message; + } + else if(identifier == getReceiveChannelIdentifier()) + { + mIdentifierUpdateReceive = message; + } + else + { + throw new IllegalArgumentException("unexpected channel band " + + "identifier [" + identifier + "]"); + } + } + + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 2 ]; - - identifiers[ 0 ] = getTransmitChannelIdentifier(); - identifiers[ 1 ] = getReceiveChannelIdentifier(); + int[] identifiers = new int[2]; - return identifiers; + identifiers[0] = getTransmitChannelIdentifier(); + identifiers[1] = getReceiveChannelIdentifier(); + + return identifiers; } public long getDownlinkFrequency() { - return calculateDownlink( mIdentifierUpdateTransmit, getReceiveChannelNumber() ); + if(mIdentifierUpdateTransmit != null) + { + return mIdentifierUpdateTransmit.getDownlinkFrequency(getTransmitChannelNumber()); + } + + return 0; } - + public long getUplinkFrequency() { - return calculateUplink( mIdentifierUpdateReceive, getTransmitChannelNumber() ); + if(mIdentifierUpdateReceive != null) + { + mIdentifierUpdateReceive.getUplinkFrequency(getReceiveChannelNumber()); + } + + return 0; } } diff --git a/src/module/decode/p25/message/tsbk/osp/data/SNDCPDataChannelGrant.java b/src/module/decode/p25/message/tsbk/osp/data/SNDCPDataChannelGrant.java index 88589309..31e62211 100644 --- a/src/module/decode/p25/message/tsbk/osp/data/SNDCPDataChannelGrant.java +++ b/src/module/decode/p25/message/tsbk/osp/data/SNDCPDataChannelGrant.java @@ -1,131 +1,164 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ package module.decode.p25.message.tsbk.osp.data; +import alias.AliasList; +import bits.BinaryMessage; import module.decode.p25.message.IBandIdentifier; import module.decode.p25.message.IdentifierReceiver; import module.decode.p25.reference.DataUnitID; -import alias.AliasList; -import bits.BinaryMessage; public class SNDCPDataChannelGrant extends SNDCPData implements IdentifierReceiver { - public static final int[] TRANSMIT_IDENTIFIER = { 88,89,90,91 }; - public static final int[] TRANSMIT_NUMBER = { 92,93,94,95,96,97,98,99,100, - 101,102,103 }; - public static final int[] RECEIVE_IDENTIFIER = { 104,105,106,107 }; - public static final int[] RECEIVE_NUMBER = { 108,109,110,111,112,113,114, - 115,116,117,118,119 }; - - public static final int[] TARGET_ADDRESS = { 120,121,122,123,124,125,126, - 127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143 }; - + public static final int[] TRANSMIT_IDENTIFIER = {88, 89, 90, 91}; + public static final int[] TRANSMIT_NUMBER = {92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103}; + public static final int[] RECEIVE_IDENTIFIER = {104, 105, 106, 107}; + public static final int[] RECEIVE_NUMBER = {108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119}; + public static final int[] TARGET_ADDRESS = {120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, 140, 141, 142, 143}; + private IBandIdentifier mIdentifierUpdateTransmit; private IBandIdentifier mIdentifierUpdateReceive; - public SNDCPDataChannelGrant( BinaryMessage message, - DataUnitID duid, - AliasList aliasList ) + public SNDCPDataChannelGrant(BinaryMessage message, DataUnitID duid, AliasList aliasList) { - super( message, duid, aliasList ); + super(message, duid, aliasList); } - + + public boolean isTDMAChannel() + { + if(mIdentifierUpdateTransmit != null) + { + return mIdentifierUpdateTransmit.isTDMA(); + } + + return false; + } + public String getMessage() { StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - - if( isEmergency() ) - { - sb.append( " EMERGENCY" ); - } - - sb.append( " UPLINK:" ); - sb.append( getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber() ); - - sb.append( " " + getUplinkFrequency() ); - - sb.append( " DOWNLINK:" ); - sb.append( getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber() ); - - sb.append( " " + getDownlinkFrequency() ); - sb.append( " TGT:" ); - sb.append( getTargetAddress() ); - + sb.append(getMessageStub()); + + if(isEmergency()) + { + sb.append(" EMERGENCY"); + } + + sb.append(" UPLINK:"); + sb.append(getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber()); + + sb.append(" " + getUplinkFrequency()); + + sb.append(" DOWNLINK:"); + sb.append(getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber()); + + sb.append(" " + getDownlinkFrequency()); + + sb.append(" TGT:"); + sb.append(getTargetAddress()); + return sb.toString(); } - + public int getTransmitChannelIdentifier() { - return mMessage.getInt( TRANSMIT_IDENTIFIER ); + return mMessage.getInt(TRANSMIT_IDENTIFIER); } - + public int getTransmitChannelNumber() { - return mMessage.getInt( TRANSMIT_NUMBER ); + return mMessage.getInt(TRANSMIT_NUMBER); } - + public String getTransmitChannel() { - return getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber(); + return getTransmitChannelIdentifier() + "-" + getTransmitChannelNumber(); } public int getReceiveChannelIdentifier() { - return mMessage.getInt( RECEIVE_IDENTIFIER ); + return mMessage.getInt(RECEIVE_IDENTIFIER); } - + public int getReceiveChannelNumber() { - return mMessage.getInt( RECEIVE_NUMBER ); + return mMessage.getInt(RECEIVE_NUMBER); } - + public String getReceiveChannel() { - return getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber(); + return getReceiveChannelIdentifier() + "-" + getReceiveChannelNumber(); } public String getTargetAddress() { - return mMessage.getHex( TARGET_ADDRESS, 6 ); + return mMessage.getHex(TARGET_ADDRESS, 6); } - @Override - public void setIdentifierMessage( int identifier, IBandIdentifier message ) + @Override + public void setIdentifierMessage(int identifier, IBandIdentifier message) { - if( identifier == getTransmitChannelIdentifier() ) - { - mIdentifierUpdateTransmit = message; - } - else if( identifier == getReceiveChannelIdentifier() ) - { - mIdentifierUpdateReceive = message; - } - else - { - throw new IllegalArgumentException( "unexpected channel band " - + "identifier [" + identifier + "]" ); - } + if(identifier == getTransmitChannelIdentifier()) + { + mIdentifierUpdateTransmit = message; + } + else if(identifier == getReceiveChannelIdentifier()) + { + mIdentifierUpdateReceive = message; + } + else + { + throw new IllegalArgumentException("unexpected channel band " + + "identifier [" + identifier + "]"); + } } - @Override + @Override public int[] getIdentifiers() { - int[] identifiers = new int[ 2 ]; - - identifiers[ 0 ] = getTransmitChannelIdentifier(); - identifiers[ 1 ] = getReceiveChannelIdentifier(); + int[] identifiers = new int[2]; - return identifiers; + identifiers[0] = getTransmitChannelIdentifier(); + identifiers[1] = getReceiveChannelIdentifier(); + + return identifiers; } public long getDownlinkFrequency() { - return calculateDownlink( mIdentifierUpdateTransmit, getTransmitChannelNumber() ); + if(mIdentifierUpdateTransmit != null) + { + return mIdentifierUpdateTransmit.getDownlinkFrequency(getTransmitChannelNumber()); + } + + return 0; } - + public long getUplinkFrequency() { - return calculateUplink( mIdentifierUpdateReceive, getReceiveChannelNumber() ); + if(mIdentifierUpdateReceive != null) + { + return mIdentifierUpdateReceive.getUplinkFrequency(getReceiveChannelNumber()); + } + + return 0; } } diff --git a/src/module/demodulate/fm/FMDemodulatorModule.java b/src/module/demodulate/fm/FMDemodulatorModule.java index 8bac1bc4..8b7646de 100644 --- a/src/module/demodulate/fm/FMDemodulatorModule.java +++ b/src/module/demodulate/fm/FMDemodulatorModule.java @@ -62,6 +62,13 @@ public class FMDemodulatorModule extends Module implements IComplexBufferListene mIQFilter.setListener(mDemodulator); } + public FMDemodulatorModule(float[] filter) + { + mIQFilter = new ComplexFIRFilter_CB_CB(filter, 1.0f); + mDemodulator = new FMDemodulator_CB(1.0f); + mIQFilter.setListener(mDemodulator); + } + @Override public Listener getComplexBufferListener() { diff --git a/src/record/AudioRecorder.java b/src/record/AudioRecorder.java index 4d118351..15723eba 100644 --- a/src/record/AudioRecorder.java +++ b/src/record/AudioRecorder.java @@ -163,7 +163,10 @@ public abstract class AudioRecorder extends Module implements Listener listener) { @@ -171,8 +174,14 @@ public abstract class AudioRecorder extends Module implements Listener { + private final static Logger mLog = LoggerFactory.getLogger(OverflowableTransferQueue.class); + public enum State {NORMAL, OVERFLOW}; - private Listener mStateListener; + private IOverflowListener mOverflowListener; private LinkedTransferQueue mQueue = new LinkedTransferQueue(); private AtomicInteger mCounter = new AtomicInteger(); + private AtomicBoolean mOverflow = new AtomicBoolean(); private int mMaximumSize; private int mResetThreshold; - private boolean mOverflow = false; /** * Concurrent transfer queue that couples a higher-throughput linked transfer queue with an atomic integer for @@ -53,7 +61,7 @@ public class OverflowableTransferQueue */ public void offer(E e) { - if(!mOverflow) + if(!mOverflow.get()) { mQueue.offer(e); @@ -73,46 +81,36 @@ public class OverflowableTransferQueue { int drainCount = mQueue.drainTo(collection, maxElements); - if(drainCount > 0) - { - int size = mCounter.addAndGet(-drainCount); + int size = mCounter.addAndGet(-drainCount); - if(mOverflow && size <= mResetThreshold) - { - setOverflow(false); - } + if(mOverflow.get() && size <= mResetThreshold) + { + setOverflow(false); } return drainCount; } /** - * Sets a listener to receive state change events + * Sets a listener to receive overflow state change events */ - public void setStateListener(Listener listener) + public void setOverflowListener(IOverflowListener listener) { - mStateListener = listener; + mOverflowListener = listener; } /** - * Current state of the queue, normal or overflow - */ - public State getState() - { - return mOverflow ? State.OVERFLOW : State.NORMAL; - } - - /** - * Toggles the overflow state + * Toggles the overflow state and broadcast state change to listener */ private void setOverflow(boolean overflow) { - mOverflow = overflow; - - if(mStateListener != null) + if(mOverflow.compareAndSet(!overflow, overflow)) { - mStateListener.receive(getState()); + if(mOverflowListener != null) + { + mOverflowListener.sourceOverflow(overflow); + } } } @@ -125,7 +123,11 @@ public class OverflowableTransferQueue { mQueue.clear(); mCounter.set(0); - mOverflow = false; + mOverflow.set(false); + if(mOverflowListener != null) + { + mOverflowListener.sourceOverflow(false); + } } } } diff --git a/src/sample/real/IOverflowListener.java b/src/sample/real/IOverflowListener.java new file mode 100644 index 00000000..61202ea3 --- /dev/null +++ b/src/sample/real/IOverflowListener.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * + ******************************************************************************/ +package sample.real; + +public interface IOverflowListener +{ + /** + * Indicates that the source is in overflow state (true) or out of overflow state (false) + * @param overflow true to indicate an overflow state + */ + void sourceOverflow(boolean overflow); +} diff --git a/src/source/Source.java b/src/source/Source.java index 217def00..2de310b8 100644 --- a/src/source/Source.java +++ b/src/source/Source.java @@ -19,6 +19,7 @@ package source; import module.Module; import sample.SampleType; +import sample.real.IOverflowListener; /** * Abstract class to define the minimum functionality of a sample data provider. @@ -26,6 +27,7 @@ import sample.SampleType; public abstract class Source extends Module { protected SampleType mSampleType; + protected IOverflowListener mOverflowListener; public Source( SampleType sampleType ) { @@ -47,4 +49,25 @@ public abstract class Source extends Module { mSampleType = sampleType; } + + /** + * Registers the listener to receive overflow state changes. Use null argument to clear the listener + */ + public void setOverflowListener(IOverflowListener listener) + { + mOverflowListener = listener; + } + + /** + * Broadcasts an overflow state + * + * @param overflow true if overlow, false if normal + */ + protected void broadcastOverflowState(boolean overflow) + { + if(mOverflowListener != null) + { + mOverflowListener.sourceOverflow(overflow); + } + } } diff --git a/src/source/tuner/TunerChannelSource.java b/src/source/tuner/TunerChannelSource.java index c50fd267..fa0cef46 100644 --- a/src/source/tuner/TunerChannelSource.java +++ b/src/source/tuner/TunerChannelSource.java @@ -29,6 +29,7 @@ import sample.Listener; import sample.OverflowableTransferQueue; import sample.complex.Complex; import sample.complex.ComplexBuffer; +import sample.real.IOverflowListener; import source.ComplexSource; import source.SourceException; import source.tuner.frequency.FrequencyChangeEvent; @@ -51,7 +52,7 @@ public class TunerChannelSource extends ComplexSource implements IFrequencyChang private static final int BUFFER_MAX_CAPACITY = 300; //Threshold for resetting buffer overflow condition - private static final int BUFFER_OVERFLOW_RESET_THRESHOLD = 200; + private static final int BUFFER_OVERFLOW_RESET_THRESHOLD = 100; private static int CHANNEL_RATE = 48000; private static int CHANNEL_PASS_FREQUENCY = 12000; @@ -101,21 +102,6 @@ public class TunerChannelSource extends ComplexSource implements IFrequencyChang mTunerFrequency = mTuner.getTunerController().getFrequency(); mBuffer = new OverflowableTransferQueue<>(BUFFER_MAX_CAPACITY, BUFFER_OVERFLOW_RESET_THRESHOLD); - mBuffer.setStateListener(new Listener() - { - @Override - public void receive(OverflowableTransferQueue.State state) - { - if(state == OverflowableTransferQueue.State.NORMAL) - { - mLog.debug("Channel [" + mTunerFrequency + "] buffer overflow - temporary pause until processing catches up"); - } - else - { - mLog.debug("Channel [" + mTunerFrequency + "] buffer overflow cleared - resuming normal processing"); - } - } - }); /* Setup the frequency translator to the current source frequency */ long frequencyOffset = mTunerFrequency - mTunerChannel.getFrequency(); @@ -126,6 +112,14 @@ public class TunerChannelSource extends ComplexSource implements IFrequencyChang frequencyChanged(new FrequencyChangeEvent(Event.NOTIFICATION_SAMPLE_RATE_CHANGE, mTuner.getTunerController().getSampleRate())); } + /** + * Overrides the default source overflow listener management to delegate responsibility to the overflow buffer + */ + @Override + public void setOverflowListener(IOverflowListener listener) + { + mBuffer.setOverflowListener(listener); + } public void start(ScheduledExecutorService executor) { @@ -175,7 +169,7 @@ public class TunerChannelSource extends ComplexSource implements IFrequencyChang } else { - mLog.warn("Attempt to stop() and already stopped tuner channel source was ignored"); + mLog.warn("Attempt to stop() an already stopped tuner channel source was ignored"); } } @@ -379,6 +373,10 @@ public class TunerChannelSource extends ComplexSource implements IFrequencyChang mLog.error("Error encountered during decimation process", e); } } + catch(Throwable throwable) + { + mLog.error("Code error encountered during decimation process - channel thread will probably die", throwable); + } /* Check to see if we've been shutdown */ if(!mProcessing) diff --git a/src/source/tuner/usb/USBTransferProcessor.java b/src/source/tuner/usb/USBTransferProcessor.java index 053250f3..aeb56bb9 100644 --- a/src/source/tuner/usb/USBTransferProcessor.java +++ b/src/source/tuner/usb/USBTransferProcessor.java @@ -30,6 +30,7 @@ import sample.Listener; import sample.OverflowableTransferQueue; import sample.adapter.ISampleAdapter; import sample.complex.ComplexBuffer; +import sample.real.IOverflowListener; import source.tuner.TunerManager; import util.ThreadPool; @@ -56,7 +57,7 @@ public class USBTransferProcessor implements TransferCallback private static final int FILLED_BUFFER_MAX_CAPACITY = 300; //Threshold for resetting buffer overflow condition - private static final int FILLED_BUFFER_OVERFLOW_RESET_THRESHOLD = 200; + private static final int FILLED_BUFFER_OVERFLOW_RESET_THRESHOLD = 100; private String mDeviceName; @@ -101,12 +102,12 @@ public class USBTransferProcessor implements TransferCallback mBufferSize = bufferSize; mFilledBuffers = new OverflowableTransferQueue<>(FILLED_BUFFER_MAX_CAPACITY, FILLED_BUFFER_OVERFLOW_RESET_THRESHOLD); - mFilledBuffers.setStateListener(new Listener() + mFilledBuffers.setOverflowListener(new IOverflowListener() { @Override - public void receive(OverflowableTransferQueue.State state) + public void sourceOverflow(boolean overflow) { - if(state == OverflowableTransferQueue.State.NORMAL) + if(overflow) { mLog.debug(mDeviceName + " - buffer overflow - temporary pause until processing catches up"); }