Bluetooth: Mesh: Add model publish support to Health Client

Mesh Profile Specification errata 11310
Section 4.4.4.1
"This model shall support model publication, as defined in Section
4.2.2 of the Mesh Profile specification and model subscription,
as defined in section 4.2.3 of the Mesh Profile specification."

Signed-off-by: Michal Narajowski <michal.narajowski@codecoup.pl>
This commit is contained in:
Michal Narajowski 2022-05-25 10:34:03 +02:00 committed by Fabio Baltieri
commit fab8e29ee2
9 changed files with 659 additions and 367 deletions

View file

@ -6,9 +6,11 @@ Health Client
The Health Client model interacts with a Health Server model to read out
diagnostics and control the node's attention state.
All message passing functions in the Health Client API have ``net_idx`` and
``addr`` as their first parameters. These should be set to the network index
and primary unicast address that the target node was provisioned with.
All message passing functions in the Health Client API have ``cli`` as
their first parameter. This is a pointer to the client model instance to be
used in this function call. The second parameter is the ``ctx`` or message
context. Message context contains netkey index, appkey index and unicast
address that the target node uses.
The Health Client model is optional, and may be instantiated in any element.
However, if a Health Client model is instantiated in an element other than the

View file

@ -141,6 +141,26 @@ Deprecated in this release
* :c:macro:`UTIL_LISTIFY` has been deprecated. Use :c:macro:`LISTIFY` instead.
* Mesh
* The following functions related to the Bluetooth Mesh Health Client model:
* :c:func:`bt_mesh_health_fault_get()` replace with :c:func:`bt_mesh_health_cli_fault_get()`
* :c:func:`bt_mesh_health_fault_clear()` replace with :c:func:`bt_mesh_health_cli_fault_clear()`
* :c:func:`bt_mesh_health_fault_clear_unack()` replace with :c:func:`bt_mesh_health_cli_fault_clear_unack()`
* :c:func:`bt_mesh_health_fault_test()` replace with :c:func:`bt_mesh_health_cli_fault_test()`
* :c:func:`bt_mesh_health_fault_test_unack()` replace with :c:func:`bt_mesh_health_cli_fault_test_unack()`
* :c:func:`bt_mesh_health_period_get()` replace with :c:func:`bt_mesh_health_cli_period_get()`
* :c:func:`bt_mesh_health_period_set()` replace with :c:func:`bt_mesh_health_cli_period_set()`
* :c:func:`bt_mesh_health_period_set_unack()` replace with :c:func:`bt_mesh_health_cli_period_set_unack()`
* :c:func:`bt_mesh_health_attention_get()` replace with :c:func:`bt_mesh_health_cli_attention_get()`
* :c:func:`bt_mesh_health_attention_set()` replace with :c:func:`bt_mesh_health_cli_attention_set()`
* :c:func:`bt_mesh_health_attention_set_unack()` replace with :c:func:`bt_mesh_health_cli_attention_set_unack()`
* The following function related to the Bluetooth Mesh Health Server model:
* :c:func:`bt_mesh_fault_update()` replace with :c:func:`bt_mesh_health_srv_fault_update()`
Stable API changes in this release
==================================

View file

