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

simple_on_off vendor model on Mesh 3.1

I am converting the simple_on_off vendor model to send a message on mesh 3.1.

the server  implemented the simple_on_off model successfully. But but my client runs into  0>, app_error_weak.c,  119, Mesh error 8 at 0x00000000 (:0)  straight away.

I suspect the line below in mesh_init could be causing the problem

  .core.p_uuid = dev_uuid, 

NOTE: This is for the PCA10059 not the DK. LEDS and Buttons have been remapped. I have removed generic_on_off model .c and . h files. I have kept model_common.c

/* Copyright (c) 2010 - 2018, 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 "boards.h"
#include "simple_hal.h"
#include "app_timer.h"

/* Core */
#include "nrf_mesh_config_core.h"
#include "nrf_mesh_gatt.h"
#include "nrf_mesh_configure.h"
#include "nrf_mesh.h"
#include "mesh_stack.h"
#include "device_state_manager.h"
#include "access_config.h"

/* Provisioning and configuration */
#include "mesh_provisionee.h"
#include "mesh_app_utils.h"

/* Models */
//#include "generic_onoff_client.h"
#include "simple_on_off_client.h"
#include "simple_on_off_common.h"

/* Logging and RTT */
#include "log.h"
#include "rtt_input.h"

/* Example specific includes */
#include "app_config.h"
#include "nrf_mesh_config_examples.h"
#include "light_switch_example_common.h"
#include "example_common.h"
#include "ble_softdevice_support.h"

#define RTT_INPUT_POLL_PERIOD_MS (100)
#define GROUP_MSG_REPEAT_COUNT (2)

#define LED_BLINK_INTERVAL_MS (200)
#define LED_BLINK_SHORT_INTERVAL_MS (50)
#define LED_BLINK_CNT_START (2)
#define LED_BLINK_CNT_RESET (3)
#define LED_BLINK_CNT_PROV (4)
#define LED_BLINK_CNT_NO_REPLY (6)



static simple_on_off_client_t m_clients[CLIENT_MODEL_INSTANCE_COUNT];
//static const uint8_t m_client_node_uuid[NRF_MESH_UUID_SIZE] = CLIENT_NODE_UUID;
static bool m_device_provisioned;

static void client_status_cb(const simple_on_off_client_t *p_self, simple_on_off_status_t status, uint16_t src);

static bool client_publication_configured(void) {
  dsm_handle_t pub_addr_handle;
  for (uint8_t i = 0; i < CLIENT_MODEL_INSTANCE_COUNT; i++) {
    if (access_model_publish_address_get(m_clients[i].model_handle, &pub_addr_handle) == NRF_SUCCESS) {
      if (pub_addr_handle == DSM_HANDLE_INVALID) {
        return false;
      }
    } else {
      return false;
    }
  }

  return true;
}

static void provisioning_complete_cb(void) {
  __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Successfully provisioned\n");

  dsm_local_unicast_address_t node_address;
  dsm_local_unicast_addresses_get(&node_address);
  __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Node Address: 0x%04x \n", node_address.address_start);

  hal_led_mask_set(LEDS_MASK, LED_MASK_STATE_OFF);
  hal_led_blink_ms(LEDS_MASK, LED_BLINK_INTERVAL_MS, LED_BLINK_CNT_PROV);
}

static uint32_t server_index_get(const simple_on_off_client_t *p_client) {
  uint32_t index = p_client - &m_clients[0];
  NRF_MESH_ASSERT(index < SERVER_NODE_COUNT);
  return index;
}

static void client_publish_timeout_cb(access_model_handle_t handle, void *p_self) {
  __LOG(LOG_SRC_APP, LOG_LEVEL_ERROR, "Acknowledged send timedout\n");
}

static void client_status_cb(const simple_on_off_client_t *p_self, simple_on_off_status_t status, uint16_t src) {
  uint32_t server_index = server_index_get(p_self);

  //__LOG(LOG_SRC_APP, LOG_LEVEL_ERROR, "server status received \n",p_self);
  switch (status) {
  case SIMPLE_ON_OFF_STATUS_ON:
    hal_led_pin_set(BSP_LED_0 + server_index, true);
    break;

  case SIMPLE_ON_OFF_STATUS_OFF:
    hal_led_pin_set(BSP_LED_0 + server_index, false);
    break;

  case SIMPLE_ON_OFF_STATUS_ERROR_NO_REPLY:
    hal_led_blink_ms(LEDS_MASK, LED_BLINK_SHORT_INTERVAL_MS, LED_BLINK_CNT_NO_REPLY);
    break;

  case SIMPLE_ON_OFF_STATUS_CANCELLED:
  default:
    __LOG(LOG_SRC_APP, LOG_LEVEL_ERROR, "Unknown status \n");
    break;
  }
}

static void node_reset(void) {
  __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- Node reset  -----\n");
  hal_led_blink_ms(LEDS_MASK, LED_BLINK_INTERVAL_MS, LED_BLINK_CNT_RESET);
  mesh_stack_device_reset();

}

