/// <summary> /// Constructor /// </summary> /// <param name="useLogicalNameReferencing">Is Logical or short name referencing used.</param> /// <param name="clientAddress">Client address. Default is 0x10</param> /// <param name="ServerAddress">Server ID. Default is 1.</param> /// <param name="interfaceType">Interface type. Default is general.</param> public GXDLMSNotify(bool useLogicalNameReferencing, int clientAddress, int serverAddress, InterfaceType interfaceType) { Settings = new GXDLMSSettings(true); Settings.UseLogicalNameReferencing = useLogicalNameReferencing; Settings.InterfaceType = interfaceType; Settings.ServerAddress = serverAddress; Settings.ClientAddress = clientAddress; }
/// <summary> /// Generates Invoke ID and priority. /// </summary> /// <param name="settings">DLMS settings.</param> /// <returns>Invoke ID and priority.</returns> static byte GetInvokeIDPriority(GXDLMSSettings settings) { byte value = 0; if (settings.Priority == Priority.High) { value = 0x80; } if (settings.ServiceClass == ServiceClass.Confirmed) { value |= 0x40; } value |= (byte)(settings.InvokeID & 0xF); return value; }
public static void HandleGetRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml) { //Return error if connection is not established. if (xml == null && !settings.Connected) { replyData.Set(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError, ServiceError.Service, (byte)Service.Unsupported)); return; } GetCommandType type = (GetCommandType)data.GetUInt8(); // Get invoke ID and priority. byte invokeID = data.GetUInt8(); if (xml != null) { xml.AppendStartTag(Command.GetRequest); xml.AppendStartTag(Command.GetRequest, type); xml.AppendLine(TranslatorTags.InvokeId, "Value", xml.IntegerToHex(invokeID, 2)); } // GetRequest normal if (type == GetCommandType.Normal) { GetRequestNormal(settings, server, data, replyData, xml); } else if (type == GetCommandType.NextDataBlock) { // Get request for next data block GetRequestNextDataBlock(settings, server, data, replyData, xml); } else if (type == GetCommandType.WithList) { // Get request with a list. GetRequestWithList(settings, server, data, replyData, xml); } else { Debug.WriteLine("HandleGetRequest failed. Invalid command type."); settings.ResetBlockIndex(); GXByteBuffer bb = new GXByteBuffer(); // Access Error : Device reports a hardware fault. bb.SetUInt8((byte)ErrorCode.HardwareFault); GXDLMS.GetLNPdu(new GXDLMSLNParameters(settings, Command.GetResponse, (byte)type, null, bb, (byte)ErrorCode.Ok), replyData); } if (xml != null) { xml.AppendEndTag(Command.GetRequest, type); xml.AppendEndTag(Command.GetRequest); } }
/// <summary> /// Generates Invoke ID and priority. /// </summary> /// <param name="settings">DLMS settings.</param> /// <returns>Invoke ID and priority.</returns> static UInt32 GetLongInvokeIDPriority(GXDLMSSettings settings) { UInt32 value = 0; if (settings.Priority == Priority.High) { value = 0x80000000; } if (settings.ServiceClass == ServiceClass.Confirmed) { value |= 0x40000000; } value |= (UInt32)(settings.longInvokeID & 0xFFFFFF); ++settings.longInvokeID; return value; }
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; } }
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, GXCommon.ToLogicalName(ln)); if (obj == null) { obj = server.NotifyFindObject(ci, 0, GXCommon.ToLogicalName(ln)); } // If target is unknown. if (obj == null) { // Device reports a undefined object. p.status = (byte)ErrorCode.UndefinedObject; } else { ValueEventArgs e = new ValueEventArgs(server, obj, index, 0, null); e.InvokeId = p.InvokeId; AccessMode am = server.NotifyGetAttributeAccess(e); // If write is denied. if (am != AccessMode.Write && am != AccessMode.ReadWrite) { //Read Write denied. p.status = (byte)ErrorCode.ReadWriteDenied; } else { try { if (value is byte[]) { DataType dt = (obj as IGXDLMSBase).GetDataType(index); if (dt != DataType.None && dt != DataType.OctetString && dt != DataType.Structure) { value = GXDLMSClient.ChangeType((byte[])value, dt, settings.UseUtc2NormalTime); } } e.Value = value; ValueEventArgs[] list = new ValueEventArgs[] { e }; if (p.multipleBlocks) { server.transaction = new GXDLMSLongTransaction(list, Command.GetRequest, data); } server.NotifyWrite(list); if (e.Error != 0) { p.status = (byte)e.Error; } else if (!e.Handled && !p.multipleBlocks) { (obj as IGXDLMSBase).SetValue(settings, e); server.NotifyPostWrite(list); if (e.Error != 0) { p.status = (byte)e.Error; } } p.InvokeId = e.InvokeId; } catch (Exception) { p.status = (byte)ErrorCode.HardwareFault; } } } }
/// <summary> /// Constructor. /// </summary> public ValueEventArgs(GXDLMSSettings settings, GXDLMSObject target, int index, int selector, object parameters) { Settings = settings; Target = target; Index = index; Selector = selector; Parameters = parameters; }
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; } }
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; } }
///<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 && !settings.AllowAnonymousAccess && (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 && !settings.AllowAnonymousAccess && obj is GXDLMSAssociationLogicalName && id == 1) { server.NotifyInvalidConnection(connectionInfo); } }
/// <summary> /// Handle get request normal command. /// </summary> /// <param name="data">Received data.</param> private static void GetRequestNormal(GXDLMSSettings settings, byte invokeID, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml) { ValueEventArgs e = null; GXByteBuffer bb = new GXByteBuffer(); // Get type. ErrorCode status = ErrorCode.Ok; settings.Count = settings.Index = 0; settings.ResetBlockIndex(); // CI ObjectType ci = (ObjectType)data.GetUInt16(); byte[] ln = new byte[6]; data.Get(ln); // Attribute Id byte attributeIndex = data.GetUInt8(); // AccessSelection byte selection = data.GetUInt8(); byte selector = 0; object parameters = null; GXDataInfo info = new GXDataInfo(); if (selection != 0) { selector = data.GetUInt8(); } if (xml != null) { AppendAttributeDescriptor(xml, (int)ci, ln, attributeIndex); if (selection != 0) { info.xml = xml; xml.AppendStartTag(TranslatorTags.AccessSelection); xml.AppendLine(TranslatorTags.AccessSelector, "Value", xml.IntegerToHex(selector, 2)); xml.AppendStartTag(TranslatorTags.AccessParameters); GXCommon.GetData(settings, data, info); xml.AppendEndTag(TranslatorTags.AccessParameters); xml.AppendEndTag(TranslatorTags.AccessSelection); } return; } if (selection != 0) { parameters = GXCommon.GetData(settings, data, info); } GXDLMSObject obj = settings.Objects.FindByLN(ci, GXCommon.ToLogicalName(ln)); if (obj == null) { obj = server.NotifyFindObject(ci, 0, GXCommon.ToLogicalName(ln)); } e = new ValueEventArgs(server, obj, attributeIndex, selector, parameters); if (obj == null) { // "Access Error : Device reports a undefined object." status = ErrorCode.UndefinedObject; } else { 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); } }
private static void HandleReadDataBlockAccess( GXDLMSSettings settings, GXDLMSServer server, Command command, GXByteBuffer data, int cnt, GXByteBuffer replyData, GXDLMSTranslatorStructure xml) { GXByteBuffer bb = new GXByteBuffer(); byte lastBlock = data.GetUInt8(); UInt16 blockNumber = data.GetUInt16(); if (xml != null) { if (command == Command.WriteResponse) { xml.AppendStartTag(TranslatorTags.WriteDataBlockAccess); } else { xml.AppendStartTag(TranslatorTags.ReadDataBlockAccess); } xml.AppendLine("<LastBlock Value=\"" + xml.IntegerToHex(lastBlock, 2) + "\" />"); xml.AppendLine("<BlockNumber Value=\"" + xml.IntegerToHex(blockNumber, 4) + "\" />"); if (command == Command.WriteResponse) { xml.AppendEndTag(TranslatorTags.WriteDataBlockAccess); } else { xml.AppendEndTag(TranslatorTags.ReadDataBlockAccess); } return; } if (blockNumber != settings.BlockIndex) { Debug.WriteLine("handleReadRequest failed. Invalid block number. " + settings.BlockIndex + "/" + blockNumber); bb.SetUInt8(ErrorCode.DataBlockNumberInvalid); GXDLMS.GetSNPdu(new GXDLMSSNParameters(settings, command, 1, (byte)SingleReadResponse.DataAccessError, bb, null), replyData); settings.ResetBlockIndex(); return; } int count = 1; byte type = (byte)DataType.OctetString; if (command == Command.WriteResponse) { count = GXCommon.GetObjectCount(data); type = data.GetUInt8(); } int size = GXCommon.GetObjectCount(data); int realSize = data.Size - data.Position; if (count != 1 || type != (byte)DataType.OctetString || size != realSize) { Debug.WriteLine("handleGetRequest failed. Invalid block size."); bb.SetUInt8(ErrorCode.DataBlockUnavailable); GXDLMS.GetSNPdu(new GXDLMSSNParameters(settings, command, cnt, (byte)SingleReadResponse.DataAccessError, bb, null), replyData); settings.ResetBlockIndex(); return; } if (server.transaction == null) { server.transaction = new GXDLMSLongTransaction(null, command, data); } else { server.transaction.data.Set(data); } if (lastBlock == 0) { bb.SetUInt16(blockNumber); settings.IncreaseBlockIndex(); if (command == Command.ReadResponse) { type = (byte)SingleReadResponse.BlockNumber; } else { type = (byte)SingleWriteResponse.BlockNumber; } GXDLMS.GetSNPdu(new GXDLMSSNParameters(settings, command, cnt, type, null, bb), replyData); return; } else { if (server.transaction != null) { data.Size = 0; data.Set(server.transaction.data); server.transaction = null; } if (command == Command.ReadResponse) { HandleReadRequest(settings, server, data, replyData, xml); } else { HandleWriteRequest(settings, server, data, replyData, xml); } settings.ResetBlockIndex(); } }
/// <summary> /// Handle read request. /// </summary> /// <param name="settings">DLMS settings.</param> /// <param name="server">DLMS server.</param> /// <param name="data">Received data.</param> public static void HandleReadRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml) { GXByteBuffer bb = new GXByteBuffer(); int cnt = 0xFF; byte type = 0; List <ValueEventArgs> list = new List <ValueEventArgs>(); List <ValueEventArgs> reads = new List <ValueEventArgs>(); List <ValueEventArgs> actions = new List <ValueEventArgs>(); //If get next frame. if (xml == null && data.Size == 0) { if (server.transaction != null) { return; } bb.Set(replyData); replyData.Clear(); foreach (ValueEventArgs it in server.transaction.targets) { list.Add(it); } } else { cnt = GXCommon.GetObjectCount(data); if (xml != null) { xml.AppendStartTag(Command.ReadRequest, "Qty", xml.IntegerToHex(cnt, 2)); } for (int pos = 0; pos != cnt; ++pos) { type = data.GetUInt8(); if (type == (byte)VariableAccessSpecification.VariableName || type == (byte)VariableAccessSpecification.ParameterisedAccess) { HandleRead(settings, server, type, data, list, reads, actions, replyData, xml); } else if (type == (byte)VariableAccessSpecification.BlockNumberAccess) { HandleReadBlockNumberAccess(settings, server, data, replyData, xml); if (xml != null) { xml.AppendEndTag(Command.ReadRequest); } return; } else if (type == (byte)VariableAccessSpecification.ReadDataBlockAccess) { HandleReadDataBlockAccess(settings, server, Command.ReadResponse, data, cnt, replyData, xml); if (xml != null) { xml.AppendEndTag(Command.ReadRequest); } return; } else { ReturnSNError(settings, server, Command.ReadResponse, ErrorCode.ReadWriteDenied, replyData); if (xml != null) { xml.AppendEndTag(Command.ReadRequest); } return; } } if (reads.Count != 0) { server.NotifyRead(reads.ToArray()); } if (actions.Count != 0) { server.NotifyAction(actions.ToArray()); } } if (xml != null) { xml.AppendEndTag(Command.ReadRequest); return; } byte requestType = (byte)GetReadData(settings, list.ToArray(), bb); if (reads.Count != 0) { server.NotifyPostRead(reads.ToArray()); } if (actions.Count != 0) { server.NotifyPostAction(actions.ToArray()); } GXDLMSSNParameters p = new GXDLMSSNParameters(settings, Command.ReadResponse, list.Count, requestType, null, bb); GXDLMS.GetSNPdu(p, replyData); if (server.transaction == null && (bb.Size != bb.Position || settings.Count != settings.Index)) { reads = new List <ValueEventArgs>(); foreach (var it in list) { reads.Add(it); } server.transaction = new GXDLMSLongTransaction(reads.ToArray(), Command.ReadRequest, bb); } else if (server.transaction != null) { replyData.Set(bb); return; } }
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); } } }
/// <summary> /// Handle read Block in blocks. /// </summary> /// <param name="data">Received data.</param> private static void HandleReadBlockNumberAccess(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml) { UInt16 blockNumber = data.GetUInt16(); if (xml != null) { xml.AppendStartTag(Command.ReadRequest, VariableAccessSpecification.BlockNumberAccess); xml.AppendLine("<BlockNumber Value=\"" + xml.IntegerToHex(blockNumber, 4) + "\" />"); xml.AppendEndTag(Command.ReadRequest, VariableAccessSpecification.BlockNumberAccess); return; } if (blockNumber != settings.BlockIndex) { GXByteBuffer bb = new GXByteBuffer(); Debug.WriteLine("handleReadRequest failed. Invalid block number. " + settings.BlockIndex + "/" + blockNumber); bb.SetUInt8(ErrorCode.DataBlockNumberInvalid); GXDLMS.GetSNPdu(new GXDLMSSNParameters(settings, Command.ReadResponse, 1, (byte)SingleReadResponse.DataAccessError, bb, null), replyData); settings.ResetBlockIndex(); return; } if (settings.Index != settings.Count && server.transaction.data.Size < settings.MaxPduSize) { List <ValueEventArgs> reads = new List <ValueEventArgs>(); List <ValueEventArgs> actions = new List <ValueEventArgs>(); foreach (ValueEventArgs it in server.transaction.targets) { if (it.action) { actions.Add(it); } else { reads.Add(it); } } if (reads.Count != 0) { server.NotifyRead(reads.ToArray()); } if (actions.Count != 0) { server.NotifyAction(actions.ToArray()); } GetReadData(settings, server.transaction.targets, server.transaction.data); if (reads.Count != 0) { server.NotifyPostRead(reads.ToArray()); } if (actions.Count != 0) { server.NotifyPostAction(actions.ToArray()); } } settings.IncreaseBlockIndex(); GXDLMSSNParameters p = new GXDLMSSNParameters(settings, Command.ReadResponse, 1, (byte)SingleReadResponse.DataBlockResult, null, server.transaction.data); p.multipleBlocks = true; GXDLMS.GetSNPdu(p, replyData); //If all data is sent. if (server.transaction.data.Size == server.transaction.data.Position) { server.transaction = null; settings.ResetBlockIndex(); } else { server.transaction.data.Trim(); } }
///<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); }
///<summary> /// Handle Access request. ///</summary> public static void HandleAccessRequest(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXByteBuffer reply, GXDLMSTranslatorStructure xml) { //Return error if connection is not established. if (xml == null && !settings.Connected && !settings.AllowAnonymousAccess) { reply.Set(GXDLMSServer.GenerateConfirmedServiceError(ConfirmedServiceError.InitiateError, ServiceError.Service, (byte)Service.Unsupported)); return; } //Get long invoke id and priority. UInt32 invokeId = data.GetUInt32(); int len = GXCommon.GetObjectCount(data); byte[] tmp = null; // If date time is given. if (len != 0) { tmp = new byte[len]; data.Get(tmp); if (xml == null) { DataType dt = DataType.DateTime; if (len == 4) { dt = DataType.Time; } else if (len == 5) { dt = DataType.Date; } GXDataInfo info = new GXDataInfo(); info.Type = dt; GXCommon.GetData(settings, new GXByteBuffer(tmp), info); } } // Get object count. int cnt = GXCommon.GetObjectCount(data); if (xml != null) { xml.AppendStartTag(Command.AccessRequest); xml.AppendLine(TranslatorTags.LongInvokeId, "Value", xml.IntegerToHex(invokeId, 2)); xml.AppendLine(TranslatorTags.DateTime, "Value", GXCommon.ToHex(tmp, false)); xml.AppendStartTag(TranslatorTags.AccessRequestBody); xml.AppendStartTag(TranslatorTags.ListOfAccessRequestSpecification, "Qty", xml.IntegerToHex(cnt, 2)); } AccessServiceCommandType type; for (int pos = 0; pos != cnt; ++pos) { type = (AccessServiceCommandType)data.GetUInt8(); if (!(type == AccessServiceCommandType.Get || type == AccessServiceCommandType.Set || type == AccessServiceCommandType.Action)) { throw new ArgumentException("Invalid access service command type."); } // CI ObjectType ci = (ObjectType)data.GetUInt16(); byte[] ln = new byte[6]; data.Get(ln); // Attribute Id byte attributeIndex = data.GetUInt8(); if (xml != null) { xml.AppendStartTag(TranslatorTags.AccessRequestSpecification); xml.AppendStartTag(Command.AccessRequest, type); AppendAttributeDescriptor(xml, (int)ci, ln, attributeIndex); xml.AppendEndTag(Command.AccessRequest, type); xml.AppendEndTag(TranslatorTags.AccessRequestSpecification); } } if (xml != null) { xml.AppendEndTag(TranslatorTags.ListOfAccessRequestSpecification); xml.AppendStartTag(TranslatorTags.AccessRequestListOfData, "Qty", xml.IntegerToHex(cnt, 2)); } // Get data count. cnt = GXCommon.GetObjectCount(data); for (int pos = 0; pos != cnt; ++pos) { GXDataInfo di = new GXDataInfo(); di.xml = xml; if (xml != null && xml.OutputType == TranslatorOutputType.StandardXml) { xml.AppendStartTag(Command.WriteRequest, SingleReadResponse.Data); } object value = GXCommon.GetData(settings, data, di); if (!di.Complete) { value = GXCommon.ToHex(data.Data, false, data.Position, data.Size - data.Position); } else if (value is byte[]) { value = GXCommon.ToHex((byte[])value, false); } if (xml != null && xml .OutputType == TranslatorOutputType.StandardXml) { xml.AppendEndTag(Command.WriteRequest, SingleReadResponse.Data); } } if (xml != null) { xml.AppendEndTag(TranslatorTags.AccessRequestListOfData); xml.AppendEndTag(TranslatorTags.AccessRequestBody); xml.AppendEndTag(Command.AccessRequest); } }
private static void HanleSetRequestWithDataBlock(GXDLMSSettings settings, GXDLMSServer server, GXByteBuffer data, GXDLMSLNParameters p, GXByteBuffer replyData, GXDLMSTranslatorStructure xml) { GXDataInfo reply = new GXDataInfo(); reply.xml = xml; byte lastBlock = data.GetUInt8(); p.multipleBlocks = lastBlock == 0; UInt32 blockNumber = data.GetUInt32(); if (xml == null && blockNumber != settings.BlockIndex) { Debug.WriteLine("HanleSetRequestWithDataBlock failed. Invalid block number. " + settings.BlockIndex + "/" + blockNumber); p.status = (byte)ErrorCode.DataBlockNumberInvalid; } else { settings.IncreaseBlockIndex(); int size = GXCommon.GetObjectCount(data); int realSize = data.Size - data.Position; if (size != realSize) { Debug.WriteLine("HanleSetRequestWithDataBlock failed. Invalid block size."); p.status = (byte)ErrorCode.DataBlockUnavailable; } if (xml != null) { xml.AppendStartTag(TranslatorTags.DataBlock); xml.AppendLine(TranslatorTags.LastBlock, "Value", xml.IntegerToHex(lastBlock, 2)); xml.AppendLine(TranslatorTags.BlockNumber, "Value", xml.IntegerToHex(blockNumber, 8)); xml.AppendLine(TranslatorTags.RawData, "Value", data.RemainingHexString(false)); xml.AppendEndTag(TranslatorTags.DataBlock); return; } server.transaction.data.Set(data); //If all data is received. if (!p.multipleBlocks) { try { object value = GXCommon.GetData(settings, server.transaction.data, reply); if (value is byte[]) { DataType dt = (server.transaction.targets[0].Target as IGXDLMSBase).GetDataType(server.transaction.targets[0].Index); if (dt != DataType.None && dt != DataType.OctetString) { value = GXDLMSClient.ChangeType((byte[])value, dt, settings.UseUtc2NormalTime); } } server.transaction.targets[0].Value = value; server.NotifyWrite(server.transaction.targets); if (!server.transaction.targets[0].Handled && !p.multipleBlocks) { (server.transaction.targets[0].Target as IGXDLMSBase).SetValue(settings, server.transaction.targets[0]); server.NotifyPostWrite(server.transaction.targets); } } catch (Exception) { p.status = (byte)ErrorCode.HardwareFault; } finally { server.transaction = null; } settings.ResetBlockIndex(); } } p.multipleBlocks = true; }
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 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); } }
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> /// Handle get request next data block command. /// </summary> /// <param name="data">Received data.</param> private static void GetRequestNextDataBlock(GXDLMSSettings settings, byte invokeID, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml) { GXByteBuffer bb = new GXByteBuffer(); UInt32 index; // Get block index. index = data.GetUInt32(); if (xml != null) { xml.AppendLine(TranslatorTags.BlockNumber, null, xml.IntegerToHex(index, 8)); return; } if (index != settings.BlockIndex) { Debug.WriteLine("handleGetRequest failed. Invalid block number. " + settings.BlockIndex + "/" + index); GXDLMS.GetLNPdu(new GXDLMSLNParameters(settings, 0, Command.GetResponse, 2, null, bb, (byte)ErrorCode.DataBlockNumberInvalid), replyData); } else { settings.IncreaseBlockIndex(); GXDLMSLNParameters p = new GXDLMSLNParameters(settings, invokeID, Command.GetResponse, 2, null, bb, (byte)ErrorCode.Ok); //If transaction is not in progress. if (server.transaction == null) { p.status = (byte)ErrorCode.NoLongGetOrReadInProgress; } else { bb.Set(server.transaction.data); bool moreData = settings.Index != settings.Count; if (moreData) { //If there is multiple blocks on the buffer. //This might happen when Max PDU size is very small. if (bb.Size < settings.MaxPduSize) { foreach (ValueEventArgs arg in server.transaction.targets) { object value; server.NotifyRead(new ValueEventArgs[] { arg }); if (arg.Handled) { value = arg.Value; } else { value = (arg.Target as IGXDLMSBase).GetValue(settings, arg); } //Add data. if (arg.ByteArray) { bb.Set((byte[])value); } else { GXDLMS.AppendData(settings, arg.Target, arg.Index, bb, value); } } moreData = settings.Index != settings.Count; } } p.multipleBlocks = true; GXDLMS.GetLNPdu(p, replyData); if (moreData || bb.Size - bb.Position != 0) { server.transaction.data = bb; } else { server.transaction = null; settings.ResetBlockIndex(); } } } }
/// <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="GetDataNotificationMessages"/> 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); }
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; } }
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; }
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 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; }
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; }
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; }
/// <summary> /// Handle get request with list command. /// </summary> /// <param name="data">Received data.</param> private static void GetRequestWithList(GXDLMSSettings settings, byte invokeID, GXDLMSServer server, GXByteBuffer data, GXByteBuffer replyData, GXDLMSTranslatorStructure xml) { ValueEventArgs e; GXByteBuffer bb = new GXByteBuffer(); int pos; int cnt = GXCommon.GetObjectCount(data); GXCommon.SetObjectCount(cnt, bb); List <ValueEventArgs> list = new List <ValueEventArgs>(); if (xml != null) { xml.AppendStartTag(TranslatorTags.AttributeDescriptorList, "Qty", xml.IntegerToHex(cnt, 2)); } try { for (pos = 0; pos != cnt; ++pos) { ObjectType ci = (ObjectType)data.GetUInt16(); byte[] ln = new byte[6]; data.Get(ln); short attributeIndex = data.GetUInt8(); // AccessSelection int selection = data.GetUInt8(); int selector = 0; object parameters = null; if (selection != 0) { selector = data.GetUInt8(); GXDataInfo info = new GXDataInfo(); parameters = GXCommon.GetData(settings, data, info); } if (xml != null) { xml.AppendStartTag(TranslatorTags.AttributeDescriptorWithSelection); xml.AppendStartTag(TranslatorTags.AttributeDescriptor); xml.AppendComment(ci.ToString()); xml.AppendLine(TranslatorTags.ClassId, "Value", xml.IntegerToHex((int)ci, 4)); xml.AppendComment(GXCommon.ToLogicalName(ln)); xml.AppendLine(TranslatorTags.InstanceId, "Value", GXCommon.ToHex(ln, false)); xml.AppendLine(TranslatorTags.AttributeId, "Value", xml.IntegerToHex(attributeIndex, 2)); xml.AppendEndTag(TranslatorTags.AttributeDescriptor); xml.AppendEndTag(TranslatorTags.AttributeDescriptorWithSelection); } else { GXDLMSObject obj = settings.Objects.FindByLN(ci, GXCommon.ToLogicalName(ln)); if (obj == null) { obj = server.NotifyFindObject(ci, 0, GXCommon.ToLogicalName(ln)); } if (obj == null) { // "Access Error : Device reports a undefined object." e = new ValueEventArgs(server, obj, attributeIndex, 0, 0); e.Error = ErrorCode.UndefinedObject; list.Add(e); } else { ValueEventArgs arg = new ValueEventArgs(server, obj, attributeIndex, selector, parameters); arg.InvokeId = invokeID; if (server.NotifyGetAttributeAccess(arg) == AccessMode.NoAccess) { //Read Write denied. arg.Error = ErrorCode.ReadWriteDenied; list.Add(arg); } else { list.Add(arg); } } } } } catch (Exception ex) { if (xml == null) { throw ex; } } if (xml != null) { xml.AppendEndTag(TranslatorTags.AttributeDescriptorList); return; } server.NotifyRead(list.ToArray()); object value; pos = 0; foreach (ValueEventArgs it in list) { try { if (it.Handled) { value = it.Value; } else { value = (it.Target as IGXDLMSBase).GetValue(settings, it); } bb.SetUInt8(it.Error); if (it.ByteArray) { bb.Set((byte[])value); } else { GXDLMS.AppendData(settings, it.Target, it.Index, bb, value); } invokeID = (byte)it.InvokeId; } catch (Exception) { bb.SetUInt8((byte)ErrorCode.HardwareFault); } if (settings.Index != settings.Count) { server.transaction = new GXDLMSLongTransaction(list.ToArray(), Command.GetRequest, null); } ++pos; } server.NotifyPostRead(list.ToArray()); GXDLMSLNParameters p = new GXDLMSLNParameters(settings, invokeID, Command.GetResponse, 3, null, bb, 0xFF); GXDLMS.GetLNPdu(p, replyData); }
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; }
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; } }
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; }
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; }
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; } }
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; } } }