@ -26,6 +26,15 @@ struct bt_mesh_health_cli {
/** Composition data model entry pointer. */
struct bt_mesh_model *model;
/** Publication structure instance */
struct bt_mesh_model_pub pub;
/** Publication buffer */
struct net_buf_simple pub_buf;
/** Publication data */
uint8_t pub_data[BT_MESH_MODEL_BUF_LEN(BT_MESH_MODEL_OP_2(0x80, 0x32), 3)];
/** @brief Optional callback for Health Period Status messages.
*
* Handles received Health Period Status messages from a Health
@ -100,7 +109,7 @@ struct bt_mesh_health_cli {
*/
#define BT_MESH_MODEL_HEALTH_CLI(cli_data) \
BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_HEALTH_CLI, bt_mesh_health_cli_op, \
NULL, cli_data, &bt_mesh_health_cli_cb)
&(cli_data)->pub, cli_data, &bt_mesh_health_cli_cb)
/** @brief Set Health client model instance to use for communication.
*
@ -108,7 +117,7 @@ struct bt_mesh_health_cli {
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_cli_set(struct bt_mesh_model *model);
__deprecated int bt_mesh_health_cli_set(struct bt_mesh_model *model);
/** @brief Get the registered fault state for the given Company ID.
*
@ -131,9 +140,8 @@ int bt_mesh_health_cli_set(struct bt_mesh_model *model);
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_fault_get(uint16_t addr, uint16_t app_idx, uint16_t cid,
uint8_t *test_id, uint8_t *faults,
size_t *fault_count);
__deprecated int bt_mesh_health_fault_get(uint16_t addr, uint16_t app_idx, uint16_t cid,
uint8_t *test_id, uint8_t *faults, size_t *fault_count);
/** @brief Clear the registered faults for the given Company ID.
*
@ -156,9 +164,8 @@ int bt_mesh_health_fault_get(uint16_t addr, uint16_t app_idx, uint16_t cid,
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_fault_clear(uint16_t addr, uint16_t app_idx, uint16_t cid,
uint8_t *test_id, uint8_t *faults,
size_t *fault_count);
__deprecated int bt_mesh_health_fault_clear(uint16_t addr, uint16_t app_idx, uint16_t cid,
uint8_t *test_id, uint8_t *faults, size_t *fault_count);
/** @brief Clear the registered faults for the given Company ID (unacked).
*
@ -170,8 +177,7 @@ int bt_mesh_health_fault_clear(uint16_t addr, uint16_t app_idx, uint16_t cid,
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_fault_clear_unack(uint16_t addr, uint16_t app_idx,
uint16_t cid);
__deprecated int bt_mesh_health_fault_clear_unack(uint16_t addr, uint16_t app_idx, uint16_t cid);
/** @brief Invoke a self-test procedure for the given Company ID.
*
@ -191,9 +197,8 @@ int bt_mesh_health_fault_clear_unack(uint16_t addr, uint16_t app_idx,
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_fault_test(uint16_t addr, uint16_t app_idx, uint16_t cid,
uint8_t test_id, uint8_t *faults,
size_t *fault_count);
__deprecated int bt_mesh_health_fault_test(uint16_t addr, uint16_t app_idx, uint16_t cid,
uint8_t test_id, uint8_t *faults, size_t *fault_count);
/** @brief Invoke a self-test procedure for the given Company ID (unacked).
*
@ -204,8 +209,8 @@ int bt_mesh_health_fault_test(uint16_t addr, uint16_t app_idx, uint16_t cid,
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_fault_test_unack(uint16_t addr, uint16_t app_idx,
uint16_t cid, uint8_t test_id);
__deprecated int bt_mesh_health_fault_test_unack(uint16_t addr, uint16_t app_idx, uint16_t cid,
uint8_t test_id);
/** @brief Get the target node's Health fast period divisor.
*
@ -230,8 +235,7 @@ int bt_mesh_health_fault_test_unack(uint16_t addr, uint16_t app_idx,
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_period_get(uint16_t addr, uint16_t app_idx,
uint8_t *divisor);
__deprecated int bt_mesh_health_period_get(uint16_t addr, uint16_t app_idx, uint8_t *divisor);
/** @brief Set the target node's Health fast period divisor.
*
@ -257,7 +261,7 @@ int bt_mesh_health_period_get(uint16_t addr, uint16_t app_idx,
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_period_set(uint16_t addr, uint16_t app_idx, uint8_t divisor,
__deprecated int bt_mesh_health_period_set(uint16_t addr, uint16_t app_idx, uint8_t divisor,
uint8_t *updated_divisor);
/** @brief Set the target node's Health fast period divisor (unacknowledged).
@ -270,8 +274,7 @@ int bt_mesh_health_period_set(uint16_t addr, uint16_t app_idx, uint8_t divisor,
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_period_set_unack(uint16_t addr, uint16_t app_idx,
uint8_t divisor);
__deprecated int bt_mesh_health_period_set_unack(uint16_t addr, uint16_t app_idx, uint8_t divisor);
/** @brief Get the current attention timer value.
*
@ -288,8 +291,7 @@ int bt_mesh_health_period_set_unack(uint16_t addr, uint16_t app_idx,
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_attention_get(uint16_t addr, uint16_t app_idx,
uint8_t *attention);
__deprecated int bt_mesh_health_attention_get(uint16_t addr, uint16_t app_idx, uint8_t *attention);
/** @brief Set the attention timer.
*
@ -308,8 +310,8 @@ int bt_mesh_health_attention_get(uint16_t addr, uint16_t app_idx,
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_attention_set(uint16_t addr, uint16_t app_idx,
uint8_t attention, uint8_t *updated_attention);
__deprecated int bt_mesh_health_attention_set(uint16_t addr, uint16_t app_idx, uint8_t attention,
uint8_t *updated_attention);
/** @brief Set the attention timer (unacknowledged).
*
@ -319,9 +321,232 @@ int bt_mesh_health_attention_set(uint16_t addr, uint16_t app_idx,
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_attention_set_unack(uint16_t addr, uint16_t app_idx,
__deprecated int bt_mesh_health_attention_set_unack(uint16_t addr, uint16_t app_idx,
uint8_t attention);
/** @brief Get the registered fault state for the given Company ID.
*
* This method can be used asynchronously by setting @p test_id
* and ( @p faults or @p fault_count ) as NULL This way the method
* will not wait for response and will return immediately after
* sending the command.
*
* To process the response arguments of an async method, register
* the @c fault_status callback in @c bt_mesh_health_cli struct.
*
* @see bt_mesh_health_faults
*
* @param cli Client model to send on.
* @param ctx Message context, or NULL to use the configured publish
* parameters.
* @param cid Company ID to get the registered faults of.
* @param test_id Test ID response buffer.
* @param faults Fault array response buffer.
* @param fault_count Fault count response buffer.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_cli_fault_get(struct bt_mesh_health_cli *cli, struct bt_mesh_msg_ctx *ctx,
uint16_t cid, uint8_t *test_id, uint8_t *faults,
size_t *fault_count);
/** @brief Clear the registered faults for the given Company ID.
*
* This method can be used asynchronously by setting @p test_id
* and ( @p faults or @p fault_count ) as NULL This way the method
* will not wait for response and will return immediately after
* sending the command.
*
* To process the response arguments of an async method, register
* the @c fault_status callback in @c bt_mesh_health_cli struct.
*
* @see bt_mesh_health_faults
*
* @param cli Client model to send on.
* @param ctx Message context, or NULL to use the configured publish
* parameters.
* @param cid Company ID to clear the registered faults for.
* @param test_id Test ID response buffer.
* @param faults Fault array response buffer.
* @param fault_count Fault count response buffer.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_cli_fault_clear(struct bt_mesh_health_cli *cli, struct bt_mesh_msg_ctx *ctx,
uint16_t cid, uint8_t *test_id, uint8_t *faults,
size_t *fault_count);
/** @brief Clear the registered faults for the given Company ID (unacked).
*
* @see bt_mesh_health_faults
*
* @param cli Client model to send on.
* @param ctx Message context, or NULL to use the configured publish
* parameters.
* @param cid Company ID to clear the registered faults for.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_cli_fault_clear_unack(struct bt_mesh_health_cli *cli,
struct bt_mesh_msg_ctx *ctx, uint16_t cid);
/** @brief Invoke a self-test procedure for the given Company ID.
*
* This method can be used asynchronously by setting @p faults
* or @p fault_count as NULL This way the method will not wait
* for response and will return immediately after sending the command.
*
* To process the response arguments of an async method, register
* the @c fault_status callback in @c bt_mesh_health_cli struct.
*
* @param cli Client model to send on.
* @param ctx Message context, or NULL to use the configured publish
* parameters.
* @param cid Company ID to invoke the test for.
* @param test_id Test ID response buffer.
* @param faults Fault array response buffer.
* @param fault_count Fault count response buffer.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_cli_fault_test(struct bt_mesh_health_cli *cli, struct bt_mesh_msg_ctx *ctx,
uint16_t cid, uint8_t test_id, uint8_t *faults,
size_t *fault_count);
/** @brief Invoke a self-test procedure for the given Company ID (unacked).
*
* @param cli Client model to send on.
* @param ctx Message context, or NULL to use the configured publish
* parameters.
* @param cid Company ID to invoke the test for.
* @param test_id Test ID response buffer.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_cli_fault_test_unack(struct bt_mesh_health_cli *cli, struct bt_mesh_msg_ctx *ctx,
uint16_t cid, uint8_t test_id);
/** @brief Get the target node's Health fast period divisor.
*
* The health period divisor is used to increase the publish rate when a fault
* is registered. Normally, the Health server will publish with the period in
* the configured publish parameters. When a fault is registered, the publish
* period is divided by (1 << divisor). For example, if the target node's
* Health server is configured to publish with a period of 16 seconds, and the
* Health fast period divisor is 5, the Health server will publish with an
* interval of 500 ms when a fault is registered.
*
* This method can be used asynchronously by setting @p divisor
* as NULL. This way the method will not wait for response and will
* return immediately after sending the command.
*
* To process the response arguments of an async method, register
* the @c period_status callback in @c bt_mesh_health_cli struct.
*
* @param cli Client model to send on.
* @param ctx Message context, or NULL to use the configured publish
* parameters.
* @param divisor Health period divisor response buffer.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_cli_period_get(struct bt_mesh_health_cli *cli, struct bt_mesh_msg_ctx *ctx,
uint8_t *divisor);
/** @brief Set the target node's Health fast period divisor.
*
* The health period divisor is used to increase the publish rate when a fault
* is registered. Normally, the Health server will publish with the period in
* the configured publish parameters. When a fault is registered, the publish
* period is divided by (1 << divisor). For example, if the target node's
* Health server is configured to publish with a period of 16 seconds, and the
* Health fast period divisor is 5, the Health server will publish with an
* interval of 500 ms when a fault is registered.
*
* This method can be used asynchronously by setting @p updated_divisor
* as NULL. This way the method will not wait for response and will
* return immediately after sending the command.
*
* To process the response arguments of an async method, register
* the @c period_status callback in @c bt_mesh_health_cli struct.
*
* @param cli Client model to send on.
* @param ctx Message context, or NULL to use the configured publish
* parameters.
* @param divisor New Health period divisor.
* @param updated_divisor Health period divisor response buffer.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_cli_period_set(struct bt_mesh_health_cli *cli, struct bt_mesh_msg_ctx *ctx,
uint8_t divisor, uint8_t *updated_divisor);
/** @brief Set the target node's Health fast period divisor (unacknowledged).
*
* This is an unacknowledged version of this API.
*
* @param cli Client model to send on.
* @param ctx Message context, or NULL to use the configured publish
* parameters.
* @param divisor New Health period divisor.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_cli_period_set_unack(struct bt_mesh_health_cli *cli, struct bt_mesh_msg_ctx *ctx,
uint8_t divisor);
/** @brief Get the current attention timer value.
*
* This method can be used asynchronously by setting @p attention
* as NULL. This way the method will not wait for response and will
* return immediately after sending the command.
*
* To process the response arguments of an async method, register
* the @c attention_status callback in @c bt_mesh_health_cli struct.
*
* @param cli Client model to send on.
* @param ctx Message context, or NULL to use the configured publish
* parameters.
* @param attention Attention timer response buffer, measured in seconds.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_cli_attention_get(struct bt_mesh_health_cli *cli, struct bt_mesh_msg_ctx *ctx,
uint8_t *attention);
/** @brief Set the attention timer.
*
* This method can be used asynchronously by setting @p updated_attention
* as NULL. This way the method will not wait for response and will
* return immediately after sending the command.
*
* To process the response arguments of an async method, register
* the @c attention_status callback in @c bt_mesh_health_cli struct.
*
* @param cli Client model to send on.
* @param ctx Message context, or NULL to use the configured publish
* parameters.
* @param attention New attention timer time, in seconds.
* @param updated_attention Attention timer response buffer, measured in
* seconds.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_cli_attention_set(struct bt_mesh_health_cli *cli, struct bt_mesh_msg_ctx *ctx,
uint8_t attention, uint8_t *updated_attention);
/** @brief Set the attention timer (unacknowledged).
*
* @param cli Client model to send on.
* @param ctx Message context, or NULL to use the configured publish
* parameters.
* @param attention New attention timer time, in seconds.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_health_cli_attention_set_unack(struct bt_mesh_health_cli *cli,
struct bt_mesh_msg_ctx *ctx, uint8_t attention);
/** @brief Get the current transmission timeout value.
*
* @return The configured transmission timeout in milliseconds.

View file

@ -182,7 +182,19 @@ struct bt_mesh_health_srv {
*
* @return 0 on success, or (negative) error code otherwise.
*/
int bt_mesh_fault_update(struct bt_mesh_elem *elem);
__deprecated int bt_mesh_fault_update(struct bt_mesh_elem *elem);
/** @brief Notify the stack that the fault array state of the given element has
* changed.
*
* This prompts the Health server on this element to publish the current fault
* array if periodic publishing is disabled.
*
* @param elem Element to update the fault state of.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int bt_mesh_health_srv_fault_update(struct bt_mesh_elem *elem);
/** @cond INTERNAL_HIDDEN */
extern const struct bt_mesh_model_op bt_mesh_health_srv_op[];

