492 Formatted Talkgroup and TalkgroupRange Editors (#493)

* Updates Talkgroup and Talkgroup ranges and editors to support formatted
talkgroup values.

* Updates talkgroup format masks to allow spaces (ie incomplete values)
 in talkgroup values.
This commit is contained in:
Denny Sheirer
2019-01-20 14:30:54 +00:00
committed by GitHub
parent 52e3d9d20d
commit 25d387f3cf
19 changed files with 1010 additions and 202 deletions

View File

@@ -1,7 +1,7 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
* Copyright (C) 2014-2019 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
@@ -284,7 +284,7 @@ public class AliasList implements Listener<AliasEvent>
{
Alias patchedAlias = patchGroupAliasList.getAlias(patchedGroup);
if(patchedAlias != null)
if(patchedAlias != null && !aliases.contains(patchedAlias))
{
aliases.add(patchedAlias);
}

View File

@@ -1,7 +1,7 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
* Copyright (C) 2014-2019 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
@@ -30,7 +30,7 @@ import io.github.dsheirer.protocol.Protocol;
*/
public class Talkgroup extends AliasID
{
private Protocol mProtocol;
private Protocol mProtocol = Protocol.UNKNOWN;
private int mValue;
public Talkgroup()
@@ -69,14 +69,21 @@ public class Talkgroup extends AliasID
@Override
public boolean isValid()
{
return mValue != 0;
if(mProtocol == null || mProtocol == Protocol.UNKNOWN)
{
return false;
}
TalkgroupFormat talkgroupFormat = TalkgroupFormat.get(mProtocol);
return talkgroupFormat.getMinimumValidValue() <= mValue && mValue <= talkgroupFormat.getMaximumValidValue();
}
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("Talkgroup:").append(mValue).append(" Protocol:").append((mProtocol != null ? mProtocol : "(unspecified)"));
sb.append("Talkgroup:").append(TalkgroupFormatter.format(mProtocol, mValue));
sb.append(" Protocol:").append((mProtocol));
if(!isValid())
{

View File

@@ -1,7 +1,7 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
* Copyright (C) 2014-2019 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
@@ -29,27 +29,32 @@ import org.slf4j.LoggerFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.text.MaskFormatter;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.ParseException;
public class TalkgroupEditor extends DocumentListenerEditor<AliasID>
{
private final static Logger mLog = LoggerFactory.getLogger(TalkgroupEditor.class);
private static final long serialVersionUID = 1L;
private static final String HELP_TEXT =
"<html><h3>Talkgroup Identifier</h3></html>";
private static final String VALID_CHARACTERS_FOR_ASTERISK_MASKS = "0123456789 ";
private MaskFormatter mMaskFormatter = new MaskFormatter();
private JComboBox<Protocol> mComboProtocol;
private JFormattedTextField mTalkgroupField;
public TalkgroupEditor(AliasID aliasID)
{
initGUI();
@@ -62,7 +67,7 @@ public class TalkgroupEditor extends DocumentListenerEditor<AliasID>
add(new JLabel("Protocol:"));
mComboProtocol = new JComboBox<Protocol>();
mComboProtocol = new JComboBox<>();
DefaultComboBoxModel<Protocol> model = new DefaultComboBoxModel<>();
@@ -77,10 +82,9 @@ public class TalkgroupEditor extends DocumentListenerEditor<AliasID>
@Override
public void actionPerformed(ActionEvent e)
{
Protocol selected = mComboProtocol.getItemAt(mComboProtocol.getSelectedIndex());
Protocol protocol = (Protocol)mComboProtocol.getSelectedItem();
updateEditor(protocol);
setModified(true);
// ValidatingEditor<Channel> editor = DecoderFactory.getEditor(selected, mChannelMapModel);
// setEditor(editor);
}
});
@@ -88,11 +92,8 @@ public class TalkgroupEditor extends DocumentListenerEditor<AliasID>
add(new JLabel("Value:"));
mTalkgroupField = new JFormattedTextField();
mTalkgroupField.setColumns(10);
mTalkgroupField.setValue(new Integer(0));
mTalkgroupField = new JFormattedTextField(mMaskFormatter);
mTalkgroupField.getDocument().addDocumentListener(this);
mTalkgroupField.setToolTipText(HELP_TEXT);
add(mTalkgroupField, "growx,push");
JLabel help = new JLabel("Help ...");
@@ -103,13 +104,50 @@ public class TalkgroupEditor extends DocumentListenerEditor<AliasID>
@Override
public void mouseClicked(MouseEvent e)
{
TalkgroupFormat talkgroupFormat = TalkgroupFormat.get(getCurrentProtocol());
JOptionPane.showMessageDialog(TalkgroupEditor.this,
HELP_TEXT, "Help", JOptionPane.INFORMATION_MESSAGE);
talkgroupFormat.getValidRangeHelpText(), "Help", JOptionPane.INFORMATION_MESSAGE);
}
});
add(help, "align left");
}
private void updateEditor(Protocol protocol)
{
TalkgroupFormat mask = TalkgroupFormat.get(protocol);
int currentValue = 0;
Talkgroup talkgroup = getTalkgroup();
if(talkgroup != null)
{
currentValue = talkgroup.getValue();
}
try
{
mTalkgroupField.setValue(null);
mTalkgroupField.setToolTipText(mask.getValidRangeHelpText());
mMaskFormatter.setMask(mask.getMask());
if(mask.getMask().contains("*"))
{
mMaskFormatter.setValidCharacters(VALID_CHARACTERS_FOR_ASTERISK_MASKS);
}
mTalkgroupField.setValue(TalkgroupFormatter.format(protocol, currentValue));
}
catch(ParseException pe)
{
mLog.error("Error applying talkgroup editor mask to mask formatter [" + mask.getMask() + "]");
}
}
private Protocol getCurrentProtocol()
{
return mComboProtocol.getItemAt(mComboProtocol.getSelectedIndex());
}
/**
* Current talkgroup alias id
*/
public Talkgroup getTalkgroup()
{
if(getItem() instanceof Talkgroup)
@@ -129,8 +167,20 @@ public class TalkgroupEditor extends DocumentListenerEditor<AliasID>
if(talkgroup != null)
{
mComboProtocol.setSelectedItem(talkgroup.getProtocol());
mTalkgroupField.setValue(new Integer(talkgroup.getValue()));
Protocol currentProtocol = getCurrentProtocol();
if(currentProtocol == talkgroup.getProtocol())
{
updateEditor(talkgroup.getProtocol());
}
mComboProtocol.getModel().setSelectedItem(talkgroup.getProtocol());
String formatted = TalkgroupFormatter.format(talkgroup.getProtocol(), talkgroup.getValue());
mTalkgroupField.setValue(formatted);
}
else
{
mComboProtocol.getModel().setSelectedItem(Protocol.UNKNOWN);
mTalkgroupField.setValue(TalkgroupFormatter.format(getCurrentProtocol(), 0));
}
setModified(false);
@@ -145,20 +195,63 @@ public class TalkgroupEditor extends DocumentListenerEditor<AliasID>
if(talkgroup != null)
{
Protocol selected = mComboProtocol.getItemAt(mComboProtocol.getSelectedIndex());
talkgroup.setProtocol(selected);
Protocol protocol = mComboProtocol.getItemAt(mComboProtocol.getSelectedIndex());
int value = -1;
try
{
int value = ((Number)mTalkgroupField.getValue()).intValue();
value = TalkgroupFormatter.parse(protocol, mTalkgroupField.getText());
}
catch(ParseException pe)
{
//ignore ... value is still -1 and outside valid value range
}
TalkgroupFormat mask = TalkgroupFormat.get(protocol);
//Check for valid value within range ... notify user but allow value to persist
if(value < mask.getMinimumValidValue() || value > mask.getMaximumValidValue())
{
String message = "Invalid value [" + mTalkgroupField.getText() + "]. " + protocol.name() +
" valid range is [" + mask.getValidRangeDescription() + "]";
JOptionPane.showMessageDialog(TalkgroupEditor.this, message, "Invalid Talkgroup Value",
JOptionPane.ERROR_MESSAGE);
}
else
{
talkgroup.setValue(value);
}
catch(Exception e)
{
mLog.error("Error parsing minimum talkgroup value from [" + mTalkgroupField.getValue() + "]");
}
talkgroup.setProtocol(protocol);
}
setModified(false);
}
public static void main(String[] args)
{
Talkgroup talkgroup = new Talkgroup();
talkgroup.setProtocol(Protocol.APCO25);
talkgroup.setValue(12345678 );
JFrame frame = new JFrame("Talkgroup Editor");
frame.setSize(new Dimension(500, 400));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
TalkgroupEditor talkgroupEditor = new TalkgroupEditor(null);
panel.add(talkgroupEditor);
frame.setContentPane(panel);
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
frame.setVisible(true);
talkgroupEditor.setItem(talkgroup);
}
});
}
}

