Ejemplo n.º 1
0
        public override void OnServicesDiscovered(BluetoothGatt gatt, [GeneratedEnum] GattStatus status)
        {
            lock (_lock)
            {
                if (status == GattStatus.Success && State == BluetoothLEDeviceState.Discovering)
                {
                    var services = new List <GattService>();
                    if (gatt.Services != null)
                    {
                        foreach (var service in gatt.Services)
                        {
                            var characteristics = new List <GattCharacteristic>();
                            if (service.Characteristics != null)
                            {
                                foreach (var characteristic in service.Characteristics)
                                {
                                    characteristics.Add(new GattCharacteristic(characteristic));
                                }
                            }

                            services.Add(new GattService(service, characteristics));
                        }
                    }

                    State = BluetoothLEDeviceState.Connected;
                    _connectCompletionSource?.TrySetResult(services);
                }
                else
                {
                    Disconnect();
                    _connectCompletionSource?.TrySetResult(null);
                }
            }
        }
Ejemplo n.º 2
0
        public async Task <IEnumerable <IGattService> > ConnectAndDiscoverServicesAsync(CancellationToken token)
        {
            lock (_lock)
            {
                if (State != BluetoothLEDeviceState.Disconnected)
                {
                    return(null);
                }

                State = BluetoothLEDeviceState.Connecting;
                _centralManager.ConnectPeripheral(_peripheral, new PeripheralConnectionOptions {
                    NotifyOnConnection = true, NotifyOnDisconnection = true
                });

                _connectCompletionSource = new TaskCompletionSource <IEnumerable <IGattService> >(TaskCreationOptions.RunContinuationsAsynchronously);
                token.Register(() =>
                {
                    lock (_lock)
                    {
                        DisconnectInternal();
                        _connectCompletionSource?.SetResult(null);
                    }
                });
            }

            var result = await _connectCompletionSource.Task;

            _connectCompletionSource = null;
            return(result);
        }
Ejemplo n.º 3
0
        public override async void DiscoveredService(CBPeripheral peripheral, NSError error)
        {
            try
            {
                if (error == null)
                {
                    var services = new List <GattService>();
                    if (_peripheral.Services != null)
                    {
                        foreach (var service in _peripheral.Services)
                        {
                            _discoverCompletionSource = new TaskCompletionSource <IEnumerable <IGattCharacteristic> >(TaskCreationOptions.RunContinuationsAsynchronously);

                            _peripheral.DiscoverCharacteristics(service);

                            var result = await _discoverCompletionSource.Task;
                            _discoverCompletionSource = null;

                            if (result != null)
                            {
                                services.Add(new GattService(service, result));
                            }
                            else
                            {
                                lock (_lock)
                                {
                                    DisconnectInternal();
                                    _connectCompletionSource?.SetResult(null);
                                }
                                return;
                            }
                        }
                    }

                    lock (_lock)
                    {
                        State = BluetoothLEDeviceState.Connected;
                        _connectCompletionSource?.SetResult(services);
                        return;
                    }
                }
                else
                {
                    lock (_lock)
                    {
                        DisconnectInternal();
                        _connectCompletionSource?.SetResult(null);
                    }
                }
            }
            catch (Exception)
            {
                lock (_lock)
                {
                    DisconnectInternal();
                    _connectCompletionSource?.SetResult(null);
                }
            }
        }
