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;
31 internal partial class BluetoothAdapterImpl : IDisposable
33 private event EventHandler<StateChangedEventArgs> _stateChanged;
34 private event EventHandler<NameChangedEventArgs> _nameChanged;
35 private event EventHandler<VisibilityModeChangedEventArgs> _visibilityModeChanged;
36 private event EventHandler<VisibilityDurationChangedEventArgs> _visibilityDurationChanged;
37 private event EventHandler<DiscoveryStateChangedEventArgs> _discoveryStateChanged;
39 private Interop.Bluetooth.StateChangedCallback _stateChangedCallback;
40 private Interop.Bluetooth.NameChangedCallback _nameChangedCallback;
41 private Interop.Bluetooth.VisibilityModeChangedCallback _visibilityChangedCallback;
42 private Interop.Bluetooth.VisibilityDurationChangedCallback _visibilitydurationChangedCallback;
43 private Interop.Bluetooth.DiscoveryStateChangedCallback _discoveryStateChangedCallback;
45 private static readonly BluetoothAdapterImpl _instance = new BluetoothAdapterImpl();
46 private bool disposed = false;
48 internal event EventHandler<StateChangedEventArgs> StateChanged
52 if (_stateChanged == null)
54 RegisterStateChangedEvent();
56 _stateChanged += value;
60 _stateChanged -= value;
61 if (_stateChanged == null)
63 UnregisterStateChangedEvent();
68 internal event EventHandler<NameChangedEventArgs> NameChanged
72 if (_nameChanged == null)
74 RegisterNameChangedEvent();
76 _nameChanged += value;
80 _nameChanged -= value;
81 if (_nameChanged == null)
83 UnregisterNameChangedEvent();
88 internal event EventHandler<VisibilityModeChangedEventArgs> VisibilityModeChanged
92 if (_visibilityModeChanged == null)
94 RegisterVisibilityChangedEvent();
96 _visibilityModeChanged += value;
100 _visibilityModeChanged -= value;
101 if (_visibilityModeChanged == null)
103 UnregisterVisibilityChangedEvent();
108 internal event EventHandler<VisibilityDurationChangedEventArgs> VisibilityDurationChanged
112 if (_visibilityDurationChanged == null)
114 RegisterVisibilityDurationChangedEvent();
116 _visibilityDurationChanged += value;
120 _visibilityDurationChanged -= value;
121 if (_visibilityDurationChanged == null)
123 UnregisterVisibilityDurationChangedEvent();
128 internal event EventHandler<DiscoveryStateChangedEventArgs> DiscoveryStateChanged
132 if (_discoveryStateChanged == null)
134 RegisterDiscoveryStateChangedEvent();
136 _discoveryStateChanged+= value;
140 _discoveryStateChanged -= value;
141 if (_discoveryStateChanged == null)
143 UnregisterDiscoveryStateChangedEvent();
148 private void RegisterStateChangedEvent()
150 _stateChangedCallback = (int result, int state, IntPtr userData) =>
152 if (_stateChanged != null)
154 BluetoothState st = (BluetoothState)state;
155 BluetoothError res = (BluetoothError)result;
156 _stateChanged(null, new StateChangedEventArgs(res,st));
159 int ret = Interop.Bluetooth.SetStateChangedCallback(_stateChangedCallback, IntPtr.Zero);
160 if (ret != (int)BluetoothError.None)
162 Log.Error(Globals.LogTag, "Failed to set state changed callback, Error - " + (BluetoothError)ret);
166 private void UnregisterStateChangedEvent()
168 int ret = Interop.Bluetooth.UnsetStateChangedCallback();
169 if (ret != (int)BluetoothError.None)
171 Log.Error(Globals.LogTag, "Failed to unset state changed callback, Error - " + (BluetoothError)ret);
175 private void RegisterNameChangedEvent()
177 _nameChangedCallback = (string deviceName, IntPtr userData) =>
179 if (_nameChanged != null)
181 _nameChanged(null, new NameChangedEventArgs(deviceName));
184 int ret = Interop.Bluetooth.SetNameChangedCallback(_nameChangedCallback, IntPtr.Zero);
185 if (ret != (int)BluetoothError.None)
187 Log.Error(Globals.LogTag, "Failed to set name changed callback, Error - " + (BluetoothError)ret);
191 private void UnregisterNameChangedEvent()
193 int ret = Interop.Bluetooth.UnsetNameChangedCallback();
194 if (ret != (int)BluetoothError.None)
196 Log.Error(Globals.LogTag, "Failed to unset name changed callback, Error - " + (BluetoothError)ret);
200 private void RegisterVisibilityChangedEvent()
202 _visibilityChangedCallback = (int result, int mode, IntPtr userData) =>
204 if (_visibilityModeChanged != null)
206 VisibilityMode visibility = (VisibilityMode)mode;
207 BluetoothError res = (BluetoothError)result;
208 _visibilityModeChanged(null, new VisibilityModeChangedEventArgs(res,visibility));
211 int ret = Interop.Bluetooth.SetVisibilityModeChangedCallback(_visibilityChangedCallback, IntPtr.Zero);
212 if (ret != (int)BluetoothError.None)
214 Log.Error(Globals.LogTag, "Failed to set visibility mode changed callback, Error - " + (BluetoothError)ret);
218 private void UnregisterVisibilityChangedEvent()
220 int ret = Interop.Bluetooth.UnsetVisibilityModeChangedCallback();
221 if (ret != (int)BluetoothError.None)
223 Log.Error(Globals.LogTag, "Failed to unset visibility mode changed callback, Error - " + (BluetoothError)ret);
227 private void RegisterVisibilityDurationChangedEvent()
229 _visibilitydurationChangedCallback = (int duration, IntPtr userData) =>
231 if (_visibilityDurationChanged != null)
233 _visibilityDurationChanged(null, new VisibilityDurationChangedEventArgs(duration));
236 int ret = Interop.Bluetooth.SetVisibilityDurationChangedCallback(_visibilitydurationChangedCallback, IntPtr.Zero);
237 if (ret != (int)BluetoothError.None)
239 Log.Error(Globals.LogTag, "Failed to set visibility duration changed callback, Error - " + (BluetoothError)ret);
243 private void UnregisterVisibilityDurationChangedEvent()
245 int ret = Interop.Bluetooth.UnsetVisibilityDurationChangedCallback();
246 if (ret != (int)BluetoothError.None)
248 Log.Error(Globals.LogTag, "Failed to unset visiiblity duration changed callback, Error - " + (BluetoothError)ret);
252 private void RegisterDiscoveryStateChangedEvent()
254 _discoveryStateChangedCallback = (int result, BluetoothDeviceDiscoveryState state, IntPtr deviceInfo, IntPtr userData) =>
256 Log.Info(Globals.LogTag, "Discovery state changed callback is called");
257 if (_discoveryStateChanged != null)
259 BluetoothError res = (BluetoothError)result;
262 case BluetoothDeviceDiscoveryState.Started:
263 _discoveryStateChanged(null, new DiscoveryStateChangedEventArgs(res,state));
265 case BluetoothDeviceDiscoveryState.Finished:
267 _discoveryStateChanged(null, new DiscoveryStateChangedEventArgs(res,state));
270 case BluetoothDeviceDiscoveryState.Found:
272 BluetoothDiscoveredDeviceStruct info = (BluetoothDiscoveredDeviceStruct)Marshal.PtrToStructure(deviceInfo, typeof(BluetoothDiscoveredDeviceStruct));
273 _discoveryStateChanged(null, new DiscoveryStateChangedEventArgs(res,state,BluetoothUtils.ConvertStructToDiscoveredDevice(info)));
281 int ret = Interop.Bluetooth.SetDiscoveryStateChangedCallback(_discoveryStateChangedCallback, IntPtr.Zero);
282 if (ret != (int)BluetoothError.None)
284 Log.Error(Globals.LogTag, "Failed to set discovery state changed callback, Error - " + (BluetoothError)ret);
288 private void UnregisterDiscoveryStateChangedEvent()
290 int ret = Interop.Bluetooth.UnsetDiscoveryStateChangedCallback();
291 if (ret != (int)BluetoothError.None)
293 Log.Error(Globals.LogTag, "Failed to unset discovery state changed callback, Error - " + (BluetoothError)ret);
297 internal bool IsBluetoothEnabled
301 BluetoothState active;
302 int ret = Interop.Bluetooth.GetState(out active);
303 if (ret != (int)BluetoothError.None)
305 Log.Error(Globals.LogTag, "Failed to get state, Error - " + (BluetoothError)ret);
307 if (active == BluetoothState.Enabled)
313 internal string Address
318 int ret = Interop.Bluetooth.GetAddress(out address);
319 if (ret != (int)BluetoothError.None)
321 Log.Error(Globals.LogTag, "Failed to get address, Error - " + (BluetoothError)ret);
328 internal VisibilityMode Visibility
334 int ret = Interop.Bluetooth.GetVisibility(out visibilityMode, out time);
335 if(ret != (int)BluetoothError.None)
337 Log.Error(Globals.LogTag, "Failed to get visibility mode, Error - " + (BluetoothError)ret);
338 return VisibilityMode.NonDiscoverable;
340 return (VisibilityMode)visibilityMode;
344 internal bool IsDiscoveryInProgress
349 int ret = Interop.Bluetooth.IsDiscovering(out isDiscovering);
350 if(ret != (int)BluetoothError.None)
352 Log.Error(Globals.LogTag, "Failed to get discovery progress state, Error - " + (BluetoothError)ret);
354 return isDiscovering;
358 internal int RemainingTimeAsVisible
364 int ret = Interop.Bluetooth.GetVisibility(out visibilityMode, out duration);
365 if ((ret != (int)BluetoothError.None) || ((VisibilityMode)visibilityMode != VisibilityMode.TimeLimitedDiscoverable))
367 Log.Error(Globals.LogTag, "Failed to get remaining visible time, Error - " + (BluetoothError)ret);
378 int ret = Interop.Bluetooth.GetName(out name);
379 if (ret != (int)BluetoothError.None)
381 Log.Error(Globals.LogTag, "Failed to get adapter name, Error - " + (BluetoothError)ret);
388 int ret = Interop.Bluetooth.SetName(value.ToString());
389 if (ret != (int)BluetoothError.None)
391 Log.Error(Globals.LogTag, "Failed to set adapter name, Error - " + (BluetoothError)ret);
392 BluetoothErrorFactory.ThrowBluetoothException(ret);
397 internal void StartDiscovery()
399 int ret = Interop.Bluetooth.StartDiscovery();
400 if (ret != (int)BluetoothError.None)
402 Log.Error(Globals.LogTag, "Failed to start discovery, Error - " + (BluetoothError)ret);
403 BluetoothErrorFactory.ThrowBluetoothException(ret);
407 internal void StopDiscovery()
409 int ret = Interop.Bluetooth.StopDiscovery();
410 if(ret != (int)BluetoothError.None)
412 Log.Error(Globals.LogTag, "Failed to stop discovery, Error - " + (BluetoothError)ret);
413 BluetoothErrorFactory.ThrowBluetoothException(ret);
417 internal IEnumerable<BluetoothDevice> GetBondedDevices()
419 List<BluetoothDevice> deviceList = new List<BluetoothDevice>();
420 Interop.Bluetooth.BondedDeviceCallback callback = (ref BluetoothDeviceStruct deviceInfo, IntPtr userData) =>
422 Log.Info(Globals.LogTag, "Bonded devices cb is called");
423 if(!deviceInfo.Equals(null))
425 deviceList.Add(BluetoothUtils.ConvertStructToDeviceClass(deviceInfo));
429 int ret = Interop.Bluetooth.GetBondedDevices(callback, IntPtr.Zero);
430 if(ret != (int)BluetoothError.None)
432 Log.Error(Globals.LogTag, "Failed to get bonded devices, Error - " + (BluetoothError)ret);
433 BluetoothErrorFactory.ThrowBluetoothException(ret);
438 internal BluetoothDevice GetBondedDevice(string address)
441 int ret = Interop.Bluetooth.GetBondedDeviceByAddress(address, out deviceInfo);
442 if(ret != (int)BluetoothError.None)
444 Log.Error(Globals.LogTag, "Failed to get bonded device by address, Error - " + (BluetoothError)ret);
445 BluetoothErrorFactory.ThrowBluetoothException(ret);
447 BluetoothDeviceStruct device = (BluetoothDeviceStruct)Marshal.PtrToStructure(deviceInfo, typeof(BluetoothDeviceStruct));
449 return BluetoothUtils.ConvertStructToDeviceClass(device);
452 internal bool IsServiceUsed(string serviceUuid)
455 int ret = Interop.Bluetooth.IsServiceUsed(serviceUuid, out isUsed);
456 if(ret != (int)BluetoothError.None)
458 Log.Error(Globals.LogTag, "Failed to check the usage of service, Error - " + (BluetoothError)ret);
463 internal BluetoothOobData GetLocalOobData()
465 BluetoothOobData oobData = new BluetoothOobData();
469 int randomizerLength;
470 int ret = Interop.Bluetooth.GetOobData(out hash, out randomizer, out hashLength, out randomizerLength);
471 if(ret != (int)BluetoothError.None)
473 Log.Error(Globals.LogTag, "Failed to get the local oob data, Error - " + (BluetoothError)ret);
474 BluetoothErrorFactory.ThrowBluetoothException(ret);
477 byte[] hashArr = new byte[hashLength];
478 Marshal.Copy(hash, hashArr, 0, hashLength);
479 byte[] randomizerArr = new byte[randomizerLength];
480 Marshal.Copy(randomizer, randomizerArr, 0, randomizerLength);
482 oobData.HashValue = hashArr;
483 oobData.RandomizerValue = randomizerArr;
487 internal void SetRemoteOobData(string deviceAddress, BluetoothOobData oobData)
489 byte[] hash = oobData.HashValue;
490 byte[] randomizer = oobData.RandomizerValue;
491 int hashLength = hash.Length;
492 int randomizerLength = randomizer.Length;
494 IntPtr hashPtr = Marshal.AllocHGlobal(hashLength);
495 Marshal.Copy(hash, 0, hashPtr, hashLength);
496 IntPtr randomizerPtr = Marshal.AllocHGlobal(randomizerLength);
497 Marshal.Copy(randomizer, 0, randomizerPtr, randomizerLength);
499 int ret = Interop.Bluetooth.SetOobData(deviceAddress, hashPtr, randomizerPtr, hashLength, randomizerLength);
500 if(ret != (int)BluetoothError.None)
502 Log.Error(Globals.LogTag, "Failed to set the remote oob data, Error - " + (BluetoothError)ret);
503 BluetoothErrorFactory.ThrowBluetoothException(ret);
507 internal void RemoveRemoteOobData(string deviceAddress)
509 int ret = Interop.Bluetooth.RemoveOobData(deviceAddress);
510 if(ret != (int)BluetoothError.None)
512 Log.Error(Globals.LogTag, "Failed to remove the remote oob data, Error - " + (BluetoothError)ret);
513 BluetoothErrorFactory.ThrowBluetoothException(ret);
517 internal BluetoothServerSocket CreateServerSocket(string serviceUuid)
520 int ret = Interop.Bluetooth.CreateServerSocket(serviceUuid, out socketFd);
521 if(ret != (int)BluetoothError.None)
523 Log.Error(Globals.LogTag, "Failed to create server socket, Error - " + (BluetoothError)ret);
524 BluetoothErrorFactory.ThrowBluetoothException(ret);
526 Log.Info (Globals.LogTag, "Created socketfd: "+ socketFd);
527 return new BluetoothServerSocket(socketFd);
530 internal void DestroyServerSocket(BluetoothServerSocket socket)
532 int ret = Interop.Bluetooth.DestroyServerSocket(socket.socketFd);
533 if (ret != (int)BluetoothError.None)
535 Log.Error(Globals.LogTag, "Failed to destroy socket, Error - " + (BluetoothError)ret);
536 BluetoothErrorFactory.ThrowBluetoothException(ret);
540 internal static BluetoothAdapterImpl Instance
548 private BluetoothAdapterImpl()
553 ~BluetoothAdapterImpl()
558 public void Dispose()
561 GC.SuppressFinalize(this);
564 private void Dispose(bool disposing)
571 // Free managed objects.
573 //Free unmanaged objects
574 RemoveAllRegisteredEvent();
579 private void initialize()
581 int ret = Interop.Bluetooth.Initialize();
582 if (ret != (int)BluetoothError.None)
584 Log.Error (Globals.LogTag, "Failed to initialize bluetooth, Error - " + (BluetoothError)ret);
585 BluetoothErrorFactory.ThrowBluetoothException (ret);
589 Globals.IsInitialize = true;
593 private void deinitialize()
595 int ret = Interop.Bluetooth.Deinitialize();
596 if (ret != (int)BluetoothError.None)
598 Log.Error (Globals.LogTag, "Failed to deinitialize bluetooth, Error - " + (BluetoothError)ret);
599 BluetoothErrorFactory.ThrowBluetoothException (ret);
603 Globals.IsInitialize = false;
607 private void RemoveAllRegisteredEvent()
609 //unregister all remaining events when this object is released.
610 if (_stateChanged != null)
612 UnregisterStateChangedEvent();
615 if (_nameChanged != null)
617 UnregisterNameChangedEvent();
620 if (_visibilityDurationChanged != null)
622 UnregisterVisibilityDurationChangedEvent();
625 if (_visibilityModeChanged != null)
627 UnregisterVisibilityChangedEvent();
630 if (_discoveryStateChanged != null)
632 UnregisterDiscoveryStateChangedEvent();