GetUInt8() public method

Get UInt8 value from byte array from the current position and then increments the position.
public GetUInt8 ( ) : byte
return byte
Esempio n. 1
0
        /// <summary>
        /// Parse discover reply.
        /// </summary>
        /// <param name="value"></param>
        /// <returns>Array of system titles and alarm descriptor error code</returns>
        public List <GXDLMSPlcMeterInfo> ParseDiscover(GXByteBuffer value, UInt16 sa, UInt16 da)
        {
            List <GXDLMSPlcMeterInfo> list = new List <GXDLMSPlcMeterInfo>();
            byte count = value.GetUInt8();

            for (int pos = 0; pos != count; ++pos)
            {
                GXDLMSPlcMeterInfo info = new GXDLMSPlcMeterInfo();
                info.SourceAddress      = sa;
                info.DestinationAddress = da;
                //Get System title.
                if (settings.InterfaceType == Enums.InterfaceType.PlcHdlc)
                {
                    info.SystemTitle = new byte[8];
                }
                else
                {
                    info.SystemTitle = new byte[6];
                }
                value.Get(info.SystemTitle);
                // Alarm descriptor of the reporting system.
                // Alarm-Descriptor presence flag
                if (value.GetUInt8() != 0)
                {
                    //Alarm-Descriptor
                    info.AlarmDescriptor = value.GetUInt8();
                }
                list.Add(info);
            }
            return(list);
        }
