internal static void GetSNPdu(GXDLMSSNParameters p, GXByteBuffer reply)
{
bool ciphering = p.settings.Cipher != null && p.settings.Cipher.Security != Gurux.DLMS.Enums.Security.None;
if (!ciphering && p.settings.InterfaceType == InterfaceType.HDLC)
{
if (p.settings.IsServer)
{
reply.Set(GXCommon.LLCReplyBytes);
}
else if (reply.Size == 0)
{
reply.Set(GXCommon.LLCSendBytes);
}
}
int cnt = 0, cipherSize = 0;
if (ciphering)
{
cipherSize = CipheringHeaderSize;
/*
if (p.settings.Cipher.Security == Security.Encryption)
{
cipherSize = 7;
}
else if (p.settings.Cipher.Security == Security.Authentication)
{
cipherSize = 19;
}
else if (p.settings.Cipher.Security == Security.AuthenticationEncryption)
{
cipherSize = 7;
}
* */
}
if (p.data != null)
{
cnt = p.data.Size - p.data.Position;
}
// Add command.
if (p.command != Command.Aarq && p.command != Command.Aare)
{
reply.SetUInt8((byte)p.command);
if (p.count != 0xFF)
{
GXCommon.SetObjectCount(p.count, reply);
}
if (p.requestType != 0xFF)
{
reply.SetUInt8(p.requestType);
}
reply.Set(p.attributeDescriptor);
if (!p.multipleBlocks)
{
p.multipleBlocks = reply.Size + cipherSize + cnt > p.settings.MaxPduSize;
//If reply data is not fit to one PDU.
if (p.multipleBlocks)
{
//Remove command.
GXByteBuffer tmp = new GXByteBuffer();
int offset = 1;
if (!ciphering && p.settings.InterfaceType == InterfaceType.HDLC)
{
offset = 4;
}
tmp.Set(reply.Data, offset, reply.Size - offset);
reply.Size = 0;
if (!ciphering && p.settings.InterfaceType == InterfaceType.HDLC)
{
if (p.settings.IsServer)
{
reply.Set(GXCommon.LLCReplyBytes);
}
else if (reply.Size == 0)
{
reply.Set(GXCommon.LLCSendBytes);
}
}
if (p.command == Command.WriteRequest)
{
p.requestType = (byte)VariableAccessSpecification.WriteDataBlockAccess;
}
else if (p.command == Command.ReadRequest)
{
p.requestType = (byte)VariableAccessSpecification.ReadDataBlockAccess;
}
else if (p.command == Command.ReadResponse)
{
p.requestType = (byte)SingleReadResponse.DataBlockResult;
}
else
{
throw new ArgumentException("Invalid command.");
}
reply.SetUInt8((byte)p.command);
//Set object count.
reply.SetUInt8(1);
if (p.requestType != 0xFF)
{
reply.SetUInt8(p.requestType);
}
cnt = GXDLMS.AppendMultipleSNBlocks(p, tmp, reply);
}
}
else
{
cnt = GXDLMS.AppendMultipleSNBlocks(p, null, reply);
}
}
// Add data.
reply.Set(p.data, cnt);
//Af all data is transfered.
if (p.data != null && p.data.Position == p.data.Size)
{
p.settings.Index = p.settings.Count = 0;
}
// If Ciphering is used.
if (ciphering && p.command != Command.Aarq && p.command != Command.Aare)
{
byte[] tmp = p.settings.Cipher.Encrypt((byte)GetGloMessage(p.command), p.settings.Cipher.SystemTitle, reply.Array());
System.Diagnostics.Debug.Assert(!(p.settings.MaxPduSize < tmp.Length));
reply.Size = 0;
if (p.settings.InterfaceType == InterfaceType.HDLC)
{
if (p.settings.IsServer)
{
reply.Set(GXCommon.LLCReplyBytes);
}
else if (reply.Size == 0)
{
reply.Set(GXCommon.LLCSendBytes);
}
}
reply.Set(tmp);
}
}