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

Provisioner and client (provisionee) roles in the same application Mesh 5.0

Provisioner and client (provisionee) roles in the same application.

 

Hello everyone,

First, I am using SDK 17.02 and BLE Mesh 5.0.

By the moment, I want to integrate a static provisioner and a generic OnOff client in the same application. I have this post in which is provided an Example using Mesh 1.0. I use this example as a reference.

Also I have followed this tutorial about how to migrate Mesh examples into SDK examples. I did it with the static provisioner example.

Now I want to include a generic On Off client in the same project (In the future I will have more) but I do not know which the order is to initialize each component. Also, I do not know if I am doing it well.

 In the provisioner example is given this order:

  1. ble_stack_init();
  2. mesh_init();
    • models_init
      • config_client_init()
      • health_client_init()
    • mesh_stack_init()
      • config_server_init()
      • health_server_init()
      • mesh_config_load()
      • dsm_load_config_apply()
      • access_load_config_apply()
      • mesh_stack_is_device_provisioned()
    • prov_helper_init
    • node_setup_cb_set
  3. node_setup_uri_check();
  4. mesh_stack_start());

I image that I should include the initial configuration of genericOnOff inside of point 2.1 and then make the fix configuration for self-provisioning below 2.2.3 point. But It does not work… Which is the best way to include more clients?

Moreover, giving the static provisioning example it makes me more questions. Is it necessary to include a config and health clients? On client examples I only see config and health servers.

Best regards,

Javier