Esempio n. 2
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. 3
0
        /// <summary>
        /// Parse discover request.
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public GXDLMSPlcRegister ParseDiscoverRequest(GXByteBuffer value)
        {
            GXDLMSPlcRegister ret = new GXDLMSPlcRegister();

            ret.ResponseProbability         = value.GetUInt8();
            ret.AllowedTimeSlots            = value.GetUInt16();
            ret.DiscoverReportInitialCredit = value.GetUInt8();
            ret.ICEqualCredit = value.GetUInt8();
            return(ret);
        }
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
        ///<summary>
        /// Handle action request.
        ///</summary>
        ///<param name="Reply">
        /// Received data from the client.
        ///</param>
        ///<returns>
        ///Reply.
        ///</returns>
        private byte[][] HandleMethodRequest()
        {
            GXByteBuffer data = Reply.Data;
            GXByteBuffer bb   = new GXByteBuffer();

            // Get type.
            data.GetUInt8();
            // Get invoke ID and priority.
            data.GetUInt8();
            // CI
            ObjectType ci = (ObjectType)data.GetUInt16();

            byte[] ln = new byte[6];
            data.Get(ln);
            // Attribute Id
            int id = data.GetUInt8();
            // Get parameters.
            object parameters = null;

            if (data.GetUInt8() != 0)
            {
                GXDataInfo info = new GXDataInfo();
                parameters = GXCommon.GetData(data, info);
            }
            GXDLMSObject obj = Settings.Objects.FindByLN(ci, GXDLMSObject.ToLogicalName(ln));

            if (obj == null)
            {
                obj = FindObject(ci, 0, GXDLMSObject.ToLogicalName(ln));
            }
            if (obj == null)
            {
                // Device reports a undefined object.
                addError(ErrorCode.UndefinedObject, bb);
                Debug.WriteLine("Undefined object.");
            }
            else
            {
                ValueEventArgs e = new ValueEventArgs(obj, id, 0, parameters);
                Action(e);
                if (e.Handled)
                {
                    bb.Add((obj as IGXDLMSBase).Invoke(Settings, id, parameters));
                }
                else
                {
                    bb.Add((obj as IGXDLMSBase).Invoke(Settings, id, parameters));
                }
            }
            return(GXDLMS.SplitPdu(Settings, Command.MethodResponse, 1, bb, ErrorCode.Ok, DateTime.MinValue)[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)
            {
                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);
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Parse register request.
        /// </summary>
        /// <param name="value"></param>
        /// <returns>System title mac address.</returns>
        public void ParseRegisterRequest(GXByteBuffer value)
        {
            //Get System title.
            byte[] st;
            if (settings.InterfaceType == Enums.InterfaceType.PlcHdlc)
            {
                st = new byte[8];
            }
            else
            {
                st = new byte[6];
            }
            value.Get(st);
            byte count = value.GetUInt8();

            for (int pos = 0; pos != count; ++pos)
            {
                //Get System title.
                if (settings.InterfaceType == Enums.InterfaceType.PlcHdlc)
                {
                    st = new byte[8];
                }
                else
                {
                    st = new byte[6];
                }
                value.Get(st);
                SystemTitle = st;
                //MAC address.
                MacSourceAddress = value.GetUInt16();
            }
        }
        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. 9
0
        /// <summary>
        /// Generate write reply.
        /// </summary>
        /// <param name="settings"></param>
        /// <param name="results"></param>
        /// <param name="replyData"></param>
        internal static void GenerateWriteResponse(GXDLMSSettings settings, GXByteBuffer results, GXByteBuffer replyData)
        {
            GXByteBuffer bb = new GXByteBuffer((UInt16)(2 * results.Size));
            byte         ret;

            for (int pos = 0; pos != results.Size; ++pos)
            {
                ret = results.GetUInt8(pos);
                // If meter returns error.
                if (ret != 0)
                {
                    bb.SetUInt8(1);
                }
                bb.SetUInt8(ret);
            }
            GXDLMSSNParameters p = new GXDLMSSNParameters(settings, Command.WriteResponse, results.Size, 0xFF, null, bb);

            GXDLMS.GetSNPdu(p, replyData);
        }
Esempio n. 10
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. 11
0
        byte IConvertible.ToByte(IFormatProvider provider)
        {
            GXByteBuffer bb = GetByteBuffer(Value, 1);

            return(bb.GetUInt8());
        }
Esempio n. 12
0
        private byte[][] HandleGetRequest()
        {
            ErrorCode    error = ErrorCode.Ok;
            GXByteBuffer data  = Reply.Data;
            GXByteBuffer bb    = new GXByteBuffer();
            short        type;
            int          index      = 0;
            object       parameters = null;

            // Get type.
            type = data.GetUInt8();
            // Get invoke ID and priority.
            data.GetUInt8();
            // GetRequest normal
            if (type == 1)
            {
                Settings.ResetBlockIndex();
                ServerReply.Index = 0;
                parameters        = null;
                // CI
                ObjectType ci = (ObjectType)data.GetUInt16();
                byte[]     ln = new byte[6];
                data.Get(ln);
                // Attribute Id
                int          attributeIndex = data.GetUInt8();
                GXDLMSObject obj            = Settings.Objects.FindByLN(ci, GXDLMSObject.ToLogicalName(ln));
                if (obj == null)
                {
                    obj = FindObject(ci, 0, GXDLMSObject.ToLogicalName(ln));
                }
                if (obj == null)
                {
                    // "Access Error : Device reports a undefined object."
                    error = ErrorCode.UndefinedObject;
                }
                else
                {
                    // AccessSelection
                    int selection = data.GetUInt8();
                    int selector  = 0;
                    if (selection != 0)
                    {
                        selector = data.GetUInt8();
                        GXDataInfo info = new GXDataInfo();
                        parameters = GXCommon.GetData(data, info);
                    }

                    ValueEventArgs e = new ValueEventArgs(obj, attributeIndex, 0, parameters);
                    Read(e);
                    object value;
                    if (e.Handled)
                    {
                        value = e.Value;
                    }
                    else
                    {
                        value = (obj as IGXDLMSBase).GetValue(Settings, attributeIndex, selector, parameters);
                    }
                    GXDLMS.AppedData(obj, attributeIndex, bb, value);
                }
                ServerReply.ReplyMessages = GXDLMS.SplitPdu(Settings, Command.GetResponse, 1, bb, error, DateTime.MinValue);
            }
            else if (type == 2)
            {
                // Get request for next data block
                // Get block index.
                index = (int)data.GetUInt32();
                if (index != Settings.BlockIndex + 1)
                {
                    Debug.WriteLine("handleGetRequest failed. Invalid block number. " + Settings.BlockIndex + "/" + index);
                    ServerReply.ReplyMessages = GXDLMS.SplitPdu(Settings, Command.GetResponse, 1, bb,
                                                                ErrorCode.DataBlockNumberInvalid, DateTime.MinValue);
                    index             = 0;
                    ServerReply.Index = index;
                }
                else
                {
                    Settings.IncreaseBlockIndex();
                    index             = ServerReply.Index + 1;
                    ServerReply.Index = index;
                }
            }
            else if (type == 3)
            {
                // Get request with a list.
                int cnt = GXCommon.GetObjectCount(data);
                GXCommon.SetObjectCount(cnt, bb);
                for (int pos = 0; pos != cnt; ++pos)
                {
                    ObjectType ci = (ObjectType)data.GetUInt16();
                    byte[]     ln = new byte[6];
                    data.Get(ln);
                    short attributeIndex = data.GetUInt8();

                    GXDLMSObject obj = Settings.Objects.FindByLN(ci, GXDLMSObject.ToLogicalName(ln));
                    if (obj == null)
                    {
                        obj = FindObject(ci, 0, GXDLMSObject.ToLogicalName(ln));
                    }
                    if (obj == null)
                    {
                        // "Access Error : Device reports a undefined object."
                        error = ErrorCode.UndefinedObject;
                    }
                    else
                    {
                        // AccessSelection
                        int selection = data.GetUInt8();
                        int selector  = 0;
                        if (selection != 0)
                        {
                            selector = data.GetUInt8();
                            GXDataInfo info = new GXDataInfo();
                            parameters = GXCommon.GetData(data, info);
                        }
                        try
                        {
                            ValueEventArgs e = new ValueEventArgs(obj, attributeIndex, 0, parameters);
                            Read(e);
                            object value;
                            if (e.Handled)
                            {
                                value = e.Value;
                            }
                            else
                            {
                                value = (obj as IGXDLMSBase).GetValue(Settings, attributeIndex, selector, parameters);
                            }
                            bb.SetUInt8(ErrorCode.Ok);
                            GXDLMS.AppedData(obj, attributeIndex, bb, value);
                        }
                        catch (Exception)
                        {
                            bb.SetUInt8(1);
                            bb.SetUInt8(ErrorCode.HardwareFault);
                        }
                    }
                }
                ServerReply.ReplyMessages = GXDLMS.SplitPdu(Settings, Command.GetResponse, 3, bb, error, DateTime.MinValue);
            }
            else
            {
                Debug.WriteLine("handleGetRequest failed. Invalid command type.");
                Settings.ResetBlockIndex();
                // Access Error : Device reports a hardware fault.
                ServerReply.ReplyMessages = GXDLMS.SplitPdu(Settings, Command.GetResponse, 1, bb, ErrorCode.HardwareFault, DateTime.MinValue);
            }
            ServerReply.Index = index;
            return(ServerReply.ReplyMessages[index]);
        }
Esempio n. 13
0
        public static bool GetData(GXDLMSSettings settings,
                                   GXByteBuffer reply, GXReplyData data)
        {
            byte frame = 0;
            // If DLMS frame is generated.
            if (settings.InterfaceType == InterfaceType.HDLC)
            {
                frame = GetHdlcData(settings.IsServer, settings, reply, data);
                data.FrameId = frame;
            }
            else if (settings.InterfaceType == InterfaceType.WRAPPER)
            {
                GetTcpData(settings, reply, data);
            }
            else if (settings.InterfaceType == InterfaceType.PDU)
            {
                data.PacketLength = reply.Size;
                data.IsComplete = true;
            }
            else
            {
                throw new ArgumentException("Invalid Interface type.");
            }
            // If all data is not read yet.
            if (!data.IsComplete)
            {
                return false;
            }

            GetDataFromFrame(reply, data);
            // If keepalive or get next frame request.
            if (data.Xml != null || (frame & 0x1) != 0)
            {
                if (settings.InterfaceType == InterfaceType.HDLC && data.Data.Size != 0)
                {
                    reply.Position += 3;
                    System.Diagnostics.Debug.Assert(reply.GetUInt8(reply.Position - 1) == 0x7e);
                }
                return true;
            }
            GetPdu(settings, data);

            if (data.Command == Command.DataNotification)
            {
                // Check is there more messages left.
                // This is Push message special case.
                if (reply.Position == reply.Size)
                {
                    reply.Clear();
                }
                else
                {
                    int cnt = reply.Size - reply.Position;
                    reply.Move(reply.Position, 0, cnt);
                    reply.Position = 0;
                }
            }
            return true;
        }
Esempio n. 14
0
 private void GetUa(GXByteBuffer data, GXDLMSTranslatorStructure xml)
 {
     xml.AppendStartTag(Command.Ua);
     data.GetUInt8(); // Skip FromatID
     data.GetUInt8(); // Skip Group ID.
     data.GetUInt8(); // Skip Group len
     Object val;
     while (data.Position < data.Size)
     {
         HDLCInfo id = (HDLCInfo)data.GetUInt8();
         short len = data.GetUInt8();
         switch (len)
         {
             case 1:
                 val = data.GetUInt8();
                 break;
             case 2:
                 val = data.GetUInt16();
                 break;
             case 4:
                 val = data.GetUInt32();
                 break;
             default:
                 throw new GXDLMSException("Invalid Exception.");
         }
         // RX / TX are delivered from the partner's point of view =>
         // reversed to ours
         switch (id)
         {
             case HDLCInfo.MaxInfoTX:
                 xml.AppendLine("<MaxInfoRX Value=\"" + val.ToString() + "\" />");
                 break;
             case HDLCInfo.MaxInfoRX:
                 xml.AppendLine("<MaxInfoTX Value=\"" + val.ToString() + "\" />");
                 break;
             case HDLCInfo.WindowSizeTX:
                 xml.AppendLine("<WindowSizeRX Value=\"" + val.ToString() + "\" />");
                 break;
             case HDLCInfo.WindowSizeRX:
                 xml.AppendLine("<WindowSizeTX Value=\"" + val.ToString() + "\" />");
                 break;
             default:
                 throw new GXDLMSException("Invalid UA response.");
         }
     }
     xml.AppendEndTag(Command.Ua);
 }
Esempio n. 15
0
        static byte GetHdlcData(bool server, GXDLMSSettings settings, GXByteBuffer reply, GXReplyData data)
        {
            short ch;
            int pos, packetStartID = reply.Position, frameLen = 0;
            int crc, crcRead;
            // If whole frame is not received yet.
            if (reply.Size - reply.Position < 9)
            {
                data.IsComplete = false;
                return 0;
            }
            data.IsComplete = true;
            // Find start of HDLC frame.
            for (pos = reply.Position; pos < reply.Size; ++pos)
            {
                ch = reply.GetUInt8();
                if (ch == GXCommon.HDLCFrameStartEnd)
                {
                    packetStartID = pos;
                    break;
                }
            }
            // Not a HDLC frame.
            // Sometimes meters can send some strange data between DLMS frames.
            if (reply.Position == reply.Size)
            {
                data.IsComplete = false;
                // Not enough data to parse;
                return 0;
            }
            byte frame = reply.GetUInt8();
            if ((frame & 0xF0) != 0xA0)
            {
                //If same strage data.
                return GetHdlcData(server, settings, reply, data);
            }
            // Check frame length.
            if ((frame & 0x7) != 0)
            {
                frameLen = ((frame & 0x7) << 8);
            }
            ch = reply.GetUInt8();
            // If not enough data.
            frameLen += ch;
            if (reply.Size - reply.Position + 1 < frameLen)
            {
                data.IsComplete = false;
                reply.Position = packetStartID;
                // Not enough data to parse;
                return 0;
            }
            int eopPos = frameLen + packetStartID + 1;
            ch = reply.GetUInt8(eopPos);
            if (ch != GXCommon.HDLCFrameStartEnd)
            {
                throw new GXDLMSException("Invalid data format.");
            }

            // Check addresses.
            if (!CheckHdlcAddress(server, settings, reply, eopPos))
            {
                //If echo,
                reply.Position = 1 + eopPos;
                return GetHdlcData(server, settings, reply, data);
            }

            // Is there more data available.
            if ((frame & 0x8) != 0)
            {
                data.MoreData = (RequestTypes)(data.MoreData | RequestTypes.Frame);
            }
            else
            {
                data.MoreData = (RequestTypes)(data.MoreData & ~RequestTypes.Frame);
            }
            // Get frame type.
            frame = reply.GetUInt8();
            if (data.Xml == null && !settings.CheckFrame(frame))
            {
                reply.Position = (eopPos + 1);
                return GetHdlcData(server, settings, reply, data);
            }
            // Check that header CRC is correct.
            crc = GXFCS16.CountFCS16(reply.Data, packetStartID + 1, reply.Position - packetStartID - 1);
            crcRead = reply.GetUInt16();
            if (crc != crcRead)
            {
                throw new Exception("Wrong CRC.");
            }
            // Check that packet CRC match only if there is a data part.
            if (reply.Position != packetStartID + frameLen + 1)
            {
                crc = GXFCS16.CountFCS16(reply.Data, packetStartID + 1,
                                         frameLen - 2);
                crcRead = reply.GetUInt16(packetStartID + frameLen - 1);
                if (crc != crcRead)
                {
                    throw new Exception("Wrong CRC.");
                }
                // Remove CRC and EOP from packet length.
                data.PacketLength = eopPos - 2;
            }
            else
            {
                data.PacketLength = reply.Position + 1;
            }

            if ((frame & (byte)HdlcFrameType.Uframe) == (byte)HdlcFrameType.Uframe)
            {
                //Get Eop if there is no data.
                if (reply.Position == packetStartID + frameLen + 1)
                {
                    // Get EOP.
                    reply.GetUInt8();
                }
                data.Command = (Command)frame;
            }
            //If S-frame
            else if ((frame & (byte)HdlcFrameType.Sframe) == (byte)HdlcFrameType.Sframe)
            {
                //If frame is rejected.
                int tmp = (frame >> 2) & 0x3;
                if (tmp == (byte)HdlcControlFrame.Reject)
                {
                    data.Error = (int)ErrorCode.Rejected;
                }
                else if (tmp == (byte)HdlcControlFrame.ReceiveNotReady)
                {
                    data.Error = (int)ErrorCode.Rejected;
                }
                else if (tmp == (byte)HdlcControlFrame.ReceiveReady)
                {
                    System.Diagnostics.Debug.WriteLine("Get next frame.");
                }
                //Get Eop if there is no data.
                if (reply.Position == packetStartID + frameLen + 1)
                {
                    // Get EOP.
                    reply.GetUInt8();
                }
            }
            else //Iframe
            {
                //Get Eop if there is no data.
                if (reply.Position == packetStartID + frameLen + 1)
                {
                    // Get EOP.
                    reply.GetUInt8();
                    if ((frame & 0x1) == 0x1)
                    {
                        data.MoreData = RequestTypes.Frame;
                    }
                }
                else
                {
                    if (!GetLLCBytes(server, reply) && data.Xml != null)
                    {
                        GetLLCBytes(!server, reply);
                    }
                }
            }
            return frame;
        }
Esempio n. 16
0
 /// <summary>
 /// Check that client and server address match.
 /// </summary>
 /// <param name="server">Is server.</param>
 /// <param name="settings">DLMS settings.</param>
 /// <param name="reply">Received data.</param>
 /// <param name="index">Position.</param>
 /// <returns>True, if client and server address match.</returns>
 private static bool CheckHdlcAddress(
     bool server,
     GXDLMSSettings settings,
     GXByteBuffer reply,
     int index)
 {
     int source, target;
     // Get destination and source addresses.
     target = GXCommon.GetHDLCAddress(reply);
     source = GXCommon.GetHDLCAddress(reply);
     if (server)
     {
         // Check that server addresses match.
         if (settings.ServerAddress != 0
                 && settings.ServerAddress != target)
         {
             if (reply.GetUInt8(reply.Position) == (int)Command.Snrm)
             {
                 settings.ServerAddress = target;
             }
             else
             {
                 throw new GXDLMSException(
                     "Destination addresses do not match. It is "
                     + target.ToString() + ". It should be "
                     + settings.ServerAddress.ToString() + ".");
             }
         }
         else
         {
             settings.ServerAddress = target;
         }
         // Check that client addresses match.
         if (settings.ClientAddress != 0 && settings.ClientAddress != source)
         {
             if (reply.GetUInt8(reply.Position) == (int)Command.Snrm)
             {
                 settings.ClientAddress = source;
             }
             else
             {
                 throw new GXDLMSException(
                     "Source addresses do not match. It is "
                     + source.ToString() + ". It should be "
                     + settings.ClientAddress.ToString()
                     + ".");
             }
         }
         else
         {
             settings.ClientAddress = source;
         }
     }
     else
     {
         // Check that client addresses match.
         if (settings.ClientAddress != target)
         {
             //If echo.
             if (settings.ClientAddress == source &&
                     settings.ServerAddress == target)
             {
                 reply.Position = (index + 1);
             }
             return false;
         }
         // Check that server addresses match.
         if (settings.ServerAddress != source)
         {
             //Check logical and physical address separately.
             //This is done because some meters might send four bytes
             //when only two bytes is needed.
             int readLogical, readPhysical, logical, physical;
             GetServerAddress(source, out readLogical, out readPhysical);
             GetServerAddress(settings.ServerAddress, out logical, out physical);
             if (readLogical != logical || readPhysical != physical)
             {
                 return false;
             }
         }
     }
     return true;
 }
        /// <summary>
        /// Handle read request.
        /// </summary>
        /// <param name="settings">DLMS settings.</param>
        /// <param name="server">DLMS server.</param>
        /// <param name="data">Received data.</param>
        public static void HandleReadRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            GXByteBuffer bb = new GXByteBuffer();
            int cnt = 0xFF;
            byte type = 0;
            List<ValueEventArgs> list = new List<ValueEventArgs>();
            //If get next frame.
            if (xml == null && data.Size == 0)
            {
                if (server.transaction != null)
                {
                    return;
                }
                bb.Set(replyData);
                replyData.Clear();
                foreach (ValueEventArgs it in server.transaction.targets)
                {
                    list.Add(it);
                }
            }
            else
            {
                cnt = GXCommon.GetObjectCount(data);
                List<ValueEventArgs> reads = new List<ValueEventArgs>();
                List<ValueEventArgs> actions = new List<ValueEventArgs>();
                if (xml != null)
                {
                    xml.AppendStartTag(Command.ReadRequest, "Qty", xml.IntegerToHex(cnt, 2));
                }

                for (int pos = 0; pos != cnt; ++pos)
                {
                    type = data.GetUInt8();
                    if (type == (byte)VariableAccessSpecification.VariableName ||
                            type == (byte)VariableAccessSpecification.ParameterisedAccess)
                    {
                        HandleRead(settings, server, type, data, list, reads, actions, replyData, xml);
                    }
                    else if (type == (byte)VariableAccessSpecification.BlockNumberAccess)
                    {
                        HandleReadBlockNumberAccess(settings, server, data, replyData, xml);
                        if (xml != null)
                        {
                            xml.AppendEndTag(Command.ReadRequest);
                        }
                        return;
                    }
                    else if (type == (byte)VariableAccessSpecification.ReadDataBlockAccess)
                    {
                        HandleReadDataBlockAccess(settings, server, Command.ReadResponse, data, cnt, replyData, xml);
                        if (xml != null)
                        {
                            xml.AppendEndTag(Command.ReadRequest);
                        }
                        return;
                    }
                    else
                    {
                        ReturnSNError(settings, server, Command.ReadResponse, ErrorCode.ReadWriteDenied, replyData);
                        if (xml != null)
                        {
                            xml.AppendEndTag(Command.ReadRequest);
                        }
                        return;
                    }
                }
                if (reads.Count != 0)
                {
                    server.NotifyRead(reads.ToArray());
                }

                if (actions.Count != 0)
                {
                    server.NotifyAction(actions.ToArray());
                }
            }
            if (xml != null)
            {
                xml.AppendEndTag(Command.ReadRequest);
                return;
            }

            byte requestType = (byte)GetReadData(settings, list.ToArray(), bb);
            GXDLMSSNParameters p = new GXDLMSSNParameters(settings, Command.ReadResponse, list.Count, requestType, null, bb);
            GXDLMS.GetSNPdu(p, replyData);
            if (server.transaction == null && (bb.Size != bb.Position || settings.Count != settings.Index))
            {
                List<ValueEventArgs> reads = new List<ValueEventArgs>();
                foreach (var it in list)
                {
                    reads.Add(it);
                }
                server.transaction = new GXDLMSLongTransaction(reads.ToArray(), Command.ReadRequest, bb);
            }
            else if (server.transaction != null)
            {
                replyData.Set(bb);
                return;
            }
        }
 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();
     }
 }
        private static void HandleRead(GXDLMSSettings settings, GXDLMSServer server, byte type, GXByteBuffer data,
                                       List<ValueEventArgs> list, List<ValueEventArgs> reads, List<ValueEventArgs> actions,
                                       GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            int sn = data.GetInt16();
            if (xml != null)
            {
                if (xml.OutputType == TranslatorOutputType.StandardXml)
                {
                    xml.AppendStartTag(
                        TranslatorTags.VariableAccessSpecification);
                }
                else
                {
                    sn &= 0xFFFF;
                }
                if (type == (byte)VariableAccessSpecification.ParameterisedAccess)
                {
                    xml.AppendStartTag(Command.ReadRequest,
                                       VariableAccessSpecification.ParameterisedAccess);
                    xml.AppendLine(
                        (int)Command.ReadRequest << 8
                        | (int)VariableAccessSpecification.VariableName,
                        "Value", xml.IntegerToHex(sn, 4));
                    xml.AppendLine(TranslatorTags.Selector, "Value",
                                   xml.IntegerToHex(data.GetUInt8(), 2));
                    GXDataInfo di = new GXDataInfo();
                    di.xml = xml;
                    xml.AppendStartTag(TranslatorTags.Parameter);
                    GXCommon.GetData(settings, data, di);
                    xml.AppendEndTag(TranslatorTags.Parameter);
                    xml.AppendEndTag(Command.ReadRequest,
                                     VariableAccessSpecification.ParameterisedAccess);
                }
                else
                {
                    xml.AppendLine(
                        (int)Command.ReadRequest << 8
                        | (int)VariableAccessSpecification.VariableName,
                        "Value", xml.IntegerToHex(sn, 4));
                }
                if (xml.OutputType == TranslatorOutputType.StandardXml)
                {
                    xml.AppendEndTag(TranslatorTags.VariableAccessSpecification);
                }
                return;
            }

            GXSNInfo info = FindSNObject(server, sn & 0xFFFF);
            ValueEventArgs e = new ValueEventArgs(settings, info.Item, info.Index, 0, null);
            e.action = info.IsAction;
            if (type == (byte)VariableAccessSpecification.ParameterisedAccess)
            {
                e.Selector = data.GetUInt8();
                GXDataInfo di = new GXDataInfo();
                e.Parameters = GXCommon.GetData(settings, data, di);
            }
            //Return error if connection is not established.
            if (!settings.Connected && (!e.action || e.Target.ShortName != 0xFA00 || e.Index != 8))
            {
                replyData.Add(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                              ServiceError.Service, (byte)Service.Unsupported));
                return;
            }

            list.Add(e);
            if (!e.action && info.Item.GetAccess(info.Index) == AccessMode.NoAccess)
            {
                e.Error = ErrorCode.ReadWriteDenied;
            }
            else if (e.action && info.Item.GetMethodAccess(info.Index) == MethodAccessMode.NoAccess)
            {
                e.Error = ErrorCode.ReadWriteDenied;
            }
            else
            {
                if (e.action)
                {
                    actions.Add(e);
                }
                else
                {
                    reads.Add(e);
                }
            }
        }
 /// <summary>
 /// Generate write reply.
 /// </summary>
 /// <param name="settings"></param>
 /// <param name="results"></param>
 /// <param name="replyData"></param>
 internal static void GenerateWriteResponse(GXDLMSSettings settings, GXByteBuffer results, GXByteBuffer replyData)
 {
     GXByteBuffer bb = new GXByteBuffer((UInt16)(2 * results.Size));
     byte ret;
     for (int pos = 0; pos != results.Size; ++pos)
     {
         ret = results.GetUInt8(pos);
         // If meter returns error.
         if (ret != 0)
         {
             bb.SetUInt8(1);
         }
         bb.SetUInt8(ret);
     }
     GXDLMSSNParameters p = new GXDLMSSNParameters(settings, Command.WriteResponse, results.Size, 0xFF, null, bb);
     GXDLMS.GetSNPdu(p, replyData);
 }
 ///<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. 22
