public void Init(out SAMNetworkConnection.ErrorType error)
        {
            if (_client == null)
            {
                error = SAMNetworkConnection.ErrorType.BluetoothAdapterNotFound; return;
            }

            _client.StartAdapter();

            _lastState         = _client.State;
            _currentConnDevice = null;
            _lastScanDevices.Clear();
            Events.Clear();
            _isScanning    = false;
            _scanStartTime = MonoSAMGame.CurrentTime.TotalElapsedSeconds;

            if (_client.State == BluetoothAdapterState.AdapterNotFound)
            {
                error = SAMNetworkConnection.ErrorType.BluetoothAdapterNotFound;
            }
            else if (_client.State == BluetoothAdapterState.AdapterNotFound)
            {
                error = SAMNetworkConnection.ErrorType.BluetoothAdapterNoPermission;
            }
            else if (_client.State == BluetoothAdapterState.Error)
            {
                error = SAMNetworkConnection.ErrorType.NetworkMediumInternalError;
            }
            else
            {
                error = SAMNetworkConnection.ErrorType.None;
            }
        }
        public void Update(out SAMNetworkConnection.ErrorType error)
        {
            var xlastState = _lastState;

            _lastState = _client.State;

            _client.Update();

            if (_client.State == BluetoothAdapterState.AdapterNotFound)
            {
                error = SAMNetworkConnection.ErrorType.BluetoothAdapterNotFound;
                return;
            }

            if (_client.State == BluetoothAdapterState.PermissionNotGranted)
            {
                error = SAMNetworkConnection.ErrorType.BluetoothAdapterNoPermission;
                return;
            }

            if (_client.State == BluetoothAdapterState.Error)
            {
                error = SAMNetworkConnection.ErrorType.NetworkMediumInternalError;
                return;
            }

            if (_client.State == BluetoothAdapterState.NotEnabledByUser)
            {
                error = SAMNetworkConnection.ErrorType.BluetoothNotEnabled;
                return;
            }

            if (_client.State == BluetoothAdapterState.ConnectionFailed)
            {
                if (_lastScanDevices.Any())
                {
                    if (_currentConnDevice != null)
                    {
                        SAMLog.Warning("BNM::ConnectionFailed", $"Connection to {_currentConnDevice.Name} failed");

                        Events.Enqueue(new BluetoothMediumEvent(BluetoothMediumEvent.BTEvent.ConnectionFailed, _currentConnDevice.Name));
                    }

                    _currentConnDevice = _lastScanDevices.First();
                    _lastScanDevices.Remove(_currentConnDevice);

                    _isScanning = false;

                    SAMLog.Debug($"Try connect to {_currentConnDevice.Name} ({_currentConnDevice.Address}|{_currentConnDevice.DeviceClass}|{_currentConnDevice.Type})");
                    Events.Enqueue(new BluetoothMediumEvent(BluetoothMediumEvent.BTEvent.TryConnection, _currentConnDevice.Name));
                    _client.Connect(_currentConnDevice);

                    error = SAMNetworkConnection.ErrorType.None;
                }
                else
                {
                    _isScanning = true;
                    _client.StartScan();
                    _scanStartTime = MonoSAMGame.CurrentTime.TotalElapsedSeconds;

                    error = SAMNetworkConnection.ErrorType.None;
                }
                return;
            }

            if (_client.State == BluetoothAdapterState.ConnectionLost)
            {
                error = SAMNetworkConnection.ErrorType.P2PConnectionLost;
                return;
            }

            if (_client.State == BluetoothAdapterState.Active)
            {
                if (_isScanning)
                {
                    _lastScanDevices = _client.FoundDevices;

                    SAMLog.Debug($"Scanning finished {_lastScanDevices.Count} devices found");

                    if (_lastScanDevices.Any())
                    {
                        foreach (var dd in _lastScanDevices)
                        {
                            SAMLog.Debug($"Device found: {dd.Name} ({dd.Address}|{dd.DeviceClass}|{dd.Type})");
                        }

                        _currentConnDevice = _lastScanDevices.First();
                        _lastScanDevices.Remove(_currentConnDevice);

                        SAMLog.Debug($"Try connect to {_currentConnDevice.Name} ({_currentConnDevice.Address}|{_currentConnDevice.DeviceClass}|{_currentConnDevice.Type})");

                        _isScanning = false;
                        _client.Connect(_currentConnDevice);
                    }
                    else
                    {
                        _isScanning = true;
                        _client.StartScan();
                        _scanStartTime = MonoSAMGame.CurrentTime.TotalElapsedSeconds;
                    }
                }
            }

            if (_client.State == BluetoothAdapterState.Scanning)
            {
                if (_isScanning && !_client.IsDiscovering && MonoSAMGame.CurrentTime.TotalElapsedSeconds - _scanStartTime > 30)
                {
                    error = SAMNetworkConnection.ErrorType.None;
                    SAMLog.Warning("BNM::ForceScanCancel", "Cancel scan by force");
                    _client.CancelScan();
                    return;
                }
            }

            if (_client.State == BluetoothAdapterState.Listen)
            {
                error = SAMNetworkConnection.ErrorType.None;
                if (!_client.IsDiscoverable)
                {
                    _client.ContinueWaiting();
                }
                return;
            }

            if (_client.State == BluetoothAdapterState.Connected)
            {
                if (xlastState == BluetoothAdapterState.Connecting && _currentConnDevice != null)
                {
                    Events.Enqueue(new BluetoothMediumEvent(BluetoothMediumEvent.BTEvent.ConnectionSucceeded, _currentConnDevice.Name));
                }
            }

            error = SAMNetworkConnection.ErrorType.None;
        }