Пример #1
0
        public async Task <byte> GAPConnectDirectAsync(string bluetoothAddress, BGGAPAdvertiserAddressType addressType, ushort connectIntervalMinMs, ushort connectIntervalMaxMs, ushort supervisionTimeoutMs, ushort latency)
        {
            const int TIMEOUT_MS = 6000;

            if (connectIntervalMinMs <= 7)
            {
                throw new ArgumentOutOfRangeException(
                          nameof(connectIntervalMaxMs),
                          "Connection Interval Min must be greater than 7ms"
                          );
            }
            var supervisionTimeoutMinMs = (1 + latency) * connectIntervalMaxMs * 2;

            if (supervisionTimeoutMs <= supervisionTimeoutMinMs)
            {
                throw new ArgumentException(
                          "According to the specification, the Supervision Timeout in milliseconds "
                          + "shall be larger than (1 + latency) * connectIntervalMaxMs * 2"
                          );
            }
            if (connectIntervalMaxMs < connectIntervalMinMs)
            {
                throw new ArgumentOutOfRangeException(
                          nameof(connectIntervalMaxMs),
                          "Connection Interval Max must be greater than or equal to Connection Interval Min"
                          );
            }

            var btaddr     = DataConverter.HexStringToByteArray(bluetoothAddress);
            var type       = (byte)addressType;
            var connIntMin = (UInt16)(connectIntervalMinMs / 1.25);
            var connIntMax = (UInt16)(connectIntervalMaxMs / 1.25);
            var timeout    = (UInt16)(supervisionTimeoutMs / 10);

            var cmd = _bglib.BLECommandGAPConnectDirect(btaddr, type, connIntMin, connIntMax, timeout, latency);
            await _bglib.SendCommandAsync(cmd).ConfigureAwait(false);

            using (var cts = new CancellationTokenSource(TIMEOUT_MS)) {
                bool didTimeout = false;
                try { await _cmdRespWaitHandle.WaitAsync(cts.Token).ConfigureAwait(false); }
                catch (OperationCanceledException) { didTimeout = true; }
                if (didTimeout)
                {
                    throw new TimeoutException();
                }
            }

            if (_lastResult != 0)
            {
                var    error  = Enum.ToObject(typeof(BGErrorCode), _lastResult);
                string errMsg = $"GAPConnectDirect returned: error={error} code=0x{_lastResult:X4}";
                throw new Exception(errMsg);
            }

            byte connectionHandle = ((ConnectDirectEventArgs)_lastResponseArgs).connection_handle;

            return(connectionHandle);
        }
 public void Connect(CancellationToken connectToken, CancellationToken appToken,
                     int connectTimeoutInMilliseconds, BgBleDevice deviceToConnect)
 {
     try
     {
         var lockTaken = false;
         Monitor.TryEnter(ThreadLock, 150, ref lockTaken);
         if (lockTaken)
         {
             if (_busy)
             {
                 return;
             }
             _busy = true;
             Monitor.Exit(ThreadLock);
         }
         _device        = deviceToConnect;
         _currentAction = new CancellationTokenSource();
         var connectToDevicesTokenSource =
             CancellationTokenSource.CreateLinkedTokenSource(connectToken,
                                                             _currentAction.Token);
         _bglib.SendCommand(_serialPort,
                            _bglib.BLECommandGAPConnectDirect(deviceToConnect.Identifier,
                                                              deviceToConnect.Advertisement.AddressType, 0x20, 0x30, 0x100, 0));
         WaitHandle.WaitAny(new[] { connectToDevicesTokenSource.Token.WaitHandle }, connectTimeoutInMilliseconds);
         // cleanup takes 125ms
         _bglib.SendCommand(_serialPort, _bglib.BLECommandGAPEndProcedure());
         WaitHandle.WaitAny(new[] { appToken.WaitHandle }, 130);
         _logger.LogInformation(
             $"ControlPlus Repository: Connected to device {deviceToConnect.Address} with {_device.Services.Count} services");
     }
     catch (Exception exception)
     {
         _logger.LogWarning(exception,
                            $"ControlPlus Repository: Unable to connect to device {deviceToConnect.Address}");
     }
     _deviceService = null;
     _device        = null;
     _busy          = false;
 }