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

Relayed message of relay node not received by other server node.

I have created three nodes(A, B, C) one client(i.e A) and two servers (i.e B and C) using simple_message_model. The node that contains the client model(A node) provision the two other nodes(B and C). Now after provisioning the node. I have kept the nodes such that (A->B->C) B is in range of A. C is in range of B but C is not in range of A. I have call the access_model_publish() on press of switch 0. which sends the message from A to B node. B node is control node contains client as well as server model (i.e it acts as a relay node.) When B receives the message it calls access_model_publish to send the received message to node C. But in my example it seems that B receives the message but C not receives the message. after sending message from B it returns status 0 still C not receives the message. Is there any need to do the access layer setup (access_setup)?. I am not able to find the actual cause of this problem. Will you please help to solve the problem?

Thanks in advance.

  • Hi,

    It is hard to tell from your descriptions alone. Can you attach the code for A, B, C for us to see what you do and how?

    Regards,
    Terje

  • I have extended the light switch example to send string message using simple_message model. I have used one client node (A node) and two server nodes(B and C) node. In client programm i used simple_message_client.c and In server i have create simple_message_control.c by merging the simple_message_client.c and simple_message_server.c. So the simple_message_control.c contains all functions of simple_message_client.c and simple_message_server.c. 

    I have flashed the server program inside B and C node then i flashed the client programm in A node. So as soon as I flashed the client programm, A node starts provisioning the B and C node. After provisioning complete I have placed the B node in range of A, And C node in range B but not in range of A. 

    Now I have done the below process.

    When I pressed the button 0 on client node(A node) send_message() function is called. The definition for send_message() function is as below.

    void send_message(){
    uint32_t status=0;
    uint8_t buffer[10]="Hello mesh";
    uint8_t length;

    //uint16_t address;
    access_message_tx_t msg;
    length= sizeof(buffer);
    if (length)
    {
    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);
    status= access_model_publish(m_clients[0].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);
    }
    }
    }

    Here I have not used the address because "address = 0xCAFE" is group address and i want to send the message to unicast address.

    Now at server node (B node) I have received the message inside set_cb() function so that I have modified the set_cb() function of light switch server main.c and rx_set_cb() of simple_message_server.c(Now here is simple_message_control.c) as below.

    static void rx_set_cb(access_model_handle_t handle, const access_message_rx_t * p_message, void * p_args)
    {
    simple_message_server_t * p_server = p_args;
    NRF_MESH_ASSERT(p_server->set_cb != NULL);
    uint8_t* value = ((simple_message_msg*) p_message->p_data)->data; // modified code.
    p_server->set_cb(p_server, p_message->meta_data.src, p_message->meta_data.dst,value,p_message->length);

    }

    static void set_cb(const simple_message_server_t * p_server, nrf_mesh_address_t src, nrf_mesh_address_t dst, uint8_t *data, uint8_t length)
    {
     
    send_message(&data[0]);

    }

    So i received the "Hello mesh" message in "data" of set_cb(). As soon as i received the message I have called the send_message() function because I have to relay that message to other server node(C node). The definition for send message() is same as below.

    void send_message(uint8_t *data){
    uint32_t status=0;
    uint8_t buffer[10]={};
    uint8_t length;
    dsm_local_unicast_address_t address;

    access_message_tx_t msg;
    for(int i=0; i<10; i++){
    buffer[i]=data[i];
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Received message = %c\n", buffer[i]);
    }

    length= sizeof(buffer);
    if (length)
    {
    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;

    status= access_model_publish(m_server.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);
    }
    }
    }

    But at node C the "Hello mesh" message is not received. What wrong i did?

    Also in network.c of mesh sdk "m_relay_enable = true;", it seems that relay feature is enabled also there is packet_relay() method which relay the received message. But when packet_relay() method is called whether it is called as soon as message received? 

    Will you please provide solution to this problem?

    Thanks in advance.

  • Hi,

    It looks like there is a misconception here. Actually you can send messages "directly" from node A to node C through the Mesh, independently of what the topology of the network looks like. You do not need to modify node B. If node B is a relay node then messages will automatically propagate from A through B to C, and so you can address C directly from A.

    The relay node functionality is handled by the Mesh stack, and you do not have to do anything in the application for it to relay messages. All you have to do is configure A and C so that the client in A can use the server in C. Then those two nodes can communicate independently of what the network in-between looks like.

    Regards,
    Terje

  • hello Pooja,

    In order to augment the advice given to you by @tesc above...

    Relaying is a feature that is implemented by the underlying mesh stack. Based upon the topology of the mesh network (i.e. where the devices are located) a network manager/admin (i.e. whoever has control of the mesh network), will determine whether to flag that a specific node will support relaying (i.e. turn that feature flag on or off). This will be done in order to enhance the delivery of messages across the mesh and is closely linked to the TTL value(s) set either as a default or across a particular model. For example, some tests have shown that for certain network topologies you might only need approx. 2% of your total nodes to act as relays. This is because too many relays will increase the mesh networks on-air traffic and depending on the TTL set, may actually stop a message from being delivered to nodes at the edge of a network.

    The bottom line is that setting a device(s) relay feature to be on or off and setting the TTL to optimum values is a consideration that needs to be done carefully and periodically to match changes in the mesh networks topology.

    Once again, I would suggest that you follow the links that I provided in my response to your previous post, and re-iterate the following advice that I subsequently gave (as follows)..

    Regards,

  • Hi Pooja

     Can you send me the configured files? I followed the instructions to configure but it always went wrong.

Related