Server uses this class to find Short Name object and attribute index. This class is reserved for internal use.
示例#1
0
        private static void HandleRead(GXDLMSSettings settings, GXDLMSServer server, byte type, GXByteBuffer data,
                                       List <ValueEventArgs> list, List <ValueEventArgs> reads,
                                       GXByteBuffer replyData, GXDLMSTranslatorStructure xml, Command cipheredCommand)
        {
            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.Dlms) == 0 && cipheredCommand == Command.None && (!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
            {
                reads.Add(e);
            }
        }
示例#2
0
        ///<summary>
        /// Handle write request.
        ///</summary>
        public static void HandleWriteRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data,
                                              GXByteBuffer replyData, GXDLMSTranslatorStructure xml, Command cipheredCommand)
        {
            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);
                }
            }
            GXDataInfo   di;
            GXSNInfo     info;
            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
                                | type,
                                "Value", xml.IntegerToHex(sn, 4));
                    }
                    else
                    {
                        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)
                {
                    //Return error if connection is not established.
                    if (xml == null && (settings.Connected & ConnectionState.Dlms) == 0 && cipheredCommand == Command.None)
                    {
                        replyData.Add(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError,
                                                                                 ServiceError.Service, (byte)Service.Unsupported));
                        return;
                    }
                    HandleReadDataBlockAccess(settings, server, Command.WriteResponse, data, cnt, replyData, xml, cipheredCommand);
                    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);
            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)
                {
                    bool access = true;
                    // If object has found.
                    GXSNInfo target = targets[pos];
                    value = GXCommon.GetData(settings, data, di);
                    ValueEventArgs e = new ValueEventArgs(server, target.Item, target.Index, 0, null);
                    if (target.IsAction)
                    {
                        MethodAccessMode am = server.NotifyGetMethodAccess(e);
                        // If action is denied.
                        if (am != MethodAccessMode.Access)
                        {
                            access = false;
                        }
                    }
                    else
                    {
                        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);
                            }
                        }
                        AccessMode am = server.NotifyGetAttributeAccess(e);
                        // If write is denied.
                        if (am != AccessMode.Write && am != AccessMode.ReadWrite)
                        {
                            access = false;
                        }
                    }
                    if (access)
                    {
                        if (target.IsAction)
                        {
                            e.Parameters = value;
                            ValueEventArgs[] actions = new ValueEventArgs[] { e };
                            server.NotifyAction(actions);
                            if (!e.Handled)
                            {
                                byte[] reply = (target.Item as IGXDLMSBase).Invoke(settings, e);
                                server.NotifyPostAction(actions);
                                if (target.Item is GXDLMSAssociationShortName && target.Index == 8 && reply != null)
                                {
                                    GXByteBuffer bb = new GXByteBuffer();
                                    bb.SetUInt8((byte)DataType.OctetString);
                                    bb.SetUInt8((byte)reply.Length);
                                    bb.Set(reply);
                                    GXDLMSSNParameters p = new GXDLMSSNParameters(settings, Command.ReadResponse, 1, 0, null, bb);
                                    GXDLMS.GetSNPdu(p, replyData);
                                }
                            }
                        }
                        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 });
                            }
                        }
                    }
                    else
                    {
                        results.SetUInt8((byte)pos, (byte)ErrorCode.ReadWriteDenied);
                    }
                }
            }
            if (xml != null)
            {
                xml.AppendEndTag(TranslatorTags.ListOfData);
                xml.AppendEndTag(Command.WriteRequest);
                return;
            }
            GenerateWriteResponse(settings, results, replyData);
        }
示例#3
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]);
        }
