public static List <object> GetDataTypes(byte[] value) { if (value == null || value.Length == 0) { return(new List <object>()); } GXDataInfo info = new GXDataInfo(); object ret = GXCommon.GetCompactArray(null, new GXByteBuffer(value), info, true); return((List <object>)ret); }
public static object[] GetDataTypes(byte[] value) { if (value == null || value.Length == 0) { return(new object[0]); } List <object> list = new List <object>(); GXDataInfo info = new GXDataInfo(); return((object[])GXCommon.GetCompactArray(null, new GXByteBuffer(value), info, true)); }
byte[] GetProfileGenericData(int selector, object parameters) { //If all data is read. if (selector == 0 || parameters == null) { return(GetData(Buffer)); } object[] arr = (object[])parameters; List <object[]> table = new List <object[]>(); lock (Buffer) { if (selector == 1) //Read by range { GXDataInfo info = new GXDataInfo(); info.Type = DataType.DateTime; DateTime start = ((GXDateTime)GXCommon.GetData(new GXByteBuffer((byte[])arr[1]), info)).Value.LocalDateTime; info.Clear(); info.Type = DataType.DateTime; DateTime end = ((GXDateTime)GXCommon.GetData(new GXByteBuffer((byte[])arr[2]), info)).Value.LocalDateTime; foreach (object[] row in Buffer) { DateTime tm = Convert.ToDateTime(row[0]); if (tm >= start && tm <= end) { table.Add(row); } } } else if (selector == 2)//Read by entry. { int start = Convert.ToInt32(arr[0]); int count = Convert.ToInt32(arr[1]); for (int pos = 0; pos < count; ++pos) { if (pos + start == Buffer.Count) { break; } table.Add(Buffer[start + pos]); } } else { throw new Exception("Invalid selector."); } } return(GetData(table)); }
private static void UpdateTemplateDescription(GXByteBuffer columns, GXByteBuffer data, int index) { DataType ch = (DataType)data.GetUInt8(); int count = GXCommon.GetObjectCount(data); if (index == -1) { columns.SetUInt8(ch); if (ch == DataType.Array) { columns.SetUInt16((UInt16)count); } else { columns.SetUInt8((byte)count); } } GXDataInfo info = new GXDataInfo(); for (int pos = 0; pos < count; ++pos) { //If all data is captured. if (index == -1 || pos == index) { DataType dt = (DataType)data.GetUInt8(data.Position); if (dt == DataType.Array || dt == DataType.Structure) { UpdateTemplateDescription(columns, data, -1); if (ch == DataType.Array) { break; } } else { info.Clear(); columns.SetUInt8((byte)dt); //Get data. GXCommon.GetData(null, data, info); } if (index == pos) { break; } } } }
/// <summary> /// Convert compact data buffer to array of values. /// </summary> /// <param name="templateDescription">Template description byte array.</param> /// <param name="buffer">Buffer byte array.</param> /// <returns>Values from byte buffer.</returns> public List <object> GetValues(byte[] templateDescription, byte[] buffer) { //If templateDescription or buffer is not given. if (templateDescription == null || buffer == null || templateDescription.Length == 0 || buffer.Length == 0) { throw new ArgumentException(); } GXDataInfo info = new GXDataInfo(); object tmp; GXByteBuffer data = new GXByteBuffer(); data.Set(templateDescription); GXCommon.SetObjectCount(buffer.Length, data); data.Set(buffer); info.Type = DataType.CompactArray; tmp = GXCommon.GetData(null, data, info); return((List <object>)tmp); }
private static void CaptureValue(GXDLMSServer server, GXByteBuffer tmp, GXByteBuffer bb) { GXByteBuffer tmp2 = new GXByteBuffer(); GXDataInfo info = new GXDataInfo(); object value = GXCommon.GetData(server.Settings, tmp, info); GXCommon.SetData(server.Settings, tmp2, info.Type, value); //If data is empty. if (tmp2.Size == 1) { bb.SetUInt8(0); } else { tmp2.Position = 1; bb.Set(tmp2); } }
public static List <object> GetData(byte[] columns, byte[] value, bool AppendAA) { if (columns == null || columns.Length == 0 || value == null || value.Length == 0) { return(new GXArray()); } List <DataType> list = new List <DataType>(); GXDataInfo info = new GXDataInfo(); info.AppendAA = AppendAA; GXByteBuffer bb = new GXByteBuffer(); bb.Set(columns); GXCommon.SetObjectCount(value.Length, bb); bb.Set(value); List <object> tmp = (List <object>)GXCommon.GetCompactArray(null, bb, info, false); return(tmp); }
public static object[][] GetData(byte[] columns, byte[] value, bool AppendAA) { List <object[]> row = new List <object[]>(); if (columns == null || columns.Length == 0 || value == null || value.Length == 0) { return(row.ToArray()); } List <DataType> list = new List <DataType>(); GXDataInfo info = new GXDataInfo(); info.AppendAA = AppendAA; GXByteBuffer bb = new GXByteBuffer(); bb.Set(columns); GXCommon.SetObjectCount(value.Length, bb); bb.Set(value); object[] tmp = (object[])GXCommon.GetCompactArray(null, bb, info, false); row.Add((object[])tmp[0]); return(row.ToArray()); }
///<summary> ///Get date and time from DLMS data. ///</summary> ///<param name="settings">DLMS settings.</param> ///<param name="buff">Received DLMS data.</param> ///<param name="info">Data info.</param> ///<returns> ///Parsed date and time. ///</returns> private static object GetDateTime(GXDLMSSettings settings, GXByteBuffer buff, GXDataInfo info) { // If there is not enough data available. if (buff.Size - buff.Position < 12) { //If time. if (buff.Size - buff.Position < 5) { return GetTime(buff, info); } //If date. else if (buff.Size - buff.Position < 6) { return GetDate(buff, info); } info.Complete = false; return null; } if (info.xml != null) { info.xml.AppendLine(info.xml.GetDataType(info.Type), "Value", GXCommon.ToHex(buff.Data, false, buff.Position, 12)); } GXDateTime dt = new GXDateTime(); //Get year. int year = buff.GetUInt16(); if (year == 0xFFFF || year == 0) { year = DateTime.Now.Year; dt.Skip |= DateTimeSkips.Year; } //Get month int month = buff.GetUInt8(); if (month == 0 || month == 0xFF || month == 0xFE || month == 0xFD) { month = 1; dt.Skip |= DateTimeSkips.Month; } int day = buff.GetUInt8(); if (day < 1 || day == 0xFF) { day = 1; dt.Skip |= DateTimeSkips.Day; } else if (day == 0xFD || day == 0xFE) { day = DateTime.DaysInMonth(year, month) + (sbyte)day + 2; } //Skip week day if (buff.GetUInt8() == 0xFF) { dt.Skip |= DateTimeSkips.DayOfWeek; } //Get time. int hours = buff.GetUInt8(); if (hours == 0xFF) { hours = 0; dt.Skip |= DateTimeSkips.Hour; } int minutes = buff.GetUInt8(); if (minutes == 0xFF) { minutes = 0; dt.Skip |= DateTimeSkips.Minute; } int seconds = buff.GetUInt8(); if (seconds == 0xFF) { seconds = 0; dt.Skip |= DateTimeSkips.Second; } int milliseconds = buff.GetUInt8(); if (milliseconds != 0xFF) { milliseconds *= 10; } else { milliseconds = 0; dt.Skip |= DateTimeSkips.Ms; } int deviation = buff.GetInt16(); dt.Status = (ClockStatus)buff.GetUInt8(); if (settings != null && settings.UtcTimeZone) { deviation = -deviation; } dt.Deviation = deviation; //0x8000 == -32768 //deviation = -1 if skipped. if (deviation != -1 && deviation != -32768 && year != 1 && (dt.Skip & DateTimeSkips.Year) == 0) { dt.Value = new DateTimeOffset(new DateTime(year, month, day, hours, minutes, seconds, milliseconds), new TimeSpan(0, -deviation, 0)); } else //Use current time if deviation is not defined. { dt.Skip |= DateTimeSkips.Devitation; DateTime tmp = new DateTime(year, month, day, hours, minutes, seconds, milliseconds, DateTimeKind.Local); dt.Value = new DateTimeOffset(tmp, TimeZoneInfo.Local.GetUtcOffset(tmp)); } return dt; }
///<summary> ///Get string value from DLMS data. ///</summary> ///<param name="buff"> ///Received DLMS data. ///</param> ///<param name="info"> ///Data info. ///</param> ///<returns> ///Parsed string value. ///</returns> private static object GetString(GXByteBuffer buff, GXDataInfo info, bool knownType) { string value; int len; if (knownType) { len = buff.Size; } else { len = GXCommon.GetObjectCount(buff); // If there is not enough data available. if (buff.Size - buff.Position < len) { info.Complete = false; return null; } } if (len > 0) { value = buff.GetString(len); } else { value = ""; } if (info.xml != null) { if (info.xml.ShowStringAsHex) { info.xml.AppendLine(info.xml.GetDataType(info.Type), "Value", GXCommon.ToHex(buff.Data, false, buff.Position - len, len)); } else { info.xml.AppendLine(info.xml.GetDataType(info.Type), "Value", value.Replace('\"', '\'')); } } return value; }
///<summary> ///Get Int32 value from DLMS data. ///</summary> ///<param name="buff"> ///Received DLMS data. ///</param> ///<param name="info"> ///Data info. ///</param> ///<returns> ///Parsed Int32 value. ///</returns> private static object GetInt32(GXByteBuffer buff, GXDataInfo info) { // If there is not enough data available. if (buff.Size - buff.Position < 4) { info.Complete = false; return null; } Int32 value = buff.GetInt32(); if (info.xml != null) { info.xml.AppendLine(info.xml.GetDataType(info.Type), "Value", value); } return value; }
byte[] GetProfileGenericData(GXDLMSSettings settings, ValueEventArgs e) { List <GXKeyValuePair <GXDLMSObject, GXDLMSCaptureObject> > columns = null; //If all data is read. if (e.Selector == 0 || e.Parameters == null || e.RowEndIndex != 0) { return(GetData(settings, e, Buffer, columns)); } object[] arr = (object[])e.Parameters; List <object[]> table = new List <object[]>(); lock (Buffer) { if (e.Selector == 1) //Read by range { GXDataInfo info = new GXDataInfo(); info.Type = DataType.DateTime; DateTime start = ((GXDateTime)GXCommon.GetData(settings, new GXByteBuffer((byte[])arr[1]), info)).Value.LocalDateTime; info.Clear(); info.Type = DataType.DateTime; DateTime end = ((GXDateTime)GXCommon.GetData(settings, new GXByteBuffer((byte[])arr[2]), info)).Value.LocalDateTime; if (arr.Length > 3) { columns = GetColumns((Object[])((Object[])arr)[3]); } foreach (object[] row in Buffer) { DateTime tm = Convert.ToDateTime(row[0]); if (tm >= start && tm <= end) { table.Add(row); } } } else if (e.Selector == 2)//Read by entry. { int start = Convert.ToInt32(arr[0]); if (start == 0) { start = 1; } int count = Convert.ToInt32(arr[1]); if (count == 0) { count = Buffer.Count; } if (start + count > Buffer.Count + 1) { count = Buffer.Count; } int colStart = 1; int colCount = 0; if (arr.Length > 2) { colStart = Convert.ToUInt16(arr[2]); } if (arr.Length > 3) { colCount = Convert.ToUInt16(arr[3]); } else if (colStart != 1) { colCount = CaptureObjects.Count; } if (colStart != 1 || colCount != 0) { columns = new List <GXKeyValuePair <GXDLMSObject, GXDLMSCaptureObject> >(); for (int pos = 0; pos != colCount; ++pos) { columns.Add(CaptureObjects[colStart + pos - 1]); } } //Get rows. // Starting index is 1. for (int pos = 0; pos < count; ++pos) { if (pos + start - 1 == Buffer.Count) { break; } table.Add(Buffer[start + pos - 1]); } } else { throw new Exception("Invalid selector."); } } return(GetData(settings, e, table, columns)); }
///<summary> ///Get octect string value from DLMS data. ///</summary> ///<param name="buff"> ///Received DLMS data. ///</param> ///<param name="info"> ///Data info. ///</param> ///<returns> ///Parsed octet string value. ///</returns> private static object GetOctetString(GXByteBuffer buff, GXDataInfo info, bool knownType) { object value; int len; if (knownType) { len = buff.Size; } else { len = GXCommon.GetObjectCount(buff); // If there is not enough data available. if (buff.Size - buff.Position < len) { info.Complete = false; return null; } } byte[] tmp = new byte[len]; buff.Get(tmp); value = tmp; if (info.xml != null) { info.xml.AppendLine(info.xml.GetDataType(info.Type), "Value", GXCommon.ToHex(tmp, false)); } return value; }
///<summary> ///Get date from DLMS data. ///</summary> ///<param name="buff"> ///Received DLMS data. ///</param> ///<param name="info"> ///Data info. ///</param> ///<returns> ///Parsed date. ///</returns> private static object GetDate(GXByteBuffer buff, GXDataInfo info) { object value; if (buff.Size - buff.Position < 5) { // If there is not enough data available. info.Complete = false; return null; } if (info.xml != null) { info.xml.AppendLine(info.xml.GetDataType(info.Type), "Value", GXCommon.ToHex(buff.Data, false, buff.Position, 5)); } // Get year. int year = buff.GetUInt16(); // Get month int month = buff.GetUInt8(); // Get day int day = buff.GetUInt8(); GXDate dt = new GXDate(year, month, day); // Skip week day if (buff.GetUInt8() == 0xFF) { dt.Skip |= DateTimeSkips.DayOfWeek; } value = dt; return value; }
/// <summary> /// Import server settings and COSEM objects from GXDLMSDirector trace. /// </summary> /// <param name="server">Server where settings are updated.</param> /// <param name="data">GXDLMSDirector trace in byte array.</param> public static void Import(GXDLMSServer server, byte[] data, Standard standard) { GXDLMSTranslator translator = new GXDLMSTranslator(TranslatorOutputType.StandardXml); translator.CompletePdu = true; translator.PduOnly = true; translator.OmitXmlNameSpace = translator.OmitXmlDeclaration = true; XmlDocument doc = new XmlDocument(); List <ValueEventArgs> targets = new List <ValueEventArgs>(); GXDLMSSettings settings = new GXDLMSSettings(true, InterfaceType.HDLC); GXByteBuffer pdu = new GXByteBuffer(); GXByteBuffer bb = new GXByteBuffer(data); server.InterfaceType = GXDLMSTranslator.GetDlmsFraming(bb); bool lastBlock = true; GXByteBuffer val = new DLMS.GXByteBuffer(); GXDLMSConverter converter = new GXDLMSConverter(standard); while (translator.FindNextFrame(bb, pdu, server.InterfaceType)) { String xml = translator.MessageToXml(bb); if (xml != "") { doc.LoadXml(xml.Replace("&", "&")); foreach (XmlNode node in doc.ChildNodes[doc.ChildNodes.Count - 1].ChildNodes) { string name = doc.ChildNodes[doc.ChildNodes.Count - 1].Name; if (name == "Ua" || name == "aarq" || name == "aare") { break; } else if (name == "get-request") { server.UseLogicalNameReferencing = true; GetLN(settings.Objects, targets, node.ChildNodes); } else if (name == "readRequest") { List <short> items = GetSN(node.ChildNodes); server.UseLogicalNameReferencing = false; foreach (short it in items) { GXSNInfo i = GXDLMSSNCommandHandler.FindSNObject(settings.Objects, Convert.ToUInt16((it) & 0xFFFF)); targets.Add(new ValueEventArgs(i.Item, i.Index, 0, null)); } } else if (name == "readResponse" || name == "get-response") { if (targets != null) { List <string> items; if (server.UseLogicalNameReferencing) { items = GetLNValues(doc.ChildNodes[doc.ChildNodes.Count - 1].ChildNodes); } else { items = GetSNValues(doc.ChildNodes[doc.ChildNodes.Count - 1].ChildNodes); } int pos = 0; foreach (string it in items) { if ("other-reason".Equals(it) || "read-write-denied".Equals(it) || "scope-of-access-violated".Equals(it) || "object-unavailable".Equals(it) || "object-class-inconsistent".Equals(it)) { ValueEventArgs ve = targets[pos]; ve.Target.SetAccess(ve.Index, AccessMode.NoAccess); continue; } try { if (server.UseLogicalNameReferencing) { lastBlock = IsLastBlock(doc.ChildNodes[doc.ChildNodes.Count - 1].ChildNodes); } val.Set(translator.XmlToData(it)); if (lastBlock) { if (settings.Objects.Count == 0) { GXDLMSClient c = new GXDLMSClient(); c.UseLogicalNameReferencing = server.UseLogicalNameReferencing; settings.Objects = c.ParseObjects(val, true); //Update OBIS code description. converter.UpdateOBISCodeInformation(settings.Objects); } else if (targets.Count != 0) { ValueEventArgs ve = targets[pos]; GXDataInfo info = new GXDataInfo(); ve.Value = GXCommon.GetData(server.Settings, val, info); if (ve.Value is byte[] && ve.Target != null) { DataType tp = ve.Target.GetUIDataType(ve.Index); if (tp != DataType.None) { ve.Value = GXDLMSClient.ChangeType((byte[])ve.Value, tp, false); ve.Target.SetDataType(ve.Index, DataType.OctetString); } } if (ve.Target is IGXDLMSBase) { ((IGXDLMSBase)ve.Target).SetValue(settings, ve); } } val.Clear(); } } catch (Exception) { ValueEventArgs ve = targets[pos]; ve.Target.SetAccess(ve.Index, AccessMode.NoAccess); } ++pos; } if (lastBlock) { targets.Clear(); break; } } } } } } server.Items.Clear(); server.Items.AddRange(settings.Objects); }
///<summary> ///Get time from DLMS data. ///</summary> ///<param name="buff"> ///Received DLMS data. ///</param> ///<param name="info"> ///Data info. ///</param> ///<returns> ///Parsed time. ///</returns> private static object GetTime(GXByteBuffer buff, GXDataInfo info) { object value; if (buff.Size - buff.Position < 4) { // If there is not enough data available. info.Complete = false; return null; } if (info.xml != null) { info.xml.AppendLine(info.xml.GetDataType(info.Type), "Value", GXCommon.ToHex(buff.Data, false, buff.Position, 4)); } // Get time. int hour = buff.GetUInt8(); int minute = buff.GetUInt8(); int second = buff.GetUInt8(); int ms = buff.GetUInt8(); if (ms != 0xFF) { ms *= 10; } GXTime dt = new GXTime(hour, minute, second, ms); value = dt; return value; }
///<summary> ///Get array from DLMS data. ///</summary> ///<param name="buff"> ///Received DLMS data. ///</param> ///<param name="info"> ///Data info. ///</param> ///<param name="index"> ///starting index. ///</param> ///<returns>Object array. ///</returns> private static object GetArray(GXByteBuffer buff, GXDataInfo info, int index) { object value; if (info.Count == 0) { info.Count = GXCommon.GetObjectCount(buff); } if (info.xml != null) { info.xml.AppendStartTag(GXDLMS.DATA_TYPE_OFFSET | (int)info.Type, "Qty", info.xml.IntegerToHex(info.Count, 2)); } int size = buff.Size - buff.Position; if (info.Count != 0 && size < 1) { info.Complete = false; return null; } int startIndex = index; List<object> arr = new List<object>(info.Count - info.Index); // Position where last row was found. Cache uses this info. int pos = info.Index; for (; pos != info.Count; ++pos) { GXDataInfo info2 = new GXDataInfo(); info2.xml = info.xml; object tmp = GetData(null, buff, info2); if (!info2.Complete) { buff.Position = (UInt16)startIndex; info.Complete = false; break; } else { if (info2.Count == info2.Index) { startIndex = buff.Position; arr.Add(tmp); } } } if (info.xml != null) { info.xml.AppendEndTag(GXDLMS.DATA_TYPE_OFFSET + (int)info.Type); } info.Index = pos; value = arr.ToArray(); return value; }
///<summary> ///Get data from DLMS frame. ///</summary> ///<param name="settings">DLMS settings.</param> ///<param name="data">Received data.</param> ///<param name="info"> Data info.</param> ///<returns>Parsed object.</returns> /// public static object GetData(GXDLMSSettings settings, GXByteBuffer data, GXDataInfo info) { object value = null; int startIndex = data.Position; if (data.Position == data.Size) { info.Complete = false; return null; } info.Complete = true; bool knownType = info.Type != DataType.None; // Get data type if it is unknown. if (!knownType) { info.Type = (DataType)data.GetUInt8(); } if (info.Type == DataType.None) { if (info.xml != null) { info.xml.AppendLine("<" + info.xml.GetDataType(info.Type) + " />"); } return value; } if (data.Position == data.Size) { info.Complete = false; return null; } switch (info.Type) { case DataType.Array: case DataType.Structure: value = GetArray(data, info, startIndex); break; case DataType.Boolean: value = GetBoolean(data, info); break; case DataType.BitString: value = GetBitString(data, info); break; case DataType.Int32: value = GetInt32(data, info); break; case DataType.UInt32: value = GetUInt32(data, info); break; case DataType.String: value = GetString(data, info, knownType); break; case DataType.StringUTF8: value = GetUtfString(data, info, knownType); break; case DataType.OctetString: value = GetOctetString(data, info, knownType); break; case DataType.Bcd: value = GetBcd(data, info, knownType); break; case DataType.Int8: value = GetInt8(data, info); break; case DataType.Int16: value = GetInt16(data, info); break; case DataType.UInt8: value = GetUInt8(data, info); break; case DataType.UInt16: value = GetUInt16(data, info); break; case DataType.CompactArray: throw new Exception("Invalid data type."); case DataType.Int64: value = GetInt64(data, info); break; case DataType.UInt64: value = GetUInt64(data, info); break; case DataType.Enum: value = GetEnum(data, info); break; case DataType.Float32: value = Getfloat(data, info); break; case DataType.Float64: value = GetDouble(data, info); break; case DataType.DateTime: value = GetDateTime(settings, data, info); break; case DataType.Date: value = GetDate(data, info); break; case DataType.Time: value = GetTime(data, info); break; default: throw new Exception("Invalid data type."); } return value; }
///<summary> ///Get boolean value from DLMS data. ///</summary> ///<param name="buff"> ///Received DLMS data. ///</param> ///<param name="info"> ///Data info. ///</param> ///<returns> ///Parsed boolean value. ///</returns> private static object GetBoolean(GXByteBuffer buff, GXDataInfo info) { // If there is not enough data available. if (buff.Size - buff.Position < 1) { info.Complete = false; return null; } byte value = buff.GetUInt8(); if (info.xml != null) { info.xml.AppendLine(GXDLMS.DATA_TYPE_OFFSET + (int)info.Type, "Value", value); } return value != 0; }
///<summary> ///Get bit string value from DLMS data. ///</summary> ///<param name="buff"> ///Received DLMS data. ///</param> ///<param name="info"> ///Data info. ///</param> ///<returns> ///Parsed bit string value. ///</returns> private static string GetBitString(GXByteBuffer buff, GXDataInfo info) { int cnt = GetObjectCount(buff); double t = cnt; t /= 8; if (cnt % 8 != 0) { ++t; } int byteCnt = (int)Math.Floor(t); // If there is not enough data available. if (buff.Size - buff.Position < byteCnt) { info.Complete = false; return null; } StringBuilder sb = new StringBuilder(); while (cnt > 0) { ToBitString(sb, buff.GetUInt8(), cnt); cnt -= 8; } if (info.xml != null) { info.xml.AppendLine(info.xml.GetDataType(info.Type), "Value", sb.ToString()); } return sb.ToString(); }
///<summary> ///Get float value from DLMS data. ///</summary> ///<param name="buff"> ///Received DLMS data. ///</param> ///<param name="info"> ///Data info. ///</param> ///<returns> ///Parsed float value. ///</returns> private static object Getfloat(GXByteBuffer buff, GXDataInfo info) { // If there is not enough data available. if (buff.Size - buff.Position < 4) { info.Complete = false; return null; } float value = buff.GetFloat(); if (info.xml != null) { GXByteBuffer tmp = new GXByteBuffer(); SetData(null, tmp, DataType.Float32, value); info.xml.AppendLine(info.xml.GetDataType(info.Type), "Value", GXCommon.ToHex(tmp.Data, false, 1, tmp.Size - 1)); } return value; }
///<summary> ///Get UInt16 value from DLMS data. ///</summary> ///<param name="buff"> ///Received DLMS data. ///</param> ///<param name="info"> ///Data info. ///</param> ///<returns> ///Parsed UInt16 value. ///</returns> private static object GetUInt16(GXByteBuffer buff, GXDataInfo info) { // If there is not enough data available. if (buff.Size - buff.Position < 2) { info.Complete = false; return null; } UInt16 value = buff.GetUInt16(); if (info.xml != null) { info.xml.AppendLine(info.xml.GetDataType(info.Type), "Value", info.xml.IntegerToHex(value, 4)); } return value; }
/// <summary> /// Import server settings and COSEM objects from GXDLMSDirector trace. /// </summary> /// <param name="server">Server where settings are updated.</param> /// <param name="data">GXDLMSDirector trace in byte array.</param> public static void Import(GXDLMSServer server, byte[] data) { GXDLMSTranslator translator = new GXDLMSTranslator(TranslatorOutputType.StandardXml); translator.CompletePdu = true; translator.PduOnly = true; XmlDocument doc = new XmlDocument(); List<ValueEventArgs> targets = new List<ValueEventArgs>(); GXDLMSSettings settings = new GXDLMSSettings(true); GXByteBuffer pdu = new GXByteBuffer(); GXByteBuffer bb = new GXByteBuffer(data); server.InterfaceType = GXDLMSTranslator.GetDlmsFraming(bb); bool lastBlock = true; GXByteBuffer val = new DLMS.GXByteBuffer(); while (translator.FindNextFrame(bb, pdu, server.InterfaceType)) { String xml = translator.MessageToXml(bb); if (xml != "") { doc.LoadXml(xml); foreach (XmlNode node in doc.ChildNodes[doc.ChildNodes.Count - 1].ChildNodes) { if (node.Name == "x:get-request") { server.UseLogicalNameReferencing = true; GetLN(settings.Objects, targets, node.ChildNodes); } else if (node.Name == "x:readRequest") { List<short> items = GetSN(node.ChildNodes); server.UseLogicalNameReferencing = false; foreach (short it in items) { GXSNInfo i = GXDLMSSNCommandHandler.FindSNObject(settings.Objects, Convert.ToUInt16((it) & 0xFFFF)); targets.Add(new ValueEventArgs(i.Item, i.Index, 0, null)); } } else if (node.Name == "x:readResponse" || node.Name == "x:get-response") { if (targets != null) { List<string> items; if (server.UseLogicalNameReferencing) { items = GetLNValues(node.ChildNodes); } else { items = GetSNValues(node.ChildNodes); } int pos = 0; foreach (string it in items) { if ("read-write-denied".Equals(it) || "scope-of-access-violated".Equals(it) || "object-unavailable".Equals(it)) { ValueEventArgs ve = targets[pos]; ve.Target.SetAccess(ve.Index, AccessMode.NoAccess); continue; } try { if (server.UseLogicalNameReferencing) { lastBlock = IsLastBlock(node.ChildNodes); } val.Set(translator.XmlToData(it)); if (lastBlock) { if (settings.Objects.Count == 0) { GXDLMSClient c = new GXDLMSClient(); c.UseLogicalNameReferencing = server.UseLogicalNameReferencing; settings.Objects = c.ParseObjects(val, true); //Update OBIS code description. GXDLMSConverter converter = new GXDLMSConverter(); converter.UpdateOBISCodeInformation(settings.Objects); } else { ValueEventArgs ve = targets[pos]; GXDataInfo info = new GXDataInfo(); ve.Value = GXCommon.GetData(server.Settings, val, info); if (ve.Value is byte[]) { DataType tp = ve.Target.GetUIDataType(ve.Index); if (tp != DataType.None) { ve.Value = GXDLMSClient.ChangeType((byte[])ve.Value, tp); } } ((IGXDLMSBase)ve.Target).SetValue(settings, ve); } val.Clear(); } } catch (Exception) { ValueEventArgs ve = targets[pos]; ve.Target.SetAccess(ve.Index, AccessMode.NoAccess); } ++pos; } if (lastBlock) { targets.Clear(); } } } } } } server.Items.Clear(); server.Items.AddRange(settings.Objects); }
///<summary> ///Get UTF string value from DLMS data. ///</summary> ///<param name="buff"> ///Received DLMS data. ///</param> ///<param name="info"> ///Data info. ///</param> ///<returns> ///Parsed UTF string value. ///</returns> private static object GetUtfString(GXByteBuffer buff, GXDataInfo info, bool knownType) { object value; int len; if (knownType) { len = buff.Size; } else { len = GXCommon.GetObjectCount(buff); // If there is not enough data available. if (buff.Size - buff.Position < len) { info.Complete = false; return null; } } if (len > 0) { value = buff.GetStringUtf8(buff.Position, len); } else { value = ""; } if (info.xml != null) { info.xml.AppendLine(info.xml.GetDataType(info.Type), "Value", value); } return value; }