View File

@@ -0,0 +1,124 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2019 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 <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.alias.id.talkgroup;
import io.github.dsheirer.protocol.Protocol;
/**
* Talkgroup protocol identifier entry masks and min/max valid ranges and valid range descriptions
*
* Note: the getMask() value is intended for use with a MaskFormatter attached to a JFormattedTextField. The
* protocol masks that have a dash (-) use the # (any digit) character and the protocol masks that do not have
* a formatting dash use an asterisk (*). Within the editor(s) that use this enumeration, the editor must use
* a setValidCharacters() on the mask formatter whenever it detects the mask containing one or more asterisks.
*/
public enum TalkgroupFormat
{
APCO25("********", 1, 0xFFFFFF, "1 to 16,777,215",
"<html>APCO25 valid range is 1 to 65,535(talkgroup)<br>or 1 to 16,777,215 (radio ID)"),
FLEETSYNC("###-####", 1, 0x7FFFFF, "001-0001 to 127-8192",
"<html>Fleetsync valid ranges are 1-127(prefix)<br>and 1-8192(ident) (ie. 001-0001 to 127-8192)"),
LTR("##-###", 257, 5375, "01-001 to 20-255",
"<html>LTR valid ranges are 1-20(repeater) and 1-255(talkgroup) (ie. 01-001 to 20-255)"),
MDC1200("*****", 1, 0xFFFF, "1 to 65,535",
"MDC-1200 valid value range is 1-65,535"),
MPT1327("###-####", 1, 0x7FFFFF, "000-0001 to 127-8192",
"<html>MPT-1327 valid ranges are 0-127(prefix)<br>and 1-8192(ident) (ie. 000-0001 to 127-8192)"),
PASSPORT("*****", 1, 0xFFFF, "1 to 65,535",
"Passport valid value range is 1-65,535"),
UNKNOWN("********", 1, 0xFFFFFF, "1 to 16,777,215",
"Unknown protocol valid value range is 1-16,777,215");
private String mMask;
private int mMinimumValue;
private int mMaximumValue;
private String mValidRangeDescription;
private String mValidRangeHelpText;
TalkgroupFormat(String mask, int minimumValue, int maximumValue, String validRangeDescription, String validRangeHelpText)
{
mMask = mask;
mMinimumValue = minimumValue;
mMaximumValue = maximumValue;
mValidRangeDescription = validRangeDescription;
mValidRangeHelpText = validRangeHelpText;
}
public String getMask()
{
return mMask;
}
/**
* Minimum valid value for the protocol
*/
public int getMinimumValidValue()
{
return mMinimumValue;
}
/**
* Maximum valid value for the protocol
*/
public int getMaximumValidValue()
{
return mMaximumValue;
}
/**
* Short description of the valid value range
*/
public String getValidRangeDescription()
{
return mValidRangeDescription;
}
/**
* Help text for valid value ranges
*/
public String getValidRangeHelpText()
{
return mValidRangeHelpText;
}
public static TalkgroupFormat get(Protocol prococol)
{
switch(prococol)
{
case APCO25:
return APCO25;
case FLEETSYNC:
return FLEETSYNC;
case LTR:
case LTR_NET:
case LTR_STANDARD:
return LTR;
case MDC1200:
return MDC1200;
case MPT1327:
return MPT1327;
case PASSPORT:
return PASSPORT;
default:
return UNKNOWN;
}
}
}

