/// <summary> /// Load XML commands from xml string. /// </summary> /// <param name="xml"></param> /// <returns></returns> public List <GXDLMSXmlPdu> LoadXml(string xml) { XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); List <GXDLMSXmlPdu> actions = new List <GXDLMSXmlPdu>(); foreach (XmlNode m1 in doc.ChildNodes) { if (m1.NodeType == XmlNodeType.Element) { foreach (XmlNode node in m1.ChildNodes) { if (node.NodeType == XmlNodeType.Element) { GXDLMSXmlSettings s = new GXDLMSXmlSettings(translator.OutputType, translator.Hex, translator.ShowStringAsHex, translator.tagsByName);; s.settings.ClientAddress = Settings.ClientAddress; s.settings.ServerAddress = Settings.ServerAddress; byte[] reply = translator.XmlToPdu(node.OuterXml, s); if (s.command == Command.Snrm && !s.settings.IsServer) { Settings.Limits.MaxInfoTX = s.settings.Limits.MaxInfoTX; Settings.Limits.MaxInfoRX = s.settings.Limits.MaxInfoRX; Settings.Limits.WindowSizeRX = s.settings.Limits.WindowSizeRX; Settings.Limits.WindowSizeTX = s.settings.Limits.WindowSizeTX; } else if (s.command == Command.Ua && s.settings.IsServer) { Settings.Limits.MaxInfoTX = s.settings.Limits.MaxInfoTX; Settings.Limits.MaxInfoRX = s.settings.Limits.MaxInfoRX; Settings.Limits.WindowSizeRX = s.settings.Limits.WindowSizeRX; Settings.Limits.WindowSizeTX = s.settings.Limits.WindowSizeTX; } if (s.template) { reply = null; } actions.Add(new GXDLMSXmlPdu(s.command, node, reply)); } } } } return(actions); }
/// <summary> /// Handle AARE and AARQ XML tags. /// </summary> /// <param name="node">XML node.</param> /// <param name="s">XML Settings.</param> /// <param name="tag">XML tag.</param> private static void HandleAarqAare(XmlNode node, GXDLMSXmlSettings s, int tag) { byte[] tmp; byte[] conformanceBlock; int value; switch (tag) { case (int)TranslatorGeneralTags.ApplicationContextName: if (s.OutputType == TranslatorOutputType.StandardXml) { value = int.Parse(node.InnerText); switch (value) { case 1: s.settings.UseLogicalNameReferencing = true; break; case 2: s.settings.UseLogicalNameReferencing = false; break; case 3: s.settings.UseLogicalNameReferencing = true; break; case 4: s.settings.UseLogicalNameReferencing = false; break; default: throw new ArgumentException("Invalid dedicated key."); } } else { string str = node.Attributes[0].InnerText; if (string.Compare(str, "SN") == 0 || string.Compare(str, "SN_WITH_CIPHERING") == 0) { s.settings.UseLogicalNameReferencing = false; } else if (string.Compare(str, "LN") == 0 || string.Compare(str, "LN_WITH_CIPHERING") == 0) { s.settings.UseLogicalNameReferencing = true; } else { throw new ArgumentException("Invalid Reference type name."); } } break; case (byte)Command.GloInitiateRequest: case (byte)Command.GloGetRequest: case (byte)Command.GloSetRequest: case (byte)Command.GloMethodRequest: case (byte)Command.GloReadRequest: case (byte)Command.GloWriteRequest: s.settings.IsServer = false; tmp = GXCommon.HexToBytes(GetValue(node, s)); s.settings.Cipher.Security = (Security)tmp[0]; s.data.Set(tmp); break; case (byte)Command.GloInitiateResponse: case (byte)Command.GloGetResponse: case (byte)Command.GloSetResponse: case (byte)Command.GloMethodResponse: case (byte)Command.GloReadResponse: case (byte)Command.GloWriteResponse: tmp = GXCommon.HexToBytes(GetValue(node, s)); s.settings.Cipher.Security = (Security)tmp[0]; s.data.Set(tmp); break; case (byte)Command.InitiateRequest: case (byte)Command.InitiateResponse: if (s.OutputType == TranslatorOutputType.StandardXml) { GXByteBuffer bb = new GXByteBuffer(); tmp = GXCommon.HexToBytes(GetValue(node, s)); GXCommon.SetObjectCount(tmp.Length, bb); bb.Set(tmp); GXAPDU.ParseUserInformation(s.settings, s.settings.Cipher, bb, null); if (s.command == Command.Aarq) { if (s.settings.UseLogicalNameReferencing) { s.settings.LnSettings.ConformanceBlock = s.settings.ConformanceBlock; } else { s.settings.SnSettings.ConformanceBlock = s.settings.ConformanceBlock; } } } break; case 0xBE00: //NegotiatedQualityOfService break; case 0xBE06: case 0xBE01: //NegotiatedDlmsVersionNumber or ProposedDlmsVersionNumber is skipped. break; case 0xBE04: //VaaName is not needed. break; case 0x8A: //SenderACSERequirements is not needed. break; case 0x8B: case 0x89: //MechanismName. s.settings.Authentication = (Authentication)Enum.Parse(typeof(Authentication), GetValue(node, s)); if (s.OutputType == TranslatorOutputType.SimpleXml) { s.settings.Authentication = (Authentication)Enum.Parse(typeof(Authentication), GetValue(node, s)); } else { s.settings.Authentication = (Authentication)int.Parse(GetValue(node, s)); } break; case 0xAC: //CallingAuthentication. if (s.settings.Authentication == Authentication.Low) { s.settings.Password = GXCommon.HexToBytes(GetValue(node, s)); } else { s.settings.CtoSChallenge = GXCommon.HexToBytes(GetValue(node, s)); } break; case (int)TranslatorGeneralTags.DedicatedKey: tmp = GXCommon.HexToBytes(GetValue(node, s)); s.settings.DedicatedKey = tmp; break; case (int)TranslatorGeneralTags.CallingAPTitle: s.settings .CtoSChallenge = GXCommon.HexToBytes(GetValue(node, s)); break; case 0xA4: //RespondingAPTitle. s.settings.StoCChallenge = GXCommon.HexToBytes(GetValue(node, s)); break; case 0xBE03: case 0xBE05: //ProposedConformance or NegotiatedConformance if (s.settings.UseLogicalNameReferencing) { s.settings.LnSettings.Clear(); } else { s.settings.SnSettings.Clear(); } if (s.OutputType == TranslatorOutputType.StandardXml) { String nodes = node.InnerText; if (s.settings.UseLogicalNameReferencing) { conformanceBlock = s.settings.LnSettings.ConformanceBlock; } else { conformanceBlock = s.settings.SnSettings.ConformanceBlock; } foreach (String it in nodes.Split(' ')) { if (it.Trim() != string.Empty) { value = (int)ValueOfConformance(it.Trim()); if (value < 0x100) { conformanceBlock[2] |= (byte)value; } else if (value < 0x10000) { conformanceBlock[1] |= (byte)(value >> 8); } else { conformanceBlock[0] |= (byte)(value >> 16); } } } } break; case 0xBE08: //ConformanceBit. value = (int)Enum.Parse(typeof(Conformance), node.Attributes["Name"].InnerText); if (s.settings.UseLogicalNameReferencing) { conformanceBlock = s.settings.LnSettings.ConformanceBlock; } else { conformanceBlock = s.settings.SnSettings.ConformanceBlock; } if (value < 0x100) { conformanceBlock[2] |= (byte)value; } else if (value < 0x10000) { conformanceBlock[1] |= (byte)(value >> 8); } else { conformanceBlock[0] |= (byte)(value >> 16); } break; case 0xA2: //AssociationResult s.result = (AssociationResult)Enum.Parse(typeof(AssociationResult), GetValue(node, s)); break; case 0xBE02: case 0xBE07: //NegotiatedMaxPduSize or ProposedMaxPduSize. s.settings.MaxPduSize = (UInt16)s.ParseInt(GetValue(node, s)); break; case 0xA3: //ResultSourceDiagnostic s.diagnostic = SourceDiagnostic.None; break; case 0xA301: //ACSEServiceUser s.diagnostic = (SourceDiagnostic)s.ParseInt(GetValue(node, s)); break; case 0xBE09: // ProposedQualityOfService break; case (int)TranslatorGeneralTags.CharString: // Get PW if (s.settings.Authentication == Authentication.Low) { s.settings .Password = GXCommon.HexToBytes(GetValue(node, s)); } else { if (s.command == Command.Aarq) { s.settings.CtoSChallenge = GXCommon.HexToBytes(GetValue(node, s)); } else { s.settings.StoCChallenge = GXCommon.HexToBytes(GetValue(node, s)); } } break; case (int)TranslatorGeneralTags.ResponderACSERequirement: break; case (int)TranslatorGeneralTags.RespondingAuthentication: s.settings .StoCChallenge = GXCommon.HexToBytes(GetValue(node, s)); break; case (int)TranslatorTags.Result: s.result = (AssociationResult) int.Parse(GetValue(node, s)); break; default: throw new ArgumentException("Invalid AARQ node: " + node.Name); } }
/// <summary> /// Load XML commands from the file. /// </summary> /// <param name="fileName"></param> /// <returns></returns> public List <GXDLMSXmlMessage> Load(string fileName) { XmlDocument doc = new XmlDocument(); doc.LoadXml(File.ReadAllText(fileName)); List <GXDLMSXmlMessage> actions = new List <GXDLMSXmlMessage>(); foreach (XmlNode m1 in doc.ChildNodes) { if (m1.NodeType == XmlNodeType.Element) { foreach (XmlNode node in m1.ChildNodes) { if (node.NodeType == XmlNodeType.Element) { List <byte[]> messages = new List <byte[]>(); GXDLMSXmlSettings s = new GXDLMSXmlSettings(translator.OutputType, translator.Hex, translator.ShowStringAsHex, translator.tagsByName);; s.settings.ClientAddress = Settings.ClientAddress; s.settings.ServerAddress = Settings.ServerAddress; GXByteBuffer reply = new GXByteBuffer(translator.XmlToPdu(node.OuterXml, s)); if (s.command == Command.Snrm) { messages.Add(reply.Array()); } else if (s.command == Command.Ua) { Settings.Limits.MaxInfoTX = s.settings.Limits.MaxInfoTX; Settings.Limits.MaxInfoRX = s.settings.Limits.MaxInfoRX; Settings.Limits.WindowSizeRX = s.settings.Limits.WindowSizeRX; Settings.Limits.WindowSizeTX = s.settings.Limits.WindowSizeTX; messages.Add(reply.Array()); } else if (s.command == Command.DisconnectRequest) { messages.Add(GXDLMS.GetHdlcFrame(Settings, (byte)Command.DisconnectRequest, reply)); } else { while (reply.Position != reply.Size) { if (Settings.InterfaceType == Enums.InterfaceType.WRAPPER) { messages.Add(GXDLMS.GetWrapperFrame(Settings, reply)); } else if (Settings.InterfaceType == Enums.InterfaceType.HDLC) { byte frame = 0; if (s.command == Command.Aarq) { frame = 0x10; } else if (s.command == Command.Aare) { frame = 0x30; } else if (s.command == Command.EventNotification) { frame = 0x13; } messages.Add(GXDLMS.GetHdlcFrame(Settings, frame, reply)); if (reply.Position != reply.Size) { if (Settings.IsServer || s.command == Command.SetRequest) { frame = 0; } else { frame = Settings.NextSend(false); } } } else if (Settings.InterfaceType == Enums.InterfaceType.PDU) { messages.Add(reply.Array()); break; } else { throw new ArgumentOutOfRangeException("InterfaceType"); } } } actions.Add(new GXDLMSXmlMessage(s.command, node, messages.ToArray())); } } } } return(actions); }
private static void ReadAllNodes(XmlDocument doc, GXDLMSXmlSettings s) { if (doc != null) { foreach (XmlNode node in doc.ChildNodes) { if (node.NodeType == XmlNodeType.Element) { ReadNode(node, s); } } } }
/// <summary> /// Get command from XML. /// </summary> /// <param name="node">XML node.</param> /// <param name="s">XML settings.</param> /// <param name="tag">tag.</param> private static void GetCommand(XmlNode node, GXDLMSXmlSettings s, int tag) { s.command = (Command)tag; switch (tag) { case (byte)Command.Snrm: case (byte)Command.Aarq: case (byte)Command.GetRequest: case (byte)Command.SetRequest: case (byte)Command.ReadRequest: case (byte)Command.WriteRequest: case (byte)Command.MethodRequest: case (byte)Command.ReleaseRequest: case (int)Command.AccessRequest: case (int)Command.InitiateRequest: case (int)Command.ConfirmedServiceError: s.settings.IsServer = false; break; case (byte)Command.Ua: case (byte)Command.Aare: case (byte)Command.GetResponse: case (byte)Command.SetResponse: case (byte)Command.ReadResponse: case (byte)Command.WriteResponse: case (byte)Command.MethodResponse: case (byte)Command.ReleaseResponse: case (int)Command.DataNotification: case (int)Command.AccessResponse: case (int)Command.InitiateResponse: break; default: throw new ArgumentException("Invalid Command: " + node.Name); } }
private static GXByteBuffer UpdateDataType(XmlNode node, GXDLMSXmlSettings s, int tag) { GXByteBuffer preData = null; switch ((DataType)(tag - GXDLMS.DATA_TYPE_OFFSET)) { case DataType.Array: s.data.SetUInt8(DataType.Array); preData = new GXByteBuffer(s.data); s.data.Size = 0; break; case DataType.Bcd: GXCommon.SetData(s.settings, s.data, DataType.Bcd, s.ParseShort(GetValue(node, s))); break; case DataType.BitString: GXCommon.SetData(s.settings, s.data, DataType.BitString, GetValue(node, s)); break; case DataType.Boolean: GXCommon.SetData(s.settings, s.data, DataType.Boolean, s.ParseShort(GetValue(node, s))); break; case DataType.Date: GXCommon.SetData(s.settings, s.data, DataType.Date, GXDLMSClient.ChangeType(GXCommon.HexToBytes(GetValue(node, s)), DataType.DateTime)); break; case DataType.DateTime: GXCommon.SetData(s.settings, s.data, DataType.DateTime, GXDLMSClient.ChangeType(GXCommon.HexToBytes(GetValue(node, s)), DataType.DateTime)); break; case DataType.Enum: GXCommon.SetData(s.settings, s.data, DataType.Enum, s.ParseShort(GetValue(node, s))); break; case DataType.Float32: GetFloat32(node, s); break; case DataType.Float64: GetFloat64(node, s); break; case DataType.Int16: GXCommon.SetData(s.settings, s.data, DataType.Int16, s.ParseShort(GetValue(node, s))); break; case DataType.Int32: GXCommon.SetData(s.settings, s.data, DataType.Int32, s.ParseInt(GetValue(node, s))); break; case DataType.Int64: GXCommon.SetData(s.settings, s.data, DataType.Int64, s.ParseLong(GetValue(node, s))); break; case DataType.Int8: GXCommon.SetData(s.settings, s.data, DataType.Int8, s.ParseShort(GetValue(node, s))); break; case DataType.None: GXCommon.SetData(s.settings, s.data, DataType.None, null); break; case DataType.OctetString: GetOctetString(node, s); break; case DataType.String: if (s.showStringAsHex) { GXCommon.SetData(s.settings, s.data, DataType.String, GXCommon.HexToBytes(GetValue(node, s))); } else { GXCommon.SetData(s.settings, s.data, DataType.String, GetValue(node, s)); } break; case DataType.StringUTF8: if (s.showStringAsHex) { GXCommon.SetData(s.settings, s.data, DataType.StringUTF8, GXCommon.HexToBytes(GetValue(node, s))); } else { GXCommon.SetData(s.settings, s.data, DataType.StringUTF8, GetValue(node, s)); } break; case DataType.Structure: s.data.SetUInt8(DataType.Structure); preData = new GXByteBuffer(s.data); s.data.Size = 0; break; case DataType.Time: GXCommon.SetData(s.settings, s.data, DataType.Time, GXDLMSClient.ChangeType(GXCommon.HexToBytes(GetValue(node, s)), DataType.DateTime)); break; case DataType.UInt16: GXCommon.SetData(s.settings, s.data, DataType.UInt16, s.ParseInt(GetValue(node, s))); break; case DataType.UInt32: GXCommon.SetData(s.settings, s.data, DataType.UInt32, s.ParseLong(GetValue(node, s))); break; case DataType.UInt64: GXCommon.SetData(s.settings, s.data, DataType.UInt64, s.ParseULong(GetValue(node, s))); break; case DataType.UInt8: GXCommon.SetData(s.settings, s.data, DataType.UInt8, s.ParseShort(GetValue(node, s))); break; default: throw new ArgumentException("Invalid node: " + node.Name); } return preData; }
/// <summary> /// Convert XML data fo bytes. /// </summary> /// <param name="xml">XML data.</param> /// <returns>Data in bytes.</returns> public byte[] XmlToData(string xml) { XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); GXDLMSXmlSettings s = new GXDLMSXmlSettings(OutputType, Hex, ShowStringAsHex, tagsByName); GetAllDataNodes(doc.ChildNodes, s); return s.data.Array(); }
private static void GetFloat64(XmlNode node, GXDLMSXmlSettings s) { GXByteBuffer bb = new GXByteBuffer(); bb.SetHexString(GetValue(node, s)); GXCommon.SetData(s.settings, s.data, DataType.Float64, bb.GetDouble()); }
/// <summary> /// Convert xml to byte array. /// </summary> /// <param name="xml">Converted xml.</param> /// <returns>Converted bytes.</returns> public byte[] XmlToPdu(string xml) { XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); GXDLMSXmlSettings s = new GXDLMSXmlSettings(OutputType, Hex, ShowStringAsHex, tagsByName); ReadAllNodes(doc, s); GXByteBuffer bb = new GXByteBuffer(); GXDLMSLNParameters ln; GXDLMSSNParameters sn; switch (s.command) { case Command.InitiateRequest: case Command.InitiateResponse: break; case Command.ReadRequest: case Command.WriteRequest: case Command.ReadResponse: case Command.WriteResponse: sn = new GXDLMSSNParameters(s.settings, s.command, s.count, s.requestType, s.attributeDescriptor, s.data); GXDLMS.GetSNPdu(sn, bb); break; case Command.GetRequest: case Command.GetResponse: case Command.SetRequest: case Command.SetResponse: case Command.MethodRequest: case Command.MethodResponse: ln = new GXDLMSLNParameters(s.settings, s.command, s.requestType, s.attributeDescriptor, s.data, 0xff); GXDLMS.GetLNPdu(ln, bb); break; case Command.GloGetRequest: case Command.GloGetResponse: case Command.GloSetRequest: case Command.GloSetResponse: case Command.GloMethodRequest: case Command.GloMethodResponse: case Command.GloReadRequest: case Command.GloWriteRequest: case Command.GloReadResponse: case Command.GloWriteResponse: bb.SetUInt8((byte)s.command); GXCommon.SetObjectCount(s.data.Size, bb); bb.Set(s.data); break; case Command.Rejected: break; case Command.Snrm: s.settings.IsServer = false; bb.Set(GXDLMS.GetHdlcFrame(s.settings, (byte)Command.Snrm, null)); break; case Command.Ua: break; case Command.Aarq: case Command.GloInitiateRequest: GXAPDU.GenerateAarq(s.settings, s.settings.Cipher, s.data, bb); break; case Command.Aare: case Command.GloInitiateResponse: GXAPDU.GenerateAARE(s.settings, bb, s.result, s.diagnostic, s.settings.Cipher, s.data); break; case Command.DisconnectRequest: break; case Command.ReleaseRequest: bb.SetUInt8((byte)s.command); bb.SetUInt8(0); break; case Command.ReleaseResponse: bb.SetUInt8((byte)s.command); //Len bb.SetUInt8(3); //BerType bb.SetUInt8(BerType.Context); //Len. bb.SetUInt8(1); bb.SetUInt8(s.reason); break; case Command.ConfirmedServiceError: break; case Command.ExceptionResponse: break; case Command.GeneralBlockTransfer: break; case Command.AccessRequest: ln = new GXDLMSLNParameters(s.settings, s.command, s.requestType, s.attributeDescriptor, s.data, 0xff); GXDLMS.GetLNPdu(ln, bb); break; case Command.AccessResponse: ln = new GXDLMSLNParameters(s.settings, s.command, s.requestType, s.attributeDescriptor, s.data, 0xff); GXDLMS.GetLNPdu(ln, bb); break; case Command.DataNotification: ln = new GXDLMSLNParameters(s.settings, s.command, s.requestType, s.attributeDescriptor, s.data, 0xff); ln.time = s.time; GXDLMS.GetLNPdu(ln, bb); break; case Command.GloGeneralCiphering: break; case Command.GloEventNotificationRequest: break; default: case Command.None: throw new ArgumentException("Invalid command."); } return bb.Array(); }
private static void ReadNode( XmlNode node, GXDLMSXmlSettings s) { int tag = 0; String str; if (s.OutputType == TranslatorOutputType.SimpleXml) { str = node.Name.ToLower(); } else { str = node.Name; } if (s.command != Command.ConfirmedServiceError || s.tags.ContainsKey(str)) { tag = s.tags[str]; } ErrorCode err; UInt32 value; byte[] tmp; GXByteBuffer preData = null; if (s.command == Command.None) { if (!((s.settings.ClientAddress == 0 || s.settings.ServerAddress == 0) && GetFrame(node, s, tag) || tag == (int)TranslatorTags.PduDlms || tag == (int)TranslatorTags.PduCse)) { GetCommand(node, s, tag); } } else if (s.command == Command.Aarq || s.command == Command.Aare) { HandleAarqAare(node, s, tag); } else if (tag >= GXDLMS.DATA_TYPE_OFFSET) { if (tag == (int)DataType.DateTime + GXDLMS.DATA_TYPE_OFFSET) { preData = UpdateDateTime(node, s, preData); } else { preData = UpdateDataType(node, s, tag); } } else if (s.command == Command.ConfirmedServiceError) { if (s.OutputType == TranslatorOutputType.StandardXml) { if (tag == (int)TranslatorTags.InitiateError) { s.attributeDescriptor.SetUInt8(1); } else { ServiceError se = TranslatorStandardTags.GetServiceError(str.Substring(2)); s.attributeDescriptor.SetUInt8(se); s.attributeDescriptor.SetUInt8(TranslatorStandardTags.GetError(se, GetValue(node, s))); } } else { if (tag == (int)TranslatorTags.ServiceError) { } else { if (s.attributeDescriptor.Size == 0) { s.attributeDescriptor.SetUInt8((byte)s.ParseShort(GetValue(node, s))); } else { ServiceError se = TranslatorSimpleTags.GetServiceError(str); s.attributeDescriptor.SetUInt8(se); s.attributeDescriptor.SetUInt8(TranslatorSimpleTags.GetError(se, GetValue(node, s))); } } } } else { switch (tag) { case (int)(Command.GetRequest) << 8 | (byte)GetCommandType.Normal: case (int)(Command.GetRequest) << 8 | (byte)GetCommandType.NextDataBlock: case (int)(Command.GetRequest) << 8 | (byte)GetCommandType.WithList: case (int)(Command.SetRequest) << 8 | (byte)SetRequestType.Normal: case (int)(Command.SetRequest) << 8 | (byte)SetRequestType.FirstDataBlock: case (int)(Command.SetRequest) << 8 | (byte)SetRequestType.WithDataBlock: case (int)(Command.SetRequest) << 8 | (byte)SetRequestType.WithList: s.requestType = (byte)(tag & 0xF); break; case (int)(Command.GetResponse) << 8 | (byte)GetCommandType.Normal: case (int)(Command.GetResponse) << 8 | (byte)GetCommandType.NextDataBlock: case (int)(Command.GetResponse) << 8 | (byte)GetCommandType.WithList: case (int)(Command.SetResponse) << 8 | (byte)SetResponseType.Normal: case (int)(Command.SetResponse) << 8 | (byte)SetResponseType.DataBlock: case (int)(Command.SetResponse) << 8 | (byte)SetResponseType.LastDataBlock: case (int)(Command.SetResponse) << 8 | (byte)SetResponseType.WithList: case (int)(Command.SetResponse) << 8 | (byte)SetResponseType.LastDataBlockWithList: s.requestType = (byte)(tag & 0xF); break; case (int)(Command.ReadResponse) << 8 | (byte)SingleReadResponse.DataBlockResult: ++s.count; s.requestType = (byte)(tag & 0xF); break; case (int)(Command.ReadRequest) << 8 | (byte)VariableAccessSpecification.ParameterisedAccess: s.requestType = (byte)VariableAccessSpecification.ParameterisedAccess; break; case (int)(Command.ReadRequest) << 8 | (byte)VariableAccessSpecification.BlockNumberAccess: s.requestType = (byte)VariableAccessSpecification.BlockNumberAccess; ++s.count; break; case (byte)(int)(Command.MethodRequest) << 8 | (byte)ActionRequestType.Normal: s.requestType = (byte)(tag & 0xFF); break; case (byte)(int)(Command.MethodRequest) << 8 | (byte)ActionRequestType.NextBlock: s.requestType = (byte)(tag & 0xFF); break; case (byte)(int)(Command.MethodRequest) << 8 | (byte)ActionRequestType.WithList: s.requestType = (byte)(tag & 0xFF); break; case (byte)(int)(Command.MethodResponse) << 8 | (byte)ActionRequestType.Normal: //MethodResponseNormal s.requestType = (byte)(tag & 0xFF); break; case (int)(Command.ReadResponse) << 8 | (byte)SingleReadResponse.Data: case (int)TranslatorTags.Data: if (s.command == Command.ReadRequest || s.command == Command.ReadResponse || s.command == Command.GetRequest) { ++s.count; s.requestType = 0; } else if (s.command == Command.GetResponse || s.command == Command.MethodResponse) { s.data.SetUInt8(0); // Add status. } break; case (int)TranslatorTags.Success: ++s.count; s.attributeDescriptor.Add((byte)ErrorCode.Ok); break; case (int)TranslatorTags.DataAccessError: ++s.count; s.attributeDescriptor.SetUInt8(1); s.attributeDescriptor.SetUInt8(ValueOfErrorCode(s.OutputType, GetValue(node, s))); break; case (int)TranslatorTags.ListOfVariableAccessSpecification: case (int)TranslatorTags.VariableAccessSpecification: break; case (int)TranslatorTags.ListOfData: if (s.command == Command.AccessResponse && s.data.Size == 0) { // If access-request-specification is not given. s.data.SetUInt8(0); } if (s.OutputType == TranslatorOutputType.SimpleXml || s.command != Command.WriteRequest) { GXCommon.SetObjectCount(node.ChildNodes.Count, s.data); } break; case (int)Command.AccessResponse << 8 | (byte)AccessServiceCommandType.Get: case (int)Command.AccessResponse << 8 | (byte)AccessServiceCommandType.Set: case (int)Command.AccessResponse << 8 | (byte)AccessServiceCommandType.Action: s.data.SetUInt8((byte)(0xFF & tag)); break; case (int)TranslatorTags.DateTime: preData = UpdateDateTime(node, s, preData); break; case (int)TranslatorTags.InvokeId: value = (uint)s.ParseShort(GetValue(node, s)); if ((value & 0x80) != 0) { s.settings.Priority = Priority.High; } else { s.settings.Priority = Priority.Normal; } if ((value & 0x40) != 0) { s.settings.ServiceClass = ServiceClass.Confirmed; } else { s.settings.ServiceClass = ServiceClass.UnConfirmed; } s.settings.InvokeID = (byte)(value & 0xF); break; case (int)TranslatorTags.LongInvokeId: value = (uint)s.ParseLong(GetValue(node, s)); if ((value & 0x80000000) != 0) { s.settings.Priority = Priority.High; } else { s.settings.Priority = Priority.Normal; } if ((value & 0x40000000) != 0) { s.settings.ServiceClass = ServiceClass.Confirmed; } else { s.settings.ServiceClass = ServiceClass.UnConfirmed; } s.settings.longInvokeID = (UInt16)(value & 0xFFFFFFF); break; case 0x88: //ResponderACSERequirement break; case 0x80: //RespondingAuthentication s.settings.StoCChallenge = GXCommon.HexToBytes(GetValue(node, s)); break; case (int)TranslatorTags.AttributeDescriptor: break; case (int)TranslatorTags.ClassId: s.attributeDescriptor.SetUInt16((UInt16)s.ParseInt(GetValue(node, s))); break; case (int)TranslatorTags.InstanceId: s.attributeDescriptor.Add(GXCommon.HexToBytes(GetValue(node, s))); break; case (int)TranslatorTags.AttributeId: s.attributeDescriptor.SetUInt8((byte)s.ParseShort(GetValue(node, s))); //Add AccessSelection. if (s.command != Command.AccessRequest) { s.attributeDescriptor.SetUInt8(0); } break; case (int)TranslatorTags.MethodInvocationParameters: s.attributeDescriptor.SetUInt8(s.attributeDescriptor.Size - 1, 1); break; case (int)TranslatorTags.Selector: s.attributeDescriptor.Set(GXCommon.HexToBytes(GetValue(node, s))); break; case (int)TranslatorTags.Parameter: break; case (int)TranslatorTags.LastBlock: s.data.SetUInt8((byte)s.ParseShort(GetValue(node, s))); break; case (int)TranslatorTags.BlockNumber: //BlockNumber if (s.command == Command.GetRequest || s.command == Command.GetResponse) { s.data.SetUInt32((UInt32)s.ParseLong(GetValue(node, s))); } else { s.data.SetUInt16((UInt16)s.ParseInt(GetValue(node, s))); } break; case (int)TranslatorTags.RawData: //RawData if (s.command == Command.GetResponse) { s.data.SetUInt8(0); } tmp = GXCommon.HexToBytes(GetValue(node, s)); GXCommon.SetObjectCount(tmp.Length, s.data); s.data.Set(tmp); break; case (int)TranslatorTags.MethodDescriptor: break; case (int)TranslatorTags.MethodId: s.attributeDescriptor.SetUInt8((byte)s.ParseShort(GetValue(node, s))); //Add MethodInvocationParameters s.attributeDescriptor.SetUInt8(0); break; case (int)TranslatorTags.Result: case (int)TranslatorGeneralTags.AssociationResult: //Result. if (s.command == Command.GetRequest || s.requestType == 3) { GXCommon.SetObjectCount(node.ChildNodes.Count, s.attributeDescriptor); } else if (s.command == Command.MethodResponse || s.command == Command.SetResponse) { str = GetValue(node, s); if (str != "") { s.attributeDescriptor.SetUInt8((byte)ValueOfErrorCode(s.OutputType, str)); } } else if (s.command == Command.AccessResponse) { str = GetValue(node, s); if (str != "") { s.data.SetUInt8(ValueOfErrorCode(s.OutputType, str)); } } break; case (int)TranslatorTags.Reason: s.reason = (ReleaseRequestReason)Enum.Parse(typeof(ReleaseRequestReason), GetValue(node, s)); break; case (int)TranslatorTags.ReturnParameters: s.attributeDescriptor.SetUInt8(1); break; case (int)TranslatorTags.AccessSelection: s.attributeDescriptor.SetUInt8(s.attributeDescriptor.Size - 1, 1); break; case (int)TranslatorTags.Value: break; case (int)TranslatorTags.AccessSelector: s.data.SetUInt8((byte)s.ParseShort(GetValue(node, s))); break; case (int)TranslatorTags.AccessParameters: break; case (int)TranslatorTags.AttributeDescriptorList: GXCommon.SetObjectCount(node.ChildNodes.Count, s.attributeDescriptor); break; case (int)TranslatorTags.AttributeDescriptorWithSelection: case (int)Command.AccessRequest << 8 | (byte)AccessServiceCommandType.Get: case (int)Command.AccessRequest << 8 | (byte)AccessServiceCommandType.Set: case (int)Command.AccessRequest << 8 | (byte)AccessServiceCommandType.Action: s.attributeDescriptor.SetUInt8((byte)(tag & 0xFF)); break; case (int)Command.ReadRequest << 8 | (byte)VariableAccessSpecification.VariableName: case (int)Command.WriteRequest << 8 | (byte)VariableAccessSpecification.VariableName: case (int)Command.WriteRequest << 8 | (byte)SingleReadResponse.Data: if (s.command != Command.AccessRequest && s.command != Command.AccessResponse) { if (!(s.OutputType == TranslatorOutputType.StandardXml && tag == ((int)Command.WriteRequest << 8 | (int)SingleReadResponse.Data))) { if (s.requestType == 0xFF) { s.attributeDescriptor.SetUInt8( VariableAccessSpecification.VariableName); } else { s.attributeDescriptor.SetUInt8(s.requestType); s.requestType = 0xFF; } ++s.count; } else { s.attributeDescriptor.SetUInt8((byte)s.count); } if (s.OutputType == TranslatorOutputType.SimpleXml) { s.attributeDescriptor.SetUInt16((UInt16)s.ParseShort(GetValue(node, s))); } else { str = GetValue(node, s); if (!String.IsNullOrEmpty(str)) { s.attributeDescriptor.SetInt16(Int16.Parse(str)); } } } break; case (int)TranslatorTags.Choice: break; case (int)Command.ReadResponse << 8 | (int)SingleReadResponse.DataAccessError: err = ValueOfErrorCode(s.OutputType, GetValue(node, s)); ++s.count; s.data.SetUInt8(1); s.data.SetUInt8(err); break; case (int)TranslatorTags.NotificationBody: break; case (int)TranslatorTags.DataValue: break; case (int)TranslatorTags.AccessRequestBody: break; case (int)TranslatorTags.PduDlms: break; case (int)TranslatorTags.ListOfAccessRequestSpecification: s.attributeDescriptor.SetUInt8((byte)node.ChildNodes.Count); break; case (int)TranslatorTags.AccessRequestSpecification: break; case (int)TranslatorTags.AccessRequestListOfData: s.attributeDescriptor.SetUInt8((byte)node.ChildNodes.Count); break; case (int)TranslatorTags.AccessResponseBody: break; case (int)TranslatorTags.ListOfAccessResponseSpecification: s.data.SetUInt8((byte)node.ChildNodes.Count); break; case (int)TranslatorTags.AccessResponseSpecification: break; case (int)TranslatorTags.AccessResponseListOfData: // Add access-response-list-of-data. Optional s.data.SetUInt8(0); s.data.SetUInt8((byte)node.ChildNodes.Count); break; case (int)TranslatorTags.SingleResponse: break; default: throw new ArgumentException("Invalid node: " + node.Name); } } foreach (XmlNode childNode in node.ChildNodes) { if (childNode.NodeType == XmlNodeType.Element) { ReadNode(childNode, s); } } if (preData != null) { GXCommon.SetObjectCount(node.ChildNodes.Count, preData); preData.Set(s.data); s.data.Size = 0; s.data.Set(preData); } }
private static void GetOctetString(XmlNode node, GXDLMSXmlSettings s) { GXByteBuffer bb = new GXByteBuffer(); bb.SetHexString(GetValue(node, s)); GXCommon.SetData(s.settings, s.data, DataType.OctetString, bb.Array()); }
static GXByteBuffer UpdateDateTime(XmlNode node, GXDLMSXmlSettings s, GXByteBuffer preData) { byte[] tmp; if (s.requestType != 0xFF) { preData = UpdateDataType(node, s, (int)DataType.DateTime + GXDLMS.DATA_TYPE_OFFSET); } else { tmp = GXCommon.HexToBytes(GetValue(node, s)); if (tmp.Length != 0) { DataType dt = DataType.DateTime; if (tmp.Length == 5) { dt = DataType.Date; } else if (tmp.Length == 4) { dt = DataType.Time; } s.time = (GXDateTime)GXDLMSClient.ChangeType(tmp, dt); } } return preData; }
private static string GetValue(XmlNode node, GXDLMSXmlSettings s) { if (s.OutputType == TranslatorOutputType.StandardXml) { if (node.FirstChild == null) { return null; } return node.FirstChild.Value; } else { if (node.Attributes.Count == 0) { return ""; } return node.Attributes[0].InnerText; } }
private static bool GetFrame(XmlNode node, GXDLMSXmlSettings s, int tag) { bool found = true; switch (tag) { case (int)TranslatorTags.Wrapper: s.settings.InterfaceType = InterfaceType.WRAPPER; break; case (int)TranslatorTags.Hdlc: s.settings.InterfaceType = InterfaceType.HDLC; break; case (int)TranslatorTags.TargetAddress: s.settings.ServerAddress = int.Parse(GetValue(node, s), System.Globalization.NumberStyles.AllowHexSpecifier); break; case (int)TranslatorTags.SourceAddress: s.settings.ClientAddress = int.Parse(GetValue(node, s), System.Globalization.NumberStyles.AllowHexSpecifier); break; default: //It's OK if frame is not found. found = false; break; } return found; }
private List <GXDLMSXmlPdu> Load(XmlDocument doc) { //Remove comments. List <XmlNode> comments = new List <XmlNode>(); foreach (XmlNode node in doc.SelectNodes("//comment()")) { comments.Add(node); } foreach (XmlNode node in comments) { node.ParentNode.RemoveChild(node); } List <GXDLMSXmlPdu> actions = new List <GXDLMSXmlPdu>(); string description = null, error = null, errorUrl = null, sleep = null; foreach (XmlNode m1 in doc.ChildNodes) { if (m1.NodeType == XmlNodeType.Element) { foreach (XmlNode node in m1.ChildNodes) { if (node.NodeType == XmlNodeType.Element) { if (node.Name == "Description") { description = node.Value; continue; } if (node.Name == "Error") { error = node.Value; continue; } if (node.Name == "ErrorUrl") { errorUrl = node.Value; continue; } if (node.Name == "Sleep") { sleep = node.Value; continue; } GXDLMSXmlSettings s = new GXDLMSXmlSettings(translator.OutputType, translator.Hex, translator.ShowStringAsHex, translator.tagsByName);; s.settings.ClientAddress = Settings.ClientAddress; s.settings.ServerAddress = Settings.ServerAddress; byte[] reply = translator.XmlToPdu(node.OuterXml, s); if (s.command == Command.Snrm && !s.settings.IsServer) { Settings.Limits.MaxInfoTX = s.settings.Limits.MaxInfoTX; Settings.Limits.MaxInfoRX = s.settings.Limits.MaxInfoRX; Settings.Limits.WindowSizeRX = s.settings.Limits.WindowSizeRX; Settings.Limits.WindowSizeTX = s.settings.Limits.WindowSizeTX; } else if (s.command == Command.Ua && s.settings.IsServer) { Settings.Limits.MaxInfoTX = s.settings.Limits.MaxInfoTX; Settings.Limits.MaxInfoRX = s.settings.Limits.MaxInfoRX; Settings.Limits.WindowSizeRX = s.settings.Limits.WindowSizeRX; Settings.Limits.WindowSizeTX = s.settings.Limits.WindowSizeTX; } if (s.template) { reply = null; } GXDLMSXmlPdu p = new GXDLMSXmlPdu(s.command, node, reply); if (description != "") { p.Description = description; } if (error != "") { p.Error = error; } if (errorUrl != "") { p.ErrorUrl = errorUrl; } if (!string.IsNullOrEmpty(sleep)) { p.Sleep = int.Parse(sleep); } actions.Add(p); } } } } return(actions); }
private void GetAllDataNodes(XmlNodeList nodes, GXDLMSXmlSettings s) { GXByteBuffer preData; foreach (XmlNode it in nodes) { int tag; if (s.OutputType == TranslatorOutputType.SimpleXml) { tag = s.tags[it.Name.ToLower()]; } else { tag = s.tags[it.Name]; } if (tag == (int)TranslatorTags.RawData) { s.data.SetHexString(it.InnerText); } else { preData = UpdateDataType(it, s, tag); if (preData != null) { GXCommon.SetObjectCount(it.ChildNodes.Count, preData); preData.Set(s.data); s.data.Size = 0; s.data.Set(preData); GetAllDataNodes(it.ChildNodes, s); } } } }
private List <GXDLMSXmlPdu> Load(XmlDocument doc, GXXmlLoadSettings settings) { //Remove comments. List <XmlNode> comments = new List <XmlNode>(); foreach (XmlNode node in doc.SelectNodes("//comment()")) { comments.Add(node); } foreach (XmlNode node in comments) { node.ParentNode.RemoveChild(node); } List <GXDLMSXmlPdu> actions = new List <GXDLMSXmlPdu>(); string description = null, error = null, errorUrl = null, sleep = null; foreach (XmlNode m1 in doc.ChildNodes) { if (m1.NodeType == XmlNodeType.Element) { if (m1.Name == "AssociationRequest") { GXDLMSXmlSettings s = new GXDLMSXmlSettings(translator.OutputType, translator.Hex, translator.ShowStringAsHex, translator.tagsByName); s.settings.ClientAddress = Settings.ClientAddress; s.settings.ServerAddress = Settings.ServerAddress; ((GXCiphering)s.settings.Cipher).TestMode = this.Ciphering.TestMode; byte[] reply = translator.XmlToPdu(m1.OuterXml, s); GXDLMSXmlPdu p = new GXDLMSXmlPdu(s.command, m1, reply); actions.Add(p); return(actions); } foreach (XmlNode node in m1.ChildNodes) { if (node.NodeType == XmlNodeType.Element) { if (node.Name == "Description") { description = node.Value; continue; } if (node.Name == "Error") { error = node.Value; continue; } if (node.Name == "ErrorUrl") { errorUrl = node.Value; continue; } if (node.Name == "Sleep") { sleep = node.Value; continue; } if (settings != null && node.Name == "GetRequest") { if (settings.Start != DateTime.MinValue && settings.End != DateTime.MinValue) { foreach (XmlNode n1 in node.ChildNodes) { if (n1.Name == "GetRequestNormal") { foreach (XmlNode n2 in n1.ChildNodes) { if (n2.Name == "AccessSelection") { foreach (XmlNode n3 in n2.ChildNodes) { if (n3.Name == "AccessSelector") { if (n3.Attributes["Value"].Value != "1") { break; } } else if (n3.Name == "AccessParameters") { foreach (XmlNode n4 in n3.ChildNodes) { if (n4.Name == "Structure") { bool start = true; foreach (XmlNode n5 in n4.ChildNodes) { if (n5.Name == "OctetString") { if (start) { GXByteBuffer bb = new GXByteBuffer(); GXCommon.SetData(this.Settings, bb, DataType.OctetString, settings.Start); n5.Attributes["Value"].Value = bb.ToHex(false, 2); start = false; } else { GXByteBuffer bb = new GXByteBuffer(); GXCommon.SetData(this.Settings, bb, DataType.OctetString, settings.End); n5.Attributes["Value"].Value = bb.ToHex(false, 2); break; } } } } break; } break; } } break; } } break; } } } } GXDLMSXmlSettings s = new GXDLMSXmlSettings(translator.OutputType, translator.ShowStringAsHex, translator.Hex, translator.tagsByName);; s.settings.ClientAddress = Settings.ClientAddress; s.settings.ServerAddress = Settings.ServerAddress; byte[] reply = translator.XmlToPdu(node.OuterXml, s); if (s.command == Command.Snrm && !s.settings.IsServer) { Settings.Limits.MaxInfoTX = s.settings.Limits.MaxInfoTX; Settings.Limits.MaxInfoRX = s.settings.Limits.MaxInfoRX; Settings.Limits.WindowSizeRX = s.settings.Limits.WindowSizeRX; Settings.Limits.WindowSizeTX = s.settings.Limits.WindowSizeTX; } else if (s.command == Command.Ua && s.settings.IsServer) { Settings.Limits.MaxInfoTX = s.settings.Limits.MaxInfoTX; Settings.Limits.MaxInfoRX = s.settings.Limits.MaxInfoRX; Settings.Limits.WindowSizeRX = s.settings.Limits.WindowSizeRX; Settings.Limits.WindowSizeTX = s.settings.Limits.WindowSizeTX; } if (s.template) { reply = null; } GXDLMSXmlPdu p = new GXDLMSXmlPdu(s.command, node, reply); if (description != "") { p.Description = description; } if (error != "") { p.Error = error; } if (errorUrl != "") { p.ErrorUrl = errorUrl; } if (!string.IsNullOrEmpty(sleep)) { p.Sleep = int.Parse(sleep); } actions.Add(p); } } } } return(actions); }
private List <GXDLMSXmlPdu> Load(XmlDocument doc) { List <GXDLMSXmlPdu> actions = new List <GXDLMSXmlPdu>(); string description = null, error = null; foreach (XmlNode m1 in doc.ChildNodes) { if (m1.NodeType == XmlNodeType.Element) { foreach (XmlNode node in m1.ChildNodes) { if (node.NodeType == XmlNodeType.Element) { if (node.Name == "Description") { description = node.Value; continue; } if (node.Name == "Error") { error = node.Value; continue; } GXDLMSXmlSettings s = new GXDLMSXmlSettings(translator.OutputType, translator.Hex, translator.ShowStringAsHex, translator.tagsByName);; s.settings.ClientAddress = Settings.ClientAddress; s.settings.ServerAddress = Settings.ServerAddress; byte[] reply = translator.XmlToPdu(node.OuterXml, s); if (s.command == Command.Snrm && !s.settings.IsServer) { Settings.Limits.MaxInfoTX = s.settings.Limits.MaxInfoTX; Settings.Limits.MaxInfoRX = s.settings.Limits.MaxInfoRX; Settings.Limits.WindowSizeRX = s.settings.Limits.WindowSizeRX; Settings.Limits.WindowSizeTX = s.settings.Limits.WindowSizeTX; } else if (s.command == Command.Ua && s.settings.IsServer) { Settings.Limits.MaxInfoTX = s.settings.Limits.MaxInfoTX; Settings.Limits.MaxInfoRX = s.settings.Limits.MaxInfoRX; Settings.Limits.WindowSizeRX = s.settings.Limits.WindowSizeRX; Settings.Limits.WindowSizeTX = s.settings.Limits.WindowSizeTX; } if (s.template) { reply = null; } GXDLMSXmlPdu p = new GXDLMSXmlPdu(s.command, node, reply); if (description != "") { p.Description = description; } if (error != "") { p.Error = error; } actions.Add(p); } } } } return(actions); }