doubao_chat/lib/net/libduer-device/examples/dcs3.0-demo/duerapp_alarm.c

289 lines
7.8 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdlib.h>
#include <string.h>
#include "duerapp_media.h"
#include "duerapp_alarm.h"
#include "duerapp_config.h"
#include "lightduer_net_ntp.h"
#include "lightduer_types.h"
#include "lightduer_dcs.h"
#include "lightduer_dcs_alert.h"
#include "lightduer_memory.h"
#include "system/time.h"
#include "lightduer_mutex.h"
#include "asm/rtc.h"
enum {
DUER_TIMER = 0,
DUER_ALARM,
};
static duerapp_alarm_node alarms[DUER_MAX_ALARM_NUM];
static duer_mutex_t duer_alarm_mutex;
static bool s_is_bell = false;
static char *s_ring_path = NULL;
static void duer_alarm_callback(void *param)
{
duerapp_alarm_node *node = (duerapp_alarm_node *)param;
if (node->del_flag) {
return;
}
node->del_flag = 1;
DUER_LOGI("alarm started: token: %s\n", node->token);
duer_dcs_report_alert_event(node->token, ALERT_START);
if (node->url) {
/* duer_media_audio_pause(); */
/* duer_media_alarm_play(node->url); */
/* s_is_bell = true; */
}
duer_mutex_lock(duer_alarm_mutex);
duer_timer_release(node->handle);
node->handle = NULL;
DUER_FREE(node->token);
node->token = NULL;
DUER_FREE(node->time);
node->time = NULL;
if (node->url) {
DUER_FREE(node->url);
node->url = NULL;
}
node->id = -1;
duer_mutex_unlock(duer_alarm_mutex);
}
void duer_dcs_alert_set_handler(const duer_dcs_alert_info_type *alert_info)
{
size_t len = 0;
int i = 0;
int ret = 0;
u32 time = 0;
duerapp_alarm_node *empty_alarm = NULL;
DuerTime cur_time;
struct sys_time rtc_time;
size_t delay = 0;
duer_mutex_lock(duer_alarm_mutex);
for (i = 0; i < sizeof(alarms) / sizeof(alarms[0]); i++) {
if (alarms[i].token == NULL) {
empty_alarm = &alarms[i];
break;
}
}
if (empty_alarm == NULL) {
DUER_LOGE("Too many alarms\n");
goto error_out;
}
len = strlen(alert_info->token) + 1;
empty_alarm->token = DUER_MALLOC(len);
if (!empty_alarm->token) {
DUER_LOGI("alarm token no memory\n");
goto error_out;
}
snprintf(empty_alarm->token, len, "%s", alert_info->token);
len = strlen(alert_info->time) + 1;
empty_alarm->time = DUER_MALLOC(len);
if (!empty_alarm->time) {
DUER_LOGI("alarm time no memory\n");
goto error_out;
}
snprintf(empty_alarm->time, len, "%s", alert_info->time);
if (alert_info->url) {
len = strlen(alert_info->url) + 1;
empty_alarm->url = DUER_MALLOC(len);
if (!empty_alarm->url) {
DUER_LOGI("alarm url no memory\n");
goto error_out;
}
snprintf(empty_alarm->url, len, "%s", alert_info->url);
} else {
empty_alarm->url = NULL;
}
DUER_LOGI("set alarm: scheduled_time: %s, token: %s, type: %s, url: %s\n", alert_info->time, alert_info->token, alert_info->type, alert_info->url);
time = iso8601_to_mktime(alert_info->time);
ret = duer_ntp_client(NULL, 0, &cur_time, NULL);
if (ret < 0) {
DUER_LOGE("Failed to get NTP time\n");
//获取RTC时间,并转换为cur_time对应格式,赋值给cur_time
if (get_rtc_sys_time(&rtc_time)) {
DUER_LOGE("Failed to get rtc time\n");
goto error_out;
}
cur_time.sec = sys_time_to_mktime(&rtc_time);
cur_time.usec = 0;
}
if (time <= cur_time.sec) {
DUER_LOGE("The alarm is expired\n");
goto error_out;
}
delay = (time - cur_time.sec) * 1000 + cur_time.usec / 1000;
empty_alarm->handle = duer_timer_acquire(duer_alarm_callback, empty_alarm, DUER_TIMER_ONCE);
if (!empty_alarm->handle) {
DUER_LOGE("Failed to set alarm: failed to create timer\n");
goto error_out;
}
ret = duer_timer_start(empty_alarm->handle, delay);
if (ret != DUER_OK) {
DUER_LOGE("Failed to set alarm: failed to start timer\n");
goto error_out;
}
if (DUER_OK != duer_dcs_report_alert_event(alert_info->token, SET_ALERT_SUCCESS)) {
DUER_LOGE("Failed to report alert event\n");
duer_dcs_report_alert_event(alert_info->token, SET_ALERT_FAIL);
duer_timer_release(empty_alarm->handle);
empty_alarm->handle = NULL;
DUER_FREE(empty_alarm->token);
empty_alarm->token = NULL;
DUER_FREE(empty_alarm->time);
empty_alarm->time = NULL;
if (empty_alarm->url) {
DUER_FREE(empty_alarm->url);
empty_alarm->url = NULL;
}
duer_mutex_unlock(duer_alarm_mutex);
return;
}
empty_alarm->id = i;
empty_alarm->del_flag = 0;
empty_alarm->is_active = 0;
if (!strncmp(alert_info->type, "TIMER", 5)) {
empty_alarm->alarm_type = DUER_TIMER;
} else if (!strncmp(alert_info->type, "ALARM", 5)) {
empty_alarm->alarm_type = DUER_ALARM;
} else {
DUER_LOGE("NO this alarm type\n");
}
/*此处需要将闹钟信息保存在VM里*/
duer_mutex_unlock(duer_alarm_mutex);
return;
error_out:
duer_dcs_report_alert_event(alert_info->token, SET_ALERT_FAIL);
if (empty_alarm->token) {
DUER_FREE(empty_alarm->token);
empty_alarm->token = NULL;
}
if (empty_alarm->time) {
DUER_FREE(empty_alarm->time);
empty_alarm->time = NULL;
}
if (empty_alarm->url) {
DUER_FREE(empty_alarm->url);
empty_alarm->url = NULL;
}
duer_mutex_unlock(duer_alarm_mutex);
}
void duer_dcs_alert_delete_handler(const char *token)
{
int i = 0;
volatile duerapp_alarm_node *target_alarm = NULL;
DUER_LOGI("delete alarm: token %s", token);
duer_mutex_lock(duer_alarm_mutex);
for (i = 0; i < sizeof(alarms) / sizeof(alarms[0]); i++) {
if (alarms[i].token) {
if (strcmp(alarms[i].token, token) == 0) {
target_alarm = &alarms[i];
break;
}
}
}
if (!target_alarm) {
duer_mutex_unlock(duer_alarm_mutex);
DUER_LOGE("Cannot find the target alarm\n");
duer_dcs_report_alert_event(token, DELETE_ALERT_FAIL);
return;
}
if (!target_alarm->del_flag) {
target_alarm->del_flag = 1;
duer_timer_release(target_alarm->handle);
target_alarm->handle = NULL;
DUER_FREE(target_alarm->token);
target_alarm->token = NULL;
DUER_FREE(target_alarm->time);
target_alarm->time = NULL;
if (target_alarm->url) {
DUER_FREE(target_alarm->url);
target_alarm->url = NULL;
}
target_alarm->id = -1;
}
duer_mutex_unlock(duer_alarm_mutex);
duer_dcs_report_alert_event(token, DELETE_ALERT_SUCCESS);
}
void duer_init_alarm()
{
memset(alarms, 0, sizeof(alarms));
if (!duer_alarm_mutex) {
duer_alarm_mutex = duer_mutex_create();
if (!duer_alarm_mutex) {
DUER_LOGE("duer_alarm_mutex create error\n");
}
}
//开机读取VM,保存在alarm数组里,重新设置定时器?
}
void duer_dcs_get_all_alert(baidu_json *alert_array)
{
int i;
duerapp_alarm_node *empty_alarm = NULL;
duer_dcs_alert_info_type alert_info;
u8 is_active = false;
duer_mutex_lock(duer_alarm_mutex);
for (i = 0; i < sizeof(alarms) / sizeof(alarms[0]); i++) {
if (alarms[i].token) {
empty_alarm = &alarms[i];
alert_info.token = empty_alarm->token;
alert_info.type = empty_alarm->alarm_type ? "ALARM" : "TIMER";
alert_info.time = empty_alarm->time;
is_active = empty_alarm->is_active;
duer_insert_alert_list(alert_array, &alert_info, is_active);
}
}
duer_mutex_unlock(duer_alarm_mutex);
}
bool duer_alert_bell()
{
return s_is_bell;
}
void duer_alert_stop()
{
if (s_is_bell) {
duer_media_alarm_stop();
} else {
DUER_LOGD("Now the alert is not ringing.");
}
}