0

Zephyr Bluetooth Mesh development

vikrant8051 gravatar image

asked 2017-11-14 16:35:22 +0100

updated 2017-11-22 09:11:13 +0100

I think Zephyr OS has better support for "Bluetooth Mesh" than Nordic own MESH SDK.

https://github.com/zephyrproject-rtos...

Using this kernel version, I've flashed $zephyr/samples/bluetooth/mesh this example into three nRF52840-PDK boards. Now each board is advertising itself as "Zephyr" & using "NRF connect" Android App we can connect to it just like any other GATT peripheral device.

Here all three boards are acting like unprovisioned Devices.

After configuration, these devices may be turn into Mesh Node. Right ??

But I don't know what to send.

Nordic Mesh light_switch server example does not show any such properties. I think Nordic Mesh SDK is using Advertising Bearer while Zephyr is using GATT Bearer.

Now what to do next ?

I also found this link, https://www.zephyrproject.org/announc...

As per my understanding, using meshctl (BlueZ 5.47) utility we have to develop Bluetooth Mesh Provisioner App. Am I right ?

Is nordic has any plan to release MESH related examples which support this https://play.google.com/store/apps/de... Android APP ?

edit retag flag offensive close delete report spam

Comments

We are not the one who is behind the Bluetooth Mesh on Zephyr. I couldn't find much documentation on the mesh implementation there. I think the question would be best answered on Zephyr site.

Hung Bui ( 2017-11-15 10:54:47 +0100 )editconvert to answer

3 answers

Sort by » oldest newest most voted
1
vikrant8051 gravatar image

answered 2017-11-24 10:11:07 +0100

updated 2017-12-15 17:26:27 +0100

Add nrf_delay.h & nrf52840.h files from nordic SDK into zephyr/boards/arm/nrf52840_pca10056.

