diff --git a/include/bluetooth/mesh/lightness_srv.h b/include/bluetooth/mesh/lightness_srv.h index cf759ebd5eda..6f65af62d38c 100644 --- a/include/bluetooth/mesh/lightness_srv.h +++ b/include/bluetooth/mesh/lightness_srv.h @@ -75,6 +75,10 @@ struct bt_mesh_lightness_srv_handlers { * @ref bt_mesh_model_transition_time returns a nonzero value, the application is * responsible for publishing a value of the Light state at the end of the transition. * + * When performing a non-instantaneous state change, the Light state at any intermediate + * point must be clamped to the current lightness range of the server using + * @ref bt_mesh_lightness_clamp. + * * @note This handler is mandatory. * * @param[in] srv Server to set the Light state of. @@ -89,6 +93,10 @@ struct bt_mesh_lightness_srv_handlers { struct bt_mesh_lightness_status *rsp); /** @brief Get the current Light state. + * + * When in the middle of a non-instantaneous state change, the Light value filled in + * @c rsp must be clamped to the current lightness range of the server using + * @ref bt_mesh_lightness_clamp. * * @note This handler is mandatory. * @@ -190,6 +198,18 @@ struct bt_mesh_lightness_srv { #endif }; +/** @brief Clamp lightness to lightness range. + * + * @return @c lightness clamped to the lightness range set on the + * @ref bt_mesh_lightness_srv pointed to by @c srv if @c lightness > 0, zero + * otherwise. + */ +static inline uint16_t bt_mesh_lightness_clamp(const struct bt_mesh_lightness_srv *srv, + uint16_t lightness) +{ + return lightness == 0 ? 0 : CLAMP(lightness, srv->range.min, srv->range.max); +} + /** @brief Publish the current Light state. * * Publishes a Light Lightness status message with the configured publish diff --git a/samples/bluetooth/mesh/light_ctrl/src/model_handler.c b/samples/bluetooth/mesh/light_ctrl/src/model_handler.c index c7408ba65fff..b22534230c07 100644 --- a/samples/bluetooth/mesh/light_ctrl/src/model_handler.c +++ b/samples/bluetooth/mesh/light_ctrl/src/model_handler.c @@ -119,8 +119,10 @@ static void periodic_led_work(struct k_work *work) k_work_reschedule(&l_ctx->per_work, K_MSEC(l_ctx->time_per)); apply_and_print: - lc_pwm_led_set(l_ctx->current_lvl); - printk("Current light lvl: %u/65535\n", l_ctx->current_lvl); + uint16_t clamped_lvl = bt_mesh_lightness_clamp(&l_ctx->lightness_srv, + l_ctx->current_lvl); + lc_pwm_led_set(clamped_lvl); + printk("Current light lvl: %u/65535\n", clamped_lvl); } static void light_set(struct bt_mesh_lightness_srv *srv, @@ -144,7 +146,7 @@ static void light_get(struct bt_mesh_lightness_srv *srv, struct lightness_ctx *l_ctx = CONTAINER_OF(srv, struct lightness_ctx, lightness_srv); - rsp->current = l_ctx->current_lvl; + rsp->current = bt_mesh_lightness_clamp(&l_ctx->lightness_srv, l_ctx->current_lvl); rsp->target = l_ctx->target_lvl; rsp->remaining_time = l_ctx->rem_time; } diff --git a/tests/bluetooth/tester/src/model_handler.c b/tests/bluetooth/tester/src/model_handler.c index ac9fa36d5e75..a4261ecf0170 100644 --- a/tests/bluetooth/tester/src/model_handler.c +++ b/tests/bluetooth/tester/src/model_handler.c @@ -382,7 +382,7 @@ start_new_lightness_trans(uint32_t step_cnt, static void lightness_status(struct lightness_ctx *ctx, struct bt_mesh_lightness_status *rsp) { - rsp->current = ctx->current; + rsp->current = bt_mesh_lightness_clamp(&ctx->srv, ctx->current); rsp->target = ctx->target; rsp->remaining_time = ctx->remaining; }