diff --git a/sw/control/KFDtool.Gui/Control/P25KeyErase.xaml b/sw/control/KFDtool.Gui/Control/P25KeyErase.xaml
index 9982ef9..ba955ad 100644
--- a/sw/control/KFDtool.Gui/Control/P25KeyErase.xaml
+++ b/sw/control/KFDtool.Gui/Control/P25KeyErase.xaml
@@ -16,6 +16,13 @@
-
+
+
+
+
+
+
+
+
diff --git a/sw/control/KFDtool.Gui/Control/P25KeyErase.xaml.cs b/sw/control/KFDtool.Gui/Control/P25KeyErase.xaml.cs
index b3132fc..938fb79 100644
--- a/sw/control/KFDtool.Gui/Control/P25KeyErase.xaml.cs
+++ b/sw/control/KFDtool.Gui/Control/P25KeyErase.xaml.cs
@@ -23,25 +23,16 @@ namespace KFDtool.Gui.Control
///
public partial class P25KeyErase : UserControl
{
+ private bool IsKek { get; set; }
+
public P25KeyErase()
{
InitializeComponent();
+ IsKek = false;
+
cbActiveKeyset.IsChecked = true; // check here to trigger the cb/txt logic on load
- }
-
- private void OnActiveKeysetChecked(object sender, RoutedEventArgs e)
- {
- txtKeysetIdDec.Text = string.Empty;
- txtKeysetIdHex.Text = string.Empty;
- txtKeysetIdDec.IsEnabled = false;
- txtKeysetIdHex.IsEnabled = false;
- }
-
- private void OnActiveKeysetUnchecked(object sender, RoutedEventArgs e)
- {
- txtKeysetIdDec.IsEnabled = true;
- txtKeysetIdHex.IsEnabled = true;
+ cboType.SelectedIndex = 0; // set to the first item here to trigger the cbo/lbl logic on load
}
private void KeysetIdDec_TextChanged(object sender, TextChangedEventArgs e)
@@ -78,6 +69,20 @@ namespace KFDtool.Gui.Control
}
}
+ private void OnActiveKeysetChecked(object sender, RoutedEventArgs e)
+ {
+ txtKeysetIdDec.Text = string.Empty;
+ txtKeysetIdHex.Text = string.Empty;
+ txtKeysetIdDec.IsEnabled = false;
+ txtKeysetIdHex.IsEnabled = false;
+ }
+
+ private void OnActiveKeysetUnchecked(object sender, RoutedEventArgs e)
+ {
+ txtKeysetIdDec.IsEnabled = true;
+ txtKeysetIdHex.IsEnabled = true;
+ }
+
private void SlnDec_TextChanged(object sender, TextChangedEventArgs e)
{
if (txtSlnDec.IsFocused)
@@ -92,6 +97,8 @@ namespace KFDtool.Gui.Control
{
txtSlnHex.Text = string.Empty;
}
+
+ UpdateType();
}
}
@@ -109,9 +116,65 @@ namespace KFDtool.Gui.Control
{
txtSlnDec.Text = string.Empty;
}
+
+ UpdateType();
}
}
+ private void UpdateType()
+ {
+ if (cboType.SelectedItem != null)
+ {
+ string name = ((ComboBoxItem)cboType.SelectedItem).Name as string;
+
+ if (name == "AUTO")
+ {
+ int num;
+
+ if (int.TryParse(txtSlnHex.Text, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out num))
+ {
+ if (num >= 0 && num <= 61439)
+ {
+ lblType.Content = "TEK";
+ IsKek = false;
+ }
+ else if (num >= 61440 && num <= 65535)
+ {
+ lblType.Content = "KEK";
+ IsKek = true;
+ }
+ else
+ {
+ lblType.Content = "Auto";
+ }
+ }
+ else
+ {
+ lblType.Content = "Auto";
+ }
+ }
+ else if (name == "TEK")
+ {
+ lblType.Content = "TEK";
+ IsKek = false;
+ }
+ else if (name == "KEK")
+ {
+ lblType.Content = "KEK";
+ IsKek = true;
+ }
+ else
+ {
+ // error
+ }
+ }
+ }
+
+ private void OnTypeChanged(object sender, SelectionChangedEventArgs e)
+ {
+ UpdateType();
+ }
+
private void Erase_Button_Click(object sender, RoutedEventArgs e)
{
int keysetId = 0;
@@ -158,13 +221,13 @@ namespace KFDtool.Gui.Control
if (!slnValidateResult)
{
- MessageBox.Show("SLN invalid - valid range 1 to 65553 (dec), 0x0001 to 0x1999 (hex)", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ MessageBox.Show("SLN invalid - valid range 0 to 65535 (dec), 0x0000 to 0xFFFF (hex)", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
try
{
- Interact.EraseKey(Settings.Port, useActiveKeyset, keysetId, sln);
+ Interact.EraseKey(Settings.Port, useActiveKeyset, keysetId, sln, IsKek);
}
catch (Exception ex)
{
diff --git a/sw/control/KFDtool.Gui/Control/P25Keyload.xaml b/sw/control/KFDtool.Gui/Control/P25Keyload.xaml
index c763fe3..ba78df8 100644
--- a/sw/control/KFDtool.Gui/Control/P25Keyload.xaml
+++ b/sw/control/KFDtool.Gui/Control/P25Keyload.xaml
@@ -7,8 +7,8 @@
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
-
-
+
+
@@ -16,24 +16,31 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/sw/control/KFDtool.Gui/Control/P25Keyload.xaml.cs b/sw/control/KFDtool.Gui/Control/P25Keyload.xaml.cs
index e8e0d33..ed3058b 100644
--- a/sw/control/KFDtool.Gui/Control/P25Keyload.xaml.cs
+++ b/sw/control/KFDtool.Gui/Control/P25Keyload.xaml.cs
@@ -26,29 +26,20 @@ namespace KFDtool.Gui.Control
///
public partial class P25Keyload : UserControl
{
+ private bool IsKek { get; set; }
+
public P25Keyload()
{
InitializeComponent();
+ IsKek = false;
+
cbActiveKeyset.IsChecked = true; // check here to trigger the cb/txt logic on load
+ cboType.SelectedIndex = 0; // set to the first item here to trigger the cbo/lbl logic on load
cboAlgo.SelectedIndex = 0; // set to the first item here to trigger the cbo/txt logic on load
cbHide.IsChecked = true; // check here to trigger the cb/txt logic on load
}
- private void OnActiveKeysetChecked(object sender, RoutedEventArgs e)
- {
- txtKeysetIdDec.Text = string.Empty;
- txtKeysetIdHex.Text = string.Empty;
- txtKeysetIdDec.IsEnabled = false;
- txtKeysetIdHex.IsEnabled = false;
- }
-
- private void OnActiveKeysetUnchecked(object sender, RoutedEventArgs e)
- {
- txtKeysetIdDec.IsEnabled = true;
- txtKeysetIdHex.IsEnabled = true;
- }
-
private void KeysetIdDec_TextChanged(object sender, TextChangedEventArgs e)
{
if (txtKeysetIdDec.IsFocused)
@@ -83,6 +74,20 @@ namespace KFDtool.Gui.Control
}
}
+ private void OnActiveKeysetChecked(object sender, RoutedEventArgs e)
+ {
+ txtKeysetIdDec.Text = string.Empty;
+ txtKeysetIdHex.Text = string.Empty;
+ txtKeysetIdDec.IsEnabled = false;
+ txtKeysetIdHex.IsEnabled = false;
+ }
+
+ private void OnActiveKeysetUnchecked(object sender, RoutedEventArgs e)
+ {
+ txtKeysetIdDec.IsEnabled = true;
+ txtKeysetIdHex.IsEnabled = true;
+ }
+
private void SlnDec_TextChanged(object sender, TextChangedEventArgs e)
{
if (txtSlnDec.IsFocused)
@@ -97,6 +102,8 @@ namespace KFDtool.Gui.Control
{
txtSlnHex.Text = string.Empty;
}
+
+ UpdateType();
}
}
@@ -114,9 +121,65 @@ namespace KFDtool.Gui.Control
{
txtSlnDec.Text = string.Empty;
}
+
+ UpdateType();
}
}
+ private void UpdateType()
+ {
+ if (cboType.SelectedItem != null)
+ {
+ string name = ((ComboBoxItem)cboType.SelectedItem).Name as string;
+
+ if (name == "AUTO")
+ {
+ int num;
+
+ if (int.TryParse(txtSlnHex.Text, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out num))
+ {
+ if (num >= 0 && num <= 61439)
+ {
+ lblType.Content = "TEK";
+ IsKek = false;
+ }
+ else if (num >= 61440 && num <= 65535)
+ {
+ lblType.Content = "KEK";
+ IsKek = true;
+ }
+ else
+ {
+ lblType.Content = "Auto";
+ }
+ }
+ else
+ {
+ lblType.Content = "Auto";
+ }
+ }
+ else if (name == "TEK")
+ {
+ lblType.Content = "TEK";
+ IsKek = false;
+ }
+ else if (name == "KEK")
+ {
+ lblType.Content = "KEK";
+ IsKek = true;
+ }
+ else
+ {
+ // error
+ }
+ }
+ }
+
+ private void OnTypeChanged(object sender, SelectionChangedEventArgs e)
+ {
+ UpdateType();
+ }
+
private void KeyIdDec_TextChanged(object sender, TextChangedEventArgs e)
{
if (txtKeyIdDec.IsFocused)
@@ -384,7 +447,7 @@ namespace KFDtool.Gui.Control
return;
}
- Tuple validateResult = FieldValidator.KeyloadValidate(keysetId, sln, keyId, algId, key);
+ Tuple validateResult = FieldValidator.KeyloadValidate(keysetId, sln, IsKek, keyId, algId, key);
if (validateResult.Item1 == ValidateResult.Warning)
{
@@ -401,7 +464,7 @@ namespace KFDtool.Gui.Control
try
{
- Interact.Keyload(Settings.Port, useActiveKeyset, keysetId, sln, keyId, algId, key);
+ Interact.Keyload(Settings.Port, useActiveKeyset, keysetId, sln, IsKek, keyId, algId, key);
}
catch (Exception ex)
{
diff --git a/sw/control/KFDtool.P25/KFDtool.P25.csproj b/sw/control/KFDtool.P25/KFDtool.P25.csproj
index 4f332fe..18f9bc3 100644
--- a/sw/control/KFDtool.P25/KFDtool.P25.csproj
+++ b/sw/control/KFDtool.P25/KFDtool.P25.csproj
@@ -53,7 +53,7 @@
-
+
diff --git a/sw/control/KFDtool.P25/Kmm/AckStatus.cs b/sw/control/KFDtool.P25/Kmm/AckStatus.cs
deleted file mode 100644
index 08e1a34..0000000
--- a/sw/control/KFDtool.P25/Kmm/AckStatus.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace KFDtool.P25.Kmm
-{
- public enum AckStatus : byte
- {
- CommandWasNotPerformed = 0x01,
- ItemDoesNotExist = 0x02,
- InvalidMessageId = 0x03,
- InvalidMac = 0x04,
- InvalidMessageNumber = 0x07
- }
-}
diff --git a/sw/control/KFDtool.P25/Kmm/KeyItem.cs b/sw/control/KFDtool.P25/Kmm/KeyItem.cs
index 3785f35..1cbb8b4 100644
--- a/sw/control/KFDtool.P25/Kmm/KeyItem.cs
+++ b/sw/control/KFDtool.P25/Kmm/KeyItem.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -65,10 +66,13 @@ namespace KFDtool.P25.Kmm
}
}
+ public bool KEK { get; set; }
+
public bool Erase { get; set; }
public KeyItem()
{
+ KEK = false;
Erase = false;
}
@@ -77,14 +81,10 @@ namespace KFDtool.P25.Kmm
byte[] contents = new byte[5 + Key.Length];
/* key format */
- if (Erase)
- {
- contents[0] = 0x20;
- }
- else
- {
- contents[0] = 0x00;
- }
+ BitArray keyFormat = new BitArray(8, false);
+ keyFormat.Set(7, KEK);
+ keyFormat.Set(5, Erase);
+ keyFormat.CopyTo(contents, 0);
/* sln */
contents[1] = (byte)(SLN >> 8);
@@ -115,6 +115,7 @@ namespace KFDtool.P25.Kmm
}
/* key format */
+ KEK = (contents[0] & 0x80) == 1;
Erase = (contents[0] & 0x20) == 1;
/* sln */
diff --git a/sw/control/KFDtool.P25/Kmm/NegativeAcknowledgment.cs b/sw/control/KFDtool.P25/Kmm/NegativeAcknowledgment.cs
index e01a29a..2cc5bd5 100644
--- a/sw/control/KFDtool.P25/Kmm/NegativeAcknowledgment.cs
+++ b/sw/control/KFDtool.P25/Kmm/NegativeAcknowledgment.cs
@@ -13,7 +13,7 @@ namespace KFDtool.P25.Kmm
public int MessageNumber { get; set; }
- public AckStatus Status { get; set; }
+ public OperationStatus Status { get; set; }
public override MessageId MessageId
{
@@ -67,7 +67,7 @@ namespace KFDtool.P25.Kmm
MessageNumber |= contents[2];
/* status */
- Status = (AckStatus)contents[3];
+ Status = (OperationStatus)contents[3];
}
}
}
diff --git a/sw/control/KFDtool.P25/Kmm/OperationStatus.cs b/sw/control/KFDtool.P25/Kmm/OperationStatus.cs
new file mode 100644
index 0000000..9de949a
--- /dev/null
+++ b/sw/control/KFDtool.P25/Kmm/OperationStatus.cs
@@ -0,0 +1,108 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace KFDtool.P25.Kmm
+{
+ public enum OperationStatus : byte
+ {
+ CommandWasPerformed = 0x00,
+ CommandWasNotPerformed = 0x01,
+ ItemDoesNotExist = 0x02,
+ InvalidMessageId = 0x03,
+ InvalidMac = 0x04,
+ OutOfMemory = 0x05,
+ CouldNotDecryptTheMessage = 0x06,
+ InvalidMessageNumber = 0x07,
+ InvalidKeyId = 0x08,
+ InvalidAlgorithmId = 0x09,
+ InvalidMfid = 0x0A,
+ ModuleFailure = 0x0B,
+ MiAllZeros = 0x0C,
+ Keyfail = 0x0D,
+ Unknown = 0xFF
+ }
+
+ public static class OperationStatusExtensions
+ {
+ public static string ToStatusString(OperationStatus status)
+ {
+ switch (status)
+ {
+ case OperationStatus.CommandWasPerformed:
+ return "Command was performed";
+ case OperationStatus.CommandWasNotPerformed:
+ return "Command not performed";
+ case OperationStatus.ItemDoesNotExist:
+ return "Item does not exist";
+ case OperationStatus.InvalidMessageId:
+ return "Invalid Message ID";
+ case OperationStatus.InvalidMac:
+ return "Invalid MAC";
+ case OperationStatus.OutOfMemory:
+ return "Out of Memory";
+ case OperationStatus.CouldNotDecryptTheMessage:
+ return "Could not decrypt the message";
+ case OperationStatus.InvalidMessageNumber:
+ return "Invalid Message Number";
+ case OperationStatus.InvalidKeyId:
+ return "Invalid Key ID";
+ case OperationStatus.InvalidAlgorithmId:
+ return "Invalid Algorithm ID";
+ case OperationStatus.InvalidMfid:
+ return "Invalid MFID";
+ case OperationStatus.ModuleFailure:
+ return "Module Failure";
+ case OperationStatus.MiAllZeros:
+ return "MI all zeros";
+ case OperationStatus.Keyfail:
+ return "Keyfail";
+ case OperationStatus.Unknown:
+ return "Unknown";
+ default:
+ return "Reserved";
+ }
+ }
+
+ public static string ToReasonString(OperationStatus status)
+ {
+ switch (status)
+ {
+ case OperationStatus.CommandWasPerformed:
+ return "Command was executed successfully";
+ case OperationStatus.CommandWasNotPerformed:
+ return "Command could not be performed due to an unspecified reason";
+ case OperationStatus.ItemDoesNotExist:
+ return "Key / Keyset needed to perform the operation does not exist";
+ case OperationStatus.InvalidMessageId:
+ return "Message ID is invalid/unsupported";
+ case OperationStatus.InvalidMac:
+ return "MAC is invalid";
+ case OperationStatus.OutOfMemory:
+ return "Memory unavailable to process the command / message";
+ case OperationStatus.CouldNotDecryptTheMessage:
+ return "KEK does not exist";
+ case OperationStatus.InvalidMessageNumber:
+ return "Message Number is invalid";
+ case OperationStatus.InvalidKeyId:
+ return "Key ID is invalid or not present";
+ case OperationStatus.InvalidAlgorithmId:
+ return "ALGID is invalid or not present";
+ case OperationStatus.InvalidMfid:
+ return "MFID is invalid";
+ case OperationStatus.ModuleFailure:
+ return "Encryption Hardware failure";
+ case OperationStatus.MiAllZeros:
+ return "Received MI was all zeros";
+ case OperationStatus.Keyfail:
+ return "Key identified by ALGID/Key ID is erased";
+ case OperationStatus.Unknown:
+ return "Unknown";
+ default:
+ return "Reserved";
+ }
+ }
+ }
+}
diff --git a/sw/control/KFDtool.P25/ManualRekey/ManualRekeyApplication.cs b/sw/control/KFDtool.P25/ManualRekey/ManualRekeyApplication.cs
index 6c1b3b1..c50695a 100644
--- a/sw/control/KFDtool.P25/ManualRekey/ManualRekeyApplication.cs
+++ b/sw/control/KFDtool.P25/ManualRekey/ManualRekeyApplication.cs
@@ -51,7 +51,7 @@ namespace KFDtool.P25.ManualRekey
}
/* TIA 102.AACD-A 3.8.1 */
- public void Keyload(bool useActiveKeyset, int keysetId, int sln, int keyId, int algId, List key)
+ public void Keyload(bool useActiveKeyset, int keysetId, int sln, bool isKek, int keyId, int algId, List key)
{
Begin();
@@ -79,6 +79,10 @@ namespace KFDtool.P25.ManualRekey
{
ksid = keysetId;
}
+ else if (useActiveKeyset && isKek)
+ {
+ ksid = 0xFF;
+ }
else if (useActiveKeyset && kmm.KsetIds.Count > 0)
{
ksid = kmm.KsetIds[0];
@@ -92,7 +96,9 @@ namespace KFDtool.P25.ManualRekey
{
NegativeAcknowledgment kmm = rspKmmBody1 as NegativeAcknowledgment;
- throw new Exception(string.Format("recieved negative acknowledgment, status {0} (0x{1:X2})", kmm.Status.ToString(), (byte)kmm.Status));
+ string statusDescr = OperationStatusExtensions.ToStatusString(kmm.Status);
+ string statusReason = OperationStatusExtensions.ToReasonString(kmm.Status);
+ throw new Exception(string.Format("received negative acknowledgment{0}status: {1} (0x{2:X2}){0}{3}", Environment.NewLine, statusDescr, kmm.Status, statusReason));
}
else
{
@@ -105,6 +111,7 @@ namespace KFDtool.P25.ManualRekey
keyItem.SLN = sln;
keyItem.KeyId = keyId;
keyItem.Key = key.ToArray();
+ keyItem.KEK = isKek;
keyItem.Erase = false;
ModifyKeyCommand modifyKeyCommand = new ModifyKeyCommand();
@@ -133,7 +140,9 @@ namespace KFDtool.P25.ManualRekey
if (status.Status != 0)
{
- throw new Exception("unexpected status");
+ string statusDescr = OperationStatusExtensions.ToStatusString((OperationStatus)status.Status);
+ string statusReason = OperationStatusExtensions.ToReasonString((OperationStatus)status.Status);
+ throw new Exception(string.Format("received unexpected key status{0}status: {1} (0x{2:X2}){0}{3}", Environment.NewLine, statusDescr, status.Status, statusReason));
}
}
}
@@ -141,11 +150,13 @@ namespace KFDtool.P25.ManualRekey
{
NegativeAcknowledgment kmm = rspKmmBody2 as NegativeAcknowledgment;
- throw new Exception(string.Format("recieved negative acknowledgment, status {0} (0x{1:X2})", kmm.Status.ToString(), (byte)kmm.Status));
+ string statusDescr = OperationStatusExtensions.ToStatusString(kmm.Status);
+ string statusReason = OperationStatusExtensions.ToReasonString(kmm.Status);
+ throw new Exception(string.Format("received negative acknowledgment{0}status: {1} (0x{2:X2}){0}{3}", Environment.NewLine, statusDescr, kmm.Status, statusReason));
}
else
{
- throw new Exception("unexpected kmm");
+ throw new Exception("received unexpected kmm");
}
}
catch
@@ -177,7 +188,7 @@ namespace KFDtool.P25.ManualRekey
}
/* TIA 102.AACD-A 3.8.5 */
- public void EraseKeys(bool useActiveKeyset, int keysetId, int sln)
+ public void EraseKeys(bool useActiveKeyset, int keysetId, int sln, bool isKek)
{
Begin();
@@ -205,6 +216,10 @@ namespace KFDtool.P25.ManualRekey
{
ksid = keysetId;
}
+ else if (useActiveKeyset && isKek)
+ {
+ ksid = 0xFF;
+ }
else if (useActiveKeyset && kmm.KsetIds.Count > 0)
{
ksid = kmm.KsetIds[0];
@@ -218,7 +233,9 @@ namespace KFDtool.P25.ManualRekey
{
NegativeAcknowledgment kmm = rspKmmBody1 as NegativeAcknowledgment;
- throw new Exception(string.Format("recieved negative acknowledgment, status {0} (0x{1:X2})", kmm.Status.ToString(), (byte)kmm.Status));
+ string statusDescr = OperationStatusExtensions.ToStatusString(kmm.Status);
+ string statusReason = OperationStatusExtensions.ToReasonString(kmm.Status);
+ throw new Exception(string.Format("received negative acknowledgment{0}status: {1} (0x{2:X2}){0}{3}", Environment.NewLine, statusDescr, kmm.Status, statusReason));
}
else
{
@@ -231,6 +248,7 @@ namespace KFDtool.P25.ManualRekey
keyItem.SLN = sln;
keyItem.KeyId = 65535; // to match KVL3000+ R3.53.03 behavior
keyItem.Key = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; // to match KVL3000+ R3.53.03 behavior
+ keyItem.KEK = isKek;
keyItem.Erase = true;
ModifyKeyCommand modifyKeyCommand = new ModifyKeyCommand();
@@ -259,7 +277,9 @@ namespace KFDtool.P25.ManualRekey
if (status.Status != 0)
{
- throw new Exception("unexpected status");
+ string statusDescr = OperationStatusExtensions.ToStatusString((OperationStatus)status.Status);
+ string statusReason = OperationStatusExtensions.ToReasonString((OperationStatus)status.Status);
+ throw new Exception(string.Format("received unexpected key status{0}status: {1} (0x{2:X2}){0}{3}", Environment.NewLine, statusDescr, status.Status, statusReason));
}
}
}
@@ -267,7 +287,9 @@ namespace KFDtool.P25.ManualRekey
{
NegativeAcknowledgment kmm = rspKmmBody2 as NegativeAcknowledgment;
- throw new Exception(string.Format("recieved negative acknowledgment, status {0} (0x{1:X2})", kmm.Status.ToString(), (byte)kmm.Status));
+ string statusDescr = OperationStatusExtensions.ToStatusString(kmm.Status);
+ string statusReason = OperationStatusExtensions.ToReasonString(kmm.Status);
+ throw new Exception(string.Format("received negative acknowledgment{0}status: {1} (0x{2:X2}){0}{3}", Environment.NewLine, statusDescr, kmm.Status, statusReason));
}
else
{
@@ -303,7 +325,9 @@ namespace KFDtool.P25.ManualRekey
{
NegativeAcknowledgment kmm = responseKmmBody as NegativeAcknowledgment;
- throw new Exception(string.Format("recieved negative acknowledgment, status {0} (0x{1:X2})", kmm.Status.ToString(), (byte)kmm.Status));
+ string statusDescr = OperationStatusExtensions.ToStatusString(kmm.Status);
+ string statusReason = OperationStatusExtensions.ToReasonString(kmm.Status);
+ throw new Exception(string.Format("received negative acknowledgment{0}status: {1} (0x{2:X2}){0}{3}", Environment.NewLine, statusDescr, kmm.Status, statusReason));
}
else
{
@@ -379,7 +403,9 @@ namespace KFDtool.P25.ManualRekey
{
NegativeAcknowledgment kmm = responseKmmBody as NegativeAcknowledgment;
- throw new Exception(string.Format("recieved negative acknowledgment, status {0} (0x{1:X2})", kmm.Status.ToString(), (byte)kmm.Status));
+ string statusDescr = OperationStatusExtensions.ToStatusString(kmm.Status);
+ string statusReason = OperationStatusExtensions.ToReasonString(kmm.Status);
+ throw new Exception(string.Format("received negative acknowledgment{0}status: {1} (0x{2:X2}){0}{3}", Environment.NewLine, statusDescr, kmm.Status, statusReason));
}
else
{
diff --git a/sw/control/KFDtool.P25/ThreeWire/ThreeWireProtocol.cs b/sw/control/KFDtool.P25/ThreeWire/ThreeWireProtocol.cs
index 2eda60e..26ada64 100644
--- a/sw/control/KFDtool.P25/ThreeWire/ThreeWireProtocol.cs
+++ b/sw/control/KFDtool.P25/ThreeWire/ThreeWireProtocol.cs
@@ -412,7 +412,7 @@ namespace KFDtool.P25.ThreeWire
NegativeAcknowledgment kmm = new NegativeAcknowledgment();
kmm.AcknowledgedMessageId = (MessageId)message[0];
- kmm.Status = AckStatus.InvalidMessageId;
+ kmm.Status = OperationStatus.InvalidMessageId;
KmmFrame frame = new KmmFrame(kmm);
diff --git a/sw/control/KFDtool.P25/TransferConstructs/Interact.cs b/sw/control/KFDtool.P25/TransferConstructs/Interact.cs
index 6dcc361..a4fe6e3 100644
--- a/sw/control/KFDtool.P25/TransferConstructs/Interact.cs
+++ b/sw/control/KFDtool.P25/TransferConstructs/Interact.cs
@@ -468,7 +468,7 @@ namespace KFDtool.P25.TransferConstructs
}
}
- public static void Keyload(string port, bool useActiveKeyset, int keysetId, int sln, int keyId, int algId, List key)
+ public static void Keyload(string port, bool useActiveKeyset, int keysetId, int sln, bool isKek, int keyId, int algId, List key)
{
if (port == string.Empty)
{
@@ -487,7 +487,7 @@ namespace KFDtool.P25.TransferConstructs
ManualRekeyApplication mra = new ManualRekeyApplication(ap);
- mra.Keyload(useActiveKeyset, keysetId, sln, keyId, algId, key);
+ mra.Keyload(useActiveKeyset, keysetId, sln, isKek, keyId, algId, key);
}
catch (Exception)
{
@@ -509,7 +509,7 @@ namespace KFDtool.P25.TransferConstructs
}
}
- public static void EraseKey(string port, bool useActiveKeyset, int keysetId, int sln)
+ public static void EraseKey(string port, bool useActiveKeyset, int keysetId, int sln, bool isKek)
{
if (port == string.Empty)
{
@@ -528,7 +528,7 @@ namespace KFDtool.P25.TransferConstructs
ManualRekeyApplication mra = new ManualRekeyApplication(ap);
- mra.EraseKeys(useActiveKeyset, keysetId, sln);
+ mra.EraseKeys(useActiveKeyset, keysetId, sln, isKek);
}
catch (Exception)
{
diff --git a/sw/control/KFDtool.P25/Validator/FieldValidator.cs b/sw/control/KFDtool.P25/Validator/FieldValidator.cs
index 3e313e2..cca3c80 100644
--- a/sw/control/KFDtool.P25/Validator/FieldValidator.cs
+++ b/sw/control/KFDtool.P25/Validator/FieldValidator.cs
@@ -26,7 +26,7 @@ namespace KFDtool.P25.Validator
public static bool IsValidSln(int sln)
{
/* TIA 102.AACA-A 10.3.25 */
- if (sln < 1 || sln > 65535)
+ if (sln < 0 || sln > 65535)
{
return false;
}
@@ -97,7 +97,7 @@ namespace KFDtool.P25.Validator
return result;
}
- public static Tuple KeyloadValidate(int keysetId, int sln, int keyId, int algId, List key)
+ public static Tuple KeyloadValidate(int keysetId, int sln, bool isKek, int keyId, int algId, List key)
{
if (!IsValidKeysetId(keysetId))
{
@@ -106,7 +106,7 @@ namespace KFDtool.P25.Validator
if (!IsValidSln(sln))
{
- return Tuple.Create(ValidateResult.Error, "SLN invalid - valid range 1 to 65553 (dec), 0x0001 to 0x1999 (hex)");
+ return Tuple.Create(ValidateResult.Error, "SLN invalid - valid range 0 to 65535 (dec), 0x0000 to 0xFFFF (hex)");
}
if (!IsValidKeyId(keyId))
@@ -321,6 +321,31 @@ namespace KFDtool.P25.Validator
return Tuple.Create(ValidateResult.Warning, string.Format("Algorithm ID 0x{0:X2} is unassigned - no key validation has been performed", algId));
}
+ // good practice validators
+
+ if (sln == 0)
+ {
+ return Tuple.Create(ValidateResult.Warning, "While the SLN 0 is valid, some equipment may have issues using it"); // *cough* Motorola KVLs *cough*
+ }
+ if (sln >= 1 && sln <= 4095)
+ {
+ if (isKek)
+ {
+ return Tuple.Create(ValidateResult.Warning, "This SLN is in the range for TEKs, but the key type KEK is selected");
+ }
+ }
+ else if (sln >= 4096 && sln <= 61439)
+ {
+ return Tuple.Create(ValidateResult.Warning, "While this SLN is valid, it uses a crypto group other than 0 or 15, some equipment may have issues using it");
+ }
+ else if (sln >= 61440 && sln <= 65535)
+ {
+ if (!isKek)
+ {
+ return Tuple.Create(ValidateResult.Warning, "This SLN is in the range for KEKs, but the key type TEK is selected");
+ }
+ }
+
return Tuple.Create(ValidateResult.Success, string.Empty);
}
}