/* * Copyright (c) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "schedule_list.h" #include "schedule_store.h" #include "iot_schedule.h" #define MAX_SCHEDULE_LIST 7 static SCHEDULE_LIST gScheduleList[MAX_SCHEDULE_LIST]; static int g_isUpdate = 0; static int g_startSeconds = -1; static int g_durationSeconds = -1; static int g_curWeekDay = -1; static ScheduleCommand g_cmd = {0}; static int g_oneTime = 0; // 获取类似 1001101 结构的weeks 的天数 返回 数组 Days下标和 值都是周几 static int GetWeekDay(unsigned char weekday, int Days[], int size) { int n = 0; if (size != MAX_SCHEDULE_LIST) { SCH_ERR("weekday array is OOR! \n"); return -1; } for (int i = 0; i < MAX_SCHEDULE_LIST; i++) { if ((weekday >> i) & 0x01) { Days[n++] = i; } } return n; } // 将每一天都放进一个链表的尾部 static void ScheduleGetStore(void) { int total = ScheduleStoreGetTotal(); if (total <= 0) { SCH_ERR("no schedule stored! \n"); return; } for (int i = 0; i < total; i++) { ScheduleInfo info = {0}; int weeknum = 0; int week[MAX_SCHEDULE_LIST] = {0}; if (ScheduleStoreGetInfo(&info, i) < 0) { SCH_ERR("read schedulestore %d failed! \n", i); continue; } weeknum = GetWeekDay(info.week, week, MAX_SCHEDULE_LIST); if (weeknum <= 0) { SCH_ERR("the schedule has no weekday info! \n"); continue; } for (int j = 0; j < weeknum; j++) { int weekday = week[j]; if (weekday >= MAX_SCHEDULE_LIST) { SCH_ERR("weekday is OOR!\n"); break; } if (ScheduleListAppend(gScheduleList[weekday], &info) < 0) { SCH_ERR("ScheduleListAppend failed!\n"); break; } SCH_DBG("add info : id--%s, starttime--%d, duration--%d, week(%d)\n", info.id, info.starttime, info.duration, weekday); } } } // 创建链表 int IOT_ScheduleInit(void) { int retval = 0; for (int i = 0; i < MAX_SCHEDULE_LIST; i++) { gScheduleList[i] = ScheduleListCreate(NULL); if (gScheduleList[i] == NULL) { SCH_ERR("ScheduleListCreate (%d) failed! \n", i); retval = -1; break; } } if (retval < 0) { for (int i = 0; i < MAX_SCHEDULE_LIST; i++) { if (gScheduleList[i] != NULL) { ScheduleListDestroy(gScheduleList[i]); gScheduleList[i] = NULL; } } } else { ScheduleGetStore(); g_isUpdate = 1; } return retval; } // 根据新的数据更新链表 static int ScheduleUpdate(const char *id, int *day, int size, int startTime, int durTime, SCHEDULE_OPTION option, int cmd, int value) { typedef int (*OptionFunc)(SCHEDULE_LIST mHandle, ScheduleInfo *info); OptionFunc opFunc[] = {ScheduleListAppend, ScheduleListUpdate, ScheduleListDelete}; ScheduleInfo info = {0}; info.starttime = startTime; info.duration = durTime; info.scheduleCmd.cmd = cmd; info.scheduleCmd.value = value; SCH_DBG("cmd = %d, value = %d \n", cmd, value); if (option > SCHEDULE_OPTION_DELETE) { SCH_ERR("OPTION OOR!\n"); return -1; } if (size == 1 && day[0] == 0) { // one time schedule g_oneTime = 1; g_isUpdate = 1; g_startSeconds = startTime; g_durationSeconds = durTime; g_cmd.value = value; g_cmd.cmd = cmd; SCH_DBG("this schedule is onetime! \n"); return 0; } strncpy(info.id, id, strlen(id)); for (int i = 0; i < size; i++) { int idx = day[i] - 1; if (idx >= MAX_SCHEDULE_LIST) { SCH_ERR("weekday is OOR! \n"); continue; } info.week += (1 << idx); if (opFunc[option](gScheduleList[idx], &info) < 0) { SCH_ERR("ScheduleListAppend failed! \n"); return -1; } SCH_DBG("add info : id--%s, starttime--%d, duration--%d, week(%d)--0x%x, cmd--%d, value -- %d\n", info.id, info.starttime, info.duration, idx, info.week, info.scheduleCmd.cmd, info.scheduleCmd.value); } ScheduleStoreUpdate(&info, option); if ((option == SCHEDULE_OPTION_DELETE) && (g_startSeconds == startTime)) { g_startSeconds = 0; g_durationSeconds = 0; } g_isUpdate = 1; return 0; } int IOT_ScheduleAdd(const char *id, int *day, int size, int startTime, int durTime, int cmd, int value) { return ScheduleUpdate(id, day, size, startTime, durTime, SCHEDULE_OPTION_ADD, cmd, value); } int IOT_ScheduleUpdate(const char *id, int *day, int size, int startTime, int durTime, int cmd, int value) { return ScheduleUpdate(id, day, size, startTime, durTime, SCHEDULE_OPTION_UPDATE, cmd, value); } int IOT_ScheduleDelete(const char *id, int *day, int size, int startTime, int durTime, int cmd, int value) { return ScheduleUpdate(id, day, size, startTime, durTime, SCHEDULE_OPTION_DELETE, cmd, value); } int IOT_ScheduleIsUpdate(unsigned int weekday, int curtime) { int total = 0; int retval = 0; if (g_isUpdate == 0) { return 0; } g_isUpdate = 0; if (g_oneTime) { g_oneTime = 0; if (g_startSeconds > curtime) { SCH_DBG("get one time schedule! \n"); return 1; } } if (weekday >= MAX_SCHEDULE_LIST || curtime < 0) { return 0; } total = ScheduleListGetSize(gScheduleList[weekday]); if (total <= 0) { return 0; } for (int i = 0; i < total; i++) { ScheduleInfo info; if (ScheduleListGet(gScheduleList[weekday], i, (ScheduleInfo *)&info) < 0) { SCH_ERR("ScheduleListGet failed! \n"); return 0; } if (curtime < (info.starttime + info.duration)) { if (g_curWeekDay == weekday) { if (g_startSeconds != info.starttime || g_durationSeconds != info.duration) { g_startSeconds = info.starttime; g_durationSeconds = info.duration; g_cmd.cmd = info.scheduleCmd.cmd; g_cmd.value = info.scheduleCmd.value; retval = 1; } } else { g_curWeekDay = weekday; g_startSeconds = info.starttime; g_durationSeconds = info.duration; g_cmd.cmd = info.scheduleCmd.cmd; g_cmd.value = info.scheduleCmd.value; retval = 1; } break; } } if (retval == 1) { SCH_DBG("cmd = %d, value = %d \n", g_cmd.cmd, g_cmd.value); } return retval; } void IOT_ScheduleSetUpdate(int update) { g_isUpdate = update; } int IOT_ScheduleGetStartTime(void) { return g_startSeconds; } int IOT_ScheduleGetDurationTime(void) { return g_durationSeconds; } int IOT_ScheduleGetCommand(int *cmd, int *value) { if (cmd != NULL) { *cmd = g_cmd.cmd; } if (value != NULL) { *value = g_cmd.value; } return 0; } void IOT_ScheduleDeinit(void) { for (int i = 0; i < MAX_SCHEDULE_LIST; i++) { if (gScheduleList[i] != NULL) { ScheduleListDestroy(gScheduleList[i]); gScheduleList[i] = NULL; } } }