/// <summary> /// Constructor. /// </summary> /// <param name="sn">Short name settings.</param> /// <param name="type">Interface type.</param> public GXDLMSBase(GXDLMSAssociationShortName sn, InterfaceType type) : base(sn, type, "GRX", 12345678) { MaxReceivePDUSize = 1024; //Default secret. sn.Secret = ASCIIEncoding.ASCII.GetBytes("Gurux"); }
/// <summary> /// Our example server accept all authentications. /// </summary> protected override SourceDiagnostic ValidateAuthentication(Authentication authentication, byte[] password) { //If low authentication fails. if (authentication == Authentication.Low) { byte[] expected; if (UseLogicalNameReferencing) { GXDLMSAssociationLogicalName ln = (GXDLMSAssociationLogicalName)Items.FindByLN(ObjectType.AssociationLogicalName, "0.0.40.0.0.255"); expected = ln.Secret; } else { GXDLMSAssociationShortName sn = (GXDLMSAssociationShortName)Items.FindByLN(ObjectType.AssociationShortName, "0.0.40.0.0.255"); expected = sn.Secret; } if (Gurux.Common.GXCommon.EqualBytes(expected, password)) { return(SourceDiagnostic.None); } return(SourceDiagnostic.AuthenticationFailure); } //Other authentication levels are check later. return(SourceDiagnostic.None); }
protected override void PostWrite(ValueEventArgs[] args) { foreach (ValueEventArgs e in args) { //If association is updated. if (e.Target is GXDLMSAssociationLogicalName && e.Index == 2) { //Update new items to object list. GXDLMSAssociationLogicalName a = (GXDLMSAssociationLogicalName)e.Target; UpdateAssociationView(a.ObjectList); } //If association is updated. else if (e.Target is GXDLMSAssociationShortName && e.Index == 2) { //Update new items to object list. GXDLMSAssociationShortName a = (GXDLMSAssociationShortName)e.Target; UpdateAssociationView(a.ObjectList); } else { SaveSettings(); } System.Diagnostics.Debug.WriteLine("Writing " + e.Target.LogicalName); } }
/// <summary> /// Constructor. /// </summary> /// <param name="sn">Short name settings.</param> /// <param name="hdlc">HDLC settings.</param> public GXDLMSBase(GXDLMSAssociationShortName sn, GXDLMSHdlcSetup hdlc) : base(sn, hdlc, "GRX", 12345678) { MaxReceivePDUSize = 1024; //Default secret. sn.Secret = ASCIIEncoding.ASCII.GetBytes("Gurux"); }
/// <summary> /// Edit object in association view. /// </summary> private void ObjectEditBtn_Click(object sender, EventArgs e) { try { if (ObjectsView.SelectedItems.Count == 1) { GXDLMSAssociationShortName target = Target as GXDLMSAssociationShortName; ListViewItem li = ObjectsView.SelectedItems[0]; GXDLMSObject it = (GXDLMSObject)li.Tag; GXDLMSAssociationViewDlg dlg = new GXDLMSAssociationViewDlg(target, it, false, false); if (dlg.ShowDialog(this) == DialogResult.OK) { it = dlg.GetTarget(); li.SubItems[0].Text = it.ShortName.ToString(); li.SubItems[1].Text = it.ObjectType.ToString(); li.SubItems[2].Text = it.Version.ToString(); li.SubItems[3].Text = it.LogicalName; li.Tag = it; errorProvider1.SetError(ObjectsView, Properties.Resources.ValueChangedTxt); Target.UpdateDirty(2, target.ObjectList); } } } catch (Exception ex) { MessageBox.Show(Parent, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
/// <summary> /// Constructor. /// </summary> /// <param name="sn">Short name settings.</param> /// <param name="type">Interface type.</param> public GXDLMSServer(GXDLMSAssociationShortName sn, InterfaceType type) { Settings = new GXDLMSSettings(true); Settings.UseLogicalNameReferencing = false; Reset(); Settings.Objects.Add(sn); this.InterfaceType = type; }
/// <summary> /// Read association view. /// </summary> public bool GetAssociationView(string outputFile) { if (outputFile != null) { //Save Association view to the cache so it is not needed to retrieve every time. if (File.Exists(outputFile)) { try { Client.Objects.Clear(); Client.Objects.AddRange(GXDLMSObjectCollection.Load(outputFile)); return(false); } catch (Exception) { if (File.Exists(outputFile)) { File.Delete(outputFile); } } } } GXReplyData reply = new GXReplyData(); ReadDataBlock(Client.GetObjectsRequest(), reply); Client.ParseObjects(reply.Data, true); //Access rights must read differently when short Name referencing is used. if (!Client.UseLogicalNameReferencing) { GXDLMSAssociationShortName sn = (GXDLMSAssociationShortName)Client.Objects.FindBySN(0xFA00); if (sn != null && sn.Version > 0) { Read(sn, 3); } } if (outputFile != null) { try { Client.Objects.Save(outputFile, new GXXmlWriterSettings() { Values = false }); } catch (Exception) { //It's OK if this fails. return(false); } } return(true); }
/// <summary> /// Add object to association view. /// </summary> private void ObjectAddBtn_Click(object sender, EventArgs e) { try { GXDLMSAssociationShortName target = Target as GXDLMSAssociationShortName; errorProvider1.SetError(ObjectsView, Properties.Resources.ValueChangedTxt); Target.UpdateDirty(2, target.ObjectList); } catch (Exception ex) { DialogResult = DialogResult.None; MessageBox.Show(Parent, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
///<summary> /// Constructor. ///</summary> ///<param name="sn">Short name settings. </param> ///<param name="type"> /// Interface type. ///</param> ///<param name="flagID"> /// Three letters FLAG ID. ///</param> ///<param name="serialNumber"> /// Meter serial number. Size of serial number is 5 bytes. ///</param> public GXDLMSSecureServer(GXDLMSAssociationShortName sn, InterfaceType type, string flagID, UInt64 serialNumber) : base(sn, type) { if (flagID == null || flagID.Length != 3) { throw new ArgumentOutOfRangeException("Invalid FLAG ID."); } if (flagID == null || flagID.Length != 3) { throw new ArgumentOutOfRangeException("Invalid FLAG ID."); } GXByteBuffer bb = new GXByteBuffer(); bb.Add(flagID); GXByteBuffer serial = new GXByteBuffer(); serial.SetUInt64(serialNumber); bb.Set(serial.Data, 3, 5); Ciphering = new GXCiphering(bb.Array()); Settings.Cipher = Ciphering; }
/// <summary> /// Remove object from association view. /// </summary> private void ObjectRemoveBtn_Click(object sender, EventArgs e) { try { GXDLMSObject item; GXDLMSAssociationShortName target = Target as GXDLMSAssociationShortName; while (ObjectsView.SelectedItems.Count != 0) { ListViewItem li = ObjectsView.SelectedItems[0]; item = (GXDLMSObject)li.Tag; ObjectsView.Items.Remove(ObjectsView.SelectedItems[0]); errorProvider1.SetError(ObjectsView, Properties.Resources.ValueChangedTxt); Target.UpdateDirty(2, target.ObjectList); target.ObjectList.Remove(item); } } catch (Exception ex) { MessageBox.Show(Parent, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
public void OnValueChanged(int index, object value, bool user) { GXDLMSAssociationShortName target = Target as GXDLMSAssociationShortName; if (index == 2) { GXDLMSObjectCollection items = target.ObjectList; CallingWindowLV.Items.Clear(); if (items != null) { SNItems.Clear(); foreach (GXDLMSObject it in items) { int sn = it.ShortName; ListViewItem li = CallingWindowLV.Items.Add(Convert.ToString(sn, 16)); li.SubItems.AddRange(new string[] { it.ObjectType.ToString(), it.Version.ToString(), it.LogicalName, "", "" }); SNItems.Add(sn, li); } } } //Update Access rights. if (index == 3) { //access_rights: access_right object[] access = (object[])target.AccessRightsList; if (access != null) { foreach (object[] it in access) { int sn = (Convert.ToInt32(it[0]) & 0xFFFF); if (SNItems.ContainsKey(sn)) { ListViewItem li = SNItems[sn]; List <string> modes = new List <string>(); foreach (object[] attributeAccess in (object[])it[1]) { uint id = Convert.ToUInt32(attributeAccess[0]); AccessMode mode = (AccessMode)Convert.ToInt32(attributeAccess[1]); modes.Add(id.ToString() + " = " + mode); } string str = null; //Show attribute access. foreach (string m in modes) { if (str != null) { str += ", "; } str += m.ToString(); } li.SubItems[4].Text = str; foreach (object[] attributeAccess in (object[])it[2]) { uint id = Convert.ToUInt32(attributeAccess[0]); AccessMode mode = (AccessMode)Convert.ToInt32(attributeAccess[1]); modes.Add(id.ToString() + " = " + mode); } //Show Method access. str = null; foreach (string m in modes) { if (str != null) { str += ", "; } str += m.ToString(); } li.SubItems[5].Text = str; } } } } }
/// <summary> /// Initialize server. /// </summary> /// <remarks> /// This must call after server objects are set. /// </remarks> public void Initialize() { bool association = false; Initialized = true; for (int pos = 0; pos != Items.Count; ++pos) { GXDLMSObject it = Items[pos]; if (this.UseLogicalNameReferencing && (string.IsNullOrEmpty(it.LogicalName) || it.LogicalName.Split('.').Length != 6)) { throw new Exception("Invalid Logical Name."); } it.Start(this); if (it is GXDLMSProfileGeneric) { GXDLMSProfileGeneric pg = it as GXDLMSProfileGeneric; foreach (var obj in pg.CaptureObjects) { if (obj.Value.AttributeIndex < 1) { throw new Exception("Invalid attribute index. SelectedAttributeIndex is not set for " + obj.Key.Name); } } } else if (it is GXDLMSAssociationShortName && !this.UseLogicalNameReferencing) { if ((it as GXDLMSAssociationShortName).ObjectList.Count == 0) { (it as GXDLMSAssociationShortName).ObjectList.AddRange(this.Items); } association = true; } else if (it is GXDLMSAssociationLogicalName && this.UseLogicalNameReferencing) { if ((it as GXDLMSAssociationLogicalName).ObjectList.Count == 0) { (it as GXDLMSAssociationLogicalName).ObjectList.AddRange(this.Items); } association = true; } else if (it is GXDLMSHdlcSetup) { hdlcSetup = it as GXDLMSHdlcSetup; } else if (!(it is IGXDLMSBase))//Remove unsupported items. { Debug.WriteLine(it.ObjectType.ToString() + " not supported."); Items.RemoveAt(pos); --pos; } } if (!association) { if (UseLogicalNameReferencing) { GXDLMSAssociationLogicalName it = new GXDLMSAssociationLogicalName(); it.ObjectList = this.Items; Items.Add(it); } else { GXDLMSAssociationShortName it = new GXDLMSAssociationShortName(); it.ObjectList = this.Items; Items.Add(it); } } //Arrange items by Short Name. int sn = 0xA0; int offset, count; if (!this.UseLogicalNameReferencing) { foreach (GXDLMSObject it in Items) { //Generate Short Name if not given. if (it.ShortName == 0) { it.ShortName = (ushort)sn; //Add method index addresses. GXDLMS.GetActionInfo(it.ObjectType, out offset, out count); if (count != 0) { sn += offset + (8 * count); } else //If there are no methods. { //Add attribute index addresses. sn += 8 * (it as IGXDLMSBase).GetAttributeCount(); } } } } }
/// <summary> /// Initialize server. /// </summary> /// <remarks> /// This must call after server objects are set. /// <param name="manually">If true, server handle objects and all data are updated manually.</param> public void Initialize(bool manually) { Initialized = true; if (manually) { return; } bool association = false; for (int pos = 0; pos != Items.Count; ++pos) { GXDLMSObject it = Items[pos]; if (this.UseLogicalNameReferencing && (string.IsNullOrEmpty(it.LogicalName) || it.LogicalName.Split('.').Length != 6)) { throw new Exception("Invalid Logical Name."); } it.Start(this); if (it is GXDLMSProfileGeneric) { GXDLMSProfileGeneric pg = it as GXDLMSProfileGeneric; foreach (var obj in pg.CaptureObjects) { if (obj.Value.AttributeIndex < 1) { throw new Exception("Invalid attribute index. SelectedAttributeIndex is not set for " + obj.Key.Name); } } } else if (it is GXDLMSAssociationShortName && !this.UseLogicalNameReferencing) { if ((it as GXDLMSAssociationShortName).ObjectList.Count == 0) { (it as GXDLMSAssociationShortName).ObjectList.AddRange(this.Items); } association = true; } else if (it is GXDLMSAssociationLogicalName && this.UseLogicalNameReferencing) { if ((it as GXDLMSAssociationLogicalName).ObjectList.Count == 0) { (it as GXDLMSAssociationLogicalName).ObjectList.AddRange(this.Items); } association = true; } else if (it is GXDLMSHdlcSetup) { hdlcSetup = it as GXDLMSHdlcSetup; } else if (!(it is IGXDLMSBase))//Remove unsupported items. { Debug.WriteLine(it.ObjectType.ToString() + " not supported."); Items.RemoveAt(pos); --pos; } } if (!association) { if (UseLogicalNameReferencing) { GXDLMSAssociationLogicalName it = new GXDLMSAssociationLogicalName(); it.ObjectList = this.Items; Items.Add(it); } else { GXDLMSAssociationShortName it = new GXDLMSAssociationShortName(); it.ObjectList = this.Items; Items.Add(it); } } //Arrange items by Short Name. UpdateShortNames(false); }
public void OnValueChanged(GXDLMSViewArguments arg) { GXDLMSAssociationShortName target = Target as GXDLMSAssociationShortName; GXDLMSObjectCollection items = target.ObjectList; if (arg.Index == 2) { ObjectsView.Items.Clear(); if (items != null) { SNItems.Clear(); foreach (GXDLMSObject it in items) { ListViewItem li = ObjectsView.Items.Add(Convert.ToString(it.ShortName, 16)); li.SubItems.AddRange(new string[] { it.ObjectType.ToString(), it.Version.ToString(), it.LogicalName }); //access_rights: access_right StringBuilder str = new StringBuilder(); //Show attribute access. int cnt = (it as IGXDLMSBase).GetAttributeCount(); for (int pos = 1; pos != cnt + 1; ++pos) { if (str != null) { str.Append(", "); } if (target.Version < 3) { AccessMode mode = it.GetAccess(pos); str.Append(pos.ToString() + " = " + mode); } else { AccessMode3 mode = it.GetAccess3(pos); str.Append(pos.ToString() + " = " + mode); } } li.SubItems.Add(str.ToString()); //Show method access. str.Length = 0; cnt = (it as IGXDLMSBase).GetMethodCount(); for (int pos = 1; pos != cnt + 1; ++pos) { if (str != null) { str.Append(", "); } if (target.Version < 3) { MethodAccessMode mode = it.GetMethodAccess(pos); str.Append(pos.ToString() + " = " + mode); } else { MethodAccessMode3 mode = it.GetMethodAccess3(pos); str.Append(pos.ToString() + " = " + mode); } } li.SubItems.Add(str.ToString()); if (it.ShortName != 0) { SNItems.Add(it.ShortName, li); } li.Tag = it; } } } //Update Access rights. if (arg.Index == 3) { //access_rights: access_right foreach (GXDLMSObject it in items) { ListViewItem li = SNItems[it.ShortName]; StringBuilder str = new StringBuilder(); //Show attribute access. int cnt = (it as IGXDLMSBase).GetAttributeCount(); for (int pos = 1; pos != cnt + 1; ++pos) { if (str != null) { str.Append(", "); } AccessMode mode = it.GetAccess(pos); str.Append(pos.ToString() + " = " + mode); } li.SubItems[4].Text = str.ToString(); //Show method access. str.Length = 0; cnt = (it as IGXDLMSBase).GetMethodCount(); for (int pos = 1; pos != cnt + 1; ++pos) { if (str != null) { str.Append(", "); } MethodAccessMode mode = it.GetMethodAccess(pos); str.Append(pos.ToString() + " = " + mode); } li.SubItems[5].Text = str.ToString(); } } //security_setup_reference else if (arg.Index == 4) { //security_setup_reference foreach (GXDLMSSecuritySetup it in target.Parent.GetObjects(ObjectType.SecuritySetup)) { SecuritySetupCb.Items.Add(it); if (target.SecuritySetupReference == it.LogicalName) { SecuritySetupCb.SelectedIndexChanged -= new System.EventHandler(this.SecuritySetupCb_SelectedIndexChanged); SecuritySetupCb.SelectedItem = it; SecuritySetupCb.SelectedIndexChanged += new System.EventHandler(this.SecuritySetupCb_SelectedIndexChanged); } } } }
/// <summary> /// Initialize server. /// </summary> /// <remarks> /// This must call after server objects are set. /// </remarks> public void Initialize() { bool association = false; Initialized = true; if (SortedItems.Count != Items.Count) { for (int pos = 0; pos != Items.Count; ++pos) { GXDLMSObject it = Items[pos]; if (this.UseLogicalNameReferencing && (string.IsNullOrEmpty(it.LogicalName) || it.LogicalName.Split('.').Length != 6)) { throw new Exception("Invalid Logical Name."); } if (it is GXDLMSProfileGeneric) { GXDLMSProfileGeneric pg = it as GXDLMSProfileGeneric; if (pg.ProfileEntries < 1) { throw new Exception("Invalid Profile Entries. Profile entries tells amount of rows in the table."); } foreach (var obj in pg.CaptureObjects) { if (obj.Value.AttributeIndex < 1) { throw new Exception("Invalid attribute index. SelectedAttributeIndex is not set for " + obj.Key.Name); } } if (pg.ProfileEntries < 1) { throw new Exception("Invalid Profile Entries. Profile entries tells amount of rows in the table."); } if (pg.CapturePeriod != 0) { GXProfileGenericUpdater p = new GXProfileGenericUpdater(this, pg); Thread thread = new Thread(new ThreadStart(p.UpdateProfileGenericData)); thread.IsBackground = true; thread.Start(); } } else if ((it is GXDLMSAssociationShortName && !this.UseLogicalNameReferencing) || (it is GXDLMSAssociationLogicalName && this.UseLogicalNameReferencing)) { association = true; } else if (!(it is IGXDLMSBase))//Remove unsupported items. { Debug.WriteLine(it.ObjectType.ToString() + " not supported."); Items.RemoveAt(pos); --pos; } } if (!association) { if (UseLogicalNameReferencing) { GXDLMSAssociationLogicalName it = new GXDLMSAssociationLogicalName(); it.ObjectList = this.Items; Items.Add(it); } else { GXDLMSAssociationShortName it = new GXDLMSAssociationShortName(); it.ObjectList = this.Items; Items.Add(it); } } //Arrange items by Short Name. ushort sn = 0xA0; if (!this.UseLogicalNameReferencing) { SortedItems.Clear(); foreach (GXDLMSObject it in Items) { if (it is GXDLMSAssociationShortName) { it.ShortName = 0xFA00; } //Generate Short Name if not given. if (it.ShortName == 0) { do { it.ShortName = sn; sn += 0xA0; }while (SortedItems.ContainsKey(it.ShortName)); } SortedItems.Add(it.ShortName, it); } } } }
/// <summary> /// Read association view. /// </summary> public void GetAssociationView(bool useCache) { if (useCache) { string path = GetCacheName(); List <Type> extraTypes = new List <Type>(Gurux.DLMS.GXDLMSClient.GetObjectTypes()); extraTypes.Add(typeof(GXDLMSAttributeSettings)); extraTypes.Add(typeof(GXDLMSAttribute)); XmlSerializer x = new XmlSerializer(typeof(GXDLMSObjectCollection), extraTypes.ToArray()); //You can save association view, but make sure that it is not change. //Save Association view to the cache so it is not needed to retrieve every time. if (File.Exists(path)) { try { using (Stream stream = File.Open(path, FileMode.Open)) { Console.WriteLine("Get available objects from the cache."); Client.Objects.AddRange(x.Deserialize(stream) as GXDLMSObjectCollection); stream.Close(); } return; } catch (Exception ex) { if (File.Exists(path)) { File.Delete(path); } throw ex; } } } GXReplyData reply = new GXReplyData(); ReadDataBlock(Client.GetObjectsRequest(), reply); Client.ParseObjects(reply.Data, true); //Access rights must read differently when short Name referencing is used. if (!Client.UseLogicalNameReferencing) { GXDLMSAssociationShortName sn = (GXDLMSAssociationShortName)Client.Objects.FindBySN(0xFA00); if (sn.Version > 0) { Read(sn, 3); } else { //LGZ is using "0.0.127.0.0.0" to mark inactive object that might cause problems. //Skip them. int cnt = Client.Objects.Count; for (int pos = 0; pos < cnt; ++pos) { if (Client.Objects[pos].LogicalName == "0.0.127.0.0.0") { Client.Objects.RemoveAt(pos); --pos; --cnt; } } } } }