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; })); }
/// <summary> /// Attempts to read the entire body of the block-wise message. Using the <paramref name="originalRequest"/> to request blocks. /// </summary> /// <param name="message">A message containing a <see cref="Block2"/> option.</param> /// <param name="client"></param> /// <param name="originalRequest">The orignal request which the block-wise response was for.</param> /// <returns>The completed body for the block-wise messages.</returns> public static byte[] GetCompletedBlockWisePayload(this CoapMessage message, CoapClient client, CoapMessage originalRequest) { var block2 = message.Options.Get <Options.Block2>() ?? throw new ArgumentException($"{nameof(CoapMessage)} does not contain a {nameof(Options.Block2)} option", nameof(message)); if (originalRequest == null) { throw new ArgumentNullException("Please provide original requesting message", nameof(originalRequest)); } if (block2.BlockNumber != 0) { throw new CoapBlockException($"Can not get completed payload starting with block {block2.BlockNumber}. Please start from 0"); } var memoryStream = new MemoryStream(); using (var reader = new CoapBlockStreamReader(client, message, originalRequest)) reader.CopyTo(memoryStream); return(memoryStream.ToArray()); }