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