Beispiel #1
0
        static public void WriteLog(string text, byte[] value)
        {
            string str = DateTime.Now.ToLongTimeString() + " " + text;

            //Show data as hex.
            if ((LogLevel & 1) != 0)
            {
                if (value != null)
                {
                    str += "\r\n" + GXCommon.ToHex(value, true);
                }
                System.Diagnostics.Trace.WriteLine(str);
            }
            //Show data as xml.
            if ((LogLevel & 2) != 0)
            {
                receivedTraceData.Set(value);
                try
                {
                    GXByteBuffer  pdu  = new GXByteBuffer();
                    InterfaceType type = GXDLMSTranslator.GetDlmsFraming(receivedTraceData);
                    if (translator.FindNextFrame(receivedTraceData, pdu, type))
                    {
                        System.Diagnostics.Trace.WriteLine(translator.MessageToXml(receivedTraceData));
                        receivedTraceData.Clear();
                    }
                }
                catch (Exception)
                {
                    receivedTraceData.Clear();
                }
            }
        }
Beispiel #2
0
 internal static byte[] Decrypt(AesGcmParameter p, GXByteBuffer data)
 {
     byte[] tmp = GXDLMSChippering.DecryptAesGcm(p, data);
     data.Clear();
     data.Set(tmp);
     return(tmp);
 }
Beispiel #3
0
        Security GXICipher.Decrypt(byte[] title, GXByteBuffer data)
        {
            AesGcmParameter p = new AesGcmParameter(title, BlockCipherKey, AuthenticationKey);

            byte[] tmp = GXDLMSChippering.DecryptAesGcm(p, data);
            data.Clear();
            data.Set(tmp);
            return(p.Security);
        }
