UDP on openthread is not received

This example automatically create the thread network. Once the button is pressed every 3 second udp is sent. 

Issue is I am not receiving the packet on 2nd device. I am not seeing print from port_data_callback().

What am I missing? Thanks.

Using nrf52840 dongle, nrf connect 1.9.1

/*
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
 */

#include <zephyr.h>
#include <dk_buttons_and_leds.h>
#include <logging/log.h>
#include <net/openthread.h>
#include <openthread/thread.h>
#include <openthread/udp.h>
#include <sys/printk.h>
#include <usb/usb_device.h>
#include <drivers/uart.h>

LOG_MODULE_REGISTER(coap_server, CONFIG_COAP_SERVER_LOG_LEVEL);

BUILD_ASSERT(DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_shell_uart), zephyr_cdc_acm_uart),
	     "Console device is not ACM CDC UART device");

#define OT_CONNECTION_LED DK_LED1

static struct k_work udp_send_work;

static struct k_timer msg_timer;

const char buf[10] = "Hello\0";

otUdpSocket m_socket;

static void port_data_callback(void                * p_context,
                               otMessage           * p_message,
                               const otMessageInfo * p_message_info)
{
    LOG_INF("port_data_callback");
    // LOG_INF("ptr to msg = %08x",p_message);
}

static void init_udp() {
    otError error = otIp6SetEnabled(openthread_get_default_instance(), true);
    if( error ){
        LOG_ERR("otIp6SetEnabled = %u", error);
    }
    error = otUdpOpen(openthread_get_default_instance(), &m_socket, port_data_callback, NULL);
    if (error != OT_ERROR_NONE )
    {
        LOG_INF("otUdpOpen err = %u", error);
        return error;
    }
    else
    {
        LOG_INF("otUdpOpen SUCCESS!");
    }
}

otError send_udp(otUdpSocket *socket)
{
    otError error = OT_ERROR_NONE;

    otMessageInfo messageInfo;

    bool is_open = otUdpIsOpen(openthread_get_default_instance(), socket);
    if (is_open == false)
    {
    	LOG_INF("socket is not open!");
    }

    memset(&messageInfo, 0, sizeof(messageInfo));

    error = otIp6AddressFromString("ff03::1", &messageInfo.mPeerAddr);
    if (error != OT_ERROR_NONE )
    {
        LOG_INF("otIp6AddressFromString err = %u", error);
        return error;
    }
    messageInfo.mPeerPort = (uint16_t)1994;
    otMessageSettings settings;
    settings.mPriority=OT_MESSAGE_PRIORITY_NORMAL;
    settings.mLinkSecurityEnabled=true;

    otMessage *test_Message  = otUdpNewMessage(openthread_get_default_instance(), &settings);

    error = otMessageAppend(test_Message, buf, (uint16_t)strlen(buf));
    if (error != OT_ERROR_NONE )
    {
        LOG_INF("otMessageAppend err = %u", error);
        return error;
    }

    error = otUdpSend(openthread_get_default_instance(), socket, test_Message, &messageInfo);
    if(error != OT_ERROR_NONE)
    {
        LOG_ERR("otUdpSend err = %u",error);
        return error;
    }

     if(test_Message != NULL)
    {
        // otMessageFree(test_Message);
        LOG_INF("otMessageFree, to be added");
    }


    return error;
}

static void activate_udp_send(struct k_work *item)
{
	ARG_UNUSED(item);
	send_udp(&m_socket);
	k_timer_start(&msg_timer, K_SECONDS(3), K_NO_WAIT);

	LOG_INF("UDP send activated");
}

static void on_msg_timer_expiry(struct k_time *timer_id)
{
	ARG_UNUSED(timer_id);
	k_work_submit(&udp_send_work);
}

static void on_button_changed(uint32_t button_state, uint32_t has_changed)
{
	uint32_t buttons = button_state & has_changed;

	if (buttons & DK_BTN1_MSK) {
		k_work_submit(&udp_send_work);
	}
}

