Example #1
0
        internal async Task <CoapMessage> RequestAsync(CoapMessage requestMessage, CancellationToken cancellationToken)
        {
            if (requestMessage is null)
            {
                throw new ArgumentNullException(nameof(requestMessage));
            }

            requestMessage.Id = _messageIdProvider.Next();

            var responseAwaiter = _messageDispatcher.AddAwaiter(requestMessage.Id);

            try
            {
                await _lowLevelClient.SendAsync(requestMessage, cancellationToken).ConfigureAwait(false);

                var responseMessage = await responseAwaiter.WaitOneAsync(_connectOptions.CommunicationTimeout).ConfigureAwait(false);

                if (responseMessage.Code == CoapMessageCodes.Empty)
                {
                    // TODO: Support message which are sent later (no piggybacking).
                }

                return(responseMessage);
            }
            finally
            {
                _messageDispatcher.RemoveAwaiter(requestMessage.Id);
            }
        }
Example #2
0
        public async Task <bool> TryHandleReceivedMessage(CoapMessage message)
        {
            if (message is null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            try
            {
                var observeOption = message.Options.FirstOrDefault(o => o.Number == CoapMessageOptionNumber.Observe);
                if (observeOption == null)
                {
                    return(false);
                }

                if (!_observedResponseHandlers.TryGetValue(new CoapMessageToken(message.Token), out var responseHandler))
                {
                    await DeregisterObservation(message).ConfigureAwait(false);

                    return(true);
                }

                if (message.Type == CoapMessageType.Confirmable)
                {
                    var ackMessage = new CoapMessage
                    {
                        Type = CoapMessageType.Acknowledgement,
                        Code = CoapMessageCodes.Empty,
                        Id   = message.Id
                    };

                    await _client.SendAsync(ackMessage, CancellationToken.None).ConfigureAwait(false);
                }

                var payload = message.Payload;

                // TODO: Check if supported etc.
                //if (CoapClientBlockTransferReceiver.IsBlockTransfer(coapMessage))
                //{
                //    payload = await new CoapClientBlockTransferReceiver(requestMessage, coapMessage, this, _logger).ReceiveFullPayload(CancellationToken.None).ConfigureAwait(false);
                //}

                var sequenceNumber = ((CoapMessageOptionUintValue)observeOption.Value).Value;
                var response       = _messageToResponseConverter.Convert(message, payload);

                await responseHandler.HandleResponseAsync(new HandleResponseContext
                {
                    SequenceNumber = sequenceNumber,
                    Response       = response
                }).ConfigureAwait(false);

                return(true);
            }
            catch (Exception exception)
            {
                _logger.Error(nameof(CoapClient), exception, "Error while handling observed message.");

                return(false);
            }
        }