[Bluetooth] Add Bluetooth Internal APIs (#598)
authorWootak <nonsan1228@gmail.com>
Thu, 20 Dec 2018 04:32:40 +0000 (13:32 +0900)
committerGitHub <noreply@github.com>
Thu, 20 Dec 2018 04:32:40 +0000 (13:32 +0900)
* Add Bluetooth Internal APIs
* Deprecated wrong AcceptStateChangedEventArgs class property and DestroyServerSocket API
* Add new SocketConnection class property

13 files changed:
src/Tizen.Network.Bluetooth/Interop/Interop.Bluetooth.cs
src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAdapter.cs
src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAdapterImpl.cs
src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAudio.cs
src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothAudioImpl.cs
src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothData.cs
src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothDevice.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/BluetoothOpp.cs
src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothServerSocket.cs
src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothSocket.cs
src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothStructs.cs

index 9d2e737..be77f93 100755 (executable)
@@ -103,65 +103,58 @@ internal static partial class Interop
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_deinitialize")]
         internal static extern int Deinitialize();
 
+        [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_enable")]
+        internal static extern int EnableAdapter();
+        [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_disable")]
+        internal static extern int DisableAdapter();
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_get_name")]
         internal static extern int GetName(out string name);
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_set_name")]
         internal static extern int SetName(string name);
-
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_get_state")]
         internal static extern int GetState(out BluetoothState isActivated);
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_get_address")]
         internal static extern int GetAddress(out string address);
-
+        [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_set_visibility")]
+        internal static extern int SetVisibility(VisibilityMode visibilityMode, int duration);
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_get_visibility")]
         internal static extern int GetVisibility(out int visibility, out int duration);
-
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_is_discovering")]
         internal static extern int IsDiscovering(out bool isDiscovering);
-
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_start_device_discovery")]
         internal static extern int StartDiscovery();
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_stop_device_discovery")]
         internal static extern int StopDiscovery();
-
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_foreach_bonded_device")]
         internal static extern int GetBondedDevices(BondedDeviceCallback bondedDeviceCb, IntPtr userData);
-
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_get_bonded_device_info")]
         internal static extern int GetBondedDeviceByAddress(string deviceAddress, out IntPtr deviceInfo);
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_free_device_info")]
-        internal static extern int FreeDeviceInfo(BluetoothDeviceStruct deviceInfo);
-
+        internal static extern int FreeDeviceInfo(IntPtr deviceInfo);
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_is_service_used")]
         internal static extern int IsServiceUsed(string serviceUuid, out bool used);
-
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_get_local_oob_data")]
         internal static extern int GetOobData(out IntPtr hash, out IntPtr randomizer, out int hashLen, out int randomizerLen);
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_set_remote_oob_data")]
         internal static extern int SetOobData(string deviceAddress, IntPtr hash, IntPtr randomizer, int hashLen, int randomizerLen);
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_remove_remote_oob_data")]
         internal static extern int RemoveOobData(string deviceAddress);
-
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_set_state_changed_cb")]
         internal static extern int SetStateChangedCallback(StateChangedCallback stateChangedCb, IntPtr userData);
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_unset_state_changed_cb")]
         internal static extern int UnsetStateChangedCallback();
-
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_set_name_changed_cb")]
         internal static extern int SetNameChangedCallback(NameChangedCallback nameChangedCb, IntPtr userData);
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_unset_name_changed_cb")]
         internal static extern int UnsetNameChangedCallback();
-
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_set_visibility_mode_changed_cb")]
         internal static extern int SetVisibilityModeChangedCallback(VisibilityModeChangedCallback visibilityChangedCb, IntPtr userData);
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_unset_visibility_mode_changed_cb")]
         internal static extern int UnsetVisibilityModeChangedCallback();
-
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_set_visibility_duration_changed_cb")]
         internal static extern int SetVisibilityDurationChangedCallback(VisibilityDurationChangedCallback durationChangedCb, IntPtr userData);
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_unset_visibility_duration_changed_cb")]
         internal static extern int UnsetVisibilityDurationChangedCallback();
-
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_set_device_discovery_state_changed_cb")]
         internal static extern int SetDiscoveryStateChangedCallback(DiscoveryStateChangedCallback discoveryChangedCb, IntPtr userData);
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_unset_device_discovery_state_changed_cb")]
@@ -336,12 +329,21 @@ internal static partial class Interop
                                         bool connectable);
 
         //Bluetooth Socket
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void SocketConnectionRequestedCallback(int socket_fd, string remoteAddress, IntPtr userData);
+
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_create_rfcomm")]
         internal static extern int CreateServerSocket(string serviceUuid, out int socketFd);
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_destroy_rfcomm")]
         internal static extern int DestroyServerSocket(int socketFd);
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_listen_and_accept_rfcomm")]
         internal static extern int Listen(int socketFd, int pendingConnections);
+        [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_listen")]
+        internal static extern int ListenWithoutAccept(int socketFd, int pendingConnections);
+        [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_accept")]
+        internal static extern int Accept(int socketFd);
+        [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_reject")]
+        internal static extern int Reject(int socketFd);
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_connect_rfcomm")]
         internal static extern int ConnectSocket(string address, string serviceUuid);
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_disconnect_rfcomm")]
@@ -356,22 +358,39 @@ internal static partial class Interop
         internal static extern int SetConnectionStateChangedCallback(SocketConnectionStateChangedCallback callback, IntPtr userData);
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_unset_connection_state_changed_cb")]
         internal static extern int UnsetSocketConnectionStateChangedCallback();
+        [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_set_connection_requested_cb")]
+        internal static extern int SetSocketConnectionRequestedCallback(SocketConnectionRequestedCallback socketConnectionRequestedCb, IntPtr userData);
+        [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_unset_connection_requested_cb")]
+        internal static extern int UnsetSocketConnectionRequestedCallback();
 
         // Bluetooth Audio
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void AgScoStateChangedCallback(int result, bool opened, IntPtr userData);
+
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_audio_initialize")]
         internal static extern int InitializeAudio();
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_audio_deinitialize")]
         internal static extern int DeinitializeAudio();
-
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_audio_connect")]
         internal static extern int Connect(string deviceAddress, int profileType);
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_audio_disconnect")]
         internal static extern int Disconnect(string deviceAddress, int profileType);
-
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_audio_set_connection_state_changed_cb")]
         internal static extern int SetAudioConnectionStateChangedCallback(AudioConnectionStateChangedCallback audioStateChangedCb, IntPtr userData);
         [DllImport(Libraries.Bluetooth, EntryPoint = "bt_audio_unset_connection_state_changed_cb")]
         internal static extern int UnsetAudioConnectionStateChangedCallback();
+        [DllImport(Libraries.Bluetooth, EntryPoint = "bt_ag_open_sco")]
+        internal static extern int OpenAgSco();
+        [DllImport(Libraries.Bluetooth, EntryPoint = "bt_ag_close_sco")]
+        internal static extern int CloseAgSco();
+        [DllImport(Libraries.Bluetooth, EntryPoint = "bt_ag_is_sco_opened")]
+        internal static extern int IsAgScoOpened(out bool opened);
+        [DllImport(Libraries.Bluetooth, EntryPoint = "bt_ag_set_sco_state_changed_cb")]
+        internal static extern int SetAgScoStateChangedCallback(AgScoStateChangedCallback scoStateChangedCb, IntPtr userData);
+        [DllImport(Libraries.Bluetooth, EntryPoint = "bt_ag_unset_sco_state_changed_cb")]
+        internal static extern int UnsetAgScoStateChangedCallback();
+        [DllImport(Libraries.Bluetooth, EntryPoint = "bt_ag_notify_voice_recognition_state")]
+        internal static extern int NotifyAgVoiceRecognitionState(bool enable);
 
         // Bluetooth Hid
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
index e82c7b9..b23b03a 100644 (file)
@@ -16,6 +16,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.ComponentModel;
 
 namespace Tizen.Network.Bluetooth
 {
@@ -372,6 +373,77 @@ namespace Tizen.Network.Bluetooth
         }
 
         /// <summary>
+        /// Enables the local Bluetooth adapter, asynchronously.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        /// <feature>http://tizen.org/feature/network.bluetooth</feature>
+        /// <privilege>http://tizen.org/privilege/bluetooth.admin</privilege>
+        /// <exception cref="NotSupportedException">Thrown when the Bluetooth is not supported.</exception>
+        /// <exception cref="InvalidOperationException">Thrown when the method is failed with message.</exception>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void Enable()
+        {
+            BluetoothAdapterImpl.Instance.Enable();
+        }
+
+        /// <summary>
+        /// Disables the local Bluetooth adapter, asynchronously.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        /// <feature>http://tizen.org/feature/network.bluetooth</feature>
+        /// <privilege>http://tizen.org/privilege/bluetooth.admin</privilege>
+        /// <exception cref="NotSupportedException">Thrown when the Bluetooth is not supported.</exception>
+        /// <exception cref="InvalidOperationException">Thrown when the method is failed with message.</exception>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void Disable()
+        {
+            BluetoothAdapterImpl.Instance.Disable();
+        }
+
+        /// <summary>
+        /// Enables the discoverable mode.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        /// <feature>http://tizen.org/feature/network.bluetooth</feature>
+        /// <privilege>http://tizen.org/privilege/bluetooth.admin</privilege>
+        /// <exception cref="NotSupportedException">Thrown when the Bluetooth is not supported.</exception>
+        /// <exception cref="InvalidOperationException">Thrown when the method is failed with message.</exception>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void EnableDiscoverable()
+        {
+            BluetoothAdapterImpl.Instance.SetVisibility(VisibilityMode.Discoverable, 0);
+        }
+
+        /// <summary>
+        /// Enables the discoverable mode.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        /// <param name="duration">The duration until the discoverable mode is to be disabled(in seconds).</param>
+        /// <feature>http://tizen.org/feature/network.bluetooth</feature>
+        /// <privilege>http://tizen.org/privilege/bluetooth.admin</privilege>
+        /// <exception cref="NotSupportedException">Thrown when the Bluetooth is not supported.</exception>
+        /// <exception cref="InvalidOperationException">Thrown when the method is failed with message.</exception>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void EnableDiscoverable(int duration)
+        {
+            BluetoothAdapterImpl.Instance.SetVisibility(VisibilityMode.TimeLimitedDiscoverable, duration);
+        }
+
+        /// <summary>
+        /// Disables the discoverable mode.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        /// <feature>http://tizen.org/feature/network.bluetooth</feature>
+        /// <privilege>http://tizen.org/privilege/bluetooth.admin</privilege>
+        /// <exception cref="NotSupportedException">Thrown when the Bluetooth is not supported.</exception>
+        /// <exception cref="InvalidOperationException">Thrown when the method is failed with message.</exception>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void DisableDiscoverable()
+        {
+            BluetoothAdapterImpl.Instance.SetVisibility(VisibilityMode.NonDiscoverable, 0);
+        }
+
+        /// <summary>
         /// Starts the device discovery process.
         /// </summary>
         /// <remarks>
@@ -439,6 +511,7 @@ namespace Tizen.Network.Bluetooth
         /// The Bluetooth must be enabled.
         /// </remarks>
         /// <returns> Information of the bonded BluetoothDeviceInfo object.</returns>
+        /// <param name="address">The remote device address.</param>
         /// <exception cref="NotSupportedException">Thrown when the Bluetooth is not supported.</exception>
         /// <exception cref="InvalidOperationException">Thrown when the Bluetooth is not enabled
         /// or reading the bonded device information fails.</exception>
@@ -639,6 +712,7 @@ namespace Tizen.Network.Bluetooth
         /// <exception cref="InvalidOperationException">Thrown when the Bluetooth is not enabled
         /// or the socket destroy error occurs.</exception>
         /// <since_tizen> 3 </since_tizen>
+        [Obsolete("Deprecated since API level 6. Please use Dispose() on BluetoothServerSocket.")]
         static public void DestroyServerSocket(BluetoothServerSocket socket)
         {
             if (IsBluetoothEnabled && Globals.IsInitialize)
index 14e2981..c5aaee3 100644 (file)
@@ -396,6 +396,57 @@ namespace Tizen.Network.Bluetooth
             }
         }
 
+        internal void Enable()
+        {
+            if (Globals.IsInitialize)
+            {
+                int ret = Interop.Bluetooth.EnableAdapter();
+                if (ret != (int)BluetoothError.None)
+                {
+                    Log.Error(Globals.LogTag, "Failed to enable adapter, Error - " + (BluetoothError)ret);
+                    BluetoothErrorFactory.ThrowBluetoothException(ret);
+                }
+            }
+            else
+            {
+                BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotInitialized);
+            }
+        }
+
+        internal void Disable()
+        {
+            if (IsBluetoothEnabled)
+            {
+                int ret = Interop.Bluetooth.DisableAdapter();
+                if (ret != (int)BluetoothError.None)
+                {
+                    Log.Error(Globals.LogTag, "Failed to disable adapter, Error - " + (BluetoothError)ret);
+                    BluetoothErrorFactory.ThrowBluetoothException(ret);
+                }
+            }
+            else
+            {
+                BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+            }
+        }
+
+        internal void SetVisibility(VisibilityMode mode, int timeout)
+        {
+            if (IsBluetoothEnabled)
+            {
+                int ret = Interop.Bluetooth.SetVisibility(mode, timeout);
+                if (ret != (int)BluetoothError.None)
+                {
+                    Log.Error(Globals.LogTag, "Failed to set visibility, Error - " + (BluetoothError)ret);
+                    BluetoothErrorFactory.ThrowBluetoothException(ret);
+                }
+            }
+            else
+            {
+                BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
+            }
+        }
+
         internal void StartDiscovery()
         {
             int ret = Interop.Bluetooth.StartDiscovery();
@@ -448,6 +499,7 @@ namespace Tizen.Network.Bluetooth
             }
             BluetoothDeviceStruct device = (BluetoothDeviceStruct)Marshal.PtrToStructure(deviceInfo, typeof(BluetoothDeviceStruct));
 
+            Interop.Bluetooth.FreeDeviceInfo(deviceInfo);
             return BluetoothUtils.ConvertStructToDeviceClass(device);
         }
 
index 8ff829d..8a20ab2 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 using System;
+using System.ComponentModel;
 
 namespace Tizen.Network.Bluetooth
 {
@@ -105,5 +106,85 @@ namespace Tizen.Network.Bluetooth
                 BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
             }
         }
+
+        /// <summary>
+        /// Opens a AG(Audio Gateway) SCO(Synchronous Connection Oriented link) to connected remote device, asynchronously.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        /// <feature>http://tizen.org/feature/network.bluetooth</feature>
+        /// <feature>http://tizen.org/feature/network.bluetooth.audio.call</feature>
+        /// <privilege>http://tizen.org/privilege/bluetooth.admin</privilege>
+        /// <exception cref="NotSupportedException">Thrown when the Bluetooth is not supported.</exception>
+        /// <exception cref="InvalidOperationException">Thrown when the method is failed with message.</exception>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void OpenAgSco()
+        {
+            BluetoothAudioImpl.Instance.OpenAgSco();
+        }
+
+        /// <summary>
+        /// Closes a AG(Audio Gateway) SCO(Synchronous Connection Oriented link) to connected remote device, asynchronously.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        /// <feature>http://tizen.org/feature/network.bluetooth</feature>
+        /// <feature>http://tizen.org/feature/network.bluetooth.audio.call</feature>
+        /// <privilege>http://tizen.org/privilege/bluetooth.admin</privilege>
+        /// <exception cref="NotSupportedException">Thrown when the Bluetooth is not supported.</exception>
+        /// <exception cref="InvalidOperationException">Thrown when the method is failed with message.</exception>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void CloseAgSco()
+        {
+            BluetoothAudioImpl.Instance.CloseAgSco();
+        }
+
+        /// <summary>
+        /// A property to check whether an opened AG(Audio Gateway) SCO(Synchronous Connection Oriented link) exists or not.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        /// <feature>http://tizen.org/feature/network.bluetooth</feature>
+        /// <feature>http://tizen.org/feature/network.bluetooth.audio.call</feature>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool IsAgScoOpened
+        {
+            get
+            {   
+                return BluetoothAudioImpl.Instance.IsAgScoOpened;
+            }
+        }
+
+        /// <summary>
+        /// This event is called when the AG(Audio Gateway) SCO(Synchronous Connection Oriented link) state is changed.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        /// <feature>http://tizen.org/feature/network.bluetooth</feature>
+        /// <feature>http://tizen.org/feature/network.bluetooth.audio.call</feature>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static event EventHandler<AgScoStateChangedEventArgs> AgScoStateChanged
+        {
+            add
+            {
+                BluetoothAudioImpl.Instance.AgScoStateChanged += value;
+            }
+            remove
+            {
+                BluetoothAudioImpl.Instance.AgScoStateChanged -= value;
+            }
+        }
+
+        /// <summary>
+        /// Notifies the state of AG(Audio Gateway) voice recognition to connected remote device.
+        /// </summary>
+        /// <param name="enable">The state of voice recognition. It is true if voice recognition state is enabled.</param>
+        /// <since_tizen> 6 </since_tizen>
+        /// <feature>http://tizen.org/feature/network.bluetooth</feature>
+        /// <feature>http://tizen.org/feature/network.bluetooth.audio.call</feature>
+        /// <privilege>http://tizen.org/privilege/bluetooth.admin</privilege>
+        /// <exception cref="NotSupportedException">Thrown when the Bluetooth is not supported.</exception>
+        /// <exception cref="InvalidOperationException">Thrown when the method is failed with message.</exception>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void NotifyAgVoiceRecognitionState(bool enable)
+        {
+            BluetoothAudioImpl.Instance.NotifyAgVoiceRecognitionState(enable);
+        }
     }
 }
index 6570dc9..c536f90 100644 (file)
@@ -21,6 +21,7 @@ namespace Tizen.Network.Bluetooth
     internal class BluetoothAudioImpl : IDisposable
     {
         private event EventHandler<AudioConnectionStateChangedEventArgs> _audioConnectionChanged;
+        private event EventHandler<AgScoStateChangedEventArgs> _agScoStateChanged;
         private Interop.Bluetooth.AudioConnectionStateChangedCallback _audioConnectionChangedCallback;
 
         private static readonly BluetoothAudioImpl _instance = new BluetoothAudioImpl();
@@ -91,6 +92,114 @@ namespace Tizen.Network.Bluetooth
             return ret;
         }
 
+        internal void OpenAgSco()
+        {
+            if (Globals.IsAudioInitialize)
+            {
+                int ret = Interop.Bluetooth.OpenAgSco();
+                if (ret != (int)BluetoothError.None)
+                {
+                    Log.Error(Globals.LogTag, "Failed to open ag sco to remote device, Error - " + (BluetoothError)ret);
+                    BluetoothErrorFactory.ThrowBluetoothException(ret);
+                }
+            }
+            else
+            {
+                BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotInitialized);
+            }   
+        }
+
+        internal void CloseAgSco()
+        {
+            if (Globals.IsAudioInitialize)
+            {
+                int ret = Interop.Bluetooth.CloseAgSco();
+                if (ret != (int)BluetoothError.None)
+                {
+                    Log.Error(Globals.LogTag, "Failed to close ag sco to remote device, Error - " + (BluetoothError)ret);
+                    BluetoothErrorFactory.ThrowBluetoothException(ret);
+                }
+            }
+            else
+            {
+                BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotInitialized);
+            }
+        }
+
+        internal bool IsAgScoOpened
+        {
+            get
+            {
+                bool isOpened;
+                int ret = Interop.Bluetooth.IsAgScoOpened(out isOpened);
+                if (ret != (int)BluetoothError.None)
+                {
+                    Log.Error(Globals.LogTag, "Failed to check whether an opened SCO exists or not., Error - " + (BluetoothError)ret);
+                }
+                return isOpened;
+            }
+        }
+
+        internal event EventHandler<AgScoStateChangedEventArgs> AgScoStateChanged
+        {
+            add
+            {
+                if (_agScoStateChanged == null)
+                {
+                    RegisterAgScoStateChangedEvent();
+                }
+                _agScoStateChanged += value;
+            }
+            remove
+            {
+                _agScoStateChanged -= value;
+                if (_agScoStateChanged == null)
+                {
+                    UnregisterAgScoStateChangedEvent();
+                }
+            }
+        }
+
+        private void RegisterAgScoStateChangedEvent()
+        {
+            Interop.Bluetooth.AgScoStateChangedCallback _agScoStateChangedCallback = (int result, bool opened, IntPtr userData) =>
+            {
+                _agScoStateChanged?.Invoke(null, new AgScoStateChangedEventArgs(opened));
+            };
+
+            int ret = Interop.Bluetooth.SetAgScoStateChangedCallback(_agScoStateChangedCallback, IntPtr.Zero);
+            if (ret != (int)BluetoothError.None)
+            {
+                Log.Error(Globals.LogTag, "Failed to set ag sco state changed callback, Error - " + (BluetoothError)ret);
+            }
+        }
+
+        private void UnregisterAgScoStateChangedEvent()
+        {
+            int ret = Interop.Bluetooth.UnsetAgScoStateChangedCallback();
+            if (ret != (int)BluetoothError.None)
+            {
+                Log.Error(Globals.LogTag, "Failed to unset ag sco state changed callback, Error - " + (BluetoothError)ret);
+            }
+        }
+
+        internal void NotifyAgVoiceRecognitionState(bool enable)
+        {
+            if (Globals.IsAudioInitialize)
+            {
+                int ret = Interop.Bluetooth.NotifyAgVoiceRecognitionState(enable);
+                if (ret != (int)BluetoothError.None)
+                {
+                    Log.Error(Globals.LogTag, "Failed to notify sco voice recognition state, Error - " + (BluetoothError)ret);
+                    BluetoothErrorFactory.ThrowBluetoothException(ret);
+                }
+            }
+            else
+            {
+                BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotInitialized);
+            }
+        }
+
         internal static BluetoothAudioImpl Instance
         {
             get
index 6bf97b5..2c132b5 100644 (file)
@@ -504,6 +504,7 @@ namespace Tizen.Network.Bluetooth
         internal string Uuid;
         internal string RemoteAddress;
         internal int Fd;
+        internal IBluetoothServerSocket ClientSocket;
 
         internal SocketConnection()
         {
@@ -542,6 +543,23 @@ namespace Tizen.Network.Bluetooth
                 return Uuid;
             }
         }
