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