[Bluetooth][Non-ACR] Add MTU functionalities (#2790)
authorWootak Jung <wootak.jung@samsung.com>
Thu, 25 Mar 2021 05:38:58 +0000 (14:38 +0900)
committerGitHub <noreply@github.com>
Thu, 25 Mar 2021 05:38:58 +0000 (14:38 +0900)
Signed-off-by: Wootak Jung <wootak.jung@samsung.com>
src/Tizen.Network.Bluetooth/Interop/Interop.Bluetooth.cs
src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothEventArgs.cs
src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGatt.cs
src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGattImpl.cs
src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothStructs.cs

index 710b0f2..d7353b2 100644 (file)
@@ -630,6 +630,9 @@ internal static partial class Interop
         [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
         internal delegate void BtGattClientRequestCompletedCallback(int result, IntPtr requestHandle, IntPtr userData);
 
+        [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+        internal delegate void BtGattClientAttMtuChangedCallback(IntPtr clientHandle, ref AttMtuInfoStruct mtuInfo, IntPtr userData);
+
         // Gatt Attribute
 
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_destroy")]
@@ -745,6 +748,18 @@ internal static partial class Interop
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_write_value")]
         internal static extern int BtGattClientWriteValue(BluetoothGattAttributeHandle gattHandle, BtGattClientRequestCompletedCallback callback, IntPtr userData);
 
+        [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_get_att_mtu")]
+        internal static extern int BtGattClientGetAttMtu(BluetoothGattClientHandle clientHandle, out int mtu);
+
+        [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_request_att_mtu_change")]
+        internal static extern int BtGattClientSetAttMtu(BluetoothGattClientHandle clientHandle, int mtu);
+
+        [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_set_att_mtu_changed_cb")]
+        internal static extern int BtGattClientSetMtuChangedCallback(BluetoothGattClientHandle clientHandle, BtGattClientAttMtuChangedCallback callback, IntPtr userData);
+
+        [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_unset_att_mtu_changed_cb")]
+        internal static extern int BtGattClientUnsetMtuChangedCallback(BluetoothGattClientHandle clientHandle);
+
         // GATT Server
 
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_destroy")]
index 263d2d5..b728454 100644 (file)
@@ -1215,6 +1215,32 @@ namespace Tizen.Network.Bluetooth
     }
 
     /// <summary>
+    /// An extended EventArgs class contains the changed MTU value.
+    /// </summary>
+    /// <since_tizen> 8 </since_tizen>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class AttMtuChangedEventArgs : EventArgs
+    {
+        internal AttMtuChangedEventArgs(string remoteAddress, int mtu)
+        {
+            RemoteAddress = remoteAddress;
+            Mtu = mtu;
+        }
+
+        /// <summary>
+        /// The remote address.
+        /// </summary>
+        /// <since_tizen> 8 </since_tizen>
+        public string RemoteAddress { get; }
+
+        /// <summary>
+        /// The MTU value
+        /// </summary>
+        /// <since_tizen> 8 </since_tizen>
+        public int Mtu { get; }
+    }
+
+    /// <summary>
     /// An extended EventArgs class contains the changed attribute value.
     /// </summary>
     /// <since_tizen> 3 </since_tizen>
index 82f2cd8..7af1526 100644 (file)
@@ -16,6 +16,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.ComponentModel;
 using System.Runtime.InteropServices;
 using System.Text;
 using System.Threading.Tasks;
@@ -266,6 +267,12 @@ namespace Tizen.Network.Bluetooth
             _impl = new BluetoothGattClientImpl(remoteAddress);
             _remoteAddress = remoteAddress;
             StaticConnectionStateChanged += OnConnectionStateChanged;
+            _impl.AttMtuChanged += OnAttMtuChanged;
+        }
+
+        private void OnAttMtuChanged(object s, AttMtuChangedEventArgs e)
+        {
+            AttMtuChanged?.Invoke(this, e);
         }
 
         /// <summary>
@@ -517,6 +524,41 @@ namespace Tizen.Network.Bluetooth
             return await _impl.WriteValueAsyncTask(descriptor.GetHandle());
         }
 
+        /// <summary>
+        /// Gets the value of the ATT MTU(Maximum Transmission Unit) for the connection.
+        /// </summary>
+        /// <returns>The MTU value</returns>
+        /// <exception cref="NotSupportedException">Thrown when the BT/BLE is not supported.</exception>
+        /// <exception cref="InvalidOperationException">Thrown when the BT/BLE is not enabled
+        /// or when the remote device is disconnected, or when other specific error occurs.</exception>
+        /// <since_tizen> 8 </since_tizen>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public int GetAttMtu()
+        {
+            return _impl.GetAttMtu();
+        }
+
+        /// <summary>
+        /// Sets the value of the ATT MTU(Maximum Transmission Unit) for the connection.
+        /// </summary>
+        /// <param name="mtu">The MTU value</param>
+        /// <exception cref="NotSupportedException">Thrown when the BT/BLE is not supported.</exception>
+        /// <exception cref="InvalidOperationException">Thrown when the BT/BLE is not enabled
+        /// or when the remote device is disconnected, or when other specific error occurs.</exception>
+        /// <since_tizen> 8 </since_tizen>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void SetAttMtu(int mtu)
+        {
+            _impl.SetAttMtu(mtu);
+        }
+
+        /// <summary>
+        /// The AttMtuChanged event is raised when the MTU value changed.
+        /// </summary>
+        /// <since_tizen> 8 </since_tizen>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public event EventHandler<AttMtuChangedEventArgs> AttMtuChanged;
+
         internal bool Isvalid()
         {
             return _impl.GetHandle().IsInvalid == false;
index 559a14b..352757d 100644 (file)
@@ -168,6 +168,8 @@ namespace Tizen.Network.Bluetooth
         Dictionary<int, TaskCompletionSource<bool>> _writeValueTaskSource = new Dictionary<int, TaskCompletionSource<bool>>();
         private Interop.Bluetooth.BtGattClientRequestCompletedCallback _writeValueCallback;
         private Interop.Bluetooth.BtGattForeachCallback _serviceForeachCallback;
+        private Interop.Bluetooth.BtGattClientAttMtuChangedCallback _attMtuChangedCallback;
+        private event EventHandler<AttMtuChangedEventArgs> _attMtuChanged;
 
         internal BluetoothGattClientImpl(string remoteAddress)
         {
@@ -320,6 +322,69 @@ namespace Tizen.Network.Bluetooth
             return task.Task;
         }
 
+        internal int GetAttMtu()
+        {
+            int err = Interop.Bluetooth.BtGattClientGetAttMtu(_handle, out int mtu);
+            if (err.IsFailed())
+            {
+                GattUtil.Error(err, "Failed to get MTU value");
+                BluetoothErrorFactory.ThrowBluetoothException(err);
+            }
+            return mtu;
+        }
+
+        internal void SetAttMtu(int mtu)
+        {
+            int err = Interop.Bluetooth.BtGattClientSetAttMtu(_handle, mtu);
+            if (err.IsFailed())
+            {
+                GattUtil.Error(err, "Failed to set MTU value");
+                BluetoothErrorFactory.ThrowBluetoothException(err);
+            }
+        }
+
+        internal event EventHandler<AttMtuChangedEventArgs> AttMtuChanged
+        {
+            add
+            {
+                if (_attMtuChanged == null)
+                {
+                    RegisterMtuChangedEvent();
+                }
+                _attMtuChanged += value;
+            }
+            remove
+            {
+                _attMtuChanged -= value;
+                if (_attMtuChanged == null)
+                {
+                    UnregisterMtuChangedEvent();
+                }
+            }
+        }
+
+        private void RegisterMtuChangedEvent()
+        {
+            _attMtuChangedCallback = (IntPtr clientHandle, ref AttMtuInfoStruct mtuInfoStruct, IntPtr userData) =>
+            {
+                _attMtuChanged?.Invoke(null, new AttMtuChangedEventArgs(mtuInfoStruct.RemoteAddress, mtuInfoStruct.Mtu));
+            };
+            int ret = Interop.Bluetooth.BtGattClientSetMtuChangedCallback(_handle, _attMtuChangedCallback, IntPtr.Zero);
+            if (ret != (int)BluetoothError.None)
+            {
+                Log.Error(Globals.LogTag, "Failed to set MTU changed callback, Error - " + (BluetoothError)ret);
+            }
+        }
+
+        private void UnregisterMtuChangedEvent()
+        {
+            int ret = Interop.Bluetooth.BtGattClientUnsetMtuChangedCallback(_handle);
+            if (ret != (int)BluetoothError.None)
+            {
+                Log.Error(Globals.LogTag, "Failed to unset MTU changed callback, Error - " + (BluetoothError)ret);
+            }
+        }
+
         internal BluetoothGattClientHandle GetHandle()
         {
             return _handle;
index af0744e..2e48533 100644 (file)
@@ -236,6 +236,17 @@ namespace Tizen.Network.Bluetooth
         internal uint number;
         internal uint duration;
     }
+
+    [NativeStruct("bt_gatt_client_att_mtu_info_s", Include = "bluetooth_type.h", PkgConfig = "capi-network-bluetooth")]
+    [StructLayout(LayoutKind.Sequential)]
+    internal struct AttMtuInfoStruct
+    {
+        [MarshalAsAttribute(UnmanagedType.LPStr)]
+        internal string RemoteAddress;
+        internal int Mtu;
+        internal int Status;
+    }
+
     internal static class BluetoothUtils
     {
         internal static BluetoothDevice ConvertStructToDeviceClass(BluetoothDeviceStruct device)