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

Sending messages to unicast addresses

In the latest Mesh SDK, nodes are subscribed to a GROUP address. In previous versions - 2.0.0 I believe - you could also send to a predetermined node.

I am trying to figure out how to send a message to any one node via its unicast address. I have created a CLIENT in node_setup.c for this:

case NODE_SETUP_CONFIG_PUBLICATION_ONOFF_CLIENT2:
        {
            config_publication_state_t pubstate = {0};
            client_pub_state_set(&pubstate, 
                                 m_current_node_addr + ELEMENT_IDX_ONOFF_CLIENT2,
                                 UNPROV_START_ADDRESS + CLIENT_MODEL_INSTANCE_COUNT + ELEMENT_IDX_ONOFF_CLIENT1);
            status = config_client_model_publication_set(&pubstate);

            static const access_status_t exp_status[] = {ACCESS_STATUS_SUCCESS};
            expected_status_set(CONFIG_OPCODE_MODEL_PUBLICATION_STATUS, ARRAY_SIZE(exp_status), exp_status);
            break;
        }

However, how do I (a) get the address of a node to send to it and (b) send to it.

Ultimately, I want to be able to configure one of the button presses to send a message to each server one by one.

Parents
  • You can easily do this using the nRF Mesh smartphone app. The procedure is similar to the Youtube video shown here. What you will need to do is have one standard light switch client & one standard light switch server board. I tested with the mesh sdk v3.1.0. Then, provision both boards. On the client board in nRF Mesh, add the application key (under appkey binding, choose the first one) &  set the publication address of the first generic on off client model to be the unicast address of the server board. If you click on the server board in nRF Mesh, you can see that the generic on off server is under element 0 with a unicast address (e.g. element 0. UNICAST: 0004). On the server board, you need to bind the same appkey to the generic on off server model. This way, both nodes will be able to communicate with each other over the access layer in the mesh sdk. Then, when you press button 1 & 2 on the client board, you will send an acknowledged set message to turn the server board either on or off. The procedure should be similar if you want to add multiple server boards.

Reply
  • You can easily do this using the nRF Mesh smartphone app. The procedure is similar to the Youtube video shown here. What you will need to do is have one standard light switch client & one standard light switch server board. I tested with the mesh sdk v3.1.0. Then, provision both boards. On the client board in nRF Mesh, add the application key (under appkey binding, choose the first one) &  set the publication address of the first generic on off client model to be the unicast address of the server board. If you click on the server board in nRF Mesh, you can see that the generic on off server is under element 0 with a unicast address (e.g. element 0. UNICAST: 0004). On the server board, you need to bind the same appkey to the generic on off server model. This way, both nodes will be able to communicate with each other over the access layer in the mesh sdk. Then, when you press button 1 & 2 on the client board, you will send an acknowledged set message to turn the server board either on or off. The procedure should be similar if you want to add multiple server boards.

Children
  • Thanks, but I would like to do this without the app. I have a version of the very old SDK (alpha) in which the client could send to any individual board because m_clients was an array of the individual boards. In the new SDK however, there are only two models - one to send to even the other to odd. I would like to use one of the models for unicast sending but I cannot figure out how to.

  • I tried to use access_model_publish_address_set() to change the address the model uses:

             case 1:
                __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "-- Acknowledged unicast\n");
                (void)access_model_reliable_cancel(m_clients[0].model_handle);
                dsm_handle_t handle;
                (void)access_model_publish_address_get(m_clients[0].model_handle, &handle);
                for (int i = 0; i < SERVER_NODE_COUNT; i++) {
                  status = access_model_publish_address_set(m_clients[0].model_handle, handle+i);
                  __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "%u\n", status);
                  status = generic_onoff_client_set(&m_clients[0], &set_params, &transition_params);
                }
                hal_led_pin_set(BSP_LED_0, set_params.on_off);
                break;

    This causes the following to be true:

    access_model_publish_address_set(...) {
    ...
    else if (DSM_ADDR_MAX <= address_handle)
    {
        return NRF_ERROR_INVALID_PARAM;
    }

    So I increased ACCESS_MODEL_COUNT to remove this error, and now I get the following when pressing button 1:

    app_error_weak.c,  108, Mesh assert at 0x000340B6 (:0)

  • If you want to provision via the provisioner light switch example, the only changes you would need to make are in the node_setup.c file like you mention above. Assuming you want the first client to publish to the first server address, you would need to find the element address of the server.

    In the latest mesh sdk (i.e. v3.1.0), the check_network_state() function will configure the different nodes. The node_setup_start() function is then called, which then calls setup_select_steps(). This function will then go through the client configuration steps first before going through the server configuration steps. config_step_execute() then goes through all of the steps in order to configure the node.

    If I were you, I would keep track of the element_address in each step. The steps are essentially hardcoded at the moment. If you go through the whole process, add a bit more logging info to the element address, you can predict the unicast element address of the server. That way, you can set the correct unicast publication address for the case NODE_SETUP_CONFIG_PUBLICATION_ONOFF_CLIENT1. The setup for setting the publication unicast address should be similar to the case NODE_SETUP_CONFIG_PUBLICATION_ONOFF_SERVER.

  • I can send to just the first server, but I want to be able to send to all nodes individually. That's what my second bit of code is trying to achieve, but getting the error.

  • Do I need to have a model for each server? When I use access_model_publish_address_set it just changes the publish address, which means that when I call generic_onoff_client_set it returns NRF_ERROR_BUSY because it's trying to run the same model. If I need a model for each server, how can I do this without having to write a separate NODE_SETUP_CONFIG_PUBLICATION_ONOFF_CLIENTx for each of them?

Related