2019-07-29 15:24:10 -06:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace KFDtool.P25.Kmm
|
|
|
|
|
{
|
|
|
|
|
public class KmmFrame
|
|
|
|
|
{
|
|
|
|
|
public KmmBody KmmBody { get; private set; }
|
|
|
|
|
|
|
|
|
|
// TODO src rsi
|
|
|
|
|
|
|
|
|
|
// TODO dest rsi
|
|
|
|
|
|
|
|
|
|
public KmmFrame(KmmBody kmmBody)
|
|
|
|
|
{
|
|
|
|
|
if (kmmBody == null)
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentNullException("kmmBody");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
KmmBody = kmmBody;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public KmmFrame(byte[] contents)
|
|
|
|
|
{
|
|
|
|
|
Parse(contents);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public byte[] ToBytes()
|
|
|
|
|
{
|
|
|
|
|
byte[] body = KmmBody.ToBytes();
|
|
|
|
|
|
|
|
|
|
int length = 10 + body.Length;
|
|
|
|
|
|
|
|
|
|
byte[] frame = new byte[length];
|
|
|
|
|
|
|
|
|
|
/* message id */
|
|
|
|
|
frame[0] = (byte)KmmBody.MessageId;
|
|
|
|
|
|
|
|
|
|
/* message length */
|
|
|
|
|
int messageLength = 7 + body.Length;
|
|
|
|
|
frame[1] = (byte)((messageLength >> 8) & 0xFF);
|
|
|
|
|
frame[2] = (byte)(messageLength & 0xFF);
|
|
|
|
|
|
|
|
|
|
/* message format */
|
|
|
|
|
BitArray messageFormat = new BitArray(8, false);
|
|
|
|
|
messageFormat.Set(7, Convert.ToBoolean(((byte)KmmBody.ResponseKind & 0x02) >> 1));
|
|
|
|
|
messageFormat.Set(6, Convert.ToBoolean((byte)KmmBody.ResponseKind & 0x01));
|
|
|
|
|
messageFormat.CopyTo(frame, 3);
|
|
|
|
|
|
|
|
|
|
/* destination rsi */
|
|
|
|
|
frame[4] = 0xFF;
|
|
|
|
|
frame[5] = 0xFF;
|
|
|
|
|
frame[6] = 0xFF;
|
|
|
|
|
|
|
|
|
|
/* source rsi */
|
|
|
|
|
frame[7] = 0xFF;
|
|
|
|
|
frame[8] = 0xFF;
|
|
|
|
|
frame[9] = 0xFF;
|
|
|
|
|
|
|
|
|
|
/* message body */
|
|
|
|
|
Array.Copy(body, 0, frame, 10, body.Length);
|
|
|
|
|
|
|
|
|
|
return frame;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Parse(byte[] contents)
|
|
|
|
|
{
|
|
|
|
|
if (contents.Length < 10)
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentOutOfRangeException(string.Format("length mismatch - expected at least 10, got {0} - {1}", contents.Length.ToString(), BitConverter.ToString(contents)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
byte messageId = contents[0];
|
|
|
|
|
|
|
|
|
|
int messageLength = 0;
|
|
|
|
|
messageLength |= contents[1] << 8;
|
|
|
|
|
messageLength |= contents[2];
|
|
|
|
|
|
|
|
|
|
int messageBodyLength = messageLength - 7;
|
|
|
|
|
byte[] messageBody = new byte[messageBodyLength];
|
|
|
|
|
Array.Copy(contents, 10, messageBody, 0, messageBodyLength);
|
|
|
|
|
|
2019-12-28 11:28:57 -07:00
|
|
|
|
if ((MessageId)messageId == MessageId.InventoryCommand)
|
|
|
|
|
{
|
|
|
|
|
if (messageBody.Length > 0)
|
|
|
|
|
{
|
|
|
|
|
InventoryType inventoryType = (InventoryType)messageBody[0];
|
|
|
|
|
|
|
|
|
|
if (inventoryType == InventoryType.ListActiveKsetIds)
|
|
|
|
|
{
|
|
|
|
|
KmmBody kmmBody = new InventoryCommandListActiveKsetIds();
|
|
|
|
|
kmmBody.Parse(messageBody);
|
|
|
|
|
KmmBody = kmmBody;
|
|
|
|
|
|
|
|
|
|
}
|
2020-01-01 07:36:05 -07:00
|
|
|
|
else if (inventoryType == InventoryType.ListRsiItems)
|
|
|
|
|
{
|
|
|
|
|
KmmBody kmmBody = new InventoryCommandListRsiItems();
|
|
|
|
|
kmmBody.Parse(messageBody);
|
|
|
|
|
KmmBody = kmmBody;
|
|
|
|
|
}
|
2019-12-28 11:28:57 -07:00
|
|
|
|
else if (inventoryType == InventoryType.ListActiveKeys)
|
|
|
|
|
{
|
|
|
|
|
KmmBody kmmBody = new InventoryCommandListActiveKeys();
|
|
|
|
|
kmmBody.Parse(messageBody);
|
|
|
|
|
KmmBody = kmmBody;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new Exception(string.Format("unknown inventory command type: 0x{0:X2}", (byte)inventoryType));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new Exception("inventory command length zero");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if ((MessageId)messageId == MessageId.InventoryResponse)
|
2019-07-29 15:24:10 -06:00
|
|
|
|
{
|
|
|
|
|
if (messageBody.Length > 0)
|
|
|
|
|
{
|
|
|
|
|
InventoryType inventoryType = (InventoryType)messageBody[0];
|
|
|
|
|
|
|
|
|
|
if (inventoryType == InventoryType.ListActiveKsetIds)
|
|
|
|
|
{
|
|
|
|
|
KmmBody kmmBody = new InventoryResponseListActiveKsetIds();
|
|
|
|
|
kmmBody.Parse(messageBody);
|
|
|
|
|
KmmBody = kmmBody;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (inventoryType == InventoryType.ListActiveKeys)
|
|
|
|
|
{
|
|
|
|
|
KmmBody kmmBody = new InventoryResponseListActiveKeys();
|
|
|
|
|
kmmBody.Parse(messageBody);
|
|
|
|
|
KmmBody = kmmBody;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new Exception(string.Format("unknown inventory response type: 0x{0:X2}", (byte)inventoryType));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new Exception("inventory response length zero");
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-12-28 11:28:57 -07:00
|
|
|
|
else if ((MessageId)messageId == MessageId.ModifyKeyCommand)
|
|
|
|
|
{
|
|
|
|
|
KmmBody kmmBody = new ModifyKeyCommand();
|
|
|
|
|
kmmBody.Parse(messageBody);
|
|
|
|
|
KmmBody = kmmBody;
|
|
|
|
|
}
|
|
|
|
|
else if ((MessageId)messageId == MessageId.NegativeAcknowledgment)
|
|
|
|
|
{
|
|
|
|
|
KmmBody kmmBody = new NegativeAcknowledgment();
|
|
|
|
|
kmmBody.Parse(messageBody);
|
|
|
|
|
KmmBody = kmmBody;
|
|
|
|
|
}
|
2019-07-29 15:24:10 -06:00
|
|
|
|
else if ((MessageId)messageId == MessageId.RekeyAcknowledgment)
|
|
|
|
|
{
|
|
|
|
|
KmmBody kmmBody = new RekeyAcknowledgment();
|
|
|
|
|
kmmBody.Parse(messageBody);
|
|
|
|
|
KmmBody = kmmBody;
|
|
|
|
|
}
|
|
|
|
|
else if ((MessageId)messageId == MessageId.ZeroizeResponse)
|
|
|
|
|
{
|
|
|
|
|
KmmBody kmmBody = new ZeroizeResponse();
|
|
|
|
|
kmmBody.Parse(messageBody);
|
|
|
|
|
KmmBody = kmmBody;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new Exception(string.Format("unknown kmm - message id: 0x{0:X2}", messageId));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|