/*
|
* Copyright (c) 2017 Intel Corporation
|
*
|
* SPDX-License-Identifier: Apache-2.0
|
*/
|
|
#include "nimble_syscfg.h"
|
#define MESH_LOG_MODULE BLE_MESH_MODEL_LOG
|
|
#include "mesh/mesh.h"
|
#include "mesh/model_srv.h"
|
#include "mesh_priv.h"
|
|
static struct bt_mesh_gen_onoff_srv *gen_onoff_srv;
|
static struct bt_mesh_gen_level_srv *gen_level_srv;
|
static struct bt_mesh_light_lightness_srv *light_lightness_srv;
|
|
static int gen_onoff_status(struct bt_mesh_model *model,
|
struct bt_mesh_msg_ctx *ctx)
|
{
|
int err;
|
struct bt_mesh_gen_onoff_srv *cb = model->user_data;
|
struct os_mbuf *msg = NET_BUF_SIMPLE(3);
|
uint8_t *state;
|
|
bt_mesh_model_msg_init(msg, OP_GEN_ONOFF_STATUS);
|
state = net_buf_simple_add(msg, 1);
|
if (cb && cb->get) {
|
cb->get(model, state);
|
}
|
|
BT_DBG("state: %d", *state);
|
|
err = bt_mesh_model_send(model, ctx, msg, NULL, NULL);
|
if (err) {
|
BT_ERR("Send status failed");
|
}
|
|
os_mbuf_free_chain(msg);
|
|
return err;
|
}
|
|
static int gen_onoff_get(struct bt_mesh_model *model,
|
struct bt_mesh_msg_ctx *ctx,
|
struct os_mbuf *buf)
|
{
|
BT_DBG("");
|
|
return gen_onoff_status(model, ctx);
|
}
|
|
static int gen_onoff_set_unack(struct bt_mesh_model *model,
|
struct bt_mesh_msg_ctx *ctx,
|
struct os_mbuf *buf)
|
{
|
struct bt_mesh_gen_onoff_srv *cb = model->user_data;
|
uint8_t state;
|
|
state = buf->om_data[0];
|
|
BT_DBG("state: %d", state);
|
|
if (cb && cb->set) {
|
return cb->set(model, state);
|
}
|
|
return 0;
|
}
|
|
static int gen_onoff_set(struct bt_mesh_model *model,
|
struct bt_mesh_msg_ctx *ctx,
|
struct os_mbuf *buf)
|
{
|
BT_DBG("");
|
|
gen_onoff_set_unack(model, ctx, buf);
|
return gen_onoff_status(model, ctx);
|
}
|
|
static int gen_level_status(struct bt_mesh_model *model,
|
struct bt_mesh_msg_ctx *ctx)
|
{
|
int err;
|
struct bt_mesh_gen_level_srv *cb = model->user_data;
|
struct os_mbuf *msg = NET_BUF_SIMPLE(4);
|
int16_t *level;
|
|
bt_mesh_model_msg_init(msg, OP_GEN_LEVEL_STATUS);
|
level = net_buf_simple_add(msg, 2);
|
if (cb && cb->get) {
|
cb->get(model, level);
|
}
|
|
BT_DBG("level: %d", *level);
|
|
err = bt_mesh_model_send(model, ctx, msg, NULL, NULL);
|
if (err) {
|
BT_ERR("Send status failed");
|
}
|
|
os_mbuf_free_chain(msg);
|
return err;
|
}
|
|
static int gen_level_get(struct bt_mesh_model *model,
|
struct bt_mesh_msg_ctx *ctx,
|
struct os_mbuf *buf)
|
{
|
BT_DBG("");
|
|
return gen_level_status(model, ctx);
|
}
|
|
static int gen_level_set_unack(struct bt_mesh_model *model,
|
struct bt_mesh_msg_ctx *ctx,
|
struct os_mbuf *buf) {
|
struct bt_mesh_gen_level_srv *cb = model->user_data;
|
int16_t level;
|
|
level = (int16_t) net_buf_simple_pull_le16(buf);
|
BT_DBG("level: %d", level);
|
|
if (cb && cb->set) {
|
return cb->set(model, level);
|
}
|
|
return 0;
|
}
|
|
static int gen_level_set(struct bt_mesh_model *model,
|
struct bt_mesh_msg_ctx *ctx,
|
struct os_mbuf *buf)
|
{
|
gen_level_set_unack(model, ctx, buf);
|
return gen_level_status(model, ctx);
|
}
|
|
static int light_lightness_status(struct bt_mesh_model *model,
|
struct bt_mesh_msg_ctx *ctx)
|
{
|
int err;
|
struct bt_mesh_light_lightness_srv *cb = model->user_data;
|
struct os_mbuf *msg = NET_BUF_SIMPLE(4);
|
int16_t *lightness;
|
|
bt_mesh_model_msg_init(msg, OP_LIGHT_LIGHTNESS_STATUS);
|
lightness = net_buf_simple_add(msg, 2);
|
if (cb && cb->get) {
|
cb->get(model, lightness);
|
}
|
|
BT_DBG("lightness: %d", *lightness);
|
|
err = bt_mesh_model_send(model, ctx, msg, NULL, NULL);
|
if (err) {
|
BT_ERR("Send status failed");
|
}
|
|
os_mbuf_free_chain(msg);
|
return err;
|
}
|
|
static int light_lightness_get(struct bt_mesh_model *model,
|
struct bt_mesh_msg_ctx *ctx,
|
struct os_mbuf *buf)
|
{
|
BT_DBG("");
|
|
return light_lightness_status(model, ctx);
|
}
|
|
static int light_lightness_set_unack(struct bt_mesh_model *model,
|
struct bt_mesh_msg_ctx *ctx,
|
struct os_mbuf *buf) {
|
struct bt_mesh_light_lightness_srv *cb = model->user_data;
|
int16_t lightness;
|
|
lightness = (int16_t) net_buf_simple_pull_le16(buf);
|
BT_DBG("lightness: %d", lightness);
|
|
if (cb && cb->set) {
|
return cb->set(model, lightness);
|
}
|
|
return 0;
|
}
|
|
static int light_lightness_set(struct bt_mesh_model *model,
|
struct bt_mesh_msg_ctx *ctx,
|
struct os_mbuf *buf)
|
{
|
light_lightness_set_unack(model, ctx, buf);
|
return light_lightness_status(model, ctx);
|
}
|
|
const struct bt_mesh_model_op gen_onoff_srv_op[] = {
|
{ OP_GEN_ONOFF_GET, 0, gen_onoff_get },
|
{ OP_GEN_ONOFF_SET, 2, gen_onoff_set },
|
{ OP_GEN_ONOFF_SET_UNACK, 2, gen_onoff_set_unack },
|
BT_MESH_MODEL_OP_END,
|
};
|
|
const struct bt_mesh_model_op gen_level_srv_op[] = {
|
{ OP_GEN_LEVEL_GET, 0, gen_level_get },
|
{ OP_GEN_LEVEL_SET, 3, gen_level_set },
|
{ OP_GEN_LEVEL_SET_UNACK, 3, gen_level_set_unack },
|
BT_MESH_MODEL_OP_END,
|
};
|
|
const struct bt_mesh_model_op light_lightness_srv_op[] = {
|
{ OP_LIGHT_LIGHTNESS_GET, 0, light_lightness_get },
|
{ OP_LIGHT_LIGHTNESS_SET, 3, light_lightness_set },
|
{ OP_LIGHT_LIGHTNESS_SET_UNACK, 3, light_lightness_set_unack },
|
BT_MESH_MODEL_OP_END,
|
};
|
|
static int onoff_srv_init(struct bt_mesh_model *model)
|
{
|
struct bt_mesh_gen_onoff_srv *cfg = model->user_data;
|
|
BT_DBG("");
|
|
if (!cfg) {
|
BT_ERR("No Generic OnOff Server context provided");
|
return -EINVAL;
|
}
|
|
cfg->model = model;
|
|
gen_onoff_srv = cfg;
|
|
return 0;
|
}
|
|
const struct bt_mesh_model_cb gen_onoff_srv_cb = {
|
.init = onoff_srv_init,
|
};
|
|
static int level_srv_init(struct bt_mesh_model *model)
|
{
|
struct bt_mesh_gen_level_srv *cfg = model->user_data;
|
|
BT_DBG("");
|
|
if (!cfg) {
|
BT_ERR("No Generic Level Server context provided");
|
return -EINVAL;
|
}
|
|
cfg->model = model;
|
|
gen_level_srv = cfg;
|
|
return 0;
|
}
|
|
const struct bt_mesh_model_cb gen_level_srv_cb = {
|
.init = level_srv_init,
|
};
|
|
static int lightness_srv_init(struct bt_mesh_model *model)
|
{
|
struct bt_mesh_light_lightness_srv *cfg = model->user_data;
|
|
BT_DBG("");
|
|
if (!cfg) {
|
BT_ERR("No Light Lightness Server context provided");
|
return -EINVAL;
|
}
|
|
cfg->model = model;
|
|
light_lightness_srv = cfg;
|
|
return 0;
|
}
|
|
const struct bt_mesh_model_cb light_lightness_srv_cb = {
|
.init = lightness_srv_init,
|
};
|