コード例 #1
0
        private async Task <(ProcedureCompletedEventArgs, AttributeValueEventArgs)> ReadByHandle(byte connection, ushort attributeHandle, CancellationToken cancellationToken, int timeout = DefaultTimeout)
        {
            Logger?.LogDebug($"Read device characteristic, Connection={connection}, AttributeHandle={attributeHandle}");

            var taskCompletionSource = new TaskCompletionSource <(ProcedureCompletedEventArgs, AttributeValueEventArgs)>();

            using (var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
            {
                cancellationTokenSource.CancelAfter(timeout);

                void OnAttributeValue(object sender, AttributeValueEventArgs e)
                {
                    if (e.connection == connection && e.atthandle == attributeHandle)
                    {
                        taskCompletionSource.SetResult((null, new AttributeValueEventArgs(e.connection, e.atthandle, e.type, e.value)));
                    }
                }

                try
                {
                    BgLib.BLEEventATTClientAttributeValue += OnAttributeValue;

                    using (cancellationTokenSource.Token.Register(() => taskCompletionSource.SetCanceled(), false))
                    {
                        BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandATTClientReadByHandle(connection, attributeHandle));

                        return(await taskCompletionSource.Task.ConfigureAwait(false));
                    }
                }
                finally
                {
                    BgLib.BLEEventATTClientAttributeValue -= OnAttributeValue;
                }
            }
        }
コード例 #2
0
        public async Task <ProcedureCompletedEventArgs> ExecuteAsync(byte connection, ushort attributeHandle, byte[] value, CancellationToken cancellationToken, int timeout = DefaultTimeout)
        {
            Logger?.LogDebug($"Write device characteristic, Connection={connection}, AttributeHandle={attributeHandle}, Value={value.ToHexString()}");

            var taskCompletionSource = new TaskCompletionSource <ProcedureCompletedEventArgs>();

            using (var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
            {
                cancellationTokenSource.CancelAfter(timeout);

                void OnProcedureCompleted(object sender, ProcedureCompletedEventArgs e)
                {
                    if (e.connection == connection && e.chrhandle == attributeHandle)
                    {
                        taskCompletionSource.SetResult(e);
                    }
                }

                try
                {
                    BgLib.BLEEventATTClientProcedureCompleted += OnProcedureCompleted;

                    using (cancellationTokenSource.Token.Register(() => taskCompletionSource.SetCanceled(), false))
                    {
                        BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandATTClientAttributeWrite(connection, attributeHandle, value));

                        return(await taskCompletionSource.Task.ConfigureAwait(false));
                    }
                }
                finally
                {
                    BgLib.BLEEventATTClientProcedureCompleted -= OnProcedureCompleted;
                }
            }
        }
コード例 #3
0
        private async Task <(ProcedureCompletedEventArgs, AttributeValueEventArgs)> ReadLong(byte connection, ushort attributeHandle, CancellationToken cancellationToken, int timeout = DefaultTimeout)
        {
            Logger?.LogDebug($"Read long device characteristic, Connection={connection}, AttributeHandle={attributeHandle}");

            var taskCompletionSource = new TaskCompletionSource <(ProcedureCompletedEventArgs, AttributeValueEventArgs)>();

            using (var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
            {
                cancellationTokenSource.CancelAfter(timeout);

                AttributeValueEventArgs attributeValueEventArgs = null;
                var attributeValueBuffer = new List <byte>();

                void OnAttributeValue(object sender, AttributeValueEventArgs e)
                {
                    if (e.connection == connection && e.atthandle == attributeHandle)
                    {
                        attributeValueEventArgs = e;
                        attributeValueBuffer.AddRange(e.value);
                    }
                }

                void OnProcedureCompleted(object sender, ProcedureCompletedEventArgs e)
                {
                    if (e.connection == connection && e.chrhandle == attributeHandle)
                    {
                        if (attributeValueEventArgs != null)
                        {
                            taskCompletionSource.SetResult((e, new AttributeValueEventArgs(attributeValueEventArgs.connection, attributeValueEventArgs.atthandle, attributeValueEventArgs.type, attributeValueBuffer.ToArray())));
                        }
                        else
                        {
                            taskCompletionSource.SetException(new Exception("Didn't receive any attribute values"));
                        }
                    }
                }

                try
                {
                    BgLib.BLEEventATTClientAttributeValue     += OnAttributeValue;
                    BgLib.BLEEventATTClientProcedureCompleted += OnProcedureCompleted;

                    using (cancellationTokenSource.Token.Register(() => taskCompletionSource.SetCanceled(), false))
                    {
                        BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandATTClientReadLong(connection, attributeHandle));

                        return(await taskCompletionSource.Task.ConfigureAwait(false));
                    }
                }
                finally
                {
                    BgLib.BLEEventATTClientAttributeValue     -= OnAttributeValue;
                    BgLib.BLEEventATTClientProcedureCompleted -= OnProcedureCompleted;
                }
            }
        }
