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 ∁ }
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?