ResetBlockIndex() private method

Resets block index to default value.
private ResetBlockIndex ( ) : void
return void
Esempio n. 1
0
        private static void ReturnSNError(GXDLMSSettings settings, GXDLMSServer server, Command cmd, ErrorCode error, GXByteBuffer replyData)
        {
            GXByteBuffer bb = new GXByteBuffer();

            bb.SetUInt8(error);
            GXDLMS.GetSNPdu(new GXDLMSSNParameters(settings, cmd, 1, (byte)SingleReadResponse.DataAccessError, bb, null), replyData);
            settings.ResetBlockIndex();
        }
        private static void HanleSetRequestWithDataBlock(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXDLMSLNParameters p, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            GXDataInfo reply = new GXDataInfo();

            p.multipleBlocks = data.GetUInt8() == 0;
            UInt32 blockNumber = data.GetUInt32();

            if (blockNumber != settings.BlockIndex)
            {
                Debug.WriteLine("HanleSetRequestWithDataBlock failed. Invalid block number. " + settings.BlockIndex + "/" + blockNumber);
                p.status = (byte)ErrorCode.DataBlockNumberInvalid;
            }
            else
            {
                int size     = GXCommon.GetObjectCount(data);
                int realSize = data.Size - data.Position;
                if (size != realSize)
                {
                    Debug.WriteLine("HanleSetRequestWithDataBlock failed. Invalid block size.");
                    p.status = (byte)ErrorCode.DataBlockUnavailable;
                }
                server.transaction.data.Set(data);
                //If all data is received.
                if (!p.multipleBlocks)
                {
                    try
                    {
                        object value = GXCommon.GetData(settings, server.transaction.data, reply);
                        if (value is byte[])
                        {
                            DataType dt = (server.transaction.targets[0].Target as IGXDLMSBase).GetDataType(server.transaction.targets[0].Index);
                            if (dt != DataType.None && dt != DataType.OctetString)
                            {
                                value = GXDLMSClient.ChangeType((byte[])value, dt, settings.UseUtc2NormalTime);
                            }
                        }
                        server.transaction.targets[0].Value = value;
                        server.NotifyWrite(server.transaction.targets);
                        if (!server.transaction.targets[0].Handled && !p.multipleBlocks)
                        {
                            (server.transaction.targets[0].Target as IGXDLMSBase).SetValue(settings, server.transaction.targets[0]);
                            server.NotifyPostWrite(server.transaction.targets);
                        }
                    }
                    catch (Exception)
                    {
                        p.status = (byte)ErrorCode.HardwareFault;
                    }
                    finally
                    {
                        server.transaction = null;
                    }
                    settings.ResetBlockIndex();
                }
            }
            p.multipleBlocks = true;
        }
Esempio n. 3
0
        public static void HandleGetRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            //Return error if connection is not established.
            if (xml == null && settings.Connected == ConnectionState.None && !settings.CanAccess())
            {
                replyData.Set(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                                                                         ServiceError.Service, (byte)Service.Unsupported));
                return;
            }
            byte           invokeID = 0;
            GetCommandType type     = GetCommandType.NextDataBlock;

            //If GBT is used data is empty.
            if (data.Size != 0)
            {
                type = (GetCommandType)data.GetUInt8();
                // Get invoke ID and priority.
                invokeID = data.GetUInt8();
                settings.UpdateInvokeId(invokeID);
                if (xml != null)
                {
                    xml.AppendStartTag(Command.GetRequest);
                    xml.AppendStartTag(Command.GetRequest, type);
                    xml.AppendLine(TranslatorTags.InvokeId, "Value", xml.IntegerToHex(invokeID, 2));
                }
            }
            // GetRequest normal
            if (type == GetCommandType.Normal)
            {
                GetRequestNormal(settings, invokeID, server, data, replyData, xml);
            }
            else if (type == GetCommandType.NextDataBlock)
            {
                // Get request for next data block
                GetRequestNextDataBlock(settings, invokeID, server, data, replyData, xml, false);
            }
            else if (type == GetCommandType.WithList)
            {
                // Get request with a list.
                GetRequestWithList(settings, invokeID, server, data, replyData, xml);
            }
            else
            {
                Debug.WriteLine("HandleGetRequest failed. Invalid command type.");
                settings.ResetBlockIndex();
                GXByteBuffer bb = new GXByteBuffer();
                // Access Error : Device reports a hardware fault.
                bb.SetUInt8((byte)ErrorCode.HardwareFault);
                GXDLMS.GetLNPdu(new GXDLMSLNParameters(null, settings, invokeID, Command.GetResponse, (byte)type, null, bb, (byte)ErrorCode.Ok), replyData);
            }
            if (xml != null)
            {
                xml.AppendEndTag(Command.GetRequest, type);
                xml.AppendEndTag(Command.GetRequest);
            }
        }
