From 2fc9ddf67a792aa5129990c818e9f3f16dc6c24c Mon Sep 17 00:00:00 2001 From: Emill Date: Mon, 6 Aug 2018 15:12:42 +0200 Subject: [PATCH] Add color, delete button support to C# lib --- .../src/FliclibDotNetClient/Enums.cs | 10 +++- .../src/FliclibDotNetClient/FlicClient.cs | 55 ++++++++++++++----- .../src/FliclibDotNetClient/Packets.cs | 48 +++++++++++++++- 3 files changed, 95 insertions(+), 18 deletions(-) diff --git a/clientlib/csharp/FliclibDotNetClient/src/FliclibDotNetClient/Enums.cs b/clientlib/csharp/FliclibDotNetClient/src/FliclibDotNetClient/Enums.cs index 09a9acf..9d429b2 100644 --- a/clientlib/csharp/FliclibDotNetClient/src/FliclibDotNetClient/Enums.cs +++ b/clientlib/csharp/FliclibDotNetClient/src/FliclibDotNetClient/Enums.cs @@ -37,7 +37,12 @@ public enum RemovedReason : byte InternetBackendError, InvalidData, - CouldntLoadDevice + CouldntLoadDevice, + + DeletedByThisClient, + DeletedByOtherClient, + + ButtonBelongsToOtherPartner }; public enum ClickType : byte @@ -71,7 +76,8 @@ public enum ScanWizardResult : byte WizardButtonIsPrivate, WizardBluetoothUnavailable, WizardInternetBackendError, - WizardInvalidData + WizardInvalidData, + WizardButtonBelongsToOtherPartner }; public enum BluetoothControllerState : byte diff --git a/clientlib/csharp/FliclibDotNetClient/src/FliclibDotNetClient/FlicClient.cs b/clientlib/csharp/FliclibDotNetClient/src/FliclibDotNetClient/FlicClient.cs index a1fbb48..5067040 100644 --- a/clientlib/csharp/FliclibDotNetClient/src/FliclibDotNetClient/FlicClient.cs +++ b/clientlib/csharp/FliclibDotNetClient/src/FliclibDotNetClient/FlicClient.cs @@ -27,11 +27,12 @@ namespace FliclibDotNetClient Bdaddr[] verifiedButtons); /// - /// Callback for GetButtonUUID + /// Callback for GetButtonInfo /// /// The Bluetooth device address for the request /// The UUID of the button. Will be null if the button was not verified bufore. - public delegate void GetButtonUUIDResponseCallback(Bdaddr bdAddr, string uuid); + /// The color of the button. Will be null if the button was not verified before. + public delegate void GetButtonInfoResponseCallback(Bdaddr bdAddr, string uuid, string color); /// /// NewVerifiedButtonEventArgs @@ -66,6 +67,22 @@ public class BluetoothControllerStateChangeEventArgs : EventArgs public BluetoothControllerState State { get; internal set; } } + /// + /// ButtonDeletedEventArgs + /// + public class ButtonDeletedEventArgs : EventArgs + { + /// + /// Bluetooth device address of removed button + /// + public Bdaddr BdAddr { get; internal set; } + + /// + /// Whether or not the button was deleted by this client + /// + public bool DeletedByThisClient { get; internal set; } + } + /// /// Flic client class /// @@ -92,7 +109,7 @@ public sealed class FlicClient : IDisposable private readonly ConcurrentDictionary _connectionChannels = new ConcurrentDictionary(); private readonly ConcurrentDictionary _scanWizards = new ConcurrentDictionary(); private readonly ConcurrentQueue _getInfoResponseCallbackQueue = new ConcurrentQueue(); - private readonly Queue _getButtonUUIDResponseCallbackQueue = new Queue(); + private readonly Queue _getButtonInfoResponseCallbackQueue = new Queue(); private readonly SortedDictionary _timers = new SortedDictionary(); /// @@ -115,6 +132,11 @@ public sealed class FlicClient : IDisposable /// This event will be raised when the number of concurrent connections has decreased from the maximum by one (only sent by the Linux server implementation). /// public event EventHandler GotSpaceForNewConnection; + + /// + /// Raised when a button is deleted, or when this client tries to delete a non-existing button. + /// + public event EventHandler ButtonDeleted; private FlicClient() { @@ -239,17 +261,17 @@ public void GetInfo(GetInfoResponseCallback callback) /// /// Bluetooth device address /// Callback to be invoked when the response arrives - public void GetButtonUUID(Bdaddr bdAddr, GetButtonUUIDResponseCallback callback) + public void GetButtonInfo(Bdaddr bdAddr, GetButtonInfoResponseCallback callback) { if (callback == null) { throw new ArgumentNullException(nameof(callback)); } - lock (_getButtonUUIDResponseCallbackQueue) + lock (_getButtonInfoResponseCallbackQueue) { - _getButtonUUIDResponseCallbackQueue.Enqueue(callback); - SendPacket(new CmdGetButtonUUID { BdAddr = bdAddr }); + _getButtonInfoResponseCallbackQueue.Enqueue(callback); + SendPacket(new CmdGetButtonInfo { BdAddr = bdAddr }); } } @@ -706,16 +728,16 @@ private void DispatchPacket(byte[] packet) BluetoothControllerStateChange.RaiseEvent(this, new BluetoothControllerStateChangeEventArgs { State = pkt.State }); } break; - case EventPacket.EVT_GET_BUTTON_UUID_RESPONSE_OPCODE: + case EventPacket.EVT_GET_BUTTON_INFO_RESPONSE_OPCODE: { - var pkt = new EvtGetButtonUUIDResponse(); + var pkt = new EvtGetButtonInfoResponse(); pkt.Parse(packet); - GetButtonUUIDResponseCallback callback; - lock (_getButtonUUIDResponseCallbackQueue) + GetButtonInfoResponseCallback callback; + lock (_getButtonInfoResponseCallbackQueue) { - callback = _getButtonUUIDResponseCallbackQueue.Dequeue(); + callback = _getButtonInfoResponseCallbackQueue.Dequeue(); } - callback(pkt.BdAddr, pkt.Uuid); + callback(pkt.BdAddr, pkt.Uuid, pkt.Color); } break; case EventPacket.EVT_SCAN_WIZARD_FOUND_PRIVATE_BUTTON_OPCODE: @@ -755,6 +777,13 @@ private void DispatchPacket(byte[] packet) wizard.OnCompleted(eventArgs); } break; + case EventPacket.EVT_BUTTON_DELETED_OPCODE: + { + var pkt = new EvtButtonDeleted(); + pkt.Parse(packet); + ButtonDeleted.RaiseEvent(this, new ButtonDeletedEventArgs { BdAddr = pkt.BdAddr, DeletedByThisClient = pkt.DeletedByThisClient }); + } + break; } } } diff --git a/clientlib/csharp/FliclibDotNetClient/src/FliclibDotNetClient/Packets.cs b/clientlib/csharp/FliclibDotNetClient/src/FliclibDotNetClient/Packets.cs index 5cdbaa4..4aef964 100644 --- a/clientlib/csharp/FliclibDotNetClient/src/FliclibDotNetClient/Packets.cs +++ b/clientlib/csharp/FliclibDotNetClient/src/FliclibDotNetClient/Packets.cs @@ -122,7 +122,7 @@ protected override void Write(BinaryWriter writer) } } - internal class CmdGetButtonUUID : CommandPacket + internal class CmdGetButtonInfo : CommandPacket { internal Bdaddr BdAddr; @@ -155,6 +155,17 @@ protected override void Write(BinaryWriter writer) } } + internal class CmdDeleteButton : CommandPacket + { + internal Bdaddr BdAddr; + + protected override void Write(BinaryWriter writer) + { + Opcode = 11; + BdAddr.WriteBytes(writer); + } + } + internal abstract class EventPacket { internal const int EVT_ADVERTISEMENT_PACKET_OPCODE = 0; @@ -171,11 +182,12 @@ internal abstract class EventPacket internal const int EVT_GOT_SPACE_FOR_NEW_CONNECTION_OPCODE = 11; internal const int EVT_BLUETOOTH_CONTROLLER_STATE_CHANGE_OPCODE = 12; internal const int EVT_PING_RESPONSE_OPCODE = 13; - internal const int EVT_GET_BUTTON_UUID_RESPONSE_OPCODE = 14; + internal const int EVT_GET_BUTTON_INFO_RESPONSE_OPCODE = 14; internal const int EVT_SCAN_WIZARD_FOUND_PRIVATE_BUTTON_OPCODE = 15; internal const int EVT_SCAN_WIZARD_FOUND_PUBLIC_BUTTON_OPCODE = 16; internal const int EVT_SCAN_WIZARD_BUTTON_CONNECTED_OPCODE = 17; internal const int EVT_SCAN_WIZARD_COMPLETED_OPCODE = 18; + internal const int EVT_BUTTON_DELETED_OPCODE = 19; internal void Parse(byte[] arr) { @@ -342,10 +354,11 @@ protected override void ParseInternal(BinaryReader reader) } } - internal class EvtGetButtonUUIDResponse : EventPacket + internal class EvtGetButtonInfoResponse : EventPacket { internal Bdaddr BdAddr; internal string Uuid; + internal string Color; protected override void ParseInternal(BinaryReader reader) { @@ -365,6 +378,23 @@ protected override void ParseInternal(BinaryReader reader) { Uuid = null; } + + if (reader.PeekChar() == -1) + { + // For old protocol + return; + } + int colorLen = reader.ReadByte(); + var bytes = new byte[colorLen]; + for (var i = 0; i < colorLen; i++) + { + bytes[i] = reader.ReadByte(); + } + for (var i = colorLen; i < 16; i++) + { + reader.ReadByte(); + } + Color = colorLen == 0 ? null : Encoding.UTF8.GetString(bytes); } } @@ -423,4 +453,16 @@ protected override void ParseInternal(BinaryReader reader) Result = (ScanWizardResult)reader.ReadByte(); } } + + internal class EvtButtonDeleted : EventPacket + { + internal Bdaddr BdAddr; + internal bool DeletedByThisClient; + + protected override void ParseInternal(BinaryReader reader) + { + BdAddr = new Bdaddr(reader); + DeletedByThisClient = reader.ReadBoolean(); + } + } }