diff --git a/src/main/java/io/github/dsheirer/edac/BPTC_196_96.java b/src/main/java/io/github/dsheirer/edac/BPTC_196_96.java index cd01f6775..0d5ac81b4 100644 --- a/src/main/java/io/github/dsheirer/edac/BPTC_196_96.java +++ b/src/main/java/io/github/dsheirer/edac/BPTC_196_96.java @@ -1,9 +1,27 @@ +/* + * ***************************************************************************** + * 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 + * 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.edac; import io.github.dsheirer.bits.BinaryMessage; import io.github.dsheirer.bits.BitSetFullException; import io.github.dsheirer.bits.CorrectedBinaryMessage; - import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -14,7 +32,7 @@ public class BPTC_196_96 { public static final int BPTC_LENGTH = 196; - public static final int EXTRACTED_LENGTH = 96; + public static final int EXTRACTED_LENGTH = 96; //However, we set the 3x reserved bits in 96, 97, and 98 making the length 99 public static final int MAX_ORIGINAL_INDEX = 136; public static final int COLUMN_COUNT = 15; public static final int MESSAGE_COLUMN_COUNT = 12; //Should be 11, but adjusted for the first pad bit @@ -99,6 +117,11 @@ public static CorrectedBinaryMessage extract(CorrectedBinaryMessage original) } } + //Transfer bits R2, R1, and R0 to the end - RAS bits + extracted.set(96, message.get(0)); + extracted.set(97, message.get(1)); + extracted.set(98, message.get(2)); + return extracted; } 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 d24a223e1..5c34c1bd6 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 @@ -44,7 +44,7 @@ import io.github.dsheirer.module.decode.dmr.message.data.csbk.CSBKMessage; import io.github.dsheirer.module.decode.dmr.message.data.csbk.motorola.CapacityMaxAloha; import io.github.dsheirer.module.decode.dmr.message.data.csbk.motorola.CapacityPlusNeighbors; -import io.github.dsheirer.module.decode.dmr.message.data.csbk.motorola.CapacityPlusSystemStatus; +import io.github.dsheirer.module.decode.dmr.message.data.csbk.motorola.CapacityPlusSiteStatus; import io.github.dsheirer.module.decode.dmr.message.data.csbk.motorola.ConnectPlusDataChannelGrant; import io.github.dsheirer.module.decode.dmr.message.data.csbk.motorola.ConnectPlusVoiceChannelUser; import io.github.dsheirer.module.decode.dmr.message.data.csbk.standard.Aloha; @@ -674,9 +674,9 @@ private void processCSBK(CSBKMessage csbk) } break; case MOTOROLA_CAPPLUS_SYSTEM_STATUS: - if(csbk instanceof CapacityPlusSystemStatus) + if(csbk instanceof CapacityPlusSiteStatus) { - CapacityPlusSystemStatus cpss = (CapacityPlusSystemStatus)csbk; + CapacityPlusSiteStatus cpss = (CapacityPlusSiteStatus)csbk; //Channel rotation monitor normally uses only CONTROL state, so when we detect that we're a //Capacity plus system, add ACTIVE as an active state to the monitor. This can be requested repeatedly. diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/DMRMessageFramer.java b/src/main/java/io/github/dsheirer/module/decode/dmr/DMRMessageFramer.java index bf54f344b..7fd234b16 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/DMRMessageFramer.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/DMRMessageFramer.java @@ -377,7 +377,7 @@ private static Identity getIdentity(LRRPPacket packet) public static void main(String[] args) { - String path = "/media/denny/Lexar/Recordings/DMR/"; + String path = "/media/denny/T7 Shield/Recordings/DMR/"; //Con+ Traffic + Voice // String file = path + "20200513_143340_9600BPS_DMR_SaiaNet_Onondaga_Control.bits"; //Enh GPS Revert Window Annce @@ -385,7 +385,7 @@ public static void main(String[] args) // String file = path + "20200514_063507_9600BPS_DMR_SaiaNet_Onondaga_LCN_3_Control.bits"; //GPS Window Grant 2579 // String file = path + "20200514_064224_9600BPS_DMR_SaiaNet_Onondaga_LCN_3_Control.bits"; //GPS Window Grant 5056035 // String file = path + "20200514_131623_9600BPS_DMR_SaiaNet_Onondaga_LCN_3_Control.bits"; //GPS Grant: 5074193 - String file = path + "20200514_133947_9600BPS_DMR_SaiaNet_Onondaga_LCN_4.bits"; //<<<<<<<------ Basic Encryption +// String file = path + "SaiaNet/20200514_133947_9600BPS_DMR_SaiaNet_Onondaga_LCN_4.bits"; //<<<<<<<------ Basic Encryption // String file = path + "20200514_142249_9600BPS_DMR_SaiaNet_Onondaga_LCN_4.bits"; // String file = path + "20200514_144534_9600BPS_DMR_SaiaNet_Onondaga_LCN_3_Control.bits"; //Con+ Control w/GPS Window Announce @@ -395,12 +395,16 @@ public static void main(String[] args) //Cap-Max Tier III CC // String file = path + "20200710_053632_9600BPS_DMR_Niles_Radio_Coconino_Control.bits"; - //Cap+ Multi-Site 1 - Traffic LCN 2 -// String file = path + "20200716_210133_9600BPS_DMR_Aerowave_Technologies_Dallas_LCN_2.bits"; -// String file = path + "20200716_212309_9600BPS_DMR_Aerowave_Technologies_Dallas_LCN_2.bits"; + //Cap+ Multi-Site 1 - Data Revert LSN1/2 with CSBKO 62 Site status +// String file = path + "Texas_Dallas_Aerowave_Capacity_Plus_Multi_Site/20200716_210133_9600BPS_DMR_Aerowave_Technologies_Dallas_LCN_2.bits"; +// String file = path + "Texas_Dallas_Aerowave_Capacity_Plus_Multi_Site/20200716_210845_9600BPS_DMR_Aerowave_Technologies_Dallas_LCN_2.bits"; +// String file = path + "Texas_Dallas_Aerowave_Capacity_Plus_Multi_Site/20200716_212309_9600BPS_DMR_Aerowave_Technologies_Dallas_LCN_2.bits"; - //Cap+ Multi-Site Enhanced GPS Channel -// String file = path + "20200714_224018_9600BPS_DMR_Farmers_Electric_Cooperative_Hunt_LCN_3.bits"; //This may have PLL mis-align issues + //Cap+ Multi-Site Enhanced Data Revert Channel (no CSBKO 62) +// String file = path + "Texas_Hunt_Farmers_Electric_Capacity_Plus_Multi_Site/20200714_224018_9600BPS_DMR_Farmers_Electric_Cooperative_Hunt_LCN_3.bits"; //This may have PLL mis-align issues + + //Cap+ Multi-Site - Dallas Unknown + String file = path + "Texas_Dallas_Unknown_1_Capacity_Plus_Multi_Site/20200716_211233_9600BPS_DMR_Dallas_Unk_Dallas_Unk.bits"; //Hytera Short Data = Proprietary (encrypted) // String file = path + "20200716_222839_9600BPS_DMR_SystemUnk_SiteUnk_Unk.bits"; //Hytera short data packets 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 1661f27da..0ac7d2271 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 @@ -111,6 +111,9 @@ public void receive(IMessage message) } } + //Now that the message has been (potentially) enriched, dispatch it to the modules + dispatch(message); + //Extract the Full Link Control message fragment from the Voice with embedded signalling message if(message instanceof VoiceEMBMessage) { @@ -202,9 +205,6 @@ else if((message instanceof IDLEMessage || message instanceof Aloha || message i { dispatch(mTalkerAliasAssembler.process(flc)); } - - //Now that the message has been (potentially) enriched, dispatch it to the modules - dispatch(message); } /** diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/channel/DMRLogicalChannel.java b/src/main/java/io/github/dsheirer/module/decode/dmr/channel/DMRLogicalChannel.java index 9117b9542..07088f10f 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/channel/DMRLogicalChannel.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/channel/DMRLogicalChannel.java @@ -1,23 +1,20 @@ /* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer * - * * ****************************************************************************** - * * Copyright (C) 2014-2019 Dennis Sheirer - * * - * * This program is free software: you can redistribute it and/or modify - * * it under the terms of the GNU General Public License as published by - * * 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.channel; @@ -87,7 +84,7 @@ public String toString() { StringBuilder sb = new StringBuilder(); sb.append("LSN:").append(getLogicalSlotNumber()); - sb.append(" LCN:").append(getValue()); +// sb.append(" LCN:").append(getValue()); return sb.toString(); } } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/DataMessage.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/DataMessage.java index 79b2581ba..fa660d4b7 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/DataMessage.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/DataMessage.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 @@ -28,6 +28,9 @@ */ public abstract class DataMessage extends DMRBurst { + //R2, R1, R0 extracted from the BPTC extraction process. Note: message length remains at 96, even though these 3x bits + //are set at the end of the message. + private static final int[] BPTC_RESERVED_BITS = new int[]{96, 97, 98}; private SlotType mSlotType; /** @@ -54,4 +57,24 @@ public SlotType getSlotType() { return mSlotType; } + + /** + * 3x reserved bits that are left-over from the BPTC encode/decode process that can be used to hold values like + * Moto RAS indicator. These message length from the BPTC decoder is set to 96 and these 3x bits are appended to + * the end. However, to keep the message.toString() correct, we specify the length as 96. + * @return reserved value. + */ + public int getBPTCReservedBits() + { + return getMessage().getInt(BPTC_RESERVED_BITS); + } + + /** + * Indicates if the BPTC reserved bits value is anything other than 0. + * @return true if non-zero. + */ + public boolean hasRAS() + { + return getBPTCReservedBits() != 0; + } } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/DataMessageWithLinkControl.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/DataMessageWithLinkControl.java index 6c9d1c419..a7c56e5dd 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/DataMessageWithLinkControl.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/DataMessageWithLinkControl.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 @@ -26,7 +26,6 @@ import io.github.dsheirer.module.decode.dmr.message.data.lc.LCMessage; import io.github.dsheirer.module.decode.dmr.message.data.lc.LCMessageFactory; import io.github.dsheirer.module.decode.dmr.message.type.DataType; - import java.util.Collections; import java.util.List; @@ -71,6 +70,10 @@ public LCMessage getLCMessage() public String toString() { StringBuilder sb = new StringBuilder(); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(getSlotType()); sb.append(" ").append(getLCMessage()); return sb.toString(); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/IDLEMessage.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/IDLEMessage.java index 4e6acbc59..60a6924b8 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/IDLEMessage.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/IDLEMessage.java @@ -1,7 +1,6 @@ /* - * ****************************************************************************** - * sdrtrunk - * Copyright (C) 2014-2020 Zhenyu Mao + * ***************************************************************************** + * 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 @@ -15,7 +14,7 @@ * * 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.message.data; @@ -23,7 +22,6 @@ import io.github.dsheirer.identifier.Identifier; import io.github.dsheirer.module.decode.dmr.DMRSyncPattern; import io.github.dsheirer.module.decode.dmr.message.CACH; - import java.util.Collections; import java.util.List; @@ -50,6 +48,12 @@ public String toString() { StringBuilder sb = new StringBuilder(); sb.append("CC:").append(getSlotType().getColorCode()); + + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } + sb.append(" IDLE"); return sb.toString(); } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/UnknownDataMessage.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/UnknownDataMessage.java index a31199a77..ad5e9b359 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/UnknownDataMessage.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/UnknownDataMessage.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 @@ -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.message.CACH; - import java.util.Collections; import java.util.List; @@ -61,6 +60,11 @@ public String toString() sb.append("TS").append(getTimeslot()); } + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } + sb.append(" ").append(getSlotType()); sb.append(" ").append(getMessage().toHexString()); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/block/DataBlock.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/block/DataBlock.java index 15696a83a..4026b5e6b 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/block/DataBlock.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/block/DataBlock.java @@ -75,6 +75,11 @@ public String toString() { StringBuilder sb = new StringBuilder(); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } + sb.append(" ").append(getSlotType()); sb.append(" ").append(getMessage().toHexString()); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/CSBKMessageFactory.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/CSBKMessageFactory.java index a2f91f1f5..1254409dd 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/CSBKMessageFactory.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/CSBKMessageFactory.java @@ -39,7 +39,7 @@ import io.github.dsheirer.module.decode.dmr.message.data.csbk.motorola.CapacityPlusDataRevertWindowGrant; import io.github.dsheirer.module.decode.dmr.message.data.csbk.motorola.CapacityPlusNeighbors; import io.github.dsheirer.module.decode.dmr.message.data.csbk.motorola.CapacityPlusPreamble; -import io.github.dsheirer.module.decode.dmr.message.data.csbk.motorola.CapacityPlusSystemStatus; +import io.github.dsheirer.module.decode.dmr.message.data.csbk.motorola.CapacityPlusSiteStatus; import io.github.dsheirer.module.decode.dmr.message.data.csbk.motorola.ConnectPlusCSBKO_16; import io.github.dsheirer.module.decode.dmr.message.data.csbk.motorola.ConnectPlusDataChannelGrant; import io.github.dsheirer.module.decode.dmr.message.data.csbk.motorola.ConnectPlusDataRevertWindowAnnouncement; @@ -269,7 +269,7 @@ public static CSBKMessage create(DMRSyncPattern pattern, CorrectedBinaryMessage csbk = new CapacityPlusPreamble(pattern, message, cach, slotType, timestamp, timeslot); break; case MOTOROLA_CAPPLUS_SYSTEM_STATUS: - csbk = new CapacityPlusSystemStatus(pattern, message, cach, slotType, timestamp, timeslot); + csbk = new CapacityPlusSiteStatus(pattern, message, cach, slotType, timestamp, timeslot); break; case MOTOROLA_CAPPLUS_DATA_WINDOW_ANNOUNCEMENT: csbk = new CapacityPlusDataRevertWindowAnnouncement(pattern, message, cach, slotType, timestamp, timeslot); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/UnknownCSBKMessage.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/UnknownCSBKMessage.java index d43af5e96..99c5610f6 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/UnknownCSBKMessage.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/UnknownCSBKMessage.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 @@ -25,7 +25,6 @@ import io.github.dsheirer.module.decode.dmr.message.CACH; import io.github.dsheirer.module.decode.dmr.message.data.SlotType; import io.github.dsheirer.module.decode.dmr.message.type.Vendor; - import java.util.Collections; import java.util.List; @@ -60,6 +59,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" CSBK *UNKNOWN*"); Vendor vendor = getVendor(); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/Hytera08Acknowledge.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/Hytera08Acknowledge.java index 7f2ee4b07..17ad6c591 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/Hytera08Acknowledge.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/Hytera08Acknowledge.java @@ -83,6 +83,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" HYTERA 08 ").append(getAcknowledgeType()); sb.append(" REASON:"); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/Hytera68Acknowledge.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/Hytera68Acknowledge.java index 8d324e82b..c8a4b6253 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/Hytera68Acknowledge.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/Hytera68Acknowledge.java @@ -82,6 +82,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" HYTERA 68 ").append(getAcknowledgeType()); sb.append(" REASON:"); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraAloha.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraAloha.java index b272ceb5f..6412c40ab 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraAloha.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraAloha.java @@ -85,6 +85,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" HYTERA ALOHA"); if(hasRadioIdentifier()) diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraAnnouncement.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraAnnouncement.java index f1be96cad..a5c0edbf6 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraAnnouncement.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraAnnouncement.java @@ -77,6 +77,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" HYTERA ANNOUNCEMENT-TYPE:").append(getAnnouncementType()); sb.append(" ").append(getSystemIdentityCode().getModel()); sb.append(" NETWORK:").append(getSystemIdentityCode().getNetwork()); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraCsbko44.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraCsbko44.java index 09192d041..f735819d9 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraCsbko44.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraCsbko44.java @@ -67,6 +67,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" HYTERA UNKNOWN CSBKO=44"); sb.append(" MSG:").append(getMessage().toHexString()); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraCsbko47.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraCsbko47.java index ee6a562b6..e6b963986 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraCsbko47.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraCsbko47.java @@ -75,6 +75,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" HYTERA CSBKO=47 ######### UNKNOWN"); sb.append(" FM:").append(getSourceRadio()); sb.append(" TO:").append(getDestinationRadio()); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraSmsAvailableNotification.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraSmsAvailableNotification.java index f70f66bff..ca3b52058 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraSmsAvailableNotification.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraSmsAvailableNotification.java @@ -75,6 +75,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" HYTERA SMS MESSAGE AVAILABLE FOR:").append(getDestinationRadio()); sb.append(" FM:").append(getSourceRadio()); sb.append(" UNK:").append(getUnknown()); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraXPTSiteState.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraXPTSiteState.java index 62649aebd..26d04c781 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraXPTSiteState.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/hytera/HyteraXPTSiteState.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 @@ -25,7 +25,6 @@ import io.github.dsheirer.module.decode.dmr.message.CACH; import io.github.dsheirer.module.decode.dmr.message.data.SlotType; import io.github.dsheirer.module.decode.dmr.message.data.csbk.CSBKMessage; - import java.util.ArrayList; import java.util.List; @@ -234,6 +233,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" HYTERA XPT SITE "); if(isAllChannelsBusy()) diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityMaxAloha.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityMaxAloha.java index 64e2a1de3..32fc3fd28 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityMaxAloha.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityMaxAloha.java @@ -82,6 +82,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" CSBK CAPACITY-MAX ALOHA"); if(hasRadioIdentifier()) diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusCSBKO_60.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusCSBKO_60.java index a16cb2bce..446cd86bb 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusCSBKO_60.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusCSBKO_60.java @@ -59,6 +59,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" CSBK CAP+ *UNKNOWN* CSBK:60"); sb.append(" MSG:").append(getMessage().toHexString()); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusDataRevertWindowAnnouncement.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusDataRevertWindowAnnouncement.java index e5e3b0f30..b663f5c67 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusDataRevertWindowAnnouncement.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusDataRevertWindowAnnouncement.java @@ -88,6 +88,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" CSBK CAP+ ENHANCED DATA REVERT ANNOUNCEMENT"); sb.append(" WINDOW:").append(getSuperFrame()).append(".").append(getWindow()); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusDataRevertWindowGrant.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusDataRevertWindowGrant.java index 0d0f2a431..9518a49e6 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusDataRevertWindowGrant.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusDataRevertWindowGrant.java @@ -71,6 +71,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" CSBK CAP+ ENHANCED DATA REVERT GRANT TO:").append(getTargetAddress()); sb.append(" TRANSMIT IN WINDOW:").append(getSuperFrame()).append(".").append(getWindow()); sb.append(" MSG:").append(getMessage().toHexString()); 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 d628735f2..9f4dc5b38 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 @@ -88,6 +88,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" CSBK CAP+ SITE:").append(getSite()); sb.append(" REST ").append(getRestChannel()); sb.append(" FL:").append(getLCSS()); 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 new file mode 100644 index 000000000..867f633bb --- /dev/null +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusSiteStatus.java @@ -0,0 +1,325 @@ +/* + * ***************************************************************************** + * 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 + * 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.message.data.csbk.motorola; + +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.DMRLogicalChannel; +import io.github.dsheirer.module.decode.dmr.channel.ITimeslotFrequencyReceiver; +import io.github.dsheirer.module.decode.dmr.channel.TimeslotFrequency; +import io.github.dsheirer.module.decode.dmr.message.CACH; +import io.github.dsheirer.module.decode.dmr.message.data.SlotType; +import io.github.dsheirer.module.decode.dmr.message.data.csbk.CSBKMessage; +import java.util.ArrayList; +import java.util.List; + +/** + * Capacity+ Site Status CSBKO=62 Message + */ +public class CapacityPlusSiteStatus extends CSBKMessage implements ITimeslotFrequencyReceiver +{ + private static final int[] BYTE = new int[]{0, 1, 2, 3, 4, 5, 6, 7}; + private static final int[] TWO_BYTES = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + private static final int[] SEGMENT_INDICATOR = new int[]{16, 17}; + private static final int TIMESLOT = 18; + private static final int RESERVED = 19; + private static final int[] REST_LSN = new int[]{20, 21, 22, 23}; + private static final int[] LSN_VOICE_BITMAP = new int[]{24, 25, 26, 27, 28, 29, 30, 31}; + private static final int LSN_1_8_BITMAP_START = 24; + private static final int[][] VOICE_TALKGROUPS = new int[][]{{32, 33, 34, 35, 36, 37, 38, 39}, + {40, 41, 42, 43, 44, 45, 46, 47}, {48, 49, 50, 51, 52, 53, 54, 55}, {56, 57, 58, 59, 60, 61, 62, 63}, + {64, 65, 66, 67, 68, 69, 70, 71}, {72, 73, 74, 75, 76, 77, 78, 79}}; + + private DMRLogicalChannel mRestChannel; + private List mIdentifiers; + + /** + * Constructs an instance + * + * @param syncPattern for the CSBK + * @param message bits + * @param cach for the DMR burst + * @param slotType for this message + * @param timestamp + * @param timeslot + */ + public CapacityPlusSiteStatus(DMRSyncPattern syncPattern, CorrectedBinaryMessage message, CACH cach, SlotType slotType, long timestamp, int timeslot) + { + super(syncPattern, message, cach, slotType, timestamp, timeslot); + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + if(!isValid()) + { + sb.append("[CRC-ERROR] "); + } + + sb.append("CC:").append(getSlotType().getColorCode()); + + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } + + sb.append(" CSBK CAP+ SITE STATUS REST ").append(getRestChannel()); + sb.append(" ").append(getSegmentIndicator()); + sb.append(" "); + + if(getSegmentIndicator().isFirst()) + { + sb.append(getActivityFragments()); + } + else + { + sb.append("CONTINUATION BLOCK"); + } + + sb.append(" MSG:").append(getMessage().toHexString()); + + return sb.toString(); + } + + /** + * Indicates if this message has voice talkgroup activity. + * + * @return true if voice activity. + */ + private boolean hasVoiceTalkgroups() + { + return getSegmentIndicator().isFirst() && getMessage().getInt(LSN_VOICE_BITMAP) > 0; + } + + /** + * Extracts the call activity from the first or first/last fragment. + * @return description of call activity. + */ + private String getActivityFragments() + { + StringBuilder sb = new StringBuilder(); + sb.append("VOICE LSN "); + int pointer = LSN_1_8_BITMAP_START; + + //Process voice LSNs 1-8 + if(getMessage().getInt(BYTE, pointer) > 0) + { + int lowLsnBitmap = pointer; + pointer += 8; + + for(int x = lowLsnBitmap; x < (lowLsnBitmap + 8); x++) + { + int lsn = x - lowLsnBitmap + 1; + + if(getMessage().get(x)) + { + if(pointer <= 72) + { + sb.append(lsn).append(":").append(getMessage().getInt(BYTE, pointer)).append(" "); + pointer += 8; + } + else + { + sb.append(lsn).append(":A "); + } + } + else + { + sb.append(lsn).append(":* "); + } + } + } + else + { + sb.append("1-8:* "); + pointer += 8; + } + + //Process voice LSNs 9 - 16 + if(pointer <= 72 && getMessage().getInt(BYTE, pointer) > 0) + { + int highLsnBitmap = pointer; + + pointer += 8; + + for(int x = highLsnBitmap; x < (highLsnBitmap + 8); x++) + { + int lsn = x - highLsnBitmap + 1 + 8; + + if(getMessage().get(x)) + { + if(pointer <= 72) + { + sb.append(lsn).append(":").append(getMessage().getInt(BYTE, pointer)).append(" "); + pointer += 8; + } + else + { + sb.append(lsn).append(":A "); + } + } + else + { + sb.append(lsn).append(":* "); + } + } + } + else + { + sb.append("9-16:* "); + pointer += 8; + } + + //Process Data and Private Radio IDs - first bit in radio options byte is set to indicate more activity + if(pointer <= 72 && getMessage().get(pointer)) + { + sb.append("DATA LSN "); + pointer += 8; + + //If we have the data revert channel bitmap ... + if(pointer <= 72 && getMessage().getInt(BYTE, pointer) > 0) + { + int lowDataLsnBitmap = pointer; + + pointer += 8; + + for(int x = lowDataLsnBitmap; x < (lowDataLsnBitmap + 8); x++) + { + int lsn = x - lowDataLsnBitmap + 1; + + if(getMessage().get(x)) + { + if(pointer <= 64) + { + sb.append(lsn).append(":").append(getMessage().getInt(TWO_BYTES, pointer)).append(" "); + pointer += 16; + } + else + { + sb.append(lsn).append(":A "); + } + } + else + { + sb.append(lsn).append(":* "); + } + } + } + else + { + sb.append("1-8:- "); + } + } + + return sb.toString(); + } + + + /** + * Segment indicator for system status message values that are fragmented across multiple system status + * messages. + */ + public SegmentIndicator getSegmentIndicator() + { + return SegmentIndicator.fromValue(getMessage().getInt(SEGMENT_INDICATOR)); + } + + /** + * Current rest channel for this site. + */ + public DMRLogicalChannel getRestChannel() + { + if(mRestChannel == null) + { + mRestChannel = new DMRLogicalChannel(getRestRepeater(), getRestTimeslot()); + } + + return mRestChannel; + } + + /** + * Rest LSN + * + * @return Logical Slot Number 1-16 + */ + public int getRestLSN() + { + return getMessage().getInt(REST_LSN); + } + + /** + * Rest Channel Repeater + */ + public int getRestRepeater() + { + return (int) Math.ceil(getRestLSN() / 2.0); + } + + /** + * Rest Channel Timeslot + * + * @return 1 or 2 + */ + public int getRestTimeslot() + { + return (getRestLSN() % 2 == 0) ? 2 : 1; + } + + /** + * Logical slot numbers that require slot to frequency mappings. + */ + @Override + public int[] getLogicalTimeslotNumbers() + { + return getRestChannel().getLSNArray(); + } + + /** + * Applies logical slot number to frequency mapping. + * + * @param timeslotFrequencies that match the logical timeslots + */ + @Override + public void apply(List timeslotFrequencies) + { + for(TimeslotFrequency timeslotFrequency : timeslotFrequencies) + { + if(getRestChannel().getLogicalSlotNumber() == timeslotFrequency.getNumber()) + { + getRestChannel().setTimeslotFrequency(timeslotFrequency); + } + } + } + + @Override + public List getIdentifiers() + { + if(mIdentifiers == null) + { + mIdentifiers = new ArrayList<>(); + mIdentifiers.add(getRestChannel()); + } + + return mIdentifiers; + } +} diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusSystemStatus.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusSystemStatus.java deleted file mode 100644 index d6598f86e..000000000 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/CapacityPlusSystemStatus.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * ***************************************************************************** - * 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 - * 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.message.data.csbk.motorola; - -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.DMRLogicalChannel; -import io.github.dsheirer.module.decode.dmr.channel.ITimeslotFrequencyReceiver; -import io.github.dsheirer.module.decode.dmr.channel.TimeslotFrequency; -import io.github.dsheirer.module.decode.dmr.message.CACH; -import io.github.dsheirer.module.decode.dmr.message.data.SlotType; -import io.github.dsheirer.module.decode.dmr.message.data.csbk.CSBKMessage; -import io.github.dsheirer.module.decode.dmr.message.type.LCSS; -import java.util.ArrayList; -import java.util.List; - -/** - * Capacity+ System Status CSBKO=62 Message - */ -public class CapacityPlusSystemStatus extends CSBKMessage implements ITimeslotFrequencyReceiver -{ - private static final int[] FRAGMENT_INDICATOR = new int[]{16, 17}; -// private static final int TIMESLOT = 18; -// private static final int[] REST_REPEATER = new int[]{19, 20, 21, 22}; - private static final int[] REST_LSN = new int[]{20, 21, 22, 23}; - //private static final int[] REST_TIMESLOT = new int[]{23}; - - private DMRLogicalChannel mRestChannel; - private List mIdentifiers; - - /** - * Constructs an instance - * - * @param syncPattern for the CSBK - * @param message bits - * @param cach for the DMR burst - * @param slotType for this message - * @param timestamp - * @param timeslot - */ - public CapacityPlusSystemStatus(DMRSyncPattern syncPattern, CorrectedBinaryMessage message, CACH cach, SlotType slotType, long timestamp, int timeslot) - { - super(syncPattern, message, cach, slotType, timestamp, timeslot); - } - - @Override - public String toString() - { - StringBuilder sb = new StringBuilder(); - - if(!isValid()) - { - sb.append("[CRC-ERROR] "); - } - - sb.append("CC:").append(getSlotType().getColorCode()); - sb.append(" CSBK CAP+ SYSTEM STATUS ").append(getFragmentIndicator()); - sb.append(" REST ").append(getRestChannel()); - sb.append(" MSG:").append(getMessage().toHexString()); - - return sb.toString(); - } - - /** - * Fragment indicator for system status message values that are fragmented across multiple system status - * messages. - */ - public LCSS getFragmentIndicator() - { - return LCSS.fromValue(getMessage().getInt(FRAGMENT_INDICATOR)); - } - - /** - * Current rest channel for this site. - */ - public DMRLogicalChannel getRestChannel() - { - if(mRestChannel == null) - { - mRestChannel = new DMRLogicalChannel(getRestRepeater(), getRestTimeslot()); - } - - return mRestChannel; - } - - /** - * Rest LSN - * @return Logical Slot Number 1-16 - */ - public int getRestLSN() - { - return getMessage().getInt(REST_LSN); - } - - /** - * Rest Channel Repeater - */ - public int getRestRepeater() { return (int) Math.ceil(getRestLSN() / 2.0); } - - /** - * Rest Channel Timeslot - * @return 1 or 2 - */ - public int getRestTimeslot() - { - return (getRestLSN() % 2 == 0) ? 2 : 1; - } - - /** - * Logical slot numbers that require slot to frequency mappings. - */ - @Override - public int[] getLogicalTimeslotNumbers() - { - return getRestChannel().getLSNArray(); - } - - /** - * Applies logical slot number to frequency mapping. - * - * @param timeslotFrequencies that match the logical timeslots - */ - @Override - public void apply(List timeslotFrequencies) - { - for(TimeslotFrequency timeslotFrequency : timeslotFrequencies) - { - if(getRestChannel().getLogicalSlotNumber() == timeslotFrequency.getNumber()) - { - getRestChannel().setTimeslotFrequency(timeslotFrequency); - } - } - } - - @Override - public List getIdentifiers() - { - if(mIdentifiers == null) - { - mIdentifiers = new ArrayList<>(); - mIdentifiers.add(getRestChannel()); - } - - return mIdentifiers; - } -} diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusCSBKO_16.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusCSBKO_16.java index 953295e63..ded576421 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusCSBKO_16.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusCSBKO_16.java @@ -71,6 +71,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" CSBK CON+ CSBKO:16 FM:").append(getSourceRadio()); sb.append(" TO:").append(getTargetRadio()); sb.append(" UNK:").append(getUnknown()); 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 64f149618..019840393 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 @@ -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 @@ -30,7 +30,6 @@ import io.github.dsheirer.module.decode.dmr.message.CACH; import io.github.dsheirer.module.decode.dmr.message.data.SlotType; import io.github.dsheirer.module.decode.dmr.message.data.csbk.CSBKMessage; - import java.util.ArrayList; import java.util.List; @@ -77,6 +76,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" CSBK ").append(getVendor()); sb.append(" DATA CHANNEL GRANT TO:").append(getTargetRadio()); sb.append(" ").append(getChannel()); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusDataRevertWindowAnnouncement.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusDataRevertWindowAnnouncement.java index 8ec0f56d4..6213c4ae3 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusDataRevertWindowAnnouncement.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusDataRevertWindowAnnouncement.java @@ -70,6 +70,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" CSBK CON+ ENHANCED DATA REVERT CHANNEL ANNOUNCE WINDOW:"); sb.append(getSuperFrame()).append(".").append(getWindow()); if(hasTargetRadio()) diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusDataRevertWindowGrant.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusDataRevertWindowGrant.java index ee59381c8..73bc3c4ac 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusDataRevertWindowGrant.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusDataRevertWindowGrant.java @@ -71,6 +71,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" CSBK CON+ ENHANCED DATA REVERT GRANT TO:").append(getTargetRadio()); sb.append(" TRANSMIT IN WINDOW:").append(getSuperFrame()).append(".").append(getWindow()); sb.append(" MSG:").append(getMessage().toHexString()); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusNeighborReport.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusNeighborReport.java index a352d9cf4..76965fe7f 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusNeighborReport.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusNeighborReport.java @@ -69,6 +69,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" CSBK CON+ NEIGHBORS:"); List neighbors = getNeighbors(); 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 5319e0479..32a9136af 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 @@ -77,6 +77,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" CSBK CON+ ANNOUNCE OTA ").append(getMessageType()); sb.append(" VER:").append(getMessageVersion()); sb.append(" AVAILABLE ON ").append(getDataChannel()); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusRegistrationRequest.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusRegistrationRequest.java index cc1e533a4..d37c5fe64 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusRegistrationRequest.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusRegistrationRequest.java @@ -71,6 +71,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" CSBK CON+ REGISTRATION REQUEST FM:").append(getSourceRadio()); sb.append(" TO:").append(getTargetRadio()); sb.append(" UNK:").append(getUnknown()); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusRegistrationResponse.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusRegistrationResponse.java index d182dd628..552b1a12a 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusRegistrationResponse.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusRegistrationResponse.java @@ -71,6 +71,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" CSBK CON+ REGISTRATION RESPONSE FM:").append(getSourceRadio()); sb.append(" TO:").append(getTargetRadio()); sb.append(" UNK:").append(getUnknown()); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusTalkgroupAffiliation.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusTalkgroupAffiliation.java index 3a374700a..1acd93edf 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusTalkgroupAffiliation.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusTalkgroupAffiliation.java @@ -73,6 +73,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" CSBK CON+ AFFILIATE RADIO:").append(getRadio()); sb.append(" TO TALKGROUP:").append(getTalkgroup()); sb.append(" UNK:").append(getUnknown()); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusTerminateChannelGrant.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusTerminateChannelGrant.java index c99315fdb..4719fcb25 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusTerminateChannelGrant.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/ConnectPlusTerminateChannelGrant.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.CACH; import io.github.dsheirer.module.decode.dmr.message.data.SlotType; import io.github.dsheirer.module.decode.dmr.message.data.csbk.CSBKMessage; - import java.util.ArrayList; import java.util.List; @@ -76,6 +75,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" CSBK ").append(getVendor()); sb.append(" TERMINATE CHANNEL GRANT TO:").append(getTargetRadio()); sb.append(" U1:").append(getUnknownField1()); 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 4bcd3ab99..e16986c38 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 @@ -79,6 +79,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" CSBK CON+ VOICE CHANNEL USER FM:").append(getRadio()); sb.append(" TO:").append(getTalkgroup()); sb.append(" ").append(getChannel()); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/SegmentIndicator.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/SegmentIndicator.java new file mode 100644 index 000000000..58bae2173 --- /dev/null +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/motorola/SegmentIndicator.java @@ -0,0 +1,92 @@ +/* + * ***************************************************************************** + * 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 + * 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.message.data.csbk.motorola; + +/** + * Used by Cap+ channel status message to indicate if the channel status payload is a single fragment, or a + * multi-sequence fragment. + */ +public enum SegmentIndicator +{ + /** + * Continuation Segment + */ + CONTINUATION_SEGMENT("[--]"), + + /** + * Last Segment in a multi-segment sequence + */ + LAST_SEGMENT("[-L]"), + + /** + * First Segment in a multi-segment sequence + */ + FIRST_SEGMENT("[F-]"), + + /** + * Single Segment. + */ + SINGLE_SEGMENT("[FL]"), + + /** + * Unknow Segment + */ + UNKNOWN("[**]"); + + private String mLabel; + + /** + * Constructs an instance + * @param label to display + */ + SegmentIndicator(String label) + { + mLabel = label; + } + + /** + * Lookup a segment indicator from the value. + * @param value to lookup + * @return segment indicator (0-3) or UNKNOWN. + */ + public static SegmentIndicator fromValue(int value) + { + if(0 <= value && value < 4) + { + return SegmentIndicator.values()[value]; + } + + return UNKNOWN; + } + + /** + * Indicates if this is the first in a multi-segment sequence or if this is a single-segment. + */ + public boolean isFirst() + { + return this.equals(FIRST_SEGMENT) || this.equals(SINGLE_SEGMENT); + } + + @Override + public String toString() + { + return mLabel; + } +} \ No newline at end of file diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/Aloha.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/Aloha.java index 367474d6d..63c320ba9 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/Aloha.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/Aloha.java @@ -82,6 +82,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" ALOHA"); if(hasRadioIdentifier()) 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 b388cd29e..da7e2466e 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 @@ -109,6 +109,11 @@ public String toString() sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } + if(isEncrypted()) { sb.append(" ENCRYPTED"); 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 e1be3736c..b8c791c8f 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 @@ -119,6 +119,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" MOVE TRUNK CONTROL CHANNEL ").append(getChannel()); if(hasRadioIdentifier()) diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/Preamble.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/Preamble.java index 13a229520..387e6bc23 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/Preamble.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/Preamble.java @@ -75,6 +75,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" CSBK PREAMBLE FM:").append(getSourceAddress()); sb.append(" TO:").append(getTargetAddress()); sb.append(isCSBKPreamble() ? " CSBK" : " DATA"); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/Protect.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/Protect.java index eff96c2a8..aa476e29d 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/Protect.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/Protect.java @@ -77,6 +77,11 @@ public String toString() sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } + if(isEncrypted()) { sb.append(" ENCRYPTED"); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/acknowledge/Acknowledge.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/acknowledge/Acknowledge.java index 32f6caf77..2cc099d54 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/acknowledge/Acknowledge.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/acknowledge/Acknowledge.java @@ -80,6 +80,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" ").append(getAcknowledgeType()); sb.append(" REASON:").append(getReason()); sb.append(" FM:").append(getSourceRadio()); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/ahoy/AuthenticateRegisterRadioCheck.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/ahoy/AuthenticateRegisterRadioCheck.java index 2a43c7667..3cdcc7e9d 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/ahoy/AuthenticateRegisterRadioCheck.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/ahoy/AuthenticateRegisterRadioCheck.java @@ -65,6 +65,11 @@ public String toString() sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } + if(isEncrypted()) { sb.append(" ENCRYPTED"); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/ahoy/CancelCall.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/ahoy/CancelCall.java index 1671394dc..25226f5c1 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/ahoy/CancelCall.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/ahoy/CancelCall.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 @@ -26,7 +26,6 @@ import io.github.dsheirer.module.decode.dmr.identifier.DMRRadio; import io.github.dsheirer.module.decode.dmr.message.CACH; import io.github.dsheirer.module.decode.dmr.message.data.SlotType; - import java.util.ArrayList; import java.util.List; @@ -65,6 +64,11 @@ public String toString() sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } + if(isEncrypted()) { sb.append(" ENCRYPTED"); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/ahoy/ServiceRadioCheck.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/ahoy/ServiceRadioCheck.java index fc6b5a4f6..ba886f7a6 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/ahoy/ServiceRadioCheck.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/ahoy/ServiceRadioCheck.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 @@ -26,7 +26,6 @@ import io.github.dsheirer.module.decode.dmr.identifier.DMRRadio; import io.github.dsheirer.module.decode.dmr.message.CACH; import io.github.dsheirer.module.decode.dmr.message.data.SlotType; - import java.util.ArrayList; import java.util.List; @@ -65,6 +64,11 @@ public String toString() sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } + if(isEncrypted()) { sb.append(" ENCRYPTED"); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/ahoy/StunReviveKill.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/ahoy/StunReviveKill.java index cba0f7895..29757be81 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/ahoy/StunReviveKill.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/ahoy/StunReviveKill.java @@ -65,6 +65,11 @@ public String toString() sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } + if(isEncrypted()) { sb.append(" ENCRYPTED"); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/ahoy/UnknownAhoy.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/ahoy/UnknownAhoy.java index c091ebc76..af9d57c21 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/ahoy/UnknownAhoy.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/ahoy/UnknownAhoy.java @@ -65,6 +65,11 @@ public String toString() sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } + if(isEncrypted()) { sb.append(" ENCRYPTED"); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/announcement/Announcement.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/announcement/Announcement.java index f05fc1c7f..4e6d2ab68 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/announcement/Announcement.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/csbk/standard/announcement/Announcement.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 @@ -27,7 +27,6 @@ import io.github.dsheirer.module.decode.dmr.message.data.csbk.CSBKMessage; import io.github.dsheirer.module.decode.dmr.message.type.AnnouncementType; import io.github.dsheirer.module.decode.dmr.message.type.SystemIdentityCode; - import java.util.ArrayList; import java.util.List; @@ -73,6 +72,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" ANNOUNCEMENT ").append(getAnnouncementType()); return sb.toString(); 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 9982e24f9..859bf907e 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 @@ -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 @@ -29,7 +29,6 @@ import io.github.dsheirer.module.decode.dmr.message.CACH; import io.github.dsheirer.module.decode.dmr.message.data.SlotType; import io.github.dsheirer.module.decode.dmr.message.data.mbc.MBCContinuationBlock; - import java.util.ArrayList; import java.util.List; @@ -88,6 +87,11 @@ public String toString() sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } + if(isEmergency()) { sb.append(" EMERGENCY"); 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 b83c50b73..5b68cb9ac 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 @@ -86,6 +86,11 @@ public String toString() sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } + if(isEmergency()) { sb.append(" EMERGENCY"); 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 daa58f9e6..eab51690a 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 @@ -86,6 +86,11 @@ public String toString() sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } + if(isEmergency()) { sb.append(" EMERGENCY"); 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 980dc1189..58400f5dc 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 @@ -86,6 +86,11 @@ public String toString() sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } + if(isEmergency()) { sb.append(" EMERGENCY"); 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 410462b1b..74492622f 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 @@ -85,6 +85,11 @@ public String toString() sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } + if(isEmergency()) { sb.append(" EMERGENCY"); 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 9355dd424..49e542577 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 @@ -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 @@ -29,7 +29,6 @@ import io.github.dsheirer.module.decode.dmr.message.CACH; import io.github.dsheirer.module.decode.dmr.message.data.SlotType; import io.github.dsheirer.module.decode.dmr.message.data.mbc.MBCContinuationBlock; - import java.util.ArrayList; import java.util.List; @@ -89,6 +88,11 @@ public String toString() sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } + if(isEmergency()) { sb.append(" EMERGENCY"); 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 40c191176..3406e6859 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 @@ -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 @@ -29,7 +29,6 @@ import io.github.dsheirer.module.decode.dmr.message.CACH; import io.github.dsheirer.module.decode.dmr.message.data.SlotType; import io.github.dsheirer.module.decode.dmr.message.data.mbc.MBCContinuationBlock; - import java.util.ArrayList; import java.util.List; @@ -88,6 +87,11 @@ public String toString() sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } + if(isEmergency()) { sb.append(" EMERGENCY"); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/header/MBCHeader.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/header/MBCHeader.java index daf4662a4..0923ce634 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/header/MBCHeader.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/header/MBCHeader.java @@ -67,6 +67,11 @@ public String toString() StringBuilder sb = new StringBuilder(); sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } + if(!isValid()) { sb.append(" [CRC ERROR]"); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/LCOpcode.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/LCOpcode.java index 38dcde62e..5b286f24a 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/LCOpcode.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/LCOpcode.java @@ -46,6 +46,12 @@ public enum LCOpcode FULL_CAPACITY_PLUS_GROUP_VOICE_CHANNEL_USER(Vendor.MOTOROLA_CAPACITY_PLUS, true, 0, "GROUP VOICE CHANNEL USER"), FULL_CAPACITY_PLUS_WIDE_AREA_VOICE_CHANNEL_USER(Vendor.MOTOROLA_CAPACITY_PLUS, true, 4, "WAN GROUP VOICE CHANNEL USER"), + //Cap+ opcodes from https://forums.radioreference.com/threads/understanding-capacity-plus-trunking-some-more.452566/ + //FLCO 0: Group Call Maintenance + //FLCO 3: Private Call Maintenance (TermLC) + //FLCO 4: Group Call Grant + //FLCO 7: Private Call Grant + //FLCO 35: Private Call Maintenance (EMB) FULL_HYTERA_GROUP_VOICE_CHANNEL_USER(Vendor.HYTERA_68, true, 0, "HYTERA GROUP VOICE CHANNEL USER"), FULL_HYTERA_UNIT_TO_UNIT_VOICE_CHANNEL_USER(Vendor.HYTERA_68, true, 3, "HYTERA UNIT-TO-UNIT VOICE CHANNEL USER"), 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 d0c86812e..f8896947c 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 @@ -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 @@ -25,7 +25,6 @@ import io.github.dsheirer.module.decode.dmr.channel.ITimeslotFrequencyReceiver; import io.github.dsheirer.module.decode.dmr.channel.TimeslotFrequency; import io.github.dsheirer.module.decode.dmr.identifier.DMRSite; - import java.util.ArrayList; import java.util.List; @@ -64,7 +63,7 @@ public String toString() sb.append("[CRC ERROR] "); } sb.append("SLC MOTOROLA CAP+ SITE:").append(getSite()); - sb.append(" REST CHANNEL:").append(getRestChannel()); + sb.append(" REST:").append(getRestChannel()); sb.append(" MSG:").append(getMessage().toHexString()); return sb.toString(); } diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/mbc/MBCContinuationBlock.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/mbc/MBCContinuationBlock.java index bd9301051..4b865312d 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/mbc/MBCContinuationBlock.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/mbc/MBCContinuationBlock.java @@ -51,6 +51,11 @@ public String toString() StringBuilder sb = new StringBuilder(); sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } + if(!isValid()) { sb.append(" [CRC ERROR]"); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/mbc/UnknownMultiCSBK.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/mbc/UnknownMultiCSBK.java index 4a16c11a1..c73fe6470 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/mbc/UnknownMultiCSBK.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/mbc/UnknownMultiCSBK.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 @@ -23,7 +23,6 @@ import io.github.dsheirer.module.decode.dmr.message.data.csbk.Opcode; import io.github.dsheirer.module.decode.dmr.message.data.header.MBCHeader; import io.github.dsheirer.module.decode.dmr.message.type.Vendor; - import java.util.Collections; import java.util.List; @@ -54,6 +53,10 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } sb.append(" CSBK *UNKNOWN*"); Vendor vendor = getVendor(); diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/usb/USBData.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/usb/USBData.java index 24bbb4eb9..199b40edb 100644 --- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/usb/USBData.java +++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/usb/USBData.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 @@ -29,7 +29,6 @@ import io.github.dsheirer.module.decode.dmr.message.data.DataMessage; import io.github.dsheirer.module.decode.dmr.message.data.SlotType; import io.github.dsheirer.module.decode.dmr.message.type.ServiceType; - import java.util.ArrayList; import java.util.List; @@ -80,6 +79,11 @@ public String toString() } sb.append("CC:").append(getSlotType().getColorCode()); + if(hasRAS()) + { + sb.append(" RAS:").append(getBPTCReservedBits()); + } + sb.append(" USB DATA BLOCK"); sb.append(" TO:").append(getTargetRadio()); sb.append(" SERVICE:").append(getServiceType());