[Bluetooth][Non-ACR] GetBondedDevice converting issue (#2518)
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.Bluetooth / Tizen.Network.Bluetooth / BluetoothAdapterImpl.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     static internal class Globals
24     {
25         internal const string LogTag = "Tizen.Network.Bluetooth";
26         internal static bool IsInitialize = false;
27         internal static bool IsAudioInitialize = false;
28         internal static bool IsHidInitialize = false;
29         internal static bool IsOppServerInitialized = false;
30         internal static bool IsOppClientInitialized = false;
31     }
32
33     internal partial class BluetoothAdapterImpl : IDisposable
34     {
35         private event EventHandler<StateChangedEventArgs> _stateChanged;
36         private event EventHandler<NameChangedEventArgs> _nameChanged;
37         private event EventHandler<VisibilityModeChangedEventArgs> _visibilityModeChanged;
38         private event EventHandler<VisibilityDurationChangedEventArgs> _visibilityDurationChanged;
39         private event EventHandler<DiscoveryStateChangedEventArgs> _discoveryStateChanged;
40
41         private Interop.Bluetooth.StateChangedCallback _stateChangedCallback;
42         private Interop.Bluetooth.NameChangedCallback _nameChangedCallback;
43         private Interop.Bluetooth.VisibilityModeChangedCallback _visibilityChangedCallback;
44         private Interop.Bluetooth.VisibilityDurationChangedCallback _visibilitydurationChangedCallback;
45         private Interop.Bluetooth.DiscoveryStateChangedCallback _discoveryStateChangedCallback;
46         private Interop.Bluetooth.BondedDeviceCallback _bondedDeviceCallback;
47
48         private static readonly BluetoothAdapterImpl _instance = new BluetoothAdapterImpl();
49         private bool disposed = false;
50
51         internal event EventHandler<StateChangedEventArgs> StateChanged
52         {
53             add
54             {
55                 if (_stateChanged == null)
56                 {
57                     RegisterStateChangedEvent();
58                 }
59                 _stateChanged += value;
60             }
61             remove
62             {
63                 _stateChanged -= value;
64                 if (_stateChanged == null)
65                 {
66                     UnregisterStateChangedEvent();
67                 }
68             }
69         }
70
71         internal event EventHandler<NameChangedEventArgs> NameChanged
72         {
73             add
74             {
75                 if (_nameChanged == null)
76                 {
77                     RegisterNameChangedEvent();
78                 }
79                 _nameChanged += value;
80             }
81             remove
82             {
83                 _nameChanged -= value;
84                 if (_nameChanged == null)
85                 {
86                     UnregisterNameChangedEvent();
87                 }
88             }
89         }
90
91         internal event EventHandler<VisibilityModeChangedEventArgs> VisibilityModeChanged
92         {
93             add
94             {
95                 if (_visibilityModeChanged == null)
96                 {
97                     RegisterVisibilityChangedEvent();
98                 }
99                 _visibilityModeChanged += value;
100             }
101             remove
102             {
103                 _visibilityModeChanged -= value;
104                 if (_visibilityModeChanged == null)
105                 {
106                     UnregisterVisibilityChangedEvent();
107                 }
108             }
109         }
110
111         internal event EventHandler<VisibilityDurationChangedEventArgs> VisibilityDurationChanged
112         {
113             add
114             {
115                 if (_visibilityDurationChanged == null)
116                 {
117                     RegisterVisibilityDurationChangedEvent();
118                 }
119                 _visibilityDurationChanged += value;
120             }
121             remove
122             {
123                 _visibilityDurationChanged -= value;
124                 if (_visibilityDurationChanged == null)
125                 {
126                     UnregisterVisibilityDurationChangedEvent();
127                 }
128             }
129         }
130
131         internal event EventHandler<DiscoveryStateChangedEventArgs> DiscoveryStateChanged
132         {
133             add
134             {
135                 if (_discoveryStateChanged == null)
136                 {
137                     RegisterDiscoveryStateChangedEvent();
138                 }
139                 _discoveryStateChanged+= value;
140             }
141             remove
142             {
143                 _discoveryStateChanged -= value;
144                 if (_discoveryStateChanged == null)
145                 {
146                     UnregisterDiscoveryStateChangedEvent();
147                 }
148             }
149         }
150
151         private void RegisterStateChangedEvent()
152         {
153             _stateChangedCallback = (int result, int state, IntPtr userData) =>
154             {
155                 if (_stateChanged != null)
156                 {
157                     BluetoothState st = (BluetoothState)state;
158                     BluetoothError res = (BluetoothError)result;
159                     _stateChanged(null, new StateChangedEventArgs(res,st));
160                 }
161             };
162             int ret = Interop.Bluetooth.SetStateChangedCallback(_stateChangedCallback, IntPtr.Zero);
163             if (ret != (int)BluetoothError.None)
164             {
165                 Log.Error(Globals.LogTag, "Failed to set state changed callback, Error - " + (BluetoothError)ret);
166             }
167         }
168
169         private void UnregisterStateChangedEvent()
170         {
171             int ret = Interop.Bluetooth.UnsetStateChangedCallback();
172             if (ret != (int)BluetoothError.None)
173             {
174                 Log.Error(Globals.LogTag, "Failed to unset state changed callback, Error - " + (BluetoothError)ret);
175             }
176         }
177
178         private void RegisterNameChangedEvent()
179         {
180             _nameChangedCallback = (string deviceName, IntPtr userData) =>
181             {
182                 if (_nameChanged != null)
183                 {
184                     _nameChanged(null, new NameChangedEventArgs(deviceName));
185                 }
186             };
187             int ret = Interop.Bluetooth.SetNameChangedCallback(_nameChangedCallback, IntPtr.Zero);
188             if (ret != (int)BluetoothError.None)
189             {
190                 Log.Error(Globals.LogTag, "Failed to set name changed callback, Error - " + (BluetoothError)ret);
191             }
192         }
193
194         private void UnregisterNameChangedEvent()
195         {
196             int ret = Interop.Bluetooth.UnsetNameChangedCallback();
197             if (ret != (int)BluetoothError.None)
198             {
199                 Log.Error(Globals.LogTag, "Failed to unset name changed callback, Error - " + (BluetoothError)ret);
200             }
201         }
202
203         private void RegisterVisibilityChangedEvent()
204         {
205             _visibilityChangedCallback = (int result, int mode, IntPtr userData) =>
206             {
207                 if (_visibilityModeChanged != null)
208                 {
209                     VisibilityMode visibility = (VisibilityMode)mode;
210                     BluetoothError res = (BluetoothError)result;
211                     _visibilityModeChanged(null, new VisibilityModeChangedEventArgs(res,visibility));
212                 }
213             };
214             int ret = Interop.Bluetooth.SetVisibilityModeChangedCallback(_visibilityChangedCallback, IntPtr.Zero);
215             if (ret != (int)BluetoothError.None)
216             {
217                 Log.Error(Globals.LogTag, "Failed to set visibility mode changed callback, Error - " + (BluetoothError)ret);
218             }
219         }
220
221         private void UnregisterVisibilityChangedEvent()
222         {
223             int ret = Interop.Bluetooth.UnsetVisibilityModeChangedCallback();
224             if (ret != (int)BluetoothError.None)
225             {
226                 Log.Error(Globals.LogTag, "Failed to unset visibility mode changed callback, Error - " + (BluetoothError)ret);
227             }
228         }
229
230         private void RegisterVisibilityDurationChangedEvent()
231         {
232             _visibilitydurationChangedCallback = (int duration, IntPtr userData) =>
233             {
234                 if (_visibilityDurationChanged != null)
235                 {
236                     _visibilityDurationChanged(null, new VisibilityDurationChangedEventArgs(duration));
237                 }
238             };
239             int ret = Interop.Bluetooth.SetVisibilityDurationChangedCallback(_visibilitydurationChangedCallback, IntPtr.Zero);
240             if (ret != (int)BluetoothError.None)
241             {
242                 Log.Error(Globals.LogTag, "Failed to set visibility duration changed callback, Error - " + (BluetoothError)ret);
243             }
244         }
245
246         private void UnregisterVisibilityDurationChangedEvent()
247         {
248             int ret = Interop.Bluetooth.UnsetVisibilityDurationChangedCallback();
249             if (ret != (int)BluetoothError.None)
250             {
251                 Log.Error(Globals.LogTag, "Failed to unset visiiblity duration changed callback, Error - " + (BluetoothError)ret);
252             }
253         }
254
255         private void RegisterDiscoveryStateChangedEvent()
256         {
257             _discoveryStateChangedCallback = (int result, BluetoothDeviceDiscoveryState state, IntPtr deviceInfo, IntPtr userData) =>
258             {
259                 Log.Info(Globals.LogTag, "Discovery state changed callback is called");
260                 if (_discoveryStateChanged != null)
261                 {
262                     BluetoothError res = (BluetoothError)result;
263                     switch(state)
264                     {
265                     case BluetoothDeviceDiscoveryState.Started:
266                         _discoveryStateChanged(null, new DiscoveryStateChangedEventArgs(res,state));
267                         break;
268                     case BluetoothDeviceDiscoveryState.Finished:
269                         {
270                             _discoveryStateChanged(null, new DiscoveryStateChangedEventArgs(res,state));
271                             break;
272                         }
273                     case BluetoothDeviceDiscoveryState.Found:
274                         {
275                             BluetoothDiscoveredDeviceStruct info = (BluetoothDiscoveredDeviceStruct)Marshal.PtrToStructure(deviceInfo, typeof(BluetoothDiscoveredDeviceStruct));
276                             _discoveryStateChanged(null, new DiscoveryStateChangedEventArgs(res,state,BluetoothUtils.ConvertStructToDiscoveredDevice(info)));
277                             break;
278                         }
279                     default:
280                         break;
281                     }
282                 }
283             };
284             int ret = Interop.Bluetooth.SetDiscoveryStateChangedCallback(_discoveryStateChangedCallback, IntPtr.Zero);
285             if (ret != (int)BluetoothError.None)
286             {
287                 Log.Error(Globals.LogTag, "Failed to set discovery state changed callback, Error - " + (BluetoothError)ret);
288             }
289         }
290
291         private void UnregisterDiscoveryStateChangedEvent()
292         {
293             int ret = Interop.Bluetooth.UnsetDiscoveryStateChangedCallback();
294             if (ret != (int)BluetoothError.None)
295             {
296                 Log.Error(Globals.LogTag, "Failed to unset discovery state changed callback, Error - " + (BluetoothError)ret);
297             }
298         }
299
300         internal bool IsBluetoothEnabled
301         {
302             get
303             {
304                 BluetoothState active;
305                 int ret = Interop.Bluetooth.GetState(out active);
306                 if (ret != (int)BluetoothError.None)
307                 {
308                     Log.Error(Globals.LogTag, "Failed to get state, Error - " + (BluetoothError)ret);
309                 }
310                 if (active == BluetoothState.Enabled)
311                     return true;
312                 else
313                     return false;
314             }
315         }
316         internal string Address
317         {
318             get
319             {
320                 string address;
321                 int ret = Interop.Bluetooth.GetAddress(out address);
322                 if (ret != (int)BluetoothError.None)
323                 {
324                     Log.Error(Globals.LogTag, "Failed to get address, Error - " + (BluetoothError)ret);
325                     return "";
326                 }
327                 return address;
328             }
329         }
330
331         internal VisibilityMode Visibility
332         {
333             get
334             {
335                 int visibilityMode;
336                 int time;
337                 int ret = Interop.Bluetooth.GetVisibility(out visibilityMode, out time);
338                 if(ret != (int)BluetoothError.None)
339                 {
340                     Log.Error(Globals.LogTag, "Failed to get visibility mode, Error - " + (BluetoothError)ret);
341                     return VisibilityMode.NonDiscoverable;
342                 }
343                 return (VisibilityMode)visibilityMode;
344             }
345         }
346
347         internal bool IsDiscoveryInProgress
348         {
349             get
350             {
351                 bool isDiscovering;
352                 int ret = Interop.Bluetooth.IsDiscovering(out isDiscovering);
353                 if(ret != (int)BluetoothError.None)
354                 {
355                     Log.Error(Globals.LogTag, "Failed to get discovery progress state, Error - " + (BluetoothError)ret);
356                 }
357                 return isDiscovering;
358             }
359         }
360
361         internal int RemainingTimeAsVisible
362         {
363             get
364             {
365                 int duration = 0;
366                 int visibilityMode;
367                 int ret = Interop.Bluetooth.GetVisibility(out visibilityMode, out duration);
368                 if ((ret != (int)BluetoothError.None) || ((VisibilityMode)visibilityMode != VisibilityMode.TimeLimitedDiscoverable))
369                 {
370                     Log.Error(Globals.LogTag, "Failed to get remaining visible time, Error - " + (BluetoothError)ret);
371                 }
372                 return duration;
373             }
374         }
375
376         internal string Name
377         {
378             get
379             {
380                 string name;
381                 int ret = Interop.Bluetooth.GetName(out name);
382                 if (ret != (int)BluetoothError.None)
383                 {
384                     Log.Error(Globals.LogTag, "Failed to get adapter name, Error - " + (BluetoothError)ret);
385                     return "";
386                 }
387                 return name;
388             }
389             set
390             {
391                 int ret = Interop.Bluetooth.SetName(value.ToString());
392                 if (ret != (int)BluetoothError.None)
393                 {
394                     Log.Error(Globals.LogTag, "Failed to set adapter name, Error - " + (BluetoothError)ret);
395                     BluetoothErrorFactory.ThrowBluetoothException(ret);
396                 }
397             }
398         }
399
400         internal void Enable()
401         {
402             if (Globals.IsInitialize)
403             {
404                 int ret = Interop.Bluetooth.EnableAdapter();
405                 if (ret != (int)BluetoothError.None)
406                 {
407                     Log.Error(Globals.LogTag, "Failed to enable adapter, Error - " + (BluetoothError)ret);
408                     BluetoothErrorFactory.ThrowBluetoothException(ret);
409                 }
410             }
411             else
412             {
413                 BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotInitialized);
414             }
415         }
416
417         internal void Disable()
418         {
419             if (IsBluetoothEnabled)
420             {
421                 int ret = Interop.Bluetooth.DisableAdapter();
422                 if (ret != (int)BluetoothError.None)
423                 {
424                     Log.Error(Globals.LogTag, "Failed to disable adapter, Error - " + (BluetoothError)ret);
425                     BluetoothErrorFactory.ThrowBluetoothException(ret);
426                 }
427             }
428             else
429             {
430                 BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
431             }
432         }
433
434         internal void SetVisibility(VisibilityMode mode, int timeout)
435         {
436             if (IsBluetoothEnabled)
437             {
438                 int ret = Interop.Bluetooth.SetVisibility(mode, timeout);
439                 if (ret != (int)BluetoothError.None)
440                 {
441                     Log.Error(Globals.LogTag, "Failed to set visibility, Error - " + (BluetoothError)ret);
442                     BluetoothErrorFactory.ThrowBluetoothException(ret);
443                 }
444             }
445             else
446             {
447                 BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
448             }
449         }
450
451         internal void StartDiscovery()
452         {
453             int ret = Interop.Bluetooth.StartDiscovery();
454             if (ret != (int)BluetoothError.None)
455             {
456                 Log.Error(Globals.LogTag, "Failed to start discovery, Error - " + (BluetoothError)ret);
457                 BluetoothErrorFactory.ThrowBluetoothException(ret);
458             }
459         }
460
461         internal void StopDiscovery()
462         {
463             int ret = Interop.Bluetooth.StopDiscovery();
464             if(ret != (int)BluetoothError.None)
465             {
466                 Log.Error(Globals.LogTag, "Failed to stop discovery, Error - " + (BluetoothError)ret);
467                 BluetoothErrorFactory.ThrowBluetoothException(ret);
468             }
469         }
470
471         internal IEnumerable<BluetoothDevice> GetBondedDevices()
472         {
473             List<BluetoothDevice> deviceList = new List<BluetoothDevice>();
474             _bondedDeviceCallback = (ref BluetoothDeviceStruct deviceInfo, IntPtr userData) =>
475             {
476                 Log.Info(Globals.LogTag, "Bonded devices cb is called");
477                 if(!deviceInfo.Equals(null))
478                 {
479                     deviceList.Add(BluetoothUtils.ConvertStructToDeviceClass(deviceInfo));
480                 }
481                 return true;
482             };
483             int ret = Interop.Bluetooth.GetBondedDevices(_bondedDeviceCallback, IntPtr.Zero);
484             if(ret != (int)BluetoothError.None)
485             {
486                 Log.Error(Globals.LogTag, "Failed to get bonded devices, Error - " + (BluetoothError)ret);
487                 BluetoothErrorFactory.ThrowBluetoothException(ret);
488             }
489             return deviceList;
490         }
491
492         internal BluetoothDevice GetBondedDevice(string address)
493         {
494             IntPtr deviceInfo;
495             BluetoothDevice btDevice;
496             int ret = Interop.Bluetooth.GetBondedDeviceByAddress(address, out deviceInfo);
497             if(ret != (int)BluetoothError.None)
498             {
499                 Log.Error(Globals.LogTag, "Failed to get bonded device by address, Error - " + (BluetoothError)ret);
500                 BluetoothErrorFactory.ThrowBluetoothException(ret);
501             }
502             BluetoothDeviceStruct device = (BluetoothDeviceStruct)Marshal.PtrToStructure(deviceInfo, typeof(BluetoothDeviceStruct));
503             btDevice = BluetoothUtils.ConvertStructToDeviceClass(device);
504             Interop.Bluetooth.FreeDeviceInfo(deviceInfo);
505             return btDevice;
506         }
507
508         internal bool IsServiceUsed(string serviceUuid)
509         {
510             bool isUsed;
511             int ret = Interop.Bluetooth.IsServiceUsed(serviceUuid, out isUsed);
512             if(ret != (int)BluetoothError.None)
513             {
514                 Log.Error(Globals.LogTag, "Failed to check the usage of service, Error - " + (BluetoothError)ret);
515             }
516             return isUsed;
517         }
518
519         internal BluetoothOobData GetLocalOobData()
520         {
521             BluetoothOobData oobData = new BluetoothOobData();
522             IntPtr hash;
523             IntPtr randomizer;
524             int hashLength;
525             int randomizerLength;
526             int ret = Interop.Bluetooth.GetOobData(out hash, out randomizer, out hashLength, out randomizerLength);
527             if(ret != (int)BluetoothError.None)
528             {
529                 Log.Error(Globals.LogTag, "Failed to get the local oob data, Error - " + (BluetoothError)ret);
530                 BluetoothErrorFactory.ThrowBluetoothException(ret);
531             }
532
533             byte[] hashArr = new byte[hashLength];
534             Marshal.Copy(hash, hashArr, 0, hashLength);
535             byte[] randomizerArr = new byte[randomizerLength];
536             Marshal.Copy(randomizer, randomizerArr, 0, randomizerLength);
537
538             oobData.HashValue = hashArr;
539             oobData.RandomizerValue = randomizerArr;
540             return oobData;
541         }
542
543         internal void SetRemoteOobData(string deviceAddress, BluetoothOobData oobData)
544         {
545             byte[] hash = oobData.HashValue;
546             byte[] randomizer = oobData.RandomizerValue;
547             int hashLength = hash.Length;
548             int randomizerLength = randomizer.Length;
549
550             IntPtr hashPtr = Marshal.AllocHGlobal(hashLength);
551             Marshal.Copy(hash, 0, hashPtr, hashLength);
552             IntPtr randomizerPtr = Marshal.AllocHGlobal(randomizerLength);
553             Marshal.Copy(randomizer, 0, randomizerPtr, randomizerLength);
554
555             int ret = Interop.Bluetooth.SetOobData(deviceAddress, hashPtr, randomizerPtr, hashLength, randomizerLength);
556             if(ret != (int)BluetoothError.None)
557             {
558                 Log.Error(Globals.LogTag, "Failed to set the remote oob data, Error - " + (BluetoothError)ret);
559                 BluetoothErrorFactory.ThrowBluetoothException(ret);
560             }
561         }
562
563         internal void RemoveRemoteOobData(string deviceAddress)
564         {
565             int ret = Interop.Bluetooth.RemoveOobData(deviceAddress);
566             if(ret != (int)BluetoothError.None)
567             {
568                 Log.Error(Globals.LogTag, "Failed to remove the remote oob data, Error - " + (BluetoothError)ret);
569                 BluetoothErrorFactory.ThrowBluetoothException(ret);
570             }
571         }
572
573         internal BluetoothServerSocket CreateServerSocket(string serviceUuid)
574         {
575             int socketFd;
576             int ret = Interop.Bluetooth.CreateServerSocket(serviceUuid, out socketFd);
577             if(ret != (int)BluetoothError.None)
578             {
579                 Log.Error(Globals.LogTag, "Failed to create server socket, Error - " + (BluetoothError)ret);
580                 BluetoothErrorFactory.ThrowBluetoothException(ret);
581             }
582             Log.Info (Globals.LogTag, "Created socketfd: "+ socketFd);
583             return new BluetoothServerSocket(socketFd);
584         }
585
586         internal void DestroyServerSocket(BluetoothServerSocket socket)
587         {
588             int ret = Interop.Bluetooth.DestroyServerSocket(socket.socketFd);
589             if (ret != (int)BluetoothError.None)
590             {
591                 Log.Error(Globals.LogTag, "Failed to destroy socket, Error - " + (BluetoothError)ret);
592                 BluetoothErrorFactory.ThrowBluetoothException(ret);
593             }
594         }
595
596         internal static BluetoothAdapterImpl Instance
597         {
598             get
599             {
600                 return _instance;
601             }
602         }
603
604         private BluetoothAdapterImpl()
605         {
606             initialize();
607         }
608
609         ~BluetoothAdapterImpl()
610         {
611             Dispose(false);
612         }
613
614         public void Dispose()
615         {
616             Dispose(true);
617             GC.SuppressFinalize(this);
618         }
619
620         private void Dispose(bool disposing)
621         {
622             if (disposed)
623                 return;
624
625             if (disposing)
626             {
627                 // Free managed objects.
628             }
629             //Free unmanaged objects
630             RemoveAllRegisteredEvent();
631             deinitialize();
632             disposed = true;
633         }
634
635         private void initialize()
636         {
637             int ret = Interop.Bluetooth.Initialize();
638             if (ret != (int)BluetoothError.None)
639             {
640                 Log.Error (Globals.LogTag, "Failed to initialize bluetooth, Error - " + (BluetoothError)ret);
641                 BluetoothErrorFactory.ThrowBluetoothException (ret);
642             }
643             else
644             {
645                 Globals.IsInitialize = true;
646             }
647         }
648
649         private void deinitialize()
650         {
651             int ret = Interop.Bluetooth.Deinitialize();
652             if (ret != (int)BluetoothError.None)
653             {
654                 Log.Error (Globals.LogTag, "Failed to deinitialize bluetooth, Error - " + (BluetoothError)ret);
655             }
656             else
657             {
658                 Globals.IsInitialize = false;
659             }
660         }
661
662         private void RemoveAllRegisteredEvent()
663         {
664             //unregister all remaining events when this object is released.
665             if (_stateChanged != null)
666             {
667                 UnregisterStateChangedEvent();
668             }
669
670             if (_nameChanged != null)
671             {
672                 UnregisterNameChangedEvent();
673             }
674
675             if (_visibilityDurationChanged != null)
676             {
677                 UnregisterVisibilityDurationChangedEvent();
678             }
679
680             if (_visibilityModeChanged != null)
681             {
682                 UnregisterVisibilityChangedEvent();
683             }
684
685             if (_discoveryStateChanged != null)
686             {
687                 UnregisterDiscoveryStateChangedEvent();
688             }
689         }
690     }
691 }