Beispiel #4
0
        static public void WriteLog(string text, byte[] value)
        {
            string str;

            if (GXDLMSDirector.Properties.Settings.Default.LogTime)
            {
                str = DateTime.Now.ToLongTimeString() + " " + text;
            }
            else
            {
                str = text;
            }
            //Show data as hex.
            if ((LogLevel & 1) != 0)
            {
                if (value != null)
                {
                    str += Environment.NewLine + GXCommon.ToHex(value, true);
                }
                System.Diagnostics.Trace.WriteLine(str);
            }
            //Show data as xml.
            if (value != null && (LogLevel & 2) != 0)
            {
                receivedTraceData.Set(value);
                try
                {
                    GXByteBuffer  pdu  = new GXByteBuffer();
                    InterfaceType type = GXDLMSTranslator.GetDlmsFraming(receivedTraceData);
                    while (translator.FindNextFrame(receivedTraceData, pdu, type))
                    {
                        System.Diagnostics.Trace.WriteLine(translator.MessageToXml(receivedTraceData));
                        receivedTraceData.Trim();
                    }
                }
                catch (Exception)
                {
                    receivedTraceData.Clear();
                }
            }
        }
        /// <summary>
        /// Convert message to XML.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TranslateBtn_Click(object sender, EventArgs e)
        {
            MessageXmlTB.Text = "";
            StringBuilder sb = new StringBuilder();
            GXByteBuffer  bb = new GXByteBuffer();
            //TODO: This can remove later.
            Security s = translator.Security;

            try
            {
                translator.Clear();
                UpdateSecurity();
                translator.Security = Security.Authentication;

                translator.PduOnly = PduOnlyCB.Checked;
                GXByteBuffer pdu = new GXByteBuffer();
                bb.Set(GXDLMSTranslator.HexToBytes(RemoveComments(MessagePduTB.Text)));
                InterfaceType type = GXDLMSTranslator.GetDlmsFraming(bb);
                int           cnt  = 1;
                while (translator.FindNextFrame(bb, pdu, type))
                {
                    int    start = bb.Position;
                    string tmp   = translator.MessageToXml(bb);
                    sb.AppendLine(cnt + ": " + bb.ToHex(true, start, bb.Position - start));
                    ++cnt;
                    sb.Append(tmp);
                    pdu.Clear();
                }
                MessageXmlTB.Text   = sb.ToString();
                translator.Security = s;
            }
            catch (Exception ex)
            {
                translator.Security = s;
                MessageXmlTB.AppendText(sb.ToString());
                MessageXmlTB.AppendText(Environment.NewLine);
                MessageXmlTB.AppendText(bb.RemainingHexString(true));

                MessageBox.Show(this, ex.Message);
            }
        }
 private void TemplateDescriptionTb_Leave(object sender, EventArgs e)
 {
     try
     {
         DataType          v;
         GXByteBuffer      bb     = new GXByteBuffer();
         GXDLMSCompactData target = Target as GXDLMSCompactData;
         bb.SetUInt8(2);
         bb.SetUInt8(0);
         foreach (string it in TemplateDescriptionTb.Text.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
         {
             if (!Enum.TryParse <DataType>(it, out v))
             {
                 bb.Clear();
                 break;
             }
             bb.SetUInt8((byte)v);
         }
         byte[] tmp;
         if (bb.Size != 0)
         {
             bb.SetUInt8(1, (byte)(bb.Size - 2));
             tmp = bb.Array();
         }
         else
         {
             tmp = GXDLMSTranslator.HexToBytes(TemplateDescriptionTb.Text);
         }
         if (GXDLMSTranslator.ToHex(tmp) != GXDLMSTranslator.ToHex(target.TemplateDescription))
         {
             target.TemplateDescription = tmp;
             Target.UpdateDirty(5, target.TemplateDescription);
             errorProvider1.SetError(TemplateDescriptionTb, Properties.Resources.ValueChangedTxt);
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
     }
 }
Beispiel #7
0
 Gurux.DLMS.Enums.Security GXICipher.Decrypt(byte[] title, GXByteBuffer data)
 {
     AesGcmParameter p = new AesGcmParameter(title, BlockCipherKey, AuthenticationKey);
     byte[] tmp = GXDLMSChippering.DecryptAesGcm(p, data);
     data.Clear();
     data.Set(tmp);
     return p.Security;
 }
Beispiel #8
0
        ///<summary>
        /// Chipher text.
        ///</summary>
        ///<param name="settings">
        ///DLMS settings.
        ///</param>
        ///<param name="cipher">
        ///Cipher.
        ///</param>
        ///<param name="ic">
        ///Invocation counter.
        ///</param>
        ///<param name="data">
        ///Text to chipher.
        ///</param>
        ///<param name="secret">
        ///Secret.
        ///</param>
        ///<returns>
        ///Chiphered text.
        ///</returns>
        public static byte[] Secure(GXDLMSSettings settings, GXICipher cipher, uint ic, byte[] data, byte[] secret)
        {
            byte[] tmp;
            if (settings.Authentication == Authentication.High)
            {
                int len = secret.Length;
                if (len % 16 != 0)
                {
                    len += 16 - (secret.Length % 16);
                }
                byte[] p = new byte[len];
                byte[] s = new byte[16];
                byte[] x = new byte[16];
                int    i;
                data.CopyTo(p, 0);
                secret.CopyTo(s, 0);
                for (i = 0; i < p.Length; i += 16)
                {
                    Buffer.BlockCopy(p, i, x, 0, 16);
                    GXAes128.Encrypt(x, s);
                    Buffer.BlockCopy(x, 0, p, i, 16);
                }
                Buffer.BlockCopy(p, 0, x, 0, 16);
                return(x);
            }
            // Get server Challenge.
            GXByteBuffer challenge = new GXByteBuffer();

            // Get shared secret
            if (settings.Authentication == Authentication.HighGMAC)
            {
                challenge.Set(data);
            }
            else
            {
                challenge.Set(data);
                challenge.Set(secret);
            }
            tmp = challenge.Array();
            if (settings.Authentication == Authentication.HighMD5)
            {
#if !WINDOWS_UWP
                using (MD5 md5Hash = MD5.Create())
                {
                    tmp = md5Hash.ComputeHash(tmp);
                    return(tmp);
                }
#endif
            }
            else if (settings.Authentication == Authentication.HighSHA1)
            {
#if !WINDOWS_UWP
                using (SHA1 sha = new SHA1CryptoServiceProvider())
                {
                    tmp = sha.ComputeHash(tmp);
                    return(tmp);
                }
#endif
            }
            else if (settings.Authentication == Authentication.HighGMAC)
            {
                //SC is always Security.Authentication.
                AesGcmParameter p = new AesGcmParameter(0, Security.Authentication, ic,
                                                        secret, cipher.BlockCipherKey, cipher.AuthenticationKey);
                p.Type = CountType.Tag;
                challenge.Clear();
                challenge.SetUInt8((byte)Security.Authentication);
                challenge.SetUInt32(p.InvocationCounter);
                challenge.Set(GXDLMSChippering.EncryptAesGcm(p, tmp));
                tmp = challenge.Array();
                return(tmp);
            }
            return(data);
        }
        /// <summary>
        /// Convert message to XML.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TranslateBtn_Click(object sender, EventArgs e)
        {
            MessageXmlTB.Text = "";
            StringBuilder sb = new StringBuilder();
            GXByteBuffer  bb = new GXByteBuffer();
            //TODO: This can remove later.
            byte s = translator.Security;

            try
            {
                translator.Clear();
                UpdateSecurity();
                translator.Security = (byte)Security.Authentication;

                translator.PduOnly = PduOnlyCB.Checked;
                GXByteBuffer pdu = new GXByteBuffer();
                bb.Set(GXDLMSTranslator.HexToBytes(RemoveComments(MessagePduTB.Text)));
                InterfaceType type = GXDLMSTranslator.GetDlmsFraming(bb);
                int           cnt  = 1;
                string        last = "";
                while (translator.FindNextFrame(bb, pdu, type))
                {
                    int start = bb.Position;
                    GXDLMSTranslatorMessage msg = new GXDLMSTranslatorMessage();
                    msg.Message = bb;
                    translator.MessageToXml(msg);
                    //Remove duplicate messages.
                    if (RemoveDuplicatesCb.Checked)
                    {
                        if (last == msg.Xml)
                        {
                            continue;
                        }
                    }
                    last = msg.Xml;
                    if (msg.Command == Command.Aarq)
                    {
                        if (msg.SystemTitle != null)
                        {
                            string st = UpdateSystemTitle(this, "Current System title \"{0}\" is different in the parsed \"{1}\". Do you want to start using parsed one?",
                                                          msg.SystemTitle, SystemTitleTB.Text, SystemTitleAsciiCb.Checked);
                            if (st != null)
                            {
                                SystemTitleTB.Text         = "";
                                SystemTitleAsciiCb.Checked = false;
                                SystemTitleTB.Text         = st;
                            }
                        }
                        if (msg.DedicatedKey != null)
                        {
                            string key = UpdateSystemTitle(this, "Current dedicated key \"{0}\" is different in the parsed \"{1}\". Do you want to start using parsed one?",
                                                           msg.DedicatedKey, DedicatedKeyTb.Text, DedicatedKeyAsciiCb.Checked);
                            if (key != null)
                            {
                                DedicatedKeyTb.Text         = "";
                                DedicatedKeyAsciiCb.Checked = false;
                                DedicatedKeyTb.Text         = key;
                            }
                        }
                    }
                    if (msg.Command == Command.Aare && msg.SystemTitle != null)
                    {
                        string st = UpdateSystemTitle(this, "Current Server System title \"{0}\" is different in the parsed \"{1}\". Do you want to start using parsed one?",
                                                      msg.SystemTitle, ServerSystemTitleTB.Text, ServerSystemTitleAsciiCb.Checked);
                        if (st != null)
                        {
                            ServerSystemTitleTB.Text   = "";
                            SystemTitleAsciiCb.Checked = false;
                            ServerSystemTitleTB.Text   = st;
                        }
                    }
                    if (!AllRb.Checked)
                    {
                        switch (msg.Command)
                        {
                        case Command.None:
                            break;

                        case Command.InitiateRequest:
                        case Command.ReadRequest:
                        case Command.WriteRequest:
                        case Command.GetRequest:
                        case Command.SetRequest:
                        case Command.MethodRequest:
                        case Command.Snrm:
                        case Command.Aarq:
                        case Command.ReleaseRequest:
                        case Command.DisconnectRequest:
                        case Command.AccessRequest:
                        case Command.GloGetRequest:
                        case Command.GloSetRequest:
                        case Command.GloMethodRequest:
                        case Command.GloInitiateRequest:
                        case Command.GloReadRequest:
                        case Command.GloWriteRequest:
                        case Command.DedInitiateRequest:
                        case Command.DedReadRequest:
                        case Command.DedWriteRequest:
                        case Command.DedGetRequest:
                        case Command.DedSetRequest:
                        case Command.DedMethodRequest:
                        case Command.GatewayRequest:
                            if (ReceivedRb.Checked)
                            {
                                continue;
                            }
                            break;

                        case Command.InitiateResponse:
                        case Command.ReadResponse:
                        case Command.WriteResponse:
                        case Command.GetResponse:
                        case Command.SetResponse:
                        case Command.MethodResponse:
                        case Command.Ua:
                        case Command.Aare:
                        case Command.ReleaseResponse:
                        case Command.AccessResponse:
                        case Command.GloGetResponse:
                        case Command.GloSetResponse:
                        case Command.GloMethodResponse:
                        case Command.GloInitiateResponse:
                        case Command.GloReadResponse:
                        case Command.GloWriteResponse:
                        case Command.DedInitiateResponse:
                        case Command.DedReadResponse:
                        case Command.DedWriteResponse:
                        case Command.DedGetResponse:
                        case Command.DedSetResponse:
                        case Command.DedMethodResponse:
                        case Command.GatewayResponse:
                            if (SentRb.Checked)
                            {
                                continue;
                            }
                            break;

                        case Command.DisconnectMode:
                        case Command.UnacceptableFrame:
                        case Command.ConfirmedServiceError:
                        case Command.ExceptionResponse:
                        case Command.GeneralBlockTransfer:
                        case Command.DataNotification:
                        case Command.GloEventNotification:
                        case Command.GloConfirmedServiceError:
                        case Command.GeneralGloCiphering:
                        case Command.GeneralDedCiphering:
                        case Command.GeneralCiphering:
                        case Command.InformationReport:
                        case Command.EventNotification:
                        case Command.DedConfirmedServiceError:
                        case Command.DedUnconfirmedWriteRequest:
                        case Command.DedInformationReport:
                        case Command.DedEventNotification:
                            break;
                        }
                    }
                    sb.AppendLine(cnt + ": " + bb.ToHex(true, start, bb.Position - start));
                    ++cnt;
                    sb.Append(msg.Xml);
                    pdu.Clear();
                }
                MessageXmlTB.Text   = sb.ToString();
                translator.Security = s;
            }
            catch (Exception ex)
            {
                translator.Security = s;
                MessageXmlTB.AppendText(sb.ToString());
                MessageXmlTB.AppendText(Environment.NewLine);
                MessageXmlTB.AppendText(bb.RemainingHexString(true));

                MessageBox.Show(this, ex.Message);
            }
        }
Beispiel #10
0
 ///<summary>
 /// Chipher text.
 ///</summary>
 ///<param name="settings">
 ///DLMS settings. 
 ///</param>
 ///<param name="cipher">
 ///Cipher. 
 ///</param>
 ///<param name="ic">
 ///Invocation counter.
 ///</param>
 ///<param name="data">
 ///Text to chipher. 
 ///</param>
 ///<param name="secret">
 ///Secret. 
 ///</param>
 ///<returns>
 ///Chiphered text.
 ///</returns>
 public static byte[] Secure(GXDLMSSettings settings, GXICipher cipher, UInt32 ic, byte[] data, byte[] secret)
 {
     byte[] tmp;
     if (settings.Authentication == Authentication.High)
     {
         int len = secret.Length;
         if (len % 16 != 0)
         {
             len += 16 - (secret.Length % 16);
         }
         byte[] p = new byte[len];
         byte[] s = new byte[16];
         byte[] x = new byte[16];
         int i;
         data.CopyTo(p, 0);
         secret.CopyTo(s, 0);
         for (i = 0; i < p.Length; i += 16)
         {
             Buffer.BlockCopy(p, i, x, 0, 16);
             GXAes128.Encrypt(x, s);
             Buffer.BlockCopy(x, 0, p, i, 16);
         }
         Buffer.BlockCopy(p, 0, x, 0, 16);
         return x;
     }
     // Get server Challenge.
     GXByteBuffer challenge = new GXByteBuffer();
     // Get shared secret
     if (settings.Authentication == Authentication.HighGMAC)
     {
         challenge.Set(data);              
     }
     else
     {
         challenge.Set(data);
         challenge.Set(secret);
     }
     tmp = challenge.Array();
     if (settings.Authentication == Authentication.HighMD5)
     {
         using (MD5 md5Hash = MD5.Create())
         {
             tmp = md5Hash.ComputeHash(tmp);
             return tmp;
         }
     }
     else if (settings.Authentication == Authentication.HighSHA1)
     {
         using (SHA1 sha = new SHA1CryptoServiceProvider())
         {
             tmp = sha.ComputeHash(tmp);
             return tmp;
         }
     }
     else if (settings.Authentication == Authentication.HighGMAC)
     {
         //SC is always Security.Authentication.
         AesGcmParameter p = new AesGcmParameter(0, Security.Authentication, ic,
             secret, cipher.BlockCipherKey, cipher.AuthenticationKey);
         p.Type = CountType.Tag;
         challenge.Clear();
         challenge.SetUInt8((byte)Security.Authentication);
         challenge.SetUInt32(p.FrameCounter);
         challenge.Set(GXDLMSChippering.EncryptAesGcm(p, tmp));
         tmp = challenge.Array();
         return tmp;
     }
     return data;
 }
Beispiel #11
0
        ///<summary>
        /// Chipher text.
        ///</summary>
        ///<param name="settings">
        ///DLMS settings.
        ///</param>
        ///<param name="cipher">
        ///Cipher.
        ///</param>
        ///<param name="ic">
        ///Invocation counter.
        ///</param>
        ///<param name="data">
        ///Text to chipher.
        ///</param>
        ///<param name="secret">
        ///Secret.
        ///</param>
        ///<returns>
        ///Chiphered text.
        ///</returns>
        internal static byte[] Secure(GXDLMSSettings settings, GXICipher cipher, UInt32 ic, byte[] data, byte[] secret)
        {
            byte[] tmp;
            if (settings.Authentication == Authentication.High)
            {
                int len = secret.Length;
                if (len % 16 != 0)
                {
                    len += 16 - (secret.Length % 16);
                }
                byte[] p = new byte[len];
                byte[] s = new byte[16];
                byte[] x = new byte[16];
                int    i;
                data.CopyTo(p, 0);
                secret.CopyTo(s, 0);
                for (i = 0; i < p.Length; i += 16)
                {
                    Buffer.BlockCopy(p, i, x, 0, 16);
                    GXAes128.Encrypt(x, s);
                    Buffer.BlockCopy(x, 0, p, i, 16);
                }
                Buffer.BlockCopy(p, 0, x, 0, 16);
                return(x);
            }
            // Get server Challenge.
            GXByteBuffer challenge = new GXByteBuffer();

            // Get shared secret
            if (settings.Authentication == Authentication.HighGMAC ||
                settings.Authentication == Authentication.HighECDSA)
            {
                challenge.Set(data);
            }
            else if (settings.Authentication == Authentication.HighSHA256)
            {
                challenge.Set(secret);
            }
            else
            {
                challenge.Set(data);
                challenge.Set(secret);
            }
            tmp = challenge.Array();
            if (settings.Authentication == Authentication.HighMD5)
            {
#if !WINDOWS_UWP
                using (MD5 md5Hash = MD5.Create())
                {
                    tmp = md5Hash.ComputeHash(tmp);
                    return(tmp);
                }
#endif
            }
            else if (settings.Authentication == Authentication.HighSHA1)
            {
#if !WINDOWS_UWP
                using (SHA1 sha = new SHA1CryptoServiceProvider())
                {
                    tmp = sha.ComputeHash(tmp);
                    return(tmp);
                }
#endif
            }
            else if (settings.Authentication == Authentication.HighSHA256)
            {
                //Windows UWP, IOS ad Android don't support this.
#if !WINDOWS_UWP && !__IOS__ && !__ANDROID__
                using (SHA256 sha = new SHA256CryptoServiceProvider())
                {
                    tmp = sha.ComputeHash(tmp);
                    return(tmp);
                }
#endif
            }
            else if (settings.Authentication == Authentication.HighGMAC)
            {
                //SC is always Security.Authentication.
                AesGcmParameter p = new AesGcmParameter(0, Security.Authentication,
                                                        cipher.SecuritySuite,
                                                        ic,
                                                        secret,
                                                        cipher.BlockCipherKey,
                                                        cipher.AuthenticationKey);
                p.Type = CountType.Tag;
                challenge.Clear();
                //Security suite is 0.
                challenge.SetUInt8((byte)Security.Authentication);
                challenge.SetUInt32((UInt32)p.InvocationCounter);
                challenge.Set(GXDLMSChippering.EncryptAesGcm(p, tmp));
                tmp = challenge.Array();
                return(tmp);
            }
            else if (settings.Authentication == Authentication.HighECDSA)
            {
                if (cipher.SigningKeyPair.Key == null)
                {
                    throw new ArgumentNullException("SigningKeyPair is not set.");
                }
                GXEcdsa      sig = new GXEcdsa(cipher.SigningKeyPair.Key);
                GXByteBuffer bb  = new GXByteBuffer();
                bb.Set(settings.Cipher.SystemTitle);
                bb.Set(settings.SourceSystemTitle);
                if (settings.IsServer)
                {
                    bb.Set(settings.CtoSChallenge);
                    bb.Set(settings.StoCChallenge);
                }
                else
                {
                    bb.Set(settings.StoCChallenge);
                    bb.Set(settings.CtoSChallenge);
                }
                data = sig.Sign(bb.Array());
            }
            return(data);
        }
Beispiel #12
0
        /// <summary>
        /// Convert message to XML.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TranslateBtn_Click(object sender, EventArgs e)
        {
            if (MessagePduTB.ReadOnly)
            {
                StatusLbl.Text = "Cancelling translate.";
                CancelTranslate.Set();
                return;
            }
            TranslateBtn.Checked  = true;
            MessagePduTB.ReadOnly = true;
            Follow       follow = (Follow)FollowmessagesCb.SelectedItem;
            ShowMessages show   = (ShowMessages)ShowCb.SelectedItem;

            MessageXmlTB.Text   = null;
            ProgressBar.Visible = true;
            object selectedInterface = InterfaceCb.SelectedItem;

            UpdateSecuritySettings();
            StatusLbl.Text = "Finding frames";
            GXByteBuffer bb = new GXByteBuffer();

            bb.Set(GXDLMSTranslator.HexToBytes(RemoveComments(string.Join(Environment.NewLine, MessagePduTB.Lines))));
            System.Threading.Tasks.Task.Run(async() =>
            {
                if (translator.BlockCipherKey != null)
                {
                    OnAppendMessage("BlockCipher key: " +
                                    GXDLMSTranslator.ToHex(translator.BlockCipherKey) + Environment.NewLine, Color.Green);
                }
                if (translator.AuthenticationKey != null)
                {
                    OnAppendMessage("Authentication Key:" +
                                    GXDLMSTranslator.ToHex(translator.AuthenticationKey) + Environment.NewLine, Color.Green);
                }
                StringBuilder sb = new StringBuilder();
                Security s       = translator.Security;
                int count        = 1;
                try
                {
                    translator.Clear();
                    translator.PduOnly = PduOnlyMnu.Checked;
                    GXByteBuffer pdu   = new GXByteBuffer();
                    UpdateProgress(0, 0);
                    UpdateMaxProgress(bb.Size, 0);
                    GXDLMSTranslatorMessage frame = new GXDLMSTranslatorMessage();
                    frame.Message = bb;
                    if (selectedInterface is string)
                    {
                        frame.InterfaceType = GXDLMSTranslator.GetDlmsFraming(bb);
                        BeginInvoke((Action)(() =>
                        {
                            InterfaceCb.SelectedItem = frame.InterfaceType;
                        }));
                    }
                    else
                    {
                        frame.InterfaceType = (InterfaceType)selectedInterface;
                    }
                    string last       = "";
                    int clientAddress = 0, serverAddress = 0;
                    while (translator.FindNextFrame(frame, pdu, clientAddress, serverAddress))
                    {
                        //Translate is cancelled.
                        if (CancelTranslate.WaitOne(1))
                        {
                            UpdateMaxProgress(0, 0);
                            BeginInvoke((Action)(() =>
                            {
                                MessagePduTB.ReadOnly = false;
                                TranslateBtn.Checked = false;
                            }));
                            CancelTranslate.Reset();
                            return;
                        }
                        int start = bb.Position;
                        UpdateProgress(start, count);
                        GXDLMSTranslatorMessage msg = new GXDLMSTranslatorMessage();
                        msg.Message = bb;
                        translator.MessageToXml(msg);
                        if (follow != Follow.None)
                        {
                            if ((follow & Follow.Client) != 0 && clientAddress == 0)
                            {
                                clientAddress = msg.SourceAddress;
                            }
                            if ((follow & Follow.Meter) != 0 && serverAddress == 0)
                            {
                                serverAddress = msg.TargetAddress;
                            }
                        }
                        //Remove duplicate messages.
                        if (RemoveDuplicatesMnu.Checked)
                        {
                            if (last == msg.Xml)
                            {
                                continue;
                            }
                        }
                        last = msg.Xml;
                        if (msg.Command == Command.Aarq)
                        {
                            if (msg.SystemTitle != null && msg.SystemTitle.Length == 8)
                            {
                                if (UpdateSystemTitle(this, "Current System title \"{0}\" is different in the parsed \"{1}\". Do you want to start using parsed one?",
                                                      msg.SystemTitle, translator.SystemTitle))
                                {
                                    translator.SystemTitle = msg.SystemTitle;
                                    BeginInvoke((Action)(() =>
                                    {
                                        Ciphering.SystemTitle = msg.SystemTitle;
                                    }));
                                }
                            }
                            if (msg.DedicatedKey != null && msg.DedicatedKey.Length == 16)
                            {
                                if (UpdateSystemTitle(this, "Current dedicated key \"{0}\" is different in the parsed \"{1}\". Do you want to start using parsed one?",
                                                      msg.DedicatedKey, translator.DedicatedKey))
                                {
                                    translator.DedicatedKey = msg.DedicatedKey;
                                    BeginInvoke((Action)(() =>
                                    {
                                        Ciphering.DedicatedKey = msg.DedicatedKey;
                                    }));
                                }
                            }
                        }
                        if (msg.Command == Command.Aare && msg.SystemTitle != null && msg.SystemTitle.Length == 8)
                        {
                            if (UpdateSystemTitle(this, "Current Server System title \"{0}\" is different in the parsed \"{1}\". Do you want to start using parsed one?",
                                                  msg.SystemTitle, translator.ServerSystemTitle))
                            {
                                translator.ServerSystemTitle = msg.SystemTitle;
                                BeginInvoke((Action)(() =>
                                {
                                    Ciphering.ServerSystemTitle = msg.SystemTitle;
                                }));
                            }
                        }
                        if (show != ShowMessages.All)
                        {
                            switch (msg.Command)
                            {
                            case Command.None:
                                break;

                            case Command.InitiateRequest:
                            case Command.ReadRequest:
                            case Command.WriteRequest:
                            case Command.GetRequest:
                            case Command.SetRequest:
                            case Command.MethodRequest:
                            case Command.Snrm:
                            case Command.Aarq:
                            case Command.ReleaseRequest:
                            case Command.DisconnectRequest:
                            case Command.AccessRequest:
                            case Command.GloGetRequest:
                            case Command.GloSetRequest:
                            case Command.GloMethodRequest:
                            case Command.GloInitiateRequest:
                            case Command.GloReadRequest:
                            case Command.GloWriteRequest:
                            case Command.DedInitiateRequest:
                            case Command.DedReadRequest:
                            case Command.DedWriteRequest:
                            case Command.DedGetRequest:
                            case Command.DedSetRequest:
                            case Command.DedMethodRequest:
                            case Command.GatewayRequest:
                                if (show == ShowMessages.Received)
                                {
                                    continue;
                                }
                                break;

                            case Command.InitiateResponse:
                            case Command.ReadResponse:
                            case Command.WriteResponse:
                            case Command.GetResponse:
                            case Command.SetResponse:
                            case Command.MethodResponse:
                            case Command.Ua:
                            case Command.Aare:
                            case Command.ReleaseResponse:
                            case Command.AccessResponse:
                            case Command.GloGetResponse:
                            case Command.GloSetResponse:
                            case Command.GloMethodResponse:
                            case Command.GloInitiateResponse:
                            case Command.GloReadResponse:
                            case Command.GloWriteResponse:
                            case Command.DedInitiateResponse:
                            case Command.DedReadResponse:
                            case Command.DedWriteResponse:
                            case Command.DedGetResponse:
                            case Command.DedSetResponse:
                            case Command.DedMethodResponse:
                            case Command.GatewayResponse:
                                if (show == ShowMessages.Sent)
                                {
                                    continue;
                                }
                                break;

                            case Command.DisconnectMode:
                            case Command.UnacceptableFrame:
                            case Command.ConfirmedServiceError:
                            case Command.ExceptionResponse:
                            case Command.GeneralBlockTransfer:
                            case Command.DataNotification:
                            case Command.GloEventNotification:
                            case Command.GloConfirmedServiceError:
                            case Command.GeneralGloCiphering:
                            case Command.GeneralDedCiphering:
                            case Command.GeneralCiphering:
                            case Command.GeneralSigning:
                            case Command.InformationReport:
                            case Command.EventNotification:
                            case Command.DedConfirmedServiceError:
                            case Command.DedUnconfirmedWriteRequest:
                            case Command.DedInformationReport:
                            case Command.DedEventNotification:
                                break;
                            }
                        }
                        if (Properties.Settings.Default.TranslatorFrame)
                        {
                            if (Properties.Settings.Default.FrameNumber)
                            {
                                sb.Append(count + ": ");
                            }
                            sb.AppendLine(bb.ToHex(true, start, bb.Position - start));
                        }
                        if (Properties.Settings.Default.TranslatorXml)
                        {
                            sb.Append(msg.Xml);
                        }
                        if (msg.Exception != null)
                        {
                            ++count;
                            OnAppendMessage(sb.ToString(), Color.Red);
                        }
                        else if (show != ShowMessages.Failed)
                        {
                            ++count;
                            OnAppendMessage(sb.ToString());
                        }
                        sb.Clear();
                        pdu.Clear();
                    }
                    OnAppendMessage(sb.ToString());
                    translator.Security = s;
                    //Update UI.
                    await System.Threading.Tasks.Task.Delay(1);
                }
                catch (Exception ex)
                {
                    translator.Security = s;
                    OnAppendMessage(sb.ToString());
                    OnAppendMessage(Environment.NewLine);
                    OnAppendMessage(bb.RemainingHexString(true));
                    MessageBox.Show(ex.Message);
                }
                //Count starts from 1.
                UpdateMaxProgress(0, count - 1);
                BeginInvoke((Action)(() =>
                {
                    MessagePduTB.ReadOnly = false;
                    TranslateBtn.Checked = false;
                }));
            });
        }