fix(ble_mesh): Miscellaneous bugfixes according to our internal bug report

This commit is contained in:
Liu Linyan
2026-02-03 10:59:04 +08:00
parent 4c39269f3b
commit 0e0fab2ea7
69 changed files with 2152 additions and 1012 deletions
@@ -210,6 +210,7 @@ static int32_t client_calc_timeout(struct bt_mesh_msg_ctx *ctx,
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;
ARG_UNUSED(mic_size);
BT_DBG("NeedSeg %u MicSize %u", need_seg, mic_size);
@@ -223,11 +224,11 @@ static int32_t client_calc_timeout(struct bt_mesh_msg_ctx *ctx,
#if CONFIG_BLE_MESH_LONG_PACKET
if (ctx->enh.long_pkt_cfg &&
msg->len > BLE_MESH_TX_SDU_MAX) {
seg_count = (msg->len + mic_size - 1) / BLE_MESH_EXT_APP_SEG_SDU_MAX + 1U;
seg_count = DIV_ROUND_UP(msg->len, BLE_MESH_EXT_APP_SEG_SDU_MAX);
} else
#endif
{
seg_count = (msg->len + mic_size - 1) / 12U + 1U;
seg_count = DIV_ROUND_UP(msg->len, BLE_MESH_APP_SEG_SDU_MAX);
}
duration = client_get_adv_duration(ctx);
@@ -272,9 +273,8 @@ static void msg_send_start(uint16_t duration, int err, void *cb_data)
BT_DBG("MsgSendStart, Duration %u Err %d", duration, err);
if (err) {
if (!k_delayed_work_free(&node->timer)) {
bt_mesh_client_free_node(node);
}
k_delayed_work_free(&node->timer);
bt_mesh_client_free_node(node);
return;
}
@@ -15,7 +15,7 @@
#if CONFIG_BLE_MESH_TIME_SCENE_CLIENT
#include "mesh/time_scene_client.h"
/* The followings are the macro definitions of Time Scene client
/* The following are the macro definitions of Time Scene client
* model message length, and a message is composed of 3 parts:
* Opcode + Payload + MIC
*/
@@ -114,12 +114,20 @@ static void time_scene_status(struct bt_mesh_model *model,
}
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);
if (buf->len) {
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);
} else {
status->sub_second = 0;
status->uncertainty = 0;
status->time_authority = 0;
status->tai_utc_delta = 0;
status->time_zone_offset = 0;
}
val = (uint8_t *)status;
len = sizeof(struct bt_mesh_time_status);
break;
@@ -1830,6 +1830,7 @@ static void gen_admin_prop_set(struct bt_mesh_model *model,
struct bt_mesh_gen_admin_prop_srv *srv = model->user_data;
struct bt_mesh_generic_property *property = NULL;
uint16_t property_id = 0U;
uint8_t expect_len = 0U;
uint8_t access = 0U;
if (srv == NULL || srv->property_count == 0U || srv->properties == NULL) {
@@ -1865,6 +1866,13 @@ static void gen_admin_prop_set(struct bt_mesh_model *model,
return;
}
expect_len = bt_mesh_get_dev_prop_len(property_id);
if (buf->len != expect_len) {
BT_ERR("Invalid Admin Property 0x%04x length, expect %d, actual %d",
property_id, expect_len, buf->len);
return;
}
property->admin_access = access;
net_buf_simple_reset(property->val);
@@ -2062,19 +2070,16 @@ static void gen_manu_prop_set(struct bt_mesh_model *model,
}
/* Generic Client Property Server message handlers */
static int search_prop_id_index(const uint16_t *array, uint8_t array_idx, uint16_t id)
static int search_prop_id_index(const uint16_t *array_start,
const uint16_t *array,
uint8_t array_idx, uint16_t id)
{
static const uint16_t *start = NULL;
uint8_t index = 0U;
uint16_t temp = 0U;
if (start == NULL) {
start = array;
}
if (array_idx == 0U) {
if (*array >= id) {
return array - start;
return array - array_start;
}
return -1;
@@ -2084,14 +2089,14 @@ static int search_prop_id_index(const uint16_t *array, uint8_t array_idx, uint16
temp = array[index];
if (temp == id) {
return array + index - start;
return array + index - array_start;
}
if (temp > id) {
return search_prop_id_index(array, index, id);
return search_prop_id_index(array_start, array, index, id);
}
return search_prop_id_index(array + index + 1, array_idx - 1 - index, id);
return search_prop_id_index(array_start, array + index + 1, array_idx - 1 - index, id);
}
static void gen_client_prop_get(struct bt_mesh_model *model,
@@ -2126,7 +2131,7 @@ static void gen_client_prop_get(struct bt_mesh_model *model,
*/
property_id = net_buf_simple_pull_le16(buf);
index = search_prop_id_index(srv->property_ids, srv->id_count - 1, property_id);
index = search_prop_id_index(srv->property_ids, srv->property_ids, srv->id_count - 1, property_id);
if (index < 0) {
NET_BUF_SIMPLE_DEFINE(msg, 1 + BLE_MESH_SERVER_TRANS_MIC_SIZE);
bt_mesh_model_msg_init(&msg, BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_STATUS);
@@ -371,7 +371,7 @@ static void light_lightness_linear_set(struct bt_mesh_model *model,
light_lightness_linear_tt_values(srv, trans_time, delay);
} else {
bt_mesh_light_server_state_change_t change = {
.lightness_linear_set.lightness = srv->state->lightness_actual,
.lightness_linear_set.lightness = srv->state->lightness_linear,
};
bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
model, ctx, (const uint8_t *)&change, sizeof(change));
@@ -1513,15 +1513,14 @@ static void light_hsl_range_set(struct bt_mesh_model *model,
saturation_min = net_buf_simple_pull_le16(buf);
saturation_max = net_buf_simple_pull_le16(buf);
if (hue_min > hue_max) {
BT_ERR("Invalid parameter, hue min 0x%04x, hue max 0x%04x",
hue_min, hue_max);
return;
}
if (saturation_min > saturation_max) {
BT_ERR("Invalid parameter, saturation min 0x%04x, saturation max 0x%04x",
saturation_min, saturation_max);
if (hue_min > hue_max || saturation_min > saturation_max) {
BT_ERR("Invalid parameter, hue 0x%04x/0x%04x saturation 0x%04x/0x%04x",
hue_min, hue_max, saturation_min, saturation_max);
srv->state->status_code = BLE_MESH_CANNOT_SET_RANGE_MIN;
if (ctx->recv_op == BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET) {
send_light_hsl_status(model, ctx, false, BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_STATUS);
}
send_light_hsl_status(model, NULL, true, BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_STATUS);
return;
}
@@ -2497,102 +2496,113 @@ static void light_lc_sensor_status(struct bt_mesh_model *model,
return;
}
mpid = net_buf_simple_pull_le16(buf);
if (mpid & BIT(0)) {
length = (uint8_t)((mpid & 0xff) >> 1);
uint8_t msb = net_buf_simple_pull_u8(buf);
prop_id = (uint16_t)(msb << 8) | (uint16_t)(mpid >> 8);
} else {
length = (uint8_t)((mpid & 0x1f) >> 1);
prop_id = (uint16_t)(mpid >> 5);
}
change.sensor_status.property_id = prop_id;
switch (prop_id) {
case BLE_MESH_MOTION_SENSED: {
if (length != BLE_MESH_MOTION_SENSED_LEN || length != buf->len) {
BT_WARN("Invalid Motion Sensed Property length %d", length);
return;
while (buf->len >= 2) {
mpid = net_buf_simple_pull_le16(buf);
if (mpid & BIT(0)) {
if (buf->len < 1) {
BT_WARN("Invalid LC Sensor status length %d", buf->len);
return;
}
length = (uint8_t)((mpid & 0xff) >> 1);
uint8_t msb = net_buf_simple_pull_u8(buf);
prop_id = (uint16_t)(msb << 8) | (uint16_t)(mpid >> 8);
} else {
length = (uint8_t)((mpid & 0x1f) >> 1);
prop_id = (uint16_t)(mpid >> 5);
}
uint8_t val = net_buf_simple_pull_u8(buf);
if (val > 0) {
srv->lc->state.occupancy = BLE_MESH_STATE_ON;
change.sensor_status.state.occupancy = srv->lc->state.occupancy;
change.sensor_status.property_id = prop_id;
switch (prop_id) {
case BLE_MESH_MOTION_SENSED: {
if (length != BLE_MESH_MOTION_SENSED_LEN ||
buf->len < BLE_MESH_MOTION_SENSED_LEN) {
BT_WARN("Invalid Motion Sensed Property length %d/%d", length, buf->len);
return;
}
uint8_t val = net_buf_simple_pull_u8(buf);
if (val > 0) {
srv->lc->state.occupancy = BLE_MESH_STATE_ON;
change.sensor_status.state.occupancy = srv->lc->state.occupancy;
bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
model, ctx, (const uint8_t *)&change, sizeof(change));
}
break;
}
case BLE_MESH_PEOPLE_COUNT: {
if (length != BLE_MESH_PEOPLE_COUNT_LEN ||
buf->len < BLE_MESH_PEOPLE_COUNT_LEN) {
BT_WARN("Invalid People Count Property length %d/%d", length, buf->len);
return;
}
uint16_t val = net_buf_simple_pull_le16(buf);
if (val > 0) {
srv->lc->state.occupancy = BLE_MESH_STATE_ON;
change.sensor_status.state.occupancy = srv->lc->state.occupancy;
bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
model, ctx, (const uint8_t *)&change, sizeof(change));
}
break;
}
case BLE_MESH_PRESENCE_DETECTED: {
if (length != BLE_MESH_PRESENCE_DETECTED_LEN ||
buf->len < BLE_MESH_PRESENCE_DETECTED_LEN) {
BT_WARN("Invalid Presence Detected Property length %d/%d", length, buf->len);
return;
}
uint8_t val = net_buf_simple_pull_u8(buf);
if (val > 0) {
srv->lc->state.occupancy = BLE_MESH_STATE_ON;
change.sensor_status.state.occupancy = srv->lc->state.occupancy;
bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
model, ctx, (const uint8_t *)&change, sizeof(change));
}
break;
}
case BLE_MESH_TIME_SINCE_MOTION_SENSED: {
if (length != BLE_MESH_TIME_SINCE_MOTION_SENSED_LEN ||
buf->len < BLE_MESH_TIME_SINCE_MOTION_SENSED_LEN) {
BT_WARN("Invalid Time Scene Motion Sensed Property length %d/%d", length, buf->len);
return;
}
uint16_t val = net_buf_simple_pull_le16(buf);
if (val <= srv->lc->prop_state.time_occupancy_delay) {
srv->lc->prop_state.set_occupancy_to_1_delay =
srv->lc->prop_state.time_occupancy_delay - val;
change.sensor_status.state.set_occupancy_to_1_delay = srv->lc->prop_state.set_occupancy_to_1_delay;
bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
model, ctx, (const uint8_t *)&change, sizeof(change));
}
break;
}
case BLE_MESH_PRESENT_AMBIENT_LIGHT_LEVEL: {
/**
* Present Ambient Light Level device property is 4 octets, but ambient
* luxlevel length is 3 octets, and other devices may send Sensor Status
* which only contains 3 octets just for Light LC Server.
* Here we just check if the length is larger than 3.
*/
if (length < BLE_MESH_PRESENT_AMBIENT_LIGHT_LEVEL_LEN ||
buf->len < BLE_MESH_PRESENT_AMBIENT_LIGHT_LEVEL_LEN) {
BT_WARN("Invalid Present Ambient Light Level Property length %d/%d", length, buf->len);
return;
}
uint16_t lsb = net_buf_simple_pull_le16(buf);
uint8_t msb = net_buf_simple_pull_u8(buf);
srv->lc->state.ambient_luxlevel = (msb << 16) | lsb;
change.sensor_status.state.ambient_luxlevel = srv->lc->state.ambient_luxlevel;
bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
model, ctx, (const uint8_t *)&change, sizeof(change));
break;
}
break;
}
case BLE_MESH_PEOPLE_COUNT: {
if (length != BLE_MESH_PEOPLE_COUNT_LEN || length != buf->len) {
BT_WARN("Invalid Motion Sensed Property length %d", length);
return;
default:
break;
}
uint16_t val = net_buf_simple_pull_le16(buf);
if (val > 0) {
srv->lc->state.occupancy = BLE_MESH_STATE_ON;
change.sensor_status.state.occupancy = srv->lc->state.occupancy;
bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
model, ctx, (const uint8_t *)&change, sizeof(change));
}
break;
}
case BLE_MESH_PRESENCE_DETECTED: {
if (length != BLE_MESH_PRESENCE_DETECTED_LEN || length != buf->len) {
BT_WARN("Invalid Motion Sensed Property length %d", length);
return;
}
uint8_t val = net_buf_simple_pull_u8(buf);
if (val > 0) {
srv->lc->state.occupancy = BLE_MESH_STATE_ON;
change.sensor_status.state.occupancy = srv->lc->state.occupancy;
bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
model, ctx, (const uint8_t *)&change, sizeof(change));
}
break;
}
case BLE_MESH_TIME_SINCE_MOTION_SENSED: {
if (length != BLE_MESH_TIME_SINCE_MOTION_SENSED_LEN || length != buf->len) {
BT_WARN("Invalid Motion Sensed Property length %d", length);
return;
}
uint16_t val = net_buf_simple_pull_le16(buf);
if (val <= srv->lc->prop_state.time_occupancy_delay) {
srv->lc->prop_state.set_occupancy_to_1_delay =
srv->lc->prop_state.time_occupancy_delay - val;
change.sensor_status.state.set_occupancy_to_1_delay = srv->lc->prop_state.set_occupancy_to_1_delay;
bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
model, ctx, (const uint8_t *)&change, sizeof(change));
}
break;
}
case BLE_MESH_PRESENT_AMBIENT_LIGHT_LEVEL: {
/**
* Present Ambient Light Level device property is 4 octets, but ambient
* luxlevel length is 3 octets, and other devices may send Sensor Status
* which only contains 3 octets just for Light LC Server.
* Here we just check if the length is larger than 3.
*/
if (buf->len < 3) {
BT_WARN("Invalid Motion Sensed Property length %d", buf->len);
return;
}
uint16_t lsb = net_buf_simple_pull_le16(buf);
uint8_t msb = net_buf_simple_pull_u8(buf);
srv->lc->state.ambient_luxlevel = (msb << 16) | lsb;
change.sensor_status.state.ambient_luxlevel = srv->lc->state.ambient_luxlevel;
bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_STATE_CHANGE,
model, ctx, (const uint8_t *)&change, sizeof(change));
break;
}
default:
break;
}
}
@@ -2731,7 +2741,7 @@ static void light_lc_prop_get(struct bt_mesh_model *model,
/* Callback the received message to the application layer */
if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
bt_mesh_light_server_recv_get_msg_t get = {
.lc_property_get.id = net_buf_simple_pull_le16(buf),
.lc_property_get.id = prop_id,
};
bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_GET_MSG,
model, ctx, (const uint8_t *)&get, sizeof(get));
@@ -2762,8 +2772,8 @@ static void light_lc_prop_set(struct bt_mesh_model *model,
if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
bt_mesh_light_server_recv_set_msg_t set = {
.lc_property_set.id = net_buf_simple_pull_le16(buf),
.lc_property_set.value = buf,
.lc_property_set.id = prop_id,
.lc_property_set.value = buf->len ? buf : NULL,
};
bt_mesh_lighting_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_LIGHTING_SERVER_RECV_SET_MSG,
model, ctx, (const uint8_t *)&set, sizeof(set));
@@ -599,6 +599,10 @@ static void sensor_get(struct bt_mesh_model *model,
ctx->recv_op == BLE_MESH_MODEL_OP_SENSOR_GET) {
bool get_all = buf->len ? false : true;
if (buf->len) {
if (buf->len != 2) {
BT_ERR("Invalid Sensor Get msg length %u", buf->len);
return;
}
prop_id = net_buf_simple_pull_le16(buf);
if (prop_id == INVALID_SENSOR_PROPERTY_ID) {
BT_ERR("Prohibited Sensor Property ID 0x0000");
@@ -806,11 +810,21 @@ static void sensor_cadence_set(struct bt_mesh_model *model,
}
if (state->cadence->trigger_delta_down) {
if (net_buf_simple_tailroom(state->cadence->trigger_delta_down) < trigger_len) {
BT_ERR("InsuffTriggerDeltaDownBufSize %d/%d",
net_buf_simple_tailroom(state->cadence->trigger_delta_down), trigger_len);
return;
}
net_buf_simple_reset(state->cadence->trigger_delta_down);
net_buf_simple_add_mem(state->cadence->trigger_delta_down, buf->data, trigger_len);
net_buf_simple_pull_mem(buf, trigger_len);
}
if (state->cadence->trigger_delta_up) {
if (net_buf_simple_tailroom(state->cadence->trigger_delta_up) < trigger_len) {
BT_ERR("InsuffTriggerDeltaUpBufSize %d/%d",
net_buf_simple_tailroom(state->cadence->trigger_delta_up), trigger_len);
return;
}
net_buf_simple_reset(state->cadence->trigger_delta_up);
net_buf_simple_add_mem(state->cadence->trigger_delta_up, buf->data, trigger_len);
net_buf_simple_pull_mem(buf, trigger_len);
@@ -831,11 +845,21 @@ static void sensor_cadence_set(struct bt_mesh_model *model,
if (buf->len) {
uint8_t range_len = buf->len / 2;
if (state->cadence->fast_cadence_low) {
if (net_buf_simple_tailroom(state->cadence->fast_cadence_low) < range_len) {
BT_ERR("InsuffFastCadenceLowBufSize %d/%d",
net_buf_simple_tailroom(state->cadence->fast_cadence_low), range_len);
return;
}
net_buf_simple_reset(state->cadence->fast_cadence_low);
net_buf_simple_add_mem(state->cadence->fast_cadence_low, buf->data, range_len);
net_buf_simple_pull_mem(buf, range_len);
}
if (state->cadence->fast_cadence_high) {
if (net_buf_simple_tailroom(state->cadence->fast_cadence_high) < range_len) {
BT_ERR("InsuffFastCadenceHighBufSize %d/%d",
net_buf_simple_tailroom(state->cadence->fast_cadence_high), range_len);
return;
}
net_buf_simple_reset(state->cadence->fast_cadence_high);
net_buf_simple_add_mem(state->cadence->fast_cadence_high, buf->data, range_len);
net_buf_simple_pull_mem(buf, range_len);
@@ -1018,7 +1042,12 @@ static int check_sensor_server_init(struct bt_mesh_sensor_state *state_start,
return -EINVAL;
}
}
if (state->setting_count && state->settings) {
if (state->setting_count) {
if (state->settings == NULL) {
BT_ERR("NullSettingsWithNonZeroSettingCount %u", state->setting_count);
return -EINVAL;
}
for (j = 0; j < state->setting_count; j++) {
setting = &state->settings[j];
if (setting->property_id == INVALID_SENSOR_SETTING_PROPERTY_ID || setting->raw == NULL) {
@@ -95,12 +95,18 @@ static void transition_time_values(struct bt_mesh_state_transition *transition,
transition->trans_time = trans_time;
transition->delay = delay;
if (trans_time == 0U) {
if ((trans_time & 0x3F) == 0U) {
transition->counter = 0U;
transition->quo_tt = 0U;
return;
}
tt_values_calculator(transition);
transition->quo_tt = transition->total_duration / transition->counter;
if (transition->counter) {
transition->quo_tt = transition->total_duration / transition->counter;
} else {
transition->quo_tt = 0;
}
}
static void transition_timer_start(struct bt_mesh_state_transition *transition)
@@ -127,16 +133,24 @@ void generic_level_tt_values(struct bt_mesh_gen_level_srv *srv,
uint8_t trans_time, uint8_t delay)
{
transition_time_values(&srv->transition, trans_time, delay);
srv->tt_delta_level =
((float) (srv->state.level - srv->state.target_level) / srv->transition.counter);
if (srv->transition.counter) {
srv->tt_delta_level =
((float) (srv->state.level - srv->state.target_level) / srv->transition.counter);
} else {
srv->tt_delta_level = 0;
}
}
void generic_power_level_tt_values(struct bt_mesh_gen_power_level_srv *srv,
uint8_t trans_time, uint8_t delay)
{
transition_time_values(&srv->transition, trans_time, delay);
srv->tt_delta_level =
((float) (srv->state->power_actual - srv->state->target_power_actual) / srv->transition.counter);
if (srv->transition.counter) {
srv->tt_delta_level =
((float) (srv->state->power_actual - srv->state->target_power_actual) / srv->transition.counter);
} else {
srv->tt_delta_level = 0;
}
}
#endif /* CONFIG_BLE_MESH_GENERIC_SERVER */
@@ -145,78 +159,117 @@ void light_lightness_actual_tt_values(struct bt_mesh_light_lightness_srv *srv,
uint8_t trans_time, uint8_t delay)
{
transition_time_values(&srv->actual_transition, trans_time, delay);
srv->tt_delta_lightness_actual =
((float) (srv->state->lightness_actual - srv->state->target_lightness_actual) / srv->actual_transition.counter);
if (srv->actual_transition.counter) {
srv->tt_delta_lightness_actual =
((float) (srv->state->lightness_actual - srv->state->target_lightness_actual) / srv->actual_transition.counter);
} else {
srv->tt_delta_lightness_actual = 0;
}
}
void light_lightness_linear_tt_values(struct bt_mesh_light_lightness_srv *srv,
uint8_t trans_time, uint8_t delay)
{
transition_time_values(&srv->linear_transition, trans_time, delay);
srv->tt_delta_lightness_linear =
((float) (srv->state->lightness_linear - srv->state->target_lightness_linear) / srv->linear_transition.counter);
if (srv->linear_transition.counter) {
srv->tt_delta_lightness_linear =
((float) (srv->state->lightness_linear - srv->state->target_lightness_linear) / srv->linear_transition.counter);
} else {
srv->tt_delta_lightness_linear = 0;
}
}
void light_ctl_tt_values(struct bt_mesh_light_ctl_srv *srv,
uint8_t trans_time, uint8_t delay)
{
transition_time_values(&srv->transition, trans_time, delay);
srv->tt_delta_lightness =
((float) (srv->state->lightness - srv->state->target_lightness) / srv->transition.counter);
srv->tt_delta_temperature =
((float) (srv->state->temperature - srv->state->target_temperature) / srv->transition.counter);
srv->tt_delta_delta_uv =
((float) (srv->state->delta_uv - srv->state->target_delta_uv) / srv->transition.counter);
if (srv->transition.counter) {
srv->tt_delta_lightness =
((float) (srv->state->lightness - srv->state->target_lightness) / srv->transition.counter);
srv->tt_delta_temperature =
((float) (srv->state->temperature - srv->state->target_temperature) / srv->transition.counter);
srv->tt_delta_delta_uv =
((float) (srv->state->delta_uv - srv->state->target_delta_uv) / srv->transition.counter);
} else {
srv->tt_delta_lightness = 0;
srv->tt_delta_temperature = 0;
srv->tt_delta_delta_uv = 0;
}
}
void light_ctl_temp_tt_values(struct bt_mesh_light_ctl_temp_srv *srv,
uint8_t trans_time, uint8_t delay)
{
transition_time_values(&srv->transition, trans_time, delay);
srv->tt_delta_temperature =
((float) (srv->state->temperature - srv->state->target_temperature) / srv->transition.counter);
srv->tt_delta_delta_uv =
((float) (srv->state->delta_uv - srv->state->target_delta_uv) / srv->transition.counter);
if (srv->transition.counter) {
srv->tt_delta_temperature =
((float) (srv->state->temperature - srv->state->target_temperature) / srv->transition.counter);
srv->tt_delta_delta_uv =
((float) (srv->state->delta_uv - srv->state->target_delta_uv) / srv->transition.counter);
} else {
srv->tt_delta_temperature = 0;
srv->tt_delta_delta_uv = 0;
}
}
void light_hsl_tt_values(struct bt_mesh_light_hsl_srv *srv,
uint8_t trans_time, uint8_t delay)
{
transition_time_values(&srv->transition, trans_time, delay);
srv->tt_delta_lightness =
((float) (srv->state->lightness - srv->state->target_lightness) / srv->transition.counter);
srv->tt_delta_hue =
((float) (srv->state->hue - srv->state->target_hue) / srv->transition.counter);
srv->tt_delta_saturation =
((float) (srv->state->saturation - srv->state->target_saturation) / srv->transition.counter);
if (srv->transition.counter) {
srv->tt_delta_lightness =
((float) (srv->state->lightness - srv->state->target_lightness) / srv->transition.counter);
srv->tt_delta_hue =
((float) (srv->state->hue - srv->state->target_hue) / srv->transition.counter);
srv->tt_delta_saturation =
((float) (srv->state->saturation - srv->state->target_saturation) / srv->transition.counter);
} else {
srv->tt_delta_lightness = 0;
srv->tt_delta_hue = 0;
srv->tt_delta_saturation = 0;
}
}
void light_hsl_hue_tt_values(struct bt_mesh_light_hsl_hue_srv *srv,
uint8_t trans_time, uint8_t delay)
{
transition_time_values(&srv->transition, trans_time, delay);
srv->tt_delta_hue =
((float) (srv->state->hue - srv->state->target_hue) / srv->transition.counter);
if (srv->transition.counter) {
srv->tt_delta_hue =
((float) (srv->state->hue - srv->state->target_hue) / srv->transition.counter);
} else {
srv->tt_delta_hue = 0;
}
}
void light_hsl_sat_tt_values(struct bt_mesh_light_hsl_sat_srv *srv,
uint8_t trans_time, uint8_t delay)
{
transition_time_values(&srv->transition, trans_time, delay);
srv->tt_delta_saturation =
((float) (srv->state->saturation - srv->state->target_saturation) / srv->transition.counter);
if (srv->transition.counter) {
srv->tt_delta_saturation =
((float) (srv->state->saturation - srv->state->target_saturation) / srv->transition.counter);
} else {
srv->tt_delta_saturation = 0;
}
}
void light_xyl_tt_values(struct bt_mesh_light_xyl_srv *srv,
uint8_t trans_time, uint8_t delay)
{
transition_time_values(&srv->transition, trans_time, delay);
srv->tt_delta_lightness =
((float) (srv->state->lightness - srv->state->target_lightness) / srv->transition.counter);
srv->tt_delta_x =
((float) (srv->state->x - srv->state->target_x) / srv->transition.counter);
srv->tt_delta_y =
((float) (srv->state->y - srv->state->target_y) / srv->transition.counter);
if (srv->transition.counter) {
srv->tt_delta_lightness =
((float) (srv->state->lightness - srv->state->target_lightness) / srv->transition.counter);
srv->tt_delta_x =
((float) (srv->state->x - srv->state->target_x) / srv->transition.counter);
srv->tt_delta_y =
((float) (srv->state->y - srv->state->target_y) / srv->transition.counter);
} else {
srv->tt_delta_lightness = 0;
srv->tt_delta_x = 0;
srv->tt_delta_y = 0;
}
}
void light_lc_tt_values(struct bt_mesh_light_lc_srv *srv,
@@ -235,6 +235,7 @@ static void time_get(struct bt_mesh_model *model,
srv->state->time.subsecond = net_buf_simple_pull_u8(buf);
srv->state->time.uncertainty = net_buf_simple_pull_u8(buf);
val = net_buf_simple_pull_le16(buf);
srv->state->time.time_authority = val & BIT(0);
srv->state->time.tai_utc_delta_curr = (val >> 1) & BIT_MASK(15);
srv->state->time.time_zone_offset_curr = net_buf_simple_pull_u8(buf);
}
@@ -754,6 +755,7 @@ static void scene_action(struct bt_mesh_model *model,
if (i == srv->state->scene_count) {
BT_WARN("Scene Register is full!");
srv->state->status_code = SCENE_REG_FULL;
#if 0
/* Get the Scene Number of the currently active scene */
for (i = 0; i < srv->state->scene_count; i++) {
scene = &srv->state->scenes[i];
@@ -766,10 +768,12 @@ static void scene_action(struct bt_mesh_model *model,
/* A value of 0x0000 when no scene is active */
srv->state->current_scene = INVALID_SCENE_NUMBER;
}
#endif
}
}
if (srv->state->in_progress == true) {
if (srv->state->status_code == SCENE_SUCCESS &&
srv->state->in_progress == true) {
/**
* 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,
@@ -940,6 +944,12 @@ static void send_scheduler_act_status(struct bt_mesh_model *model,
switch (model->id) {
case BLE_MESH_MODEL_ID_SCHEDULER_SRV: {
struct bt_mesh_scheduler_srv *srv = model->user_data;
if (srv == NULL || srv->state == NULL ||
srv->state->schedules == NULL ||
index >= srv->state->schedule_count) {
BT_ERR("InvalidScheduleSrvParams");
return;
}
value = get_schedule_reg_state(srv->state, index);
net_buf_simple_add_le32(&msg, (uint32_t)value);
net_buf_simple_add_le32(&msg, (uint32_t)(value >> 32));
@@ -948,6 +958,12 @@ static void send_scheduler_act_status(struct bt_mesh_model *model,
}
case BLE_MESH_MODEL_ID_SCHEDULER_SETUP_SRV: {
struct bt_mesh_scheduler_setup_srv *srv = model->user_data;
if (srv == NULL || srv->state == NULL ||
srv->state->schedules == NULL ||
index >= srv->state->schedule_count) {
BT_ERR("InvalidScheduleSrvParams");
return;
}
value = get_schedule_reg_state(srv->state, index);
net_buf_simple_add_le32(&msg, (uint32_t)value);
net_buf_simple_add_le32(&msg, (uint32_t)(value >> 32));
@@ -1056,6 +1072,11 @@ static void scheduler_act_set(struct bt_mesh_model *model,
return;
}
if (index >= srv->state->schedule_count) {
BT_ERR("TooLargeScheduleIndex %u/%u", index, srv->state->schedule_count);
return;
}
if (year > SCHEDULE_YEAR_ANY_YEAR) {
BT_ERR("Invalid Scheduler Register year 0x%02x", year);
return;