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

Invalid Model when trying to bind app key to Level model

Hi

When I select the Generic Level server model and try to bind the app key I get an invalid model Error. I am using the nRF Mesh android app.

This might be relevant or no but i see this in the debug terminal when provisioning

config_server.c,  629, dsm_appkey_add(appkey_handle:0 appkey_index:0)

I have two elements 0x0002 has 3 models

Configuration server

Health server

Generic on Off server

element  0x0003 has my model Generic Level server

My settings is as follow :

ACCESS_MODEL_COUNT (6)

ACCESS_ELEMENT_COUNT (3)

Thanks for any help !

Parents
  • Hi,

    What Mesh SDK version are you using? And which example? Is ACCESS_MODEL_COUNT and ACCESS_ELEMENT_COUNT the only modifications you have done?

  • Andre Lochner said:
    I did the same with the client and it is working fine and can subscribe to level model.

    So it works fine when trying to bind the app key to the Generic Level client model?

  • Yes, works fine with the client model. Its only with the server model where I get this error when I assign an app key.

  • /* Copyright (c) 2010 - 2019, 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"
    #include "nrf_delay.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"
    #include "proxy.h"

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

    /* Models */
    #include "generic_onoff_server.h"
    #include "generic_level_server.h"

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

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

    // andre custom files
    #include "brd_io.h"

    #define ONOFF_SERVER_0_LED (BSP_LED_0)
    #define APP_ONOFF_ELEMENT_INDEX (0)

    static bool m_device_provisioned;

    static uint32_t level_counter = 0;

    /*************************************************************************************************/
    static void app_onoff_server_set_cb(const app_onoff_server_t * p_server, bool onoff);
    static void app_onoff_server_get_cb(const app_onoff_server_t * p_server, bool * p_present_onoff);

    /* Generic OnOff server structure definition and initialization */
    APP_ONOFF_SERVER_DEF(m_onoff_server_0,
    APP_CONFIG_FORCE_SEGMENTATION,
    APP_CONFIG_MIC_SIZE,
    app_onoff_server_set_cb,
    app_onoff_server_get_cb)

    // EDS
    static generic_level_server_t l_server;

    // forward declarations for callbacks
    static void level_server_get_cb(const generic_level_server_t * p_self,const access_message_rx_meta_t * p_meta, generic_level_status_params_t * p_out );

    static void level_server_set_cb(const generic_level_server_t * p_self,
    const access_message_rx_meta_t * p_meta,
    const generic_level_set_params_t * p_in,
    const model_transition_t * p_in_transition,
    generic_level_status_params_t * p_out);

    static void level_server_delta_set_cb(const generic_level_server_t * p_self,
    const access_message_rx_meta_t * p_meta,
    const generic_level_delta_set_params_t * p_in,
    const model_transition_t * p_in_transition,
    generic_level_status_params_t * p_out );

    static void level_server_move_set_cb(const generic_level_server_t * p_self,
    const access_message_rx_meta_t * p_meta,
    const generic_level_move_set_params_t * p_in,
    const model_transition_t * p_in_transition,
    generic_level_status_params_t * p_out);

    // EDS -- define the callbacks for the level server
    const generic_level_server_state_cbs_t server_cbs =
    {
    .get_cb = level_server_get_cb,
    .set_cb = level_server_set_cb,
    .delta_set_cb = level_server_delta_set_cb,
    .move_set_cb = level_server_move_set_cb
    };

    const generic_level_server_callbacks_t levels_cbs = {
    server_cbs
    };

    //EDS all callbacks for the level server
    static void level_server_get_cb(const generic_level_server_t * p_self,const access_message_rx_meta_t * p_meta, generic_level_status_params_t * p_out )
    {
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "level_server_get_cb\n");

    }

    static void level_server_set_cb(const generic_level_server_t * p_self,
    const access_message_rx_meta_t * p_meta,
    const generic_level_set_params_t * p_in,
    const model_transition_t * p_in_transition,
    generic_level_status_params_t * p_out)
    {
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "level_server_set_cb\n");

    }

    static void level_server_delta_set_cb(const generic_level_server_t * p_self,
    const access_message_rx_meta_t * p_meta,
    const generic_level_delta_set_params_t * p_in,
    const model_transition_t * p_in_transition,
    generic_level_status_params_t * p_out )
    {
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "level_server_delta_set_cb\n");
    //__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "level_server_delta_set_cb level %d\n", onoff);
    }

    static void level_server_move_set_cb(const generic_level_server_t * p_self,
    const access_message_rx_meta_t * p_meta,
    const generic_level_move_set_params_t * p_in,
    const model_transition_t * p_in_transition,
    generic_level_status_params_t * p_out)
    {
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "level_server_move_set_cb\n");

    }

    /* Callback for updating the hardware state */
    static void app_onoff_server_set_cb(const app_onoff_server_t * p_server, bool onoff)
    {
    /* Resolve the server instance here if required, this example uses only 1 instance. */

    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Setting GPIO value: %d\n", onoff)
    brd_io_led_on(3);
    brd_io_led_on(0);
    nrf_delay_ms(200);
    brd_io_led_off(3);
    brd_io_led_off(0);
    brd_io_led_on(1);
    brd_io_led_on(2);
    nrf_delay_ms(200);
    brd_io_led_off(1);
    brd_io_led_off(2);
    brd_io_led_on(3);
    brd_io_led_on(0);
    nrf_delay_ms(200);
    brd_io_led_off(3);
    brd_io_led_off(0);
    brd_io_led_on(1);
    brd_io_led_on(2);
    nrf_delay_ms(200);
    brd_io_led_off(1);
    brd_io_led_off(2);
    //hal_led_pin_set(ONOFF_SERVER_0_LED, onoff);
    }

    /* Callback for reading the hardware state */
    static void app_onoff_server_get_cb(const app_onoff_server_t * p_server, bool * p_present_onoff)
    {
    /* Resolve the server instance here if required, this example uses only 1 instance. */

    *p_present_onoff = hal_led_pin_get(ONOFF_SERVER_0_LED);
    }

    static void app_model_init(void)
    {
    /* Instantiate onoff server on element index APP_ONOFF_ELEMENT_INDEX */
    ERROR_CHECK(app_onoff_init(&m_onoff_server_0, APP_ONOFF_ELEMENT_INDEX));
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "App OnOff Model Handle: %d\n", m_onoff_server_0.server.model_handle);
    }

    /*************************************************************************************************/

    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);
    /* This function may return if there are ongoing flash operations. */
    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);
    switch (button_number)
    {
    /* Pressing SW1 on the Development Kit will result in LED state to toggle and trigger
    the STATUS message to inform client about the state change. This is a demonstration of
    state change publication due to local event. */
    case 0:
    {
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "User action \n");
    //hal_led_pin_set(ONOFF_SERVER_0_LED, !hal_led_pin_get(ONOFF_SERVER_0_LED));
    app_onoff_status_publish(&m_onoff_server_0);
    break;
    }

    /* Initiate node reset */
    case 3:
    {
    /* Clear all the states to reset the node. */
    if (mesh_stack_is_device_provisioned())
    {
    #if MESH_FEATURE_GATT_PROXY_ENABLED
    (void) proxy_stop();
    #endif
    mesh_stack_config_clear();
    node_reset();
    }
    else
    {
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "The device is unprovisioned. Resetting has no effect.\n");
    }
    break;
    }

    default:
    break;
    }
    }

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

    static void device_identification_start_cb(uint8_t attention_duration_s)
    {
    //hal_led_mask_set(LEDS_MASK, false);
    /*hal_led_blink_ms(BSP_LED_2_MASK | BSP_LED_3_MASK,
    LED_BLINK_ATTENTION_INTERVAL_MS,
    LED_BLINK_ATTENTION_COUNT(attention_duration_s));*/
    }

    static void provisioning_aborted_cb(void)
    {
    //hal_led_blink_stop();
    }

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

    #if MESH_FEATURE_GATT_ENABLED
    /* Restores the application parameters after switching from the Provisioning
    * service to the Proxy */
    gap_params_init();
    conn_params_init();
    #endif

    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_blink_stop();
    //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 void models_init_cb(void)
    {
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Initializing and adding models\n");
    app_model_init();
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Initializing and adding level model\n");
    l_server.settings.p_callbacks = &levels_cbs;

    l_server.settings.force_segmented = APP_CONFIG_FORCE_SEGMENTATION;
    l_server.settings.transmic_size = APP_CONFIG_MIC_SIZE;
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "App Level Model Handle: %d\n", l_server.model_handle);
    ERROR_CHECK(generic_level_server_init(&l_server, 3));

    }

    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));
    }

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

    ERROR_CHECK(app_timer_init());
    // hal_leds_init();

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

    ble_stack_init();

    #if MESH_FEATURE_GATT_ENABLED
    gap_params_init();
    conn_params_init();
    #endif

    mesh_init();
    }

    static void start(void)
    {
    rtt_input_enable(app_rtt_input_handler, RTT_INPUT_POLL_PERIOD_MS);

    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,
    .prov_device_identification_start_cb = device_identification_start_cb,
    .prov_device_identification_stop_cb = NULL,
    .prov_abort_cb = provisioning_aborted_cb,
    .p_device_uri = EX_URI_LS_SERVER
    };
    ERROR_CHECK(mesh_provisionee_prov_start(&prov_start_params));
    }

    mesh_app_uuid_print(nrf_mesh_configure_device_uuid_get());

    ERROR_CHECK(mesh_stack_start());

    //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);
    bsp_board_leds_on();
    brd_io_led_on(3);
    brd_io_led_on(0);
    nrf_delay_ms(200);
    brd_io_led_off(3);
    brd_io_led_off(0);
    brd_io_led_on(1);
    brd_io_led_on(2);
    nrf_delay_ms(200);
    brd_io_led_off(1);
    brd_io_led_off(2);
    brd_io_led_on(3);
    brd_io_led_on(0);
    nrf_delay_ms(200);
    brd_io_led_off(3);
    brd_io_led_off(0);
    brd_io_led_on(1);
    brd_io_led_on(2);
    nrf_delay_ms(200);
    brd_io_led_off(1);
    brd_io_led_off(2);
    initialize();
    start();

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

  • Hi,

    Are you testing with a DK or a custom board? Which chip are you using? I'm not able to build your code, getting an error. "server_cbs", initializer is not a constant. How can I reproduce this?

  • Hi,

    I am using a custom board with NRF52840 module on it. Everything is is standard examples that I modified. the server_cbs comes from  C:\Nordic_SDK\nrf5SDKforMeshv320src\models\model_spec\generic_level\include\generic_level_server.h

  • /**
    * Level server callback list.
    */
    typedef struct
    {
    /** Callbacks for the level state. */
    generic_level_server_state_cbs_t level_cbs;
    } generic_level_server_callbacks_t;

Reply Children
Related