2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 using System.Collections.Generic;
19 using System.Runtime.InteropServices;
21 namespace Tizen.Network.Bluetooth
23 static internal class Globals
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;
33 internal partial class BluetoothAdapterImpl : IDisposable
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;
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;
47 private static readonly BluetoothAdapterImpl _instance = new BluetoothAdapterImpl();
48 private bool disposed = false;
50 internal event EventHandler<StateChangedEventArgs> StateChanged
54 if (_stateChanged == null)
56 RegisterStateChangedEvent();
58 _stateChanged += value;
62 _stateChanged -= value;
63 if (_stateChanged == null)
65 UnregisterStateChangedEvent();
70 internal event EventHandler<NameChangedEventArgs> NameChanged
74 if (_nameChanged == null)
76 RegisterNameChangedEvent();
78 _nameChanged += value;
82 _nameChanged -= value;
83 if (_nameChanged == null)
85 UnregisterNameChangedEvent();
90 internal event EventHandler<VisibilityModeChangedEventArgs> VisibilityModeChanged
94 if (_visibilityModeChanged == null)
96 RegisterVisibilityChangedEvent();
98 _visibilityModeChanged += value;
102 _visibilityModeChanged -= value;
103 if (_visibilityModeChanged == null)
105 UnregisterVisibilityChangedEvent();
110 internal event EventHandler<VisibilityDurationChangedEventArgs> VisibilityDurationChanged
114 if (_visibilityDurationChanged == null)
116 RegisterVisibilityDurationChangedEvent();
118 _visibilityDurationChanged += value;
122 _visibilityDurationChanged -= value;
123 if (_visibilityDurationChanged == null)
125 UnregisterVisibilityDurationChangedEvent();
130 internal event EventHandler<DiscoveryStateChangedEventArgs> DiscoveryStateChanged
134 if (_discoveryStateChanged == null)
136 RegisterDiscoveryStateChangedEvent();
138 _discoveryStateChanged+= value;
142 _discoveryStateChanged -= value;
143 if (_discoveryStateChanged == null)
145 UnregisterDiscoveryStateChangedEvent();
150 private void RegisterStateChangedEvent()
152 _stateChangedCallback = (int result, int state, IntPtr userData) =>
154 if (_stateChanged != null)
156 BluetoothState st = (BluetoothState)state;
157 BluetoothError res = (BluetoothError)result;
158 _stateChanged(null, new StateChangedEventArgs(res,st));
161 int ret = Interop.Bluetooth.SetStateChangedCallback(_stateChangedCallback, IntPtr.Zero);
162 if (ret != (int)BluetoothError.None)
164 Log.Error(Globals.LogTag, "Failed to set state changed callback, Error - " + (BluetoothError)ret);
168 private void UnregisterStateChangedEvent()
170 int ret = Interop.Bluetooth.UnsetStateChangedCallback();
171 if (ret != (int)BluetoothError.None)
173 Log.Error(Globals.LogTag, "Failed to unset state changed callback, Error - " + (BluetoothError)ret);
177 private void RegisterNameChangedEvent()
179 _nameChangedCallback = (string deviceName, IntPtr userData) =>
181 if (_nameChanged != null)
183 _nameChanged(null, new NameChangedEventArgs(deviceName));
186 int ret = Interop.Bluetooth.SetNameChangedCallback(_nameChangedCallback, IntPtr.Zero);
187 if (ret != (int)BluetoothError.None)
189 Log.Error(Globals.LogTag, "Failed to set name changed callback, Error - " + (BluetoothError)ret);
193 private void UnregisterNameChangedEvent()
195 int ret = Interop.Bluetooth.UnsetNameChangedCallback();
196 if (ret != (int)BluetoothError.None)
198 Log.Error(Globals.LogTag, "Failed to unset name changed callback, Error - " + (BluetoothError)ret);
202 private void RegisterVisibilityChangedEvent()
204 _visibilityChangedCallback = (int result, int mode, IntPtr userData) =>
206 if (_visibilityModeChanged != null)
208 VisibilityMode visibility = (VisibilityMode)mode;
209 BluetoothError res = (BluetoothError)result;
210 _visibilityModeChanged(null, new VisibilityModeChangedEventArgs(res,visibility));
213 int ret = Interop.Bluetooth.SetVisibilityModeChangedCallback(_visibilityChangedCallback, IntPtr.Zero);
214 if (ret != (int)BluetoothError.None)
216 Log.Error(Globals.LogTag, "Failed to set visibility mode changed callback, Error - " + (BluetoothError)ret);
220 private void UnregisterVisibilityChangedEvent()
222 int ret = Interop.Bluetooth.UnsetVisibilityModeChangedCallback();
223 if (ret != (int)BluetoothError.None)
225 Log.Error(Globals.LogTag, "Failed to unset visibility mode changed callback, Error - " + (BluetoothError)ret);
229 private void RegisterVisibilityDurationChangedEvent()
231 _visibilitydurationChangedCallback = (int duration, IntPtr userData) =>
233 if (_visibilityDurationChanged != null)
235 _visibilityDurationChanged(null, new VisibilityDurationChangedEventArgs(duration));
238 int ret = Interop.Bluetooth.SetVisibilityDurationChangedCallback(_visibilitydurationChangedCallback, IntPtr.Zero);
239 if (ret != (int)BluetoothError.None)
241 Log.Error(Globals.LogTag, "Failed to set visibility duration changed callback, Error - " + (BluetoothError)ret);
245 private void UnregisterVisibilityDurationChangedEvent()
247 int ret = Interop.Bluetooth.UnsetVisibilityDurationChangedCallback();
248 if (ret != (int)BluetoothError.None)
250 Log.Error(Globals.LogTag, "Failed to unset visiiblity duration changed callback, Error - " + (BluetoothError)ret);
254 private void RegisterDiscoveryStateChangedEvent()
256 _discoveryStateChangedCallback = (int result, BluetoothDeviceDiscoveryState state, IntPtr deviceInfo, IntPtr userData) =>
258 Log.Info(Globals.LogTag, "Discovery state changed callback is called");
259 if (_discoveryStateChanged != null)
261 BluetoothError res = (BluetoothError)result;
264 case BluetoothDeviceDiscoveryState.Started:
265 _discoveryStateChanged(null, new DiscoveryStateChangedEventArgs(res,state));
267 case BluetoothDeviceDiscoveryState.Finished:
269 _discoveryStateChanged(null, new DiscoveryStateChangedEventArgs(res,state));
272 case BluetoothDeviceDiscoveryState.Found:
274 BluetoothDiscoveredDeviceStruct info = (BluetoothDiscoveredDeviceStruct)Marshal.PtrToStructure(deviceInfo, typeof(BluetoothDiscoveredDeviceStruct));
275 _discoveryStateChanged(null, new DiscoveryStateChangedEventArgs(res,state,BluetoothUtils.ConvertStructToDiscoveredDevice(info)));
283 int ret = Interop.Bluetooth.SetDiscoveryStateChangedCallback(_discoveryStateChangedCallback, IntPtr.Zero);
284 if (ret != (int)BluetoothError.None)
286 Log.Error(Globals.LogTag, "Failed to set discovery state changed callback, Error - " + (BluetoothError)ret);
290 private void UnregisterDiscoveryStateChangedEvent()
292 int ret = Interop.Bluetooth.UnsetDiscoveryStateChangedCallback();
293 if (ret != (int)BluetoothError.None)
295 Log.Error(Globals.LogTag, "Failed to unset discovery state changed callback, Error - " + (BluetoothError)ret);
299 internal bool IsBluetoothEnabled
303 BluetoothState active;
304 int ret = Interop.Bluetooth.GetState(out active);
305 if (ret != (int)BluetoothError.None)
307 Log.Error(Globals.LogTag, "Failed to get state, Error - " + (BluetoothError)ret);
309 if (active == BluetoothState.Enabled)
315 internal string Address
320 int ret = Interop.Bluetooth.GetAddress(out address);
321 if (ret != (int)BluetoothError.None)
323 Log.Error(Globals.LogTag, "Failed to get address, Error - " + (BluetoothError)ret);
330 internal VisibilityMode Visibility
336 int ret = Interop.Bluetooth.GetVisibility(out visibilityMode, out time);
337 if(ret != (int)BluetoothError.None)
339 Log.Error(Globals.LogTag, "Failed to get visibility mode, Error - " + (BluetoothError)ret);
340 return VisibilityMode.NonDiscoverable;
342 return (VisibilityMode)visibilityMode;
346 internal bool IsDiscoveryInProgress
351 int ret = Interop.Bluetooth.IsDiscovering(out isDiscovering);
352 if(ret != (int)BluetoothError.None)
354 Log.Error(Globals.LogTag, "Failed to get discovery progress state, Error - " + (BluetoothError)ret);
356 return isDiscovering;
360 internal int RemainingTimeAsVisible
366 int ret = Interop.Bluetooth.GetVisibility(out visibilityMode, out duration);
367 if ((ret != (int)BluetoothError.None) || ((VisibilityMode)visibilityMode != VisibilityMode.TimeLimitedDiscoverable))
369 Log.Error(Globals.LogTag, "Failed to get remaining visible time, Error - " + (BluetoothError)ret);
380 int ret = Interop.Bluetooth.GetName(out name);
381 if (ret != (int)BluetoothError.None)
383 Log.Error(Globals.LogTag, "Failed to get adapter name, Error - " + (BluetoothError)ret);
390 int ret = Interop.Bluetooth.SetName(value.ToString());
391 if (ret != (int)BluetoothError.None)
393 Log.Error(Globals.LogTag, "Failed to set adapter name, Error - " + (BluetoothError)ret);
394 BluetoothErrorFactory.ThrowBluetoothException(ret);
399 internal void StartDiscovery()
401 int ret = Interop.Bluetooth.StartDiscovery();
402 if (ret != (int)BluetoothError.None)
404 Log.Error(Globals.LogTag, "Failed to start discovery, Error - " + (BluetoothError)ret);
405 BluetoothErrorFactory.ThrowBluetoothException(ret);
409 internal void StopDiscovery()
411 int ret = Interop.Bluetooth.StopDiscovery();
412 if(ret != (int)BluetoothError.None)
414 Log.Error(Globals.LogTag, "Failed to stop discovery, Error - " + (BluetoothError)ret);
415 BluetoothErrorFactory.ThrowBluetoothException(ret);
419 internal IEnumerable<BluetoothDevice> GetBondedDevices()
421 List<BluetoothDevice> deviceList = new List<BluetoothDevice>();
422 Interop.Bluetooth.BondedDeviceCallback callback = (ref BluetoothDeviceStruct deviceInfo, IntPtr userData) =>
424 Log.Info(Globals.LogTag, "Bonded devices cb is called");
425 if(!deviceInfo.Equals(null))
427 deviceList.Add(BluetoothUtils.ConvertStructToDeviceClass(deviceInfo));
431 int ret = Interop.Bluetooth.GetBondedDevices(callback, IntPtr.Zero);
432 if(ret != (int)BluetoothError.None)
434 Log.Error(Globals.LogTag, "Failed to get bonded devices, Error - " + (BluetoothError)ret);
435 BluetoothErrorFactory.ThrowBluetoothException(ret);
440 internal BluetoothDevice GetBondedDevice(string address)
443 int ret = Interop.Bluetooth.GetBondedDeviceByAddress(address, out deviceInfo);
444 if(ret != (int)BluetoothError.None)
446 Log.Error(Globals.LogTag, "Failed to get bonded device by address, Error - " + (BluetoothError)ret);
447 BluetoothErrorFactory.ThrowBluetoothException(ret);
449 BluetoothDeviceStruct device = (BluetoothDeviceStruct)Marshal.PtrToStructure(deviceInfo, typeof(BluetoothDeviceStruct));
451 return BluetoothUtils.ConvertStructToDeviceClass(device);
454 internal bool IsServiceUsed(string serviceUuid)
457 int ret = Interop.Bluetooth.IsServiceUsed(serviceUuid, out isUsed);
458 if(ret != (int)BluetoothError.None)
460 Log.Error(Globals.LogTag, "Failed to check the usage of service, Error - " + (BluetoothError)ret);
465 internal BluetoothOobData GetLocalOobData()
467 BluetoothOobData oobData = new BluetoothOobData();
471 int randomizerLength;
472 int ret = Interop.Bluetooth.GetOobData(out hash, out randomizer, out hashLength, out randomizerLength);
473 if(ret != (int)BluetoothError.None)
475 Log.Error(Globals.LogTag, "Failed to get the local oob data, Error - " + (BluetoothError)ret);
476 BluetoothErrorFactory.ThrowBluetoothException(ret);
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);
484 oobData.HashValue = hashArr;
485 oobData.RandomizerValue = randomizerArr;
489 internal void SetRemoteOobData(string deviceAddress, BluetoothOobData oobData)
491 byte[] hash = oobData.HashValue;
492 byte[] randomizer = oobData.RandomizerValue;
493 int hashLength = hash.Length;
494 int randomizerLength = randomizer.Length;
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);
501 int ret = Interop.Bluetooth.SetOobData(deviceAddress, hashPtr, randomizerPtr, hashLength, randomizerLength);
502 if(ret != (int)BluetoothError.None)
504 Log.Error(Globals.LogTag, "Failed to set the remote oob data, Error - " + (BluetoothError)ret);
505 BluetoothErrorFactory.ThrowBluetoothException(ret);
509 internal void RemoveRemoteOobData(string deviceAddress)
511 int ret = Interop.Bluetooth.RemoveOobData(deviceAddress);
512 if(ret != (int)BluetoothError.None)
514 Log.Error(Globals.LogTag, "Failed to remove the remote oob data, Error - " + (BluetoothError)ret);
515 BluetoothErrorFactory.ThrowBluetoothException(ret);
519 internal BluetoothServerSocket CreateServerSocket(string serviceUuid)
522 int ret = Interop.Bluetooth.CreateServerSocket(serviceUuid, out socketFd);
523 if(ret != (int)BluetoothError.None)
525 Log.Error(Globals.LogTag, "Failed to create server socket, Error - " + (BluetoothError)ret);
526 BluetoothErrorFactory.ThrowBluetoothException(ret);
528 Log.Info (Globals.LogTag, "Created socketfd: "+ socketFd);
529 return new BluetoothServerSocket(socketFd);
532 internal void DestroyServerSocket(BluetoothServerSocket socket)
534 int ret = Interop.Bluetooth.DestroyServerSocket(socket.socketFd);
535 if (ret != (int)BluetoothError.None)
537 Log.Error(Globals.LogTag, "Failed to destroy socket, Error - " + (BluetoothError)ret);
538 BluetoothErrorFactory.ThrowBluetoothException(ret);
542 internal static BluetoothAdapterImpl Instance
550 private BluetoothAdapterImpl()
555 ~BluetoothAdapterImpl()
560 public void Dispose()
563 GC.SuppressFinalize(this);
566 private void Dispose(bool disposing)
573 // Free managed objects.
575 //Free unmanaged objects
576 RemoveAllRegisteredEvent();
581 private void initialize()
583 int ret = Interop.Bluetooth.Initialize();
584 if (ret != (int)BluetoothError.None)
586 Log.Error (Globals.LogTag, "Failed to initialize bluetooth, Error - " + (BluetoothError)ret);
587 BluetoothErrorFactory.ThrowBluetoothException (ret);
591 Globals.IsInitialize = true;
595 private void deinitialize()
597 int ret = Interop.Bluetooth.Deinitialize();
598 if (ret != (int)BluetoothError.None)
600 Log.Error (Globals.LogTag, "Failed to deinitialize bluetooth, Error - " + (BluetoothError)ret);
601 BluetoothErrorFactory.ThrowBluetoothException (ret);
605 Globals.IsInitialize = false;
609 private void RemoveAllRegisteredEvent()
611 //unregister all remaining events when this object is released.
612 if (_stateChanged != null)
614 UnregisterStateChangedEvent();
617 if (_nameChanged != null)
619 UnregisterNameChangedEvent();
622 if (_visibilityDurationChanged != null)
624 UnregisterVisibilityDurationChangedEvent();
627 if (_visibilityModeChanged != null)
629 UnregisterVisibilityChangedEvent();
632 if (_discoveryStateChanged != null)
634 UnregisterDiscoveryStateChangedEvent();