0
 /// <summary>
 /// Find next frame from the string.
 /// </summary>
 /// <remarks>
 /// Position of data is set to the begin of new frame. If Pdu is null it is not updated.
 /// </remarks>
 /// <param name="data">Data where frame is search.</param>
 /// <param name="pdu">Pdu of received frame is set here.</param>
 /// <returns>Is new frame found.</returns>
 public bool FindNextFrame(GXByteBuffer data, GXByteBuffer pdu)
 {
     GXDLMSSettings settings = new GXDLMSSettings(true);
     GXReplyData reply = new GXReplyData();
     reply.Xml = new GXDLMSTranslatorStructure(OutputType, Hex, ShowStringAsHex, null);
     int pos;
     while (data.Position != data.Size)
     {
         if (data.GetUInt8(data.Position) == 0x7e)
         {
             pos = data.Position;
             settings.InterfaceType = Enums.InterfaceType.HDLC;
             GXDLMS.GetData(settings, data, reply);
             data.Position = pos;
             break;
         }
         else if (data.Position + 2 < data.Size && data.GetUInt16(data.Position) == 0x1)
         {
             pos = data.Position;
             settings.InterfaceType = Enums.InterfaceType.WRAPPER;
             GXDLMS.GetData(settings, data, reply);
             data.Position = pos;
             break;
         }
         ++data.Position;
     }
     if (pdu != null)
     {
         pdu.Clear();
         pdu.Set(reply.Data.Data, 0, reply.Data.Size);
     }
     return data.Position != data.Size;
 }
        ///<summary>
        /// Handle action request.
        ///</summary>
        ///<param name="Reply">
        /// Received data from the client.
        ///</param>
        ///<returns>
        ///Reply.
        ///</returns>
        public static void HandleMethodRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXDLMSConnectionEventArgs connectionInfo, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            ErrorCode error = ErrorCode.Ok;
            GXByteBuffer bb = new GXByteBuffer();
            // Get type.
            ActionRequestType type = (ActionRequestType)data.GetUInt8();
            // Get invoke ID and priority.
            byte invokeId = data.GetUInt8();
            // CI
            ObjectType ci = (ObjectType)data.GetUInt16();
            byte[] ln = new byte[6];
            data.Get(ln);
            // Attribute Id
            byte id = data.GetUInt8();
            // Get parameters.
            object parameters = null;
            byte selection = data.GetUInt8();
            if (xml != null)
            {
                xml.AppendStartTag(Command.MethodRequest);
                if (type == ActionRequestType.Normal)
                {
                    xml.AppendStartTag(Command.MethodRequest, ActionRequestType.Normal);
                    xml.AppendLine(TranslatorTags.InvokeId, "Value", xml.IntegerToHex(invokeId, 2));
                    AppendMethodDescriptor(xml, (int)ci, ln, id);
                    if (selection != 0)
                    {
                        //MethodInvocationParameters
                        xml.AppendStartTag(TranslatorTags.MethodInvocationParameters);
                        GXDataInfo di = new GXDataInfo();
                        di.xml = xml;
                        GXCommon.GetData(settings, data, di);
                        xml.AppendEndTag(TranslatorTags.MethodInvocationParameters);
                    }
                    xml.AppendEndTag(Command.MethodRequest, ActionRequestType.Normal);
                }
                xml.AppendEndTag(Command.MethodRequest);
                return;
            }
            if (selection != 0)
            {
                GXDataInfo info = new GXDataInfo();
                parameters = GXCommon.GetData(settings, data, info);
            }

            GXDLMSObject obj = settings.Objects.FindByLN(ci, GXDLMSObject.ToLogicalName(ln));
            if (!settings.Connected && (ci != ObjectType.AssociationLogicalName || id != 1))
            {
                replyData.Set(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                              ServiceError.Service, (byte)Service.Unsupported));
                return;
            }

            if (obj == null)
            {
                obj = server.NotifyFindObject(ci, 0, GXDLMSObject.ToLogicalName(ln));
            }
            if (obj == null)
            {
                // Device reports a undefined object.
                error = ErrorCode.UndefinedObject;
            }
            else
            {
                if (obj.GetMethodAccess(id) == MethodAccessMode.NoAccess)
                {
                    error = ErrorCode.ReadWriteDenied;
                }
                else
                {
                    ValueEventArgs e = new ValueEventArgs(settings, obj, id, 0, parameters);
                    server.NotifyAction(new ValueEventArgs[] { e });
                    byte[] actionReply;
                    if (e.Handled)
                    {
                        actionReply = (byte[])e.Value;
                    }
                    else
                    {
                        actionReply = (obj as IGXDLMSBase).Invoke(settings, e);
                    }
                    //Set default action reply if not given.
                    if (actionReply != null && e.Error == 0)
                    {
                        //Add return parameters
                        bb.SetUInt8(1);
                        //Add parameters error code.
                        bb.SetUInt8(0);
                        GXCommon.SetData(settings, bb, GXCommon.GetValueType(actionReply), actionReply);
                    }
                    else
                    {
                        error = e.Error;
                        //Add return parameters
                        bb.SetUInt8(0);
                    }
                }
            }

            GXDLMSLNParameters p = new GXDLMSLNParameters(settings, Command.MethodResponse, 1, null, bb, (byte)error);
            GXDLMS.GetLNPdu(p, replyData);
            //If High level authentication fails.
            if (!settings.Connected && obj is GXDLMSAssociationLogicalName && id == 1)
            {
                server.NotifyInvalidConnection(connectionInfo);
            }
        }
Esempio n. 24
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]);
        }
        /// <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);
            }
        }