Parents
  • Hi,

    Is there a reason for you to have both in the same application? Could you tell me more about your use-case?

  • Hi,

    Provisioner as a role is always a separate device as by spec you must use one of the specified provisioner bearers (ADV or GATT) in order to provision a device. However, by reading the spec, nothing prevents the node that implements Provisioner and Configuration Client to have other models (like it was with generic onoff client). But generally, yes, provisioner and configuration client is a smartphone or some other device that can add devices to a mesh network. Regarding the static provisioner, we see it as an example that can provision and configure all our samples, not just generic onoff client.

    Regarding your case, if you won't have a smartphone or any other separate device, then the CORE device could implement provisioner and configuration client roles together with generic onoff client.

    I have attached a patch that adds Generic OnOff Client from light switch client example to static provisioner example for nRF5 SDK for Mesh v5.0. Actually, the static provisioner can be any other device as well as CORE device. But since CORE device should subscribe to button status, it should have Generic OnOff Server instance, not the client one. Or use Device A as a provisioner. Then the rest devices could be Light Switch server examples. The important thing is that one and only one device must have provisioner and configuration client roles on it.

    diff --git a/examples/provisioner/CMakeLists.txt b/examples/provisioner/CMakeLists.txt
    index e60858743..d7b670b92 100644
    --- a/examples/provisioner/CMakeLists.txt
    +++ b/examples/provisioner/CMakeLists.txt
    @@ -12,6 +12,7 @@ add_executable(${target}
         ${WEAK_SOURCE_FILES}
         ${MESH_CORE_SOURCE_FILES}
         ${MESH_BEARER_SOURCE_FILES}
    +    ${GENERIC_ONOFF_CLIENT_SOURCE_FILES}
         ${CONFIG_CLIENT_SOURCE_FILES}
         ${CONFIG_SERVER_SOURCE_FILES}
         ${HEALTH_SERVER_SOURCE_FILES}
    diff --git a/examples/provisioner/include/nrf_mesh_config_app.h b/examples/provisioner/include/nrf_mesh_config_app.h
    index c659c8a6f..779b69e00 100644
    --- a/examples/provisioner/include/nrf_mesh_config_app.h
    +++ b/examples/provisioner/include/nrf_mesh_config_app.h
    @@ -97,7 +97,8 @@
     #define ACCESS_MODEL_COUNT (1 + /* Configuration client */  \
                                 1 + /* Configuration server */  \
                                 1 + /* Health server */ \
    -                            1   /* Health client */)
    +                            1 + /* Health client */ \
    +                            2   /* Generic OnOff client (2 groups) */)
     
     /**
      * The number of elements in the application.
    @@ -105,7 +106,8 @@
      * @warning If the application is to support _multiple instances_ of the _same_ model, these instances
      * cannot be in the same element and a separate element is needed for each new instance of the same model.
      */
    -#define ACCESS_ELEMENT_COUNT (1) /* Provisioner node has only 1 element */
    +#define CLIENT_MODEL_INSTANCE_COUNT  (2)
    +#define ACCESS_ELEMENT_COUNT (1 + CLIENT_MODEL_INSTANCE_COUNT) /* Provisioner node has only 1 element */
     
     /**
      * The number of scene setup server instances used by the application. This is only used to
    @@ -165,7 +167,7 @@
     /** Maximum number of non-virtual addresses. One for each of the servers and a group address. */
     #define DSM_NONVIRTUAL_ADDR_MAX                         (1 + /* For self address. */\
                                                              GROUP_ADDR_COUNT + /* Group addresses.  */\
    -		                                         2 * MAX_PROVISIONEE_NUMBER)
    +							 2 * MAX_PROVISIONEE_NUMBER)
     /** @} end of DSM_CONFIG */
     
     /** @} */
    diff --git a/examples/provisioner/src/main.c b/examples/provisioner/src/main.c
    index 821a862d9..f15cd3afb 100644
    --- a/examples/provisioner/src/main.c
    +++ b/examples/provisioner/src/main.c
    @@ -65,6 +65,7 @@
     #include "config_client.h"
     #include "config_server.h"
     #include "health_client.h"
    +#include "generic_onoff_client.h"
     
     /* Logging and RTT */
     #include "rtt_input.h"
    @@ -97,6 +98,107 @@ static void app_mesh_core_event_cb (const nrf_mesh_evt_t * p_evt);
     static void app_start(void);
     
     
    +
    +
    +
    +/*****************************************************************************
    + * Definitions
    + *****************************************************************************/
    +#define APP_STATE_OFF                (0)
    +#define APP_STATE_ON                 (1)
    +
    +#define APP_UNACK_MSG_REPEAT_COUNT   (2)
    +
    +/* Controls if the model instance should force all mesh messages to be segmented messages. */
    +#define APP_FORCE_SEGMENTATION       (false)
    +/* Controls the MIC size used by the model instance for sending the mesh messages. */
    +#define APP_MIC_SIZE                 (NRF_MESH_TRANSMIC_SIZE_SMALL)
    +/* Delay value used by the OnOff client for sending OnOff Set messages. */
    +#define APP_ONOFF_DELAY_MS           (50)
    +/* Transition time value used by the OnOff client for sending OnOff Set messages. */
    +#define APP_ONOFF_TRANSITION_TIME_MS (100)
    +
    +
    +/*****************************************************************************
    + * Forward declaration of static functions
    + *****************************************************************************/
    +static void app_gen_onoff_client_publish_interval_cb(access_model_handle_t handle, void * p_self);
    +static void app_generic_onoff_client_status_cb(const generic_onoff_client_t * p_self,
    +                                               const access_message_rx_meta_t * p_meta,
    +                                               const generic_onoff_status_params_t * p_in);
    +static void app_gen_onoff_client_transaction_status_cb(access_model_handle_t model_handle,
    +                                                       void * p_args,
    +                                                       access_reliable_status_t status);
    +
    +
    +/*****************************************************************************
    + * Static variables
    + *****************************************************************************/
    +static generic_onoff_client_t m_clients[CLIENT_MODEL_INSTANCE_COUNT];
    +
    +const generic_onoff_client_callbacks_t client_cbs =
    +{
    +    .onoff_status_cb = app_generic_onoff_client_status_cb,
    +    .ack_transaction_status_cb = app_gen_onoff_client_transaction_status_cb,
    +    .periodic_publish_cb = app_gen_onoff_client_publish_interval_cb
    +};
    +
    +/* This callback is called periodically if model is configured for periodic publishing */
    +static void app_gen_onoff_client_publish_interval_cb(access_model_handle_t handle, void * p_self)
    +{
    +     __LOG(LOG_SRC_APP, LOG_LEVEL_WARN, "Publish desired message here.\n");
    +}
    +
    +/* Acknowledged transaction status callback, if acknowledged transfer fails, application can
    +* determine suitable course of action (e.g. re-initiate previous transaction) by using this
    +* callback.
    +*/
    +static void app_gen_onoff_client_transaction_status_cb(access_model_handle_t model_handle,
    +                                                       void * p_args,
    +                                                       access_reliable_status_t status)
    +{
    +    switch(status)
    +    {
    +        case ACCESS_RELIABLE_TRANSFER_SUCCESS:
    +            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Acknowledged transfer success.\n");
    +            break;
    +
    +        case ACCESS_RELIABLE_TRANSFER_TIMEOUT:
    +            hal_led_blink_ms(HAL_LED_MASK, LED_BLINK_SHORT_INTERVAL_MS, LED_BLINK_CNT_NO_REPLY);
    +            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Acknowledged transfer timeout.\n");
    +            break;
    +
    +        case ACCESS_RELIABLE_TRANSFER_CANCELLED:
    +            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Acknowledged transfer cancelled.\n");
    +            break;
    +
    +        default:
    +            ERROR_CHECK(NRF_ERROR_INTERNAL);
    +            break;
    +    }
    +}
    +
    +/* Generic OnOff client model interface: Process the received status message in this callback */
    +static void app_generic_onoff_client_status_cb(const generic_onoff_client_t * p_self,
    +                                               const access_message_rx_meta_t * p_meta,
    +                                               const generic_onoff_status_params_t * p_in)
    +{
    +    if (p_in->remaining_time_ms > 0)
    +    {
    +        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "OnOff server: 0x%04x, Present OnOff: %d, Target OnOff: %d, Remaining Time: %d ms\n",
    +              p_meta->src.value, p_in->present_on_off, p_in->target_on_off, p_in->remaining_time_ms);
    +    }
    +    else
    +    {
    +        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "OnOff server: 0x%04x, Present OnOff: %d\n",
    +              p_meta->src.value, p_in->present_on_off);
    +    }
    +}
    +
    +
    +
    +
    +
     /*****************************************************************************
      * Static variables
      *****************************************************************************/
    @@ -365,6 +467,7 @@ static const char m_usage_string[] =
         "\n"
         "\t\t--------------------------------------------------------------------------------\n"
         "\t\t Button/RTT 1) Initiate provisioning and configuration of unprovisioned devices.\n"
    +    "\t\t Button/RTT 3) Send Generic OnOff Set Unack message. \n"
         "\t\t Button/RTT 4) Clear all the states to reset the node.\n"
         "\t\t--------------------------------------------------------------------------------\n";
     #endif
    @@ -389,6 +492,32 @@ static void button_event_handler(uint32_t button_number)
                 break;
             }
     
    +        case 3:
    +        {
    +            uint32_t status;
    +            static bool state;
    +            generic_onoff_set_params_t set_params = {
    +                .on_off = state ? APP_STATE_ON : APP_STATE_OFF,
    +            };
    +            model_transition_t transition_params;
    +            static uint8_t tid = 0;
    +
    +            state = !state;
    +
    +            set_params.tid = tid++;
    +            transition_params.delay_ms = APP_ONOFF_DELAY_MS;
    +            transition_params.transition_time_ms = APP_ONOFF_TRANSITION_TIME_MS;
    +            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Sending msg: ONOFF SET %d\n", set_params.on_off);
    +
    +            status = generic_onoff_client_set_unack(&m_clients[0], &set_params,
    +                                                    &transition_params, APP_UNACK_MSG_REPEAT_COUNT);
    +            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Client send status: %d\n", status);
    +            status = generic_onoff_client_set_unack(&m_clients[1], &set_params,
    +                                                    &transition_params, APP_UNACK_MSG_REPEAT_COUNT);
    +            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Client send status: %d\n", status);
    +            break;
    +        }
    +
             /* Initiate node reset */
             case 4:
             {
    @@ -433,6 +562,16 @@ void models_init_cb(void)
          * health client : To be able to interact with other health servers */
         ERROR_CHECK(config_client_init(app_config_client_event_cb));
         ERROR_CHECK(health_client_init(&m_dev_handles.m_health_client_instance, 0, app_health_event_cb));
    +
    +    for (uint32_t i = 0; i < CLIENT_MODEL_INSTANCE_COUNT; ++i)
    +    {
    +        m_clients[i].settings.p_callbacks = &client_cbs;
    +        m_clients[i].settings.timeout = 0;
    +        m_clients[i].settings.force_segmented = APP_FORCE_SEGMENTATION;
    +        m_clients[i].settings.transmic_size = APP_MIC_SIZE;
    +
    +        ERROR_CHECK(generic_onoff_client_init(&m_clients[i], i + 1));
    +    }
     }
     
     static void mesh_init(void)
    @@ -482,6 +621,40 @@ static void mesh_init(void)
                 prov_helper_provision_self();
                 app_default_models_bind_setup();
                 app_data_store_cb();
    +
    +            for (uint32_t i = 0; i < CLIENT_MODEL_INSTANCE_COUNT; ++i)
    +            {
    +                /** Configure Model Subscription. */
    +                dsm_handle_t subscription_address_handle;
    +                uint32_t subscription_address = ((i + 1) & 1) ? SERVER_PUB_GROUP_ADDRESS_EVEN : SERVER_PUB_GROUP_ADDRESS_ODD;
    +                ERROR_CHECK(dsm_address_subscription_add(subscription_address, &subscription_address_handle));
    +                ERROR_CHECK(access_model_subscription_add(m_clients[i].model_handle, subscription_address_handle));
    +
    +                /** Configure Model Publication. */
    +                uint32_t publish_address = ((i + 1) & 1) ? CLIENT_PUB_GROUP_ADDRESS_EVEN : CLIENT_PUB_GROUP_ADDRESS_ODD;
    +                dsm_handle_t publish_address_handle = DSM_HANDLE_INVALID;
    +
    +                ERROR_CHECK(dsm_address_publish_add(publish_address, &publish_address_handle));
    +
    +                access_publish_period_t publish_period =
    +                {
    +                    .step_num = 1,
    +                    .step_res = ACCESS_PUBLISH_RESOLUTION_10S
    +                };
    +                access_publish_retransmit_t publish_retransmit =
    +                {
    +                    .count = 1,
    +                    .interval_steps = 0,
    +                };
    +                dsm_handle_t publish_appkey_handle = dsm_appkey_index_to_appkey_handle(APPKEY_INDEX);
    +
    +                ERROR_CHECK(access_model_publish_retransmit_set(m_clients[i].model_handle, publish_retransmit));
    +                ERROR_CHECK(access_model_publish_address_set(m_clients[i].model_handle, publish_address_handle));
    +                ERROR_CHECK(access_model_publish_application_set(m_clients[i].model_handle, publish_appkey_handle));
    +                ERROR_CHECK(access_model_publish_ttl_set(m_clients[i].model_handle, ACCESS_DEFAULT_TTL));
    +                ERROR_CHECK(access_model_publish_period_set(m_clients[i].model_handle, (access_publish_resolution_t) publish_period.step_res, publish_period.step_num));
    +
    +            }
             }
             else
             {
    

Reply
  • Hi,

    Provisioner as a role is always a separate device as by spec you must use one of the specified provisioner bearers (ADV or GATT) in order to provision a device. However, by reading the spec, nothing prevents the node that implements Provisioner and Configuration Client to have other models (like it was with generic onoff client). But generally, yes, provisioner and configuration client is a smartphone or some other device that can add devices to a mesh network. Regarding the static provisioner, we see it as an example that can provision and configure all our samples, not just generic onoff client.

    Regarding your case, if you won't have a smartphone or any other separate device, then the CORE device could implement provisioner and configuration client roles together with generic onoff client.

    I have attached a patch that adds Generic OnOff Client from light switch client example to static provisioner example for nRF5 SDK for Mesh v5.0. Actually, the static provisioner can be any other device as well as CORE device. But since CORE device should subscribe to button status, it should have Generic OnOff Server instance, not the client one. Or use Device A as a provisioner. Then the rest devices could be Light Switch server examples. The important thing is that one and only one device must have provisioner and configuration client roles on it.

    diff --git a/examples/provisioner/CMakeLists.txt b/examples/provisioner/CMakeLists.txt
    index e60858743..d7b670b92 100644
    --- a/examples/provisioner/CMakeLists.txt
    +++ b/examples/provisioner/CMakeLists.txt
    @@ -12,6 +12,7 @@ add_executable(${target}
         ${WEAK_SOURCE_FILES}
         ${MESH_CORE_SOURCE_FILES}
         ${MESH_BEARER_SOURCE_FILES}
    +    ${GENERIC_ONOFF_CLIENT_SOURCE_FILES}
         ${CONFIG_CLIENT_SOURCE_FILES}
         ${CONFIG_SERVER_SOURCE_FILES}
         ${HEALTH_SERVER_SOURCE_FILES}
    diff --git a/examples/provisioner/include/nrf_mesh_config_app.h b/examples/provisioner/include/nrf_mesh_config_app.h
    index c659c8a6f..779b69e00 100644
    --- a/examples/provisioner/include/nrf_mesh_config_app.h
    +++ b/examples/provisioner/include/nrf_mesh_config_app.h
    @@ -97,7 +97,8 @@
     #define ACCESS_MODEL_COUNT (1 + /* Configuration client */  \
                                 1 + /* Configuration server */  \
                                 1 + /* Health server */ \
    -                            1   /* Health client */)
    +                            1 + /* Health client */ \
    +                            2   /* Generic OnOff client (2 groups) */)
     
     /**
      * The number of elements in the application.
    @@ -105,7 +106,8 @@
      * @warning If the application is to support _multiple instances_ of the _same_ model, these instances
      * cannot be in the same element and a separate element is needed for each new instance of the same model.
      */
    -#define ACCESS_ELEMENT_COUNT (1) /* Provisioner node has only 1 element */
    +#define CLIENT_MODEL_INSTANCE_COUNT  (2)
    +#define ACCESS_ELEMENT_COUNT (1 + CLIENT_MODEL_INSTANCE_COUNT) /* Provisioner node has only 1 element */
     
     /**
      * The number of scene setup server instances used by the application. This is only used to
    @@ -165,7 +167,7 @@
     /** Maximum number of non-virtual addresses. One for each of the servers and a group address. */
     #define DSM_NONVIRTUAL_ADDR_MAX                         (1 + /* For self address. */\
                                                              GROUP_ADDR_COUNT + /* Group addresses.  */\
    -		                                         2 * MAX_PROVISIONEE_NUMBER)
    +							 2 * MAX_PROVISIONEE_NUMBER)
     /** @} end of DSM_CONFIG */
     
     /** @} */
    diff --git a/examples/provisioner/src/main.c b/examples/provisioner/src/main.c
    index 821a862d9..f15cd3afb 100644
    --- a/examples/provisioner/src/main.c
    +++ b/examples/provisioner/src/main.c
    @@ -65,6 +65,7 @@
     #include "config_client.h"
     #include "config_server.h"
     #include "health_client.h"
    +#include "generic_onoff_client.h"
     
     /* Logging and RTT */
     #include "rtt_input.h"
    @@ -97,6 +98,107 @@ static void app_mesh_core_event_cb (const nrf_mesh_evt_t * p_evt);
     static void app_start(void);
     
     
    +
    +
    +
    +/*****************************************************************************
    + * Definitions
    + *****************************************************************************/
    +#define APP_STATE_OFF                (0)
    +#define APP_STATE_ON                 (1)
    +
    +#define APP_UNACK_MSG_REPEAT_COUNT   (2)
    +
    +/* Controls if the model instance should force all mesh messages to be segmented messages. */
    +#define APP_FORCE_SEGMENTATION       (false)
    +/* Controls the MIC size used by the model instance for sending the mesh messages. */
    +#define APP_MIC_SIZE                 (NRF_MESH_TRANSMIC_SIZE_SMALL)
    +/* Delay value used by the OnOff client for sending OnOff Set messages. */
    +#define APP_ONOFF_DELAY_MS           (50)
    +/* Transition time value used by the OnOff client for sending OnOff Set messages. */
    +#define APP_ONOFF_TRANSITION_TIME_MS (100)
    +
    +
    +/*****************************************************************************
    + * Forward declaration of static functions
    + *****************************************************************************/
    +static void app_gen_onoff_client_publish_interval_cb(access_model_handle_t handle, void * p_self);
    +static void app_generic_onoff_client_status_cb(const generic_onoff_client_t * p_self,
    +                                               const access_message_rx_meta_t * p_meta,
    +                                               const generic_onoff_status_params_t * p_in);
    +static void app_gen_onoff_client_transaction_status_cb(access_model_handle_t model_handle,
    +                                                       void * p_args,
    +                                                       access_reliable_status_t status);
    +
    +
    +/*****************************************************************************
    + * Static variables
    + *****************************************************************************/
    +static generic_onoff_client_t m_clients[CLIENT_MODEL_INSTANCE_COUNT];
    +
    +const generic_onoff_client_callbacks_t client_cbs =
    +{
    +    .onoff_status_cb = app_generic_onoff_client_status_cb,
    +    .ack_transaction_status_cb = app_gen_onoff_client_transaction_status_cb,
    +    .periodic_publish_cb = app_gen_onoff_client_publish_interval_cb
    +};
    +
    +/* This callback is called periodically if model is configured for periodic publishing */
    +static void app_gen_onoff_client_publish_interval_cb(access_model_handle_t handle, void * p_self)
    +{
    +     __LOG(LOG_SRC_APP, LOG_LEVEL_WARN, "Publish desired message here.\n");
    +}
    +
    +/* Acknowledged transaction status callback, if acknowledged transfer fails, application can
    +* determine suitable course of action (e.g. re-initiate previous transaction) by using this
    +* callback.
    +*/
    +static void app_gen_onoff_client_transaction_status_cb(access_model_handle_t model_handle,
    +                                                       void * p_args,
    +                                                       access_reliable_status_t status)
    +{
    +    switch(status)
    +    {
    +        case ACCESS_RELIABLE_TRANSFER_SUCCESS:
    +            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Acknowledged transfer success.\n");
    +            break;
    +
    +        case ACCESS_RELIABLE_TRANSFER_TIMEOUT:
    +            hal_led_blink_ms(HAL_LED_MASK, LED_BLINK_SHORT_INTERVAL_MS, LED_BLINK_CNT_NO_REPLY);
    +            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Acknowledged transfer timeout.\n");
    +            break;
    +
    +        case ACCESS_RELIABLE_TRANSFER_CANCELLED:
    +            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Acknowledged transfer cancelled.\n");
    +            break;
    +
    +        default:
    +            ERROR_CHECK(NRF_ERROR_INTERNAL);
    +            break;
    +    }
    +}
    +
    +/* Generic OnOff client model interface: Process the received status message in this callback */
    +static void app_generic_onoff_client_status_cb(const generic_onoff_client_t * p_self,
    +                                               const access_message_rx_meta_t * p_meta,
    +                                               const generic_onoff_status_params_t * p_in)
    +{
    +    if (p_in->remaining_time_ms > 0)
    +    {
    +        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "OnOff server: 0x%04x, Present OnOff: %d, Target OnOff: %d, Remaining Time: %d ms\n",
    +              p_meta->src.value, p_in->present_on_off, p_in->target_on_off, p_in->remaining_time_ms);
    +    }
    +    else
    +    {
    +        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "OnOff server: 0x%04x, Present OnOff: %d\n",
    +              p_meta->src.value, p_in->present_on_off);
    +    }
    +}
    +
    +
    +
    +
    +
     /*****************************************************************************
      * Static variables
      *****************************************************************************/
    @@ -365,6 +467,7 @@ static const char m_usage_string[] =
         "\n"
         "\t\t--------------------------------------------------------------------------------\n"
         "\t\t Button/RTT 1) Initiate provisioning and configuration of unprovisioned devices.\n"
    +    "\t\t Button/RTT 3) Send Generic OnOff Set Unack message. \n"
         "\t\t Button/RTT 4) Clear all the states to reset the node.\n"
         "\t\t--------------------------------------------------------------------------------\n";
     #endif
    @@ -389,6 +492,32 @@ static void button_event_handler(uint32_t button_number)
                 break;
             }
     
    +        case 3:
    +        {
    +            uint32_t status;
    +            static bool state;
    +            generic_onoff_set_params_t set_params = {
    +                .on_off = state ? APP_STATE_ON : APP_STATE_OFF,
    +            };
    +            model_transition_t transition_params;
    +            static uint8_t tid = 0;
    +
    +            state = !state;
    +
    +            set_params.tid = tid++;
    +            transition_params.delay_ms = APP_ONOFF_DELAY_MS;
    +            transition_params.transition_time_ms = APP_ONOFF_TRANSITION_TIME_MS;
    +            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Sending msg: ONOFF SET %d\n", set_params.on_off);
    +
    +            status = generic_onoff_client_set_unack(&m_clients[0], &set_params,
    +                                                    &transition_params, APP_UNACK_MSG_REPEAT_COUNT);
    +            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Client send status: %d\n", status);
    +            status = generic_onoff_client_set_unack(&m_clients[1], &set_params,
    +                                                    &transition_params, APP_UNACK_MSG_REPEAT_COUNT);
    +            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Client send status: %d\n", status);
    +            break;
    +        }
    +
             /* Initiate node reset */
             case 4:
             {
    @@ -433,6 +562,16 @@ void models_init_cb(void)
          * health client : To be able to interact with other health servers */
         ERROR_CHECK(config_client_init(app_config_client_event_cb));
         ERROR_CHECK(health_client_init(&m_dev_handles.m_health_client_instance, 0, app_health_event_cb));
    +
    +    for (uint32_t i = 0; i < CLIENT_MODEL_INSTANCE_COUNT; ++i)
    +    {
    +        m_clients[i].settings.p_callbacks = &client_cbs;
    +        m_clients[i].settings.timeout = 0;
    +        m_clients[i].settings.force_segmented = APP_FORCE_SEGMENTATION;
    +        m_clients[i].settings.transmic_size = APP_MIC_SIZE;
    +
    +        ERROR_CHECK(generic_onoff_client_init(&m_clients[i], i + 1));
    +    }
     }
     
     static void mesh_init(void)
    @@ -482,6 +621,40 @@ static void mesh_init(void)
                 prov_helper_provision_self();
                 app_default_models_bind_setup();
                 app_data_store_cb();
    +
    +            for (uint32_t i = 0; i < CLIENT_MODEL_INSTANCE_COUNT; ++i)
    +            {
    +                /** Configure Model Subscription. */
    +                dsm_handle_t subscription_address_handle;
    +                uint32_t subscription_address = ((i + 1) & 1) ? SERVER_PUB_GROUP_ADDRESS_EVEN : SERVER_PUB_GROUP_ADDRESS_ODD;
    +                ERROR_CHECK(dsm_address_subscription_add(subscription_address, &subscription_address_handle));
    +                ERROR_CHECK(access_model_subscription_add(m_clients[i].model_handle, subscription_address_handle));
    +
    +                /** Configure Model Publication. */
    +                uint32_t publish_address = ((i + 1) & 1) ? CLIENT_PUB_GROUP_ADDRESS_EVEN : CLIENT_PUB_GROUP_ADDRESS_ODD;
    +                dsm_handle_t publish_address_handle = DSM_HANDLE_INVALID;
    +
    +                ERROR_CHECK(dsm_address_publish_add(publish_address, &publish_address_handle));
    +
    +                access_publish_period_t publish_period =
    +                {
    +                    .step_num = 1,
    +                    .step_res = ACCESS_PUBLISH_RESOLUTION_10S
    +                };
    +                access_publish_retransmit_t publish_retransmit =
    +                {
    +                    .count = 1,
    +                    .interval_steps = 0,
    +                };
    +                dsm_handle_t publish_appkey_handle = dsm_appkey_index_to_appkey_handle(APPKEY_INDEX);
    +
    +                ERROR_CHECK(access_model_publish_retransmit_set(m_clients[i].model_handle, publish_retransmit));
    +                ERROR_CHECK(access_model_publish_address_set(m_clients[i].model_handle, publish_address_handle));
    +                ERROR_CHECK(access_model_publish_application_set(m_clients[i].model_handle, publish_appkey_handle));
    +                ERROR_CHECK(access_model_publish_ttl_set(m_clients[i].model_handle, ACCESS_DEFAULT_TTL));
    +                ERROR_CHECK(access_model_publish_period_set(m_clients[i].model_handle, (access_publish_resolution_t) publish_period.step_res, publish_period.step_num));
    +
    +            }
             }
             else
             {
    

Children
No Data
Related