borepin/Borepin/Borepin/PageModel/CreateCardPageModel.cs
2023-02-11 14:54:55 +01:00

442 lines
14 KiB
C#

using Borepin.Base;
using Prism.Commands;
using Prism.Navigation;
using System.Windows.Input;
using FabAccessAPI.Schema;
using Prism.Services;
using Borepin.Service;
using System.Threading.Tasks;
using Borepin.Base.Exceptions;
using NFC.Interfaces;
using System.Collections.Generic;
using Borepin.Model;
using Xamarin.Forms;
using System;
using Borepin.Service.ErrorMessage;
using System.Linq;
namespace Borepin.PageModel
{
public class CreateCardPageModel : ConnectionModelBase
{
#region Private Fields
private CardConfig _CardConfig;
private User _User;
private INFCService _NFCService;
private IErrorMessageService _ErrorMessageService;
private KeyTypes _ScanKeyType = KeyTypes.NONE;
private KeyTypes _ScanedKeyType = KeyTypes.NONE;
#endregion
#region Contructors
public CreateCardPageModel(INavigationService navigationService, IPageDialogService pageDialogService, IAPIService apiService, INFCService nfcService, IErrorMessageService errorMessageService) : base(navigationService, pageDialogService, apiService)
{
_NFCService = nfcService;
_ErrorMessageService = errorMessageService;
_CardConfig= new CardConfig();
CreateCardCommand = new DelegateCommand(CreateCardCommandExecute);
ScanPICCKeyCommand = new DelegateCommand(ScanPICCKeyCommandExecute);
ScanAPPKeyCommand = new DelegateCommand(ScanAPPKeyCommandExecute);
RandomAPPKeyCommand = new DelegateCommand(RandomAPPKeyCommandExecute);
RefreshCommand = new DelegateCommand(async () => await RefreshCommandExecute().ConfigureAwait(true));
}
#endregion
#region Data
public override Task LoadInstance(object instance)
{
if (instance is string)
{
_CardConfig.UserID = instance as string;
}
else if (instance is CardConfig)
{
_CardConfig = instance as CardConfig;
}
else if (instance is KeyScan)
{
KeyScan keyScan = instance as KeyScan;
_CardConfig = keyScan.CardConfig;
_ScanedKeyType = keyScan.KeyType;
_ScanKeyType = KeyTypes.NONE;
}
else
{
throw new InstanceIncorrectException();
}
return Task.CompletedTask;
}
public override Task LoadFromParameters(INavigationParameters parameters)
{
if (parameters.ContainsKey("result") && string.Equals((string)parameters["result"], "scanned", StringComparison.Ordinal) && parameters.ContainsKey("value"))
{
switch(_ScanedKeyType)
{
case (KeyTypes.PICC):
try
{
_CardConfig.PICCKey = _CardConfig.ConvertFromString(PICCKey);
}
catch
{
_CardConfig.PICCKey = _CardConfig.GenerateEmptyKey();
}
_CardConfig.PICCKey = _CardConfig.ConvertFromString((string)parameters["value"]);
PICCKey = _CardConfig.ConvertToString(_CardConfig.PICCKey);
break;
case (KeyTypes.APP):
try
{
_CardConfig.APPKey = _CardConfig.ConvertFromString((string)parameters["value"]);
}
catch
{
_CardConfig.APPKey = _CardConfig.GenerateEmptyKey();
}
APPKey = _CardConfig.ConvertToString(_CardConfig.APPKey);
break;
}
}
return Task.CompletedTask;
}
public override async Task LoadAPIData()
{
_User = (await _API.Session.UserSystem.Search.GetUserByName(_CardConfig.UserID).ConfigureAwait(false)).Just;
ReaderIDs = await Task.Run(() =>
{
return _NFCService.GetReaderIDs();
}).ConfigureAwait(false);
// Delay to sync with XAML Picker Item Source
await Task.Delay(100).ConfigureAwait(false);
if (ReaderIDs.Count > 0)
{
ReaderID = ReaderIDs[0];
}
PICCKey = _CardConfig.ConvertToString(_CardConfig.PICCKey);
APPKey = _CardConfig.ConvertToString(_CardConfig.APPKey);
FormatCard = _CardConfig.DoFormat;
}
public override Task<object> CreateInstance()
{
try
{
_CardConfig.PICCKey = _CardConfig.ConvertFromString(PICCKey);
}
catch
{
_CardConfig.PICCKey = _CardConfig.GenerateEmptyKey();
}
try
{
_CardConfig.APPKey = _CardConfig.ConvertFromString(APPKey);
}
catch
{
_CardConfig.APPKey = _CardConfig.GenerateEmptyKey();
}
_CardConfig.DoFormat = FormatCard;
switch(_ScanKeyType)
{
case (KeyTypes.PICC):
return Task.FromResult<object>(new KeyScan(_CardConfig, KeyTypes.PICC));
case (KeyTypes.APP):
return Task.FromResult<object>(new KeyScan(_CardConfig, KeyTypes.APP));
case (KeyTypes.NONE):
default:
return Task.FromResult<object>(_CardConfig);
}
}
#endregion
#region Fields
private IList<string> _ReaderIDs;
public IList<string> ReaderIDs
{
get => _ReaderIDs;
set => SetProperty(ref _ReaderIDs, value);
}
private string _ReaderID;
public string ReaderID
{
get => _ReaderID;
set => SetProperty(ref _ReaderID, value);
}
private string _PICCKey;
public string PICCKey
{
get => _PICCKey;
set => SetProperty(ref _PICCKey, value);
}
private string _APPKey;
public string APPKey
{
get => _APPKey;
set => SetProperty(ref _APPKey, value);
}
private bool _FormatCard;
public bool FormatCard
{
get => _FormatCard;
set => SetProperty(ref _FormatCard, value);
}
#endregion
#region Commands
private ICommand _RefreshCommand;
public ICommand RefreshCommand
{
get => _RefreshCommand;
set => SetProperty(ref _RefreshCommand, value);
}
public async Task RefreshCommandExecute()
{
if (_API.IsConnected)
{
try
{
await LoadAPIData().ConfigureAwait(true);
}
catch (System.Exception)
{
// TODO
}
}
}
private ICommand _CreateCardCommand;
public ICommand CreateCardCommand
{
get => _CreateCardCommand;
set => SetProperty(ref _CreateCardCommand, value);
}
public async void CreateCardCommandExecute()
{
IsBusy = true;
if(ReaderID == null)
{
Device.BeginInvokeOnMainThread(async () =>
{
await _PageDialogService.DisplayAlertAsync("NFC Error", "No Card Reader selected", Resources.Text.TextResource.OK).ConfigureAwait(false);
IsBusy = false;
});
return;
}
try
{
_CardConfig.PICCKey = _CardConfig.ConvertFromString(PICCKey);
}
catch
{
Device.BeginInvokeOnMainThread(async () =>
{
await _PageDialogService.DisplayAlertAsync("NFC Error", "PICC Key invalid", Resources.Text.TextResource.OK).ConfigureAwait(false);
IsBusy = false;
});
return;
}
try
{
_CardConfig.APPKey = _CardConfig.ConvertFromString(APPKey);
}
catch
{
Device.BeginInvokeOnMainThread(async () =>
{
await _PageDialogService.DisplayAlertAsync("NFC Error", "APP Key invalid", Resources.Text.TextResource.OK).ConfigureAwait(false);
IsBusy = false;
});
return;
}
_CardConfig.DoFormat = FormatCard;
_CardConfig.CardToken = (await _User.CardDESFireEV2.GenCardToken().ConfigureAwait(false)).ToArray();
_CardConfig.SpaceInfo = (await _User.CardDESFireEV2.GetSpaceInfo().ConfigureAwait(false)).ToArray();
_CardConfig.MetaInfo = (await _User.CardDESFireEV2.GetMetaInfo().ConfigureAwait(false)).ToArray();
FabFireCard fabFireCard = new FabFireCard(_NFCService, _ErrorMessageService);
try
{
if(FormatCard)
{
fabFireCard.FormatCard(ReaderID, _CardConfig);
}
}
catch(Exception exception)
{
Device.BeginInvokeOnMainThread(async () =>
{
await _PageDialogService.DisplayAlertAsync("NFC Error", "Format failed", Resources.Text.TextResource.OK).ConfigureAwait(false);
IsBusy = false;
});
_NFCService.Disconnect();
return;
}
try
{
byte[] key = fabFireCard.CreateCard(ReaderID, _CardConfig);
await _User.CardDESFireEV2.Bind(_CardConfig.CardToken, new List<byte>(key)).ConfigureAwait(false);
}
catch(Exception excpetion)
{
Device.BeginInvokeOnMainThread(async () =>
{
await _PageDialogService.DisplayAlertAsync("NFC Error", "Card Creation failed", Resources.Text.TextResource.OK).ConfigureAwait(false);
IsBusy = false;
});
_NFCService.Disconnect();
return;
}
Device.BeginInvokeOnMainThread(async () =>
{
INavigationResult result = await _NavigationService.GoBackAsync().ConfigureAwait(false);
});
IsBusy = false;
}
#region PICCKey
private ICommand _ScanPICCKeyCommand;
public ICommand ScanPICCKeyCommand
{
get => _ScanPICCKeyCommand;
set => SetProperty(ref _ScanPICCKeyCommand, value);
}
public void ScanPICCKeyCommandExecute()
{
_ScanKeyType = KeyTypes.PICC;
Device.BeginInvokeOnMainThread(async () =>
{
INavigationResult result = await _NavigationService.NavigateAsync("ScanPage").ConfigureAwait(false);
if (result.Exception != null)
{
Log.Fatal(result.Exception, "Navigating failed");
}
});
}
private ICommand _RandomPICCKeyCommand;
public ICommand RandomPICCKeyCommand
{
get => _RandomPICCKeyCommand;
set => SetProperty(ref _RandomPICCKeyCommand, value);
}
public void RandomPICCKeyCommandExecute()
{
_CardConfig.PICCKey = _CardConfig.GenerateRandomKey();
PICCKey = _CardConfig.ConvertToString(_CardConfig.PICCKey);
}
private ICommand _ExportPICCKeyCommand;
public ICommand ExportPICCKeyCommand
{
get => _ExportPICCKeyCommand;
set => SetProperty(ref _ExportPICCKeyCommand, value);
}
public async void ExportPICCKeyCommandExecute()
{
IsBusy = true;
await Task.Delay(1000).ConfigureAwait(false);
IsBusy = false;
}
#endregion
#region APPKey
private ICommand _ScanAPPKeyCommand;
public ICommand ScanAPPKeyCommand
{
get => _ScanAPPKeyCommand;
set => SetProperty(ref _ScanAPPKeyCommand, value);
}
public void ScanAPPKeyCommandExecute()
{
_ScanKeyType = KeyTypes.APP;
Device.BeginInvokeOnMainThread(async () =>
{
INavigationResult result = await _NavigationService.NavigateAsync("ScanPage").ConfigureAwait(false);
if (result.Exception != null)
{
Log.Fatal(result.Exception, "Navigating failed");
}
});
}
private ICommand _RandomAPPKeyCommand;
public ICommand RandomAPPKeyCommand
{
get => _RandomAPPKeyCommand;
set => SetProperty(ref _RandomAPPKeyCommand, value);
}
public void RandomAPPKeyCommandExecute()
{
_CardConfig.APPKey = _CardConfig.GenerateRandomKey();
APPKey = _CardConfig.ConvertToString(_CardConfig.APPKey);
}
private ICommand _ExportAPPKeyCommand;
public ICommand ExportAPPKeyCommand
{
get => _ExportAPPKeyCommand;
set => SetProperty(ref _ExportAPPKeyCommand, value);
}
public async void ExportAPPKeyCommandExecute()
{
IsBusy = true;
await Task.Delay(1000).ConfigureAwait(false);
IsBusy = false;
}
#endregion
#endregion
}
}