static void on_thread_state_changed(uint32_t flags, void *context)
{
	struct openthread_context *ot_context = context;

	if (flags & OT_CHANGED_THREAD_ROLE) {
		switch (otThreadGetDeviceRole(ot_context->instance)) {
		case OT_DEVICE_ROLE_CHILD:
		case OT_DEVICE_ROLE_ROUTER:
		case OT_DEVICE_ROLE_LEADER:
			dk_set_led_on(OT_CONNECTION_LED);
			break;

		case OT_DEVICE_ROLE_DISABLED:
		case OT_DEVICE_ROLE_DETACHED:
		default:
			dk_set_led_off(OT_CONNECTION_LED);
			break;
		}
	}
}

void main(void)
{
	int ret;
	k_timer_init(&msg_timer, on_msg_timer_expiry, NULL);

	k_work_init(&udp_send_work, activate_udp_send);

	ret = dk_leds_init();
	if (ret) {
		LOG_ERR("Could not initialize leds, err code: %d", ret);
		goto end;
	}

	ret = dk_buttons_init(on_button_changed);
	if (ret) {
		LOG_ERR("Cannot init buttons (error: %d)", ret);
		goto end;
	}

#if DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_shell_uart), zephyr_cdc_acm_uart)
	const struct device *dev;
	uint32_t dtr = 0U;

	ret = usb_enable(NULL);
	if (ret != 0) {
		LOG_ERR("Failed to enable USB");
		return;
	}

	dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_shell_uart));
	if (dev == NULL) {
		LOG_ERR("Failed to find specific UART device");
		return;
	}

	LOG_INF("Waiting for host to be ready to communicate");

	/* Data Terminal Ready - check if host is ready to communicate */
	while (!dtr) {
		ret = uart_line_ctrl_get(dev, UART_LINE_CTRL_DTR, &dtr);
		if (ret) {
			LOG_ERR("Failed to get Data Terminal Ready line state: %d",
				ret);
			continue;
		}
		k_msleep(100);
	}

	/* Data Carrier Detect Modem - mark connection as established */
	(void)uart_line_ctrl_set(dev, UART_LINE_CTRL_DCD, 1);
	/* Data Set Ready - the NCP SoC is ready to communicate */
	(void)uart_line_ctrl_set(dev, UART_LINE_CTRL_DSR, 1);
#endif

	openthread_set_state_changed_cb(on_thread_state_changed);
	openthread_start(openthread_get_default_context());
	init_udp();

end:
	return;
}