Esempio n. 4
0
        ///<summary>
        ///Handle set request.
        ///</summary>
        ///<returns>
        ///Reply to the client.
        ///</returns>
        public static void HandleSetRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            //Return error if connection is not established.
            if (xml == null && settings.Connected == ConnectionState.None && !settings.CanAccess())
            {
                replyData.Set(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                                                                         ServiceError.Service, (byte)Service.Unsupported));
                return;
            }
            // Get type.
            SetRequestType type = (SetRequestType)data.GetUInt8();
            // Get invoke ID and priority.
            byte invoke = data.GetUInt8();

            settings.UpdateInvokeId(invoke);
            // SetRequest normal or Set Request With First Data Block
            GXDLMSLNParameters p = new GXDLMSLNParameters(null, settings, invoke, Command.SetResponse, (byte)type, null, null, 0);

            if (xml != null)
            {
                xml.AppendStartTag(Command.SetRequest);
                xml.AppendStartTag(Command.SetRequest, type);
                //InvokeIdAndPriority
                xml.AppendLine(TranslatorTags.InvokeId, "Value", xml.IntegerToHex(invoke, 2));
            }
            switch (type)
            {
            case SetRequestType.Normal:
            case SetRequestType.FirstDataBlock:
                HandleSetRequestNormal(settings, server, data, (byte)type, p, replyData, xml);
                break;

            case SetRequestType.WithDataBlock:
                HanleSetRequestWithDataBlock(settings, server, data, p, replyData, xml);
                break;

            case SetRequestType.WithList:
                HanleSetRequestWithList(settings, invoke, server, data, p, replyData, xml);
                break;

            default:
                System.Diagnostics.Debug.WriteLine("HandleSetRequest failed. Unknown command.");
                settings.ResetBlockIndex();
                p.status = (byte)ErrorCode.HardwareFault;
                break;
            }
            if (xml != null)
            {
                xml.AppendEndTag(Command.SetRequest, type);
                xml.AppendEndTag(Command.SetRequest);
                return;
            }
            GXDLMS.GetLNPdu(p, replyData);
        }
