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;
46 private Interop.Bluetooth.BondedDeviceCallback _bondedDeviceCallback;
48 private static readonly BluetoothAdapterImpl _instance = new BluetoothAdapterImpl();
49 private bool disposed = false;
51 internal event EventHandler<StateChangedEventArgs> StateChanged
55 if (_stateChanged == null)
57 RegisterStateChangedEvent();
59 _stateChanged += value;
63 _stateChanged -= value;
64 if (_stateChanged == null)
66 UnregisterStateChangedEvent();
71 internal event EventHandler<NameChangedEventArgs> NameChanged
75 if (_nameChanged == null)
77 RegisterNameChangedEvent();
79 _nameChanged += value;
83 _nameChanged -= value;
84 if (_nameChanged == null)
86 UnregisterNameChangedEvent();
91 internal event EventHandler<VisibilityModeChangedEventArgs> VisibilityModeChanged
95 if (_visibilityModeChanged == null)
97 RegisterVisibilityChangedEvent();
99 _visibilityModeChanged += value;
103 _visibilityModeChanged -= value;
104 if (_visibilityModeChanged == null)
106 UnregisterVisibilityChangedEvent();
111 internal event EventHandler<VisibilityDurationChangedEventArgs> VisibilityDurationChanged
115 if (_visibilityDurationChanged == null)
117 RegisterVisibilityDurationChangedEvent();
119 _visibilityDurationChanged += value;
123 _visibilityDurationChanged -= value;
124 if (_visibilityDurationChanged == null)
126 UnregisterVisibilityDurationChangedEvent();
131 internal event EventHandler<DiscoveryStateChangedEventArgs> DiscoveryStateChanged
135 if (_discoveryStateChanged == null)
137 RegisterDiscoveryStateChangedEvent();
139 _discoveryStateChanged+= value;
143 _discoveryStateChanged -= value;
144 if (_discoveryStateChanged == null)
146 UnregisterDiscoveryStateChangedEvent();
151 private void RegisterStateChangedEvent()
153 _stateChangedCallback = (int result, int state, IntPtr userData) =>
155 if (_stateChanged != null)
157 BluetoothState st = (BluetoothState)state;
158 BluetoothError res = (BluetoothError)result;
159 _stateChanged(null, new StateChangedEventArgs(res,st));
162 int ret = Interop.Bluetooth.SetStateChangedCallback(_stateChangedCallback, IntPtr.Zero);
163 if (ret != (int)BluetoothError.None)
165 Log.Error(Globals.LogTag, "Failed to set state changed callback, Error - " + (BluetoothError)ret);
169 private void UnregisterStateChangedEvent()
171 int ret = Interop.Bluetooth.UnsetStateChangedCallback();
172 if (ret != (int)BluetoothError.None)
174 Log.Error(Globals.LogTag, "Failed to unset state changed callback, Error - " + (BluetoothError)ret);
178 private void RegisterNameChangedEvent()
180 _nameChangedCallback = (string deviceName, IntPtr userData) =>
182 if (_nameChanged != null)
184 _nameChanged(null, new NameChangedEventArgs(deviceName));
187 int ret = Interop.Bluetooth.SetNameChangedCallback(_nameChangedCallback, IntPtr.Zero);
188 if (ret != (int)BluetoothError.None)
190 Log.Error(Globals.LogTag, "Failed to set name changed callback, Error - " + (BluetoothError)ret);
194 private void UnregisterNameChangedEvent()
196 int ret = Interop.Bluetooth.UnsetNameChangedCallback();
197 if (ret != (int)BluetoothError.None)
199 Log.Error(Globals.LogTag, "Failed to unset name changed callback, Error - " + (BluetoothError)ret);
203 private void RegisterVisibilityChangedEvent()
205 _visibilityChangedCallback = (int result, int mode, IntPtr userData) =>
207 if (_visibilityModeChanged != null)
209 VisibilityMode visibility = (VisibilityMode)mode;
210 BluetoothError res = (BluetoothError)result;
211 _visibilityModeChanged(null, new VisibilityModeChangedEventArgs(res,visibility));
214 int ret = Interop.Bluetooth.SetVisibilityModeChangedCallback(_visibilityChangedCallback, IntPtr.Zero);
215 if (ret != (int)BluetoothError.None)
217 Log.Error(Globals.LogTag, "Failed to set visibility mode changed callback, Error - " + (BluetoothError)ret);
221 private void UnregisterVisibilityChangedEvent()
223 int ret = Interop.Bluetooth.UnsetVisibilityModeChangedCallback();
224 if (ret != (int)BluetoothError.None)
226 Log.Error(Globals.LogTag, "Failed to unset visibility mode changed callback, Error - " + (BluetoothError)ret);
230 private void RegisterVisibilityDurationChangedEvent()
232 _visibilitydurationChangedCallback = (int duration, IntPtr userData) =>
234 if (_visibilityDurationChanged != null)
236 _visibilityDurationChanged(null, new VisibilityDurationChangedEventArgs(duration));
239 int ret = Interop.Bluetooth.SetVisibilityDurationChangedCallback(_visibilitydurationChangedCallback, IntPtr.Zero);
240 if (ret != (int)BluetoothError.None)
242 Log.Error(Globals.LogTag, "Failed to set visibility duration changed callback, Error - " + (BluetoothError)ret);
246 private void UnregisterVisibilityDurationChangedEvent()
248 int ret = Interop.Bluetooth.UnsetVisibilityDurationChangedCallback();
249 if (ret != (int)BluetoothError.None)
251 Log.Error(Globals.LogTag, "Failed to unset visiiblity duration changed callback, Error - " + (BluetoothError)ret);
255 private void RegisterDiscoveryStateChangedEvent()
257 _discoveryStateChangedCallback = (int result, BluetoothDeviceDiscoveryState state, IntPtr deviceInfo, IntPtr userData) =>
259 Log.Info(Globals.LogTag, "Discovery state changed callback is called");
260 if (_discoveryStateChanged != null)
262 BluetoothError res = (BluetoothError)result;
265 case BluetoothDeviceDiscoveryState.Started:
266 _discoveryStateChanged(null, new DiscoveryStateChangedEventArgs(res,state));
268 case BluetoothDeviceDiscoveryState.Finished:
270 _discoveryStateChanged(null, new DiscoveryStateChangedEventArgs(res,state));
273 case BluetoothDeviceDiscoveryState.Found:
275 BluetoothDiscoveredDeviceStruct info = (BluetoothDiscoveredDeviceStruct)Marshal.PtrToStructure(deviceInfo, typeof(BluetoothDiscoveredDeviceStruct));
276 _discoveryStateChanged(null, new DiscoveryStateChangedEventArgs(res,state,BluetoothUtils.ConvertStructToDiscoveredDevice(info)));
284 int ret = Interop.Bluetooth.SetDiscoveryStateChangedCallback(_discoveryStateChangedCallback, IntPtr.Zero);
285 if (ret != (int)BluetoothError.None)
287 Log.Error(Globals.LogTag, "Failed to set discovery state changed callback, Error - " + (BluetoothError)ret);
291 private void UnregisterDiscoveryStateChangedEvent()
293 int ret = Interop.Bluetooth.UnsetDiscoveryStateChangedCallback();
294 if (ret != (int)BluetoothError.None)
296 Log.Error(Globals.LogTag, "Failed to unset discovery state changed callback, Error - " + (BluetoothError)ret);
300 internal bool IsBluetoothEnabled
304 BluetoothState active;
305 int ret = Interop.Bluetooth.GetState(out active);
306 if (ret != (int)BluetoothError.None)
308 Log.Error(Globals.LogTag, "Failed to get state, Error - " + (BluetoothError)ret);
310 if (active == BluetoothState.Enabled)
316 internal string Address
321 int ret = Interop.Bluetooth.GetAddress(out address);
322 if (ret != (int)BluetoothError.None)
324 Log.Error(Globals.LogTag, "Failed to get address, Error - " + (BluetoothError)ret);
331 internal VisibilityMode Visibility
337 int ret = Interop.Bluetooth.GetVisibility(out visibilityMode, out time);
338 if(ret != (int)BluetoothError.None)
340 Log.Error(Globals.LogTag, "Failed to get visibility mode, Error - " + (BluetoothError)ret);
341 return VisibilityMode.NonDiscoverable;
343 return (VisibilityMode)visibilityMode;
347 internal bool IsDiscoveryInProgress
352 int ret = Interop.Bluetooth.IsDiscovering(out isDiscovering);
353 if(ret != (int)BluetoothError.None)
355 Log.Error(Globals.LogTag, "Failed to get discovery progress state, Error - " + (BluetoothError)ret);
357 return isDiscovering;
361 internal int RemainingTimeAsVisible
367 int ret = Interop.Bluetooth.GetVisibility(out visibilityMode, out duration);
368 if ((ret != (int)BluetoothError.None) || ((VisibilityMode)visibilityMode != VisibilityMode.TimeLimitedDiscoverable))
370 Log.Error(Globals.LogTag, "Failed to get remaining visible time, Error - " + (BluetoothError)ret);
381 int ret = Interop.Bluetooth.GetName(out name);
382 if (ret != (int)BluetoothError.None)
384 Log.Error(Globals.LogTag, "Failed to get adapter name, Error - " + (BluetoothError)ret);
391 int ret = Interop.Bluetooth.SetName(value.ToString());
392 if (ret != (int)BluetoothError.None)
394 Log.Error(Globals.LogTag, "Failed to set adapter name, Error - " + (BluetoothError)ret);
395 BluetoothErrorFactory.ThrowBluetoothException(ret);
400 internal void Enable()
402 if (Globals.IsInitialize)
404 int ret = Interop.Bluetooth.EnableAdapter();
405 if (ret != (int)BluetoothError.None)
407 Log.Error(Globals.LogTag, "Failed to enable adapter, Error - " + (BluetoothError)ret);
408 BluetoothErrorFactory.ThrowBluetoothException(ret);
413 BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotInitialized);
417 internal void Disable()
419 if (IsBluetoothEnabled)
421 int ret = Interop.Bluetooth.DisableAdapter();
422 if (ret != (int)BluetoothError.None)
424 Log.Error(Globals.LogTag, "Failed to disable adapter, Error - " + (BluetoothError)ret);
425 BluetoothErrorFactory.ThrowBluetoothException(ret);
430 BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
434 internal void SetVisibility(VisibilityMode mode, int timeout)
436 if (IsBluetoothEnabled)
438 int ret = Interop.Bluetooth.SetVisibility(mode, timeout);
439 if (ret != (int)BluetoothError.None)
441 Log.Error(Globals.LogTag, "Failed to set visibility, Error - " + (BluetoothError)ret);
442 BluetoothErrorFactory.ThrowBluetoothException(ret);
447 BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled);
451 internal void StartDiscovery()
453 int ret = Interop.Bluetooth.StartDiscovery();
454 if (ret != (int)BluetoothError.None)
456 Log.Error(Globals.LogTag, "Failed to start discovery, Error - " + (BluetoothError)ret);
457 BluetoothErrorFactory.ThrowBluetoothException(ret);
461 internal void StopDiscovery()
463 int ret = Interop.Bluetooth.StopDiscovery();
464 if(ret != (int)BluetoothError.None)
466 Log.Error(Globals.LogTag, "Failed to stop discovery, Error - " + (BluetoothError)ret);
467 BluetoothErrorFactory.ThrowBluetoothException(ret);
471 internal IEnumerable<BluetoothDevice> GetBondedDevices()
473 List<BluetoothDevice> deviceList = new List<BluetoothDevice>();
474 _bondedDeviceCallback = (ref BluetoothDeviceStruct deviceInfo, IntPtr userData) =>
476 Log.Info(Globals.LogTag, "Bonded devices cb is called");
477 if(!deviceInfo.Equals(null))
479 deviceList.Add(BluetoothUtils.ConvertStructToDeviceClass(deviceInfo));
483 int ret = Interop.Bluetooth.GetBondedDevices(_bondedDeviceCallback, IntPtr.Zero);
484 if(ret != (int)BluetoothError.None)
486 Log.Error(Globals.LogTag, "Failed to get bonded devices, Error - " + (BluetoothError)ret);
487 BluetoothErrorFactory.ThrowBluetoothException(ret);
492 internal BluetoothDevice GetBondedDevice(string address)
495 BluetoothDevice btDevice;
496 int ret = Interop.Bluetooth.GetBondedDeviceByAddress(address, out deviceInfo);
497 if(ret != (int)BluetoothError.None)
499 Log.Error(Globals.LogTag, "Failed to get bonded device by address, Error - " + (BluetoothError)ret);
500 BluetoothErrorFactory.ThrowBluetoothException(ret);
502 BluetoothDeviceStruct device = (BluetoothDeviceStruct)Marshal.PtrToStructure(deviceInfo, typeof(BluetoothDeviceStruct));
503 btDevice = BluetoothUtils.ConvertStructToDeviceClass(device);
504 Interop.Bluetooth.FreeDeviceInfo(deviceInfo);
508 internal bool IsServiceUsed(string serviceUuid)
511 int ret = Interop.Bluetooth.IsServiceUsed(serviceUuid, out isUsed);
512 if(ret != (int)BluetoothError.None)
514 Log.Error(Globals.LogTag, "Failed to check the usage of service, Error - " + (BluetoothError)ret);
519 internal BluetoothOobData GetLocalOobData()
521 BluetoothOobData oobData = new BluetoothOobData();
525 int randomizerLength;
526 int ret = Interop.Bluetooth.GetOobData(out hash, out randomizer, out hashLength, out randomizerLength);
527 if(ret != (int)BluetoothError.None)
529 Log.Error(Globals.LogTag, "Failed to get the local oob data, Error - " + (BluetoothError)ret);
530 BluetoothErrorFactory.ThrowBluetoothException(ret);
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);
538 oobData.HashValue = hashArr;
539 oobData.RandomizerValue = randomizerArr;
543 internal void SetRemoteOobData(string deviceAddress, BluetoothOobData oobData)
545 byte[] hash = oobData.HashValue;
546 byte[] randomizer = oobData.RandomizerValue;
547 int hashLength = hash.Length;
548 int randomizerLength = randomizer.Length;
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);
555 int ret = Interop.Bluetooth.SetOobData(deviceAddress, hashPtr, randomizerPtr, hashLength, randomizerLength);
556 if(ret != (int)BluetoothError.None)
558 Log.Error(Globals.LogTag, "Failed to set the remote oob data, Error - " + (BluetoothError)ret);
559 BluetoothErrorFactory.ThrowBluetoothException(ret);
563 internal void RemoveRemoteOobData(string deviceAddress)
565 int ret = Interop.Bluetooth.RemoveOobData(deviceAddress);
566 if(ret != (int)BluetoothError.None)
568 Log.Error(Globals.LogTag, "Failed to remove the remote oob data, Error - " + (BluetoothError)ret);
569 BluetoothErrorFactory.ThrowBluetoothException(ret);
573 internal BluetoothServerSocket CreateServerSocket(string serviceUuid)
576 int ret = Interop.Bluetooth.CreateServerSocket(serviceUuid, out socketFd);
577 if(ret != (int)BluetoothError.None)
579 Log.Error(Globals.LogTag, "Failed to create server socket, Error - " + (BluetoothError)ret);
580 BluetoothErrorFactory.ThrowBluetoothException(ret);
582 Log.Info (Globals.LogTag, "Created socketfd: "+ socketFd);
583 return new BluetoothServerSocket(socketFd);
586 internal void DestroyServerSocket(BluetoothServerSocket socket)
588 int ret = Interop.Bluetooth.DestroyServerSocket(socket.socketFd);
589 if (ret != (int)BluetoothError.None)
591 Log.Error(Globals.LogTag, "Failed to destroy socket, Error - " + (BluetoothError)ret);
592 BluetoothErrorFactory.ThrowBluetoothException(ret);
596 internal static BluetoothAdapterImpl Instance
604 private BluetoothAdapterImpl()
609 ~BluetoothAdapterImpl()
614 public void Dispose()
617 GC.SuppressFinalize(this);
620 private void Dispose(bool disposing)
627 // Free managed objects.
629 //Free unmanaged objects
630 RemoveAllRegisteredEvent();
635 private void initialize()
637 int ret = Interop.Bluetooth.Initialize();
638 if (ret != (int)BluetoothError.None)
640 Log.Error (Globals.LogTag, "Failed to initialize bluetooth, Error - " + (BluetoothError)ret);
641 BluetoothErrorFactory.ThrowBluetoothException (ret);
645 Globals.IsInitialize = true;
649 private void deinitialize()
651 int ret = Interop.Bluetooth.Deinitialize();
652 if (ret != (int)BluetoothError.None)
654 Log.Error (Globals.LogTag, "Failed to deinitialize bluetooth, Error - " + (BluetoothError)ret);
658 Globals.IsInitialize = false;
662 private void RemoveAllRegisteredEvent()
664 //unregister all remaining events when this object is released.
665 if (_stateChanged != null)
667 UnregisterStateChangedEvent();
670 if (_nameChanged != null)
672 UnregisterNameChangedEvent();
675 if (_visibilityDurationChanged != null)
677 UnregisterVisibilityDurationChangedEvent();
680 if (_visibilityModeChanged != null)
682 UnregisterVisibilityChangedEvent();
685 if (_discoveryStateChanged != null)
687 UnregisterDiscoveryStateChangedEvent();