示例#1
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="ln">Logical name settings.</param>
 /// <param name="hdlc">HDLC settings.</param>
 public GXDLMSBase(GXDLMSAssociationLogicalName ln, GXDLMSHdlcSetup hdlc)
     : base(ln, hdlc)
 {
     MaxReceivePDUSize = 1024;
     //Default secret.
     ln.Secret = ASCIIEncoding.ASCII.GetBytes("Gurux");
 }
示例#2
0
 /// <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");
 }
示例#3
0
        ///<summary>
        /// Constructor.
        ///</summary>
        ///<param name="sn">Short name settings. </param>
        ///<param name="hdlc">
        /// 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, GXDLMSHdlcSetup hdlc, string flagID, UInt64 serialNumber) :
            base(sn, hdlc)
        {
            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;
        }
示例#4
0
 ///<summary>
 /// Constructor.
 ///</summary>
 ///<param name="logicalNameReferencing">
 /// Is logical name referencing used.
 ///</param>
 ///<param name="type">
 /// Interface type.
 ///</param>
 public GXDLMSSecureServer(GXDLMSAssociationLogicalName ln, GXDLMSHdlcSetup hdlc) :
     base(ln, hdlc)
 {
     Ciphering       = new GXCiphering(ASCIIEncoding.ASCII.GetBytes("ABCDEFGH"));
     Settings.Cipher = Ciphering;
 }
示例#5
0
        /// <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();
                        }
                    }
                }
            }
        }
示例#6
0
        /// <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);
        }