Esempio n. 5
0
        private static void HandleReadDataBlockAccess(
            GXDLMSSettings settings, GXDLMSServer server,
            Command command, GXByteBuffer data, int cnt, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            GXByteBuffer bb          = new GXByteBuffer();
            byte         lastBlock   = data.GetUInt8();
            UInt16       blockNumber = data.GetUInt16();

            if (xml != null)
            {
                if (command == Command.WriteResponse)
                {
                    xml.AppendStartTag(TranslatorTags.WriteDataBlockAccess);
                }
                else
                {
                    xml.AppendStartTag(TranslatorTags.ReadDataBlockAccess);
                }
                xml.AppendLine("<LastBlock Value=\"" + xml.IntegerToHex(lastBlock, 2) + "\" />");
                xml.AppendLine("<BlockNumber Value=\"" + xml.IntegerToHex(blockNumber, 4) + "\" />");
                if (command == Command.WriteResponse)
                {
                    xml.AppendEndTag(TranslatorTags.WriteDataBlockAccess);
                }
                else
                {
                    xml.AppendEndTag(TranslatorTags.ReadDataBlockAccess);
                }
                return;
            }
            if (blockNumber != settings.BlockIndex)
            {
                Debug.WriteLine("handleReadRequest failed. Invalid block number. " + settings.BlockIndex + "/" + blockNumber);
                bb.SetUInt8(ErrorCode.DataBlockNumberInvalid);
                GXDLMS.GetSNPdu(new GXDLMSSNParameters(settings, command, 1, (byte)SingleReadResponse.DataAccessError, bb, null), replyData);
                settings.ResetBlockIndex();
                return;
            }
            int  count = 1;
            byte type  = (byte)DataType.OctetString;

            if (command == Command.WriteResponse)
            {
                count = GXCommon.GetObjectCount(data);
                type  = data.GetUInt8();
            }
            int size     = GXCommon.GetObjectCount(data);
            int realSize = data.Size - data.Position;

            if (count != 1 || type != (byte)DataType.OctetString || size != realSize)
            {
                Debug.WriteLine("handleGetRequest failed. Invalid block size.");
                bb.SetUInt8(ErrorCode.DataBlockUnavailable);
                GXDLMS.GetSNPdu(new GXDLMSSNParameters(settings, command, cnt, (byte)SingleReadResponse.DataAccessError, bb, null), replyData);
                settings.ResetBlockIndex();
                return;
            }
            if (server.transaction == null)
            {
                server.transaction = new GXDLMSLongTransaction(null, command, data);
            }
            else
            {
                server.transaction.data.Set(data);
            }
            if (lastBlock == 0)
            {
                bb.SetUInt16(blockNumber);
                settings.IncreaseBlockIndex();
                if (command == Command.ReadResponse)
                {
                    type = (byte)SingleReadResponse.BlockNumber;
                }
                else
                {
                    type = (byte)SingleWriteResponse.BlockNumber;
                }
                GXDLMS.GetSNPdu(new GXDLMSSNParameters(settings, command, cnt, type, null, bb), replyData);
                return;
            }
            else
            {
                if (server.transaction != null)
                {
                    data.Size = 0;
                    data.Set(server.transaction.data);
                    server.transaction = null;
                }
                if (command == Command.ReadResponse)
                {
                    HandleReadRequest(settings, server, data, replyData, xml);
                }
                else
                {
                    HandleWriteRequest(settings, server, data, replyData, xml);
                }
                settings.ResetBlockIndex();
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Handle read Block in blocks.
        /// </summary>
        /// <param name="data">Received data.</param>
        private static void HandleReadBlockNumberAccess(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            UInt16 blockNumber = data.GetUInt16();

            if (xml != null)
            {
                xml.AppendStartTag(Command.ReadRequest, VariableAccessSpecification.BlockNumberAccess);
                xml.AppendLine("<BlockNumber Value=\"" + xml.IntegerToHex(blockNumber, 4) + "\" />");
                xml.AppendEndTag(Command.ReadRequest, VariableAccessSpecification.BlockNumberAccess);
                return;
            }

            if (blockNumber != settings.BlockIndex)
            {
                GXByteBuffer bb = new GXByteBuffer();
                Debug.WriteLine("handleReadRequest failed. Invalid block number. " + settings.BlockIndex + "/" + blockNumber);
                bb.SetUInt8(ErrorCode.DataBlockNumberInvalid);
                GXDLMS.GetSNPdu(new GXDLMSSNParameters(settings, Command.ReadResponse, 1, (byte)SingleReadResponse.DataAccessError, bb, null), replyData);
                settings.ResetBlockIndex();
                return;
            }
            if (settings.Index != settings.Count && server.transaction.data.Size < settings.MaxPduSize)
            {
                List <ValueEventArgs> reads   = new List <ValueEventArgs>();
                List <ValueEventArgs> actions = new List <ValueEventArgs>();
                foreach (ValueEventArgs it in server.transaction.targets)
                {
                    if (it.action)
                    {
                        actions.Add(it);
                    }
                    else
                    {
                        reads.Add(it);
                    }
                }
                if (reads.Count != 0)
                {
                    server.NotifyRead(reads.ToArray());
                }

                if (actions.Count != 0)
                {
                    server.NotifyAction(actions.ToArray());
                }
                GetReadData(settings, server.transaction.targets, server.transaction.data);
                if (reads.Count != 0)
                {
                    server.NotifyPostRead(reads.ToArray());
                }

                if (actions.Count != 0)
                {
                    server.NotifyPostAction(actions.ToArray());
                }
            }
            settings.IncreaseBlockIndex();
            GXDLMSSNParameters p = new GXDLMSSNParameters(settings, Command.ReadResponse, 1,
                                                          (byte)SingleReadResponse.DataBlockResult, null, server.transaction.data);

            p.multipleBlocks = true;
            GXDLMS.GetSNPdu(p, replyData);
            //If all data is sent.
            if (server.transaction.data.Size == server.transaction.data.Position)
            {
                server.transaction = null;
                settings.ResetBlockIndex();
            }
            else
            {
                server.transaction.data.Trim();
            }
        }
Esempio n. 7
0
        ///<summary>
        ///Handle set request.
        ///</summary>
        ///<returns>
        ///Reply to the client.
        ///</returns>
        private byte[][] HandleSetRequest()
        {
            ErrorCode    error = ErrorCode.Ok;
            GXByteBuffer data  = Reply.Data;
            GXDataInfo   info  = new GXDataInfo();
            GXByteBuffer bb    = new GXByteBuffer();
            // Get type.
            short type = data.GetUInt8();

            // Get invoke ID and priority.
            data.GetUInt8();
            // SetRequest normal
            if (type == 1)
            {
                Settings.ResetBlockIndex();
                ServerReply.Index = 0;
                // CI
                ObjectType ci = (ObjectType)data.GetUInt16();
                byte[]     ln = new byte[6];
                data.Get(ln);
                // Attribute index.
                int index = data.GetUInt8();
                // Get Access Selection.
                data.GetUInt8();
                object       value = GXCommon.GetData(data, info);
                GXDLMSObject obj   = Settings.Objects.FindByLN(ci, GXDLMSObject.ToLogicalName(ln));
                if (obj == null)
                {
                    obj = FindObject(ci, 0, GXDLMSObject.ToLogicalName(ln));
                }
                // If target is unknown.
                if (obj == null)
                {
                    Debug.WriteLine("Undefined object.");
                    // Device reports a undefined object.
                    error = ErrorCode.UndefinedObject;
                }
                else
                {
                    AccessMode am = obj.GetAccess(index);
                    // If write is denied.
                    if (am != AccessMode.Write && am != AccessMode.ReadWrite)
                    {
                        Debug.WriteLine("Read Write denied.");
                        error = ErrorCode.ReadWriteDenied;
                    }
                    else
                    {
                        try
                        {
                            if (value is byte[])
                            {
                                DataType dt = (obj as IGXDLMSBase).GetDataType(index);
                                if (dt != DataType.None)
                                {
                                    value = GXDLMSClient.ChangeType((byte[])value, dt);
                                }
                            }
                            ValueEventArgs e = new ValueEventArgs(obj, index, 0, null);
                            Write(e);
                            if (!e.Handled)
                            {
                                (obj as IGXDLMSBase).SetValue(Settings, index, value);
                            }
                        }
                        catch (Exception e)
                        {
                            Debug.WriteLine(e.Message);
                            error = ErrorCode.HardwareFault;
                        }
                    }
                }
            }
            else
            {
                Debug.WriteLine("handleSetRequest failed. Unknown command.");
                Settings.ResetBlockIndex();
                error = ErrorCode.HardwareFault;
            }
            return(GXDLMS.SplitPdu(Settings, Command.SetResponse, 1, bb, error, DateTime.MinValue)[0]);
        }
 private static void HandleReadDataBlockAccess(
     GXDLMSSettings settings, GXDLMSServer server,
     Command command, GXByteBuffer data, int cnt, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
 {
     GXByteBuffer bb = new GXByteBuffer();
     byte lastBlock = data.GetUInt8();
     UInt16 blockNumber = data.GetUInt16();
     if (xml != null)
     {
         if (command == Command.WriteResponse)
         {
             xml.AppendStartTag(TranslatorTags.WriteDataBlockAccess);
         }
         else
         {
             xml.AppendStartTag(TranslatorTags.ReadDataBlockAccess);
         }
         xml.AppendLine("<LastBlock Value=\"" + xml.IntegerToHex(lastBlock, 2) + "\" />");
         xml.AppendLine("<BlockNumber Value=\"" + xml.IntegerToHex(blockNumber, 4) + "\" />");
         if (command == Command.WriteResponse)
         {
             xml.AppendEndTag(TranslatorTags.WriteDataBlockAccess);
         }
         else
         {
             xml.AppendEndTag(TranslatorTags.ReadDataBlockAccess);
         }
         return;
     }
     if (blockNumber != settings.BlockIndex)
     {
         Debug.WriteLine("handleReadRequest failed. Invalid block number. " + settings.BlockIndex + "/" + blockNumber);
         bb.SetUInt8(ErrorCode.DataBlockNumberInvalid);
         GXDLMS.GetSNPdu(new GXDLMSSNParameters(settings, command, 1, (byte)SingleReadResponse.DataAccessError, bb, null), replyData);
         settings.ResetBlockIndex();
         return;
     }
     int count = 1;
     byte type = (byte)DataType.OctetString;
     if (command == Command.WriteResponse)
     {
         count = GXCommon.GetObjectCount(data);
         type = data.GetUInt8();
     }
     int size = GXCommon.GetObjectCount(data);
     int realSize = data.Size - data.Position;
     if (count != 1 || type != (byte)DataType.OctetString || size != realSize)
     {
         Debug.WriteLine("handleGetRequest failed. Invalid block size.");
         bb.SetUInt8(ErrorCode.DataBlockUnavailable);
         GXDLMS.GetSNPdu(new GXDLMSSNParameters(settings, command, cnt, (byte)SingleReadResponse.DataAccessError, bb, null), replyData);
         settings.ResetBlockIndex();
         return;
     }
     if (server.transaction == null)
     {
         server.transaction = new GXDLMSLongTransaction(null, command, data);
     }
     else
     {
         server.transaction.data.Set(data);
     }
     if (lastBlock == 0)
     {
         bb.SetUInt16(blockNumber);
         settings.IncreaseBlockIndex();
         if (command == Command.ReadResponse)
         {
             type = (byte)SingleReadResponse.BlockNumber;
         }
         else
         {
             type = (byte)SingleWriteResponse.BlockNumber;
         }
         GXDLMS.GetSNPdu(new GXDLMSSNParameters(settings, command, cnt, type, null, bb), replyData);
         return;
     }
     else
     {
         if (server.transaction != null)
         {
             data.Size = 0;
             data.Set(server.transaction.data);
             server.transaction = null;
         }
         if (command == Command.ReadResponse)
         {
             HandleReadRequest(settings, server, data, replyData, xml);
         }
         else
         {
             HandleWriteRequest(settings, server, data, replyData, xml);
         }
         settings.ResetBlockIndex();
     }
 }
Esempio n. 9
0
        /// <summary>
        /// Handle get request normal command.
        /// </summary>
        /// <param name="data">Received data.</param>
        private static void GetRequestNormal(GXDLMSSettings settings, byte invokeID, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            ValueEventArgs e  = null;
            GXByteBuffer   bb = new GXByteBuffer();
            // Get type.
            ErrorCode status = ErrorCode.Ok;

            settings.Count = settings.Index = 0;
            settings.ResetBlockIndex();
            // CI
            ObjectType ci = (ObjectType)data.GetUInt16();

            byte[] ln = new byte[6];
            data.Get(ln);
            // Attribute Id
            byte attributeIndex = data.GetUInt8();

            // AccessSelection
            byte       selection  = data.GetUInt8();
            byte       selector   = 0;
            object     parameters = null;
            GXDataInfo info       = new GXDataInfo();

            if (selection != 0)
            {
                selector = data.GetUInt8();
            }
            if (xml != null)
            {
                AppendAttributeDescriptor(xml, (int)ci, ln, attributeIndex);
                if (selection != 0)
                {
                    info.xml = xml;
                    xml.AppendStartTag(TranslatorTags.AccessSelection);
                    xml.AppendLine(TranslatorTags.AccessSelector, "Value", xml.IntegerToHex(selector, 2));
                    xml.AppendStartTag(TranslatorTags.AccessParameters);
                    GXCommon.GetData(settings, data, info);
                    xml.AppendEndTag(TranslatorTags.AccessParameters);
                    xml.AppendEndTag(TranslatorTags.AccessSelection);
                }
                return;
            }
            if (selection != 0)
            {
                parameters = GXCommon.GetData(settings, data, info);
            }

            GXDLMSObject obj = settings.Objects.FindByLN(ci, GXCommon.ToLogicalName(ln));

            if (obj == null)
            {
                obj = server.NotifyFindObject(ci, 0, GXCommon.ToLogicalName(ln));
            }
            e          = new ValueEventArgs(server, obj, attributeIndex, selector, parameters);
            e.InvokeId = invokeID;
            if (obj == null)
            {
                // "Access Error : Device reports a undefined object."
                status = ErrorCode.UndefinedObject;
            }
            else
            {
                if (server.NotifyGetAttributeAccess(e) == AccessMode.NoAccess)
                {
                    //Read Write denied.
                    status = ErrorCode.ReadWriteDenied;
                }
                else
                {
                    if (e.Target is GXDLMSProfileGeneric && attributeIndex == 2)
                    {
                        e.RowToPdu = GXDLMS.RowsToPdu(settings, (GXDLMSProfileGeneric)e.Target);
                    }
                    object value;
                    server.NotifyRead(new ValueEventArgs[] { e });
                    if (e.Handled)
                    {
                        value = e.Value;
                    }
                    else
                    {
                        settings.Count = e.RowEndIndex - e.RowBeginIndex;
                        value          = (obj as IGXDLMSBase).GetValue(settings, e);
                    }
                    if (e.ByteArray)
                    {
                        bb.Set((byte[])value);
                    }
                    else
                    {
                        GXDLMS.AppendData(settings, obj, attributeIndex, bb, value);
                    }
                    server.NotifyPostRead(new ValueEventArgs[] { e });
                    status = e.Error;
                }
            }
            GXDLMSLNParameters p = new GXDLMSLNParameters(null, settings, e.InvokeId, Command.GetResponse, 1, null, bb, (byte)status);

            GXDLMS.GetLNPdu(p, replyData);
            if (settings.Count != settings.Index || bb.Size != bb.Position)
            {
                server.transaction = new GXDLMSLongTransaction(new ValueEventArgs[] { e }, Command.GetRequest, bb);
            }
        }
        /// <summary>
        /// Handle get request normal command.
        /// </summary>
        /// <param name="data">Received data.</param>
        private static void GetRequestNormal(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            ValueEventArgs e = null;
            GXByteBuffer bb = new GXByteBuffer();
            // Get type.
            ErrorCode status = ErrorCode.Ok;

            settings.Count = settings.Index = 0;
            settings.ResetBlockIndex();
            // CI
            ObjectType ci = (ObjectType)data.GetUInt16();
            byte[] ln = new byte[6];
            data.Get(ln);
            // Attribute Id
            byte attributeIndex = data.GetUInt8();

            // AccessSelection
            byte selection = data.GetUInt8();
            byte selector = 0;
            object parameters = null;
            GXDataInfo info = new GXDataInfo();
            if (selection != 0)
            {
                selector = data.GetUInt8();
            }
            if (xml != null)
            {
                AppendAttributeDescriptor(xml, (int)ci, ln, attributeIndex);
                if (selection != 0)
                {
                    info.xml = xml;
                    xml.AppendStartTag(TranslatorTags.AccessSelection);
                    xml.AppendLine(TranslatorTags.AccessSelector, "Value", xml.IntegerToHex(selector, 2));
                    xml.AppendStartTag(TranslatorTags.AccessParameters);
                    GXCommon.GetData(settings, data, info);
                    xml.AppendEndTag(TranslatorTags.AccessParameters);
                    xml.AppendEndTag(TranslatorTags.AccessSelection);
                }
                return;
            }
            if (selection != 0)
            {
                parameters = GXCommon.GetData(settings, data, info);
            }

            GXDLMSObject obj = settings.Objects.FindByLN(ci, GXDLMSObject.ToLogicalName(ln));
            if (obj == null)
            {
                obj = server.NotifyFindObject(ci, 0, GXDLMSObject.ToLogicalName(ln));
            }
            if (obj == null)
            {
                // "Access Error : Device reports a undefined object."
                status = ErrorCode.UndefinedObject;
            }
            else
            {
                if (obj.GetAccess(attributeIndex) == AccessMode.NoAccess)
                {
                    //Read Write denied.
                    status = ErrorCode.ReadWriteDenied;
                }
                else
                {
                    e = new ValueEventArgs(settings, obj, attributeIndex, selector, parameters);
                    server.NotifyRead(new ValueEventArgs[] { e });
                    object value;
                    if (e.Handled)
                    {
                        value = e.Value;
                    }
                    else
                    {
                        value = (obj as IGXDLMSBase).GetValue(settings, e);
                    }
                    GXDLMS.AppendData(settings, obj, attributeIndex, bb, value);
                    status = e.Error;
                }
            }
            GXDLMS.GetLNPdu(new GXDLMSLNParameters(settings, Command.GetResponse, 1, null, bb, (byte)status), replyData);
            if (settings.Count != settings.Index || bb.Size != bb.Position)
            {
                server.transaction = new GXDLMSLongTransaction(new ValueEventArgs[] { e }, Command.GetRequest, bb);
            }
        }
 ///<summary>
 ///Handle set request.
 ///</summary>
 ///<returns>
 ///Reply to the client.
 ///</returns>
 public static void HandleSetRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
 {
     //Return error if connection is not established.
     if (xml == null && !settings.Connected)
     {
         replyData.Set(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                       ServiceError.Service, (byte)Service.Unsupported));
         return;
     }
     // Get type.
     SetRequestType type = (SetRequestType)data.GetUInt8();
     // Get invoke ID and priority.
     byte invoke = data.GetUInt8();
     // SetRequest normal or Set Request With First Data Block
     GXDLMSLNParameters p = new GXDLMSLNParameters(settings, Command.SetResponse, (byte)type, null, null, 0);
     if (xml != null)
     {
         xml.AppendStartTag(Command.SetRequest);
         xml.AppendStartTag(Command.SetRequest, type);
         //InvokeIdAndPriority
         xml.AppendLine(TranslatorTags.InvokeId, "Value", xml.IntegerToHex(invoke, 2));
     }
     switch (type)
     {
         case SetRequestType.Normal:
         case SetRequestType.FirstDataBlock:
             HandleSetRequestNormal(settings, server, data, (byte)type, p, replyData, xml);
             break;
         case SetRequestType.WithDataBlock:
             HanleSetRequestWithDataBlock(settings, server, data, p, replyData, xml);
             break;
         default:
             System.Diagnostics.Debug.WriteLine("HandleSetRequest failed. Unknown command.");
             settings.ResetBlockIndex();
             p.status = (byte)ErrorCode.HardwareFault;
             break;
     }
     if (xml != null)
     {
         xml.AppendEndTag(Command.SetRequest, type);
         xml.AppendEndTag(Command.SetRequest);
         return;
     }
     GXDLMS.GetLNPdu(p, replyData);
 }
Esempio n. 12
0
        /// <summary>
        /// Get value from the data.
        /// </summary>
        /// <param name="settings">DLMS settings.</param>
        /// <param name="reply"> Received data.</param>
        internal static void GetValueFromData(GXDLMSSettings settings, GXReplyData reply)
        {
            GXByteBuffer data = reply.Data;
            GXDataInfo info = new GXDataInfo();
            if (reply.Value is Object[])
            {
                info.Type = DataType.Array;
                info.Count = reply.TotalCount;
                info.Index = reply.Count;
            }
            int index = data.Position;
            data.Position = reply.ReadPosition;
            try
            {
                Object value = GXCommon.GetData(settings, data, info);
                if (value != null)
                {
                    lock (reply)
                    {
                        // If new data.
                        if (!(value is Object[]))
                        {
                            reply.DataType = info.Type;
                            reply.Value = value;
                            reply.TotalCount = 0;
                            reply.ReadPosition = data.Position;
                        }
                        else
                        {
                            if (((Object[])value).Length != 0)
                            {
                                if (reply.Value == null)
                                {
                                    reply.Value = value;
                                }
                                else
                                {
                                    // Add items to collection.
                                    List<Object> list = new List<Object>();
                                    list.AddRange((Object[])reply.Value);
                                    list.AddRange((Object[])value);
                                    reply.Value = list.ToArray();
                                }
                            }
                            reply.ReadPosition = data.Position;
                            // Element count.
                            reply.TotalCount = info.Count;
                        }
                    }
                }
                else if (info.Complete
                         && reply.Command == Command.DataNotification)
                {
                    // If last item is null. This is a special case.
                    reply.ReadPosition = data.Position;
                }
            }
            finally
            {
                data.Position = index;
            }

            // If last data frame of the data block is read.
            if (reply.Command != Command.DataNotification
                    && info.Complete && reply.MoreData == RequestTypes.None)
            {
                // If all blocks are read.
                settings.ResetBlockIndex();
                data.Position = 0;
            }
        }
Esempio n. 13
0
        /// <summary>
        /// Handle get response and get data from block and/or update error status.
        /// </summary>
        /// <param name="settings">DLMS settings.</param>
        /// <param name="reply">Received data from the client.</param>
        /// <param name="index">Block index number.</param>
        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;
        }
Esempio n. 14
0
 /// <summary>
 /// Handle read response data block result.
 /// </summary>
 /// <param name="settings">DLMS settings.</param>
 /// <param name="reply">Received reply.</param>
 /// <param name="index">Starting index.</param>
 static bool ReadResponseDataBlockResult(GXDLMSSettings settings, GXReplyData reply, int index)
 {
     reply.Error = 0;
     byte lastBlock = reply.Data.GetUInt8();
     // Get Block number.
     UInt32 number = reply.Data.GetUInt16();
     int blockLength = GXCommon.GetObjectCount(reply.Data);
     // Check block length when all data is received.
     if ((reply.MoreData & RequestTypes.Frame) == 0)
     {
         if (blockLength != reply.Data.Size - reply.Data.Position)
         {
             throw new OutOfMemoryException();
         }
         reply.Command = Command.None;
         if (reply.Xml != null)
         {
             reply.Data.Trim();
             reply.Xml.AppendStartTag(Command.ReadResponse, SingleReadResponse.DataBlockResult);
             reply.Xml.AppendLine(TranslatorTags.LastBlock, "Value", reply.Xml.IntegerToHex(lastBlock, 2));
             reply.Xml.AppendLine(TranslatorTags.BlockNumber, "Value", reply.Xml.IntegerToHex(number, 4));
             reply.Xml.AppendLine(TranslatorTags.RawData, "Value", GXCommon.ToHex(reply.Data.Data, false, 0, reply.Data.Size));
             reply.Xml.AppendEndTag(Command.ReadResponse, SingleReadResponse.DataBlockResult);
             return false;
         }
     }
     GetDataFromBlock(reply.Data, index);
     // Is not Last block.
     if (lastBlock == 0)
     {
         reply.MoreData = (RequestTypes)(reply.MoreData | RequestTypes.DataBlock);
     }
     else
     {
         reply.MoreData = (RequestTypes)(reply.MoreData & ~RequestTypes.DataBlock);
     }
     //If meter's block index is zero based.
     if (number != 1 && settings.BlockIndex == 1)
     {
         settings.BlockIndex = (uint)number;
     }
     UInt32 expectedIndex = settings.BlockIndex;
     if (number != expectedIndex)
     {
         throw new ArgumentException(
             "Invalid Block number. It is " + number
             + " and it should be " + expectedIndex + ".");
     }
     // If last packet and data is not try to peek.
     if (reply.MoreData == RequestTypes.None)
     {
         reply.Data.Position = 0;
         HandleReadResponse(settings, reply, index);
         settings.ResetBlockIndex();
     }
     return true;
 }
 private static void ReturnSNError(GXDLMSSettings settings, GXDLMSServer server, Command cmd, ErrorCode error, GXByteBuffer replyData)
 {
     GXByteBuffer bb = new GXByteBuffer();
     bb.SetUInt8(error);
     GXDLMS.GetSNPdu(new GXDLMSSNParameters(settings, cmd, 1, (byte)SingleReadResponse.DataAccessError, bb, null), replyData);
     settings.ResetBlockIndex();
 }
        public static void HandleGetRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            //Return error if connection is not established.
            if (xml == null && !settings.Connected)
            {
                replyData.Set(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                              ServiceError.Service, (byte)Service.Unsupported));
                return;
            }

            GetCommandType type = (GetCommandType)data.GetUInt8();
            // Get invoke ID and priority.
            byte invokeID = data.GetUInt8();
            if (xml != null)
            {
                xml.AppendStartTag(Command.GetRequest);
                xml.AppendStartTag(Command.GetRequest, type);
                xml.AppendLine(TranslatorTags.InvokeId, "Value", xml.IntegerToHex(invokeID, 2));
            }

            // GetRequest normal
            if (type == GetCommandType.Normal)
            {
                GetRequestNormal(settings, server, data, replyData, xml);
            }
            else if (type == GetCommandType.NextDataBlock)
            {
                // Get request for next data block
                GetRequestNextDataBlock(settings, server, data, replyData, xml);
            }
            else if (type == GetCommandType.WithList)
            {
                // Get request with a list.
                GetRequestWithList(settings, server, data, replyData, xml);
            }
            else
            {
                Debug.WriteLine("HandleGetRequest failed. Invalid command type.");
                settings.ResetBlockIndex();
                GXByteBuffer bb = new GXByteBuffer();
                // Access Error : Device reports a hardware fault.
                bb.SetUInt8((byte)ErrorCode.HardwareFault);
                GXDLMS.GetLNPdu(new GXDLMSLNParameters(settings, Command.GetResponse, (byte)type, null, bb, (byte)ErrorCode.Ok), replyData);
            }
            if (xml != null)
            {
                xml.AppendEndTag(Command.GetRequest, type);
                xml.AppendEndTag(Command.GetRequest);
            }
        }
        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;
                    }
                }
            }
        }
