mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 16:47:31 -05:00
#1637 Resolves issue with DMR Cap+/CapMax trunking channel to frequency map. Updates the DMR channel map to use LCN instead of LSN and aligns standard DMR with Tier-III DMR for channel identification.
Warning: breaking change. Users will need to either recreate their DMR channel to frequency maps or simply delete and reload the channel from Radio Reference to correct the channel to frequency map. Updates the DMR Decoder State to better track and update DMR events versus creating a new event and causing lots of scrolling in the event window of the Now Playing tab.
This commit is contained in:
@@ -23,6 +23,7 @@ import io.github.dsheirer.buffer.INativeBufferProvider;
|
||||
import io.github.dsheirer.controller.channel.event.ChannelStopProcessingRequest;
|
||||
import io.github.dsheirer.dsp.filter.design.FilterDesignException;
|
||||
import io.github.dsheirer.eventbus.MyEventBus;
|
||||
import io.github.dsheirer.log.LoggingSuppressor;
|
||||
import io.github.dsheirer.sample.Broadcaster;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.complex.InterleavedComplexSamples;
|
||||
@@ -65,6 +66,7 @@ import org.slf4j.LoggerFactory;
|
||||
public class PolyphaseChannelManager implements ISourceEventProcessor
|
||||
{
|
||||
private static final DecimalFormat FREQUENCY_FORMAT = new DecimalFormat("0.00000");
|
||||
private static final LoggingSuppressor LOGGING_SUPPRESSOR = new LoggingSuppressor(LoggerFactory.getLogger(PolyphaseChannelManager.class));
|
||||
private final static Logger mLog = LoggerFactory.getLogger(PolyphaseChannelManager.class);
|
||||
private static final double MINIMUM_CHANNEL_BANDWIDTH = 25000.0;
|
||||
private static final double CHANNEL_OVERSAMPLING = 2.0;
|
||||
@@ -203,7 +205,8 @@ public class PolyphaseChannelManager implements ISourceEventProcessor
|
||||
}
|
||||
catch(IllegalArgumentException iae)
|
||||
{
|
||||
mLog.debug("Couldn't design final output low pass filter for polyphase channel source");
|
||||
LOGGING_SUPPRESSOR.error(iae.getMessage(), 3, "Couldn't allocate channel. " + iae.getMessage());
|
||||
channelSource = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ public class DMRConfigurationEditor extends ChannelConfigurationEditor
|
||||
private ToggleSwitch mUseCompressedTalkgroupsToggle;
|
||||
private Spinner<Integer> mTrafficChannelPoolSizeSpinner;
|
||||
private TableView<TimeslotFrequency> mTimeslotFrequencyTable;
|
||||
private IntegerTextField mLogicalSlotNumberField;
|
||||
private IntegerTextField mLogicalChannelNumberField;
|
||||
private FrequencyField mDownlinkFrequencyField;
|
||||
// private FrequencyField mUplinkFrequencyField;
|
||||
private Button mAddTimeslotFrequencyButton;
|
||||
@@ -172,7 +172,7 @@ public class DMRConfigurationEditor extends ChannelConfigurationEditor
|
||||
GridPane.setConstraints(useCompressedTalkgroupsLabel, 7, row);
|
||||
gridPane.getChildren().add(useCompressedTalkgroupsLabel);
|
||||
|
||||
Label timeslotTableLabel = new Label("Logical Slot Number (LSN) to Frequency Map. Required for: Connect Plus and Tier-III systems that don't use absolute frequencies");
|
||||
Label timeslotTableLabel = new Label("Logical Channel Number (LCN) to Frequency Map. Required for: Connect Plus and Tier-III systems that don't use absolute frequencies. LSN = Logical Slot Number");
|
||||
GridPane.setHalignment(timeslotTableLabel, HPos.LEFT);
|
||||
GridPane.setConstraints(timeslotTableLabel, 0, ++row, 6, 1);
|
||||
gridPane.getChildren().add(timeslotTableLabel);
|
||||
@@ -194,17 +194,13 @@ public class DMRConfigurationEditor extends ChannelConfigurationEditor
|
||||
editorBox.setAlignment(Pos.CENTER_LEFT);
|
||||
editorBox.setSpacing(5);
|
||||
|
||||
Label lsnLabel = new Label("LSN");
|
||||
editorBox.getChildren().addAll(lsnLabel,getLogicalSlotNumberField());
|
||||
Label lcnLabel = new Label("LCN");
|
||||
editorBox.getChildren().addAll(lcnLabel, getLogicalChannelNumberField());
|
||||
|
||||
Label downlinkLabel = new Label("Frequency (MHz)");
|
||||
downlinkLabel.setPadding(new Insets(0,0,0,5));
|
||||
editorBox.getChildren().addAll(downlinkLabel,getDownlinkFrequencyField());
|
||||
|
||||
// Label uplinkLabel = new Label("Uplink");
|
||||
// uplinkLabel.setPadding(new Insets(0,0,0,5));
|
||||
// editorBox.getChildren().addAll(uplinkLabel,getUplinkFrequencyField());
|
||||
|
||||
GridPane.setConstraints(editorBox, 0, row, 4, 1);
|
||||
gridPane.getChildren().add(editorBox);
|
||||
|
||||
@@ -287,20 +283,22 @@ public class DMRConfigurationEditor extends ChannelConfigurationEditor
|
||||
mTimeslotFrequencyTable = new TableView<>(FXCollections.observableArrayList(TimeslotFrequency.extractor()));
|
||||
mTimeslotFrequencyTable.setPrefHeight(100.0);
|
||||
|
||||
TableColumn<TimeslotFrequency,Number> numberColumn = new TableColumn("LSN");
|
||||
numberColumn.setPrefWidth(70);
|
||||
TableColumn<TimeslotFrequency,Number> numberColumn = new TableColumn("LCN");
|
||||
numberColumn.setPrefWidth(75);
|
||||
numberColumn.setCellValueFactory(cellData -> cellData.getValue().getNumberProperty());
|
||||
mTimeslotFrequencyTable.getColumns().addAll(numberColumn);
|
||||
mTimeslotFrequencyTable.getSortOrder().add(numberColumn);
|
||||
|
||||
TableColumn<TimeslotFrequency,Number> downlinkColumn = new TableColumn("Frequency (MHz)");
|
||||
downlinkColumn.setCellValueFactory(cellData -> cellData.getValue().getDownlinkMHz());
|
||||
downlinkColumn.setPrefWidth(175);
|
||||
downlinkColumn.setPrefWidth(150);
|
||||
mTimeslotFrequencyTable.getColumns().addAll(downlinkColumn);
|
||||
|
||||
// TableColumn<TimeslotFrequency,Number> uplinkColumn = new TableColumn("Uplink (MHz)");
|
||||
// uplinkColumn.setCellValueFactory(cellData -> cellData.getValue().getUplinkMHz());
|
||||
// mTimeslotFrequencyTable.getColumns().addAll(uplinkColumn);
|
||||
TableColumn<TimeslotFrequency,String> lsnColumn = new TableColumn("IDs (TS1/TS2)");
|
||||
lsnColumn.setPrefWidth(225);
|
||||
lsnColumn.setCellValueFactory(new PropertyValueFactory<>("logicalSlotNumbers"));
|
||||
mTimeslotFrequencyTable.getColumns().addAll(lsnColumn);
|
||||
|
||||
|
||||
mTimeslotFrequencyTable.getSelectionModel().selectedItemProperty()
|
||||
.addListener((observable, oldValue, newValue) -> setTimeslot(newValue));
|
||||
@@ -317,20 +315,20 @@ public class DMRConfigurationEditor extends ChannelConfigurationEditor
|
||||
//Preserve the current modified flag state since setting values in the editor will change it.
|
||||
boolean modified = modifiedProperty().get();
|
||||
|
||||
getLogicalSlotNumberField().setDisable(timeslot == null);
|
||||
getLogicalChannelNumberField().setDisable(timeslot == null);
|
||||
getDownlinkFrequencyField().setDisable(timeslot == null);
|
||||
// getUplinkFrequencyField().setDisable(timeslot == null);
|
||||
getDeleteTimeslotFrequencyButton().setDisable(timeslot == null);
|
||||
|
||||
if(timeslot != null)
|
||||
{
|
||||
getLogicalSlotNumberField().set(timeslot.getNumber());
|
||||
getLogicalChannelNumberField().set(timeslot.getNumber());
|
||||
getDownlinkFrequencyField().set(timeslot.getDownlinkFrequency());
|
||||
// getUplinkFrequencyField().set(timeslot.getUplinkFrequency());
|
||||
}
|
||||
else
|
||||
{
|
||||
getLogicalSlotNumberField().set(0);
|
||||
getLogicalChannelNumberField().set(0);
|
||||
getDownlinkFrequencyField().set(0);
|
||||
// getUplinkFrequencyField().set(0);
|
||||
}
|
||||
@@ -412,19 +410,19 @@ public class DMRConfigurationEditor extends ChannelConfigurationEditor
|
||||
return mDeleteTimeslotFrequencyButton;
|
||||
}
|
||||
|
||||
private IntegerTextField getLogicalSlotNumberField()
|
||||
private IntegerTextField getLogicalChannelNumberField()
|
||||
{
|
||||
if(mLogicalSlotNumberField == null)
|
||||
if(mLogicalChannelNumberField == null)
|
||||
{
|
||||
mLogicalSlotNumberField = new IntegerTextField();
|
||||
mLogicalSlotNumberField.setDisable(true);
|
||||
mLogicalSlotNumberField.setPrefWidth(65);
|
||||
mLogicalSlotNumberField.textProperty().addListener((observable, oldValue, newValue) -> {
|
||||
mLogicalChannelNumberField = new IntegerTextField();
|
||||
mLogicalChannelNumberField.setDisable(true);
|
||||
mLogicalChannelNumberField.setPrefWidth(65);
|
||||
mLogicalChannelNumberField.textProperty().addListener((observable, oldValue, newValue) -> {
|
||||
TimeslotFrequency selected = getTimeslotTable().getSelectionModel().getSelectedItem();
|
||||
|
||||
if(selected != null)
|
||||
{
|
||||
Integer value = mLogicalSlotNumberField.get();
|
||||
Integer value = mLogicalChannelNumberField.get();
|
||||
|
||||
if(value != null)
|
||||
{
|
||||
@@ -436,7 +434,7 @@ public class DMRConfigurationEditor extends ChannelConfigurationEditor
|
||||
});
|
||||
}
|
||||
|
||||
return mLogicalSlotNumberField;
|
||||
return mLogicalChannelNumberField;
|
||||
}
|
||||
|
||||
private FrequencyField getDownlinkFrequencyField()
|
||||
@@ -610,8 +608,8 @@ public class DMRConfigurationEditor extends ChannelConfigurationEditor
|
||||
getTimeslotTable().setDisable(config == null);
|
||||
getAddTimeslotFrequencyButton().setDisable(config == null);
|
||||
getDeleteTimeslotFrequencyButton().setDisable(true);
|
||||
getLogicalSlotNumberField().set(0);
|
||||
getLogicalSlotNumberField().setDisable(true);
|
||||
getLogicalChannelNumberField().set(0);
|
||||
getLogicalChannelNumberField().setDisable(true);
|
||||
getDownlinkFrequencyField().set(0);
|
||||
getDownlinkFrequencyField().setDisable(true);
|
||||
// getUplinkFrequencyField().set(0);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -41,13 +41,12 @@ import io.github.dsheirer.rrapi.type.Tag;
|
||||
import io.github.dsheirer.rrapi.type.Talkgroup;
|
||||
import io.github.dsheirer.rrapi.type.Type;
|
||||
import io.github.dsheirer.rrapi.type.Voice;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Utility class for decoding type, flavor and voice for systems and formatting talkgroups according to user preferences.
|
||||
@@ -374,16 +373,10 @@ public class RadioReferenceDecoder
|
||||
}
|
||||
}
|
||||
|
||||
int lsn = (lcn - 1) * 2 + 1;
|
||||
TimeslotFrequency timeslot1Frequency = new TimeslotFrequency();
|
||||
timeslot1Frequency.setNumber(lsn);
|
||||
timeslot1Frequency.setDownlinkFrequency((long)(siteFrequency.getFrequency() * 1E6));
|
||||
frequencies.add(timeslot1Frequency);
|
||||
|
||||
TimeslotFrequency timeslot2Frequency = new TimeslotFrequency();
|
||||
timeslot2Frequency.setNumber(lsn + 1);
|
||||
timeslot2Frequency.setDownlinkFrequency((long)(siteFrequency.getFrequency() * 1E6));
|
||||
frequencies.add(timeslot2Frequency);
|
||||
TimeslotFrequency timeslotFrequency = new TimeslotFrequency();
|
||||
timeslotFrequency.setNumber(lcn);
|
||||
timeslotFrequency.setDownlinkFrequency((long)(siteFrequency.getFrequency() * 1E6));
|
||||
frequencies.add(timeslotFrequency);
|
||||
}
|
||||
|
||||
return frequencies;
|
||||
|
||||
@@ -90,9 +90,9 @@ import io.github.dsheirer.module.decode.ip.mototrbo.xcmp.XCMPPacket;
|
||||
import io.github.dsheirer.protocol.Protocol;
|
||||
import io.github.dsheirer.source.tuner.channel.rotation.AddChannelRotationActiveStateRequest;
|
||||
import io.github.dsheirer.util.PacketUtil;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import org.jdesktop.swingx.mapviewer.GeoPosition;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -111,7 +111,7 @@ public class DMRDecoderState extends TimeslotDecoderState
|
||||
private DecodeEvent mCurrentCallEvent;
|
||||
private long mCurrentFrequency;
|
||||
private boolean mIgnoreCRCChecksums;
|
||||
private Map<Integer,DecodeEvent> mDetectedCallEventsMap = new TreeMap<>();
|
||||
private Map<DMRChannel,DecodeEvent> mDetectedCallEventsMap = new HashMap<>();
|
||||
private static final AddChannelRotationActiveStateRequest CAPACITY_PLUS_ACTIVE_STATE_REQUEST =
|
||||
new AddChannelRotationActiveStateRequest(State.ACTIVE);
|
||||
|
||||
@@ -417,7 +417,7 @@ public class DMRDecoderState extends TimeslotDecoderState
|
||||
else
|
||||
{
|
||||
DecodeEvent packetEvent = DMRDecodeEvent.builder(DecodeEventType.DATA_PACKET, packet.getTimestamp())
|
||||
.identifiers(getMergedIdentifierCollection(packet.getIdentifiers()))
|
||||
.identifiers(new IdentifierCollection(packet.getIdentifiers()))
|
||||
.timeslot(getTimeslot())
|
||||
.details(packet.toString())
|
||||
.build();
|
||||
@@ -429,7 +429,7 @@ public class DMRDecoderState extends TimeslotDecoderState
|
||||
if (geoPosition != null) {
|
||||
PlottableDecodeEvent plottableDecodeEvent = PlottableDecodeEvent.plottableBuilder(DecodeEventType.GPS, packet.getTimestamp())
|
||||
.channel(getCurrentChannel())
|
||||
.identifiers(getMergedIdentifierCollection(packet.getIdentifiers()))
|
||||
.identifiers(new IdentifierCollection(packet.getIdentifiers()))
|
||||
.protocol(Protocol.LRRP)
|
||||
.location(geoPosition)
|
||||
.build();
|
||||
@@ -735,21 +735,22 @@ public class DMRDecoderState extends TimeslotDecoderState
|
||||
ChannelGrant dataGrant = (ChannelGrant)csbk;
|
||||
DMRChannel channel = dataGrant.getChannel();
|
||||
|
||||
IdentifierCollection mergedIdentifiers = getMergedIdentifierCollection(csbk.getIdentifiers());
|
||||
|
||||
if(hasTrafficChannelManager())
|
||||
{
|
||||
IdentifierCollection mergedIdentifiers = getMergedIdentifierCollection(csbk.getIdentifiers());
|
||||
mTrafficChannelManager.processChannelGrant(channel, mergedIdentifiers, csbk.getOpcode(),
|
||||
csbk.getTimestamp(), csbk.isEncrypted());
|
||||
}
|
||||
else
|
||||
{
|
||||
DecodeEvent event = mDetectedCallEventsMap.get(channel.getValue());
|
||||
DecodeEvent event = mDetectedCallEventsMap.get(channel);
|
||||
|
||||
if(isStale(event, csbk.getTimestamp(), csbk.getIdentifiers()))
|
||||
{
|
||||
event = getDecodeEvent(csbk, DecodeEventType.DATA_CALL, channel, mergedIdentifiers);
|
||||
mDetectedCallEventsMap.put(channel.getValue(), event);
|
||||
event = getDecodeEvent(csbk, DecodeEventType.DATA_CALL, channel,
|
||||
new IdentifierCollection(csbk.getIdentifiers()));
|
||||
mDetectedCallEventsMap.put(channel, event);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -768,21 +769,22 @@ public class DMRDecoderState extends TimeslotDecoderState
|
||||
ChannelGrant tgGrant = (ChannelGrant)csbk;
|
||||
DMRChannel channel = tgGrant.getChannel();
|
||||
|
||||
IdentifierCollection mergedIdentifiers = getMergedIdentifierCollection(csbk.getIdentifiers());
|
||||
|
||||
if(hasTrafficChannelManager())
|
||||
{
|
||||
IdentifierCollection mergedIdentifiers = getMergedIdentifierCollection(csbk.getIdentifiers());
|
||||
|
||||
mTrafficChannelManager.processChannelGrant(channel, mergedIdentifiers,
|
||||
csbk.getOpcode(), csbk.getTimestamp(), csbk.isEncrypted());
|
||||
}
|
||||
else
|
||||
{
|
||||
DecodeEvent event = mDetectedCallEventsMap.get(channel.getValue());
|
||||
DecodeEvent event = mDetectedCallEventsMap.get(channel);
|
||||
|
||||
if(isStale(event, csbk.getTimestamp(), csbk.getIdentifiers()))
|
||||
{
|
||||
event = getDecodeEvent(csbk, DecodeEventType.CALL_GROUP, channel, mergedIdentifiers);
|
||||
mDetectedCallEventsMap.put(channel.getValue(), event);
|
||||
event = getDecodeEvent(csbk, DecodeEventType.CALL_GROUP, channel,
|
||||
new IdentifierCollection(csbk.getIdentifiers()));
|
||||
mDetectedCallEventsMap.put(channel, event);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -800,21 +802,23 @@ public class DMRDecoderState extends TimeslotDecoderState
|
||||
{
|
||||
ChannelGrant channelGrant = (ChannelGrant)csbk;
|
||||
DMRChannel channel = channelGrant.getChannel();
|
||||
IdentifierCollection mergedIdentifiers = getMergedIdentifierCollection(csbk.getIdentifiers());
|
||||
|
||||
if(hasTrafficChannelManager())
|
||||
{
|
||||
IdentifierCollection mergedIdentifiers = getMergedIdentifierCollection(csbk.getIdentifiers());
|
||||
|
||||
mTrafficChannelManager.processChannelGrant(channel, mergedIdentifiers,
|
||||
csbk.getOpcode(), csbk.getTimestamp(), csbk.isEncrypted());
|
||||
}
|
||||
else
|
||||
{
|
||||
DecodeEvent event = mDetectedCallEventsMap.get(channel.getValue());
|
||||
DecodeEvent event = mDetectedCallEventsMap.get(channel);
|
||||
|
||||
if(isStale(event, csbk.getTimestamp(), csbk.getIdentifiers()))
|
||||
{
|
||||
event = getDecodeEvent(csbk, DecodeEventType.CALL_UNIT_TO_UNIT, channel, mergedIdentifiers);
|
||||
mDetectedCallEventsMap.put(channel.getValue(), event);
|
||||
event = getDecodeEvent(csbk, DecodeEventType.CALL_UNIT_TO_UNIT, channel,
|
||||
new IdentifierCollection(csbk.getIdentifiers()));
|
||||
mDetectedCallEventsMap.put(channel, event);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -845,21 +849,22 @@ public class DMRDecoderState extends TimeslotDecoderState
|
||||
ConnectPlusDataChannelGrant cpdcg = (ConnectPlusDataChannelGrant)csbk;
|
||||
DMRChannel channel = cpdcg.getChannel();
|
||||
|
||||
IdentifierCollection mergedIdentifiers = getMergedIdentifierCollection(csbk.getIdentifiers());
|
||||
|
||||
if(hasTrafficChannelManager())
|
||||
{
|
||||
IdentifierCollection mergedIdentifiers = getMergedIdentifierCollection(csbk.getIdentifiers());
|
||||
|
||||
mTrafficChannelManager.processChannelGrant(channel, mergedIdentifiers, csbk.getOpcode(),
|
||||
csbk.getTimestamp(), csbk.isEncrypted());
|
||||
}
|
||||
else
|
||||
{
|
||||
DecodeEvent event = mDetectedCallEventsMap.get(channel.getValue());
|
||||
DecodeEvent event = mDetectedCallEventsMap.get(channel);
|
||||
|
||||
if(isStale(event, csbk.getTimestamp(), csbk.getIdentifiers()))
|
||||
{
|
||||
event = getDecodeEvent(csbk, DecodeEventType.DATA_CALL, channel, mergedIdentifiers);
|
||||
mDetectedCallEventsMap.put(channel.getValue(), event);
|
||||
event = getDecodeEvent(csbk, DecodeEventType.DATA_CALL, channel,
|
||||
new IdentifierCollection(csbk.getIdentifiers()));
|
||||
mDetectedCallEventsMap.put(channel, event);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -875,7 +880,7 @@ public class DMRDecoderState extends TimeslotDecoderState
|
||||
case MOTOROLA_CONPLUS_REGISTRATION_REQUEST:
|
||||
DecodeEvent event = DMRDecodeEvent.builder(DecodeEventType.REQUEST, csbk.getTimestamp())
|
||||
.details("Registration Request")
|
||||
.identifiers(getMergedIdentifierCollection(csbk.getIdentifiers()))
|
||||
.identifiers(new IdentifierCollection(csbk.getIdentifiers()))
|
||||
.timeslot(getTimeslot())
|
||||
.build();
|
||||
broadcast(event);
|
||||
@@ -884,7 +889,7 @@ public class DMRDecoderState extends TimeslotDecoderState
|
||||
case MOTOROLA_CONPLUS_REGISTRATION_RESPONSE:
|
||||
DecodeEvent regRespEvent = DMRDecodeEvent.builder(DecodeEventType.RESPONSE, csbk.getTimestamp())
|
||||
.details("Registration Response")
|
||||
.identifiers(getMergedIdentifierCollection(csbk.getIdentifiers()))
|
||||
.identifiers(new IdentifierCollection(csbk.getIdentifiers()))
|
||||
.timeslot(getTimeslot())
|
||||
.build();
|
||||
broadcast(regRespEvent);
|
||||
@@ -896,21 +901,22 @@ public class DMRDecoderState extends TimeslotDecoderState
|
||||
ConnectPlusVoiceChannelUser cpvcu = (ConnectPlusVoiceChannelUser)csbk;
|
||||
DMRChannel channel = cpvcu.getChannel();
|
||||
|
||||
IdentifierCollection mergedIdentifiers = getMergedIdentifierCollection(csbk.getIdentifiers());
|
||||
|
||||
if(hasTrafficChannelManager())
|
||||
{
|
||||
IdentifierCollection mergedIdentifiers = getMergedIdentifierCollection(csbk.getIdentifiers());
|
||||
|
||||
mTrafficChannelManager.processChannelGrant(channel, mergedIdentifiers, csbk.getOpcode(),
|
||||
csbk.getTimestamp(), csbk.isEncrypted());
|
||||
}
|
||||
else
|
||||
{
|
||||
DecodeEvent detectedEvent = mDetectedCallEventsMap.get(channel.getValue());
|
||||
DecodeEvent detectedEvent = mDetectedCallEventsMap.get(channel);
|
||||
|
||||
if(isStale(detectedEvent, csbk.getTimestamp(), csbk.getIdentifiers()))
|
||||
{
|
||||
detectedEvent = getDecodeEvent(csbk, DecodeEventType.CALL_GROUP, channel, mergedIdentifiers);
|
||||
mDetectedCallEventsMap.put(channel.getValue(), detectedEvent);
|
||||
detectedEvent = getDecodeEvent(csbk, DecodeEventType.CALL_GROUP, channel,
|
||||
new IdentifierCollection(csbk.getIdentifiers()));
|
||||
mDetectedCallEventsMap.put(channel, detectedEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -926,7 +932,7 @@ public class DMRDecoderState extends TimeslotDecoderState
|
||||
case MOTOROLA_CONPLUS_TALKGROUP_AFFILIATION:
|
||||
DecodeEvent affiliateEvent = DMRDecodeEvent.builder(DecodeEventType.AFFILIATE, csbk.getTimestamp())
|
||||
.details("TALKGROUP AFFILIATION")
|
||||
.identifiers(getMergedIdentifierCollection(csbk.getIdentifiers()))
|
||||
.identifiers(new IdentifierCollection(csbk.getIdentifiers()))
|
||||
.timeslot(getTimeslot())
|
||||
.build();
|
||||
broadcast(affiliateEvent);
|
||||
@@ -939,18 +945,18 @@ public class DMRDecoderState extends TimeslotDecoderState
|
||||
}
|
||||
|
||||
private DecodeEvent getDecodeEvent(CSBKMessage csbk, DecodeEventType decodeEventType, DMRChannel channel,
|
||||
IdentifierCollection mergedIdentifiers) {
|
||||
IdentifierCollection identifierCollection) {
|
||||
return DMRDecodeEvent.builder(decodeEventType, csbk.getTimestamp())
|
||||
.channel(channel)
|
||||
.details(csbk.getOpcode().getLabel())
|
||||
.identifiers(mergedIdentifiers)
|
||||
.identifiers(identifierCollection)
|
||||
.timeslot(getTimeslot())
|
||||
.build();
|
||||
}
|
||||
|
||||
private DecodeEvent getDecodeEvent(CSBKMessage csbk, DecodeEventType decodeEventType, String details) {
|
||||
return DMRDecodeEvent.builder(decodeEventType, csbk.getTimestamp())
|
||||
.identifiers(getMergedIdentifierCollection(csbk.getIdentifiers()))
|
||||
.identifiers(new IdentifierCollection(csbk.getIdentifiers()))
|
||||
.timeslot(getTimeslot())
|
||||
.details(details)
|
||||
.build();
|
||||
|
||||
@@ -127,19 +127,19 @@ public class DMRMessageProcessor implements Listener<IMessage>
|
||||
}
|
||||
}
|
||||
|
||||
//Enrich messages that carry DMR Logical Slot Number channels with LCN to frequency mappings
|
||||
//Enrich messages that carry DMR Logical Channel Numbers with LCN to frequency mappings
|
||||
if(message instanceof ITimeslotFrequencyReceiver)
|
||||
{
|
||||
ITimeslotFrequencyReceiver receiver = (ITimeslotFrequencyReceiver)message;
|
||||
int[] lsns = receiver.getLogicalSlotNumbers();
|
||||
int[] lcns = receiver.getLogicalChannelNumbers();
|
||||
|
||||
List<TimeslotFrequency> timeslotFrequencies = new ArrayList<>();
|
||||
|
||||
for(int lsn: lsns)
|
||||
for(int lcn: lcns)
|
||||
{
|
||||
if(mTimeslotFrequencyMap.containsKey(lsn))
|
||||
if(mTimeslotFrequencyMap.containsKey(lcn))
|
||||
{
|
||||
timeslotFrequencies.add(mTimeslotFrequencyMap.get(lsn));
|
||||
timeslotFrequencies.add(mTimeslotFrequencyMap.get(lcn));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2023 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 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/>
|
||||
* * *****************************************************************************
|
||||
* 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.module.decode.dmr;
|
||||
@@ -41,14 +38,13 @@ import io.github.dsheirer.module.decode.dmr.message.data.lc.shorty.ConnectPlusCo
|
||||
import io.github.dsheirer.module.decode.dmr.message.data.lc.shorty.ConnectPlusTrafficChannel;
|
||||
import io.github.dsheirer.module.decode.dmr.message.type.Model;
|
||||
import io.github.dsheirer.module.decode.dmr.message.type.SystemIdentityCode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Tracks the network configuration details of a DMR network from the broadcast messages
|
||||
@@ -250,7 +246,7 @@ public class DMRNetworkConfigurationMonitor
|
||||
ConnectPlusNeighborReport cpnr = (ConnectPlusNeighborReport)csbk;
|
||||
mNeighborSites.addAll(cpnr.getNeighbors());
|
||||
}
|
||||
if(mBrand == null)
|
||||
if(mBrand == null || mBrand != BRAND_MOTOROLA_CONNECT_PLUS)
|
||||
{
|
||||
mBrand = BRAND_MOTOROLA_CONNECT_PLUS;
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ public class DMRTrafficChannelManager extends TrafficChannelManager implements I
|
||||
private List<Channel> mManagedTrafficChannels;
|
||||
|
||||
private Map<Long,Channel> mAllocatedTrafficChannelFrequencyMap = new ConcurrentHashMap<>();
|
||||
private Map<Integer,DMRChannelGrantEvent> mLSNGrantEventMap = new ConcurrentHashMap<>();
|
||||
private Map<DMRChannel,DMRChannelGrantEvent> mChannelGrantEventMap = new ConcurrentHashMap<>();
|
||||
|
||||
private Listener<ChannelEvent> mChannelEventListener;
|
||||
private Listener<IDecodeEvent> mDecodeEventListener;
|
||||
@@ -322,9 +322,7 @@ public class DMRTrafficChannelManager extends TrafficChannelManager implements I
|
||||
public void processChannelGrant(DMRChannel channel, IdentifierCollection identifierCollection,
|
||||
Opcode opcode, long timestamp, boolean encrypted)
|
||||
{
|
||||
int lsn = channel.getValue();
|
||||
|
||||
DMRChannelGrantEvent event = mLSNGrantEventMap.get(lsn);
|
||||
DMRChannelGrantEvent event = mChannelGrantEventMap.get(channel);
|
||||
DecodeEventType decodeEventType = getEventType(opcode, identifierCollection, encrypted);
|
||||
|
||||
if(isStale(event, timestamp, identifierCollection)) //Create new event
|
||||
@@ -335,7 +333,7 @@ public class DMRTrafficChannelManager extends TrafficChannelManager implements I
|
||||
.identifiers(identifierCollection)
|
||||
.build();
|
||||
|
||||
mLSNGrantEventMap.put(lsn, event);
|
||||
mChannelGrantEventMap.put(channel, event);
|
||||
|
||||
}
|
||||
else //Update current event
|
||||
@@ -355,7 +353,7 @@ public class DMRTrafficChannelManager extends TrafficChannelManager implements I
|
||||
.identifiers(identifierCollection)
|
||||
.build();
|
||||
|
||||
mLSNGrantEventMap.put(lsn, event);
|
||||
mChannelGrantEventMap.put(channel, event);
|
||||
broadcast(event);
|
||||
}
|
||||
}
|
||||
@@ -643,37 +641,37 @@ public class DMRTrafficChannelManager extends TrafficChannelManager implements I
|
||||
*/
|
||||
private void removeCallEvents(long frequency)
|
||||
{
|
||||
List<Integer> lsnsToRemove = new ArrayList<>();
|
||||
List<DMRChannel> channelsToRemove = new ArrayList<>();
|
||||
|
||||
for(Map.Entry<Integer,DMRChannelGrantEvent> entry: mLSNGrantEventMap.entrySet())
|
||||
for(Map.Entry<DMRChannel,DMRChannelGrantEvent> entry: mChannelGrantEventMap.entrySet())
|
||||
{
|
||||
if(entry.getValue().getChannelDescriptor().getDownlinkFrequency() == frequency)
|
||||
if(entry.getKey().getDownlinkFrequency() == frequency)
|
||||
{
|
||||
lsnsToRemove.add(entry.getKey());
|
||||
channelsToRemove.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
for(Integer lsn: lsnsToRemove)
|
||||
for(DMRChannel channel: channelsToRemove)
|
||||
{
|
||||
mLSNGrantEventMap.remove(lsn);
|
||||
mChannelGrantEventMap.remove(channel);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCallEventDetails(long frequency, String detailFragment)
|
||||
{
|
||||
List<Integer> lsnsToUpdate = new ArrayList<>();
|
||||
List<DMRChannel> channelsToUpdate = new ArrayList<>();
|
||||
|
||||
for(Map.Entry<Integer,DMRChannelGrantEvent> entry: mLSNGrantEventMap.entrySet())
|
||||
for(Map.Entry<DMRChannel,DMRChannelGrantEvent> entry: mChannelGrantEventMap.entrySet())
|
||||
{
|
||||
if(entry.getValue().getChannelDescriptor().getDownlinkFrequency() == frequency)
|
||||
{
|
||||
lsnsToUpdate.add(entry.getKey());
|
||||
channelsToUpdate.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
for(Integer lsn: lsnsToUpdate)
|
||||
for(DMRChannel channel: channelsToUpdate)
|
||||
{
|
||||
DMRChannelGrantEvent event = mLSNGrantEventMap.get(lsn);
|
||||
DMRChannelGrantEvent event = mChannelGrantEventMap.get(channel);
|
||||
|
||||
if(event != null)
|
||||
{
|
||||
|
||||
@@ -26,6 +26,8 @@ import io.github.dsheirer.identifier.Role;
|
||||
import io.github.dsheirer.identifier.integer.IntegerIdentifier;
|
||||
import io.github.dsheirer.module.decode.p25.phase1.message.IFrequencyBand;
|
||||
import io.github.dsheirer.protocol.Protocol;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
/**
|
||||
@@ -33,8 +35,9 @@ import org.apache.commons.lang3.Validate;
|
||||
*
|
||||
* Note: timeslots are tracked as 1 and 2
|
||||
*/
|
||||
public abstract class DMRChannel extends IntegerIdentifier implements IChannelDescriptor
|
||||
public abstract class DMRChannel extends IntegerIdentifier implements IChannelDescriptor, ITimeslotFrequencyReceiver
|
||||
{
|
||||
private TimeslotFrequency mTimeslotFrequency;
|
||||
private int mTimeslot;
|
||||
|
||||
/**
|
||||
@@ -56,13 +59,23 @@ public abstract class DMRChannel extends IntegerIdentifier implements IChannelDe
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeater number or channel number for the channel.
|
||||
* Repeater number aka Logical Channel Number (LCN) for the channel.
|
||||
*/
|
||||
public int getChannel()
|
||||
public int getChannelNumber()
|
||||
{
|
||||
return getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to format the single channel number as an array for TimeslotFrequency matching.
|
||||
* @return channel number as an integer array.
|
||||
*/
|
||||
public int[] getLogicalChannelNumbers()
|
||||
{
|
||||
return new int[]{getChannelNumber()};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Timeslot for the channel.
|
||||
* @return timeslot as zero-based index with values in range: 0 or 1.
|
||||
@@ -95,7 +108,7 @@ public abstract class DMRChannel extends IntegerIdentifier implements IChannelDe
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "CHAN:" + getChannel() + ":" + getTimeslot();
|
||||
return "CHAN:" + getChannelNumber() + ":" + getTimeslot();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,4 +128,72 @@ public abstract class DMRChannel extends IntegerIdentifier implements IChannelDe
|
||||
{
|
||||
throw new IllegalArgumentException("This method is not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDownlinkFrequency()
|
||||
{
|
||||
if(mTimeslotFrequency != null)
|
||||
{
|
||||
return mTimeslotFrequency.getDownlinkFrequency();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getUplinkFrequency()
|
||||
{
|
||||
if(mTimeslotFrequency != null)
|
||||
{
|
||||
return mTimeslotFrequency.getUplinkFrequency();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the lsn to frequency mapper value.
|
||||
* @param timeslotFrequency to set
|
||||
*/
|
||||
public void setTimeslotFrequency(TimeslotFrequency timeslotFrequency)
|
||||
{
|
||||
mTimeslotFrequency = timeslotFrequency;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(List<TimeslotFrequency> timeslotFrequencies)
|
||||
{
|
||||
for(TimeslotFrequency timeslotFrequency: timeslotFrequencies)
|
||||
{
|
||||
if(timeslotFrequency.getChannelNumber() == getChannelNumber())
|
||||
{
|
||||
setTimeslotFrequency(timeslotFrequency);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if(this == o)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(!(o instanceof DMRChannel that))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(!super.equals(o))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return getTimeslot() == that.getTimeslot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return Objects.hash(super.hashCode(), getTimeslot());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
package io.github.dsheirer.module.decode.dmr.channel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* DMR Logical Slot Number (LSN) channel.
|
||||
*
|
||||
@@ -44,10 +42,8 @@ import java.util.List;
|
||||
* 15: 8/1
|
||||
* 16: 8/2
|
||||
*/
|
||||
public class DMRLsn extends DMRChannel implements ITimeslotFrequencyReceiver
|
||||
public class DMRLsn extends DMRChannel
|
||||
{
|
||||
private TimeslotFrequency mTimeslotFrequency;
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
*
|
||||
@@ -61,7 +57,7 @@ public class DMRLsn extends DMRChannel implements ITimeslotFrequencyReceiver
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "LSN:" + getLsn();
|
||||
return "LSN:" + getLsn() + " LCN:" + getChannelNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,65 +66,7 @@ public class DMRLsn extends DMRChannel implements ITimeslotFrequencyReceiver
|
||||
*/
|
||||
public int getLsn()
|
||||
{
|
||||
return ((getChannel() - 1) * 2) + getTimeslot();
|
||||
return ((getChannelNumber() - 1) * 2) + getTimeslot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDownlinkFrequency()
|
||||
{
|
||||
if(mTimeslotFrequency != null)
|
||||
{
|
||||
return mTimeslotFrequency.getDownlinkFrequency();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getUplinkFrequency()
|
||||
{
|
||||
if(mTimeslotFrequency != null)
|
||||
{
|
||||
return mTimeslotFrequency.getUplinkFrequency();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getLogicalSlotNumbers()
|
||||
{
|
||||
return new int[]{getLsn()};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the lsn to frequency mapper value.
|
||||
* @param timeslotFrequency to set
|
||||
*/
|
||||
public void setTimeslotFrequency(TimeslotFrequency timeslotFrequency)
|
||||
{
|
||||
mTimeslotFrequency = timeslotFrequency;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(List<TimeslotFrequency> timeslotFrequencies)
|
||||
{
|
||||
for(TimeslotFrequency timeslotFrequency: timeslotFrequencies)
|
||||
{
|
||||
if(timeslotFrequency.getNumber() == getLsn())
|
||||
{
|
||||
setTimeslotFrequency(timeslotFrequency);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
for(int x = 1; x <= 16; x++)
|
||||
{
|
||||
DMRLsn lsn = new DmrRestLsn(x);
|
||||
System.out.println(lsn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,14 +24,12 @@ package io.github.dsheirer.module.decode.dmr.channel;
|
||||
*/
|
||||
public class DMRTier3Channel extends DMRChannel
|
||||
{
|
||||
private TimeslotFrequency mTimeslotFrequency;
|
||||
|
||||
/**
|
||||
* Constructs an instance. Note: radio reference uses a one based index, so we add a value of one to the
|
||||
* calculated logical slot value for visual compatibility for users.
|
||||
*
|
||||
* @param channel number or repeater number
|
||||
* @param logicalSlotNumber - zero based index.
|
||||
* @param timeslot either 1 or 2.
|
||||
*/
|
||||
public DMRTier3Channel(int channel, int timeslot)
|
||||
{
|
||||
@@ -39,42 +37,12 @@ public class DMRTier3Channel extends DMRChannel
|
||||
}
|
||||
|
||||
/**
|
||||
* Downlink frequency
|
||||
* @return value in Hertz, or 0 if this channel doesn't have a timeslot frequency mapping
|
||||
* Tier III Channel ID
|
||||
* @return channel ID
|
||||
*/
|
||||
@Override
|
||||
public long getDownlinkFrequency()
|
||||
public int getChannelId()
|
||||
{
|
||||
if(mTimeslotFrequency != null)
|
||||
{
|
||||
return mTimeslotFrequency.getDownlinkFrequency();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uplink frequency
|
||||
* @return value in Hertz, or 0 if this channel doesn't have a timeslot frequency mapping
|
||||
*/
|
||||
@Override
|
||||
public long getUplinkFrequency()
|
||||
{
|
||||
if(mTimeslotFrequency != null)
|
||||
{
|
||||
return mTimeslotFrequency.getUplinkFrequency();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the timeslot frequency mapping
|
||||
* @param timeslotFrequency
|
||||
*/
|
||||
public void setTimeslotFrequency(TimeslotFrequency timeslotFrequency)
|
||||
{
|
||||
mTimeslotFrequency = timeslotFrequency;
|
||||
return getChannelNumber() * 2 + getTimeslot();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,7 +51,8 @@ public class DMRTier3Channel extends DMRChannel
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(" LCN:").append(getValue());
|
||||
sb.append(" LCN:").append(getChannelNumber());
|
||||
sb.append(" CHANID:").append(getChannelId());
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,9 +24,9 @@ import java.util.List;
|
||||
public interface ITimeslotFrequencyReceiver
|
||||
{
|
||||
/**
|
||||
* Provides the logical slot number(s) that require a matching timeslot frequency mapping
|
||||
* Provides the logical channel number(s) that require a matching timeslot frequency mapping
|
||||
*/
|
||||
public int[] getLogicalSlotNumbers();
|
||||
public int[] getLogicalChannelNumbers();
|
||||
|
||||
/**
|
||||
* Applies the list of timeslot frequency mappings to the implementer
|
||||
|
||||
@@ -31,7 +31,7 @@ import javafx.beans.property.SimpleLongProperty;
|
||||
import javafx.util.Callback;
|
||||
|
||||
/**
|
||||
* Maps a logical slot number (LSN) to a pair of channel frequency values
|
||||
* Maps a logical channel number (LCN) to a pair of channel frequency values
|
||||
*/
|
||||
public class TimeslotFrequency
|
||||
{
|
||||
@@ -100,7 +100,10 @@ public class TimeslotFrequency
|
||||
}
|
||||
|
||||
/**
|
||||
* Logical slot number (LSN) as a 1-index based counter
|
||||
* Logical channel number (LCN) as a 1-index based counter
|
||||
*
|
||||
* Note: lsn (logical slot number) is a legacy name for this field. The field currently holds the LCN or logical
|
||||
* channel number. To avoid breaking serialization, we leave this field labeled as lsn.
|
||||
*/
|
||||
@JacksonXmlProperty(isAttribute = true, localName = "lsn")
|
||||
public int getNumber()
|
||||
@@ -109,12 +112,52 @@ public class TimeslotFrequency
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the logical slot number (LSN) as a 1-index start
|
||||
* @param lsn where LSN 1 is the first slot, 2 the second, etc
|
||||
* Logical channel number which is the same value as getNumber.
|
||||
* @return
|
||||
*/
|
||||
public void setNumber(int lsn)
|
||||
@JsonIgnore
|
||||
public int getChannelNumber()
|
||||
{
|
||||
mNumberProperty.set(lsn);
|
||||
return getNumber();
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public String getLogicalSlotNumbers()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int channel = getChannelNumber();
|
||||
|
||||
if(channel > 0)
|
||||
{
|
||||
if(channel < 32) //Connect Plus uses 5-bits for LSN for a maximum value of 31
|
||||
{
|
||||
//Cap+ & Con+ Logical Slot Numbers
|
||||
int lsn1 = (channel - 1) * 2 + 1;
|
||||
int lsn2 = (channel - 1) * 2 + 2;
|
||||
sb.append("LSN:").append(lsn1).append("/").append(lsn2).append(" or ");
|
||||
}
|
||||
|
||||
//Tier III channel IDs
|
||||
int chanId1 = channel * 2 + 1;
|
||||
int chanId2 = channel * 2 + 2;
|
||||
sb.append("Tier3 Chan:").append(chanId1).append("/").append(chanId2);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append("(empty)");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the logical channel number (LCN) as a 1-index start
|
||||
* @param lcn where LCN 1 is logical slot numbers (LSN) 1 and 2, LCN2=LSN3/4, etc.
|
||||
*/
|
||||
public void setNumber(int lcn)
|
||||
{
|
||||
mNumberProperty.set(lcn);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,7 +203,7 @@ public class TimeslotFrequency
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "TIMESLOT LSN:" + getNumber() + " DOWNLINK:" + getDownlinkFrequency();
|
||||
return "LCN:" + getNumber() + " DOWNLINK:" + getDownlinkFrequency();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -299,9 +299,9 @@ public class CapacityPlusNeighbors extends CSBKMessage implements ITimeslotFrequ
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getLogicalSlotNumbers()
|
||||
public int[] getLogicalChannelNumbers()
|
||||
{
|
||||
return getRestChannel().getLogicalSlotNumbers();
|
||||
return getRestChannel().getLogicalChannelNumbers();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -312,13 +312,7 @@ public class CapacityPlusNeighbors extends CSBKMessage implements ITimeslotFrequ
|
||||
@Override
|
||||
public void apply(List<TimeslotFrequency> timeslotFrequencies)
|
||||
{
|
||||
for(TimeslotFrequency timeslotFrequency : timeslotFrequencies)
|
||||
{
|
||||
if(timeslotFrequency.getNumber() == getRestChannel().getValue())
|
||||
{
|
||||
getRestChannel().setTimeslotFrequency(timeslotFrequency);
|
||||
}
|
||||
}
|
||||
getRestChannel().apply(timeslotFrequencies);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -299,9 +299,9 @@ public class CapacityPlusSiteStatus extends CSBKMessage implements ITimeslotFreq
|
||||
* Logical slot numbers that require slot to frequency mappings.
|
||||
*/
|
||||
@Override
|
||||
public int[] getLogicalSlotNumbers()
|
||||
public int[] getLogicalChannelNumbers()
|
||||
{
|
||||
return getRestChannel().getLogicalSlotNumbers();
|
||||
return getRestChannel().getLogicalChannelNumbers();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -312,13 +312,7 @@ public class CapacityPlusSiteStatus extends CSBKMessage implements ITimeslotFreq
|
||||
@Override
|
||||
public void apply(List<TimeslotFrequency> timeslotFrequencies)
|
||||
{
|
||||
for(TimeslotFrequency timeslotFrequency : timeslotFrequencies)
|
||||
{
|
||||
if(getRestChannel().getValue() == timeslotFrequency.getNumber())
|
||||
{
|
||||
getRestChannel().setTimeslotFrequency(timeslotFrequency);
|
||||
}
|
||||
}
|
||||
getRestChannel().apply(timeslotFrequencies);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -40,7 +40,7 @@ public class ConnectPlusDataChannelGrant extends CSBKMessage implements ITimeslo
|
||||
{
|
||||
private static final int[] TARGET_ADDRESS = new int[]{16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39};
|
||||
private static final int[] REPEATER = new int[]{40, 41, 42, 43, 44};
|
||||
private static final int[] LOGICAL_SLOT_NUMBER = new int[]{40, 41, 42, 43, 44};
|
||||
|
||||
//Analysis: this field correlates to UNKNOWN_FIELD_1(bits: 40-48) in ConnectPlusTerminateChannelGrant.
|
||||
private static final int[] UNKNOWN_FIELD = new int[]{48, 49, 50, 51, 52, 53, 54, 55};
|
||||
@@ -109,11 +109,11 @@ public class ConnectPlusDataChannelGrant extends CSBKMessage implements ITimeslo
|
||||
}
|
||||
|
||||
/**
|
||||
* Channel grant repeater number
|
||||
* Channel grant logical slot number
|
||||
*/
|
||||
public int getRepeater()
|
||||
public int getLsn()
|
||||
{
|
||||
return getMessage().getInt(REPEATER);
|
||||
return getMessage().getInt(LOGICAL_SLOT_NUMBER) - 1; //Don't change this ... always subtract 1 to get the repeater LSN
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,16 +123,16 @@ public class ConnectPlusDataChannelGrant extends CSBKMessage implements ITimeslo
|
||||
{
|
||||
if(mDmrLsn == null)
|
||||
{
|
||||
mDmrLsn = new DMRLsn(getRepeater());
|
||||
mDmrLsn = new DMRLsn(getLsn());
|
||||
}
|
||||
|
||||
return mDmrLsn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getLogicalSlotNumbers()
|
||||
public int[] getLogicalChannelNumbers()
|
||||
{
|
||||
return getChannel().getLogicalSlotNumbers();
|
||||
return getChannel().getLogicalChannelNumbers();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,13 +142,7 @@ public class ConnectPlusDataChannelGrant extends CSBKMessage implements ITimeslo
|
||||
@Override
|
||||
public void apply(List<TimeslotFrequency> timeslotFrequencies)
|
||||
{
|
||||
for(TimeslotFrequency timeslotFrequency: timeslotFrequencies)
|
||||
{
|
||||
if(timeslotFrequency.getNumber() == getChannel().getValue())
|
||||
{
|
||||
getChannel().setTimeslotFrequency(timeslotFrequency);
|
||||
}
|
||||
}
|
||||
getChannel().apply(timeslotFrequencies);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -45,7 +45,7 @@ public class ConnectPlusOTAAnnouncement extends CSBKMessage implements ITimeslot
|
||||
private static final int[] VERSION = new int[]{24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39};
|
||||
private static final int[] UNKNOWN = new int[]{40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
|
||||
57, 58, 59, 60, 61, 62};
|
||||
private static final int[] DATA_REPEATER = new int[]{63, 64, 65, 66, 67};
|
||||
private static final int[] LOGICAL_SLOT_NUMBER = new int[]{63, 64, 65, 66, 67};
|
||||
|
||||
private DMRLsn mDataChannel;
|
||||
private List<Identifier> mIdentifiers;
|
||||
@@ -99,11 +99,11 @@ public class ConnectPlusOTAAnnouncement extends CSBKMessage implements ITimeslot
|
||||
}
|
||||
|
||||
/**
|
||||
* Data repeater number
|
||||
* Data logical slot numberrepeater number
|
||||
*/
|
||||
public int getDataRepeater()
|
||||
public int getDataLsn()
|
||||
{
|
||||
return getMessage().getInt(DATA_REPEATER);
|
||||
return getMessage().getInt(LOGICAL_SLOT_NUMBER) - 1; //Leave this as minus 1
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,16 +113,16 @@ public class ConnectPlusOTAAnnouncement extends CSBKMessage implements ITimeslot
|
||||
{
|
||||
if(mDataChannel == null)
|
||||
{
|
||||
mDataChannel = new DMRLsn(getDataRepeater());
|
||||
mDataChannel = new DMRLsn(getDataLsn());
|
||||
}
|
||||
|
||||
return mDataChannel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getLogicalSlotNumbers()
|
||||
public int[] getLogicalChannelNumbers()
|
||||
{
|
||||
return getDataChannel().getLogicalSlotNumbers();
|
||||
return getDataChannel().getLogicalChannelNumbers();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,13 +133,7 @@ public class ConnectPlusOTAAnnouncement extends CSBKMessage implements ITimeslot
|
||||
@Override
|
||||
public void apply(List<TimeslotFrequency> timeslotFrequencies)
|
||||
{
|
||||
for(TimeslotFrequency timeslotFrequency : timeslotFrequencies)
|
||||
{
|
||||
if(timeslotFrequency.getNumber() == getDataChannel().getValue())
|
||||
{
|
||||
getDataChannel().setTimeslotFrequency(timeslotFrequency);
|
||||
}
|
||||
}
|
||||
getDataChannel().apply(timeslotFrequencies);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -44,7 +44,7 @@ public class ConnectPlusVoiceChannelUser extends CSBKMessage implements ITimeslo
|
||||
32, 33, 34, 35, 36, 37, 38, 39};
|
||||
private static final int[] GROUP_ADDRESS = new int[]{40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
|
||||
56, 57, 58, 59, 60, 61, 62, 63};
|
||||
private static final int[] TRAFFIC_CHANNEL_REPEATER = new int[]{64, 65, 66, 67, 68};
|
||||
private static final int[] LOGICAL_SLOT_NUMBER = new int[]{64, 65, 66, 67, 68};
|
||||
private static final int[] UNKNOWN_FIELD = new int[]{72, 73, 74, 75, 76, 77, 78, 79};
|
||||
|
||||
private RadioIdentifier mRadio;
|
||||
@@ -126,9 +126,9 @@ public class ConnectPlusVoiceChannelUser extends CSBKMessage implements ITimeslo
|
||||
/**
|
||||
* Traffic channel repeater
|
||||
*/
|
||||
public int getTrafficChannelRepeater()
|
||||
public int getTrafficLsn()
|
||||
{
|
||||
return getMessage().getInt(TRAFFIC_CHANNEL_REPEATER);
|
||||
return getMessage().getInt(LOGICAL_SLOT_NUMBER) - 1; //Always leave as minus 1
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -138,16 +138,16 @@ public class ConnectPlusVoiceChannelUser extends CSBKMessage implements ITimeslo
|
||||
{
|
||||
if(mDmrLsn == null)
|
||||
{
|
||||
mDmrLsn = new DMRLsn(getTrafficChannelRepeater());
|
||||
mDmrLsn = new DMRLsn(getTrafficLsn());
|
||||
}
|
||||
|
||||
return mDmrLsn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getLogicalSlotNumbers()
|
||||
public int[] getLogicalChannelNumbers()
|
||||
{
|
||||
return getChannel().getLogicalSlotNumbers();
|
||||
return getChannel().getLogicalChannelNumbers();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,13 +157,7 @@ public class ConnectPlusVoiceChannelUser extends CSBKMessage implements ITimeslo
|
||||
@Override
|
||||
public void apply(List<TimeslotFrequency> timeslotFrequencies)
|
||||
{
|
||||
for(TimeslotFrequency timeslotFrequency: timeslotFrequencies)
|
||||
{
|
||||
if(timeslotFrequency.getNumber() == getChannel().getValue())
|
||||
{
|
||||
getChannel().setTimeslotFrequency(timeslotFrequency);
|
||||
}
|
||||
}
|
||||
getChannel().apply(timeslotFrequencies);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -25,7 +25,6 @@ import io.github.dsheirer.identifier.integer.IntegerIdentifier;
|
||||
import io.github.dsheirer.identifier.radio.RadioIdentifier;
|
||||
import io.github.dsheirer.module.decode.dmr.DMRSyncPattern;
|
||||
import io.github.dsheirer.module.decode.dmr.channel.DMRChannel;
|
||||
import io.github.dsheirer.module.decode.dmr.channel.DMRLsn;
|
||||
import io.github.dsheirer.module.decode.dmr.channel.DMRTier3Channel;
|
||||
import io.github.dsheirer.module.decode.dmr.channel.ITimeslotFrequencyReceiver;
|
||||
import io.github.dsheirer.module.decode.dmr.channel.TimeslotFrequency;
|
||||
@@ -224,11 +223,11 @@ public class Clear extends CSBKMessage implements ITimeslotFrequencyReceiver
|
||||
* Logical Slot Number(s) for channels contained in this message
|
||||
*/
|
||||
@Override
|
||||
public int[] getLogicalSlotNumbers()
|
||||
public int[] getLogicalChannelNumbers()
|
||||
{
|
||||
if(getMoveToChannel() instanceof DMRLsn dmrLsn)
|
||||
if(getMoveToChannel() != null)
|
||||
{
|
||||
return dmrLsn.getLogicalSlotNumbers();
|
||||
return getMoveToChannel().getLogicalChannelNumbers();
|
||||
}
|
||||
|
||||
return new int[0];
|
||||
@@ -241,17 +240,9 @@ public class Clear extends CSBKMessage implements ITimeslotFrequencyReceiver
|
||||
@Override
|
||||
public void apply(List<TimeslotFrequency> timeslotFrequencies)
|
||||
{
|
||||
if(getMoveToChannel() instanceof DMRTier3Channel)
|
||||
if(getMoveToChannel() != null)
|
||||
{
|
||||
DMRTier3Channel channel = (DMRTier3Channel)getMoveToChannel();
|
||||
|
||||
for(TimeslotFrequency timeslotFrequency: timeslotFrequencies)
|
||||
{
|
||||
if(channel.getValue() == timeslotFrequency.getNumber())
|
||||
{
|
||||
channel.setTimeslotFrequency(timeslotFrequency);
|
||||
}
|
||||
}
|
||||
getMoveToChannel().apply(timeslotFrequencies);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -88,7 +88,8 @@ public class MoveTSCC extends CSBKMessage
|
||||
|
||||
if(multiBlock != null)
|
||||
{
|
||||
mAbsoluteChannelParameters = new AbsoluteChannelParameters(multiBlock.getMessage(), 0, 0);
|
||||
//Timeslot hard-coded to 1 since this is a control channel.
|
||||
mAbsoluteChannelParameters = new AbsoluteChannelParameters(multiBlock.getMessage(), 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -84,8 +84,8 @@ public class AdjacentSiteInformation extends Announcement
|
||||
|
||||
if(multiBlock != null)
|
||||
{
|
||||
//Timeslot hard-coded to zero for control channel
|
||||
mAbsoluteChannelParameters = new AbsoluteChannelParameters(multiBlock.getMessage(), 0, 0);
|
||||
//Timeslot hard-coded to one for control channel
|
||||
mAbsoluteChannelParameters = new AbsoluteChannelParameters(multiBlock.getMessage(), 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* Copyright (C) 2014-2023 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,7 +27,6 @@ import io.github.dsheirer.module.decode.dmr.message.data.SlotType;
|
||||
import io.github.dsheirer.module.decode.dmr.message.data.mbc.MBCContinuationBlock;
|
||||
import io.github.dsheirer.module.decode.dmr.message.type.AbsoluteChannelParameters;
|
||||
import io.github.dsheirer.module.decode.dmr.message.type.DataType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -56,7 +55,8 @@ public class AnnounceChannelFrequency extends Announcement
|
||||
|
||||
if(multiBlock != null)
|
||||
{
|
||||
mAbsoluteChannelParameters = new AbsoluteChannelParameters(multiBlock.getMessage(), 0, 0);
|
||||
//Timeslot hard-coded to one
|
||||
mAbsoluteChannelParameters = new AbsoluteChannelParameters(multiBlock.getMessage(), 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,8 +86,8 @@ public class AnnounceWithdrawTSCC extends Announcement
|
||||
|
||||
if(multiBlock != null)
|
||||
{
|
||||
//Control channel timeslot hard-coded to 0
|
||||
mAbsoluteChannelParameters = new AbsoluteChannelParameters(multiBlock.getMessage(), 0, 0);
|
||||
//Control channel timeslot hard-coded to 1
|
||||
mAbsoluteChannelParameters = new AbsoluteChannelParameters(multiBlock.getMessage(), 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ import io.github.dsheirer.bits.CorrectedBinaryMessage;
|
||||
import io.github.dsheirer.identifier.Identifier;
|
||||
import io.github.dsheirer.module.decode.dmr.DMRSyncPattern;
|
||||
import io.github.dsheirer.module.decode.dmr.channel.DMRChannel;
|
||||
import io.github.dsheirer.module.decode.dmr.channel.DMRLsn;
|
||||
import io.github.dsheirer.module.decode.dmr.channel.DMRTier3Channel;
|
||||
import io.github.dsheirer.module.decode.dmr.channel.ITimeslotFrequencyReceiver;
|
||||
import io.github.dsheirer.module.decode.dmr.channel.TimeslotFrequency;
|
||||
@@ -90,7 +89,8 @@ public class VoteNowAdvice extends Announcement implements ITimeslotFrequencyRec
|
||||
|
||||
if(multiBlock != null)
|
||||
{
|
||||
mAbsoluteChannelParameters = new AbsoluteChannelParameters(multiBlock.getMessage(), 0, 0);
|
||||
//Timeslot hard-coded to one for control channel
|
||||
mAbsoluteChannelParameters = new AbsoluteChannelParameters(multiBlock.getMessage(), 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,11 +239,11 @@ public class VoteNowAdvice extends Announcement implements ITimeslotFrequencyRec
|
||||
* Logical Slot Number(s) for channels contained in this message
|
||||
*/
|
||||
@Override
|
||||
public int[] getLogicalSlotNumbers()
|
||||
public int[] getLogicalChannelNumbers()
|
||||
{
|
||||
if(getChannel() instanceof DMRLsn dmrLsn)
|
||||
if(getChannel() != null)
|
||||
{
|
||||
return dmrLsn.getLogicalSlotNumbers();
|
||||
return getChannel().getLogicalChannelNumbers();
|
||||
}
|
||||
|
||||
return new int[0];
|
||||
@@ -256,17 +256,9 @@ public class VoteNowAdvice extends Announcement implements ITimeslotFrequencyRec
|
||||
@Override
|
||||
public void apply(List<TimeslotFrequency> timeslotFrequencies)
|
||||
{
|
||||
if(getChannel() instanceof DMRTier3Channel)
|
||||
if(getChannel() != null)
|
||||
{
|
||||
DMRTier3Channel channel = (DMRTier3Channel)getChannel();
|
||||
|
||||
for(TimeslotFrequency timeslotFrequency: timeslotFrequencies)
|
||||
{
|
||||
if(channel.getValue() == timeslotFrequency.getNumber())
|
||||
{
|
||||
channel.setTimeslotFrequency(timeslotFrequency);
|
||||
}
|
||||
}
|
||||
getChannel().apply(timeslotFrequencies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ public class BroadcastTalkgroupVoiceChannelGrant extends ChannelGrant
|
||||
|
||||
sb.append(" BROADCAST TALKGROUP VOICE CHANNEL GRANT FM:").append(getSourceRadio());
|
||||
sb.append(" TO:").append(getDestinationTalkgroup());
|
||||
sb.append(" CHAN:").append(getChannel());
|
||||
sb.append(" ").append(getChannel());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ package io.github.dsheirer.module.decode.dmr.message.data.csbk.standard.grant;
|
||||
import io.github.dsheirer.bits.CorrectedBinaryMessage;
|
||||
import io.github.dsheirer.module.decode.dmr.DMRSyncPattern;
|
||||
import io.github.dsheirer.module.decode.dmr.channel.DMRChannel;
|
||||
import io.github.dsheirer.module.decode.dmr.channel.DMRLsn;
|
||||
import io.github.dsheirer.module.decode.dmr.channel.DMRTier3Channel;
|
||||
import io.github.dsheirer.module.decode.dmr.channel.ITimeslotFrequencyReceiver;
|
||||
import io.github.dsheirer.module.decode.dmr.channel.TimeslotFrequency;
|
||||
@@ -158,11 +157,11 @@ public abstract class ChannelGrant extends CSBKMessage implements ITimeslotFrequ
|
||||
* Logical Slot Number(s) for channels contained in this message
|
||||
*/
|
||||
@Override
|
||||
public int[] getLogicalSlotNumbers()
|
||||
public int[] getLogicalChannelNumbers()
|
||||
{
|
||||
if(getChannel() instanceof DMRLsn dmrLsn)
|
||||
if(getChannel() != null)
|
||||
{
|
||||
return dmrLsn.getLogicalSlotNumbers();
|
||||
return getChannel().getLogicalChannelNumbers();
|
||||
}
|
||||
|
||||
return new int[0];
|
||||
@@ -175,17 +174,9 @@ public abstract class ChannelGrant extends CSBKMessage implements ITimeslotFrequ
|
||||
@Override
|
||||
public void apply(List<TimeslotFrequency> timeslotFrequencies)
|
||||
{
|
||||
if(getChannel() instanceof DMRTier3Channel)
|
||||
if(getChannel() != null)
|
||||
{
|
||||
DMRTier3Channel channel = (DMRTier3Channel)getChannel();
|
||||
|
||||
for(TimeslotFrequency timeslotFrequency: timeslotFrequencies)
|
||||
{
|
||||
if(channel.getValue() == timeslotFrequency.getNumber())
|
||||
{
|
||||
channel.setTimeslotFrequency(timeslotFrequency);
|
||||
}
|
||||
}
|
||||
getChannel().apply(timeslotFrequencies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ public class DuplexPrivateDataChannelGrant extends ChannelGrant
|
||||
|
||||
sb.append(" DUPLEX PRIVATE DATA CHANNEL GRANT FM:").append(getSourceRadio());
|
||||
sb.append(" TO:").append(getDestinationRadio());
|
||||
sb.append(" CHAN:").append(getChannel());
|
||||
sb.append(" ").append(getChannel());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ public class DuplexPrivateVoiceChannelGrant extends ChannelGrant
|
||||
|
||||
sb.append(" DUPLEX PRIVATE VOICE CHANNEL GRANT FM:").append(getSourceRadio());
|
||||
sb.append(" TO:").append(getDestinationRadio());
|
||||
sb.append(" CHAN:").append(getChannel());
|
||||
sb.append(" ").append(getChannel());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ public class PrivateDataChannelGrant extends ChannelGrant
|
||||
|
||||
sb.append(" PRIVATE DATA CHANNEL GRANT FM:").append(getSourceRadio());
|
||||
sb.append(" TO:").append(getDestinationRadio());
|
||||
sb.append(" CHAN:").append(getChannel());
|
||||
sb.append(" ").append(getChannel());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ public class PrivateVoiceChannelGrant extends ChannelGrant
|
||||
|
||||
sb.append(" PRIVATE VOICE CHANNEL GRANT FM:").append(getSourceRadio());
|
||||
sb.append(" TO:").append(getDestinationRadio());
|
||||
sb.append(" CHAN:").append(getChannel());
|
||||
sb.append(" ").append(getChannel());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ public class TalkgroupDataChannelGrant extends ChannelGrant
|
||||
|
||||
sb.append(" TALKGROUP DATA CHANNEL GRANT FM:").append(getSourceRadio());
|
||||
sb.append(" TO:").append(getDestinationTalkgroup());
|
||||
sb.append(" CHAN:").append(getChannel());
|
||||
sb.append(" ").append(getChannel());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ public class TalkgroupVoiceChannelGrant extends ChannelGrant
|
||||
|
||||
sb.append(" TALKGROUP VOICE CHANNEL GRANT FM:").append(getSourceRadio());
|
||||
sb.append(" TO:").append(getDestinationTalkgroup());
|
||||
sb.append(" CHAN:").append(getChannel());
|
||||
sb.append(" ").append(getChannel());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -176,9 +176,9 @@ public class CapacityPlusWideAreaVoiceChannelUser extends CapacityPlusVoiceChann
|
||||
* Exposes the rest channel logical slot number so that a LSN to frequency map can be applied to this message.
|
||||
*/
|
||||
@Override
|
||||
public int[] getLogicalSlotNumbers()
|
||||
public int[] getLogicalChannelNumbers()
|
||||
{
|
||||
return getRestChannel().getLogicalSlotNumbers();
|
||||
return getRestChannel().getLogicalChannelNumbers();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,12 +189,6 @@ public class CapacityPlusWideAreaVoiceChannelUser extends CapacityPlusVoiceChann
|
||||
@Override
|
||||
public void apply(List<TimeslotFrequency> timeslotFrequencies)
|
||||
{
|
||||
for(TimeslotFrequency timeslotFrequency : timeslotFrequencies)
|
||||
{
|
||||
if(getRestChannel().getValue() == timeslotFrequency.getNumber())
|
||||
{
|
||||
getRestChannel().setTimeslotFrequency(timeslotFrequency);
|
||||
}
|
||||
}
|
||||
getRestChannel().apply(timeslotFrequencies);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,9 +105,9 @@ public class CapacityPlusRestChannel extends ShortLCMessage implements ITimeslot
|
||||
* Exposes the rest channel logical slot number so that a LSN to frequency map can be applied to this message.
|
||||
*/
|
||||
@Override
|
||||
public int[] getLogicalSlotNumbers()
|
||||
public int[] getLogicalChannelNumbers()
|
||||
{
|
||||
return getRestChannel().getLogicalSlotNumbers();
|
||||
return getRestChannel().getLogicalChannelNumbers();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,13 +117,7 @@ public class CapacityPlusRestChannel extends ShortLCMessage implements ITimeslot
|
||||
@Override
|
||||
public void apply(List<TimeslotFrequency> timeslotFrequencies)
|
||||
{
|
||||
for(TimeslotFrequency timeslotFrequency: timeslotFrequencies)
|
||||
{
|
||||
if(getRestChannel().getValue() == timeslotFrequency.getNumber())
|
||||
{
|
||||
getRestChannel().setTimeslotFrequency(timeslotFrequency);
|
||||
}
|
||||
}
|
||||
getRestChannel().apply(timeslotFrequencies);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -221,7 +221,7 @@ public class DecodeEventPanel extends JPanel implements Listener<ProcessingChain
|
||||
sb.append(",");
|
||||
}
|
||||
|
||||
if(identifier.getForm() == Form.TALKGROUP)
|
||||
if(identifier.getForm() == Form.TALKGROUP || identifier.getForm() == Form.RADIO || identifier.getForm() == Form.PATCH_GROUP)
|
||||
{
|
||||
sb.append(mUserPreferences.getTalkgroupFormatPreference().format(identifier));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user