mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 08:37:25 -05:00
* P25 Phase 2 now supports control channel decoding and decoder was enhanced to improve decodes. * Radio reference site editor updated for phase 2 sites to allow user to select FDMA or TDMA control. * Decode events are now minimized and de-duplicated. * Fully parsing all phase 1/2 messages from the latest ICD. * Vendor specific messaging recoveries (Moto & Harris). * Patch group management enhancements with stale patch detection. * Tuner editor now fully resets the min/max frequency values * Default traffic channel count increased to 20 (from 3). * ISSI roaming radio and talkgroup values now displayed and aliasable as fully qualified values (e.g. 1234(123.456.7890) * Moto emergency alarm activation messaging support * Expanded list of P25 encryption algorithms * Message (bits) viewer enhanced for P25 phase 1 and phase 2 * IPV4 addresses and UDP ports no longer classified as user values - won't display in event views. * New framework for describing message binary fields that should reduce overall memory footprint and enhance code readability Co-authored-by: Dennis Sheirer <dsheirer@github.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2023 Dennis Sheirer
|
||||
* Copyright (C) 2014-2024 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
|
||||
@@ -21,31 +21,41 @@ package io.github.dsheirer.preference.identifier.talkgroup;
|
||||
|
||||
import io.github.dsheirer.identifier.patch.PatchGroup;
|
||||
import io.github.dsheirer.identifier.patch.PatchGroupIdentifier;
|
||||
import io.github.dsheirer.identifier.radio.FullyQualifiedRadioIdentifier;
|
||||
import io.github.dsheirer.identifier.radio.RadioIdentifier;
|
||||
import io.github.dsheirer.identifier.talkgroup.FullyQualifiedTalkgroupIdentifier;
|
||||
import io.github.dsheirer.identifier.talkgroup.TalkgroupIdentifier;
|
||||
import io.github.dsheirer.preference.identifier.IntegerFormat;
|
||||
|
||||
public class APCO25TalkgroupFormatter extends AbstractIntegerFormatter
|
||||
{
|
||||
public static final int GROUP_DECIMAL_WIDTH = 5;
|
||||
public static final int UNIT_DECIMAL_WIDTH = 8;
|
||||
public static final int GROUP_HEXADECIMAL_WIDTH = 4;
|
||||
public static final int UNIT_HEXADECIMAL_WIDTH = 6;
|
||||
public static final int RADIO_DECIMAL_WIDTH = 8;
|
||||
public static final int RADIO_HEXADECIMAL_WIDTH = 6;
|
||||
public static final int SYSTEM_HEXADECIMAL_WIDTH = 3;
|
||||
public static final int TALKGROUP_DECIMAL_WIDTH = 5;
|
||||
public static final int TALKGROUP_HEXADECIMAL_WIDTH = 4;
|
||||
public static final int WACN_HEXADECIMAL_WIDTH = 5;
|
||||
|
||||
|
||||
/**
|
||||
* 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 FullyQualifiedTalkgroupIdentifier fqti)
|
||||
{
|
||||
return format(fqti, format, fixedWidth);
|
||||
}
|
||||
|
||||
if(fixedWidth)
|
||||
{
|
||||
switch(format)
|
||||
{
|
||||
case DECIMAL:
|
||||
case FORMATTED:
|
||||
return toDecimal(identifier.getValue(), GROUP_DECIMAL_WIDTH);
|
||||
return toDecimal(identifier.getValue(), TALKGROUP_DECIMAL_WIDTH);
|
||||
case HEXADECIMAL:
|
||||
return toHex(identifier.getValue(), GROUP_HEXADECIMAL_WIDTH);
|
||||
return toHex(identifier.getValue(), TALKGROUP_HEXADECIMAL_WIDTH);
|
||||
default:
|
||||
throw new IllegalArgumentException("Unrecognized integer format: " + format);
|
||||
}
|
||||
@@ -65,6 +75,62 @@ public class APCO25TalkgroupFormatter extends AbstractIntegerFormatter
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the fully qualified group identifier to the specified format and width.
|
||||
*/
|
||||
public static String format(FullyQualifiedTalkgroupIdentifier identifier, IntegerFormat format, boolean fixedWidth)
|
||||
{
|
||||
int id = identifier.getValue();
|
||||
int wacn = identifier.getWacn();
|
||||
int system = identifier.getSystem();
|
||||
int talkgroup = identifier.getTalkgroup();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if(fixedWidth)
|
||||
{
|
||||
switch(format)
|
||||
{
|
||||
case DECIMAL:
|
||||
case FORMATTED:
|
||||
sb.append(toDecimal(id, TALKGROUP_DECIMAL_WIDTH));
|
||||
sb.append("(").append(toHex(wacn, WACN_HEXADECIMAL_WIDTH));
|
||||
sb.append(".").append(toHex(system, SYSTEM_HEXADECIMAL_WIDTH));
|
||||
sb.append(".").append(toDecimal(talkgroup, TALKGROUP_DECIMAL_WIDTH)).append(")");
|
||||
return sb.toString();
|
||||
case HEXADECIMAL:
|
||||
sb.append(toHex(id, TALKGROUP_HEXADECIMAL_WIDTH));
|
||||
sb.append("(").append(toHex(wacn, WACN_HEXADECIMAL_WIDTH));
|
||||
sb.append(".").append(toHex(system, SYSTEM_HEXADECIMAL_WIDTH));
|
||||
sb.append(".").append(toHex(talkgroup, TALKGROUP_HEXADECIMAL_WIDTH)).append(")");
|
||||
return sb.toString();
|
||||
default:
|
||||
throw new IllegalArgumentException("Unrecognized integer format: " + format);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(format)
|
||||
{
|
||||
case DECIMAL:
|
||||
case FORMATTED:
|
||||
sb.append(id);
|
||||
sb.append("(").append(toHex(wacn, WACN_HEXADECIMAL_WIDTH));
|
||||
sb.append(".").append(toHex(system, SYSTEM_HEXADECIMAL_WIDTH));
|
||||
sb.append(".").append(talkgroup).append(")");
|
||||
return sb.toString();
|
||||
case HEXADECIMAL:
|
||||
sb.append(toHex(id));
|
||||
sb.append("(").append(toHex(wacn, WACN_HEXADECIMAL_WIDTH));
|
||||
sb.append(".").append(toHex(system, SYSTEM_HEXADECIMAL_WIDTH));
|
||||
sb.append(".").append(toHex(talkgroup)).append(")");
|
||||
return sb.toString();
|
||||
default:
|
||||
throw new IllegalArgumentException("Unrecognized integer format: " + format);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the patch group to the specified format and width
|
||||
*/
|
||||
@@ -110,15 +176,20 @@ public class APCO25TalkgroupFormatter extends AbstractIntegerFormatter
|
||||
*/
|
||||
public static String format(RadioIdentifier identifier, IntegerFormat format, boolean fixedWidth)
|
||||
{
|
||||
if(identifier instanceof FullyQualifiedRadioIdentifier fqri)
|
||||
{
|
||||
return format(fqri, format, fixedWidth);
|
||||
}
|
||||
|
||||
if(fixedWidth)
|
||||
{
|
||||
switch(format)
|
||||
{
|
||||
case DECIMAL:
|
||||
case FORMATTED:
|
||||
return toDecimal(identifier.getValue(), UNIT_DECIMAL_WIDTH);
|
||||
return toDecimal(identifier.getValue(), RADIO_DECIMAL_WIDTH);
|
||||
case HEXADECIMAL:
|
||||
return toHex(identifier.getValue(), UNIT_HEXADECIMAL_WIDTH);
|
||||
return toHex(identifier.getValue(), RADIO_HEXADECIMAL_WIDTH);
|
||||
default:
|
||||
throw new IllegalArgumentException("Unrecognized integer format: " + format);
|
||||
}
|
||||
@@ -138,6 +209,62 @@ public class APCO25TalkgroupFormatter extends AbstractIntegerFormatter
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the fully qualified radio identifier to the specified format and width.
|
||||
*/
|
||||
public static String format(FullyQualifiedRadioIdentifier identifier, IntegerFormat format, boolean fixedWidth)
|
||||
{
|
||||
int id = identifier.getValue();
|
||||
int wacn = identifier.getWacn();
|
||||
int system = identifier.getSystem();
|
||||
int radio = identifier.getRadio();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if(fixedWidth)
|
||||
{
|
||||
switch(format)
|
||||
{
|
||||
case DECIMAL:
|
||||
case FORMATTED:
|
||||
sb.append(toDecimal(id, RADIO_DECIMAL_WIDTH));
|
||||
sb.append("(").append(toHex(wacn, WACN_HEXADECIMAL_WIDTH));
|
||||
sb.append(".").append(toHex(system, SYSTEM_HEXADECIMAL_WIDTH));
|
||||
sb.append(".").append(toDecimal(radio, RADIO_DECIMAL_WIDTH)).append(")");
|
||||
return sb.toString();
|
||||
case HEXADECIMAL:
|
||||
sb.append(toHex(id, RADIO_HEXADECIMAL_WIDTH));
|
||||
sb.append("(").append(toHex(wacn, WACN_HEXADECIMAL_WIDTH));
|
||||
sb.append(".").append(toHex(system, SYSTEM_HEXADECIMAL_WIDTH));
|
||||
sb.append(".").append(toHex(radio, RADIO_HEXADECIMAL_WIDTH)).append(")");
|
||||
return sb.toString();
|
||||
default:
|
||||
throw new IllegalArgumentException("Unrecognized integer format: " + format);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(format)
|
||||
{
|
||||
case DECIMAL:
|
||||
case FORMATTED:
|
||||
sb.append(id);
|
||||
sb.append("(").append(toHex(wacn, WACN_HEXADECIMAL_WIDTH));
|
||||
sb.append(".").append(toHex(system, SYSTEM_HEXADECIMAL_WIDTH));
|
||||
sb.append(".").append(radio).append(")");
|
||||
return sb.toString();
|
||||
case HEXADECIMAL:
|
||||
sb.append(toHex(id));
|
||||
sb.append("(").append(toHex(wacn, WACN_HEXADECIMAL_WIDTH));
|
||||
sb.append(".").append(toHex(system, SYSTEM_HEXADECIMAL_WIDTH));
|
||||
sb.append(".").append(toHex(radio)).append(")");
|
||||
return sb.toString();
|
||||
default:
|
||||
throw new IllegalArgumentException("Unrecognized integer format: " + format);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String format(int value, IntegerFormat integerFormat)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user