Esempio n. 26
0
        ///
        ///<summary>Handle read request.
        /// </summary>
        ///<returns> Reply to the client. </returns>
        ///
        private byte[][] HandleReadRequest()
        {
            GXByteBuffer data = Reply.Data;
            short        type;
            object       value = null;
            GXByteBuffer bb    = new GXByteBuffer();
            int          cnt   = GXCommon.GetObjectCount(data);

            GXCommon.SetObjectCount(cnt, bb);
            GXSNInfo info;

            for (int pos = 0; pos != cnt; ++pos)
            {
                type = data.GetUInt8();
                // GetRequest normal
                if (type == 2)
                {
                    int sn = data.GetUInt16();
                    info = FindSNObject(sn);
                    if (!info.IsAction)
                    {
                        ValueEventArgs e = new ValueEventArgs(info.Item, info.Index, 0, null);
                        Read(e);
                        if (e.Handled)
                        {
                            value = e.Value;
                        }
                        else
                        {
                            value = (info.Item as IGXDLMSBase).GetValue(Settings, info.Index, 0, null);
                        }
                        // Set status.
                        bb.SetUInt8(0);
                        GXDLMS.AppedData(info.Item, info.Index, bb, value);
                    }
                    else
                    {
                        ValueEventArgs e = new ValueEventArgs(info.Item, info.Index, 0, null);
                        Action(e);
                        if (e.Handled)
                        {
                            value = e.Value;
                        }
                        else
                        {
                            value = ((IGXDLMSBase)info.Item).Invoke(Settings, info.Index, null);
                        }
                        // Set status.
                        bb.SetUInt8(0);
                        // Add value
                        bb.SetUInt8(GXCommon.GetValueType(value));
                        bb.Add(value);
                    }
                }
                else if (type == 2)
                {
                    // Get request for next data block
                    throw new System.ArgumentException("TODO: Invalid Command.");
                }
                else if (type == 4)
                {
                    // Parameterised access.
                    int        sn         = data.GetUInt16();
                    int        selector   = data.GetUInt8();
                    GXDataInfo di         = new GXDataInfo();
                    object     parameters = GXCommon.GetData(data, di);
                    info = FindSNObject(sn);
                    if (!info.IsAction)
                    {
                        ValueEventArgs e = new ValueEventArgs(info.Item, info.Index, 0, parameters);
                        Read(e);
                        if (e.Handled)
                        {
                            value = e.Value;
                        }
                        else
                        {
                            value = (info.Item as IGXDLMSBase).GetValue(Settings, info.Index, selector, parameters);
                        }
                        // Set status.
                        bb.SetUInt8(0);
                        GXDLMS.AppedData(info.Item, info.Index, bb, value);
                    }
                    else
                    {
                        ValueEventArgs e = new ValueEventArgs(info.Item, info.Index, 0, parameters);
                        e.Value = parameters;
                        Action(e);
                        if (e.Handled)
                        {
                            value = e.Value;
                        }
                        else
                        {
                            value = ((IGXDLMSBase)info.Item).Invoke(Settings, info.Index, parameters);
                        }
                        // Add value
                        bb.Add(value);
                    }
                }
                else
                {
                    throw new System.ArgumentException("Invalid Command.");
                }
            }
            return(GXDLMS.SplitPdu(Settings, Command.ReadResponse, 1, bb,
                                   ErrorCode.Ok, DateTime.MinValue)[0]);
        }
        /// <summary>
        /// Handle get request with list command.
        /// </summary>
        /// <param name="data">Received data.</param>
        private static void GetRequestWithList(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            ValueEventArgs e;
            GXByteBuffer bb = new GXByteBuffer();
            int pos;
            int cnt = GXCommon.GetObjectCount(data);
            GXCommon.SetObjectCount(cnt, bb);
            List<ValueEventArgs> list = new List<ValueEventArgs>();
            if (xml != null)
            {
                xml.AppendStartTag(TranslatorTags.AttributeDescriptorList, "Qty", xml.IntegerToHex(cnt, 2));
            }
            try
            {
                for (pos = 0; pos != cnt; ++pos)
                {
                    ObjectType ci = (ObjectType)data.GetUInt16();
                    byte[] ln = new byte[6];
                    data.Get(ln);
                    short attributeIndex = data.GetUInt8();
                    // AccessSelection
                    int selection = data.GetUInt8();
                    int selector = 0;
                    object parameters = null;
                    if (selection != 0)
                    {
                        selector = data.GetUInt8();
                        GXDataInfo info = new GXDataInfo();
                        parameters = GXCommon.GetData(settings, data, info);
                    }
                    if (xml != null)
                    {
                        xml.AppendStartTag(TranslatorTags.AttributeDescriptorWithSelection);
                        xml.AppendStartTag(TranslatorTags.AttributeDescriptor);
                        xml.AppendLine(TranslatorTags.ClassId, "Value", xml.IntegerToHex((int)ci, 4));
                        xml.AppendLine(TranslatorTags.InstanceId, "Value", GXCommon.ToHex(ln, false));
                        xml.AppendLine(TranslatorTags.AttributeId, "Value", xml.IntegerToHex(attributeIndex, 2));
                        xml.AppendEndTag(TranslatorTags.AttributeDescriptor);
                        xml.AppendEndTag(TranslatorTags.AttributeDescriptorWithSelection);
                    }
                    else
                    {
                        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."
                            e = new ValueEventArgs(settings, obj, attributeIndex, 0, 0);
                            e.Error = ErrorCode.UndefinedObject;
                            list.Add(e);
                        }
                        else
                        {
                            if (obj.GetAccess(attributeIndex) == AccessMode.NoAccess)
                            {
                                //Read Write denied.
                                ValueEventArgs arg = new ValueEventArgs(settings, obj, attributeIndex, 0, null);
                                arg.Error = ErrorCode.ReadWriteDenied;
                                list.Add(arg);
                            }
                            else
                            {
                                ValueEventArgs arg = new ValueEventArgs(settings, obj, attributeIndex, selector, parameters);
                                list.Add(arg);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (xml == null)
                {
                    throw ex;
                }
            }
            if (xml != null)
            {
                xml.AppendEndTag(TranslatorTags.AttributeDescriptorList);
                return;
            }

            server.NotifyRead(list.ToArray());
            object value;
            pos = 0;
            foreach (ValueEventArgs it in list)
            {
                try
                {
                    if (it.Handled)
                    {
                        value = it.Value;
                    }
                    else
                    {
                        value = (it.Target as IGXDLMSBase).GetValue(settings, it);
                    }
                    bb.SetUInt8(it.Error);
                    GXDLMS.AppendData(settings, it.Target, it.Index, bb, value);
                }
                catch (Exception)
                {
                    bb.SetUInt8((byte)ErrorCode.HardwareFault);
                }
                if (settings.Index != settings.Count)
                {
                    server.transaction = new GXDLMSLongTransaction(list.ToArray(), Command.GetRequest, null);
                }
                ++pos;
            }
            GXDLMSLNParameters p = new GXDLMSLNParameters(settings, Command.GetResponse, 3, null, bb, 0xFF);
            GXDLMS.GetLNPdu(p, replyData);
        }
Esempio n. 28
0
 /// <summary>
 /// Convert message to xml.
 /// </summary>
 /// <param name="value">Bytes to convert.</param>
 /// <returns>Converted xml.</returns>
 /// <seealso cref="PduOnly"/>
 /// <seealso cref="CompletePdu"/>
 public string MessageToXml(GXByteBuffer value)
 {
     if (value == null || value.Size == 0)
     {
         throw new ArgumentNullException("value");
     }
     try
     {
         GXReplyData data = new GXReplyData();
         GXDLMSTranslatorStructure xml = new GXDLMSTranslatorStructure(OutputType, Hex, ShowStringAsHex, tags);
         data.Xml = xml;
         //If HDLC framing.
         int offset = value.Position;
         if (value.GetUInt8(value.Position) == 0x7e)
         {
             GXDLMSSettings settings = new GXDLMSSettings(true);
             settings.InterfaceType = Enums.InterfaceType.HDLC;
             if (GXDLMS.GetData(settings, value, data))
             {
                 if (!PduOnly)
                 {
                     xml.AppendLine("<HDLC len=\"" + (data.PacketLength - offset).ToString("X") + "\" >");
                     xml.AppendLine("<TargetAddress Value=\"" + settings.ServerAddress.ToString("X") + "\" />");
                     xml.AppendLine("<SourceAddress Value=\"" + settings.ClientAddress.ToString("X") + "\" />");
                 }
                 if (data.Data.Size == 0)
                 {
                     if ((data.FrameId & 1) != 0 && data.Command == Command.None)
                     {
                         if (!CompletePdu)
                         {
                             xml.AppendLine("<Command Value=\"NextFrame\" />");
                         }
                         multipleFrames = true;
                     }
                     else
                     {
                         xml.AppendStartTag(data.Command);
                         xml.AppendEndTag(data.Command);
                     }
                 }
                 else
                 {
                     if (multipleFrames || (data.MoreData & Enums.RequestTypes.Frame) != 0)
                     {
                         if (CompletePdu)
                         {
                             pduFrames.Set(data.Data.Data);
                         }
                         else
                         {
                             xml.AppendLine("<NextFrame Value=\"" + GXCommon.ToHex(data.Data.Data, false, data.Data.Position, data.Data.Size - data.Data.Position) + "\" />");
                         }
                         multipleFrames = false;
                     }
                     if (!data.IsMoreData)
                     {
                         if (!PduOnly)
                         {
                             xml.AppendLine("<PDU>");
                         }
                         if (pduFrames.Size != 0)
                         {
                             if (!CompletePdu)
                             {
                                 pduFrames.Set(data.Data.Data);
                             }
                             xml.AppendLine(PduToXml(pduFrames));
                             pduFrames.Clear();
                         }
                         else
                         {
                             xml.AppendLine(PduToXml(data.Data));
                         }
                         //Remove \r\n.
                         xml.sb.Length -= 2;
                         if (!PduOnly)
                         {
                             xml.AppendLine("</PDU>");
                         }
                     }
                 }
                 if (!PduOnly)
                 {
                     xml.AppendLine("</HDLC>");
                 }
             }
             return xml.sb.ToString();
         }
         //If wrapper.
         if (value.GetUInt16(value.Position) == 1)
         {
             GXDLMSSettings settings = new GXDLMSSettings(true);
             settings.InterfaceType = Enums.InterfaceType.WRAPPER;
             GXDLMS.GetData(settings, value, data);
             if (!PduOnly)
             {
                 xml.AppendLine("<WRAPPER len=\"" + (data.PacketLength - offset).ToString("X") + "\" >");
                 xml.AppendLine("<TargetAddress Value=\"" + settings.ClientAddress.ToString("X") + "\" />");
                 xml.AppendLine("<SourceAddress Value=\"" + settings.ServerAddress.ToString("X") + "\" />");
             }
             if (data.Data.Size == 0)
             {
                 xml.AppendLine("<Command Value=\"" + data.Command.ToString().ToUpper() + "\" />");
             }
             else
             {
                 if (data.Data.Size == 0)
                 {
                     if ((data.FrameId & 1) != 0 && data.Command == Command.None)
                     {
                         if (!CompletePdu)
                         {
                             xml.AppendLine("<Command Value=\"NextFrame\" />");
                         }
                         multipleFrames = true;
                     }
                     else
                     {
                         xml.AppendStartTag(data.Command);
                         xml.AppendEndTag(data.Command);
                     }
                 }
                 else
                 {
                     if (multipleFrames || (data.MoreData & Enums.RequestTypes.Frame) != 0)
                     {
                         if (CompletePdu)
                         {
                             pduFrames.Set(data.Data.Data);
                         }
                         else
                         {
                             xml.AppendLine("<NextFrame Value=\"" + GXCommon.ToHex(data.Data.Data, false, data.Data.Position, data.Data.Size - data.Data.Position) + "\" />");
                         }
                         multipleFrames = false;
                     }
                     if (!data.IsMoreData)
                     {
                         if (!PduOnly)
                         {
                             xml.AppendLine("<PDU>");
                         }
                         if (pduFrames.Size != 0)
                         {
                             if (!CompletePdu)
                             {
                                 pduFrames.Set(data.Data.Data);
                             }
                             xml.AppendLine(PduToXml(pduFrames));
                             pduFrames.Clear();
                         }
                         else
                         {
                             xml.AppendLine(PduToXml(data.Data));
                         }
                         //Remove \r\n.
                         xml.sb.Length -= 2;
                         if (!PduOnly)
                         {
                             xml.AppendLine("</PDU>");
                         }
                     }
                 }
             }
             if (!PduOnly)
             {
                 xml.AppendLine("</WRAPPER>");
             }
             return xml.sb.ToString();
         }
     }
     catch (Exception ex)
     {
         System.Diagnostics.Debug.Write(ex.ToString());
     }
     throw new ArgumentNullException("Invalid DLMS framing.");
 }
Esempio n. 29
0
 private string PduToXml(GXByteBuffer value, bool omitDeclaration, bool omitNameSpace)
 {
     if (value == null || value.Size == 0)
     {
         throw new ArgumentNullException("value");
     }
     GXDLMSTranslatorStructure xml = new GXDLMSTranslatorStructure(OutputType, Hex, ShowStringAsHex, tags);
     GXDLMSSettings settings = new GXDLMSSettings(true);
     GXReplyData data = new GXReplyData();
     byte cmd = value.GetUInt8();
     switch (cmd)
     {
         case (byte)Command.Aarq:
             value.Position = 0;
             settings = new GXDLMSSettings(true);
             GXAPDU.ParsePDU(settings, settings.Cipher, value, xml);
             break;
         case 0x81://Ua
             value.Position = 0;
             GetUa(value, xml);
             break;
         case (byte)Command.Aare:
             value.Position = 0;
             settings = new GXDLMSSettings(false);
             GXAPDU.ParsePDU(settings, settings.Cipher, value, xml);
             break;
         case (byte)Command.GetRequest:
             GXDLMSLNCommandHandler.HandleGetRequest(settings, null, value, null, xml);
             break;
         case (byte)Command.SetRequest:
             GXDLMSLNCommandHandler.HandleSetRequest(settings, null, value, null, xml);
             break;
         case (byte)Command.ReadRequest:
             GXDLMSSNCommandHandler.HandleReadRequest(settings, null, value, null, xml);
             break;
         case (byte)Command.MethodRequest:
             GXDLMSLNCommandHandler.HandleMethodRequest(settings, null, value, null, null, xml);
             break;
         case (byte)Command.WriteRequest:
             GXDLMSSNCommandHandler.HandleWriteRequest(settings, null, value, null, xml);
             break;
         case (byte)Command.AccessRequest:
             GXDLMSLNCommandHandler.HandleAccessRequest(settings, null, value, null, xml);
             break;
         case (byte)Command.DataNotification:
             data.Xml = xml;
             data.Data = value;
             value.Position = 0;
             GXDLMS.GetPdu(settings, data);
             break;
         case (byte)Command.ReadResponse:
         case (byte)Command.WriteResponse:
         case (byte)Command.GetResponse:
         case (byte)Command.SetResponse:
         case (byte)Command.MethodResponse:
         case (byte)Command.AccessResponse:
             data.Xml = xml;
             data.Data = value;
             value.Position = 0;
             GXDLMS.GetPdu(settings, data);
             break;
         case (byte)Command.ReleaseRequest:
         case (byte)Command.ReleaseResponse:
             xml.AppendStartTag((Command)cmd);
             //Len.
             if (value.GetUInt8() != 0)
             {
                 //BerType
                 value.GetUInt8();
                 //Len.
                 value.GetUInt8();
                 xml.AppendLine(TranslatorTags.Reason, "Value", ((ReleaseRequestReason)value.GetUInt8()).ToString());
             }
             xml.AppendEndTag((Command)cmd);
             break;
         case (byte)Command.GloReadRequest:
         case (byte)Command.GloWriteRequest:
         case (byte)Command.GloGetRequest:
         case (byte)Command.GloSetRequest:
         case (byte)Command.GloReadResponse:
         case (byte)Command.GloWriteResponse:
         case (byte)Command.GloGetResponse:
         case (byte)Command.GloSetResponse:
         case (byte)Command.GloMethodRequest:
         case (byte)Command.GloMethodResponse:
             int cnt = GXCommon.GetObjectCount(value);
             xml.AppendLine(cmd, "Value", GXCommon.ToHex(value.Data, false, value.Position, value.Size - value.Position));
             break;
         case (byte)Command.ConfirmedServiceError:
             data.Xml = xml;
             data.Data = value;
             GXDLMS.HandleConfirmedServiceError(data);
             break;
         default:
             xml.AppendLine("<Data=\"" + GXCommon.ToHex(value.Data, false, value.Position, value.Size - value.Position) + "\" />");
             break;
     }
     if (OutputType == TranslatorOutputType.StandardXml)
     {
         StringBuilder sb = new StringBuilder();
         if (!omitDeclaration)
         {
             sb.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
         }
         if (!omitNameSpace)
         {
             if (cmd != (byte)Command.Aare && cmd != (byte)Command.Aarq)
             {
                 sb.AppendLine(
                     "<x:xDLMS-APDU xmlns:x=\"http://www.dlms.com/COSEMpdu\">");
             }
             else
             {
                 sb.AppendLine(
                     "<x:aCSE-APDU xmlns:x=\"http://www.dlms.com/COSEMpdu\">");
             }
         }
         sb.Append(xml.ToString());
         if (!omitNameSpace)
         {
             if (cmd != (byte)Command.Aare && cmd != (byte)Command.Aarq)
             {
                 sb.AppendLine("</x:xDLMS-APDU>");
             }
             else
             {
                 sb.AppendLine("</x:aCSE-APDU>");
             }
         }
         return sb.ToString();
     }
     return xml.ToString();
 }
Esempio n. 30
0
 public byte[] GetPdu(GXByteBuffer value)
 {
     GXReplyData data = new GXReplyData();
     data.Xml = new GXDLMSTranslatorStructure(OutputType, Hex, ShowStringAsHex, tags);
     GXDLMSSettings settings = new GXDLMSSettings(true);
     if (value.GetUInt8(0) == 0x7e)
     {
         settings.InterfaceType = Enums.InterfaceType.HDLC;
     }
     //If wrapper.
     else if (value.GetUInt16(0) == 1)
     {
         settings.InterfaceType = Enums.InterfaceType.WRAPPER;
     }
     else
     {
         throw new ArgumentNullException("Invalid DLMS framing.");
     }
     GXDLMS.GetData(settings, value, data);
     //Only fully PDUs are returned.
     if (data.IsMoreData)
     {
         return null;
     }
     return data.Data.Array();
 }
Esempio n. 31
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);
            }
        }
