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

node cannot receive message

I use access_model_pulish to send group message by a server, and make other servers listen. the message can go through, but after 5~30 mins, one of the receiver server cannot receive the message any more. message sending are controlled by a timer which send one message out every 100ms. the code is based on the light_switch example from mesh v1.0.0.  I post the code here, if any one knows what's going on and why it stop listening, please help. thanks.

/* Copyright (c) 2010 - 2017, 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.
 */

#include <stdint.h>
#include <string.h>

/* HAL */
#include "nrf.h"
#include "boards.h"
#include "nrf_mesh_sdk.h"
#include "nrf_delay.h"
#include "simple_hal.h"

/* Core */
#include "nrf_mesh.h"
#include "nrf_mesh_events.h"
#include "log.h"

#include "access.h"
#include "access_config.h"
#include "device_state_manager.h"
#include "nrf_mesh_node_config.h"

#include "simple_on_off_server.h"
#include "simple_on_off_common.h"

#include "light_switch_example_common.h"

#include "test_config.h"
#include "uart.h"
#include "test_timer.h"

/*****************************************************************************
 * Definitions
 *****************************************************************************/

#define GROUP_ADDRESS (0xCAFE)

/*****************************************************************************
 * Static data
 *****************************************************************************/

static simple_on_off_server_t m_server;

/* Forward declaration */
static bool get_cb(const simple_on_off_server_t * p_server);
static bool set_cb(const simple_on_off_server_t * p_server, bool value);

static dsm_handle_t m_central_handle;
extern uint8_t dataready;
extern char cmd_buf[128];

typedef struct {
    bool active;
    uint16_t count;
} timer_ctrl_t;
timer_ctrl_t test_ctrl_timer = { .active = false, .count = 0 };

/*****************************************************************************
 * Static utility functions
 *****************************************************************************/
 uint32_t address_set(uint16_t addr) {
    uint32_t status = 0xFF;
    ERROR_CHECK(dsm_address_publish_add(addr, &m_central_handle));
    status = access_model_publish_address_set(m_server.model_handle, m_central_handle);
    return status;
 }

static void configuration_setup(void * p_unused)
{
    m_server.get_cb = get_cb;
    m_server.set_cb = set_cb;
    ERROR_CHECK(simple_on_off_server_init(&m_server, 0));
    ERROR_CHECK(access_model_subscription_list_alloc(m_server.model_handle));
}

static void provisioning_complete(void * p_unused)
{
    uart_writef(DEBUG_PRINT, "Successfully provisioned\r\n");
    nrf_gpio_pin_set(RGB_LED_RED);
}

/*****************************************************************************
 * Simple OnOff Callbacks
 *****************************************************************************/

static bool get_cb(const simple_on_off_server_t * p_server)
{
    return true;
}

static bool set_cb(const simple_on_off_server_t * p_server, bool value)
{
    nrf_gpio_pin_toggle(RGB_LED_GREEN);
    return value;
}

uint8_t test_message = 0;
void half_ms_tasks(void) {
    access_message_tx_t msg;
    static uint16_t count = 0;

    if (count % 2 == 0) {
        if (test_ctrl_timer.active == true) {
            test_ctrl_timer.count++;
            if (test_ctrl_timer.count >= 100) {
                test_ctrl_timer.count = 0;
                msg.opcode.opcode = SIMPLE_ON_OFF_OPCODE_SET;
                msg.opcode.company_id = ACCESS_COMPANY_ID_NORDIC;
                msg.p_buffer = &test_message;
                msg.length = sizeof(uint8_t);
                access_model_publish(m_server.model_handle, &msg);
                nrf_gpio_pin_toggle(RGB_LED_RED);
            }
        }
    }

    count++;
    if (count >= 2000) count = 0;
}

void input_handler(void) {
    if (dataready) {
        switch (cmd_buf[0]) {
            case 'S':
                uart_writef(DEBUG_PRINT, "Start sending message\r\n");
                test_ctrl_timer.active = true;
                test_ctrl_timer.count = 0;
                address_set(GROUP_ADDRESS);
                break;
            default:
                break;
        }
    }
}

int main(void)
{
    static const uint8_t static_auth_data[NRF_MESH_KEY_SIZE] = STATIC_AUTH_DATA;
    static nrf_mesh_node_config_params_t config_params =
        {.prov_caps = NRF_MESH_PROV_OOB_CAPS_DEFAULT(ACCESS_ELEMENT_COUNT)};
    config_params.p_static_data = static_auth_data;
    config_params.complete_callback = provisioning_complete;
    config_params.setup_callback = configuration_setup;
    config_params.irq_priority = NRF_MESH_IRQ_PRIORITY_LOWEST;

    /*clock settings for ivani board*/
    config_params.lf_clk_cfg.source        = NRF_CLOCK_LF_SRC_RC;
    config_params.lf_clk_cfg.rc_ctiv       = 16;
    config_params.lf_clk_cfg.rc_temp_ctiv  = 2;
    config_params.lf_clk_cfg.accuracy = NRF_CLOCK_LF_ACCURACY_20_PPM;

    uart_init();
    timer_init(half_ms_tasks);

    nrf_gpio_cfg_output(RGB_LED_RED);
    nrf_gpio_cfg_output(RGB_LED_GREEN);
    nrf_gpio_cfg_output(RGB_LED_BLUE);

    nrf_gpio_pin_clear(RGB_LED_RED);
    nrf_gpio_pin_set(RGB_LED_GREEN);
    nrf_gpio_pin_set(RGB_LED_BLUE);

    ERROR_CHECK(nrf_mesh_node_config(&config_params));

    while (true) {
        input_handler();
        flush_uart_buffer();
    }
}

Parents
  • A similar test was run to be even more similar to the light_switch example.

    • Server code was only modified to use different pins for our board and to toggle an LED when they receive a group message.
    • Client code was modified to
      • Have a timer that ticks every half ms
      • Have a divided down variant that ticks every 100ms
      • When 100ms timer ticks
        • Toggle an LED
        • Send a group message using access_model_publish (this is doing the same thing as simple_on_off_client_set_unreliable in the example)


    Doing this we see client and 3 servers all blink every 100ms initially (as expected).
    After some time, which can vary, we see a server stop blinking.
    Eventually the other servers also stop blinking.

    This is still in line with our earlier findings that servers are not reliably receiving messages for a large volume of messages over time.

Reply
  • A similar test was run to be even more similar to the light_switch example.

    • Server code was only modified to use different pins for our board and to toggle an LED when they receive a group message.
    • Client code was modified to
      • Have a timer that ticks every half ms
      • Have a divided down variant that ticks every 100ms
      • When 100ms timer ticks
        • Toggle an LED
        • Send a group message using access_model_publish (this is doing the same thing as simple_on_off_client_set_unreliable in the example)


    Doing this we see client and 3 servers all blink every 100ms initially (as expected).
    After some time, which can vary, we see a server stop blinking.
    Eventually the other servers also stop blinking.

    This is still in line with our earlier findings that servers are not reliably receiving messages for a large volume of messages over time.

Children
No Data
Related