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(); } } }
internal static byte[] Decrypt(AesGcmParameter p, GXByteBuffer data) { byte[] tmp = GXDLMSChippering.DecryptAesGcm(p, data); data.Clear(); data.Set(tmp); return(tmp); }
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); }
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); } }
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; }
///<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); } }
///<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; }
///<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); }
/// <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; })); }); }