static bool HandleGetResponse(GXDLMSSettings settings,
GXReplyData reply, int index)
{
bool ret = true;
long number;
short ch = 0;
GXByteBuffer data = reply.Data;
// Get type.
GetCommandType type = (GetCommandType)data.GetUInt8();
// Get invoke ID and priority.
ch = data.GetUInt8();
if (reply.Xml != null)
{
reply.Xml.AppendStartTag(Command.GetResponse);
reply.Xml.AppendStartTag(Command.GetResponse, type);
//InvokeIdAndPriority
reply.Xml.AppendLine(TranslatorTags.InvokeId, "Value", reply.Xml.IntegerToHex(ch, 2));
}
// Response normal
if (type == GetCommandType.Normal)
{
// Result
ch = data.GetUInt8();
if (ch != 0)
{
reply.Error = data.GetUInt8();
}
if (reply.Xml != null)
{
// Result start tag.
reply.Xml.AppendStartTag(TranslatorTags.Result);
if (reply.Error != 0)
{
reply.Xml.AppendLine(TranslatorTags.DataAccessError,
"Value",
GXDLMSTranslator.ErrorCodeToString(
reply.Xml.OutputType, (ErrorCode)reply.Error));
}
else
{
reply.Xml.AppendStartTag(TranslatorTags.Data);
GXDataInfo di = new GXDataInfo();
di.xml = reply.Xml;
GXCommon.GetData(settings, reply.Data, di);
reply.Xml.AppendEndTag(TranslatorTags.Data);
}
}
else
{
GetDataFromBlock(data, 0);
}
}
else if (type == GetCommandType.NextDataBlock)
{
// Is Last block.
ch = data.GetUInt8();
if (reply.Xml != null)
{
//Result start tag.
reply.Xml.AppendStartTag(TranslatorTags.Result);
//LastBlock
reply.Xml.AppendLine(TranslatorTags.LastBlock, "Value", reply.Xml.IntegerToHex(ch, 2));
}
if (ch == 0)
{
reply.MoreData = (RequestTypes)(reply.MoreData | RequestTypes.DataBlock);
}
else
{
reply.MoreData = (RequestTypes)(reply.MoreData & ~RequestTypes.DataBlock);
}
// Get Block number.
number = data.GetUInt32();
if (reply.Xml != null)
{
//BlockNumber
reply.Xml.AppendLine(TranslatorTags.BlockNumber, "Value", reply.Xml.IntegerToHex(number, 8));
}
else
{
//If meter's block index is zero based.
if (number != 1 && settings.BlockIndex == 1)
{
settings.BlockIndex = (uint)number;
}
if (number != settings.BlockIndex)
{
throw new ArgumentException(
"Invalid Block number. It is " + number
+ " and it should be " + settings.BlockIndex + ".");
}
}
// Get status.
ch = data.GetUInt8();
if (ch != 0)
{
reply.Error = data.GetUInt8();
}
if (reply.Xml != null)
{
// Get data size.
int blockLength = GXCommon.GetObjectCount(data);
// if whole block is read.
if ((reply.MoreData & RequestTypes.Frame) == 0)
{
// Check Block length.
if (blockLength > data.Size - data.Position)
{
throw new OutOfMemoryException();
}
}
//Result
reply.Xml.AppendStartTag(TranslatorTags.Result);
reply.Xml.AppendLine(TranslatorTags.RawData, "Value",
GXCommon.ToHex(reply.Data.Data, false, data.Position, reply.Data.Size - data.Position));
reply.Xml.AppendEndTag(TranslatorTags.Result);
}
else if (data.Position != data.Size)
{
// Get data size.
int blockLength = GXCommon.GetObjectCount(data);
// if whole block is read.
if ((reply.MoreData & RequestTypes.Frame) == 0)
{
// Check Block length.
if (blockLength > data.Size - data.Position)
{
throw new OutOfMemoryException();
}
reply.Command = Command.None;
}
GetDataFromBlock(data, index);
// If last packet and data is not try to peek.
if (reply.MoreData == RequestTypes.None)
{
if (!reply.Peek)
{
data.Position = 0;
}
settings.ResetBlockIndex();
}
}
}
else if (type == GetCommandType.WithList)
{
//Get object count.
int cnt = GXCommon.GetObjectCount(data);
object[] values = new object[cnt];
if (reply.Xml != null)
{
//Result start tag.
reply.Xml.AppendStartTag(TranslatorTags.Result, "Qty", reply.Xml.IntegerToHex(cnt, 2));
}
for (int pos = 0; pos != cnt; ++pos)
{
// Result
ch = data.GetUInt8();
if (ch != 0)
{
reply.Error = data.GetUInt8();
}
else
{
if (reply.Xml != null)
{
GXDataInfo di = new GXDataInfo();
di.xml = reply.Xml;
//Data.
reply.Xml.AppendStartTag(Command.ReadResponse, SingleReadResponse.Data);
GXCommon.GetData(settings, reply.Data, di);
reply.Xml.AppendEndTag(Command.ReadResponse, SingleReadResponse.Data);
}
else
{
reply.ReadPosition = reply.Data.Position;
GetValueFromData(settings, reply);
reply.Data.Position = reply.ReadPosition;
if (values != null)
{
values[pos] = reply.Value;
}
reply.Value = null;
}
}
}
reply.Value = values;
ret = false;
}
else
{
throw new ArgumentException("Invalid Get response.");
}
if (reply.Xml != null)
{
reply.Xml.AppendEndTag(TranslatorTags.Result);
reply.Xml.AppendEndTag(Command.GetResponse, type);
reply.Xml.AppendEndTag(Command.GetResponse);
}
return ret;
}