Esempio n. 32
0
        ///<summary>
        /// Handle write request.
        ///</summary>
        public static void HandleWriteRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data,
                                              GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            //Return error if connection is not established.
            if (xml == null && !settings.Connected)
            {
                replyData.Add(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                                                                         ServiceError.Service, (byte)Service.Unsupported));
                return;
            }
            short  type;
            object value;
            // Get object count.
            List <GXSNInfo> targets = new List <GXSNInfo>();
            int             cnt     = GXCommon.GetObjectCount(data);

            if (xml != null)
            {
                xml.AppendStartTag(Command.WriteRequest);
                xml.AppendStartTag(
                    TranslatorTags.ListOfVariableAccessSpecification, "Qty",
                    xml.IntegerToHex(cnt, 2));
                if (xml.OutputType == TranslatorOutputType.StandardXml)
                {
                    xml.AppendStartTag(
                        TranslatorTags.VariableAccessSpecification);
                }
            }
            GXByteBuffer results = new GXByteBuffer((ushort)cnt);

            for (int pos = 0; pos != cnt; ++pos)
            {
                type = data.GetUInt8();
                if (type == (byte)VariableAccessSpecification.VariableName)
                {
                    int sn = data.GetUInt16();
                    if (xml != null)
                    {
                        xml.AppendLine(
                            (int)Command.WriteRequest << 8
                                | (int)VariableAccessSpecification.VariableName,
                                "Value", xml.IntegerToHex(sn, 4));
                    }
                    else
                    {
                        GXSNInfo info = FindSNObject(server, sn);
                        targets.Add(info);
                        // If target is unknown.
                        if (info == null)
                        {
                            // Device reports a undefined object.
                            results.SetUInt8(ErrorCode.UndefinedObject);
                        }
                        else
                        {
                            results.SetUInt8(ErrorCode.Ok);
                        }
                    }
                }
                else if (type == (byte)VariableAccessSpecification.WriteDataBlockAccess)
                {
                    HandleReadDataBlockAccess(settings, server, Command.WriteResponse, data, cnt, replyData, xml);
                    if (xml == null)
                    {
                        return;
                    }
                }
                else
                {
                    // Device reports a HW error.
                    results.SetUInt8(ErrorCode.HardwareFault);
                }
            }

            if (xml != null)
            {
                if (xml.OutputType == TranslatorOutputType.StandardXml)
                {
                    xml.AppendEndTag(TranslatorTags.VariableAccessSpecification);
                }
                xml.AppendEndTag(
                    TranslatorTags.ListOfVariableAccessSpecification);
            }
            // Get data count.
            cnt = GXCommon.GetObjectCount(data);
            GXDataInfo di = new GXDataInfo();

            di.xml = xml;
            if (xml != null)
            {
                xml.AppendStartTag(TranslatorTags.ListOfData, "Qty", xml.IntegerToHex(cnt, 2));
            }
            for (int pos = 0; pos != cnt; ++pos)
            {
                di.Clear();
                if (xml != null)
                {
                    if (xml.OutputType == TranslatorOutputType.StandardXml)
                    {
                        xml.AppendStartTag(Command.WriteRequest,
                                           SingleReadResponse.Data);
                    }
                    value = GXCommon.GetData(settings, data, di);
                    if (!di.Complete)
                    {
                        value = GXCommon.ToHex(data.Data, false,
                                               data.Position, data.Size - data.Position);
                        xml.AppendLine(
                            GXDLMS.DATA_TYPE_OFFSET + (int)di.Type,
                            "Value", value.ToString());
                    }
                    if (xml.OutputType == TranslatorOutputType.StandardXml)
                    {
                        xml.AppendEndTag(Command.WriteRequest, SingleReadResponse.Data);
                    }
                    GXCommon.GetData(settings, data, di);
                }
                else if (results.GetUInt8(pos) == 0)
                {
                    // If object has found.
                    GXSNInfo target = targets[pos];
                    value = GXCommon.GetData(settings, data, di);
                    if (value is byte[])
                    {
                        DataType dt = target.Item.GetDataType(target.Index);
                        if (dt != DataType.None && dt != DataType.OctetString)
                        {
                            value = GXDLMSClient.ChangeType((byte[])value, dt, settings.UseUtc2NormalTime);
                        }
                    }
                    ValueEventArgs e  = new ValueEventArgs(server, target.Item, target.Index, 0, null);
                    AccessMode     am = server.NotifyGetAttributeAccess(e);
                    // If write is denied.
                    if (am != AccessMode.Write && am != AccessMode.ReadWrite)
                    {
                        results.SetUInt8((byte)pos, (byte)ErrorCode.ReadWriteDenied);
                    }
                    else
                    {
                        e.Value = value;
                        server.NotifyWrite(new ValueEventArgs[] { e });
                        if (e.Error != 0)
                        {
                            results.SetUInt8((byte)pos, (byte)e.Error);
                        }
                        else if (!e.Handled)
                        {
                            (target.Item as IGXDLMSBase).SetValue(settings, e);
                            server.NotifyPostWrite(new ValueEventArgs[] { e });
                        }
                    }
                }
            }
            if (xml != null)
            {
                xml.AppendEndTag(TranslatorTags.ListOfData);
                xml.AppendEndTag(Command.WriteRequest);
                return;
            }
            GenerateWriteResponse(settings, results, replyData);
        }
