context: //
  // --------------------------------------------------------------------------
  //  Gurux Ltd
  //
  //
  //
  // Filename:        $HeadURL$
  //
  // Version:         $Revision$,
  //                  $Date$
  //                  $Author$
  //
  // Copyright (c) Gurux Ltd
  //
  //---------------------------------------------------------------------------
  //
  //  DESCRIPTION
  //
  // This file is a part of Gurux Device Framework.
  //
  // Gurux Device Framework is Open Source software; you can redistribute it
  // and/or modify it under the terms of the GNU General Public License
  // as published by the Free Software Foundation; version 2 of the License.
  // Gurux Device Framework is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  // See the GNU General Public License for more details.
  //
  // More information of Gurux products: https://www.gurux.org
  //
  // This code is licensed under the GNU General Public License v2.
  // Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
  //---------------------------------------------------------------------------
  
  using System;
  using System.Collections.Generic;
  using System.Xml.Serialization;
  using Gurux.DLMS.Enums;
  using Gurux.DLMS.Internal;
  using Gurux.DLMS.Objects.Enums;
  
  namespace Gurux.DLMS.Objects
  {
      /// <summary>
      /// Online help:
      /// https://www.gurux.fi/Gurux.DLMS.Objects.GXDLMSCommunicationPortProtection
      /// </summary>
      public class GXDLMSCommunicationPortProtection : GXDLMSObject, IGXDLMSBase
      {
          /// <summary>
          /// Constructor.
          /// </summary>
          public GXDLMSCommunicationPortProtection()
          : this("0.0.44.2.0.255", 0)
          {
          }
  
          /// <summary>
          /// Constructor.
          /// </summary>
          /// <param name="ln">Logical Name of the object.</param>
          public GXDLMSCommunicationPortProtection(string ln)
          : this(ln, 0)
          {
          }
  
          /// <summary>
          /// Constructor.
          /// </summary>
          /// <param name="ln">Logical Name of the object.</param>
          /// <param name="sn">Short Name of the object.</param>
          public GXDLMSCommunicationPortProtection(string ln, ushort sn)
          : base(ObjectType.CommunicationPortProtection, ln, sn)
          {
              ProtectionMode = ProtectionMode.LockedOnFailedAttempts;
              SteepnessFactor = 1;
              ProtectionStatus = ProtectionStatus.Unlocked;
          }
  
          /// <summary>
          /// Controls the protection mode. 
          /// </summary>
          [XmlIgnore()]
          public ProtectionMode ProtectionMode
          {
              get;
              set;
          }
  
          /// <summary>
          /// Number of allowed failed communication attempts before port is disabled.
          /// </summary>
          [XmlIgnore()]
          public UInt16 AllowedFailedAttempts
          {
              get;
              set;
          }
  
          /// <summary>
          /// The lockout time. 
          /// </summary>
          [XmlIgnore()]
          public UInt32 InitialLockoutTime
          {
              get;
              set;
          }
  
          /// <summary>
          /// Holds a factor that controls how the lockout time is increased with 
          /// each failed attempt.
          /// </summary>
          [XmlIgnore()]
          public byte SteepnessFactor
          {
              get;
              set;
          }
  
          /// <summary>
          /// The lockout time. 
          /// </summary>
          [XmlIgnore()]
          public UInt32 MaxLockoutTime
          {
              get;
              set;
          }
  
          /// <summary>
          /// The communication port being protected
          /// </summary>
          [XmlIgnore()]
          public GXDLMSObject Port
          {
              get;
              set;
          }
  
          /// <summary>
          /// Current protection status.
          /// </summary>
          [XmlIgnore()]
          public ProtectionStatus ProtectionStatus
          {
              get;
              set;
          }
  
          /// <summary>
          /// Failed attempts. 
          /// </summary>
          [XmlIgnore()]
          public UInt32 FailedAttempts
          {
              get;
              set;
          }
  
          /// <summary>
          /// Total failed attempts. 
          /// </summary>
          [XmlIgnore()]
          public UInt32 CumulativeFailedAttempts
          {
              get;
              set;
          }
  
          /// <summary>
          /// Resets FailedAttempts and current lockout time to zero.
          /// Protection status is set to unlocked.
          /// </summary>
          /// <param name="client">DLMS client.</param>
          /// <returns>Action bytes.</returns>
          public byte[][] Reset(GXDLMSClient client)
          {
              return client.Method(this, 1, (sbyte)0);
          }
  
          /// <inheritdoc cref="GXDLMSObject.GetValues"/>
          public override object[] GetValues()
          {
              return new object[] { LogicalName, ProtectionMode, AllowedFailedAttempts, InitialLockoutTime , SteepnessFactor,
              MaxLockoutTime, Port, ProtectionStatus, FailedAttempts, CumulativeFailedAttempts};
          }
  
          #region IGXDLMSBase Members
  
          byte[] IGXDLMSBase.Invoke(GXDLMSSettings settings, ValueEventArgs e)
          {
              if (e.Index == 1)
              {
                  FailedAttempts = 0;
                  //TODO: Reset current lockout time.
                  if (ProtectionMode == ProtectionMode.LockedOnFailedAttempts)
                  {
                      ProtectionStatus = ProtectionStatus.Unlocked;
                  }
              }
              else
              {
                  e.Error = ErrorCode.ReadWriteDenied;
              }
              return null;
          }
  
          int[] IGXDLMSBase.GetAttributeIndexToRead(bool all)
          {
              List<int> attributes = new List<int>();
              //LN is static and read only once.
              if (all || string.IsNullOrEmpty(LogicalName))
              {
                  attributes.Add(1);
              }
              //ProtectionMode
              if (all || CanRead(2))
              {
                  attributes.Add(2);
              }
              //AllowedFailedAttempts
              if (all || CanRead(3))
              {
                  attributes.Add(3);
              }
              //InitialLockoutTime
              if (all || CanRead(4))
              {
                  attributes.Add(4);
              }
              //SteepnessFactor
              if (all || CanRead(5))
              {
                  attributes.Add(5);
              }
              //MaxLockoutTime
              if (all || CanRead(6))
              {
                  attributes.Add(6);
              }
              //Port
              if (all || CanRead(7))
              {
                  attributes.Add(7);
              }
              //ProtectionStatus
  
gt:             if (all || CanRead(8))