/// <summary> /// Generates Push message. /// </summary> /// <param name="objects">List of objects and attribute indexes to push.</param> /// <returns>Generated push message(s).</returns> public byte[][] GeneratePushMessage(DateTime date, List <KeyValuePair <GXDLMSObject, int> > objects) { DataType dt; object value; if (objects == null) { throw new ArgumentNullException("objects"); } GXByteBuffer buff = new GXByteBuffer(); //Add data buff.SetUInt8(DataType.Structure); GXCommon.SetObjectCount(objects.Count, buff); foreach (KeyValuePair <GXDLMSObject, int> it in objects) { dt = it.Key.GetDataType(it.Value); value = (it.Key as IGXDLMSBase).GetValue(Settings, it.Value, 0, null); if (dt == DataType.None && value != null) { dt = GXCommon.GetValueType(value); } GXCommon.SetData(buff, dt, value); } List <byte[][]> list = GXDLMS.SplitPdu(Settings, Command.Push, 0, buff, ErrorCode.Ok, DateTime.MinValue); List <byte[]> arr = new List <byte[]>(); foreach (byte[][] it in list) { arr.AddRange(it); } return(arr.ToArray()); }
object IGXDLMSBase.GetValue(int index, int selector, object parameters) { if (index == 1) { return(this.LogicalName); } if (index == 2) { int cnt = Scripts.Count; List <byte> data = new List <byte>(); data.Add((byte)DataType.Array); //Add count GXCommon.SetObjectCount(cnt, data); if (cnt != 0) { foreach (var it in Scripts) { data.Add((byte)DataType.Structure); data.Add(2); //Count GXCommon.SetData(data, DataType.UInt16, it.Key); //Script_identifier: data.Add((byte)DataType.Array); data.Add(5); //Count GXDLMSScriptAction tmp = it.Value; GXCommon.SetData(data, DataType.Enum, tmp.Type); //service_id GXCommon.SetData(data, DataType.UInt16, tmp.ObjectType); //class_id GXCommon.SetData(data, DataType.OctetString, tmp.LogicalName); //logical_name GXCommon.SetData(data, DataType.Int8, tmp.Index); //index GXCommon.SetData(data, GXCommon.GetValueType(tmp.Parameter), tmp.Parameter); //parameter } } return(data.ToArray()); } throw new ArgumentException("GetValue failed. Invalid attribute index."); }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return(GXCommon.LogicalNameToBytes(LogicalName)); } if (e.Index == 2) { int cnt = Scripts.Count; GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); //Add count GXCommon.SetObjectCount(cnt, data); foreach (GXDLMSScript it in Scripts) { data.SetUInt8((byte)DataType.Structure); data.SetUInt8(2); //Count GXCommon.SetData(settings, data, DataType.UInt16, it.Id); //Script_identifier: data.SetUInt8((byte)DataType.Array); data.SetUInt8((byte)it.Actions.Count); //Count foreach (GXDLMSScriptAction a in it.Actions) { data.SetUInt8((byte)DataType.Structure); //Count data.SetUInt8(5); //service_id GXCommon.SetData(settings, data, DataType.Enum, a.Type); if (a.Target == null) { #pragma warning disable CS0618 //class_id GXCommon.SetData(settings, data, DataType.UInt16, a.ObjectType); //logical_name GXCommon.SetData(settings, data, DataType.OctetString, GXCommon.LogicalNameToBytes(a.LogicalName)); #pragma warning restore CS0618 } else { //class_id GXCommon.SetData(settings, data, DataType.UInt16, a.Target.ObjectType); //logical_name GXCommon.SetData(settings, data, DataType.OctetString, GXCommon.LogicalNameToBytes(a.Target.LogicalName)); } //index GXCommon.SetData(settings, data, DataType.Int8, a.Index); //parameter DataType tp = a.ParameterDataType; if (tp == DataType.None) { tp = GXCommon.GetValueType(a.Parameter); } GXCommon.SetData(settings, data, tp, a.Parameter); } } return(data.Array()); } e.Error = ErrorCode.ReadWriteDenied; return(null); }
/// <summary> /// Add value of COSEM object to byte buffer. /// </summary> /// <param name="obj">COSEM object.</param> /// <param name="index">Attribute index.</param> /// <param name="buff">Byte buffer.</param> /// <remarks> /// AddData method can be used with GetDataNotificationMessage -method. /// DLMS spesification do not specify the structure of Data-Notification body. /// So each manufacture can sent different data. /// </remarks> internal static void AddData(GXDLMSSettings settings, GXDLMSObject obj, int index, GXByteBuffer buff) { DataType dt; object value = (obj as IGXDLMSBase).GetValue(settings, new ValueEventArgs(settings, obj, index, 0, null)); dt = obj.GetDataType(index); if (dt == DataType.None && value != null) { dt = GXCommon.GetValueType(value); } GXCommon.SetData(settings, buff, dt, value); }
/// <summary> /// Get data for Read command. /// </summary> /// <param name="list">received objects.</param> /// <param name="data">Data as byte array.</param> /// <returns>Response type.</returns> private static SingleReadResponse GetReadData(GXDLMSSettings settings, ValueEventArgs[] list, GXByteBuffer data) { object value; bool first = true; SingleReadResponse type = SingleReadResponse.Data; foreach (ValueEventArgs e in list) { if (e.Handled) { value = e.Value; } else { //If action. if (e.action) { value = ((IGXDLMSBase)e.Target).Invoke(settings, e); } else { value = (e.Target as IGXDLMSBase).GetValue(settings, e); } } if (e.Error == 0) { if (!first && list.Length != 1) { data.SetUInt8(SingleReadResponse.Data); } //If action. if (e.action) { GXCommon.SetData(settings, data, GXCommon.GetValueType(value), value); } else { GXDLMS.AppendData(settings, e.Target, e.Index, data, value); } } else { if (!first && list.Length != 1) { data.SetUInt8(SingleReadResponse.DataAccessError); } data.SetUInt8(e.Error); type = SingleReadResponse.DataAccessError; } first = false; } return(type); }
/// <summary> /// Add value of COSEM object to byte buffer. /// </summary> /// <param name="obj">COSEM object.</param> /// <param name="index">Attribute index.</param> /// <param name="buff">Byte buffer.</param> /// <remarks> /// AddData method can be used with GetDataNotificationMessage -method. /// DLMS spesification do not specify the structure of Data-Notification body. /// So each manufacture can sent different data. /// </remarks> /// <seealso cref="GetDataNotificationMessage"/> public void AddData(GXDLMSObject obj, int index, GXByteBuffer buff) { DataType dt; object value = (obj as IGXDLMSBase).GetValue(Settings, index, 0, null); dt = obj.GetDataType(index); if (dt == DataType.None && value != null) { dt = GXCommon.GetValueType(value); } GXCommon.SetData(buff, dt, value); }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return(this.LogicalName); } if (e.Index == 2) { return(MaxHops); } if (e.Index == 3) { return(WeakLqiValue); } if (e.Index == 4) { return(SecurityLevel); } if (e.Index == 5) { GXByteBuffer bb = new GXByteBuffer(); bb.SetUInt8((byte)DataType.Array); if (PrefixTable == null) { bb.SetUInt8(0); } else { GXCommon.SetObjectCount(PrefixTable.Length, bb); foreach (var it in PrefixTable) { GXCommon.SetData(settings, bb, GXCommon.GetValueType(it), it); } } return(bb.Array()); } if (e.Index == 6) { GXByteBuffer bb = new GXByteBuffer(); bb.SetUInt8((byte)DataType.Array); if (RoutingConfiguration == null) { bb.SetUInt8(0); } else { GXCommon.SetObjectCount(RoutingConfiguration.Count, bb); foreach (GXDLMSRoutingConfiguration it in RoutingConfiguration) { bb.SetUInt8((byte)DataType.Structure); bb.SetUInt8(14); GXCommon.SetData(settings, bb, DataType.UInt8, it.NetTraversalTime); GXCommon.SetData(settings, bb, DataType.UInt16, it.RoutingTableEntryTtl); GXCommon.SetData(settings, bb, DataType.UInt8, it.Kr); GXCommon.SetData(settings, bb, DataType.UInt8, it.Km); GXCommon.SetData(settings, bb, DataType.UInt8, it.Kc); GXCommon.SetData(settings, bb, DataType.UInt8, it.Kq); GXCommon.SetData(settings, bb, DataType.UInt8, it.Kh); GXCommon.SetData(settings, bb, DataType.UInt8, it.Krt); GXCommon.SetData(settings, bb, DataType.UInt8, it.RreqRetries); GXCommon.SetData(settings, bb, DataType.UInt8, it.RreqRerrWait); GXCommon.SetData(settings, bb, DataType.UInt16, it.BlacklistTableEntryTtl); GXCommon.SetData(settings, bb, DataType.Boolean, it.UnicastRreqGenEnable); GXCommon.SetData(settings, bb, DataType.Boolean, it.RlcEnabled); GXCommon.SetData(settings, bb, DataType.UInt8, it.AddRevLinkCost); } } return(bb.Array()); } if (e.Index == 7) { return(BroadcastLogTableEntryTtl); } if (e.Index == 8) { GXByteBuffer bb = new GXByteBuffer(); bb.SetUInt8((byte)DataType.Array); if (RoutingTable == null) { bb.SetUInt8(0); } else { GXCommon.SetObjectCount(RoutingTable.Count, bb); foreach (GXDLMSRoutingTable it in RoutingTable) { bb.SetUInt8((byte)DataType.Structure); bb.SetUInt8(6); GXCommon.SetData(settings, bb, DataType.UInt16, it.DestinationAddress); GXCommon.SetData(settings, bb, DataType.UInt16, it.NextHopAddress); GXCommon.SetData(settings, bb, DataType.UInt16, it.RouteCost); GXCommon.SetData(settings, bb, DataType.UInt8, it.HopCount); GXCommon.SetData(settings, bb, DataType.UInt8, it.WeakLinkCount); GXCommon.SetData(settings, bb, DataType.UInt16, it.ValidTime); } } return(bb.Array()); } if (e.Index == 9) { GXByteBuffer bb = new GXByteBuffer(); bb.SetUInt8((byte)DataType.Array); if (ContextInformationTable == null) { bb.SetUInt8(0); } else { GXCommon.SetObjectCount(ContextInformationTable.Count, bb); foreach (GXDLMSContextInformationTable it in ContextInformationTable) { bb.SetUInt8((byte)DataType.Structure); bb.SetUInt8(5); GXCommon.SetData(settings, bb, DataType.BitString, it.CID); if (it.Context == null) { GXCommon.SetData(settings, bb, DataType.UInt8, 0); } else { GXCommon.SetData(settings, bb, DataType.UInt8, it.Context.Length); } GXCommon.SetData(settings, bb, DataType.OctetString, it.Context); GXCommon.SetData(settings, bb, DataType.Boolean, it.Compression); GXCommon.SetData(settings, bb, DataType.UInt16, it.ValidLifetime); } } return(bb.Array()); } if (e.Index == 10) { GXByteBuffer bb = new GXByteBuffer(); bb.SetUInt8((byte)DataType.Array); if (BlacklistTable == null) { bb.SetUInt8(0); } else { GXCommon.SetObjectCount(BlacklistTable.Count, bb); foreach (var it in BlacklistTable) { bb.SetUInt8((byte)DataType.Structure); bb.SetUInt8(2); GXCommon.SetData(settings, bb, DataType.UInt16, it.Key); GXCommon.SetData(settings, bb, DataType.UInt16, it.Value); } } return(bb.Array()); } if (e.Index == 11) { GXByteBuffer bb = new GXByteBuffer(); bb.SetUInt8((byte)DataType.Array); if (BroadcastLogTable == null) { bb.SetUInt8(0); } else { GXCommon.SetObjectCount(BroadcastLogTable.Count, bb); foreach (GXDLMSBroadcastLogTable it in BroadcastLogTable) { bb.SetUInt8((byte)DataType.Structure); bb.SetUInt8(3); GXCommon.SetData(settings, bb, DataType.UInt16, it.SourceAddress); GXCommon.SetData(settings, bb, DataType.UInt8, it.SequenceNumber); GXCommon.SetData(settings, bb, DataType.UInt16, it.ValidTime); } } return(bb.Array()); } if (e.Index == 12) { GXByteBuffer bb = new GXByteBuffer(); bb.SetUInt8((byte)DataType.Array); if (GroupTable == null) { bb.SetUInt8(0); } else { GXCommon.SetObjectCount(GroupTable.Length, bb); foreach (UInt16 it in GroupTable) { GXCommon.SetData(settings, bb, DataType.UInt16, it); } } return(bb.Array()); } if (e.Index == 13) { return(MaxJoinWaitTime); } if (e.Index == 14) { return(PathDiscoveryTime); } if (e.Index == 15) { return(ActiveKeyIndex); } if (e.Index == 16) { return(MetricType); } if (e.Index == 17) { return(CoordShortAddress); } if (e.Index == 18) { return(DisableDefaultRouting); } if (e.Index == 19) { return(DeviceType); } e.Error = ErrorCode.ReadWriteDenied; return(null); }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, int index, int selector, object parameters) { if (index == 1) { return(this.LogicalName); } if (index == 2) { return(PHYReference); } if (index == 3) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); if (LCPOptions == null) { data.SetUInt8(0); } else { data.SetUInt8((byte)IPCPOptions.Length); foreach (GXDLMSPppSetupLcpOption it in LCPOptions) { data.SetUInt8((byte)DataType.Structure); data.SetUInt8((byte)3); GXCommon.SetData(data, DataType.UInt8, it.Type); GXCommon.SetData(data, DataType.UInt8, it.Length); GXCommon.SetData(data, GXCommon.GetValueType(it.Data), it.Data); } } return(data.Array()); } if (index == 4) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); if (IPCPOptions == null) { data.SetUInt8(0); } else { data.SetUInt8((byte)IPCPOptions.Length); foreach (GXDLMSPppSetupIPCPOption it in IPCPOptions) { data.SetUInt8((byte)DataType.Structure); data.SetUInt8((byte)3); GXCommon.SetData(data, DataType.UInt8, it.Type); GXCommon.SetData(data, DataType.UInt8, it.Length); GXCommon.SetData(data, GXCommon.GetValueType(it.Data), it.Data); } } return(data.Array()); } else if (index == 5) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Structure); data.SetUInt8(2); GXCommon.SetData(data, DataType.OctetString, UserName); GXCommon.SetData(data, DataType.OctetString, Password); return(data.Array()); } throw new ArgumentException("GetValue failed. Invalid attribute index."); }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return(GXCommon.LogicalNameToBytes(LogicalName)); } if (e.Index == 2) { return(GXCommon.LogicalNameToBytes(PHYReference)); } if (e.Index == 3) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); if (LCPOptions == null) { data.SetUInt8(0); } else { data.SetUInt8((byte)LCPOptions.Length); foreach (GXDLMSPppSetupLcpOption it in LCPOptions) { data.SetUInt8((byte)DataType.Structure); data.SetUInt8((byte)3); GXCommon.SetData(settings, data, DataType.UInt8, it.Type); GXCommon.SetData(settings, data, DataType.UInt8, it.Length); GXCommon.SetData(settings, data, GXCommon.GetValueType(it.Data), it.Data); } } return(data.Array()); } if (e.Index == 4) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); if (IPCPOptions == null) { data.SetUInt8(0); } else { data.SetUInt8((byte)IPCPOptions.Length); foreach (GXDLMSPppSetupIPCPOption it in IPCPOptions) { data.SetUInt8((byte)DataType.Structure); data.SetUInt8((byte)3); GXCommon.SetData(settings, data, DataType.UInt8, it.Type); GXCommon.SetData(settings, data, DataType.UInt8, it.Length); GXCommon.SetData(settings, data, GXCommon.GetValueType(it.Data), it.Data); } } return(data.Array()); } else if (e.Index == 5) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Structure); data.SetUInt8(2); GXCommon.SetData(settings, data, DataType.OctetString, UserName); GXCommon.SetData(settings, data, DataType.OctetString, Password); return(data.Array()); } e.Error = ErrorCode.ReadWriteDenied; return(null); }
/// <summary> /// Get DLMS data type. /// </summary> /// <param name="value">Object</param> /// <returns>DLMS data type.</returns> static public DataType GetDLMSDataType(object value) { return(GXCommon.GetValueType(value)); }
///<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(); // 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 && (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, GXCommon.GetValueType(actionReply), actionReply); } else { error = e.Error; //Add return parameters bb.SetUInt8(0); } } invokeId = (byte)e.InvokeId; } GXDLMSLNParameters p = new GXDLMSLNParameters(settings, invokeId, 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); } }
/// ///<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]); }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { switch (e.Index) { case 1: return(GXCommon.LogicalNameToBytes(LogicalName)); case 2: { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Structure); data.SetUInt8(4); if (ChangedParameter == null) { GXCommon.SetData(settings, data, DataType.UInt16, 0); GXCommon.SetData(settings, data, DataType.OctetString, new byte[] { 0, 0, 0, 0, 0, 0 }); GXCommon.SetData(settings, data, DataType.Int8, 1); GXCommon.SetData(settings, data, DataType.None, null); } else { GXCommon.SetData(settings, data, DataType.UInt16, ChangedParameter.Target.ObjectType); GXCommon.SetData(settings, data, DataType.OctetString, GXCommon.LogicalNameToBytes(ChangedParameter.Target.LogicalName)); GXCommon.SetData(settings, data, DataType.Int8, ChangedParameter.AttributeIndex); GXCommon.SetData(settings, data, GXCommon.GetValueType(ChangedParameter.Value), ChangedParameter.Value); } return(data.Array()); } case 3: return(CaptureTime); case 4: { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); if (Parameters == null) { data.SetUInt8(0); } else { data.SetUInt8((byte)Parameters.Count); foreach (GXDLMSTarget it in Parameters) { data.SetUInt8((byte)DataType.Structure); data.SetUInt8((byte)3); GXCommon.SetData(settings, data, DataType.UInt16, it.Target.ObjectType); GXCommon.SetData(settings, data, DataType.OctetString, GXCommon.LogicalNameToBytes(it.Target.LogicalName)); GXCommon.SetData(settings, data, DataType.Int8, it.AttributeIndex); } } return(data.Array()); } default: e.Error = ErrorCode.ReadWriteDenied; break; } return(null); }