Stuck at creating a basic Vendor Model in BT-Mesh

Hi,
I have followed the Chat Sample Walkthough, Vendor Model Development Overview and other examples from different vendors using zephyr, but I'm getting stuck at the following point:

In the model_handler at  bt_mesh_elem list I add my vendor model with callbacks:

static struct bt_mesh_elem elements[] = {
	BT_MESH_ELEM(
		1,
		BT_MESH_MODEL_LIST(
			BT_MESH_MODEL_CFG_SRV,
			BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub)),
		BT_MESH_MODEL_LIST(
			BT_MESH_MODEL_VND_CB(BT_MESH_VIBE_SERVER_VENDOR_COMPANY_ID,       \
				BT_MESH_VIBE_SERVER_VENDOR_MODEL_ID,                      \
				vibe_server_opcode_list, \
				NULL,                   \
				NULL, \
				&vibe_server_cb)
		)),
};

I have added init, start and reset functions in my vendor model with log outputs, but those never get called. I trimmed down the chat sample a lot and had to create the server vendor model (since the chat model doesn't really show a server approach), but I think I may have done something incorrectly or missed a step.

custom vendor model header:

#ifndef VIBE_SERVER_H
#define VIBE_SERVER_H

#include <zephyr/bluetooth/mesh.h>

// Company ID is Nordic
#define BT_MESH_VIBE_SERVER_VENDOR_COMPANY_ID 0x0059
#define BT_MESH_VIBE_SERVER_VENDOR_MODEL_ID 0x0020

// OPCodes for the Vibe Server
#define BT_MESH_VIBE_SERVER_OP_STOP BT_MESH_MODEL_OP_3(0x20, BT_MESH_VIBE_SERVER_VENDOR_COMPANY_ID)

// Vibe Server Model
extern struct bt_mesh_model vibe_server;

// Handlers
void handler_vibe_sever_stop(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf);

// Callbacks
void vibe_server_init(struct bt_mesh_model *model);
void vibe_server_start(struct bt_mesh_model *model);
void vibe_server_reset(struct bt_mesh_model *model);

// OPCode List for the Model
static struct bt_mesh_model_op vibe_server_opcode_list[];

// Callback Struct
static struct bt_mesh_model_cb vibe_server_cb;

#endif /*VIBE_SERVER_H*/

custom vendor model source:

#include <zephyr/bluetooth/mesh.h>
#include "vibe_server.h"
#include "mesh/net.h"
#include <string.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(vibe_server, 3);

/* ============================
*  Vibe Server Handler Functions
*/ 
void handler_vibe_server_stop(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf){
    printk("vibe_stop");
};

/* ============================
 * Vibe Server Callbacks
*/
// Init Callback. It is called when the model is initialized.
void vibe_server_init(struct bt_mesh_model *model){
    LOG_INF("Vibe Server Init!\n");
};

// Start Callback
void vibe_server_start(struct bt_mesh_model *model){
    LOG_INF("Vibe Server Start!\n");
};

// Reset Callback.
void vibe_server_reset(struct bt_mesh_model *model){
    LOG_INF("Vibe Server Reset!\n");
};

/* ============================
 * Vibe Server Model
*/
struct bt_mesh_model vibe_server = {
    .id = BT_MESH_VIBE_SERVER_VENDOR_MODEL_ID,
    .op = vibe_server_opcode_list,
    .cb = &vibe_server_cb,
};

/* ============================
 * Vibe Server Model Entries
*/
// OPCodes Struct.
static struct bt_mesh_model_op vibe_server_opcode_list[] = {
    {BT_MESH_VIBE_SERVER_OP_STOP,
    BT_MESH_LEN_MIN(0),
    handler_vibe_server_stop},
    BT_MESH_MODEL_OP_END
};

// Callback Functions Struct
static struct bt_mesh_model_cb vibe_server_cb = {
	.init = vibe_server_init,
	.start = vibe_server_start,
	.reset = vibe_server_reset,
};

model_handler:

#include <stdio.h>

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

#include "model_handler.h"
#include "vibe_server.h"

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(model_handler, 3);

/******************************************************************************/
/*************************** Health server setup ******************************/
/******************************************************************************/
/* Set up a repeating delayed work to blink the DK's LEDs when attention is
 * requested.
 */
static struct k_work_delayable attention_blink_work;
static bool attention;

static void attention_blink(struct k_work *work)
{
	//static int idx;
	//const uint8_t pattern[] = {
	//	BIT(0) | BIT(1),
	//	BIT(1) | BIT(2),
	//	BIT(2) | BIT(3),
	//	BIT(3) | BIT(0),
	//};

	//if (attention) {
	//	dk_set_leds(pattern[idx++ % ARRAY_SIZE(pattern)]);
	//	k_work_reschedule(&attention_blink_work, K_MSEC(30));
	//} else {
	//	dk_set_leds(DK_NO_LEDS_MSK);
	//}
}

static void attention_on(struct bt_mesh_model *mod)
{
	attention = true;
	k_work_reschedule(&attention_blink_work, K_NO_WAIT);
}

static void attention_off(struct bt_mesh_model *mod)
{
	/* Will stop rescheduling blink timer */
	attention = false;
}

static const struct bt_mesh_health_srv_cb health_srv_cb = {
	.attn_on = attention_on,
	.attn_off = attention_off,
};

static struct bt_mesh_health_srv health_srv = {
	.cb = &health_srv_cb,
};

BT_MESH_HEALTH_PUB_DEFINE(health_pub, 0);

/******************************************************************************/
/******************************** Vibe Server *********************************/
/******************************************************************************/
static struct bt_mesh_elem elements[] = {
	BT_MESH_ELEM(
		1,
		BT_MESH_MODEL_LIST(
			BT_MESH_MODEL_CFG_SRV,
			BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub)),
		BT_MESH_MODEL_LIST(
			BT_MESH_MODEL_VND_CB(BT_MESH_VIBE_SERVER_VENDOR_COMPANY_ID,       \
				BT_MESH_VIBE_SERVER_VENDOR_MODEL_ID,                      \
				vibe_server_opcode_list, \
				NULL,                   \
				NULL, \
				&vibe_server_cb)
		)),
};

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

