static bool HandleReadResponse(GXDLMSSettings settings, GXReplyData reply, int index)
{
int cnt = GXCommon.GetObjectCount(reply.Data);
//Set total count if not set yet.
if (reply.TotalCount == 0)
{
reply.TotalCount = cnt;
}
SingleReadResponse type = SingleReadResponse.Data;
List<object> values = null;
if (cnt != 1)
{
values = new List<object>();
}
if (reply.Xml != null)
{
reply.Xml.AppendStartTag(Command.ReadResponse, "Qty", reply.Xml.IntegerToHex(cnt, 2));
}
for (int pos = 0; pos != cnt; ++pos)
{
//Some meters are returning wrong count.
if (reply.Xml != null && reply.Data.Position == reply.Data.Size)
{
}
else
{
// Get status code.
if (reply.Data.Position == reply.ReadPosition)
{
reply.TotalCount = 0;
reply.Data.Position = index;
GetDataFromBlock(reply.Data, 0);
reply.Value = null;
//Ask that data is parsed after last block is received.
reply.CommandType = (byte)SingleReadResponse.DataBlockResult;
return false;
}
reply.CommandType = reply.Data.GetUInt8();
type = (SingleReadResponse)reply.CommandType;
}
switch (type)
{
case SingleReadResponse.Data:
reply.Error = 0;
if (reply.Xml != null)
{
if (reply.Xml.OutputType == TranslatorOutputType.StandardXml)
{
reply.Xml.AppendStartTag(TranslatorTags.Choice);
}
reply.Xml.AppendStartTag(Command.ReadResponse, SingleReadResponse.Data);
GXDataInfo di = new GXDataInfo();
di.xml = reply.Xml;
GXCommon.GetData(settings, reply.Data, di);
reply.Xml.AppendEndTag(Command.ReadResponse, SingleReadResponse.Data);
if (reply.Xml.OutputType == TranslatorOutputType.StandardXml)
{
reply.Xml.AppendEndTag(TranslatorTags.Choice);
}
}
else if (cnt == 1)
{
GetDataFromBlock(reply.Data, 0);
}
else
{
reply.ReadPosition = reply.Data.Position;
GetValueFromData(settings, reply);
if (reply.Data.Position == reply.ReadPosition)
{
//If multiple values remove command.
if (cnt != 1 && reply.TotalCount == 0)
{
++index;
}
reply.TotalCount = 0;
reply.Data.Position = index;
GetDataFromBlock(reply.Data, 0);
reply.Value = null;
//Ask that data is parsed after last block is received.
reply.CommandType = (byte)SingleReadResponse.DataBlockResult;
return false;
}
reply.Data.Position = reply.ReadPosition;
values.Add(reply.Value);
reply.Value = null;
}
break;
case SingleReadResponse.DataAccessError:
// Get error code.
reply.Error = reply.Data.GetUInt8();
if (reply.Xml != null)
{
if (reply.Xml.OutputType == TranslatorOutputType.StandardXml)
{
reply.Xml.AppendStartTag(TranslatorTags.Choice);
}
reply.Xml.AppendLine(
(int)Command.ReadResponse << 8
| (int)SingleReadResponse.DataAccessError,
null,
GXDLMSTranslator.ErrorCodeToString(
reply.Xml.OutputType,
(ErrorCode)reply.Error));
if (reply.Xml.OutputType == TranslatorOutputType.StandardXml)
{
reply.Xml.AppendEndTag(TranslatorTags.Choice);
}
//reply.Xml.AppendLine("<" + SingleReadResponse.DataAccessError.ToString() + " Value=\"" + ((ErrorCode)reply.Error).ToString() + "\" />");
}
break;
case SingleReadResponse.DataBlockResult:
if (!ReadResponseDataBlockResult(settings, reply, index))
{
//If xml only received bytes are shown. Data is not try to parse.
if (reply.Xml != null)
{
reply.Xml.AppendEndTag(Command.ReadResponse);
}
return false;
}
break;
case SingleReadResponse.BlockNumber:
// Get Block number.
UInt32 number = reply.Data.GetUInt16();
if (number != settings.BlockIndex)
{
throw new ArgumentException(
"Invalid Block number. It is " + number
+ " and it should be " + settings.BlockIndex + ".");
}
settings.IncreaseBlockIndex();
reply.MoreData = (RequestTypes)(reply.MoreData | RequestTypes.DataBlock);
break;
default:
throw new GXDLMSException("HandleReadResponse failed. Invalid tag.");
}
}
if (reply.Xml != null)
{
reply.Xml.AppendEndTag(Command.ReadResponse);
return true;
}
if (values != null)
{
reply.Value = values.ToArray();
}
return cnt == 1;
}