Esempio n. 33
0
        /// <summary>
        /// Handle get request with list command.
        /// </summary>
        /// <param name="data">Received data.</param>
        private static void GetRequestWithList(GXDLMSSettings settings, byte invokeID, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            ValueEventArgs e;
            GXByteBuffer   bb = new GXByteBuffer();
            int            pos;
            int            cnt = GXCommon.GetObjectCount(data);

            GXCommon.SetObjectCount(cnt, bb);
            List <ValueEventArgs> list = new List <ValueEventArgs>();

            if (xml != null)
            {
                xml.AppendStartTag(TranslatorTags.AttributeDescriptorList, "Qty", xml.IntegerToHex(cnt, 2));
            }
            try
            {
                for (pos = 0; pos != cnt; ++pos)
                {
                    ObjectType ci = (ObjectType)data.GetUInt16();
                    byte[]     ln = new byte[6];
                    data.Get(ln);
                    short attributeIndex = data.GetUInt8();
                    // AccessSelection
                    int    selection  = data.GetUInt8();
                    int    selector   = 0;
                    object parameters = null;
                    if (selection != 0)
                    {
                        selector = data.GetUInt8();
                        GXDataInfo info = new GXDataInfo();
                        parameters = GXCommon.GetData(settings, data, info);
                    }
                    if (xml != null)
                    {
                        xml.AppendStartTag(TranslatorTags.AttributeDescriptorWithSelection);
                        xml.AppendStartTag(TranslatorTags.AttributeDescriptor);
                        xml.AppendComment(ci.ToString());
                        xml.AppendLine(TranslatorTags.ClassId, "Value", xml.IntegerToHex((int)ci, 4));
                        xml.AppendComment(GXCommon.ToLogicalName(ln));
                        xml.AppendLine(TranslatorTags.InstanceId, "Value", GXCommon.ToHex(ln, false));
                        xml.AppendLine(TranslatorTags.AttributeId, "Value", xml.IntegerToHex(attributeIndex, 2));
                        xml.AppendEndTag(TranslatorTags.AttributeDescriptor);
                        xml.AppendEndTag(TranslatorTags.AttributeDescriptorWithSelection);
                    }
                    else
                    {
                        GXDLMSObject obj = settings.Objects.FindByLN(ci, GXCommon.ToLogicalName(ln));
                        if (obj == null)
                        {
                            obj = server.NotifyFindObject(ci, 0, GXCommon.ToLogicalName(ln));
                        }
                        if (obj == null)
                        {
                            // "Access Error : Device reports a undefined object."
                            e       = new ValueEventArgs(server, obj, attributeIndex, 0, 0);
                            e.Error = ErrorCode.UndefinedObject;
                            list.Add(e);
                        }
                        else
                        {
                            ValueEventArgs arg = new ValueEventArgs(server, obj, attributeIndex, selector, parameters);
                            arg.InvokeId = invokeID;
                            if (server.NotifyGetAttributeAccess(arg) == AccessMode.NoAccess)
                            {
                                //Read Write denied.
                                arg.Error = ErrorCode.ReadWriteDenied;
                                list.Add(arg);
                            }
                            else
                            {
                                list.Add(arg);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (xml == null)
                {
                    throw ex;
                }
            }
            if (xml != null)
            {
                xml.AppendEndTag(TranslatorTags.AttributeDescriptorList);
                return;
            }

            server.NotifyRead(list.ToArray());
            object value;

            pos = 0;
            foreach (ValueEventArgs it in list)
            {
                try
                {
                    if (it.Handled)
                    {
                        value = it.Value;
                    }
                    else
                    {
                        value = (it.Target as IGXDLMSBase).GetValue(settings, it);
                    }
                    bb.SetUInt8(it.Error);
                    if (it.ByteArray)
                    {
                        bb.Set((byte[])value);
                    }
                    else
                    {
                        GXDLMS.AppendData(settings, it.Target, it.Index, bb, value);
                    }
                    invokeID = (byte)it.InvokeId;
                }
                catch (Exception)
                {
                    bb.SetUInt8((byte)ErrorCode.HardwareFault);
                }
                if (settings.Index != settings.Count)
                {
                    server.transaction = new GXDLMSLongTransaction(list.ToArray(), Command.GetRequest, null);
                }
                ++pos;
            }
            server.NotifyPostRead(list.ToArray());
            GXDLMSLNParameters p = new GXDLMSLNParameters(null, settings, invokeID, Command.GetResponse, 3, null, bb, 0xFF);

            GXDLMS.GetLNPdu(p, replyData);
        }
Esempio n. 34
0
        private static void HandleRead(GXDLMSSettings settings, GXDLMSServer server, byte type, GXByteBuffer data,
                                       List <ValueEventArgs> list, List <ValueEventArgs> reads, List <ValueEventArgs> actions,
                                       GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            int sn = data.GetInt16();

            if (xml != null)
            {
                if (xml.OutputType == TranslatorOutputType.StandardXml)
                {
                    xml.AppendStartTag(
                        TranslatorTags.VariableAccessSpecification);
                }
                else
                {
                    sn &= 0xFFFF;
                }
                if (type == (byte)VariableAccessSpecification.ParameterisedAccess)
                {
                    xml.AppendStartTag(Command.ReadRequest,
                                       VariableAccessSpecification.ParameterisedAccess);
                    xml.AppendLine(
                        (int)Command.ReadRequest << 8
                            | (int)VariableAccessSpecification.VariableName,
                            "Value", xml.IntegerToHex(sn, 4));
                    xml.AppendLine(TranslatorTags.Selector, "Value",
                                   xml.IntegerToHex(data.GetUInt8(), 2));
                    GXDataInfo di = new GXDataInfo();
                    di.xml = xml;
                    xml.AppendStartTag(TranslatorTags.Parameter);
                    GXCommon.GetData(settings, data, di);
                    xml.AppendEndTag(TranslatorTags.Parameter);
                    xml.AppendEndTag(Command.ReadRequest,
                                     VariableAccessSpecification.ParameterisedAccess);
                }
                else
                {
                    xml.AppendLine(
                        (int)Command.ReadRequest << 8
                            | (int)VariableAccessSpecification.VariableName,
                            "Value", xml.IntegerToHex(sn, 4));
                }
                if (xml.OutputType == TranslatorOutputType.StandardXml)
                {
                    xml.AppendEndTag(TranslatorTags.VariableAccessSpecification);
                }
                return;
            }

            GXSNInfo       info = FindSNObject(server, sn & 0xFFFF);
            ValueEventArgs e    = new ValueEventArgs(server, info.Item, info.Index, 0, null);

            e.action = info.IsAction;
            if (type == (byte)VariableAccessSpecification.ParameterisedAccess)
            {
                e.Selector = data.GetUInt8();
                GXDataInfo di = new GXDataInfo();
                e.Parameters = GXCommon.GetData(settings, data, di);
            }
            //Return error if connection is not established.
            if (!settings.Connected && (!e.action || e.Target.ShortName != 0xFA00 || e.Index != 8))
            {
                replyData.Add(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                                                                         ServiceError.Service, (byte)Service.Unsupported));
                return;
            }
            if (e.Target is GXDLMSProfileGeneric && info.Index == 2)
            {
                e.RowToPdu = GXDLMS.RowsToPdu(settings, (GXDLMSProfileGeneric)e.Target);
            }
            list.Add(e);
            if (!e.action && server.NotifyGetAttributeAccess(e) == AccessMode.NoAccess)
            {
                e.Error = ErrorCode.ReadWriteDenied;
            }
            else if (e.action && server.NotifyGetMethodAccess(e) == MethodAccessMode.NoAccess)
            {
                e.Error = ErrorCode.ReadWriteDenied;
            }
            else
            {
                if (e.action)
                {
                    actions.Add(e);
                }
                else
                {
                    reads.Add(e);
                }
            }
        }
Esempio n. 35
0
        private static void HanleSetRequestWithList(GXDLMSSettings settings, byte invokeID, GXDLMSServer server, GXByteBuffer data, GXDLMSLNParameters p, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            ValueEventArgs        e;
            int                   cnt  = GXCommon.GetObjectCount(data);
            List <ValueEventArgs> list = new List <ValueEventArgs>();

            if (xml != null)
            {
                xml.AppendStartTag(TranslatorTags.AttributeDescriptorList, "Qty", xml.IntegerToHex(cnt, 2));
            }
            try
            {
                for (int pos = 0; pos != cnt; ++pos)
                {
                    ObjectType ci = (ObjectType)data.GetUInt16();
                    byte[]     ln = new byte[6];
                    data.Get(ln);
                    short attributeIndex = data.GetUInt8();
                    // AccessSelection
                    int    selection  = data.GetUInt8();
                    int    selector   = 0;
                    object parameters = null;
                    if (selection != 0)
                    {
                        selector = data.GetUInt8();
                        GXDataInfo info = new GXDataInfo();
                        parameters = GXCommon.GetData(settings, data, info);
                    }
                    if (xml != null)
                    {
                        xml.AppendStartTag(TranslatorTags.AttributeDescriptorWithSelection);
                        xml.AppendStartTag(TranslatorTags.AttributeDescriptor);
                        xml.AppendComment(ci.ToString());
                        xml.AppendLine(TranslatorTags.ClassId, "Value", xml.IntegerToHex((int)ci, 4));
                        xml.AppendComment(GXCommon.ToLogicalName(ln));
                        xml.AppendLine(TranslatorTags.InstanceId, "Value", GXCommon.ToHex(ln, false));
                        xml.AppendLine(TranslatorTags.AttributeId, "Value", xml.IntegerToHex(attributeIndex, 2));
                        xml.AppendEndTag(TranslatorTags.AttributeDescriptor);
                        xml.AppendEndTag(TranslatorTags.AttributeDescriptorWithSelection);
                    }
                    else
                    {
                        GXDLMSObject obj = settings.Objects.FindByLN(ci, GXCommon.ToLogicalName(ln));
                        if (obj == null)
                        {
                            obj = server.NotifyFindObject(ci, 0, GXCommon.ToLogicalName(ln));
                        }
                        if (obj == null)
                        {
                            // "Access Error : Device reports a undefined object."
                            e       = new ValueEventArgs(server, obj, attributeIndex, 0, 0);
                            e.Error = ErrorCode.UndefinedObject;
                            list.Add(e);
                        }
                        else
                        {
                            ValueEventArgs arg = new ValueEventArgs(server, obj, attributeIndex, selector, parameters);
                            arg.InvokeId = invokeID;
                            if (server.NotifyGetAttributeAccess(arg) == AccessMode.NoAccess)
                            {
                                //Read Write denied.
                                arg.Error = ErrorCode.ReadWriteDenied;
                                list.Add(arg);
                            }
                            else
                            {
                                list.Add(arg);
                            }
                        }
                    }
                }
                cnt = GXCommon.GetObjectCount(data);
                if (xml != null)
                {
                    xml.AppendEndTag(TranslatorTags.AttributeDescriptorList);
                    xml.AppendStartTag(TranslatorTags.ValueList, "Qty", xml.IntegerToHex(cnt, 2));
                }
                for (int pos = 0; pos != cnt; ++pos)
                {
                    GXDataInfo di = new GXDataInfo();
                    di.xml = xml;
                    if (xml != null && xml.OutputType == TranslatorOutputType.StandardXml)
                    {
                        xml.AppendStartTag(Command.WriteRequest, SingleReadResponse.Data);
                    }
                    object 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);
                    }
                    if (xml != null && xml
                        .OutputType == TranslatorOutputType.StandardXml)
                    {
                        xml.AppendEndTag(Command.WriteRequest, SingleReadResponse.Data);
                    }
                }
                if (xml != null)
                {
                    xml.AppendEndTag(TranslatorTags.ValueList);
                }
            }
            catch (Exception ex)
            {
                if (xml == null)
                {
                    throw ex;
                }
            }
        }
Esempio n. 36
0
        /// <summary>
        /// Handle read request.
        /// </summary>
        /// <param name="settings">DLMS settings.</param>
        /// <param name="server">DLMS server.</param>
        /// <param name="data">Received data.</param>
        public static void HandleReadRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            GXByteBuffer          bb      = new GXByteBuffer();
            int                   cnt     = 0xFF;
            byte                  type    = 0;
            List <ValueEventArgs> list    = new List <ValueEventArgs>();
            List <ValueEventArgs> reads   = new List <ValueEventArgs>();
            List <ValueEventArgs> actions = new List <ValueEventArgs>();

            //If get next frame.
            if (xml == null && data.Size == 0)
            {
                if (server.transaction != null)
                {
                    return;
                }
                bb.Set(replyData);
                replyData.Clear();
                foreach (ValueEventArgs it in server.transaction.targets)
                {
                    list.Add(it);
                }
            }
            else
            {
                cnt = GXCommon.GetObjectCount(data);
                if (xml != null)
                {
                    xml.AppendStartTag(Command.ReadRequest, "Qty", xml.IntegerToHex(cnt, 2));
                }

                for (int pos = 0; pos != cnt; ++pos)
                {
                    type = data.GetUInt8();
                    if (type == (byte)VariableAccessSpecification.VariableName ||
                        type == (byte)VariableAccessSpecification.ParameterisedAccess)
                    {
                        HandleRead(settings, server, type, data, list, reads, actions, replyData, xml);
                    }
                    else if (type == (byte)VariableAccessSpecification.BlockNumberAccess)
                    {
                        HandleReadBlockNumberAccess(settings, server, data, replyData, xml);
                        if (xml != null)
                        {
                            xml.AppendEndTag(Command.ReadRequest);
                        }
                        return;
                    }
                    else if (type == (byte)VariableAccessSpecification.ReadDataBlockAccess)
                    {
                        HandleReadDataBlockAccess(settings, server, Command.ReadResponse, data, cnt, replyData, xml);
                        if (xml != null)
                        {
                            xml.AppendEndTag(Command.ReadRequest);
                        }
                        return;
                    }
                    else
                    {
                        ReturnSNError(settings, server, Command.ReadResponse, ErrorCode.ReadWriteDenied, replyData);
                        if (xml != null)
                        {
                            xml.AppendEndTag(Command.ReadRequest);
                        }
                        return;
                    }
                }
                if (reads.Count != 0)
                {
                    server.NotifyRead(reads.ToArray());
                }

                if (actions.Count != 0)
                {
                    server.NotifyAction(actions.ToArray());
                }
            }
            if (xml != null)
            {
                xml.AppendEndTag(Command.ReadRequest);
                return;
            }

            byte requestType = (byte)GetReadData(settings, list.ToArray(), bb);

            if (reads.Count != 0)
            {
                server.NotifyPostRead(reads.ToArray());
            }

            if (actions.Count != 0)
            {
                server.NotifyPostAction(actions.ToArray());
            }

            GXDLMSSNParameters p = new GXDLMSSNParameters(settings, Command.ReadResponse, list.Count, requestType, null, bb);

            GXDLMS.GetSNPdu(p, replyData);
            if (server.transaction == null && (bb.Size != bb.Position || settings.Count != settings.Index))
            {
                reads = new List <ValueEventArgs>();
                foreach (var it in list)
                {
                    reads.Add(it);
                }
                server.transaction = new GXDLMSLongTransaction(reads.ToArray(), Command.ReadRequest, bb);
            }
            else if (server.transaction != null)
            {
                replyData.Set(bb);
                return;
            }
        }
        ///<summary>
        /// Handle write request.
        ///</summary>
        ///<param name="Reply">
        /// Received data from the client.
        /// </param>
        ///<returns>
        /// Reply.
        ///</returns>
        public static void HandleWriteRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data,
                                              GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            //Return error if connection is not established.
            if (xml == null && !settings.Connected)
            {
                replyData.Add(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                              ServiceError.Service, (byte)Service.Unsupported));
                return;
            }
            short type;
            object value;
            // Get object count.
            List<GXSNInfo> targets = new List<GXSNInfo>();
            int cnt = GXCommon.GetObjectCount(data);
            if (xml != null)
            {
                xml.AppendStartTag(Command.WriteRequest);
                xml.AppendStartTag(
                    TranslatorTags.ListOfVariableAccessSpecification, "Qty",
                    xml.IntegerToHex(cnt, 2));
                if (xml.OutputType == TranslatorOutputType.StandardXml)
                {
                    xml.AppendStartTag(
                        TranslatorTags.VariableAccessSpecification);
                }
            }
            GXByteBuffer results = new GXByteBuffer((ushort)cnt);
            for (int pos = 0; pos != cnt; ++pos)
            {
                type = data.GetUInt8();
                if (type == (byte)VariableAccessSpecification.VariableName)
                {
                    int sn = data.GetUInt16();
                    if (xml != null)
                    {
                        xml.AppendLine(
                            (int)Command.WriteRequest << 8
                            | (int)VariableAccessSpecification.VariableName,
                            "Value", xml.IntegerToHex(sn, 4));
                    }
                    else
                    {
                        GXSNInfo info = FindSNObject(server, sn);
                        targets.Add(info);
                        // If target is unknown.
                        if (info == null)
                        {
                            // Device reports a undefined object.
                            results.SetUInt8(ErrorCode.UndefinedObject);
                        }
                        else
                        {
                            results.SetUInt8(ErrorCode.Ok);
                        }
                    }
                }
                else if (type == (byte)VariableAccessSpecification.WriteDataBlockAccess)
                {
                    HandleReadDataBlockAccess(settings, server, Command.WriteResponse, data, cnt, replyData, xml);
                    if (xml == null)
                    {
                        return;
                    }
                }
                else
                {
                    // Device reports a HW error.
                    results.SetUInt8(ErrorCode.HardwareFault);
                }
            }

            if (xml != null)
            {
                if (xml.OutputType == TranslatorOutputType.StandardXml)
                {
                    xml.AppendEndTag(TranslatorTags.VariableAccessSpecification);
                }
                xml.AppendEndTag(
                    TranslatorTags.ListOfVariableAccessSpecification);
            }
            // Get data count.
            cnt = GXCommon.GetObjectCount(data);
            GXDataInfo di = new GXDataInfo();
            di.xml = xml;
            if (xml != null)
            {
                xml.AppendStartTag(TranslatorTags.ListOfData, "Qty", xml.IntegerToHex(cnt, 2));
            }
            for (int pos = 0; pos != cnt; ++pos)
            {
                di.Clear();
                if (xml != null)
                {
                    if (xml.OutputType == TranslatorOutputType.StandardXml)
                    {
                        xml.AppendStartTag(Command.WriteRequest,
                                           SingleReadResponse.Data);
                    }
                    value = GXCommon.GetData(settings, data, di);
                    if (!di.Complete)
                    {
                        value = GXCommon.ToHex(data.Data, false,
                                               data.Position, data.Size - data.Position);
                        xml.AppendLine(
                            GXDLMS.DATA_TYPE_OFFSET + (int)di.Type,
                            "Value", value.ToString());
                    }
                    if (xml.OutputType == TranslatorOutputType.StandardXml)
                    {
                        xml.AppendEndTag(Command.WriteRequest, SingleReadResponse.Data);
                    }
                    GXCommon.GetData(settings, data, di);
                }
                else if (results.GetUInt8(pos) == 0)
                {
                    // If object has found.
                    GXSNInfo target = targets[pos];
                    value = GXCommon.GetData(settings, data, di);
                    if (value is byte[])
                    {
                        DataType dt = target.Item.GetDataType(target.Index);
                        if (dt != DataType.None && dt != DataType.OctetString)
                        {
                            value = GXDLMSClient.ChangeType((byte[])value, dt);
                        }
                    }
                    AccessMode am = target.Item.GetAccess(target.Index);
                    // If write is denied.
                    if (am != AccessMode.Write && am != AccessMode.ReadWrite)
                    {
                        results.SetUInt8((byte)pos, (byte)ErrorCode.ReadWriteDenied);
                    }
                    else
                    {
                        ValueEventArgs e = new ValueEventArgs(settings, target.Item, target.Index, 0, null);
                        e.Value = value;
                        server.NotifyWrite(new ValueEventArgs[] { e });
                        if (e.Error != 0)
                        {
                            results.SetUInt8((byte)pos, (byte)e.Error);
                        }
                        else if (!e.Handled)
                        {
                            (target.Item as IGXDLMSBase).SetValue(settings, e);
                        }
                    }
                }
            }
            if (xml != null)
            {
                xml.AppendEndTag(TranslatorTags.ListOfData);
                xml.AppendEndTag(Command.WriteRequest);
                return;
            }
            GenerateWriteResponse(settings, results, replyData);
        }
