OpenThread CoAP response is not transmitted

I have a NCS v2.0.0 OpenThread CoAP server running on a nRF52840 set up as a MTD SED (2s data poll) that seems to not be able to respond to CoAP requests. I can send the request from a Linux system running ot-daemon using ot-cli and aiocoap for Python, both give the same results. Basically the CoAP message is received, however, there seems to be no attempt at sending a response and with verbose low level logging enabled, I also see no attempts or warnings/errors. 

As an experiment, I overrode the response peer address with the multicast address (as opposed to the Linux system's IP Address from the request), and the response was sent. So this seems like an issue with the CoAP implementation? Or perhaps a settings issue? Here are the logs showing the nRF52840 receiving and "attempting" (at the application level) to send a response (you can see the second retransmit from the client side):

[00:00:10.834,472] <inf> net_openthread: [I] Mac-----------: Sent data poll, fp:yes
[00:00:10.862,030] <inf> net_openthread: [I] MeshForwarder-: Received IPv6 UDP msg, len:84, chksum:e3c1, ecn:no, from:0xd000, sec:yes, prio:normal, rss:-56.0
[00:00:10.862,335] <inf> net_openthread: [I] MeshForwarder-: src:[2601:40b:c200:44e0:225:caff:fe48:d83b]:45150
[00:00:10.862,640] <inf> net_openthread: [I] MeshForwarder-: dst:[fdca:27f4:d1ed:a0fe:61b1:b45c:6807:1f25]:5683
[00:00:10.862,792] <inf> command_server: diagnostic
[00:00:10.865,356] <inf> battery: Battery voltage: 2963V
[00:00:10.866,485] <inf> command: Sending response (MID 59527) to coap://[2601:40b:c200:44e0:225:caff:fe48:d83b]:45150
[00:00:10.866,516] <inf> command: Payload
[00:00:12.833,740] <inf> net_openthread: [I] Mac-----------: Sent data poll, fp:no
[00:00:14.834,838] <inf> net_openthread: [I] Mac-----------: Sent data poll, fp:yes
[00:00:14.861,968] <inf> net_openthread: [I] MeshForwarder-: Received IPv6 UDP msg, len:84, chksum:e3c1, ecn:no, from:0xd000, sec:yes, prio:normal, rss:-53.0
[00:00:14.862,274] <inf> net_openthread: [I] MeshForwarder-: src:[2601:40b:c200:44e0:225:caff:fe48:d83b]:45150
[00:00:14.862,579] <inf> net_openthread: [I] MeshForwarder-: dst:[fdca:27f4:d1ed:a0fe:61b1:b45c:6807:1f25]:5683
[00:00:16.834,320] <inf> net_openthread: [I] Mac-----------: Sent data poll, fp:no
[00:00:18.833,282] <inf> net_openthread: [I] Mac-----------: Sent data poll, fp:no


Here is a good attempt when I override the peer IP address with the multicast address:

[00:00:10.878,540] <inf> net_openthread: [I] MeshForwarder-: Received IPv6 UDP msg, len:84, chksum:4f33, ecn:no, from:0x0c00, sec:yes, prio:normal, rss:-38.0
[00:00:10.878,845] <inf> net_openthread: [I] MeshForwarder-: src:[2601:40b:c200:44e0:225:caff:fe48:d83b]:46874
[00:00:10.879,150] <inf> net_openthread: [I] MeshForwarder-: dst:[fdca:27f4:d1ed:a0fe:61b1:b45c:6807:1f25]:5683
[00:00:10.879,302] <inf> command_server: diagnostic
[00:00:10.881,866] <inf> battery: Battery voltage: 2959V
[00:00:10.882,843] <inf> command: Sending response (MID 53988) to coap://[ff03:0:0:0:0:0:0:2]:46874
[00:00:10.882,873] <inf> command: Payload
[00:00:10.901,092] <inf> net_openthread: [I] MeshForwarder-: Sent IPv6 HopOpts msg, len:257, chksum:0000, ecn:no, to:0x0c00, sec:yes, prio:normal
[00:00:10.901,397] <inf> net_openthread: [I] MeshForwarder-: src:[fdca:27f4:d1ed:a0fe:61b1:b45c:6807:1f25]
[00:00:10.901,672] <inf> net_openthread: [I] MeshForwarder-: dst:[ff03:0:0:0:0:0:0:2]


Config:

# Network
CONFIG_NETWORKING=y
CONFIG_NET_L2_OPENTHREAD=y
CONFIG_NET_UDP_CHECKSUM=y

# OpenThread
CONFIG_OPENTHREAD_THREAD_VERSION_1_2=y
CONFIG_OPENTHREAD_MANUAL_START=y
CONFIG_OPENTHREAD_MTD=y
CONFIG_OPENTHREAD_MTD_SED=y
CONFIG_OPENTHREAD_JOINER=y
CONFIG_OPENTHREAD_COAP=y
CONFIG_OPENTHREAD_COAP_BLOCK=y
CONFIG_OPENTHREAD_DEBUG=y
CONFIG_OPENTHREAD_LOG_LEVEL_INFO=y
CONFIG_OPENTHREAD_L2_DEBUG=y


Send response function:

otError xCommandResponseSend(otMessage *pxRequestMessage, const otMessageInfo *pxMessageInfo, uint8_t *pucData, uint16_t usLength)
{
	otError xErr = OT_ERROR_NONE;
	bool bBlock = false;
	uint64_t ullBlockValue = 0;
	otMessage *pxResponseMessage = NULL;
	otCoapCode xResponseCode = OT_COAP_CODE_EMPTY;
	BlockInfo_t xBlockInfo = {.pucData = pucData, .usLength = usLength};

	if (pucData == NULL && usLength > 0)
	{
		xErr = OT_ERROR_INVALID_ARGS;
	}

	if (otCoapMessageGetCode(pxRequestMessage) == OT_COAP_CODE_GET)
	{
		otCoapOptionIterator xIterator;
		xErr = otCoapOptionIteratorInit(&xIterator, pxRequestMessage);
		if (otCoapOptionIteratorGetFirstOptionMatching(&xIterator, OT_COAP_OPTION_BLOCK2) != NULL)
		{
			xErr = otCoapOptionIteratorGetOptionUintValue(&xIterator, &ullBlockValue);
			bBlock = true;
		}
	}

	if (xErr == OT_ERROR_NONE)
	{
		if (otCoapMessageGetType(pxRequestMessage) == OT_COAP_TYPE_CONFIRMABLE || otCoapMessageGetCode(pxRequestMessage) == OT_COAP_CODE_GET)
    	{
			if (otCoapMessageGetCode(pxRequestMessage) == OT_COAP_CODE_GET)
			{
				xResponseCode = OT_COAP_CODE_CONTENT;
			}
			else
			{
				xResponseCode = OT_COAP_CODE_VALID;
			}

			pxResponseMessage = otCoapNewMessage(openthread_get_default_instance(), NULL);
			if (pxResponseMessage == NULL)
			{
				xErr = OT_ERROR_NO_BUFS;
			}
		}
	}

	if (xErr == OT_ERROR_NONE)
	{
		pxResponseMessage = otCoapNewMessage(openthread_get_default_instance(), NULL);
		if (pxResponseMessage == NULL)
		{
			xErr = OT_ERROR_NO_BUFS;
		}
	}

	if (xErr == OT_ERROR_NONE)
	{
		xErr = otCoapMessageInitResponse(pxResponseMessage, pxRequestMessage, OT_COAP_TYPE_ACKNOWLEDGMENT, xResponseCode);
	}

	if (xErr == OT_ERROR_NONE && xResponseCode == OT_COAP_CODE_CONTENT)
	{
		if (bBlock == true)
		{
			xErr = otCoapMessageAppendBlock2Option(pxResponseMessage, (uint32_t)(ullBlockValue >> 4), true, (otCoapBlockSzx)(ullBlockValue & 0x7));
			if (xErr == OT_ERROR_NONE)
			{
				xErr = otCoapMessageSetPayloadMarker(pxResponseMessage);
			}
		}
		else
		{
			xErr = otCoapMessageSetPayloadMarker(pxResponseMessage);
			if (xErr == OT_ERROR_NONE)
			{
				xErr = otMessageAppend(pxResponseMessage, pucData, usLength);
			}
		}
	}

	if (xErr == OT_ERROR_NONE)
	{
		if (bBlock == true)
		{
			xErr = otCoapSendResponseBlockWise(openthread_get_default_instance(), pxResponseMessage, pxMessageInfo, &xBlockInfo, prvBlockwiseTxHook);
		}
		else
		{
			xErr = otCoapSendResponse(openthread_get_default_instance(), pxResponseMessage, pxMessageInfo);
		}
	}

	if (xErr != OT_ERROR_NONE && pxResponseMessage != NULL)
	{
		otMessageFree(pxResponseMessage);
	}

	if (xErr != OT_ERROR_NONE)
	{
		LOG_ERR("%s -> Unable to send CoAP response: %s (%d)", __FUNCTION__, otThreadErrorToString(xErr), xErr);
	}
	else
	{
		char cPeerAddr[OT_IP6_SOCK_ADDR_STRING_SIZE];
		otIp6AddressToString(&pxMessageInfo->mPeerAddr, cPeerAddr, OT_IP6_SOCK_ADDR_STRING_SIZE);

		LOG_INF("Sending response (MID %d) to coap://[%s]:%d", otCoapMessageGetMessageId(pxRequestMessage), cPeerAddr, pxMessageInfo->mPeerPort);

	}

	return xErr;
}



Parents Reply Children
  • I'm deleting my old answer. Everything was working while I was on a work trip in a different environment. Now that I'm home, the setup is no longer working ,which makes me wonder if there is an environmental issue causing this. In either case, I'm still stuck and this project is once again blocked. 

    The environment during my work trip had no other 802.15.4 devices in the area. However, there are a number of 802.15.4 devices in my house (Google Home, etc.). 



    Now I'm wondering if there is something going on related to my home environment.

  • I believe I found the issue and it is more related to the host Linux system's source IP address selection rules (I'm using Debian). By default, the system was using the wlan0 inet6 address as opposed to the wpan0 inet6 address (wpan0 is used by ot-daemon/RCP). I was able to fix this by changing the rules by setting the desired outgoing address as the home address. This causes the correct wpan0 inet6 address to win when the source selection rules are applied.

    The command I used was ip addr change fdca:27f4:d1ed:a0fe:6b70:406d:1275:4eb8 home dev wpan0. This change is not persistent and will need to be set permanently. 


Related