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);
    }
}

Parents
  • 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

Reply
  • 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

Children
No Data
Related