View File

@@ -0,0 +1,93 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2019 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 <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.alias.id.talkgroup;
import io.github.dsheirer.preference.identifier.talkgroup.APCO25TalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.FleetsyncTalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.IntegerFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.LTRTalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.MDC1200TalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.MPT1327TalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.PassportTalkgroupFormatter;
import io.github.dsheirer.protocol.Protocol;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;
/**
* Protocol-specific formatting of talkgroup values and parsing of formatted talkgroup values.
*/
public class TalkgroupFormatter
{
private final static Logger mLog = LoggerFactory.getLogger(TalkgroupFormatter.class);
private static Map<Protocol,IntegerFormatter> mFormatterMap = new HashMap<>();
static
{
mFormatterMap.put(Protocol.APCO25, new APCO25TalkgroupFormatter());
mFormatterMap.put(Protocol.FLEETSYNC, new FleetsyncTalkgroupFormatter());
LTRTalkgroupFormatter ltr = new LTRTalkgroupFormatter();
mFormatterMap.put(Protocol.LTR, ltr);
mFormatterMap.put(Protocol.LTR_NET, ltr);
mFormatterMap.put(Protocol.LTR_STANDARD, ltr);
mFormatterMap.put(Protocol.MDC1200, new MDC1200TalkgroupFormatter());
mFormatterMap.put(Protocol.MPT1327, new MPT1327TalkgroupFormatter());
mFormatterMap.put(Protocol.PASSPORT, new PassportTalkgroupFormatter());
mFormatterMap.put(Protocol.UNKNOWN, new IntegerFormatter());
}
public TalkgroupFormatter()
{
}
/**
* Parses the formatted value into an integer using a protocol specific formatter
*/
public static int parse(Protocol protocol, String value) throws ParseException
{
IntegerFormatter formatter = mFormatterMap.get(protocol);
if(formatter == null)
{
formatter = mFormatterMap.get(Protocol.UNKNOWN);
}
return formatter.parse(value);
}
/**
* Formats the integer value using a protocol-specific formatter
*/
public static String format(Protocol protocol, int value)
{
IntegerFormatter formatter = mFormatterMap.get(protocol);
if(formatter == null)
{
formatter = mFormatterMap.get(Protocol.UNKNOWN);
}
return formatter.format(value);
}
}

View File

