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 Reply Children
  • Thead start -> wait for device to have their role in network -> udp open -> create buffer -> udp send

    Address and port is not needed in initiation stage in otUdpOpen but it needs in otUDPsend().

    Detailed:

    - otUdpOpen ~ In this function parameter otUdpSocket does not need to be initalize with values. It can be memset(&m_socket, 0, sizeof(otUdpSocket)); otUdpReceive also need to be passed so, response can be seen when it receives

     - otUdpSend ~ In this function parameter otMessageInfo, it need the address (in my case ff03::1) and port 1234

    Note: I suggest Nordic to add this as an example, I have seen lot of people struggled on same issue in devzone forums.

    Best,

    Swap

Related