static void config_server_evt_cb(const config_server_evt_t *p_evt) {
  if (p_evt->type == CONFIG_SERVER_EVT_NODE_RESET) {
    node_reset();
  }
}

static void button_event_handler(uint32_t button_number) {
  //__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Button %u pressed\n", button_number);

  if (client_publication_configured()) {
    uint32_t status = NRF_SUCCESS;
    switch (button_number) {
    case 0:
    case 1:
      /* send unicast message, with inverted GPIO pin value */
     
      status = simple_on_off_client_set(&m_clients[button_number],
          !hal_led_pin_get(BSP_LED_0 + button_number));

      break;

    case 2:
    case 3:
   
      /* send a group message to the ODD group, with inverted GPIO pin value */
      status = simple_on_off_client_set_unreliable(&m_clients[button_number],
          !hal_led_pin_get(BSP_LED_0 + button_number),
          GROUP_MSG_REPEAT_COUNT);
      hal_led_pin_set(BSP_LED_0 + button_number, !hal_led_pin_get(BSP_LED_0 + button_number));
      break;
    default:
      break;
    }

    if (status == NRF_ERROR_INVALID_STATE ||status == NRF_ERROR_NO_MEM ||status == NRF_ERROR_BUSY) {
      __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Cannot send. Device is busy.\n");
      hal_led_blink_ms(LEDS_MASK, LED_BLINK_SHORT_INTERVAL_MS, LED_BLINK_CNT_NO_REPLY);
    } else {
      ERROR_CHECK(status);
    }
  } else {
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Ignored. Node is not configured.\n");
  }
}
/*uint32_t send_command_client(simple_on_off_client_t *p_client, uint8_t *msg, uint16_t length) {
  //int i;
  send_command_msg_t command_msg;

  command_msg.length = length;
  strncpy(command_msg.command, msg, length);

  access_message_tx_t message;
  message.opcode.opcode = SEND_COMMAND;
  message.opcode.company_id = ACCESS_COMPANY_ID_NORDIC;
  message.p_buffer = (const uint8_t *)&command_msg;
  message.length = command_msg.length + 2;

  uint32_t status = NRF_SUCCESS;

  status = access_model_publish(p_client->model_handle, &message);

  Method for sending to all nodes!
  for (uint8_t i = 0; i < 3; ++i)
    {
        status = access_model_publish(p_client->model_handle, &message);
        if (status == NRF_SUCCESS) {
            break;
        }
    }
  return status;
}*/

static void rtt_input_handler(int key)
{
    if (key >= '0' && key <= '3')
    {
        uint32_t button_number = key - '0';
        button_event_handler(button_number);
    }
}

static void models_init_cb(void) {
  __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Initializing and adding models\n");

  for (uint32_t i = 0; i < CLIENT_MODEL_INSTANCE_COUNT; ++i) {
    m_clients[i].status_cb = client_status_cb;
    m_clients[i].timeout_cb = client_publish_timeout_cb;
    ERROR_CHECK(simple_on_off_client_init(&m_clients[i], i + 1));
    ERROR_CHECK(access_model_subscription_list_alloc(m_clients[i].model_handle));
  }
}

static void mesh_init(void) {

uint8_t dev_uuid[NRF_MESH_UUID_SIZE];
 uint8_t node_uuid_prefix[NODE_UUID_PREFIX_LEN] = CLIENT_NODE_UUID_PREFIX;
 
  mesh_stack_init_params_t init_params =
      {
          .core.irq_priority = NRF_MESH_IRQ_PRIORITY_LOWEST,
          .core.lfclksrc = DEV_BOARD_LF_CLK_CFG,
          .core.p_uuid = dev_uuid,
          .models.models_init_cb = models_init_cb,
          .models.config_server_cb = config_server_evt_cb};
  ERROR_CHECK(mesh_stack_init(&init_params, &m_device_provisioned));
}

static void initialize(void) {
  __LOG_INIT(LOG_SRC_APP | LOG_SRC_ACCESS, LOG_LEVEL_INFO, LOG_CALLBACK_DEFAULT);
  __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- BLE Mesh Light Switch Client Demo -----\n");

  hal_leds_init();
#if BUTTON_BOARD
  ERROR_CHECK(hal_buttons_init(button_event_handler));
#endif

 nrf_clock_lf_cfg_t lfc_cfg = DEV_BOARD_LF_CLK_CFG;
  
  mesh_init();
}