Ejemplo n.º 4
0
        public async Task <IEnumerable <IGattService> > ConnectAndDiscoverServicesAsync(bool autoConnect, CancellationToken token)
        {
            CancellationTokenRegistration tokenRegistration;

            lock (_lock)
            {
                if (State != BluetoothLEDeviceState.Disconnected)
                {
                    return(null);
                }

                State = BluetoothLEDeviceState.Connecting;

                _bluetoothDevice = _bluetoothAdapter.GetRemoteDevice(Address);
                if (_bluetoothDevice == null)
                {
                    State = BluetoothLEDeviceState.Disconnected;
                    return(null);
                }

                if (Build.VERSION.SdkInt >= BuildVersionCodes.M)
                {
                    _bluetoothGatt = _bluetoothDevice.ConnectGatt(_context, autoConnect, this, BluetoothTransports.Le);
                }
                else
                {
                    _bluetoothGatt = _bluetoothDevice.ConnectGatt(_context, autoConnect, this);
                }

                if (_bluetoothGatt == null)
                {
                    _bluetoothDevice.Dispose();
                    _bluetoothDevice = null;
                    State            = BluetoothLEDeviceState.Disconnected;
                    return(null);
                }

                _connectCompletionSource = new TaskCompletionSource <IEnumerable <IGattService> >(TaskCreationOptions.RunContinuationsAsynchronously);
                tokenRegistration        = token.Register(() =>
                {
                    lock (_lock)
                    {
                        Disconnect();
                        _connectCompletionSource?.SetResult(null);
                    }
                });
            }

            var result = await _connectCompletionSource.Task;

            _connectCompletionSource = null;
            tokenRegistration.Dispose();
            return(result);
        }
Ejemplo n.º 5
0
        public void Disconnect()
        {
            lock (_lock)
            {
                _onDeviceDisconnected    = null;
                _onCharacteristicChanged = null;

                _centralManager.CancelPeripheralConnection(_peripheral);
                State = BluetoothLEDeviceState.Disconnected;
            }
        }
Ejemplo n.º 6
0
        public void Disconnect()
        {
            lock (_lock)
            {
                if (_bluetoothGatt != null)
                {
                    _bluetoothGatt.Disconnect();
                    _bluetoothGatt.Close();
                    _bluetoothGatt.Dispose();
                    _bluetoothGatt = null;

                    _bluetoothDevice.Dispose();
                    _bluetoothDevice = null;
                }

                State = BluetoothLEDeviceState.Disconnected;
            }
        }
Ejemplo n.º 7
0
        public async Task <IEnumerable <IGattService> > ConnectAndDiscoverServicesAsync(
            bool autoConnect,
            Action <Guid, byte[]> onCharacteristicChanged,
            Action <IBluetoothLEDevice> onDeviceDisconnected,
            CancellationToken token)
        {
            using (token.Register(() =>
            {
                lock (_lock)
                {
                    Disconnect();
                    _connectCompletionSource?.TrySetResult(null);
                }
            }))
            {
                lock (_lock)
                {
                    if (State != BluetoothLEDeviceState.Disconnected)
                    {
                        return(null);
                    }

                    _onCharacteristicChanged = onCharacteristicChanged;
                    _onDeviceDisconnected    = onDeviceDisconnected;

                    State = BluetoothLEDeviceState.Connecting;
                    _centralManager.ConnectPeripheral(_peripheral, new PeripheralConnectionOptions {
                        NotifyOnConnection = true, NotifyOnDisconnection = true
                    });

                    _connectCompletionSource = new TaskCompletionSource <IEnumerable <IGattService> >(TaskCreationOptions.RunContinuationsAsynchronously);
                }

                var result = await _connectCompletionSource.Task;

                lock (_lock)
                {
                    _connectCompletionSource = null;
                    return(result);
                }
            }
        }
Ejemplo n.º 8
0
        public void Disconnect()
        {
            lock (_lock)
            {
                _onDeviceDisconnected    = null;
                _onCharacteristicChanged = null;

                if (_bluetoothGatt != null)
                {
                    _bluetoothGatt.Disconnect();
                    _bluetoothGatt.Close();
                    _bluetoothGatt.Dispose();
                    _bluetoothGatt = null;

                    _bluetoothDevice.Dispose();
                    _bluetoothDevice = null;
                }

                State = BluetoothLEDeviceState.Disconnected;
            }
        }
Ejemplo n.º 9
0
        internal void OnDeviceConnected()
        {
            lock (_lock)
            {
                if (State == BluetoothLEDeviceState.Connecting)
                {
                    State = BluetoothLEDeviceState.Discovering;
                    Task.Run(() =>
                    {
                        Thread.Sleep(750);

                        lock (_lock)
                        {
                            if (State == BluetoothLEDeviceState.Discovering)
                            {
                                _peripheral.DiscoverServices();
                            }
                        }
                    });
                }
            }
        }
