private static void HandleSetRequestNormal(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, byte type, GXDLMSLNParameters p, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
{
object value = null;
GXDataInfo reply = new GXDataInfo();
// CI
ObjectType ci = (ObjectType)data.GetUInt16();
byte[] ln = new byte[6];
data.Get(ln);
// Attribute index.
byte index = data.GetUInt8();
// Get Access Selection.
data.GetUInt8();
if (xml != null)
{
AppendAttributeDescriptor(xml, (int)ci, ln, index);
xml.AppendStartTag(TranslatorTags.Value);
GXDataInfo di = new GXDataInfo();
di.xml = xml;
value = GXCommon.GetData(settings, data, di);
if (!di.Complete)
{
value = GXCommon.ToHex(data.Data, false, data.Position, data.Size - data.Position);
}
else if (value is byte[])
{
value = GXCommon.ToHex((byte[])value, false);
}
xml.AppendEndTag(TranslatorTags.Value);
return;
}
if (type == 2)
{
p.multipleBlocks = data.GetUInt8() == 0;
UInt32 blockNumber = data.GetUInt32();
if (blockNumber != settings.BlockIndex)
{
Debug.WriteLine("HandleSetRequest failed. Invalid block number. " + settings.BlockIndex + "/" + blockNumber);
p.status = (byte)ErrorCode.DataBlockNumberInvalid;
return;
}
settings.IncreaseBlockIndex();
int size = GXCommon.GetObjectCount(data);
int realSize = data.Size - data.Position;
if (size != realSize)
{
Debug.WriteLine("HandleSetRequest failed. Invalid block size.");
p.status = (byte)ErrorCode.DataBlockUnavailable;
return;
}
}
if (!p.multipleBlocks)
{
settings.ResetBlockIndex();
value = GXCommon.GetData(settings, data, reply);
}
GXDLMSObject obj = settings.Objects.FindByLN(ci, GXDLMSObject.ToLogicalName(ln));
if (obj == null)
{
obj = server.NotifyFindObject(ci, 0, GXDLMSObject.ToLogicalName(ln));
}
// If target is unknown.
if (obj == null)
{
// Device reports a undefined object.
p.status = (byte)ErrorCode.UndefinedObject;
}
else
{
AccessMode am = obj.GetAccess(index);
// If write is denied.
if (am != AccessMode.Write && am != AccessMode.ReadWrite)
{
//Read Write denied.
p.status = (byte)ErrorCode.ReadWriteDenied;
}
else
{
try
{
if (value is byte[])
{
DataType dt = (obj as IGXDLMSBase).GetDataType(index);
if (dt != DataType.None && dt != DataType.OctetString)
{
value = GXDLMSClient.ChangeType((byte[])value, dt);
}
}
ValueEventArgs e = new ValueEventArgs(settings, obj, index, 0, null);
e.Value = value;
ValueEventArgs[] list = new ValueEventArgs[] { e };
if (p.multipleBlocks)
{
server.transaction = new GXDLMSLongTransaction(list, Command.GetRequest, data);
}
server.NotifyWrite(list);
if (e.Error != 0)
{
p.status = (byte)e.Error;
}
else if (!e.Handled && !p.multipleBlocks)
{
(obj as IGXDLMSBase).SetValue(settings, e);
}
}
catch (Exception)
{
p.status = (byte)ErrorCode.HardwareFault;
}
}
}
}