static void start(void) {
  rtt_input_enable(rtt_input_handler, RTT_INPUT_POLL_PERIOD_MS);
  ERROR_CHECK(mesh_stack_start());

  if (!m_device_provisioned) {
    static const uint8_t static_auth_data[NRF_MESH_KEY_SIZE] = STATIC_AUTH_DATA;
    mesh_provisionee_start_params_t prov_start_params =
        {
            .p_static_data = static_auth_data,
            .prov_complete_cb = provisioning_complete_cb};
    ERROR_CHECK(mesh_provisionee_prov_start(&prov_start_params));
  }

  const uint8_t *p_uuid = nrf_mesh_configure_device_uuid_get();
  __LOG_XB(LOG_SRC_APP, LOG_LEVEL_INFO, "Device UUID ", p_uuid, NRF_MESH_UUID_SIZE);

  hal_led_mask_set(LEDS_MASK, LED_MASK_STATE_OFF);
  hal_led_blink_ms(LEDS_MASK, LED_BLINK_INTERVAL_MS, LED_BLINK_CNT_START);
}

int main(void) {
  bsp_board_init(BSP_INIT_LEDS); // leds fro pca10059
  initialize();
  start();

  for (;;) {
    (void)sd_app_evt_wait();
  }
}

If someone could shed some light as to why im getting error 8

thanks in advance

Parents Reply Children
  • What I am actually trying to do is send a small string on a mesh.  the latest example I found is here   

    I want to use mesh 3.1. Also looking at the on_off_example I see there is now an included generic_on_off_messages.h file. Can this model now send messages?

  • Hi.

    Have you read about creating new models for your mesh network?

    melt said:
    Can this model now send messages?

    Do you mean packages or string messages?

    Best regards,

    Andreas

  • Yip strings. I have read how to create models and  go over it almost every day.  Can you please share how these functions are structured for the vendor simple_on_off model.

    static void mesh_init(void)

    and

    static void models_init_cb(void)

    thank you.

  • Hi.

    I'm a bit unsure what your question is, are you looking for the implementation of mesh_init() and models_init_cb() where the simple_on_off model were used?

    The simple_on_off model was used up to Mesh SDK 2.0.0, after this the generic_on_off model is used, which should be used in real applications using the mesh.

    The implementation of mesh_init() and models_init_cb() in Mesh SDK 2.0.0 are for example:

    (examples\enocean_switch example)

    mesh_init() :

    static void mesh_init(void)
    {
        uint8_t dev_uuid[NRF_MESH_UUID_SIZE] = CLIENT_NODE_UUID;
    
        mesh_stack_init_params_t init_params =
        {
            .core.irq_priority       = NRF_MESH_IRQ_PRIORITY_LOWEST,
            .core.lfclksrc           = DEV_BOARD_LF_CLK_CFG,
            .core.p_uuid             = dev_uuid,
            .models.models_init_cb   = models_init_cb,
            .models.config_server_cb = config_server_evt_cb
        };
        ERROR_CHECK(mesh_stack_init(&init_params, &m_device_provisioned));
    
        /* Register event handler to receive NRF_MESH_EVT_FLASH_STABLE. Application functionality will
        be started after this event */
        nrf_mesh_evt_handler_add(&m_mesh_core_event_handler);
    }

    models_init_cb() :

    static void models_init_cb(void)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Initializing and adding models\n");
    
        /* Model initialization */
        for (uint32_t i = 0; i < LIGHT_SWITCH_CLIENTS; ++i)
        {
            m_clients[i].status_cb = client_status_cb;
            ERROR_CHECK(simple_on_off_client_init(&m_clients[i], i + 1));
            ERROR_CHECK(access_model_subscription_list_alloc(m_clients[i].model_handle));
        }
    }

    The implementation of mesh_init() and models_init_cb() in Mesh SDK 3.1.0 are for example:

    (examples\enocean_switch example)

    mesh_init() :

    static void mesh_init(void)
    {
        mesh_stack_init_params_t init_params =
        {
            .core.irq_priority       = NRF_MESH_IRQ_PRIORITY_LOWEST,
            .core.lfclksrc           = DEV_BOARD_LF_CLK_CFG,
            .core.p_uuid             = NULL,
            .models.models_init_cb   = models_init_cb,
            .models.config_server_cb = config_server_evt_cb
        };
        ERROR_CHECK(mesh_stack_init(&init_params, &m_device_provisioned));
    
        /* Register event handler to receive NRF_MESH_EVT_FLASH_STABLE. Application functionality will
        be started after this event */
        nrf_mesh_evt_handler_add(&m_mesh_core_event_handler);
    }

    models_init_cb() :

    static void models_init_cb(void)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Initializing and adding models\n");
    
        /* Model initialization */
        for (uint32_t i = 0; i < LIGHT_SWITCH_CLIENTS; ++i)
        {
            m_clients[i].settings.p_callbacks = &client_cbs;
            m_clients[i].settings.timeout = 0;
            m_clients[i].settings.force_segmented = APP_CONFIG_FORCE_SEGMENTATION;
            m_clients[i].settings.transmic_size = APP_CONFIG_MIC_SIZE;
    
            ERROR_CHECK(generic_onoff_client_init(&m_clients[i], i + 1));
        }
    }
    

    Is this what you are looking for?

    Best regards,

    Andreas

  • Thanks Andreas, these are for the Generic model. Im looking for a sample of the functions or sample main.c for simple_on_off model in the vendor directory

    They don't work together

Related