using CoreScanner; using SafeBagDE70.API; using Serilog; using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Automation; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; using System.Xml; using System.Xml.Linq; namespace SafeBagDE70 { /// /// Interaction logic for WelcomeWindow.xaml /// public partial class WelcomeUC : UserControl { public string? PinCode = null; public bool IsAuthenticated = false; public CCoreScannerClass? cCoreScannerClass=null; public WelcomeUC() { InitializeComponent(); InitQRCodeScanner(); Loaded += WelcomeUC_Loaded; } private void WelcomeUC_Loaded(object sender, RoutedEventArgs e) { AppData.IsAuthenticated = false; txtVersion.Text = "Version " + AppData.CurrentVersion; } public void Init() { AppData.IsAuthenticated = false; AppData.CurrentCustomerAccount = null; lblPincodeError.Content = ""; PinCodeBox.Text = ""; QrCodePanel.Visibility = Visibility.Collapsed; } public void ShowLogin() { gridInfor.Visibility = Visibility.Collapsed; gridMain.Visibility = Visibility.Visible; btnQRCodeLogin.IsEnabled = true; } public void ShowInfor(string strMessage) { gridInfor.Visibility = Visibility.Visible; gridMain.Visibility = Visibility.Collapsed; txtInfor.Text = strMessage; txtInfor.Foreground = new SolidColorBrush(Colors.DarkRed); } private void LoginButton_Click(object sender, RoutedEventArgs e) { Log.Information("Login sử dụng PINCODE"); string pin = PinCodeBox.Text; if (ValidatePin(pin)) { PinCode=PinCodeBox.Text.ToString(); if (AppData.customerAccounts != null) { CustomerAccount? cca = null; if (PinCode != null) { var strPincode = PinCode.ToUpper(); cca = AppData.customerAccounts.Where(x => x.PINCode == strPincode).FirstOrDefault(); } if (cca != null) { AppData.IsAuthenticated=true; AppData.CurrentCustomerAccount=cca; AppData.CreateNewTransactionCode(); ((MainWindow)Application.Current.MainWindow).ShowDepositScreen(); //DialogResult = true; //this.Close(); var str = "Login Pincode thành công"; Log.Information(str); } else { var str = "PINCODE không đúng, vui lòng thử lại"; Log.Information(str); lblPincodeError.Content =str ; } } } else { MessageBox.Show("Invalid PIN. Please try again."); } } private void ForgotPin_Click(object sender, RoutedEventArgs e) { MessageBox.Show("Forgot PIN clicked."); } private void Help_Click(object sender, RoutedEventArgs e) { MessageBox.Show("Phiên bản đang sử dụng là phiên bản mới nhất"); } private bool ValidatePin(string pin) { return true; } private async void PinCodeButton_Click(object sender, RoutedEventArgs e) { try { QrCodePanel.Visibility = Visibility.Collapsed; PinCodePanel.Visibility = Visibility.Visible; btnQRCodeLogin.IsEnabled = true; cCoreScannerClass.BarcodeEvent -= new _ICoreScannerEvents_BarcodeEventEventHandler(OnBarcodeEvent); } catch { } } private void btnQRCodeLogin_Click(object sender, RoutedEventArgs e) { PinCodePanel.Visibility = Visibility.Collapsed; QrCodePanel.Visibility=Visibility.Visible; btnQRCodeLogin.IsEnabled = false; cCoreScannerClass.BarcodeEvent -= new _ICoreScannerEvents_BarcodeEventEventHandler(OnBarcodeEvent); cCoreScannerClass.BarcodeEvent += new _ICoreScannerEvents_BarcodeEventEventHandler(OnBarcodeEvent); } public void InitQRCodeScanner() { try { // Instantiate CoreScanner Class cCoreScannerClass = new CCoreScannerClass(); // Call Open API short[] scannerTypes = new short[1]; // Scanner Types you are interested in scannerTypes[0] = 1; // 1 for all scanner types short numberOfScannerTypes = 1; // Size of the scannerTypes array int status; // Extended API return code cCoreScannerClass.Open(0, scannerTypes, numberOfScannerTypes, out status); short numberOfScanners; // Number of scanners expect to be used int[] connectedScannerIDList = new int[255]; // List of scanner IDs to be returned string outXML; cCoreScannerClass.GetScanners(out numberOfScanners, connectedScannerIDList, out outXML, out status); if (numberOfScanners > 0) { // Let's subscribe for events int opcode = 1001; // Method for Subscribe events //string outXML; // XML Output string inXML = "" + "" + "1" + // Number of events you want to subscribe "1" + // Comma separated event IDs "" + ""; cCoreScannerClass.ExecCommand(opcode, ref inXML, out outXML, out status); } else { Log.Information("Không tìm thấy đầu đọc QR"); AppData.DeviceStatus.OtherError = 1; AppData.DeviceStatus.Description = "Không tìm thấy đầu đọc QR"; APIModels.SendEvent(AppData.DeviceStatus); } } catch (Exception exp) { Console.WriteLine("Something wrong please check... " + exp.Message); } } private void OnBarcodeEvent(short eventType, ref string pscanData) { var str = "Login QRCODE thành công"; Log.Information(str); string xmlString = pscanData; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xmlString); XmlNode rawDataNode = xmlDoc.SelectSingleNode("//datalabel"); string rawDataHex = rawDataNode.InnerText.Trim(); var QRCodeContentFull = HexStringToString(rawDataHex); string? CustomerID = null; VerifyQRCode(QRCodeContentFull, out CustomerID); if(CustomerID!=null) { this.Dispatcher.Invoke(() => { if (AppData.customerAccounts != null) { CustomerAccount? cca = null; if (CustomerID != null) { cca = AppData.customerAccounts.Where(x => x.QRCode == CustomerID).FirstOrDefault(); } if (cca != null) { cCoreScannerClass.BarcodeEvent -= new _ICoreScannerEvents_BarcodeEventEventHandler(OnBarcodeEvent); AppData.IsAuthenticated = true; AppData.CurrentCustomerAccount = cca; AppData.CreateNewTransactionCode(); ((MainWindow)Application.Current.MainWindow).ShowDepositScreen(); str = "Login QRCode thành công"; Log.Information(str); } else { str = "QRCODE không đúng, vui lòng thử lại"; Log.Information(str); lblQRcodeError.Content = str; } } }); } Dispatcher.Invoke(() => { btnQRCodeLogin.IsEnabled = true; }); } private void VerifyQRCode(string decodedString,out string? ConsumerID) { ConsumerID = null; try { var qrCodeData = decodedString; // Extract the CRC from the QR code string string extractedCRC = qrCodeData.Substring(qrCodeData.Length - 4); // Get the data without the CRC part string dataWithoutCRC = qrCodeData.Substring(0, qrCodeData.Length - 8); // Calculate CRC string calculatedCRC = CalculateCRC(dataWithoutCRC); // Verify CRC if (extractedCRC.Equals(calculatedCRC, StringComparison.OrdinalIgnoreCase)) { this.Dispatcher.Invoke(() => { lblQRcodeError.Content = "CRC is valid."; }); Dictionary fields = ExtractFields(qrCodeData); foreach (var field in fields) { Console.WriteLine($"ID: {field.Key}, Length: {field.Value.Length}, Value: {field.Value.Value}"); } var fields2 = ExtractFields(fields["38"].Value); var fields3 = ExtractFields(fields2["01"].Value); ConsumerID = fields3["01"].Value; } else { //this.Dispatcher.Invoke(() => //{ // lblQRcodeError.Content = "CRC is invalid."; //}); } } catch (Exception e) { this.Dispatcher.Invoke(() => { lblQRcodeError.Content = e.Message; }); } } Dictionary ExtractFields(string qrCodeData) { Dictionary fields = new Dictionary(); int currentIndex = 0; while (currentIndex < qrCodeData.Length) { // Extract ID string id = qrCodeData.Substring(currentIndex, 2); currentIndex += 2; // Extract Length int length = int.Parse(qrCodeData.Substring(currentIndex, 2)); currentIndex += 2; // Extract Value string value = qrCodeData.Substring(currentIndex, length); currentIndex += length; // Add the field to the dictionary fields[id] = (length, value); } return fields; } string CalculateCRC(string data) { ushort polynomial = 0x1021; // CRC-16-CCITT polynomial ushort crc = 0xFFFF; // Initial value // Convert the string to a byte array byte[] bytes = Encoding.ASCII.GetBytes(data + "6304"); // Append "6304" for CRC calculation as per standard foreach (byte b in bytes) { crc ^= (ushort)(b << 8); for (int i = 0; i < 8; i++) { if ((crc & 0x8000) != 0) { crc = (ushort)((crc << 1) ^ polynomial); } else { crc <<= 1; } } } // Ensure CRC is a 16-bit value crc &= 0xFFFF; // Return CRC as a hexadecimal string return crc.ToString("X4"); } static string HexStringToString(string hexString) { string[] hexValues = hexString.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries); byte[] bytes = new byte[hexValues.Length]; for (int i = 0; i < hexValues.Length; i++) { bytes[i] = Convert.ToByte(hexValues[i], 16); } return Encoding.ASCII.GetString(bytes); } } }