Esempio n. 18
0
        /// <summary>
        /// Handle get request next data block command.
        /// </summary>
        /// <param name="data">Received data.</param>
        internal static void GetRequestNextDataBlock(GXDLMSSettings settings, byte invokeID, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml, bool streaming)
        {
            GXByteBuffer bb = new GXByteBuffer();

            if (!streaming)
            {
                UInt32 index;
                // Get block index.
                index = data.GetUInt32();
                if (xml != null)
                {
                    xml.AppendLine(TranslatorTags.BlockNumber, null, xml.IntegerToHex(index, 8));
                    return;
                }
                if (index != settings.BlockIndex)
                {
                    Debug.WriteLine("handleGetRequest failed. Invalid block number. " + settings.BlockIndex + "/" + index);
                    GXDLMS.GetLNPdu(new GXDLMSLNParameters(null, settings, 0, Command.GetResponse, 2, null, bb, (byte)ErrorCode.DataBlockNumberInvalid), replyData);
                    return;
                }
            }
            settings.IncreaseBlockIndex();
            GXDLMSLNParameters p = new GXDLMSLNParameters(null, settings, invokeID, streaming ? Command.GeneralBlockTransfer : Command.GetResponse, 2, null, bb, (byte)ErrorCode.Ok);

            p.Streaming  = streaming;
            p.WindowSize = settings.WindowSize;
            //If transaction is not in progress.
            if (server.transaction == null)
            {
                p.status = (byte)ErrorCode.NoLongGetOrReadInProgress;
            }
            else
            {
                bb.Set(server.transaction.data);
                bool moreData = settings.Index != settings.Count;
                if (moreData)
                {
                    //If there is multiple blocks on the buffer.
                    //This might happen when Max PDU size is very small.
                    if (bb.Size < settings.MaxPduSize)
                    {
                        foreach (ValueEventArgs arg in server.transaction.targets)
                        {
                            object value;
                            server.NotifyRead(new ValueEventArgs[] { arg });
                            if (arg.Handled)
                            {
                                value = arg.Value;
                            }
                            else
                            {
                                value = (arg.Target as IGXDLMSBase).GetValue(settings, arg);
                            }
                            //Add data.
                            if (arg.ByteArray)
                            {
                                bb.Set((byte[])value);
                            }
                            else
                            {
                                GXDLMS.AppendData(settings, arg.Target, arg.Index, bb, value);
                            }
                        }
                        moreData = settings.Index != settings.Count;
                    }
                }
                p.multipleBlocks = true;
                GXDLMS.GetLNPdu(p, replyData);
                if (moreData || bb.Size - bb.Position != 0)
                {
                    server.transaction.data = bb;
                }
                else
                {
                    server.transaction = null;
                    settings.ResetBlockIndex();
                }
            }
        }
 private static void HanleSetRequestWithDataBlock(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXDLMSLNParameters p, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
 {
     GXDataInfo reply = new GXDataInfo();
     p.multipleBlocks = data.GetUInt8() == 0;
     UInt32 blockNumber = data.GetUInt32();
     if (blockNumber != settings.BlockIndex)
     {
         Debug.WriteLine("HanleSetRequestWithDataBlock failed. Invalid block number. " + settings.BlockIndex + "/" + blockNumber);
         p.status = (byte)ErrorCode.DataBlockNumberInvalid;
     }
     else
     {
         int size = GXCommon.GetObjectCount(data);
         int realSize = data.Size - data.Position;
         if (size != realSize)
         {
             Debug.WriteLine("HanleSetRequestWithDataBlock failed. Invalid block size.");
             p.status = (byte)ErrorCode.DataBlockUnavailable;
         }
         server.transaction.data.Set(data);
         //If all data is received.
         if (!p.multipleBlocks)
         {
             try
             {
                 object value = GXCommon.GetData(settings, server.transaction.data, reply);
                 if (value is byte[])
                 {
                     DataType dt = (server.transaction.targets[0].Target as IGXDLMSBase).GetDataType(server.transaction.targets[0].Index);
                     if (dt != DataType.None && dt != DataType.OctetString)
                     {
                         value = GXDLMSClient.ChangeType((byte[])value, dt);
                     }
                 }
                 server.transaction.targets[0].Value = value;
                 server.NotifyWrite(server.transaction.targets);
                 if (!server.transaction.targets[0].Handled && !p.multipleBlocks)
                 {
                     (server.transaction.targets[0].Target as IGXDLMSBase).SetValue(settings, server.transaction.targets[0]);
                 }
             }
             catch (Exception)
             {
                 p.status = (byte)ErrorCode.HardwareFault;
             }
             finally
             {
                 server.transaction = null;
             }
             settings.ResetBlockIndex();
         }
     }
     p.multipleBlocks = true;
 }
Esempio n. 20
0
        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 (type == 2)
            {
                byte lastBlock = data.GetUInt8();
                p.multipleBlocks = lastBlock == 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 (xml != null)
                {
                    AppendAttributeDescriptor(xml, (int)ci, ln, index);
                    xml.AppendStartTag(TranslatorTags.DataBlock);
                    xml.AppendLine(TranslatorTags.LastBlock, "Value", xml.IntegerToHex(lastBlock, 2));
                    xml.AppendLine(TranslatorTags.BlockNumber, "Value", xml.IntegerToHex(blockNumber, 8));
                    xml.AppendLine(TranslatorTags.RawData, "Value", data.RemainingHexString(false));
                    xml.AppendEndTag(TranslatorTags.DataBlock);
                }
                return;
            }
            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 (!p.multipleBlocks)
            {
                settings.ResetBlockIndex();
                value = GXCommon.GetData(settings, data, reply);
            }

            GXDLMSObject obj = settings.Objects.FindByLN(ci, GXCommon.ToLogicalName(ln));

            if (obj == null)
            {
                obj = server.NotifyFindObject(ci, 0, GXCommon.ToLogicalName(ln));
            }
            // If target is unknown.
            if (obj == null)
            {
                // Device reports a undefined object.
                p.status = (byte)ErrorCode.UndefinedObject;
            }
            else
            {
                ValueEventArgs e = new ValueEventArgs(server, obj, index, 0, null);
                e.InvokeId = p.InvokeId;
                AccessMode am = server.NotifyGetAttributeAccess(e);
                // 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 && dt != DataType.Structure)
                            {
                                value = GXDLMSClient.ChangeType((byte[])value, dt, settings.UseUtc2NormalTime);
                            }
                        }
                        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);
                            server.NotifyPostWrite(list);
                            if (e.Error != 0)
                            {
                                p.status = (byte)e.Error;
                            }
                        }
                        p.InvokeId = e.InvokeId;
                    }
                    catch (Exception)
                    {
                        p.status = (byte)ErrorCode.HardwareFault;
                    }
                }
            }
        }
        /// <summary>
        /// Handle read Block in blocks.
        /// </summary>
        /// <param name="data">Received data.</param>
        private static void HandleReadBlockNumberAccess(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            UInt16 blockNumber = data.GetUInt16();
            if (xml != null)
            {
                xml.AppendStartTag(Command.ReadRequest, VariableAccessSpecification.BlockNumberAccess);
                xml.AppendLine("<BlockNumber Value=\"" + xml.IntegerToHex(blockNumber, 4) + "\" />");
                xml.AppendEndTag(Command.ReadRequest, VariableAccessSpecification.BlockNumberAccess);
                return;
            }

            if (blockNumber != settings.BlockIndex)
            {
                GXByteBuffer bb = new GXByteBuffer();
                Debug.WriteLine("handleReadRequest failed. Invalid block number. " + settings.BlockIndex + "/" + blockNumber);
                bb.SetUInt8(ErrorCode.DataBlockNumberInvalid);
                GXDLMS.GetSNPdu(new GXDLMSSNParameters(settings, Command.ReadResponse, 1, (byte)SingleReadResponse.DataAccessError, bb, null), replyData);
                settings.ResetBlockIndex();
                return;
            }
            if (settings.Index != settings.Count && server.transaction.data.Size < settings.MaxPduSize)
            {
                List<ValueEventArgs> reads = new List<ValueEventArgs>();
                List<ValueEventArgs> actions = new List<ValueEventArgs>();
                foreach (ValueEventArgs it in server.transaction.targets)
                {
                    if (it.action)
                    {
                        actions.Add(it);
                    }
                    else
                    {
                        reads.Add(it);
                    }
                }
                if (reads.Count != 0)
                {
                    server.NotifyRead(reads.ToArray());
                }

                if (actions.Count != 0)
                {
                    server.NotifyAction(actions.ToArray());
                }
                GetReadData(settings, server.transaction.targets, server.transaction.data);
            }
            settings.IncreaseBlockIndex();
            GXDLMSSNParameters p = new GXDLMSSNParameters(settings, Command.ReadResponse, 1,
                    (byte)SingleReadResponse.DataBlockResult, null, server.transaction.data);
            p.multipleBlocks = true;
            GXDLMS.GetSNPdu(p, replyData);
            //If all data is sent.
            if (server.transaction.data.Size == server.transaction.data.Position)
            {
                server.transaction = null;
                settings.ResetBlockIndex();
            }
            else
            {
                server.transaction.data.Trim();
            }
        }