+
+        internal int ServerFd
+        {
+            get;
+            set;
+        }
+        /// <summary>
+        /// The client socket.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public IBluetoothServerSocket Client
+        {
+            get
+            {
+                return ClientSocket;
+            }
+        }
     }
 
     /// <summary>
index 34894a0..f40c7c8 100644 (file)
@@ -676,6 +676,7 @@ namespace Tizen.Network.Bluetooth
         /// <remarks>
         /// The Bluetooth must be enabled.
         /// </remarks>
+        /// <returns>The profile instance.</returns>
         /// <since_tizen> 3 </since_tizen>
         public T GetProfile<T>() where T : BluetoothProfile
         {
index d3288e8..ebfa544 100644 (file)
@@ -552,6 +552,7 @@ namespace Tizen.Network.Bluetooth
         /// The server socket instance.
         /// </summary>
         /// <since_tizen> 3 </since_tizen>
+        [Obsolete("Deprecated since API level 6. Please use the 'Client' in the SocketConnection.")]
         public IBluetoothServerSocket Server
         {
             get
@@ -562,6 +563,40 @@ namespace Tizen.Network.Bluetooth
     }
 
     /// <summary>
+    /// An extended EventArgs class contains the socket connection requested.
+    /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class SocketConnectionRequestedEventArgs : EventArgs
+    {
+        internal SocketConnectionRequestedEventArgs(int socketFd, string remoteAddress)
+        {
+            SocketFd = socketFd;
+            RemoteAddress = remoteAddress;
+        }
+
+        /// <summary>
+        /// The socket fd.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        internal int SocketFd
+        {
+            get;
+            private set;
+        }
+
+        /// <summary>
+        /// The remote address.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public string RemoteAddress
+        {
+            get;
+            private set;
+        }
+    }
+
+    /// <summary>
     /// An extended EventArgs class contains the connection state, remote address, and the type of audio profile.
     /// </summary>
     /// <since_tizen> 3 </since_tizen>
@@ -632,6 +667,29 @@ namespace Tizen.Network.Bluetooth
     /// <summary>
     /// An extended EventArgs class contains the connection state and the address of the remote Bluetooth device.
     /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class AgScoStateChangedEventArgs : EventArgs
+    {
+        internal AgScoStateChangedEventArgs(bool isOpened)
+        {
+            IsOpened = isOpened;
+        }
+
+        /// <summary>
+        /// A value indicating whether the state is connected.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public bool IsOpened
+        {
+            get;
+            private set;
+        }
+    }
+
+    /// <summary>
+    /// An extended EventArgs class contains the connection state and the address of the remote Bluetooth device.
+    /// </summary>
     /// <since_tizen> 3 </since_tizen>
     public class HidConnectionStateChangedEventArgs : EventArgs
     {
@@ -1350,11 +1408,10 @@ namespace Tizen.Network.Bluetooth
         }
     }
 