示例#4
0
        /// <summary>
        /// Handle Information Report.
        /// </summary>
        /// <param name="settings">DLMS settings.</param>
        /// <param name="reply"></param>
        /// <returns></returns>
        public static void HandleInformationReport(GXDLMSSettings settings, GXReplyData reply, List <KeyValuePair <GXDLMSObject, int> > list)
        {
            reply.Time = DateTime.MinValue;
            int len = reply.Data.GetUInt8();

            byte[] tmp = null;
            // If date time is given.
            if (len != 0)
            {
                tmp = new byte[len];
                reply.Data.Get(tmp);
                reply.Time = (GXDateTime)GXDLMSClient.ChangeType(tmp, DataType.DateTime, settings.UseUtc2NormalTime);
            }
            byte type;
            int  count = GXCommon.GetObjectCount(reply.Data);

            if (reply.Xml != null)
            {
                reply.Xml.AppendStartTag(Command.InformationReport);
                if (reply.Time != DateTime.MinValue)
                {
                    reply.Xml.AppendComment(Convert.ToString(reply.Time));
                    if (reply.Xml.OutputType == TranslatorOutputType.SimpleXml)
                    {
                        reply.Xml.AppendLine(TranslatorTags.CurrentTime, null, GXCommon.ToHex(tmp, false));
                    }
                    else
                    {
                        reply.Xml.AppendLine(TranslatorTags.CurrentTime, null,
                                             GXCommon.GeneralizedTime(reply.Time));
                    }
                }
                reply.Xml.AppendStartTag(TranslatorTags.ListOfVariableAccessSpecification, "Qty", reply.Xml.IntegerToHex(count, 2));
            }
            for (int pos = 0; pos != count; ++pos)
            {
                type = reply.Data.GetUInt8();
                if (type == (byte)VariableAccessSpecification.VariableName)
                {
                    int sn = reply.Data.GetUInt16();
                    if (reply.Xml != null)
                    {
                        reply.Xml.AppendLine(
                            (int)Command.WriteRequest << 8
                                | (int)VariableAccessSpecification.VariableName,
                                "Value", reply.Xml.IntegerToHex(sn, 4));
                    }
                    else
                    {
                        GXSNInfo info = FindSNObject(settings.Objects, sn);
                        if (info.Item != null)
                        {
                            list.Add(new KeyValuePair <GXDLMSObject, int>(info.Item, info.Index));
                        }
                        else
                        {
                            System.Diagnostics.Debug.WriteLine(string.Format("Unknown object : {0}.", sn));
                        }
                    }
                }
            }
            if (reply.Xml != null)
            {
                reply.Xml.AppendEndTag(TranslatorTags.ListOfVariableAccessSpecification);
                reply.Xml.AppendStartTag(TranslatorTags.ListOfData, "Qty", reply.Xml.IntegerToHex(count, 2));
            }
            //Get values.
            count = GXCommon.GetObjectCount(reply.Data);
            GXDataInfo di = new GXDataInfo();

            di.xml = reply.Xml;
            for (int pos = 0; pos != count; ++pos)
            {
                di.Clear();
                if (reply.Xml != null)
                {
                    GXCommon.GetData(settings, reply.Data, di);
                }
                else
                {
                    ValueEventArgs v = new ValueEventArgs(list[pos].Key, list[pos].Value, 0, null);
                    v.Value = GXCommon.GetData(settings, reply.Data, di);
                    (list[pos].Key as IGXDLMSBase).SetValue(settings, v);
                }
            }
            if (reply.Xml != null)
            {
                reply.Xml.AppendEndTag(TranslatorTags.ListOfData);
                reply.Xml.AppendEndTag(Command.InformationReport);
            }
        }
 internal static GXSNInfo FindSNObject(GXDLMSObjectCollection items, int sn)
 {
     GXSNInfo i = new GXSNInfo();
     int offset, count;
     foreach (GXDLMSObject it in items)
     {
         if (sn >= it.ShortName)
         {
             //If attribute is accessed.
             if (sn < it.ShortName + (it as IGXDLMSBase).GetAttributeCount() * 8)
             {
                 i.IsAction = false;
                 i.Item = it;
                 i.Index = ((sn - i.Item.ShortName) / 8) + 1;
                 break;
             }
             else
             {
                 //If method is accessed.
                 GXDLMS.GetActionInfo(it.ObjectType, out offset, out count);
                 if (sn < it.ShortName + offset + (8 * count))
                 {
                     i.Item = it;
                     i.IsAction = true;
                     i.Index = (sn - it.ShortName - offset) / 8 + 1;
                     break;
                 }
             }
         }
     }
     return i;
 }