345 lines
12 KiB
Plaintext
345 lines
12 KiB
Plaintext
using CoreScanner;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
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;
|
|
|
|
namespace SafeBagDE70
|
|
{
|
|
/// <summary>
|
|
/// Interaction logic for WelcomeWindow.xaml
|
|
/// </summary>
|
|
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 = "";
|
|
}
|
|
|
|
private void LoginButton_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
|
|
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.GetNewTransactionCode();
|
|
AppData.GetNewTransactionCode();
|
|
((MainWindow)Application.Current.MainWindow).ShowDepositScreen();
|
|
//DialogResult = true;
|
|
//this.Close();
|
|
}
|
|
else
|
|
{
|
|
lblPincodeError.Content = "PINCODE không đúng, vui lòng thử lại";
|
|
}
|
|
}
|
|
}
|
|
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)
|
|
{
|
|
//var onScreenKeyboardProcess = new ProcessStartInfo("osk.exe")
|
|
//{
|
|
// UseShellExecute = true
|
|
//};
|
|
try
|
|
{
|
|
//var progFiles = @"C:\Program Files\Common Files\Microsoft Shared\ink";
|
|
//var keyboardPath = System.IO.Path.Combine(progFiles, "TabTip.exe");
|
|
//Process.Start(keyboardPath);
|
|
// AutomationElement.FromHandle(-1);
|
|
|
|
// string keyboardPath = @"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe";
|
|
// Process.Start(keyboardPath);
|
|
//await Launcher.LaunchUriAsync(new Uri("ms-inputapp://"));
|
|
|
|
//var onScreenKeyboardProcess = new ProcessStartInfo(@"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe")
|
|
//{
|
|
// UseShellExecute = true
|
|
//};
|
|
//Process.Start(onScreenKeyboardProcess);
|
|
|
|
QrCodePanel.Visibility = Visibility.Collapsed;
|
|
PinCodePanel.Visibility = Visibility.Visible;
|
|
|
|
|
|
cCoreScannerClass.BarcodeEvent -= new _ICoreScannerEvents_BarcodeEventEventHandler(OnBarcodeEvent);
|
|
}
|
|
catch {
|
|
|
|
}
|
|
|
|
}
|
|
private void btnQRCodeLogin_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
PinCodePanel.Visibility = Visibility.Collapsed;
|
|
QrCodePanel.Visibility=Visibility.Visible;
|
|
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);
|
|
|
|
// Subscribe for barcode events in cCoreScannerClass
|
|
|
|
|
|
// Let's subscribe for events
|
|
int opcode = 1001; // Method for Subscribe events
|
|
string outXML; // XML Output
|
|
string inXML = "<inArgs>" +
|
|
"<cmdArgs>" +
|
|
"<arg-int>1</arg-int>" + // Number of events you want to subscribe
|
|
"<arg-int>1</arg-int>" + // Comma separated event IDs
|
|
"</cmdArgs>" +
|
|
"</inArgs>";
|
|
|
|
cCoreScannerClass.ExecCommand(opcode, ref inXML, out outXML, out status);
|
|
}
|
|
catch (Exception exp)
|
|
{
|
|
Console.WriteLine("Something wrong please check... " + exp.Message);
|
|
}
|
|
}
|
|
private void OnBarcodeEvent(short eventType, ref string pscanData)
|
|
{
|
|
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.GetNewTransactionCode();
|
|
((MainWindow)Application.Current.MainWindow).ShowDepositScreen();
|
|
}
|
|
else
|
|
{
|
|
lblQRcodeError.Content = "QRCODE không đúng, vui lòng thử lại";
|
|
}
|
|
}
|
|
|
|
});
|
|
}
|
|
|
|
}
|
|
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<string, (int Length, string Value)> 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<string, (int Length, string Value)> ExtractFields(string qrCodeData)
|
|
{
|
|
Dictionary<string, (int Length, string Value)> fields = new Dictionary<string, (int Length, string Value)>();
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|