shinyorg / shiny

.NET Framework for Backgrounding & Device Hardware Services (iOS, Android, & Catalyst)
https://shinylib.net
MIT License
1.43k stars 227 forks source link

[Bug]: WriteCharacteristic is always timeout once "GATT is not connected" is thrown #1434

Closed ygl-rg closed 5 months ago

ygl-rg commented 5 months ago

Component/Nuget

BluetoothLE Client (Shiny.BluetoothLE)

What operating system(s) are effected?

Version(s) of Operation Systems

ios 16.7

Android: 13+

Shiny version: 3.1.2+

MAUI Version: 8.0.7

Hosting Model

Steps To Reproduce

  1. scanned a device
  2. connected to it with autoconnect is false
  3. called WriteCharacteristic
  4. walked away and returned
  5. started over 1

Expected Behavior

WriteCharacteristic is successful as long as the device is connected.

Actual Behavior

in step 3, once "GATT is not connected" is thrown, WriteCharacteristic would never been successful instead kept throwing Timeout exception.

the 2.7.x version works as expected.

Exception or Log output

No response

Code Sample

public class InitCommand
    {
        private readonly BleRefManager mgr;
        private CancellationTokenSource token_src;
        private int WAITING_MS;
        private string _password = string.Empty;

        public int POLL_DONGLE_MS { get; set; } = 20;

        public InitCommand(BleRefManager arg, string password, CancellationTokenSource src, int waiting_ms)
        {
            this.mgr = arg;
            this._password = password;
            this.token_src = src;
            this.WAITING_MS = waiting_ms;
        }

        public async Task<byte> Execute()
        {
            var cmd = createCommand();
            var result = await send(cmd);
            while (result == InitErrorCodes.Wait)
            {
                await Task.Delay(TimeSpan.FromMilliseconds(POLL_DONGLE_MS));
                var waitCmd = createCommand();
                result = await send(waitCmd);
            }
            return result;
        }

        Task<byte> send(byte[] cmd)
        {
            this.token_src.CancelAfter(this.WAITING_MS);
            var ob = Observable.Create<byte>(async x =>
            {
                IDisposable readSub = null;
                readSub = this.mgr.CurrentBle.Val
                    .NotifyCharacteristic(ServiceIds.SettingService, ServiceIds.SettingServiceRecv, false)
                    .Subscribe(c =>
                    {
                        Log.Logger.Information($"init cmd get {BitConverter.ToString(c.Data)}");
                        if (c.Data.Length <= 0) return;
                        x.OnNext(c.Data[0]);
                        x.OnCompleted();
                    });
                Log.Logger.Information($"init cmd {BitConverter.ToString(cmd)}");
                await this.mgr.CurrentBle.Val.WriteCharacteristic(ServiceIds.SettingService,
                    ServiceIds.SettingServiceSend, cmd, false).ToTask(this.token_src.Token);
                Log.Logger.Information($"init sent cmd {BitConverter.ToString(cmd)}");
                return () =>
                {
                    readSub?.Dispose();
                    readSub = null;
                };
            });
            return ob.ToTask(this.token_src.Token);
        }

        private byte[] createCommand()
        {
            var pwd_bytes = Array.Empty<byte>();
            if (this._password != string.Empty)
            {
                pwd_bytes = ByteTools.BigEndianEncode(ushort.Parse(this._password));
            }

            return ByteTools.ConcatBytes(CommandConsts.InitCmd, pwd_bytes);
        }
    }

Code of Conduct

aritchie commented 5 months ago

I don't see a connection anywhere in your code. You're going to have to submit something with a complete example

HausBJB commented 5 months ago

Hi everyone, I had the same error in my example, but I don't know if that was a consequential error now, but you can see under exceptions

https://github.com/shinyorg/shiny/issues/1433

image

aritchie commented 5 months ago

Insufficient sample provided. Please note that reproducible samples should be small, focused, and without additional abstractions.