using System; using System.Runtime.Serialization; using Newtonsoft.Json; using TINK.Model.Connector; namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock { /// Locking states. public enum LockingState { /// App is not connected to lock. UnknownDisconnected, /// Lock might be open, closed or something in between. /// /// Under certain circumstances lock reports/ is known to be in this state (genuine ILOCKIT locking state LockitLockingState.Unknown). /// Example: If bold is blocked it might happen that opening or closing lock leads to state unknown, i.e. might be open, closed or inbetween. /// UnknownFromHardwareError, /// Lock is closed. Closed, /// Lock is open. Open } [DataContract] public class LockInfo : ILockInfo, IEquatable { /// Identification number of bluetooth lock, 6-digits, second part of advertisement name. [DataMember] public int Id { get; private set; } = TextToLockItTypeHelper.INVALIDLOCKID; /// Identification GUID of bluetooth lock. [DataMember] public Guid Guid { get; private set; } = TextToLockItTypeHelper.INVALIDLOCKGUID; [DataMember] public byte[] UserKey { get; private set; } [DataMember] public byte[] AdminKey { get; private set; } [DataMember] public byte[] Seed { get; private set; } /// Locking state of bluetooth lock. [DataMember] public LockingState State { get; private set; } = LockingState.UnknownDisconnected; public bool IsIdValid => Id != TextToLockItTypeHelper.INVALIDLOCKID; public bool IsGuidValid => Guid != TextToLockItTypeHelper.INVALIDLOCKGUID; public override bool Equals(object obj) => Equals(obj as LockInfo); public bool Equals(LockInfo other) { if (ReferenceEquals(other, null)) return false; if (ReferenceEquals(this, other)) return true; if (GetType() != other.GetType()) return false; return ToString() == other.ToString(); } public override int GetHashCode() => ToString().GetHashCode(); public override string ToString() => JsonConvert.SerializeObject(this); public static bool operator ==(LockInfo lhs, LockInfo rhs) { if (ReferenceEquals(lhs, null)) return ReferenceEquals(rhs, null) ? true /*null == null = true*/: false; return lhs.Equals(rhs); } public static bool operator !=(LockInfo lhs, LockInfo rhs) => !(lhs == rhs); public class Builder { public Builder(LockInfo lockInfo = null) { if (lockInfo == null) { return; } LockInfo = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(lockInfo)); } private readonly LockInfo LockInfo = new LockInfo(); public byte[] UserKey { get => LockInfo.UserKey; set => LockInfo.UserKey = value; } public byte[] AdminKey { get => LockInfo.AdminKey; set => LockInfo.AdminKey = value; } public byte[] Seed { get => LockInfo.Seed; set => LockInfo.Seed = value; } public int Id { get => LockInfo.Id; set => LockInfo.Id = value; } public Guid Guid { get => LockInfo.Guid; set => LockInfo.Guid = value; } public LockingState State { get => LockInfo.State; set => LockInfo.State = value; } public LockInfo Build() { // Ensure consistency. if ((UserKey?.Length > 0 || Seed?.Length > 0) && (UserKey?.Length == 0 || Seed?.Length == 0 || !LockInfo.IsIdValid)) throw new ArgumentException($"Can not build {typeof(LockInfo).Name}. Lock parameters must either be all know or all unknown."); if (UserKey == null) UserKey = new byte[0]; if (AdminKey == null) AdminKey = new byte[0]; if (Seed == null) Seed = new byte[0]; return LockInfo; } } } }