diff --git a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelManager.java b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelManager.java index e4bc0153b..8c9013779 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelManager.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelManager.java @@ -23,6 +23,7 @@ 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 @@ 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 TunerChannelSource getChannel(TunerChannel tunerChannel) } 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; } } diff --git a/src/main/java/io/github/dsheirer/gui/playlist/channel/DMRConfigurationEditor.java b/src/main/java/io/github/dsheirer/gui/playlist/channel/DMRConfigurationEditor.java index 5fa5b3523..c0bfbc787 100644 --- a/src/main/java/io/github/dsheirer/gui/playlist/channel/DMRConfigurationEditor.java +++ b/src/main/java/io/github/dsheirer/gui/playlist/channel/DMRConfigurationEditor.java @@ -85,7 +85,7 @@ public class DMRConfigurationEditor extends ChannelConfigurationEditor private ToggleSwitch mUseCompressedTalkgroupsToggle; private Spinner mTrafficChannelPoolSizeSpinner; private TableView mTimeslotFrequencyTable; - private IntegerTextField mLogicalSlotNumberField; + private IntegerTextField mLogicalChannelNumberField; private FrequencyField mDownlinkFrequencyField; // private FrequencyField mUplinkFrequencyField; private Button mAddTimeslotFrequencyButton; @@ -172,7 +172,7 @@ private TitledPane getDecoderPane() 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 @@ private TitledPane getDecoderPane() 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 @@ private TableView getTimeslotTable() mTimeslotFrequencyTable = new TableView<>(FXCollections.observableArrayList(TimeslotFrequency.extractor())); mTimeslotFrequencyTable.setPrefHeight(100.0); - TableColumn numberColumn = new TableColumn("LSN"); - numberColumn.setPrefWidth(70); + TableColumn numberColumn = new TableColumn("LCN"); + numberColumn.setPrefWidth(75); numberColumn.setCellValueFactory(cellData -> cellData.getValue().getNumberProperty()); mTimeslotFrequencyTable.getColumns().addAll(numberColumn); mTimeslotFrequencyTable.getSortOrder().add(numberColumn); TableColumn downlinkColumn = new TableColumn("Frequency (MHz)"); downlinkColumn.setCellValueFactory(cellData -> cellData.getValue().getDownlinkMHz()); - downlinkColumn.setPrefWidth(175); + downlinkColumn.setPrefWidth(150); mTimeslotFrequencyTable.getColumns().addAll(downlinkColumn); -// TableColumn uplinkColumn = new TableColumn("Uplink (MHz)"); -// uplinkColumn.setCellValueFactory(cellData -> cellData.getValue().getUplinkMHz()); -// mTimeslotFrequencyTable.getColumns().addAll(uplinkColumn); + TableColumn 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 @@ private void setTimeslot(TimeslotFrequency timeslot) //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 void handle(ActionEvent event) 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 @@ private IntegerTextField getLogicalSlotNumberField() }); } - return mLogicalSlotNumberField; + return mLogicalChannelNumberField; } private FrequencyField getDownlinkFrequencyField() @@ -610,8 +608,8 @@ protected void setDecoderConfiguration(DecodeConfiguration config) 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); diff --git a/src/main/java/io/github/dsheirer/gui/playlist/radioreference/RadioReferenceDecoder.java b/src/main/java/io/github/dsheirer/gui/playlist/radioreference/RadioReferenceDecoder.java index 9027d9674..d0eb7b95f 100644 --- a/src/main/java/io/github/dsheirer/gui/playlist/radioreference/RadioReferenceDecoder.java +++ b/src/main/java/io/github/dsheirer/gui/playlist/radioreference/RadioReferenceDecoder.java @@ -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.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 List getTimeslotFrequencies(SystemInformation systemIn } } - 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; diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/DMRDecoderState.java b/src/main/java/io/github/dsheirer/module/decode/dmr/DMRDecoderState.java index 5cc33f1dd..6d1fdf3cd 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/DMRDecoderState.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/DMRDecoderState.java @@ -90,9 +90,9 @@ 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 mDetectedCallEventsMap = new TreeMap<>(); + private Map mDetectedCallEventsMap = new HashMap<>(); private static final AddChannelRotationActiveStateRequest CAPACITY_PLUS_ACTIVE_STATE_REQUEST = new AddChannelRotationActiveStateRequest(State.ACTIVE); @@ -417,7 +417,7 @@ else if(packet.getPacket() instanceof XCMPPacket xcmp) 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 @@ else if(packet.getPacket() instanceof XCMPPacket xcmp) 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 @@ private void processCSBK(CSBKMessage csbk) 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 @@ private void processCSBK(CSBKMessage csbk) 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 @@ private void processCSBK(CSBKMessage csbk) { 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 @@ private void processCSBK(CSBKMessage csbk) 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 @@ private void processCSBK(CSBKMessage csbk) 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 @@ private void processCSBK(CSBKMessage csbk) 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 @@ private void processCSBK(CSBKMessage csbk) 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 @@ private void processCSBK(CSBKMessage csbk) 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 @@ private void processCSBK(CSBKMessage csbk) } 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(); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/DMRMessageProcessor.java b/src/main/java/io/github/dsheirer/module/decode/dmr/DMRMessageProcessor.java index 97a9f3672..c3a6f4597 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/DMRMessageProcessor.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/DMRMessageProcessor.java @@ -127,19 +127,19 @@ else if(message instanceof DMRBurst dmrBurst && dmrBurst.isValid()) } } - //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 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)); } } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/DMRNetworkConfigurationMonitor.java b/src/main/java/io/github/dsheirer/module/decode/dmr/DMRNetworkConfigurationMonitor.java index 857d46f7f..8ce211671 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/DMRNetworkConfigurationMonitor.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/DMRNetworkConfigurationMonitor.java @@ -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 - * * ***************************************************************************** + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** */ package io.github.dsheirer.module.decode.dmr; @@ -41,14 +38,13 @@ 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 void process(CSBKMessage csbk) ConnectPlusNeighborReport cpnr = (ConnectPlusNeighborReport)csbk; mNeighborSites.addAll(cpnr.getNeighbors()); } - if(mBrand == null) + if(mBrand == null || mBrand != BRAND_MOTOROLA_CONNECT_PLUS) { mBrand = BRAND_MOTOROLA_CONNECT_PLUS; } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/DMRTrafficChannelManager.java b/src/main/java/io/github/dsheirer/module/decode/dmr/DMRTrafficChannelManager.java index 3b64a8e8a..9d0e18dda 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/DMRTrafficChannelManager.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/DMRTrafficChannelManager.java @@ -98,7 +98,7 @@ public class DMRTrafficChannelManager extends TrafficChannelManager implements I private List mManagedTrafficChannels; private Map mAllocatedTrafficChannelFrequencyMap = new ConcurrentHashMap<>(); - private Map mLSNGrantEventMap = new ConcurrentHashMap<>(); + private Map mChannelGrantEventMap = new ConcurrentHashMap<>(); private Listener mChannelEventListener; private Listener mDecodeEventListener; @@ -322,9 +322,7 @@ public void processEndChannelGrant() 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 void processChannelGrant(DMRChannel channel, IdentifierCollection identif .identifiers(identifierCollection) .build(); - mLSNGrantEventMap.put(lsn, event); + mChannelGrantEventMap.put(channel, event); } else //Update current event @@ -355,7 +353,7 @@ public void processChannelGrant(DMRChannel channel, IdentifierCollection identif .identifiers(identifierCollection) .build(); - mLSNGrantEventMap.put(lsn, event); + mChannelGrantEventMap.put(channel, event); broadcast(event); } } @@ -643,37 +641,37 @@ public class TrafficChannelTeardownMonitor implements Listener */ private void removeCallEvents(long frequency) { - List lsnsToRemove = new ArrayList<>(); + List channelsToRemove = new ArrayList<>(); - for(Map.Entry entry: mLSNGrantEventMap.entrySet()) + for(Map.Entry 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 lsnsToUpdate = new ArrayList<>(); + List channelsToUpdate = new ArrayList<>(); - for(Map.Entry entry: mLSNGrantEventMap.entrySet()) + for(Map.Entry 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) { diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/channel/DMRChannel.java b/src/main/java/io/github/dsheirer/module/decode/dmr/channel/DMRChannel.java index e4653a2ca..cc2040c9e 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/channel/DMRChannel.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/channel/DMRChannel.java @@ -26,6 +26,8 @@ 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 @@ * * 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 Protocol getProtocol() } /** - * 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 boolean isTDMAChannel() @Override public String toString() { - return "CHAN:" + getChannel() + ":" + getTimeslot(); + return "CHAN:" + getChannelNumber() + ":" + getTimeslot(); } /** @@ -115,4 +128,72 @@ public void setFrequencyBand(IFrequencyBand bandIdentifier) { 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 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()); + } } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/channel/DMRLsn.java b/src/main/java/io/github/dsheirer/module/decode/dmr/channel/DMRLsn.java index 1cb9c5a83..ceb74c33d 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/channel/DMRLsn.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/channel/DMRLsn.java @@ -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 @@ * 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 DMRLsn(int lsn) @Override public String toString() { - return "LSN:" + getLsn(); + return "LSN:" + getLsn() + " LCN:" + getChannelNumber(); } /** @@ -70,65 +66,7 @@ public String toString() */ public int getLsn() { - return ((getChannel() - 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; + return ((getChannelNumber() - 1) * 2) + getTimeslot(); } - @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 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); - } - } } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/channel/DMRTier3Channel.java b/src/main/java/io/github/dsheirer/module/decode/dmr/channel/DMRTier3Channel.java index 3955bc46b..b14b2a10a 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/channel/DMRTier3Channel.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/channel/DMRTier3Channel.java @@ -24,14 +24,12 @@ */ 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 DMRTier3Channel(int channel, int timeslot) } /** - * Downlink frequency - * @return value in Hertz, or 0 if this channel doesn't have a timeslot frequency mapping - */ - @Override - public long getDownlinkFrequency() - { - 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 + * Tier III Channel ID + * @return channel ID */ - public void setTimeslotFrequency(TimeslotFrequency timeslotFrequency) + public int getChannelId() { - mTimeslotFrequency = timeslotFrequency; + return getChannelNumber() * 2 + getTimeslot(); } /** @@ -83,7 +51,8 @@ public void setTimeslotFrequency(TimeslotFrequency timeslotFrequency) 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(); } } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/channel/ITimeslotFrequencyReceiver.java b/src/main/java/io/github/dsheirer/module/decode/dmr/channel/ITimeslotFrequencyReceiver.java index fffd15418..50f5b9bd7 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/channel/ITimeslotFrequencyReceiver.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/channel/ITimeslotFrequencyReceiver.java @@ -24,9 +24,9 @@ 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 diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/channel/TimeslotFrequency.java b/src/main/java/io/github/dsheirer/module/decode/dmr/channel/TimeslotFrequency.java index 1a5a4e810..a83d730e7 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/channel/TimeslotFrequency.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/channel/TimeslotFrequency.java @@ -31,7 +31,7 @@ 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 DoubleProperty getUplinkMHz() } /** - * 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 int getNumber() } /** - * 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() + { + 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(lsn); + mNumberProperty.set(lcn); } /** @@ -160,7 +203,7 @@ public void setUplinkFrequency(long uplinkFrequency) @Override public String toString() { - return "TIMESLOT LSN:" + getNumber() + " DOWNLINK:" + getDownlinkFrequency(); + return "LCN:" + getNumber() + " DOWNLINK:" + getDownlinkFrequency(); } /** diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusNeighbors.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusNeighbors.java index 409d10bad..c228ae9be 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusNeighbors.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusNeighbors.java @@ -299,9 +299,9 @@ public DmrRestLsn getRestChannel() } @Override - public int[] getLogicalSlotNumbers() + public int[] getLogicalChannelNumbers() { - return getRestChannel().getLogicalSlotNumbers(); + return getRestChannel().getLogicalChannelNumbers(); } /** @@ -312,13 +312,7 @@ public int[] getLogicalSlotNumbers() @Override public void apply(List timeslotFrequencies) { - for(TimeslotFrequency timeslotFrequency : timeslotFrequencies) - { - if(timeslotFrequency.getNumber() == getRestChannel().getValue()) - { - getRestChannel().setTimeslotFrequency(timeslotFrequency); - } - } + getRestChannel().apply(timeslotFrequencies); } @Override diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusSiteStatus.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusSiteStatus.java index d42a49543..6a7c7651d 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusSiteStatus.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusSiteStatus.java @@ -299,9 +299,9 @@ public int getRestLSN() * 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 int[] getLogicalSlotNumbers() @Override public void apply(List timeslotFrequencies) { - for(TimeslotFrequency timeslotFrequency : timeslotFrequencies) - { - if(getRestChannel().getValue() == timeslotFrequency.getNumber()) - { - getRestChannel().setTimeslotFrequency(timeslotFrequency); - } - } + getRestChannel().apply(timeslotFrequencies); } @Override diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusDataChannelGrant.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusDataChannelGrant.java index b2e56521d..dedd64f9a 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusDataChannelGrant.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusDataChannelGrant.java @@ -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 int getUnknownField() } /** - * 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 DMRLsn getChannel() { 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 int[] getLogicalSlotNumbers() @Override public void apply(List timeslotFrequencies) { - for(TimeslotFrequency timeslotFrequency: timeslotFrequencies) - { - if(timeslotFrequency.getNumber() == getChannel().getValue()) - { - getChannel().setTimeslotFrequency(timeslotFrequency); - } - } + getChannel().apply(timeslotFrequencies); } @Override diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusOTAAnnouncement.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusOTAAnnouncement.java index a886be8e0..1da6ac4aa 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusOTAAnnouncement.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusOTAAnnouncement.java @@ -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 mIdentifiers; @@ -99,11 +99,11 @@ public int getMessageVersion() } /** - * 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 DMRLsn getDataChannel() { 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 int[] getLogicalSlotNumbers() @Override public void apply(List timeslotFrequencies) { - for(TimeslotFrequency timeslotFrequency : timeslotFrequencies) - { - if(timeslotFrequency.getNumber() == getDataChannel().getValue()) - { - getDataChannel().setTimeslotFrequency(timeslotFrequency); - } - } + getDataChannel().apply(timeslotFrequencies); } @Override diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusVoiceChannelUser.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusVoiceChannelUser.java index ea6741639..e09ca5d3b 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusVoiceChannelUser.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusVoiceChannelUser.java @@ -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 int getUnknownField() /** * 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 DMRLsn getChannel() { 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 int[] getLogicalSlotNumbers() @Override public void apply(List timeslotFrequencies) { - for(TimeslotFrequency timeslotFrequency: timeslotFrequencies) - { - if(timeslotFrequency.getNumber() == getChannel().getValue()) - { - getChannel().setTimeslotFrequency(timeslotFrequency); - } - } + getChannel().apply(timeslotFrequencies); } @Override diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/Clear.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/Clear.java index d99632c14..b84ebd242 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/Clear.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/Clear.java @@ -25,7 +25,6 @@ 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 DMRChannel getMoveToChannel() * 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 int[] getLogicalSlotNumbers() @Override public void apply(List 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); } } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/MoveTSCC.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/MoveTSCC.java index b8c791c8f..d3579412c 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/MoveTSCC.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/MoveTSCC.java @@ -88,7 +88,8 @@ public MoveTSCC(DMRSyncPattern syncPattern, CorrectedBinaryMessage message, CACH 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); } } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/announcement/AdjacentSiteInformation.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/announcement/AdjacentSiteInformation.java index 73121bdec..3baae7139 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/announcement/AdjacentSiteInformation.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/announcement/AdjacentSiteInformation.java @@ -84,8 +84,8 @@ public AdjacentSiteInformation(DMRSyncPattern syncPattern, CorrectedBinaryMessag 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); } } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/announcement/AnnounceChannelFrequency.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/announcement/AnnounceChannelFrequency.java index bdbedeb11..3213f4026 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/announcement/AnnounceChannelFrequency.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/announcement/AnnounceChannelFrequency.java @@ -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.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 AnnounceChannelFrequency(DMRSyncPattern syncPattern, CorrectedBinaryMessa if(multiBlock != null) { - mAbsoluteChannelParameters = new AbsoluteChannelParameters(multiBlock.getMessage(), 0, 0); + //Timeslot hard-coded to one + mAbsoluteChannelParameters = new AbsoluteChannelParameters(multiBlock.getMessage(), 0, 1); } } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/announcement/AnnounceWithdrawTSCC.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/announcement/AnnounceWithdrawTSCC.java index b1674fde3..99a09bb3f 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/announcement/AnnounceWithdrawTSCC.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/announcement/AnnounceWithdrawTSCC.java @@ -86,8 +86,8 @@ public AnnounceWithdrawTSCC(DMRSyncPattern syncPattern, CorrectedBinaryMessage m 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); } } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/announcement/VoteNowAdvice.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/announcement/VoteNowAdvice.java index c0c5c6dab..5850895b5 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/announcement/VoteNowAdvice.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/announcement/VoteNowAdvice.java @@ -23,7 +23,6 @@ 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 VoteNowAdvice(DMRSyncPattern syncPattern, CorrectedBinaryMessage message, 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 List getIdentifiers() * 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 int[] getLogicalSlotNumbers() @Override public void apply(List 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); } } } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/BroadcastTalkgroupVoiceChannelGrant.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/BroadcastTalkgroupVoiceChannelGrant.java index 859bf907e..dff501891 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/BroadcastTalkgroupVoiceChannelGrant.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/BroadcastTalkgroupVoiceChannelGrant.java @@ -104,7 +104,7 @@ public String toString() 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(); } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/ChannelGrant.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/ChannelGrant.java index 6229430e4..555781035 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/ChannelGrant.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/ChannelGrant.java @@ -22,7 +22,6 @@ 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 DMRChannel getChannel() * 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 int[] getLogicalSlotNumbers() @Override public void apply(List 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); } } } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/DuplexPrivateDataChannelGrant.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/DuplexPrivateDataChannelGrant.java index 5b68cb9ac..6e42736a7 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/DuplexPrivateDataChannelGrant.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/DuplexPrivateDataChannelGrant.java @@ -103,7 +103,7 @@ public String toString() 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(); } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/DuplexPrivateVoiceChannelGrant.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/DuplexPrivateVoiceChannelGrant.java index eab51690a..c9fdcca7a 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/DuplexPrivateVoiceChannelGrant.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/DuplexPrivateVoiceChannelGrant.java @@ -103,7 +103,7 @@ public String toString() 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(); } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/PrivateDataChannelGrant.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/PrivateDataChannelGrant.java index 58400f5dc..f643f66e7 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/PrivateDataChannelGrant.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/PrivateDataChannelGrant.java @@ -108,7 +108,7 @@ public String toString() 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(); } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/PrivateVoiceChannelGrant.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/PrivateVoiceChannelGrant.java index 74492622f..d68889090 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/PrivateVoiceChannelGrant.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/PrivateVoiceChannelGrant.java @@ -102,7 +102,7 @@ public String toString() 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(); } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/TalkgroupDataChannelGrant.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/TalkgroupDataChannelGrant.java index 49e542577..e44f46a80 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/TalkgroupDataChannelGrant.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/TalkgroupDataChannelGrant.java @@ -110,7 +110,7 @@ public String toString() 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(); } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/TalkgroupVoiceChannelGrant.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/TalkgroupVoiceChannelGrant.java index 3406e6859..a52526ba7 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/TalkgroupVoiceChannelGrant.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/grant/TalkgroupVoiceChannelGrant.java @@ -104,7 +104,7 @@ public String toString() 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(); } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/full/motorola/CapacityPlusWideAreaVoiceChannelUser.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/full/motorola/CapacityPlusWideAreaVoiceChannelUser.java index f44af10e4..25e38f833 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/full/motorola/CapacityPlusWideAreaVoiceChannelUser.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/full/motorola/CapacityPlusWideAreaVoiceChannelUser.java @@ -176,9 +176,9 @@ public List getIdentifiers() * 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 int[] getLogicalSlotNumbers() @Override public void apply(List timeslotFrequencies) { - for(TimeslotFrequency timeslotFrequency : timeslotFrequencies) - { - if(getRestChannel().getValue() == timeslotFrequency.getNumber()) - { - getRestChannel().setTimeslotFrequency(timeslotFrequency); - } - } + getRestChannel().apply(timeslotFrequencies); } } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/shorty/CapacityPlusRestChannel.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/shorty/CapacityPlusRestChannel.java index b3e3e893b..51e79fa29 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/shorty/CapacityPlusRestChannel.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/shorty/CapacityPlusRestChannel.java @@ -105,9 +105,9 @@ public int getRestLSN() * 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 int[] getLogicalSlotNumbers() @Override public void apply(List timeslotFrequencies) { - for(TimeslotFrequency timeslotFrequency: timeslotFrequencies) - { - if(getRestChannel().getValue() == timeslotFrequency.getNumber()) - { - getRestChannel().setTimeslotFrequency(timeslotFrequency); - } - } + getRestChannel().apply(timeslotFrequencies); } @Override diff --git a/src/main/java/io/github/dsheirer/module/decode/event/DecodeEventPanel.java b/src/main/java/io/github/dsheirer/module/decode/event/DecodeEventPanel.java index 4dcec1515..2105d4f47 100644 --- a/src/main/java/io/github/dsheirer/module/decode/event/DecodeEventPanel.java +++ b/src/main/java/io/github/dsheirer/module/decode/event/DecodeEventPanel.java @@ -221,7 +221,7 @@ protected String format(List identifiers) 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)); }