From 0cf19915085a9bd0e88b4e1ba40f2cbf22851761 Mon Sep 17 00:00:00 2001 From: Vikrant More Date: Fri, 10 May 2019 00:31:55 +0530 Subject: [PATCH] samples: mesh: corrected implemenation of gen. move message handlers After receiving Generic Level Move set/set_unack message, generic level state should move towards positive or negative extreme end (which is depend upon sign of delta value) till it not get interruped. This commit has introduced this feature. Signed-off-by: Vikrant More --- .../src/mesh/device_composition.c | 168 ++++++++---------- .../src/mesh/transition.c | 86 ++++++++- .../src/mesh/transition.h | 10 +- 3 files changed, 160 insertions(+), 104 deletions(-) diff --git a/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c b/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c index 472726676c5167..fba5d69870430f 100644 --- a/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c +++ b/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c @@ -209,6 +209,7 @@ static void gen_onoff_set_unack(struct bt_mesh_model *model, state->target_onoff = onoff; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = ONOFF_TT; if (state->target_onoff != state->onoff) { onoff_tt_values(state); @@ -283,6 +284,7 @@ static void gen_onoff_set(struct bt_mesh_model *model, state->target_onoff = onoff; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = ONOFF_TT; if (state->target_onoff != state->onoff) { onoff_tt_values(state); @@ -338,9 +340,15 @@ static void gen_level_get(struct bt_mesh_model *model, } if (state->transition->counter) { - calculate_rt(state->transition); - net_buf_simple_add_le16(msg, state->target_level); - net_buf_simple_add_u8(msg, state->transition->rt); + if (state->transition->type == LEVEL_TT_MOVE || + state->transition->type == LEVEL_TEMP_TT_MOVE) { + net_buf_simple_add_le16(msg, state->target_level); + net_buf_simple_add_u8(msg, UNKNOWN_VALUE); + } else { + calculate_rt(state->transition); + net_buf_simple_add_le16(msg, state->target_level); + net_buf_simple_add_u8(msg, state->transition->rt); + } } send: @@ -367,9 +375,15 @@ void gen_level_publish(struct bt_mesh_model *model) } if (state->transition->counter) { - calculate_rt(state->transition); - net_buf_simple_add_le16(msg, state->target_level); - net_buf_simple_add_u8(msg, state->transition->rt); + if (state->transition->type == LEVEL_TT_MOVE || + state->transition->type == LEVEL_TEMP_TT_MOVE) { + net_buf_simple_add_le16(msg, state->target_level); + net_buf_simple_add_u8(msg, UNKNOWN_VALUE); + } else { + calculate_rt(state->transition); + net_buf_simple_add_le16(msg, state->target_level); + net_buf_simple_add_u8(msg, state->transition->rt); + } } publish: @@ -426,6 +440,7 @@ static void gen_level_set_unack(struct bt_mesh_model *model, state->target_level = level; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = UNKNOWN_TT; if (state->target_level != state->level) { level_tt_values(state); @@ -444,11 +459,11 @@ static void gen_level_set_unack(struct bt_mesh_model *model, if (bt_mesh_model_elem(model)->addr == elements[0].addr) { /* Root element */ - transition_type = LEVEL_TT; + state->transition->type = LEVEL_TT; level_lightness_handler(state); } else if (bt_mesh_model_elem(model)->addr == elements[1].addr) { /* Secondary element */ - transition_type = LEVEL_TEMP_TT; + state->transition->type = LEVEL_TEMP_TT; level_temp_handler(state); } } @@ -501,6 +516,7 @@ static void gen_level_set(struct bt_mesh_model *model, state->target_level = level; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = UNKNOWN_TT; if (state->target_level != state->level) { level_tt_values(state); @@ -521,11 +537,11 @@ static void gen_level_set(struct bt_mesh_model *model, if (bt_mesh_model_elem(model)->addr == elements[0].addr) { /* Root element */ - transition_type = LEVEL_TT; + state->transition->type = LEVEL_TT; level_lightness_handler(state); } else if (bt_mesh_model_elem(model)->addr == elements[1].addr) { /* Secondary element */ - transition_type = LEVEL_TEMP_TT; + state->transition->type = LEVEL_TEMP_TT; level_temp_handler(state); } } @@ -593,6 +609,7 @@ static void gen_delta_set_unack(struct bt_mesh_model *model, state->target_level = tmp32; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = UNKNOWN_TT; if (state->target_level != state->level) { level_tt_values(state); @@ -611,12 +628,11 @@ static void gen_delta_set_unack(struct bt_mesh_model *model, if (bt_mesh_model_elem(model)->addr == elements[0].addr) { /* Root element */ - transition_type = LEVEL_TT_DELTA; + state->transition->type = LEVEL_TT_DELTA; level_lightness_handler(state); - } else if (bt_mesh_model_elem(model)->addr == - elements[1].addr) { + } else if (bt_mesh_model_elem(model)->addr == elements[1].addr) { /* Secondary element */ - transition_type = LEVEL_TEMP_TT_DELTA; + state->transition->type = LEVEL_TEMP_TT_DELTA; level_temp_handler(state); } } @@ -685,6 +701,7 @@ static void gen_delta_set(struct bt_mesh_model *model, state->target_level = tmp32; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = UNKNOWN_TT; if (state->target_level != state->level) { level_tt_values(state); @@ -705,76 +722,21 @@ static void gen_delta_set(struct bt_mesh_model *model, if (bt_mesh_model_elem(model)->addr == elements[0].addr) { /* Root element */ - transition_type = LEVEL_TT_DELTA; + state->transition->type = LEVEL_TT_DELTA; level_lightness_handler(state); } else if (bt_mesh_model_elem(model)->addr == elements[1].addr) { /* Secondary element */ - transition_type = LEVEL_TEMP_TT_DELTA; + state->transition->type = LEVEL_TEMP_TT_DELTA; level_temp_handler(state); } } -static void gen_level_move_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) -{ - struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 5 + 4); - struct generic_level_state *state = model->user_data; - - bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_LEVEL_STATUS); - net_buf_simple_add_le16(msg, state->level); - - if (state->transition->counter) { - if (state->last_delta < 0) { - net_buf_simple_add_le16(msg, INT16_MIN); - } else { /* 0 should not be possible */ - net_buf_simple_add_le16(msg, INT16_MAX); - } - - net_buf_simple_add_u8(msg, UNKNOWN_VALUE); - } - - if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { - printk("Unable to send GEN_LEVEL_SRV Status response\n"); - } -} - -static void gen_level_move_publish(struct bt_mesh_model *model) -{ - int err; - struct net_buf_simple *msg = model->pub->msg; - struct generic_level_state *state = model->user_data; - - if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) { - return; - } - - bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_LEVEL_STATUS); - net_buf_simple_add_le16(msg, state->level); - - if (state->transition->counter) { - if (state->last_delta < 0) { - net_buf_simple_add_le16(msg, INT16_MIN); - } else { /* 0 should not be possible */ - net_buf_simple_add_le16(msg, INT16_MAX); - } - - net_buf_simple_add_u8(msg, UNKNOWN_VALUE); - } - - err = bt_mesh_model_publish(model); - if (err) { - printk("bt_mesh_model_publish err %d\n", err); - } -} - static void gen_move_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { u8_t tid, tt, delay; s16_t delta; - s32_t tmp32; s64_t now; struct generic_level_state *state = model->user_data; @@ -815,21 +777,22 @@ static void gen_move_set_unack(struct bt_mesh_model *model, state->last_msg_timestamp = now; state->last_delta = delta; - tmp32 = state->level + delta; - if (tmp32 < INT16_MIN) { - tmp32 = INT16_MIN; - } else if (tmp32 > INT16_MAX) { - tmp32 = INT16_MAX; + if (delta < 0) { + state->target_level = INT16_MIN; + } else if (delta > 0) { + state->target_level = INT16_MAX; + } else if (delta == 0) { + state->target_level = state->level; } - state->target_level = tmp32; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = UNKNOWN_TT; if (state->target_level != state->level) { - level_tt_values(state); + level_move_tt_values(state); } else { - gen_level_move_publish(model); + gen_level_publish(model); return; } @@ -838,15 +801,16 @@ static void gen_move_set_unack(struct bt_mesh_model *model, } state->transition->just_started = true; - gen_level_move_publish(model); if (bt_mesh_model_elem(model)->addr == elements[0].addr) { /* Root element */ - transition_type = LEVEL_TT_MOVE; + state->transition->type = LEVEL_TT_MOVE; + gen_level_publish(model); level_lightness_handler(state); } else if (bt_mesh_model_elem(model)->addr == elements[1].addr) { /* Secondary element */ - transition_type = LEVEL_TEMP_TT_MOVE; + state->transition->type = LEVEL_TEMP_TT_MOVE; + gen_level_publish(model); level_temp_handler(state); } } @@ -857,7 +821,6 @@ static void gen_move_set(struct bt_mesh_model *model, { u8_t tid, tt, delay; s16_t delta; - s32_t tmp32; s64_t now; struct generic_level_state *state = model->user_data; @@ -869,7 +832,7 @@ static void gen_move_set(struct bt_mesh_model *model, state->last_src_addr == ctx->addr && state->last_dst_addr == ctx->recv_dst && (now - state->last_msg_timestamp <= K_SECONDS(6))) { - gen_level_move_get(model, ctx, buf); + gen_level_get(model, ctx, buf); return; } @@ -899,22 +862,23 @@ static void gen_move_set(struct bt_mesh_model *model, state->last_msg_timestamp = now; state->last_delta = delta; - tmp32 = state->level + delta; - if (tmp32 < INT16_MIN) { - tmp32 = INT16_MIN; - } else if (tmp32 > INT16_MAX) { - tmp32 = INT16_MAX; + if (delta < 0) { + state->target_level = INT16_MIN; + } else if (delta > 0) { + state->target_level = INT16_MAX; + } else if (delta == 0) { + state->target_level = state->level; } - state->target_level = tmp32; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = UNKNOWN_TT; if (state->target_level != state->level) { - level_tt_values(state); + level_move_tt_values(state); } else { - gen_level_move_get(model, ctx, buf); - gen_level_move_publish(model); + gen_level_get(model, ctx, buf); + gen_level_publish(model); return; } @@ -923,16 +887,18 @@ static void gen_move_set(struct bt_mesh_model *model, } state->transition->just_started = true; - gen_level_move_get(model, ctx, buf); - gen_level_move_publish(model); if (bt_mesh_model_elem(model)->addr == elements[0].addr) { /* Root element */ - transition_type = LEVEL_TT_MOVE; + state->transition->type = LEVEL_TT_MOVE; + gen_level_get(model, ctx, buf); + gen_level_publish(model); level_lightness_handler(state); } else if (bt_mesh_model_elem(model)->addr == elements[1].addr) { /* Secondary element */ - transition_type = LEVEL_TEMP_TT_MOVE; + state->transition->type = LEVEL_TEMP_TT_MOVE; + gen_level_get(model, ctx, buf); + gen_level_publish(model); level_temp_handler(state); } } @@ -1313,6 +1279,7 @@ static void light_lightness_set_unack(struct bt_mesh_model *model, state->target_actual = actual; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = LIGHT_ACTUAL_TT; if (state->target_actual != state->actual) { light_lightness_actual_tt_values(state); @@ -1386,6 +1353,7 @@ static void light_lightness_set(struct bt_mesh_model *model, state->target_actual = actual; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = LIGHT_ACTUAL_TT; if (state->target_actual != state->actual) { light_lightness_actual_tt_values(state); @@ -1511,6 +1479,7 @@ static void light_lightness_linear_set_unack(struct bt_mesh_model *model, state->target_linear = linear; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = LIGHT_LINEAR_TT; if (state->target_linear != state->linear) { light_lightness_linear_tt_values(state); @@ -1577,6 +1546,7 @@ static void light_lightness_linear_set(struct bt_mesh_model *model, state->target_linear = linear; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = LIGHT_LINEAR_TT; if (state->target_linear != state->linear) { light_lightness_linear_tt_values(state); @@ -1960,6 +1930,7 @@ static void light_ctl_set_unack(struct bt_mesh_model *model, state->target_delta_uv = delta_uv; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = LIGHT_CTL_TT; if (state->target_lightness != state->lightness || state->target_temp != state->temp || @@ -2046,6 +2017,7 @@ static void light_ctl_set(struct bt_mesh_model *model, state->target_delta_uv = delta_uv; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = LIGHT_CTL_TT; if (state->target_lightness != state->lightness || state->target_temp != state->temp || @@ -2446,6 +2418,7 @@ static void light_ctl_temp_set_unack(struct bt_mesh_model *model, state->target_delta_uv = delta_uv; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = LIGHT_CTL_TEMP_TT; if (state->target_temp != state->temp || state->target_delta_uv != state->delta_uv) { @@ -2528,6 +2501,7 @@ static void light_ctl_temp_set(struct bt_mesh_model *model, state->target_delta_uv = delta_uv; state->transition->tt = tt; state->transition->delay = delay; + state->transition->type = LIGHT_CTL_TEMP_TT; if (state->target_temp != state->temp || state->target_delta_uv != state->delta_uv) { diff --git a/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/transition.c b/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/transition.c index bd280f67dbf89c..d7500bc4e466ba 100644 --- a/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/transition.c +++ b/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/transition.c @@ -13,7 +13,7 @@ #include "state_binding.h" #include "transition.h" -u8_t transition_type, default_tt; +u8_t default_tt; u32_t *ptr_counter; struct k_timer *ptr_timer = &dummy_timer; @@ -130,6 +130,23 @@ void level_tt_values(struct generic_level_state *state) state->transition->counter); } +void level_move_tt_values(struct generic_level_state *state) +{ + if (state == &gen_level_srv_root_user_data) { + calculate_lightness_target_values(LEVEL); + } else if (state == &gen_level_srv_s0_user_data) { + calculate_temp_target_values(LEVEL_TEMP); + } + + if (!tt_values_calculator(state->transition)) { + return; + } + + state->transition->quo_tt = state->transition->total_duration; + + state->tt_delta = state->last_delta; +} + void light_lightness_actual_tt_values(struct light_lightness_state *state) { calculate_lightness_target_values(ACTUAL); @@ -249,12 +266,35 @@ static void onoff_work_handler(struct k_work *work) } } +static void level_move_lightness_work_handler(void) +{ + s32_t level; + struct generic_level_state *state = &gen_level_srv_root_user_data; + + level = state->level + state->tt_delta; + if (level <= INT16_MIN || level >= INT16_MAX) { + state->transition->counter = 0U; + k_timer_stop(ptr_timer); + + if (level > 0) { + level = INT16_MAX; + } else if (level < 0) { + level = INT16_MIN; + } + } + + state->level = level; + + state_binding(LEVEL, IGNORE_TEMP); + update_light_state(); +} + static void level_lightness_work_handler(struct k_work *work) { u8_t level; struct generic_level_state *state = &gen_level_srv_root_user_data; - switch (transition_type) { + switch (state->transition->type) { case LEVEL_TT: level = LEVEL; break; @@ -262,8 +302,13 @@ static void level_lightness_work_handler(struct k_work *work) level = DELTA_LEVEL; break; case LEVEL_TT_MOVE: - level = LEVEL; - break; + if (state->transition->just_started) { + state->transition->just_started = false; + return; + } + + level_move_lightness_work_handler(); + return; default: return; } @@ -302,17 +347,46 @@ static void level_lightness_work_handler(struct k_work *work) } } +static void level_move_temp_work_handler(void) +{ + s32_t level; + struct generic_level_state *state = &gen_level_srv_s0_user_data; + + level = state->level + state->tt_delta; + if (level <= INT16_MIN || level >= INT16_MAX) { + state->transition->counter = 0U; + k_timer_stop(ptr_timer); + + if (level > 0) { + level = INT16_MAX; + } else if (level < 0) { + level = INT16_MIN; + } + } + + state->level = level; + + state_binding(IGNORE, LEVEL_TEMP); + update_light_state(); +} + static void level_temp_work_handler(struct k_work *work) { struct generic_level_state *state = &gen_level_srv_s0_user_data; - switch (transition_type) { + switch (state->transition->type) { case LEVEL_TEMP_TT: break; case LEVEL_TEMP_TT_DELTA: break; case LEVEL_TEMP_TT_MOVE: - break; + if (state->transition->just_started) { + state->transition->just_started = false; + return; + } + + level_move_temp_work_handler(); + return; default: return; } diff --git a/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/transition.h b/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/transition.h index a815d9fa7ebfa3..73e4dc4988d1ad 100644 --- a/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/transition.h +++ b/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/transition.h @@ -12,17 +12,24 @@ #define DEVICE_SPECIFIC_RESOLUTION 10 enum level_transition_types { + UNKNOWN_TT, + ONOFF_TT, LEVEL_TT, LEVEL_TT_DELTA, LEVEL_TT_MOVE, + LIGHT_ACTUAL_TT, + LIGHT_LINEAR_TT, + LIGHT_CTL_TT, LEVEL_TEMP_TT, LEVEL_TEMP_TT_DELTA, LEVEL_TEMP_TT_MOVE, + LIGHT_CTL_TEMP_TT, }; struct transition { bool just_started; + u8_t type; u8_t tt; u8_t rt; u8_t delay; @@ -34,7 +41,7 @@ struct transition { struct k_timer timer; }; -extern u8_t transition_type, default_tt; +extern u8_t default_tt; extern u32_t *ptr_counter; extern struct k_timer *ptr_timer; @@ -47,6 +54,7 @@ void calculate_rt(struct transition *transition); void onoff_tt_values(struct generic_onoff_state *state); void level_tt_values(struct generic_level_state *state); +void level_move_tt_values(struct generic_level_state *state); void light_lightness_actual_tt_values(struct light_lightness_state *state); void light_lightness_linear_tt_values(struct light_lightness_state *state); void light_ctl_tt_values(struct light_ctl_state *state);