Fix GetLocalOobData memory leak (#2725)
[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             if (hashLength > 0) {
534                 byte[] hashArr = new byte[hashLength];
535                 Marshal.Copy(hash, hashArr, 0, hashLength);
536                 oobData.HashValue = hashArr;
537                 Interop.Libc.Free(hash);
538             }
539
540             if (randomizerLength > 0) {
541                 byte[] randomizerArr = new byte[randomizerLength];
542                 Marshal.Copy(randomizer, randomizerArr, 0, randomizerLength);
543                 oobData.RandomizerValue = randomizerArr;
544                 Interop.Libc.Free(randomizer);
545             }
546
547             return oobData;
548         }
549
550         internal void SetRemoteOobData(string deviceAddress, BluetoothOobData oobData)
551         {
552             byte[] hash = oobData.HashValue;
553             byte[] randomizer = oobData.RandomizerValue;
554             int hashLength = hash.Length;
555             int randomizerLength = randomizer.Length;
556
557             IntPtr hashPtr = Marshal.AllocHGlobal(hashLength);
558             Marshal.Copy(hash, 0, hashPtr, hashLength);
559             IntPtr randomizerPtr = Marshal.AllocHGlobal(randomizerLength);
560             Marshal.Copy(randomizer, 0, randomizerPtr, randomizerLength);
561
562             int ret = Interop.Bluetooth.SetOobData(deviceAddress, hashPtr, randomizerPtr, hashLength, randomizerLength);
563             if(ret != (int)BluetoothError.None)
564             {
565                 Log.Error(Globals.LogTag, "Failed to set the remote oob data, Error - " + (BluetoothError)ret);
566                 BluetoothErrorFactory.ThrowBluetoothException(ret);
567             }
568         }
569
570         internal void RemoveRemoteOobData(string deviceAddress)
571         {
572             int ret = Interop.Bluetooth.RemoveOobData(deviceAddress);
573             if(ret != (int)BluetoothError.None)
574             {
575                 Log.Error(Globals.LogTag, "Failed to remove the remote oob data, Error - " + (BluetoothError)ret);
576                 BluetoothErrorFactory.ThrowBluetoothException(ret);
577             }
578         }
579
580         internal BluetoothServerSocket CreateServerSocket(string serviceUuid)
581         {
582             int socketFd;
583             int ret = Interop.Bluetooth.CreateServerSocket(serviceUuid, out socketFd);
584             if(ret != (int)BluetoothError.None)
585             {
586                 Log.Error(Globals.LogTag, "Failed to create server socket, Error - " + (BluetoothError)ret);
587                 BluetoothErrorFactory.ThrowBluetoothException(ret);
588             }
589             Log.Info (Globals.LogTag, "Created socketfd: "+ socketFd);
590             return new BluetoothServerSocket(socketFd);
591         }
592
593         internal void DestroyServerSocket(BluetoothServerSocket socket)
594         {
595             int ret = Interop.Bluetooth.DestroyServerSocket(socket.socketFd);
596             if (ret != (int)BluetoothError.None)
597             {
598                 Log.Error(Globals.LogTag, "Failed to destroy socket, Error - " + (BluetoothError)ret);
599                 BluetoothErrorFactory.ThrowBluetoothException(ret);
600             }
601         }
602
603         internal static BluetoothAdapterImpl Instance
604         {
605             get
606             {
607                 return _instance;
608             }
609         }
610
611         private BluetoothAdapterImpl()
612         {
613             initialize();
614         }
615
616         ~BluetoothAdapterImpl()
617         {
618             Dispose(false);
619         }
620
621         public void Dispose()
622         {
623             Dispose(true);
624             GC.SuppressFinalize(this);
625         }
626
627         private void Dispose(bool disposing)
628         {
629             if (disposed)
630                 return;
631
632             if (disposing)
633             {
634                 // Free managed objects.
635             }
636             //Free unmanaged objects
637             RemoveAllRegisteredEvent();
638             deinitialize();
639             disposed = true;
640         }
641
642         private void initialize()
643         {
644             int ret = Interop.Bluetooth.Initialize();
645             if (ret != (int)BluetoothError.None)
646             {
647                 Log.Error (Globals.LogTag, "Failed to initialize bluetooth, Error - " + (BluetoothError)ret);
648                 BluetoothErrorFactory.ThrowBluetoothException (ret);
649             }
650             else
651             {
652                 Globals.IsInitialize = true;
653             }
654         }
655
656         private void deinitialize()
657         {
658             int ret = Interop.Bluetooth.Deinitialize();
659             if (ret != (int)BluetoothError.None)
660             {
661                 Log.Error (Globals.LogTag, "Failed to deinitialize bluetooth, Error - " + (BluetoothError)ret);
662             }
663             else
664             {
665                 Globals.IsInitialize = false;
666             }
667         }
668
669         private void RemoveAllRegisteredEvent()
670         {
671             //unregister all remaining events when this object is released.
672             if (_stateChanged != null)
673             {
674                 UnregisterStateChangedEvent();
675             }
676
677             if (_nameChanged != null)
678             {
679                 UnregisterNameChangedEvent();
680             }
681
682             if (_visibilityDurationChanged != null)
683             {
684                 UnregisterVisibilityDurationChangedEvent();
685             }
686
687             if (_visibilityModeChanged != null)
688             {
689                 UnregisterVisibilityChangedEvent();
690             }
691
692             if (_discoveryStateChanged != null)
693             {
694                 UnregisterDiscoveryStateChangedEvent();
695             }
696         }
697     }
698 }