This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Detect timeout of confirmable CoAP message

Hello
I would like to detect timeout when I send a confirmable coap message not received.
My problem is that the response I receive in my response_handler is always "OT_ERROR_RESPONSE_TIMEOUT" even if I receive the ack with the correct token and the correct message ID (I see it with Wireshark).
Do you see an error in what I did?

  
My function which sends the confirmable frame:
void thread_coap_utils_unicast_uart_request_send(otIp6Address                        *destination_address,
                                                    uint8_t                             message_length,
                                                    char                                *message)
{
    otError       error = OT_ERROR_NONE;
    otMessage   * p_request;
    otMessageInfo message_info;
    otInstance  * p_instance = thread_ot_instance_get();
    const char  * p_scope = NULL;

    do
    {
        if (otIp6IsAddressEqual(&destination_address, &m_unspecified_ipv6))
        {
            NRF_LOG_INFO("Failed to send the CoAP Request to the Unspecified IPv6 Address\r\n");
            break;
        }

        p_request = otCoapNewMessage(p_instance, NULL);
        if (p_request == NULL)
        {
            NRF_LOG_INFO("Failed to allocate message for CoAP Request\r\n");
            break;
        }
        otCoapMessageInit(p_request, OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_PUT);
        otCoapMessageGenerateToken(p_request, 2);

        error = otCoapMessageAppendUriPathOptions(p_request, "uart");
        ASSERT(error == OT_ERROR_NONE);

        otCoapMessageSetPayloadMarker(p_request);

        // decrease the polling period for higher responsiveness
        uint32_t err_code = poll_period_response_set();
        if (err_code == NRF_ERROR_BUSY)
        {
            break;
        }

        error = otMessageAppend(p_request, message, message_length);
        if (error != OT_ERROR_NONE)
        {
            break;
        }

        memset(&message_info, 0, sizeof(message_info));
        message_info.mPeerPort    = OT_DEFAULT_COAP_PORT;
        memcpy(&message_info.mPeerAddr, destination_address, sizeof(message_info.mPeerAddr));

        error = otCoapSendRequest(p_instance, p_request, &message_info, thread_coap_utils_response_handler, p_instance);
    } while (false);

    if (error != OT_ERROR_NONE && p_request != NULL)
    {
        NRF_LOG_INFO("Failed to send CoAP Request: %d\r\n", error);
        otMessageFree(p_request);
    }
}


My functions which ack the frame received:
static void uart_request_handler(void                * p_context,
                                                    otMessage           * p_message,
                                                    const otMessageInfo * p_message_info)
{
    UNUSED_PARAMETER(p_message);
    uint32_t err_code;
    char message[100];
    uint16_t message_length = 0;

    do
    {
        if (otCoapMessageGetType(p_message) != OT_COAP_TYPE_CONFIRMABLE &&
            otCoapMessageGetType(p_message) != OT_COAP_TYPE_NON_CONFIRMABLE)
        {
            break;
        }

        if (otCoapMessageGetCode(p_message) != OT_COAP_CODE_PUT)
        {
            break;
        }

        message_length = otMessageGetLength(p_message) - otMessageGetOffset(p_message);
        if(message_length<=0){break;}

        otMessageRead(p_message, otMessageGetOffset(p_message), &message, message_length);

        if (otCoapMessageGetType(p_message) == OT_COAP_TYPE_CONFIRMABLE)
        {
            thread_coap_utils_uart_response_send(p_message, p_message_info);
        }
        else if (otCoapMessageGetType(p_message) == OT_COAP_TYPE_NON_CONFIRMABLE)
        {
            // To do
        }

    } while (false);
}

void thread_coap_utils_uart_response_send(otMessage           * p_request_message,
                                           const otMessageInfo * p_message_info)
{
    otError    error = OT_ERROR_NO_BUFS;
    otMessage  * p_response;
    otInstance * p_instance = thread_ot_instance_get();
    do
    {
		p_response = otCoapNewMessage(p_instance, NULL);
		if (p_response == NULL)
		{
			NRF_LOG_ERROR("Could not create new message in ot_paring_response.");
			return;
		}

		error = otCoapMessageInitResponse(p_response,
										  p_request_message,
										  OT_COAP_TYPE_ACKNOWLEDGMENT,
										  OT_COAP_CODE_VALID);

		error = otCoapMessageSetToken(p_response,
									  otCoapMessageGetToken(p_request_message),
									  otCoapMessageGetTokenLength(p_request_message));
		if (error != OT_ERROR_NONE)
		{
			break;
		}

		error = otCoapMessageSetPayloadMarker(p_response);
		if (error != OT_ERROR_NONE)
		{
			break;
		}

		if (error != OT_ERROR_NONE)
		{
			NRF_LOG_ERROR("Could not init new message in ot_paring_response.");
		}
		else
		{
			error = otCoapSendResponse(p_instance, p_response, p_message_info);
			ASSERT(error == OT_ERROR_NONE);
		}
    } while (false);

    if ((error != OT_ERROR_NONE) && (p_response != NULL))
    {
        otMessageFree(p_response);
    }
}
My function managing the response of the command sent:
static void thread_coap_utils_response_handler(void           * p_context,
                                          otMessage           * p_message,
                                          const otMessageInfo * p_message_info,
                                          otError               result)
{
    UNUSED_PARAMETER(p_context);
    char str[6];
    itoa(otCoapMessageGetMessageId(p_message), str, 10);

    if (result == OT_ERROR_NONE)
    {
      if (otCoapMessageGetType(p_message) == OT_COAP_TYPE_ACKNOWLEDGMENT)
      {
          ret_code_t ret = 0;
          char  p_ack[] = "Ack message ";

          ret = uart_log_send_string(p_ack);
      }      
    }
    else 
    {
      if (result == OT_ERROR_RESPONSE_TIMEOUT)  // Coap response or acknowledgment or DNS response not received
      {
          ret_code_t ret = 0;
          char  p_ack[] = "Timeout message ";

          ret = uart_log_send_string(p_ack);
      }    
    }
}
Thank you
Related