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

Thread GET response issue

Hello every one !

I am trying to use the GET_CODE to ask information from one of my device.

I have a ressource called RES1 to which I send a GET request with the following fonction.

void thread_coap_TRYGET_request_send(otInstance * p_instance, otIp6Address* add){  
    otError       error = OT_ERROR_NONE;
    otMessage   * p_request;
    otMessageInfo message_info;
    otCoapHeader  header;
	
    do
		{	
				
			otCoapHeaderInit(&header, OT_COAP_TYPE_NON_CONFIRMABLE, OT_COAP_CODE_GET);
			otCoapHeaderGenerateToken(&header, 2);	
            UNUSED_VARIABLE(otCoapHeaderAppendUriPathOptions(&header, "RES1"));
            UNUSED_VARIABLE(otCoapHeaderSetPayloadMarker(&header));
				
            memset(&message_info, 0, sizeof(message_info));
            message_info.mInterfaceId = OT_NETIF_INTERFACE_ID_THREAD;
            message_info.mPeerPort    = OT_DEFAULT_COAP_PORT;
			memcpy(&message_info.mPeerAddr, add, sizeof(otIp6Address));
				
			p_request = otCoapNewMessage(p_instance, &header);
            if (p_request == NULL)
            {
                break;
            }
				
            error = otCoapSendRequest(p_instance, p_request, &message_info,thread_coap_TRYGET_response_handler, p_instance);	
				
    		if (error == OT_ERROR_NONE){
    				LEDS_INVERT(BSP_LED_2_MASK);
    		}
        } 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);
    }
}

First of all : could any one tell me if a CONFIRMABLE header type necesseraly needs an acknoledge answer ? if not I can use it as a trick to repeat the request until I get a response.

Also I found out if there is no data append (otMessageAppend) into the message, I got an OT_ERROR_PARSE.

So to get a message send, I had to add to have a OT_ERROR_NONE

uint8_t data = 0;
error = otMessageAppend(p_request, &data, sizeof(data));

The requested device executes the following code (I would like to send back data2send)

    otError      error = OT_ERROR_NO_BUFS;
    otCoapHeader header;
    otMessage  * p_response;
    uint8_t data2send = 0;
    
    do
    {
		//otCoapHeaderInit(&header, OT_COAP_TYPE_ACKNOWLEDGMENT, OT_COAP_CODE_CHANGED);
        otCoapHeaderInit(&header, OT_COAP_TYPE_NON_CONFIRMABLE , OT_COAP_CODE_CONTENT);
        otCoapHeaderSetMessageId(&header, otCoapHeaderGetMessageId(p_request_header));
        otCoapHeaderSetToken(&header,
                             otCoapHeaderGetToken(p_request_header),
                             otCoapHeaderGetTokenLength(p_request_header));

        p_response = otCoapNewMessage(p_context, &header);
        if (p_response == NULL)
        {
            break;
        }
				
		error = otMessageAppend(p_response, &data2send,  sizeof(uint8_t));
        error = otCoapSendResponse(p_context, p_response, p_message_info);

    } while (false);

    if ((error != OT_ERROR_NONE) && (p_response != NULL))
    {
        otMessageFree(p_response);
    }

Again, the message is not sent and I have an OT_ERROR_PARSE.

Is otCoapSendRequest made only for TYPE_ACKNOLEDGMENT  ?

I replaced the otCoapSendRequest  by a otCoapSendRequest(p_context, p_response, p_message_info, NULL, NULL) but I got the same issue.

I tried a few things, the only times I get into this thread_coap_TRYGET_response_handler is when I used

CONFIRMABLE request, and TYPE_ACKNOLEDGMENT and CODE_CHANGED into the response.

But in the TYPE_ACKNOLEDGMENT  case if I put data with otMessageAppend, the response is not sent (OT_ERROR_PARSE)

Would you have any idea of what is wrong with my code ?

void thread_coap_TRYGET_request_send(otInstance * p_instance, otIp6Address* add){  
    otError       error = OT_ERROR_NONE;
    otMessage   * p_request;
    otMessageInfo message_info;
    otCoapHeader  header;
	
    do
		{	
				
			otCoapHeaderInit(&header, OT_COAP_TYPE_NON_CONFIRMABLE, OT_COAP_CODE_GET);
			otCoapHeaderGenerateToken(&header, 2);	
            UNUSED_VARIABLE(otCoapHeaderAppendUriPathOptions(&header, "RES1"));
            UNUSED_VARIABLE(otCoapHeaderSetPayloadMarker(&header));
				
            memset(&message_info, 0, sizeof(message_info));
            message_info.mInterfaceId = OT_NETIF_INTERFACE_ID_THREAD;
            message_info.mPeerPort    = OT_DEFAULT_COAP_PORT;
			memcpy(&message_info.mPeerAddr, add, sizeof(otIp6Address));
				
			p_request = otCoapNewMessage(p_instance, &header);
            if (p_request == NULL)
            {
                break;
            }
				
            error = otCoapSendRequest(p_instance, p_request, &message_info,thread_coap_TRYGET_response_handler, p_instance);	
				
    		if (error == OT_ERROR_NONE){
    				LEDS_INVERT(BSP_LED_2_MASK);
    		}
        } 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);
    }
}

  • Hi Simon,

    Unfortunately we have reduce staffing during next week due to Easter holiday. We will try to answer as soon as possible, unless someone in the community are able to help you in the meantime Slight smile

    Best Regards,

    Marjeris

  • Hi Simon,

    Sorry for the very delay response. I am quite new to the Thread SDK and needed some time to dig into it.

    Firstly, I don't know if you are aware of but a new version of the Zigbee & Thread SDK has been released (v3.0.0). I strongly recommend switching to the new version.

    I found some discrepancies between your code and the way request send and response send functions are implemented in the examples in our SDK.

    In your thread_coap_TRYGET_request_send function you are calling otCoapHeaderSetPayloadMarker, this function adds a Payload Marker indicating the beginning of the payload. This is not necessary to do when doing sending a get request, as you are not appending any payload.

    From RFC7252, page 16: " The presence of a marker followed by a zero-length payload MUST be processed as a message format error." So this why you are getting OT_ERROR_PARSE when no data was appended.

    Then in the request response you want to send a payload, but you haven't set a payload marker before otMessageAppend and otCoapSendRequest. For SDK v3.0.0 you should add:

    error = otCoapMessageSetPayloadMarker(p_response);
    ASSERT(error == OT_ERROR_NONE);

     think this two things should be able to fix your problem. Let me know how it goes.

    Best Regards,

    Marjeris

Related