コード例 #1
0
        /// <summary>
        /// Initialize connection to the meter.
        /// </summary>
        public void InitializeConnection()
        {
            UpdateFrameCounter();
            InitializeOpticalHead();
            GXReplyData reply = new GXReplyData();

            byte[] data;
            data = Client.SNRMRequest();
            if (data != null)
            {
                if (Trace > TraceLevel.Info)
                {
                    Console.WriteLine("Send SNRM request." + GXCommon.ToHex(data, true));
                }
                ReadDataBlock(data, reply);
                if (Trace == TraceLevel.Verbose)
                {
                    Console.WriteLine("Parsing UA reply." + reply.ToString());
                }
                //Has server accepted client.
                Client.ParseUAResponse(reply.Data);
                if (Trace > TraceLevel.Info)
                {
                    Console.WriteLine("Parsing UA reply succeeded.");
                }
            }
            //Generate AARQ request.
            //Split requests to multiple packets if needed.
            //If password is used all data might not fit to one packet.
            foreach (byte[] it in Client.AARQRequest())
            {
                if (Trace > TraceLevel.Info)
                {
                    Console.WriteLine("Send AARQ request", GXCommon.ToHex(it, true));
                }
                reply.Clear();
                ReadDataBlock(it, reply);
            }
            if (Trace > TraceLevel.Info)
            {
                Console.WriteLine("Parsing AARE reply" + reply.ToString());
            }
            //Parse reply.
            Client.ParseAAREResponse(reply.Data);
            reply.Clear();
            //Get challenge Is HLS authentication is used.
            if (Client.IsAuthenticationRequired)
            {
                foreach (byte[] it in Client.GetApplicationAssociationRequest())
                {
                    reply.Clear();
                    ReadDataBlock(it, reply);
                }
                Client.ParseApplicationAssociationResponse(reply.Data);
            }
            if (Trace > TraceLevel.Info)
            {
                Console.WriteLine("Parsing AARE reply succeeded.");
            }
        }
