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

Thread Border Router networking fail

Hello Nordic Taam:

I follow the WEB steps below

https://infocenter.nordicsemi.com/index.jsp?topic=%2Fsdk_tz_v4.1.0%2Fthread_ot_performance_measurement.html

Software Development Kit > nRF5 SDK for Thread and Zigbee v4.1.0 > Thread > Thread tools > Thread Border Router

nRF52840 DK Version:nRF5_SDK_for_Thread_and_Zigbee_v4.1.0_32ce5f8\examples\thread\ncp\ftd\uart\hex

Raspberry Pi 3 Version:RaspPi_OT_Border_Router_Demo_v4.1.0-1.alpha

Use nRF52840 DK UART connect Raspberry Pi 3 to get the following information

wpan0 => [
"NCP:State" => "associating"
"Daemon:Enabled" => true
"NCP:Version" => "OPENTHREAD/20191113-00534-gc6a258e3; NRF52840; Apr 5 2020 21:51:18"
"Daemon:Version" => "0.08.00d (; Apr 21 2020 19:11:43)"
"Config:NCP:DriverName" => "spinel"
"NCP:HardwareAddress" => [F4CE363EC3C45B0E]
]


pi@raspberrypi:~ $ sudo wpanctl status
wpan0 => [
"NCP:State" => "uninitialized"
"Daemon:Enabled" => true
"NCP:Version" => ""
"Daemon:Version" => "0.08.00d (; Apr 21 2020 19:11:43)"
"Config:NCP:DriverName" => "spinel"
"NCP:HardwareAddress" => [F4CE363EC3C45B0E]
]

If I have the wrong steps or have not completed, please give me some pointers, thank you.

Also, can you teach me how to set up the Thread Border Router successfully on Raspberry Pi 3?

Best Regards

Rick.

