Version 3.0.290

This commit is contained in:
Oliver Hauff 2022-04-10 17:38:34 +02:00
parent af3c20ea1c
commit ad3cdbcadf
231 changed files with 14555 additions and 7798 deletions

View file

@ -18,12 +18,33 @@ namespace TINK.Services.BluetoothLock.BLE
/// <summary> Manages ILockIt- Locks.</summary>
public abstract class LockItByScanServiceBase : LockItServiceBase
{
/// <summary> Service to manage bluetooth stack. </summary>
private IBluetoothLE BluetoothService { get; }
/// <summary> Returns true if location permission is required (Android) but on given. </summary>
private Func<Task<bool>> IsLocationPermissionMissingDelegate {get; }
/// <summary> Returns true if location service is required (Android) and off. </summary>
private Func<bool> IsLocationRequiredAndOffDelegate { get; }
private Func<IDevice, LockInfoAuthTdo, IAdapter, Task<LockItBase>> AuthenticateDelegate { get; set; }
public LockItByScanServiceBase(
ICipher cipher,
Func<IDevice, LockInfoAuthTdo, IAdapter, Task<LockItBase>> authenticateDelegate) : base(cipher)
Func<IDevice, LockInfoAuthTdo, IAdapter, Task<LockItBase>> authenticateDelegate,
IBluetoothLE bluetoothLE,
Func<Task<bool>> isLocationPermissionMissingDelegate,
Func<bool> isLocationRequiredAndOffDelegate) : base(cipher)
{
BluetoothService = bluetoothLE
?? throw new ArgumentException($"Can not instantiate {nameof(LockItByScanServiceBase)}- object. No bluetooth service available.");
IsLocationPermissionMissingDelegate = isLocationPermissionMissingDelegate
?? throw new ArgumentException($"Can not instantiate {nameof(LockItByScanServiceBase)}- object. No location permission missing delegate available.");
IsLocationRequiredAndOffDelegate = isLocationRequiredAndOffDelegate
?? throw new ArgumentException($"Can not instantiate {nameof(LockItByScanServiceBase)}- object. No location .");
AuthenticateDelegate = authenticateDelegate;
}
@ -63,6 +84,28 @@ namespace TINK.Services.BluetoothLock.BLE
if (bleDevice == null)
{
// Try to check why lock was not found.
var bluetoothState = await BluetoothService.GetBluetoothState();
switch (bluetoothState)
{
case BluetoothState.On:
break;
case BluetoothState.Off:
throw new ConnectBluetoothNotOnException();
default:
throw new ConnectBluetoothNotOnException(bluetoothState);
}
if (await IsLocationPermissionMissingDelegate())
{
throw new ConnectLocationPermissionMissingException();
}
if (IsLocationRequiredAndOffDelegate())
{
throw new ConnectLocationOffException();
}
Log.ForContext<LockItByScanServiceBase>().Debug("Can not connect because device was not discovered.");
throw new OutOfReachException();

View file

@ -1,11 +1,17 @@
using TINK.Model.Device;
using Plugin.BLE.Abstractions.Contracts;
using System;
using System.Threading.Tasks;
using TINK.Model.Device;
namespace TINK.Services.BluetoothLock.BLE
{
public class LockItByScanServiceEventBased : LockItByScanServiceBase, ILocksService
{
public LockItByScanServiceEventBased(ICipher cipher) : base(
public LockItByScanServiceEventBased(ICipher cipher, IBluetoothLE bluetoothLE, Func<Task<bool>> isLocationPermissionMissingDelegate, Func<bool> isLocationRequiredAndOffDelegate) : base(
cipher,
(bleDevice, authInfo, adapter) => LockItEventBased.Authenticate(bleDevice, authInfo, adapter, cipher)) { }
(bleDevice, authInfo, adapter) => LockItEventBased.Authenticate(bleDevice, authInfo, adapter, cipher),
bluetoothLE,
isLocationPermissionMissingDelegate,
isLocationRequiredAndOffDelegate) { }
}
}

View file

@ -1,11 +1,17 @@
using TINK.Model.Device;
using Plugin.BLE.Abstractions.Contracts;
using System;
using System.Threading.Tasks;
using TINK.Model.Device;
namespace TINK.Services.BluetoothLock.BLE
{
public class LockItByScanServicePolling : LockItByScanServiceBase, ILocksService
{
public LockItByScanServicePolling(ICipher cipher) : base(
public LockItByScanServicePolling(ICipher cipher, IBluetoothLE bluetoothLE, Func<Task<bool>> isLocationPermissionMissingDelegate, Func<bool> isLocationRequiredAndOffDelegate) : base(
cipher,
(bleDevice, authInfo, adapter) => LockItPolling.Authenticate(bleDevice, authInfo, adapter, cipher)) { }
(bleDevice, authInfo, adapter) => LockItPolling.Authenticate(bleDevice, authInfo, adapter, cipher),
bluetoothLE,
isLocationPermissionMissingDelegate,
isLocationRequiredAndOffDelegate) { }
}
}

View file

@ -164,7 +164,7 @@ namespace TINK.Services.BluetoothLock.BLE
if (lockIt == null)
{
// Nothing to do
return LockingState.Disconnected;
return LockingState.UnknownDisconnected;
}
DeviceList.Remove(lockIt);
@ -172,11 +172,11 @@ namespace TINK.Services.BluetoothLock.BLE
if (lockIt.GetDeviceState() == DeviceState.Disconnected)
{
// Nothing to do
return LockingState.Disconnected;
return LockingState.UnknownDisconnected;
}
await lockIt.Disconnect();
return LockingState.Disconnected;
return LockingState.UnknownDisconnected;
}
}
}

View file

@ -0,0 +1,41 @@
using Plugin.BLE.Abstractions.Contracts;
using System;
using System.Threading.Tasks;
namespace TINK.Services.BluetoothLock
{
public static class StateChecker
{
/// <summary>
/// Get current bluetooth state
/// </summary>
/// <remarks>See https://github.com/xabre/xamarin-bluetooth-le/issues/112#issuecomment-380994887.</remarks>
/// <param name="ble">Crossplatform bluetooth implementation object</param>
/// <returns>BluetoothState</returns>
public static Task<BluetoothState> GetBluetoothState(this IBluetoothLE ble)
{
var tcs = new TaskCompletionSource<BluetoothState>();
if (ble.State != BluetoothState.Unknown)
{
// If we can detect state out of box just returning in
tcs.SetResult(ble.State);
}
else
{
// Otherwise let's setup dynamic event handler and wait for first state update
EventHandler<Plugin.BLE.Abstractions.EventArgs.BluetoothStateChangedArgs> handler = null;
handler = (o, e) =>
{
ble.StateChanged -= handler;
// and return it as our state
// we can have an 'Unknown' check here, but in normal situation it should never occur
tcs.SetResult(e.NewState);
};
ble.StateChanged += handler;
}
return tcs.Task;
}
}
}