コード例 #4
0
        public Task ExecuteAsync(byte connection)
        {
            Logger?.LogDebug($"Disconnect from device, Connection={connection}");

            var disconnect = BgLib.BLECommandConnectionDisconnect(connection);

            BgLib.SendCommand(BleModuleConnection.SerialPort, disconnect);

            return(Task.FromResult(0));
        }
コード例 #5
0
        public async Task <(List <BleCharacteristic>, List <BleAttribute>)> ExecuteAsync(byte connection, ushort startHandle, ushort endHandle, CancellationToken cancellationToken, int timeout = DefaultTimeout)
        {
            Logger?.LogDebug($"Find device characteristics, Connection={connection}, StartHandle={startHandle}, EndHandle={endHandle}");

            var taskCompletionSource = new TaskCompletionSource <(List <BleCharacteristic>, List <BleAttribute>)>();

            using (var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
            {
                cancellationTokenSource.CancelAfter(timeout);

                var attributes = new List <BleAttribute>();

                void OnFindInformationFound(object sender, FindInformationFoundEventArgs e)
                {
                    if (e.connection == connection)
                    {
                        attributes.Add(new BleAttribute(e.connection, e.uuid, e.chrhandle));
                    }
                }

                void OnProcedureCompleted(object sender, ProcedureCompletedEventArgs e)
                {
                    if (e.connection == connection)
                    {
                        if (attributes.Any())
                        {
                            var characteristics = ConvertAttributesToCharacteristics(attributes);
                            taskCompletionSource.SetResult((characteristics, attributes));
                        }
                        else
                        {
                            taskCompletionSource.SetException(new Exception("Couldn't find any characteristics"));
                        }
                    }
                }

                try
                {
                    BgLib.BLEEventATTClientFindInformationFound += OnFindInformationFound;
                    BgLib.BLEEventATTClientProcedureCompleted   += OnProcedureCompleted;

                    using (cancellationTokenSource.Token.Register(() => taskCompletionSource.SetCanceled(), false))
                    {
                        BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandATTClientFindInformation(connection, startHandle, endHandle));

                        return(await taskCompletionSource.Task.ConfigureAwait(false));
                    }
                }
                finally
                {
                    BgLib.BLEEventATTClientFindInformationFound -= OnFindInformationFound;
                    BgLib.BLEEventATTClientProcedureCompleted   -= OnProcedureCompleted;
                }
            }
        }
