Good day!
This function in scheduler server compares timestamps only between each other and if scheduler stores settings after reset and set new time (without bt_mesh_scheduler_srv_time_update) will "brick" scheduler.
Also I wasn't able to use periodic tasks because they wasn't automatically rescheduled.
My fast fix
static void reschedule(struct bt_mesh_scheduler_srv *srv,
struct bt_mesh_time_status *status)
{
uint8_t cnt = u32_count_trailing_zeros(srv->active_bitmap);
while (++cnt < BT_MESH_SCHEDULER_ACTION_ENTRY_COUNT) {
if (srv->active_bitmap & BIT(cnt) &&
srv->sched_tai[cnt].sec < status->tai.sec) {
WRITE_BIT(srv->active_bitmap, cnt, 0);
schedule_action(srv, cnt);
}
}
}
static void run_scheduler(struct bt_mesh_scheduler_srv *srv)
{
int64_t current_uptime = k_uptime_get();
struct bt_mesh_time_status status;
int err =
bt_mesh_time_srv_status(srv->time_srv, current_uptime, &status);
int64_t offset_sec =
srv->time_srv->data.sync.status.time_zone_offset / 4 * 60 * 60;
if (err != 0) {
BT_DBG("Time server don't respond (%d)", err);
return;
}
reschedule(srv, &status);
uint8_t planned_idx = get_least_time_index(srv);
if (planned_idx == BT_MESH_SCHEDULER_ACTION_ENTRY_COUNT) {
return;
}
srv->idx = planned_idx;
int64_t scheduled_uptime = srv->sched_tai[planned_idx].sec -
(status.tai.sec + offset_sec - 218);
k_work_reschedule(&srv->delayed_work, K_MSEC(MAX(scheduled_uptime, 0)));
BT_DBG("Scheduler started. %u Target uptime: %lld", srv->idx,
scheduled_uptime);
}