And modify zephyr/samples/bluetooth/mesh/src/main.c as follow :

    /* main.c - Application main entry point */

    /*
     * Copyright (c) 2017 Intel Corporation
     *
     * SPDX-License-Identifier: Apache-2.0
     */

    #include <misc/printk.h>

    #include <bluetooth/bluetooth.h>
    #include <bluetooth/mesh.h>

    #include "board.h"

    #include "nrf52840.h"
    #include "nrf_delay.h"

    #define CID_INTEL 0x0002

    static struct bt_mesh_cfg_srv cfg_srv = {
        .relay = BT_MESH_RELAY_ENABLED,
        .beacon = BT_MESH_BEACON_ENABLED,
    #if defined(CONFIG_BT_MESH_FRIEND)
        .frnd = BT_MESH_FRIEND_ENABLED,
    #else
        .frnd = BT_MESH_FRIEND_NOT_SUPPORTED,
    #endif
    #if defined(CONFIG_BT_MESH_GATT_PROXY)
        .gatt_proxy = BT_MESH_GATT_PROXY_ENABLED,
    #else
        .gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED,
    #endif
        .default_ttl = 7,

        /* 3 transmissions with 20ms interval */
        .net_transmit = BT_MESH_TRANSMIT(2, 20),
        .relay_retransmit = BT_MESH_TRANSMIT(2, 20),
    };

    static struct bt_mesh_health_srv health_srv = {
    };

    static struct bt_mesh_model_pub gen_level_pub;
    static struct bt_mesh_model_pub gen_onoff_pub;

    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    static void gen_onoff_get(struct bt_mesh_model *model,
                  struct bt_mesh_msg_ctx *ctx,
                  struct net_buf_simple *buf)
    {
    }

    static void gen_onoff_set(struct bt_mesh_model *model,
                  struct bt_mesh_msg_ctx *ctx,
                  struct net_buf_simple *buf)
    {   


            unsigned char tmp = net_buf_simple_pull_u8(buf);

             if(tmp == 1)
            {
                   NRF_P0->OUT &= ~(1<<13);
                 }  
                 else
                 {   
                   NRF_P0->OUTSET |= (1<<13);                             
                 }                   
        } 


        static void gen_onoff_set_unack(struct bt_mesh_model *model,
                        struct bt_mesh_msg_ctx *ctx,
                        struct net_buf_simple *buf)
        {
    unsigned char tmp = net_buf_simple_pull_u8(buf);

                 if(tmp == 1)
                {
                       NRF_P0->OUT &= ~(1<<14);
                 }  
                 else
                 {   
                   NRF_P0->OUTSET |= (1<<14);                             
                 }
        }

        static const struct bt_mesh_model_op gen_onoff_op[] = {
            { BT_MESH_MODEL_OP_2(0x82, 0x01), 0, gen_onoff_get },
            { BT_MESH_MODEL_OP_2(0x82, 0x02), 2, gen_onoff_set },
            { BT_MESH_MODEL_OP_2(0x82, 0x03), 2, gen_onoff_set_unack },
            BT_MESH_MODEL_OP_END,
        };


        //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

        static void gen_level_get(struct bt_mesh_model *model,
                      struct bt_mesh_msg_ctx *ctx,
                      struct net_buf_simple *buf)
        {
        }

        static void gen_level_set(struct bt_mesh_model *model,
                      struct bt_mesh_msg_ctx *ctx,
                      struct net_buf_simple *buf)
        {   
        }

        static void gen_level_set_unack(struct bt_mesh_model *model,
                        struct bt_mesh_msg_ctx *ctx,
                        struct net_buf_simple *buf)
        {
        }

        static void gen_delta_set(struct bt_mesh_model *model,
                      struct bt_mesh_msg_ctx *ctx,
                      struct net_buf_simple *buf)
        {
        }

        static void gen_delta_set_unack(struct bt_mesh_model *model,
                        struct bt_mesh_msg_ctx *ctx,
                        struct net_buf_simple *buf)
        {
        }

        static void gen_move_set(struct bt_mesh_model *model,
                     struct bt_mesh_msg_ctx *ctx,
                     struct net_buf_simple *buf)
        {
        }

        static void gen_move_set_unack(struct bt_mesh_model *model,
                           struct bt_mesh_msg_ctx *ctx,
                           struct net_buf_simple *buf)
        {
        }

        static const struct bt_mesh_model_op gen_level_op[] = {
            { BT_MESH_MODEL_OP_2(0x82, 0x05), 0, gen_level_get },
            { BT_MESH_MODEL_OP_2(0x82, 0x06), 3, gen_level_set },
            { BT_MESH_MODEL_OP_2(0x82, 0x07), 3, gen_level_set_unack },
            { BT_MESH_MODEL_OP_2(0x82, 0x09), 5, gen_delta_set },
            { BT_MESH_MODEL_OP_2(0x82, 0x0a), 5, gen_delta_set_unack },
            { BT_MESH_MODEL_OP_2(0x82, 0x0b), 3, gen_move_set },
            { BT_MESH_MODEL_OP_2(0x82, 0x0c), 3, gen_move_set_unack },
            BT_MESH_MODEL_OP_END,
        };

        //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

        static struct bt_mesh_model root_models[] = {
            BT_MESH_MODEL_CFG_SRV(&cfg_srv),
            BT_MESH_MODEL_HEALTH_SRV(&health_srv),
            BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV, gen_onoff_op,
                      &gen_onoff_pub, NULL),
            BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_LEVEL_SRV, gen_level_op,
                      &gen_level_pub, NULL),
        };

        //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

        static struct bt_mesh_elem elements[] = {
            BT_MESH_ELEM(0, root_models, BT_MESH_MODEL_NONE),
        };

        //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

        static const struct bt_mesh_comp comp = {
            .cid = CID_INTEL,
            .elem = elements,
            .elem_count = ARRAY_SIZE(elements),
        };

        //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

        static int output_number(bt_mesh_output_action_t action, uint32_t number)
        {
            printk("OOB Number: %u\n", number);

            board_output_number(action, number);

            return 0;
        }

        static void prov_complete(u16_t net_idx, u16_t addr)
        {
            board_prov_complete();
        }

        static void prov_reset(void)
        {
            bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
        }

        static const uint8_t dev_uuid[16] = { 0xdd, 0xdd };

        static const struct bt_mesh_prov prov = {
            .uuid = dev_uuid,
            //.output_size = 4,
            //.output_actions = BT_MESH_DISPLAY_NUMBER,
            //.output_number = output_number,
            .complete = prov_complete,
            .reset = prov_reset,
        };

        static void bt_ready(int err)
        {
            if (err) {
                printk("Bluetooth init failed (err %d)\n", err);
                return;
            }

            printk("Bluetooth initialized\n");

            board_init();

            err = bt_mesh_init(&prov, &comp);
            if (err) {
                printk("Initializing mesh failed (err %d)\n", err);
                return;
            }

            bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);

            printk("Mesh initialized\n");
        }

        void main(void)
        {
            int err=0;

            NRF_P0->DIR |= 0x0001E000;
        NRF_P0->OUTSET |= 0x0001E000;

        printk("Initializing...\n");

        /* Initialize the Bluetooth Subsystem */
        err = bt_enable(bt_ready);
        if (err) {
            printk("Bluetooth init failed (err %d)\n", err);
        }
    }

Compile & flash the this example into nRF52840-PDK board.

After that we have to build BlueZ5.47 (since old version doesn't have support for bluetooth Mesh). For that use this link https://github.com/hadess/bluez

Then decompress BlueZ5.47 & cd into it.

Build using following commands

1) #./bootstrap-configure (solve error by your self by installing suggested packages)
2)make 
3)make install
4)systemctl daemon-reload
5)systemctl restart bluetooth

