Release 4.0.0-preview1-00285
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.Bluetooth / Tizen.Network.Bluetooth / BluetoothServerSocket.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.Collections.Generic;
19 using System.Runtime.InteropServices;
20
21 namespace Tizen.Network.Bluetooth
22 {
23     /// <summary>
24     /// The BluetoothSocket provides functions for managing connections to other devices and exchanging data.
25     /// </summary>
26     public class BluetoothServerSocket : IDisposable
27     {
28         private event EventHandler<AcceptStateChangedEventArgs> _acceptStateChanged;
29         private Interop.Bluetooth.SocketConnectionStateChangedCallback _connectionStateChangedCallback;
30         internal int socketFd;
31         private bool disposed = false;
32
33         /// <summary>
34         /// The AcceptStateChanged event is raised when the socket connection state is changed.
35         /// </summary>
36         /// <exception cref="InvalidOperationException">Thrown when the Bluetooth is not enabled
37         /// or when the register accpet state changed callback fails.</exception>
38         public event EventHandler<AcceptStateChangedEventArgs> AcceptStateChanged
39         {
40             add
41             {
42                 if (_acceptStateChanged == null)
43                 {
44                     RegisterAcceptStateChangedEvent();
45                 }
46                 _acceptStateChanged += value;
47             }
48             remove
49             {
50                 _acceptStateChanged -= value;
51                 if (_acceptStateChanged == null)
52                 {
53                     UnregisterAcceptStateChangedEvent();
54                 }
55             }
56         }
57
58         private void RegisterAcceptStateChangedEvent()
59         {
60             _connectionStateChangedCallback = (int result, BluetoothSocketState connectionState, ref SocketConnectionStruct socketConnection, IntPtr userData) =>
61             {
62                 Log.Info(Globals.LogTag, "AcceptStateChanged cb is called");
63                 if (_acceptStateChanged != null)
64                 {
65                     BluetoothSocket socket = new BluetoothSocket();
66                     socket.connectedSocket = socketConnection.SocketFd;
67                     GCHandle handle2 = (GCHandle) userData;
68                     _acceptStateChanged(handle2.Target as BluetoothServerSocket, new AcceptStateChangedEventArgs((BluetoothError)result, connectionState, BluetoothUtils.ConvertStructToSocketConnection(socketConnection), socket));
69                 }
70             };
71             GCHandle handle1 = GCHandle.Alloc(this);
72             IntPtr data = (IntPtr) handle1;
73             int ret = Interop.Bluetooth.SetConnectionStateChangedCallback(_connectionStateChangedCallback, data);
74             if (ret != (int)BluetoothError.None)
75             {
76                 Log.Error(Globals.LogTag, "Failed to set accept state changed callback, Error - " + (BluetoothError)ret);
77                 BluetoothErrorFactory.ThrowBluetoothException(ret);
78             }
79         }
80
81         private void UnregisterAcceptStateChangedEvent()
82         {
83             int ret = Interop.Bluetooth.UnsetSocketConnectionStateChangedCallback();
84             if (ret != (int)BluetoothError.None)
85             {
86                 Log.Error(Globals.LogTag, "Failed to unset accept state changed callback, Error - " + (BluetoothError)ret);
87                 BluetoothErrorFactory.ThrowBluetoothException(ret);
88             }
89         }
90
91         internal BluetoothServerSocket(int socketFd)
92         {
93             Log.Info (Globals.LogTag, "Constructing server socket");
94             this.socketFd = socketFd;
95         }
96
97         /// <summary>
98         /// Starts listening on the passed RFCOMM socket and accepts connection requests.
99         /// </summary>
100         /// <remarks>
101         /// The socket must be created with CreateServerSocket(). This API invokes the ConnectionStateChanged event.
102         /// </remarks>
103         /// <exception cref="InvalidOperationException">Thrown when the Bluetooth is not enabled
104         /// or when the listen on socket procedure fails.</exception>
105         public void Listen()
106         {
107             int ret = Interop.Bluetooth.Listen(socketFd, 1);
108             if (ret != (int)BluetoothError.None)
109             {
110                 Log.Error(Globals.LogTag, "Failed to accept connection, Error - " + (BluetoothError)ret);
111                 BluetoothErrorFactory.ThrowBluetoothException(ret);
112             }
113         }
114
115         /// <summary>
116         /// BluetoothServerSocket distructor.
117         /// </summary>
118         ~BluetoothServerSocket()
119         {
120             Dispose(false);
121         }
122
123         /// <summary>
124         /// Dispose
125         /// </summary>
126         public void Dispose()
127         {
128             Dispose(true);
129             GC.SuppressFinalize(this);
130         }
131
132         private void Dispose(bool disposing)
133         {
134             if (disposed)
135                 return;
136
137             if (disposing)
138             {
139                 // Free managed objects.
140             }
141             //Free unmanaged objects
142             RemoveRegisteredEvents();
143             disposed = true;
144         }
145
146         private void RemoveRegisteredEvents()
147         {
148             //unregister all remaining events when this object is released.
149             if (_acceptStateChanged != null)
150             {
151                 UnregisterAcceptStateChangedEvent();
152             }
153         }
154     }
155 }