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

Broadcast Mesh Message

Hi,

I'm trying to send a broadcast message from my client to all my server. Actually i'm working over a modifed version of the light switch example.

i saw that in the node_setup of the provisioner the server address is set.

The easiest thing that i thought to do the broadcast is to change this part from this

if ((m_current_node_addr % 0x02))
{
    address.value  = GROUP_ADDRESS_ODD;
}
else
{
    address.value  = GROUP_ADDRESS_EVEN;
}

to this

address.value = GROUP_ADDRESS_ODD;

And then on the client side doing this

static void button_event_handler(uint32_t button_number)
{
    ...
    
    status = simple_on_off_client_set_unreliable(&m_clients[3],
                                                         &ptr[0],4,
                                                         GROUP_MSG_REPEAT_COUNT);
                                                         
    ...
}

I should be able to send a message to all server. Actually the message is recived but after the 1st time i send it the client stop work but not getting any errors. The client just looks like he's lost on his code.

Any suggestion?

The only change that i've made to this code is the possibility to send an array of values and i added as well the code for the dfu even if that last part has not been tested yet.

Thanks for the help.

Parents Reply Children
  • Very sorry for the delayed response. It seems like you are using the regular provisioning example. What changes have you made to the simple_on_off_client_set_unreliable() function? I understand the first argument , but what about the second & third arguments?

    What does the log for the client & server look like? Could you upload it please?

    It seems like you are doing the correct thing in the provisioner by making all of the server nodes subscribe to the GROUP_ADDRESS_ODD address.

    In the code below in node_setup.c of the provisioner:

            case NODE_SETUP_CONFIG_PUBLICATION_ONOFF_CLIENT3:
            {
                config_publication_state_t pubstate = {0};
                client_pub_state_set(&pubstate,
                                     m_current_node_addr + ELEMENT_IDX_ONOFF_CLIENT3,
                                     GROUP_ADDRESS_ODD);
                retry_on_fail(config_client_model_publication_set(&pubstate));
    
                static const uint8_t exp_status[] = {ACCESS_STATUS_SUCCESS};
                expected_status_set(CONFIG_OPCODE_MODEL_PUBLICATION_STATUS, sizeof(exp_status), exp_status);
                break;
            }
    
            case NODE_SETUP_CONFIG_PUBLICATION_ONOFF_CLIENT4:
            {
                config_publication_state_t pubstate = {0};
                client_pub_state_set(&pubstate,
                                     m_current_node_addr + ELEMENT_IDX_ONOFF_CLIENT4,
                                     GROUP_ADDRESS_EVEN);
                retry_on_fail(config_client_model_publication_set(&pubstate));
    
                static const uint8_t exp_status[] = {ACCESS_STATUS_SUCCESS};
                expected_status_set(CONFIG_OPCODE_MODEL_PUBLICATION_STATUS, sizeof(exp_status), exp_status);
                break;
            }

    You could try to change the GROUP_ADDRESS_EVEN in client_pub_state_set() to GROUP_ADDRESS_ODD & see if that makes a difference. I am not sure it will, but it could be worth a shot.

    If you use the smartphone as the provisioner with the nrf mesh app & the proxy client & proxy server examples, it is really easy to setup a group address. The generic on off client model on the client can publish to a group address (e.g. 0xc001) & all of the servers can subscribe to this address in their respective generic on off server models. Take a look at this youtube video for more info.

    In addition, here are two pdf's which explain the steps further:

    Mesh Hands-on Android_october2018.pdf

    Mesh Hands-on iOS_October2018.pdf

    Hope that helps!

  • Hi,

    Sorry for my late answer as well.

    Anyway the code inside the unreliable command is the following:

    uint32_t simple_on_off_client_set_unreliable(simple_on_off_client_t * p_client, 
                                                 uint8_t *msg, uint16_t lenght, 
                                                 uint8_t repeats)
    {
        uint8_t i;
        simple_on_off_msg_set_unreliable_t set_unreliable;
        
        for(i = 0; i < 4; i++){
          set_unreliable.msg[i] = *msg;
          msg++;
        }
    
        set_unreliable.tid = m_tid++;
    
        access_message_tx_t message;
        message.opcode.opcode = SIMPLE_ON_OFF_OPCODE_SET_UNRELIABLE;
        message.opcode.company_id = SIMPLE_ON_OFF_COMPANY_ID;
        message.p_buffer = (const uint8_t*) &set_unreliable; //msg;
        message.length = sizeof(set_unreliable); //lenght + 1;
        message.force_segmented = false;
        message.transmic_size = NRF_MESH_TRANSMIC_SIZE_DEFAULT;
    
        uint32_t status = NRF_SUCCESS;
        for (uint8_t i = 0; i < repeats; ++i)
        {
            message.access_token = nrf_mesh_unique_token_get();
            status = access_model_publish(p_client->model_handle, &message);
            if (status != NRF_SUCCESS)
            {
                break;
            }
        }
        return status;
    }

    The idea is to send an array of uint8_t value (this code is inside the client).

    In the server side the code to recive is the following:

    static void handle_set_unreliable_cb(access_model_handle_t handle, const access_message_rx_t * p_message, void * p_args)
    {
        simple_on_off_server_t * p_server = p_args;
        NRF_MESH_ASSERT(p_server->set_cb != NULL);
        
        p_server->set_cb(p_server,(uint8_t*) p_message->p_data,(uint16_t) p_message ->length);
        (void)simple_on_off_server_status_publish(p_server, true);
    }

    Here I just changed the callback to have the pointer of the array so i can go through it.

    Here on the server side what i get is:

    <t:     442373>, main.c,  171, Got SET command<t:     442375>, main.c,  174, Value: 0x0010 
    <t:     442377>, main.c,  174, Value: 0x0020 
    <t:     442379>, main.c,  174, Value: 0x0030 
    <t:     442381>, main.c,  174, Value: 0x0040 
    <t:     442383>, main.c,  174, Value: 0x0000 
    <t:     443321>, main.c,  171, Got SET command<t:     443323>, main.c,  174, Value: 0x0010 
    <t:     443325>, main.c,  174, Value: 0x0020 
    <t:     443327>, main.c,  174, Value: 0x0030 
    <t:     443329>, main.c,  174, Value: 0x0040 
    <t:     443332>, main.c,  174, Value: 0x0000 

    Printed by:

    static void on_off_server_set_cb(const simple_on_off_server_t * p_server, uint8_t *msg, uint16_t lenght)
    {
        uint8_t i;
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Got SET command");
    
        for(i = 0; i < lenght; i++){
          __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Value: 0x%04x \n", *msg);
          msg++;
        }
    
        hal_led_pin_set(BSP_LED_0, !hal_led_pin_get(BSP_LED_0));
    }

    On the client side:

    static void button_event_handler(uint32_t button_number)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Button %u pressed\n", button_number);
    
        uint32_t status = NRF_SUCCESS;
        switch (button_number)
        {
            ...
            case 3:
                /* send a group message to the ODD group, with inverted GPIO pin value */
                status = simple_on_off_client_set_unreliable(&m_clients[2],
                                                             &ptr[0],4,
                                                             GROUP_MSG_REPEAT_COUNT);
    
                /*status = simple_on_off_client_set_unreliable(&m_clients[3],
                                                             &ptr[0],4,
                                                             GROUP_MSG_REPEAT_COUNT);*/
    
                if (status == NRF_SUCCESS)
                {
                    hal_led_pin_set(BSP_LED_0 + button_number, !hal_led_pin_get(BSP_LED_0 + button_number));
                }
                break;
            default:
                break;
        }
    
        ...
    }
    

    <t:     398996>, main.c,  228, Button 2 pressed
    <t:     399488>, main.c,  189, OnOff server 0 status ON
    <t:     400415>, main.c,  189, OnOff server 0 status ON

    On the provisioner the address is always GROUP_ADDRESS_ODD.

    Here if i press the button again nothing appen. The code seems to stuck on the "m_prepare_for_reserve" inside "packet_buffer.c".

    I've found something not working fine. The value recived should be "0x10 0x20 0x30 0x40" but the first one is missing.

    If i decrese by one the pointer inside the unreliable_set then i recive the 1st one but not the last one.

    That's what i've found and i'm still looking if i can do something more to help to find the error.

    Thanks for the help

  • Hi,

    I made this work by making another one from the example. Don't know what was the error but looks like i fixed it.

    Thanks for the support

Related