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.

  • 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)

  • I've got it working now, though the code is not ideal, I have NODE_SETUP_CONFIG_APPKEY_BIND_ONOFF_CLIENT listed 31 (!) times in client_config_steps and NODE_SETUP_CONFIG_PUBLICATION_ONOFF_CLIENT2 listed 30 (!) times. Many thanks for the help.

  • Hi Bjørn,

    I was also looking into sending unicast messages. It seems very silly to me to have a model instance for every possible node in the network, so I was wondering:

    Is it out of spec if a node sends messages to unicast addresses it was not specifically told to publish to by a provisioner?

    Can you call access_model_publish_address_set() before publishing a message, maybe multiple times per second. Or does that break some mesh code? Is this maybe different for reliable and unreliable messages?

  • Hi Bart, any luck on this? I tried using access_model_publish_address_set(), but it takes in a handle not an actual address. From my exploration of the code it appears that handles are determined at the configuration stage by the provisioner. There is also dsm_address_publish_add() which takes in a raw address, but I haven't had any luck with that either.

  • Hey, I haven't actually tried it yet, as i first need to implement functionality before optimizing thing =] Didn't see that it takes a handle. I'd also say you need to call dsm_address_publish_add() for each unicast address then.

  • Solved! 

    static uint32_t set_model_publish_address(uint16_t publish_address, access_model_handle_t model_handle) 
    {  
        uint32_t status = NRF_SUCCESS;
        dsm_handle_t publish_address_handle = DSM_HANDLE_INVALID;
        access_model_publish_address_get(model_handle, &publish_address_handle);
        NRF_MESH_ASSERT(dsm_address_publish_remove(publish_address_handle) == NRF_SUCCESS);
        status = dsm_address_publish_add(publish_address, &publish_address_handle); 
        if (status != NRF_SUCCESS) {
            return status;
        } 
        else {
            return access_model_publish_address_set(model_handle, publish_address_handle);
        }
    } 

    I call this function like so:

    set_model_publish_address(UNI_ADDR, m_clients[2].model_handle);

    Credit: Hung Bui (https://devzone.nordicsemi.com/f/nordic-q-a/35931/multiple-server-on-one-client---light-switch-demo)

Reply Children
No Data
Related