499 lines
14 KiB
C
499 lines
14 KiB
C
#include "server/ai_server.h"
|
|
#include "system/database.h"
|
|
#include "dui.h"
|
|
#include "iot.h"
|
|
#ifdef DUI_MEMHEAP_DEBUG
|
|
#include "mem_leak_test.h"
|
|
#endif
|
|
#include "syscfg/syscfg_id.h"
|
|
|
|
static volatile u8 msg_notify_disable;
|
|
static u8 dui_app_init_flag = 0;
|
|
static int dui_app_task_pid;
|
|
static u8 s_is_record = false;
|
|
static u8 record_break_flag;
|
|
static u32 record_sessionid; //当次录音的id,用于快速丢弃数据
|
|
static media_item_t item = {0};
|
|
static u8 play_status = STOP;
|
|
static u8 play_mode = LOOPPLAY_MODE;
|
|
static enum media_source_type source_type = 0xff;
|
|
static char dui_net_cfg_uid[64];
|
|
|
|
static struct dui_var dui_hdl;
|
|
#define __this (&dui_hdl)
|
|
|
|
|
|
extern void sys_power_shutdown(void);
|
|
extern unsigned int random32(int type);
|
|
|
|
media_item_t *get_media_item(void)
|
|
{
|
|
return &item;
|
|
}
|
|
|
|
u8 get_s_is_record(void)
|
|
{
|
|
return s_is_record;
|
|
}
|
|
|
|
u8 get_record_break_flag(void)
|
|
{
|
|
return record_break_flag;
|
|
}
|
|
|
|
void set_record_break_flag(u8 value)
|
|
{
|
|
record_break_flag = value;
|
|
}
|
|
|
|
const char *dui_get_net_cfg_uid(void)
|
|
{
|
|
memset(dui_net_cfg_uid, 0x00, sizeof(dui_net_cfg_uid));
|
|
/* db_select_buffer(VM_USER_ID_INDEX, (char *)dui_net_cfg_uid, sizeof(dui_net_cfg_uid)); */
|
|
syscfg_read(VM_USER_ID_INDEX, (char *)dui_net_cfg_uid, sizeof(dui_net_cfg_uid));
|
|
printf("\n\nget uid = %s\n\n", dui_net_cfg_uid);
|
|
return dui_net_cfg_uid[0] != 0 ? dui_net_cfg_uid : NULL;
|
|
}
|
|
|
|
void dui_set_net_cfg_uid(const char *uid)
|
|
{
|
|
memset(dui_net_cfg_uid, 0x00, sizeof(dui_net_cfg_uid));
|
|
memcpy(dui_net_cfg_uid, uid, strlen(uid) + 1);
|
|
printf("\n\nset uid = %s\n\n", uid);
|
|
/* db_update_buffer(VM_USER_ID_INDEX, (char *)dui_net_cfg_uid, sizeof(dui_net_cfg_uid)); */
|
|
syscfg_write(VM_USER_ID_INDEX, (char *)dui_net_cfg_uid, sizeof(dui_net_cfg_uid));
|
|
}
|
|
|
|
const char *dui_get_userid(void)
|
|
{
|
|
memset(dui_net_cfg_uid, 0x00, sizeof(dui_net_cfg_uid));
|
|
/* db_select_buffer(VM_USER_ID_INDEX, (char *)dui_net_cfg_uid, sizeof(dui_net_cfg_uid)); */
|
|
syscfg_read(VM_USER_ID_INDEX, (char *)dui_net_cfg_uid, sizeof(dui_net_cfg_uid));
|
|
char *str = strchr(dui_net_cfg_uid, '_');
|
|
if (!str) {
|
|
return NULL;
|
|
}
|
|
dui_net_cfg_uid[str - dui_net_cfg_uid] = 0;
|
|
/* printf("\n\nget user uid = %s\n\n", dui_net_cfg_uid); */
|
|
return dui_net_cfg_uid[0] != 0 ? dui_net_cfg_uid : NULL;
|
|
}
|
|
|
|
const char *dui_get_device_id(void)
|
|
{
|
|
struct dui_para *para = &__this->para;
|
|
return para->param.deviceID;
|
|
}
|
|
|
|
const char *dui_get_version(void)
|
|
{
|
|
return "V1.3.0";
|
|
}
|
|
|
|
const char *dui_get_product_code(void)
|
|
{
|
|
return "01f";
|
|
}
|
|
|
|
const char *dui_get_product_id(void)
|
|
{
|
|
return "001b";
|
|
}
|
|
|
|
const char *dui_get_product_data(void)
|
|
{
|
|
return "20200320";
|
|
}
|
|
|
|
const int dui_media_get_playing_status(void)
|
|
{
|
|
return play_status;
|
|
}
|
|
|
|
void dui_media_set_playing_status(int value)
|
|
{
|
|
play_status = value;
|
|
if (item.linkUrl) {
|
|
iot_ctl_state(&item);
|
|
}
|
|
}
|
|
|
|
void dui_media_music_mode_set(int mode)
|
|
{
|
|
play_mode = mode;
|
|
}
|
|
|
|
int dui_media_music_mode_get(void)
|
|
{
|
|
return play_mode;
|
|
}
|
|
|
|
void dui_media_set_source(enum media_source_type type)
|
|
{
|
|
source_type = type;
|
|
}
|
|
|
|
enum media_source_type dui_media_get_source(void)
|
|
{
|
|
return source_type;
|
|
}
|
|
|
|
void dui_ai_media_audio_play(const char *url)
|
|
{
|
|
struct dui_para *para = &__this->para;
|
|
strcpy(para->reply.url, url);
|
|
dui_media_set_source(MEDIA_SOURCE_AI);
|
|
dui_media_audio_play(para->reply.url);
|
|
}
|
|
|
|
void dui_iot_media_audio_play(const char *url)
|
|
{
|
|
struct dui_para *para = &__this->para;
|
|
strcpy(para->reply.url, url);
|
|
dui_media_set_source(MEDIA_SOURCE_IOT);
|
|
dui_media_audio_play(para->reply.url);
|
|
}
|
|
|
|
int dui_net_music_play_prev(void)
|
|
{
|
|
if (dui_media_get_source() == MEDIA_SOURCE_IOT) {
|
|
return iot_ctl_play_prev();
|
|
} else if (dui_media_get_source() == MEDIA_SOURCE_AI) {
|
|
int play_list_match = get_play_list_match();
|
|
int play_list_max = get_play_list_max();
|
|
play_list_match = play_list_match == 0 ? (play_list_max - 1) : --play_list_match;
|
|
set_play_list_match(play_list_match);
|
|
dui_play_playlist_for_match(&item, play_list_match);
|
|
if (item.linkUrl) {
|
|
dui_ai_media_audio_play(item.linkUrl);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int dui_net_music_play_next(void)
|
|
{
|
|
if (dui_media_get_source() == MEDIA_SOURCE_IOT) {
|
|
return iot_ctl_play_next();
|
|
} else if (dui_media_get_source() == MEDIA_SOURCE_AI) {
|
|
int play_list_match = get_play_list_match();
|
|
int play_list_max = get_play_list_max();
|
|
play_list_match = play_list_match == (play_list_max - 1) ? 0 : ++play_list_match;
|
|
set_play_list_match(play_list_match);
|
|
dui_play_playlist_for_match(&item, play_list_match);
|
|
if (item.linkUrl) {
|
|
dui_ai_media_audio_play(item.linkUrl);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
media_item_t *dui_get_ai_music_item(void)
|
|
{
|
|
return &item;
|
|
}
|
|
|
|
void dui_shutdown(void *priv)
|
|
{
|
|
sys_power_shutdown();
|
|
}
|
|
|
|
u32 get_record_sessionid(void)
|
|
{
|
|
return record_sessionid;//每次启动录音都会增加
|
|
}
|
|
|
|
struct dui_var *get_dui_hdl(void)
|
|
{
|
|
return __this;
|
|
}
|
|
|
|
extern const char *get_dui_auth_product_key(void);
|
|
extern const char *get_dui_auth_product_id(void);
|
|
extern const char *get_dui_auth_product_secret(void);
|
|
extern const char *get_dui_auth_deviceid(void);
|
|
|
|
static void init_dui_para(struct dui_para *para)
|
|
{
|
|
//使用白名单
|
|
#if 1
|
|
strcpy(para->param.productKey, get_dui_auth_product_key());
|
|
strcpy(para->param.productId, get_dui_auth_product_id());
|
|
strcpy(para->param.ProductSecret, get_dui_auth_product_secret());
|
|
strcpy(para->param.deviceID, get_dui_auth_deviceid());
|
|
//不使用白名单
|
|
#else
|
|
strcpy(para->param.productKey, "58f1aeeb54fadab27a6ce70fd222ec46");
|
|
strcpy(para->param.productId, "279594353");
|
|
strcpy(para->param.ProductSecret, "89249b0fb48d7c12454a079fc97aee72");
|
|
|
|
u8 mac_addr[6];
|
|
extern int wifi_get_mac(u8 * mac);
|
|
wifi_get_mac(mac_addr);
|
|
/*DUI deviceID格式*/
|
|
sprintf(para->param.deviceID, "00000%s%s%s%02X%02X%02X%02X%02X%02X",
|
|
dui_get_product_id(),
|
|
dui_get_product_code(),
|
|
dui_get_product_data(),
|
|
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
|
|
#endif
|
|
}
|
|
|
|
static void dui_app_task(void *priv)
|
|
{
|
|
int err;
|
|
int msg[32];
|
|
struct dui_var *p = (struct dui_var *)priv;
|
|
struct dui_para *para = &p->para;
|
|
|
|
u32 delay_ms = 1000;
|
|
u8 dly_cnt = 0;
|
|
u8 retry = 5;
|
|
|
|
init_dui_para(para);
|
|
|
|
while (retry > 0 && !__this->exit_flag) {
|
|
if (dly_cnt--) {
|
|
os_time_dly(10);
|
|
continue;
|
|
}
|
|
err = get_dui_token(para);
|
|
if (!err) {
|
|
break;
|
|
}
|
|
--retry;
|
|
delay_ms <<= 1;
|
|
dly_cnt = delay_ms / 100;
|
|
};
|
|
|
|
if (err || __this->exit_flag) {
|
|
goto exit;
|
|
}
|
|
|
|
iot_mgr_init(dui_get_device_id());
|
|
dui_net_thread_run(para);
|
|
|
|
while (1) {
|
|
err = os_taskq_pend("taskq", msg, ARRAY_SIZE(msg));
|
|
if (err != OS_TASKQ || msg[0] != Q_USER) {
|
|
continue;
|
|
}
|
|
|
|
//统一在这里给网络线程发消息
|
|
switch (msg[1]) {
|
|
case DUI_SPEAK_END:
|
|
puts("===========DUI_SPEAK_END\n");
|
|
//播放完提示音,判断是不是需要重新启动录音
|
|
|
|
u8 get_alarm_ring_flag(void);
|
|
void set_alarm_ring_flag(u8 value);
|
|
if (get_alarm_ring_flag()) {
|
|
set_alarm_ring_flag(0);
|
|
u8 get_alarm_type(void);
|
|
if (get_alarm_type() == ALARM_CLOCK_TYPE) {
|
|
dui_event_notify(AI_SERVER_EVENT_PLAY_BEEP, "reminder.mp3");
|
|
} else {
|
|
dui_event_notify(AI_SERVER_EVENT_PLAY_BEEP, "schedule.mp3");
|
|
}
|
|
break;
|
|
}
|
|
if (get_reopen_record()) {
|
|
DUI_OS_TASKQ_POST("dui_app_task", 1, DUI_RECORD_START);
|
|
break;
|
|
}
|
|
if (para->reply.url[0]) {
|
|
dui_media_audio_play(para->reply.url);
|
|
para->reply.url[0] = 0;
|
|
} else {
|
|
dui_media_audio_resume_play();
|
|
}
|
|
break;
|
|
case DUI_SPEAK_START:
|
|
break;
|
|
case DUI_RECORD_START:
|
|
puts("===========DUI_SPEAK_START\n");
|
|
if (!s_is_record) {
|
|
DUI_OS_TASKQ_POST("dui_net_task", 1, DUI_RECORD_START_MSG);
|
|
__this->voice_mode = msg[2] & 0x3;
|
|
p->use_vad = (msg[2] & VAD_ENABLE) ? 1 : 0;
|
|
record_sessionid++;
|
|
set_record_break_flag(0);
|
|
set_reopen_record(0);
|
|
dui_recorder_start(16000, msg[2], p->use_vad);
|
|
s_is_record = true;
|
|
msg_notify_disable = 1;
|
|
}
|
|
break;
|
|
case DUI_RECORD_SEND:
|
|
puts("===========DUI_SPEAK_SEND\n");
|
|
DUI_OS_TASKQ_POST("dui_net_task", 1, DUI_RECORD_SEND_MSG); //消息转发
|
|
break;
|
|
case DUI_RECORD_STOP:
|
|
puts("===========DUI_SPEAK_STOP\n");
|
|
if (s_is_record) {
|
|
int dui_recorder_stop(u8 voice_mode);
|
|
dui_recorder_stop(0);
|
|
s_is_record = false;
|
|
msg_notify_disable = 0;
|
|
DUI_OS_TASKQ_POST("dui_net_task", 1, DUI_RECORD_STOP_MSG);
|
|
}
|
|
break;
|
|
case DUI_RECORD_BREAK:
|
|
printf("\n DUI_RECORD_BREAK\n");
|
|
set_record_break_flag(1);
|
|
if (s_is_record) {
|
|
int dui_recorder_stop(u8 voice_mode);
|
|
dui_recorder_stop(0);
|
|
s_is_record = false;
|
|
msg_notify_disable = 0;
|
|
DUI_OS_TASKQ_POST("dui_net_task", 1, DUI_RECORD_STOP_MSG);
|
|
}
|
|
if (msg[2] && msg[3]) {
|
|
DUI_OS_TASKQ_POST("dui_net_task", 3, msg[2], msg[3], msg[4]);
|
|
}
|
|
break;
|
|
case DUI_RECORD_ERR:
|
|
if (s_is_record) {
|
|
dui_recorder_stop(__this->voice_mode);
|
|
s_is_record = false;
|
|
msg_notify_disable = 0;
|
|
DUI_OS_TASKQ_POST("dui_net_task", 1, DUI_RECORD_STOP_MSG);
|
|
}
|
|
break;
|
|
case DUI_PREVIOUS_SONG:
|
|
dui_net_music_play_prev();
|
|
break;
|
|
case DUI_NEXT_SONG:
|
|
dui_net_music_play_next();
|
|
break;
|
|
case DUI_MEDIA_END:
|
|
puts("\nDUI_MEDIA_END\n");
|
|
dui_media_set_playing_status(STOP);
|
|
if (dui_media_get_source() == MEDIA_SOURCE_AI) {
|
|
para->reply.url[0] = 0;
|
|
int mode = dui_media_music_mode_get();
|
|
int play_list_match = get_play_list_match();
|
|
int play_list_max = get_play_list_max();
|
|
printf("\nplay_list_max = %d\n", play_list_max);
|
|
if (mode == ORDERPLAY_MODE) {
|
|
play_list_match = play_list_match == (play_list_max - 1) ? (play_list_max) : ++play_list_match; //顺序播放,播放完停止播放
|
|
} else if (mode == LOOPPLAY_MODE) {
|
|
play_list_match = play_list_match == (play_list_max - 1) ? 0 : ++play_list_match; //循环播放,播放完重头开始
|
|
} else if (mode == RANDOMPLAY_MODE) {
|
|
play_list_match = random32(0) % (play_list_max);
|
|
}
|
|
set_play_list_match(play_list_match);
|
|
dui_play_playlist_for_match(&item, play_list_match);
|
|
if (item.linkUrl[0] != 0) {
|
|
dui_ai_media_audio_play(item.linkUrl);
|
|
}
|
|
} else if (dui_media_get_source() == MEDIA_SOURCE_IOT) {
|
|
iot_ctl_play_done();
|
|
}
|
|
break;
|
|
case DUI_MEDIA_STOP:
|
|
puts("\nDUI_MEDIA_STOP\n");
|
|
dui_media_set_playing_status(STOP);
|
|
para->reply.url[0] = 0;
|
|
break;
|
|
case DUI_MEDIA_START:
|
|
dui_media_set_playing_status(PLAY);
|
|
puts("\nDUI_MEDIA_START\n");
|
|
if (dui_media_get_source() == MEDIA_SOURCE_AI) {
|
|
int play_list_match = get_play_list_match();
|
|
dui_play_playlist_for_match(&item, play_list_match);
|
|
if (item.linkUrl) {
|
|
iot_ctl_play_dui(&item);
|
|
}
|
|
} else {
|
|
dui_media_music_item(&item);
|
|
}
|
|
item.duration = get_app_music_total_time();
|
|
break;
|
|
case DUI_PLAY_PAUSE:
|
|
if (play_status == PLAY) {
|
|
|
|
if (dui_media_get_source() == MEDIA_SOURCE_IOT) {
|
|
iot_ctl_play_pause();
|
|
}
|
|
|
|
dui_media_set_playing_status(PAUSE);
|
|
|
|
} else if (play_status == PAUSE) {
|
|
if (dui_media_get_source() == MEDIA_SOURCE_IOT) {
|
|
iot_ctl_play_resume();
|
|
}
|
|
dui_media_set_playing_status(PLAY);
|
|
|
|
}
|
|
break;
|
|
case DUI_QUIT:
|
|
if (s_is_record) {
|
|
dui_recorder_stop(0);
|
|
s_is_record = false;
|
|
DUI_OS_TASKQ_POST("dui_net_task", 1, DUI_RECORD_STOP_MSG);
|
|
}
|
|
DUI_OS_TASKQ_POST("dui_net_task", 1, DUI_QUIT_MSG);
|
|
iot_mgr_deinit();
|
|
dui_net_thread_kill();
|
|
goto exit;
|
|
break;
|
|
case DUI_VOLUME_CHANGE:
|
|
iot_ctl_play_volume(msg[2]);
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
exit:
|
|
printf("\n %s exit \n", __func__);
|
|
}
|
|
|
|
u8 dui_app_get_connect_status(void)
|
|
{
|
|
struct dui_para *para = &__this->para;
|
|
return para->hdl.connect_status;
|
|
}
|
|
|
|
u8 get_dui_msg_notify(void)
|
|
{
|
|
return msg_notify_disable;
|
|
}
|
|
|
|
void set_dui_msg_notify(u8 value)
|
|
{
|
|
msg_notify_disable = value;
|
|
}
|
|
|
|
int dui_app_init(void)
|
|
{
|
|
struct dui_para *para = &__this->para;
|
|
if (!dui_app_init_flag) {
|
|
dui_app_init_flag = 1;
|
|
__this->exit_flag = 0;
|
|
msg_notify_disable = 0;
|
|
para->hdl.connect_status = 0;
|
|
return thread_fork("dui_app_task", 15, 1536, 256, &dui_app_task_pid, dui_app_task, __this);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void dui_app_uninit(void)
|
|
{
|
|
struct dui_para *para = &__this->para;
|
|
if (dui_app_init_flag) {
|
|
dui_app_init_flag = 0;
|
|
para->hdl.connect_status = 0;
|
|
para->reply.sessionId[0] = 0;
|
|
__this->exit_flag = 1;
|
|
do {
|
|
if (OS_Q_FULL != os_taskq_post("dui_app_task", 1, DUI_QUIT)) {
|
|
break;
|
|
}
|
|
log_e("dui_app_task send msg QUIT timeout \n");
|
|
os_time_dly(5);
|
|
} while (1);
|
|
thread_kill(&dui_app_task_pid, KILL_WAIT);
|
|
}
|
|
}
|
|
|