mIdentifiers;
/**
@@ -98,8 +94,6 @@ public String toString()
{
sb.append("--");
}
- sb.append(" SITE:").append(getSite());
- sb.append(" ").append(getServiceOptions());
sb.append(" ").append(getServiceOptions());
sb.append(" UNK1:").append(getUnknown1());
sb.append(" UNK2:").append(getUnknown2());
@@ -120,7 +114,7 @@ public String getUnknown1()
*/
public String getUnknown2()
{
- return getMessage().getHex(UNKNOWN_2, 5);
+ return getMessage().getHex(UNKNOWN_2, 6);
}
/**
@@ -153,20 +147,6 @@ public boolean hasRestChannel()
return getRestLSN() != 0;
}
- /**
- * Site number
- * @return site
- */
- public DMRSite getSite()
- {
- if(mSite == null)
- {
- mSite = new DMRSite(getMessage().getInt(SITE));
- }
-
- return mSite;
- }
-
/**
* Source radio address
*/
diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/full/motorola/CapacityPlusEncryptionParameters.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/full/motorola/MotorolaEncryptionParameters.java
similarity index 72%
rename from src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/full/motorola/CapacityPlusEncryptionParameters.java
rename to src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/full/motorola/MotorolaEncryptionParameters.java
index b98409c8b..76f226d79 100644
--- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/full/motorola/CapacityPlusEncryptionParameters.java
+++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/full/motorola/MotorolaEncryptionParameters.java
@@ -21,33 +21,25 @@
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
-import io.github.dsheirer.identifier.radio.RadioIdentifier;
-import io.github.dsheirer.identifier.talkgroup.TalkgroupIdentifier;
-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.identifier.DMRRadio;
import io.github.dsheirer.module.decode.dmr.identifier.DMRTalkgroup;
import io.github.dsheirer.module.decode.dmr.message.data.lc.full.FullLCMessage;
-
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
/**
- * Motorola Capacity Plus - Encryption Parameters
+ * Motorola Encryption Parameters
*
* Note: observed as FLC payload for a PI_HEADER slot type.
+ * Note: observed on a possible Hytera (clone) system that was configured as IP Site Connect compatible.
*/
-public class CapacityPlusEncryptionParameters extends FullLCMessage
+public class MotorolaEncryptionParameters extends FullLCMessage
{
- //NOTE: field definitions are best guesses ... algorithm and key ID fields might be interchanged
- private static final int[] ENCRYPTION_ALGORITHM = new int[]{16, 17, 18, 19, 20, 21, 22, 23};
+ private static final int[] KEY_ID = new int[]{16, 17, 18, 19, 20, 21, 22, 23};
private static final int[] INITIALIZATION_VECTOR = new int[]{24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55};
- private static final int[] KEY_ID = new int[]{56, 57, 58, 59, 60, 61, 62, 63};
+ private static final int[] ALGORITHM = new int[]{56, 57, 58, 59, 60, 61, 62, 63};
private static final int[] DESTINATION_GROUP = new int[]{64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79};
- private static final int[] UNKNOWN = new int[]{80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 83, 94, 95};
+ private static final int[] UNKNOWN = new int[]{80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95};
private DMRTalkgroup mTalkgroup;
private List mIdentifiers;
@@ -57,7 +49,7 @@ public class CapacityPlusEncryptionParameters extends FullLCMessage
*
* @param message for the link control payload
*/
- public CapacityPlusEncryptionParameters(CorrectedBinaryMessage message, long timestamp, int timeslot)
+ public MotorolaEncryptionParameters(CorrectedBinaryMessage message, long timestamp, int timeslot)
{
super(message, timestamp, timeslot);
}
@@ -82,11 +74,10 @@ public String toString()
sb.append(" *RESERVED-BIT*");
}
- sb.append("FLC MOTOROLA CAP+ ENCRYPTION PARAMETERS - ALGORITHM:").append(getEncryptionAlgorithm());
+ sb.append("FLC MOTOROLA ENCRYPTION PARAMETERS - ALGORITHM:").append(getAlgorithm());
sb.append(" KEY:").append(getKeyId());
sb.append(" IV:").append(getInitializationVector());
sb.append(" TALKGROUP:").append(getTalkgroup());
- sb.append(" UNK:").append(getUnknown());
sb.append(" MSG:").append(getMessage().toHexString());
return sb.toString();
}
@@ -106,9 +97,16 @@ public int getKeyId()
return getMessage().getInt(KEY_ID);
}
- public int getEncryptionAlgorithm()
+ public String getAlgorithm()
{
- return getMessage().getInt(ENCRYPTION_ALGORITHM);
+ int algorithm = getMessage().getInt(ALGORITHM);
+
+ if(algorithm == 0)
+ {
+ return "EP/RC4";
+ }
+
+ return "UNK(" + algorithm + ")";
}
public String getInitializationVector()
diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/shorty/ActivityUpdateMessage.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/shorty/ActivityUpdateMessage.java
index 1c1763c42..8eb7fa64d 100644
--- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/shorty/ActivityUpdateMessage.java
+++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/shorty/ActivityUpdateMessage.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
@@ -22,7 +22,6 @@
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.module.decode.dmr.message.type.Activity;
-
import java.util.Collections;
import java.util.List;
@@ -55,13 +54,18 @@ public String toString()
{
sb.append("[CRC ERROR] ");
}
-
- sb.append("SLC ACTIVITY UPDATE TS1 [");
- sb.append(getHashAddressTS1()).append("] ");
+ sb.append("SLC TS1:");
sb.append(getActivityTS1());
- sb.append(" / TS2 [");
- sb.append(getHashAddressTS2()).append("] ");
+ if(getActivityTS1() != Activity.IDLE)
+ {
+ sb.append(" [").append(getHashAddressTS1()).append("]");
+ }
+ sb.append(" TS2:");
sb.append(getActivityTS2());
+ if(getActivityTS2() != Activity.IDLE)
+ {
+ sb.append(" [").append(getHashAddressTS2()).append("]");
+ }
sb.append(" MSG:").append(getMessage().toHexString());
return sb.toString();
}
diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/shorty/NullMessage.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/shorty/NullMessage.java
index 8a18ce85f..ef96de9fe 100644
--- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/shorty/NullMessage.java
+++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/lc/shorty/NullMessage.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
@@ -21,7 +21,6 @@
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
-
import java.util.Collections;
import java.util.List;
@@ -48,8 +47,7 @@ public String toString()
{
sb.append("[CRC ERROR] ");
}
- sb.append("SLC IDLE/NULL MESSAGE");
- sb.append(" MSG:").append(getMessage().toHexString());
+ sb.append("SLC TS1:IDLE TS2:IDLE");
return sb.toString();
}
diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/packet/DMRPacketMessage.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/packet/DMRPacketMessage.java
index 063295a90..6d7dfcb62 100644
--- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/packet/DMRPacketMessage.java
+++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/packet/DMRPacketMessage.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.message.DMRMessage;
import io.github.dsheirer.module.decode.ip.IPacket;
-
import java.util.ArrayList;
import java.util.List;
@@ -75,6 +74,10 @@ public String toString()
sb.append("CC:").append(getPacketSequence().getPacketSequenceHeader().getSlotType().getColorCode());
sb.append(" FM:").append(getPacketSequence().getPacketSequenceHeader().getSourceLLID());
sb.append(" TO:").append(getPacketSequence().getPacketSequenceHeader().getDestinationLLID());
+ if(getPacketSequence().isEncrypted())
+ {
+ sb.append(" ENCRYPTED");
+ }
sb.append(" ").append(getPacket().toString());
return sb.toString();
}
diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/packet/PacketSequence.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/packet/PacketSequence.java
index 9136b1519..d22bc6812 100644
--- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/packet/PacketSequence.java
+++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/packet/PacketSequence.java
@@ -24,6 +24,7 @@
import io.github.dsheirer.module.decode.dmr.message.data.header.PacketSequenceHeader;
import io.github.dsheirer.module.decode.dmr.message.data.header.ProprietaryDataHeader;
import io.github.dsheirer.module.decode.dmr.message.data.header.UDTHeader;
+import io.github.dsheirer.module.decode.dmr.message.data.header.motorola.MotorolaDataEncryptionHeader;
import java.util.ArrayList;
import java.util.List;
@@ -89,6 +90,15 @@ public boolean isComplete()
return false;
}
+ /**
+ * Indicates if this sequence contains a Motorola data encryption header.
+ * @return true if so
+ */
+ public boolean isEncrypted()
+ {
+ return hasProprietaryDataHeader() && getProprietaryDataHeader() instanceof MotorolaDataEncryptionHeader;
+ }
+
public int getTimeslot()
{
return mTimeslot;
diff --git a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/packet/PacketSequenceMessageFactory.java b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/packet/PacketSequenceMessageFactory.java
index cb444b37d..4a27855c0 100644
--- a/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/packet/PacketSequenceMessageFactory.java
+++ b/src/main/java/io/github/dsheirer/module/decode/dmr/message/data/packet/PacketSequenceMessageFactory.java
@@ -29,7 +29,10 @@
import io.github.dsheirer.module.decode.dmr.message.data.header.UDTHeader;
import io.github.dsheirer.module.decode.dmr.message.data.header.hytera.HyteraProprietaryDataHeader;
import io.github.dsheirer.module.decode.dmr.message.data.header.motorola.MNISProprietaryDataHeader;
+import io.github.dsheirer.module.decode.dmr.message.data.header.motorola.MotorolaDataEncryptionHeader;
import io.github.dsheirer.module.decode.dmr.message.type.ApplicationType;
+import io.github.dsheirer.module.decode.dmr.message.type.DataPacketFormat;
+import io.github.dsheirer.module.decode.ip.DefinedShortDataPacket;
import io.github.dsheirer.module.decode.ip.UnknownPacket;
import io.github.dsheirer.module.decode.ip.hytera.sds.HyteraTokenHeader;
import io.github.dsheirer.module.decode.ip.hytera.sds.HyteraUnknownPacket;
@@ -179,9 +182,20 @@ else if(secondaryHeader instanceof HyteraProprietaryDataHeader)
packetSequence.getTimeslot(), packetSequence.getPacketSequenceHeader().getTimestamp());
}
}
+ else if(secondaryHeader instanceof MotorolaDataEncryptionHeader &&
+ packetSequence.getPacketSequenceHeader().getDataPacketFormat() == DataPacketFormat.DEFINED_SHORT_DATA)
+ {
+ return createDefinedShortData(packetSequence, packet);
+ }
else
{
- mLog.info("Unknown Proprietary Packet Header Type - creating unknown packet.");
+ if(packetSequence.getProprietaryDataHeader() != null)
+ {
+ mLog.info("Unknown Proprietary Packet Header Type - creating unknown packet. Data Packet Format: " +
+ packetSequence.getPacketSequenceHeader().getDataPacketFormat() + " Proprietary Header: " +
+ packetSequence.getProprietaryDataHeader().getClass());
+ }
+
return new DMRPacketMessage(packetSequence, new UnknownPacket(packet, 0), packet,
packetSequence.getTimeslot(), packetSequence.getPacketSequenceHeader().getTimestamp());
}
@@ -217,8 +231,7 @@ public static IMessage createIPPacketData(PacketSequence packetSequence, Correct
*/
public static IMessage createDefinedShortData(PacketSequence packetSequence, CorrectedBinaryMessage packet)
{
- mLog.info("Unknown Short Data Packet Header Type - creating unknown packet.");
- return new DMRPacketMessage(packetSequence, new UnknownPacket(packet, 0), packet,
+ return new DMRPacketMessage(packetSequence, new DefinedShortDataPacket(packet, 0), packet,
packetSequence.getTimeslot(), packetSequence.getPacketSequenceHeader().getTimestamp());
}
diff --git a/src/main/java/io/github/dsheirer/module/decode/ip/DefinedShortDataPacket.java b/src/main/java/io/github/dsheirer/module/decode/ip/DefinedShortDataPacket.java
new file mode 100644
index 000000000..a89ba9c15
--- /dev/null
+++ b/src/main/java/io/github/dsheirer/module/decode/ip/DefinedShortDataPacket.java
@@ -0,0 +1,98 @@
+/*
+ * *****************************************************************************
+ * 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.ip;
+
+import io.github.dsheirer.bits.BinaryMessage;
+import io.github.dsheirer.identifier.Identifier;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Defined Short Data Packet
+ */
+public class DefinedShortDataPacket implements IPacket
+{
+ private BinaryMessage mMessage;
+ private int mOffset;
+
+ /**
+ * Constructor
+ * @param message of the complete packet
+ * @param offset into the message
+ */
+ public DefinedShortDataPacket(BinaryMessage message, int offset)
+ {
+ mMessage = message;
+ mOffset = offset;
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append("DEFINED SHORT DATA PACKET:");
+
+ if(getMessage().size() > getOffset())
+ {
+ sb.append(mMessage.getSubMessage(getOffset(), getMessage().size()).toHexString());
+ }
+ else
+ {
+ sb.append("(EMPTY)");
+ }
+
+ return sb.toString();
+ }
+
+ public BinaryMessage getMessage()
+ {
+ return mMessage;
+ }
+
+ public int getOffset()
+ {
+ return mOffset;
+ }
+
+ @Override
+ public IHeader getHeader()
+ {
+ return null;
+ }
+
+ @Override
+ public IPacket getPayload()
+ {
+ return null;
+ }
+
+ @Override
+ public boolean hasPayload()
+ {
+ return false;
+ }
+
+ @Override
+ public List getIdentifiers()
+ {
+ return Collections.emptyList();
+ }
+}