View file

@ -39,6 +39,7 @@ static int health_fault_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
struct bt_mesh_health_cli *cli = model->user_data;
struct health_fault_param *param;
uint8_t test_id;
uint16_t cid;
@ -50,7 +51,7 @@ static int health_fault_status(struct bt_mesh_model *model,
test_id = net_buf_simple_pull_u8(buf);
cid = net_buf_simple_pull_le16(buf);
if (bt_mesh_msg_ack_ctx_match(&health_cli->ack_ctx,
if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx,
OP_HEALTH_FAULT_STATUS, ctx->addr,
(void **)&param)) {
if (param->expect_test_id &&
@ -76,12 +77,12 @@ static int health_fault_status(struct bt_mesh_model *model,
memcpy(param->faults, buf->data, *param->fault_count);
}
bt_mesh_msg_ack_ctx_rx(&health_cli->ack_ctx);
bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
}
done:
if (health_cli->fault_status) {
health_cli->fault_status(health_cli, ctx->addr, test_id, cid,
if (cli->fault_status) {
cli->fault_status(cli, ctx->addr, test_id, cid,
buf->data, buf->len);
}
@ -92,6 +93,7 @@ static int health_current_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
struct bt_mesh_health_cli *cli = model->user_data;
uint8_t test_id;
uint16_t cid;
@ -105,8 +107,8 @@ static int health_current_status(struct bt_mesh_model *model,
BT_DBG("Test ID 0x%02x Company ID 0x%04x Fault Count %u", test_id, cid,
buf->len);
if (health_cli->current_status) {
health_cli->current_status(health_cli, ctx->addr, test_id, cid,
if (cli->current_status) {
cli->current_status(cli, ctx->addr, test_id, cid,
buf->data, buf->len);
}
@ -121,6 +123,7 @@ static int health_period_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
struct bt_mesh_health_cli *cli = model->user_data;
struct health_period_param *param;
uint8_t divisor;
@ -130,18 +133,18 @@ static int health_period_status(struct bt_mesh_model *model,
divisor = net_buf_simple_pull_u8(buf);
if (bt_mesh_msg_ack_ctx_match(&health_cli->ack_ctx,
if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx,
OP_HEALTH_PERIOD_STATUS, ctx->addr,
(void **)&param)) {
if (param->divisor) {
*param->divisor = divisor;
}
bt_mesh_msg_ack_ctx_rx(&health_cli->ack_ctx);
bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
}
if (health_cli->period_status) {
health_cli->period_status(health_cli, ctx->addr, divisor);
if (cli->period_status) {
cli->period_status(cli, ctx->addr, divisor);
}
return 0;
@ -155,6 +158,7 @@ static int health_attention_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
struct bt_mesh_health_cli *cli = model->user_data;
struct health_attention_param *param;
uint8_t attention;
@ -164,17 +168,17 @@ static int health_attention_status(struct bt_mesh_model *model,
attention = net_buf_simple_pull_u8(buf);
if (bt_mesh_msg_ack_ctx_match(&health_cli->ack_ctx, OP_ATTENTION_STATUS,
if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_ATTENTION_STATUS,
ctx->addr, (void **)&param)) {
if (param->attention) {
*param->attention = attention;
}
bt_mesh_msg_ack_ctx_rx(&health_cli->ack_ctx);
bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
}
if (health_cli->attention_status) {
health_cli->attention_status(health_cli, ctx->addr, attention);
if (cli->attention_status) {
cli->attention_status(cli, ctx->addr, attention);
}
return 0;
}
@ -187,400 +191,335 @@ const struct bt_mesh_model_op bt_mesh_health_cli_op[] = {
BT_MESH_MODEL_OP_END,
};
static int cli_prepare(void *param, uint32_t op, uint16_t addr)
static int model_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
return bt_mesh_msg_ack_ctx_prepare(&health_cli->ack_ctx, op, addr, param);
if (!ctx && !model->pub) {
return -ENOTSUP;
}
if (ctx) {
return bt_mesh_model_send(model, ctx, buf, NULL, 0);
}
net_buf_simple_reset(model->pub->msg);
net_buf_simple_add_mem(model->pub->msg, buf->data, buf->len);
return bt_mesh_model_publish(model);
}
static int model_ackd_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf, struct bt_mesh_msg_ack_ctx *ack,
uint32_t rsp_op, void *user_data)
{
if (ack && bt_mesh_msg_ack_ctx_prepare(ack, rsp_op, ctx ? ctx->addr : model->pub->addr,
user_data) != 0) {
return -EALREADY;
}
int retval = model_send(model, ctx, buf);
if (ack) {
if (retval == 0) {
return bt_mesh_msg_ack_ctx_wait(ack, K_MSEC(msg_timeout));
}
bt_mesh_msg_ack_ctx_clear(ack);
}
return retval;
}
int bt_mesh_health_attention_get(uint16_t addr, uint16_t app_idx, uint8_t *attention)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_ATTENTION_GET, 0);
struct bt_mesh_msg_ctx ctx = {
.app_idx = app_idx,
.addr = addr,
.send_ttl = BT_MESH_TTL_DEFAULT,
};
struct health_attention_param param = {
.attention = attention,
};
int err;
err = cli_prepare(&param, OP_ATTENTION_STATUS, addr);
if (err) {
return err;
}
bt_mesh_model_msg_init(&msg, OP_ATTENTION_GET);
err = bt_mesh_model_send(health_cli->model, &ctx, &msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx);
return err;
}
if (!attention) {
bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx);
return 0;
}
return bt_mesh_msg_ack_ctx_wait(&health_cli->ack_ctx, K_MSEC(msg_timeout));
return bt_mesh_health_cli_attention_get(health_cli, &ctx, attention);
}
int bt_mesh_health_attention_set(uint16_t addr, uint16_t app_idx,
uint8_t attention, uint8_t *updated_attention)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_ATTENTION_SET, 1);
struct bt_mesh_msg_ctx ctx = {
.app_idx = app_idx,
.addr = addr,
.send_ttl = BT_MESH_TTL_DEFAULT,
};
struct health_attention_param param = {
.attention = updated_attention,
};
int err;
err = cli_prepare(&param, OP_ATTENTION_STATUS, addr);
if (err) {
return err;
}
bt_mesh_model_msg_init(&msg, OP_ATTENTION_SET);
net_buf_simple_add_u8(&msg, attention);
err = bt_mesh_model_send(health_cli->model, &ctx, &msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx);
return err;
}
if (!updated_attention) {
bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx);
return 0;
}
return bt_mesh_msg_ack_ctx_wait(&health_cli->ack_ctx, K_MSEC(msg_timeout));
return bt_mesh_health_cli_attention_set(health_cli, &ctx, attention, updated_attention);
}
int bt_mesh_health_attention_set_unack(uint16_t addr, uint16_t app_idx,
uint8_t attention)
int bt_mesh_health_attention_set_unack(uint16_t addr, uint16_t app_idx, uint8_t attention)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_ATTENTION_SET_UNREL, 1);
struct bt_mesh_msg_ctx ctx = {
.app_idx = app_idx,
.addr = addr,
.send_ttl = BT_MESH_TTL_DEFAULT,
};
int err;
err = cli_prepare(NULL, OP_ATTENTION_STATUS, addr);
if (err) {
return err;
}
bt_mesh_model_msg_init(&msg, OP_ATTENTION_SET_UNREL);
net_buf_simple_add_u8(&msg, attention);
err = bt_mesh_model_send(health_cli->model, &ctx, &msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx);
return err;
}
bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx);
return 0;
return bt_mesh_health_cli_attention_set_unack(health_cli, &ctx, attention);
}
int bt_mesh_health_period_get(uint16_t addr, uint16_t app_idx, uint8_t *divisor)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_PERIOD_GET, 0);
struct bt_mesh_msg_ctx ctx = {
.app_idx = app_idx,
.addr = addr,
.send_ttl = BT_MESH_TTL_DEFAULT,
};
struct health_period_param param = {
.divisor = divisor,
};
int err;
err = cli_prepare(&param, OP_HEALTH_PERIOD_STATUS, addr);
if (err) {
return err;
}
bt_mesh_model_msg_init(&msg, OP_HEALTH_PERIOD_GET);
err = bt_mesh_model_send(health_cli->model, &ctx, &msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx);
return err;
}
if (!divisor) {
bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx);
return 0;
}
return bt_mesh_msg_ack_ctx_wait(&health_cli->ack_ctx,
K_MSEC(msg_timeout));
return bt_mesh_health_cli_period_get(health_cli, &ctx, divisor);
}
int bt_mesh_health_period_set(uint16_t addr, uint16_t app_idx, uint8_t divisor,
uint8_t *updated_divisor)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_PERIOD_SET, 1);
struct bt_mesh_msg_ctx ctx = {
.app_idx = app_idx,
.addr = addr,
.send_ttl = BT_MESH_TTL_DEFAULT,
};
struct health_period_param param = {
.divisor = updated_divisor,
};
int err;
err = cli_prepare(&param, OP_HEALTH_PERIOD_STATUS, addr);
if (err) {
return err;
}
bt_mesh_model_msg_init(&msg, OP_HEALTH_PERIOD_SET);
net_buf_simple_add_u8(&msg, divisor);
err = bt_mesh_model_send(health_cli->model, &ctx, &msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx);
return err;
}
if (!updated_divisor) {
bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx);
return 0;
}
return bt_mesh_msg_ack_ctx_wait(&health_cli->ack_ctx,
K_MSEC(msg_timeout));
return bt_mesh_health_cli_period_set(health_cli, &ctx, divisor, updated_divisor);
}
int bt_mesh_health_period_set_unack(uint16_t addr, uint16_t app_idx,
uint8_t divisor)
int bt_mesh_health_period_set_unack(uint16_t addr, uint16_t app_idx, uint8_t divisor)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_PERIOD_SET_UNREL, 1);
struct bt_mesh_msg_ctx ctx = {
.app_idx = app_idx,
.addr = addr,
.send_ttl = BT_MESH_TTL_DEFAULT,
};
int err;
err = cli_prepare(NULL, OP_HEALTH_PERIOD_STATUS, addr);
if (err) {
return err;
}
bt_mesh_model_msg_init(&msg, OP_HEALTH_PERIOD_SET_UNREL);
net_buf_simple_add_u8(&msg, divisor);
err = bt_mesh_model_send(health_cli->model, &ctx, &msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx);
return err;
}
bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx);
return 0;
return bt_mesh_health_cli_period_set_unack(health_cli, &ctx, divisor);
}
int bt_mesh_health_fault_test(uint16_t addr, uint16_t app_idx, uint16_t cid,
uint8_t test_id, uint8_t *faults,
size_t *fault_count)
int bt_mesh_health_fault_test(uint16_t addr, uint16_t app_idx, uint16_t cid, uint8_t test_id,
uint8_t *faults, size_t *fault_count)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_FAULT_TEST, 3);
struct bt_mesh_msg_ctx ctx = {
.app_idx = app_idx,
.addr = addr,
.send_ttl = BT_MESH_TTL_DEFAULT,
};
struct health_fault_param param = {
.cid = cid,
.expect_test_id = &test_id,
.faults = faults,
.fault_count = fault_count,
};
int err;
err = cli_prepare(&param, OP_HEALTH_FAULT_STATUS, addr);
if (err) {
return err;
}
bt_mesh_model_msg_init(&msg, OP_HEALTH_FAULT_TEST);
net_buf_simple_add_u8(&msg, test_id);
net_buf_simple_add_le16(&msg, cid);
err = bt_mesh_model_send(health_cli->model, &ctx, &msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx);
return err;
}
if (!faults || !fault_count) {
bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx);
return 0;
}
return bt_mesh_msg_ack_ctx_wait(&health_cli->ack_ctx, K_MSEC(msg_timeout));
return bt_mesh_health_cli_fault_test(health_cli, &ctx, cid, test_id, faults, fault_count);
}
int bt_mesh_health_fault_test_unack(uint16_t addr, uint16_t app_idx,
uint16_t cid, uint8_t test_id)
int bt_mesh_health_fault_test_unack(uint16_t addr, uint16_t app_idx, uint16_t cid, uint8_t test_id)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_FAULT_TEST, 3);
struct bt_mesh_msg_ctx ctx = {
.app_idx = app_idx,
.addr = addr,
.send_ttl = BT_MESH_TTL_DEFAULT,
};
int err;
err = cli_prepare(NULL, OP_HEALTH_FAULT_STATUS, addr);
if (err) {
return err;
}
bt_mesh_model_msg_init(&msg, OP_HEALTH_FAULT_TEST_UNREL);
net_buf_simple_add_u8(&msg, test_id);
net_buf_simple_add_le16(&msg, cid);
err = bt_mesh_model_send(health_cli->model, &ctx, &msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx);
return err;
}
bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx);
return 0;
return bt_mesh_health_cli_fault_test_unack(health_cli, &ctx, cid, test_id);
}
int bt_mesh_health_fault_clear(uint16_t addr, uint16_t app_idx, uint16_t cid,
uint8_t *test_id, uint8_t *faults,
size_t *fault_count)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_FAULT_CLEAR, 2);
struct bt_mesh_msg_ctx ctx = {
.app_idx = app_idx,
.addr = addr,
.send_ttl = BT_MESH_TTL_DEFAULT,
};
struct health_fault_param param = {
.cid = cid,
.test_id = test_id,
.faults = faults,
.fault_count = fault_count,
};
int err;
err = cli_prepare(&param, OP_HEALTH_FAULT_STATUS, addr);
if (err) {
return err;
}
bt_mesh_model_msg_init(&msg, OP_HEALTH_FAULT_CLEAR);
net_buf_simple_add_le16(&msg, cid);
err = bt_mesh_model_send(health_cli->model, &ctx, &msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx);
return err;
}
if (!test_id && (!faults || !fault_count)) {
bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx);
return 0;
}
return bt_mesh_msg_ack_ctx_wait(&health_cli->ack_ctx, K_MSEC(msg_timeout));
return bt_mesh_health_cli_fault_clear(health_cli, &ctx, cid, test_id, faults, fault_count);
}
int bt_mesh_health_fault_clear_unack(uint16_t addr, uint16_t app_idx,
uint16_t cid)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_FAULT_CLEAR_UNREL, 2);
struct bt_mesh_msg_ctx ctx = {
.app_idx = app_idx,
.addr = addr,
.send_ttl = BT_MESH_TTL_DEFAULT,
};
int err;
err = cli_prepare(NULL, OP_HEALTH_FAULT_STATUS, addr);
if (err) {
return err;
}
bt_mesh_model_msg_init(&msg, OP_HEALTH_FAULT_CLEAR_UNREL);
net_buf_simple_add_le16(&msg, cid);
err = bt_mesh_model_send(health_cli->model, &ctx, &msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx);
return err;
}
bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx);
return 0;
return bt_mesh_health_cli_fault_clear_unack(health_cli, &ctx, cid);
}
int bt_mesh_health_fault_get(uint16_t addr, uint16_t app_idx, uint16_t cid,
uint8_t *test_id, uint8_t *faults,
size_t *fault_count)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_FAULT_GET, 2);
struct bt_mesh_msg_ctx ctx = {
.app_idx = app_idx,
.addr = addr,
.send_ttl = BT_MESH_TTL_DEFAULT,
};
return bt_mesh_health_cli_fault_get(health_cli, &ctx, cid, test_id, faults, fault_count);
}
int bt_mesh_health_cli_attention_get(struct bt_mesh_health_cli *cli, struct bt_mesh_msg_ctx *ctx,
uint8_t *attention)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_ATTENTION_GET, 0);
struct health_attention_param param = {
.attention = attention,
};
bt_mesh_model_msg_init(&msg, OP_ATTENTION_GET);
return model_ackd_send(cli->model, ctx, &msg, attention ? &cli->ack_ctx : NULL,
OP_ATTENTION_STATUS, &param);
}
int bt_mesh_health_cli_attention_set(struct bt_mesh_health_cli *cli, struct bt_mesh_msg_ctx *ctx,
uint8_t attention, uint8_t *updated_attention)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_ATTENTION_SET, 1);
struct health_attention_param param = {
.attention = updated_attention,
};
bt_mesh_model_msg_init(&msg, OP_ATTENTION_SET);
net_buf_simple_add_u8(&msg, attention);
return model_ackd_send(cli->model, ctx, &msg, updated_attention ? &cli->ack_ctx : NULL,
OP_ATTENTION_STATUS, &param);
}
int bt_mesh_health_cli_attention_set_unack(struct bt_mesh_health_cli *cli,
struct bt_mesh_msg_ctx *ctx, uint8_t attention)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_ATTENTION_SET_UNREL, 1);
bt_mesh_model_msg_init(&msg, OP_ATTENTION_SET_UNREL);
net_buf_simple_add_u8(&msg, attention);
return model_send(cli->model, ctx, &msg);
}
int bt_mesh_health_cli_period_get(struct bt_mesh_health_cli *cli, struct bt_mesh_msg_ctx *ctx,
uint8_t *divisor)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_PERIOD_GET, 0);
struct health_period_param param = {
.divisor = divisor,
};
bt_mesh_model_msg_init(&msg, OP_HEALTH_PERIOD_GET);
return model_ackd_send(cli->model, ctx, &msg, divisor ? &cli->ack_ctx : NULL,
OP_HEALTH_PERIOD_STATUS, &param);
}
int bt_mesh_health_cli_period_set(struct bt_mesh_health_cli *cli, struct bt_mesh_msg_ctx *ctx,
uint8_t divisor, uint8_t *updated_divisor)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_PERIOD_SET, 1);
struct health_period_param param = {
.divisor = updated_divisor,
};
bt_mesh_model_msg_init(&msg, OP_HEALTH_PERIOD_SET);
net_buf_simple_add_u8(&msg, divisor);
return model_ackd_send(cli->model, ctx, &msg, updated_divisor ? &cli->ack_ctx : NULL,
OP_HEALTH_PERIOD_STATUS, &param);
}
int bt_mesh_health_cli_period_set_unack(struct bt_mesh_health_cli *cli,
struct bt_mesh_msg_ctx *ctx, uint8_t divisor)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_PERIOD_SET_UNREL, 1);
bt_mesh_model_msg_init(&msg, OP_HEALTH_PERIOD_SET_UNREL);
net_buf_simple_add_u8(&msg, divisor);
return model_send(cli->model, ctx, &msg);
}
int bt_mesh_health_cli_fault_test(struct bt_mesh_health_cli *cli, struct bt_mesh_msg_ctx *ctx,
uint16_t cid, uint8_t test_id, uint8_t *faults,
size_t *fault_count)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_FAULT_TEST, 3);
struct health_fault_param param = {
.cid = cid,
.expect_test_id = &test_id,
.faults = faults,
.fault_count = fault_count,
};
bt_mesh_model_msg_init(&msg, OP_HEALTH_FAULT_TEST);
net_buf_simple_add_u8(&msg, test_id);
net_buf_simple_add_le16(&msg, cid);
return model_ackd_send(cli->model, ctx, &msg,
(!faults || !fault_count) ? &cli->ack_ctx : NULL,
OP_HEALTH_FAULT_STATUS, &param);
}
int bt_mesh_health_cli_fault_test_unack(struct bt_mesh_health_cli *cli,
struct bt_mesh_msg_ctx *ctx, uint16_t cid, uint8_t test_id)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_FAULT_TEST_UNREL, 3);
bt_mesh_model_msg_init(&msg, OP_HEALTH_FAULT_TEST_UNREL);
net_buf_simple_add_u8(&msg, test_id);
net_buf_simple_add_le16(&msg, cid);
return model_send(cli->model, ctx, &msg);
}
int bt_mesh_health_cli_fault_clear(struct bt_mesh_health_cli *cli, struct bt_mesh_msg_ctx *ctx,
uint16_t cid, uint8_t *test_id, uint8_t *faults,
size_t *fault_count)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_FAULT_CLEAR, 2);
struct health_fault_param param = {
.cid = cid,
.test_id = test_id,
.faults = faults,
.fault_count = fault_count,
};
int err;
err = cli_prepare(&param, OP_HEALTH_FAULT_STATUS, addr);
if (err) {
return err;
}
bt_mesh_model_msg_init(&msg, OP_HEALTH_FAULT_CLEAR);
net_buf_simple_add_le16(&msg, cid);
return model_ackd_send(cli->model, ctx, &msg,
(!test_id && (!faults || !fault_count)) ? &cli->ack_ctx : NULL,
OP_HEALTH_FAULT_STATUS, &param);
}
int bt_mesh_health_cli_fault_clear_unack(struct bt_mesh_health_cli *cli,
struct bt_mesh_msg_ctx *ctx, uint16_t cid)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_FAULT_CLEAR_UNREL, 2);
bt_mesh_model_msg_init(&msg, OP_HEALTH_FAULT_CLEAR_UNREL);
net_buf_simple_add_le16(&msg, cid);
return model_send(cli->model, ctx, &msg);
}
int bt_mesh_health_cli_fault_get(struct bt_mesh_health_cli *cli, struct bt_mesh_msg_ctx *ctx,
uint16_t cid, uint8_t *test_id, uint8_t *faults,
size_t *fault_count)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_FAULT_GET, 2);
struct health_fault_param param = {
.cid = cid,
.test_id = test_id,
.faults = faults,
.fault_count = fault_count,
};
bt_mesh_model_msg_init(&msg, OP_HEALTH_FAULT_GET);
net_buf_simple_add_le16(&msg, cid);
err = bt_mesh_model_send(health_cli->model, &ctx, &msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx);
return err;
}
if (!test_id && (!faults || !fault_count)) {
bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx);
return 0;
}
return bt_mesh_msg_ack_ctx_wait(&health_cli->ack_ctx, K_MSEC(msg_timeout));
return model_ackd_send(cli->model, ctx, &msg,
(!test_id && (!faults || !fault_count)) ? &cli->ack_ctx : NULL,
OP_HEALTH_FAULT_STATUS, &param);
}
int32_t bt_mesh_health_cli_timeout_get(void)
@ -617,19 +556,25 @@ static int health_cli_init(struct bt_mesh_model *model)
return -EINVAL;
}
cli = model->user_data;
cli->model = model;
msg_timeout = 2 * MSEC_PER_SEC;
/* Set the default health client pointer */
if (!health_cli) {
health_cli = cli;
}
msg_timeout = CONFIG_BT_MESH_HEALTH_CLI_TIMEOUT;
bt_mesh_msg_ack_ctx_init(&health_cli->ack_ctx);
cli->pub.msg = &cli->pub_buf;
net_buf_simple_init_with_data(&cli->pub_buf, cli->pub_data, sizeof(cli->pub_data));
bt_mesh_msg_ack_ctx_init(&cli->ack_ctx);
return 0;
}
static void health_cli_reset(struct bt_mesh_model *model)
{
struct bt_mesh_health_cli *cli = model->user_data;
net_buf_simple_reset(cli->pub.msg);
}
const struct bt_mesh_model_cb bt_mesh_health_cli_cb = {
.init = health_cli_init,
.reset = health_cli_reset,
};