Parents
  • Hi,

    The instructions on Thread Border Router is the latest and should be correct. It also looks like you are using the correct versions of the firmware and border router image. 

    I have tested this multiple times before, and have not had any issues with getting the network up and running.

    Are you using a revision 1 DK or later? Did you have the DK connected to the RPi before you booted it? Did you run 'erase all' command on the DK before flashing the NCP FW? You did not run any other commands on the border router prior to the "sudo wpanctl status" command?

    If nothing works, I would suggest that you start over and flash the DK and border router image again to the devices to see if that solves any issues.

    Best regards,
    Jørgen

  • Hi Jørgen:

    How are you today!

    Is there any update?

    Pls kindly help advise how to solve it?

    Best Regards,

    Rick.

  • Hi Jørgen,

    I get the message_type is 1.

    both are the same.

    Pls kindly help advise how to solve it?

    Best Regards,

    Rick.

  • Hi Jørgen:

    How are you today!

    Are you have any advice? and are you have the same issue?

    Pls kindly help advise how to solve it?

    Best Regards,

    Rick.

  • Hi Rick,

    I tested this on my end, and I am seeing the same behavior. I believe that the unhandled event message happens because the second board is in a state where it does not expect to receive this event when the first board does a Gateway search. The examples are most likely not written with multiple publishers in mind.

    I'm not sure if the limitation is in the example code, or in the configuration of the Eclipse Paho MQTT-SN Gateway on the Raspberry Pi, but a workaround that seems to work is to disconnect after each node is done publishing (by pushing button 3), and reconnecting (by pressing button 3) on the second board before pressing button 4 to publish a message. You can also integrate this into a single button-press:

    case BSP_EVENT_KEY_3:
    {
        uint32_t err_code;
    
        if (mqttsn_client_state_get(&m_client) == MQTTSN_CLIENT_DISCONNECTED)
        {
            err_code = mqttsn_client_connect(&m_client, &m_gateway_addr, m_gateway_id, &m_connect_opt);
            if (err_code != NRF_SUCCESS)
            {
                NRF_LOG_ERROR("CONNECT message could not be sent. Error: 0x%x\r\n", err_code);
            }
        }
        while(ready_to_publish == false)
        {
            thread_process();
        }
        publish();
        while(ready_to_publish == true)
        {
            thread_process();
        }
        err_code = mqttsn_client_disconnect(&m_client);
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("DISCONNECT message could not be sent. Error: 0x%x\r\n", err_code);
        }
        break;
    }

    You also needs to declare the flag in top of main.c:

    static uint8_t ready_to_publish = false;

    And set/clear the flags in the appropriate event cases:

    case MQTTSN_EVENT_REGISTERED:
        NRF_LOG_INFO("MQTT-SN event: Client registered topic.\r\n");
        regack_callback(p_event);
        ready_to_publish = true;
        break;
    
    case MQTTSN_EVENT_PUBLISHED:
        NRF_LOG_INFO("MQTT-SN event: Client has successfully published content.\r\n");
        ready_to_publish = false;
        break;

    You can now remove/comment out the entire BSP_EVENT_KEY_2 case, as this is no longer needed.

    Attaching full main.c as well: 

    /**
     * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
     *
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    /** @file
     *
     * @defgroup thread_mqttsn_publisher_example_main main.c
     * @{
     * @ingroup thread_mqttsn_publisher_example
     * @brief Thread MQTT-SN Client Publisher Example Application main file.
     *
     * @details This example demonstrates an MQTT-SN client publisher application that enables to toggle
     *          BSP_LED_2 on a board with related MQTT-SN client subscriber application via MQTT-SN messages.
     *
     */
    
    #include <stdbool.h>
    #include <stdint.h>
    #include <string.h>
    
    #include "app_scheduler.h"
    #include "app_timer.h"
    #include "bsp_thread.h"
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    #include "mqttsn_client.h"
    #include "thread_utils.h"
    
    #include <openthread/thread.h>
    
    #define SEARCH_GATEWAY_TIMEOUT 5                                            /**< MQTT-SN Gateway discovery procedure timeout in [s]. */
    
    #define SCHED_QUEUE_SIZE       32                                           /**< Maximum number of events in the scheduler queue. */
    #define SCHED_EVENT_DATA_SIZE  APP_TIMER_SCHED_EVENT_DATA_SIZE              /**< Maximum app_scheduler event size. */
    
    static mqttsn_client_t      m_client;                                       /**< An MQTT-SN client instance. */
    static mqttsn_remote_t      m_gateway_addr;                                 /**< A gateway address. */
    static uint8_t              m_gateway_id;                                   /**< A gateway ID. */
    static mqttsn_connect_opt_t m_connect_opt;                                  /**< Connect options for the MQTT-SN client. */
    static uint8_t              m_led_state        = 0;                         /**< Previously sent BSP_LED_2 command. */
    static uint16_t             m_msg_id           = 0;                         /**< Message ID thrown with MQTTSN_EVENT_TIMEOUT. */
    static char                 m_client_id[]      = "nRF52840_publisher";      /**< The MQTT-SN Client's ID. */
    static char                 m_topic_name[]     = "nRF52840_resources/led3"; /**< Name of the topic corresponding to subscriber's BSP_LED_2. */
    static mqttsn_topic_t       m_topic            =                            /**< Topic corresponding to subscriber's BSP_LED_2. */
    {
        .p_topic_name = (unsigned char *)m_topic_name,
        .topic_id     = 0,
    };
    static uint8_t ready_to_publish = false;
    
    /***************************************************************************************************
     * @section MQTT-SN
     **************************************************************************************************/
    
    /**@brief Turns the MQTT-SN network indication LED on.
     *
     * @details This LED is on when an MQTT-SN client is in connected or awake state.
     */
    static void light_on(void)
    {
        LEDS_ON(BSP_LED_3_MASK);
    }
    
    
    /**@brief Turns the MQTT-SN network indication LED off.
     *
     * @details This LED is on when an MQTT-SN client is in disconnected or asleep state.
     */
    static void light_off(void)
    {
        LEDS_OFF(BSP_LED_3_MASK);
    }
    
    /**@brief Initializes MQTT-SN client's connection options.
     */
    static void connect_opt_init(void)
    {
        m_connect_opt.alive_duration = MQTTSN_DEFAULT_ALIVE_DURATION,
        m_connect_opt.clean_session  = MQTTSN_DEFAULT_CLEAN_SESSION_FLAG,
        m_connect_opt.will_flag      = MQTTSN_DEFAULT_WILL_FLAG,
        m_connect_opt.client_id_len  = strlen(m_client_id),
    
        memcpy(m_connect_opt.p_client_id, (unsigned char *)m_client_id, m_connect_opt.client_id_len);
    }
    
    
    /**@brief Processes GWINFO message from a gateway.
     *
     * @details This function updates MQTT-SN Gateway information.
     *
     * @param[in]    p_event  Pointer to MQTT-SN event.
     */
    static void gateway_info_callback(mqttsn_event_t * p_event)
    {
        m_gateway_addr = *(p_event->event_data.connected.p_gateway_addr);
        m_gateway_id   = p_event->event_data.connected.gateway_id;
    }
    
    
    /**@brief Processes CONNACK message from a gateway.
     *
     * @details This function launches the topic registration procedure if necessary.
     */
    static void connected_callback(void)
    {
        light_on();
    
        uint32_t err_code = mqttsn_client_topic_register(&m_client,
                                                         m_topic.p_topic_name,
                                                         strlen(m_topic_name),
                                                         &m_msg_id);
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("REGISTER message could not be sent. Error code: 0x%x\r\n", err_code);
        }
    }
    
    
    /**@brief Processes DISCONNECT message from a gateway. */
    static void disconnected_callback(void)
    {
        light_off();
    }
    
    
    /**@brief Processes REGACK message from a gateway.
     *
     * @param[in] p_event Pointer to MQTT-SN event.
     */
    static void regack_callback(mqttsn_event_t * p_event)
    {
        m_topic.topic_id = p_event->event_data.registered.packet.topic.topic_id;
        NRF_LOG_INFO("MQTT-SN event: Topic has been registered with ID: %d.\r\n",
                     p_event->event_data.registered.packet.topic.topic_id);
    }
    
    
    /**@brief Processes retransmission limit reached event. */
    static void timeout_callback(mqttsn_event_t * p_event)
    {
        NRF_LOG_INFO("MQTT-SN event: Timed-out message: %d. Message ID: %d.\r\n",
                      p_event->event_data.error.msg_type,
                      p_event->event_data.error.msg_id);
    }
    
    
    /**@brief Processes results of gateway discovery procedure. */
    static void searchgw_timeout_callback(mqttsn_event_t * p_event)
    {
        NRF_LOG_INFO("MQTT-SN event: Gateway discovery result: 0x%x.\r\n", p_event->event_data.discovery);
    }
    
    /**@brief Function for handling MQTT-SN events. */
    void mqttsn_evt_handler(mqttsn_client_t * p_client, mqttsn_event_t * p_event)
    {
        switch(p_event->event_id)
        {
            case MQTTSN_EVENT_GATEWAY_FOUND:
                NRF_LOG_INFO("MQTT-SN event: Client has found an active gateway.\r\n");
                gateway_info_callback(p_event);
                break;
    
            case MQTTSN_EVENT_CONNECTED:
                NRF_LOG_INFO("MQTT-SN event: Client connected.\r\n");
                connected_callback();
                break;
    
            case MQTTSN_EVENT_DISCONNECT_PERMIT:
                NRF_LOG_INFO("MQTT-SN event: Client disconnected.\r\n");
                disconnected_callback();
                break;
    
            case MQTTSN_EVENT_REGISTERED:
                NRF_LOG_INFO("MQTT-SN event: Client registered topic.\r\n");
                regack_callback(p_event);
                ready_to_publish = true;
                break;
    
            case MQTTSN_EVENT_PUBLISHED:
                NRF_LOG_INFO("MQTT-SN event: Client has successfully published content.\r\n");
                ready_to_publish = false;
                break;
    
            case MQTTSN_EVENT_TIMEOUT:
                NRF_LOG_INFO("MQTT-SN event: Retransmission retries limit has been reached.\r\n");
                timeout_callback(p_event);
                break;
    
            case MQTTSN_EVENT_SEARCHGW_TIMEOUT:
                NRF_LOG_INFO("MQTT-SN event: Gateway discovery procedure has finished.\r\n");
                searchgw_timeout_callback(p_event);
                break;
    
            default:
                NRF_LOG_INFO("MQTT-SN unhandled event: %d\r\n", p_event->event_id);
                break;
        }
    }
    
    /***************************************************************************************************
     * @section State
     **************************************************************************************************/
    
    static void state_changed_callback(uint32_t flags, void * p_context)
    {
        NRF_LOG_INFO("State changed! Flags: 0x%08x Current role: %d\r\n",
                     flags, otThreadGetDeviceRole(p_context));
    }
    
    /***************************************************************************************************
     * @section Buttons
     **************************************************************************************************/
    
    static void led_state_pub(uint8_t led_state)
    {
        uint32_t err_code = mqttsn_client_publish(&m_client, m_topic.topic_id, &led_state, 1, &m_msg_id);
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("PUBLISH message could not be sent. Error code: 0x%x\r\n", err_code)
        }
    }
    
    static void publish(void)
    {
        m_led_state = m_led_state == 1 ? 0 : 1;
        led_state_pub(m_led_state);
    }
    
    static void bsp_event_handler(bsp_event_t event)
    {
        if (otThreadGetDeviceRole(thread_ot_instance_get()) < OT_DEVICE_ROLE_CHILD )
        {
            (void)event;
            return;
        }
        
        switch (event)
        {
            case BSP_EVENT_KEY_1:
            {
                uint32_t err_code = mqttsn_client_search_gateway(&m_client, SEARCH_GATEWAY_TIMEOUT);
                if (err_code != NRF_SUCCESS)
                {
                    NRF_LOG_ERROR("SEARCH GATEWAY message could not be sent. Error: 0x%x\r\n", err_code);
                }
                break;
            }
    
            case BSP_EVENT_KEY_2:
            {
    //            uint32_t err_code;
    //
    //            if (mqttsn_client_state_get(&m_client) == MQTTSN_CLIENT_CONNECTED)
    //            {
    //                err_code = mqttsn_client_disconnect(&m_client);
    //                if (err_code != NRF_SUCCESS)
    //                {
    //                    NRF_LOG_ERROR("DISCONNECT message could not be sent. Error: 0x%x\r\n", err_code);
    //                }
    //            }
    //            else
    //            {
    //                err_code = mqttsn_client_connect(&m_client, &m_gateway_addr, m_gateway_id, &m_connect_opt);
    //                if (err_code != NRF_SUCCESS)
    //                {
    //                    NRF_LOG_ERROR("CONNECT message could not be sent. Error: 0x%x\r\n", err_code);
    //                }
    //            }
                break;
            }
    
            case BSP_EVENT_KEY_3:
            {
                uint32_t err_code;
    
                if (mqttsn_client_state_get(&m_client) == MQTTSN_CLIENT_DISCONNECTED)
                {
                    err_code = mqttsn_client_connect(&m_client, &m_gateway_addr, m_gateway_id, &m_connect_opt);
                    if (err_code != NRF_SUCCESS)
                    {
                        NRF_LOG_ERROR("CONNECT message could not be sent. Error: 0x%x\r\n", err_code);
                    }
                }
                while(ready_to_publish == false)
                {
                    thread_process();
                }
                publish();
                while(ready_to_publish == true)
                {
                    thread_process();
                }
                err_code = mqttsn_client_disconnect(&m_client);
                if (err_code != NRF_SUCCESS)
                {
                    NRF_LOG_ERROR("DISCONNECT message could not be sent. Error: 0x%x\r\n", err_code);
                }
                break;
            }
    
            default:
                break;
        }
    }
    
    /***************************************************************************************************
     * @section Initialization
     **************************************************************************************************/
    
    /**@brief Function for initializing the Application Timer Module.
     */
    static void timer_init(void)
    {
        uint32_t err_code = app_timer_init();
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for initializing the LEDs.
     */
    static void leds_init(void)
    {
        LEDS_CONFIGURE(LEDS_MASK);
        LEDS_OFF(LEDS_MASK);
    }
    
    
    /**@brief Function for initializing the nrf log module.
     */
    static void log_init(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    }
    
    
    /**@brief Function for initializing the Thread Board Support Package.
     */
    static void thread_bsp_init(void)
    {
        uint32_t err_code;
        err_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_event_handler);
        APP_ERROR_CHECK(err_code);
    
        err_code = bsp_thread_init(thread_ot_instance_get());
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for initializing the Thread Stack.
     */
    static void thread_instance_init(void)
    {
        thread_configuration_t thread_configuration =
        {
            .radio_mode        = THREAD_RADIO_MODE_RX_ON_WHEN_IDLE,
            .autocommissioning = true,
        };
    
        thread_init(&thread_configuration);
        thread_cli_init();
        thread_state_changed_callback_set(state_changed_callback);
    }
    
    
    /**@brief Function for initializing the MQTTSN client.
     */
    static void mqttsn_init(void)
    {
        uint32_t err_code = mqttsn_client_init(&m_client,
                                               MQTTSN_DEFAULT_CLIENT_PORT,
                                               mqttsn_evt_handler,
                                               thread_ot_instance_get());
        APP_ERROR_CHECK(err_code);
    
        connect_opt_init();
    }
    
    
    /**@brief Function for initializing scheduler module.
     */
    static void scheduler_init(void)
    {
        APP_SCHED_INIT(SCHED_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE);
    }
    
    /***************************************************************************************************
     * @section Main
     **************************************************************************************************/
    
    int main(int argc, char *argv[])
    {
        log_init();
        scheduler_init();
        timer_init();
        leds_init();
    
        thread_instance_init();
        thread_bsp_init();
        mqttsn_init();
    
        while (true)
        {
            thread_process();
            app_sched_execute();
    
            if (NRF_LOG_PROCESS() == false)
            {
                thread_sleep();
            }
        }
    }
    
    /**
     *@}
     **/
    

    Best regards,
    Jørgen

  • Hi Jørgen,

    Thank you for your reply.

    if work is to disconnect after each node is done publishing, it can subscribe MQTT?
    because I follow the WEB steps below Playing with Thread and MQTT-SN on Nordic nRF52840, I need support to publish and subscribe at the same time in the device.

    Pls kindly help advise how to solve it?

    Best Regards,

    Rick.

  • I only tested the publisher, as it looked like this was the one you are using. 

    Are you having problem with two subscribers as well? You did not mention that you wanted to combine these operations, that may require large modifications of the examples.

Reply Children
  • Hi Jørgen,


    1. I did not use the publish of two devices.
    I use this example "Thread MQTT-SN Example".
    Use one device of the MQTT-SN Subscriber application and other one device of the MQTT-SN Publisher application. (one publish device, one subscribe device)

    2. Yes, two subscribers well the same problems too. do you have any advice that can solve the problems of two subscribers?

    3. Now I have two devices, wanted to combine operations publish and subscribe at the same time in the device.
    Pls kindly help advise how to solve it?

    Best Regards,

    Rick.

  • Hi Rick,

    Your latest questions is getting far outside of the topic of this thread. Can you please post it in a new thread, to prevent this from getting too messy? That will help other users with similar questions find the information much more easily.

    If you do that, we will try to help you achieve what you want.

    Best regards,
    Jørgen

  • Hi Jørgen:

    I created a new thread is Thread MQTT-SN Example publish and subscribe can not combine operations ,

    Pls kindly help advise how to solve it?

    Best Regards,

    Rick.

  • Hi Jørgen:

    Now I have support IPv6 from ISP and Router is (ASUS RT-AX56U),but I still not get /62 prefix.

    this is my ifconfig from RPi .

    pi@raspberrypi:~ $ ifconfig eth0
    
    eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
    
            inet 192.168.50.103  netmask 255.255.255.0  broadcast 192.168.50.255
    
            inet6 2001:b030:214e:2200:****:****:****:****  prefixlen 64  scopeid 0x0<global>
    
            inet6 fe80::ba27:ebff:feda:4146  prefixlen 64  scopeid 0x20<link>
    
            ether b8:27:eb:da:41:46  txqueuelen 1000  (Ethernet)
    
            RX packets 870  bytes 76151 (74.3 KiB)
    
            RX errors 0  dropped 0  overruns 0  frame 0
    
            TX packets 530  bytes 78362 (76.5 KiB)
    
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

    and the WEB steps description, How can I setting DHCPv6 service for Rpi and disable autoconfig?

    When dealing with the native IPv6 connectivity, make sure you use the DHCPv6 service and not the popular Stateless Address Autoconfiguration (SLAAC) tool. This autoconfig tool will only provide a 64-bit long prefix that is not sufficient to delegate a new 64-bit long prefix for the Thread network.

    Best Regards,

    Rick.

  • Hi,

    I do not have this router available, so unfortunately I'm not able to help you with configuration of this. You should contact the manufacturer of the router (Asus) to get help on configuration and details about whether this router can support larger address spaces. I have only been able to get this to work with a router running OpenWRT firmware, but I have not tested on a large number of devices..

    Best regards,
    Jørgen

Related