Beispiel #1
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);
            }
        }
Beispiel #2
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);
        }
Beispiel #3
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);
            }
        }
Beispiel #4
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;
                }
            }
        }
Beispiel #5
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 == ConnectionState.None && !settings.CanAccess() && (!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);
                }
            }
        }
Beispiel #6
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 == ConnectionState.None && !settings.CanAccess())
            {
                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);
                    }
                }
                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);
        }