Gurux.DLMS.GXDLMS.HandleReadResponse C# (CSharp) Method

HandleReadResponse() static private method

Handle read response and get data from block and/or update error status.
static private HandleReadResponse ( GXDLMSSettings settings, GXReplyData reply, int index ) : bool
settings GXDLMSSettings
reply GXReplyData Received data from the client.
index int
return bool
        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;
        }