Esempio n. 38
0
        ///<summary>
        /// Handle action request.
        ///</summary>
        public static void HandleMethodRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXDLMSConnectionEventArgs connectionInfo, GXByteBuffer replyData, GXDLMSTranslatorStructure xml)
        {
            ErrorCode    error = ErrorCode.Ok;
            GXByteBuffer bb    = new GXByteBuffer();
            // Get type.
            ActionRequestType type = (ActionRequestType)data.GetUInt8();
            // Get invoke ID and priority.
            byte invokeId = data.GetUInt8();

            settings.UpdateInvokeId(invokeId);
            // CI
            ObjectType ci = (ObjectType)data.GetUInt16();

            byte[] ln = new byte[6];
            data.Get(ln);
            // Attribute Id
            byte id = data.GetUInt8();
            // Get parameters.
            object parameters = null;
            byte   selection  = data.GetUInt8();

            if (xml != null)
            {
                xml.AppendStartTag(Command.MethodRequest);
                if (type == ActionRequestType.Normal)
                {
                    xml.AppendStartTag(Command.MethodRequest, ActionRequestType.Normal);
                    xml.AppendLine(TranslatorTags.InvokeId, "Value", xml.IntegerToHex(invokeId, 2));
                    AppendMethodDescriptor(xml, (int)ci, ln, id);
                    if (selection != 0)
                    {
                        //MethodInvocationParameters
                        xml.AppendStartTag(TranslatorTags.MethodInvocationParameters);
                        GXDataInfo di = new GXDataInfo();
                        di.xml = xml;
                        GXCommon.GetData(settings, data, di);
                        xml.AppendEndTag(TranslatorTags.MethodInvocationParameters);
                    }
                    xml.AppendEndTag(Command.MethodRequest, ActionRequestType.Normal);
                }
                xml.AppendEndTag(Command.MethodRequest);
                return;
            }
            if (selection != 0)
            {
                GXDataInfo info = new GXDataInfo();
                parameters = GXCommon.GetData(settings, data, info);
            }

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

            if (settings.Connected == ConnectionState.None && !settings.CanAccess() && (ci != ObjectType.AssociationLogicalName || id != 1))
            {
                replyData.Set(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                                                                         ServiceError.Service, (byte)Service.Unsupported));
                return;
            }

            if (obj == null)
            {
                obj = server.NotifyFindObject(ci, 0, GXCommon.ToLogicalName(ln));
            }
            if (obj == null)
            {
                // Device reports a undefined object.
                error = ErrorCode.UndefinedObject;
            }
            else
            {
                ValueEventArgs e = new ValueEventArgs(server, obj, id, 0, parameters);
                e.InvokeId = invokeId;
                if (server.NotifyGetMethodAccess(e) == MethodAccessMode.NoAccess)
                {
                    error = ErrorCode.ReadWriteDenied;
                }
                else
                {
                    server.NotifyAction(new ValueEventArgs[] { e });
                    byte[] actionReply;
                    if (e.Handled)
                    {
                        actionReply = (byte[])e.Value;
                    }
                    else
                    {
                        actionReply = (obj as IGXDLMSBase).Invoke(settings, e);
                        server.NotifyPostAction(new ValueEventArgs[] { e });
                    }
                    //Set default action reply if not given.
                    if (actionReply != null && e.Error == 0)
                    {
                        //Add return parameters
                        bb.SetUInt8(1);
                        //Add parameters error code.
                        bb.SetUInt8(0);
                        GXCommon.SetData(settings, bb, GXDLMSConverter.GetDLMSDataType(actionReply), actionReply);
                    }
                    else
                    {
                        error = e.Error;
                        //Add return parameters
                        bb.SetUInt8(0);
                    }
                }
                invokeId = (byte)e.InvokeId;
            }

            GXDLMSLNParameters p = new GXDLMSLNParameters(null, settings, invokeId, Command.MethodResponse, 1, null, bb, (byte)error);

            GXDLMS.GetLNPdu(p, replyData);
            //If High level authentication fails.
            if (obj is GXDLMSAssociationLogicalName && id == 1)
            {
                if ((obj as GXDLMSAssociationLogicalName).AssociationStatus == Objects.Enums.AssociationStatus.Associated)
                {
                    server.NotifyConnected(connectionInfo);
                    settings.Connected |= ConnectionState.Dlms;
                }
                else
                {
                    server.NotifyInvalidConnection(connectionInfo);
                    settings.Connected &= ~ConnectionState.Dlms;
                }
            }
        }
        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;
                    }
                }
            }
        }
 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;
 }
        ///<summary>
        /// Handle Access request.
        ///</summary>
        ///<param name="Reply">
        /// Received data from the client.
        /// </param>
        ///<returns>
        /// Reply.
        ///</returns>
        public static void HandleAccessRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data,
                                               GXByteBuffer reply, GXDLMSTranslatorStructure xml)
        {
            //Return error if connection is not established.
            if (xml == null && !settings.Connected)
            {
                reply.Set(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                          ServiceError.Service, (byte)Service.Unsupported));
                return;
            }
            //Get long invoke id and priority.
            UInt32 invokeId = data.GetUInt32();
            int len = GXCommon.GetObjectCount(data);
            byte[] tmp = null;
            // If date time is given.
            if (len != 0)
            {
                tmp = new byte[len];
                data.Get(tmp);
                if (xml == null)
                {
                    DataType dt = DataType.DateTime;
                    if (len == 4)
                    {
                        dt = DataType.Time;
                    }
                    else if (len == 5)
                    {
                        dt = DataType.Date;
                    }
                    GXDataInfo info = new GXDataInfo();
                    info.Type = dt;
                    GXCommon.GetData(settings, new GXByteBuffer(tmp), info);

                }
            }
            // Get object count.
            int cnt = GXCommon.GetObjectCount(data);
            if (xml != null)
            {
                xml.AppendStartTag(Command.AccessRequest);
                xml.AppendLine(TranslatorTags.LongInvokeId, "Value", xml.IntegerToHex(invokeId, 2));
                xml.AppendLine(TranslatorTags.DateTime, "Value", GXCommon.ToHex(tmp, false));
                xml.AppendStartTag(TranslatorTags.AccessRequestBody);
                xml.AppendStartTag(TranslatorTags.ListOfAccessRequestSpecification, "Qty",
                                   xml.IntegerToHex(cnt, 2));
            }
            AccessServiceCommandType type;
            for (int pos = 0; pos != cnt; ++pos)
            {
                type = (AccessServiceCommandType)data.GetUInt8();
                if (!(type == AccessServiceCommandType.Get ||
                        type == AccessServiceCommandType.Set ||
                        type == AccessServiceCommandType.Action))
                {
                    throw new ArgumentException("Invalid access service command type.");
                }
                // CI
                ObjectType ci = (ObjectType)data.GetUInt16();
                byte[] ln = new byte[6];
                data.Get(ln);
                // Attribute Id
                byte attributeIndex = data.GetUInt8();
                if (xml != null)
                {
                    xml.AppendStartTag(TranslatorTags.AccessRequestSpecification);
                    xml.AppendStartTag(Command.AccessRequest, type);
                    AppendAttributeDescriptor(xml, (int)ci, ln, attributeIndex);
                    xml.AppendEndTag(Command.AccessRequest, type);
                    xml.AppendEndTag(TranslatorTags.AccessRequestSpecification);

                }
            }
            if (xml != null)
            {
                xml.AppendEndTag(TranslatorTags.ListOfAccessRequestSpecification);
                xml.AppendStartTag(TranslatorTags.AccessRequestListOfData, "Qty", xml.IntegerToHex(cnt, 2));
            }
            // Get data count.
            cnt = GXCommon.GetObjectCount(data);
            for (int pos = 0; pos != cnt; ++pos)
            {

                GXDataInfo di = new GXDataInfo();
                di.xml = xml;
                if (xml != null && xml.OutputType == TranslatorOutputType.StandardXml)
                {
                    xml.AppendStartTag(Command.WriteRequest, SingleReadResponse.Data);
                }
                object 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);
                }
                if (xml != null && xml
                        .OutputType == TranslatorOutputType.StandardXml)
                {
                    xml.AppendEndTag(Command.WriteRequest, SingleReadResponse.Data);
                }
            }
            if (xml != null)
            {
                xml.AppendEndTag(TranslatorTags.AccessRequestListOfData);
                xml.AppendEndTag(TranslatorTags.AccessRequestBody);
                xml.AppendEndTag(Command.AccessRequest);
            }
        }
