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

A simple message from server to client in mesh 2.0.1.

Hi,

I am trying to send a simple message from server to client in mesh 2.0.1. I am following this post for the same. I successfully sent a message from client to server and received it in the server side. Now I want to send a message from server to client. I have added all codes provided in the above post and made the specified changes for the server too. But message is not getting sent. 

void address_set(uint16_t addr)                 //function for setting address
{
  uint32_t err_code;
  err_code = dsm_address_publish_add(addr, &m_central_handle); //NRF_ERROR_NO_MEM
  ERROR_CHECK(err_code);
  ERROR_CHECK(access_model_publish_address_set(m_clients[0].model_handle, m_central_handle));
}

I am getting error:   <t:     663640>, app_error_weak.c,  105, Mesh error 4 at 0x000267E9 at examples\simple_message\server\src\main.c:269 ie. at

err_code = dsm_address_publish_add(addr, &m_central_handle); //NRF_ERROR_NO_MEM
ERROR_CHECK(err_code);

The error code is NRF_ERROR_NO_MEM . Can you help me to resolve this? I want to sent a unicast message to the client from server.

Parents Reply
  • Hi Edvin,

    This is the log of the server before provisioning. I am setting the address as 0xCAFE.

    <t: 0>, main.c, 276, ----- BLE Mesh Light Switch Client Demo -----
    <t: 0>, mesh_softdevice_init.c, 112, Initializing SoftDevice...
    <t: 0>, mesh_softdevice_init.c, 77, Enabling BLE...
    <t: 2>, mesh_softdevice_init.c, 88, Ram base: 0x200032C8
    <t: 538>, main.c, 249, Initializing and adding models
    <t: 5445>, main.c, 304, Device UUID : 0059ABCDEFABCDEFACCDEFABCDEFABCD

Children
  • Sorry for the late reply,

     

    It looks like the function add_address() doesn't find a handle for the new address. 

    Can you check the nrf_mesh_address_type_t * p_type of the address? I assume it is NRF_MESH_ADDRESS_TYPE_GROUP. Just step through the code from:

    dsm_address_publish_add() (the time that it fails) -> 

    add_address() -> 

    address_exists() (I assume this one returns &handle = DSM_HANDLE_INVALID) ->

    And see whether it steps int p_type == NRF_MESH_ADDRESS_TYPE_VIRTUAL or p_type == NRF_MESH_ADDRESS_TYPE_GROUP

     

    As mentioned, I assume it is NRF_MESH_ADDRESS_TYPE_GROUP. In that case, can you try to increase DSM_NONVIRTUAL_ADDR_MAX (in nrf_mesh_config_app.h) ?

     

    Best regards,

    Edvin

  • Hi Edvin,

    Thank you for replying. As per the instructions I increased DSM_NONVIRTUAL_ADDR_MAX. 

    #define DSM_NONVIRTUAL_ADDR_MAX                         (4)

    I was able to send a message to client like the below given code

    void address_set(uint16_t addr)                   //setting address for sending message
    {
      ERROR_CHECK(dsm_address_publish_add(addr, &m_central_handle));
      ERROR_CHECK(access_model_publish_address_set(m_clients[0].model_handle, m_central_handle));
      }

    In this case I set the address as 0xCAFE, the group address.

    Then tried unicast to client by setting address as 0x100 (client's address). It worked, I got message in client from server. But then I tried to broad cast from server.

    void address_set(uint16_t addr)                   //setting address for sending message
    {
      ERROR_CHECK(dsm_address_publish_add(addr, &m_central_handle));
      ERROR_CHECK(access_model_publish_address_set(m_server.model_handle, m_central_handle));
    }
    
    Here the address was 0xCAFE. But servers did not receive the message. Why is that? There is no error. Message is being sent.

  • Hello,

    The provisioner project is quite hard coded to provision exactly 2 servers with a unicast address, and two groups. 

     

    So you can send a message from the client to the server, and the light changes, right? But the client doesn't receive a message back from the server, is that correct? Does this mean that you don't receive confirmation that the light is changed when it is the client that sent the message, or is it only when the server turns off by itself that the server do not get the message? 

    The changes that you are doing, are they in node_setup.c? Or are you doing the changes outside this file? If the changes are in this file, can you upload that file here?

     

    Best regards,

    Edvin

  • Hi Edvin,

    1. I changed the group address to 0xC002 in example_network_config.h, in order to send message to all servers instead of group cast.

    #define GROUP_ADDRESS_EVEN (0xC002)
    #define GROUP_ADDRESS_ODD  (0xC002)

    2. I can send message from client to server and LED changes its state in response. I am sending a string from client to server, which is also received there in server.

    3. After changing this parameter ,I can send a message(string) from server to client.

    #define DSM_NONVIRTUAL_ADDR_MAX                         (4)

    4. I am not changing codes in node_setup.c. I am changing in main.c according to this post

    void address_set(uint16_t addr)                   //setting address for sending message
    {
      ERROR_CHECK(dsm_address_publish_add(addr, &m_central_handle));
      ERROR_CHECK(access_model_publish_address_set(m_server.model_handle, m_central_handle));
    }
    
    void send_message(void)                         //function for sending a simple message
    {
        uint32_t status=0;
        uint8_t buffer[5] = "hello";
        uint8_t length;
        uint16_t address;
        access_message_tx_t msg;
        length = sizeof(buffer); //SEGGER_RTT_Read(0, buffer, sizeof(buffer));
        
        if(length)
        {
          //no-need:SEGGER_RTT_WriteString(0, "entering message field\n");
          msg.opcode.opcode = simple_message_OPCODE_SEND;
          msg.opcode.company_id = 0x0059; // Nordic's company ID
    
          msg.p_buffer = (const uint8_t *) &buffer[0];
          msg.length = length;
          address = 0xCAFE;
          address_set(address);
          SEGGER_RTT_printf(0,"Sending to group address 0x%04x\n", address);
          status= access_model_publish(m_clients[3].model_handle, &msg);
    
          if(status == NRF_ERROR_INVALID_STATE ||
          status == NRF_ERROR_BUSY||
          status == NRF_ERROR_NO_MEM)
          {
            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Cannot send. Device is busy.\n");
            hal_led_blink_ms(LEDS_MASK, 50, 4);
          }
          else
          {
             ERROR_CHECK(status);
          }
        }
    }
    

    These two functions and some necessary changes have been made in main.c

    5. I want to send the same above message from a server to another server as a broadcast. Should I begin a new case for that?

    Thank you.

  • Ok. I see.

    You should take a look in node_setup.c as well.

    The fist two servers are set up with individual unix addresses. You must do this for the third server as well. 

    On line 123 you'll see:
    static const config_steps_t client_config_steps[] = ...

    which is the provisioning steps that the client will go through. 

    line 141 describes the steps that the first two servers will go through:
    static const config_steps_t server1_server2_config_steps[] = ...

    line 154 describes a step that all of the servers will go through:
    static const config_steps_t server_config_steps[] = ...

     

    Line 321 decides what steps the node that is being provisioned will go through.

     

    You must alter these lists to set up a unix address to all devices. This decides what addresses the different devices are publishing on, and what addresses the different devices are listening on.

     

    BR,

    Edvin

Related