-    /// <Summary>
+    /// <summary>
     /// An extended EventArgs class which contains the Push Request respond state
-    /// </Summary>
+    /// </summary>
     /// <since_tizen> 4 </since_tizen>
-
     public class PushRespondedEventArgs : EventArgs
     {
         int _result;
@@ -1445,11 +1502,10 @@ namespace Tizen.Network.Bluetooth
         }
     }
 
-    /// <Summary>
+    /// <summary>
     /// An extended EventArgs class which contains the Push Request respond state
-    /// </Summary>
+    /// </summary>
     /// <since_tizen> 4 </since_tizen>
-
     public class PushFinishedEventArgs : EventArgs
     {
         int _result;
index 4d6f2d5..36e0314 100644 (file)
@@ -54,7 +54,7 @@ namespace Tizen.Network.Bluetooth
         /// <summary>
         /// Creates the Bluetooth GATT server.
         /// </summary>
-        /// <returns></returns>
+        /// <returns>The BluetoothGattServer instance.</returns>
         /// <exception cref="NotSupportedException">Thrown when the BT/BTLE is not supported.</exception>
         /// <exception cref="InvalidOperationException">Thrown when the create GATT server fails.</exception>
         /// <since_tizen> 3 </since_tizen>
@@ -158,6 +158,7 @@ namespace Tizen.Network.Bluetooth
         /// </summary>
         /// <param name="characteristic">The characteristic whose the value is changed.</param>
         /// <param name="clientAddress">The remote device address to send, notify, or indicate and if set to NULL, then notify/indicate all is enabled.</param>
+        /// <returns>true on success, false otherwise.</returns>
         /// <exception cref="InvalidOperationException">Thrown when the BT/BTLE is not enabled
         /// or when the remote device is disconnected, or when service is not registered, or when the CCCD is not enabled.</exception>
         /// <since_tizen> 3 </since_tizen>
@@ -943,7 +944,7 @@ namespace Tizen.Network.Bluetooth
         /// <summary>
         /// Returns a string value at the specified offset.
         /// </summary>
-        /// <param name="offset"></param>
+        /// <param name="offset">An offset in the attribute value buffer.</param>
         /// <returns>The string value at specified offset.</returns>
         /// <since_tizen> 3 </since_tizen>
         public string GetValue(int offset)
index 5a4a379..d3b76a0 100644 (file)
@@ -92,6 +92,7 @@ namespace Tizen.Network.Bluetooth
         /// The device must be bonded with remote device by CreateBond().
         /// If connection request is received from OPP Client, ConnectionRequested event will be invoked.
         /// </remarks>
+        /// <returns>The BluetoothOppServer instance.</returns>
         /// <param name="FilePath"> Path to store the files.</param>
         /// <feature>http://tizen.org/feature/network.bluetooth.opp</feature>
         /// <exception cref="NotSupportedException">Thrown when the required feature is not Supported.</exception>
@@ -156,6 +157,7 @@ namespace Tizen.Network.Bluetooth
         /// <summary>
         /// Accept File Push request.
         /// </summary>
+        /// <returns>The id of transfer.</returns>
         /// <param name="FileName"> File name to accept.</param>
         /// <feature>http://tizen.org/feature/network.bluetooth.opp</feature>
         /// <exception cref="NotSupportedException">Thrown when the required feature is not Supported.</exception>
index 8601ac9..22aadec 100644 (file)
@@ -17,6 +17,8 @@
 using System;
 using System.Collections.Generic;
 using System.Runtime.InteropServices;
+using System.ComponentModel;
+using System.Threading.Tasks;
 
 namespace Tizen.Network.Bluetooth
 {
@@ -26,18 +28,58 @@ namespace Tizen.Network.Bluetooth
     /// <since_tizen> 3 </since_tizen>
     public class BluetoothServerSocket : IDisposable
     {
-        private event EventHandler<AcceptStateChangedEventArgs> _acceptStateChanged;
-        private Interop.Bluetooth.SocketConnectionStateChangedCallback _connectionStateChangedCallback;
+        private static event EventHandler<AcceptStateChangedEventArgs> _acceptStateChanged;
+        private static event EventHandler<SocketConnectionRequestedEventArgs> _connectionRequested;
+        private static Interop.Bluetooth.SocketConnectionStateChangedCallback _connectionStateChangedCallback;
+        private static Interop.Bluetooth.SocketConnectionRequestedCallback _connectionRequestedCallback;
+        private TaskCompletionSource<SocketConnection> _taskForAccept;
         internal int socketFd;
         private bool disposed = false;
 
+        internal BluetoothServerSocket()
+        {
+            StaticAcceptStateChanged += OnAcceptStateChanged;
+            StaticConnectionRequested += OnConnectionRequested;
+        }
+
+        private void OnConnectionRequested(Object s, SocketConnectionRequestedEventArgs e)
+        {
+            if (e.SocketFd == socketFd)
+            {
+                ConnectionRequested?.Invoke(this, e);
+            }
+        }
+
+        private void OnAcceptStateChanged(Object s, AcceptStateChangedEventArgs e)
+        {
+            if (e.Connection.ServerFd == socketFd)
+            {
+                if (_taskForAccept != null && !_taskForAccept.Task.IsCompleted)
+                {
+                    if (e.State == BluetoothSocketState.Connected)
+                    {
+                        _taskForAccept.SetResult(e.Connection);
+                    }
+                    else
+                    {
+                        _taskForAccept.SetException(BluetoothErrorFactory.CreateBluetoothException((int)e.Result));
+                    }
+                    _taskForAccept = null;
+                }
+
+                AcceptStateChanged?.Invoke(this, e);
+            }
+        }
+
         /// <summary>
         /// The AcceptStateChanged event is raised when the socket connection state is changed.
         /// </summary>
         /// <exception cref="InvalidOperationException">Thrown when the Bluetooth is not enabled
         /// or when the register accpet state changed callback fails.</exception>
         /// <since_tizen> 3 </since_tizen>
-        public event EventHandler<AcceptStateChangedEventArgs> AcceptStateChanged
+        public event EventHandler<AcceptStateChangedEventArgs> AcceptStateChanged;
+
+        private static event EventHandler<AcceptStateChangedEventArgs> StaticAcceptStateChanged
         {
             add
             {
@@ -57,22 +99,19 @@ namespace Tizen.Network.Bluetooth
             }
         }
 
-        private void RegisterAcceptStateChangedEvent()
+        private static void RegisterAcceptStateChangedEvent()
         {
             _connectionStateChangedCallback = (int result, BluetoothSocketState connectionState, ref SocketConnectionStruct socketConnection, IntPtr userData) =>
             {
                 Log.Info(Globals.LogTag, "AcceptStateChanged cb is called");
-                if (_acceptStateChanged != null)
-                {
-                    BluetoothSocket socket = new BluetoothSocket();
-                    socket.connectedSocket = socketConnection.SocketFd;
-                    GCHandle handle2 = (GCHandle) userData;
-                    _acceptStateChanged(handle2.Target as BluetoothServerSocket, new AcceptStateChangedEventArgs((BluetoothError)result, connectionState, BluetoothUtils.ConvertStructToSocketConnection(socketConnection), socket));
-                }
+                BluetoothSocket socket = new BluetoothSocket();
+                socket.connectedSocket = socketConnection.SocketFd;
+                socket.remoteAddress = socketConnection.Address;
+                socket.serviceUuid = socketConnection.ServiceUuid;
+                _acceptStateChanged?.Invoke(null, new AcceptStateChangedEventArgs((BluetoothError)result, connectionState, BluetoothUtils.ConvertStructToSocketConnection(socketConnection), socket));
             };
-            GCHandle handle1 = GCHandle.Alloc(this);
-            IntPtr data = (IntPtr) handle1;
-            int ret = Interop.Bluetooth.SetConnectionStateChangedCallback(_connectionStateChangedCallback, data);
+
+            int ret = Interop.Bluetooth.SetConnectionStateChangedCallback(_connectionStateChangedCallback, IntPtr.Zero);
             if (ret != (int)BluetoothError.None)
             {
                 Log.Error(Globals.LogTag, "Failed to set accept state changed callback, Error - " + (BluetoothError)ret);
@@ -80,7 +119,7 @@ namespace Tizen.Network.Bluetooth
             }
         }
 
-        private void UnregisterAcceptStateChangedEvent()
+        private static void UnregisterAcceptStateChangedEvent()
         {
             int ret = Interop.Bluetooth.UnsetSocketConnectionStateChangedCallback();
             if (ret != (int)BluetoothError.None)
@@ -116,7 +155,126 @@ namespace Tizen.Network.Bluetooth
         }
 
         /// <summary>
-        /// BluetoothServerSocket distructor.
+        /// Starts listening on the passed RFCOMM socket without accepting connection requests.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        /// <feature>http://tizen.org/feature/network.bluetooth</feature>
+        /// <privilege>http://tizen.org/privilege/bluetooth.admin</privilege>
+        /// <exception cref="NotSupportedException">Thrown when the Bluetooth is not supported.</exception>
+        /// <exception cref="InvalidOperationException">Thrown when the method is failed with message.</exception>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void ListenWithoutAccept()
+        {
+            int ret = Interop.Bluetooth.ListenWithoutAccept(socketFd, 1);
+            if (ret != (int)BluetoothError.None)
+            {
+                Log.Error(Globals.LogTag, "Failed to ListenWithoutAccept, Error - " + (BluetoothError)ret);
+                BluetoothErrorFactory.ThrowBluetoothException(ret);
+            }
+        }
+
+        /// <summary>
+        /// Accepts a connection request asynchronously.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        /// <returns> A task indicating whether the method is done or not.</returns>
+        /// <feature>http://tizen.org/feature/network.bluetooth</feature>
+        /// <privilege>http://tizen.org/privilege/bluetooth.admin</privilege>
+        /// <exception cref="NotSupportedException">Thrown when the Bluetooth is not supported.</exception>
+        /// <exception cref="InvalidOperationException">Thrown when the method is failed with message.</exception>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Task<SocketConnection> AcceptAsync()
+        {
+            if (_taskForAccept != null && !_taskForAccept.Task.IsCompleted)
+            {
+                BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NowInProgress);
+            }
+            _taskForAccept = new TaskCompletionSource<SocketConnection>();
+
+            int ret = Interop.Bluetooth.Accept(socketFd);
+            if (ret != (int)BluetoothError.None)
+            {
+                Log.Error(Globals.LogTag, "Failed to accept connection, Error - " + (BluetoothError)ret);
+                BluetoothErrorFactory.ThrowBluetoothException(ret);
+            }
+            return _taskForAccept.Task;
+        }
+
+        /// <summary>
+        /// Rejects a connection request.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        /// <feature>http://tizen.org/feature/network.bluetooth</feature>
+        /// <privilege>http://tizen.org/privilege/bluetooth.admin</privilege>
+        /// <exception cref="NotSupportedException">Thrown when the Bluetooth is not supported.</exception>
+        /// <exception cref="InvalidOperationException">Thrown when the method is failed with message.</exception>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void Reject()
+        {
+            int ret = Interop.Bluetooth.Reject(socketFd);
+            if (ret != (int)BluetoothError.None)
+            {
+                Log.Error(Globals.LogTag, "Failed to reject connection, Error - " + (BluetoothError)ret);
+                BluetoothErrorFactory.ThrowBluetoothException(ret);
+            }
+        }
+
+        /// <summary>
+        /// Registers a callback function that will be invoked when a RFCOMM connection is requested.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        /// <feature>http://tizen.org/feature/network.bluetooth</feature>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public event EventHandler<SocketConnectionRequestedEventArgs> ConnectionRequested;
+
+        private static event EventHandler<SocketConnectionRequestedEventArgs> StaticConnectionRequested
+        {
+            add
+            {
+                if (_connectionRequested == null)
+                {
+                    RegisterConnectionRequestedEvent();
+                }
+                _connectionRequested += value;
+            }
+            remove
+            {
+                _connectionRequested -= value;
+                if (_connectionRequested == null)
+                {
+                    UnregisterConnectionRequestedEvent();
+                }
+            }
+        }
+
+        private static void RegisterConnectionRequestedEvent()
+        {
+            _connectionRequestedCallback = (int socketFd, string remoteAddress, IntPtr userData) =>
+            {
+                Log.Info(Globals.LogTag, "SocketConnectionRequestedCallback is called");
+                _connectionRequested?.Invoke(null, new SocketConnectionRequestedEventArgs(socketFd, remoteAddress));
+            };
+
+            int ret = Interop.Bluetooth.SetSocketConnectionRequestedCallback(_connectionRequestedCallback, IntPtr.Zero);
+            if (ret != (int)BluetoothError.None)
+            {
+                Log.Error(Globals.LogTag, "Failed to set connection requested callback, Error - " + (BluetoothError)ret);
+                BluetoothErrorFactory.ThrowBluetoothException(ret);
+            }
+        }
+
+        private static void UnregisterConnectionRequestedEvent()
+        {
+            int ret = Interop.Bluetooth.UnsetSocketConnectionRequestedCallback();
+            if (ret != (int)BluetoothError.None)
+            {
+                Log.Error(Globals.LogTag, "Failed to unset connection requested callback, Error - " + (BluetoothError)ret);
+                BluetoothErrorFactory.ThrowBluetoothException(ret);
+            }
+        }
+
+        /// <summary>
+        /// BluetoothServerSocket destructor.
         /// </summary>
         ~BluetoothServerSocket()
         {
@@ -138,22 +296,14 @@ namespace Tizen.Network.Bluetooth
             if (disposed)
                 return;
 
-            if (disposing)
+            int ret = Interop.Bluetooth.DestroyServerSocket(socketFd);
+            if (ret != (int)BluetoothError.None)
             {
-                // Free managed objects.
+                Log.Error(Globals.LogTag, "Failed to destroy socket, Error - " + (BluetoothError)ret);
             }
-            //Free unmanaged objects
-            RemoveRegisteredEvents();
+            StaticAcceptStateChanged -= OnAcceptStateChanged;
+            StaticConnectionRequested -= OnConnectionRequested;
             disposed = true;
         }
-
-        private void RemoveRegisteredEvents()
-        {
-            //unregister all remaining events when this object is released.
-            if (_acceptStateChanged != null)
-            {
-                UnregisterAcceptStateChangedEvent();
-            }
-        }
     }
 }
index 35b8ba1..fc3ceb8 100644 (file)
@@ -48,7 +48,6 @@ namespace Tizen.Network.Bluetooth
         /// The connection must be established.
         /// </remarks>
         /// <param name="data">The data to be sent.</param>
-        /// <returns></returns>
         /// <since_tizen> 3 </since_tizen>
         int SendData(string data);
     }
index 55cb1d1..454d675 100644 (file)
@@ -397,6 +397,14 @@ namespace Tizen.Network.Bluetooth
             connectionInfo.Fd = structInfo.SocketFd;
             connectionInfo.RemoteAddress = structInfo.Address;
             connectionInfo.Uuid = structInfo.ServiceUuid;
+            connectionInfo.ServerFd = structInfo.ServerFd;
+
+            BluetoothSocket clientSocket = new BluetoothSocket();
+            clientSocket.connectedSocket = structInfo.SocketFd;
+            clientSocket.remoteAddress = structInfo.Address;
+            clientSocket.serviceUuid = structInfo.ServiceUuid;
+            connectionInfo.ClientSocket = (IBluetoothServerSocket)clientSocket;
+
             return connectionInfo;
         }
     }