@@ -1,7 +1,7 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
* Copyright (C) 2014-2019 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
@@ -30,7 +30,7 @@ import io.github.dsheirer.protocol.Protocol;
*/
public class TalkgroupRange extends AliasID
{
private Protocol mProtocol;
private Protocol mProtocol = Protocol.UNKNOWN;
private int mMinTalkgroup;
private int mMaxTalkgroup;
@@ -88,15 +88,25 @@ public class TalkgroupRange extends AliasID
@Override
public boolean isValid()
{
return mProtocol != null && mMinTalkgroup != 0 && mMaxTalkgroup != 0 && mMinTalkgroup <= mMaxTalkgroup;
if(mProtocol == null || mProtocol == Protocol.UNKNOWN)
{
return false;
}
TalkgroupFormat talkgroupFormat = TalkgroupFormat.get(mProtocol);
return talkgroupFormat.getMinimumValidValue() <= mMinTalkgroup &&
mMinTalkgroup <= talkgroupFormat.getMaximumValidValue() &&
talkgroupFormat.getMinimumValidValue() <= mMaxTalkgroup &&
mMaxTalkgroup <= talkgroupFormat.getMaximumValidValue();
}
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("Talkgroup Range:").append(mMinTalkgroup).append(" to ").append(mMaxTalkgroup)
.append(" Protocol:").append(mProtocol == null ? "unspecified" : mProtocol);
sb.append("Talkgroup Range:").append(TalkgroupFormatter.format(mProtocol, mMinTalkgroup));
sb.append(" to ").append(TalkgroupFormatter.format(mProtocol, mMaxTalkgroup));
sb.append(" Protocol:").append(mProtocol != null ? mProtocol : "unspecified");
if(!isValid())
{

View File

@@ -1,7 +1,7 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
* Copyright (C) 2014-2019 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
@@ -31,21 +31,22 @@ import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.text.MaskFormatter;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.ParseException;
public class TalkgroupRangeEditor extends DocumentListenerEditor<AliasID>
{
private final static Logger mLog = LoggerFactory.getLogger(TalkgroupRangeEditor.class);
private static final long serialVersionUID = 1L;
private static final String HELP_TEXT =
"<html><h3>Talkgroup Range Identifier</h3>Identifies a range of talkgroup values</html>";
private static final String VALID_CHARACTERS_FOR_ASTERISK_MASKS = "0123456789 ";
private MaskFormatter mMaskFormatter = new MaskFormatter();
private JComboBox<Protocol> mComboProtocol;
private JFormattedTextField mMinTalkgroupField;
private JFormattedTextField mMaxTalkgroupField;
@@ -78,10 +79,9 @@ public class TalkgroupRangeEditor extends DocumentListenerEditor<AliasID>
@Override
public void actionPerformed(ActionEvent e)
{
Protocol selected = mComboProtocol.getItemAt(mComboProtocol.getSelectedIndex());
Protocol protocol = (Protocol)mComboProtocol.getSelectedItem();
updateEditor(protocol);
setModified(true);
// ValidatingEditor<Channel> editor = DecoderFactory.getEditor(selected, mChannelMapModel);
// setEditor(editor);
}
});
@@ -89,20 +89,14 @@ public class TalkgroupRangeEditor extends DocumentListenerEditor<AliasID>
add(new JLabel("Min:"));
mMinTalkgroupField = new JFormattedTextField();
mMinTalkgroupField.setColumns(10);
mMinTalkgroupField.setValue(new Integer(0));
mMinTalkgroupField = new JFormattedTextField(mMaskFormatter);
mMinTalkgroupField.getDocument().addDocumentListener(this);
mMinTalkgroupField.setToolTipText(HELP_TEXT);
add(mMinTalkgroupField, "growx,push");
add(new JLabel("Max:"));
mMaxTalkgroupField = new JFormattedTextField();
mMaxTalkgroupField.setColumns(10);
mMaxTalkgroupField.setValue(new Integer(0));
mMaxTalkgroupField = new JFormattedTextField(mMaskFormatter);
mMaxTalkgroupField.getDocument().addDocumentListener(this);
mMaxTalkgroupField.setToolTipText(HELP_TEXT);
add(mMaxTalkgroupField, "growx,push");
JLabel help = new JLabel("Help ...");
@@ -113,13 +107,56 @@ public class TalkgroupRangeEditor extends DocumentListenerEditor<AliasID>
@Override
public void mouseClicked(MouseEvent e)
{
TalkgroupFormat talkgroupFormat = TalkgroupFormat.get(getCurrentProtocol());
JOptionPane.showMessageDialog(TalkgroupRangeEditor.this,
HELP_TEXT, "Help", JOptionPane.INFORMATION_MESSAGE);
talkgroupFormat.getValidRangeHelpText(), "Help", JOptionPane.INFORMATION_MESSAGE);
}
});
add(help, "align left");
}
private void updateEditor(Protocol protocol)
{
TalkgroupFormat mask = TalkgroupFormat.get(protocol);
int currentMinValue = 0;
int currentMaxValue = 0;
TalkgroupRange talkgroupRange = getTalkgroupRange();
if(talkgroupRange != null)
{
currentMinValue = talkgroupRange.getMinTalkgroup();
currentMaxValue = talkgroupRange.getMaxTalkgroup();
}
try
{
mMinTalkgroupField.setValue(null);
mMaxTalkgroupField.setValue(null);
mMinTalkgroupField.setToolTipText(mask.getValidRangeHelpText());
mMaxTalkgroupField.setToolTipText(mask.getValidRangeHelpText());
mMaskFormatter.setMask(mask.getMask());
if(mask.getMask().contains("*"))
{
mMaskFormatter.setValidCharacters(VALID_CHARACTERS_FOR_ASTERISK_MASKS);
}
mMinTalkgroupField.setValue(TalkgroupFormatter.format(protocol, currentMinValue));
mMaxTalkgroupField.setValue(TalkgroupFormatter.format(protocol, currentMaxValue));
}
catch(ParseException pe)
{
mLog.error("Error applying talkgroup editor mask to mask formatter [" + mask.getMask() + "]");
}
}
private Protocol getCurrentProtocol()
{
return mComboProtocol.getItemAt(mComboProtocol.getSelectedIndex());
}
public TalkgroupRange getTalkgroupRange()
{
if(getItem() instanceof TalkgroupRange)
@@ -139,9 +176,17 @@ public class TalkgroupRangeEditor extends DocumentListenerEditor<AliasID>
if(talkgroupRange != null)
{
mComboProtocol.setSelectedItem(talkgroupRange.getProtocol());
mMinTalkgroupField.setValue(new Integer(talkgroupRange.getMinTalkgroup()));
mMaxTalkgroupField.setValue(new Integer(talkgroupRange.getMaxTalkgroup()));
mComboProtocol.getModel().setSelectedItem(talkgroupRange.getProtocol());
String minFormatted = TalkgroupFormatter.format(talkgroupRange.getProtocol(), talkgroupRange.getMinTalkgroup());
mMinTalkgroupField.setValue(minFormatted);
String maxFormatted = TalkgroupFormatter.format(talkgroupRange.getProtocol(), talkgroupRange.getMaxTalkgroup());
mMaxTalkgroupField.setValue(maxFormatted);
}
else
{
mComboProtocol.getModel().setSelectedItem(Protocol.UNKNOWN);
mMinTalkgroupField.setValue(TalkgroupFormatter.format(getCurrentProtocol(), 0));
mMaxTalkgroupField.setValue(TalkgroupFormatter.format(getCurrentProtocol(), 0));
}
setModified(false);
@@ -156,28 +201,61 @@ public class TalkgroupRangeEditor extends DocumentListenerEditor<AliasID>
if(talkgroupRange != null)
{
Protocol selected = mComboProtocol.getItemAt(mComboProtocol.getSelectedIndex());
talkgroupRange.setProtocol(selected);
Protocol protocol = mComboProtocol.getItemAt(mComboProtocol.getSelectedIndex());
talkgroupRange.setProtocol(protocol);
int minValue = -1;
int maxValue = -1;
try
{
int minTalkgroup = ((Number)mMinTalkgroupField.getValue()).intValue();
talkgroupRange.setMinTalkgroup(minTalkgroup);
minValue = TalkgroupFormatter.parse(protocol, mMinTalkgroupField.getText());
}
catch(Exception e)
catch(ParseException pe)
{
mLog.error("Error parsing minimum talkgroup value from [" + mMinTalkgroupField.getText() + "]");
//ignore ... value is still -1 and outside valid value range
}
try
{
int maxTalkgroup = ((Number)mMaxTalkgroupField.getValue()).intValue();
talkgroupRange.setMaxTalkgroup(maxTalkgroup);
maxValue = TalkgroupFormatter.parse(protocol, mMaxTalkgroupField.getText());
}
catch(Exception e)
catch(ParseException pe)
{
mLog.error("Error parsing maximum talkgroup value from [" + mMaxTalkgroupField.getText() + "]");
//ignore ... value is still -1 and outside valid value range
}
TalkgroupFormat mask = TalkgroupFormat.get(protocol);
//Check for valid value within range ... notify user but allow value to persist
if(minValue < mask.getMinimumValidValue() || minValue > mask.getMaximumValidValue())
{
String message = "Invalid minimum value [" + mMinTalkgroupField.getText() + "]. " + protocol.name() +
" valid range is [" + mask.getValidRangeDescription() + "]";
JOptionPane.showMessageDialog(TalkgroupRangeEditor.this, message,
"Invalid Talkgroup Value", JOptionPane.ERROR_MESSAGE);
}
else
{
talkgroupRange.setMinTalkgroup(minValue);
}
//Check for valid value within range ... notify user but allow value to persist
if(maxValue < mask.getMinimumValidValue() || maxValue > mask.getMaximumValidValue())
{
String message = "Invalid maximum value [" + mMaxTalkgroupField.getText() + "]. " + protocol.name() +
" valid range is [" + mask.getValidRangeDescription() + "]";
JOptionPane.showMessageDialog(TalkgroupRangeEditor.this, message,
"Invalid Talkgroup Value", JOptionPane.ERROR_MESSAGE);
}
else
{
talkgroupRange.setMaxTalkgroup(maxValue);
}
talkgroupRange.setProtocol(protocol);
}
setModified(false);

View File

@@ -1,10 +1,29 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2019 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 <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.gui.editor;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public abstract class DocumentListenerEditor<T> extends Editor<T>
implements DocumentListener
public abstract class DocumentListenerEditor<T> extends Editor<T> implements DocumentListener
{
private static final long serialVersionUID = 1L;

View File

@@ -1,23 +1,28 @@
/*******************************************************************************
* sdr-trunk
* Copyright (C) 2014-2018 Dennis Sheirer
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2019 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 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.
* 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 <http://www.gnu.org/licenses/>
*
******************************************************************************/
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.mpt1327.identifier;
import io.github.dsheirer.identifier.Role;
import io.github.dsheirer.identifier.talkgroup.TalkgroupIdentifier;
import io.github.dsheirer.preference.identifier.talkgroup.MPT1327TalkgroupFormatter;
import io.github.dsheirer.protocol.Protocol;
/**
@@ -40,35 +45,19 @@ public class MPT1327Talkgroup extends TalkgroupIdentifier
}
/**
* This identifier formatted as PPP-IIII where P=prefix and I=ident
*/
public String formatted()
{
return String.format("%03d-%04d", getPrefix(), getIdent());
}
/**
* Prefix for the talkgroup
* Prefix for this talkgroup
*/
public int getPrefix()
{
return (getValue() >> 13) & 0x7F;
return MPT1327TalkgroupFormatter.getPrefix(getValue());
}
/**
* Ident for the talkgroup
* Ident for this talkgroup
*/
public int getIdent()
{
return getValue() & 0x1FFF;
}
/**
* Indicates the type of ident value
*/
public IdentType getIdentType()
{
return IdentType.fromIdent(getIdent());
return MPT1327TalkgroupFormatter.getIdent(getValue());
}
/**

View File

@@ -1,7 +1,7 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
* Copyright (C) 2014-2019 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
@@ -25,11 +25,11 @@ import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.alias.id.AliasIDType;
import io.github.dsheirer.alias.id.legacy.fleetsync.FleetsyncID;
import io.github.dsheirer.alias.id.legacy.mdc.MDC1200ID;
import io.github.dsheirer.alias.id.legacy.mobileID.Min;
import io.github.dsheirer.alias.id.legacy.mpt1327.MPT1327ID;
import io.github.dsheirer.alias.id.legacy.talkgroup.LegacyTalkgroupID;
import io.github.dsheirer.alias.id.legacy.mobileID.Min;
import io.github.dsheirer.alias.id.talkgroup.Talkgroup;
import io.github.dsheirer.alias.id.legacy.uniqueID.UniqueID;
import io.github.dsheirer.alias.id.talkgroup.Talkgroup;
import io.github.dsheirer.controller.channel.Channel;
import io.github.dsheirer.module.log.EventLogType;
import io.github.dsheirer.module.log.config.EventLogConfiguration;
@@ -308,8 +308,6 @@ public class PlaylistUpdater
{
int value = Integer.valueOf(m.group(3));
value += (Integer.valueOf(m.group(2)) << 8);
value += (Integer.valueOf(m.group(1)) << 13);
toAdd.add(new Talkgroup(Protocol.LTR, value));
it.remove();
updated++;

View File

@@ -1,7 +1,7 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
* Copyright (C) 2014-2019 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
@@ -27,8 +27,10 @@ import io.github.dsheirer.preference.Preference;
import io.github.dsheirer.preference.PreferenceType;
import io.github.dsheirer.preference.identifier.talkgroup.APCO25TalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.FleetsyncTalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.LtrNetTalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.LTRTalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.MDC1200TalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.MPT1327TalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.PassportTalkgroupFormatter;
import io.github.dsheirer.protocol.Protocol;
import io.github.dsheirer.sample.Listener;
import org.slf4j.Logger;
@@ -135,10 +137,6 @@ public class TalkgroupFormatPreference extends Preference
return IntegerFormat.DECIMAL;
case FLEETSYNC:
return IntegerFormat.FORMATTED;
case IPV4:
return IntegerFormat.DECIMAL;
case LOJACK:
return IntegerFormat.DECIMAL;
case LTR:
return IntegerFormat.FORMATTED;
case LTR_NET:
@@ -151,8 +149,6 @@ public class TalkgroupFormatPreference extends Preference
return IntegerFormat.FORMATTED;
case PASSPORT:
return IntegerFormat.DECIMAL;
case TAIT1200:
return IntegerFormat.DECIMAL;
case UNKNOWN:
default:
return IntegerFormat.DECIMAL;
@@ -167,10 +163,6 @@ public class TalkgroupFormatPreference extends Preference
return true;
case FLEETSYNC:
return true;
case IPV4:
return true;
case LOJACK:
return true;
case LTR:
return true;
case LTR_NET:
@@ -183,8 +175,6 @@ public class TalkgroupFormatPreference extends Preference
return true;
case PASSPORT:
return false;
case TAIT1200:
return false;
case UNKNOWN:
default:
return true;
@@ -304,12 +294,21 @@ public class TalkgroupFormatPreference extends Preference
case FLEETSYNC:
return FleetsyncTalkgroupFormatter.format(talkgroupIdentifier, getTalkgroupFormat(Protocol.FLEETSYNC),
isTalkgroupFixedWidth(Protocol.FLEETSYNC));
case LTR_STANDARD:
return LTRTalkgroupFormatter.format(talkgroupIdentifier, getTalkgroupFormat(Protocol.LTR_STANDARD),
isTalkgroupFixedWidth(Protocol.LTR_STANDARD));
case LTR_NET:
return LtrNetTalkgroupFormatter.format(talkgroupIdentifier, getTalkgroupFormat(Protocol.LTR_NET),
return LTRTalkgroupFormatter.format(talkgroupIdentifier, getTalkgroupFormat(Protocol.LTR_NET),
isTalkgroupFixedWidth(Protocol.LTR_NET));
case MDC1200:
return MDC1200TalkgroupFormatter.format(talkgroupIdentifier, getTalkgroupFormat(Protocol.MDC1200),
isTalkgroupFixedWidth(Protocol.MDC1200));
case MPT1327:
return MPT1327TalkgroupFormatter.format(talkgroupIdentifier, getTalkgroupFormat(Protocol.MPT1327),
isTalkgroupFixedWidth(Protocol.MPT1327));
case PASSPORT:
return PassportTalkgroupFormatter.format(talkgroupIdentifier, getTalkgroupFormat(Protocol.PASSPORT),
isTalkgroupFixedWidth(Protocol.PASSPORT));
default:
return talkgroupIdentifier.toString();
}

View File

@@ -1,7 +1,7 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
* Copyright (C) 2014-2019 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
@@ -23,17 +23,25 @@ package io.github.dsheirer.preference.identifier.talkgroup;
import io.github.dsheirer.identifier.talkgroup.TalkgroupIdentifier;
import io.github.dsheirer.module.decode.fleetsync2.identifier.FleetsyncIdentifier;
import io.github.dsheirer.preference.identifier.IntegerFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.ParseException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Formats Fleetsync 20-bit identifiers into either an integer value or an 8-bit fleet and 12-bit ident
*/
public class FleetsyncTalkgroupFormatter extends IntegerFormatter
{
private final static Logger mLog = LoggerFactory.getLogger(FleetsyncTalkgroupFormatter.class);
private static final int IDENTIFIER_DECIMAL_WIDTH = 7;
private static final int IDENTIFIER_HEXADECIMAL_WIDTH = 5;
private static final int FLEET_DECIMAL_WIDTH = 3;
private static final int IDENT_DECIMAL_WIDTH = 4;
private static final String SEPARATOR = "-";
private static final Pattern FLEETSYNC_PATTERN = Pattern.compile("(\\d{1,3})-(\\d{1,4})");
/**
* Formats the individual or group identifier to the specified format and width.
@@ -77,4 +85,72 @@ public class FleetsyncTalkgroupFormatter extends IntegerFormatter
return identifier.toString();
}
@Override
public String format(int talkgroup)
{
return toDecimal(getPrefix(talkgroup), FLEET_DECIMAL_WIDTH) + SEPARATOR +
toDecimal(getIdent(talkgroup), IDENT_DECIMAL_WIDTH);
}
@Override
public int parse(String formattedTalkgroup) throws ParseException
{
if(formattedTalkgroup != null)
{
Matcher m = FLEETSYNC_PATTERN.matcher(formattedTalkgroup);
if(m.matches())
{
String rawPrefix = m.group(1);
String rawIdent = m.group(2);
try
{
int prefix = Integer.parseInt(rawPrefix);
if(prefix < 1 || prefix > 127)
{
throw new ParseException("Fleetsync prefix must be in range 1-127. Error parsing [" + formattedTalkgroup + "]", 0);
}
int ident = Integer.parseInt(rawIdent);
if(ident < 1 || ident > 8191)
{
throw new ParseException("Fleetsync ident must be in range 1-8192. Error parsing [" + formattedTalkgroup + "]", 0);
}
return (prefix << 13) + ident;
}
catch(Exception e)
{
//exception is rethrown below
}
}
}
throw new ParseException("Error parsing value from fleetsync talkgroup [" + formattedTalkgroup + "]", 0);
}
/**
* Prefix for the specified talkgroup value
* @param talkgroup value containing a prefix
* @return prefix value
*/
public static int getPrefix(int talkgroup)
{
return (talkgroup >> 13) & 0x7F;
}
/**
* Ident for the specified talkgroup
* @param talkgroup containing an ident
* @return ident value
*/
public static int getIdent(int talkgroup)
{
return talkgroup & 0x1FFF;
}
}

View File

@@ -1,7 +1,7 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
* Copyright (C) 2014-2019 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
@@ -23,6 +23,8 @@ package io.github.dsheirer.preference.identifier.talkgroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.ParseException;
/**
* Base formatter class for integer values
*/
@@ -44,4 +46,34 @@ public class IntegerFormatter
{
return String.format("%0" + width + "d", value);
}
/**
* Formats the integer value for display as a string.
*
* Subclass implementations should override this method to return formatted values.
*/
public String format(int value)
{
return String.valueOf(value);
}
/**
* Parses an integer value from the formatted string value
*
* Subclass implementations should override this method to provide custom parsing of formatted values
*/
public int parse(String formattedValue) throws ParseException
{
try
{
return Integer.parseInt(formattedValue.trim());
}
catch(Exception e)
{
//exception re-thrown below
}
mLog.error("Throwing a parse exception for value [" + formattedValue + "]");
throw new ParseException("Error parsing integer value from [" + formattedValue + "]", 0);
}
}

View File

@@ -0,0 +1,163 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2019 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 <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.preference.identifier.talkgroup;
import io.github.dsheirer.identifier.talkgroup.LTRTalkgroup;
import io.github.dsheirer.identifier.talkgroup.TalkgroupIdentifier;
import io.github.dsheirer.preference.identifier.IntegerFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.ParseException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Formats LTR identifiers
*/
public class LTRTalkgroupFormatter extends IntegerFormatter
{
private final static Logger mLog = LoggerFactory.getLogger(LTRTalkgroupFormatter.class);
private static final int IDENTIFIER_DECIMAL_WIDTH = 4;
private static final int IDENTIFIER_HEXADECIMAL_WIDTH = 4;
private static final int HOME_REPEATER_DECIMAL_WIDTH = 2;
private static final int TALKGROUP_DECIMAL_WIDTH = 3;
private static final String SEPARATOR = "-";
private static final Pattern LTR_PATTERN = Pattern.compile("(\\d{1,2})-(\\d{1,3})");
/**
* Formats the group identifier to the specified format and width.
*/
public static String format(TalkgroupIdentifier identifier, IntegerFormat format, boolean fixedWidth)
{
if(identifier instanceof LTRTalkgroup)
{
LTRTalkgroup ltr = (LTRTalkgroup)identifier;
if(fixedWidth)
{
switch(format)
{
case DECIMAL:
return toDecimal(ltr.getValue(), IDENTIFIER_DECIMAL_WIDTH);
case FORMATTED:
return toDecimal(ltr.getHomeChannel(), HOME_REPEATER_DECIMAL_WIDTH) + SEPARATOR +
toDecimal(ltr.getTalkgroup(), TALKGROUP_DECIMAL_WIDTH);
case HEXADECIMAL:
return toHex(ltr.getValue(), IDENTIFIER_HEXADECIMAL_WIDTH);
default:
throw new IllegalArgumentException("Unrecognized integer format: " + format);
}
}
else
{
switch(format)
{
case DECIMAL:
return ltr.toString();
case FORMATTED:
return ltr.getHomeChannel() + SEPARATOR + ltr.getTalkgroup();
case HEXADECIMAL:
return toHex(identifier.getValue());
default:
throw new IllegalArgumentException("Unrecognized integer format: " + format);
}
}
}
return identifier.toString();
}
/**
* Parses an integer value from a formatted talkgroup string (e.g. 12-243)
*/
public int parse(String formattedTalkgroup) throws ParseException
{
if(formattedTalkgroup != null)
{
Matcher m = LTR_PATTERN.matcher(formattedTalkgroup);
if(m.matches())
{
String rawLcn = m.group(1);
String rawGroup = m.group(2);
try
{
int lcn = Integer.parseInt(rawLcn);
if(lcn < 1 || lcn > 20)
{
throw new ParseException("LTR repeater must be in range 1-20. Error parsing [" + formattedTalkgroup + "]", 0);
}
int group = Integer.parseInt(rawGroup);
if(group < 0 || group > 255)
{
throw new ParseException("LTR talkgroup must be in range 1-255. Error parsing [" + formattedTalkgroup + "]", 0);
}
return (lcn << 8) + group;
}
catch(Exception e)
{
//exception is rethrown below
}
}
}
throw new ParseException("Error parsing LTR talkgroup [" + formattedTalkgroup + "]", 0);
}
/**
* Formats the talkgroup as a string
* @param talkgroup to format
* @return formatted talkgroup
*/
public String format(int talkgroup)
{
return toDecimal(getLcn(talkgroup), HOME_REPEATER_DECIMAL_WIDTH) + SEPARATOR +
toDecimal(getTalkgroup(talkgroup), TALKGROUP_DECIMAL_WIDTH);
}
/**
* LCN for the specified talkgroup value
* @param value containing an LCN prefix
* @return lcn value
*/
public static int getLcn(int value)
{
return (value >> 8) & 0x1F;
}
/**
* Talkgroup value for the specified composite talkgroup
* @param value containing an LCN and talkgroup value
* @return talkgroup value
*/
public static int getTalkgroup(int value)
{
return value & 0xFF;
}
}

View File

@@ -1,80 +0,0 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 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 <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.preference.identifier.talkgroup;
import io.github.dsheirer.identifier.talkgroup.LTRTalkgroup;
import io.github.dsheirer.identifier.talkgroup.TalkgroupIdentifier;
import io.github.dsheirer.preference.identifier.IntegerFormat;
/**
* Formats Fleetsync 20-bit identifiers into either an integer value or an 8-bit fleet and 12-bit ident
*/
public class LtrNetTalkgroupFormatter extends IntegerFormatter
{
private static final int IDENTIFIER_DECIMAL_WIDTH = 4;
private static final int IDENTIFIER_HEXADECIMAL_WIDTH = 4;
private static final int HOME_REPEATER_DECIMAL_WIDTH = 2;
private static final int TALKGROUP_DECIMAL_WIDTH = 3;
private static final String SEPARATOR = "-";
/**
* Formats the individual or group identifier to the specified format and width.
*/
public static String format(TalkgroupIdentifier identifier, IntegerFormat format, boolean fixedWidth)
{
if(identifier instanceof LTRTalkgroup)
{
LTRTalkgroup ltrnet = (LTRTalkgroup)identifier;
if(fixedWidth)
{
switch(format)
{
case DECIMAL:
return toDecimal(ltrnet.getValue(), IDENTIFIER_DECIMAL_WIDTH);
case FORMATTED:
return toDecimal(ltrnet.getHomeChannel(), HOME_REPEATER_DECIMAL_WIDTH) + SEPARATOR +
toDecimal(ltrnet.getTalkgroup(), TALKGROUP_DECIMAL_WIDTH);
case HEXADECIMAL:
return toHex(ltrnet.getValue(), IDENTIFIER_HEXADECIMAL_WIDTH);
default:
throw new IllegalArgumentException("Unrecognized integer format: " + format);
}
}
else
{
switch(format)
{
case DECIMAL:
return ltrnet.toString();
case FORMATTED:
return ltrnet.getHomeChannel() + SEPARATOR + ltrnet.getTalkgroup();
case HEXADECIMAL:
return toHex(identifier.getValue());
default:
throw new IllegalArgumentException("Unrecognized integer format: " + format);
}
}
}
return identifier.toString();
}
}

View File

@@ -0,0 +1,62 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2019 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 <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.preference.identifier.talkgroup;
import io.github.dsheirer.identifier.talkgroup.TalkgroupIdentifier;
import io.github.dsheirer.preference.identifier.IntegerFormat;
public class MDC1200TalkgroupFormatter extends IntegerFormatter
{
public static final int DECIMAL_WIDTH = 5;
public static final int HEXADECIMAL_WIDTH = 4;
/**
* Formats the individual or group identifier to the specified format and width.
*/
public static String format(TalkgroupIdentifier identifier, IntegerFormat format, boolean fixedWidth)
{
if(fixedWidth)
{
switch(format)
{
case DECIMAL:
return toDecimal(identifier.getValue(), DECIMAL_WIDTH);
case HEXADECIMAL:
return toHex(identifier.getValue(), HEXADECIMAL_WIDTH);
default:
throw new IllegalArgumentException("Unrecognized integer format: " + format);
}
}
else
{
switch(format)
{
case DECIMAL:
case FORMATTED:
return identifier.getValue().toString();
case HEXADECIMAL:
return toHex(identifier.getValue());
default:
throw new IllegalArgumentException("Unrecognized integer format: " + format);
}
}
}
}

View File

@@ -1,7 +1,7 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
* Copyright (C) 2014-2019 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
@@ -23,17 +23,26 @@ package io.github.dsheirer.preference.identifier.talkgroup;
import io.github.dsheirer.identifier.talkgroup.TalkgroupIdentifier;
import io.github.dsheirer.module.decode.mpt1327.identifier.MPT1327Talkgroup;
import io.github.dsheirer.preference.identifier.IntegerFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.ParseException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Formats Fleetsync 20-bit identifiers into either an integer value or an 8-bit fleet and 12-bit ident
*/
public class MPT1327TalkgroupFormatter extends IntegerFormatter
{
private final static Logger mLog = LoggerFactory.getLogger(MPT1327TalkgroupFormatter.class);
private static final int IDENTIFIER_DECIMAL_WIDTH = 7;
private static final int IDENTIFIER_HEXADECIMAL_WIDTH = 5;
private static final int FLEET_DECIMAL_WIDTH = 3;
private static final int IDENT_DECIMAL_WIDTH = 4;
private static final String SEPARATOR = "-";
private static final Pattern MPT1327_PATTERN = Pattern.compile("(\\d{1,3})-(\\d{1,4})");
/**
* Formats the individual or group identifier to the specified format and width.
@@ -77,4 +86,78 @@ public class MPT1327TalkgroupFormatter extends IntegerFormatter
return identifier.toString();
}
/**
* Parses an integer value from a formatted talkgroup string (e.g. 123-4567)
*/
public int parse(String formattedTalkgroup) throws ParseException
{
if(formattedTalkgroup != null)
{
Matcher m = MPT1327_PATTERN.matcher(formattedTalkgroup);
if(m.matches())
{
String rawPrefix = m.group(1);
String rawIdent = m.group(2);
try
{
int prefix = Integer.parseInt(rawPrefix);
if(prefix < 0 || prefix > 127)
{
throw new ParseException("MPT-1327 prefix must be in range 0-127. Error parsing [" + formattedTalkgroup + "]", 0);
}
int ident = Integer.parseInt(rawIdent);
if(ident < 1 || ident > 8191)
{
throw new ParseException("MPT-1327 ident must be in range 1-8192. Error parsing [" + formattedTalkgroup + "]", 0);
}
return (prefix << 13) + ident;
}
catch(Exception e)
{
//exception is rethrown below
}
}
}
throw new ParseException("Error parsing MPT1327 talkgroup value [" + formattedTalkgroup + "]", 0);
}
/**
* Formats the MPT-1327 talkgroup as a string
* @param talkgroup to format
* @return formatted talkgroup
*/
public String format(int talkgroup)
{
return toDecimal(getPrefix(talkgroup), FLEET_DECIMAL_WIDTH) + SEPARATOR + toDecimal(getIdent(talkgroup), IDENT_DECIMAL_WIDTH);
}
/**
* Prefix for the specified talkgroup value
* @param talkgroup value containing a prefix
* @return prefix value
*/
public static int getPrefix(int talkgroup)
{
return (talkgroup >> 13) & 0x7F;
}
/**
* Ident for the specified talkgroup
* @param talkgroup containing an ident
* @return ident value
*/
public static int getIdent(int talkgroup)
{
return talkgroup & 0x1FFF;
}
}

View File

@@ -0,0 +1,62 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2019 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 <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.preference.identifier.talkgroup;
import io.github.dsheirer.identifier.talkgroup.TalkgroupIdentifier;
import io.github.dsheirer.preference.identifier.IntegerFormat;
public class PassportTalkgroupFormatter extends IntegerFormatter
{
public static final int DECIMAL_WIDTH = 5;
public static final int HEXADECIMAL_WIDTH = 4;
/**
* Formats the individual or group identifier to the specified format and width.
*/
public static String format(TalkgroupIdentifier identifier, IntegerFormat format, boolean fixedWidth)
{
if(fixedWidth)
{
switch(format)
{
case DECIMAL:
return toDecimal(identifier.getValue(), DECIMAL_WIDTH);
case HEXADECIMAL:
return toHex(identifier.getValue(), HEXADECIMAL_WIDTH);
default:
throw new IllegalArgumentException("Unrecognized integer format: " + format);
}
}
else
{
switch(format)
{
case DECIMAL:
case FORMATTED:
return identifier.getValue().toString();
case HEXADECIMAL:
return toHex(identifier.getValue());
default:
throw new IllegalArgumentException("Unrecognized integer format: " + format);
}
}
}
}

View File

@@ -1,7 +1,7 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
* Copyright (C) 2014-2019 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
@@ -52,7 +52,7 @@ public enum Protocol
}
public static EnumSet<Protocol> TALKGROUP_PROTOCOLS = EnumSet.of(APCO25, FLEETSYNC, LTR_NET, LTR_STANDARD, MDC1200,
MPT1327, PASSPORT, TAIT1200);
MPT1327, PASSPORT);
@Override
public String toString()