Ejemplo n.º 10
0
 private void DisconnectInternal()
 {
     _centralManager.CancelPeripheralConnection(_peripheral);
     State = BluetoothLEDeviceState.Disconnected;
 }
Ejemplo n.º 11
0
        public override void OnConnectionStateChange(BluetoothGatt gatt, [GeneratedEnum] GattStatus status, [GeneratedEnum] ProfileState newState)
        {
            switch (newState)
            {
            case ProfileState.Connecting:
                break;

            case ProfileState.Connected:
                lock (_lock)
                {
                    if (State == BluetoothLEDeviceState.Connecting && status == GattStatus.Success)
                    {
                        State = BluetoothLEDeviceState.Discovering;
                        Task.Run(async() =>
                        {
                            await Task.Delay(750);
                            lock (_lock)
                            {
                                if (State == BluetoothLEDeviceState.Discovering && _bluetoothGatt != null)
                                {
                                    if (!_bluetoothGatt.DiscoverServices())
                                    {
                                        Disconnect();
                                        _connectCompletionSource?.TrySetResult(null);
                                    }
                                }
                            }
                        });
                    }
                    else
                    {
                        Disconnect();
                        _connectCompletionSource?.TrySetResult(null);
                    }
                }

                break;

            case ProfileState.Disconnecting:
                break;

            case ProfileState.Disconnected:
                lock (_lock)
                {
                    switch (State)
                    {
                    case BluetoothLEDeviceState.Connecting:
                    case BluetoothLEDeviceState.Discovering:
                        Disconnect();
                        _connectCompletionSource?.TrySetResult(null);
                        break;

                    case BluetoothLEDeviceState.Connected:
                        _writeCompletionSource?.TrySetResult(false);

                        // Copy the _onDeviceDisconnected callback to call it
                        // in case of an unexpected disconnection
                        var onDeviceDisconnected = _onDeviceDisconnected;

                        Disconnect();
                        onDeviceDisconnected?.Invoke(this);
                        break;

                    default:
                        break;
                    }
                }

                break;
            }
        }
Ejemplo n.º 12
0
        public override void OnConnectionStateChange(BluetoothGatt gatt, [GeneratedEnum] GattStatus status, [GeneratedEnum] ProfileState newState)
        {
            System.Diagnostics.Debug.WriteLine($"OnConnectionStateChanged - status: {status}, newState: {newState}");

            switch (newState)
            {
            case ProfileState.Connecting:
                break;

            case ProfileState.Connected:
                lock (_lock)
                {
                    if (State == BluetoothLEDeviceState.Connecting && status == GattStatus.Success)
                    {
                        State = BluetoothLEDeviceState.Discovering;
                        Task.Run(async() =>
                        {
                            await Task.Delay(750);
                            lock (_lock)
                            {
                                if (State == BluetoothLEDeviceState.Discovering && _bluetoothGatt != null)
                                {
                                    if (!_bluetoothGatt.DiscoverServices())
                                    {
                                        Disconnect();
                                        _connectCompletionSource?.SetResult(null);
                                    }
                                }
                            }
                        });
                    }
                    else
                    {
                        Disconnect();
                        _connectCompletionSource?.SetResult(null);
                    }
                }

                break;

            case ProfileState.Disconnecting:
                break;

            case ProfileState.Disconnected:
                lock (_lock)
                {
                    switch (State)
                    {
                    case BluetoothLEDeviceState.Connecting:
                    case BluetoothLEDeviceState.Discovering:
                        Disconnect();
                        _connectCompletionSource?.SetResult(null);
                        break;

                    case BluetoothLEDeviceState.Connected:
                        _writeCompletionSource?.SetResult(false);
                        Disconnect();
                        Disconnected?.Invoke(this, EventArgs.Empty);
                        break;

                    default:
                        break;
                    }
                }

                break;
            }
        }