コード例 #6
0
        public async Task <List <BleService> > ExecuteAsync(byte connection, CancellationToken cancellationToken, int timeout = DefaultTimeout)
        {
            Logger?.LogDebug($"Find device services, Connection={connection}");

            var taskCompletionSource = new TaskCompletionSource <List <BleService> >();

            using (var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
            {
                cancellationTokenSource.CancelAfter(timeout);

                var services = new List <BleService>();

                void OnGroupFound(object sender, GroupFoundEventArgs e)
                {
                    if (e.connection == connection)
                    {
                        services.Add(new BleService(e.uuid, e.start, e.end));
                    }
                }

                void OnProcedureCompleted(object sender, ProcedureCompletedEventArgs e)
                {
                    if (e.connection == connection)
                    {
                        if (services.Any())
                        {
                            taskCompletionSource.SetResult(services);
                        }
                        else
                        {
                            taskCompletionSource.SetException(new Exception("Couldn't find any services"));
                        }
                    }
                }

                try
                {
                    BgLib.BLEEventATTClientGroupFound         += OnGroupFound;
                    BgLib.BLEEventATTClientProcedureCompleted += OnProcedureCompleted;

                    using (cancellationTokenSource.Token.Register(() => taskCompletionSource.SetCanceled(), false))
                    {
                        BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandATTClientReadByGroupType(connection, GattMinHandle, GattMaxHandle, (byte[])GattServiceTypePrimary));

                        return(await taskCompletionSource.Task.ConfigureAwait(false));
                    }
                }
                finally
                {
                    BgLib.BLEEventATTClientGroupFound         -= OnGroupFound;
                    BgLib.BLEEventATTClientProcedureCompleted -= OnProcedureCompleted;
                }
            }
        }
        public async Task <ScanResponseEventArgs> ExecuteAsync(ushort manufacturerId, CancellationToken cancellationToken, int timeout = DefaultTimeout)
        {
            Logger?.LogDebug($"Discover device by Manufacturer ID {manufacturerId}");

            var taskCompletionSource = new TaskCompletionSource <ScanResponseEventArgs>();

            using (var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
            {
                cancellationTokenSource.CancelAfter(timeout);

                void OnScanResponse(object sender, ScanResponseEventArgs e)
                {
                    var advertisementData             = BleAdvertisingDataParser.Parse(e.data);
                    var manufacturerAdvertisementData = advertisementData.SingleOrDefault(x => x.Type == BleAdvertisingDataType.ManufacturerSpecificData);

                    if (manufacturerAdvertisementData?.GetManufacturerId() == manufacturerId)
                    {
                        taskCompletionSource.SetResult(e);
                    }
                }

                try
                {
                    BgLib.BLEEventGAPScanResponse += OnScanResponse;

                    using (cancellationTokenSource.Token.Register(() => taskCompletionSource.SetCanceled(), false))
                    {
                        BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandGAPSetScanParameters(0xC8, 0xC8, 1));
                        BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandGAPDiscover(1));

                        return(await taskCompletionSource.Task.ConfigureAwait(false));
                    }
                }
                finally
                {
                    BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandGAPEndProcedure());

                    BgLib.BLEEventGAPScanResponse -= OnScanResponse;
                }
            }
        }
コード例 #8
0
        public async Task <ScanResponseEventArgs> ExecuteAsync(byte[] serviceUuid, CancellationToken cancellationToken, int timeout = DefaultTimeout)
        {
            Logger?.LogDebug($"Discover device by service Uuid {serviceUuid.ToHexString()}");

            var taskCompletionSource = new TaskCompletionSource <ScanResponseEventArgs>();

            using (var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
            {
                cancellationTokenSource.CancelAfter(timeout);

                void OnScanResponse(object sender, ScanResponseEventArgs e)
                {
                    var advertisementData = BleAdvertisingDataParser.Parse(e.data);

                    if (advertisementData.Where(x => ServiceUuidAdvertisements.Contains(x.Type)).Any(x => x.Data.SequenceEqual(serviceUuid)))
                    {
                        taskCompletionSource.SetResult(e);
                    }
                }

                try
                {
                    BgLib.BLEEventGAPScanResponse += OnScanResponse;

                    using (cancellationTokenSource.Token.Register(() => taskCompletionSource.SetCanceled(), false))
                    {
                        BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandGAPSetScanParameters(0xC8, 0xC8, 1));
                        BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandGAPDiscover(1));

                        return(await taskCompletionSource.Task.ConfigureAwait(false));
                    }
                }
                finally
                {
                    BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandGAPEndProcedure());

                    BgLib.BLEEventGAPScanResponse -= OnScanResponse;
                }
            }
        }
コード例 #9
0
        public async Task <StatusEventArgs> ExecuteAsync(byte[] address, BleAddressType addressType, CancellationToken cancellationToken, int timeout = DefaultTimeout)
        {
            Logger?.LogDebug($"Connect to device, Address={address.ToHexString()}, AddressType={addressType}");

            var taskCompletionSource = new TaskCompletionSource <StatusEventArgs>();

            using (var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
            {
                cancellationTokenSource.CancelAfter(timeout);

                void OnConnectionStatus(object sender, StatusEventArgs e)
                {
                    if ((e.flags & 0x05) == 0x05)
                    {
                        taskCompletionSource.SetResult(e);
                    }
                    else
                    {
                        taskCompletionSource.SetException(new Exception("Couldn't connect to device"));
                    }
                }

                try
                {
                    BgLib.BLEEventConnectionStatus += OnConnectionStatus;

                    using (cancellationTokenSource.Token.Register(() => taskCompletionSource.SetCanceled(), false))
                    {
                        BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandGAPConnectDirect((byte[])address, (byte)addressType, 0x20, 0x30, 0x100, 0));

                        return(await taskCompletionSource.Task.ConfigureAwait(false));
                    }
                }
                finally
                {
                    BgLib.BLEEventConnectionStatus -= OnConnectionStatus;
                }
            }
        }