object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return this.LogicalName; } if (e.Index == 2) { return PHYReference; } if (e.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(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; }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return this.LogicalName; } if (e.Index == 2) { return OutputState; } if (e.Index == 3) { return ControlState; } if (e.Index == 4) { return ControlMode; } e.Error = ErrorCode.ReadWriteDenied; return null; }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return this.LogicalName; } if (e.Index == 2) { return TransmissionErrors; } if (e.Index == 3) { return TransmitFailure; } if (e.Index == 4) { return TransmitRetries; } if (e.Index == 5) { return ReceiveFull; } if (e.Index == 6) { return LostMessages; ; } if (e.Index == 7) { return MissedMessages; } if (e.Index == 8) { return Layer2Received; } if (e.Index == 9) { return Layer3Received; } if (e.Index == 10) { return MessagesReceived; } if (e.Index == 11) { return MessagesValidated; } e.Error = ErrorCode.ReadWriteDenied; return null; }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { if (e.Value is string) { LogicalName = e.Value.ToString(); } else { LogicalName = GXDLMSClient.ChangeType((byte[])e.Value, DataType.OctetString).ToString(); } } else if (e.Index == 2) { Mode = (AutoConnectMode)Convert.ToInt32(e.Value); } else if (e.Index == 3) { Repetitions = Convert.ToInt32(e.Value); } else if (e.Index == 4) { RepetitionDelay = Convert.ToInt32(e.Value); } else if (e.Index == 5) { CallingWindow.Clear(); if (e.Value != null) { foreach (Object[] item in (Object[])e.Value) { GXDateTime start = (GXDateTime)GXDLMSClient.ChangeType((byte[])item[0], DataType.DateTime); GXDateTime end = (GXDateTime)GXDLMSClient.ChangeType((byte[])item[1], DataType.DateTime); CallingWindow.Add(new KeyValuePair<GXDateTime, GXDateTime>(start, end)); } } } else if (e.Index == 6) { Destinations = null; if (e.Value != null) { List<string> items = new List<string>(); foreach (byte[] item in (object[])e.Value) { string it = GXDLMSClient.ChangeType(item, DataType.String).ToString(); items.Add(it); } Destinations = items.ToArray(); } } else { e.Error = ErrorCode.ReadWriteDenied; } }
///<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 && !settings.AllowAnonymousAccess) { 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); }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { if (e.Value is string) { LogicalName = e.Value.ToString(); } else if (e.Value == null) { LogicalName = null; } else { LogicalName = GXDLMSClient.ChangeType((byte[])e.Value, DataType.OctetString).ToString(); } } else if (e.Index == 2) { if (Scaler != 1) { try { Value = Convert.ToDouble(e.Value) * Scaler; } catch (Exception) { //Sometimes scaler is set for wrong Object type. Value = e.Value; } } else { Value = e.Value; } } else if (e.Index == 3) { if (e.Value == null) { Scaler = 1; Unit = Unit.None; } else { object[] arr = (object[])e.Value; if (arr.Length != 2) { throw new Exception("setValue failed. Invalid scaler unit value."); } scaler = Convert.ToInt32(arr[0]); Unit = (Unit)(Convert.ToInt32(arr[1]) & 0xFF); } } else { e.Error = ErrorCode.ReadWriteDenied; } }
/// <summary> /// Action is occurred. /// </summary> /// <param name="e"></param> abstract public void Action(ValueEventArgs e);
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 { 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) { value = GXDLMSClient.ChangeType((byte[])value, dt); } } 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); } p.InvokeId = e.InvokeId; } catch (Exception) { p.status = (byte)ErrorCode.HardwareFault; } } } }
/// <summary> /// Get attribute access mode. /// </summary> /// <param name="arg">Value event argument.</param> /// <returns>Access mode.</returns> protected abstract AccessMode GetAttributeAccess(ValueEventArgs arg);
/// <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, 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 { e = new ValueEventArgs(server, obj, attributeIndex, selector, parameters); e.InvokeId = invokeID; 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; } } GXDLMS.GetLNPdu(new GXDLMSLNParameters(settings, e.InvokeId, Command.GetResponse, 1, null, bb, (byte)status), replyData); if (settings.Count != settings.Index || bb.Size != bb.Position) { server.transaction = new GXDLMSLongTransaction(new ValueEventArgs[] { e }, Command.GetRequest, bb); } }
/// <summary> /// Handle 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(GXDLMSObject.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, 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(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(settings, invokeID, Command.GetResponse, 3, null, bb, 0xFF); GXDLMS.GetLNPdu(p, replyData); }
///<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, 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 { 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 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); } }
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 && !settings.AllowAnonymousAccess && (!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); } } }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return this.LogicalName; } if (e.Index == 2) { return MBusPortReference; } if (e.Index == 3) { GXByteBuffer buff = new GXByteBuffer(); buff.Add((byte)DataType.Array); GXCommon.SetObjectCount(CaptureDefinition.Count, buff); foreach (KeyValuePair<string, string> it in CaptureDefinition) { buff.Add((byte)DataType.Structure); buff.Add(2); GXCommon.SetData(settings, buff, DataType.UInt8, it.Key); GXCommon.SetData(settings, buff, DataType.OctetString, ASCIIEncoding.ASCII.GetBytes(it.Value)); } return buff.Array(); } if (e.Index == 4) { return CapturePeriod; } if (e.Index == 5) { return PrimaryAddress; } if (e.Index == 6) { return IdentificationNumber; } if (e.Index == 7) { return ManufacturerID; } if (e.Index == 8) { return DataHeaderVersion; } if (e.Index == 9) { return DeviceType; } if (e.Index == 10) { return AccessNumber; } if (e.Index == 11) { return Status; } if (e.Index == 12) { return Alarm; } if (Version > 0) { if (e.Index == 13) { return Configuration; } if (e.Index == 14) { return EncryptionKeyStatus; } } e.Error = ErrorCode.ReadWriteDenied; return null; }
/// <summary> /// Get method access mode. /// </summary> /// <param name="arg">Value event argument.</param> /// <returns>Method access mode.</returns> protected abstract MethodAccessMode GetMethodAccess(ValueEventArgs arg);
byte[] IGXDLMSBase.Invoke(GXDLMSSettings settings, ValueEventArgs e) { // Resets the value to the default value. // The default value is an instance specific constant. if (e.Index == 1) { Value = null; } else { e.Error = ErrorCode.ReadWriteDenied; } return null; }
/// <summary> /// Get method access mode. /// </summary> /// <param name="arg"></param> /// <returns>Method access mode</returns> internal MethodAccessMode NotifyGetMethodAccess(ValueEventArgs arg) { return(GetMethodAccess(arg)); }
/// <summary> /// Read selected item. /// </summary> /// <param name="e"></param> abstract public void Read(ValueEventArgs e);
///<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]); }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { if (e.Value is string) { LogicalName = e.Value.ToString(); } else { LogicalName = GXDLMSClient.ChangeType((byte[])e.Value, DataType.OctetString).ToString(); } } else if (e.Index == 2) { if (Scaler != 1) { try { CurrentAverageValue = Convert.ToDouble(e.Value) * Scaler; } catch (Exception) { //Sometimes scaler is set for wrong Object type. CurrentAverageValue = e.Value; } } else { CurrentAverageValue = e.Value; } } else if (e.Index == 3) { if (Scaler != 1) { try { LastAverageValue = Convert.ToDouble(e.Value) * Scaler; } catch (Exception) { //Sometimes scaler is set for wrong Object type. LastAverageValue = e.Value; } } else { LastAverageValue = e.Value; } } else if (e.Index == 4) { if (e.Value == null) { Scaler = 1; Unit = Unit.None; } else { object[] arr = (object[])e.Value; if (arr.Length != 2) { throw new Exception("setValue failed. Invalid scaler unit value."); } _scaler = Convert.ToInt32(arr[0]); Unit = (Unit)Convert.ToInt32(arr[1]); } } else if (e.Index == 5) { Status = Convert.ToInt32(e.Value); } else if (e.Index == 6) { if (e.Value == null) { CaptureTime = new GXDateTime(DateTime.MinValue); } else { if (e.Value is byte[]) { e.Value = GXDLMSClient.ChangeType((byte[])e.Value, DataType.DateTime); } CaptureTime = (GXDateTime)e.Value; } } else if (e.Index == 7) { if (e.Value == null) { StartTimeCurrent = new GXDateTime(DateTime.MinValue); } else { if (e.Value is byte[]) { e.Value = GXDLMSClient.ChangeType((byte[])e.Value, DataType.DateTime); } StartTimeCurrent = (GXDateTime)e.Value; } } else if (e.Index == 8) { Period = Convert.ToUInt32(e.Value); } else if (e.Index == 9) { NumberOfPeriods = Convert.ToUInt16(e.Value); } else { e.Error = ErrorCode.ReadWriteDenied; } }
/// <summary> /// Read selected item. /// </summary> /// <param name="e"></param> abstract public void Read(ValueEventArgs e);
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { if (e.Value is string) { LogicalName = e.Value.ToString(); } else { LogicalName = GXDLMSClient.ChangeType((byte[])e.Value, DataType.OctetString).ToString(); } } else if (e.Index == 2) { PlcInactivityTimeout = (byte)e.Value; } else { e.Error = ErrorCode.ReadWriteDenied; } }
/// <summary> /// Write selected item. /// </summary> /// <param name="e"></param> abstract public void Write(ValueEventArgs e);
ParsePush(Object[] data) { int index; GXDLMSObject obj; object value; DataType dt; List<KeyValuePair<GXDLMSObject, int>> items = new List<KeyValuePair<GXDLMSObject, int>>(); if (data != null) { GXDLMSConverter c = new GXDLMSConverter(); GXDLMSObjectCollection objects = new GXDLMSObjectCollection(); foreach (Object it in (Object[])data[0]) { Object[] tmp = (Object[])it; int classID = ((UInt16)(tmp[0])) & 0xFFFF; if (classID > 0) { GXDLMSObject comp; comp = this.Objects.FindByLN((ObjectType)classID, GXDLMSObject.ToLogicalName(tmp[1] as byte[])); if (comp == null) { comp = GXDLMSClient.CreateDLMSObject(classID, 0, 0, tmp[1], null); c.UpdateOBISCodeInformation(comp); objects.Add(comp); } if ((comp is IGXDLMSBase)) { items.Add(new KeyValuePair<GXDLMSObject, int>(comp, (sbyte)tmp[2])); } else { System.Diagnostics.Debug.WriteLine(string.Format("Unknown object : {0} {1}", classID, GXDLMSObject.ToLogicalName((byte[])tmp[1]))); } } } for (int pos = 0; pos < data.Length; ++pos) { obj = items[pos].Key as GXDLMSObject; value = data[pos]; index = items[pos].Value; if (value is byte[] && (dt = obj.GetUIDataType(index)) != DataType.None) { value = GXDLMSClient.ChangeType(value as byte[], dt); } ValueEventArgs e = new ValueEventArgs(Settings, obj, index, 0, null); e.Value = value; (obj as IGXDLMSBase).SetValue(Settings, e); } } return items; }
/// <summary> /// Action is occurred. /// </summary> /// <param name="e"></param> abstract public void Action(ValueEventArgs e);
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { if (e.Value is string) { LogicalName = e.Value.ToString(); } else { LogicalName = GXDLMSClient.ChangeType((byte[])e.Value, DataType.OctetString).ToString(); } } else if (e.Index == 2) { OutputState = Convert.ToBoolean(e.Value); } else if (e.Index == 3) { ControlState = (ControlState)Convert.ToInt32(e.Value); } else if (e.Index == 4) { ControlMode = (ControlMode)Convert.ToInt32(e.Value); } else { e.Error = ErrorCode.ReadWriteDenied; } }
///<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]); }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { if (e.Value is string) { LogicalName = e.Value.ToString(); } else { LogicalName = GXDLMSClient.ChangeType((byte[])e.Value, DataType.OctetString).ToString(); } } else if (e.Index == 2) { TransmissionErrors = (UInt16)e.Value; } else if (e.Index == 3) { TransmitFailure = (UInt16)e.Value; } else if (e.Index == 4) { TransmitRetries = (UInt16)e.Value; } else if (e.Index == 5) { ReceiveFull = (UInt16)e.Value; } else if (e.Index == 6) { LostMessages = (UInt16)e.Value; } else if (e.Index == 7) { MissedMessages = (UInt16)e.Value; } else if (e.Index == 8) { Layer2Received = (UInt16)e.Value; } else if (e.Index == 9) { Layer3Received = (UInt16)e.Value; } else if (e.Index == 10) { MessagesReceived = (UInt16)e.Value; } else if (e.Index == 11) { MessagesValidated = (UInt16)e.Value; } else { e.Error = ErrorCode.ReadWriteDenied; } }
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]); }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { if (e.Value is string) { LogicalName = e.Value.ToString(); } else { LogicalName = GXDLMSClient.ChangeType((byte[])e.Value, DataType.OctetString).ToString(); } } else if (e.Index == 2) { if (e.Value is string) { PHYReference = e.Value.ToString(); } else { PHYReference = GXDLMSClient.ChangeType((byte[])e.Value, DataType.OctetString).ToString(); } } else if (e.Index == 3) { List<GXDLMSPppSetupLcpOption> items = new List<GXDLMSPppSetupLcpOption>(); if (e.Value is Object[]) { foreach (Object[] item in (Object[])e.Value) { GXDLMSPppSetupLcpOption it = new GXDLMSPppSetupLcpOption(); it.Type = (PppSetupLcpOptionType)Convert.ToByte(item[0]); it.Length = Convert.ToByte(item[1]); it.Data = item[2]; items.Add(it); } } LCPOptions = items.ToArray(); } else if (e.Index == 4) { List<GXDLMSPppSetupIPCPOption> items = new List<GXDLMSPppSetupIPCPOption>(); if (e.Value is Object[]) { foreach (Object[] item in (Object[])e.Value) { GXDLMSPppSetupIPCPOption it = new GXDLMSPppSetupIPCPOption(); it.Type = (PppSetupIPCPOptionType)Convert.ToByte(item[0]); it.Length = Convert.ToByte(item[1]); it.Data = item[2]; items.Add(it); } } IPCPOptions = items.ToArray(); } else if (e.Index == 5) { UserName = (byte[])((Object[])e.Value)[0]; Password = (byte[])((Object[])e.Value)[1]; } else { e.Error = ErrorCode.ReadWriteDenied; } }
/// ///<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]); }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { if (e.Value is string) { LogicalName = e.Value.ToString(); } else { LogicalName = GXDLMSClient.ChangeType((byte[])e.Value, DataType.OctetString).ToString(); } } else if (e.Index == 2) { if (e.Value is string) { MBusPortReference = e.Value.ToString(); } else { MBusPortReference = GXDLMSClient.ChangeType((byte[])e.Value, DataType.OctetString).ToString(); } } else if (e.Index == 3) { CaptureDefinition.Clear(); if (e.Value != null) { foreach (object[] it in (object[])e.Value) { CaptureDefinition.Add(new KeyValuePair<string, string>(GXDLMSClient.ChangeType((byte[])it[0], DataType.OctetString).ToString(), GXDLMSClient.ChangeType((byte[])it[1], DataType.OctetString).ToString())); } } } else if (e.Index == 4) { CapturePeriod = Convert.ToUInt32(e.Value); } else if (e.Index == 5) { PrimaryAddress = Convert.ToByte(e.Value); } else if (e.Index == 6) { IdentificationNumber = Convert.ToUInt32(e.Value); } else if (e.Index == 7) { ManufacturerID = Convert.ToUInt16(e.Value); } else if (e.Index == 8) { DataHeaderVersion = Convert.ToByte(e.Value); } else if (e.Index == 9) { DeviceType = Convert.ToByte(e.Value); } else if (e.Index == 10) { AccessNumber = Convert.ToByte(e.Value); } else if (e.Index == 11) { Status = Convert.ToByte(e.Value); } else if (e.Index == 12) { Alarm = Convert.ToByte(e.Value); } else if (Version > 0) { if (e.Index == 13) { Configuration = Convert.ToUInt16(e.Value); } else if (e.Index == 14) { EncryptionKeyStatus = (MBusEncryptionKeyStatus)Convert.ToInt32(e.Value); } else { e.Error = ErrorCode.ReadWriteDenied; } } else { e.Error = ErrorCode.ReadWriteDenied; } }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return this.LogicalName; } if (e.Index == 2) { return (byte)Mode; } if (e.Index == 3) { return (byte)Speed; } if (e.Index == 4) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); if (PrimaryAddresses == null) { data.SetUInt8(0); } else { data.SetUInt8((byte)PrimaryAddresses.Length); foreach (byte it in PrimaryAddresses) { data.SetUInt8((byte)DataType.UInt8); data.SetUInt8(it); } } return data.Array(); } if (e.Index == 5) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); if (Tabis == null) { data.SetUInt8(0); } else { data.SetUInt8((byte)Tabis.Length); foreach (sbyte it in Tabis) { data.SetUInt8((byte)DataType.UInt8); data.SetUInt8((byte)it); } } return data.Array(); } e.Error = ErrorCode.ReadWriteDenied; return null; }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return this.LogicalName; } if (e.Index == 2) { return Value; } if (e.Index == 3) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Structure); data.SetUInt8(2); GXCommon.SetData(settings, data, DataType.Int8, scaler); GXCommon.SetData(settings, data, DataType.Enum, Unit); return data.Array(); } e.Error = ErrorCode.ReadWriteDenied; return null; }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { if (e.Value is string) { LogicalName = e.Value.ToString(); } else { LogicalName = GXDLMSClient.ChangeType((byte[])e.Value, DataType.OctetString).ToString(); } } else if (e.Index == 2) { Mode = (IecTwistedPairSetupMode)e.Value; } else if (e.Index == 3) { Speed = (BaudRate)e.Value; } else if (e.Index == 4) { GXByteBuffer list = new GXByteBuffer(); foreach (object it in (object[])e.Value) { list.Add((byte)it); } PrimaryAddresses = list.Array(); } else if (e.Index == 5) { List<sbyte> list = new List<sbyte>(); foreach (object it in (object[])e.Value) { list.Add((sbyte)it); } Tabis = list.ToArray(); } else { e.Error = ErrorCode.ReadWriteDenied; } }
/// <summary> /// Mandles client request. /// </summary> /// <param name="buff">Received data from the client.</param> /// <returns>Response to the request.</returns> /// <remarks> /// Response is null if request packet is not compleate. /// </remarks> public byte[] HandleRequest(byte[] buff) { byte command = 0; lock (this) { if (buff == null) { return null; } if (!Initialized) { throw new Exception("Server not Initialized."); } try { byte[] data = null; if (ReceivedFrame.Count != 0) { ReceivedFrame.AddRange(buff); data = ReceivedFrame.ToArray(); } else { data = buff; } if (m_Base.ServerID == null) { object sid = null, cid = null; GetAddress(data, ref cid, ref sid); //If there is not enough data yet. if (cid == null || sid == null) { ReceivedFrame.AddRange(buff); return null; } foreach (object it in this.ServerIDs) { if (sid.Equals(it)) { m_Base.ServerID = sid; m_Base.ClientID = cid; break; } } //We do not communicate if server ID not found. if (m_Base.ServerID == null) { System.Diagnostics.Debug.WriteLine("Invalid server ID: " + sid.ToString()); InvalidConnection(new ConnectionEventArgs(sid)); return null; } } if (!m_Base.IsDLMSPacketComplete(data)) { if (ReceivedFrame.Count == 0) { ReceivedFrame.AddRange(buff); } return null; //Wait more data. } List<object> names = new List<object>(); GXDLMSObject item = null; byte[] allData = null; byte frame; RequestTypes ret = m_Base.GetDataFromPacket(data, ref allData, out frame, out command); ReceivedFrame.Clear(); //Ask next part. if ((ret & (RequestTypes.Frame | RequestTypes.DataBlock)) != 0) { if (ret == RequestTypes.DataBlock) { //Add new data. if ((frame & 0x1) == 0) { if (command != 0) { LastCommand = command; } ReceivedData.AddRange(allData); SendData.Clear(); FrameIndex = 0; return m_Base.ReceiverReady(RequestTypes.DataBlock); } ++FrameIndex; int index = 0; int BlockIndex = (int)GXCommon.GetUInt32(allData, ref index); return SendData[FrameIndex]; } else { ++FrameIndex; //Add new data. if ((frame & 0x1) == 0) { if (command != 0) { LastCommand = command; } ReceivedData.AddRange(allData); SendData.Clear(); FrameIndex = 0; --m_Base.ExpectedFrame; byte[] tmp = m_Base.ReceiverReady(RequestTypes.Frame); return tmp; } //Keep alive... else if (FrameIndex >= SendData.Count && (frame & 0x1) == 1) { SendData.Clear(); FrameIndex = 0; return m_Base.AddFrame(m_Base.GenerateAliveFrame(), false, null, 0, 0); } return SendData[FrameIndex]; } } if (ReceivedData.Count != 0) { ReceivedData.AddRange(allData); allData = ReceivedData.ToArray(); ReceivedData.Clear(); command = LastCommand; } FrameIndex = 0; SendData.Clear(); if (command == (byte) Command.GloGetRequest || command == (byte) Command.GloSetRequest || command == (byte) Command.GloMethodRequest) { Command cmd; int error; allData = m_Base.Decrypt(allData.ToArray(), out cmd, out error); command = (byte) cmd; } if (command == (int)Command.Snrm) { SendData.Add(HandleSnrmRequest()); return SendData[FrameIndex]; } else if (command == (int)Command.Aarq) { SendData.Add(HandleAARQRequest(data)); return SendData[FrameIndex]; } else if (command == (int)Command.DisconnectRequest) { System.Diagnostics.Debug.WriteLine("Disconnecting"); SendData.Add(GenerateDisconnectRequest()); return SendData[FrameIndex]; } else if (command == (int)Command.WriteRequest) { int attributeIndex = 0; object value = null; ObjectType type; int selector; GetCommand(command, allData, out type, names, out attributeIndex, out selector, out value); ushort sn = (ushort)names[0]; foreach (var it in SortedItems) { int aCnt = (it.Value as IGXDLMSBase).GetAttributeCount(); if (sn >= it.Key && sn <= (it.Key + (8 * aCnt))) { item = it.Value; attributeIndex = ((sn - item.ShortName) / 8) + 1; //If write is denied. AccessMode acc = item.GetAccess(attributeIndex); if (acc == AccessMode.NoAccess || acc == AccessMode.Read || acc == AccessMode.AuthenticatedRead) { SendData.AddRange(ServerReportError((Command)command, 3)); return SendData[FrameIndex]; } if (value is byte[]) { DataType tp = item.GetUIDataType(attributeIndex); if (tp != DataType.None) { value = GXDLMSClient.ChangeType((byte[])value, tp); } } ValueEventArgs e = new ValueEventArgs(item, attributeIndex, selector); e.Value = value; Write(e); if (!e.Handled) { (item as IGXDLMSBase).SetValue(attributeIndex, value); } //Return OK. SendData.AddRange(Acknowledge(UseLogicalNameReferencing ? Command.SetResponse : Command.WriteResponse, 0)); return SendData[FrameIndex]; } } } else if (command == (int)Command.SetRequest) { int attributeIndex = 0; object value = null; ObjectType type; int selector; GetCommand(command, allData, out type, names, out attributeIndex, out selector, out value); item = Items.FindByLN(type, names[0].ToString()); if (item != null) { //If write is denied. AccessMode acc = item.GetAccess(attributeIndex); if (acc == AccessMode.NoAccess || acc == AccessMode.Read || acc == AccessMode.AuthenticatedRead) { SendData.AddRange(ServerReportError((Command)command, 3)); return SendData[FrameIndex]; } if (value is byte[]) { DataType tp = item.GetUIDataType(attributeIndex); if (tp != DataType.None) { value = GXDLMSClient.ChangeType((byte[])value, tp); } } ValueEventArgs e = new ValueEventArgs(item, attributeIndex, selector); e.Value = value; Write(e); if (!e.Handled) { (item as IGXDLMSBase).SetValue(attributeIndex, value); } //Return OK. SendData.AddRange(Acknowledge(UseLogicalNameReferencing ? Command.SetResponse : Command.WriteResponse, 0)); return SendData[FrameIndex]; } } else if (command == (int)Command.ReadRequest && !UseLogicalNameReferencing) { ObjectType type; int attributeIndex; object value; int selector; GetCommand(command, allData, out type, names, out attributeIndex, out selector, out value); ushort sn = Convert.ToUInt16(names[0]); foreach (var it in SortedItems) { int aCnt = (it.Value as IGXDLMSBase).GetAttributeCount(); if (sn >= it.Key && sn <= (it.Key + (8 * aCnt))) { item = it.Value; attributeIndex = ((sn - item.ShortName) / 8) + 1; System.Diagnostics.Debug.WriteLine(string.Format("Reading {0}, attribute index {1}", item.Name, attributeIndex)); ValueEventArgs e = new ValueEventArgs(item, attributeIndex, selector); e.Value = value; Read(e); if (e.Handled) { Gurux.DLMS.DataType tp = Gurux.DLMS.Internal.GXCommon.GetValueType(e.Value); SendData.AddRange(ReadReply(names[0], type, attributeIndex, e.Value, tp)); return SendData[FrameIndex]; } if (item != null) { return GetValue(names[0], item, attributeIndex, selector, value); } } //If action. else if (sn >= it.Key + aCnt && (it.Value as IGXDLMSBase).GetMethodCount() != 0) { //Convert DLMS data to object type. int value2 = 0, count = 0; GXDLMS.GetActionInfo(it.Value.ObjectType, out value2, out count); if (sn <= it.Key + value2 + (8 * count))//If action { item = it.Value; attributeIndex = ((sn - item.ShortName - value2) / 8) + 1; ValueEventArgs e = new ValueEventArgs(item, attributeIndex, selector); System.Diagnostics.Debug.WriteLine(string.Format("Action on {0}, attribute index {1}", item.ShortName, attributeIndex)); e.Value = value; Action(e); if (!e.Handled) { byte[][] reply = (item as IGXDLMSBase).Invoke(this, attributeIndex, e.Value); if (reply != null) { SendData.AddRange(reply); return SendData[FrameIndex]; } } SendData.AddRange(Acknowledge(Command.MethodResponse, 0)); return SendData[FrameIndex]; } } } throw new ArgumentOutOfRangeException(); } else if (command == (int)Command.GetRequest && UseLogicalNameReferencing) { ObjectType type; int index; object parameter; int selector; GetCommand(command, allData, out type, names, out index, out selector, out parameter); System.Diagnostics.Debug.WriteLine(string.Format("Reading {0}, attribute index {1}", names[0], index)); item = Items.FindByLN(type, names[0].ToString()); if (item != null) { ValueEventArgs e = new ValueEventArgs(item, index, selector); Read(e); if (e.Handled) { Gurux.DLMS.DataType tp = Gurux.DLMS.Internal.GXCommon.GetValueType(e.Value); SendData.AddRange(ReadReply(names[0], type, index, e.Value, tp)); return SendData[FrameIndex]; } return GetValue(names[0], item, index, selector, parameter); } } else if (command == (int)Command.MethodRequest) { ObjectType type; int index; object parameter; int selector; GetCommand(command, allData, out type, names, out index, out selector, out parameter); item = Items.FindByLN(type, names[0].ToString()); if (item != null) { System.Diagnostics.Debug.WriteLine(string.Format("Action on {0}, attribute index {1}", names[0], index)); ValueEventArgs e = new ValueEventArgs(item, index, selector); e.Value = parameter; Action(e); if (!e.Handled && item is IGXDLMSBase) { byte[][] reply = (item as IGXDLMSBase).Invoke(this, index, e.Value); if (reply != null) { SendData.AddRange(reply); return SendData[FrameIndex]; } } SendData.AddRange(Acknowledge(Command.MethodResponse, 0)); return SendData[FrameIndex]; } } //Return HW error. SendData.AddRange(ServerReportError((Command) command, 1)); return SendData[FrameIndex]; } catch(Exception ex) { //Return HW error. ReceivedFrame.Clear(); SendData.AddRange(ServerReportError((Command) command, 1)); return SendData[FrameIndex]; } } }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return this.LogicalName; } if (e.Index == 2) { int cnt = 0; if (SapAssignmentList != null) { cnt = SapAssignmentList.Count; } GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); //Add count GXCommon.SetObjectCount(cnt, data); if (cnt != 0) { foreach (var it in SapAssignmentList) { data.SetUInt8((byte)DataType.Structure); data.SetUInt8((byte)2); //Count GXCommon.SetData(settings, data, DataType.UInt16, it.Key); GXCommon.SetData(settings, data, DataType.OctetString, ASCIIEncoding.ASCII.GetBytes(it.Value)); } } return data.Array(); } e.Error = ErrorCode.ReadWriteDenied; return null; }
/// <summary> /// Write selected item. /// </summary> /// <param name="e"></param> abstract public void Write(ValueEventArgs e);
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { if (e.Value is string) { LogicalName = e.Value.ToString(); } else { LogicalName = GXDLMSClient.ChangeType((byte[])e.Value, DataType.OctetString).ToString(); } } else if (e.Index == 2) { SapAssignmentList.Clear(); if (e.Value != null) { foreach (Object[] item in (Object[])e.Value) { string str; if (item[1] is byte[]) { str = GXDLMSClient.ChangeType((byte[])item[1], DataType.String).ToString(); } else { str = Convert.ToString(item[1]); } SapAssignmentList.Add(new KeyValuePair<UInt16, string>(Convert.ToUInt16(item[0]), str)); } } } else { e.Error = ErrorCode.ReadWriteDenied; } }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return this.LogicalName; } if (e.Index == 2) { return this.CurrentAverageValue; } if (e.Index == 3) { return this.LastAverageValue; } if (e.Index == 4) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Structure); data.SetUInt8(2); GXCommon.SetData(settings, data, DataType.Int8, _scaler); GXCommon.SetData(settings, data, DataType.Enum, Unit); return data.Array(); } if (e.Index == 5) { return this.Status; } if (e.Index == 6) { return CaptureTime; } if (e.Index == 7) { return StartTimeCurrent; } if (e.Index == 8) { return Period; } if (e.Index == 9) { return NumberOfPeriods; } e.Error = ErrorCode.ReadWriteDenied; return null; }
byte[] IGXDLMSBase.Invoke(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 2) { foreach (object tmp in e.Parameters as object[]) { object[] item = tmp as object[]; GlobalKeyType type = (GlobalKeyType)Convert.ToInt32(item[0]); byte[] data = (byte[])item[1]; switch (type) { case GlobalKeyType.UnicastEncryption: case GlobalKeyType.BroadcastEncryption: //Invalid type e.Error = ErrorCode.ReadWriteDenied; break; case GlobalKeyType.Authentication: //if settings.Cipher is null non secure server is used. settings.Cipher.AuthenticationKey = GXDLMSSecureClient.Decrypt(settings.Kek, data); break; case GlobalKeyType.Kek: settings.Kek = GXDLMSSecureClient.Decrypt(settings.Kek, data); break; default: //Invalid type e.Error = ErrorCode.ReadWriteDenied; break; } } //Return standard reply. return null; } else { e.Error = ErrorCode.ReadWriteDenied; return null; } }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return this.LogicalName; } if (e.Index == 2) { return (byte)Mode; } if (e.Index == 3) { return Repetitions; } if (e.Index == 4) { return RepetitionDelay; } if (e.Index == 5) { int cnt = CallingWindow.Count; GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); //Add count GXCommon.SetObjectCount(cnt, data); if (cnt != 0) { foreach (var it in CallingWindow) { data.SetUInt8((byte)DataType.Structure); data.SetUInt8((byte)2); //Count GXCommon.SetData(settings, data, DataType.OctetString, it.Key); //start_time GXCommon.SetData(settings, data, DataType.OctetString, it.Value); //end_time } } return data.Array(); } if (e.Index == 6) { GXByteBuffer data = new GXByteBuffer(); data.SetUInt8((byte)DataType.Array); if (Destinations == null) { //Add count GXCommon.SetObjectCount(0, data); } else { int cnt = Destinations.Length; //Add count GXCommon.SetObjectCount(cnt, data); foreach (string it in Destinations) { GXCommon.SetData(settings, data, DataType.OctetString, ASCIIEncoding.ASCII.GetBytes(it)); //destination } } return data.Array(); } e.Error = ErrorCode.ReadWriteDenied; return null; }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return this.LogicalName; } if (e.Index == 2) { return SecurityPolicy; } if (e.Index == 3) { return SecuritySuite; } if (this.Version > 0) { if (e.Index == 4) { return ClientSystemTitle; } if (e.Index == 5) { return ServerSystemTitle; } if (e.Index == 6) { return GetSertificates(); } } e.Error = ErrorCode.ReadWriteDenied; return null; }
object IGXDLMSBase.GetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { return this.LogicalName; } if (e.Index == 2) { return PlcInactivityTimeout; } e.Error = ErrorCode.ReadWriteDenied; return null; }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { if (e.Value is string) { LogicalName = e.Value.ToString(); } else { LogicalName = GXDLMSClient.ChangeType((byte[])e.Value, DataType.OctetString).ToString(); } } else if (e.Index == 2) { SecurityPolicy = (SecurityPolicy)Convert.ToInt32(e.Value); } else if (e.Index == 3) { SecuritySuite = (SecuritySuite)Convert.ToInt32(e.Value); } else if (e.Index == 4) { ClientSystemTitle = (byte[])e.Value; } else if (e.Index == 5) { ServerSystemTitle = (byte[])e.Value; } else if (e.Index == 6) { UpdateSertificates((object[])e.Value); } else { e.Error = ErrorCode.ReadWriteDenied; } }
byte[] IGXDLMSBase.Invoke(GXDLMSSettings settings, ValueEventArgs e) { e.Error = ErrorCode.ReadWriteDenied; return null; }
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; } } }