public CoapBlockStreamWriter(CoapBlockWiseContext context, ICoapEndpoint endpoint = null) : base(context, endpoint) { if (!Context.Request.Code.IsRequest()) { throw new InvalidOperationException($"Can not create a {nameof(CoapBlockStreamWriter)} with a {nameof(context)}.{nameof(context.Request)}.{nameof(CoapMessage.Type)} of {context.Request.Type}"); } _writerTask = WriteBlocksAsync(); }
public IObservable <Message> SendMessage(Message message, ICoapEndpoint endpoint) { if (message is null) { return(Observable.Empty <Message>()); } var coapMessage = message.ToCoapMessage(); var messageContext = coapMessage.CreateBlockWiseContext(_coapClient); return(Observable.Create <Message>(observer => { var cts = new CancellationTokenSource(); Task.Run(async() => { try { if (coapMessage.IsBlockWise()) { using (var writer = new CoapBlockStreamWriter(messageContext, endpoint)) await message.PayloadStream.CopyToAsync(writer, writer.BlockSize); } else { var id = await _coapClient.SendAsync(coapMessage, endpoint, cts.Token); messageContext = new CoapBlockWiseContext(_coapClient, coapMessage, await _coapClient.GetResponseAsync(id, cts.Token)); } var response = messageContext.Response.ToMessage(); if (messageContext.Response.IsBlockWise()) { var memoryStream = new MemoryStream(); using (var reader = new CoapBlockStreamReader(messageContext, endpoint)) reader.CopyTo(memoryStream); response.Payload = memoryStream.ToArray(); } observer.OnNext(response); observer.OnCompleted(); } catch (Exception ex) { observer.OnError(ex); } }); return cts.Cancel; })); }
public CoapBlockStreamReader(CoapBlockWiseContext context, ICoapEndpoint endpoint = null) : base(context, endpoint) { if (context.Response == null) { throw new ArgumentNullException($"{nameof(context)}.{nameof(context.Response)}"); } var payload = Context.Response.Payload; Context.Request.Payload = null; Context.Response.Payload = null; if (payload != null) { _reader.Enqueue(payload, 0, payload.Length); } var block2 = Context.Response.Options.Get <Block2>(); if (block2 != null) { _readBlockNumber = block2.BlockNumber; BlockSizeInternal = block2.BlockSize; EndOfStream = !block2.IsMoreFollowing; if (payload != null) { _readBlockNumber += payload.Length / BlockSizeInternal; } _readerTask = ReadBlocksAsync(); } else { EndOfStream = true; _readerTask = Task.CompletedTask; } }