View file

@ -385,6 +385,11 @@ static int health_pub_update(struct bt_mesh_model *mod)
}
int bt_mesh_fault_update(struct bt_mesh_elem *elem)
{
return bt_mesh_health_srv_fault_update(elem);
}
int bt_mesh_health_srv_fault_update(struct bt_mesh_elem *elem)
{
struct bt_mesh_model *mod;

View file

@ -2602,6 +2602,11 @@ int cmd_timeout(const struct shell *shell, size_t argc, char *argv[])
#if defined(CONFIG_BT_MESH_HEALTH_CLI)
static int cmd_fault_get(const struct shell *shell, size_t argc, char *argv[])
{
struct bt_mesh_msg_ctx ctx = {
.net_idx = net.net_idx,
.addr = net.dst,
.app_idx = net.app_idx,
};
uint8_t faults[32];
size_t fault_count;
uint8_t test_id;
@ -2616,8 +2621,8 @@ static int cmd_fault_get(const struct shell *shell, size_t argc, char *argv[])
fault_count = sizeof(faults);
err = bt_mesh_health_fault_get(net.dst, net.app_idx, cid, &test_id,
faults, &fault_count);
err = bt_mesh_health_cli_fault_get(&bt_mesh_shell_health_cli, &ctx, cid, &test_id, faults,
&fault_count);
if (err) {
shell_error(shell, "Failed to send Health Fault Get (err %d)",
err);
@ -2631,6 +2636,11 @@ static int cmd_fault_get(const struct shell *shell, size_t argc, char *argv[])
static int cmd_fault_clear(const struct shell *shell, size_t argc,
char *argv[])
{
struct bt_mesh_msg_ctx ctx = {
.net_idx = net.net_idx,
.addr = net.dst,
.app_idx = net.app_idx,
};
uint8_t faults[32];
size_t fault_count;
uint8_t test_id;
@ -2645,8 +2655,8 @@ static int cmd_fault_clear(const struct shell *shell, size_t argc,
fault_count = sizeof(faults);
err = bt_mesh_health_fault_clear(net.dst, net.app_idx, cid,
&test_id, faults, &fault_count);
err = bt_mesh_health_cli_fault_clear(&bt_mesh_shell_health_cli, &ctx, cid, &test_id, faults,
&fault_count);
if (err) {
shell_error(shell, "Failed to send Health Fault Clear (err %d)",
err);
@ -2660,6 +2670,11 @@ static int cmd_fault_clear(const struct shell *shell, size_t argc,
static int cmd_fault_clear_unack(const struct shell *shell, size_t argc,
char *argv[])
{
struct bt_mesh_msg_ctx ctx = {
.net_idx = net.net_idx,
.addr = net.dst,
.app_idx = net.app_idx,
};
uint16_t cid;
int err = 0;
@ -2669,7 +2684,7 @@ static int cmd_fault_clear_unack(const struct shell *shell, size_t argc,
return err;
}
err = bt_mesh_health_fault_clear_unack(net.dst, net.app_idx, cid);
err = bt_mesh_health_cli_fault_clear_unack(&bt_mesh_shell_health_cli, &ctx, cid);
if (err) {
shell_error(shell, "Health Fault Clear Unacknowledged failed "
"(err %d)", err);
@ -2680,6 +2695,11 @@ static int cmd_fault_clear_unack(const struct shell *shell, size_t argc,
static int cmd_fault_test(const struct shell *shell, size_t argc, char *argv[])
{
struct bt_mesh_msg_ctx ctx = {
.net_idx = net.net_idx,
.addr = net.dst,
.app_idx = net.app_idx,
};
uint8_t faults[32];
size_t fault_count;
uint8_t test_id;
@ -2694,8 +2714,8 @@ static int cmd_fault_test(const struct shell *shell, size_t argc, char *argv[])
return err;
}
err = bt_mesh_health_fault_test(net.dst, net.app_idx, cid,
test_id, faults, &fault_count);
err = bt_mesh_health_cli_fault_test(&bt_mesh_shell_health_cli, &ctx, cid, test_id, faults,
&fault_count);
if (err) {
shell_error(shell, "Failed to send Health Fault Test (err %d)",
err);
@ -2709,6 +2729,11 @@ static int cmd_fault_test(const struct shell *shell, size_t argc, char *argv[])
static int cmd_fault_test_unack(const struct shell *shell, size_t argc,
char *argv[])
{
struct bt_mesh_msg_ctx ctx = {
.net_idx = net.net_idx,
.addr = net.dst,
.app_idx = net.app_idx,
};
uint16_t cid;
uint8_t test_id;
int err = 0;
@ -2720,7 +2745,7 @@ static int cmd_fault_test_unack(const struct shell *shell, size_t argc,
return err;
}
err = bt_mesh_health_fault_test_unack(net.dst, net.app_idx, cid, test_id);
err = bt_mesh_health_cli_fault_test_unack(&bt_mesh_shell_health_cli, &ctx, cid, test_id);
if (err) {
shell_error(shell, "Health Fault Test Unacknowledged failed "
"(err %d)", err);
@ -2731,10 +2756,15 @@ static int cmd_fault_test_unack(const struct shell *shell, size_t argc,
static int cmd_period_get(const struct shell *shell, size_t argc, char *argv[])
{
struct bt_mesh_msg_ctx ctx = {
.net_idx = net.net_idx,
.addr = net.dst,
.app_idx = net.app_idx,
};
uint8_t divisor;
int err;
err = bt_mesh_health_period_get(net.dst, net.app_idx, &divisor);
err = bt_mesh_health_cli_period_get(&bt_mesh_shell_health_cli, &ctx, &divisor);
if (err) {
shell_error(shell, "Failed to send Health Period Get (err %d)",
err);
@ -2747,6 +2777,11 @@ static int cmd_period_get(const struct shell *shell, size_t argc, char *argv[])
static int cmd_period_set(const struct shell *shell, size_t argc, char *argv[])
{
struct bt_mesh_msg_ctx ctx = {
.net_idx = net.net_idx,
.addr = net.dst,
.app_idx = net.app_idx,
};
uint8_t divisor, updated_divisor;
int err = 0;
@ -2756,7 +2791,7 @@ static int cmd_period_set(const struct shell *shell, size_t argc, char *argv[])
return err;
}
err = bt_mesh_health_period_set(net.dst, net.app_idx, divisor,
err = bt_mesh_health_cli_period_set(&bt_mesh_shell_health_cli, &ctx, divisor,
&updated_divisor);
if (err) {
shell_error(shell, "Failed to send Health Period Set (err %d)",
@ -2772,6 +2807,11 @@ static int cmd_period_set(const struct shell *shell, size_t argc, char *argv[])
static int cmd_period_set_unack(const struct shell *shell, size_t argc,
char *argv[])
{
struct bt_mesh_msg_ctx ctx = {
.net_idx = net.net_idx,
.addr = net.dst,
.app_idx = net.app_idx,
};
uint8_t divisor;
int err = 0;
@ -2781,7 +2821,7 @@ static int cmd_period_set_unack(const struct shell *shell, size_t argc,
return err;
}
err = bt_mesh_health_period_set_unack(net.dst, net.app_idx, divisor);
err = bt_mesh_health_cli_period_set_unack(&bt_mesh_shell_health_cli, &ctx, divisor);
if (err) {
shell_print(shell, "Failed to send Health Period Set (err %d)",
err);
@ -2793,11 +2833,15 @@ static int cmd_period_set_unack(const struct shell *shell, size_t argc,
static int cmd_attention_get(const struct shell *shell, size_t argc,
char *argv[])
{
struct bt_mesh_msg_ctx ctx = {
.net_idx = net.net_idx,
.addr = net.dst,
.app_idx = net.app_idx,
};
uint8_t attention;
int err;
err = bt_mesh_health_attention_get(net.dst, net.app_idx,
&attention);
err = bt_mesh_health_cli_attention_get(&bt_mesh_shell_health_cli, &ctx, &attention);
if (err) {
shell_error(shell, "Failed to send Health Attention Get "
"(err %d)", err);
@ -2811,6 +2855,11 @@ static int cmd_attention_get(const struct shell *shell, size_t argc,
static int cmd_attention_set(const struct shell *shell, size_t argc,
char *argv[])
{
struct bt_mesh_msg_ctx ctx = {
.net_idx = net.net_idx,
.addr = net.dst,
.app_idx = net.app_idx,
};
uint8_t attention, updated_attention;
int err = 0;
@ -2820,7 +2869,7 @@ static int cmd_attention_set(const struct shell *shell, size_t argc,
return err;
}
err = bt_mesh_health_attention_set(net.dst, net.app_idx, attention,
err = bt_mesh_health_cli_attention_set(&bt_mesh_shell_health_cli, &ctx, attention,
&updated_attention);
if (err) {
shell_error(shell, "Failed to send Health Attention Set "
@ -2836,6 +2885,11 @@ static int cmd_attention_set(const struct shell *shell, size_t argc,
static int cmd_attention_set_unack(const struct shell *shell, size_t argc,
char *argv[])
{
struct bt_mesh_msg_ctx ctx = {
.net_idx = net.net_idx,
.addr = net.dst,
.app_idx = net.app_idx,
};
uint8_t attention;
int err = 0;
@ -2845,7 +2899,7 @@ static int cmd_attention_set_unack(const struct shell *shell, size_t argc,
return err;
}
err = bt_mesh_health_attention_set_unack(net.dst, net.app_idx, attention);
err = bt_mesh_health_cli_attention_set_unack(&bt_mesh_shell_health_cli, &ctx, attention);
if (err) {
shell_error(shell, "Failed to send Health Attention Set "
"(err %d)", err);
@ -2914,7 +2968,7 @@ static int cmd_add_fault(const struct shell *shell, size_t argc, char *argv[])
shell_print(shell, "No space to store more registered faults");
}
bt_mesh_fault_update(elem);
bt_mesh_health_srv_fault_update(elem);
return 0;
}
@ -2935,7 +2989,7 @@ static int cmd_del_fault(const struct shell *shell, size_t argc, char *argv[])
if (argc < 2) {
(void)memset(cur_faults, 0, sizeof(cur_faults));
shell_print(shell, "All current faults cleared");
bt_mesh_fault_update(elem);
bt_mesh_health_srv_fault_update(elem);
return 0;
}
@ -2957,7 +3011,7 @@ static int cmd_del_fault(const struct shell *shell, size_t argc, char *argv[])
}
}
bt_mesh_fault_update(elem);
bt_mesh_health_srv_fault_update(elem);
return 0;
}

View file

@ -74,7 +74,7 @@ static int fault_test(struct bt_mesh_model *model, uint8_t test_id,
}
has_reg_fault = true;
bt_mesh_fault_update(bt_mesh_model_elem(model));
bt_mesh_health_srv_fault_update(bt_mesh_model_elem(model));
return 0;
}

View file

@ -745,7 +745,7 @@ static void health_generate_faults(uint8_t *data, uint16_t len)
net_buf_simple_add_mem(&buf, reg_faults, reg_faults_count);
rp->reg_faults_count = reg_faults_count;
bt_mesh_fault_update(&elements[0]);
bt_mesh_health_srv_fault_update(&elements[0]);
tester_send(BTP_SERVICE_ID_MESH, MESH_HEALTH_GENERATE_FAULTS,
CONTROLLER_INDEX, buf.data, buf.len);
@ -758,7 +758,7 @@ static void health_clear_faults(uint8_t *data, uint16_t len)
(void)memset(cur_faults, 0, sizeof(cur_faults));
(void)memset(reg_faults, 0, sizeof(reg_faults));
bt_mesh_fault_update(&elements[0]);
bt_mesh_health_srv_fault_update(&elements[0]);
tester_rsp(BTP_SERVICE_ID_MESH, MESH_HEALTH_CLEAR_FAULTS,
CONTROLLER_INDEX, BTP_STATUS_SUCCESS);
@ -2142,6 +2142,11 @@ fail:
static void health_fault_get(uint8_t *data, uint16_t len)
{
struct mesh_health_fault_get_cmd *cmd = (void *)data;
struct bt_mesh_msg_ctx ctx = {
.net_idx = net.net_idx,
.addr = cmd->address,
.app_idx = cmd->app_idx,
};
uint8_t test_id;
size_t fault_count = 16;
uint8_t faults[fault_count];
@ -2149,8 +2154,8 @@ static void health_fault_get(uint8_t *data, uint16_t len)
LOG_DBG("");
err = bt_mesh_health_fault_get(cmd->address, cmd->app_idx, cmd->cid,
&test_id, faults, &fault_count);
err = bt_mesh_health_cli_fault_get(&health_cli, &ctx, cmd->cid, &test_id, faults,
&fault_count);
if (err) {
LOG_ERR("err %d", err);
@ -2165,6 +2170,11 @@ fail:
static void health_fault_clear(uint8_t *data, uint16_t len)
{
struct mesh_health_fault_clear_cmd *cmd = (void *)data;
struct bt_mesh_msg_ctx ctx = {
.net_idx = net.net_idx,
.addr = cmd->address,
.app_idx = cmd->app_idx,
};
uint8_t test_id;
size_t fault_count = 16;
uint8_t faults[fault_count];
@ -2173,11 +2183,10 @@ static void health_fault_clear(uint8_t *data, uint16_t len)
LOG_DBG("");
if (cmd->ack) {
err = bt_mesh_health_fault_clear(cmd->address, cmd->app_idx,
cmd->cid, &test_id, faults,
err = bt_mesh_health_cli_fault_clear(&health_cli, &ctx, cmd->cid, &test_id, faults,
&fault_count);
} else {
err = bt_mesh_health_fault_clear_unack(cmd->address, cmd->app_idx, cmd->cid);
err = bt_mesh_health_cli_fault_clear_unack(&health_cli, &ctx, cmd->cid);
}
if (err) {
@ -2201,6 +2210,11 @@ static void health_fault_test(uint8_t *data, uint16_t len)
{
struct mesh_health_fault_test_cmd *cmd = (void *)data;
struct net_buf_simple *buf = NET_BUF_SIMPLE(19);
struct bt_mesh_msg_ctx ctx = {
.net_idx = net.net_idx,
.addr = cmd->address,
.app_idx = cmd->app_idx,
};
size_t fault_count = 16;
uint8_t faults[fault_count];
uint8_t test_id;
@ -2213,12 +2227,10 @@ static void health_fault_test(uint8_t *data, uint16_t len)
cid = cmd->cid;
if (cmd->ack) {
err = bt_mesh_health_fault_test(cmd->address, cmd->app_idx,
cid, test_id, faults,
err = bt_mesh_health_cli_fault_test(&health_cli, &ctx, cid, test_id, faults,
&fault_count);
} else {
err = bt_mesh_health_fault_test_unack(cmd->address, cmd->app_idx,
cid, test_id);
err = bt_mesh_health_cli_fault_test_unack(&health_cli, &ctx, cid, test_id);
}
if (err) {
@ -2246,12 +2258,17 @@ fail:
static void health_period_get(uint8_t *data, uint16_t len)
{
struct mesh_health_period_get_cmd *cmd = (void *)data;
struct bt_mesh_msg_ctx ctx = {
.net_idx = net.net_idx,
.addr = cmd->address,
.app_idx = cmd->app_idx,
};
uint8_t divisor;
int err;
LOG_DBG("");
err = bt_mesh_health_period_get(cmd->address, cmd->app_idx, &divisor);
err = bt_mesh_health_cli_period_get(&health_cli, &ctx, &divisor);
if (err) {
LOG_ERR("err %d", err);
@ -2267,16 +2284,21 @@ fail:
static void health_period_set(uint8_t *data, uint16_t len)
{
struct mesh_health_period_set_cmd *cmd = (void *)data;
struct bt_mesh_msg_ctx ctx = {
.net_idx = net.net_idx,
.addr = cmd->address,
.app_idx = cmd->app_idx,
};
uint8_t updated_divisor;
int err;
LOG_DBG("");
if (cmd->ack) {
err = bt_mesh_health_period_set(cmd->address, cmd->app_idx,
cmd->divisor, &updated_divisor);
err = bt_mesh_health_cli_period_set(&health_cli, &ctx, cmd->divisor,
&updated_divisor);
} else {
err = bt_mesh_health_period_set_unack(cmd->address, cmd->app_idx, cmd->divisor);
err = bt_mesh_health_cli_period_set_unack(&health_cli, &ctx, cmd->divisor);
}
if (err) {
@ -2300,13 +2322,17 @@ fail:
static void health_attention_get(uint8_t *data, uint16_t len)
{
struct mesh_health_attention_get_cmd *cmd = (void *)data;
struct bt_mesh_msg_ctx ctx = {
.net_idx = net.net_idx,
.addr = cmd->address,
.app_idx = cmd->app_idx,
};
uint8_t attention;
int err;
LOG_DBG("");
err = bt_mesh_health_attention_get(cmd->address, cmd->app_idx,
&attention);
err = bt_mesh_health_cli_attention_get(&health_cli, &ctx, &attention);
if (err) {
LOG_ERR("err %d", err);
@ -2322,18 +2348,21 @@ fail:
static void health_attention_set(uint8_t *data, uint16_t len)
{
struct mesh_health_attention_set_cmd *cmd = (void *)data;
struct bt_mesh_msg_ctx ctx = {
.net_idx = net.net_idx,
.addr = cmd->address,
.app_idx = cmd->app_idx,
};
uint8_t updated_attention;
int err;
LOG_DBG("");
if (cmd->ack) {
err = bt_mesh_health_attention_set(cmd->address, cmd->app_idx,
cmd->attention,
err = bt_mesh_health_cli_attention_set(&health_cli, &ctx, cmd->attention,
&updated_attention);
} else {
err = bt_mesh_health_attention_set_unack(cmd->address, cmd->app_idx,
cmd->attention);
err = bt_mesh_health_cli_attention_set_unack(&health_cli, &ctx, cmd->attention);
}
if (err) {