Fork ESP-IDF's bluetooth component

i want better sbc encoding, and no cla will stop me
This commit is contained in:
jacqueline
2024-03-28 14:32:49 +11:00
parent 239e6d8950
commit ee29c25b29
1761 changed files with 737738 additions and 0 deletions
@@ -0,0 +1,492 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <errno.h>
#include "mesh.h"
#include "mesh/main.h"
#include "transport.h"
#include "foundation.h"
#include "mesh/client_common.h"
#include "mesh/common.h"
#include "mesh_v1.1/utils.h"
#define HCI_TIME_FOR_START_ADV K_MSEC(5) /* Three adv related hci commands may take 4 ~ 5ms */
static bt_mesh_client_node_t *bt_mesh_client_pick_node(sys_slist_t *list, uint16_t tx_dst)
{
bt_mesh_client_node_t *node = NULL;
sys_snode_t *cur = NULL;
bt_mesh_list_lock();
if (sys_slist_is_empty(list)) {
bt_mesh_list_unlock();
return NULL;
}
for (cur = sys_slist_peek_head(list);
cur != NULL; cur = sys_slist_peek_next(cur)) {
node = (bt_mesh_client_node_t *)cur;
if (node->ctx.addr == tx_dst) {
bt_mesh_list_unlock();
return node;
}
}
bt_mesh_list_unlock();
return NULL;
}
bt_mesh_client_node_t *bt_mesh_is_client_recv_publish_msg(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf, bool need_pub)
{
bt_mesh_client_internal_data_t *data = NULL;
bt_mesh_client_user_data_t *cli = NULL;
bt_mesh_client_node_t *node = NULL;
if (!model || !ctx || !buf) {
BT_ERR("%s, Invalid parameter", __func__);
return NULL;
}
cli = (bt_mesh_client_user_data_t *)model->user_data;
if (!cli) {
BT_ERR("Invalid client user data");
return NULL;
}
/** If the received message address is not a unicast address,
* the address may be a group/virtual address, and we push
* this message to the application layer.
*/
if (!BLE_MESH_ADDR_IS_UNICAST(ctx->recv_dst)) {
BT_DBG("Unexpected status message 0x%08x", ctx->recv_op);
if (cli->publish_status && need_pub) {
cli->publish_status(ctx->recv_op, model, ctx, buf);
}
return NULL;
}
/** If the source address of the received status message is
* different with the destination address of the sending
* message, then the message is from another element and
* push it to application layer.
*/
data = (bt_mesh_client_internal_data_t *)cli->internal_data;
if (!data) {
BT_ERR("Invalid client internal data");
return NULL;
}
if ((node = bt_mesh_client_pick_node(&data->queue, ctx->addr)) == NULL) {
BT_DBG("Unexpected status message 0x%08x", ctx->recv_op);
if (cli->publish_status && need_pub) {
cli->publish_status(ctx->recv_op, model, ctx, buf);
}
return NULL;
}
if (node->op_pending != ctx->recv_op) {
BT_DBG("Unexpected status message 0x%08x", ctx->recv_op);
if (cli->publish_status && need_pub) {
cli->publish_status(ctx->recv_op, model, ctx, buf);
}
return NULL;
}
if (k_delayed_work_remaining_get(&node->timer) == 0) {
BT_DBG("Unexpected status message 0x%08x", ctx->recv_op);
if (cli->publish_status && need_pub) {
cli->publish_status(ctx->recv_op, model, ctx, buf);
}
return NULL;
}
return node;
}
static bool bt_mesh_client_check_node_in_list(sys_slist_t *list, uint16_t tx_dst)
{
bt_mesh_client_node_t *node = NULL;
sys_snode_t *cur = NULL;
bt_mesh_list_lock();
if (sys_slist_is_empty(list)) {
bt_mesh_list_unlock();
return false;
}
for (cur = sys_slist_peek_head(list);
cur != NULL; cur = sys_slist_peek_next(cur)) {
node = (bt_mesh_client_node_t *)cur;
if (node->ctx.addr == tx_dst) {
bt_mesh_list_unlock();
return true;
}
}
bt_mesh_list_unlock();
return false;
}
static uint32_t bt_mesh_client_get_status_op(const bt_mesh_client_op_pair_t *op_pair,
int size, uint32_t opcode)
{
if (!op_pair || size == 0) {
return 0;
}
const bt_mesh_client_op_pair_t *op = op_pair;
for (int i = 0; i < size; i++) {
if (op->cli_op == opcode) {
return op->status_op;
}
op++;
}
return 0;
}
static int32_t bt_mesh_get_adv_duration(struct bt_mesh_msg_ctx *ctx)
{
uint16_t duration = 0, adv_int = 0;
uint8_t xmit = 0;
/* Initialize with network transmission */
xmit = bt_mesh_net_transmit_get();
if (bt_mesh_tag_immutable_cred(ctx->send_tag)) {
#if CONFIG_BLE_MESH_DF_SRV
if (ctx->send_cred == BLE_MESH_DIRECTED_CRED) {
xmit = bt_mesh_direct_net_transmit_get(); /* Directed network transmission */
}
#endif
}
adv_int = BLE_MESH_TRANSMIT_INT(xmit);
duration = (BLE_MESH_TRANSMIT_COUNT(xmit) + 1) * (adv_int + 10);
return (int32_t)duration;
}
static int32_t bt_mesh_client_calc_timeout(struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *msg,
uint32_t opcode, int32_t timeout)
{
int32_t seg_rtx_to = 0, duration = 0, time = 0;
uint8_t seg_count = 0, seg_rtx_num = 0;
bool need_seg = false;
uint8_t mic_size = 0;
if (msg->len > BLE_MESH_SDU_UNSEG_MAX ||
bt_mesh_tag_send_segmented(ctx->send_tag)) {
need_seg = true; /* Needs segmentation */
}
mic_size = (need_seg && ctx->send_szmic == BLE_MESH_SEG_SZMIC_LONG &&
net_buf_simple_tailroom(msg) >= BLE_MESH_MIC_LONG) ?
BLE_MESH_MIC_LONG : BLE_MESH_MIC_SHORT;
if (need_seg) {
/* Based on the message length, calculate how many segments are needed.
* All the messages sent from here are access messages.
*/
seg_rtx_num = bt_mesh_get_seg_rtx_num();
seg_rtx_to = bt_mesh_get_seg_rtx_timeout(ctx->addr, ctx->send_ttl);
seg_count = (msg->len + mic_size - 1) / 12U + 1U;
duration = bt_mesh_get_adv_duration(ctx);
/* Currently only consider the time consumption of the same segmented
* messages, but if there are other messages between any two retrans-
* missions of the same segmented messages, then the whole time will
* be longer.
*
* Since the transport behavior has been changed, i.e. start retransmit
* timer after the last segment is sent, so we can simplify the timeout
* calculation here. And the retransmit timer will be started event if
* the attempts reaches ZERO when the dst is a unicast address.
*/
int32_t seg_duration = seg_count * (duration + HCI_TIME_FOR_START_ADV);
time = (seg_duration + seg_rtx_to) * seg_rtx_num;
BT_INFO("Original timeout %dms, calculated timeout %dms", timeout, time);
if (time < timeout) {
/* If the calculated time is smaller than the input timeout value,
* then use the original timeout value.
*/
time = timeout;
}
} else {
/* For unsegmented access messages, directly use the timeout
* value from the application layer.
*/
time = timeout;
}
BT_INFO("Client message 0x%08x with timeout %dms", opcode, time);
return time;
}
static void msg_send_start(uint16_t duration, int err, void *cb_data)
{
bt_mesh_client_node_t *node = cb_data;
BT_DBG("%s, duration %ums", __func__, duration);
if (err) {
if (!k_delayed_work_free(&node->timer)) {
bt_mesh_client_free_node(node);
}
return;
}
k_delayed_work_submit(&node->timer, node->timeout);
}
static const struct bt_mesh_send_cb send_cb = {
.start = msg_send_start,
.end = NULL,
};
int bt_mesh_client_send_msg(bt_mesh_client_common_param_t *param,
struct net_buf_simple *msg, bool need_ack,
k_work_handler_t timer_handler)
{
bt_mesh_client_internal_data_t *internal = NULL;
bt_mesh_client_user_data_t *client = NULL;
bt_mesh_client_node_t *node = NULL;
int err = 0;
if (!param || !param->model || !msg) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
client = (bt_mesh_client_user_data_t *)param->model->user_data;
if (!client) {
BT_ERR("Invalid client user data");
return -EINVAL;
}
internal = (bt_mesh_client_internal_data_t *)client->internal_data;
if (!internal) {
BT_ERR("Invalid client internal data");
return -EINVAL;
}
if (param->ctx.addr == BLE_MESH_ADDR_UNASSIGNED) {
BT_ERR("Invalid DST 0x%04x", param->ctx.addr);
return -EINVAL;
}
if (need_ack == false || !BLE_MESH_ADDR_IS_UNICAST(param->ctx.addr)) {
/* 1. If this is an unacknowledged message, send it directly.
* 2. If this is an acknowledged message, but the destination
* is not a unicast address, e.g. a group/virtual address,
* then all the corresponding responses will be treated as
* publish messages, and no timeout will be used.
*/
err = bt_mesh_model_send(param->model, &param->ctx, msg, param->cb, param->cb_data);
if (err) {
BT_ERR("Failed to send client message 0x%08x", param->opcode);
}
return err;
}
if (!timer_handler) {
BT_ERR("Invalid timeout handler");
return -EINVAL;
}
if (bt_mesh_client_check_node_in_list(&internal->queue, param->ctx.addr)) {
BT_ERR("Busy sending message to DST 0x%04x", param->ctx.addr);
return -EBUSY;
}
/* Don't forget to free the node in the timeout (timer_handler) function. */
node = (bt_mesh_client_node_t *)bt_mesh_calloc(sizeof(bt_mesh_client_node_t));
if (!node) {
BT_ERR("%s, Out of memory", __func__);
return -ENOMEM;
}
memcpy(&node->ctx, &param->ctx, sizeof(struct bt_mesh_msg_ctx));
node->model = param->model;
node->opcode = param->opcode;
node->op_pending = bt_mesh_client_get_status_op(client->op_pair, client->op_pair_size, param->opcode);
if (node->op_pending == 0U) {
BT_ERR("Status opcode not found in op_pair list, opcode 0x%08x", param->opcode);
bt_mesh_free(node);
return -EINVAL;
}
node->timeout = bt_mesh_client_calc_timeout(&param->ctx, msg, param->opcode,
param->msg_timeout ? param->msg_timeout : CONFIG_BLE_MESH_CLIENT_MSG_TIMEOUT);
if (k_delayed_work_init(&node->timer, timer_handler)) {
BT_ERR("Failed to create a timer");
bt_mesh_free(node);
return -EIO;
}
bt_mesh_list_lock();
sys_slist_append(&internal->queue, &node->client_node);
bt_mesh_list_unlock();
/* "bt_mesh_model_send" will post the mesh packet to the mesh adv queue.
* Due to the higher priority of adv_thread (than btc task), we need to
* send the packet after the list item "node" is initialized properly.
*/
err = bt_mesh_model_send(param->model, &param->ctx, msg, &send_cb, node);
if (err) {
BT_ERR("Failed to send client message 0x%08x", node->opcode);
k_delayed_work_free(&node->timer);
bt_mesh_client_free_node(node);
}
return err;
}
static bt_mesh_mutex_t client_model_lock;
void bt_mesh_client_model_lock(void)
{
bt_mesh_mutex_lock(&client_model_lock);
}
void bt_mesh_client_model_unlock(void)
{
bt_mesh_mutex_unlock(&client_model_lock);
}
int bt_mesh_client_init(struct bt_mesh_model *model)
{
bt_mesh_client_internal_data_t *internal = NULL;
bt_mesh_client_user_data_t *client = NULL;
if (!model || !model->op) {
BT_ERR("Invalid vendor client model");
return -EINVAL;
}
client = (bt_mesh_client_user_data_t *)model->user_data;
if (!client) {
BT_ERR("No vendor client context provided");
return -EINVAL;
}
if (client->internal_data) {
BT_WARN("%s, Already", __func__);
return -EALREADY;
}
internal = bt_mesh_calloc(sizeof(bt_mesh_client_internal_data_t));
if (!internal) {
BT_ERR("%s, Out of memory", __func__);
return -ENOMEM;
}
sys_slist_init(&internal->queue);
client->model = model;
client->internal_data = internal;
bt_mesh_mutex_create(&client_model_lock);
return 0;
}
#if CONFIG_BLE_MESH_DEINIT
int bt_mesh_client_deinit(struct bt_mesh_model *model)
{
bt_mesh_client_user_data_t *client = NULL;
if (!model) {
BT_ERR("Invalid vendor client model");
return -EINVAL;
}
client = (bt_mesh_client_user_data_t *)model->user_data;
if (!client) {
BT_ERR("No vendor client context provided");
return -EINVAL;
}
if (client->internal_data) {
/* Remove items from the list */
bt_mesh_client_clear_list(client->internal_data);
/* Free the allocated internal data */
bt_mesh_free(client->internal_data);
client->internal_data = NULL;
}
bt_mesh_mutex_free(&client_model_lock);
return 0;
}
#endif /* CONFIG_BLE_MESH_DEINIT */
int bt_mesh_client_free_node(bt_mesh_client_node_t *node)
{
bt_mesh_client_internal_data_t *internal = NULL;
bt_mesh_client_user_data_t *client = NULL;
if (!node || !node->model) {
BT_ERR("Invalid client list item");
return -EINVAL;
}
client = (bt_mesh_client_user_data_t *)node->model->user_data;
if (!client) {
BT_ERR("Invalid client user data");
return -EINVAL;
}
internal = (bt_mesh_client_internal_data_t *)client->internal_data;
if (!internal) {
BT_ERR("Invalid client internal data");
return -EINVAL;
}
// Release the client node from the queue
bt_mesh_list_lock();
sys_slist_find_and_remove(&internal->queue, &node->client_node);
bt_mesh_list_unlock();
// Free the node
bt_mesh_free(node);
return 0;
}
int bt_mesh_client_clear_list(void *data)
{
bt_mesh_client_internal_data_t *internal = NULL;
bt_mesh_client_node_t *node = NULL;
if (!data) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
internal = (bt_mesh_client_internal_data_t *)data;
bt_mesh_list_lock();
while (!sys_slist_is_empty(&internal->queue)) {
node = (void *)sys_slist_get_not_empty(&internal->queue);
k_delayed_work_free(&node->timer);
bt_mesh_free(node);
}
bt_mesh_list_unlock();
return 0;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,119 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _CLIENT_COMMON_H_
#define _CLIENT_COMMON_H_
#include "mesh/access.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Client model opcode pair table */
typedef struct {
uint32_t cli_op; /* Client message opcode */
uint32_t status_op; /* Corresponding status message opcode */
} bt_mesh_client_op_pair_t;
/** Client model user data context */
typedef struct {
/** Pointer to the client model */
struct bt_mesh_model *model;
/** Size of the opcode pair table */
uint32_t op_pair_size;
/** Pointer to the opcode pair table */
const bt_mesh_client_op_pair_t *op_pair;
/**
* @brief This function is a callback function used to push the received unsolicited
* messages to the application layer.
*
* @param[in] opcode: Opcode of received status message
* @param[in] model: Model associated with the status message
* @param[in] ctx: Context information of the status message
* @param[in] buf: Buffer contains the status message value
*
* @return None
*/
void (*publish_status)(uint32_t opcode, struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf);
/** Pointer to the internal data of client model */
void *internal_data;
/** Pointer to the vendor data of client model */
void *vendor_data;
/** Role of the device to which the client model belongs */
uint8_t msg_role __attribute__((deprecated));
} bt_mesh_client_user_data_t;
/** Client model internal data context */
typedef struct {
sys_slist_t queue;
} bt_mesh_client_internal_data_t;
/** Client model sending message related context */
typedef struct {
sys_snode_t client_node;
struct bt_mesh_model *model; /* Pointer to the client model */
struct bt_mesh_msg_ctx ctx; /* Message context */
uint32_t opcode; /* Message opcode */
uint32_t op_pending; /* Expected status message opcode */
int32_t timeout; /* Calculated message timeout value */
struct k_delayed_work timer; /* Time used to get response. Only for internal use. */
} bt_mesh_client_node_t;
/** Client model sending message parameters */
typedef struct {
uint32_t opcode; /* Message opcode */
struct bt_mesh_model *model; /* Pointer to the client model */
struct bt_mesh_msg_ctx ctx; /* Message context */
int32_t msg_timeout; /* Time to get corresponding response */
uint8_t msg_role __attribute__((deprecated)); /* Role (Node/Provisioner) of the device */
const struct bt_mesh_send_cb *cb; /* User defined callback function */
void *cb_data; /* User defined callback value */
} bt_mesh_client_common_param_t;
void bt_mesh_client_model_lock(void);
void bt_mesh_client_model_unlock(void);
int bt_mesh_client_init(struct bt_mesh_model *model);
int bt_mesh_client_deinit(struct bt_mesh_model *model);
/**
* @brief Check if the msg received by client model is a publish msg or not
*
* @param model Mesh (client) Model that the message belongs to.
* @param ctx Message context, includes keys, TTL, etc.
* @param buf The message buffer
* @param need_pub Indicate if the msg sent to app layer as a publish msg
* @return 0 on success, or (negative) error code on failure.
*/
bt_mesh_client_node_t *bt_mesh_is_client_recv_publish_msg(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf,
bool need_pub);
int bt_mesh_client_send_msg(bt_mesh_client_common_param_t *param,
struct net_buf_simple *msg, bool need_ack,
k_work_handler_t timer_handler);
int bt_mesh_client_free_node(bt_mesh_client_node_t *node);
int bt_mesh_client_clear_list(void *data);
#ifdef __cplusplus
}
#endif
#endif /* _CLIENT_COMMON_H_ */
@@ -0,0 +1,408 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/** @file
* @brief Bluetooth Mesh Generic Client Model APIs.
*/
#ifndef _GENERIC_CLIENT_H_
#define _GENERIC_CLIENT_H_
#include "mesh/client_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Generic client model common structure */
typedef bt_mesh_client_user_data_t bt_mesh_generic_client_t;
typedef bt_mesh_client_internal_data_t generic_internal_data_t;
/* Generic Client Model Callback */
extern const struct bt_mesh_model_cb bt_mesh_generic_client_cb;
/* Generic OnOff Client Model Context */
extern const struct bt_mesh_model_op bt_mesh_gen_onoff_cli_op[];
/** @def BLE_MESH_MODEL_GEN_ONOFF_CLI
*
* Define a new generic onoff client model. Note that this API
* needs to be repeated for each element which the application
* wants to have a generic onoff client model on.
* @param cli_pub Pointer to a unique struct bt_mesh_model_pub.
* @param cli_data Pointer to a unique struct bt_mesh_gen_onoff_cli.
*
* @return New generic onoff client model instance.
*/
#define BLE_MESH_MODEL_GEN_ONOFF_CLI(cli_pub, cli_data) \
BLE_MESH_MODEL_CB(BLE_MESH_MODEL_ID_GEN_ONOFF_CLI, \
bt_mesh_gen_onoff_cli_op, cli_pub, cli_data, &bt_mesh_generic_client_cb)
typedef bt_mesh_client_user_data_t bt_mesh_gen_onoff_client_t;
struct bt_mesh_gen_onoff_status {
bool op_en; /* Indicate whether optional parameters included */
uint8_t present_onoff; /* Present value of Generic OnOff state */
uint8_t target_onoff; /* Target value of Generic OnOff state (optional) */
uint8_t remain_time; /* Time to complete state transition (C.1) */
};
struct bt_mesh_gen_onoff_set {
bool op_en; /* Indicate whether optional parameters included */
uint8_t onoff; /* Target value of Generic OnOff state */
uint8_t tid; /* Transaction Identifier */
uint8_t trans_time; /* Time to complete state transition (optional) */
uint8_t delay; /* Indicate message execution delay (C.1) */
};
/* Generic Level Client Model Context */
extern const struct bt_mesh_model_op bt_mesh_gen_level_cli_op[];
/** @def BLE_MESH_MODEL_GEN_LEVEL_CLI
*
* Define a new generic level client model. Note that this API
* needs to be repeated for each element which the application
* wants to have a generic level client model on.
* @param cli_pub Pointer to a unique struct bt_mesh_model_pub.
* @param cli_data Pointer to a unique struct bt_mesh_gen_level_cli.
*
* @return New generic level client model instance.
*/
#define BLE_MESH_MODEL_GEN_LEVEL_CLI(cli_pub, cli_data) \
BLE_MESH_MODEL_CB(BLE_MESH_MODEL_ID_GEN_LEVEL_CLI, \
bt_mesh_gen_level_cli_op, cli_pub, cli_data, &bt_mesh_generic_client_cb)
typedef bt_mesh_client_user_data_t bt_mesh_gen_level_client_t;
struct bt_mesh_gen_level_status {
bool op_en; /* Indicate whether optional parameters included */
int16_t present_level; /* Present value of Generic Level state */
int16_t target_level; /* Target value of the Generic Level state (optional) */
uint8_t remain_time; /* Time to complete state transition (C.1) */
};
struct bt_mesh_gen_level_set {
bool op_en; /* Indicate whether optional parameters included */
int16_t level; /* Target value of Generic Level state */
uint8_t tid; /* Transaction Identifier */
uint8_t trans_time; /* Time to complete state transition (optional) */
uint8_t delay; /* Indicate message execution delay (C.1) */
};
struct bt_mesh_gen_delta_set {
bool op_en; /* Indicate whether optional parameters included */
int32_t delta_level; /* Delta change of Generic Level state */
uint8_t tid; /* Transaction Identifier */
uint8_t trans_time; /* Time to complete state transition (optional) */
uint8_t delay; /* Indicate message execution delay (C.1) */
};
struct bt_mesh_gen_move_set {
bool op_en; /* Indicate whether optional parameters included */
int16_t delta_level; /* Delta Level step to calculate Move speed for Generic Level state */
uint8_t tid; /* Transaction Identifier */
uint8_t trans_time; /* Time to complete state transition (optional) */
uint8_t delay; /* Indicate message execution delay (C.1) */
};
/* Generic Default Transition Time Client Model Context */
extern const struct bt_mesh_model_op bt_mesh_gen_def_trans_time_cli_op[];
/** @def BLE_MESH_MODEL_GEN_DEF_TRANS_TIME_CLI
*
* Define a new generic default transition time client model. Note
* that this API needs to be repeated for each element that the
* application wants to have a generic default transition client
* model on.
* @param cli_pub Pointer to a unique struct bt_mesh_model_pub.
* @param cli_data Pointer to a unique struct bt_mesh_gen_def_trans_time_cli.
*
* @return New generic default transition time client model instance.
*/
#define BLE_MESH_MODEL_GEN_DEF_TRANS_TIME_CLI(cli_pub, cli_data) \
BLE_MESH_MODEL_CB(BLE_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_CLI, \
bt_mesh_gen_def_trans_time_cli_op, cli_pub, cli_data, &bt_mesh_generic_client_cb)
typedef bt_mesh_client_user_data_t bt_mesh_gen_def_trans_time_client_t;
struct bt_mesh_gen_def_trans_time_set {
uint8_t trans_time; /* The value of the Generic Default Transition Time state */
};
struct bt_mesh_gen_def_trans_time_status {
uint8_t trans_time; /* The value of the Generic Default Transition Time state */
};
/* Generic Power OnOff Client Model Context */
extern const struct bt_mesh_model_op bt_mesh_gen_power_onoff_cli_op[];
/** @def BLE_MESH_MODEL_GEN_POWER_ONOFF_CLI
*
* Define a new generic power onoff client model. Note that this API
* needs to be repeated for each element which the application wants
* to have a generic power onoff client model on.
* @param cli_pub Pointer to a unique struct bt_mesh_model_pub.
* @param cli_data Pointer to a unique struct bt_mesh_gen_power_onoff_cli.
*
* @return New generic power onoff client model instance.
*/
#define BLE_MESH_MODEL_GEN_POWER_ONOFF_CLI(cli_pub, cli_data) \
BLE_MESH_MODEL_CB(BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_CLI, \
bt_mesh_gen_power_onoff_cli_op, cli_pub, cli_data, &bt_mesh_generic_client_cb)
typedef bt_mesh_client_user_data_t bt_mesh_gen_power_onoff_client_t;
struct bt_mesh_gen_onpowerup_set {
uint8_t onpowerup; /* The value of the Generic OnPowerUp state */
};
struct bt_mesh_gen_onpowerup_status {
uint8_t onpowerup; /* The value of the Generic OnPowerUp state */
};
/* Generic Power Level Client Model Context */
extern const struct bt_mesh_model_op bt_mesh_gen_power_level_cli_op[];
/** @def BLE_MESH_MODEL_GEN_POWER_LEVEL_CLI
*
* Define a new generic power level client model. Note that this API
* needs to be repeated for each element which the application wants
* to have a generic power level client model on.
* @param cli_pub Pointer to a unique struct bt_mesh_model_pub.
* @param cli_data Pointer to a unique struct bt_mesh_gen_power_level_cli.
*
* @return New generic power level client model instance.
*/
#define BLE_MESH_MODEL_GEN_POWER_LEVEL_CLI(cli_pub, cli_data) \
BLE_MESH_MODEL_CB(BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_CLI, \
bt_mesh_gen_power_level_cli_op, cli_pub, cli_data, &bt_mesh_generic_client_cb)
typedef bt_mesh_client_user_data_t bt_mesh_gen_power_level_client_t;
struct bt_mesh_gen_power_level_status {
bool op_en; /* Indicate whether optional parameters included */
uint16_t present_power; /* Present value of Generic Power Actual state */
uint16_t target_power; /* Target value of Generic Power Actual state (optional) */
uint8_t remain_time; /* Time to complete state transition (C.1) */
};
struct bt_mesh_gen_power_last_status {
uint16_t power; /* The value of the Generic Power Last state */
};
struct bt_mesh_gen_power_default_status {
uint16_t power; /* The value of the Generic Default Last state */
};
struct bt_mesh_gen_power_range_status {
uint8_t status_code; /* Status Code for the requesting message */
uint16_t range_min; /* Value of Range Min field of Generic Power Range state */
uint16_t range_max; /* Value of Range Max field of Generic Power Range state */
};
struct bt_mesh_gen_power_level_set {
bool op_en; /* Indicate whether optional parameters included */
uint16_t power; /* Target value of Generic Power Actual state */
uint8_t tid; /* Transaction Identifier */
uint8_t trans_time; /* Time to complete state transition (optional) */
uint8_t delay; /* Indicate message execution delay (C.1) */
};
struct bt_mesh_gen_power_default_set {
uint16_t power; /* The value of the Generic Power Default state */
};
struct bt_mesh_gen_power_range_set {
uint16_t range_min; /* Value of Range Min field of Generic Power Range state */
uint16_t range_max; /* Value of Range Max field of Generic Power Range state */
};
/* Generic Battery Client Model Context */
extern const struct bt_mesh_model_op bt_mesh_gen_battery_cli_op[];
/** @def BLE_MESH_MODEL_GEN_BATTERY_CLI
*
* Define a new generic battery client model. Note that this API
* needs to be repeated for each element which the application
* wants to have a generic battery client model on.
* @param cli_pub Pointer to a unique struct bt_mesh_model_pub.
* @param cli_data Pointer to a unique struct bt_mesh_gen_battery_cli.
*
* @return New generic battery client model instance.
*/
#define BLE_MESH_MODEL_GEN_BATTERY_CLI(cli_pub, cli_data) \
BLE_MESH_MODEL_CB(BLE_MESH_MODEL_ID_GEN_BATTERY_CLI, \
bt_mesh_gen_battery_cli_op, cli_pub, cli_data, &bt_mesh_generic_client_cb)
typedef bt_mesh_client_user_data_t bt_mesh_gen_battery_client_t;
struct bt_mesh_gen_battery_status {
uint32_t battery_level : 8; /* Value of Generic Battery Level state */
uint32_t time_to_discharge : 24; /* Value of Generic Battery Time to Discharge state */
uint32_t time_to_charge : 24; /* Value of Generic Battery Time to Charge state */
uint32_t flags : 8; /* Value of Generic Battery Flags state */
};
/* Generic Location Client Model Context */
extern const struct bt_mesh_model_op bt_mesh_gen_location_cli_op[];
/** @def BLE_MESH_MODEL_GEN_LOCATION_CLI
*
* Define a new generic location client model. Note that this API
* needs to be repeated for each element which the application
* wants to have a generic location client model on.
* @param cli_pub Pointer to a unique struct bt_mesh_model_pub.
* @param cli_data Pointer to a unique struct bt_mesh_gen_location_cli.
*
* @return New generic location client model instance.
*/
#define BLE_MESH_MODEL_GEN_LOCATION_CLI(cli_pub, cli_data) \
BLE_MESH_MODEL_CB(BLE_MESH_MODEL_ID_GEN_LOCATION_CLI, \
bt_mesh_gen_location_cli_op, cli_pub, cli_data, &bt_mesh_generic_client_cb)
typedef bt_mesh_client_user_data_t bt_mesh_gen_location_client_t;
struct bt_mesh_gen_loc_global_status {
int32_t global_latitude; /* Global Coordinates (Latitude) */
int32_t global_longitude; /* Global Coordinates (Longitude) */
int16_t global_altitude; /* Global Altitude */
};
struct bt_mesh_gen_loc_local_status {
int16_t local_north; /* Local Coordinates (North) */
int16_t local_east; /* Local Coordinates (East) */
int16_t local_altitude; /* Local Altitude */
uint8_t floor_number; /* Floor Number */
uint16_t uncertainty; /* Uncertainty */
};
struct bt_mesh_gen_loc_global_set {
int32_t global_latitude; /* Global Coordinates (Latitude) */
int32_t global_longitude; /* Global Coordinates (Longitude) */
int16_t global_altitude; /* Global Altitude */
};
struct bt_mesh_gen_loc_local_set {
int16_t local_north; /* Local Coordinates (North) */
int16_t local_east; /* Local Coordinates (East) */
int16_t local_altitude; /* Local Altitude */
uint8_t floor_number; /* Floor Number */
uint16_t uncertainty; /* Uncertainty */
};
/* Generic Property Client Model Context */
extern const struct bt_mesh_model_op bt_mesh_gen_property_cli_op[];
/** @def BLE_MESH_MODEL_GEN_LOCATION_CLI
*
* Define a new generic location client model. Note that this API
* needs to be repeated for each element which the application
* wants to have a generic location client model on.
* @param cli_pub Pointer to a unique struct bt_mesh_model_pub.
* @param cli_data Pointer to a unique struct bt_mesh_gen_location_cli.
*
* @return New generic location client model instance.
*/
#define BLE_MESH_MODEL_GEN_PROPERTY_CLI(cli_pub, cli_data) \
BLE_MESH_MODEL_CB(BLE_MESH_MODEL_ID_GEN_PROP_CLI, \
bt_mesh_gen_property_cli_op, cli_pub, cli_data, &bt_mesh_generic_client_cb)
typedef bt_mesh_client_user_data_t bt_mesh_gen_property_client_t;
struct bt_mesh_gen_user_properties_status {
struct net_buf_simple *user_property_ids; /* Buffer contains a sequence of N User Property IDs */
};
struct bt_mesh_gen_user_property_status {
bool op_en; /* Indicate whether optional parameters included */
uint16_t user_property_id; /* Property ID identifying a Generic User Property */
uint8_t user_access; /* Enumeration indicating user access (optional) */
struct net_buf_simple *user_property_value; /* Raw value for the User Property (C.1) */
};
struct bt_mesh_gen_admin_properties_status {
struct net_buf_simple *admin_property_ids; /* Buffer contains a sequence of N Admin Property IDs */
};
struct bt_mesh_gen_admin_property_status {
bool op_en; /* Indicate whether optional parameters included */
uint16_t admin_property_id; /* Property ID identifying a Generic Admin Property */
uint8_t admin_user_access; /* Enumeration indicating user access (optional) */
struct net_buf_simple *admin_property_value; /* Raw value for the Admin Property (C.1) */
};
struct bt_mesh_gen_manu_properties_status {
struct net_buf_simple *manu_property_ids; /* Buffer contains a sequence of N Manufacturer Property IDs */
};
struct bt_mesh_gen_manu_property_status {
bool op_en; /* Indicate whether optional parameters included */
uint16_t manu_property_id; /* Property ID identifying a Generic Manufacturer Property */
uint8_t manu_user_access; /* Enumeration indicating user access (optional) */
struct net_buf_simple *manu_property_value; /* Raw value for the Manufacturer Property (C.1) */
};
struct bt_mesh_gen_client_properties_status {
struct net_buf_simple *client_property_ids; /* Buffer contains a sequence of N Client Property IDs */
};
struct bt_mesh_gen_user_property_get {
uint16_t user_property_id; /* Property ID identifying a Generic User Property */
};
struct bt_mesh_gen_user_property_set {
uint16_t user_property_id; /* Property ID identifying a Generic User Property */
struct net_buf_simple *user_property_value; /* Raw value for the User Property */
};
struct bt_mesh_gen_admin_property_get {
uint16_t admin_property_id; /* Property ID identifying a Generic Admin Property */
};
struct bt_mesh_gen_admin_property_set {
uint16_t admin_property_id; /* Property ID identifying a Generic Admin Property */
uint8_t admin_user_access; /* Enumeration indicating user access */
struct net_buf_simple *admin_property_value; /* Raw value for the Admin Property */
};
struct bt_mesh_gen_manu_property_get {
uint16_t manu_property_id; /* Property ID identifying a Generic Manufacturer Property */
};
struct bt_mesh_gen_manu_property_set {
uint16_t manu_property_id; /* Property ID identifying a Generic Manufacturer Property */
uint8_t manu_user_access; /* Enumeration indicating user access */
};
struct bt_mesh_gen_client_properties_get {
uint16_t client_property_id; /* A starting Client Property ID present within an element */
};
/**
* @brief This function is called to get generic states.
*
* @param[in] common: Message common information structure
* @param[in] get: Pointer of generic get message value
*
* @return Zero-success, other-fail
*/
int bt_mesh_generic_client_get_state(bt_mesh_client_common_param_t *common, void *get);
/**
* @brief This function is called to set generic states.
*
* @param[in] common: Message common information structure
* @param[in] set: Pointer of generic set message value
*
* @return Zero-success, other-fail
*/
int bt_mesh_generic_client_set_state(bt_mesh_client_common_param_t *common, void *set);
#ifdef __cplusplus
}
#endif
#endif /* _GENERIC_CLIENT_H_ */
@@ -0,0 +1,440 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/** @file
* @brief Bluetooth Mesh Lighting Client Model APIs.
*/
#ifndef _LIGHTING_CLIENT_H_
#define _LIGHTING_CLIENT_H_
#include "mesh/client_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Light client model common structure */
typedef bt_mesh_client_user_data_t bt_mesh_light_client_t;
typedef bt_mesh_client_internal_data_t light_internal_data_t;
/* Lighting Client Model Callback */
extern const struct bt_mesh_model_cb bt_mesh_lighting_client_cb;
/* Light Lightness Client Model Context */
extern const struct bt_mesh_model_op bt_mesh_light_lightness_cli_op[];
/** @def BLE_MESH_MODEL_LIGHT_LIGHTNESS_CLI
*
* Define a new light lightness client model. Note that this API
* needs to be repeated for each element which the application
* wants to have a light lightness client model on.
* @param cli_pub Pointer to a unique struct bt_mesh_model_pub.
* @param cli_data Pointer to a unique struct bt_mesh_light_lightness_cli.
*
* @return New light lightness client model instance.
*/
#define BLE_MESH_MODEL_LIGHT_LIGHTNESS_CLI(cli_pub, cli_data) \
BLE_MESH_MODEL_CB(BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_CLI, \
bt_mesh_light_lightness_cli_op, cli_pub, cli_data, &bt_mesh_lighting_client_cb)
typedef bt_mesh_client_user_data_t bt_mesh_light_lightness_client_t;
struct bt_mesh_light_lightness_status {
bool op_en; /* Indicate whether optional parameters included */
uint16_t present_lightness; /* Present value of light lightness actual state */
uint16_t target_lightness; /* Target value of light lightness actual state (optional) */
uint8_t remain_time; /* Time to complete state transition (C.1) */
};
struct bt_mesh_light_lightness_linear_status {
bool op_en; /* Indicate whether optional parameters included */
uint16_t present_lightness; /* Present value of light lightness linear state */
uint16_t target_lightness; /* Target value of light lightness linear state (optional) */
uint8_t remain_time; /* Time to complete state transition (C.1) */
};
struct bt_mesh_light_lightness_last_status {
uint16_t lightness; /* The value of the Light Lightness Last state */
};
struct bt_mesh_light_lightness_default_status {
uint16_t lightness; /* The value of the Light Lightness default state */
};
struct bt_mesh_light_lightness_range_status {
uint8_t status_code; /* Status Code for the requesting message */
uint16_t range_min; /* Value of range min field of light lightness range state */
uint16_t range_max; /* Value of range max field of light lightness range state */
};
struct bt_mesh_light_lightness_set {
bool op_en; /* Indicate whether optional parameters included */
uint16_t lightness; /* Target value of light lightness actual state */
uint8_t tid; /* Transaction Identifier */
uint8_t trans_time; /* Time to complete state transition (optional) */
uint8_t delay; /* Indicate message execution delay (C.1) */
};
struct bt_mesh_light_lightness_linear_set {
bool op_en; /* Indicate whether optional parameters included */
uint16_t lightness; /* Target value of light lightness linear state */
uint8_t tid; /* Transaction Identifier */
uint8_t trans_time; /* Time to complete state transition (optional) */
uint8_t delay; /* Indicate message execution delay (C.1) */
};
struct bt_mesh_light_lightness_default_set {
uint16_t lightness; /* The value of the Light Lightness Default state */
};
struct bt_mesh_light_lightness_range_set {
uint16_t range_min; /* Value of range min field of light lightness range state */
uint16_t range_max; /* Value of range max field of light lightness range state */
};
/* Light CTL Client Model Context */
extern const struct bt_mesh_model_op bt_mesh_light_ctl_cli_op[];
/** @def BLE_MESH_MODEL_LIGHT_CTL_CLI
*
* Define a new light CTL client model. Note that this API needs
* to be repeated for each element which the application wants to
* have a light CTL client model on.
* @param cli_pub Pointer to a unique struct bt_mesh_model_pub.
* @param cli_data Pointer to a unique struct bt_mesh_light_ctl_cli.
*
* @return New light CTL client model instance.
*/
#define BLE_MESH_MODEL_LIGHT_CTL_CLI(cli_pub, cli_data) \
BLE_MESH_MODEL_CB(BLE_MESH_MODEL_ID_LIGHT_CTL_CLI, \
bt_mesh_light_ctl_cli_op, cli_pub, cli_data, &bt_mesh_lighting_client_cb)
typedef bt_mesh_client_user_data_t bt_mesh_light_ctl_client_t;
struct bt_mesh_light_ctl_status {
bool op_en; /* Indicate whether optional parameters included */
uint16_t present_ctl_lightness; /* Present value of light ctl lightness state */
uint16_t present_ctl_temperature; /* Present value of light ctl temperature state */
uint16_t target_ctl_lightness; /* Target value of light ctl lightness state (optional) */
uint16_t target_ctl_temperature; /* Target value of light ctl temperature state (C.1) */
uint8_t remain_time; /* Time to complete state transition (C.1) */
};
struct bt_mesh_light_ctl_temperature_status {
bool op_en; /* Indicate whether optional parameters included */
uint16_t present_ctl_temperature; /* Present value of light ctl temperature state */
uint16_t present_ctl_delta_uv; /* Present value of light ctl delta UV state */
uint16_t target_ctl_temperature; /* Target value of light ctl temperature state (optional) */
uint16_t target_ctl_delta_uv; /* Target value of light ctl delta UV state (C.1) */
uint8_t remain_time; /* Time to complete state transition (C.1) */
};
struct bt_mesh_light_ctl_temperature_range_status {
uint8_t status_code; /* Status code for the requesting message */
uint16_t range_min; /* Value of temperature range min field of light ctl temperature range state */
uint16_t range_max; /* Value of temperature range max field of light ctl temperature range state */
};
struct bt_mesh_light_ctl_default_status {
uint16_t lightness; /* Value of light lightness default state */
uint16_t temperature; /* Value of light temperature default state */
int16_t delta_uv; /* Value of light delta UV default state */
};
struct bt_mesh_light_ctl_set {
bool op_en; /* Indicate whether optional parameters included */
uint16_t ctl_lightness; /* Target value of light ctl lightness state */
uint16_t ctl_temperature; /* Target value of light ctl temperature state */
int16_t ctl_delta_uv; /* Target value of light ctl delta UV state */
uint8_t tid; /* Transaction Identifier */
uint8_t trans_time; /* Time to complete state transition (optional) */
uint8_t delay; /* Indicate message execution delay (C.1) */
};
struct bt_mesh_light_ctl_temperature_set {
bool op_en; /* Indicate whether optional parameters included */
uint16_t ctl_temperature; /* Target value of light ctl temperature state */
int16_t ctl_delta_uv; /* Target value of light ctl delta UV state */
uint8_t tid; /* Transaction Identifier */
uint8_t trans_time; /* Time to complete state transition (optional) */
uint8_t delay; /* Indicate message execution delay (C.1) */
};
struct bt_mesh_light_ctl_temperature_range_set {
uint16_t range_min; /* Value of temperature range min field of light ctl temperature range state */
uint16_t range_max; /* Value of temperature range max field of light ctl temperature range state */
};
struct bt_mesh_light_ctl_default_set {
uint16_t lightness; /* Value of light lightness default state */
uint16_t temperature; /* Value of light temperature default state */
int16_t delta_uv; /* Value of light delta UV default state */
};
/* Light HSL Client Model Context */
extern const struct bt_mesh_model_op bt_mesh_light_hsl_cli_op[];
/** @def BLE_MESH_MODEL_LIGHT_HSL_CLI
*
* Define a new light HSL client model. Note that this API needs
* to be repeated for each element which the application wants to
* have a light HSL client model on.
* @param cli_pub Pointer to a unique struct bt_mesh_model_pub.
* @param cli_data Pointer to a unique struct bt_mesh_light_hsl_cli.
*
* @return New light HSL client model instance.
*/
#define BLE_MESH_MODEL_LIGHT_HSL_CLI(cli_pub, cli_data) \
BLE_MESH_MODEL_CB(BLE_MESH_MODEL_ID_LIGHT_HSL_CLI, \
bt_mesh_light_hsl_cli_op, cli_pub, cli_data, &bt_mesh_lighting_client_cb)
typedef bt_mesh_client_user_data_t bt_mesh_light_hsl_client_t;
struct bt_mesh_light_hsl_status {
bool op_en; /* Indicate whether optional parameters included */
uint16_t hsl_lightness; /* Present value of light hsl lightness state */
uint16_t hsl_hue; /* Present value of light hsl hue state */
uint16_t hsl_saturation; /* Present value of light hsl saturation state */
uint8_t remain_time; /* Time to complete state transition (optional) */
};
struct bt_mesh_light_hsl_target_status {
bool op_en; /* Indicate whether optional parameters included */
uint16_t hsl_lightness_target; /* Target value of light hsl lightness state */
uint16_t hsl_hue_target; /* Target value of light hsl hue state */
uint16_t hsl_saturation_target; /* Target value of light hsl saturation state */
uint8_t remain_time; /* Time to complete state transition (optional) */
};
struct bt_mesh_light_hsl_hue_status {
bool op_en; /* Indicate whether optional parameters included */
uint16_t present_hue; /* Present value of light hsl hue state */
uint16_t target_hue; /* Target value of light hsl hue state (optional) */
uint8_t remain_time; /* Time to complete state transition (C.1) */
};
struct bt_mesh_light_hsl_saturation_status {
bool op_en; /* Indicate whether optional parameters included */
uint16_t present_saturation; /* Present value of light hsl saturation state */
uint16_t target_saturation; /* Target value of light hsl saturation state (optional) */
uint8_t remain_time; /* Time to complete state transition (C.1) */
};
struct bt_mesh_light_hsl_default_status {
uint16_t lightness; /* Value of light lightness default state */
uint16_t hue; /* Value of light hue default state */
uint16_t saturation; /* Value of light saturation default state */
};
struct bt_mesh_light_hsl_range_status {
uint8_t status_code; /* Status code for the requesting message */
uint16_t hue_range_min; /* Value of hue range min field of light hsl hue range state */
uint16_t hue_range_max; /* Value of hue range max field of light hsl hue range state */
uint16_t saturation_range_min; /* Value of saturation range min field of light hsl saturation range state */
uint16_t saturation_range_max; /* Value of saturation range max field of light hsl saturation range state */
};
struct bt_mesh_light_hsl_set {
bool op_en; /* Indicate whether optional parameters included */
uint16_t hsl_lightness; /* Target value of light hsl lightness state */
uint16_t hsl_hue; /* Target value of light hsl hue state */
uint16_t hsl_saturation; /* Target value of light hsl saturation state */
uint8_t tid; /* Transaction Identifier */
uint8_t trans_time; /* Time to complete state transition (optional) */
uint8_t delay; /* Indicate message execution delay (C.1) */
};
struct bt_mesh_light_hsl_hue_set {
bool op_en; /* Indicate whether optional parameters included */
uint16_t hue; /* Target value of light hsl hue state */
uint8_t tid; /* Transaction Identifier */
uint8_t trans_time; /* Time to complete state transition (optional) */
uint8_t delay; /* Indicate message execution delay (C.1) */
};
struct bt_mesh_light_hsl_saturation_set {
bool op_en; /* Indicate whether optional parameters included */
uint16_t saturation; /* Target value of light hsl hue state */
uint8_t tid; /* Transaction Identifier */
uint8_t trans_time; /* Time to complete state transition (optional) */
uint8_t delay; /* Indicate message execution delay (C.1) */
};
struct bt_mesh_light_hsl_default_set {
uint16_t lightness; /* Value of light lightness default state */
uint16_t hue; /* Value of light hue default state */
uint16_t saturation; /* Value of light saturation default state */
};
struct bt_mesh_light_hsl_range_set {
uint16_t hue_range_min; /* Value of hue range min field of light hsl hue range state */
uint16_t hue_range_max; /* Value of hue range max field of light hsl hue range state */
uint16_t saturation_range_min; /* Value of saturation range min field of light hsl saturation range state */
uint16_t saturation_range_max; /* Value of saturation range max field of light hsl saturation range state */
};
/* Light xyL Client Model Context */
extern const struct bt_mesh_model_op bt_mesh_light_xyl_cli_op[];
/** @def BLE_MESH_MODEL_LIGHT_XYL_CLI
*
* Define a new light xyL client model. Note that this API needs
* to be repeated for each element which the application wants
* to have a light xyL client model on.
* @param cli_pub Pointer to a unique struct bt_mesh_model_pub.
* @param cli_data Pointer to a unique struct bt_mesh_light_xyl_cli.
*
* @return New light xyL client model instance.
*/
#define BLE_MESH_MODEL_LIGHT_XYL_CLI(cli_pub, cli_data) \
BLE_MESH_MODEL_CB(BLE_MESH_MODEL_ID_LIGHT_XYL_CLI, \
bt_mesh_light_xyl_cli_op, cli_pub, cli_data, &bt_mesh_lighting_client_cb)
typedef bt_mesh_client_user_data_t bt_mesh_light_xyl_client_t;
struct bt_mesh_light_xyl_status {
bool op_en; /* Indicate whether optional parameters included */
uint16_t xyl_lightness; /* The present value of the Light xyL Lightness state */
uint16_t xyl_x; /* The present value of the Light xyL x state */
uint16_t xyl_y; /* The present value of the Light xyL y state */
uint8_t remain_time; /* Time to complete state transition (optional) */
};
struct bt_mesh_light_xyl_target_status {
bool op_en; /* Indicate whether optional parameters included */
uint16_t target_xyl_lightness; /* The target value of the Light xyL Lightness state */
uint16_t target_xyl_x; /* The target value of the Light xyL x state */
uint16_t target_xyl_y; /* The target value of the Light xyL y state */
uint8_t remain_time; /* Time to complete state transition (optional) */
};
struct bt_mesh_light_xyl_default_status {
uint16_t lightness; /* The value of the Light Lightness Default state */
uint16_t xyl_x; /* The value of the Light xyL x Default state */
uint16_t xyl_y; /* The value of the Light xyL y Default state */
};
struct bt_mesh_light_xyl_range_status {
uint8_t status_code; /* Status Code for the requesting message */
uint16_t xyl_x_range_min; /* The value of the xyL x Range Min field of the Light xyL x Range state */
uint16_t xyl_x_range_max; /* The value of the xyL x Range Max field of the Light xyL x Range state */
uint16_t xyl_y_range_min; /* The value of the xyL y Range Min field of the Light xyL y Range state */
uint16_t xyl_y_range_max; /* The value of the xyL y Range Max field of the Light xyL y Range state */
};
struct bt_mesh_light_xyl_set {
bool op_en; /* Indicate whether optional parameters included */
uint16_t xyl_lightness; /* The target value of the Light xyL Lightness state */
uint16_t xyl_x; /* The target value of the Light xyL x state */
uint16_t xyl_y; /* The target value of the Light xyL y state */
uint8_t tid; /* Transaction Identifier */
uint8_t trans_time; /* Time to complete state transition (optional) */
uint8_t delay; /* Indicate message execution delay (C.1) */
};
struct bt_mesh_light_xyl_default_set {
uint16_t lightness; /* The value of the Light Lightness Default state */
uint16_t xyl_x; /* The value of the Light xyL x Default state */
uint16_t xyl_y; /* The value of the Light xyL y Default state */
};
struct bt_mesh_light_xyl_range_set {
uint16_t xyl_x_range_min; /* The value of the xyL x Range Min field of the Light xyL x Range state */
uint16_t xyl_x_range_max; /* The value of the xyL x Range Max field of the Light xyL x Range state */
uint16_t xyl_y_range_min; /* The value of the xyL y Range Min field of the Light xyL y Range state */
uint16_t xyl_y_range_max; /* The value of the xyL y Range Max field of the Light xyL y Range state */
};
/* Light LC Client Model Context */
extern const struct bt_mesh_model_op bt_mesh_light_lc_cli_op[];
/** @def BLE_MESH_MODEL_LIGHT_LC_CLI
*
* Define a new light lc client model. Note that this API needs
* to be repeated for each element which the application wants
* to have a light lc client model on.
* @param cli_pub Pointer to a unique struct bt_mesh_model_pub.
* @param cli_data Pointer to a unique struct bt_mesh_light_lc_cli.
*
* @return New light lc client model instance.
*/
#define BLE_MESH_MODEL_LIGHT_LC_CLI(cli_pub, cli_data) \
BLE_MESH_MODEL_CB(BLE_MESH_MODEL_ID_LIGHT_LC_CLI, \
bt_mesh_light_lc_cli_op, cli_pub, cli_data, &bt_mesh_lighting_client_cb)
typedef bt_mesh_client_user_data_t bt_mesh_light_lc_client_t;
struct bt_mesh_light_lc_mode_status {
uint8_t mode; /* The present value of the Light LC Mode state */
};
struct bt_mesh_light_lc_om_status {
uint8_t mode; /* The present value of the Light LC Occupancy Mode state */
};
struct bt_mesh_light_lc_light_onoff_status {
bool op_en; /* Indicate whether optional parameters included */
uint8_t present_light_onoff; /* The present value of the Light LC Light OnOff state */
uint8_t target_light_onoff; /* The target value of the Light LC Light OnOff state (Optional) */
uint8_t remain_time; /* Time to complete state transition (C.1) */
};
struct bt_mesh_light_lc_property_status {
uint16_t light_lc_property_id; /* Property ID identifying a Light LC Property */
struct net_buf_simple *light_lc_property_value; /* Raw value for the Light LC Property */
};
struct bt_mesh_light_lc_mode_set {
uint8_t mode; /* The target value of the Light LC Mode state */
};
struct bt_mesh_light_lc_om_set {
uint8_t mode; /* The target value of the Light LC Occupancy Mode state */
};
struct bt_mesh_light_lc_light_onoff_set {
bool op_en; /* Indicate whether optional parameters included */
uint8_t light_onoff; /* The target value of the Light LC Light OnOff state */
uint8_t tid; /* Transaction Identifier */
uint8_t trans_time; /* Time to complete state transition (optional) */
uint8_t delay; /* Indicate message execution delay (C.1) */
};
struct bt_mesh_light_lc_property_get {
uint16_t light_lc_property_id; /* Property ID identifying a Light LC Property */
};
struct bt_mesh_light_lc_property_set {
uint16_t light_lc_property_id; /* Property ID identifying a Light LC Property */
struct net_buf_simple *light_lc_property_value; /* Raw value for the Light LC Property */
};
/**
* @brief This function is called to get light states.
*
* @param[in] common: Message common information structure
* @param[in] get: Pointer of light get message value
*
* @return Zero-success, other-fail
*/
int bt_mesh_light_client_get_state(bt_mesh_client_common_param_t *common, void *get);
/**
* @brief This function is called to set light states.
*
* @param[in] common: Message common information structure
* @param[in] set: Pointer of light set message value
*
* @return Zero-success, other-fail
*/
int bt_mesh_light_client_set_state(bt_mesh_client_common_param_t *common, void *set);
#ifdef __cplusplus
}
#endif
#endif /* _LIGHTING_CLIENT_H_ */
@@ -0,0 +1,155 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/** @file
* @brief Bluetooth Mesh Sensor Client Model APIs.
*/
#ifndef _SENSOR_CLIENT_H_
#define _SENSOR_CLIENT_H_
#include "mesh/client_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Sensor Client Model Callback */
extern const struct bt_mesh_model_cb bt_mesh_sensor_client_cb;
/* Sensor Client Model Context */
extern const struct bt_mesh_model_op bt_mesh_sensor_cli_op[];
/** @def BLE_MESH_MODEL_SENSOR_CLI
*
* Define a new sensor client model. Note that this API needs to
* be repeated for each element which the application wants to
* have a sensor client model on.
* @param cli_pub Pointer to a unique struct bt_mesh_model_pub.
* @param cli_data Pointer to a unique struct bt_mesh_sensor_cli.
*
* @return New sensor client model instance.
*/
#define BLE_MESH_MODEL_SENSOR_CLI(cli_pub, cli_data) \
BLE_MESH_MODEL_CB(BLE_MESH_MODEL_ID_SENSOR_CLI, \
bt_mesh_sensor_cli_op, cli_pub, cli_data, &bt_mesh_sensor_client_cb)
typedef bt_mesh_client_user_data_t bt_mesh_sensor_client_t;
typedef bt_mesh_client_internal_data_t sensor_internal_data_t;
struct bt_mesh_sensor_descriptor_status {
struct net_buf_simple *descriptor; /* Sequence of 8-octet sensor descriptors (optional) */
};
struct bt_mesh_sensor_cadence_status {
uint16_t property_id; /* Property for the sensor */
struct net_buf_simple *sensor_cadence_value; /* Value of sensor cadence state */
};
struct bt_mesh_sensor_settings_status {
uint16_t sensor_property_id; /* Property ID identifying a sensor */
struct net_buf_simple *sensor_setting_property_ids; /* A sequence of N sensor setting property IDs (optional) */
};
struct bt_mesh_sensor_setting_status {
bool op_en; /* Indicate whether optional parameters included */
uint16_t sensor_property_id; /* Property ID identifying a sensor */
uint16_t sensor_setting_property_id; /* Setting ID identifying a setting within a sensor */
uint8_t sensor_setting_access; /* Read/Write access rights for the setting (optional) */
struct net_buf_simple *sensor_setting_raw; /* Raw value for the setting */
};
struct bt_mesh_sensor_status {
struct net_buf_simple *marshalled_sensor_data; /* Value of sensor data state (optional) */
};
struct bt_mesh_sensor_column_status {
uint16_t property_id; /* Property identifying a sensor and the Y axis */
struct net_buf_simple *sensor_column_value; /* Left values of sensor column status */
};
struct bt_mesh_sensor_series_status {
uint16_t property_id; /* Property identifying a sensor and the Y axis */
struct net_buf_simple *sensor_series_value; /* Left values of sensor series status */
};
struct bt_mesh_sensor_descriptor_get {
bool op_en; /* Indicate whether optional parameters included */
uint16_t property_id; /* Property ID for the sensor (optional) */
};
struct bt_mesh_sensor_cadence_get {
uint16_t property_id; /* Property ID for the sensor */
};
struct bt_mesh_sensor_cadence_set {
uint16_t property_id; /* Property ID for the sensor */
uint8_t fast_cadence_period_divisor : 7, /* Divisor for the publish period */
status_trigger_type : 1; /* The unit and format of the Status Trigger Delta fields */
struct net_buf_simple *status_trigger_delta_down; /* Delta down value that triggers a status message */
struct net_buf_simple *status_trigger_delta_up; /* Delta up value that triggers a status message */
uint8_t status_min_interval; /* Minimum interval between two consecutive Status messages */
struct net_buf_simple *fast_cadence_low; /* Low value for the fast cadence range */
struct net_buf_simple *fast_cadence_high; /* Fast value for the fast cadence range */
};
struct bt_mesh_sensor_settings_get {
uint16_t sensor_property_id; /* Property ID for the sensor */
};
struct bt_mesh_sensor_setting_get {
uint16_t sensor_property_id; /* Property ID identifying a sensor */
uint16_t sensor_setting_property_id; /* Setting ID identifying a setting within a sensor */
};
struct bt_mesh_sensor_setting_set {
uint16_t sensor_property_id; /* Property ID identifying a sensor */
uint16_t sensor_setting_property_id; /* Setting ID identifying a setting within a sensor */
struct net_buf_simple *sensor_setting_raw; /* Raw value for the setting */
};
struct bt_mesh_sensor_get {
bool op_en; /* Indicate whether optional parameters included */
uint16_t property_id; /* Property ID for the sensor (optional) */
};
struct bt_mesh_sensor_column_get {
uint16_t property_id; /* Property identifying a sensor */
struct net_buf_simple *raw_value_x; /* Raw value identifying a column */
};
struct bt_mesh_sensor_series_get {
bool op_en; /* Indicate whether optional parameters included */
uint16_t property_id; /* Property identifying a sensor */
struct net_buf_simple *raw_value_x1; /* Raw value identifying a starting column (optional) */
struct net_buf_simple *raw_value_x2; /* Raw value identifying a ending column (C.1) */
};
/**
* @brief This function is called to get sensor states.
*
* @param[in] common: Message common information structure
* @param[in] get: Pointer of sensor get message value
*
* @return Zero-success, other-fail
*/
int bt_mesh_sensor_client_get_state(bt_mesh_client_common_param_t *common, void *get);
/**
* @brief This function is called to set sensor states.
*
* @param[in] common: Message common information structure
* @param[in] set: Pointer of sensor set message value
*
* @return Zero-success, other-fail
*/
int bt_mesh_sensor_client_set_state(bt_mesh_client_common_param_t *common, void *set);
#ifdef __cplusplus
}
#endif
#endif /* _SENSOR_CLIENT_H_ */
@@ -0,0 +1,225 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/** @file
* @brief Bluetooth Mesh Time and Scene Client Model APIs.
*/
#ifndef _TIME_SCENE_CLIENT_H_
#define _TIME_SCENE_CLIENT_H_
#include "mesh/client_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Time scene client model common structure */
typedef bt_mesh_client_user_data_t bt_mesh_time_scene_client_t;
typedef bt_mesh_client_internal_data_t time_scene_internal_data_t;
/* Time Scene Client Model Callback */
extern const struct bt_mesh_model_cb bt_mesh_time_scene_client_cb;
/* Time Client Model Context */
extern const struct bt_mesh_model_op bt_mesh_time_cli_op[];
/** @def BLE_MESH_MODEL_TIME_CLI
*
* Define a new time client model. Note that this API needs to
* be repeated for each element which the application wants to
* have a time model on.
* @param cli_pub Pointer to a unique struct bt_mesh_model_pub.
* @param cli_data Pointer to a unique struct bt_mesh_time_cli.
*
* @return New time client model instance.
*/
#define BLE_MESH_MODEL_TIME_CLI(cli_pub, cli_data) \
BLE_MESH_MODEL_CB(BLE_MESH_MODEL_ID_TIME_CLI, \
bt_mesh_time_cli_op, cli_pub, cli_data, &bt_mesh_time_scene_client_cb)
typedef bt_mesh_client_user_data_t bt_mesh_time_client_t;
struct bt_mesh_time_status {
uint8_t tai_seconds[5]; /* The current TAI time in seconds */
uint8_t sub_second; /* The sub-second time in units of 1/256 second */
uint8_t uncertainty; /* The estimated uncertainty in 10-millisecond steps */
uint16_t time_authority : 1; /* 0 = No Time Authority, 1 = Time Authority */
uint16_t tai_utc_delta : 15; /* Current difference between TAI and UTC in seconds */
uint8_t time_zone_offset; /* The local time zone offset in 15-minute increments */
};
struct bt_mesh_time_zone_status {
uint8_t time_zone_offset_curr; /* Current local time zone offset */
uint8_t time_zone_offset_new; /* Upcoming local time zone offset */
uint8_t tai_zone_change[5]; /* TAI Seconds time of the upcoming Time Zone Offset change */
};
struct bt_mesh_tai_utc_delta_status {
uint16_t tai_utc_delta_curr : 15; /* Current difference between TAI and UTC in seconds */
uint16_t padding_1 : 1; /* Always 0b0. Other values are Prohibited. */
uint16_t tai_utc_delta_new : 15; /* Upcoming difference between TAI and UTC in seconds */
uint16_t padding_2 : 1; /* Always 0b0. Other values are Prohibited. */
uint8_t tai_delta_change[5]; /* TAI Seconds time of the upcoming TAI-UTC Delta change */
};
struct bt_mesh_time_role_status {
uint8_t time_role; /* The Time Role for the element */
};
struct bt_mesh_time_set {
uint8_t tai_seconds[5]; /* The current TAI time in seconds */
uint8_t sub_second; /* The sub-second time in units of 1/256 second */
uint8_t uncertainty; /* The estimated uncertainty in 10-millisecond steps */
uint16_t time_authority : 1; /* 0 = No Time Authority, 1 = Time Authority */
uint16_t tai_utc_delta : 15; /* Current difference between TAI and UTC in seconds */
uint8_t time_zone_offset; /* The local time zone offset in 15-minute increments */
};
struct bt_mesh_time_zone_set {
uint8_t time_zone_offset_new; /* Upcoming local time zone offset */
uint8_t tai_zone_change[5]; /* TAI Seconds time of the upcoming Time Zone Offset change */
};
struct bt_mesh_tai_utc_delta_set {
uint16_t tai_utc_delta_new : 15; /* Upcoming difference between TAI and UTC in seconds */
uint16_t padding : 1; /* Always 0b0. Other values are Prohibited. */
uint8_t tai_delta_change[5]; /* TAI Seconds time of the upcoming TAI-UTC Delta change */
};
struct bt_mesh_time_role_set {
uint8_t time_role; /* The Time Role for the element */
};
/* Scene Client Model Context */
extern const struct bt_mesh_model_op bt_mesh_scene_cli_op[];
/** @def BLE_MESH_MODEL_SCENE_CLI
*
* Define a new scene client model. Note that this API needs to
* be repeated for each element which the application wants to
* have a scene model on.
* @param cli_pub Pointer to a unique struct bt_mesh_model_pub.
* @param cli_data Pointer to a unique struct bt_mesh_scene_cli.
*
* @return New scene client model instance.
*/
#define BLE_MESH_MODEL_SCENE_CLI(cli_pub, cli_data) \
BLE_MESH_MODEL_CB(BLE_MESH_MODEL_ID_SCENE_CLI, \
bt_mesh_scene_cli_op, cli_pub, cli_data, &bt_mesh_time_scene_client_cb)
typedef bt_mesh_client_user_data_t bt_mesh_scene_client_t;
struct bt_mesh_scene_status {
bool op_en; /* Indicate whether optional parameters included */
uint8_t status_code; /* Status code for the last operation */
uint16_t current_scene; /* Scene Number of a current scene */
uint16_t target_scene; /* Scene Number of a target scene (optional) */
uint8_t remain_time; /* Time to complete state transition (C.1) */
};
struct bt_mesh_scene_register_status {
uint8_t status_code; /* Status code for the previous operation */
uint16_t current_scene; /* Scene Number of a current scene */
struct net_buf_simple *scenes; /* A list of scenes stored within an element */
};
struct bt_mesh_scene_store {
uint16_t scene_number; /* The number of the scene to be stored */
};
struct bt_mesh_scene_recall {
bool op_en; /* Indicate whether optional parameters included */
uint16_t scene_number; /* The number of the scene to be recalled */
uint8_t tid; /* Transaction Identifier */
uint8_t trans_time; /* Time to complete state transition (optional) */
uint8_t delay; /* Indicate message execution delay (C.1) */
};
struct bt_mesh_scene_delete {
uint16_t scene_number; /* The number of the scene to be deleted */
};
/* Scheduler Client Model Context */
extern const struct bt_mesh_model_op bt_mesh_scheduler_cli_op[];
/** @def BLE_MESH_MODEL_SCHEDULER_CLI
*
* Define a new scheduler client model. Note that this API needs to
* be repeated for each element which the application wants to
* have a scheduler model on.
* @param cli_pub Pointer to a unique struct bt_mesh_model_pub.
* @param cli_data Pointer to a unique struct bt_mesh_scheduler_cli.
*
* @return New scheduler client model instance.
*/
#define BLE_MESH_MODEL_SCHEDULER_CLI(cli_pub, cli_data) \
BLE_MESH_MODEL_CB(BLE_MESH_MODEL_ID_SCHEDULER_CLI, \
bt_mesh_scheduler_cli_op, cli_pub, cli_data, &bt_mesh_time_scene_client_cb)
typedef bt_mesh_client_user_data_t bt_mesh_scheduler_client_t;
struct bt_mesh_scheduler_status {
uint16_t schedules; /* Bit field indicating defined Actions in the Schedule Register */
};
struct bt_mesh_scheduler_act_status {
uint64_t index : 4; /* Enumerates (selects) a Schedule Register entry */
uint64_t year : 7; /* Scheduled year for the action */
uint64_t month : 12; /* Scheduled month for the action */
uint64_t day : 5; /* Scheduled day of the month for the action */
uint64_t hour : 5; /* Scheduled hour for the action */
uint64_t minute : 6; /* Scheduled minute for the action */
uint64_t second : 6; /* Scheduled second for the action */
uint64_t day_of_week : 7; /* Schedule days of the week for the action */
uint64_t action : 4; /* Action to be performed at the scheduled time */
uint64_t trans_time : 8; /* Transition time for this action */
uint16_t scene_number; /* Transition time for this action */
};
struct bt_mesh_scheduler_act_get {
uint8_t index; /* Index of the Schedule Register entry to get */
};
struct bt_mesh_scheduler_act_set {
uint64_t index : 4; /* Index of the Schedule Register entry to set */
uint64_t year : 7; /* Scheduled year for the action */
uint64_t month : 12; /* Scheduled month for the action */
uint64_t day : 5; /* Scheduled day of the month for the action */
uint64_t hour : 5; /* Scheduled hour for the action */
uint64_t minute : 6; /* Scheduled minute for the action */
uint64_t second : 6; /* Scheduled second for the action */
uint64_t day_of_week : 7; /* Schedule days of the week for the action */
uint64_t action : 4; /* Action to be performed at the scheduled time */
uint64_t trans_time : 8; /* Transition time for this action */
uint16_t scene_number; /* Transition time for this action */
};
/**
* @brief This function is called to get scene states.
*
* @param[in] common: Message common information structure
* @param[in] get: Pointer of time scene get message value
*
* @return Zero-success, other-fail
*/
int bt_mesh_time_scene_client_get_state(bt_mesh_client_common_param_t *common, void *get);
/**
* @brief This function is called to set scene states.
*
* @param[in] common: Message common information structure
* @param[in] set: Pointer of time scene set message value
*
* @return Zero-success, other-fail
*/
int bt_mesh_time_scene_client_set_state(bt_mesh_client_common_param_t *common, void *set);
#ifdef __cplusplus
}
#endif
#endif /* _TIME_SCENE_CLIENT_H_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,625 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <errno.h>
#include "btc_ble_mesh_sensor_model.h"
#include "mesh/config.h"
#include "mesh/model_opcode.h"
#if CONFIG_BLE_MESH_SENSOR_CLI
#include "mesh/sensor_client.h"
/* The followings are the macro definitions of Sensor client
* model message length, and a message is composed of 3 parts:
* Opcode + Payload + MIC
*/
/* Sensor client messages length */
#define BLE_MESH_SENSOR_DESCRIPTOR_GET_MSG_LEN (2 + 2 + 4)
#define BLE_MESH_SENSOR_CADENCE_GET_MSG_LEN (2 + 2 + 4)
#define BLE_MESH_SENSOR_CADENCE_SET_MSG_LEN /* variable */
#define BLE_MESH_SENSOR_SETTINGS_GET_MSG_LEN (2 + 2 + 4)
#define BLE_MESH_SENSOR_SETTING_GET_MSG_LEN (2 + 4 + 4)
#define BLE_MESH_SENSOR_SETTING_SET_MSG_LEN /* variable */
#define BLE_MESH_SENSOR_GET_MSG_LEN (2 + 2 + 4)
#define BLE_MESH_SENSOR_COLUMN_GET_MSG_LEN /* variable */
#define BLE_MESH_SENSOR_SERIES_GET_MSG_LEN /* variable */
static const bt_mesh_client_op_pair_t sensor_op_pair[] = {
{ BLE_MESH_MODEL_OP_SENSOR_DESCRIPTOR_GET, BLE_MESH_MODEL_OP_SENSOR_DESCRIPTOR_STATUS },
{ BLE_MESH_MODEL_OP_SENSOR_CADENCE_GET, BLE_MESH_MODEL_OP_SENSOR_CADENCE_STATUS },
{ BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET, BLE_MESH_MODEL_OP_SENSOR_CADENCE_STATUS },
{ BLE_MESH_MODEL_OP_SENSOR_SETTINGS_GET, BLE_MESH_MODEL_OP_SENSOR_SETTINGS_STATUS },
{ BLE_MESH_MODEL_OP_SENSOR_SETTING_GET, BLE_MESH_MODEL_OP_SENSOR_SETTING_STATUS },
{ BLE_MESH_MODEL_OP_SENSOR_SETTING_SET, BLE_MESH_MODEL_OP_SENSOR_SETTING_STATUS },
{ BLE_MESH_MODEL_OP_SENSOR_GET, BLE_MESH_MODEL_OP_SENSOR_STATUS },
{ BLE_MESH_MODEL_OP_SENSOR_COLUMN_GET, BLE_MESH_MODEL_OP_SENSOR_COLUMN_STATUS },
{ BLE_MESH_MODEL_OP_SENSOR_SERIES_GET, BLE_MESH_MODEL_OP_SENSOR_SERIES_STATUS },
};
static bt_mesh_mutex_t sensor_client_lock;
static void timeout_handler(struct k_work *work)
{
struct k_delayed_work *timer = NULL;
bt_mesh_client_node_t *node = NULL;
struct bt_mesh_model *model = NULL;
struct bt_mesh_msg_ctx ctx = {0};
uint32_t opcode = 0U;
BT_WARN("Receive sensor status message timeout");
bt_mesh_mutex_lock(&sensor_client_lock);
timer = CONTAINER_OF(work, struct k_delayed_work, work);
if (timer && !k_delayed_work_free(timer)) {
node = CONTAINER_OF(work, bt_mesh_client_node_t, timer.work);
if (node) {
memcpy(&ctx, &node->ctx, sizeof(ctx));
opcode = node->opcode;
model = node->model;
bt_mesh_client_free_node(node);
bt_mesh_sensor_client_cb_evt_to_btc(
opcode, BTC_BLE_MESH_EVT_SENSOR_CLIENT_TIMEOUT, model, &ctx, NULL, 0);
}
}
bt_mesh_mutex_unlock(&sensor_client_lock);
}
static void sensor_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
bt_mesh_client_node_t *node = NULL;
uint8_t *val = NULL;
uint8_t evt = 0xFF;
size_t len = 0U;
BT_DBG("len %d, bytes %s", buf->len, bt_hex(buf->data, buf->len));
switch (ctx->recv_op) {
case BLE_MESH_MODEL_OP_SENSOR_DESCRIPTOR_STATUS: {
struct bt_mesh_sensor_descriptor_status *status = NULL;
status = bt_mesh_calloc(sizeof(struct bt_mesh_sensor_descriptor_status));
if (!status) {
BT_ERR("%s, Out of memory", __func__);
return;
}
status->descriptor = bt_mesh_alloc_buf(buf->len);
if (!status->descriptor) {
BT_ERR("%s, Out of memory", __func__);
bt_mesh_free(status);
return;
}
net_buf_simple_add_mem(status->descriptor, buf->data, buf->len);
val = (uint8_t *)status;
len = sizeof(struct bt_mesh_sensor_descriptor_status);
break;
}
case BLE_MESH_MODEL_OP_SENSOR_CADENCE_STATUS: {
struct bt_mesh_sensor_cadence_status *status = NULL;
status = bt_mesh_calloc(sizeof(struct bt_mesh_sensor_cadence_status));
if (!status) {
BT_ERR("%s, Out of memory", __func__);
return;
}
status->property_id = net_buf_simple_pull_le16(buf);
status->sensor_cadence_value = bt_mesh_alloc_buf(buf->len);
if (!status->sensor_cadence_value) {
BT_ERR("%s, Out of memory", __func__);
bt_mesh_free(status);
return;
}
net_buf_simple_add_mem(status->sensor_cadence_value, buf->data, buf->len);
val = (uint8_t *)status;
len = sizeof(struct bt_mesh_sensor_cadence_status);
break;
}
case BLE_MESH_MODEL_OP_SENSOR_SETTINGS_STATUS: {
struct bt_mesh_sensor_settings_status *status = NULL;
status = bt_mesh_calloc(sizeof(struct bt_mesh_sensor_settings_status));
if (!status) {
BT_ERR("%s, Out of memory", __func__);
return;
}
status->sensor_property_id = net_buf_simple_pull_le16(buf);
status->sensor_setting_property_ids = bt_mesh_alloc_buf(buf->len);
if (!status->sensor_setting_property_ids) {
BT_ERR("%s, Out of memory", __func__);
bt_mesh_free(status);
return;
}
net_buf_simple_add_mem(status->sensor_setting_property_ids, buf->data, buf->len);
val = (uint8_t *)status;
len = sizeof(struct bt_mesh_sensor_settings_status);
break;
}
case BLE_MESH_MODEL_OP_SENSOR_SETTING_STATUS: {
struct bt_mesh_sensor_setting_status *status = NULL;
status = bt_mesh_calloc(sizeof(struct bt_mesh_sensor_setting_status));
if (!status) {
BT_ERR("%s, Out of memory", __func__);
return;
}
status->sensor_property_id = net_buf_simple_pull_le16(buf);
status->sensor_setting_property_id = net_buf_simple_pull_le16(buf);
if (buf->len) {
status->op_en = true;
status->sensor_setting_access = net_buf_simple_pull_u8(buf);
status->sensor_setting_raw = bt_mesh_alloc_buf(buf->len);
if (!status->sensor_setting_raw) {
BT_ERR("%s, Out of memory", __func__);
bt_mesh_free(status);
return;
}
net_buf_simple_add_mem(status->sensor_setting_raw, buf->data, buf->len);
}
val = (uint8_t *)status;
len = sizeof(struct bt_mesh_sensor_setting_status);
break;
}
case BLE_MESH_MODEL_OP_SENSOR_STATUS: {
struct bt_mesh_sensor_status *status = NULL;
status = bt_mesh_calloc(sizeof(struct bt_mesh_sensor_status));
if (!status) {
BT_ERR("%s, Out of memory", __func__);
return;
}
status->marshalled_sensor_data = bt_mesh_alloc_buf(buf->len);
if (!status->marshalled_sensor_data) {
BT_ERR("%s, Out of memory", __func__);
bt_mesh_free(status);
return;
}
net_buf_simple_add_mem(status->marshalled_sensor_data, buf->data, buf->len);
val = (uint8_t *)status;
len = sizeof(struct bt_mesh_sensor_status);
break;
}
case BLE_MESH_MODEL_OP_SENSOR_COLUMN_STATUS: {
struct bt_mesh_sensor_column_status *status = NULL;
status = bt_mesh_calloc(sizeof(struct bt_mesh_sensor_column_status));
if (!status) {
BT_ERR("%s, Out of memory", __func__);
return;
}
status->property_id = net_buf_simple_pull_le16(buf);
status->sensor_column_value = bt_mesh_alloc_buf(buf->len);
if (!status->sensor_column_value) {
BT_ERR("%s, Out of memory", __func__);
bt_mesh_free(status);
return;
}
net_buf_simple_add_mem(status->sensor_column_value, buf->data, buf->len);
val = (uint8_t *)status;
len = sizeof(struct bt_mesh_sensor_column_status);
break;
}
case BLE_MESH_MODEL_OP_SENSOR_SERIES_STATUS: {
struct bt_mesh_sensor_series_status *status = NULL;
status = bt_mesh_calloc(sizeof(struct bt_mesh_sensor_series_status));
if (!status) {
BT_ERR("%s, Out of memory", __func__);
return;
}
status->property_id = net_buf_simple_pull_le16(buf);
status->sensor_series_value = bt_mesh_alloc_buf(buf->len);
if (!status->sensor_series_value) {
BT_ERR("%s, Out of memory", __func__);
bt_mesh_free(status);
return;
}
net_buf_simple_add_mem(status->sensor_series_value, buf->data, buf->len);
val = (uint8_t *)status;
len = sizeof(struct bt_mesh_sensor_series_status);
break;
}
default:
BT_ERR("Invalid Sensor Status opcode 0x%04x", ctx->recv_op);
return;
}
buf->data = val;
buf->len = len;
bt_mesh_mutex_lock(&sensor_client_lock);
node = bt_mesh_is_client_recv_publish_msg(model, ctx, buf, true);
if (!node) {
BT_DBG("Unexpected Sensor Status 0x%04x", ctx->recv_op);
} else {
switch (node->opcode) {
case BLE_MESH_MODEL_OP_SENSOR_DESCRIPTOR_GET:
case BLE_MESH_MODEL_OP_SENSOR_CADENCE_GET:
case BLE_MESH_MODEL_OP_SENSOR_SETTINGS_GET:
case BLE_MESH_MODEL_OP_SENSOR_SETTING_GET:
case BLE_MESH_MODEL_OP_SENSOR_GET:
case BLE_MESH_MODEL_OP_SENSOR_COLUMN_GET:
case BLE_MESH_MODEL_OP_SENSOR_SERIES_GET:
evt = BTC_BLE_MESH_EVT_SENSOR_CLIENT_GET_STATE;
break;
case BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET:
case BLE_MESH_MODEL_OP_SENSOR_SETTING_SET:
evt = BTC_BLE_MESH_EVT_SENSOR_CLIENT_SET_STATE;
break;
default:
break;
}
if (!k_delayed_work_free(&node->timer)) {
uint32_t opcode = node->opcode;
bt_mesh_client_free_node(node);
bt_mesh_sensor_client_cb_evt_to_btc(opcode, evt, model, ctx, val, len);
}
}
bt_mesh_mutex_unlock(&sensor_client_lock);
switch (ctx->recv_op) {
case BLE_MESH_MODEL_OP_SENSOR_DESCRIPTOR_STATUS: {
struct bt_mesh_sensor_descriptor_status *status;
status = (struct bt_mesh_sensor_descriptor_status *)val;
bt_mesh_free_buf(status->descriptor);
break;
}
case BLE_MESH_MODEL_OP_SENSOR_CADENCE_STATUS: {
struct bt_mesh_sensor_cadence_status *status;
status = (struct bt_mesh_sensor_cadence_status *)val;
bt_mesh_free_buf(status->sensor_cadence_value);
break;
}
case BLE_MESH_MODEL_OP_SENSOR_SETTINGS_STATUS: {
struct bt_mesh_sensor_settings_status *status;
status = (struct bt_mesh_sensor_settings_status *)val;
bt_mesh_free_buf(status->sensor_setting_property_ids);
break;
}
case BLE_MESH_MODEL_OP_SENSOR_SETTING_STATUS: {
struct bt_mesh_sensor_setting_status *status;
status = (struct bt_mesh_sensor_setting_status *)val;
bt_mesh_free_buf(status->sensor_setting_raw);
break;
}
case BLE_MESH_MODEL_OP_SENSOR_STATUS: {
struct bt_mesh_sensor_status *status;
status = (struct bt_mesh_sensor_status *)val;
bt_mesh_free_buf(status->marshalled_sensor_data);
break;
}
case BLE_MESH_MODEL_OP_SENSOR_COLUMN_STATUS: {
struct bt_mesh_sensor_column_status *status;
status = (struct bt_mesh_sensor_column_status *)val;
bt_mesh_free_buf(status->sensor_column_value);
break;
}
case BLE_MESH_MODEL_OP_SENSOR_SERIES_STATUS: {
struct bt_mesh_sensor_series_status *status;
status = (struct bt_mesh_sensor_series_status *)val;
bt_mesh_free_buf(status->sensor_series_value);
break;
}
default:
break;
}
bt_mesh_free(val);
}
const struct bt_mesh_model_op bt_mesh_sensor_cli_op[] = {
{ BLE_MESH_MODEL_OP_SENSOR_DESCRIPTOR_STATUS, 0, sensor_status },
{ BLE_MESH_MODEL_OP_SENSOR_CADENCE_STATUS, 2, sensor_status },
{ BLE_MESH_MODEL_OP_SENSOR_SETTINGS_STATUS, 2, sensor_status },
{ BLE_MESH_MODEL_OP_SENSOR_SETTING_STATUS, 4, sensor_status },
{ BLE_MESH_MODEL_OP_SENSOR_STATUS, 0, sensor_status },
{ BLE_MESH_MODEL_OP_SENSOR_COLUMN_STATUS, 2, sensor_status },
{ BLE_MESH_MODEL_OP_SENSOR_SERIES_STATUS, 2, sensor_status },
BLE_MESH_MODEL_OP_END,
};
static int sensor_act_state(bt_mesh_client_common_param_t *common,
void *value, uint16_t value_len, bool need_ack)
{
struct net_buf_simple *msg = NULL;
int err = 0;
msg = bt_mesh_alloc_buf(value_len);
if (!msg) {
BT_ERR("%s, Out of memory", __func__);
return -ENOMEM;
}
bt_mesh_model_msg_init(msg, common->opcode);
switch (common->opcode) {
case BLE_MESH_MODEL_OP_SENSOR_DESCRIPTOR_GET: {
struct bt_mesh_sensor_descriptor_get *act;
act = (struct bt_mesh_sensor_descriptor_get *)value;
if (act->op_en) {
net_buf_simple_add_le16(msg, act->property_id);
}
break;
}
case BLE_MESH_MODEL_OP_SENSOR_CADENCE_GET: {
struct bt_mesh_sensor_cadence_get *act;
act = (struct bt_mesh_sensor_cadence_get *)value;
net_buf_simple_add_le16(msg, act->property_id);
break;
}
case BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET:
case BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET_UNACK: {
struct bt_mesh_sensor_cadence_set *act;
act = (struct bt_mesh_sensor_cadence_set *)value;
net_buf_simple_add_le16(msg, act->property_id);
net_buf_simple_add_u8(msg, act->status_trigger_type << 7 | act->fast_cadence_period_divisor);
net_buf_simple_add_mem(msg, act->status_trigger_delta_down->data, act->status_trigger_delta_down->len);
net_buf_simple_add_mem(msg, act->status_trigger_delta_up->data, act->status_trigger_delta_up->len);
net_buf_simple_add_u8(msg, act->status_min_interval);
net_buf_simple_add_mem(msg, act->fast_cadence_low->data, act->fast_cadence_low->len);
net_buf_simple_add_mem(msg, act->fast_cadence_high->data, act->fast_cadence_high->len);
break;
}
case BLE_MESH_MODEL_OP_SENSOR_SETTINGS_GET: {
struct bt_mesh_sensor_settings_get *act;
act = (struct bt_mesh_sensor_settings_get *)value;
net_buf_simple_add_le16(msg, act->sensor_property_id);
break;
}
case BLE_MESH_MODEL_OP_SENSOR_SETTING_GET: {
struct bt_mesh_sensor_setting_get *act;
act = (struct bt_mesh_sensor_setting_get *)value;
net_buf_simple_add_le16(msg, act->sensor_property_id);
net_buf_simple_add_le16(msg, act->sensor_setting_property_id);
break;
}
case BLE_MESH_MODEL_OP_SENSOR_SETTING_SET:
case BLE_MESH_MODEL_OP_SENSOR_SETTING_SET_UNACK: {
struct bt_mesh_sensor_setting_set *act;
act = (struct bt_mesh_sensor_setting_set *)value;
net_buf_simple_add_le16(msg, act->sensor_property_id);
net_buf_simple_add_le16(msg, act->sensor_setting_property_id);
net_buf_simple_add_mem(msg, act->sensor_setting_raw->data, act->sensor_setting_raw->len);
break;
}
case BLE_MESH_MODEL_OP_SENSOR_GET: {
struct bt_mesh_sensor_get *act;
act = (struct bt_mesh_sensor_get *)value;
if (act->op_en) {
net_buf_simple_add_le16(msg, act->property_id);
}
break;
}
case BLE_MESH_MODEL_OP_SENSOR_COLUMN_GET: {
struct bt_mesh_sensor_column_get *act;
act = (struct bt_mesh_sensor_column_get *)value;
net_buf_simple_add_le16(msg, act->property_id);
net_buf_simple_add_mem(msg, act->raw_value_x->data, act->raw_value_x->len);
break;
}
case BLE_MESH_MODEL_OP_SENSOR_SERIES_GET: {
struct bt_mesh_sensor_series_get *act;
act = (struct bt_mesh_sensor_series_get *)value;
net_buf_simple_add_le16(msg, act->property_id);
if (act->op_en) {
net_buf_simple_add_mem(msg, act->raw_value_x1->data, act->raw_value_x1->len);
net_buf_simple_add_mem(msg, act->raw_value_x2->data, act->raw_value_x2->len);
}
break;
}
default:
BT_ERR("Invalid Sensor client opcode 0x%04x", common->opcode);
err = -EINVAL;
goto end;
}
err = bt_mesh_client_send_msg(common, msg, need_ack, timeout_handler);
end:
bt_mesh_free_buf(msg);
return err;
}
int bt_mesh_sensor_client_get_state(bt_mesh_client_common_param_t *common, void *get)
{
bt_mesh_sensor_client_t *client = NULL;
uint16_t length = 0U;
if (!common || !common->model || !get) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
client = (bt_mesh_sensor_client_t *)common->model->user_data;
if (!client || !client->internal_data) {
BT_ERR("Invalid Sensor client data");
return -EINVAL;
}
switch (common->opcode) {
case BLE_MESH_MODEL_OP_SENSOR_DESCRIPTOR_GET:
length = BLE_MESH_SENSOR_DESCRIPTOR_GET_MSG_LEN;
break;
case BLE_MESH_MODEL_OP_SENSOR_CADENCE_GET:
length = BLE_MESH_SENSOR_CADENCE_GET_MSG_LEN;
break;
case BLE_MESH_MODEL_OP_SENSOR_SETTINGS_GET:
length = BLE_MESH_SENSOR_SETTINGS_GET_MSG_LEN;
break;
case BLE_MESH_MODEL_OP_SENSOR_SETTING_GET:
length = BLE_MESH_SENSOR_SETTING_GET_MSG_LEN;
break;
case BLE_MESH_MODEL_OP_SENSOR_GET:
length = BLE_MESH_SENSOR_GET_MSG_LEN;
break;
case BLE_MESH_MODEL_OP_SENSOR_COLUMN_GET: {
struct bt_mesh_sensor_column_get *value;
value = (struct bt_mesh_sensor_column_get *)get;
if (!value->raw_value_x) {
BT_ERR("Invalid Sensor Column Get");
return -EINVAL;
}
length = (2 + 2 + value->raw_value_x->len + 4);
break;
}
case BLE_MESH_MODEL_OP_SENSOR_SERIES_GET: {
struct bt_mesh_sensor_series_get *value;
value = (struct bt_mesh_sensor_series_get *)get;
if (value->op_en) {
if (!value->raw_value_x1 || !value->raw_value_x2) {
BT_ERR("Invalid Sensor Series Get");
return -EINVAL;
}
}
if (value->op_en) {
length = value->raw_value_x1->len + value->raw_value_x2->len;
}
length += (2 + 2 + 4);
break;
}
default:
BT_ERR("Invalid Sensor Get opcode 0x%04x", common->opcode);
return -EINVAL;
}
return sensor_act_state(common, get, length, true);
}
int bt_mesh_sensor_client_set_state(bt_mesh_client_common_param_t *common, void *set)
{
bt_mesh_sensor_client_t *client = NULL;
uint16_t length = 0U;
bool need_ack = false;
if (!common || !common->model || !set) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
client = (bt_mesh_sensor_client_t *)common->model->user_data;
if (!client || !client->internal_data) {
BT_ERR("Invalid Sensor client data");
return -EINVAL;
}
switch (common->opcode) {
case BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET:
need_ack = true;
case BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET_UNACK: {
struct bt_mesh_sensor_cadence_set *value;
value = (struct bt_mesh_sensor_cadence_set *)set;
if (!value->status_trigger_delta_down || !value->status_trigger_delta_up ||
!value->fast_cadence_low || !value->fast_cadence_high) {
BT_ERR("Invalid Sensor Cadence Set");
return -EINVAL;
}
length = value->status_trigger_delta_down->len + \
value->status_trigger_delta_up->len + \
value->fast_cadence_low->len + \
value->fast_cadence_high->len;
length += (1 + 2 + 1 + 1 + 4);
break;
}
case BLE_MESH_MODEL_OP_SENSOR_SETTING_SET:
need_ack = true;
case BLE_MESH_MODEL_OP_SENSOR_SETTING_SET_UNACK: {
struct bt_mesh_sensor_setting_set *value;
value = (struct bt_mesh_sensor_setting_set *)set;
if (!value->sensor_setting_raw) {
BT_ERR("Invalid Sensor Setting Raw value");
return -EINVAL;
}
length = (1 + 2 + 2 + value->sensor_setting_raw->len + 4);
break;
}
default:
BT_ERR("Invalid Sensor Set opcode 0x%04x", common->opcode);
return -EINVAL;
}
return sensor_act_state(common, set, length, need_ack);
}
static int sensor_client_init(struct bt_mesh_model *model)
{
sensor_internal_data_t *internal = NULL;
bt_mesh_sensor_client_t *client = NULL;
if (!model) {
BT_ERR("Invalid Sensor client model");
return -EINVAL;
}
client = (bt_mesh_sensor_client_t *)model->user_data;
if (!client) {
BT_ERR("No Sensor client context provided");
return -EINVAL;
}
if (client->internal_data) {
BT_WARN("%s, Already", __func__);
return -EALREADY;
}
internal = bt_mesh_calloc(sizeof(sensor_internal_data_t));
if (!internal) {
BT_ERR("%s, Out of memory", __func__);
return -ENOMEM;
}
sys_slist_init(&internal->queue);
client->model = model;
client->op_pair_size = ARRAY_SIZE(sensor_op_pair);
client->op_pair = sensor_op_pair;
client->internal_data = internal;
bt_mesh_mutex_create(&sensor_client_lock);
return 0;
}
#if CONFIG_BLE_MESH_DEINIT
static int sensor_client_deinit(struct bt_mesh_model *model)
{
bt_mesh_sensor_client_t *client = NULL;
if (!model) {
BT_ERR("Invalid Sensor client model");
return -EINVAL;
}
client = (bt_mesh_sensor_client_t *)model->user_data;
if (!client) {
BT_ERR("No Sensor client context provided");
return -EINVAL;
}
if (client->internal_data) {
/* Remove items from the list */
bt_mesh_client_clear_list(client->internal_data);
/* Free the allocated internal data */
bt_mesh_free(client->internal_data);
client->internal_data = NULL;
}
bt_mesh_mutex_free(&sensor_client_lock);
return 0;
}
#endif /* CONFIG_BLE_MESH_DEINIT */
const struct bt_mesh_model_cb bt_mesh_sensor_client_cb = {
.init = sensor_client_init,
#if CONFIG_BLE_MESH_DEINIT
.deinit = sensor_client_deinit,
#endif /* CONFIG_BLE_MESH_DEINIT */
};
#endif /* CONFIG_BLE_MESH_SENSOR_CLI */
@@ -0,0 +1,681 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <errno.h>
#include "btc_ble_mesh_time_scene_model.h"
#include "mesh/config.h"
#include "mesh/model_opcode.h"
#if CONFIG_BLE_MESH_TIME_SCENE_CLIENT
#include "mesh/time_scene_client.h"
/* The followings are the macro definitions of Time Scene client
* model message length, and a message is composed of 3 parts:
* Opcode + Payload + MIC
*/
/* Time client messages length */
#define BLE_MESH_TIME_SET_MSG_LEN (1 + 10 + 4)
#define BLE_MESH_TIME_ZONE_SET_MSG_LEN (2 + 6 + 4)
#define BLE_MESH_TAI_UTC_DELTA_SET_MSG_LEN (2 + 7 + 4)
#define BLE_MESH_TIME_ROLE_SET_MSG_LEN (2 + 1 + 4)
/* Scene client messages length */
#define BLE_MESH_SCENE_STORE_MSG_LEN (2 + 2 + 4)
#define BLE_MESH_SCENE_RECALL_MSG_LEN (2 + 5 + 4)
#define BLE_MESH_SCENE_GET_MSG_LEN (2 + 0 + 4)
#define BLE_MESH_SCENE_REGISTER_GET_MSG_LEN (2 + 0 + 4)
#define BLE_MESH_SCENE_DELETE_MSG_LEN (2 + 2 + 4)
/* Scheduler client messages length */
#define BLE_MESH_SCHEDULER_ACT_GET_MSG_LEN (2 + 1 + 4)
#define BLE_MESH_SCHEDULER_ACT_SET_MSG_LEN (1 + 10 + 4)
#define BLE_MESH_SCENE_GET_STATE_MSG_LEN (2 + 1 + 4)
#define BLE_MESH_SCENE_ACT_STATE_MSG_LEN (2 + 2 + 4)
static const bt_mesh_client_op_pair_t time_scene_op_pair[] = {
{ BLE_MESH_MODEL_OP_TIME_GET, BLE_MESH_MODEL_OP_TIME_STATUS },
{ BLE_MESH_MODEL_OP_TIME_SET, BLE_MESH_MODEL_OP_TIME_STATUS },
{ BLE_MESH_MODEL_OP_TIME_ZONE_GET, BLE_MESH_MODEL_OP_TIME_ZONE_STATUS },
{ BLE_MESH_MODEL_OP_TIME_ZONE_SET, BLE_MESH_MODEL_OP_TIME_ZONE_STATUS },
{ BLE_MESH_MODEL_OP_TAI_UTC_DELTA_GET, BLE_MESH_MODEL_OP_TAI_UTC_DELTA_STATUS },
{ BLE_MESH_MODEL_OP_TAI_UTC_DELTA_SET, BLE_MESH_MODEL_OP_TAI_UTC_DELTA_STATUS },
{ BLE_MESH_MODEL_OP_TIME_ROLE_GET, BLE_MESH_MODEL_OP_TIME_ROLE_STATUS },
{ BLE_MESH_MODEL_OP_TIME_ROLE_SET, BLE_MESH_MODEL_OP_TIME_ROLE_STATUS },
{ BLE_MESH_MODEL_OP_SCENE_STORE, BLE_MESH_MODEL_OP_SCENE_REGISTER_STATUS },
{ BLE_MESH_MODEL_OP_SCENE_RECALL, BLE_MESH_MODEL_OP_SCENE_STATUS },
{ BLE_MESH_MODEL_OP_SCENE_GET, BLE_MESH_MODEL_OP_SCENE_STATUS },
{ BLE_MESH_MODEL_OP_SCENE_REGISTER_GET, BLE_MESH_MODEL_OP_SCENE_REGISTER_STATUS },
{ BLE_MESH_MODEL_OP_SCENE_DELETE, BLE_MESH_MODEL_OP_SCENE_REGISTER_STATUS },
{ BLE_MESH_MODEL_OP_SCHEDULER_GET, BLE_MESH_MODEL_OP_SCHEDULER_STATUS },
{ BLE_MESH_MODEL_OP_SCHEDULER_ACT_GET, BLE_MESH_MODEL_OP_SCHEDULER_ACT_STATUS },
{ BLE_MESH_MODEL_OP_SCHEDULER_ACT_SET, BLE_MESH_MODEL_OP_SCHEDULER_ACT_STATUS },
};
static bt_mesh_mutex_t time_scene_client_lock;
static void timeout_handler(struct k_work *work)
{
struct k_delayed_work *timer = NULL;
bt_mesh_client_node_t *node = NULL;
struct bt_mesh_model *model = NULL;
struct bt_mesh_msg_ctx ctx = {0};
uint32_t opcode = 0U;
BT_WARN("Receive time scene status message timeout");
bt_mesh_mutex_lock(&time_scene_client_lock);
timer = CONTAINER_OF(work, struct k_delayed_work, work);
if (timer && !k_delayed_work_free(timer)) {
node = CONTAINER_OF(work, bt_mesh_client_node_t, timer.work);
if (node) {
memcpy(&ctx, &node->ctx, sizeof(ctx));
opcode = node->opcode;
model = node->model;
bt_mesh_client_free_node(node);
bt_mesh_time_scene_client_cb_evt_to_btc(
opcode, BTC_BLE_MESH_EVT_TIME_SCENE_CLIENT_TIMEOUT, model, &ctx, NULL, 0);
}
}
bt_mesh_mutex_unlock(&time_scene_client_lock);
}
static void time_scene_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
bt_mesh_client_node_t *node = NULL;
uint8_t *val = NULL;
uint8_t evt = 0xFF;
size_t len = 0U;
BT_DBG("len %d, bytes %s", buf->len, bt_hex(buf->data, buf->len));
switch (ctx->recv_op) {
case BLE_MESH_MODEL_OP_TIME_STATUS: {
struct bt_mesh_time_status *status = NULL;
if (buf->len != 5 && buf->len != 10) {
BT_ERR("Invalid Time Status length %d", buf->len);
return;
}
status = bt_mesh_calloc(sizeof(struct bt_mesh_time_status));
if (!status) {
BT_ERR("%s, Out of memory", __func__);
return;
}
memcpy(status->tai_seconds, buf->data, 5);
net_buf_simple_pull(buf, 5);
status->sub_second = net_buf_simple_pull_u8(buf);
status->uncertainty = net_buf_simple_pull_u8(buf);
uint16_t temp = net_buf_simple_pull_le16(buf);
status->time_authority = temp & BIT(0);
status->tai_utc_delta = temp >> 15;
status->time_zone_offset = net_buf_simple_pull_u8(buf);
val = (uint8_t *)status;
len = sizeof(struct bt_mesh_time_status);
break;
}
case BLE_MESH_MODEL_OP_TIME_ZONE_STATUS: {
struct bt_mesh_time_zone_status *status = NULL;
if (buf->len != 7) {
BT_ERR("Invalid Time Zone Status length %d", buf->len);
return;
}
status = bt_mesh_calloc(sizeof(struct bt_mesh_time_zone_status));
if (!status) {
BT_ERR("%s, Out of memory", __func__);
return;
}
status->time_zone_offset_curr = net_buf_simple_pull_u8(buf);
status->time_zone_offset_new = net_buf_simple_pull_u8(buf);
memcpy(status->tai_zone_change, buf->data, 5);
net_buf_simple_pull(buf, 5);
val = (uint8_t *)status;
len = sizeof(struct bt_mesh_time_zone_status);
break;
}
case BLE_MESH_MODEL_OP_TAI_UTC_DELTA_STATUS: {
struct bt_mesh_tai_utc_delta_status *status = NULL;
if (buf->len != 9) {
BT_ERR("Invalid TAI UTC Delta Status length %d", buf->len);
return;
}
status = bt_mesh_calloc(sizeof(struct bt_mesh_tai_utc_delta_status));
if (!status) {
BT_ERR("%s, Out of memory", __func__);
return;
}
uint16_t temp = net_buf_simple_pull_le16(buf);
status->tai_utc_delta_curr = temp & BIT_MASK(15);
status->padding_1 = (temp >> 15) & BIT(0);
temp = net_buf_simple_pull_le16(buf);
status->tai_utc_delta_new = temp & BIT_MASK(15);
status->padding_2 = (temp >> 15) & BIT(0);
memcpy(status->tai_delta_change, buf->data, 5);
net_buf_simple_pull(buf, 5);
val = (uint8_t *)status;
len = sizeof(struct bt_mesh_tai_utc_delta_status);
break;
}
case BLE_MESH_MODEL_OP_TIME_ROLE_STATUS: {
struct bt_mesh_time_role_status *status = NULL;
if (buf->len != 1) {
BT_ERR("Invalid Time Role Status length %d", buf->len);
return;
}
status = bt_mesh_calloc(sizeof(struct bt_mesh_time_role_status));
if (!status) {
BT_ERR("%s, Out of memory", __func__);
return;
}
status->time_role = net_buf_simple_pull_u8(buf);
val = (uint8_t *)status;
len = sizeof(struct bt_mesh_time_role_status);
break;
}
case BLE_MESH_MODEL_OP_SCENE_STATUS: {
struct bt_mesh_scene_status *status = NULL;
if (buf->len != 3 && buf->len != 6) {
BT_ERR("Invalid Scene Status length %d", buf->len);
return;
}
status = bt_mesh_calloc(sizeof(struct bt_mesh_scene_status));
if (!status) {
BT_ERR("%s, Out of memory", __func__);
return;
}
status->status_code = net_buf_simple_pull_u8(buf);
status->current_scene = net_buf_simple_pull_le16(buf);
if (buf->len) {
status->op_en = true;
status->target_scene = net_buf_simple_pull_le16(buf);
status->remain_time = net_buf_simple_pull_u8(buf);
}
val = (uint8_t *)status;
len = sizeof(struct bt_mesh_scene_status);
break;
}
case BLE_MESH_MODEL_OP_SCENE_REGISTER_STATUS: {
struct bt_mesh_scene_register_status *status = NULL;
status = bt_mesh_calloc(sizeof(struct bt_mesh_scene_register_status));
if (!status) {
BT_ERR("%s, Out of memory", __func__);
return;
}
status->status_code = net_buf_simple_pull_u8(buf);
status->current_scene = net_buf_simple_pull_le16(buf);
status->scenes = bt_mesh_alloc_buf(buf->len);
if (!status->scenes) {
BT_ERR("%s, Out of memory", __func__);
bt_mesh_free(status);
return;
}
net_buf_simple_add_mem(status->scenes, buf->data, buf->len);
val = (uint8_t *)status;
len = sizeof(struct bt_mesh_scene_register_status);
break;
}
case BLE_MESH_MODEL_OP_SCHEDULER_STATUS: {
struct bt_mesh_scheduler_status *status = NULL;
if (buf->len != 2) {
BT_ERR("Invalid Scheduler Status length %d", buf->len);
return;
}
status = bt_mesh_calloc(sizeof(struct bt_mesh_scheduler_status));
if (!status) {
BT_ERR("%s, Out of memory", __func__);
return;
}
status->schedules = net_buf_simple_pull_le16(buf);
val = (uint8_t *)status;
len = sizeof(struct bt_mesh_scheduler_status);
break;
}
case BLE_MESH_MODEL_OP_SCHEDULER_ACT_STATUS: {
struct bt_mesh_scheduler_act_status *status = NULL;
if (buf->len != 10) {
BT_ERR("Invalid Scheduler Action Status length %d", buf->len);
return;
}
status = bt_mesh_calloc(sizeof(struct bt_mesh_scheduler_act_status));
if (!status) {
BT_ERR("%s, Out of memory", __func__);
return;
}
memcpy(status, buf->data, offsetof(struct bt_mesh_scheduler_act_status, scene_number));
net_buf_simple_pull(buf, offsetof(struct bt_mesh_scheduler_act_status, scene_number));
status->scene_number = net_buf_simple_pull_le16(buf);
val = (uint8_t *)status;
len = sizeof(struct bt_mesh_scheduler_act_status);
break;
}
default:
BT_ERR("Invalid Time Scene Status opcode 0x%04x", ctx->recv_op);
return;
}
buf->data = val;
buf->len = len;
bt_mesh_mutex_lock(&time_scene_client_lock);
node = bt_mesh_is_client_recv_publish_msg(model, ctx, buf, true);
if (!node) {
BT_DBG("Unexpected Time Scene Status 0x%04x", ctx->recv_op);
} else {
switch (node->opcode) {
case BLE_MESH_MODEL_OP_TIME_GET:
case BLE_MESH_MODEL_OP_TIME_ZONE_GET:
case BLE_MESH_MODEL_OP_TAI_UTC_DELTA_GET:
case BLE_MESH_MODEL_OP_TIME_ROLE_GET:
case BLE_MESH_MODEL_OP_SCENE_GET:
case BLE_MESH_MODEL_OP_SCENE_REGISTER_GET:
case BLE_MESH_MODEL_OP_SCHEDULER_GET:
case BLE_MESH_MODEL_OP_SCHEDULER_ACT_GET:
evt = BTC_BLE_MESH_EVT_TIME_SCENE_CLIENT_GET_STATE;
break;
case BLE_MESH_MODEL_OP_TIME_SET:
case BLE_MESH_MODEL_OP_TIME_ZONE_SET:
case BLE_MESH_MODEL_OP_TAI_UTC_DELTA_SET:
case BLE_MESH_MODEL_OP_TIME_ROLE_SET:
case BLE_MESH_MODEL_OP_SCENE_STORE:
case BLE_MESH_MODEL_OP_SCENE_RECALL:
case BLE_MESH_MODEL_OP_SCENE_DELETE:
case BLE_MESH_MODEL_OP_SCHEDULER_ACT_SET:
evt = BTC_BLE_MESH_EVT_TIME_SCENE_CLIENT_SET_STATE;
break;
default:
break;
}
if (!k_delayed_work_free(&node->timer)) {
uint32_t opcode = node->opcode;
bt_mesh_client_free_node(node);
bt_mesh_time_scene_client_cb_evt_to_btc(opcode, evt, model, ctx, val, len);
}
}
bt_mesh_mutex_unlock(&time_scene_client_lock);
switch (ctx->recv_op) {
case BLE_MESH_MODEL_OP_SCENE_REGISTER_STATUS: {
struct bt_mesh_scene_register_status *status;
status = (struct bt_mesh_scene_register_status *)val;
bt_mesh_free_buf(status->scenes);
break;
}
default:
break;
}
bt_mesh_free(val);
}
const struct bt_mesh_model_op bt_mesh_time_cli_op[] = {
{ BLE_MESH_MODEL_OP_TIME_STATUS, 5, time_scene_status },
{ BLE_MESH_MODEL_OP_TIME_ZONE_STATUS, 7, time_scene_status },
{ BLE_MESH_MODEL_OP_TAI_UTC_DELTA_STATUS, 9, time_scene_status },
{ BLE_MESH_MODEL_OP_TIME_ROLE_STATUS, 1, time_scene_status },
BLE_MESH_MODEL_OP_END,
};
const struct bt_mesh_model_op bt_mesh_scene_cli_op[] = {
{ BLE_MESH_MODEL_OP_SCENE_STATUS, 3, time_scene_status },
{ BLE_MESH_MODEL_OP_SCENE_REGISTER_STATUS, 3, time_scene_status },
BLE_MESH_MODEL_OP_END,
};
const struct bt_mesh_model_op bt_mesh_scheduler_cli_op[] = {
{ BLE_MESH_MODEL_OP_SCHEDULER_STATUS, 2, time_scene_status },
{ BLE_MESH_MODEL_OP_SCHEDULER_ACT_STATUS, 10, time_scene_status },
BLE_MESH_MODEL_OP_END,
};
static int time_scene_get_state(bt_mesh_client_common_param_t *common, void *value)
{
NET_BUF_SIMPLE_DEFINE(msg, BLE_MESH_SCENE_GET_STATE_MSG_LEN);
bt_mesh_model_msg_init(&msg, common->opcode);
if (value) {
switch (common->opcode) {
case BLE_MESH_MODEL_OP_SCHEDULER_ACT_GET: {
struct bt_mesh_scheduler_act_get *get;
get = (struct bt_mesh_scheduler_act_get *)value;
net_buf_simple_add_u8(&msg, get->index);
break;
}
default:
BT_DBG("No parameters for Time Scene Get 0x%04x", common->opcode);
break;
}
}
return bt_mesh_client_send_msg(common, &msg, true, timeout_handler);
}
static int time_scene_set_state(bt_mesh_client_common_param_t *common,
void *value, uint16_t value_len, bool need_ack)
{
struct net_buf_simple *msg = NULL;
int err = 0;
msg = bt_mesh_alloc_buf(value_len);
if (!msg) {
BT_ERR("%s, Out of memory", __func__);
return -ENOMEM;
}
bt_mesh_model_msg_init(msg, common->opcode);
switch (common->opcode) {
case BLE_MESH_MODEL_OP_TIME_SET: {
struct bt_mesh_time_set *set;
set = (struct bt_mesh_time_set *)value;
net_buf_simple_add_mem(msg, set->tai_seconds, 5);
net_buf_simple_add_u8(msg, set->sub_second);
net_buf_simple_add_u8(msg, set->uncertainty);
net_buf_simple_add_le16(msg, set->tai_utc_delta << 1 | set->time_authority);
net_buf_simple_add_u8(msg, set->time_zone_offset);
break;
}
case BLE_MESH_MODEL_OP_TIME_ZONE_SET: {
struct bt_mesh_time_zone_set *set;
set = (struct bt_mesh_time_zone_set *)value;
net_buf_simple_add_u8(msg, set->time_zone_offset_new);
net_buf_simple_add_mem(msg, set->tai_zone_change, 5);
break;
}
case BLE_MESH_MODEL_OP_TAI_UTC_DELTA_SET: {
struct bt_mesh_tai_utc_delta_set *set;
set = (struct bt_mesh_tai_utc_delta_set *)value;
net_buf_simple_add_le16(msg, set->padding << 15 | set->tai_utc_delta_new);
net_buf_simple_add_mem(msg, set->tai_delta_change, 5);
break;
}
case BLE_MESH_MODEL_OP_TIME_ROLE_SET: {
struct bt_mesh_time_role_set *set;
set = (struct bt_mesh_time_role_set *)value;
net_buf_simple_add_u8(msg, set->time_role);
break;
}
case BLE_MESH_MODEL_OP_SCENE_STORE:
case BLE_MESH_MODEL_OP_SCENE_STORE_UNACK: {
struct bt_mesh_scene_store *set;
set = (struct bt_mesh_scene_store *)value;
net_buf_simple_add_le16(msg, set->scene_number);
break;
}
case BLE_MESH_MODEL_OP_SCENE_RECALL:
case BLE_MESH_MODEL_OP_SCENE_RECALL_UNACK: {
struct bt_mesh_scene_recall *set;
set = (struct bt_mesh_scene_recall *)value;
net_buf_simple_add_le16(msg, set->scene_number);
net_buf_simple_add_u8(msg, set->tid);
if (set->op_en) {
net_buf_simple_add_u8(msg, set->trans_time);
net_buf_simple_add_u8(msg, set->delay);
}
break;
}
case BLE_MESH_MODEL_OP_SCENE_DELETE:
case BLE_MESH_MODEL_OP_SCENE_DELETE_UNACK: {
struct bt_mesh_scene_delete *set;
set = (struct bt_mesh_scene_delete *)value;
net_buf_simple_add_le16(msg, set->scene_number);
break;
}
case BLE_MESH_MODEL_OP_SCHEDULER_ACT_SET:
case BLE_MESH_MODEL_OP_SCHEDULER_ACT_SET_UNACK: {
struct bt_mesh_scheduler_act_set *set;
set = (struct bt_mesh_scheduler_act_set *)value;
net_buf_simple_add_mem(msg, set, offsetof(struct bt_mesh_scheduler_act_set, scene_number));
net_buf_simple_add_le16(msg, set->scene_number);
break;
}
default:
BT_ERR("Invalid Time Scene Set opcode 0x%04x", common->opcode);
err = -EINVAL;
goto end;
}
err = bt_mesh_client_send_msg(common, msg, need_ack, timeout_handler);
end:
bt_mesh_free_buf(msg);
return err;
}
int bt_mesh_time_scene_client_get_state(bt_mesh_client_common_param_t *common, void *get)
{
bt_mesh_time_scene_client_t *client = NULL;
if (!common || !common->model) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
client = (bt_mesh_time_scene_client_t *)common->model->user_data;
if (!client || !client->internal_data) {
BT_ERR("Invalid Time Scene client data");
return -EINVAL;
}
switch (common->opcode) {
case BLE_MESH_MODEL_OP_TIME_GET:
case BLE_MESH_MODEL_OP_TIME_ZONE_GET:
case BLE_MESH_MODEL_OP_TAI_UTC_DELTA_GET:
case BLE_MESH_MODEL_OP_TIME_ROLE_GET:
case BLE_MESH_MODEL_OP_SCENE_GET:
case BLE_MESH_MODEL_OP_SCENE_REGISTER_GET:
case BLE_MESH_MODEL_OP_SCHEDULER_GET:
break;
case BLE_MESH_MODEL_OP_SCHEDULER_ACT_GET:
if (!get) {
BT_ERR("Invalid Scheduler Action Get");
return -EINVAL;
}
break;
default:
BT_ERR("Invalid Time Scene Get opcode 0x%04x", common->opcode);
return -EINVAL;
}
return time_scene_get_state(common, get);
}
int bt_mesh_time_scene_client_set_state(bt_mesh_client_common_param_t *common, void *set)
{
bt_mesh_time_scene_client_t *client = NULL;
uint16_t length = 0U;
bool need_ack = false;
if (!common || !common->model || !set) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
client = (bt_mesh_time_scene_client_t *)common->model->user_data;
if (!client || !client->internal_data) {
BT_ERR("Invalid Time Scene client data");
return -EINVAL;
}
switch (common->opcode) {
case BLE_MESH_MODEL_OP_TIME_SET:
need_ack = true;
length = BLE_MESH_TIME_SET_MSG_LEN;
break;
case BLE_MESH_MODEL_OP_TIME_ZONE_SET:
need_ack = true;
length = BLE_MESH_TIME_ZONE_SET_MSG_LEN;
break;
case BLE_MESH_MODEL_OP_TAI_UTC_DELTA_SET: {
struct bt_mesh_tai_utc_delta_set *value;
value = (struct bt_mesh_tai_utc_delta_set *)set;
if (value->padding) {
BT_ERR("Non-zero padding value is prohibited");
return -EINVAL;
}
need_ack = true;
length = BLE_MESH_TAI_UTC_DELTA_SET_MSG_LEN;
break;
}
case BLE_MESH_MODEL_OP_TIME_ROLE_SET: {
struct bt_mesh_time_role_set *value;
value = (struct bt_mesh_time_role_set *)set;
if (value->time_role > 0x03) {
BT_ERR("Time role 0x%02x is prohibited", value->time_role);
return -EINVAL;
}
need_ack = true;
length = BLE_MESH_TIME_ROLE_SET_MSG_LEN;
break;
}
case BLE_MESH_MODEL_OP_SCENE_STORE:
need_ack = true;
case BLE_MESH_MODEL_OP_SCENE_STORE_UNACK: {
struct bt_mesh_scene_store *value;
value = (struct bt_mesh_scene_store *)set;
if (!value->scene_number) {
BT_ERR("Scene Store scene number 0x0000 is prohibited");
return -EINVAL;
}
length = BLE_MESH_SCENE_STORE_MSG_LEN;
break;
}
case BLE_MESH_MODEL_OP_SCENE_RECALL:
need_ack = true;
case BLE_MESH_MODEL_OP_SCENE_RECALL_UNACK: {
struct bt_mesh_scene_recall *value;
value = (struct bt_mesh_scene_recall *)set;
if (!value->scene_number) {
BT_ERR("Scene Recall scene number 0x0000 is prohibited");
return -EINVAL;
}
if (value->op_en) {
if ((value->trans_time & 0x3F) > 0x3E) {
BT_ERR("Invalid Scene Recall transition time");
return -EINVAL;
}
}
length = BLE_MESH_SCENE_RECALL_MSG_LEN;
break;
}
case BLE_MESH_MODEL_OP_SCENE_DELETE:
need_ack = true;
case BLE_MESH_MODEL_OP_SCENE_DELETE_UNACK: {
length = BLE_MESH_SCENE_DELETE_MSG_LEN;
break;
}
case BLE_MESH_MODEL_OP_SCHEDULER_ACT_SET:
need_ack = true;
case BLE_MESH_MODEL_OP_SCHEDULER_ACT_SET_UNACK: {
struct bt_mesh_scheduler_act_set *value;
value = (struct bt_mesh_scheduler_act_set *)set;
if (value->year > 0x64) {
BT_ERR("Scheduler Register year 0x%02x is prohibited", value->year);
return -EINVAL;
}
if (value->hour > 0x19) {
BT_ERR("Scheduler Register hour 0x%02x is prohibited", value->hour);
return -EINVAL;
}
length = BLE_MESH_SCHEDULER_ACT_SET_MSG_LEN;
break;
}
default:
BT_ERR("Invalid Time Scene Set opcode 0x%04x", common->opcode);
return -EINVAL;
}
return time_scene_set_state(common, set, length, need_ack);
}
static int time_scene_client_init(struct bt_mesh_model *model)
{
time_scene_internal_data_t *internal = NULL;
bt_mesh_time_scene_client_t *client = NULL;
if (!model) {
BT_ERR("Invalid Time Scene client model");
return -EINVAL;
}
client = (bt_mesh_time_scene_client_t *)model->user_data;
if (!client) {
BT_ERR("No Time Scene client context provided");
return -EINVAL;
}
if (client->internal_data) {
BT_WARN("%s, Already", __func__);
return -EALREADY;
}
internal = bt_mesh_calloc(sizeof(time_scene_internal_data_t));
if (!internal) {
BT_ERR("%s, Out of memory", __func__);
return -ENOMEM;
}
sys_slist_init(&internal->queue);
client->model = model;
client->op_pair_size = ARRAY_SIZE(time_scene_op_pair);
client->op_pair = time_scene_op_pair;
client->internal_data = internal;
bt_mesh_mutex_create(&time_scene_client_lock);
return 0;
}
#if CONFIG_BLE_MESH_DEINIT
static int time_scene_client_deinit(struct bt_mesh_model *model)
{
bt_mesh_time_scene_client_t *client = NULL;
if (!model) {
BT_ERR("Invalid Time Scene client model");
return -EINVAL;
}
client = (bt_mesh_time_scene_client_t *)model->user_data;
if (!client) {
BT_ERR("No Time Scene client context provided");
return -EINVAL;
}
if (client->internal_data) {
/* Remove items from the list */
bt_mesh_client_clear_list(client->internal_data);
/* Free the allocated internal data */
bt_mesh_free(client->internal_data);
client->internal_data = NULL;
}
bt_mesh_mutex_free(&time_scene_client_lock);
return 0;
}
#endif /* CONFIG_BLE_MESH_DEINIT */
const struct bt_mesh_model_cb bt_mesh_time_scene_client_cb = {
.init = time_scene_client_init,
#if CONFIG_BLE_MESH_DEINIT
.deinit = time_scene_client_deinit,
#endif /* CONFIG_BLE_MESH_DEINIT */
};
#endif /* CONFIG_BLE_MESH_TIME_SCENE_CLIENT */
@@ -0,0 +1,209 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "mesh/common.h"
#include "mesh/server_common.h"
#include "mesh/device_property.h"
static struct bt_mesh_dev_prop {
uint16_t prop_id;
uint8_t len;
} device_properties[] = {
{ BLE_MESH_INVALID_DEVICE_PROPERTY_ID, 0xFF }, /* Prohibited */
{ BLE_MESH_AVERAGE_AMBIENT_TEMPERATURE_IN_A_PERIOD_OF_DAY, 0x03 },
{ BLE_MESH_AVERAGE_INPUT_CURRENT, 0x03 },
{ BLE_MESH_AVERAGE_INPUT_VOLTAGE, 0x03 },
{ BLE_MESH_AVERAGE_OUTPUT_CURRENT, 0x03 },
{ BLE_MESH_AVERAGE_OUTPUT_VOLTAGE, 0x03 },
{ BLE_MESH_CENTER_BEAM_INTENSITY_AT_FULL_POWER, 0x02 },
{ BLE_MESH_CHROMATICITY_TOLERANCE, 0x01 },
{ BLE_MESH_COLOR_RENDERING_INDEX_R9, 0x01 },
{ BLE_MESH_COLOR_RENDERING_INDEX_RA, 0x01 },
{ BLE_MESH_DEVICE_APPEARANCE, 0x02 },
{ BLE_MESH_DEVICE_COUNTRY_OF_ORIGIN, 0x02 },
{ BLE_MESH_DEVICE_DATE_OF_MANUFACTURE, 0x03 },
{ BLE_MESH_DEVICE_ENERGY_USE_SINCE_TURN_ON, 0x03 },
{ BLE_MESH_DEVICE_FIRMWARE_REVISION, 0x08 },
{ BLE_MESH_DEVICE_GLOBAL_TRADE_ITEM_NUMBER, 0x06 },
{ BLE_MESH_DEVICE_HARDWARE_REVISION, 0x10 },
{ BLE_MESH_DEVICE_MANUFACTURER_NAME, 0x24 },
{ BLE_MESH_DEVICE_MODEL_NUMBER, 0x18 },
{ BLE_MESH_DEVICE_OPERATING_TEMPERATURE_RANGE_SPECIFICATION, 0x04 },
{ BLE_MESH_DEVICE_OPERATING_TEMPERATURE_STATISTICAL_VALUES, 0x09 },
{ BLE_MESH_DEVICE_OVER_TEMPERATURE_EVENT_STATISTICS, 0x06 },
{ BLE_MESH_DEVICE_POWER_RANGE_SPECIFICATION, 0x09 },
{ BLE_MESH_DEVICE_RUNTIME_SINCE_TURN_ON, 0x03 },
{ BLE_MESH_DEVICE_RUNTIME_WARRANTY, 0x03 },
{ BLE_MESH_DEVICE_SERIAL_NUMBER, 0x10 },
{ BLE_MESH_DEVICE_SOFTWARE_REVISION, 0x08 },
{ BLE_MESH_DEVICE_UNDER_TEMPERATURE_EVENT_STATISTICS, 0x06 },
{ BLE_MESH_INDOOR_AMBIENT_TEMPERATURE_STATISTICAL_VALUES, 0x05 },
{ BLE_MESH_INITIAL_CIE_1931_CHROMATICITY_COORDINATES, 0x04 },
{ BLE_MESH_INITIAL_CORRELATED_COLOR_TEMPERATURE, 0x02 },
{ BLE_MESH_INITIAL_LUMINOUS_FLUX, 0x02 },
{ BLE_MESH_INITIAL_PLANCKIAN_DISTANCE, 0x02 },
{ BLE_MESH_INPUT_CURRENT_RANGE_SPECIFICATION, 0x06 },
{ BLE_MESH_INPUT_CURRENT_STATISTICS, 0x09 },
{ BLE_MESH_INPUT_OVER_CURRENT_EVENT_STATISTICS, 0x06 },
{ BLE_MESH_INPUT_OVER_RIPPLE_VOLTAGE_EVENT_STATISTICS, 0x06 },
{ BLE_MESH_INPUT_OVER_VOLTAGE_EVENT_STATISTICS, 0x06 },
{ BLE_MESH_INPUT_UNDER_CURRENT_EVENT_STATISTICS, 0x06 },
{ BLE_MESH_INPUT_UNDER_VOLTAGE_EVENT_STATISTICS, 0x06 },
{ BLE_MESH_INPUT_VOLTAGE_RANGE_SPECIFICATION, 0x06 },
{ BLE_MESH_INPUT_VOLTAGE_RIPPLE_SPECIFICATION, 0x01 },
{ BLE_MESH_INPUT_VOLTAGE_STATISTICS, 0x09 },
{ BLE_MESH_LIGHT_CONTROL_AMBIENT_LUXLEVEL_ON, 0x03 },
{ BLE_MESH_LIGHT_CONTROL_AMBIENT_LUXLEVEL_PROLONG, 0x03 },
{ BLE_MESH_LIGHT_CONTROL_AMBIENT_LUXLEVEL_STANDBY, 0x03 },
{ BLE_MESH_LIGHT_CONTROL_LIGHTNESS_ON, 0x02 },
{ BLE_MESH_LIGHT_CONTROL_LIGHTNESS_PROLONG, 0x02 },
{ BLE_MESH_LIGHT_CONTROL_LIGHTNESS_STANDBY, 0x02 },
{ BLE_MESH_LIGHT_CONTROL_REGULATOR_ACCURACY, 0x01 },
{ BLE_MESH_LIGHT_CONTROL_REGULATOR_KID, 0x04 },
{ BLE_MESH_LIGHT_CONTROL_REGULATOR_KIU, 0x04 },
{ BLE_MESH_LIGHT_CONTROL_REGULATOR_KPD, 0x04 },
{ BLE_MESH_LIGHT_CONTROL_REGULATOR_KPU, 0x04 },
{ BLE_MESH_LIGHT_CONTROL_TIME_FADE, 0x03 },
{ BLE_MESH_LIGHT_CONTROL_TIME_FADE_ON, 0x03 },
{ BLE_MESH_LIGHT_CONTROL_TIME_FADE_STANDBY_AUTO, 0x03 },
{ BLE_MESH_LIGHT_CONTROL_TIME_FADE_STANDBY_MANUAL, 0x03 },
{ BLE_MESH_LIGHT_CONTROL_TIME_OCCUPANCY_DELAY, 0x03 },
{ BLE_MESH_LIGHT_CONTROL_TIME_PROLONG, 0x03 },
{ BLE_MESH_LIGHT_CONTROL_TIME_RUN_ON, 0x03 },
{ BLE_MESH_LUMEN_MAINTENANCE_FACTOR, 0x01 },
{ BLE_MESH_LUMINOUS_EFFICACY, 0x02 },
{ BLE_MESH_LUMINOUS_ENERGY_SINCE_TURN_ON, 0x03 },
{ BLE_MESH_LUMINOUS_EXPOSURE, 0x03 },
{ BLE_MESH_LUMINOUS_FLUX_RANGE, 0x04 },
{ BLE_MESH_MOTION_SENSED, 0x01 },
{ BLE_MESH_MOTION_THRESHOLD, 0x01 },
{ BLE_MESH_OPEN_CIRCUIT_EVENT_STATISTICS, 0x06 },
{ BLE_MESH_OUTDOOR_STATISTICAL_VALUES, 0x05 },
{ BLE_MESH_OUTPUT_CURRENT_RANGE, 0x04 },
{ BLE_MESH_OUTPUT_CURRENT_STATISTICS, 0x09 },
{ BLE_MESH_OUTPUT_RIPPLE_VOLTAGE_SPECIFICATION, 0x01 },
{ BLE_MESH_OUTPUT_VOLTAGE_RANGE, 0x06 },
{ BLE_MESH_OUTPUT_VOLTAGE_STATISTICS, 0x09 },
{ BLE_MESH_OVER_OUTPUT_RIPPLE_VOLTAGE_EVENT_STATISTICS, 0x06 },
{ BLE_MESH_PEOPLE_COUNT, 0x02 },
{ BLE_MESH_PRESENCE_DETECTED, 0x01 },
{ BLE_MESH_PRESENT_AMBIENT_LIGHT_LEVEL, 0x03 },
{ BLE_MESH_PRESENT_AMBIENT_TEMPERATURE, 0x01 },
{ BLE_MESH_PRESENT_CIE_1931_CHROMATICITY, 0x04 },
{ BLE_MESH_PRESENT_CORRELATED_COLOR_TEMPERATURE, 0x02 },
{ BLE_MESH_PRESENT_DEVICE_INPUT_POWER, 0x03 },
{ BLE_MESH_PRESENT_DEVICE_OPERATING_EFFICIENCY, 0x01 },
{ BLE_MESH_PRESENT_DEVICE_OPERATING_TEMPERATURE, 0x02 },
{ BLE_MESH_PRESENT_ILLUMINANCE, 0x03 },
{ BLE_MESH_PRESENT_INDOOR_AMBIENT_TEMPERATURE, 0x01 },
{ BLE_MESH_PRESENT_INPUT_CURRENT, 0x02 },
{ BLE_MESH_PRESENT_INPUT_RIPPLE_VOLTAGE, 0x01 },
{ BLE_MESH_PRESENT_INPUT_VOLTAGE, 0x02 },
{ BLE_MESH_PRESENT_LUMINOUS_FLUX, 0x02 },
{ BLE_MESH_PRESENT_OUTDOOR_AMBIENT_TEMPERATURE, 0x01 },
{ BLE_MESH_PRESENT_OUTPUT_CURRENT, 0x02 },
{ BLE_MESH_PRESENT_OUTPUT_VOLTAGE, 0x02 },
{ BLE_MESH_PRESENT_PLANCKIAN_DISTANCE, 0x02 },
{ BLE_MESH_PRESENT_RELATIVE_OUTPUT_RIPPLE_VOLTAGE, 0x01 },
{ BLE_MESH_RELATIVE_DEVICE_ENERGY_USE_IN_A_PERIOD_OF_DAY, 0x05 },
{ BLE_MESH_RELATIVE_DEVICE_RUNTIME_IN_A_GENERIC_LEVEL_RANGE, 0x05 },
{ BLE_MESH_RELATIVE_EXPOSURE_TIME_IN_AN_ILLUMINANCE_RANGE, 0x05 },
{ BLE_MESH_RELATIVE_RUNTIME_IN_A_CORRELATED_COLOR_TEMPERATURE_RANGE, 0x03 },
{ BLE_MESH_RELATIVE_RUNTIME_IN_A_DEVICE_OPERATING_TEMPERATURE_RANGE, 0x03 },
{ BLE_MESH_RELATIVE_RUNTIME_IN_AN_INPUT_CURRENT_RANGE, 0x05 },
{ BLE_MESH_RELATIVE_RUNTIME_IN_AN_INPUT_VOLTAGE_RANGE, 0x05 },
{ BLE_MESH_SHORT_CIRCUIT_EVENT_STATISTICS, 0x06 },
{ BLE_MESH_TIME_SINCE_MOTION_SENSED, 0x02 },
{ BLE_MESH_TIME_SINCE_PRESENCE_DETECTED, 0x02 },
{ BLE_MESH_TOTAL_DEVICE_ENERGY_USE, 0x03 },
{ BLE_MESH_TOTAL_DEVICE_OFF_ON_CYCLES, 0x03 },
{ BLE_MESH_TOTAL_DEVICE_POWER_ON_CYCLES, 0x03 },
{ BLE_MESH_TOTAL_DEVICE_POWER_ON_TIME, 0x03 },
{ BLE_MESH_TOTAL_DEVICE_RUNTIME, 0x03 },
{ BLE_MESH_TOTAL_LIGHT_EXPOSURE_TIME, 0x03 },
{ BLE_MESH_TOTAL_LUMINOUS_ENERGY, 0x03 },
{ BLE_MESH_DESIRED_AMBIENT_TEMPERATURE, 0x01 },
{ BLE_MESH_PRECISE_TOTAL_DEVICE_ENERGY_USE, 0x04 },
{ BLE_MESH_POWER_FACTOR, 0x01 },
{ BLE_MESH_SENSOR_GAIN, 0x04 },
{ BLE_MESH_PRECISE_PRESENT_AMBIENT_TEMPERATURE, 0x02 },
{ BLE_MESH_PRESENT_AMBIENT_RELATIVE_HUMIDITY, 0x02 },
{ BLE_MESH_PRESENT_AMBIENT_CARBON_DIOXIDE_CONCENTRATION, 0x02 },
{ BLE_MESH_PRESENT_AMBIENT_VOLATILE_ORGANIC_COMPOUNDS_CONCENTRATION, 0x02 },
{ BLE_MESH_PRESENT_AMBIENT_NOISE, 0x01 },
{ 0x007A, 0xFF }, /* Not defined */
{ 0x007B, 0xFF }, /* Not defined */
{ 0x007C, 0xFF }, /* Not defined */
{ 0x007D, 0xFF }, /* Not defined */
{ 0x007E, 0xFF }, /* Not defined */
{ 0x007F, 0xFF }, /* Not defined */
{ BLE_MESH_ACTIVE_ENERGY_LOADSIDE, 0x04 },
{ BLE_MESH_ACTIVE_POWER_LOADSIDE, 0x03 },
{ BLE_MESH_AIR_PRESSURE, 0x04 },
{ BLE_MESH_APPARENT_ENERGY, 0x04 },
{ BLE_MESH_APPARENT_POWER, 0x03 },
{ BLE_MESH_APPARENT_WIND_DIRECTION, 0x02 },
{ BLE_MESH_APPARENT_WIND_SPEED, 0x02 },
{ BLE_MESH_DEW_POINT, 0x01 },
{ BLE_MESH_EXTERNAL_SUPPLY_VOLTAGE, 0x03 },
{ BLE_MESH_EXTERNAL_SUPPLY_VOLTAGE_FREQUENCY, 0x02 },
{ BLE_MESH_GUST_FACTOR, 0x01 },
{ BLE_MESH_HEAT_INDEX, 0x01 },
{ BLE_MESH_LIGHT_DISTRIBUTION, 0x01 },
{ BLE_MESH_LIGHT_SOURCE_CURRENT, 0x03 },
{ BLE_MESH_LIGHT_SOURCE_ON_TIME_NOT_RESETTABLE, 0x04 },
{ BLE_MESH_LIGHT_SOURCE_ON_TIME_RESETTABLE, 0x04 },
{ BLE_MESH_LIGHT_SOURCE_OPEN_CIRCUIT_STATISTICS, 0x06 },
{ BLE_MESH_LIGHT_SOURCE_OVERALL_FAILURES_STATISTICS, 0x06 },
{ BLE_MESH_LIGHT_SOURCE_SHORT_CIRCUIT_STATISTICS, 0x06 },
{ BLE_MESH_LIGHT_SOURCE_START_COUNTER_RESETTABLE, 0x03 },
{ BLE_MESH_LIGHT_SOURCE_TEMPERATURE, 0x02 },
{ BLE_MESH_LIGHT_SOURCE_THERMAL_DERATING_STATISTICS, 0x06 },
{ BLE_MESH_LIGHT_SOURCE_THERMAL_SHUTDOWN_STATISTICS, 0x06 },
{ BLE_MESH_LIGHT_SOURCE_TOTAL_POWER_ON_CYCLES, 0x03 },
{ BLE_MESH_LIGHT_SOURCE_VOLTAGE, 0x03 },
{ BLE_MESH_LUMINAIRE_COLOR, 0x18 },
{ BLE_MESH_LUMINAIRE_IDENTIFICATION_NUMBER, 0x18 },
{ BLE_MESH_LUMINAIRE_MANUFACTURER_GTIN, 0x06 },
{ BLE_MESH_LUMINAIRE_NOMINAL_INPUT_POWER, 0x03 },
{ BLE_MESH_LUMINAIRE_NOMINAL_MAXIMUM_AC_MAINS_VOLTAGE, 0x02 },
{ BLE_MESH_LUMINAIRE_NOMINAL_MINIMUM_AC_MAINS_VOLTAGE, 0x02 },
{ BLE_MESH_LUMINAIRE_POWER_AT_MINIMUM_DIM_LEVEL, 0x03 },
{ BLE_MESH_LUMINAIRE_TIME_OF_MANUFACTURE, 0x03 },
{ BLE_MESH_MAGNETIC_DECLINATION, 0x02 },
{ BLE_MESH_MAGNETIC_FLUX_DENSITY_2D, 0x04 },
{ BLE_MESH_MAGNETIC_FLUX_DENSITY_3D, 0x06 },
{ BLE_MESH_NOMINAL_LIGHT_OUTPUT, 0x03 },
{ BLE_MESH_OVERALL_FAILURE_CONDITION, 0x06 },
{ BLE_MESH_POLLEN_CONCENTRATION, 0x03 },
{ BLE_MESH_PRESENT_INDOOR_RELATIVE_HUMIDITY, 0x02 },
{ BLE_MESH_PRESENT_OUTDOOR_RELATIVE_HUMIDITY, 0x02 },
{ BLE_MESH_PRESSURE, 0x04 },
{ BLE_MESH_RAINFALL, 0x02 },
{ BLE_MESH_RATED_MEDIAN_USEFUL_LIFE_OF_LUMINAIRE, 0x03 },
{ BLE_MESH_RATED_MEDIAN_USEFUL_LIGHT_SOURCE_STARTS, 0x03 },
{ BLE_MESH_REFERENCE_TEMPERATURE, 0x02 },
{ BLE_MESH_TOTAL_DEVICE_STARTS, 0x03 },
{ BLE_MESH_TRUE_WIND_DIRECTION, 0x02 },
{ BLE_MESH_TRUE_WIND_SPEED, 0x02 },
{ BLE_MESH_UV_INDEX, 0x01 },
{ BLE_MESH_WIND_CHILL, 0x01 },
{ BLE_MESH_LIGHT_SOURCE_TYPE, 0x01 },
{ BLE_MESH_LUMINAIRE_IDENTIFICATION_STRING, 0x40 },
{ BLE_MESH_OUTPUT_POWER_LIMITATION, 0x06 },
{ BLE_MESH_THERMAL_DERATING, 0x06 },
{ BLE_MESH_OUTPUT_CURRENT_PERCENT, 0x01 },
};
uint8_t bt_mesh_get_dev_prop_len(uint16_t prop_id)
{
if (prop_id > BLE_MESH_OUTPUT_CURRENT_PERCENT) {
BT_ERR("Unknown Device Property ID 0x%04x", prop_id);
return UINT8_MAX;
}
return device_properties[prop_id].len;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,27 @@
/*
* SPDX-FileCopyrightText: 2018 Vikrant More
* SPDX-FileContributor: 2018-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _MODEL_COMMON_H_
#define _MODEL_COMMON_H_
#include "mesh/types.h"
#ifdef __cplusplus
extern "C" {
#endif
float bt_mesh_sqrt(float square);
int32_t bt_mesh_ceil(float num);
float bt_mesh_log2(float num);
#ifdef __cplusplus
}
#endif
#endif /* _MODEL_COMMON_H_ */
@@ -0,0 +1,289 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _MODEL_OPCODE_H_
#define _MODEL_OPCODE_H_
#include "mesh/access.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Generic OnOff Message Opcode */
#define BLE_MESH_MODEL_OP_GEN_ONOFF_GET BLE_MESH_MODEL_OP_2(0x82, 0x01)
#define BLE_MESH_MODEL_OP_GEN_ONOFF_SET BLE_MESH_MODEL_OP_2(0x82, 0x02)
#define BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x03)
#define BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x04)
/* Generic Level Message Opcode */
#define BLE_MESH_MODEL_OP_GEN_LEVEL_GET BLE_MESH_MODEL_OP_2(0x82, 0x05)
#define BLE_MESH_MODEL_OP_GEN_LEVEL_SET BLE_MESH_MODEL_OP_2(0x82, 0x06)
#define BLE_MESH_MODEL_OP_GEN_LEVEL_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x07)
#define BLE_MESH_MODEL_OP_GEN_LEVEL_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x08)
#define BLE_MESH_MODEL_OP_GEN_DELTA_SET BLE_MESH_MODEL_OP_2(0x82, 0x09)
#define BLE_MESH_MODEL_OP_GEN_DELTA_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x0A)
#define BLE_MESH_MODEL_OP_GEN_MOVE_SET BLE_MESH_MODEL_OP_2(0x82, 0x0B)
#define BLE_MESH_MODEL_OP_GEN_MOVE_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x0C)
/* Generic Default Transition Time Message Opcode*/
#define BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_GET BLE_MESH_MODEL_OP_2(0x82, 0x0D)
#define BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET BLE_MESH_MODEL_OP_2(0x82, 0x0E)
#define BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x0F)
#define BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x10)
/* Generic Power OnOff Message Opcode*/
#define BLE_MESH_MODEL_OP_GEN_ONPOWERUP_GET BLE_MESH_MODEL_OP_2(0x82, 0x11)
#define BLE_MESH_MODEL_OP_GEN_ONPOWERUP_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x12)
/* Generic Power OnOff Setup Message Opcode */
#define BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET BLE_MESH_MODEL_OP_2(0x82, 0x13)
#define BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x14)
/* Generic Power Level Message Opcode */
#define BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_GET BLE_MESH_MODEL_OP_2(0x82, 0x15)
#define BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET BLE_MESH_MODEL_OP_2(0x82, 0x16)
#define BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x17)
#define BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x18)
#define BLE_MESH_MODEL_OP_GEN_POWER_LAST_GET BLE_MESH_MODEL_OP_2(0x82, 0x19)
#define BLE_MESH_MODEL_OP_GEN_POWER_LAST_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x1A)
#define BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_GET BLE_MESH_MODEL_OP_2(0x82, 0x1B)
#define BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x1C)
#define BLE_MESH_MODEL_OP_GEN_POWER_RANGE_GET BLE_MESH_MODEL_OP_2(0x82, 0x1D)
#define BLE_MESH_MODEL_OP_GEN_POWER_RANGE_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x1E)
/* Generic Power Level Setup Message Opcode */
#define BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET BLE_MESH_MODEL_OP_2(0x82, 0x1F)
#define BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x20)
#define BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET BLE_MESH_MODEL_OP_2(0x82, 0x21)
#define BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x22)
/* Generic Battery Message Opcode */
#define BLE_MESH_MODEL_OP_GEN_BATTERY_GET BLE_MESH_MODEL_OP_2(0x82, 0x23)
#define BLE_MESH_MODEL_OP_GEN_BATTERY_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x24)
/* Generic Location Message Opcode */
#define BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_GET BLE_MESH_MODEL_OP_2(0x82, 0x25)
#define BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_STATUS BLE_MESH_MODEL_OP_1(0x40)
#define BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_GET BLE_MESH_MODEL_OP_2(0x82, 0x26)
#define BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x27)
/* Generic Location Setup Message Opcode */
#define BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET BLE_MESH_MODEL_OP_1(0x41)
#define BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET_UNACK BLE_MESH_MODEL_OP_1(0x42)
#define BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET BLE_MESH_MODEL_OP_2(0x82, 0x28)
#define BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x29)
/* Generic Manufacturer Property Message Opcode */
#define BLE_MESH_MODEL_OP_GEN_MANU_PROPERTIES_GET BLE_MESH_MODEL_OP_2(0x82, 0x2A)
#define BLE_MESH_MODEL_OP_GEN_MANU_PROPERTIES_STATUS BLE_MESH_MODEL_OP_1(0x43)
#define BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_GET BLE_MESH_MODEL_OP_2(0x82, 0x2B)
#define BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_SET BLE_MESH_MODEL_OP_1(0x44)
#define BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_SET_UNACK BLE_MESH_MODEL_OP_1(0x45)
#define BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_STATUS BLE_MESH_MODEL_OP_1(0x46)
/* Generic Admin Property Message Opcode */
#define BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_GET BLE_MESH_MODEL_OP_2(0x82, 0x2C)
#define BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_STATUS BLE_MESH_MODEL_OP_1(0x47)
#define BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_GET BLE_MESH_MODEL_OP_2(0x82, 0x2D)
#define BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET BLE_MESH_MODEL_OP_1(0x48)
#define BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET_UNACK BLE_MESH_MODEL_OP_1(0x49)
#define BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_STATUS BLE_MESH_MODEL_OP_1(0x4A)
/* Generic User Property Message Opcode */
#define BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_GET BLE_MESH_MODEL_OP_2(0x82, 0x2E)
#define BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_STATUS BLE_MESH_MODEL_OP_1(0x4B)
#define BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_GET BLE_MESH_MODEL_OP_2(0x82, 0x2F)
#define BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET BLE_MESH_MODEL_OP_1(0x4C)
#define BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET_UNACK BLE_MESH_MODEL_OP_1(0x4D)
#define BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_STATUS BLE_MESH_MODEL_OP_1(0x4E)
/* Generic Client Property Message Opcode */
#define BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_GET BLE_MESH_MODEL_OP_1(0x4F)
#define BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_STATUS BLE_MESH_MODEL_OP_1(0x50)
/* Sensor Message Opcode */
#define BLE_MESH_MODEL_OP_SENSOR_DESCRIPTOR_GET BLE_MESH_MODEL_OP_2(0x82, 0x30)
#define BLE_MESH_MODEL_OP_SENSOR_DESCRIPTOR_STATUS BLE_MESH_MODEL_OP_1(0x51)
#define BLE_MESH_MODEL_OP_SENSOR_GET BLE_MESH_MODEL_OP_2(0x82, 0x31)
#define BLE_MESH_MODEL_OP_SENSOR_STATUS BLE_MESH_MODEL_OP_1(0x52)
#define BLE_MESH_MODEL_OP_SENSOR_COLUMN_GET BLE_MESH_MODEL_OP_2(0x82, 0x32)
#define BLE_MESH_MODEL_OP_SENSOR_COLUMN_STATUS BLE_MESH_MODEL_OP_1(0x53)
#define BLE_MESH_MODEL_OP_SENSOR_SERIES_GET BLE_MESH_MODEL_OP_2(0x82, 0x33)
#define BLE_MESH_MODEL_OP_SENSOR_SERIES_STATUS BLE_MESH_MODEL_OP_1(0x54)
/* Sensor Setup Message Opcode */
#define BLE_MESH_MODEL_OP_SENSOR_CADENCE_GET BLE_MESH_MODEL_OP_2(0x82, 0x34)
#define BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET BLE_MESH_MODEL_OP_1(0x55)
#define BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET_UNACK BLE_MESH_MODEL_OP_1(0x56)
#define BLE_MESH_MODEL_OP_SENSOR_CADENCE_STATUS BLE_MESH_MODEL_OP_1(0x57)
#define BLE_MESH_MODEL_OP_SENSOR_SETTINGS_GET BLE_MESH_MODEL_OP_2(0x82, 0x35)
#define BLE_MESH_MODEL_OP_SENSOR_SETTINGS_STATUS BLE_MESH_MODEL_OP_1(0x58)
#define BLE_MESH_MODEL_OP_SENSOR_SETTING_GET BLE_MESH_MODEL_OP_2(0x82, 0x36)
#define BLE_MESH_MODEL_OP_SENSOR_SETTING_SET BLE_MESH_MODEL_OP_1(0x59)
#define BLE_MESH_MODEL_OP_SENSOR_SETTING_SET_UNACK BLE_MESH_MODEL_OP_1(0x5A)
#define BLE_MESH_MODEL_OP_SENSOR_SETTING_STATUS BLE_MESH_MODEL_OP_1(0x5B)
/* Time Message Opcode */
#define BLE_MESH_MODEL_OP_TIME_GET BLE_MESH_MODEL_OP_2(0x82, 0x37)
#define BLE_MESH_MODEL_OP_TIME_SET BLE_MESH_MODEL_OP_1(0x5C)
#define BLE_MESH_MODEL_OP_TIME_STATUS BLE_MESH_MODEL_OP_1(0x5D)
#define BLE_MESH_MODEL_OP_TIME_ROLE_GET BLE_MESH_MODEL_OP_2(0x82, 0x38)
#define BLE_MESH_MODEL_OP_TIME_ROLE_SET BLE_MESH_MODEL_OP_2(0x82, 0x39)
#define BLE_MESH_MODEL_OP_TIME_ROLE_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x3A)
#define BLE_MESH_MODEL_OP_TIME_ZONE_GET BLE_MESH_MODEL_OP_2(0x82, 0x3B)
#define BLE_MESH_MODEL_OP_TIME_ZONE_SET BLE_MESH_MODEL_OP_2(0x82, 0x3C)
#define BLE_MESH_MODEL_OP_TIME_ZONE_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x3D)
#define BLE_MESH_MODEL_OP_TAI_UTC_DELTA_GET BLE_MESH_MODEL_OP_2(0x82, 0x3E)
#define BLE_MESH_MODEL_OP_TAI_UTC_DELTA_SET BLE_MESH_MODEL_OP_2(0x82, 0x3F)
#define BLE_MESH_MODEL_OP_TAI_UTC_DELTA_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x40)
/* Scene Message Opcode */
#define BLE_MESH_MODEL_OP_SCENE_GET BLE_MESH_MODEL_OP_2(0x82, 0x41)
#define BLE_MESH_MODEL_OP_SCENE_RECALL BLE_MESH_MODEL_OP_2(0x82, 0x42)
#define BLE_MESH_MODEL_OP_SCENE_RECALL_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x43)
#define BLE_MESH_MODEL_OP_SCENE_STATUS BLE_MESH_MODEL_OP_1(0x5E)
#define BLE_MESH_MODEL_OP_SCENE_REGISTER_GET BLE_MESH_MODEL_OP_2(0x82, 0x44)
#define BLE_MESH_MODEL_OP_SCENE_REGISTER_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x45)
/* Scene Setup Message Opcode */
#define BLE_MESH_MODEL_OP_SCENE_STORE BLE_MESH_MODEL_OP_2(0x82, 0x46)
#define BLE_MESH_MODEL_OP_SCENE_STORE_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x47)
#define BLE_MESH_MODEL_OP_SCENE_DELETE BLE_MESH_MODEL_OP_2(0x82, 0x9E)
#define BLE_MESH_MODEL_OP_SCENE_DELETE_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x9F)
/* Scheduler Message Opcode */
#define BLE_MESH_MODEL_OP_SCHEDULER_ACT_GET BLE_MESH_MODEL_OP_2(0x82, 0x48)
#define BLE_MESH_MODEL_OP_SCHEDULER_ACT_STATUS BLE_MESH_MODEL_OP_1(0x5F)
#define BLE_MESH_MODEL_OP_SCHEDULER_GET BLE_MESH_MODEL_OP_2(0x82, 0x49)
#define BLE_MESH_MODEL_OP_SCHEDULER_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x4A)
/* Scheduler Setup Message Opcode */
#define BLE_MESH_MODEL_OP_SCHEDULER_ACT_SET BLE_MESH_MODEL_OP_1(0x60)
#define BLE_MESH_MODEL_OP_SCHEDULER_ACT_SET_UNACK BLE_MESH_MODEL_OP_1(0x61)
/* Light Lightness Message Opcode */
#define BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_GET BLE_MESH_MODEL_OP_2(0x82, 0x4B)
#define BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET BLE_MESH_MODEL_OP_2(0x82, 0x4C)
#define BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x4D)
#define BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x4E)
#define BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_GET BLE_MESH_MODEL_OP_2(0x82, 0x4F)
#define BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET BLE_MESH_MODEL_OP_2(0x82, 0x50)
#define BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x51)
#define BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x52)
#define BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_GET BLE_MESH_MODEL_OP_2(0x82, 0x53)
#define BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x54)
#define BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_GET BLE_MESH_MODEL_OP_2(0x82, 0x55)
#define BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x56)
#define BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_GET BLE_MESH_MODEL_OP_2(0x82, 0x57)
#define BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x58)
/* Light Lightness Setup Message Opcode */
#define BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET BLE_MESH_MODEL_OP_2(0x82, 0x59)
#define BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x5A)
#define BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET BLE_MESH_MODEL_OP_2(0x82, 0x5B)
#define BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x5C)
/* Light CTL Message Opcode */
#define BLE_MESH_MODEL_OP_LIGHT_CTL_GET BLE_MESH_MODEL_OP_2(0x82, 0x5D)
#define BLE_MESH_MODEL_OP_LIGHT_CTL_SET BLE_MESH_MODEL_OP_2(0x82, 0x5E)
#define BLE_MESH_MODEL_OP_LIGHT_CTL_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x5F)
#define BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x60)
#define BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_GET BLE_MESH_MODEL_OP_2(0x82, 0x61)
#define BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_GET BLE_MESH_MODEL_OP_2(0x82, 0x62)
#define BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x63)
#define BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET BLE_MESH_MODEL_OP_2(0x82, 0x64)
#define BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x65)
#define BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x66)
#define BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_GET BLE_MESH_MODEL_OP_2(0x82, 0x67)
#define BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x68)
/* Light CTL Setup Message Opcode */
#define BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET BLE_MESH_MODEL_OP_2(0x82, 0x69)
#define BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x6A)
#define BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET BLE_MESH_MODEL_OP_2(0x82, 0x6B)
#define BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x6C)
/* Light HSL Message Opcode */
#define BLE_MESH_MODEL_OP_LIGHT_HSL_GET BLE_MESH_MODEL_OP_2(0x82, 0x6D)
#define BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_GET BLE_MESH_MODEL_OP_2(0x82, 0x6E)
#define BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET BLE_MESH_MODEL_OP_2(0x82, 0x6F)
#define BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x70)
#define BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x71)
#define BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_GET BLE_MESH_MODEL_OP_2(0x82, 0x72)
#define BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET BLE_MESH_MODEL_OP_2(0x82, 0x73)
#define BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x74)
#define BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x75)
#define BLE_MESH_MODEL_OP_LIGHT_HSL_SET BLE_MESH_MODEL_OP_2(0x82, 0x76)
#define BLE_MESH_MODEL_OP_LIGHT_HSL_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x77)
#define BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x78)
#define BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_GET BLE_MESH_MODEL_OP_2(0x82, 0x79)
#define BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x7A)
#define BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_GET BLE_MESH_MODEL_OP_2(0x82, 0x7B)
#define BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x7C)
#define BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_GET BLE_MESH_MODEL_OP_2(0x82, 0x7D)
#define BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x7E)
/* Light HSL Setup Message Opcode */
#define BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_SET BLE_MESH_MODEL_OP_2(0x82, 0x7F)
#define BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x80)
#define BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET BLE_MESH_MODEL_OP_2(0x82, 0x81)
#define BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x82)
/* Light xyL Message Opcode */
#define BLE_MESH_MODEL_OP_LIGHT_XYL_GET BLE_MESH_MODEL_OP_2(0x82, 0x83)
#define BLE_MESH_MODEL_OP_LIGHT_XYL_SET BLE_MESH_MODEL_OP_2(0x82, 0x84)
#define BLE_MESH_MODEL_OP_LIGHT_XYL_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x85)
#define BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x86)
#define BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_GET BLE_MESH_MODEL_OP_2(0x82, 0x87)
#define BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x88)
#define BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_GET BLE_MESH_MODEL_OP_2(0x82, 0x89)
#define BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x8A)
#define BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_GET BLE_MESH_MODEL_OP_2(0x82, 0x8B)
#define BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x8C)
/* Light xyL Setup Message Opcode */
#define BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_SET BLE_MESH_MODEL_OP_2(0x82, 0x8D)
#define BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x8E)
#define BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_SET BLE_MESH_MODEL_OP_2(0x82, 0x8F)
#define BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x90)
/* Light Control Message Opcode */
#define BLE_MESH_MODEL_OP_LIGHT_LC_MODE_GET BLE_MESH_MODEL_OP_2(0x82, 0x91)
#define BLE_MESH_MODEL_OP_LIGHT_LC_MODE_SET BLE_MESH_MODEL_OP_2(0x82, 0x92)
#define BLE_MESH_MODEL_OP_LIGHT_LC_MODE_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x93)
#define BLE_MESH_MODEL_OP_LIGHT_LC_MODE_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x94)
#define BLE_MESH_MODEL_OP_LIGHT_LC_OM_GET BLE_MESH_MODEL_OP_2(0x82, 0x95)
#define BLE_MESH_MODEL_OP_LIGHT_LC_OM_SET BLE_MESH_MODEL_OP_2(0x82, 0x96)
#define BLE_MESH_MODEL_OP_LIGHT_LC_OM_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x97)
#define BLE_MESH_MODEL_OP_LIGHT_LC_OM_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x98)
#define BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_GET BLE_MESH_MODEL_OP_2(0x82, 0x99)
#define BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET BLE_MESH_MODEL_OP_2(0x82, 0x9A)
#define BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET_UNACK BLE_MESH_MODEL_OP_2(0x82, 0x9B)
#define BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS BLE_MESH_MODEL_OP_2(0x82, 0x9C)
#define BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_GET BLE_MESH_MODEL_OP_2(0x82, 0x9D)
#define BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET BLE_MESH_MODEL_OP_1(0x62)
#define BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET_UNACK BLE_MESH_MODEL_OP_1(0x63)
#define BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_STATUS BLE_MESH_MODEL_OP_1(0x64)
/* Blob Transfer Message Opcode - TBD */
#define BLE_MESH_BLOB_TRANSFER_GET BLE_MESH_MODEL_OP_2(0x83, 0x00)
#define BLE_MESH_BLOB_TRANSFER_START BLE_MESH_MODEL_OP_2(0x83, 0x01)
#define BLE_MESH_BLOB_TRANSFER_CANCEL BLE_MESH_MODEL_OP_2(0x83, 0x02)
#define BLE_MESH_BLOB_TRANSFER_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x03)
#define BLE_MESH_BLOB_BLOCK_GET BLE_MESH_MODEL_OP_2(0x83, 0x05)
#define BLE_MESH_BLOB_BLOCK_START BLE_MESH_MODEL_OP_2(0x83, 0x04)
#define BLE_MESH_BLOB_PARTIAL_BLOCK_REPORT BLE_MESH_MODEL_OP_1(0x65)
#define BLE_MESH_BLOB_BLOCK_STATUS BLE_MESH_MODEL_OP_1(0x67)
#define BLE_MESH_BLOB_CHUNK_TRANSFER BLE_MESH_MODEL_OP_1(0x66)
#define BLE_MESH_BLOB_INFORMATION_GET BLE_MESH_MODEL_OP_2(0x83, 0x06)
#define BLE_MESH_BLOB_INFORMATION_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x07)
#ifdef __cplusplus
}
#endif
#endif /* _MODEL_OPCODE_H_ */
@@ -0,0 +1,47 @@
/*
* SPDX-FileCopyrightText: 2018 Vikrant More
* SPDX-FileContributor: 2018-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <math.h>
#include "mesh/types.h"
#define MINDIFF (2.25e-308)
float bt_mesh_sqrt(float square)
{
float root = 0.0, last = 0.0, diff = 0.0;
root = square / 3.0;
diff = 1;
if (square <= 0) {
return 0;
}
do {
last = root;
root = (root + square / root) / 2.0;
diff = root - last;
} while (diff > MINDIFF || diff < -MINDIFF);
return root;
}
int32_t bt_mesh_ceil(float num)
{
int32_t inum = (int32_t)num;
if (num == (float)inum) {
return inum;
}
return inum + 1;
}
float bt_mesh_log2(float num)
{
return log2f(num);
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,367 @@
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
*
* SPDX-FileCopyrightText: 2018 Vikrant More
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _GENERIC_SERVER_H_
#define _GENERIC_SERVER_H_
#include "mesh/server_common.h"
#ifdef __cplusplus
extern "C" {
#endif
struct bt_mesh_gen_onoff_state {
uint8_t onoff;
uint8_t target_onoff;
};
struct bt_mesh_gen_onoff_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_gen_onoff_state state;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition transition;
};
struct bt_mesh_gen_level_state {
int16_t level;
int16_t target_level;
int16_t last_level;
int32_t last_delta;
bool move_start;
bool positive;
};
struct bt_mesh_gen_level_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_gen_level_state state;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition transition;
int32_t tt_delta_level;
};
struct bt_mesh_gen_def_trans_time_state {
uint8_t trans_time;
};
struct bt_mesh_gen_def_trans_time_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_gen_def_trans_time_state state;
};
struct bt_mesh_gen_onpowerup_state {
uint8_t onpowerup;
};
struct bt_mesh_gen_power_onoff_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_gen_onpowerup_state *state;
};
struct bt_mesh_gen_power_onoff_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_gen_onpowerup_state *state;
};
struct bt_mesh_gen_power_level_state {
uint16_t power_actual;
uint16_t target_power_actual;
uint16_t power_last;
uint16_t power_default;
uint8_t status_code;
uint16_t power_range_min;
uint16_t power_range_max;
};
struct bt_mesh_gen_power_level_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_gen_power_level_state *state;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition transition;
int32_t tt_delta_level;
};
struct bt_mesh_gen_power_level_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_gen_power_level_state *state;
};
struct bt_mesh_gen_battery_state {
uint32_t battery_level : 8,
time_to_discharge : 24;
uint32_t time_to_charge : 24,
battery_flags : 8;
};
struct bt_mesh_gen_battery_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_gen_battery_state state;
};
struct bt_mesh_gen_location_state {
int32_t global_latitude;
int32_t global_longitude;
int16_t global_altitude;
int16_t local_north;
int16_t local_east;
int16_t local_altitude;
uint8_t floor_number;
uint16_t uncertainty;
};
struct bt_mesh_gen_location_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_gen_location_state *state;
};
struct bt_mesh_gen_location_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_gen_location_state *state;
};
/**
* According to the hierarchy of Generic Property states (Model Spec section 3.1.8),
* the Manufacturer Properties and Admin Properties may contain multiple Property
* states. User Properties just a collection of which can be accessed.
*
* property_count: Number of the properties contained in the table
* properties: Table of the properties
*
* These variables need to be initialized in the application layer, the precise
* number of the properties should be set and memories used to store the property
* values should be allocated.
*/
enum bt_mesh_gen_user_prop_access {
USER_ACCESS_PROHIBIT,
USER_ACCESS_READ,
USER_ACCESS_WRITE,
USER_ACCESS_READ_WRITE,
};
enum bt_mesh_gen_admin_prop_access {
ADMIN_NOT_USER_PROP,
ADMIN_ACCESS_READ,
ADMIN_ACCESS_WRITE,
ADMIN_ACCESS_READ_WRITE,
};
enum bt_mesh_gen_manu_prop_access {
MANU_NOT_USER_PROP,
MANU_ACCESS_READ,
};
struct bt_mesh_generic_property {
uint16_t id;
uint8_t user_access;
uint8_t admin_access;
uint8_t manu_access;
struct net_buf_simple *val;
};
struct bt_mesh_gen_user_prop_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
uint8_t property_count;
struct bt_mesh_generic_property *properties;
};
struct bt_mesh_gen_admin_prop_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
uint8_t property_count;
struct bt_mesh_generic_property *properties;
};
struct bt_mesh_gen_manu_prop_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
uint8_t property_count;
struct bt_mesh_generic_property *properties;
};
struct bt_mesh_gen_client_prop_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
uint8_t id_count;
uint16_t *property_ids;
};
typedef union {
struct {
uint8_t onoff;
} gen_onoff_set;
struct {
int16_t level;
} gen_level_set;
struct {
int16_t level;
} gen_delta_set;
struct {
int16_t level;
} gen_move_set;
struct {
uint8_t trans_time;
} gen_def_trans_time_set;
struct {
uint8_t onpowerup;
} gen_onpowerup_set;
struct {
uint16_t power;
} gen_power_level_set;
struct {
uint16_t power;
} gen_power_default_set;
struct {
uint16_t range_min;
uint16_t range_max;
} gen_power_range_set;
struct {
int32_t latitude;
int32_t longitude;
int16_t altitude;
} gen_loc_global_set;
struct {
int16_t north;
int16_t east;
int16_t altitude;
uint8_t floor_number;
uint16_t uncertainty;
} gen_loc_local_set;
struct {
uint16_t id;
struct net_buf_simple *value;
} gen_user_prop_set;
struct {
uint16_t id;
uint8_t access;
struct net_buf_simple *value;
} gen_admin_prop_set;
struct {
uint16_t id;
uint8_t access;
} gen_manu_prop_set;
} bt_mesh_gen_server_state_change_t;
typedef union {
struct {
uint16_t id;
} user_property_get;
struct {
uint16_t id;
} admin_property_get;
struct {
uint16_t id;
} manu_property_get;
struct {
uint16_t id;
} client_properties_get;
} bt_mesh_gen_server_recv_get_msg_t;
typedef union {
struct {
bool op_en;
uint8_t onoff;
uint8_t tid;
uint8_t trans_time;
uint8_t delay;
} onoff_set;
struct {
bool op_en;
int16_t level;
uint8_t tid;
uint8_t trans_time;
uint8_t delay;
} level_set;
struct {
bool op_en;
int32_t delta_level;
uint8_t tid;
uint8_t trans_time;
uint8_t delay;
} delta_set;
struct {
bool op_en;
int16_t delta_level;
uint8_t tid;
uint8_t trans_time;
uint8_t delay;
} move_set;
struct {
uint8_t trans_time;
} def_trans_time_set;
struct {
uint8_t onpowerup;
} onpowerup_set;
struct {
bool op_en;
uint16_t power;
uint8_t tid;
uint8_t trans_time;
uint8_t delay;
} power_level_set;
struct {
uint16_t power;
} power_default_set;
struct {
uint16_t range_min;
uint16_t range_max;
} power_range_set;
struct {
int32_t latitude;
int32_t longitude;
int16_t altitude;
} loc_global_set;
struct {
int16_t north;
int16_t east;
int16_t altitude;
uint8_t floor_number;
uint16_t uncertainty;
} loc_local_set;
struct {
uint16_t id;
struct net_buf_simple *value;
} user_property_set;
struct {
uint16_t id;
uint8_t access;
struct net_buf_simple *value;
} admin_property_set;
struct {
uint16_t id;
uint8_t access;
} manu_property_set;
} bt_mesh_gen_server_recv_set_msg_t;
void bt_mesh_generic_server_lock(void);
void bt_mesh_generic_server_unlock(void);
void gen_onoff_publish(struct bt_mesh_model *model);
void gen_level_publish(struct bt_mesh_model *model);
void gen_onpowerup_publish(struct bt_mesh_model *model);
void gen_power_level_publish(struct bt_mesh_model *model, uint16_t opcode);
#ifdef __cplusplus
}
#endif
#endif /* _GENERIC_SERVER_H_ */
@@ -0,0 +1,510 @@
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
*
* SPDX-FileCopyrightText: 2018 Vikrant More
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _LIGHTING_SERVER_H_
#define _LIGHTING_SERVER_H_
#include "mesh/server_common.h"
#ifdef __cplusplus
extern "C" {
#endif
struct bt_mesh_light_lightness_state {
uint16_t lightness_linear;
uint16_t target_lightness_linear;
uint16_t lightness_actual;
uint16_t target_lightness_actual;
uint16_t lightness_last;
uint16_t lightness_default;
uint8_t status_code;
uint16_t lightness_range_min;
uint16_t lightness_range_max;
};
struct bt_mesh_light_lightness_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_lightness_state *state;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition actual_transition;
struct bt_mesh_state_transition linear_transition;
int32_t tt_delta_lightness_actual;
int32_t tt_delta_lightness_linear;
};
struct bt_mesh_light_lightness_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_lightness_state *state;
};
struct bt_mesh_light_ctl_state {
uint16_t lightness;
uint16_t target_lightness;
uint16_t temperature;
uint16_t target_temperature;
int16_t delta_uv;
int16_t target_delta_uv;
uint8_t status_code;
uint16_t temperature_range_min;
uint16_t temperature_range_max;
uint16_t lightness_default;
uint16_t temperature_default;
int16_t delta_uv_default;
};
struct bt_mesh_light_ctl_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_ctl_state *state;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition transition;
int32_t tt_delta_lightness;
int32_t tt_delta_temperature;
int32_t tt_delta_delta_uv;
};
struct bt_mesh_light_ctl_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_ctl_state *state;
};
struct bt_mesh_light_ctl_temp_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_ctl_state *state;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition transition;
int32_t tt_delta_temperature;
int32_t tt_delta_delta_uv;
};
struct bt_mesh_light_hsl_state {
uint16_t lightness;
uint16_t target_lightness;
uint16_t hue;
uint16_t target_hue;
uint16_t saturation;
uint16_t target_saturation;
uint16_t lightness_default;
uint16_t hue_default;
uint16_t saturation_default;
uint8_t status_code;
uint16_t hue_range_min;
uint16_t hue_range_max;
uint16_t saturation_range_min;
uint16_t saturation_range_max;
};
struct bt_mesh_light_hsl_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_hsl_state *state;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition transition;
int32_t tt_delta_lightness;
int32_t tt_delta_hue;
int32_t tt_delta_saturation;
};
struct bt_mesh_light_hsl_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_hsl_state *state;
};
struct bt_mesh_light_hsl_hue_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_hsl_state *state;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition transition;
int32_t tt_delta_hue;
};
struct bt_mesh_light_hsl_sat_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_hsl_state *state;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition transition;
int32_t tt_delta_saturation;
};
struct bt_mesh_light_xyl_state {
uint16_t lightness;
uint16_t target_lightness;
uint16_t x;
uint16_t target_x;
uint16_t y;
uint16_t target_y;
uint16_t lightness_default;
uint16_t x_default;
uint16_t y_default;
uint8_t status_code;
uint16_t x_range_min;
uint16_t x_range_max;
uint16_t y_range_min;
uint16_t y_range_max;
};
struct bt_mesh_light_xyl_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_xyl_state *state;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition transition;
int32_t tt_delta_lightness;
int32_t tt_delta_x;
int32_t tt_delta_y;
};
struct bt_mesh_light_xyl_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_xyl_state *state;
};
struct bt_mesh_light_lc_state {
uint32_t mode : 1, /* default 0 */
occupancy_mode : 1, /* default 1 */
light_onoff : 1,
target_light_onoff : 1,
occupancy : 1,
ambient_luxlevel : 24; /* 0x000000 ~ 0xFFFFFF */
uint16_t linear_output; /* 0x0000 ~ 0xFFFF */
};
struct bt_mesh_light_lc_property_state {
uint32_t time_occupancy_delay; /* 0x003A */
uint32_t time_fade_on; /* 0x0037 */
uint32_t time_run_on; /* 0x003C */
uint32_t time_fade; /* 0x0036 */
uint32_t time_prolong; /* 0x003B */
uint32_t time_fade_standby_auto; /* 0x0038 */
uint32_t time_fade_standby_manual; /* 0x0039 */
uint16_t lightness_on; /* 0x002E */
uint16_t lightness_prolong; /* 0x002F */
uint16_t lightness_standby; /* 0x0030 */
uint16_t ambient_luxlevel_on; /* 0x002B, 0x0000 ~ 0xFFFF */
uint16_t ambient_luxlevel_prolong; /* 0x002C, 0x0000 ~ 0xFFFF */
uint16_t ambient_luxlevel_standby; /* 0x002D, 0x0000 ~ 0xFFFF */
float regulator_kiu; /* 0x0033, 0.0 ~ 1000.0, default 250.0 */
float regulator_kid; /* 0x0032, 0.0 ~ 1000.0, default 25.0 */
float regulator_kpu; /* 0x0035, 0.0 ~ 1000.0, default 80.0 */
float regulator_kpd; /* 0x0034, 0.0 ~ 1000.0, default 80.0 */
int8_t regulator_accuracy; /* 0x0031, 0.0 ~ 100.0, default 2.0 */
uint32_t set_occupancy_to_1_delay;
};
typedef enum {
LC_OFF,
LC_STANDBY,
LC_FADE_ON,
LC_RUN,
LC_FADE,
LC_PROLONG,
LC_FADE_STANDBY_AUTO,
LC_FADE_STANDBY_MANUAL,
} bt_mesh_lc_state;
struct bt_mesh_light_lc_state_machine {
struct {
uint8_t fade_on;
uint8_t fade;
uint8_t fade_standby_auto;
uint8_t fade_standby_manual;
} trans_time;
bt_mesh_lc_state state;
struct k_delayed_work timer;
};
struct bt_mesh_light_control {
struct bt_mesh_light_lc_state state;
struct bt_mesh_light_lc_property_state prop_state;
struct bt_mesh_light_lc_state_machine state_machine;
};
struct bt_mesh_light_lc_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_control *lc;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition transition;
};
struct bt_mesh_light_lc_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_light_control *lc;
};
typedef union {
struct {
uint16_t lightness;
} lightness_set;
struct {
uint16_t lightness;
} lightness_linear_set;
struct {
uint16_t lightness;
} lightness_default_set;
struct {
uint16_t range_min;
uint16_t range_max;
} lightness_range_set;
struct {
uint16_t lightness;
uint16_t temperature;
int16_t delta_uv;
} ctl_set;
struct {
uint16_t temperature;
int16_t delta_uv;
} ctl_temp_set;
struct {
uint16_t range_min;
uint16_t range_max;
} ctl_temp_range_set;
struct {
uint16_t lightness;
uint16_t temperature;
int16_t delta_uv;
} ctl_default_set;
struct {
uint16_t lightness;
uint16_t hue;
uint16_t saturation;
} hsl_set;
struct {
uint16_t hue;
} hsl_hue_set;
struct {
uint16_t saturation;
} hsl_saturation_set;
struct {
uint16_t lightness;
uint16_t hue;
uint16_t saturation;
} hsl_default_set;
struct {
uint16_t hue_range_min;
uint16_t hue_range_max;
uint16_t sat_range_min;
uint16_t sat_range_max;
} hsl_range_set;
struct {
uint16_t lightness;
uint16_t x;
uint16_t y;
} xyl_set;
struct {
uint16_t lightness;
uint16_t x;
uint16_t y;
} xyl_default_set;
struct {
uint16_t x_range_min;
uint16_t x_range_max;
uint16_t y_range_min;
uint16_t y_range_max;
} xyl_range_set;
struct {
uint8_t mode;
} lc_mode_set;
struct {
uint8_t mode;
} lc_om_set;
struct {
uint8_t onoff;
} lc_light_onoff_set;
struct {
uint16_t id;
struct net_buf_simple *value;
} lc_property_set;
struct {
uint16_t property_id;
union {
uint8_t occupancy;
uint32_t set_occupancy_to_1_delay;
uint32_t ambient_luxlevel;
} state;
} sensor_status;
} bt_mesh_light_server_state_change_t;
typedef union {
struct {
uint16_t id;
} lc_property_get;
} bt_mesh_light_server_recv_get_msg_t;
typedef union {
struct {
bool op_en;
uint16_t lightness;
uint8_t tid;
uint8_t trans_time;
uint8_t delay;
} lightness_set;
struct {
bool op_en;
uint16_t lightness;
uint8_t tid;
uint8_t trans_time;
uint8_t delay;
} lightness_linear_set;
struct {
uint16_t lightness;
} lightness_default_set;
struct {
uint16_t range_min;
uint16_t range_max;
} lightness_range_set;
struct {
bool op_en;
uint16_t lightness;
uint16_t temperature;
int16_t delta_uv;
uint8_t tid;
uint8_t trans_time;
uint8_t delay;
} ctl_set;
struct {
bool op_en;
uint16_t temperature;
int16_t delta_uv;
uint8_t tid;
uint8_t trans_time;
uint8_t delay;
} ctl_temp_set;
struct {
uint16_t range_min;
uint16_t range_max;
} ctl_temp_range_set;
struct {
uint16_t lightness;
uint16_t temperature;
int16_t delta_uv;
} ctl_default_set;
struct {
bool op_en;
uint16_t lightness;
uint16_t hue;
uint16_t saturation;
uint8_t tid;
uint8_t trans_time;
uint8_t delay;
} hsl_set;
struct {
bool op_en;
uint16_t hue;
uint8_t tid;
uint8_t trans_time;
uint8_t delay;
} hsl_hue_set;
struct {
bool op_en;
uint16_t saturation;
uint8_t tid;
uint8_t trans_time;
uint8_t delay;
} hsl_saturation_set;
struct {
uint16_t lightness;
uint16_t hue;
uint16_t saturation;
} hsl_default_set;
struct {
uint16_t hue_range_min;
uint16_t hue_range_max;
uint16_t sat_range_min;
uint16_t sat_range_max;
} hsl_range_set;
struct {
bool op_en;
uint16_t lightness;
uint16_t x;
uint16_t y;
uint8_t tid;
uint8_t trans_time;
uint8_t delay;
} xyl_set;
struct {
uint16_t lightness;
uint16_t x;
uint16_t y;
} xyl_default_set;
struct {
uint16_t x_range_min;
uint16_t x_range_max;
uint16_t y_range_min;
uint16_t y_range_max;
} xyl_range_set;
struct {
uint8_t mode;
} lc_mode_set;
struct {
uint8_t mode;
} lc_om_set;
struct {
bool op_en;
uint8_t light_onoff;
uint8_t tid;
uint8_t trans_time;
uint8_t delay;
} lc_light_onoff_set;
struct {
uint16_t id;
struct net_buf_simple *value;
} lc_property_set;
} bt_mesh_light_server_recv_set_msg_t;
typedef union {
struct {
struct net_buf_simple *data;
} sensor_status;
} bt_mesh_light_server_recv_status_msg_t;
void bt_mesh_light_server_lock(void);
void bt_mesh_light_server_unlock(void);
uint8_t *bt_mesh_get_lc_prop_value(struct bt_mesh_model *model, uint16_t prop_id);
void light_lightness_publish(struct bt_mesh_model *model, uint16_t opcode);
void light_ctl_publish(struct bt_mesh_model *model, uint16_t opcode);
void light_hsl_publish(struct bt_mesh_model *model, uint16_t opcode);
void light_xyl_publish(struct bt_mesh_model *model, uint16_t opcode);
void light_lc_publish(struct bt_mesh_model *model, uint16_t opcode);
#ifdef __cplusplus
}
#endif
#endif /* _LIGHTING_SERVER_H_ */
@@ -0,0 +1,246 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _SENSOR_SERVER_H_
#define _SENSOR_SERVER_H_
#include "mesh/server_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Sensor Property ID related */
#define INVALID_SENSOR_PROPERTY_ID 0x0000
#define SENSOR_PROPERTY_ID_LEN 0x02
/* Sensor Descriptor state related */
#define SENSOR_DESCRIPTOR_LEN 0x08
#define SENSOR_UNSPECIFIED_POS_TOLERANCE 0x000
#define SENSOR_UNSPECIFIED_NEG_TOLERANCE 0x000
#define SENSOR_NOT_APPL_MEASURE_PERIOD 0x00
#define SENSOR_NOT_APPL_UPDATE_INTERVAL 0x00
/* Sensor Setting state related */
#define INVALID_SENSOR_SETTING_PROPERTY_ID 0x0000
#define SENSOR_SETTING_PROPERTY_ID_LEN 0x02
#define SENSOR_SETTING_ACCESS_LEN 0x01
#define SENSOR_SETTING_ACCESS_READ 0x01
#define SENSOR_SETTING_ACCESS_READ_WRITE 0x03
/* Sensor Cadence state related */
#define SENSOR_DIVISOR_TRIGGER_TYPE_LEN 0x01
#define SENSOR_STATUS_MIN_INTERVAL_LEN 0x01
#define SENSOR_PERIOD_DIVISOR_MAX_VALUE 15
#define SENSOR_STATUS_MIN_INTERVAL_MAX 26
#define SENSOR_STATUS_TRIGGER_TYPE_CHAR 0
#define SENSOR_STATUS_TRIGGER_TYPE_UINT16 1
#define SENSOR_STATUS_TRIGGER_UINT16_LEN 0x02
/* Sensor Data state related */
#define SENSOR_DATA_FORMAT_A 0x00
#define SENSOR_DATA_FORMAT_B 0x01
#define SENSOR_DATA_FORMAT_A_MPID_LEN 0x02
#define SENSOR_DATA_FORMAT_B_MPID_LEN 0x03
#define SENSOR_DATA_ZERO_LEN 0x7F
enum bt_mesh_sensor_sample_func {
UNSPECIFIED,
INSTANTANEOUS,
ARITHMETIC_MEAN,
RMS,
MAXIMUM,
MINIMUM,
ACCUMULATED,
COUNT,
};
struct sensor_descriptor {
uint32_t positive_tolerance : 12,
negative_tolerance : 12,
sample_function : 8;
uint8_t measure_period;
uint8_t update_interval;
};
struct sensor_setting {
uint16_t property_id;
uint8_t access;
/* Or use union to include all possible types */
struct net_buf_simple *raw;
};
struct sensor_cadence {
uint8_t period_divisor : 7,
trigger_type : 1;
struct net_buf_simple *trigger_delta_down;
struct net_buf_simple *trigger_delta_up;
uint8_t min_interval;
struct net_buf_simple *fast_cadence_low;
struct net_buf_simple *fast_cadence_high;
};
struct sensor_data {
/**
* Format A: The Length field is a 1-based uint4 value (valid range 0x00xF,
* representing range of 1 16).
* Format B: The Length field is a 1-based uint7 value (valid range 0x00x7F,
* representing range of 1 127). The value 0x7F represents a
* length of zero.
*/
uint8_t format : 1,
length : 7;
struct net_buf_simple *raw_value;
};
struct sensor_series_column {
struct net_buf_simple *raw_value_x;
struct net_buf_simple *column_width;
struct net_buf_simple *raw_value_y;
};
struct bt_mesh_sensor_state {
uint16_t sensor_property_id;
/* Constant throughout the lifetime of an element */
struct sensor_descriptor descriptor;
/* Multiple Sensor Setting states may be present for each sensor.
* The Sensor Setting Property ID values shall be unique for each
* Sensor Property ID that identifies a sensor within an element.
*/
const uint8_t setting_count;
struct sensor_setting *settings;
/* The Sensor Cadence state may be not supported by sensors based
* on device properties referencing "non-scalar characteristics"
* such as "histograms" or "composite characteristics".
*/
struct sensor_cadence *cadence;
struct sensor_data sensor_data;
/* Values measured by sensors may be organized as arrays (and
* represented as series of columns, such as histograms).
* 1. The Sensor Raw Value X field has a size and representation
* defined by the Sensor Property ID and represents the left
* corner of the column on the X axis.
* 2. The Sensor Column Width field has a size and representation
* defined by the Sensor Property ID and represents the width
* of the column on the X axis.
* 3. The Sensor Raw Value Y field has a size and representation
* defined by the Sensor Property ID and represents the height
* of the column on the Y axis.
* Note: Values outside the bins defined by a Sensor Property are
* not included. For example, if the histogram is defined as 3 bins
* representing lamp operating hours in a given temperature range
* and the bins are [40,60), [60, 80), and [80,100], then any hours
* outside that [40, 100] range would not be included.
*/
struct sensor_series_column series_column;
};
/* 1. Multiple instances of the Sensor states may be present within the
* same model, provided that each instance has a unique value of the
* Sensor Property ID to allow the instances to be differentiated.
* 2. Note: The number of sensors within a multi-sensor is limited by the
* size of the message payload for the Sensor Descriptor Status message.
* A single Sensor Descriptor may be sent using a single Unsegmented
* Access message. Using Segmentation and Reassembly (SAR), up to 38
* Sensor Descriptor states may be sent.
*/
struct bt_mesh_sensor_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
const uint8_t state_count;
struct bt_mesh_sensor_state *states;
};
struct bt_mesh_sensor_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
const uint8_t state_count;
struct bt_mesh_sensor_state *states;
};
typedef union {
struct {
uint16_t id;
uint8_t period_divisor : 7,
trigger_type : 1;
struct net_buf_simple *trigger_delta_down;
struct net_buf_simple *trigger_delta_up;
uint8_t min_interval;
struct net_buf_simple *fast_cadence_low;
struct net_buf_simple *fast_cadence_high;
} sensor_cadence_set;
struct {
uint16_t id;
uint16_t setting_id;
struct net_buf_simple *value;
} sensor_setting_set;
} bt_mesh_sensor_server_state_change_t;
typedef union {
struct {
bool op_en;
uint16_t id;
} sensor_descriptor_get;
struct {
uint16_t id;
} sensor_cadence_get;
struct {
uint16_t id;
} sensor_settings_get;
struct {
uint16_t id;
uint16_t setting_id;
} sensor_setting_get;
struct {
bool op_en;
uint16_t id;
} sensor_get;
struct {
uint16_t id;
struct net_buf_simple *raw_x;
} sensor_column_get;
struct {
bool op_en;
uint16_t id;
struct net_buf_simple *raw;
} sensor_series_get;
} bt_mesh_sensor_server_recv_get_msg_t;
typedef union {
struct {
uint16_t id;
struct net_buf_simple *cadence;
} sensor_cadence_set;
struct {
uint16_t id;
uint16_t setting_id;
struct net_buf_simple *raw;
} sensor_setting_set;
} bt_mesh_sensor_server_recv_set_msg_t;
#ifdef __cplusplus
}
#endif
#endif /* _SENSOR_SERVER_H_ */
@@ -0,0 +1,124 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _SERVER_COMMON_H_
#define _SERVER_COMMON_H_
#include <string.h>
#include <stdint.h>
#include "mesh/access.h"
#ifdef __cplusplus
extern "C" {
#endif
#define BLE_MESH_SERVER_RSP_MAX_LEN 384
#define BLE_MESH_SERVER_TRANS_MIC_SIZE 4
#define BLE_MESH_CHECK_SEND_STATUS(_func) do { \
int __status = (_func); \
if (__status) { \
BT_ERR("%s, Send failed, err %d", __func__, __status); \
} \
} while(0);
#define BLE_MESH_STATE_OFF 0x00
#define BLE_MESH_STATE_ON 0x01
#define BLE_MESH_STATE_RESTORE 0x02
/* Following 4 values are as per Mesh Model specification */
#define BLE_MESH_LIGHTNESS_MIN 0x0001
#define BLE_MESH_LIGHTNESS_MAX 0xFFFF
#define BLE_MESH_TEMPERATURE_MIN 0x0320
#define BLE_MESH_TEMPERATURE_MAX 0x4E20
#define BLE_MESH_TEMPERATURE_UNKNOWN 0xFFFF
/* Refer 7.2 of Mesh Model Specification */
#define BLE_MESH_RANGE_UPDATE_SUCCESS 0x00
#define BLE_MESH_CANNOT_SET_RANGE_MIN 0x01
#define BLE_MESH_CANNOT_SET_RANGE_MAX 0x02
#define BLE_MESH_UNKNOWN_REMAIN_TIME 0x3F
#define BLE_MESH_DEVICE_SPECIFIC_RESOLUTION 10
enum {
BLE_MESH_TRANS_TIMER_START, /* Proper transition timer has been started */
BLE_MESH_TRANS_FLAG_MAX,
};
struct bt_mesh_state_transition {
bool just_started;
uint8_t trans_time;
uint8_t remain_time;
uint8_t delay;
uint32_t quo_tt;
uint32_t counter;
uint32_t total_duration;
int64_t start_timestamp;
BLE_MESH_ATOMIC_DEFINE(flag, BLE_MESH_TRANS_FLAG_MAX);
struct k_delayed_work timer;
};
struct bt_mesh_last_msg_info {
uint8_t tid;
uint16_t src;
uint16_t dst;
int64_t timestamp;
};
#define BLE_MESH_SERVER_RSP_BY_APP 0
#define BLE_MESH_SERVER_AUTO_RSP 1
struct bt_mesh_server_rsp_ctrl {
/**
* @brief BLE Mesh Server Response Option
* 1. If get_auto_rsp is set to BLE_MESH_SERVER_RSP_BY_APP, then the response
* of Client Get messages need to be replied by the application;
* 2. If get_auto_rsp is set to BLE_MESH_SERVER_AUTO_RSP, then the response
* of Client Get messages will be replied by the server models;
* 3. If set_auto_rsp is set to BLE_MESH_SERVER_RSP_BY_APP, then the response
* of Client Set messages need to be replied by the application;
* 4. If set_auto_rsp is set to BLE_MESH_SERVER_AUTO_RSP, then the response
* of Client Set messages will be replied by the server models;
* 5. If status_auto_rsp is set to BLE_MESH_SERVER_RSP_BY_APP, then the response
* of Server Status messages need to be replied by the application;
* 6. If status_auto_rsp is set to BLE_MESH_SERVER_AUTO_RSP, then the response
* of Server status messages will be replied by the server models;
*/
uint8_t get_auto_rsp : 1, /* Response for Client Get messages */
set_auto_rsp : 1, /* Response for Client Set messages */
status_auto_rsp : 1; /* Response for Server Status messages */
};
uint8_t bt_mesh_get_default_trans_time(struct bt_mesh_model *model);
int bt_mesh_get_light_lc_trans_time(struct bt_mesh_model *model, uint8_t *trans_time);
int bt_mesh_server_get_optional(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf,
uint8_t *trans_time, uint8_t *delay,
bool *optional);
void bt_mesh_server_alloc_ctx(struct k_work *work);
void bt_mesh_server_free_ctx(struct k_work *work);
bool bt_mesh_is_server_recv_last_msg(struct bt_mesh_last_msg_info *last,
uint8_t tid, uint16_t src, uint16_t dst, int64_t *now);
void bt_mesh_server_update_last_msg(struct bt_mesh_last_msg_info *last,
uint8_t tid, uint16_t src, uint16_t dst, int64_t *now);
struct net_buf_simple *bt_mesh_server_get_pub_msg(struct bt_mesh_model *model, uint16_t msg_len);
#ifdef __cplusplus
}
#endif
#endif /* _SERVER_COMMON_H_ */
@@ -0,0 +1,108 @@
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
*
* SPDX-FileCopyrightText: 2018 Vikrant More
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _STATE_BINDING_H_
#define _STATE_BINDING_H_
#include "mesh/access.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
GENERIC_ONOFF_STATE,
GENERIC_LEVEL_STATE,
GENERIC_ONPOWERUP_STATE,
GENERIC_POWER_ACTUAL_STATE,
LIGHT_LIGHTNESS_ACTUAL_STATE,
LIGHT_LIGHTNESS_LINEAR_STATE,
LIGHT_CTL_LIGHTNESS_STATE,
LIGHT_CTL_TEMP_DELTA_UV_STATE,
LIGHT_HSL_STATE,
LIGHT_HSL_LIGHTNESS_STATE,
LIGHT_HSL_HUE_STATE,
LIGHT_HSL_SATURATION_STATE,
LIGHT_XYL_LIGHTNESS_STATE,
LIGHT_LC_LIGHT_ONOFF_STATE,
BIND_STATE_MAX,
} bt_mesh_server_state_type_t;
typedef union {
struct {
uint8_t onoff;
} gen_onoff;
struct {
int16_t level;
} gen_level;
struct {
uint8_t onpowerup;
} gen_onpowerup;
struct {
uint16_t power;
} gen_power_actual;
struct {
uint16_t lightness;
} light_lightness_actual;
struct {
uint16_t lightness;
} light_lightness_linear;
struct {
uint16_t lightness;
} light_ctl_lightness;
struct {
uint16_t temperature;
int16_t delta_uv;
} light_ctl_temp_delta_uv;
struct {
uint16_t lightness;
uint16_t hue;
uint16_t saturation;
} light_hsl;
struct {
uint16_t lightness;
} light_hsl_lightness;
struct {
uint16_t hue;
} light_hsl_hue;
struct {
uint16_t saturation;
} light_hsl_saturation;
struct {
uint16_t lightness;
} light_xyl_lightness;
struct {
uint8_t onoff;
} light_lc_light_onoff;
} bt_mesh_server_state_value_t;
uint16_t bt_mesh_convert_lightness_actual_to_linear(uint16_t actual);
uint16_t bt_mesh_convert_lightness_linear_to_actual(uint16_t linear);
int16_t bt_mesh_convert_temperature_to_gen_level(uint16_t temp, uint16_t min, uint16_t max);
uint16_t bt_mesh_covert_gen_level_to_temperature(int16_t level, uint16_t min, uint16_t max);
int16_t bt_mesh_convert_hue_to_level(uint16_t hue);
uint16_t bt_mesh_convert_level_to_hue(int16_t level);
int16_t bt_mesh_convert_saturation_to_level(uint16_t saturation);
uint16_t bt_mesh_convert_level_to_saturation(int16_t level);
int bt_mesh_update_binding_state(struct bt_mesh_model *model,
bt_mesh_server_state_type_t type,
bt_mesh_server_state_value_t *value);
#ifdef __cplusplus
}
#endif
#endif /* _STATE_BINDING_H_ */
@@ -0,0 +1,100 @@
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
*
* SPDX-FileCopyrightText: 2018 Vikrant More
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _STATE_TRANSITION_H_
#define _STATE_TRANSITION_H_
#include "mesh/server_common.h"
#include "mesh/generic_server.h"
#include "mesh/sensor_server.h"
#include "mesh/lighting_server.h"
#include "mesh/time_scene_server.h"
#ifdef __cplusplus
extern "C" {
#endif
void bt_mesh_server_calc_remain_time(struct bt_mesh_state_transition *transition);
/* APIs used to get server model transition time values */
void generic_onoff_tt_values(struct bt_mesh_gen_onoff_srv *srv,
uint8_t trans_time, uint8_t delay);
void generic_level_tt_values(struct bt_mesh_gen_level_srv *srv,
uint8_t trans_time, uint8_t delay);
void generic_power_level_tt_values(struct bt_mesh_gen_power_level_srv *srv,
uint8_t trans_time, uint8_t delay);
void light_lightness_actual_tt_values(struct bt_mesh_light_lightness_srv *srv,
uint8_t trans_time, uint8_t delay);
void light_lightness_linear_tt_values(struct bt_mesh_light_lightness_srv *srv,
uint8_t trans_time, uint8_t delay);
void light_ctl_tt_values(struct bt_mesh_light_ctl_srv *srv,
uint8_t trans_time, uint8_t delay);
void light_ctl_temp_tt_values(struct bt_mesh_light_ctl_temp_srv *srv,
uint8_t trans_time, uint8_t delay);
void light_hsl_tt_values(struct bt_mesh_light_hsl_srv *srv,
uint8_t trans_time, uint8_t delay);
void light_hsl_hue_tt_values(struct bt_mesh_light_hsl_hue_srv *srv,
uint8_t trans_time, uint8_t delay);
void light_hsl_sat_tt_values(struct bt_mesh_light_hsl_sat_srv *srv,
uint8_t trans_time, uint8_t delay);
void light_xyl_tt_values(struct bt_mesh_light_xyl_srv *srv,
uint8_t trans_time, uint8_t delay);
void light_lc_tt_values(struct bt_mesh_light_lc_srv *srv,
uint8_t trans_time, uint8_t delay);
void scene_tt_values(struct bt_mesh_scene_srv *srv, uint8_t trans_time, uint8_t delay);
/* Server model transition timer handlers */
void generic_onoff_work_handler(struct k_work *work);
void generic_level_work_handler(struct k_work *work);
void generic_power_level_work_handler(struct k_work *work);
void light_lightness_actual_work_handler(struct k_work *work);
void light_lightness_linear_work_handler(struct k_work *work);
void light_ctl_work_handler(struct k_work *work);
void light_ctl_temp_work_handler(struct k_work *work);
void light_hsl_work_handler(struct k_work *work);
void light_hsl_hue_work_handler(struct k_work *work);
void light_hsl_sat_work_handler(struct k_work *work);
void light_xyl_work_handler(struct k_work *work);
void light_lc_work_handler(struct k_work *work);
void scene_recall_work_handler(struct k_work *work);
void bt_mesh_server_stop_transition(struct bt_mesh_state_transition *transition);
void bt_mesh_server_start_transition(struct bt_mesh_state_transition *transition);
#ifdef __cplusplus
}
#endif
#endif /* _STATE_TRANSITION_H_ */
@@ -0,0 +1,384 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _TIME_SCENE_SERVER_H_
#define _TIME_SCENE_SERVER_H_
#include "mesh/server_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* 1. Mesh defines times based on International Atomic Time (TAI). The base
* representation of times is the number of seconds after 00:00:00 TAI
* on 2000-01-01 (that is, 1999-12-31 T23:59:28 UTC).
* 2. UTC: Coordinated Universal Time. For more information, please refer
* to https://time.is/zh/UTC
* 3. For the algorithm used for the transfer between TAI and UTC, please
* refer to Mesh Model Spec Section 5.1.1
*/
#define UNKNOWN_TAI_SECONDS 0x0000000000
#define UNKNOWN_TAI_ZONE_CHANGE 0x0000000000
#define UNKNOWN_TAI_DELTA_CHANGE 0x0000000000
#define TAI_UTC_DELTA_MAX_VALUE 0x7FFF
#define TAI_SECONDS_LEN 0x05
#define TAI_OF_ZONE_CHANGE_LEN 0x05
#define TAI_OF_DELTA_CHANGE_LEN 0x05
#define INVALID_SCENE_NUMBER 0x0000
#define SCENE_NUMBER_LEN 0x02
#define SCHEDULE_YEAR_ANY_YEAR 0x64
#define SCHEDULE_DAY_ANY_DAY 0x00
#define SCHEDULE_HOUR_ANY_HOUR 0x18
#define SCHEDULE_HOUR_ONCE_A_DAY 0x19
#define SCHEDULE_SEC_ANY_OF_HOUR 0x3C
#define SCHEDULE_SEC_EVERY_15_MIN 0x3D
#define SCHEDULE_SEC_EVERY_20_MIN 0x3E
#define SCHEDULE_SEC_ONCE_AN_HOUR 0x3F
#define SCHEDULE_SEC_ANY_OF_MIN 0x3C
#define SCHEDULE_SEC_EVERY_15_SEC 0x3D
#define SCHEDULE_SEC_EVERY_20_SEC 0x3E
#define SCHEDULE_SEC_ONCE_AN_MIN 0x3F
#define SCHEDULE_ACT_TURN_OFF 0x00
#define SCHEDULE_ACT_TURN_ON 0x01
#define SCHEDULE_ACT_SCENE_RECALL 0x02
#define SCHEDULE_ACT_NO_ACTION 0x0F
#define SCHEDULE_SCENE_NO_SCENE 0x0000
#define SCHEDULE_ENTRY_MAX_INDEX 0x0F
#define TIME_NONE 0x00
#define TIME_AUTHORITY 0x01
#define TIME_RELAY 0x02
#define TIME_CLIENT 0x03
#define SCENE_SUCCESS 0x00
#define SCENE_REG_FULL 0x01
#define SCENE_NOT_FOUND 0x02
/**
* The Time state represents the present TAI time, the current TAI-UTC Delta
* and local time zone offset, and the next change to each of the latter
* (e.g., because of a switch from winter to summer time or an announced leap
* second). It consists of 10 fields with a total size of 183 bits.
*/
struct bt_mesh_time_state {
struct {
uint8_t tai_seconds[5];
uint8_t subsecond;
uint8_t uncertainty;
uint8_t time_zone_offset_curr;
uint8_t time_zone_offset_new;
uint8_t tai_zone_change[5];
uint16_t time_authority : 1,
tai_utc_delta_curr : 15;
uint16_t tai_utc_delta_new : 15;
uint8_t tai_delta_change[5];
} time;
uint8_t time_role;
};
struct bt_mesh_time_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_time_state *state;
};
struct bt_mesh_time_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_time_state *state;
};
struct scene_register {
uint16_t scene_number;
uint8_t scene_type; /* Indicate the type of scene value */
/**
* Scene value may use a union to represent later, the union contains
* structures of all the model states which can be stored in a scene.
*/
struct net_buf_simple *scene_value;
};
/**
* Scenes serve as memory banks for storage of states (e.g., a power level
* or a light level/color). Values of states of an element can be stored
* as a scene and can be recalled later from the scene memory.
*
* A scene is represented by a Scene Number, which is a 16-bit non-zero,
* mesh-wide value. (There can be a maximum of 65535 scenes in a mesh
* network.) The meaning of a scene, as well as the state storage container
* associated with it, are determined by a model.
*
* The Scenes state change may start numerous parallel model transitions.
* In that case, each individual model handles the transition internally.
*
* The scene transition is defined as a group of individual model transitions
* started by a Scene Recall operation. The scene transition is in progress
* when at least one transition from the group of individual model transitions
* is in progress.
*/
struct bt_mesh_scenes_state {
const uint16_t scene_count;
struct scene_register *scenes;
/**
* The Current Scene state is a 16-bit value that contains either the Scene
* Number of the currently active scene or a value of 0x0000 when no scene
* is active.
*
* When a Scene Store operation or a Scene Recall operation completes with
* success, the Current Scene state value shall be to the Scene Number used
* during that operation.
*
* When the Current Scene Number is deleted from a Scene Register state as a
* result of Scene Delete operation, the Current Scene state shall be set to
* 0x0000.
*
* When any of the element's state that is marked as Stored with Scene has
* changed not as a result of a Scene Recall operation, the value of the
* Current Scene state shall be set to 0x0000.
*
* When a scene transition is in progress, the value of the Current Scene
* state shall be set to 0x0000.
*/
uint16_t current_scene;
/**
* The Target Scene state is a 16-bit value that contains the target Scene
* Number when a scene transition is in progress.
*
* When the scene transition is in progress and the target Scene Number is
* deleted from a Scene Register state as a result of Scene Delete operation,
* the Target Scene state shall be set to 0x0000.
*
* When the scene transition is in progress and a new Scene Number is stored
* in the Scene Register as a result of Scene Store operation, the Target
* Scene state shall be set to the new Scene Number.
*
* When the scene transition is not in progress, the value of the Target Scene
* state shall be set to 0x0000.
*/
uint16_t target_scene;
/* Indicate the status code for the last operation */
uint8_t status_code;
/* Indicate if scene transition is in progress */
bool in_progress;
};
struct bt_mesh_scene_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_scenes_state *state;
struct bt_mesh_last_msg_info last;
struct bt_mesh_state_transition transition;
};
struct bt_mesh_scene_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_scenes_state *state;
};
struct schedule_register {
bool in_use;
uint64_t year : 7,
month : 12,
day : 5,
hour : 5,
minute : 6,
second : 6,
day_of_week : 7,
action : 4,
trans_time : 8;
uint16_t scene_number;
};
struct bt_mesh_scheduler_state {
const uint8_t schedule_count;
struct schedule_register *schedules; /* Up to 16 scheduled entries */
/**
* A recommended implementation of the Scheduler should calculate the
* value of the TAI Seconds of the next scheduled event and put it in
* a queue of scheduled events sorted by time.
*
* Every second, the first event in the queue is compared with the value
* of the Time state. The first event is executed if it is less than or
* equal to the Time state and then removed from the queue. After
* execution, the Repeat Flag shall be checked, and the next occurrence
* of the scheduled event is calculated and put in the queue.
*
* One second timeout value, and compare the first event in queue with the
* Time state. If it is satisfied, then execute the first event. Also the
* Repeat Flag need to be checked, if it is set then the event needs to
* be put into the end of queue.
*
* sys_slist_t event_queue;
*
* For each event_queue item, it can use the following struct:
* struct schedule_event {
* sys_snode_t node;
* uint8_t event_index;
* };
*
* Also we need a "struct k_delayed_work track_timer" which can be used to
* track the schedule timer and handle proper scheduled events.
*/
};
struct bt_mesh_scheduler_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_scheduler_state *state;
};
struct bt_mesh_scheduler_setup_srv {
struct bt_mesh_model *model;
struct bt_mesh_server_rsp_ctrl rsp_ctrl;
struct bt_mesh_scheduler_state *state;
};
typedef union {
struct {
uint8_t tai_seconds[5];
uint8_t subsecond;
uint8_t uncertainty;
uint16_t time_authority : 1;
uint16_t tai_utc_delta_curr : 15;
uint8_t time_zone_offset_curr;
} time_set;
struct {
uint8_t tai_seconds[5];
uint8_t subsecond;
uint8_t uncertainty;
uint16_t time_authority : 1;
uint16_t tai_utc_delta_curr : 15;
uint8_t time_zone_offset_curr;
} time_status;
struct {
uint8_t time_zone_offset_new;
uint8_t tai_zone_change[5];
} time_zone_set;
struct {
uint16_t tai_utc_delta_new : 15;
uint8_t tai_delta_change[5];
} tai_utc_delta_set;
struct {
uint8_t role;
} time_role_set;
struct {
uint16_t scene_number;
} scene_store;
struct {
uint16_t scene_number;
} scene_recall;
struct {
uint16_t scene_number;
} scene_delete;
struct {
uint64_t index : 4,
year : 7,
month : 12,
day : 5,
hour : 5,
minute : 6,
second : 6,
day_of_week : 7,
action : 4,
trans_time : 8;
uint16_t scene_number;
} scheduler_act_set;
} bt_mesh_time_scene_server_state_change_t;
typedef union {
struct {
uint8_t index;
} scheduler_act_get;
} bt_mesh_time_scene_server_recv_get_msg_t;
typedef union {
struct {
uint8_t tai_seconds[5];
uint8_t subsecond;
uint8_t uncertainty;
uint16_t time_authority : 1;
uint16_t tai_utc_delta : 15;
uint8_t time_zone_offset;
} time_set;
struct {
uint8_t time_zone_offset_new;
uint8_t tai_zone_change[5];
} time_zone_set;
struct {
uint16_t tai_utc_delta_new : 15;
uint16_t padding : 1;
uint8_t tai_delta_change[5];
} tai_utc_delta_set;
struct {
uint8_t time_role;
} time_role_set;
struct {
uint16_t scene_number;
} scene_store;
struct {
bool op_en;
uint16_t scene_number;
uint8_t tid;
uint8_t trans_time;
uint8_t delay;
} scene_recall;
struct {
uint16_t scene_number;
} scene_delete;
struct {
uint64_t index : 4,
year : 7,
month : 12,
day : 5,
hour : 5,
minute : 6,
second : 6,
day_of_week : 7,
action : 4,
trans_time : 8;
uint16_t scene_number;
} scheduler_act_set;
} bt_mesh_time_scene_server_recv_set_msg_t;
typedef union {
struct {
uint8_t tai_seconds[5];
uint8_t subsecond;
uint8_t uncertainty;
uint16_t time_authority : 1;
uint16_t tai_utc_delta : 15;
uint8_t time_zone_offset;
} time_status;
} bt_mesh_time_scene_server_recv_status_msg_t;
void bt_mesh_time_scene_server_lock(void);
void bt_mesh_time_scene_server_unlock(void);
void scene_publish(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, uint16_t opcode);
#ifdef __cplusplus
}
#endif
#endif /* _TIME_SCENE_SERVER_H_ */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,248 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <errno.h>
#include "mesh.h"
#include "mesh/config.h"
#include "access.h"
#include "mesh/common.h"
#include "mesh/generic_server.h"
#include "mesh/lighting_server.h"
#if CONFIG_BLE_MESH_SERVER_MODEL
/**
* According to Mesh Model Spec:
* If the Transition Time field is not present and the Generic Default Transition
* Time state is supported, the Generic Default Transition Time state shall be
* used. Otherwise the transition shall be instantaneous.
*/
#define INSTANTANEOUS_TRANS_TIME 0
uint8_t bt_mesh_get_default_trans_time(struct bt_mesh_model *model)
{
/**
* 1. If a Generic Default Transition Time Server model is present on the
* main element of the model, that model instance shall be used.
* 2. If a Generic Default Transition Time Server model is not present on
* the main element of the model, then the Generic Default Transition
* Time Server model instance that is present on the element with the
* largest address that is smaller than the address of the main element
* of the node shall be used; if no model instance is present on any
* element with an address smaller than the address of the main element,
* then the Generic Default Transition Time Server is not supported.
*/
struct bt_mesh_elem *element = bt_mesh_model_elem(model);
struct bt_mesh_gen_def_trans_time_srv *state = NULL;
uint16_t primary_addr = bt_mesh_primary_addr();
struct bt_mesh_model *srv = NULL;
for (uint16_t addr = element->addr; addr >= primary_addr; addr--) {
element = bt_mesh_elem_find(addr);
if (element) {
srv = bt_mesh_model_find(element, BLE_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV);
if (srv) {
state = (struct bt_mesh_gen_def_trans_time_srv *)srv->user_data;
if (state) {
return state->state.trans_time;
}
}
}
}
return INSTANTANEOUS_TRANS_TIME;
}
int bt_mesh_get_light_lc_trans_time(struct bt_mesh_model *model, uint8_t *trans_time)
{
struct bt_mesh_light_lc_srv *srv = NULL;
uint32_t value = 0U;
if (model == NULL || trans_time == NULL) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
if (model->id != BLE_MESH_MODEL_ID_LIGHT_LC_SRV) {
BT_ERR("Invalid a Light LC Server 0x%04x", model->id);
return -EINVAL;
}
srv = (struct bt_mesh_light_lc_srv *)model->user_data;
if (srv == NULL) {
BT_ERR("Invalid Light LC Server user data");
return -EINVAL;
}
/**
* 1. Set transition time to 0x54 for BQB test case MESH/SR/LLC/BV-04-C.
* Light LC Property Set: 0x3C, 0x004E20 -> Light LC Time Run On
* Light LC Property Set: 0x37, 0x004E20 -> Light LC Time Fade On
* Light LC Property Set: 0x39, 0x004E20 -> Light LC Time Fade Standby Manual
*
* 2. Set transition time to 0x0 for BQB test case MESH/SR/LLC/BV-08-C.
*
* TODO: Based on Light LC state and choose property property value as the
* transition time. Currently directly use Light LC Time Run On property value.
* Unit: Millisecond, range: [0, 16777214(0xFFFFFE)]
*/
value = srv->lc->prop_state.time_run_on & 0xFFFFFF;
/**
* Convert value into Default Transition Time state format.
* 0b00: 0 ~ 6.2s, 100 millisecond step resolution
* 0b01: 0 ~ 62s, 1 second step resolution
* 0b10: 0 ~ 620s, 10 seconds step resolution
* 0b11: 0 ~ 620m, 10 minutes step resolution
*/
if (value <= 6200) {
*trans_time = (0 << 6) | (value / 100);
} else if (value <= 62000) {
*trans_time = (1 << 6) | (value / 1000);
} else if (value <= 620000) {
*trans_time = (2 << 6) | (value / 10000);
} else {
*trans_time = (3 << 6) | (value / 600000);
}
return 0;
}
int bt_mesh_server_get_optional(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf,
uint8_t *trans_time, uint8_t *delay,
bool *optional)
{
if (model == NULL || buf == NULL || trans_time == NULL ||
delay == NULL || optional == NULL) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
if (buf->len != 0x00 && buf->len != 0x02) {
BT_ERR("Invalid optional message length %d", buf->len);
return -EINVAL;
}
/* No optional fields are available */
if (buf->len == 0x00) {
if (model->id == BLE_MESH_MODEL_ID_LIGHT_LC_SRV) {
/**
* Both messages(i.e. Light LC OnOff Set/Set Unack) may optionally include
* a Transition Time field indicating the transition time to the target state.
* If the Transition Time is not included, the Light LC Server shall use
* its appropriate transition times defined by the Light LC Property states.
*/
if (bt_mesh_get_light_lc_trans_time(model, trans_time)) {
BT_ERR("Failed to get Light LC transition time");
return -EIO;
}
} else {
*trans_time = bt_mesh_get_default_trans_time(model);
}
*delay = 0U;
*optional = false;
return 0;
}
/* Optional fields are available */
*trans_time = net_buf_simple_pull_u8(buf);
if ((*trans_time & 0x3F) == 0x3F) {
BT_ERR("Invalid Transaction Number of Steps 0x3f");
return -EINVAL;
}
*delay = net_buf_simple_pull_u8(buf);
*optional = true;
return 0;
}
void bt_mesh_server_alloc_ctx(struct k_work *work)
{
/**
* This function is used to allocate memory for storing "struct bt_mesh_msg_ctx"
* of the received messages, because some server models will callback the "struct
* bt_mesh_msg_ctx" info to the application layer after a certain delay.
* Here we use the allocated heap memory to store the "struct bt_mesh_msg_ctx".
*/
__ASSERT(work, "Invalid parameter");
if (!work->user_data) {
work->user_data = bt_mesh_calloc(sizeof(struct bt_mesh_msg_ctx));
__ASSERT(work->user_data, "Out of memory");
}
}
#if CONFIG_BLE_MESH_DEINIT
void bt_mesh_server_free_ctx(struct k_work *work)
{
__ASSERT(work, "Invalid parameter");
if (work->user_data) {
bt_mesh_free(work->user_data);
work->user_data = NULL;
}
}
#endif /* CONFIG_BLE_MESH_DEINIT */
bool bt_mesh_is_server_recv_last_msg(struct bt_mesh_last_msg_info *last,
uint8_t tid, uint16_t src, uint16_t dst, int64_t *now)
{
*now = k_uptime_get();
/* Currently we only compare msg info which dst is set to a unicast address */
if (!BLE_MESH_ADDR_IS_UNICAST(dst)) {
return false;
}
if (last->tid == tid && last->src == src && last->dst == dst &&
(*now - last->timestamp <= K_SECONDS(6))) {
return true;
}
return false;
}
void bt_mesh_server_update_last_msg(struct bt_mesh_last_msg_info *last,
uint8_t tid, uint16_t src, uint16_t dst, int64_t *now)
{
/* Currently we only update msg info which dst is set to a unicast address */
if (!BLE_MESH_ADDR_IS_UNICAST(dst)) {
return;
}
last->tid = tid;
last->src = src;
last->dst = dst;
last->timestamp = *now;
}
struct net_buf_simple *bt_mesh_server_get_pub_msg(struct bt_mesh_model *model, uint16_t msg_len)
{
struct net_buf_simple *buf = NULL;
if (model == NULL) {
BT_ERR("%s, Invalid parameter", __func__);
return NULL;
}
if (model->pub == NULL || model->pub->msg == NULL ||
model->pub->addr == BLE_MESH_ADDR_UNASSIGNED) {
BT_DBG("No publication support, model id 0x%04x", model->id);
return NULL;
}
buf = model->pub->msg;
if (buf->size < msg_len) {
BT_ERR("Too small publication msg size %d, model id 0x%04x",
buf->size, model->id);
return NULL;
}
return buf;
}
#endif /* CONFIG_BLE_MESH_SERVER_MODEL */
@@ -0,0 +1,336 @@
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
*
* SPDX-FileCopyrightText: 2018 Vikrant More
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <errno.h>
#include "mesh/config.h"
#include "mesh/common.h"
#include "mesh/model_common.h"
#include "mesh/model_opcode.h"
#include "mesh/state_binding.h"
#include "mesh/state_transition.h"
#if CONFIG_BLE_MESH_SERVER_MODEL
uint16_t bt_mesh_convert_lightness_actual_to_linear(uint16_t actual)
{
float tmp = ((float) actual / UINT16_MAX);
return bt_mesh_ceil(UINT16_MAX * tmp * tmp);
}
uint16_t bt_mesh_convert_lightness_linear_to_actual(uint16_t linear)
{
return (uint16_t) (UINT16_MAX * bt_mesh_sqrt(((float) linear / UINT16_MAX)));
}
int16_t bt_mesh_convert_temperature_to_gen_level(uint16_t temp, uint16_t min, uint16_t max)
{
float tmp = (temp - min) * UINT16_MAX / (max - min);
return (int16_t) (tmp + INT16_MIN);
}
uint16_t bt_mesh_covert_gen_level_to_temperature(int16_t level, uint16_t min, uint16_t max)
{
float diff = (float) (max - min) / UINT16_MAX;
uint16_t tmp = (uint16_t) ((level - INT16_MIN) * diff);
return (uint16_t) (min + tmp);
}
int16_t bt_mesh_convert_hue_to_level(uint16_t hue)
{
return (int16_t) (hue + INT16_MIN);
}
uint16_t bt_mesh_convert_level_to_hue(int16_t level)
{
return (uint16_t) (level - INT16_MIN);
}
int16_t bt_mesh_convert_saturation_to_level(uint16_t saturation)
{
return (int16_t) (saturation + INT16_MIN);
}
uint16_t bt_mesh_convert_level_to_saturation(int16_t level)
{
return (uint16_t) (level - INT16_MIN);
}
int bt_mesh_update_binding_state(struct bt_mesh_model *model,
bt_mesh_server_state_type_t type,
bt_mesh_server_state_value_t *value)
{
if (model == NULL || model->user_data == NULL ||
value == NULL || type > BIND_STATE_MAX) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
switch (type) {
#if CONFIG_BLE_MESH_GENERIC_SERVER
case GENERIC_ONOFF_STATE: {
if (model->id != BLE_MESH_MODEL_ID_GEN_ONOFF_SRV) {
BT_ERR("Invalid Generic OnOff Server, model id 0x%04x", model->id);
return -EINVAL;
}
struct bt_mesh_gen_onoff_srv *srv = model->user_data;
bt_mesh_server_stop_transition(&srv->transition);
srv->state.onoff = value->gen_onoff.onoff;
gen_onoff_publish(model);
break;
}
case GENERIC_LEVEL_STATE: {
if (model->id != BLE_MESH_MODEL_ID_GEN_LEVEL_SRV) {
BT_ERR("Invalid Generic Level Server, model id 0x%04x", model->id);
return -EINVAL;
}
struct bt_mesh_gen_level_srv *srv = model->user_data;
bt_mesh_server_stop_transition(&srv->transition);
srv->state.level = value->gen_level.level;
gen_level_publish(model);
break;
}
case GENERIC_ONPOWERUP_STATE: {
if (model->id != BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SRV) {
BT_ERR("Invalid Generic Power OnOff Server, model id 0x%04x", model->id);
return -EINVAL;
}
struct bt_mesh_gen_power_onoff_srv *srv = model->user_data;
if (srv->state == NULL) {
BT_ERR("Invalid Generic Power OnOff Server state");
return -EINVAL;
}
srv->state->onpowerup = value->gen_onpowerup.onpowerup;
gen_onpowerup_publish(model);
break;
}
case GENERIC_POWER_ACTUAL_STATE: {
if (model->id != BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SRV) {
BT_ERR("Invalid Generic Power Level Server, model id 0x%04x", model->id);
return -EINVAL;
}
struct bt_mesh_gen_power_level_srv *srv = model->user_data;
if (srv->state == NULL) {
BT_ERR("Invalid Generic Power Level Server state");
return -EINVAL;
}
bt_mesh_server_stop_transition(&srv->transition);
srv->state->power_actual = value->gen_power_actual.power;
/**
* Whenever the Generic Power Actual state is changed to a non-zero value
* as a result of a non-transactional message or a completed sequence of
* transactional messages, the value of the Generic Power Last state shall
* be set to the value of the Generic Power Actual state.
*/
if (srv->state->power_actual) {
srv->state->power_last = srv->state->power_actual;
}
gen_power_level_publish(model, BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS);
break;
}
#endif /* CONFIG_BLE_MESH_GENERIC_SERVER */
#if CONFIG_BLE_MESH_LIGHTING_SERVER
case LIGHT_LIGHTNESS_ACTUAL_STATE: {
if (model->id != BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV) {
BT_ERR("Invalid Light Lightness Server, model id 0x%04x", model->id);
return -EINVAL;
}
struct bt_mesh_light_lightness_srv *srv = model->user_data;
if (srv->state == NULL) {
BT_ERR("Invalid Light Lightness Server state");
return -EINVAL;
}
bt_mesh_server_stop_transition(&srv->actual_transition);
srv->state->lightness_actual = value->light_lightness_actual.lightness;
/**
* Whenever the Light Lightness Actual state is changed with a non-transactional
* message or a completed sequence of transactional messages to a non-zero value,
* the value of the Light Lightness Last shall be set to the value of the Light
* Lightness Actual.
*/
if (srv->state->lightness_actual) {
srv->state->lightness_last = srv->state->lightness_actual;
}
light_lightness_publish(model, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS);
break;
}
case LIGHT_LIGHTNESS_LINEAR_STATE: {
if (model->id != BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV) {
BT_ERR("Invalid Light Lightness Server, model id 0x%04x", model->id);
return -EINVAL;
}
struct bt_mesh_light_lightness_srv *srv = model->user_data;
if (srv->state == NULL) {
BT_ERR("Invalid Light Lightness Server state");
return -EINVAL;
}
bt_mesh_server_stop_transition(&srv->linear_transition);
srv->state->lightness_linear = value->light_lightness_linear.lightness;
light_lightness_publish(model, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS);
break;
}
case LIGHT_CTL_LIGHTNESS_STATE: {
if (model->id != BLE_MESH_MODEL_ID_LIGHT_CTL_SRV) {
BT_ERR("Invalid Light CTL Server, model id 0x%04x", model->id);
return -EINVAL;
}
struct bt_mesh_light_ctl_srv *srv = model->user_data;
if (srv->state == NULL) {
BT_ERR("Invalid Light CTL Server state");
return -EINVAL;
}
bt_mesh_server_stop_transition(&srv->transition);
srv->state->lightness = value->light_ctl_lightness.lightness;
light_ctl_publish(model, BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS);
break;
}
case LIGHT_CTL_TEMP_DELTA_UV_STATE: {
if (model->id != BLE_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV) {
BT_ERR("Invalid Light CTL Temperature Server, model id 0x%04x", model->id);
return -EINVAL;
}
struct bt_mesh_light_ctl_temp_srv *srv = model->user_data;
if (srv->state == NULL) {
BT_ERR("Invalid Light CTL Temperature Server state");
return -EINVAL;
}
bt_mesh_server_stop_transition(&srv->transition);
srv->state->temperature = value->light_ctl_temp_delta_uv.temperature;
srv->state->delta_uv = value->light_ctl_temp_delta_uv.delta_uv;
light_ctl_publish(model, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS);
break;
}
case LIGHT_HSL_STATE: {
if (model->id != BLE_MESH_MODEL_ID_LIGHT_HSL_SRV) {
BT_ERR("Invalid Light HSL Server, model id 0x%04x", model->id);
return -EINVAL;
}
struct bt_mesh_light_hsl_srv *srv = model->user_data;
if (srv->state == NULL) {
BT_ERR("Invalid Light HSL Server state");
return -EINVAL;
}
bt_mesh_server_stop_transition(&srv->transition);
srv->state->lightness = value->light_hsl.lightness;
srv->state->hue = value->light_hsl.hue;
srv->state->saturation = value->light_hsl.saturation;
light_hsl_publish(model, BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS);
break;
}
case LIGHT_HSL_LIGHTNESS_STATE: {
if (model->id != BLE_MESH_MODEL_ID_LIGHT_HSL_SRV) {
BT_ERR("Invalid Light HSL Server, model id 0x%04x", model->id);
return -EINVAL;
}
struct bt_mesh_light_hsl_srv *srv = model->user_data;
if (srv->state == NULL) {
BT_ERR("Invalid Light HSL Server state");
return -EINVAL;
}
bt_mesh_server_stop_transition(&srv->transition);
srv->state->lightness = value->light_hsl_lightness.lightness;
light_hsl_publish(model, BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS);
break;
}
case LIGHT_HSL_HUE_STATE: {
if (model->id != BLE_MESH_MODEL_ID_LIGHT_HSL_HUE_SRV) {
BT_ERR("Invalid Light HSL Hue Server, model id 0x%04x", model->id);
return -EINVAL;
}
struct bt_mesh_light_hsl_hue_srv *srv = model->user_data;
if (srv->state == NULL) {
BT_ERR("Invalid Light HSL Hue Server state");
return -EINVAL;
}
bt_mesh_server_stop_transition(&srv->transition);
srv->state->hue = value->light_hsl_hue.hue;
light_hsl_publish(model, BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS);
break;
}
case LIGHT_HSL_SATURATION_STATE: {
if (model->id != BLE_MESH_MODEL_ID_LIGHT_HSL_SAT_SRV) {
BT_ERR("Invalid Light HSL Saturation Server, model id 0x%04x", model->id);
return -EINVAL;
}
struct bt_mesh_light_hsl_sat_srv *srv = model->user_data;
if (srv->state == NULL) {
BT_ERR("Invalid Light HSL Saturation Server state");
return -EINVAL;
}
bt_mesh_server_stop_transition(&srv->transition);
srv->state->saturation = value->light_hsl_saturation.saturation;
light_hsl_publish(model, BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS);
break;
}
case LIGHT_XYL_LIGHTNESS_STATE: {
if (model->id != BLE_MESH_MODEL_ID_LIGHT_XYL_SRV) {
BT_ERR("Invalid Light xyL Server, model id 0x%04x", model->id);
return -EINVAL;
}
struct bt_mesh_light_xyl_srv *srv = model->user_data;
if (srv->state == NULL) {
BT_ERR("Invalid Light xyL Server state");
return -EINVAL;
}
bt_mesh_server_stop_transition(&srv->transition);
srv->state->lightness = value->light_xyl_lightness.lightness;
light_xyl_publish(model, BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS);
break;
}
case LIGHT_LC_LIGHT_ONOFF_STATE: {
if (model->id != BLE_MESH_MODEL_ID_LIGHT_LC_SRV) {
BT_ERR("Invalid Light LC Server, model id 0x%04x", model->id);
return -EINVAL;
}
struct bt_mesh_light_lc_srv *srv = model->user_data;
if (srv->lc == NULL) {
BT_ERR("Invalid Light LC Server state");
return -EINVAL;
}
bt_mesh_server_stop_transition(&srv->transition);
srv->lc->state.light_onoff = value->light_lc_light_onoff.onoff;
light_lc_publish(model, BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS);
break;
}
#endif /* CONFIG_BLE_MESH_LIGHTING_SERVER */
default:
BT_WARN("Unknown binding state type 0x%02x", type);
return -EINVAL;
}
return 0;
}
#endif /* CONFIG_BLE_MESH_SERVER_MODEL */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff