Ejemplo n.º 1
0
        private async Task ReadAttributeByType(GATTAttributeType attributeType, int timeoutMs)
        {
            Debug.WriteLine($"Discovering characteristics of type: {attributeType}");
            _uuidOfAttributeBeingRead = attributeType;

            await _bgApi.ATTClientReadByTypeAsync(
                ConnectionHandle,
                StartATTHandle,
                EndATTHandle,
                BitConverter.GetBytes((UInt16)_uuidOfAttributeBeingRead)
                ).ConfigureAwait(false);

            using (var cancel = new CancellationTokenSource(timeoutMs)) {
                try {
                    await _procedureCompletedWaitHandle
                    .WaitAsync(cancel.Token)
                    .ConfigureAwait(false);

                    _exceptionToRethrow?.Throw();
                }
                catch (OperationCanceledException) {
                    throw new TimeoutException($"Timeout occured while discovering characteristics of type: {attributeType}");
                }
            }
        }
Ejemplo n.º 2
0
        public override async Task <IReadOnlyCollection <Characteristic> > DiscoverCharacteristicsAsync(IList <byte[]> characteristicUUIDs = null, int timeoutMs = 10000)
        {
            try {
                ThrowIfDisposed();
                ThrowIfNotConnected();

                if (State != ServiceState.Idle)
                {
                    throw new Exception("Already busy discovering services");
                }
                State = ServiceState.DiscoveringCharacteristics;

                ClearCharacteristics();
                _bgApi.ATTClientAttributeValue     += BGApi_ATTClientAttributeValue;
                _bgApi.ATTClientProcedureCompleted += BGApi_ATTClientProcedureCompleted;
                _clientConfigurationAttributeHandles.Clear();

                // Discover characteristic declaration attributes
                await ReadAttributeByType(
                    GATTAttributeType.CharacteristicUUID,
                    timeoutMs / 2
                    ).ConfigureAwait(false);

                if (!Characteristics.Any())
                {
                    return(Characteristics);
                }

                // Discover client characteristic configuration attributes
                await ReadAttributeByType(
                    GATTAttributeType.CharacteristicClientConfigurationUUID,
                    timeoutMs / 2
                    ).ConfigureAwait(false);

                // now determine which characteristic each client characteristic configuration handle belongs to
                if ((_clientConfigurationAttributeHandles.Count == 1) && (Characteristics.Count == 1))
                {
                    Characteristics.First().CharacteristicClientConfigurationHandle =
                        _clientConfigurationAttributeHandles.First();
                }
                else if ((_clientConfigurationAttributeHandles.Count > 0) && (Characteristics.Count > 0))
                {
                    // sort the characteristic list by handle (ascending)
                    var charsAscending = Characteristics.OrderBy(
                        c => c.CharacteristicDeclarationHandle).ToArray();

                    // for each config handle, find the closest characteristic handle going up in values
                    foreach (var cfgHnd in _clientConfigurationAttributeHandles)
                    {
                        Characteristic charWhereCurrConfigHandleBelongs = null;
                        for (int i = 1; i < charsAscending.Length; i++)
                        {
                            var currCharHnd = charsAscending[i].CharacteristicDeclarationHandle;
                            var lastCharHnd = charsAscending[i - 1].CharacteristicDeclarationHandle;

                            if ((cfgHnd > lastCharHnd) && (cfgHnd < currCharHnd))
                            {
                                charWhereCurrConfigHandleBelongs = charsAscending[i - 1];
                                break;
                            }
                        }
                        if (charWhereCurrConfigHandleBelongs == null)
                        {
                            charWhereCurrConfigHandleBelongs = charsAscending.Last();
                        }
                        charWhereCurrConfigHandleBelongs.CharacteristicClientConfigurationHandle = cfgHnd;
                    }
                }
            }
            finally {
                _bgApi.ATTClientAttributeValue     -= BGApi_ATTClientAttributeValue;
                _bgApi.ATTClientProcedureCompleted -= BGApi_ATTClientProcedureCompleted;
                _exceptionToRethrow       = null;
                _uuidOfAttributeBeingRead = 0;
                _clientConfigurationAttributeHandles.Clear();
            }

            State = ServiceState.Idle;

            var results = FilterCharacteristicsByUUIDs(Characteristics, characteristicUUIDs);

            return(results);
        }