Parents
  • Hello,

    On the receiver, does any of the function calls in init_udp() return any errors?

    And on the receiver, does any of the function calls in send_udp() return any errors?

    Best regards,

    Edvin

  • I run same code on both devices posted above.

    No, init_udp() and send_udp() is not printing any error.

  • I got an update. I think UDP packet is received by the net_openthead but it's not propogated to the callback passed in by otUdpOpen() function. ( I have not verified by nrf sniffer yet)

    There are two devices in this screenshot. both devices are flashed with the code posted above. 

    left device addr- fe80:0:0:0:dc50:c721:81ac:8d9a:49153 send to ff02::1:1994 ----> received at right device

    right device addr: fe80:0:0:0:24af:a408:99fc:72e5:49153 send to ff02::1:1994 -----> received at left device

    Do I need to set any type of filter so, it can be seen in callback?

    After adding CONFIG_OPENTHREAD_LOG_LEVEL_INFO=y, I saw the prints starting [INFO]-MAC-----:

    prj.config

    #
    # Copyright (c) 2020 Nordic Semiconductor
    #
    # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
    #
    
    # nRF board library
    CONFIG_DK_LIBRARY=y
    
    #CONFIG_OPENTHREAD_NORDIC_LIBRARY_MASTER=y
    
    # Enable CoAP utils and CoAP protocol
    #CONFIG_COAP_UTILS=y
    
    
    # Enable OpenThread CoAP support API
    #CONFIG_OPENTHREAD_COAP=y
    
    # Configure sample logging setting
    CONFIG_LOG=y
    CONFIG_OPENTHREAD_LOG_LEVEL_INFO=y
    CONFIG_OPENTHREAD_DEBUG=y
    
    # Adjust log strdup settings
    CONFIG_LOG_STRDUP_MAX_STRING=512
    CONFIG_LOG_STRDUP_BUF_COUNT=10
    
    # Network shell
    CONFIG_SHELL=y
    CONFIG_OPENTHREAD_SHELL=y
    CONFIG_SHELL_ARGC_MAX=26
    CONFIG_SHELL_CMD_BUFF_SIZE=416
    
    # Network sockets
    CONFIG_NET_SOCKETS=y
    CONFIG_NET_SOCKETS_POSIX_NAMES=y
    CONFIG_NET_SOCKETS_POLL_MAX=4
    CONFIG_NET_IPV6=y
    CONFIG_NET_UDP=y
    
    # Same network Master Key for client and server
    CONFIG_OPENTHREAD_NETWORKKEY="00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff"
    
    # L2 OpenThread enabling
    CONFIG_NET_L2_OPENTHREAD=y
    
    # Generic networking options
    CONFIG_NETWORKING=y
    
    CONFIG_ASSERT=y
    CONFIG_ASSERT_NO_COND_INFO=y
    CONFIG_MBEDTLS_SHA1_C=n
    CONFIG_FPU=y
    
    CONFIG_SHELL_BACKEND_SERIAL_INIT_PRIORITY=51
    
    CONFIG_UART_LINE_CTRL=y
    CONFIG_SHELL_BACKEND_SERIAL_CHECK_DTR=y
    CONFIG_USB_CDC_ACM_LOG_LEVEL_OFF=y
    
    CONFIG_USB_DEVICE_STACK=y
    CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor ASA"
    CONFIG_USB_DEVICE_PRODUCT="Thread"
    CONFIG_USB_DEVICE_VID=0x1915
    CONFIG_USB_DEVICE_PID=0x0000

  • I just want to confirm:

    swap007 said:
    , init_udp() and send_udp() is not printing any error

    Does that mean that you see "otUdpOpen SUCCESS" in the log, or that you don't see anything?

    I am not sure about this one. We don't have any examples using this UDP other than deep inside "Matter", so it is not that easy to see how it is supposed to be used. 

    Assuming that this is Openthreads take on the UDP IP protocol, I would assume that it requires a bit more setup, such as an UDP port, which I assume will be part of the socket setup. 

    Perhaps you can try to both send and receive, but replace the other device (receiver and sender, respectively) with the CLI example.

    Looking at the testing description it looks like you need to bind to a port, and there is a function called otUdpBind(), so I believe you need to call this from the receiver. From the description it looks like the 3rd parameter in otUdpBind() is an otSockAddr, which contains a port number. 

    Best regards,

    Edvin

Reply
  • I just want to confirm:

    swap007 said:
    , init_udp() and send_udp() is not printing any error

    Does that mean that you see "otUdpOpen SUCCESS" in the log, or that you don't see anything?

    I am not sure about this one. We don't have any examples using this UDP other than deep inside "Matter", so it is not that easy to see how it is supposed to be used. 

    Assuming that this is Openthreads take on the UDP IP protocol, I would assume that it requires a bit more setup, such as an UDP port, which I assume will be part of the socket setup. 

    Perhaps you can try to both send and receive, but replace the other device (receiver and sender, respectively) with the CLI example.

    Looking at the testing description it looks like you need to bind to a port, and there is a function called otUdpBind(), so I believe you need to call this from the receiver. From the description it looks like the 3rd parameter in otUdpBind() is an otSockAddr, which contains a port number. 

    Best regards,

    Edvin

Children
No Data
Related