Esempio n. 42
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;
                    }
                }
            }
        }
Esempio n. 43
0
        ///<summary>
        /// Handle write request.
        ///</summary>
        ///<param name="Reply">
        /// Received data from the client.
        /// </param>
        ///<returns>
        /// Reply.
        ///</returns>
        private byte[][] HandleWriteRequest()
        {
            GXByteBuffer data = Reply.Data;
            short        type;
            object       value;
            // Get object count.
            IList <GXSNInfo> targets = new List <GXSNInfo>();
            int          cnt         = GXCommon.GetObjectCount(data);
            GXByteBuffer results     = new GXByteBuffer((ushort)cnt);

            for (int pos = 0; pos != cnt; ++pos)
            {
                type = data.GetUInt8();
                if (type == 2)
                {
                    int      sn   = data.GetUInt16();
                    GXSNInfo info = FindSNObject(sn);
                    targets.Add(info);
                    // If target is unknown.
                    if (info == null)
                    {
                        // Device reports a undefined object.
                        results.SetUInt8(ErrorCode.UndefinedObject);
                    }
                    else
                    {
                        results.SetUInt8(ErrorCode.Ok);
                    }
                }
                else
                {
                    // Device reports a HW error.
                    results.SetUInt8(ErrorCode.HardwareFault);
                }
            }
            // Get data count.
            cnt = GXCommon.GetObjectCount(data);
            GXDataInfo di = new GXDataInfo();

            for (int pos = 0; pos != cnt; ++pos)
            {
                if (results.GetUInt8(pos) == 0)
                {
                    // If object has found.
                    GXSNInfo target = targets[pos];
                    value = GXCommon.GetData(data, di);
                    if (value is byte[])
                    {
                        DataType dt = target.Item.GetDataType(target.Index);
                        if (dt != DataType.None && dt != DataType.OctetString)
                        {
                            value = GXDLMSClient.ChangeType((byte[])value, dt);
                        }
                    }
                    di.Clear();
                    AccessMode am = target.Item.GetAccess(target.Index);
                    // If write is denied.
                    if (am != AccessMode.Write && am != AccessMode.ReadWrite)
                    {
                        results.SetUInt8((byte)pos, (byte)ErrorCode.ReadWriteDenied);
                    }
                    else
                    {
                        ValueEventArgs e = new ValueEventArgs(target.Item, target.Index, 0, null);
                        e.Value = value;
                        Write(e);
                        if (!e.Handled)
                        {
                            (target.Item as IGXDLMSBase).SetValue(Settings, target.Index, value);
                        }
                    }
                }
            }
            GXByteBuffer bb = new GXByteBuffer((UInt16)(2 * cnt + 2));

            GXCommon.SetObjectCount(cnt, bb);
            byte ret;

            for (int pos = 0; pos != cnt; ++pos)
            {
                ret = results.GetUInt8(pos);
                // If meter returns error.
                if (ret != 0)
                {
                    bb.SetUInt8(1);
                }
                bb.SetUInt8(ret);
            }
            return(GXDLMS.SplitPdu(Settings, Command.WriteResponse, 1, bb, ErrorCode.Ok, DateTime.MinValue)[0]);
        }
Esempio n. 44
0
        ///<summary>
        /// Handle Access request.
        ///</summary>
        public static void HandleAccessRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data,
                                               GXByteBuffer reply, GXDLMSTranslatorStructure xml)
        {
            //Return error if connection is not established.
            if (xml == null && settings.Connected == ConnectionState.None && !settings.CanAccess())
            {
                reply.Set(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                                                                     ServiceError.Service, (byte)Service.Unsupported));
                return;
            }
            //Get long invoke id and priority.
            UInt32 invokeId = data.GetUInt32();

            settings.longInvokeID = invokeId;
            int len = GXCommon.GetObjectCount(data);

            byte[] tmp = null;
            // If date time is given.
            if (len != 0)
            {
                tmp = new byte[len];
                data.Get(tmp);
                if (xml == null)
                {
                    DataType dt = DataType.DateTime;
                    if (len == 4)
                    {
                        dt = DataType.Time;
                    }
                    else if (len == 5)
                    {
                        dt = DataType.Date;
                    }
                    GXDataInfo info = new GXDataInfo();
                    info.Type = dt;
                    GXCommon.GetData(settings, new GXByteBuffer(tmp), info);
                }
            }
            // Get object count.
            int cnt = GXCommon.GetObjectCount(data);

            if (xml != null)
            {
                xml.AppendStartTag(Command.AccessRequest);
                xml.AppendLine(TranslatorTags.LongInvokeId, "Value", xml.IntegerToHex(invokeId, 2));
                xml.AppendLine(TranslatorTags.DateTime, "Value", GXCommon.ToHex(tmp, false));
                xml.AppendStartTag(TranslatorTags.AccessRequestBody);
                xml.AppendStartTag(TranslatorTags.ListOfAccessRequestSpecification, "Qty",
                                   xml.IntegerToHex(cnt, 2));
            }
            AccessServiceCommandType type;

            for (int pos = 0; pos != cnt; ++pos)
            {
                type = (AccessServiceCommandType)data.GetUInt8();
                if (!(type == AccessServiceCommandType.Get ||
                      type == AccessServiceCommandType.Set ||
                      type == AccessServiceCommandType.Action))
                {
                    throw new ArgumentException("Invalid access service command type.");
                }
                // CI
                ObjectType ci = (ObjectType)data.GetUInt16();
                byte[]     ln = new byte[6];
                data.Get(ln);
                // Attribute Id
                byte attributeIndex = data.GetUInt8();
                if (xml != null)
                {
                    xml.AppendStartTag(TranslatorTags.AccessRequestSpecification);
                    xml.AppendStartTag(Command.AccessRequest, type);
                    AppendAttributeDescriptor(xml, (int)ci, ln, attributeIndex);
                    xml.AppendEndTag(Command.AccessRequest, type);
                    xml.AppendEndTag(TranslatorTags.AccessRequestSpecification);
                }
            }
            if (xml != null)
            {
                xml.AppendEndTag(TranslatorTags.ListOfAccessRequestSpecification);
                xml.AppendStartTag(TranslatorTags.AccessRequestListOfData, "Qty", xml.IntegerToHex(cnt, 2));
            }
            // Get data count.
            cnt = GXCommon.GetObjectCount(data);
            for (int pos = 0; pos != cnt; ++pos)
            {
                GXDataInfo di = new GXDataInfo();
                di.xml = xml;
                if (xml != null && xml.OutputType == TranslatorOutputType.StandardXml)
                {
                    xml.AppendStartTag(Command.WriteRequest, SingleReadResponse.Data);
                }
                object 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);
                }
                if (xml != null && xml
                    .OutputType == TranslatorOutputType.StandardXml)
                {
                    xml.AppendEndTag(Command.WriteRequest, SingleReadResponse.Data);
                }
            }
            if (xml != null)
            {
                xml.AppendEndTag(TranslatorTags.AccessRequestListOfData);
                xml.AppendEndTag(TranslatorTags.AccessRequestBody);
                xml.AppendEndTag(Command.AccessRequest);
            }
        }
Esempio n. 45
0
 /// <summary>
 /// Identify used DLMS framing type.
 /// </summary>
 /// <param name="value">Input data.</param>
 /// <returns>Interface type.</returns>
 public static InterfaceType GetDlmsFraming(GXByteBuffer value)
 {
     for (int pos = value.Position; pos != value.Size; ++pos)
     {
         if (value.GetUInt8(pos) == 0x7e)
         {
             return InterfaceType.HDLC;
         }
         if (value.GetUInt16(pos) == 1)
         {
             return InterfaceType.WRAPPER;
         }
     }
     throw new ArgumentException("Invalid DLMS framing.");
 }