From a444cb53725a48739d745ecda0f42ce931131e8b Mon Sep 17 00:00:00 2001 From: Wootak Jung Date: Mon, 30 Aug 2021 08:10:37 +0900 Subject: [PATCH] [Bluetooth][TCSACR-437] Add GATT related APIs (#3377) BluetoothGattServer.GetAttMtu(string clientAddress) BluetoothGattClient.ServiceChanged ServiceChangedEventArgs BluetoothGattServiceChangeType Signed-off-by: Wootak Jung --- .../Interop/Interop.Bluetooth.cs | 12 +++++ .../BluetoothEnumerations.cs | 16 +++++++ .../Tizen.Network.Bluetooth/BluetoothEventArgs.cs | 25 ++++++++++ .../Tizen.Network.Bluetooth/BluetoothGatt.cs | 27 +++++++++++ .../Tizen.Network.Bluetooth/BluetoothGattImpl.cs | 55 ++++++++++++++++++++++ 5 files changed, 135 insertions(+) diff --git a/src/Tizen.Network.Bluetooth/Interop/Interop.Bluetooth.cs b/src/Tizen.Network.Bluetooth/Interop/Interop.Bluetooth.cs index e87209e..52a5a97 100644 --- a/src/Tizen.Network.Bluetooth/Interop/Interop.Bluetooth.cs +++ b/src/Tizen.Network.Bluetooth/Interop/Interop.Bluetooth.cs @@ -638,6 +638,9 @@ internal static partial class Interop [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)] internal delegate void BtGattServerAttMtuChangedCallback(IntPtr clientHandle, ref AttMtuInfoStruct mtuInfo, IntPtr userData); + [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)] + internal delegate void BtClientServiceChangedCallback(IntPtr clientHandle, BluetoothGattServiceChangeType changeType, string serviceUuid, IntPtr userData); + // Gatt Attribute [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_destroy")] @@ -704,6 +707,12 @@ internal static partial class Interop [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_characteristic_foreach_descriptors")] internal static extern int BtGattCharacteristicForeachDescriptors(BluetoothGattAttributeHandle characteristicHandle, BtGattForeachCallback callback, IntPtr userData); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_set_service_changed_cb")] + internal static extern int BtGattClientSetServiceChangedCallback(BluetoothGattClientHandle clientHandle, BtClientServiceChangedCallback cb, IntPtr userData); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_unset_service_changed_cb")] + internal static extern int BtGattClientUnsetServiceChangedCallback(BluetoothGattClientHandle clientHandle); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_set_characteristic_value_changed_cb")] internal static extern int BtGattClientSetCharacteristicValueChangedCallback(BluetoothGattAttributeHandle characteristicHandle, BtClientCharacteristicValueChangedCallback cb, IntPtr userData); @@ -820,6 +829,9 @@ internal static partial class Interop [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_notify_characteristic_changed_value")] internal static extern int BtGattServerNotify(BluetoothGattAttributeHandle characteristicHandle, BtGattServerNotificationSentCallback callback, string clientAddress, IntPtr userData); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_get_device_mtu")] + internal static extern int BtGattServerGetDeviceMtu(string remoteAddress, out int mtu); } } diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothEnumerations.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothEnumerations.cs index 217e03f..70c504e 100644 --- a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothEnumerations.cs +++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothEnumerations.cs @@ -1308,6 +1308,22 @@ namespace Tizen.Network.Bluetooth } /// + /// Enumeration for the GATT service change type. + /// + /// 9 + public enum BluetoothGattServiceChangeType + { + /// + /// Service added. + /// + Added = 0, + /// + /// Service removed. + /// + Removed, + } + + /// /// Enumeration for the Bluetooth HID header type. /// /// 6 diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothEventArgs.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothEventArgs.cs index b728454..ec87eaa 100644 --- a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothEventArgs.cs +++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothEventArgs.cs @@ -1241,6 +1241,31 @@ namespace Tizen.Network.Bluetooth } /// + /// An extended EventArgs class contains the service changed information. + /// + /// 9 + public class ServiceChangedEventArgs : EventArgs + { + internal ServiceChangedEventArgs(BluetoothGattServiceChangeType changeType, string serviceUuid) + { + ChangeType = changeType; + ServiceUuid = serviceUuid; + } + + /// + /// The service changed type. + /// + /// 9 + public BluetoothGattServiceChangeType ChangeType { get; } + + /// + /// The service UUID. + /// + /// 9 + public string ServiceUuid { get; } + } + + /// /// An extended EventArgs class contains the changed attribute value. /// /// 3 diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGatt.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGatt.cs index 56dfb9d..166e6ac 100644 --- a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGatt.cs +++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGatt.cs @@ -217,6 +217,20 @@ namespace Tizen.Network.Bluetooth } /// + /// Gets the value of the ATT MTU(Maximum Transmission Unit) for the connection. + /// + /// The remote device address. + /// http://tizen.org/feature/network.bluetooth.le.gatt.server + /// The MTU value + /// Thrown when the BT/BLE is not supported. + /// Thrown when the BT/BLE is not enabled + /// or when the remote device is disconnected, or when other specific error occurs. + /// 9 + public int GetAttMtu(string clientAddress) + { + return _impl.GetAttMtu(clientAddress); + } + /// The AttMtuChanged event is raised when the MTU value changed. /// /// 9 @@ -281,6 +295,7 @@ namespace Tizen.Network.Bluetooth _remoteAddress = remoteAddress; StaticConnectionStateChanged += OnConnectionStateChanged; _impl.AttMtuChanged += OnAttMtuChanged; + _impl.ServiceChanged += OnServiceChanged; } private void OnAttMtuChanged(object s, AttMtuChangedEventArgs e) @@ -288,6 +303,11 @@ namespace Tizen.Network.Bluetooth AttMtuChanged?.Invoke(this, e); } + private void OnServiceChanged(object s, ServiceChangedEventArgs e) + { + ServiceChanged?.Invoke(this, e); + } + /// /// Creates the Bluetooth GATT client. /// @@ -569,6 +589,13 @@ namespace Tizen.Network.Bluetooth [EditorBrowsable(EditorBrowsableState.Never)] public event EventHandler AttMtuChanged; + /// + /// The ServiceChanged event is raised when the service is changed from the remote device(GATT server). + /// + /// http://tizen.org/feature/network.bluetooth.le.gatt.client + /// 9 + public event EventHandler ServiceChanged; + internal bool Isvalid() { return _impl.GetHandle().IsInvalid == false; diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGattImpl.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGattImpl.cs index 7a623bc..42ce160 100644 --- a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGattImpl.cs +++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGattImpl.cs @@ -155,6 +155,17 @@ namespace Tizen.Network.Bluetooth return task.Task; } + internal int GetAttMtu(string clientAddress) + { + int err = Interop.Bluetooth.BtGattServerGetDeviceMtu(clientAddress, out int mtu); + if (err.IsFailed()) + { + GattUtil.Error(err, "Failed to get MTU value"); + BluetoothErrorFactory.ThrowBluetoothException(err); + } + return mtu; + } + internal event EventHandler AttMtuChanged { add @@ -214,6 +225,8 @@ namespace Tizen.Network.Bluetooth private Interop.Bluetooth.BtGattForeachCallback _serviceForeachCallback; private Interop.Bluetooth.BtGattClientAttMtuChangedCallback _attMtuChangedCallback; private event EventHandler _attMtuChanged; + private Interop.Bluetooth.BtClientServiceChangedCallback _serviceChangedCallback; + private event EventHandler _serviceChanged; internal BluetoothGattClientImpl(string remoteAddress) { @@ -429,6 +442,48 @@ namespace Tizen.Network.Bluetooth } } + internal event EventHandler ServiceChanged + { + add + { + if (_serviceChanged == null) + { + RegisterServiceChangedEvent(); + } + _serviceChanged += value; + } + remove + { + _serviceChanged -= value; + if (_serviceChanged == null) + { + UnregisterServiceChangedEvent(); + } + } + } + + private void RegisterServiceChangedEvent() + { + _serviceChangedCallback = (IntPtr clientHandle, BluetoothGattServiceChangeType changeType, string serviceUuid, IntPtr userData) => + { + _serviceChanged?.Invoke(null, new ServiceChangedEventArgs(changeType, serviceUuid)); + }; + int ret = Interop.Bluetooth.BtGattClientSetServiceChangedCallback(_handle, _serviceChangedCallback, IntPtr.Zero); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set service changed callback, Error - " + (BluetoothError)ret); + } + } + + private void UnregisterServiceChangedEvent() + { + int ret = Interop.Bluetooth.BtGattClientUnsetServiceChangedCallback(_handle); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to unset service changed callback, Error - " + (BluetoothError)ret); + } + } + internal BluetoothGattClientHandle GetHandle() { return _handle; -- 2.7.4