diff --git a/dvmconsole/Codeplug.cs b/dvmconsole/Codeplug.cs
index 81ef59e..4418284 100644
--- a/dvmconsole/Codeplug.cs
+++ b/dvmconsole/Codeplug.cs
@@ -9,7 +9,7 @@
*
* Copyright (C) 2024-2025 Caleb, K4PHP
* Copyright (C) 2025 Bryan Biedenkapp, N2PLL
- * Copyright (C) 2025 Steven Jennison, KD8RHO
+* Copyright (C) 2025 Steven Jennison, KD8RHO
*
*/
@@ -22,6 +22,16 @@ namespace dvmconsole
///
public class Codeplug
{
+ ///
+ /// Enumeration of channel modes.
+ ///
+ public enum ChannelMode
+ {
+ DMR = 0,
+ NXDN = 1,
+ P25 = 2
+ } // public enum ChannelMode
+
/*
** Properties
*/
@@ -31,11 +41,11 @@ namespace dvmconsole
///
public string KeyFile { get; set; } = null;
///
- ///
+ /// List of systems.
///
public List Systems { get; set; }
///
- ///
+ /// List of zones.
///
public List Zones { get; set; }
@@ -53,41 +63,46 @@ namespace dvmconsole
*/
///
- ///
+ /// Textual name for system.
///
public string Name { get; set; }
+
///
- ///
+ /// Textual identity string reported to the FNE core.
///
public string Identity { get; set; }
///
- ///
+ /// IP/hostname of the FNE.
///
public string Address { get; set; }
///
- ///
+ /// Port number for the FNE connection.
+ ///
+ public int Port { get; set; }
+ ///
+ /// Authentication password.
///
public string Password { get; set; }
+
///
- ///
+ /// Preshared Encryption key.
///
public string PresharedKey { get; set; }
///
- ///
+ /// Flag indicating whether or not the connection to the FNE is encrypted.
///
public bool Encrypted { get; set; }
+
///
- ///
+ /// Unique Peer ID.
///
public uint PeerId { get; set; }
+
///
- ///
- ///
- public int Port { get; set; }
- ///
- ///
+ /// Unique Radio ID.
///
public string Rid { get; set; }
+
///
///
///
@@ -112,7 +127,7 @@ namespace dvmconsole
} // public class System
///
- ///
+ /// Data structure representation of the data for a zone.
///
public class Zone
{
@@ -121,17 +136,17 @@ namespace dvmconsole
*/
///
- ///
+ /// Textual name for zone.
///
public string Name { get; set; }
///
- ///
+ /// List of channels in the zone.
///
public List Channels { get; set; }
} // public class Zone
///
- ///
+ /// Data structure representation of the data for a channel.
///
public class Channel
{
@@ -140,31 +155,31 @@ namespace dvmconsole
*/
///
- ///
+ /// Textual name for channel.
///
public string Name { get; set; }
///
- ///
+ /// Textual name for system channel is a member of.
///
public string System { get; set; }
///
- ///
+ /// Talkgroup ID.
///
public string Tgid { get; set; }
///
- ///
+ /// DMR Timeslot.
///
- public string EncryptionKey { get; set; }
+ public int Slot { get; set; }
///
- ///
+ /// Textual algorithm name.
///
public string Algo { get; set; } = "none";
///
- ///
+ /// Encryption Key ID.
///
public string KeyId { get; set; }
///
- ///
+ /// Digital Voice Mode.
///
public string Mode { get; set; } = "p25";
@@ -173,7 +188,7 @@ namespace dvmconsole
*/
///
- ///
+ /// Helper to return the key ID as a numeric value from a string.
///
///
public ushort GetKeyId()
@@ -182,7 +197,7 @@ namespace dvmconsole
}
///
- ///
+ /// Helper to return the algorithm ID from the configured algorithm type string.
///
///
public byte GetAlgoId()
@@ -199,42 +214,18 @@ namespace dvmconsole
}
///
- ///
- ///
- ///
- public byte[] GetEncryptionKey()
- {
- if (EncryptionKey == null)
- return [];
-
- return EncryptionKey.Split(',').Select(s => Convert.ToByte(s.Trim(), 16)).ToArray();
- }
-
- ///
- ///
+ /// Helper to return the channel mode.
///
///
public ChannelMode GetChannelMode()
{
if (Enum.TryParse(typeof(ChannelMode), Mode, ignoreCase: true, out var result))
- {
return (ChannelMode)result;
- }
return ChannelMode.P25;
}
} // public class Channel
- ///
- ///
- ///
- public enum ChannelMode
- {
- DMR = 0,
- NXDN = 1,
- P25 = 2
- } // public enum ChannelMode
-
///
/// Helper to return a system by looking up a
///
@@ -252,9 +243,9 @@ namespace dvmconsole
///
public System GetSystemForChannel(string channelName)
{
- foreach (var zone in Zones)
+ foreach (Zone zone in Zones)
{
- var channel = zone.Channels.FirstOrDefault(c => c.Name == channelName);
+ Channel channel = zone.Channels.FirstOrDefault(c => c.Name == channelName);
if (channel != null)
return Systems.FirstOrDefault(s => s.Name == channel.System);
}
@@ -269,9 +260,9 @@ namespace dvmconsole
///
public Channel GetChannelByName(string channelName)
{
- foreach (var zone in Zones)
+ foreach (Zone zone in Zones)
{
- var channel = zone.Channels.FirstOrDefault(c => c.Name == channelName);
+ Channel channel = zone.Channels.FirstOrDefault(c => c.Name == channelName);
if (channel != null)
return channel;
}
diff --git a/dvmconsole/MainWindow.DMR.cs b/dvmconsole/MainWindow.DMR.cs
index 82ac7ea..dd1d877 100644
--- a/dvmconsole/MainWindow.DMR.cs
+++ b/dvmconsole/MainWindow.DMR.cs
@@ -43,7 +43,7 @@ namespace dvmconsole
try
{
- byte slot = 1; // TODO: Support both time slots
+ byte slot = (byte)(cpgChannel.Slot - 1);
byte[] data = null, dmrpkt = null;
channel.dmrN = (byte)(channel.dmrSeqNo % 6);
@@ -196,7 +196,7 @@ namespace dvmconsole
if (samples != null)
{
- //Log.WriteLine($"({system.SystemName}) DMRD: Traffic *VOICE FRAME * PEER {e.PeerId} SRC_ID {e.SrcId} TGID {e.DstId} TS {e.Slot + 1} VC{e.n}.{n} ERRS {errs} [STREAM ID {e.StreamId}]");
+ Log.WriteLine($"({system.SystemName}) DMRD: Traffic *VOICE FRAME * PEER {e.PeerId} SRC_ID {e.SrcId} TGID {e.DstId} TS {e.Slot + 1} VC{e.n}.{n} ERRS {errs} [STREAM ID {e.StreamId}]");
// Log.Logger.Debug($"PARTIAL AMBE {FneUtils.HexDump(ambePartial)}");
// Log.Logger.Debug($"SAMPLE BUFFER {FneUtils.HexDump(samples)}");
@@ -264,7 +264,7 @@ namespace dvmconsole
{
channel.IsReceiving = true;
systemStatuses[cpgChannel.Name + e.Slot].RxStart = pktTime;
- Log.WriteLine($"({system.Name}) DMRD: Traffic *CALL START * PEER {e.PeerId} SRC_ID {e.SrcId} TGID {e.DstId} Slot {e.Slot} [STREAM ID {e.StreamId}]");
+ Log.WriteLine($"({system.Name}) DMRD: Traffic *CALL START * PEER {e.PeerId} SRC_ID {e.SrcId} TGID {e.DstId} TS {e.Slot} [STREAM ID {e.StreamId}]");
// if we can, use the LC from the voice header as to keep all options intact
if ((e.FrameType == FrameType.DATA_SYNC) && (e.DataType == DMRDataType.VOICE_LC_HEADER))
@@ -314,7 +314,7 @@ namespace dvmconsole
{
channel.IsReceiving = false;
TimeSpan callDuration = pktTime - systemStatuses[cpgChannel.Name + e.Slot].RxStart;
- Log.WriteLine($"({system.Name}) DMRD: Traffic *CALL END * PEER {e.PeerId} SRC_ID {e.SrcId} TGID {e.DstId} Slot {e.Slot} DUR {callDuration} [STREAM ID {e.StreamId}]");
+ Log.WriteLine($"({system.Name}) DMRD: Traffic *CALL END * PEER {e.PeerId} SRC_ID {e.SrcId} TGID {e.DstId} TS {e.Slot} DUR {callDuration} [STREAM ID {e.StreamId}]");
channel.Background = ChannelBox.BLUE_GRADIENT;
channel.VolumeMeterLevel = 0;
callHistoryWindow.ChannelUnkeyed(cpgChannel.Name, (int)e.SrcId);
diff --git a/dvmconsole/MainWindow.xaml.cs b/dvmconsole/MainWindow.xaml.cs
index 089413d..27abfce 100644
--- a/dvmconsole/MainWindow.xaml.cs
+++ b/dvmconsole/MainWindow.xaml.cs
@@ -298,6 +298,12 @@ namespace dvmconsole
channel.Name = channel.Name.Substring(0, MAX_CHANNEL_NAME_LEN);
Log.WriteLine($"{original} CHANNEL NAME was greater then {MAX_CHANNEL_NAME_LEN} characters, truncated {channel.Name}");
}
+
+ // clamp slot value
+ if (channel.Slot <= 0)
+ channel.Slot = 1;
+ if (channel.Slot > 2)
+ channel.Slot = 1;
}
}