/// <summary> /// Used for writing blobs /// </summary> /// <param name="ch">The characteristic to write on</param> /// <param name="stream">The stream to send</param> public static IObservable <BleWriteSegment> BlobWrite(this IGattCharacteristic ch, Stream stream) => Observable.Create <BleWriteSegment>(async(ob, ct) => { var trans = ch.Service.Peripheral.TryBeginTransaction() ?? new VoidGattReliableWriteTransaction(); using (trans) { var mtu = ch.Service.Peripheral.MtuSize; var buffer = new byte[mtu]; var read = stream.Read(buffer, 0, buffer.Length); var pos = read; var len = Convert.ToInt32(stream.Length); while (!ct.IsCancellationRequested && read > 0) { await trans .Write(ch, buffer) .ToTask(ct) .ConfigureAwait(false); //if (this.Value != buffer) //{ // trans.Abort(); // throw new GattReliableWriteTransactionException("There was a mismatch response"); //} var seg = new BleWriteSegment(buffer, pos, len); ob.OnNext(seg); read = stream.Read(buffer, 0, buffer.Length); pos += read; } await trans.Commit(); } ob.OnCompleted(); return(trans); });
/// <summary> /// Used for writing blobs /// </summary> /// <param name="ch">The characteristic to write on</param> /// <param name="stream">The stream to send</param> /// <param name="packetSendTimeout">How long to wait before timing out a packet send - defaults to 5 seconds</param> public static IObservable <BleWriteSegment> WriteBlobWithProgress(this IGattCharacteristic ch, Stream stream, TimeSpan?packetSendTimeout = null) => Observable.Create <BleWriteSegment>(async(ob, ct) => { var mtu = ch.Service.Peripheral.MtuSize; var buffer = new byte[mtu]; var read = stream.Read(buffer, 0, buffer.Length); var pos = read; var len = Convert.ToInt32(stream.Length); var remaining = 0; var timeout = packetSendTimeout ?? TimeSpan.FromSeconds(5); while (!ct.IsCancellationRequested && read > 0) { await ch .Write(buffer) .Timeout(timeout) .ToTask(ct) .ConfigureAwait(false); //if (this.Value != buffer) //{ // trans.Abort(); // throw new GattReliableWriteTransactionException("There was a mismatch response"); //} var seg = new BleWriteSegment(buffer, pos, len); ob.OnNext(seg); remaining = len - pos; if (remaining > 0 && remaining < mtu) { // readjust buffer -- we don't want to send extra garbage buffer = new byte[remaining]; } read = stream.Read(buffer, 0, buffer.Length); pos += read; } ob.OnCompleted(); return(Disposable.Empty); });