コード例 #2
0
        public void Write(GXDLMSObject obj, object target, int index, List <object> UpdatedObjects)
        {
            object      value;
            GXReplyData reply = new GXReplyData();

            for (int it = 1; it != (obj as IGXDLMSBase).GetAttributeCount() + 1; ++it)
            {
                reply.Clear();
                if (obj.GetDirty(it, out value))
                {
                    //Read DLMS data type if not known.
                    DataType type = obj.GetDataType(it);
                    if (type == DataType.None)
                    {
                        byte[] data = client.Read(obj, it)[0];
                        ReadDataBlock(data, "Write object type " + obj.ObjectType, reply);
                        type = reply.DataType;
                        if (type == DataType.None)
                        {
                            throw new Exception("Failed to write value. Data type not set.");
                        }
                        obj.SetDataType(it, type);
                    }
                    try
                    {
                        ValueEventArgs e = new ValueEventArgs(obj, it, 0, null);
                        e.Value = value;
                        ((IGXDLMSBase)obj).SetValue(null, e);
                        foreach (byte[] tmp in client.Write(obj, it))
                        {
                            ReadDataBlock(tmp, "Write object", reply);
                        }
                        obj.ClearDirty(it);
                        //Read data once again to make sure it is updated.
                        reply.Clear();
                        byte[] data = client.Read(obj, it)[0];
                        ReadDataBlock(data, "Read object " + obj.ObjectType, reply);

                        value = reply.Value;
                        if (value is byte[] && (type = obj.GetUIDataType(it)) != DataType.None)
                        {
                            value = GXDLMSClient.ChangeType((byte[])value, type);
                        }
                        client.UpdateValue(obj, it, value);
                    }
                    catch (GXDLMSException ex)
                    {
                        if (ex.ErrorCode == 3)
                        {
                            throw new Exception("Read/Write Failed.");
                        }
                        else
                        {
                            throw ex;
                        }
                    }
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// Initialize connection to the meter.
        /// </summary>
        public void InitializeConnection()
        {
            Console.WriteLine("Standard: " + Client.Standard);
            if (Client.Ciphering.Security != (byte)Security.None)
            {
                Console.WriteLine("Security: " + Client.Ciphering.Security);
                Console.WriteLine("System title: " + GXCommon.ToHex(Client.Ciphering.SystemTitle, true));
                Console.WriteLine("Authentication key: " + GXCommon.ToHex(Client.Ciphering.AuthenticationKey, true));
                Console.WriteLine("Block cipher key " + GXCommon.ToHex(Client.Ciphering.BlockCipherKey, true));
                if (Client.Ciphering.DedicatedKey != null)
                {
                    Console.WriteLine("Dedicated key: " + GXCommon.ToHex(Client.Ciphering.DedicatedKey, true));
                }
            }
            UpdateFrameCounter();
            InitializeOpticalHead();
            GXReplyData reply = new GXReplyData();

            SNRMRequest();
            //Generate AARQ request.
            //Split requests to multiple packets if needed.
            //If password is used all data might not fit to one packet.
            foreach (byte[] it in Client.AARQRequest())
            {
                if (Trace > TraceLevel.Info)
                {
                    Console.WriteLine("Send AARQ request", GXCommon.ToHex(it, true));
                }
                reply.Clear();
                ReadDataBlock(it, reply);
            }
            if (Trace > TraceLevel.Info)
            {
                Console.WriteLine("Parsing AARE reply" + reply.ToString());
            }
            //Parse reply.
            Client.ParseAAREResponse(reply.Data);
            reply.Clear();
            //Get challenge Is HLS authentication is used.
            if (Client.IsAuthenticationRequired)
            {
                foreach (byte[] it in Client.GetApplicationAssociationRequest())
                {
                    reply.Clear();
                    ReadDataBlock(it, reply);
                }
                Client.ParseApplicationAssociationResponse(reply.Data);
            }
            if (Trace > TraceLevel.Info)
            {
                Console.WriteLine("Parsing AARE reply succeeded.");
            }
        }
コード例 #4
0
        /// <summary>
        /// Read attribute value.
        /// </summary>
        /// <param name="it">COSEM object to read.</param>
        /// <param name="attributeIndex">Attribute index.</param>
        /// <returns>Read value.</returns>
        public object Read(GXDLMSObject it, int attributeIndex)
        {
            if ((it.GetAccess(attributeIndex) & AccessMode.Read) != 0)
            {
                GXReplyData reply = new GXReplyData();
                if (!ReadDataBlock(Client.Read(it, attributeIndex), reply))
                {
                    if (reply.Error != (short)ErrorCode.Rejected)
                    {
                        throw new GXDLMSException(reply.Error);
                    }
                    reply.Clear();
                    Thread.Sleep(1000);
                    if (!ReadDataBlock(Client.Read(it, attributeIndex), reply))
                    {
                        throw new GXDLMSException(reply.Error);
                    }
                }
                //Update data type.
                if (it.GetDataType(attributeIndex) == DataType.None)
                {
                    it.SetDataType(attributeIndex, reply.DataType);
                }
                return(Client.UpdateValue(it, attributeIndex, reply.Value));
            }

            return(null);
        }
コード例 #5
0
 /// <summary>
 /// Close connection to the meter.
 /// </summary>
 public void Close()
 {
     if (Media != null && Client != null)
     {
         try
         {
             if (Trace > TraceLevel.Info)
             {
                 Console.WriteLine("Disconnecting from the meter.");
             }
             GXReplyData reply = new GXReplyData();
             try
             {
                 ReadDataBlock(Client.ReleaseRequest(), reply);
             }
             catch (Exception)
             {
                 //All meters don't support release.
             }
             reply.Clear();
             ReadDLMSPacket(Client.DisconnectRequest(), reply);
             Media.Close();
         }
         catch
         {
         }
         Media  = null;
         Client = null;
     }
 }
コード例 #6
0
        /// <summary>
        /// Read list of attributes.
        /// </summary>
        public void ReadList(List <KeyValuePair <GXDLMSObject, int> > list)
        {
            byte[][]      data   = Client.ReadList(list);
            GXReplyData   reply  = new GXReplyData();
            List <object> values = new List <object>();

            foreach (byte[] it in data)
            {
                ReadDataBlock(it, reply);
                if (reply.Value is object[])
                {
                    values.AddRange((object[])reply.Value);
                }
                else if (reply.Value != null)
                {
                    //Value is null if data is send multiple frames.
                    values.Add(reply.Value);
                }
                reply.Clear();
            }
            if (values.Count != list.Count)
            {
                throw new Exception("Invalid reply. Read items count do not match.");
            }
            Client.UpdateValues(list, values);
        }
コード例 #7
0
 /// <summary>
 /// Close connection to the meter.
 /// </summary>
 public void Close()
 {
     if (Media != null && Client != null)
     {
         try
         {
             if (Trace > TraceLevel.Info)
             {
                 Console.WriteLine("Disconnecting from the meter.");
             }
             GXReplyData reply = new GXReplyData();
             //Release is called only for secured connections. Some older meters don't support release and it might kill them.
             if (Client is GXDLMSSecureClient && (Client as GXDLMSSecureClient).Ciphering.Security != Security.None)
             {
                 ReadDataBlock(Client.ReleaseRequest(), reply);
             }
             reply.Clear();
             ReadDLMSPacket(Client.DisconnectRequest(), reply);
             Media.Close();
         }
         catch
         {
         }
         Media  = null;
         Client = null;
     }
 }
コード例 #8
0
ファイル: Driver.cs プロジェクト: matrixitUser/matrix-mx
        /// <summary>
        /// Read DLMS Data from the device.
        /// </summary>
        /// <remarks>
        /// If access is denied return null.
        /// </remarks>
        /// <param name="data">Data to send.</param>
        /// <returns>Received data.</returns>
        public void ReadDLMSPacket(byte[] data, GXReplyData reply)
        {
            if ((data == null || data.Length == 0) && !reply.IsStreaming())
            {
                return;
            }
            GXReplyData notify = new GXReplyData();

            reply.Error = 0;
            object eop = (byte)0x7E;

            //In network connection terminator is not used.
            if (client.InterfaceType == InterfaceType.WRAPPER && !parent.UseRemoteSerial)
            {
                eop = null;
            }
            ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>()
            {
                AllData  = false,
                Eop      = eop,
                Count    = 5,
                WaitTime = parent.WaitTime * 1000,
            };
            var          answer = Send(data);
            GXByteBuffer rd     = new GXByteBuffer(answer.Body);

            try
            {
                //Loop until whole COSEM packet is received.
                while (!client.GetData(rd, reply, notify))
                {
                    p.Reply = null;
                    if (notify.Data.Size != 0)
                    {
                        // Handle notify.
                        if (!notify.IsMoreData)
                        {
                            rd.Trim();
                            notify.Clear();
                            p.Eop = eop;
                        }
                        continue;
                    }
                    //If Eop is not set read one byte at time.
                    if (p.Eop == null)
                    {
                        p.Count = client.GetFrameSize(rd);
                    }
                    rd.Set(p.Reply);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            if (reply.Error != 0)
            {
                throw new GXDLMSException(reply.Error);
            }
        }
コード例 #9
0
ファイル: Driver.cs プロジェクト: matrixitUser/matrix-mx
        public void Disconnect()
        {
            GXReplyData reply = new GXReplyData();

            try
            {
                //Release is call only for secured connections.
                //All meters are not supporting Release and it's causing problems.
                if (client.InterfaceType == InterfaceType.WRAPPER ||
                    (client.InterfaceType == InterfaceType.HDLC && client.Ciphering.Security != Security.None && !parent.PreEstablished))
                {
                    byte[] data = ReleaseRequest();
                    if (data != null)
                    {
                        ReadDataBlock(data, "Release request", reply);
                    }
                }
                reply.Clear();
                if (client.InterfaceType == InterfaceType.HDLC && !parent.PreEstablished)
                {
                    ReadDataBlock(DisconnectRequest(), "Disconnect request", reply);
                }
            }
            catch (Exception)
            {
                //All meters don't support release.
            }
        }
コード例 #10
0
        public void MethodRequest(GXDLMSObject target, int methodIndex, object data, string text, GXReplyData reply)
        {
            byte[][] tmp;
            if (data is byte[])
            {
                tmp = client.Method(target, methodIndex, data, DataType.Array);
            }
            else
            {
                tmp = client.Method(target, methodIndex, data, GXDLMSConverter.GetDLMSDataType(data));
            }
            int    pos = 0;
            string str = string.Format("Method object {0}, interface {1}", target.LogicalName, target.ObjectType);

            foreach (byte[] it in tmp)
            {
                reply.Clear();
                if (tmp.Length != 1)
                {
                    ++pos;
                    NotifyProgress(text, pos, tmp.Length);
                }
                ReadDataBlock(it, str, reply);
            }
            NotifyProgress(text, 1, 1);
        }
コード例 #11
0
 internal void ReadDataBlock(byte[][] data, string text, int multiplier, GXReplyData reply)
 {
     foreach (byte[] it in data)
     {
         reply.Clear();
         ReadDataBlock(it, text, multiplier, reply);
     }
 }
コード例 #12
0
 void ReadDataBlock(byte[][] data, string text, GXReplyData reply)
 {
     foreach (byte[] it in data)
     {
         reply.Clear();
         ReadDataBlock(it, text, reply);
     }
 }
コード例 #13
0
        /// <summary>
        /// Read all data from the meter.
        /// </summary>
        public void ReadAll(bool useCache)
        {
            try
            {
                InitializeConnection();
                GetAssociationView(useCache);
                //Mikko
                GXDLMSAssociationLogicalName ln = Client.Objects.GetObjects(ObjectType.AssociationLogicalName)[0] as GXDLMSAssociationLogicalName;
                Read(ln, 10);
                Read(ln, 11);
                if (ln.UserList.Count != 0)
                {
                    throw new Exception("Mikko");
                }
                GXReplyData reply = new GXReplyData();
                if (!ReadDataBlock(ln.AddUser(Client, 1, "Mikko"), reply))
                {
                    if (reply.Error != (short)ErrorCode.Rejected)
                    {
                        throw new GXDLMSException(reply.Error);
                    }
                }
                //Update data type.
                Read(ln, 10);
                if (ln.UserList.Count != 1)
                {
                    throw new Exception("Mikko");
                }
                if (ln.UserList[0].Key != 1 || ln.UserList[0].Value != "Mikko")
                {
                    throw new Exception("Mikko");
                }
                reply.Clear();
                if (!ReadDataBlock(ln.RemoveUser(Client, 1, "Mikko"), reply))
                {
                    if (reply.Error != (short)ErrorCode.Rejected)
                    {
                        throw new GXDLMSException(reply.Error);
                    }
                }
                Read(ln, 10);
                if (ln.UserList.Count != 0)
                {
                    throw new Exception("Mikko");
                }

                /*
                 * GetScalersAndUnits();
                 * GetProfileGenericColumns();
                 * GetReadOut();
                 * GetProfileGenerics();
                 */
            }
            finally
            {
                Close();
            }
        }
コード例 #14
0
 public bool ReadDataBlock(byte[][] data, GXReplyData reply)
 {
     foreach (byte[] it in data)
     {
         reply.Clear();
         ReadDataBlock(it, reply);
     }
     return(true);
 }
コード例 #15
0
        /// <summary>
        /// Write list of attributes.
        /// </summary>
        public void WriteList(List <KeyValuePair <GXDLMSObject, int> > list)
        {
            byte[][]    data  = Client.WriteList(list);
            GXReplyData reply = new GXReplyData();

            foreach (byte[] it in data)
            {
                ReadDataBlock(it, reply);
                reply.Clear();
            }
        }
コード例 #16
0
        /// <summary>
        /// Send AARQ Request to the meter.
        /// </summary>
        public void AarqRequest()
        {
            GXReplyData reply = new GXReplyData();

            //Generate AARQ request.
            //Split requests to multiple packets if needed.
            //If password is used all data might not fit to one packet.
            foreach (byte[] it in Client.AARQRequest())
            {
                if (Trace > TraceLevel.Info)
                {
                    Console.WriteLine("Send AARQ request" + GXCommon.ToHex(it, true));
                    GXDLMSTranslator t = new GXDLMSTranslator(TranslatorOutputType.SimpleXml);
                    Console.WriteLine(t.MessageToXml(it));
                }
                reply.Clear();
                ReadDataBlock(it, reply);
            }
            if (Trace > TraceLevel.Info)
            {
                Console.WriteLine("Parsing AARE reply\r\n" + reply.ToString());
            }
            //Parse reply.
            Client.ParseAAREResponse(reply.Data);
            reply.Clear();
            //Get challenge Is HLS authentication is used.
            if (Client.IsAuthenticationRequired)
            {
                foreach (byte[] it in Client.GetApplicationAssociationRequest())
                {
                    reply.Clear();
                    ReadDataBlock(it, reply);
                }
                Client.ParseApplicationAssociationResponse(reply.Data);
            }
            if (Trace > TraceLevel.Info)
            {
                Console.WriteLine("Parsing AARE reply succeeded.");
            }
        }
コード例 #17
0
 /// <summary>
 /// Send data block(s) to the meter.
 /// </summary>
 /// <param name="data">Send data block(s).</param>
 /// <param name="reply">Received reply from the meter.</param>
 /// <returns>Return false if frame is rejected.</returns>
 public bool ReadDataBlock(byte[][] data, GXReplyData reply)
 {
     if (data == null)
     {
         return(true);
     }
     foreach (byte[] it in data)
     {
         reply.Clear();
         ReadDataBlock(it, reply);
     }
     return(reply.Error == 0);
 }
コード例 #18
0
 public bool ReadDataBlock(byte[][] data, GXReplyData reply)
 {
     foreach (byte[] it in data)
     {
         reply.Clear();
         ReadDataBlock(it, reply);
         if (reply.Error == (short)ErrorCode.Rejected)
         {
             return(false);
         }
     }
     return(true);
 }
コード例 #19
0
 /// <summary>
 /// Client has send data.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 void OnReceived(object sender, Gurux.Common.ReceiveEventArgs e)
 {
     try
     {
         lock (this)
         {
             if (trace)
             {
                 Console.WriteLine("<- " + Gurux.Common.GXCommon.ToHex((byte[])e.Data, true));
             }
             reply.Set((byte[])e.Data);
             GetData(reply, data);
             // If all data is received.
             if (data.IsComplete && !data.IsMoreData)
             {
                 try
                 {
                     List <KeyValuePair <GXDLMSObject, int> > list;
                     list = ParsePush((Object[])data.Value);
                     // Print received data.
                     foreach (KeyValuePair <GXDLMSObject, int> it in list)
                     {
                         // Print LN.
                         Console.WriteLine(it.Key.ToString());
                         // Print Value.
                         Console.WriteLine(it.Key.GetValues()[it.Value - 1]);
                     }
                 }
                 catch (Exception ex)
                 {
                     Console.WriteLine(ex.Message);
                 }
                 finally
                 {
                     data.Clear();
                 }
             }
         }
     }
     catch (Exception ex)
     {
         Console.WriteLine(ex.Message);
     }
 }
コード例 #20
0
ファイル: Driver.cs プロジェクト: matrixitUser/matrix-mx
 /// <summary>
 /// Read object.
 /// </summary>
 public void ReadMineCommunicator(string objectName, ObjectType objectType, int it)
 {
     GXReplyData reply = new GXReplyData();
     {
         reply.Clear();
         {
             byte[] data = client.Read(objectName, objectType, it)[0];
             try
             {
                 ReadDataBlock(data, $"Read object type {objectName} index: {it}", reply);
                 object value = reply.Value;
                 log($"{objectName}: value = {value}");
             }
             catch (Exception ex)
             {
                 throw ex;
             }
         }
     }
 }
コード例 #21
0
        /// <summary>
        /// Read attribute value.
        /// </summary>
        /// <param name="it">COSEM object to read.</param>
        /// <param name="attributeIndex">Attribute index.</param>
        /// <returns>Read value.</returns>
        public object Read(GXDLMSObject it, int attributeIndex)
        {
            GXReplyData reply = new GXReplyData();

            if (!ReadDataBlock(Client.Read(it, attributeIndex), reply))
            {
                if (reply.Error != (short)ErrorCode.Rejected)
                {
                    throw new GXDLMSException(reply.Error);
                }
                reply.Clear();
                Thread.Sleep(1000);
                if (!ReadDataBlock(Client.Read(it, attributeIndex), reply))
                {
                    throw new GXDLMSException(reply.Error);
                }
            }
            //Update data type.
            DataType dt = it.GetDataType(attributeIndex);

            if (dt == DataType.None)
            {
                it.SetDataType(attributeIndex, reply.DataType);
                dt = reply.DataType;
            }
            if (dt == DataType.Array || dt == DataType.Structure || reply.Value is GXStructure || reply.Value is GXArray)
            {
                if (it is GXDLMSProfileGeneric && attributeIndex == 2)
                {
                    return(reply.Value);
                }
                if (reply.Value == null)
                {
                    return("");
                }
                return(GXDLMSTranslator.ValueToXml(reply.Value));
            }
            return(Client.UpdateValue(it, attributeIndex, reply.Value));
        }
コード例 #22
0
ファイル: Driver.cs プロジェクト: matrixitUser/matrix-mx
 void ReadDataBlock(byte[][] data, string text, GXReplyData reply)
 {
     foreach (byte[] it in data)
     {
         reply.Clear(); try
         {
             ReadDataBlock(it, text, reply);
         }
         catch (Exception ex)
         {
             //Update frame ID if meter returns error.
             if (client.InterfaceType == InterfaceType.HDLC)
             {
                 int  target, source;
                 byte type;
                 GXDLMSClient.GetHdlcAddressInfo(new GXByteBuffer(it), out target, out source, out type);
                 client.Limits.SenderFrame = type;
             }
             throw ex;
         }
     }
 }
コード例 #23
0
 /// <summary>
 /// Close connection to the meter.
 /// </summary>
 public void Close()
 {
     if (Media != null && Client != null)
     {
         try
         {
             if (Trace > TraceLevel.Info)
             {
                 Console.WriteLine("Disconnecting from the meter.");
             }
             GXReplyData reply = new GXReplyData();
             try
             {
                 if ((Client.ConnectionState & ConnectionState.Dlms) != 0 &&
                     (Client.InterfaceType == InterfaceType.WRAPPER ||
                      Client.Ciphering.Security != (byte)Security.None))
                 {
                     ReadDataBlock(Client.ReleaseRequest(), reply);
                 }
             }
             catch (Exception ex)
             {
                 //All meters don't support Release.
                 Console.WriteLine("Release failed. " + ex.Message);
             }
             reply.Clear();
             if (Client.ConnectionState != 0)
             {
                 ReadDLMSPacket(Client.DisconnectRequest(), reply);
             }
             Media.Close();
         }
         catch
         {
         }
         Media  = null;
         Client = null;
     }
 }
コード例 #24
0
 /// <summary>
 /// Close connection to the meter.
 /// </summary>
 public void Close()
 {
     if (Media != null && Client != null)
     {
         try
         {
             if (Trace > TraceLevel.Info)
             {
                 Console.WriteLine("Disconnecting from the meter.");
             }
             GXReplyData reply = new GXReplyData();
             try
             {
                 //Release is call only for secured connections.
                 //All meters are not supporting Release and it's causing problems.
                 if (Client.InterfaceType == InterfaceType.WRAPPER ||
                     (Client.InterfaceType == InterfaceType.HDLC && Client.Ciphering.Security != (byte)Security.None))
                 {
                     ReadDataBlock(Client.ReleaseRequest(), reply);
                 }
             }
             catch (Exception ex)
             {
                 //All meters don't support Release.
                 Console.WriteLine("Release failed. " + ex.Message);
             }
             reply.Clear();
             ReadDLMSPacket(Client.DisconnectRequest(), reply);
             Media.Close();
         }
         catch
         {
         }
         Media  = null;
         Client = null;
     }
 }
コード例 #25
0
 public void Disconnect()
 {
     if (media != null && media.IsOpen)
     {
         try
         {
             GXReplyData reply = new GXReplyData();
             try
             {
                 //Release is call only for secured connections.
                 //Add meters are not supporting Release and it's causing problems.
                 if (client.Ciphering.Security != Security.None)
                 {
                     ReadDataBlock(ReleaseRequest(), "Release request", reply);
                 }
             }
             catch (Exception)
             {
                 //All meters don't support release.
             }
             reply.Clear();
             ReadDataBlock(DisconnectRequest(), "Disconnect request", reply);
         }
         finally
         {
             if (media != null)
             {
                 media.Close();
                 //Restore old settings.
                 if (media is GXSerial)
                 {
                     media.Settings = parent.StartMediaSettings;
                 }
             }
         }
     }
 }
コード例 #26
0
 /// <summary>
 /// Read Invocation counter (frame counter) from the meter and update it.
 /// </summary>
 private void UpdateFrameCounter()
 {
     //Read frame counter if GeneralProtection is used.
     if (!string.IsNullOrEmpty(InvocationCounter) && Client.Ciphering != null && Client.Ciphering.Security != (byte)Security.None)
     {
         InitializeOpticalHead();
         byte[]      data;
         GXReplyData reply = new GXReplyData();
         Client.ProposedConformance |= Conformance.GeneralProtection;
         int            add       = Client.ClientAddress;
         Authentication auth      = Client.Authentication;
         Security       security  = Client.Ciphering.Security;
         byte[]         challenge = Client.CtoSChallenge;
         try
         {
             Client.ClientAddress      = 16;
             Client.Authentication     = Authentication.None;
             Client.Ciphering.Security = (byte)Security.None;
             data = Client.SNRMRequest();
             if (data != null)
             {
                 if (Trace > TraceLevel.Info)
                 {
                     Console.WriteLine("Send SNRM request." + GXCommon.ToHex(data, true));
                 }
                 ReadDataBlock(data, reply);
                 if (Trace == TraceLevel.Verbose)
                 {
                     Console.WriteLine("Parsing UA reply." + reply.ToString());
                 }
                 //Has server accepted client.
                 Client.ParseUAResponse(reply.Data);
                 if (Trace > TraceLevel.Info)
                 {
                     Console.WriteLine("Parsing UA reply succeeded.");
                 }
             }
             //Generate AARQ request.
             //Split requests to multiple packets if needed.
             //If password is used all data might not fit to one packet.
             foreach (byte[] it in Client.AARQRequest())
             {
                 if (Trace > TraceLevel.Info)
                 {
                     Console.WriteLine("Send AARQ request", GXCommon.ToHex(it, true));
                 }
                 reply.Clear();
                 ReadDataBlock(it, reply);
             }
             if (Trace > TraceLevel.Info)
             {
                 Console.WriteLine("Parsing AARE reply" + reply.ToString());
             }
             try
             {
                 //Parse reply.
                 Client.ParseAAREResponse(reply.Data);
                 reply.Clear();
                 GXDLMSData d = new GXDLMSData(InvocationCounter);
                 Read(d, 2);
                 Client.Ciphering.InvocationCounter = 1 + Convert.ToUInt32(d.Value);
                 Console.WriteLine("Invocation counter: " + Convert.ToString(Client.Ciphering.InvocationCounter));
                 reply.Clear();
                 Disconnect();
             }
             catch (Exception Ex)
             {
                 Disconnect();
                 throw Ex;
             }
         }
         finally
         {
             Client.ClientAddress      = add;
             Client.Authentication     = auth;
             Client.Ciphering.Security = security;
             Client.CtoSChallenge      = challenge;
         }
     }
 }
コード例 #27
0
        /// <summary>
        /// Read DLMS Data from the device.
        /// </summary>
        /// <param name="data">Data to send.</param>
        /// <returns>Received data.</returns>
        public void ReadDLMSPacket(byte[] data, GXReplyData reply)
        {
            if (data == null && !reply.IsStreaming())
            {
                return;
            }
            GXReplyData notify = new GXReplyData();

            reply.Error = 0;
            object eop = (byte)0x7E;

            //In network connection terminator is not used.
            if (Client.InterfaceType == InterfaceType.WRAPPER)
            {
                eop = null;
            }
            int  pos       = 0;
            bool succeeded = false;
            ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>()
            {
                Eop      = eop,
                WaitTime = WaitTime,
            };

            if (eop == null)
            {
                p.Count = 8;
            }
            else
            {
                p.Count = 5;
            }
            GXByteBuffer rd = new GXByteBuffer();

            lock (Media.Synchronous)
            {
                while (!succeeded && pos != 3)
                {
                    if (!reply.IsStreaming())
                    {
                        WriteTrace("TX:\t" + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(data, true));
                        Media.Send(data, null);
                    }
                    succeeded = Media.Receive(p);
                    if (!succeeded)
                    {
                        if (++pos >= RetryCount)
                        {
                            throw new Exception("Failed to receive reply from the device in given time.");
                        }
                        //If Eop is not set read one byte at time.
                        if (p.Eop == null)
                        {
                            p.Count = 1;
                        }
                        //Try to read again...
                        System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3");
                    }
                }
                rd = new GXByteBuffer(p.Reply);
                try
                {
                    pos = 0;
                    //Loop until whole COSEM packet is received.
                    while (!Client.GetData(rd, reply, notify))
                    {
                        p.Reply = null;
                        if (notify.IsComplete && notify.Data.Data != null)
                        {
                            //Handle notify.
                            if (!notify.IsMoreData)
                            {
                                //Show received push message as XML.
                                string           xml;
                                GXDLMSTranslator t = new GXDLMSTranslator(TranslatorOutputType.SimpleXml);
                                t.DataToXml(notify.Data, out xml);
                                Console.WriteLine(xml);
                                notify.Clear();
                                continue;
                            }
                        }
                        if (p.Eop == null)
                        {
                            p.Count = Client.GetFrameSize(rd);
                        }
                        while (!Media.Receive(p))
                        {
                            if (++pos >= RetryCount)
                            {
                                throw new Exception("Failed to receive reply from the device in given time.");
                            }
                            //If echo.
                            if (rd == null || rd.Size == data.Length)
                            {
                                Media.Send(data, null);
                            }
                            //Try to read again...
                            System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3");
                        }
                        rd.Set(p.Reply);
                    }
                }
                catch (Exception ex)
                {
                    WriteTrace("RX:\t" + DateTime.Now.ToLongTimeString() + "\t" + rd);
                    throw ex;
                }
            }
            WriteTrace("RX:\t" + DateTime.Now.ToLongTimeString() + "\t" + rd);
            if (reply.Error != 0)
            {
                if (reply.Error == (short)ErrorCode.Rejected)
                {
                    Thread.Sleep(1000);
                    ReadDLMSPacket(data, reply);
                }
                else
                {
                    throw new GXDLMSException(reply.Error);
                }
            }
        }
コード例 #28
0
        /// <summary>
        /// Client has send data.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnReceived(object sender, Gurux.Common.ReceiveEventArgs e)
        {
            try
            {
                lock (this)
                {
                    if (trace)
                    {
                        Console.WriteLine("<- " + Gurux.Common.GXCommon.ToHex((byte[])e.Data, true));
                    }
                    reply.Set((byte[])e.Data);
                    //Example handles only notify messages.
                    GXReplyData data = new GXReplyData();
                    client.GetData(reply, data, notify);
                    // If all data is received.
                    if (notify.IsComplete && !notify.IsMoreData)
                    {
                        try
                        {
                            //Show data as XML.
                            string           xml;
                            GXDLMSTranslator t = new GXDLMSTranslator(TranslatorOutputType.SimpleXml);
                            t.DataToXml(notify.Data, out xml);
                            Console.WriteLine(xml);

                            // Print received data.
                            PrintData(notify.Value, 0);

                            //Example is sending list of push messages in first parameter.
                            if (notify.Value is object[])
                            {
                                object[] tmp = notify.Value as object[];
                                List <KeyValuePair <GXDLMSObject, int> > objects = client.ParsePushObjects((object[])tmp[0]);
                                //Remove first item because it's not needed anymore.
                                objects.RemoveAt(0);
                                //Update clock.
                                int Valueindex = 1;
                                foreach (KeyValuePair <GXDLMSObject, int> it in objects)
                                {
                                    client.UpdateValue(it.Key, it.Value, tmp[Valueindex]);
                                    ++Valueindex;
                                    //Print value
                                    Console.WriteLine(it.Key.ObjectType + " " + it.Key.LogicalName + " " + it.Value + ":" + it.Key.GetValues()[it.Value - 1]);
                                }
                            }
                            Console.WriteLine("Server address:" + notify.ServerAddress + " Client Address:" + notify.ClientAddress);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                        finally
                        {
                            notify.Clear();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
コード例 #29
0
        /// <summary>
        /// Read DLMS Data from the device.
        /// </summary>
        /// <param name="data">Data to send.</param>
        /// <returns>Received data.</returns>
        public void ReadDLMSPacket(byte[] data, GXReplyData reply)
        {
            if (data == null && !reply.IsStreaming())
            {
                return;
            }
            reply.Error = 0;
            object eop = (byte)0x7E;

            //In network connection terminator is not used.
            if (Client.InterfaceType == InterfaceType.WRAPPER && Media is GXNet)
            {
                eop = null;
            }
            int  pos       = 0;
            bool succeeded = false;
            ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>()
            {
                Eop      = eop,
                Count    = 5,
                WaitTime = WaitTime,
            };
            GXReplyData notify = new GXReplyData();

            lock (Media.Synchronous)
            {
                while (!succeeded && pos != 3)
                {
                    if (!reply.IsStreaming())
                    {
                        WriteTrace(true, "TX:\t" + DateTime.Now.ToString("hh:mm:ss") + "\t" + GXCommon.ToHex(data, true));
                        Media.Send(data, null);
                    }
                    succeeded = Media.Receive(p);
                    if (!succeeded)
                    {
                        if (++pos >= RetryCount)
                        {
                            throw new Exception("Failed to receive reply from the device in given time.");
                        }
                        //If Eop is not set read one byte at time.
                        if (p.Eop == null)
                        {
                            p.Count = 1;
                        }
                        //Try to read again...
                        System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3");
                    }
                }
                try
                {
                    pos = 0;
                    //Loop until whole COSEM packet is received.
                    while (!Client.GetData(p.Reply, reply, notify))
                    {
                        // If all data is received.
                        if (notify.IsComplete && !notify.IsMoreData)
                        {
                            /*
                             * try
                             * {
                             *  if (GXNotifyListener.Parser != null)
                             *  {
                             *      GXAMIClient cl = new GXAMIClient();
                             *      GXNotifyListener.Parser.Parse(Media.ToString(), notify.Value, cl.GetData, cl.SetData);
                             *  }
                             * }
                             * catch (Exception ex)
                             * {
                             *  //TODO: Save error to the database.
                             * }
                             */
                            notify.Clear();
                        }

                        //If Eop is not set read one byte at time.
                        if (p.Eop == null)
                        {
                            p.Count = 1;
                        }
                        while (!Media.Receive(p))
                        {
                            if (++pos >= RetryCount)
                            {
                                throw new Exception("Failed to receive reply from the device in given time.");
                            }
                            //If echo.
                            if (p.Reply == null || p.Reply.Length == data.Length)
                            {
                                Media.Send(data, null);
                            }
                            //Try to read again...
                            System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3");
                        }
                    }
                }
                catch (Exception ex)
                {
                    WriteTrace(false, "RX:\t" + DateTime.Now.ToString("hh:mm:ss") + "\t" + GXCommon.ToHex(p.Reply, true));
                    throw ex;
                }
            }
            WriteTrace(false, "RX:\t" + DateTime.Now.ToString("hh:mm:ss") + "\t" + GXCommon.ToHex(p.Reply, true));
            if (reply.Error != 0)
            {
                if (reply.Error == (short)ErrorCode.Rejected)
                {
                    Thread.Sleep(1000);
                    ReadDLMSPacket(data, reply);
                }
                else
                {
                    throw new GXDLMSException(reply.Error);
                }
            }
        }
コード例 #30
0
 /// <summary>
 /// Client has send data for for the gateway.
 /// </summary>
 /// <remarks>
 /// GW finds the correct client and sends data for it.
 /// </remarks>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 public static void OnGatewayReceived(object sender, Gurux.Common.ReceiveEventArgs e)
 {
     try
     {
         lock (buffers)
         {
             GXByteBuffer bb;
             if (!buffers.ContainsKey(e.SenderInfo))
             {
                 bb = new GXByteBuffer();
                 buffers[e.SenderInfo] = bb;
             }
             else
             {
                 bb = buffers[e.SenderInfo];
             }
             bb.Set((byte[])e.Data);
             GXServerReply sr = new GXServerReply(bb.Data);
             GatewayServer.Reset();
             try
             {
                 GatewayServer.HandleRequest(sr);
                 if (sr.Reply != null)
                 {
                     if (Trace > TraceLevel.Info)
                     {
                         Console.WriteLine("TX:\t" + Gurux.Common.GXCommon.ToHex(sr.Reply, true));
                     }
                     ((IGXMedia)sender).Send(sr.Reply, e.SenderInfo);
                     return;
                 }
             }
             catch (Exception)
             {
                 //Return error.
                 sr.Reply = GatewayServer.ReportError(sr.Command, ErrorCode.HardwareFault);
             }
             if (sr.Gateway != null && sr.Data != null)
             {
                 GXByteBuffer  pdu     = new GXByteBuffer(sr.Data);
                 InterfaceType type    = (InterfaceType)sr.Gateway.NetworkId;
                 GXByteBuffer  address = new GXByteBuffer();
                 address.Set(sr.Gateway.PhysicalDeviceAddress);
                 int addr = address.GetUInt8();
                 //Find correct meter using GW information.
                 if (meters.ContainsKey(addr))
                 {
                     //Find client for the server or create a new one.
                     GXDLMSClient cl;
                     if (!clients.ContainsKey(addr))
                     {
                         //Set client address if data is send without framing.
                         if (GatewayServer.Settings.ClientAddress == 0)
                         {
                             GatewayServer.Settings.ClientAddress = 0x10;
                         }
                         cl = new GXDLMSClient(true, GatewayServer.Settings.ClientAddress, addr, GatewayServer.Authentication, null, type);
                         clients.Add(addr, cl);
                     }
                     else
                     {
                         cl = clients[addr];
                     }
                     GXReplyData data   = new GXReplyData();
                     GXReplyData notify = new GXReplyData();
                     GXDLMSMeter m      = meters[addr];
                     //Send SNRM if needed.
                     if (sr.Command == Command.Aarq && (type == InterfaceType.HDLC || type == InterfaceType.HdlcWithModeE))
                     {
                         GXServerReply sr2 = new GXServerReply(cl.SNRMRequest());
                         m.HandleRequest(sr2);
                         if (cl.GetData(sr2.Reply, data, notify))
                         {
                             data.Clear();
                             notify.Clear();
                         }
                         else
                         {
                             //If the meter doesn't reply.
                             bb.Clear();
                             return;
                         }
                     }
                     byte[][] frames = cl.CustomFrameRequest(Command.None, pdu);
                     foreach (byte[] it in frames)
                     {
                         sr.Data = it;
                         m.HandleRequest(sr);
                         if (Trace > TraceLevel.Info)
                         {
                             Console.WriteLine("RX:\t" + Gurux.Common.GXCommon.ToHex(sr.Reply, true));
                         }
                         data.RawPdu = true;
                         if (cl.GetData(sr.Reply, data, notify))
                         {
                             while (data.IsMoreData)
                             {
                                 sr.Data = cl.ReceiverReady(data);
                                 m.HandleRequest(sr);
                                 if (Trace > TraceLevel.Info)
                                 {
                                     Console.WriteLine("RX:\t" + Gurux.Common.GXCommon.ToHex(sr.Reply, true));
                                 }
                                 cl.GetData(sr.Reply, data, notify);
                             }
                             byte[] reply = sr.Reply;
                             try
                             {
                                 GXByteBuffer tmp = new GXByteBuffer();
                                 tmp.Set(data.Data);
                                 GatewayServer.Gateway = sr.Gateway;
                                 reply = GatewayServer.CustomFrameRequest(Command.None, tmp);
                             }
                             finally
                             {
                                 GatewayServer.Gateway = null;
                             }
                             if (Trace > TraceLevel.Info)
                             {
                                 Console.WriteLine("TX:\t" + Gurux.Common.GXCommon.ToHex(reply, true));
                             }
                             ((IGXMedia)sender).Send(reply, e.SenderInfo);
                         }
                     }
                 }
                 bb.Clear();
             }
         }
     }
     catch (Exception ex)
     {
         if (!(ex is SocketException))
         {
             Console.WriteLine(ex.Message);
         }
     }
 }