示例#7
0
        /// <summary>
        /// Execute basic tests.
        /// </summary>
        /// <param name="settings">Settings.</param>
        /// <param name="output">Generated output.</param>
        public static bool Basic(GXSettings settings, GXOutput output)
        {
            Reader.GXDLMSReader reader = new Reader.GXDLMSReader(settings.client, settings.media, settings.trace, settings.iec);
            reader.WaitTime = settings.WaitTime;
            try
            {
                settings.media.Open();
            }
            catch (System.Net.Sockets.SocketException e)
            {
                //If failed to make connection to the meter.
                output.Errors.Add("Failed to connect to the meter: " + e.Message);
                output.MakeReport();
                return(false);
            }
            if (settings.trace > TraceLevel.Error)
            {
                Console.WriteLine("------------------------------------------------------------");
                Console.WriteLine("Initialize connection.");
            }
            reader.InitializeConnection();
            if (settings.trace > TraceLevel.Error)
            {
                Console.WriteLine("Get association view.");
            }
            reader.GetAssociationView(false);
            if (settings.client.UseLogicalNameReferencing)
            {
                output.PreInfo.Add("Testing using Logical Name referencing.");
            }
            else
            {
                output.PreInfo.Add("Testing using Short Name referencing.");
            }
            output.PreInfo.Add("Authentication level: " + settings.client.Authentication);
            output.PreInfo.Add("Total amount of objects: " + settings.client.Objects.Count.ToString());
            if (settings.client.UseLogicalNameReferencing)
            {
                if (settings.trace > TraceLevel.Error)
                {
                    Console.WriteLine("Finding Logical Device Name and SAP.");
                }
                GXDLMSObject           ldn  = settings.client.Objects.FindByLN(ObjectType.None, "0.0.42.0.0.255");
                GXDLMSObjectCollection saps = settings.client.Objects.GetObjects(ObjectType.SapAssignment);
                if (ldn == null && saps.Count == 0)
                {
                    output.Errors.Add("Logical Device Name or SAP is not implemented. Read more: GB: 4.1.8.4.");
                }
                if (settings.trace > TraceLevel.Error)
                {
                    if (ldn != null)
                    {
                        reader.Read(ldn, 2);
                        output.PreInfo.Add("Meter Logical Device Name is: " + (ldn as GXDLMSData).Value.ToString() + ".");
                    }
                    if (saps.Count != 0)
                    {
                        output.PreInfo.Add("SAP is not implemented.");
                    }
                }
            }
            //Check OBIS codes.
            foreach (GXDLMSObject it in settings.client.Objects)
            {
                if (it.Description == "Invalid")
                {
                    output.Errors.Add("Invalid OBIS code " + it.LogicalName + " for <a target=\"_blank\" href=http://www.gurux.fi/" + it.GetType().FullName + ">" + it.ObjectType + "</a>.");
                    if (settings.trace > TraceLevel.Warning)
                    {
                        Console.WriteLine("------------------------------------------------------------");
                        Console.WriteLine(it.LogicalName + ": Invalid OBIS code.");
                    }
                }
            }

            //Read structures of Cosem objects.
            List <KeyValuePair <string, List <GXDLMSXmlPdu> > > cosemTests = new List <KeyValuePair <string, List <GXDLMSXmlPdu> > >();
            GXDLMSTranslator translator = new GXDLMSTranslator(TranslatorOutputType.SimpleXml);

            foreach (string it in GetTests())
            {
                using (Stream stream = typeof(Program).Assembly.GetManifestResourceStream(it))
                    using (StreamReader sr = new StreamReader(stream))
                    {
                        XmlDocument doc = new XmlDocument();
                        doc.LoadXml(sr.ReadToEnd());
                        XmlNodeList list = doc.SelectNodes("/Messages/GetRequest/GetRequestNormal");
                        ObjectType  ot   = ObjectType.None;
                        foreach (XmlNode node in list)
                        {
                            ot = (ObjectType)int.Parse(node.SelectNodes("AttributeDescriptor/ClassId")[0].Attributes["Value"].Value);
                            //If this object type is skipped.
                            if (settings.excludedObjects.Contains(ot))
                            {
                                output.Info.Add("Skipping " + ot.ToString() + " object types.");
                                break;
                            }
                            int index = int.Parse(node.SelectNodes("AttributeDescriptor/AttributeId")[0].Attributes["Value"].Value);
                            //Update logical name.
                            foreach (GXDLMSObject obj in settings.client.Objects.GetObjects(ot))
                            {
                                if ((obj.GetAccess(index) & AccessMode.Read) != 0)
                                {
                                    string tmp = GXCommon.ToHex(LogicalNameToBytes(obj.LogicalName), false);
                                    foreach (XmlNode n in list)
                                    {
                                        XmlAttribute ln = n.SelectNodes("AttributeDescriptor/InstanceId")[0].Attributes["Value"];
                                        ln.Value = tmp;
                                    }
                                    cosemTests.Add(new KeyValuePair <string, List <GXDLMSXmlPdu> >(ot.ToString(), settings.client.LoadXml(doc.InnerXml)));
                                }
                            }
                            break;
                        }
                    }
            }
            foreach (KeyValuePair <string, List <GXDLMSXmlPdu> > it in cosemTests)
            {
                try
                {
                    Execute(settings, reader, it.Key, it.Value, output);
                }
                catch (Exception ex)
                {
                    if (settings.trace > TraceLevel.Off)
                    {
                        Console.WriteLine("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
                        Console.WriteLine(ex.Message);
                    }
                }
            }
            List <ObjectType> unknownDataTypes = new List <ObjectType>();

            foreach (GXDLMSObject o in settings.client.Objects)
            {
                if (!unknownDataTypes.Contains(o.ObjectType))
                {
                    bool found = false;
                    foreach (KeyValuePair <string, List <GXDLMSXmlPdu> > t in cosemTests)
                    {
                        if (o.ObjectType.ToString() == t.Key)
                        {
                            found = true;
                            break;
                        }
                    }
                    if (!found)
                    {
                        unknownDataTypes.Add(o.ObjectType);
                        output.Warnings.Add("<a target=\"_blank\" href=http://www.gurux.fi/" + o.GetType().FullName + ">" + o.ObjectType + "</a> is not tested.");
                    }
                }
            }
            //Check InactivityTimeout.
            bool fail = false;
            int  rc   = reader.RetryCount;
            int  wt   = reader.WaitTime;
            int  inactivityTimeout;

            if (settings.client.InterfaceType == InterfaceType.HDLC)
            {
                GXDLMSHdlcSetup s = (GXDLMSHdlcSetup)settings.client.Objects.GetObjects(ObjectType.IecHdlcSetup)[0];
                s.InactivityTimeout = 0;
                reader.Read(s, 8);
                inactivityTimeout = s.InactivityTimeout;
                output.PreInfo.Add("HdlcSetup default inactivity timeout value is " + inactivityTimeout + " seconds.");
                if ((s.GetAccess(8) & AccessMode.Write) != 0)
                {
                    //Wait second.
                    s.InactivityTimeout = 1;
                    reader.Write(s, 8);
                    Thread.Sleep(2000);
                    try
                    {
                        reader.WaitTime   = 1000;
                        reader.RetryCount = 0;
                        reader.Read(s, 8);
                    }
                    catch (Exception)
                    {
                        //This should fails.
                        fail = true;
                    }
                    reader.InitializeConnection();
                    s.InactivityTimeout = inactivityTimeout;
                    reader.Write(s, 8);
                    if (!fail)
                    {
                        output.Errors.Add("HdlcSetup failed. InactivityTimeout don't work.");
                    }
                }
                else
                {
                    output.PreInfo.Add("HdlcSetup inactivity timeout is not tested.");
                }
            }
            else
            {
                GXDLMSTcpUdpSetup s = (GXDLMSTcpUdpSetup)settings.client.Objects.GetObjects(ObjectType.TcpUdpSetup)[0];
                s.InactivityTimeout = 0;
                reader.Read(s, 6);
                inactivityTimeout = s.InactivityTimeout;
                output.PreInfo.Add("TcpUdpSetup default inactivity timeout value is " + inactivityTimeout + " seconds.");
                if ((s.GetAccess(6) & AccessMode.Write) != 0)
                {
                    //Wait second.
                    s.InactivityTimeout = 1;
                    reader.Write(s, 6);
                    Thread.Sleep(2000);
                    try
                    {
                        reader.WaitTime   = 1000;
                        reader.RetryCount = 0;
                        reader.Read(s, 6);
                    }
                    catch (Exception)
                    {
                        //This should fails.
                        fail = true;
                    }
                    reader.InitializeConnection();
                    s.InactivityTimeout = inactivityTimeout;
                    reader.Write(s, 6);
                    if (!fail)
                    {
                        output.Errors.Add("TcpUdpSetup failed. InactivityTimeout don't work.");
                    }
                }
                else
                {
                    output.PreInfo.Add("TcpUdpSetup inactivity timeout is not tested.");
                }
            }
            reader.WaitTime   = wt;
            reader.RetryCount = rc;
            output.MakeReport();
            return(true);
        }