/******************************************************************************/
/******************************** Public API **********************************/
/******************************************************************************/
const struct bt_mesh_comp *model_handler_init(void)
{
	k_work_init_delayable(&attention_blink_work, attention_blink);

	return &comp;
}

Is my approach to the custom vendor model doable or should I follow more strictly the chat sample with it's chat_cli struct and function pointers?

Parents
  • Hi,

    Apologies for delayed response time. From what I can see according to the links you've provided it looks like you're on the right path. I'm currently in and out of office until next week, but I will try to get a closer look at the case then. In the meanwhile, could you provide me with any device logs while running and could you also verify if the device gets stuck anywhere or if the functions you were expecting to see called getting called or not? In addition if you could keep comparing your changes with the Mesh chat sample to see whats missing?

    There is also the webinars based on the documentation you refer to (albeit with an older SDK version) that you may find on our webinar portal as well as on YouTube: https://www.youtube.com/@NordicSemi starting with https://www.youtube.com/watch?v=Jt2ui22fBjM that you might find helpful if you've not already seen them

    Kind regards,
    Andreas

Reply
  • Hi,

    Apologies for delayed response time. From what I can see according to the links you've provided it looks like you're on the right path. I'm currently in and out of office until next week, but I will try to get a closer look at the case then. In the meanwhile, could you provide me with any device logs while running and could you also verify if the device gets stuck anywhere or if the functions you were expecting to see called getting called or not? In addition if you could keep comparing your changes with the Mesh chat sample to see whats missing?

    There is also the webinars based on the documentation you refer to (albeit with an older SDK version) that you may find on our webinar portal as well as on YouTube: https://www.youtube.com/@NordicSemi starting with https://www.youtube.com/watch?v=Jt2ui22fBjM that you might find helpful if you've not already seen them

    Kind regards,
    Andreas

Children
No Data
Related