Then cd into bluez/mesh & execute meshctl utility. (Make sure nrf52840-pdk is ON)

Then on meshctl terminal execute following commands:

1)discover-unprovisioned on (this will return list of unprovisioned node details)
2)security 0
3)provision dddd0000000000000000000000000000 (This will return long log)
4)configure 0100
   add-appkey 1
   bind 0 1 1000
   back
5)onoff 0100  // This will turn ON & OFF led 1 on nRF52840-PDK
   onoff 0
   onoff 1

I personally feel that, Zephyr coding style is simple & easy to understand. Plus after flashing above code, we can see & provision our devices even using Silicon Lab #BluetoothMeshApp.

https://play.google.com/store/apps/de...

For more details subscribe & ask on this :

zephyr-devel@lists.zephyrproject.org zephyr-users@lists.zephyrproject.org

If any one want to add his knowledge to extend support for all developers working on #BluetoothMesh is welcome to contribute !!

Thank You!!

edit flag offensive delete publish link more

Comments

Previously I'm not able to control on board LED1 of nRF52840-PDk board using Silicon Labs #BluetoothMeshAPP. But after modifying main.c as mentioned above (I 've modified my previous answer), now I can provision + configure + control LED1 of nRF52840-PDK board.

Now I can create GROUP of multiple devices. Using "Master Control" I can turn on/off LED1, on all devices simultaneously which are part of single group.

Zephyr is in the process of launching support so that provisioning & configuration setting (along with real time mesh data) will get save into on board flash.

I wanna thanks here Mr. Johan Hedberg who is brain behind Zephyr's #BluetoothMesh stack .

https://www.youtube.com/watch?v=IC5ht...

https://www.youtube.com/watch?v=TwVwI...

vikrant8051 ( 2017-12-15 17:08:56 +0100 )editconvert to answer

Hello World !! Using this version's < https://git.kernel.org/pub/scm/blueto... > meshctl utility we can configure any type of MODEL (defined by Bluetooth_SIG + Vendor ).

vikrant8051 ( 2017-12-22 10:16:07 +0100 )editconvert to answer

Hi there, I tried to run meshctl tool with bluez-5.48 ubuntu 16.04(laptop with bluetooth adapter attached inside), it seems doesn't work well: Local config directory not provided. Waiting to connect to bluetoothd...Failed to parse local node configuration file local_node.json Do you have any idea what's wrong with it? B.R.

breaker_CHN ( 2018-01-11 07:47:27 +0100 )editconvert to answer

https://lists.zephyrproject.org/piper...

Follow these commands to build BlueZ 5.48 from scratch. You may be facing this error because #meshctl is not able to find local_node.json.

Is local_node.json available at $bluez_BASE/mesh ?

One important thing is, instead of download use,

git pull git://git.kernel.org/pub/scm/bluetooth/bluez.git

it will helpful in future to reset local_node.json & prov_db.json using following command ->

git checkout *.json
vikrant8051 ( 2018-01-11 08:14:31 +0100 )editconvert to answer

Thanks for comments. I copied *.json file from git pull git://git.kernel.org/pub/scm/bluetooth/bluez.git to bluez-5.48/mesh directory and meshctl works. Many thanks.

breaker_CHN ( 2018-01-11 08:51:08 +0100 )editconvert to answer
0
introiboad gravatar image

answered 2017-11-15 12:17:42 +0100

updated 2017-11-15 12:20:25 +0100

Hi there,

Please direct this question to the zephyr-devel or zephyr-users mailing list instead:

https://lists.zephyrproject.org/mailm...

You can also join #zephyrproject on freenode.net to get additional help.

Regards,

Carles

edit flag offensive delete publish link more
0
pgv gravatar image

answered 2017-11-17 16:18:01 +0100

You need the Silicon Labs Bluetooth Mesh app to do the provisioning. Provisioning is enabled on both PB-GATT and PB-ADV (at least in the source it is) but you need to change the dev-id for each dev kit, because it is a static one in the demo code.

edit flag offensive delete publish link more

Comments

Which demo ... from nordic mesh sdk or zephyr sdk ??

In which file dev-id is mentioned ??

Why nordic semiconductor has not provided its own utility for mesh provisioner ?

vikrant8051 ( 2017-11-17 16:28:46 +0100 )editconvert to answer

zephyr/samples/bluetooth/mesh/src/main.c line:160 The nordic stack / samples are completely unrelated to zephyr. So this forum won't help you much. I am not an employee so I have no clue.

Paul ( 2017-11-17 16:37:20 +0100 )editconvert to answer

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer. Do not ask a new question or reply to an answer here.

[hide preview]

User menu

    or sign up

Recent questions

Question Tools

1 follower

Stats

Asked: 2017-11-14 16:35:22 +0100

Seen: 666 times

Last updated: des. 15 '17