about success rate of publish-subscribe mechanism of Zephyr Bluetooth Mesh


Vikrant More <vikrant8051@...>
 

void foo(int a,int b,unsigned char c)
{

    static volatile unsigned char tmp = 0;

    struct net_buf_simple *msg1 = NET_BUF_SIMPLE(2+4+2);

    struct bt_mesh_msg_ctx ctx1 = {
        .net_idx = b,
        .app_idx = a,
        .addr = 0xC001,
        .send_ttl = BT_MESH_TTL_DEFAULT,
    };

   
    bt_mesh_model_msg_init(msg1, BT_MESH_MODEL_OP_2(0x82, 0x03));

    net_buf_simple_add_u8(msg1,c);            // <------------------------------------------------------- C is 0 or 1
    net_buf_simple_add_u8(msg1, 00);    //<-------------------------------------------------------- what to send from here ??
                                                                                                                       // If I didn't add this then firmware throws error after receiving message.

    if (bt_mesh_model_send(&root_models[2], &ctx1, msg1, NULL, NULL)) {
        printk("Unable to send Vendor Button message\n\r");
    }

    printk("Button message sent with OpCode 0x%08x......\n\r", BT_MESH_MODEL_OP_2(0x82, 0x03));

}

I am calling this function from Button interrupt to publish data as '1' or '0' to all nodes which are part
one particular group. But success rate is not impressive at all.

I'm able to see printk("Button message sent with OpCode 0x%08x......\n\r", BT_MESH_MODEL_OP_2(0x82, 0x03)) on
serial terminal of Publisher on each click of button. That means foo() is executing.

But on an average only 6 out 10 times, exact data get received by all Subscribers.

Silicon Labs Bluetooth Mesh App has functionality of Master Control (on/off switch which control LED on all nodes in single click).
It is working perfectly. Success rate is 100%.

But if I try the same with (Publisher) node based on Zephyr as mentioned above then it is not 100% reliable.

Is there anything that I am missing in my code ?

Thank You !!






Johan Hedberg
 

Hi Vikrant,

On Fri, Dec 01, 2017, Vikrant More wrote:
if (bt_mesh_model_send(&root_models[2], &ctx1, msg1, NULL, NULL)) {
Note that strictly speaking this isn't publishing. For publishing you'd
use the bt_mesh_model_publish() API. The bt_mesh_model_send() is
primarily intended to be used for responding to messages when you're
implementing a server model.

I am calling this function from Button interrupt
The Mesh APIs aren't designed to be called directly from interrupt
context since they need to potentially block while waiting for buffers
to become available. The encryption procedures also consume a lot of CPU
time, which is unacceptable e.g. for the controller code which relies on
low-latency interrupts. So I'd recommend deferring the calls to thread
context using e.g. k_work, like the mesh_demo app does for the BBC
micro:bit button presses.

But on an average only 6 out 10 times, exact data get received by all
*Subscribers*.

Silicon Labs Bluetooth Mesh App has functionality of *Master Control *(on/off
switch which control LED on all nodes in single click).
It is working perfectly. Success rate is 100%.

But if I try the same with (*Publisher*) node based on Zephyr as mentioned
above then it is not 100% reliable.

Is there anything that I am missing in my code ?
The SiLabs Android app only uses GATT, and GATT is a 100% reliable
bearer. The advertising bearer is not, so you may easily get lost
packets. This is why the Mesh specification comes with all sorts of ways
for fine-tuning transmission reliability. You've e.g. got the Network
Transmit state as well as the Publish Retransmit state that can be used
to increase the number of transmissions that your node does when sending
out data over the advertising bearer.

Johan