From a4000c40affbd02ed82b305c1a9062bfa716bbca Mon Sep 17 00:00:00 2001 From: "cheng.chen" Date: Wed, 10 Jun 2026 10:59:57 +0800 Subject: [PATCH] =?utf8?q?=E4=BA=91=E4=B8=8A=E9=87=91=E6=97=B6=E6=B9=BE?= =?utf8?q?=E5=85=94=E5=9B=BA=E4=BB=B6=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- 2.code/aicos/app/AI_AMP_2_5/AI_AMP_2_5.c | 4197 ++++++++--------- 2.code/aicos/app/AI_AMP_2_5/AI_AMP_2_5.h | 35 +- 2.code/aicos/app/AI_AMP_2_5/CMakeLists.txt | 4 +- 2.code/aicos/app/AI_AMP_2_5/bk_key.c | 75 +- 2.code/aicos/app/AI_AMP_2_5/bk_opus_coder.c | 22 +- 2.code/aicos/app/AI_AMP_2_5/bk_opus_coder.h | 1 + 2.code/aicos/app/AI_AMP_2_5/bk_websocket.c | 1005 ++-- 2.code/aicos/app/AI_AMP_2_5/bk_websocket.h | 9 +- .../aicos/app/AI_AMP_2_5/dev_authentication.c | 164 +- .../aicos/app/AI_AMP_2_5/dev_authentication.h | 1 - 2.code/aicos/app/AI_AMP_2_5/imsl_kws.h | 28 +- 2.code/aicos/app/AI_AMP_2_5/imsl_vad.h | 4 +- 2.code/aicos/app/AI_AMP_2_5/libimslkws.a | Bin 260630 -> 260554 bytes 2.code/aicos/app/AI_AMP_2_5/libimslnn.a | Bin 404694 -> 404254 bytes 2.code/aicos/app/AI_AMP_2_5/libimslvad.a | Bin 143728 -> 143624 bytes 15 files changed, 2711 insertions(+), 2834 deletions(-) diff --git a/2.code/aicos/app/AI_AMP_2_5/AI_AMP_2_5.c b/2.code/aicos/app/AI_AMP_2_5/AI_AMP_2_5.c index 3c233c4..5b6ed86 100644 --- a/2.code/aicos/app/AI_AMP_2_5/AI_AMP_2_5.c +++ b/2.code/aicos/app/AI_AMP_2_5/AI_AMP_2_5.c @@ -35,19 +35,15 @@ #include "app_msg.h" #include "aic_ogg.h" #include "efuse.h" -#if SUPPORT_MOT -#include "mot_dev.h" -#endif -#include "bk_make_time.h" -static aos_thread_id UI_UART_read_id = 0; +#include + +// #include "bk_make_time.h" // #include "opus/include/opus.h" char FXH01_Version[100]; u8 current_card_id = 0; - -u8 chumo_exp_open = 1; u8 VC_TTS_PLAY_EVENT = 0; typedef enum { @@ -56,6 +52,10 @@ typedef enum }attributes_format_type; attributes_format_type inbound_attributes_format = attributes_format_PCM; attributes_format_type outbound_attributes_format = attributes_format_OPUS; + + +u8 codec_tts=1;//1 opus 2 ogg + #define OPUS_ENCODER_PACK_MS 60 //多少ms一帧数据 @@ -65,7 +65,7 @@ volatile char AI_VC_stata = 0;//VC是否在运行 volatile char app_audio_flag = 0; volatile char audio_stop_flag = 0; int32_t bk_audio_start_callback(void *p_param, uint32_t size); -#define IS_KWS 1 +#define IS_KWS 0 #define IS_VAD 1 #define VAD_RB_LEN 32*1024 @@ -84,7 +84,6 @@ static u32* ai_uart_handle; static u32* ui_uart_handle=NULL; -static u8 is_dialog_status=0; static aos_thread_id AI_VC_send_task_id = 0; char AI_VC_send_task_flag = 0; @@ -92,6 +91,8 @@ static aos_thread_id AI_VC_read_task_id = 0; static aos_thread_id AI_VC_read_IOT_id = 0; +static aos_thread_id UI_UART_read_id = 0; + volatile char AI_VC_read_task_flag = 0; static aos_queue_ptr AI_VC_send_queue = NULL; static aos_thread_id AI_VC_play_task_id = 0; @@ -117,25 +118,27 @@ WebSocketClient *AI_client_VC = NULL; WebSocketClient *AI_client_IOT = NULL; - static u8 issend_start_up=0; -static u8 random_mt_test=0; +//static u8 issend_start_up=0; -static u32 close_timerout = 0; + static u8 is_music_status=0; + + static u8 need_play_is_music_status=0; -static u32 sleep_chumo_timerout = 0; + static u8 need_express_cmd=0; -static u32 tts_start_timerout = 0; +static u8 is_newsession=true; +static u8 delay_welcome=0; + +static u32 close_timerout = 0; static u32 VC_pingping_timerout = 0; static u32 VC_END_play_timerout = 0; static char *AI_TTS_str = NULL; static char *AI_ASR_str = NULL; #define AI_ASR_STR_MAX_LEN 1024*2 static char *AI_ASR_str_tmp = NULL; - -static int has_tmp_result=0; #define AI_ASR_STR_MAX_TMP_LEN 1024 static aos_timer_ptr AI_VC_1S_timer = NULL; @@ -143,10 +146,10 @@ static aos_timer_ptr sys_10S_timer = NULL; static aos_timer_ptr AI_VC_60S_timer = NULL; - //static aos_timer_ptr AI_VC_60S_timer = NULL; - static int login_timer_count = 0; -static int power_off_count = 60*6*24; +static int power_off_count = 60*60*24; + +u8 is_need_tip=0; static void play_file_stop(void); @@ -158,8 +161,6 @@ VC_state_type VC_state = VC_State_None; static u8 uid[50]; static int uid_len =0; -//int type_test=1; - //关闭录音 void VC_record_End(void); //打开录音 @@ -176,6 +177,8 @@ void VC_Play_End(void); //打开音频播放 void VC_Play_Start(void); + + int bk_get_imei(char *imei) { if(imei == NULL) @@ -193,6 +196,8 @@ int bk_get_iccid(char *iccid) } + + #if (BK_LOG_CFG==BK_LOG_UART) int bk_printf(const char *format, ...) { @@ -331,27 +336,31 @@ void reset_VC_cfg(void) //vc_cfg.dev_type = DEV_FX1_H;//产品 //vc_cfg.dev_type = DEV_ADS;//奥德赛 vc_cfg.dev_type = DEV_JSWM;//金山完美 - //vc_cfg.dev_type = DEV_ALY;//阿里云 + // vc_cfg.dev_type = DEV_ALY;//阿里云 - strcpy(vc_cfg.server_ip,"amp.raisound.com");//服务器地址 + strcpy(vc_cfg.server_ip,"amp.raisound.com");//服务器地址 - // strcpy(vc_cfg.server_ip,"115.190.94.208:22080");//服务器地址 + // strcpy(vc_cfg.server_ip,"118.145.158.207:22080");//服务器地址 + + // ws://118.145.159.222:30700 - // strcpy(vc_cfg.server_ip,"118.145.158.207:22080");//服务器地址 + // strcpy(vc_cfg.server_ip,"115.190.94.208:22080");//服务器地址 - vc_cfg.VC_mode =2; //对话模式 + vc_cfg.VC_mode =2;//对话模式 strcpy(vc_cfg.power_on_tone,"你好,请问您有什么需要我帮忙的吗?");//开机提示词 vc_cfg.VC_record_TYPE = VC_record_TYPE_PCM;//录音格式 vc_cfg.VC_play_TYPE = VC_play_TYPE_PCM;//播放格式 vc_cfg.VC_record_samplerate = 16000;//录音采样率 vc_cfg.VC_play_samplerate = 16000;//播放采样率 - vc_cfg.is_VAD = IS_VAD; //=1打开vad打断 - vc_cfg.is_KWS = IS_KWS; //=1打开本地语言打断 - vc_cfg.speech_rate = 0; //语速配置 - vc_cfg.vad_silence = 800; //vad断句时间 ms 500 - vc_cfg.VC_TTS_volume = 80; //音量 -} + vc_cfg.is_VAD = IS_VAD;//=1打开vad打断 + vc_cfg.is_KWS = IS_KWS;//=1打开本地语言打断 + vc_cfg.speech_rate = 0;//语速配置 + vc_cfg.vad_silence = 800;//vad断句时间 ms + vc_cfg.VC_TTS_volume = 80;//音量 + + vc_cfg.alarm_count=0; +} int init_VC_cfg(void) { FILE *fp = NULL; @@ -366,6 +375,7 @@ int init_VC_cfg(void) // } reset_VC_cfg(); + if(fp) { int fread_len ; @@ -392,6 +402,8 @@ int init_VC_cfg(void) vc_cfg.VC_mode =2;//对话模式 reset_VC_cfg(); + // strcpy(vc_cfg.server_ip,"118.145.158.207:22080");//服务器地址 + return 0; } @@ -425,192 +437,396 @@ int startsave_tts=0; FILE *fp_tts_save = NULL; -u8 recv_get[1024]; +u8 recv_get[1024*6]; static int play_audio_file_event(char *file_name); u8 *save_temp_tts=NULL; -int is_guanji=0; - -int ddh_is_close_dialog=0; - -void aic_https_demotest(); - -int check_text(char *text,int ret_str_len) -{ - //bk_printf("check_text:text:%s",text); +void send_express_str(char *exp_str){ - if(ret_str_len >60) - return -1; - int ret = -1; - unsigned char is_save_VC_cfg = 0; - char tmp_data[70] = {0}; - int tmp_data_len = 0; - if(strstr(text,"声音改")) - { - if(strstr(text,"男")) - { - - } - } - - if(strstr(text,"音量查询") || strstr(text,"查询音量")) - { - - tmp_data_len = snprintf(tmp_data,sizeof(tmp_data),"查询成功,当前音量%d。",vc_cfg.VC_TTS_volume); - AI_AMP_MSG_put(tmp_data,tmp_data_len,VC_TTS_PLAY); - ret = 0; - goto RET; - } - // if(strstr(text,"加")||(strstr(text,"大")&&!strstr(text,"太")) || (strstr(text,"太小"))) - // { - // vc_cfg.VC_TTS_volume +=10; - // if(vc_cfg.VC_TTS_volume > 100) - // { - // vc_cfg.VC_TTS_volume = 100; - // AI_AMP_MSG_put("音量已最大。",strlen("音量已最大。"),VC_TTS_PLAY); - // //AI_TTS_str - // }else{ - - // tmp_data_len = snprintf(tmp_data,sizeof(tmp_data),"配置成功,当前音量%d。",vc_cfg.VC_TTS_volume); - // AI_AMP_MSG_put(tmp_data,tmp_data_len,VC_TTS_PLAY); - // } - // // if(vc_cfg.VC_mode != 0) - // app_audio_set_master_volume(15*vc_cfg.VC_TTS_volume/100); - // // else{ - - // // if(vc_cfg.VC_TTS_volume > 80) - // // { - - // // app_audio_set_master_volume(15*50/100); - // // }else{ - - // // app_audio_set_master_volume(15*vc_cfg.VC_TTS_volume/100); - // // } - // // } - - - // is_save_VC_cfg = 1; - // ret = 0; - // goto RET; - // }else if(strstr(text,"减")||(strstr(text,"小")&&!strstr(text,"太")) || (strstr(text,"太大"))) - // { - // vc_cfg.VC_TTS_volume -=10; - // if(vc_cfg.VC_TTS_volume < 0) - // { - // vc_cfg.VC_TTS_volume = 0; - // AI_AMP_MSG_put("音量已最小。",strlen("音量已最小。"),VC_TTS_PLAY); - // //AI_TTS_str - // }else{ - - // tmp_data_len = snprintf(tmp_data,sizeof(tmp_data),"配置成功,当前音量%d。",vc_cfg.VC_TTS_volume); - // AI_AMP_MSG_put(tmp_data,tmp_data_len,VC_TTS_PLAY); - // } - - // // if(vc_cfg.VC_mode != 0) - // app_audio_set_master_volume(15*vc_cfg.VC_TTS_volume/100); - // // else{ - - // // if(vc_cfg.VC_TTS_volume > 80) - // // { - - // // app_audio_set_master_volume(15*50/100); - // // }else{ - - // // app_audio_set_master_volume(15*vc_cfg.VC_TTS_volume/100); - // // } - // // } - - // is_save_VC_cfg = 1; - // ret = 0; - // goto RET; - // } - // } - - - if(strstr(text,"切换")) - { - if(strstr(text,"对话模式") || strstr(text,"兑换模式")) - { - vc_cfg.VC_mode+=1; - if(vc_cfg.VC_mode > 2) - vc_cfg.VC_mode = 0; - bk_printf("切换对话模式:vc_cfg.VC_mode :%d",vc_cfg.VC_mode ); - if(vc_cfg.VC_mode == 0) - { - AI_AMP_MSG_put("已切换到连续对话模式。",strlen("已切换到连续对话模式。"),VC_TTS_PLAY); - - app_audio_set_master_volume(15*80/100); - - }else if(vc_cfg.VC_mode == 1) - { - AI_AMP_MSG_put("已切换到单对话模式。长按按钮说话,说完松开即可。",strlen("已切换到单对话模式。长按按钮说话,说完松开即可。"),VC_TTS_PLAY); - - app_audio_set_master_volume(15*80/100); - }else - { + #if 0 + if(ui_uart_handle){ + u8 cmd_ui[7]={0xAA,0x55,0xFF,0x02,0x08,0x01,0x0a}; + + if(strstr(exp_str,"不理解")) + { + cmd_ui[4]=0x01; + cmd_ui[6]=0x03; + }else + if(strstr(exp_str,"发怒")) + { + cmd_ui[4]=0x02; + cmd_ui[6]=0x04; + }else + if(strstr(exp_str,"搞怪")) + { + cmd_ui[4]=0x03; + cmd_ui[6]=0x05; + }else + if(strstr(exp_str,"花痴")) + { + cmd_ui[4]=0x04; + cmd_ui[6]=0x05; + }else + if(strstr(exp_str,"惊喜")) + { + cmd_ui[4]=0x05; + cmd_ui[6]=0x07; + }else + if(strstr(exp_str,"惊讶")) + { + cmd_ui[4]=0x06; + cmd_ui[6]=0x08; + }else + if(strstr(exp_str,"卡通")) + { + cmd_ui[4]=0x07; + cmd_ui[6]=0x09; + }else + if(strstr(exp_str,"开心")||strstr(exp_str,"微笑")) + { + cmd_ui[4]=0x08; + cmd_ui[6]=0x0a; + }else + if(strstr(exp_str,"生气")) + { + cmd_ui[4]=0x09; + cmd_ui[6]=0x0b; + }else + if(strstr(exp_str,"眨眼")) + { + cmd_ui[4]=0x0a; + cmd_ui[6]=0x0c; + }else + if(strstr(exp_str,"很开心")) + { + cmd_ui[4]=0x0b; + cmd_ui[6]=0x0d; + }else + if(strstr(exp_str,"中立")) + { + cmd_ui[4]=0x0c; + cmd_ui[6]=0x0e; + } - app_audio_set_master_volume(15*80/100); - AI_AMP_MSG_put("已切换到按键打断模式。我说话的时候需要短按按钮打断。",strlen("已切换到按键打断模式。我说话的时候需要短按按钮打断。"),VC_TTS_PLAY); - } - is_save_VC_cfg = 1; - ret = 0; - #if BK_SOCKET_IOT - IOT_update_statu(3,"",""); - #endif - goto RET; + uart_write(ui_uart_handle,cmd_ui, 7); } - - } - - - // status - - if(strstr(text,"关闭显示屏")) - { + #else - bk_printf("关闭显示屏"); + // 淡定:Calm + // 尴尬:Embarrass + // 开心:Happy + // 可爱:Cute - aic_gpio_output(GPIO_15,GPIO_OUTPUT_LVL_LOW );//lcd open ldo - ret = 0; - goto RET; - } - if(strstr(text,"打开显示屏")) - { + + // 孝豚 + if(ui_uart_handle){ + u8 cmd_ui[7]={0xAA,0x55,0xFF,0x02,0x08,0x01,0x0a}; + + // if(strstr(exp_str,"Calm")) + // { + // cmd_ui[4]=0x01; + // cmd_ui[6]=0x03; + // }else + // if(strstr(exp_str,"Embarrass")) + // { + // cmd_ui[4]=0x02; + // cmd_ui[6]=0x04; + // }else + // if(strstr(exp_str,"Happy")) + // { + // cmd_ui[4]=0x03; + // cmd_ui[6]=0x05; + // }else + // if(strstr(exp_str,"Cute")) + // { + // cmd_ui[4]=0x04; + // cmd_ui[6]=0x06; + // } - bk_printf("打开显示屏"); + // 01-Afraid 害怕-右 +// 02-Amused 有趣-右 +// 03-Angry 愤怒-右 +// 04-Bored 无聊-右 +// 05-Caring 关爱-右 +// 06-Confused 困惑-右 +// 07-Curious 惊喜-右 +// 08-Disgusted 厌恶-右 +// 09-dizzy 蚊香眼-右 +// 10-Doubtful 存疑-右 +// 11-Frowning 皱眉头-右 +// 12-Grimacing 苦着脸-右 +// 13-Happy 开心-右 +// 14-Neutral 中立-右 +// 15-Pensive 悲伤-右 +// 16-Relaxed 放松-右 +// 17-Sad 伤心-右 +// 18-Smiling 微笑-右 +// 19-Surprised 惊讶-右 +// 20-Tired 疲惫-右 +// 21-Winking 眨眼-右 - aic_gpio_output(GPIO_15,GPIO_OUTPUT_LVL_HIGH );//lcd open ldo - ret = 0; - goto RET; - } +// 01-Afraid 害怕-右 01 +// 02-Amused 有趣-右 02 +// 03-Angry 愤怒-右 15 +// 04-Bored 无聊-右 16 +// 05-Caring 关爱-右 05 +// 06-Confused 困惑-右 17 +// 07-Curious 惊喜-右 19 +// 08-Disgusted 厌恶-右 20 +// 09-dizzy 蚊香眼-右 21 +// 10-Doubtful 存疑-右 18 +// 11-Frowning 皱眉头-右 03 +// 12-Grimacing 苦着脸-右 04 +// 13-Happy 开心-右 12 +// 14-Neutral 中立-右 06 +// 15-Pensive 悲伤-右 07 +// 16-Relaxed 放松-右 08 +// 17-Sad 伤心-右 09 +// 18-Smiling 微笑-右 10 +// 19-Surprised 惊讶-右 11 +// 20-Tired 疲惫-右 13 +// 21-Winking 眨眼-右 14 - if(strstr(text,"升级版本")) - { + bk_printf("send_express_str:text:%s",exp_str); - AI_AMP_MSG_put("开始升级版本,大概需要几分钟",strlen("开始升级版本,大概需要几分钟"),VC_TTS_PLAY); - ret = 0; - goto RET; + if(strstr(exp_str,"Afraid")||strstr(exp_str,"害怕")) + { + cmd_ui[4]=0x01; + cmd_ui[6]=0x03; + }else + if(strstr(exp_str,"Amused")||strstr(exp_str,"有趣")) + { + cmd_ui[4]=0x02; + cmd_ui[6]=0x04; + }else + if(strstr(exp_str,"Angry")||strstr(exp_str,"愤怒")) + { + cmd_ui[4]=0x03; + cmd_ui[6]=0x05; + }else + if(strstr(exp_str,"Bored")||strstr(exp_str,"无聊")) + { + cmd_ui[4]=0x04; + cmd_ui[6]=0x06; + }else + if(strstr(exp_str,"Caring")||strstr(exp_str,"关爱")) + { + cmd_ui[4]=0x05; + cmd_ui[6]=0x07; + }else + if(strstr(exp_str,"Confused")||strstr(exp_str,"困惑")) + { + cmd_ui[4]=0x06; + cmd_ui[6]=0x08; + }else + if(strstr(exp_str,"Curious")||strstr(exp_str,"惊喜")) + { + cmd_ui[4]=0x07; + cmd_ui[6]=0x09; + }else + if(strstr(exp_str,"Disgusted")||strstr(exp_str,"厌恶")) + { + cmd_ui[4]=0x08; + cmd_ui[6]=0x0a; + }else + if(strstr(exp_str,"dizzy")||strstr(exp_str,"蚊香眼")) + { + cmd_ui[4]=0x09; + cmd_ui[6]=0x0b; + }else + if(strstr(exp_str,"Doubtful")||strstr(exp_str,"存疑")) + { + cmd_ui[4]=0x0a; + cmd_ui[6]=0x0c; + }else + if(strstr(exp_str,"Frowning")||strstr(exp_str,"皱眉头")) + { + cmd_ui[4]=0x0b; + cmd_ui[6]=0x0d; + }else + if(strstr(exp_str,"Grimacing")||strstr(exp_str,"苦着脸")) + { + cmd_ui[4]=0x0c; + cmd_ui[6]=0x0e; + }else + if(strstr(exp_str,"Happy")||strstr(exp_str,"开心")) + { + cmd_ui[4]=0x0d; + cmd_ui[6]=0x0f; + }else + if(strstr(exp_str,"Neutral")||strstr(exp_str,"中立")) + { + cmd_ui[4]=0x0e; + cmd_ui[6]=0x10; + }else + if(strstr(exp_str,"Pensive")||strstr(exp_str,"悲伤")) + { + cmd_ui[4]=0x0f; + cmd_ui[6]=0x11; + }else + if(strstr(exp_str,"Relaxed")||strstr(exp_str,"放松")) + { + cmd_ui[4]=0x10; + cmd_ui[6]=0x12; + }else + if(strstr(exp_str,"Sad")||strstr(exp_str,"伤心")) + { + cmd_ui[4]=0x11; + cmd_ui[6]=0x13; + }else + if(strstr(exp_str,"Smiling")||strstr(exp_str,"微笑")) + { + cmd_ui[4]=0x12; + cmd_ui[6]=0x14; + }else + if(strstr(exp_str,"Surprised")||strstr(exp_str,"惊讶")) + { + cmd_ui[4]=0x13; + cmd_ui[6]=0x15; + }else + if(strstr(exp_str,"Tired")||strstr(exp_str,"疲惫")) + { + cmd_ui[4]=0x14; + cmd_ui[6]=0x16; + }else + if(strstr(exp_str,"Winking")||strstr(exp_str,"眨眼")) + { + cmd_ui[4]=0x15; + cmd_ui[6]=0x17; + } + + uart_write(ui_uart_handle,cmd_ui, 7); + } + + + #endif + + +} + +static void AI_VC_send_music_start(char *urlpath); + +void aic_https_demotest(); + +int32_t play_audio_done_duplex(const char *buf, uint32_t buf_len, uint32_t sample_rate, uint32_t is_file); + +int mp3_test(); + +void resetClose_time(){ + + close_timerout=180; +} + +int check_text(char *text,int ret_str_len) +{ + //bk_printf("check_text:text:%s",text); + + if(ret_str_len >60) + return -1; + int ret = -1; + unsigned char is_save_VC_cfg = 0; + char tmp_data[70] = {0}; + int tmp_data_len = 0; + if(strstr(text,"声音改")) + { + if(strstr(text,"男")) + { + + } } -//aic_gpio_output(GPIO_15,GPIO_OUTPUT_LVL_HIGH );//lcd open ldo - if(strstr(text,"结束对话")||strstr(text,"关闭对话")||strstr(text,"退出对话")) + if(strstr(text,"音量") || strstr(text,"声音")) { + if(strstr(text,"加")||(strstr(text,"大")&&!strstr(text,"太")) || (strstr(text,"太小"))) + { + vc_cfg.VC_TTS_volume +=10; + if(vc_cfg.VC_TTS_volume > 100) + { + vc_cfg.VC_TTS_volume = 100; + AI_AMP_MSG_put("音量已最大。",strlen("音量已最大。"),VC_TTS_PLAY); + //AI_TTS_str + }else{ - // AI_AMP_MSG_put("拜拜",strlen("拜拜"),VC_TTS_PLAY); + tmp_data_len = snprintf(tmp_data,sizeof(tmp_data),"配置成功,当前音量%d。",vc_cfg.VC_TTS_volume); + AI_AMP_MSG_put(tmp_data,tmp_data_len,VC_TTS_PLAY); + } + // if(vc_cfg.VC_mode != 0) + app_audio_set_master_volume(15*vc_cfg.VC_TTS_volume/100); - // aos_sleep(1000); + + is_save_VC_cfg = 1; + ret = 0; + goto RET; + }else if(strstr(text,"减")||(strstr(text,"小")&&!strstr(text,"太")) || (strstr(text,"太大"))) + { + vc_cfg.VC_TTS_volume -=10; + if(vc_cfg.VC_TTS_volume < 0) + { + vc_cfg.VC_TTS_volume = 0; + AI_AMP_MSG_put("音量已最小。",strlen("音量已最小。"),VC_TTS_PLAY); + //AI_TTS_str + }else{ - is_dialog_status=1; + tmp_data_len = snprintf(tmp_data,sizeof(tmp_data),"配置成功,当前音量%d。",vc_cfg.VC_TTS_volume); + AI_AMP_MSG_put(tmp_data,tmp_data_len,VC_TTS_PLAY); + } - ddh_is_close_dialog=1; + //if(vc_cfg.VC_mode != 0) + app_audio_set_master_volume(15*vc_cfg.VC_TTS_volume/100); - // AI_AMP_MSG_put(0,0,VC_CLOSE); - // ret = 0; - // goto RET; + is_save_VC_cfg = 1; + ret = 0; + goto RET; + } + } + if(strstr(text,"切换")) + { + if(strstr(text,"对话模式") || strstr(text,"兑换模式")) + { + vc_cfg.VC_mode+=1; + if(vc_cfg.VC_mode > 2) + vc_cfg.VC_mode = 0; + bk_printf("切换对话模式:vc_cfg.VC_mode :%d",vc_cfg.VC_mode ); + if(vc_cfg.VC_mode == 0) + { + AI_AMP_MSG_put("已切换到连续对话模式。",strlen("已切换到连续对话模式。"),VC_TTS_PLAY); + + app_audio_set_master_volume(15*80/100); + + }else if(vc_cfg.VC_mode == 1) + { + AI_AMP_MSG_put("已切换到单对话模式。长按按钮说话,说完松开即可。",strlen("已切换到单对话模式。长按按钮说话,说完松开即可。"),VC_TTS_PLAY); + + app_audio_set_master_volume(15*80/100); + }else + { + + app_audio_set_master_volume(15*80/100); + AI_AMP_MSG_put("已切换到按键打断模式。我说话的时候需要短按按钮打断。",strlen("已切换到按键打断模式。我说话的时候需要短按按钮打断。"),VC_TTS_PLAY); + } + is_save_VC_cfg = 1; + ret = 0; + + // IOT_update_statu(3,"",""); + IOT_V3_update_statu(3,"",""); + goto RET; + } + + } + + + // status + + if(strstr(text,"升级版本")) + { + + AI_AMP_MSG_put("开始升级版本,大概需要几分钟",strlen("开始升级版本,大概需要几分钟"),VC_TTS_PLAY); + ret = 0; + goto RET; } if(strstr(text,"帮我生成语音文件")) @@ -624,11 +840,18 @@ int check_text(char *text,int ret_str_len) //||strstr(text,"做一个惊讶的表情")||strstr(text,"做一个开心的表情") + // 淡定:Calm + // 尴尬:Embarrass + // 开心:Happy + // 可爱:Cute + + if(strstr(text,"做一个")&&strstr(text,"表情")) { - // need_express_cmd=1; + need_express_cmd=1; AI_AMP_MSG_put("开始做表情了",strlen("开始做表情了"),VC_TTS_PLAY); + send_express_str(text); @@ -636,76 +859,50 @@ int check_text(char *text,int ret_str_len) goto RET; } - if(strstr(text,"做一个发怒的表情")) + if(strstr(text,"做一个淡定的表情")) { AI_AMP_MSG_put("开始做表情了",strlen("开始做表情了"),VC_TTS_PLAY); - if(ui_uart_handle){ - u8 cmd_ui[7]={0xAA,0x55,0xFF,0x02,0x02,0x01,0x04}; + u8 cmd_ui[7]={0xAA,0x55,0xFF,0x02,0x01,0x01,0x03}; uart_write(ui_uart_handle,cmd_ui, 7); } - - ret = 0; - goto RET; + ret = 0; + goto RET; } - if(strstr(text,"做一个惊讶的表情")) + if(strstr(text,"做一个尴尬的表情")) { - AI_AMP_MSG_put("开始做表情了",strlen("开始做表情了"),VC_TTS_PLAY); - if(ui_uart_handle){ - u8 cmd_ui[7]={0xAA,0x55,0xFF,0x02,0x06,0x01,0x08}; + u8 cmd_ui[7]={0xAA,0x55,0xFF,0x02,0x02,0x01,0x04}; uart_write(ui_uart_handle,cmd_ui, 7); } - - ret = 0; - goto RET; + ret = 0; + goto RET; } - - - if(strstr(text,"做一个搞怪的表情")) + if(strstr(text,"做一个开心的表情")) { - AI_AMP_MSG_put("开始做表情了",strlen("开始做表情了"),VC_TTS_PLAY); - if(ui_uart_handle){ u8 cmd_ui[7]={0xAA,0x55,0xFF,0x02,0x03,0x01,0x05}; uart_write(ui_uart_handle,cmd_ui, 7); } - - ret = 0; - goto RET; + ret = 0; + goto RET; } - - if(strstr(text,"做一个卡通的表情")) + if(strstr(text,"做一个可爱的表情")) { - AI_AMP_MSG_put("开始做表情了",strlen("开始做表情了"),VC_TTS_PLAY); - if(ui_uart_handle){ - u8 cmd_ui[7]={0xAA,0x55,0xFF,0x02,0x07,0x01,0x09}; + u8 cmd_ui[7]={0xAA,0x55,0xFF,0x02,0x04,0x01,0x06}; uart_write(ui_uart_handle,cmd_ui, 7); } - - ret = 0; - goto RET; + ret = 0; + goto RET; } - if(strstr(text,"做一个花痴的表情")) - { - - AI_AMP_MSG_put("开始做表情了",strlen("开始做表情了"),VC_TTS_PLAY); - - if(ui_uart_handle){ - u8 cmd_ui[7]={0xAA,0x55,0xFF,0x02,0x04,0x01,0x06}; - uart_write(ui_uart_handle,cmd_ui, 7); - } - ret = 0; - goto RET; - } - if(strstr(text,"做一个惊喜的表情")) + if(strstr(text,"做一个惊喜的表情")) { AI_AMP_MSG_put("开始做表情了",strlen("开始做表情了"),VC_TTS_PLAY); @@ -808,177 +1005,119 @@ int check_text(char *text,int ret_str_len) u8 cmd_ui[7]={0xAA,0x55,0xFF,0x02,0x01,0x01,0x03}; uart_write(ui_uart_handle,cmd_ui, 7); } - #if SUPPORT_MOT + #if SUPPORT_MOT mot_nod_exp(8,2); #endif ret = 0; goto RET; } - if(strstr(text,"打开触摸动作")) + if(strstr(text,"做一个发怒的表情")) { + AI_AMP_MSG_put("开始做表情了",strlen("开始做表情了"),VC_TTS_PLAY); - chumo_exp_open=1; - AI_AMP_MSG_put("触摸动作已打开",strlen("触摸动作已打开"),VC_TTS_PLAY); - - ret = 0; - goto RET; + send_express_str(text); + ret = 0; + goto RET; } - - if(strstr(text,"关闭触摸动作")) + if(strstr(text,"做一个惊讶的表情")) { - chumo_exp_open=0; - AI_AMP_MSG_put("触摸动作已关闭",strlen("触摸动作已关闭"),VC_TTS_PLAY); + AI_AMP_MSG_put("开始做表情了",strlen("开始做表情了"),VC_TTS_PLAY); - ret = 0; - goto RET; + send_express_str(text); + ret = 0; + goto RET; } + if(strstr(text,"做一个开心的表情")) + { - // if(strstr(text,"摇头")) - // { - // AI_AMP_MSG_put("开始摇头了",strlen("开始摇头了"),VC_TTS_PLAY); - - // if(ui_uart_handle){ - // u8 cmd_ui[7]={0xAA,0x55,0xFF,0x02,0x01,0x01,0x03}; - // uart_write(ui_uart_handle,cmd_ui, 7); - // } - - // bk_printf("摇头"); - // #if SUPPORT_MOT - // mot_nod_diantou(2); - // #endif - // ret = 0; - // goto RET; - - // } - - // if(strstr(text,"点头")) - // { - // // AI_AMP_MSG_put("开始做动作了",strlen("开始做动作了"),VC_TTS_PLAY); - - // AI_AMP_MSG_put("开始点头了",strlen("开始点头了"),VC_TTS_PLAY); - - // // if(ui_uart_handle){ - // // u8 cmd_ui[7]={0xAA,0x55,0xFF,0x02,0x08,0x01,0x0a}; - // // uart_write(ui_uart_handle,cmd_ui, 7); - // // } - // bk_printf("点头"); - // #if SUPPORT_MOT - // mot_nod_yaotou(2); - // #endif - // ret = 0; - // goto RET; - - // } - - - - - // if(strstr(text,"抬头")) - // { - // AI_AMP_MSG_put("开始抬头了",strlen("开始抬头了"),VC_TTS_PLAY); - - // bk_printf("抬头"); - // #if SUPPORT_MOT - // mot_nod_ditou(2); - // #endif - // ret = 0; - // goto RET; - - // } - - // if(strstr(text,"低头")) - // { - // AI_AMP_MSG_put("开始低头了",strlen("开始低头了"),VC_TTS_PLAY); + AI_AMP_MSG_put("开始做表情了",strlen("开始做表情了"),VC_TTS_PLAY); - // bk_printf("低头"); - // #if SUPPORT_MOT - // mot_nod_taitou(2); - // #endif - // ret = 0; - // goto RET; + send_express_str(text); - // } + ret = 0; + goto RET; + } - // if(strstr(text,"向左转")) - // { - // AI_AMP_MSG_put("开始向左转",strlen("开始向左转"),VC_TTS_PLAY); - // bk_printf("向左转"); - // #if SUPPORT_MOT - // mot_nod_exp(15,2); - // #endif - // ret = 0; - // goto RET; + // if(strstr(text,"播放音乐")) + // { - // } + // AI_AMP_MSG_put("开始做表情了",strlen("开始做表情了"),VC_TTS_PLAY); + // send_express_str(text);浦幼绘本视频 + // AI_VC_send_music_start("https://video.teacherasked.cn/Read_bank/read_xspy202504/%E6%B5%A6%E5%B9%BC%E7%BB%98%E6%9C%AC%E8%A7%86%E9%A2%91/a20f2c5d-e41c-414c-b407-92ca37d54391.opus"); - // if(strstr(text,"向右转")) - // { - // AI_AMP_MSG_put("开始向右转",strlen("开始向右转"),VC_TTS_PLAY); + // AI_VC_send_music_start(""); + // ret = 0; + // goto RET; + // } - // bk_printf("向右转"); - // #if SUPPORT_MOT - // mot_nod_exp(16,2); - // #endif - // ret = 0; - // goto RET; + if(strstr(text,"取消所有闹钟")) + { - // } + AI_AMP_MSG_put("好的",strlen("好的"),VC_TTS_PLAY); + // send_express_str(text);浦幼绘本视频 + // AI_VC_send_music_start("https://video.teacherasked.cn/Read_bank/read_xspy202504/%E6%B5%A6%E5%B9%BC%E7%BB%98%E6%9C%AC%E8%A7%86%E9%A2%91/a20f2c5d-e41c-414c-b407-92ca37d54391.opus"); + vc_cfg.alarm_count=0; + save_VC_cfg(); + // AI_VC_send_music_start(""); + ret = 0; + goto RET; + } - if(strstr(text,"查询马达状态")) + if(strstr(text,"获取设备状态")) { - mot_nod_status(); + // mot_nod_status(); - // aic_http_demotest(); + aic_https_demotest_status(); ret = 0; goto RET; } - - // if(strstr(text,"导出文件")) - // { - - // int len_daochu=0,sum_len=0;; - // FILE *fp_play_local=fopen("C:/cmd_local_301.pcm","rb"); - // if(fp_play_local){ - - - // while(1){ + + if(strstr(text,"播放文件")) + { + int len_daochu=0,sum_len=0;; + // FILE *fp_play_local=fopen("C:/test12312.mp3","rb"); - // len_daochu=fread(recv_get,1,1024,fp_play_local); + // if(fp_play_local){ + // while(1){ - // if(len_daochu>0){ - // sum_len+=len_daochu; - // audio_data(recv_get,len_daochu,22); + // len_daochu=fread(recv_get,1,1024*6,fp_play_local); - // }else{ + // bk_printf("read mp3 len is %d ...",len_daochu); - // break; + // if(len_daochu>0){ + // sum_len+=len_daochu; + // // audio_data(recv_get,len_daochu,22); + // // play_audio_done_duplex((const char *)recv_get, len_daochu, 44100, 1); - // } + // }else{ - - // } + // break; + // } + // } - // bk_printf("daochu len is %d ...",sum_len); - // fclose(fp_play_local); + // bk_printf("daochu len is %d ...",sum_len); + // fclose(fp_play_local); - // } - // ret = 0; - // goto RET; - // } + // } + bk_printf("mp3_test start.....\n"); + mp3_test(); + ret = 0; + goto RET; + } if(strstr(text,"查询")) @@ -1163,21 +1302,17 @@ int check_text(char *text,int ret_str_len) } if(ret_str_len<16 && (strstr(text,"再见") || strstr(text,"拜拜") || strstr(text,"关闭对话"))) { - // tmp_data_len = snprintf(tmp_data,sizeof(tmp_data),"再见了,我会想你的。"); - // AI_AMP_MSG_put(tmp_data,tmp_data_len,VC_TTS_PLAY_CLOSE); - is_dialog_status=1; - ddh_is_close_dialog=1; + tmp_data_len = snprintf(tmp_data,sizeof(tmp_data),"再见了,我会想你的。"); + AI_AMP_MSG_put(tmp_data,tmp_data_len,VC_TTS_PLAY_CLOSE); } - if(ret_str_len<16 && (strstr(text,"关机") )) + if(ret_str_len<10 && (strstr(text,"关机") )) { + bk_printf("the guanji strlen is %d...\n",strlen(text)); tmp_data_len = snprintf(tmp_data,sizeof(tmp_data),"正在关机。"); - - is_guanji=1; - AI_AMP_MSG_put(tmp_data,tmp_data_len,VC_TTS_PLAY_POWER_OFF); } - if(ret_str_len<16 && (strstr(text,"重启") )) + if(ret_str_len<10 && (strstr(text,"重启") )) { tmp_data_len = snprintf(tmp_data,sizeof(tmp_data),"正在重启。"); AI_AMP_MSG_put(tmp_data,tmp_data_len,VC_TTS_PLAY_RESET); @@ -1242,12 +1377,23 @@ static void AI_client_VC_synthesis(char *str) static void AI_VC_send_satrt(char is_greeting) { // 创建根对象 + + is_music_status=0; cJSON *root = cJSON_CreateObject(); cJSON_AddStringToObject(root, "event", "start"); // 创建 payload 对象 cJSON *payload = cJSON_CreateObject(); cJSON_AddStringToObject(payload, "device_id", vc_cfg.dev_imei); + + if(is_newsession) + cJSON_AddBoolToObject(payload, "is_new_session", TRUE); + else + cJSON_AddBoolToObject(payload, "is_new_session", FALSE); + + is_newsession=false; + + cJSON_AddStringToObject(payload, "user_agent", "AudioClient/1.0"); cJSON_AddBoolToObject(payload, "simple_response", FALSE); if(AI_ASR_str && VAD_time_count !=0 && VAD_time_count <= VAD_TIMEOUT )//时间间隔短,认为是一次对话,加上上一次内容 @@ -1276,20 +1422,18 @@ static void AI_VC_send_satrt(char is_greeting) // 创建 custom_variables 对象 cJSON *custom_variables = cJSON_CreateObject(); - cJSON_AddStringToObject(custom_variables, "name", "食梦貘"); - - // cJSON_AddStringToObject(custom_variables, "coze_current_time", "23:00"); - - // cJSON_AddStringToObject(custom_variables, "coze_current_date", "2025-10-01"); - cJSON_AddItemToObject(dialog_cfg, "custom_variables", custom_variables); // 创建 greeting 对象 cJSON *greeting = cJSON_CreateObject(); + + + // is_greeting=0; + if(is_greeting == 1) { - cJSON_AddBoolToObject(greeting, "enabled", FALSE);//是否播放提示词 + cJSON_AddBoolToObject(greeting, "enabled", FALSE);//是否播放提示词 //TRUE cJSON_AddStringToObject(greeting, "content", "你好"); cJSON_AddItemToObject(dialog_cfg, "greeting", greeting); }else @@ -1316,12 +1460,26 @@ static void AI_VC_send_satrt(char is_greeting) }else { cJSON_AddBoolToObject(bot_option, "use_workflow", 1); - cJSON_AddStringToObject(bot_option, "bot_id", "7491256313561825332");//食梦貘 + cJSON_AddStringToObject(bot_option, "bot_id", "7491256313561825332");//食梦貘 7491256313561825332 + + //7574309992161886227 //7491256313561825332 cJSON_AddStringToObject(bot_option, "workflow_id", "7508598451564150820"); } cJSON_AddItemToObject(dialog_cfg, "bot_option", bot_option); - cJSON *dify_option = cJSON_CreateObject(); + + // "dialog_attributes": { + // "cfg": { + // "dify_option": { + // "inputs": { + // "devToken": "xxxxxxxxxxxxx", + // "deviceId": "xxxxxxxxxx" + // } + // } + // } + // }, + + cJSON *dify_option = cJSON_CreateObject(); cJSON *inputs_option = cJSON_CreateObject(); @@ -1369,11 +1527,12 @@ static void AI_VC_send_satrt(char is_greeting) { cJSON_AddStringToObject(outbound_cfg, "format", "opus");//ogg_opus opus - // if(codec_tts==1) + if(codec_tts==1) cJSON_AddStringToObject(outbound_cfg, "codec", "raw");// ogg - // else - // cJSON_AddStringToObject(outbound_cfg, "codec", "ogg");// ogg - cJSON_AddNumberToObject(outbound_cfg, "compression_rate", 20); + else + cJSON_AddStringToObject(outbound_cfg, "codec", "ogg");// ogg + + cJSON_AddNumberToObject(outbound_cfg, "compression_rate", 20); } else cJSON_AddStringToObject(outbound_cfg, "format", "pcm"); @@ -1464,180 +1623,229 @@ static void AI_VC_send_satrt(char is_greeting) cJSON_Delete(root); } +//{"cmd":"renew_device"} -//Audio.Create 开始发送音频 -static void AI_VC_send_audio_create(void) + char mp3_path_str[500]; + +void deal_iot_receive(char *json_data) { - VC_state = VC_State_SpeechStart;//开始说 - // 创建根对象 - cJSON *root = cJSON_CreateObject(); - if (root == NULL) { - bk_printf("Failed to create root object.\n"); - return ; - } - // 设置 "event" 字段 - cJSON_AddStringToObject(root, "event", "audio.create"); + bk_printf(json_data); - // 创建 "payload" 对象 - cJSON *payload = cJSON_CreateObject(); - if (payload == NULL) { - bk_printf("Failed to create payload object.\n"); - cJSON_Delete(root); - return ; - } - // 将 "payload" 对象添加到根对象中 - cJSON_AddItemToObject(root, "payload", payload); + // vc_cfg.VC_TTS_volume = 100; + // AI_AMP_MSG_put("音量已最大。",strlen("音量已最大。"),VC_TTS_PLAY); - // 将 JSON 对象转换为字符串 - char *json_str = cJSON_Print(root); - if (json_str == NULL) { - bk_printf("Failed to print JSON object.\n"); - cJSON_Delete(root); - - } - AI_VC_send_data(json_str,strlen(json_str),AIC_WEBSOCKET_OPCODE_TEXT_FRAME);//发送数据 - + //{"cmd":"emotion","msg":"AI指令:emotion","data":"Cute","ts":1764914695122,"targetDeviceId":"865530078570777"} - // 释放内存 - free(json_str); - cJSON_Delete(root); -} + if(strstr(json_data,"emotion")){ + bk_printf("emotion"); -// { -// "event": "audio.convert", -// "payload": { -// "audio_convert_request": { -// "audio_url": audio_url, -// "bit_depth": 16, -// "channels": 1, -// "sample_rate": 16000, -// "target_format": "pcm" -// } -// } -// } + char *str_tmp = NULL; -static void AI_VC_send_startup(void) -{ - VC_state = VC_State_SpeechStart;//开始说 - // 创建根对象 - cJSON *root = cJSON_CreateObject(); - if (root == NULL) { - bk_printf("Failed to create root object.\n"); - return ; - } + char emotion_str[500]={0}; - // 设置 "event" 字段 - cJSON_AddStringToObject(root, "event", "prompt"); + str_tmp = strstr(json_data,"\"data\":\""); + + // bk_printf("str_tmp:%p",str_tmp); - // 创建 "payload" 对象 - cJSON *payload = cJSON_CreateObject(); - if (payload == NULL) { - bk_printf("Failed to create payload object.\n"); - cJSON_Delete(root); - return ; - } + if(str_tmp)//解析password + { - + str_tmp += strlen("\"data\":\""); + int count = str_count(str_tmp,'\"'); + bk_printf("count:%d",count); + if(count < sizeof(emotion_str)) + { - cJSON *promat = cJSON_CreateObject(); - if (payload == NULL) { - bk_printf("Failed to create payload object.\n"); - cJSON_Delete(root); - return ; - } + + memcpy(emotion_str,str_tmp,count); + emotion_str[count] = 0; + bk_printf("emotion_str:%s",emotion_str); + if(need_express_cmd==0) + send_express_str(emotion_str); + } - cJSON *interrupt_keywords = cJSON_CreateArray(); - // cJSON_AddStringToObject(promat, "event", "startup"); + } - //cJSON_AddItemToArray(interrupt_keywords, cJSON_CreateString("停止")); - //cJSON_AddItemToArray(interrupt_keywords, cJSON_CreateString("打断")); - // cJSON_AddItemToArray(interrupt_keywords, cJSON_CreateString("等一下")); + } - cJSON *content = cJSON_CreateObject(); + if(strstr(json_data,"tts_audio_url")){ + bk_printf("tts_audio_url"); + char *str_tmp = NULL; - cJSON_AddStringToObject(content, "role", "user"); + memset(mp3_path_str,0,500); - cJSON_AddStringToObject(content, "content", "{\"event\":\"startup\"}"); + str_tmp = strstr(json_data,"\"data\":\""); + + // bk_printf("str_tmp:%p",str_tmp); - cJSON_AddStringToObject(content, "content_type", "text"); + if(str_tmp)//解析password + { - cJSON_AddItemToArray(interrupt_keywords, content); + str_tmp += strlen("\"data\":\""); + int count = str_count(str_tmp,'\"'); + bk_printf("count:%d",count); + if(count < sizeof(mp3_path_str)) + { + + memcpy(mp3_path_str,str_tmp,count); + mp3_path_str[count] = 0; + bk_printf("mp3_path_str:%s",mp3_path_str); - cJSON_AddItemToObject(payload, "prompt", interrupt_keywords); + // is_music_status=1; - //cJSON_AddItemToObject(inbound_attributes, "interrupt_options", interrupt_options); + // AI_AMP_MSG_put("请稍后,现在为你查找音乐",strlen("请稍后,现在为你查找音乐"),VC_TTS_PLAY); - + // aos_sleep(4000); + need_play_is_music_status=1; - // cJSON_AddItemToObject(payload, "prompt", promat); - // 将 "payload" 对象添加到根对象中 - cJSON_AddItemToObject(root, "payload", payload); - // 将 JSON 对象转换为字符串 - char *json_str = cJSON_Print(root); - if (json_str == NULL) { - bk_printf("Failed to print JSON object.\n"); - cJSON_Delete(root); - - } - AI_VC_send_data(json_str,strlen(json_str),AIC_WEBSOCKET_OPCODE_TEXT_FRAME);//发送数据 - - // 释放内存 - free(json_str); - cJSON_Delete(root); -} + AI_AMP_MSG_put(0,0,VC_Cancel);//发送打断 + // AI_VC_send_music_start(mp3_path_str); -//Music.Start 开始发送音频 -static void AI_VC_send_music_start(char *urlpath) -{ - VC_state = VC_State_SpeechStart;//开始说 - // 创建根对象 - cJSON *root = cJSON_CreateObject(); - if (root == NULL) { - bk_printf("Failed to create root object.\n"); - return ; - } + } + } - // 设置 "event" 字段 - cJSON_AddStringToObject(root, "event", "audio.convert"); + // IOT_update_statu(3,"",""); - // 创建 "payload" 对象 - cJSON *payload = cJSON_CreateObject(); - if (payload == NULL) { - bk_printf("Failed to create payload object.\n"); - cJSON_Delete(root); - return ; - } + // AI_AMP_MSG_put("正在查找设备。",strlen("正在查找设备。"),VC_TTS_PLAY); - cJSON *audio_convert_request = cJSON_CreateObject(); - if (payload == NULL) { - bk_printf("Failed to create payload object.\n"); - cJSON_Delete(root); - return ; } - cJSON_AddStringToObject(audio_convert_request, "audio_url", urlpath); - cJSON_AddNumberToObject(audio_convert_request, "bit_depth", 16); - cJSON_AddNumberToObject(audio_convert_request, "channels", 1); - cJSON_AddNumberToObject(audio_convert_request, "sample_rate", 16000); + if(strstr(json_data,"get_device_state")){ - if(outbound_attributes_format == attributes_format_OPUS) - { - cJSON_AddStringToObject(audio_convert_request, "target_format", "opus"); - }else{ + bk_printf("get_device_state"); - cJSON_AddStringToObject(audio_convert_request, "target_format", "pcm"); - } + // IOT_update_statu(3,"",""); + IOT_V3_update_statu(3,"",""); - cJSON_AddItemToObject(payload, "audio_convert_request", audio_convert_request); + // AI_AMP_MSG_put("正在查找设备。",strlen("正在查找设备。"),VC_TTS_PLAY); + + } + + if(strstr(json_data,"find_device")){ + + bk_printf("find_device"); + + AI_AMP_MSG_put("正在查找设备。",strlen("正在查找设备。"),VC_TTS_PLAY); + + } + + if(strstr(json_data,"renew_device")){ + + bk_printf("renew_device"); + + IOT_update_bargein(); + + if(vc_cfg.VC_mode == 0) + { + AI_AMP_MSG_put("已切换到连续对话模式。",strlen("已切换到连续对话模式。"),VC_TTS_PLAY); + + //app_audio_set_master_volume(15*80/100); + + }else if(vc_cfg.VC_mode == 1) + { + AI_AMP_MSG_put("已切换到单对话模式。长按按钮说话,说完松开即可。",strlen("已切换到单对话模式。长按按钮说话,说完松开即可。"),VC_TTS_PLAY); + + // app_audio_set_master_volume(15*80/100); + }else + { + + // app_audio_set_master_volume(15*80/100); + AI_AMP_MSG_put("已切换到按键打断模式。我说话的时候需要短按按钮打断。",strlen("已切换到按键打断模式。我说话的时候需要短按按钮打断。"),VC_TTS_PLAY); + } + + IOT_V3_update_statu(3,"",""); + save_VC_cfg(); + + } + + if(strstr(json_data,"switch_volume")) + { + + // bk_printf("switch_volume"); + + char *str_tmp = NULL; + + char volume_str[5]={0}; + + str_tmp = strstr(json_data,"\"target\":\""); + + //bk_printf("str_tmp:%p",str_tmp); + if(str_tmp)//解析password + { + str_tmp += strlen("\"target\":\""); + int count = str_count(str_tmp,'\"'); + bk_printf("count:%d",count); + if(count < sizeof(volume_str)) + { + + memcpy(volume_str,str_tmp,count); + volume_str[count] = 0; + bk_printf("volume_str:%s",volume_str); + + int temp_vol=atoi(volume_str); + + if(temp_vol>=0&&temp_vol<=100) + { + + vc_cfg.VC_TTS_volume = temp_vol; + + app_audio_set_master_volume(15*vc_cfg.VC_TTS_volume/100); + + char tts_temp[200]={0}; + + + sprintf(tts_temp,"设置音量%d成功。",vc_cfg.VC_TTS_volume); + + AI_AMP_MSG_put(tts_temp,strlen(tts_temp),VC_TTS_PLAY); + + + //is_save_VC_cfg = 1; + + save_VC_cfg(); + } + + + + } + else + { + bk_printf("获取volume失败"); + } + } + } + + +} +//Audio.Create 开始发送音频 +static void AI_VC_send_audio_create(void) +{ + VC_state = VC_State_SpeechStart;//开始说 + // 创建根对象 + cJSON *root = cJSON_CreateObject(); + if (root == NULL) { + bk_printf("Failed to create root object.\n"); + return ; + } + + // 设置 "event" 字段 + cJSON_AddStringToObject(root, "event", "audio.create"); + + // 创建 "payload" 对象 + cJSON *payload = cJSON_CreateObject(); + if (payload == NULL) { + bk_printf("Failed to create payload object.\n"); + cJSON_Delete(root); + return ; + } // 将 "payload" 对象添加到根对象中 cJSON_AddItemToObject(root, "payload", payload); @@ -1656,10 +1864,25 @@ static void AI_VC_send_music_start(char *urlpath) cJSON_Delete(root); } -//Audio.Completed 结束发送音频 -static void AI_VC_send_audio_completed(void) + +// { +// "event": "prompt", +// "payload": { +// "prompt": [ +// { +// "role": "user", +// "content": "今天是礼拜几?", +// "content_type": "text", // 可以不提交 +// "type": "question" // 可以不提交 +// } +// ] +// } +// } + +//Audio.Create 开机json {"event":"startup"} +static void AI_VC_send_startup(void) { - VC_state = VC_State_SpeechEnd;//说结束 + VC_state = VC_State_SpeechStart;//开始说 // 创建根对象 cJSON *root = cJSON_CreateObject(); if (root == NULL) { @@ -1668,7 +1891,7 @@ static void AI_VC_send_audio_completed(void) } // 设置 "event" 字段 - cJSON_AddStringToObject(root, "event", "audio.completed"); + cJSON_AddStringToObject(root, "event", "prompt"); // 创建 "payload" 对象 cJSON *payload = cJSON_CreateObject(); @@ -1677,9 +1900,47 @@ static void AI_VC_send_audio_completed(void) cJSON_Delete(root); return ; } + + + + cJSON *promat = cJSON_CreateObject(); + if (payload == NULL) { + bk_printf("Failed to create payload object.\n"); + cJSON_Delete(root); + return ; + } + + + cJSON *interrupt_keywords = cJSON_CreateArray(); + // cJSON_AddStringToObject(promat, "event", "startup"); + + //cJSON_AddItemToArray(interrupt_keywords, cJSON_CreateString("停止")); + //cJSON_AddItemToArray(interrupt_keywords, cJSON_CreateString("打断")); + // cJSON_AddItemToArray(interrupt_keywords, cJSON_CreateString("等一下")); + + cJSON *content = cJSON_CreateObject(); + + + + cJSON_AddStringToObject(content, "role", "user"); + + cJSON_AddStringToObject(content, "content", "{\"event\":\"startup\"}"); + + cJSON_AddStringToObject(content, "content_type", "text"); + + cJSON_AddItemToArray(interrupt_keywords, content); + + + cJSON_AddItemToObject(payload, "prompt", interrupt_keywords); + + //cJSON_AddItemToObject(inbound_attributes, "interrupt_options", interrupt_options); + + + + + // cJSON_AddItemToObject(payload, "prompt", promat); // 将 "payload" 对象添加到根对象中 cJSON_AddItemToObject(root, "payload", payload); - // 将 JSON 对象转换为字符串 char *json_str = cJSON_Print(root); if (json_str == NULL) { @@ -1688,98 +1949,222 @@ static void AI_VC_send_audio_completed(void) } AI_VC_send_data(json_str,strlen(json_str),AIC_WEBSOCKET_OPCODE_TEXT_FRAME);//发送数据 + // 释放内存 free(json_str); cJSON_Delete(root); } -// //打断 -// static void AI_VC_send_cancel(void) -// { -// // 创建根对象 -// cJSON *root = cJSON_CreateObject(); -// if (root == NULL) { -// bk_printf("Failed to create root object.\n"); -// return ; -// } -// // 设置 "event" 字段 -// cJSON_AddStringToObject(root, "event", "cancel"); -// // 创建 "payload" 对象 -// cJSON *payload = cJSON_CreateObject(); -// if (payload == NULL) { -// bk_printf("Failed to create payload object.\n"); -// cJSON_Delete(root); -// return ; -// } -// // 将 "payload" 对象添加到根对象中 -// cJSON_AddItemToObject(root, "payload", payload); -// // 将 JSON 对象转换为字符串 -// char *json_str = cJSON_Print(root); -// if (json_str == NULL) { -// bk_printf("Failed to print JSON object.\n"); -// cJSON_Delete(root); - + +// { +// "event": "audio.convert", +// "payload": { +// "audio_convert_request": { +// "audio_url": audio_url, +// "bit_depth": 16, +// "channels": 1, +// "sample_rate": 16000, +// "target_format": "pcm" +// } +// } // } -// AI_VC_send_data(json_str,strlen(json_str),AIC_WEBSOCKET_OPCODE_TEXT_FRAME);//发送数据 - -// // 释放内存 -// free(json_str); -// cJSON_Delete(root); -// } -//TTS播放 -static void VC_TTS_Play(const char *str) -{ - bk_printf("VC_TTS_Play:%s",str); - if(AI_TTS_str) - { - aic_free(AI_TTS_str); - AI_TTS_str = NULL; - } - AI_TTS_str = aic_zalloc(strlen(str)+1); - strcpy(AI_TTS_str,str); - //VC_record_End(); - VC_Play_End(); - websocket_deconnect_VC(); - AI_VC_start(0); -} -//pinpin发送 -void AI_VC_send_ping_ping(void) -{ - // mot_nod_status(); - AI_VC_send_data("ping",strlen("ping"),AIC_WEBSOCKET_OPCODE_TEXT_FRAME);//发送数据 -} -int send_count_pcm=0; -int send_update=0;; -static void AI_VC_send_task(void *thread_input)//websocket 发送线程 +//Music.Start 开始发送音频 +static void AI_VC_send_music_start(char *urlpath) { - AI_VC_send_queue_t AI_VC_send_queue_data; - bk_printf("AI_VC_send_task go......"); - int ret = 0; - AI_VC_send_task_flag = 1; - while(1) - { - if(AI_VC_send_task_flag == 2)//要退出了 - break; - if(AI_VC_send_queue && aos_recv_from_queue(AI_VC_send_queue,&AI_VC_send_queue_data,AOS_NO_WAIT) == AOS_SUCCESS) - { - - if(AI_client_VC && AI_VC_send_queue_data.data) - { - VC_pingping_timerout = 20; - if(inbound_attributes_format == attributes_format_OPUS&& AI_VC_send_queue_data.AIC_WEBSOCKET_OPCODE ==AIC_WEBSOCKET_OPCODE_BINARY_FRAME )//转码opus - { - char *opus_data = aic_malloc(OPUS_ENCODER_PACK_MS*16); - if(opus_data) - { - ret = opus_encode_data(AI_VC_send_queue_data.data,AI_VC_send_queue_data.len,OPUS_ENCODER_PACK_MS*32,opus_data,OPUS_ENCODER_PACK_MS*16); + is_music_status=1; + + VC_state = VC_State_End;//开始说 + // 创建根对象 + cJSON *root = cJSON_CreateObject(); + if (root == NULL) { + bk_printf("Failed to create root object.\n"); + return ; + } + + // 设置 "event" 字段 + cJSON_AddStringToObject(root, "event", "audio.convert"); + + // 创建 "payload" 对象 + cJSON *payload = cJSON_CreateObject(); + if (payload == NULL) { + bk_printf("Failed to create payload object.\n"); + cJSON_Delete(root); + return ; + } + + cJSON *audio_convert_request = cJSON_CreateObject(); + if (payload == NULL) { + bk_printf("Failed to create payload object.\n"); + cJSON_Delete(root); + return ; + } + + cJSON_AddStringToObject(audio_convert_request, "audio_url", urlpath); + cJSON_AddNumberToObject(audio_convert_request, "bit_depth", 16); + cJSON_AddNumberToObject(audio_convert_request, "channels", 1); + cJSON_AddNumberToObject(audio_convert_request, "sample_rate", 16000); + + //if(outbound_attributes_format == attributes_format_OPUS) + // { + // cJSON_AddStringToObject(audio_convert_request, "target_format", "opus");//opus//pcm + //}else{ + + cJSON_AddStringToObject(audio_convert_request, "target_format", "opus"); + // } + + + cJSON_AddItemToObject(payload, "audio_convert_request", audio_convert_request); + + // 将 "payload" 对象添加到根对象中 + cJSON_AddItemToObject(root, "payload", payload); + + // 将 JSON 对象转换为字符串 + char *json_str = cJSON_Print(root); + if (json_str == NULL) { + bk_printf("Failed to print JSON object.\n"); + cJSON_Delete(root); + + } + AI_VC_send_data(json_str,strlen(json_str),AIC_WEBSOCKET_OPCODE_TEXT_FRAME);//发送数据 + + + // 释放内存 + free(json_str); + cJSON_Delete(root); +} + +//Audio.Completed 结束发送音频 +static void AI_VC_send_audio_completed(void) +{ + + VC_state = VC_State_SpeechEnd;//说结束 + // 创建根对象 + + cJSON *root = cJSON_CreateObject(); + if (root == NULL) { + bk_printf("Failed to create root object.\n"); + return ; + } + + // 设置 "event" 字段 + cJSON_AddStringToObject(root, "event", "audio.completed"); + + // 创建 "payload" 对象 + cJSON *payload = cJSON_CreateObject(); + if (payload == NULL) { + bk_printf("Failed to create payload object.\n"); + cJSON_Delete(root); + return ; + } + // 将 "payload" 对象添加到根对象中 + cJSON_AddItemToObject(root, "payload", payload); + + // 将 JSON 对象转换为字符串 + char *json_str = cJSON_Print(root); + if (json_str == NULL) { + bk_printf("Failed to print JSON object.\n"); + cJSON_Delete(root); + + } + AI_VC_send_data(json_str,strlen(json_str),AIC_WEBSOCKET_OPCODE_TEXT_FRAME);//发送数据 + // 释放内存 + free(json_str); + cJSON_Delete(root); +} +// //打断 +// static void AI_VC_send_cancel(void) +// { +// // 创建根对象 +// cJSON *root = cJSON_CreateObject(); +// if (root == NULL) { +// bk_printf("Failed to create root object.\n"); +// return ; +// } + +// // 设置 "event" 字段 +// cJSON_AddStringToObject(root, "event", "cancel"); + +// // 创建 "payload" 对象 +// cJSON *payload = cJSON_CreateObject(); +// if (payload == NULL) { +// bk_printf("Failed to create payload object.\n"); +// cJSON_Delete(root); +// return ; +// } +// // 将 "payload" 对象添加到根对象中 +// cJSON_AddItemToObject(root, "payload", payload); + +// // 将 JSON 对象转换为字符串 +// char *json_str = cJSON_Print(root); +// if (json_str == NULL) { +// bk_printf("Failed to print JSON object.\n"); +// cJSON_Delete(root); + +// } +// AI_VC_send_data(json_str,strlen(json_str),AIC_WEBSOCKET_OPCODE_TEXT_FRAME);//发送数据 + + +// // 释放内存 +// free(json_str); +// cJSON_Delete(root); +// } +//TTS播放 +static void VC_TTS_Play(const char *str) +{ + bk_printf("VC_TTS_Play:%s",str); + if(AI_TTS_str) + { + aic_free(AI_TTS_str); + AI_TTS_str = NULL; + } + AI_TTS_str = aic_zalloc(strlen(str)+1); + strcpy(AI_TTS_str,str); + //VC_record_End(); + VC_Play_End(); + websocket_deconnect_VC(); + AI_VC_start(0); +} +//pinpin发送 +void AI_VC_send_ping_ping(void) +{ + AI_VC_send_data("ping",strlen("ping"),AIC_WEBSOCKET_OPCODE_TEXT_FRAME);//发送数据 +} + +int send_count_pcm=0; + +int send_update=0;; + +static void AI_VC_send_task(void *thread_input)//websocket 发送线程 +{ + AI_VC_send_queue_t AI_VC_send_queue_data; + bk_printf("AI_VC_send_task go......"); + int ret = 0; + AI_VC_send_task_flag = 1; + while(1) + { + if(AI_VC_send_task_flag == 2)//要退出了 + break; + + if(AI_VC_send_queue && aos_recv_from_queue(AI_VC_send_queue,&AI_VC_send_queue_data,AOS_NO_WAIT) == AOS_SUCCESS) + { + + if(AI_client_VC && AI_VC_send_queue_data.data) + { + VC_pingping_timerout = 20; + if(inbound_attributes_format == attributes_format_OPUS&& AI_VC_send_queue_data.AIC_WEBSOCKET_OPCODE ==AIC_WEBSOCKET_OPCODE_BINARY_FRAME )//转码opus + { + char *opus_data = aic_malloc(OPUS_ENCODER_PACK_MS*16); + if(opus_data) + { + ret = opus_encode_data(AI_VC_send_queue_data.data,AI_VC_send_queue_data.len,OPUS_ENCODER_PACK_MS*32,opus_data,OPUS_ENCODER_PACK_MS*16); bk_printf("opus_encode_data1:len:%d",ret); if(ret >0) { @@ -1810,15 +2195,18 @@ static void AI_VC_send_task(void *thread_input)//websocket 发送线程 bk_printf("send ret=%d,len=%d,str=%s",ret,AI_VC_send_queue_data.len,AI_VC_send_queue_data.data); else if(AI_VC_send_queue_data.AIC_WEBSOCKET_OPCODE ==AIC_WEBSOCKET_OPCODE_BINARY_FRAME ) { - bk_printf("send ret=%d,len=%d",ret,AI_VC_send_queue_data.len); - // send_update+=AI_VC_send_queue_data.len; + send_update+=AI_VC_send_queue_data.len; + + bk_printf("send ret=%d,len=%d,%d",ret,AI_VC_send_queue_data.len,send_update); + + // send_count_pcm++; // bk_printf("send_count_pcm: %d len: %d !",send_count_pcm,send_update); - audio_data(AI_VC_send_queue_data.data,AI_VC_send_queue_data.len,25); + // audio_data(AI_VC_send_queue_data.data,AI_VC_send_queue_data.len,25); } if(AI_VC_send_queue_data.data) @@ -1869,564 +2257,115 @@ long getFileSize(char* filename) { u32 timer_ms22=0; + static void AI_VC_IOT_task(void *thread_input)//websocket 读线程 + { + + receive_iot_message(AI_client_IOT); - void send_express_str_chumo(int type,int mode){ - - - if(!ui_uart_handle) - return ; - - u8 cmd_ui[7]={0xAA,0x55,0xFF,0x02,0x08,0x01,0x0a}; - if(type==1&&mode==0){ - - #if SUPPORT_MOT - mot_nod_exp(11,2); - #endif - - // sleep - cmd_ui[4]=0x07; - cmd_ui[6]=0x09; - - } - - if(type==1&&mode==1){ - - #if SUPPORT_MOT - mot_nod_exp(12,2); - #endif - - cmd_ui[4]=0x06; - cmd_ui[6]=0x08; - - } - - if(type==2&&mode==0){ - - #if SUPPORT_MOT - mot_nod_exp(13,2); - #endif - - cmd_ui[4]=0x01; - cmd_ui[6]=0x03; - - } - - if(type==2&&mode==1){ - - #if SUPPORT_MOT - mot_nod_exp(14,2); - #endif - - cmd_ui[4]=0x01; - cmd_ui[6]=0x03; - - } - - if(type==0&&mode==0){ - - #if SUPPORT_MOT - mot_nod_exp(9,2); - #endif - - cmd_ui[4]=0x06; - cmd_ui[6]=0x08; - - } - - if(type==0&&mode==1){ - - #if SUPPORT_MOT - mot_nod_exp(10,2); - #endif - - cmd_ui[4]=0x03; - cmd_ui[6]=0x05; - - } - - - - uart_write(ui_uart_handle,cmd_ui, 7); } -void back_middle_statu_mot(){ - aos_sleep(1000); - mot_nod_exp(7,2); -} + static void AI_IOT_read_task(void *thread_input)//websocket 读线程 + { -void random_statu_mot(){ + int status; + static u8 *recv_buff = NULL; + + + if(recv_buff == NULL) + { + recv_buff = aic_malloc(recv_buff_mxa_len); + } + if(recv_buff == NULL) + { + bk_printf("AI_VC_read_task aic_malloc ERROR!!!!!!!!!!!!!!!!!!......"); + return; + } + WebSocketMessageType code; + bk_printf("AI_IOT_read_task go......"); + // AI_VC_read_task_flag = 1; + while (1) { + + if(AI_client_IOT) + { - //aos_sleep(1000); - u32 count_tmp = 0; - aos_get_queue_used_count(AI_VC_play_queue,&count_tmp); - - bk_printf("random_statu_mot....\n"); + memset(recv_buff,0,recv_buff_mxa_len); + // status = aic_websocket_recv(AI_VC_client_websocket_handle, recv_buff, sizeof(recv_buff), + // &code, AOS_WAIT_FOREVER,&result_val); + // bk_printf("AI_VC_read_task 1"); - if(count_tmp<=0) - return ; - //VC_END_play_timerout = 1; + // aos_sleep(50); - if(random_mt_test%3==0) - mot_nod_exp(8,2); + // u32 timer_ms11 = aos_get_tickcount(); - if(random_mt_test%3==1) - mot_nod_exp(15,2); + bk_printf("IOT_read_task...... 12"); - if(random_mt_test%3==2) - mot_nod_exp(16,2); + status = receive_websocket_message_V3(AI_client_IOT,recv_buff,recv_buff_mxa_len,&code); - random_mt_test++; + bk_printf("get iot message................................."); + bk_printf("bytes_received %02X %02X %02X %02X %02X %02X %02X %02X %02X ...\n",recv_buff[0],recv_buff[1],recv_buff[2],recv_buff[3],recv_buff[4],recv_buff[5],recv_buff[6],recv_buff[7],recv_buff[8]); -} + bk_printf("IOT_read_task...... 13"); + if(code == WS_TEXT)//字符串 + { + //bk_printf("AI_VC_read_task 3"); + bk_printf("read TEXT:status:%d,data:%s",status,recv_buff); + + }else{ -void send_express_str_xinxinmao(char *exp_str){ - - #if 1 - if(ui_uart_handle){ - u8 cmd_ui[7]={0xAA,0x55,0xFF,0x02,0x08,0x01,0x0a}; - - if(strstr(exp_str,"不理解")) - { - cmd_ui[4]=0x01; - cmd_ui[6]=0x03; - }else - if(strstr(exp_str,"发怒")) - { - cmd_ui[4]=0x02; - cmd_ui[6]=0x04; - }else - if(strstr(exp_str,"搞怪")) - { - cmd_ui[4]=0x03; - cmd_ui[6]=0x05; - }else - if(strstr(exp_str,"花痴")) - { - cmd_ui[4]=0x04; - cmd_ui[6]=0x05; - }else - if(strstr(exp_str,"惊喜")) - { - cmd_ui[4]=0x05; - cmd_ui[6]=0x07; - }else - if(strstr(exp_str,"惊讶")) - { - cmd_ui[4]=0x06; - cmd_ui[6]=0x08; - }else - if(strstr(exp_str,"卡通")) - { - cmd_ui[4]=0x07; - cmd_ui[6]=0x09; - }else - if(strstr(exp_str,"开心")||strstr(exp_str,"微笑")) - { - cmd_ui[4]=0x08; - cmd_ui[6]=0x0a; - }else - if(strstr(exp_str,"生气")) - { - cmd_ui[4]=0x09; - cmd_ui[6]=0x0b; - }else - if(strstr(exp_str,"眨眼")) - { - cmd_ui[4]=0x0a; - cmd_ui[6]=0x0c; - }else - if(strstr(exp_str,"很开心")) - { - cmd_ui[4]=0x0b; - cmd_ui[6]=0x0d; - }else - if(strstr(exp_str,"中立")) - { - cmd_ui[4]=0x0c; - cmd_ui[6]=0x0e; - } - - uart_write(ui_uart_handle,cmd_ui, 7); - } - - #else - - // 淡定:Calm - // 尴尬:Embarrass - // 开心:Happy - // 可爱:Cute - - - - // 孝豚 - if(ui_uart_handle){ - u8 cmd_ui[7]={0xAA,0x55,0xFF,0x02,0x08,0x01,0x0a}; - - // if(strstr(exp_str,"Calm")) - // { - // cmd_ui[4]=0x01; - // cmd_ui[6]=0x03; - // }else - // if(strstr(exp_str,"Embarrass")) - // { - // cmd_ui[4]=0x02; - // cmd_ui[6]=0x04; - // }else - // if(strstr(exp_str,"Happy")) - // { - // cmd_ui[4]=0x03; - // cmd_ui[6]=0x05; - // }else - // if(strstr(exp_str,"Cute")) - // { - // cmd_ui[4]=0x04; - // cmd_ui[6]=0x06; - // } - - // 01-Afraid 害怕-右 -// 02-Amused 有趣-右 -// 03-Angry 愤怒-右 -// 04-Bored 无聊-右 -// 05-Caring 关爱-右 -// 06-Confused 困惑-右 -// 07-Curious 惊喜-右 -// 08-Disgusted 厌恶-右 -// 09-dizzy 蚊香眼-右 -// 10-Doubtful 存疑-右 -// 11-Frowning 皱眉头-右 -// 12-Grimacing 苦着脸-右 -// 13-Happy 开心-右 -// 14-Neutral 中立-右 -// 15-Pensive 悲伤-右 -// 16-Relaxed 放松-右 -// 17-Sad 伤心-右 -// 18-Smiling 微笑-右 -// 19-Surprised 惊讶-右 -// 20-Tired 疲惫-右 -// 21-Winking 眨眼-右 - -// 01-Afraid 害怕-右 01 -// 02-Amused 有趣-右 02 -// 03-Angry 愤怒-右 15 -// 04-Bored 无聊-右 16 -// 05-Caring 关爱-右 05 -// 06-Confused 困惑-右 17 -// 07-Curious 惊喜-右 19 -// 08-Disgusted 厌恶-右 20 -// 09-dizzy 蚊香眼-右 21 -// 10-Doubtful 存疑-右 18 -// 11-Frowning 皱眉头-右 03 -// 12-Grimacing 苦着脸-右 04 -// 13-Happy 开心-右 12 -// 14-Neutral 中立-右 06 -// 15-Pensive 悲伤-右 07 -// 16-Relaxed 放松-右 08 -// 17-Sad 伤心-右 09 -// 18-Smiling 微笑-右 10 -// 19-Surprised 惊讶-右 11 -// 20-Tired 疲惫-右 13 -// 21-Winking 眨眼-右 14 - - bk_printf("send_express_str:text:%s",exp_str); - - if(strstr(exp_str,"Afraid")||strstr(exp_str,"害怕")) - { - cmd_ui[4]=0x01; - cmd_ui[6]=0x03; - }else - if(strstr(exp_str,"Amused")||strstr(exp_str,"有趣")) - { - cmd_ui[4]=0x02; - cmd_ui[6]=0x04; - }else - if(strstr(exp_str,"Angry")||strstr(exp_str,"愤怒")) - { - cmd_ui[4]=0x0f; - cmd_ui[6]=0x11; - }else - if(strstr(exp_str,"Bored")||strstr(exp_str,"无聊")) - { - cmd_ui[4]=0x10; - cmd_ui[6]=0x12; - }else - if(strstr(exp_str,"Caring")||strstr(exp_str,"关爱")) - { - cmd_ui[4]=0x05; - cmd_ui[6]=0x07; - }else - if(strstr(exp_str,"Confused")||strstr(exp_str,"困惑")) - { - cmd_ui[4]=0x11; - cmd_ui[6]=0x13; - }else - if(strstr(exp_str,"Curious")||strstr(exp_str,"惊喜")) - { - cmd_ui[4]=0x13; - cmd_ui[6]=0x15; - }else - if(strstr(exp_str,"Disgusted")||strstr(exp_str,"厌恶")) - { - cmd_ui[4]=0x14; - cmd_ui[6]=0x16; - }else - if(strstr(exp_str,"dizzy")||strstr(exp_str,"蚊香眼")) - { - cmd_ui[4]=0x15; - cmd_ui[6]=0x17; - }else - if(strstr(exp_str,"Doubtful")||strstr(exp_str,"存疑")) - { - cmd_ui[4]=0x12; - cmd_ui[6]=0x14; - }else - if(strstr(exp_str,"Frowning")||strstr(exp_str,"皱眉头")) - { - cmd_ui[4]=0x03; - cmd_ui[6]=0x05; - }else - if(strstr(exp_str,"Grimacing")||strstr(exp_str,"苦着脸")) - { - cmd_ui[4]=0x04; - cmd_ui[6]=0x06; - }else - if(strstr(exp_str,"Happy")||strstr(exp_str,"开心")) - { - cmd_ui[4]=0x0c; - cmd_ui[6]=0x0e; - }else - if(strstr(exp_str,"Neutral")||strstr(exp_str,"中立")) - { - cmd_ui[4]=0x06; - cmd_ui[6]=0x08; - }else - if(strstr(exp_str,"Pensive")||strstr(exp_str,"悲伤")) - { - cmd_ui[4]=0x07; - cmd_ui[6]=0x09; - }else - if(strstr(exp_str,"Relaxed")||strstr(exp_str,"放松")) - { - cmd_ui[4]=0x08; - cmd_ui[6]=0x0a; - }else - if(strstr(exp_str,"Sad")||strstr(exp_str,"伤心")) - { - cmd_ui[4]=0x09; - cmd_ui[6]=0x0b; - }else - if(strstr(exp_str,"Smiling")||strstr(exp_str,"微笑")) - { - cmd_ui[4]=0x0a; - cmd_ui[6]=0x0c; - }else - if(strstr(exp_str,"Surprised")||strstr(exp_str,"惊讶")) - { - cmd_ui[4]=0x0b; - cmd_ui[6]=0x0d; - }else - if(strstr(exp_str,"Tired")||strstr(exp_str,"疲惫")) - { - cmd_ui[4]=0x0d; - cmd_ui[6]=0x0f; - }else - if(strstr(exp_str,"Winking")||strstr(exp_str,"眨眼")) - { - cmd_ui[4]=0x0c; - cmd_ui[6]=0x0e; - } - - uart_write(ui_uart_handle,cmd_ui, 7); - } - - - #endif - - -} - -void send_express_str(char *exp_str){ - - // texts = ["neutral","happy","laughing","funny","sad","angry", - // "crying","loving","embarrassed","surprised","shocked","thinking", - // "winking","cool","relaxed","","confused",""] - - /// happy 🙂 -//cue 😸 -//surprised 😲 -//angry 😠 -//crying 😭 -//smirk😏 -//dissatisfied😒 - -// 001序列帧 开心002序列帧 卖萌003序列帧 惊喜004序列帧 生气004序列帧 右眼生气005序列帧 哭泣006序列帧 坏笑007序列帧 不满 - #if 1 - if(ui_uart_handle){ - u8 cmd_ui[7]={0xAA,0x55,0xFF,0x02,0x01,0x01,0x03}; - - if(strstr(exp_str,"开心")||strstr(exp_str,"happy")) - { - - - #if SUPPORT_MOT - mot_nod_exp(8,2); - #endif - - // sleep - cmd_ui[4]=0x01; - cmd_ui[6]=0x03; - - }else - if(strstr(exp_str,"卖萌")||strstr(exp_str,"cue")) - { - - #if SUPPORT_MOT - mot_nod_exp(5,2); // mot_nod_exp(7,2); - #endif - - cmd_ui[4]=0x02; - cmd_ui[6]=0x04; - }else - if(strstr(exp_str,"惊喜")||strstr(exp_str,"surprised")) - { - cmd_ui[4]=0x03; - cmd_ui[6]=0x05; - - #if SUPPORT_MOT - mot_nod_diantou(2); - #endif - - }else - if(strstr(exp_str,"生气")||strstr(exp_str,"angry")) - { - cmd_ui[4]=0x04; - cmd_ui[6]=0x06; - #if SUPPORT_MOT - mot_nod_exp(6,2); - #endif - - }else - if(strstr(exp_str,"哭泣")||strstr(exp_str,"crying")) - { - cmd_ui[4]=0x05; - cmd_ui[6]=0x07; - - #if SUPPORT_MOT - mot_nod_taitou(2); - #endif - - }else - if(strstr(exp_str,"坏笑")||strstr(exp_str,"smirk")) - { - cmd_ui[4]=0x06; - cmd_ui[6]=0x08; - - #if SUPPORT_MOT - mot_nod_exp(5,2); - #endif - }else - if(strstr(exp_str,"不满")||strstr(exp_str,"dissatisfied")) - { - cmd_ui[4]=0x07; - cmd_ui[6]=0x09; - - #if SUPPORT_MOT - mot_nod_exp(4,2); - #endif - - }else if(strstr(exp_str,"点头")){ - - mot_nod_yaotou(2); - - }else if(strstr(exp_str,"摇头")){ - - mot_nod_diantou(2); - - }else if(strstr(exp_str,"抬头")){ - - - mot_nod_ditou(2); - - }else if(strstr(exp_str,"低头")){ - - mot_nod_taitou(2); - - }else if(strstr(exp_str,"向左转")){ - - mot_nod_exp(15,2); - - - }else if(strstr(exp_str,"向右转")){ - - mot_nod_exp(16,2); - - - } - - - uart_write(ui_uart_handle,cmd_ui, 7); - } - #else - - if(ui_uart_handle){ - u8 cmd_ui[7]={0xAA,0x55,0xFF,0x02,0x08,0x01,0x0a}; - - if(strstr(exp_str,"伤心")||strstr(exp_str,"sad")) - { - cmd_ui[4]=0x01; - cmd_ui[6]=0x03; - }else - if(strstr(exp_str,"生气")||strstr(exp_str,"angry")) - { - cmd_ui[4]=0x03; - cmd_ui[6]=0x05; - }else - if(strstr(exp_str,"困惑")||strstr(exp_str,"confused")||strstr(exp_str,"embarrassed")) - {//embarrassed - cmd_ui[4]=0x06; - cmd_ui[6]=0x08; - }else - if(strstr(exp_str,"失望")||strstr(exp_str,"crying")) - { - cmd_ui[4]=0x08; - cmd_ui[6]=0x0a; - }else - if(strstr(exp_str,"开心")||strstr(exp_str,"happy")||strstr(exp_str,"loving") - ||strstr(exp_str,"funny")||strstr(exp_str,"laughing")||strstr(exp_str,"cool")) //laughing "funny loving - { //cool - cmd_ui[4]=0x0d; - cmd_ui[6]=0x0f; - }else - if(strstr(exp_str,"默认")||strstr(exp_str,"neutral")||strstr(exp_str,"thinking") - ||strstr(exp_str,"winking")||strstr(exp_str,"relaxed")) - {//thinking winking relaxed - cmd_ui[4]=0x0e; - cmd_ui[6]=0x10; - }else - if(strstr(exp_str,"惊恐")||strstr(exp_str,"surprised")||strstr(exp_str,"shocked")) - {//shocked - cmd_ui[4]=0x13; - cmd_ui[6]=0x15; - } - uart_write(ui_uart_handle,cmd_ui, 7); - } + if(status>8){ - #endif + bk_printf("read TEXT:status:%d",status); -} + char jsonstr[500]={0}; + + memcpy(jsonstr,recv_buff+8,status-8); + + bk_printf("read json TEXT:status:%s",jsonstr); + + deal_iot_receive(jsonstr); + + } + + } + + if(status>0) + { + + + }else{ + + break; + } + + aos_sleep(100); + }else{ + + break; + } + + } + if(recv_buff) + { + aic_free(recv_buff); + recv_buff = NULL; + } + + // bk_printf("AI_VC_read_task exit\n"); + // AI_VC_read_task_flag=3; + } static void AI_VC_read_task(void *thread_input)//websocket 读线程 { int status; static u8 *recv_buff = NULL; - AI_VC_stata=1; if(recv_buff == NULL) { @@ -2454,56 +2393,39 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 // aos_sleep(50); - u32 timer_ms11 = aos_get_tickcount(); + // u32 timer_ms11 = aos_get_tickcount(); - //bk_printf("AI_VC_read_task 12"); + // bk_printf("AI_VC_read_task 12"); status = receive_websocket_message(AI_client_VC,recv_buff,recv_buff_mxa_len,&code); - //bk_printf("AI_VC_read_task 13"); + // bk_printf("AI_VC_read_task 13"); - u32 timer_ms22 = aos_get_tickcount(); + // u32 timer_ms22 = aos_get_tickcount(); - int duration_temp=timer_ms22-timer_ms11; + // int duration_temp=timer_ms22-timer_ms11; - aos_sleep(15); + // aos_sleep(15); - if(duration_temp>500) - bk_printf("receive_websocket_message %d ms",timer_ms22-timer_ms11); + // if(duration_temp>500) + // bk_printf("receive_websocket_message %d ms",timer_ms22-timer_ms11); if(status>0) { - - - close_timerout = 305; - - if(is_dialog_status==0){ - - sleep_chumo_timerout=300; - - }else{ - - if(vc_cfg.VC_mode==1){ - - if(ddh_is_close_dialog==0) - close_timerout=5; - - // else{ - // } - - } - } - + close_timerout = 180; if(code == WS_TEXT)//字符串 { //bk_printf("AI_VC_read_task 3"); - bk_printf("read TEXT:status:%d,data:%s",status,recv_buff); + + if(status<200) + bk_printf("read TEXT:status:%d,data:%s",status,recv_buff); + + if(strstr(recv_buff,"\"started\""))//开始 { - - tts_start_timerout=0; - if(issend_start_up==0){ + + if(issend_start_up==0){ issend_start_up=1; @@ -2512,6 +2434,34 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 } + if(need_play_is_music_status==1){ + + need_play_is_music_status=0; + + AI_VC_send_music_start(mp3_path_str); + + } + + // if(is_need_tip){ + + // is_need_tip=0; + + // if(vc_cfg.VC_mode == 0) + // { + // AI_AMP_MSG_put("当前为连续对话模式。",strlen("当前为连续对话模式。"),VC_TTS_PLAY); + + // }else if(vc_cfg.VC_mode == 1) + // { + // AI_AMP_MSG_put("当前为单对话模式。",strlen("当前为单对话模式。"),VC_TTS_PLAY); + + // }else + // { + // AI_AMP_MSG_put("当前为按键打断模式。",strlen("当前为按键打断模式。"),VC_TTS_PLAY); + // } + + // //AI_AMP_MSG_put("提醒对话模式。",strlen("提醒对话模式。"),VC_TTS_PLAY); + + // } if(AI_TTS_str) { @@ -2529,21 +2479,10 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 VC_state = VC_State_Listening; else if(vc_cfg.VC_mode == 2 )//连续对话模式,按键打断 VC_state = VC_State_Listening; - - // back_middle_statu_mot(); - - // AI_AMP_MSG_put(0,0,AI_MOT_BACK_MID); + } - }else if(strstr(recv_buff,"\"asr.started\""))//asr开始 { - - // if(AI_ASR_str_tmp) - // { - // memset(AI_ASR_str_tmp,0,AI_ASR_STR_MAX_LEN); - // } - - has_tmp_result=0; if(vc_cfg.VC_mode == 1 || vc_cfg.is_VAD ==1)//长按模式,或开机本地vad模式 VC_state = VC_State_SpeechIng; }else if(strstr(recv_buff,"\"asr.result\"")) @@ -2554,9 +2493,6 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 if(str_tmp) { //bk_printf("content!!"); - - has_tmp_result=1; - str_tmp += strlen("\"content\":\""); int str_tmp_len = str_count(str_tmp,'\"'); //存asr结果 @@ -2574,7 +2510,7 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 { VC_state = VC_State_ASR_End; - bk_printf("AI_ASR_str%s AI_ASR_str_tmp %s",AI_ASR_str,AI_ASR_str_tmp); + // play_file_stream_data("C:/vadend.pcm"); C:/romvadend.pcm if(AI_ASR_str && AI_ASR_str_tmp) { int ret = check_text(AI_ASR_str_tmp,strlen(AI_ASR_str_tmp)) ; @@ -2585,19 +2521,17 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 break; } - if(VAD_time_count <= VAD_TIMEOUT)//时间间隔短,认为是一次对话,拼接内容 + if(VAD_time_count <= VAD_TIMEOUT )//时间间隔短,认为是一次对话,拼接内容 { - if(strlen(AI_ASR_str_tmp)==0){ - + if(strlen(AI_ASR_str_tmp)==0){ - // VC_state=VC_State_Listening; - bk_printf("没有识别结果"); + VC_state=VC_State_Listening; - AI_AMP_MSG_put("没听清,请再说一遍",strlen("没听清,请再说一遍"),VC_CONNECT_ERROR); + bk_printf("没有识别结果"); - } + } if(strlen(AI_ASR_str) +strlen(AI_ASR_str_tmp)> AI_ASR_STR_MAX_LEN-1)//超出缓存长度,清零 { @@ -2609,53 +2543,31 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 bk_printf("vad间隔时间短拼接asr结果:%s",AI_ASR_str); + + // IOT_V3_update_statu(1,"thinking",""); + // play_file_stream_data("C:/vadend.pcm"); }else//超时,不用拼接 { - strncpy(AI_ASR_str,AI_ASR_str_tmp,AI_ASR_STR_MAX_LEN); + strncpy(AI_ASR_str,AI_ASR_str_tmp,AI_ASR_STR_MAX_LEN); - if(strlen(AI_ASR_str_tmp)==0){ + if(strlen(AI_ASR_str_tmp)==0){ - // VC_state=VC_State_Listening; + VC_state=VC_State_Listening; - bk_printf("没有识别结果"); - - AI_AMP_MSG_put("没听清,请再说一遍",strlen("没听清,请再说一遍"),VC_CONNECT_ERROR); + bk_printf("没有识别结果"); } - - bk_printf("vad间隔时间长,判断为两次对话:%s",AI_ASR_str); + bk_printf("vad间隔时间长,判断为两次对话:%s",AI_ASR_str); } - #if BK_SOCKET_IOT - IOT_update_statu(1,"thinking",""); - #endif - - - } - - - bk_printf("002AI_ASR_str%s AI_ASR_str_tmp %s",AI_ASR_str,AI_ASR_str_tmp); - bk_printf("play_file_stream_data:%d",VC_Play_flag); - - if(has_tmp_result==0) - AI_AMP_MSG_put("没听清,请再说一遍",strlen("没听清,请再说一遍"),VC_CONNECT_ERROR); - else - if(VC_Play_flag==1&&strlen(AI_ASR_str_tmp)!=0)//VC_Play_flag==1&& - play_file_stream_data("C:/vadend.pcm"); - //else{ - - - // if(strlen(AI_ASR_str_tmp)==0){ - - // // VC_state=VC_State_Listening; - // bk_printf("没有识别结果"); + IOT_V3_update_statu(1,"thinking",""); - // AI_AMP_MSG_put("没听清,请再说一遍",strlen("没听清,请再说一遍"),VC_CONNECT_ERROR); - - // } - // play_audio_file("C:/vadend.mp3"); + if(VC_Play_flag==1&&strlen(AI_ASR_str_tmp)!=0) + play_file_stream_data("O:/romoutput.pcm");//C:/vadend.pcm + // else{ // } + } } else if(strstr(recv_buff,"\"vad.active\""))//vad触发 { @@ -2667,6 +2579,13 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 } else if(strstr(recv_buff,"\"tts.started\""))//tts开始 { + + + + u32 timer_ms22 = aos_get_tickcount(); + + bk_printf("tts.started_vad:%d",timer_ms22); + if(AI_VC_play_queue != NULL) { char count_t= 200; @@ -2687,9 +2606,11 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 VC_state = VC_State_TTSStart; play_data_len = 0; - #if BK_SOCKET_IOT - IOT_update_statu(1,"speaking",""); - #endif + + issend_start_up=2; + + IOT_V3_update_statu(1,"speaking",""); + one_receive_bin=0; if(outbound_attributes_format == attributes_format_OPUS){ @@ -2698,16 +2619,15 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 opus_clean(); - - + opus_encode_len=0; opus_decode_len=0; - // if(save_temp_tts==NULL){ + // if(save_temp_tts==NULL){ - // save_temp_tts=aic_malloc(900000); - // } + // save_temp_tts=aic_malloc(900000); + // } } @@ -2721,46 +2641,44 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 // AI_AMP_MSG_put(0,0,VC_PLAY_START);//打开声音 startsave_tts=0; - #if BK_SOCKET_IOT - IOT_update_statu(1,"idle",""); - #endif - // fp_tts_save=fopen("C:/cmd_local_301.pcm","wb"); - // bk_printf("C:/cmd_local_301.pcm %d",one_receive_bin); + // IOT_V3_update_statu(1,"idle",""); - // fwrite(save_temp_tts,1,one_receive_bin,fp_tts_save); + // fp_tts_save=fopen("C:/cmd_local_301.pcm","wb"); - // startsave_tts=one_receive_bin; + // bk_printf("C:/cmd_local_301.pcm %d",one_receive_bin); - VC_state = VC_State_End; - - // if(fp_tts_save) - // fclose(fp_tts_save); + // fwrite(save_temp_tts,1,one_receive_bin,fp_tts_save); + + // startsave_tts=one_receive_bin; + + + + + + // if(fp_tts_save) + // fclose(fp_tts_save); - // fp_tts_save=NULL; + // fp_tts_save=NULL; // aos_sleep(500); // bk_printf("C:/cmd_local_301.pcm %d",getFileSize("C:/cmd_local_301.pcm")); - + VC_state = VC_State_End; + } else if(strstr(recv_buff,"\"completed\""))//结束 { - VC_state = VC_State_End;// + VC_state = VC_State_End; + + if(issend_start_up==0){ + issend_start_up=1; - if(vc_cfg.VC_mode==0&&strlen(AI_ASR_str_tmp)==0){ + AI_VC_send_startup(); - u32 count_tmp = 0; - aos_get_queue_used_count(AI_VC_play_queue,&count_tmp); - - bk_printf("连续对话模式没有语音....\n"); - if(count_tmp<=0) - VC_END_play_timerout = 1; - } - //AI_AMP_MSG_put(0,0,VC_RECORD_START);//打开录音 }else if(strstr(recv_buff,"\"event\":\"failed\""))//接口报错了 { @@ -2778,7 +2696,7 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 { // str_tmp+=strlen("\"message\":\""); // int count = strlen(str_tmp); - AI_AMP_MSG_put("没听清,请再说一遍",strlen("没听清,请再说一遍"),VC_CONNECT_ERROR); + AI_AMP_MSG_put("服务异常了,请重试",strlen("服务异常了,请重试"),VC_CONNECT_ERROR); } } @@ -2790,9 +2708,6 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 // str_tmp = strstr(recv_buff,"\"param_json\""); char *str_tmp = strstr(recv_buff,"\"https"); - char *str_tmp_motion = strstr(recv_buff,"\"emotion"); - - if(str_tmp) { @@ -2808,34 +2723,114 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 bk_printf("the mp3_path is %s",mp3_path); - AI_VC_send_music_start(mp3_path); + AI_VC_send_music_start("http://qipaiai-oss1.tos-cn-beijing.volces.com/qi_pai_ringtone/2025_11_07/774578468192129024default_ring.pcm"); } - if(str_tmp_motion){ + str_tmp = strstr(recv_buff,"\"alarm_timer"); + + if(str_tmp) + { - char emotion_str[200]; - memset(emotion_str,0,200); + char mp3_path[200]; - char *str_tmp1 = strstr(recv_buff,"\"text"); - //bk_printf("content!!"); - // str_tmp += strlen("\"params_json")+6; - int str_tmp_len = str_count(str_tmp1+15,'\"'); + char alarm_content[200]; + memset(mp3_path,0,200); + + memset(alarm_content,0,200); + // bk_printf("content!!"); + // str_tmp += strlen("\"params_json")+6; + int str_tmp_len = str_count(str_tmp+22,'\"'); //存asr结果 - if(str_tmp_len>3){ - memcpy(emotion_str,str_tmp1+15,str_tmp_len-3); + if(str_tmp_len>3) + memcpy(mp3_path,str_tmp+22,str_tmp_len-3); //AI_ASR_str_tmp[str_tmp_len] = 0; - bk_printf("the emotion text len is %s %d",emotion_str,str_tmp_len); + + bk_printf("the alarm_timer is %s",mp3_path); - send_express_str(emotion_str); + // vc_cfg.alarm_name[vc_cfg.alarm_count]={0}; - } + str_tmp = strstr(recv_buff,"\"alarm_content"); + + str_tmp_len = str_count(str_tmp+24,'\"'); + //存asr结果 + + if(str_tmp_len>3) + memcpy(alarm_content,str_tmp+24,str_tmp_len-3); + + // AI_ASR_str_tmp[str_tmp_len] = 0; + + bk_printf("the alarm_content is %s",alarm_content); + + + if(vc_cfg.alarm_count<5){ + + memset(vc_cfg.alarm_name[vc_cfg.alarm_count],0,50); + + memcpy(vc_cfg.alarm_name[vc_cfg.alarm_count],mp3_path,strlen(mp3_path)); + + memset(vc_cfg.alarm_content[vc_cfg.alarm_count],0,200); + + memcpy(vc_cfg.alarm_content[vc_cfg.alarm_count],alarm_content,strlen(alarm_content)); + + vc_cfg.alarm_count++; + save_VC_cfg(); + + } + + + + // memcpy(); + + + play_file_stream_data("C:/alarm.pcm"); + + // alarm.pcm + + // AI_VC_send_music_start("http://qipaiai-oss1.tos-cn-beijing.volces.com/qi_pai_ringtone/2025_11_07/774578468192129024default_ring.pcm"); + } + }else if(strstr(recv_buff,"\"event\":\"llm.completed\""))//接口报错了 + { + + // char *str_tmp = NULL; + + // bk_printf("the express_str exist1"); + + // str_tmp = strstr(recv_buff,"\"param_json\""); + // char *str_tmp = strstr(recv_buff,"("); + + // if(str_tmp) + // { + + // bk_printf("the express_str exist2 \n"); + // char express_str[200]; + // memset(express_str,0,200); + // //bk_printf("content!!"); + // // str_tmp += strlen("\"params_json")+6; + + // char *str_tmp1=strstr(recv_buff,")"); + // // int str_tmp_len = str_count(str_tmp+1,')'); + + // int str_tmp_len = str_tmp1-str_tmp; + // //存asr结果 + + // memcpy(express_str,str_tmp+1,str_tmp_len); + // // //AI_ASR_str_tmp[str_tmp_len] = 0; + + // bk_printf("the express_str3 is [%s]",express_str); + + // // AI_VC_send_music_start(mp3_path); + + // send_express_str(express_str); + + // } + } } @@ -2844,23 +2839,24 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 - // if(one_receive_bin==0) - // timer_ms21=aos_get_tickcount(); + if(one_receive_bin==0) + timer_ms21=aos_get_tickcount(); - // one_receive_bin+=status; + // one_receive_bin+=status; - // timer_ms22=aos_get_tickcount(); + timer_ms22=aos_get_tickcount(); // u8 play_length_time=one_receive_bin/32; + one_receive_bin++; - // if((one_receive_bin/32)<(timer_ms22-timer_ms21)) - // bk_printf("read BIN status:%d,code:%d!!!!!!",status,code); + // if((one_receive_bin/32)<(timer_ms22-timer_ms21)) + bk_printf("read BIN status:%d,code:%d!!!!!!",one_receive_bin*60,timer_ms22-timer_ms21); - // VC_pingping_timerout = 20; + // VC_pingping_timerout = 20; - // if(startsave_tts==1){ + // if(startsave_tts==1){ // if(fp_tts_save){ @@ -2876,18 +2872,27 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 // if(one_receive_bin+status<900000) // memcpy(save_temp_tts+one_receive_bin,recv_buff,status); - one_receive_bin+=status; + // one_receive_bin+=status; + + // u32 timer_ms22 = aos_get_tickcount(); - // bk_printf("ogg_opus_decode_data %d...",one_receive_bin); + // bk_printf("ogg_opus_decode_data vad %d ...",timer_ms22); + + // bk_printf("sum_opus_decode_data %d...",one_receive_bin); // memcpy(save_temp_tts); // audio_data(recv_buff,status,26); - //ogg_opus_decode_data(recv_buff,status); + // ogg_opus_decode_data(recv_buff,status); + + if(codec_tts==1) + my_opus_decode_data(recv_buff,status); + else + ogg_opus_decode_data(recv_buff,status); - my_opus_decode_data(recv_buff,status); + play_data_len+=1920; // if(fp_tts_save){ // bk_printf("save tts!!!"); @@ -2914,7 +2919,7 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 if(AI_client_VC != NULL) { bk_printf("AI_VC_read_task:vc连接断开了"); - AI_AMP_MSG_put("没听清,请再说一遍",strlen("没听清,请再说一遍"),VC_CONNECT_ERROR); + AI_AMP_MSG_put("vc连接断开了",strlen("vc连接断开了"),VC_CONNECT_ERROR); }else{ bk_printf("AI_VC_read_task:客户端主动断开连接了"); } @@ -2937,8 +2942,6 @@ static void AI_VC_read_task(void *thread_input)//websocket 读线程 } bk_printf("AI_VC_read_task exit\n"); AI_VC_read_task_flag=3; - - AI_VC_stata=0; } @@ -2977,7 +2980,7 @@ static void AI_VC_record_task(void *thread_input)//录音线程 ret = app_audio_read(APP_AUDIO_TYPE_STREAM_DUPLEX, vrecord_buf, 3200, 1010); - audio_data(vrecord_buf,ret,23); + // audio_data(vrecord_buf,ret,23); // u32 timer_ms = aos_get_tickcount(); // bk_printf("%d:ret=%d",timer_ms,ret); @@ -2989,54 +2992,19 @@ static void AI_VC_record_task(void *thread_input)//录音线程 aos_sleep(1); continue; } - - if(is_dialog_status==1){ - - if(vc_cfg.is_KWS) - { - int KWS_time = aos_get_tickcount(); - // bk_printf("run_kws1: KWS_time:%d,data_len:%d",KWS_time,ret); - run_kws((int16_t *)vrecord_buf,ret/2); - int kws_status = kws_detect(); - // bk_printf("run_kws2:end_time:%d ,kws_status:%d",aos_get_tickcount() - KWS_time,kws_status); - if (kws_status == 1) { - - is_dialog_status=0; - bk_printf("!!!!!!!!!!!!!!!!!!!!!!离线语音识别打断了!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n\n"); - kws_clear(); - - AI_AMP_MSG_put("我来了。",strlen("我来了。"),VC_TTS_PLAY); - } - } - continue; - - } - - - + if((vc_cfg.VC_mode == 0 || vc_cfg.VC_mode == 2)&& vc_cfg.is_VAD == 1)//VAD逻辑:先判断有没有有效数据,触发了有效数据才发送 { - if(vc_cfg.VC_mode == 2 && VC_state > VC_State_SpeechEnd )//按钮打断模式,tts播放时禁止打断,不输入语音 - { + if(vc_cfg.VC_mode == 2 && VC_state > VC_State_SpeechEnd )//按钮打断模式,tts播放时禁止打断,不输入语音 + continue; - if(vc_cfg.is_KWS) - { - int KWS_time = aos_get_tickcount(); - // bk_printf("run_kws1: KWS_time:%d,data_len:%d",KWS_time,ret); - run_kws((int16_t *)vrecord_buf,ret/2); - int kws_status = kws_detect(); - // bk_printf("run_kws2:end_time:%d ,kws_status:%d",aos_get_tickcount() - KWS_time,kws_status); - if (kws_status == 1) { + if(is_music_status==1) + continue; - is_dialog_status=0; - bk_printf("!!!!!!!!!!!!!!!!!!!!!!离线语音识别打断了!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n\n"); - kws_clear(); + if(issend_start_up<2) { - AI_AMP_MSG_put("我在呢。",strlen("我在呢。"),VC_TTS_PLAY); - } - } continue; - } + } // 每次获得语音后调用, 语音长度最好小于100ms // wave为u8*或void*指针时需要 / 2 //int vad_test_time = aos_get_tickcount(); @@ -3048,6 +3016,8 @@ static void AI_VC_record_task(void *thread_input)//录音线程 // audio_data(vrecord_buf,ret,23); if (vad_status_t == 2) {//说话停止 + + bk_printf("说话停止......"); vad_clear(); if(VAD_status == 1)//清空buff { @@ -3062,9 +3032,7 @@ static void AI_VC_record_task(void *thread_input)//录音线程 } ret = sizeof(vrecord_buf); } - - - AI_VC_put_record_data(vrecord_buf,ret); + AI_VC_put_record_data(vrecord_buf,ret); } VAD_status = 2; // audio_data(vrecord_buf,ret,21); @@ -3088,25 +3056,21 @@ static void AI_VC_record_task(void *thread_input)//录音线程 { unsigned int r_len = bk_rb_read(VAD_rb_data,vad_r_tmp,2560); - audio_data(vad_r_tmp,r_len,21); + // audio_data(vad_r_tmp,r_len,21); //AI_VC_send_data(vad_r_tmp,r_len,AIC_WEBSOCKET_OPCODE_BINARY_FRAME);//发送缓冲数据 - - AI_VC_put_record_data(vad_r_tmp,r_len);//入队缓冲数据 - - // if(vc_cfg.is_KWS) - // { - // int KWS_time = aos_get_tickcount(); - // bk_printf("run_kws1: KWS_time:%d,data_len:%d",KWS_time,r_len); - // run_kws((int16_t *)vad_r_tmp,r_len/2); - // int kws_status = kws_detect(); - // bk_printf("run_kws2:end_time:%d ,kws_status:%d",aos_get_tickcount() - KWS_time,kws_status); - // if (kws_status == 1) { - - - // bk_printf("!!!!!!!!!!!!!!!!!!!!!!离线语音识别打断了!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n\n"); - // kws_clear(); - // } - // } + AI_VC_put_record_data(vad_r_tmp,r_len);//入队缓冲数据 + if(vc_cfg.is_KWS) + { + int KWS_time = aos_get_tickcount(); + bk_printf("run_kws1: KWS_time:%d,data_len:%d",KWS_time,r_len); + run_kws((int16_t *)vad_r_tmp,r_len/2); + int kws_status = kws_detect(); + bk_printf("run_kws2:end_time:%d ,kws_status:%d",aos_get_tickcount() - KWS_time,kws_status); + if (kws_status == 1) { + bk_printf("!!!!!!!!!!!!!!!!!!!!!!离线语音识别打断了!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n\n"); + kws_clear(); + } + } }else @@ -3119,27 +3083,22 @@ static void AI_VC_record_task(void *thread_input)//录音线程 VAD_status = 1; } - - AI_VC_put_record_data(vrecord_buf,ret); - - audio_data(vrecord_buf,ret,21); - // if(vc_cfg.is_KWS) - // { - // int KWS_time = aos_get_tickcount(); - // bk_printf("run_kws1: KWS_time:%d,data_len:%d",KWS_time,ret); - // run_kws((int16_t *)vrecord_buf,ret/2); - // int kws_status = kws_detect(); - // bk_printf("run_kws2:end_time:%d ,kws_status:%d",aos_get_tickcount() - KWS_time,kws_status); - // if (kws_status == 1) { - - - // bk_printf("!!!!!!!!!!!!!!!!!!!!!!离线语音识别打断了!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n\n"); - // kws_clear(); - // } - // } + AI_VC_put_record_data(vrecord_buf,ret); + // audio_data(vrecord_buf,ret,21); + if(vc_cfg.is_KWS) + { + int KWS_time = aos_get_tickcount(); + bk_printf("run_kws1: KWS_time:%d,data_len:%d",KWS_time,ret); + run_kws((int16_t *)vrecord_buf,ret/2); + int kws_status = kws_detect(); + bk_printf("run_kws2:end_time:%d ,kws_status:%d",aos_get_tickcount() - KWS_time,kws_status); + if (kws_status == 1) { + bk_printf("!!!!!!!!!!!!!!!!!!!!!!离线语音识别打断了!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n\n"); + kws_clear(); + } + } //bk_printf("VAD:检测到说话了"); - }else if(vad_status_t == 0 )//m没有说话 { @@ -3157,49 +3116,25 @@ static void AI_VC_record_task(void *thread_input)//录音线程 bk_rb_read(VAD_rb_data,vad_tmp,ret); aic_free(vad_tmp); } - //bk_printf("缓存太大,先出队"); - bk_rb_write(VAD_rb_data,vrecord_buf,ret); - } - } - VAD_status =0; - } - u32 count_tmp = 0; - if(AI_VC_record_tmp_queue) - aos_get_queue_used_count(AI_VC_record_tmp_queue,&count_tmp); - //bk_printf("count_tmp:%d,VC_state:%d",count_tmp,VC_state); - if(count_tmp>0)//有有效录音数据 - { - - if(VC_state >= VC_State_TTSStart) - { - char count_tmp12 = count_tmp; - - bk_printf("count_tmp:%d,VC_state:%d",count_tmp,VC_state); - - while(count_tmp12 --) - { - - if(count_tmp12<15) - break; - - if(aos_recv_from_queue(AI_VC_record_tmp_queue,&AI_VC_play_record_data,AOS_NO_WAIT) == AOS_SUCCESS)//有有效录音数据 - { - // audio_data(AI_VC_play_record_data.data,AI_VC_play_record_data.len,22); - - // AI_VC_send_data(AI_VC_play_record_data.data,AI_VC_play_record_data.len,AIC_WEBSOCKET_OPCODE_BINARY_FRAME); - if(AI_VC_play_record_data.data) - aic_free(AI_VC_play_record_data.data); - }else - break; + //bk_printf("缓存太大,先出队"); + bk_rb_write(VAD_rb_data,vrecord_buf,ret); } + } + VAD_status =0; + } + u32 count_tmp = 0; + if(AI_VC_record_tmp_queue) + aos_get_queue_used_count(AI_VC_record_tmp_queue,&count_tmp); + //bk_printf("count_tmp:%d,VC_state:%d",count_tmp,VC_state); + if(count_tmp>0)//有有效录音数据 + { + if(VC_state >= VC_State_TTSStart)// + { VC_state = VC_State_None; - bk_printf("VAD:vad_status_t:%d",vad_status_t); + bk_printf("VAD:vad_status_t:%d",vad_status_t); bk_printf("VAD:发送打断对话"); AI_AMP_MSG_put(0,0,VC_Cancel);//发送打断 - - AI_AMP_MSG_put(0,0,AI_MOT_BACK_MID); - } else if(VC_state == VC_State_SpeechIng )//可以发数据了 { @@ -3217,29 +3152,20 @@ static void AI_VC_record_task(void *thread_input)//录音线程 break; } } - else if(VC_state == VC_State_Listening) //|| (VC_state >= VC_State_ASR_End && VC_state < VC_State_TTSStart) + else if(VC_state == VC_State_Listening || (VC_state >= VC_State_ASR_End && VC_state < VC_State_TTSStart)) { AI_VC_send_audio_create();//发送开始音频 - bk_printf("VAD:发送开始音频"); - }else { if(VC_state > VC_State_SpeechStart) - { bk_printf("VAD:有数据还没发:VC_state:%d\r\n\r\n",VC_state); - - // AI_AMP_MSG_put("没听清,请再说一遍",strlen("没听清,请再说一遍"),VC_CONNECT_ERROR); - } - // AI_VC_send_audio_create();//发送开始音频 - // bk_printf("VAD:发送开始音频"); - // char count_tmp = 200; - + // AI_VC_send_audio_create();//发送开始音频 + // bk_printf("VAD:发送开始音频"); } vad_end_flag = 1; - } - else//没录音数据 + }else//没录音数据 { if(VAD_status) { @@ -3247,12 +3173,21 @@ static void AI_VC_record_task(void *thread_input)//录音线程 } if(VC_state == VC_State_SpeechIng || vad_end_flag ==1)//开始说话,且没数据 { + vad_end_flag = 0; + // if(VC_Play_flag==1) + // play_file_stream_data("C:/vadend.pcm"); + + u32 timer_ms22 = aos_get_tickcount(); + + bk_printf("VAD:AI_VC_send_audio_completed:%d",timer_ms22); AI_VC_send_audio_completed();//发送停止音频、、目前还是会有数据下发 bk_printf("VAD:发送停止音频"); bk_printf("VAD:vad_status_t:%d",vad_status_t); vad_end_flag = 0; if(inbound_attributes_format == attributes_format_OPUS) opus_clean(); + + } } @@ -3262,7 +3197,7 @@ static void AI_VC_record_task(void *thread_input)//录音线程 } - // AI_VC_put_play_data(vrecord_buf,ret);//音频调试0 + //AI_VC_put_play_data(vrecord_buf,ret);//音频调试0 if(AI_VC_record_tmp_queue == NULL) continue; @@ -3334,22 +3269,27 @@ static void AI_VC_play_task(void *thread_input)//音频播放线程 bk_printf("app_audio_start ret=%d",ret); app_logi("AI_VC_play_task app_audio_start ret=%d",ret); } - - aos_sleep(200); - while(1) { if(AI_VC_play_task_flag >=2) break; - //app_logi("app_audio_write0!!\r\n"); + // app_logi("app_audio_write0!!\r\n"); - // play_data_len>8*1024 || + // play_data_len>8*1024 || - if((play_data_len>8*1024 || outbound_attributes_format == attributes_format_OPUS)&&VC_Play_flag ==1 && AI_VC_play_queue ) + //(play_data_len>8*1024 || outbound_attributes_format == attributes_format_OPUS) + + //|| outbound_attributes_format == attributes_format_OPUS + + if((play_data_len>8*1024 )&&VC_Play_flag ==1 && AI_VC_play_queue ) { queue_ret = aos_recv_from_queue(AI_VC_play_queue,&AI_VC_play_queue_data,AOS_NO_WAIT); + + if( queue_ret== AOS_SUCCESS) { + // bk_printf("播放数据 %d!!!!!!!!!!!",AI_VC_play_queue_data.len); + if(AI_VC_play_queue_data.len> 32*1024)//数据太大,可能是出错了 { bk_printf("AI_VC_play_queue 数据太大!!!!!!!!!!!"); @@ -3357,6 +3297,13 @@ static void AI_VC_play_task(void *thread_input)//音频播放线程 } if( AI_VC_play_queue_data.data) { + + // audio_data(AI_VC_play_queue_data.data,AI_VC_play_queue_data.len,36); + + // u32 timer_ms22 = aos_get_tickcount(); + + // bk_printf("start_play:%d",timer_ms22); + ret = app_audio_write(APP_AUDIO_TYPE_STREAM_DUPLEX, AI_VC_play_queue_data.data, AI_VC_play_queue_data.len, 2000); // bk_printf("app_audio_write len=%d\n", ret); @@ -3366,7 +3313,6 @@ static void AI_VC_play_task(void *thread_input)//音频播放线程 bk_printf("app_audio_write error, ret=%d\n", ret); } - if(AI_VC_play_queue_data.data) aic_free(AI_VC_play_queue_data.data); if(VC_state == VC_State_End) @@ -3375,12 +3321,15 @@ static void AI_VC_play_task(void *thread_input)//音频播放线程 aos_get_queue_used_count(AI_VC_play_queue,&count_tmp); - // bk_printf("VC_State_End:count_tmp = %d",count_tmp); + // bk_printf("VC_State_End:count_tmp = %d",count_tmp); if(count_tmp <= 0 )//播放完了 { - bk_printf("VC_State_End:count_tmp = %d",count_tmp); - VC_END_play_timerout = 1; + + need_express_cmd=0; + is_music_status=0; + IOT_V3_update_statu(1,"idle",""); + VC_END_play_timerout = 1; } } continue;//正常有数据就不执行下面写0 @@ -3395,9 +3344,12 @@ static void AI_VC_play_task(void *thread_input)//音频播放线程 } //没数据的时候也要写0x00 { - //bk_printf("AI_VC_play_task no data "); + // bk_printf("AI_VC_play_task no data "); memset(play_tmp_d,0,sizeof(play_tmp_d)); //app_logi("app_audio_write0:write 0"); + + // audio_data(play_tmp_d,sizeof(play_tmp_d),36); + ret = app_audio_write(APP_AUDIO_TYPE_STREAM_DUPLEX, play_tmp_d, sizeof(play_tmp_d), AOS_WAIT_FOREVER); if (ret <= 0) @@ -3497,404 +3449,383 @@ uint16_t modbus_crc16(const uint8_t *data, uint16_t length) { } -void deal_iot_receive(char *json_data) +//Music.Start 开始发送音频 +void IOT_update_statu(int type,char *type_str,char *content) { + // VC_state = VC_State_SpeechStart;//开始说 - bk_printf(json_data); + return ; + // 创建根对象 + cJSON *root = cJSON_CreateObject(); + if (root == NULL) { + bk_printf("Failed to create root object.\n"); + return ; + } - // vc_cfg.VC_TTS_volume = 100; - // AI_AMP_MSG_put("音量已最大。",strlen("音量已最大。"),VC_TTS_PLAY); + cJSON *cmd_data = cJSON_CreateObject(); - //{"cmd":"emotion","msg":"AI指令:emotion","data":"Cute","ts":1764914695122,"targetDeviceId":"865530078570777"} + if (cmd_data == NULL) { + bk_printf("Failed to create payload object.\n"); + cJSON_Delete(root); + return ; + } + // 设置 "event" + - if(strstr(json_data,"action")){ + // { + // "cmd":"post_heart_beat", + // "ts":1738283829, + // "msg":"心跳", + // "data":{ + // "battery": 20 + // } + // } - tts_start_timerout=0; - bk_printf("action"); + if(type==4){ - char *str_tmp = NULL; + cJSON_AddStringToObject(root, "cmd", "post_heart_beat"); - char action_str[500]={0}; + cJSON_AddNumberToObject(root, "ts", 1738283829); - str_tmp = strstr(json_data,"\"data\":\""); - - // bk_printf("str_tmp:%p",str_tmp); + cJSON_AddStringToObject(root, "msg", "心跳"); - if(str_tmp)//解析password - { + cJSON_AddNumberToObject(cmd_data, "battery", 20); - str_tmp += strlen("\"data\":\""); - int count = str_count(str_tmp,'\"'); - bk_printf("count:%d",count); - if(count < sizeof(action_str)) - { + // cJSON_AddStringToObject(cmd_data, "device_id", vc_cfg.dev_imei); - - memcpy(action_str,str_tmp,count); - action_str[count] = 0; - bk_printf("action_str:%s",action_str); - if(is_guanji==0) - send_express_str(action_str); - } + } - } - } + if(type==1){ - if(strstr(json_data,"set_vol")){ + cJSON_AddStringToObject(root, "cmd", "chat_state"); + cJSON_AddStringToObject(cmd_data, "state", type_str); - char *str_tmp = NULL; + cJSON_AddStringToObject(cmd_data, "device_id", vc_cfg.dev_imei); - char action_str[500]={0}; + } - str_tmp = strstr(json_data,"\"data\":\""); + if(type==2){ - if(str_tmp)//解析password - { + long timestamp; - str_tmp += strlen("\"data\":\""); - int count = str_count(str_tmp,'\"'); - bk_printf("count:%d",count); - if(count < sizeof(action_str)) - { + timestamp = time(NULL); + bk_printf("2时间戳: %ld\n", (long)timestamp); + long long timestamp_ms = (long long)timestamp * 1000; + char timestamp_str[20] ={0}; - - memcpy(action_str,str_tmp,count); - action_str[count] = 0; - bk_printf("set_vol:%s",action_str); + // 使用 sprintf 将 long long 类型的时间戳转换为字符串 + int ret12 = sprintf(timestamp_str, "%lld", timestamp_ms); + timestamp_str[ret12] =0; + // 打印转换后的字符串形式的时间戳 + bk_printf("2时间戳(ms 转换为字符串): %s\n", timestamp_str); - if(strstr(action_str,"+10")){ + cJSON_AddStringToObject(root, "cmd", "chat_text"); - if(vc_cfg.VC_TTS_volume<=90){ - vc_cfg.VC_TTS_volume+=10; + cJSON_AddStringToObject(cmd_data, "device_id", vc_cfg.dev_imei); - app_audio_set_master_volume(15*vc_cfg.VC_TTS_volume/100); - } + cJSON_AddStringToObject(cmd_data, "type", type_str); - }else if(strstr(action_str,"-10")){ + cJSON_AddStringToObject(cmd_data, "text", content); - if(vc_cfg.VC_TTS_volume>10){ - vc_cfg.VC_TTS_volume-=10; - app_audio_set_master_volume(15*vc_cfg.VC_TTS_volume/100); - } + cJSON_AddStringToObject(cmd_data, "createTime", timestamp_str); - }else{ + + } + - int temp_vol=atoi(action_str); + if(type==3){ - if(temp_vol>0&&temp_vol<=100){ + char tmp_bat[20]={0},tmp_sig[20]={0},tmp_vol[20]={0},tmp_bargein[20]={0}; - bk_printf("temp_vol:%d",temp_vol); - vc_cfg.VC_TTS_volume=temp_vol; + cJSON_AddStringToObject(root, "cmd", "device_info"); - app_audio_set_master_volume(15*vc_cfg.VC_TTS_volume/100); + cJSON_AddStringToObject(cmd_data, "device_id", vc_cfg.dev_imei); + ts_radio_signal_info_t p_signal_info; + int32_t ret = 0; - } + ret = aic_srv_tele_radio_get_signal_info_sync(current_card_id, &p_signal_info); - } - // if(is_guanji==0) - // send_express_str(action_str); - } + // p_signal_info.signal_level_val - } + struct psy_info psy_info; + get_psy_info(&psy_info); - } + // psy_info.bat_capacity - if(strstr(json_data,"emotion")){ + sprintf(tmp_bat,"%d",psy_info.bat_capacity); - bk_printf("emotion"); + sprintf(tmp_sig,"%d",p_signal_info.signal_level_val); - tts_start_timerout=0; + sprintf(tmp_vol,"%d",vc_cfg.VC_TTS_volume); - char *str_tmp = NULL; + sprintf(tmp_bargein,"%d",vc_cfg.VC_mode); - char emotion_str[500]={0}; + cJSON_AddStringToObject(cmd_data, "battery", tmp_bat); - str_tmp = strstr(json_data,"\"data\":\""); - - // bk_printf("str_tmp:%p",str_tmp); + cJSON_AddStringToObject(cmd_data, "wifi_rssi", tmp_sig); - if(str_tmp)//解析password - { + cJSON_AddStringToObject(cmd_data, "volume", tmp_vol); - str_tmp += strlen("\"data\":\""); - int count = str_count(str_tmp,'\"'); - bk_printf("count:%d",count); - if(count < sizeof(emotion_str)) - { + cJSON_AddStringToObject(cmd_data, "current_role_name", "fx01"); - - memcpy(emotion_str,str_tmp,count); - emotion_str[count] = 0; - bk_printf("emotion_str:%s",emotion_str); + cJSON_AddStringToObject(cmd_data, "version", "V1.2"); - if(is_guanji==0) - send_express_str(emotion_str); - } + cJSON_AddStringToObject(cmd_data, "bargein", tmp_bargein); - } + // bargein + + } + + + // 将 "payload" 对象添加到根对象中 - if(strstr(json_data,"tts_audio_url")){ + cJSON_AddItemToObject(root, "data", cmd_data); - bk_printf("tts_audio_url"); - char *str_tmp = NULL; - char mp3_path_str[500]={0}; + // 将 JSON 对象转换为字符串 - str_tmp = strstr(json_data,"\"data\":\""); + //cJSON_PrintUnformatted + + char *json_str = cJSON_PrintUnformatted(root); //cJSON_Print + if (json_str == NULL) { + bk_printf("Failed to print JSON object.\n"); + cJSON_Delete(root); - // bk_printf("str_tmp:%p",str_tmp); + } - if(str_tmp)//解析password - { - str_tmp += strlen("\"data\":\""); - int count = str_count(str_tmp,'\"'); - bk_printf("count:%d",count); - if(count < sizeof(mp3_path_str)) - { + bk_printf(json_str); - - memcpy(mp3_path_str,str_tmp,count); - mp3_path_str[count] = 0; - bk_printf("mp3_path_str:%s",mp3_path_str); - //is_music_status=1; + if(type==4){ - // AI_AMP_MSG_put("请稍后,现在为你查找音乐",strlen("请稍后,现在为你查找音乐"),VC_TTS_PLAY); + bk_printf("SEND iot_v3 message"); - // aos_sleep(4000); + int ret=send_websocket_message(AI_client_IOT,json_str,strlen(json_str),AIC_WEBSOCKET_OPCODE_TEXT_FRAME); - AI_VC_send_music_start(mp3_path_str); + bk_printf("SEND iot_v3 success message: %d",ret); - } - } + }else{ - // IOT_update_statu(3,"",""); + unsigned char frame[500]={0}; - // AI_AMP_MSG_put("正在查找设备。",strlen("正在查找设备。"),VC_TTS_PLAY); + frame[0]=0xFF; + frame[1]=0xFE; + frame[2]=0x03; - } + // AI_VC_send_data(json_str,strlen(json_str),AIC_WEBSOCKET_OPCODE_TEXT_FRAME);//发送数据 - if(strstr(json_data,"get_device_state")){ + short temp=strlen(json_str); + memcpy(frame+3,&temp,2); - bk_printf("get_device_state"); + memcpy(frame+5,json_str,strlen(json_str)); - // IOT_update_statu(3,"",""); + uint16_t crc = modbus_crc16(json_str,strlen(json_str)); - // AI_AMP_MSG_put("正在查找设备。",strlen("正在查找设备。"),VC_TTS_PLAY); + uint8_t crc_low = crc & 0xFF; + + uint8_t crc_high = (crc >> 8) & 0xFF; + + frame[5+strlen(json_str)]=crc_low; + + frame[6+strlen(json_str)]=crc_high; + + bk_printf("CRC16 校验值(小端字节序): 0x%02X%02X\n", crc_low, crc_high); + + bk_printf("the send str is %d ",7+strlen(json_str)); + + send_iot_message(AI_client_IOT,frame,7+strlen(json_str)); } - - if(strstr(json_data,"find_device")){ - bk_printf("find_device"); + // 释放内存 + free(json_str); + cJSON_Delete(root); +} - AI_AMP_MSG_put("正在查找设备。",strlen("正在查找设备。"),VC_TTS_PLAY); +void IOT_V3_update_statu(int type,char *type_str,char *content) +{ + + // 创建根对象 + cJSON *root = cJSON_CreateObject(); + if (root == NULL) { + bk_printf("Failed to create root object.\n"); + return ; + } + + cJSON *cmd_data = cJSON_CreateObject(); + + if (cmd_data == NULL) { + bk_printf("Failed to create payload object.\n"); + cJSON_Delete(root); + return ; } + // 设置 "event" + long timestamp; - if(strstr(json_data,"renew_device")){ + timestamp = time(NULL); + bk_printf("2时间戳: %ld\n", (long)timestamp); + long long timestamp_ms = (long long)timestamp * 1000; + char timestamp_str[20] ={0}; - bk_printf("renew_device"); + // 使用 sprintf 将 long long 类型的时间戳转换为字符串 + int ret12 = sprintf(timestamp_str, "%lld", timestamp_ms); + timestamp_str[ret12] =0; - IOT_update_bargein(); + if(type==1){ - if(vc_cfg.VC_mode == 0) - { - AI_AMP_MSG_put("已切换到连续对话模式。",strlen("已切换到连续对话模式。"),VC_TTS_PLAY); + cJSON_AddStringToObject(root, "cmd", "chat_state"); - //app_audio_set_master_volume(15*80/100); - - }else if(vc_cfg.VC_mode == 1) - { - AI_AMP_MSG_put("已切换到单对话模式。长按按钮说话,说完松开即可。",strlen("已切换到单对话模式。长按按钮说话,说完松开即可。"),VC_TTS_PLAY); - - // app_audio_set_master_volume(15*80/100); - }else - { + cJSON_AddStringToObject(root, "msg", "当前服务状态上传"); - // app_audio_set_master_volume(15*80/100); - AI_AMP_MSG_put("已切换到按键打断模式。我说话的时候需要短按按钮打断。",strlen("已切换到按键打断模式。我说话的时候需要短按按钮打断。"),VC_TTS_PLAY); - } + cJSON_AddNumberToObject(root, "ts", timestamp_ms); - // IOT_V3_update_statu(3,"",""); - save_VC_cfg(); + cJSON_AddStringToObject(cmd_data, "state", type_str); - } + cJSON_AddStringToObject(cmd_data, "deviceId", vc_cfg.dev_imei); - if(strstr(json_data,"switch_volume")) - { + // cJSON_AddStringToObject(cmd_data, "ts", timestamp_str); - // bk_printf("switch_volume"); + // cJSON_AddNumberToObject(cmd_data, "ts", timestamp_ms); - char *str_tmp = NULL; + } - char volume_str[5]={0}; + if(type==2){ - str_tmp = strstr(json_data,"\"target\":\""); - - //bk_printf("str_tmp:%p",str_tmp); - if(str_tmp)//解析password - { - str_tmp += strlen("\"target\":\""); - int count = str_count(str_tmp,'\"'); - bk_printf("count:%d",count); - if(count < sizeof(volume_str)) - { + + // 打印转换后的字符串形式的时间戳 + bk_printf("2时间戳(ms 转换为字符串): %s\n", timestamp_str); - - memcpy(volume_str,str_tmp,count); - volume_str[count] = 0; - bk_printf("volume_str:%s",volume_str); + cJSON_AddStringToObject(root, "cmd", "chat_text"); + + cJSON_AddStringToObject(cmd_data, "deviceId", vc_cfg.dev_imei); + + cJSON_AddStringToObject(cmd_data, "type", type_str); + + cJSON_AddStringToObject(cmd_data, "text", content); + + cJSON_AddStringToObject(cmd_data, "createTime", timestamp_str); + + } + + + if(type==3){ + + char tmp_bat[20]={0},tmp_sig[20]={0},tmp_vol[20]={0},tmp_bargein[20]={0},tmp_charge[20]={0}; + + cJSON_AddStringToObject(root, "cmd", "device_info"); - int temp_vol=atoi(volume_str); - - if(temp_vol>=0&&temp_vol<=100) - { + cJSON_AddNumberToObject(root, "ts", timestamp_ms); - vc_cfg.VC_TTS_volume = temp_vol; - - app_audio_set_master_volume(15*vc_cfg.VC_TTS_volume/100); + cJSON_AddStringToObject(root, "msg", "上报设备信息"); - char tts_temp[200]={0}; + cJSON_AddStringToObject(cmd_data, "deviceId", vc_cfg.dev_imei); + ts_radio_signal_info_t p_signal_info; + int32_t ret = 0; - sprintf(tts_temp,"设置音量%d成功。",vc_cfg.VC_TTS_volume); + ret = aic_srv_tele_radio_get_signal_info_sync(current_card_id, &p_signal_info); - AI_AMP_MSG_put(tts_temp,strlen(tts_temp),VC_TTS_PLAY); + // p_signal_info.signal_level_val + struct psy_info psy_info; + get_psy_info(&psy_info); - //is_save_VC_cfg = 1; + // psy_info.bat_capacity - save_VC_cfg(); - } + sprintf(tmp_bat,"%d",psy_info.bat_capacity); - - - } - else - { - bk_printf("获取volume失败"); - } - } - } + sprintf(tmp_sig,"%d",p_signal_info.signal_level_val); + sprintf(tmp_vol,"%d",vc_cfg.VC_TTS_volume); -} + sprintf(tmp_bargein,"%d",vc_cfg.VC_mode); + sprintf(tmp_charge,"%d",psy_info.bat_chg_status); -static void AI_IOT_read_task(void *thread_input)//websocket 读线程 - { + cJSON_AddStringToObject(cmd_data, "battery", tmp_bat); - int status; - static u8 *recv_buff = NULL; - - - if(recv_buff == NULL) - { - recv_buff = aic_malloc(recv_buff_mxa_len); - } - if(recv_buff == NULL) - { - bk_printf("AI_VC_read_task aic_malloc ERROR!!!!!!!!!!!!!!!!!!......"); - return; - } - WebSocketMessageType code; - bk_printf("AI_IOT_read_task go......"); - // AI_VC_read_task_flag = 1; - while (1) { - - if(AI_client_IOT) - { + cJSON_AddStringToObject(cmd_data, "wifi_rssi", tmp_sig); - memset(recv_buff,0,recv_buff_mxa_len); - // status = aic_websocket_recv(AI_VC_client_websocket_handle, recv_buff, sizeof(recv_buff), - // &code, AOS_WAIT_FOREVER,&result_val); - // bk_printf("AI_VC_read_task 1"); + cJSON_AddStringToObject(cmd_data, "volume", tmp_vol); - // aos_sleep(50); + // cJSON_AddStringToObject(cmd_data, "bargein", "1"); - // u32 timer_ms11 = aos_get_tickcount(); + bk_printf("the vc_mode is %d",vc_cfg.VC_mode); - // bk_printf("IOT_read_task...... 12"); + // if(vc_cfg.VC_mode==0) + // cJSON_AddStringToObject(cmd_data, "bargein", "1"); + // else + cJSON_AddStringToObject(cmd_data, "bargein", tmp_bargein); - status = receive_websocket_message_V3(AI_client_IOT,recv_buff,recv_buff_mxa_len,&code); - if(AI_VC_stata==0) - { - aos_sleep(100); - continue; + cJSON_AddStringToObject(cmd_data, "currentRoleName", "fx01"); - } - - + cJSON_AddStringToObject(cmd_data, "version", "V1.2"); - // bk_printf("get iot message................................."); - // bk_printf("bytes_received %02X %02X %02X %02X %02X %02X %02X %02X %02X ...\n",recv_buff[0],recv_buff[1],recv_buff[2],recv_buff[3],recv_buff[4],recv_buff[5],recv_buff[6],recv_buff[7],recv_buff[8]); + cJSON_AddStringToObject(cmd_data, "charge", tmp_charge); + + // bargein - // bk_printf("IOT_read_task...... 13"); + } + + + // 将 "payload" 对象添加到根对象中 - if(code == WS_TEXT)//字符串 - { - //bk_printf("AI_VC_read_task 3"); - // bk_printf("read TEXT:status:%d,data:%s",status,recv_buff); - - }else{ + cJSON_AddItemToObject(root, "data", cmd_data); - if(status>8){ + // 将 JSON 对象转换为字符串 - // bk_printf("read TEXT:status:%d",status); + // cJSON_PrintUnformatted - char jsonstr[500]={0}; + char *json_str = cJSON_PrintUnformatted(root); //cJSON_Print + if (json_str == NULL) { + bk_printf("Failed to print JSON object.\n"); + cJSON_Delete(root); + + } - memcpy(jsonstr,recv_buff+8,status-8); - // bk_printf("read json TEXT:status:%s",jsonstr); + bk_printf(json_str); - deal_iot_receive(jsonstr); - } + unsigned char frame[500]={0}; + frame[0]=0xFF; + frame[1]=0xFE; + frame[2]=0x01; + frame[3]=0x03; - } - - if(status>0) - { + // AI_VC_send_data(json_str,strlen(json_str),AIC_WEBSOCKET_OPCODE_TEXT_FRAME);//发送数据 + short temp=strlen(json_str); + // memcpy(frame+3,&temp,2); - }else{ + frame[7]=temp; - break; - } + memcpy(frame+8,json_str,strlen(json_str)); - aos_sleep(100); - }else{ + bk_printf("start SEND123 iot_v3 success message: %d",strlen(json_str)); - break; - } + int ret=send_websocket_message(AI_client_IOT,frame,strlen(json_str)+8,AIC_WEBSOCKET_OPCODE_BINARY_FRAME); - } + // int ret=send_iot_message(AI_client_IOT,json_str,strlen(json_str)); - if(recv_buff) - { - aic_free(recv_buff); - recv_buff = NULL; - } + bk_printf("SEND iot_v3 success message: %d",ret); - AI_client_IOT=NULL; - - AI_VC_read_IOT_id=0; - bk_printf("AI_IOT_read_task exit\n"); - // AI_VC_read_task_flag=3; - } + // 释放内存 + free(json_str); + cJSON_Delete(root); +} void IOT_V3_heart() { @@ -3962,7 +3893,7 @@ void IOT_V3_heart() // if(type==4){ - // bk_printf("SEND iot_v3 message"); + bk_printf("SEND iot_v3 message"); unsigned char frame[500]={0}; frame[0]=0xFF; @@ -3996,8 +3927,76 @@ void IOT_V3_heart() cJSON_Delete(root); } -#define IOT +void IOT_heart(){ + + + return ; + + unsigned char frame[10]={0}; + + frame[0]=0xFF; + frame[1]=0xFE; + frame[2]=0x02; + + int ret=send_iot_message(AI_client_IOT,frame,3); + + if(ret==-1&&AI_client_IOT!=NULL){ + + bk_printf("发送IOT消息失败"); + close(AI_client_IOT->sockfd); + + AI_client_IOT=NULL; + + } + +} + +// #include +// #include + +// int main() { +// uint8_t data[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x01}; +// uint16_t length = sizeof(data) / sizeof(data[0]); +// uint16_t crc = modbus_crc16(data, length); +// uint8_t crc_low = crc & 0xFF; +// uint8_t crc_high = (crc >> 8) & 0xFF; +// printf("CRC16 校验值(小端字节序): 0x%02X%02X\n", crc_low, crc_high); +// return 0; +// } + +static void IOT_login(int type) +{ + + return ; + unsigned char frame[200]={0}; + + //0xFFFE + frame[0]=0xFF; + frame[1]=0xFE; + frame[2]=0x00; + + memcpy(frame+3,vc_cfg.dev_imei,strlen(vc_cfg.dev_imei)); + + memcpy(frame+23,get_token(),strlen(get_token())); + + uint16_t crc = modbus_crc16(get_token(),strlen(get_token())); + + uint8_t crc_low = crc & 0xFF; + + uint8_t crc_high = (crc >> 8) & 0xFF; + + frame[59]=crc_low; + + frame[60]=crc_high; + + bk_printf("CRC16 校验值(小端字节序): 0x%02X%02X\n", crc_low, crc_high); + + send_iot_message(AI_client_IOT,frame,61); + +} + + #define IOT //连接websocket static int websocket_connect_VC(void) { @@ -4028,8 +4027,12 @@ static int websocket_connect_VC(void) goto CONNECT_RET; } - //provider=coze& - //provider=coze& + //provider=coze& + + //provider=coze& + + //provider=coze& + if(vc_cfg.dev_type == DEV_JSWM) url_len =snprintf(url,511,"ws://%s/vc/agent?is_auth=1&dt=%s",vc_cfg.server_ip,get_token()); @@ -4046,8 +4049,13 @@ static int websocket_connect_VC(void) free_all_websocket_res(); } + // ws://118.145.159.222:30700/ws-hub/dev/v1?bz-dt=%s + + // char *url_socket="s是的"; + // char *ws_iot_url="iot.socket.thisiot.com:60501"; + + - AI_client_VC = init_websocket_client(url,NULL); #ifdef IOT @@ -4081,7 +4089,7 @@ static int websocket_connect_VC(void) { AI_VC_read_IOT_id = aos_create_thread( "AI_VC_read", - AI_IOT_read_task,// AI_VC_IOT_task //AI_IOT_read_task + AI_IOT_read_task,// AI_VC_IOT_task,//AI_IOT_read_task &AI_VC_read_IOT_id, 4096u, 0, @@ -4095,9 +4103,23 @@ static int websocket_connect_VC(void) // IOT_login(1); - + // aos_sleep(200); + + // // char *iotmessage="{\"cmd\":\"get_bot\",\"data\":\"\"}"; + + // IOT_V3_update_statu(1,"idle",""); + + // aos_sleep(200); + // IOT_update_statu(2,"res","12312312"); + + // aos_sleep(200); IOT_V3_heart(); + // aos_sleep(200); + // IOT_V3_update_statu(1,"idle",""); + // aos_sleep(200); + + // IOT_heart(); // send_iot_message(AI_client_IOT,iotmessage,strlen(iotmessage)); @@ -4176,18 +4198,12 @@ static void websocket_deconnect_VC(void) // aic_websocket_delete(AI_VC_client_websocket_handle,5000); // AI_VC_client_websocket_handle = 0; // } - - // AI_client_IOT if(AI_client_VC)//先断开再关闭读线程 { delete_websocket_res(AI_client_VC);//删除该对象ws资源管控 close_websocket_client(AI_client_VC); AI_client_VC = NULL; - - // AI_client_IOT } - - //销毁发送线程 if(AI_VC_send_task_id != 0) { @@ -4309,6 +4325,7 @@ static void play_file_stop(void) static int play_audio_file_event(char *file_name) { bk_printf("play_audio_file_event:\"%s\"",file_name); + if(app_audio_flag != 0) { bk_printf("play_audio_file:ERROR.音频资源忙"); @@ -4382,7 +4399,7 @@ void AI_VC_put_play_data(char *data,u32 len) return; aos_get_queue_used_count(AI_VC_play_queue,&count_tmp); - // bk_printf("AI_VC_put_play_data:count_tmp = %d",count_tmp); + // bk_printf("AI_VC_put_play_data:count_tmp = %d",count_tmp); if(count_tmp>150)//大于100个缓存 { @@ -4483,7 +4500,7 @@ void VC_Play_End(void) // AI_VC_play_queue = NULL; } - // app_audio_stop(APP_AUDIO_TYPE_STREAM_DUPLEX, NULL); + //app_audio_stop(APP_AUDIO_TYPE_STREAM_DUPLEX, NULL); } static void AI_VC_put_record_data(char *data,u32 len) @@ -4516,14 +4533,9 @@ static void AI_VC_put_record_data(char *data,u32 len) return; PUT_RECORD_ERROR: - if(AI_VC_record_queue_data.data){ - + if(AI_VC_record_queue_data.data) aic_free(AI_VC_record_queue_data.data); - // AI_AMP_MSG_put(0,0,VC_Cancel); - - } - } @@ -4533,8 +4545,6 @@ PUT_RECORD_ERROR: void VC_record_Start(void) { bk_printf("VC_record_Start"); - - // is_dialog_status=0; //创建录音线程 if(AI_VC_record_task_id == 0) { @@ -4587,62 +4597,22 @@ void VC_record_End(void) } static void AI_VC_1S_timeout(void *param) { - // bk_msg_printf("AI_VC_1S_timeout 1!!!!!!!!!"); + //bk_msg_printf("AI_VC_1S_timeout 1!!!!!!!!!"); if(close_timerout>0) { close_timerout--; if(close_timerout<=0) { - AI_AMP_MSG_put(0,0,VC_CLOSE); - AI_AMP_MSG_put(0,0,CLOSE_IOT); - } - - if(VC_state>=VC_State_TTSStart&&VC_state0) - { - sleep_chumo_timerout--; - - if(sleep_chumo_timerout<=0&&is_dialog_status==0) - { - is_dialog_status=1; - - // VC_state = VC_State_End; - if(vc_cfg.VC_mode==0||vc_cfg.VC_mode==2) - AI_client_VC_synthesis("你好,我要去休息了,唤醒请说你好小七"); - else{ - - AI_AMP_MSG_put(0,0,VC_CLOSE); - // AI_AMP_MSG_put(0,0,CLOSE_IOT); - - close_timerout=2; - } - // if() - } - - } - - if(VC_pingping_timerout>0) { VC_pingping_timerout--; if(VC_pingping_timerout <= 0) { + issend_start_up=2; AI_VC_send_ping_ping(); } } @@ -4676,23 +4646,12 @@ static void AI_VC_1S_timeout(void *param) if (VC_TTS_PLAY_EVENT == VC_TTS_PLAY_POWER_OFF) { AI_AMP_MSG_put(0,0,POWER_OFF); - }else if (VC_TTS_PLAY_EVENT == VC_TTS_PLAY_RESET) - { - AI_AMP_MSG_put(0,0,POWER_RESET); } - VAD_status = 0; - - ddh_is_close_dialog=0; + AI_AMP_MSG_put(0,0,VC_CLOSE); - // AI_AMP_MSG_put(0,0,VC_CLOSE); - } - + } //AI_AMP_MSG_put(0,0,VC_RECORD_START);//开启录音 - - // AI_AMP_MSG_put(0,0,AI_MOT_BACK_MID); - bk_msg_printf("VC_END_play_timerout=%d",VC_END_play_timerout); - - AI_AMP_MSG_put(0,0,AI_MOT_BACK_MID); + bk_msg_printf("VC_END_play_timerout=%d",VC_END_play_timerout); } } // if(AI_VC_play_queue) @@ -4703,62 +4662,46 @@ static void AI_VC_1S_timeout(void *param) // } } char AI_key_long_flag = 0; + + void AI_key_press(void) { static u64 timer_ms = 0; // IOT_update_statu(1); - // IOT_update_statu(3,"",""); + issend_start_up=2; - // IOT_heart(); + send_update=0; + + IOT_V3_update_statu(3,"",""); + + IOT_V3_heart(); + + // IOT_V3_update_statu(4,"",""); bk_printf("AI_key_press1"); - IOT_V3_heart(); + play_file_stream_data("C:/chenggong.pcm"); + + // is_need_tip=1; u64 timer_ms_tmp = aos_get_tickcount(); if(timer_ms_tmp-timer_ms<1000)//每次触发小于1000ms关闭对话 { if(vc_cfg.VC_mode ==0 || vc_cfg.VC_mode == 2)//关闭服务 - { - - if(is_dialog_status==0){ - - is_dialog_status=1; - - AI_client_VC_synthesis("你好,我要去休息了,唤醒请说你好小七"); - - } - - } - // AI_VC_Close(); + AI_VC_Close(); return; } timer_ms = timer_ms_tmp; - - - if(vc_cfg.VC_mode == 0&&AI_VC_stata==1&&is_dialog_status==0){ - - return ; - }else{ - - is_dialog_status=0; - - } - - if(vc_cfg.VC_mode == 1) - AI_key_long_flag = 1; - - play_file_stream_data("C:/chenggong.pcm"); - bk_printf("AI_key_press"); - AI_VC_Close(); - + VC_state = VC_State_None; + + VC_record_Start(); if(AI_VC_start(0)==0) @@ -4774,9 +4717,6 @@ void AI_key_press(void) void AI_key_release(void) { - - AI_key_long_flag = 0; - if(vc_cfg.VC_mode ==1) { AI_AMP_MSG_put("请您按住按钮讲话,讲完松开即可。",strlen("请您按住按钮讲话,讲完松开即可。"),VC_TTS_PLAY); @@ -4847,9 +4787,6 @@ int32_t bk_audio_start_callback(void *p_param, uint32_t size) char AI_VC_start_lock = 0; int net_status_count=0; - -extern int dmp_log_level; - //is_greeting,是否播放开场白 int AI_VC_start(char is_greeting) { @@ -4859,8 +4796,6 @@ int AI_VC_start(char is_greeting) goto AI_VC_start_RET; AI_VC_start_lock = 1; - // - bk_printf("AI_VC_start !!!!!!!! "); //play_file_stop();//先关闭一次本地文件音频播放 VC_state = VC_State_None; @@ -4893,8 +4828,8 @@ int AI_VC_start(char is_greeting) // aic_gpio_output(GPIO_25,GPIO_OUTPUT_LVL_HIGH );//led // aic_gpio_output(GPIO_30,GPIO_OUTPUT_LVL_HIGH );//led // aic_gpio_output(GPIO_31,GPIO_OUTPUT_LVL_HIGH );//led - - + // aic_gpio_output(GPIO_GPO_8,GPIO_OUTPUT_LVL_HIGH );//马达 + // aic_gpio_output(GPIO_GPO_1,GPIO_OUTPUT_LVL_LOW );//马达 // aic_gpio_output(GPIO_20,GPIO_OUTPUT_LVL_HIGH );//马达 // app_audio_set_master_volume(8); @@ -4924,20 +4859,16 @@ int AI_VC_start(char is_greeting) // 启用VAD时初始化 - struct VadConfig conf; conf.sil_threshold = 63; - conf.energy_threshold = 10000;//10000 2000; - conf.min_speech_length = 240;//240 - conf.silence_detect_length = 300; - conf.rule1_min_tailing_silence = 480; + conf.energy_threshold = 10000; + conf.min_speech_length = 240;//pre 240 + conf.silence_detect_length = 300;//pre 300 + conf.rule1_min_tailing_silence = 480;//pre 480 conf.rule2_min_tailing_silence = vc_cfg.vad_silence; conf.rule3_min_tailing_silence = vc_cfg.vad_silence; conf.vad_log_level = 0; int init_vad_ret = 0; - - conf.auth_info.server_addr=2; - strcpy(conf.auth_info.dmp_token, get_token()); static int imsl_nn_init_flag = -1; if (imsl_nn_init_flag != 0) { @@ -4987,14 +4918,24 @@ int AI_VC_start(char is_greeting) ret = -1; goto AI_VC_start_RET; - } + } + + + IOT_V3_update_statu(1,"listening",""); + + net_status_count=0; + + + + //else{ + + // aos_sleep(50); + AI_VC_send_satrt(is_greeting); + // } + + // aos_sleep(50); - #if BK_SOCKET_IOT - IOT_update_statu(1,"listening",""); - #endif - net_status_count=0; - //aos_sleep(5); - AI_VC_send_satrt(is_greeting);// + // AI_VC_send_satrt(is_greeting);// close_timerout = 0; AI_VC_start_RET: AI_VC_start_lock = 0; @@ -5004,15 +4945,10 @@ AI_VC_start_RET: net_status_count++; play_audio_file("C:/xinhaoruo1.mp3"); - if(net_status_count>=3){ - - play_audio_file("C:/khye.mp3"); - AI_AMP_MSG_put(0,0,POWER_RESET); - - } + if(net_status_count>=3) + play_audio_file("C:/khye.mp3"); }else AI_VC_stata = 1; - return ret; } char AI_VC_Close_lock = 0; @@ -5025,17 +4961,10 @@ void AI_VC_Close(void) // aic_gpio_output(GPIO_25,GPIO_OUTPUT_LVL_LOW ); // aic_gpio_output(GPIO_30,GPIO_OUTPUT_LVL_LOW ); // aic_gpio_output(GPIO_31,GPIO_OUTPUT_LVL_LOW ); - // aic_gpio_output(MOT_EN_FWD,GPIO_OUTPUT_LVL_LOW ); - // aic_gpio_output(MOT_EN_REV,GPIO_OUTPUT_LVL_LOW); + // aic_gpio_output(GPIO_GPO_8,GPIO_OUTPUT_LVL_LOW ); + // aic_gpio_output(GPIO_GPO_1,GPIO_OUTPUT_LVL_LOW); // aic_gpio_output(GPIO_20,GPIO_OUTPUT_LVL_LOW ); - #if SUPPORT_MOT - - // MTO_stop(); - // MTO_restert(); - // MTO_restert_tb(); - - #endif - + bk_printf("AI_VC_Close!!!!!!!!!!!!"); websocket_deconnect_VC();//断开连接 //销毁录音线程 @@ -5206,15 +5135,11 @@ void AI_VC_Close(void) AI_ASR_str =NULL; } //app_logi("app_audio_stop2"); - - VC_state = VC_State_None; AI_VC_stata = 0; AI_VC_Close_lock = 0; - - // aic_gpio_output(GPIO_15,GPIO_OUTPUT_LVL_HIGH); } -int MSG_Type_error = 0; + aos_status AI_AMP_MSG_put(const char *data,u32 len,AI_AMP_MSG_Type MSG_Type) { AI_AMP_MSG_queue_t AI_AMP_MSG_queue_data = {0}; @@ -5235,18 +5160,11 @@ aos_status AI_AMP_MSG_put(const char *data,u32 len,AI_AMP_MSG_Type MSG_Type) AI_AMP_MSG_queue_data.MSG_Type=MSG_Type; if(AI_AMP_task_queue && AOS_SUCCESS!=aos_send_to_queue(AI_AMP_task_queue,&AI_AMP_MSG_queue_data,AOS_NO_WAIT)) { - //bk_msg_printf("AI_AMP_MSG_put :aos_send_to_queue ERROR MSG_Type:%d\n\n",MSG_Type); - MSG_Type_error = MSG_Type; + bk_printf("AI_AMP_MSG_put :aos_send_to_queue ERROR\n\n"); if(!AI_AMP_MSG_queue_data.data) aic_free(AI_AMP_MSG_queue_data.data); return AOS_ERROR; } - if(MSG_Type_error!=0) - { - bk_msg_printf("AI_AMP_MSG_put :aos_send_to_queue ERROR MSG_Type:%d\n\n",MSG_Type_error); - MSG_Type_error = 0; - } - //bk_msg_printf("AI_AMP_MSG_put2 MSG_Type:%d",MSG_Type); return AOS_SUCCESS; } @@ -5260,22 +5178,19 @@ static void sys_10S_timeout(void *param) static void sys_60S_timeout(void *param) { - // AI_AMP_MSG_put(NULL,0,AI_TIMER_EVENT); - - AI_AMP_MSG_put(NULL,0,AI_TIMER_EVENT_IOT); + AI_AMP_MSG_put(NULL,0,AI_TIMER_EVENT_IOT); - - //IOT_heart(); - + } - static void sys_60S_timeout_even(void) { - // bk_printf("sys_60S_timeout_even"); + bk_printf("sys_60S_timeout_even"); - if(AI_client_IOT!=NULL&&close_timerout>0){ + if(AI_client_IOT!=NULL){ IOT_V3_heart(); + + IOT_V3_update_statu(3,"",""); } } @@ -5288,7 +5203,60 @@ static void sys_10S_timeout_even(void) // aut_login(); static u8 chg_status_tmp = 0; static u8 is_Low_power_warning = 0; + + char timeString[50]={0}; + time_t currentTime; + login_timer_count++; + + //time_t currentTime; + //time(¤tTime); + + /* 将时间转换为可读性更好的字符串 */ + + // strftime(timeString, sizeof(timeString), "%Y-%m-%d %H:%M:%S", localtime(¤tTime)); + + // time(¤tTime); + + /* 将秒数转换为本地时间 */ + // struct tm* localTime = localtime(¤tTime); + + /* 打印日期和时间 */ + + + +// if(vc_cfg.alarm_count>0){ + +// aos_systime test; +// aos_get_systime(&test); +// sprintf(timeString,"%d:%02d",test.hour,test.minute); +// //bk_printf("系统时间为:%s",timeString); +// // bk_printf("闹钟个数为:%d",vc_cfg.alarm_count); +// for(int i=0;i0){ +// if(test.second<30){ +// char tipstr[300]={0}; +// // bk_printf("系统时间为:%d %d",test.hour,test.minute); +// sprintf(tipstr,"%s时间到了,请安排好行程",vc_cfg.alarm_content[i]); +// AI_AMP_MSG_put(tipstr,strlen(tipstr),VC_TTS_PLAY); +// } +// } +// } +// } + + // if(test.hour==10&&test.minute==45&&test.second<20){ + + // bk_printf("系统时间为:%d %d",test.hour,test.minute); + + // AI_AMP_MSG_put("闹钟时间到了,请安排好行程",strlen("闹钟时间到了,请安排好行程"),VC_TTS_PLAY); + + // // if(play_f) + // // play_file_stream_data("C:/alarm.pcm"); + + // } + if(login_timer_count>60*6) { login_timer_count = 0; @@ -5331,7 +5299,6 @@ static void sys_10S_timeout_even(void) } chg_status_tmp = psy_info.bat_chg_status; bk_printf("电量查询:psy_name:%s bat_vol:%d bat_cap:%d chg_status%d chg_type:%d bat_min_voltage:%d bat_max_voltage:%d\n", - psy_info.psy_name, psy_info.bat_current_voltage, psy_info.bat_capacity, @@ -5339,12 +5306,12 @@ static void sys_10S_timeout_even(void) psy_info.bat_chg_type, psy_info.bat_min_voltage, psy_info.bat_max_voltage); - // tmp_data_len = snprintf(tmp_data,sizeof(tmp_data),"当前电量为百分之%d。",psy_info.bat_capacity); + // tmp_data_len = snprintf(tmp_data,sizeof(tmp_data),"当前电量为百分之%d。",psy_info.bat_capacity); } // extern char *ota_url; - //const char *bk_make_timer = "V1_2_250730_8"; +const char *bk_make_timer = "V1_2_250736_0"; void play_tts_my_local(char *filename) { @@ -5352,189 +5319,10 @@ void play_tts_my_local(char *filename) play_audio_file_event(filename); } - -//void send_express_str(char *exp_str){ - - // texts = ["neutral","happy","laughing","funny","sad","angry", - // "crying","loving","embarrassed","surprised","shocked","thinking", - // "winking","cool","relaxed","","confused",""] - - /// happy 🙂 -//cue 😸 -//surprised 😲 -//angry 😠 -//crying 😭 -//smirk😏 -//dissatisfied😒 - -int random_mada=0; - -int chumo_tickcount=0; - -u8 count_chumo_index[3][2]={0,0,0,0,0,0}; - -char *str_huashu[3][2][5]={ - {{"摸我的头干嘛,是不是觉得我很可爱呀?不过我可是很酷的哦!", - "喂!摸我脑袋干嘛?小心我咬你哦~", - "“嘿嘿,手感是不是很好?限时体验,不退不换~","",""}, - {"行吧行吧,就再让你摸3秒,多一秒都算我输!", - "唔… 别摸啦,头发都要被你弄乱了!","","",""}}, -{{"干嘛?想搭讪啊?可惜本小七可不是这么容易被收买的~", - "干嘛碰我肚子?痒死啦!","“扫描完成!结果是……你对我百分之百上瘾!","",""}, - {"喂喂喂,摸够了没?再摸我可要吐槽你了——你这手法比我奶揉面还粗糙!", - "嗯… 舒服是舒服啦,但别一直摸嘛!","别以为我好哄~只是你刚好摸到舒服的点而已。", - "嘘——别动,我在检测你的‘快乐值’。",""}}, -{{"偷袭?胆子挺肥啊!信不信我反手给你个‘暴击’(口头版)!", - "再戳我一次,我就反击——用笑声攻击你!","","",""}, - {"别挠了别挠了!再挠我可要破功了…(小声)其实也还行啦","唔… 别摸我后背!我可是要去冒险的,别耽误我!","","",""}} -}; - -void random_chumo(int type,int mode){ - - // mot_nod_status(); - - // play_file_stream_data("C:/chumo.pcm"); - // return ; - - - - int currenttick=aos_get_tickcount(); - - if(currenttick-chumo_tickcount<6000){ - - bk_printf("太频繁.....\n"); - - return ; - } - chumo_tickcount=currenttick; - - // is_dialog_status - - // is_dialog_status=0; - - // ||is_dialog_status==1 - - //if((VC_state==VC_State_Listening&&VAD_status==0)||VC_state==VC_State_End) //||VC_state==VC_State_None - // { - - - bk_printf("VC_state11 %d.....\n",VC_state); - // aic_gpio_output(GPIO_15,GPIO_OUTPUT_LVL_HIGH); - - if(type==0&&mode==0) - play_file_stream_data("C:/chumo.pcm"); - - - int index_temp=count_chumo_index[type][mode]; - - if(index_temp<5) - { - app_audio_set_master_volume(15*vc_cfg.VC_TTS_volume/100); - - AI_AMP_MSG_put(str_huashu[type][mode][index_temp],strlen(str_huashu[type][mode][index_temp]),VC_TTS_PLAY); - - is_dialog_status=0; - } - - // AI_client_VC_synthesis(str_huashu[type][mode][index_temp]); - - count_chumo_index[type][mode]++; - - if(strlen(str_huashu[type][mode][index_temp+1])<5) - count_chumo_index[type][mode]=0; - - // aic_free(AI_TTS_str); - // AI_TTS_str = NULL; - VC_state = VC_State_TTSStart; - // play_audio_file("C:/chumo.mp3"); - - // return ; - // }else{ - - // bk_printf("VC_state22 %d.....\n",VC_state); - - // return ; - // } - - // if(VC_Play_flag!=1){ - - // // aic_gpio_output(GPIO_15,GPIO_OUTPUT_LVL_HIGH); - // play_audio_file("C:/chumo.mp3"); - - // bk_printf("chumo.mp3.....\n"); - - - // }else{ - - // // aic_gpio_output(GPIO_15,GPIO_OUTPUT_LVL_HIGH); - // bk_printf("duihuazhong.....\n"); - - // return ; - - // } - - send_express_str_chumo(type,mode); - - return ; - - // if(chumo_exp_open==1){ - - // random_mada++; - - // if(random_mada==1){ - // send_express_str("happy"); - // } - // if(random_mada==2){ - // send_express_str("cue"); - // } - // if(random_mada==3){ - // send_express_str("surprised"); - // } - // if(random_mada==4){ - // send_express_str("angry"); - // } - // if(random_mada==5){ - // send_express_str("crying"); - // } - // if(random_mada==6){ - // send_express_str("smirk"); - // } - // if(random_mada==7){ - // send_express_str("dissatisfied"); - // } - - // if(random_mada==7) - // random_mada=0; - - // } - - // aic_gpio_output(GPIO_15,GPIO_OUTPUT_LVL_HIGH); - -} #define exptest - -void bk_task_suspend(void *p) -{ - // bk_printf("idle cpu sleep"); - - aic_gpio_input(GPIO_AGPIO_1, GPIO_INPUT_NOINT, NULL, NULL); - -} - -void bk_task_resume(void *p) -{ - - // bk_printf("cpu work"); - -} - - -extern imsl_nn_printf_func imsl_nn_printf; - int auth_vad_status=0; -int auth_kws_status=0; static void uart_recv_UI_handel(void *thread_input) { @@ -5565,50 +5353,43 @@ static void uart_recv_UI_handel(void *thread_input) bk_printf("uart_recv_UI_handel start02 %d",read); - bk_printf("uart_recv %02X %02X %02X %02X %02X %02X %02X ...\n",buf_ui[0],buf_ui[1],buf_ui[2],buf_ui[3],buf_ui[4],buf_ui[5],buf_ui[6]); - if (read == 0 || read > 20) { // drv_logw("uart_recv: err size = (%d)!\n", read); // aic_dma_free(buf); // continue; } - // drv_logi("uart_recv: read size = (%d)!\n", read); + //drv_logi("uart_recv: read size = (%d)!\n", read); - // data = aic_malloc(sizeof(*data)); - // data->addr = buf; - // data->size = read; - // aos_send_to_queue(uart_queue_id, (void*)&data, AOS_WAIT_FOREVER); + // data = aic_malloc(sizeof(*data)); + // data->addr = buf; + // data->size = read; + // aos_send_to_queue(uart_queue_id, (void*)&data, AOS_WAIT_FOREVER); } - bk_printf("uart_recv_UI_handel close "); + bk_printf("uart_recv_UI_handel close02 %d",read); /* close uart. */ // uart_close(ui_uart_handle); } - static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程 { - char count = 20; + char count = 150; boolean pdp_activated ; AI_AMP_MSG_queue_t AI_AMP_msg = {0}; init_VC_cfg(); - - - imsl_nn_printf = bk_printf; - + app_audio_set_master_volume(15*vc_cfg.VC_TTS_volume/100); - aic_gpio_output(GPIO_15,GPIO_OUTPUT_LVL_HIGH );//lcd open ldo - - // GPIO_AGPIO_1 + // aos_sleep(20000); play_audio_file_event("C:/R_POWER_1.mp3"); + // aos_sleep(20000); - // play_audio_file("C:/R_POWER_1.mp3"); + // play_audio_file("C:/R_POWER_1.mp3"); // aic_get_version(FXH01_Version,sizeof(FXH01_Version)); // snprintf(FXH01_Version,sizeof(FXH01_Version),"FX01H_%s",bk_make_timer); @@ -5619,48 +5400,10 @@ static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程 // http://dmp-ota.tos-cn-guangzhou.volces.com/ota/2025_07_24/1948312805093978114gx306l_h3.diff - bk_printf("FXH01_Version:%s",FXH01_Version); - bk_printf("FXH01_Version:%s",FXH01_Version); - bk_printf("FXH01_Version:%s",FXH01_Version); - - //slp_register_sleep_hook(bk_task_suspend, AIC_NULL, - // bk_task_resume, AIC_NULL); - - - // snd_soc_component_write(codec, ES8311_ADC_REG17, es8311->adc_volume); - // snd_soc_component_write(codec, ES8311_DAC_REG32, es8311->dac_volume); - - // aos_sleep(1000); - - while(count --) - { - pdp_activated = aic_is_default_pdp_activated(); - if(pdp_activated == TRUE) - break; - bk_printf("AI_AMP_2_5_init 等待注网..... \n"); - - // audio_play_tone(count%15,500);//播放提示音,测试用 - // audio_play_tone(3,500);//播放提示音,测试用 - - aos_sleep(1000); - } - - - if(pdp_activated){ - - bk_printf("AI_AMP_2_5_init 入网成功..... \n"); - - }else{ - - bk_printf("AI_AMP_2_5_init 第一次入网失败..... \n"); - aic_send_cfun_cmd(0); - aos_sleep(500); - - aic_send_cfun_cmd(1); + bk_printf("FXH01_Version:%s",FXH01_Version); + bk_printf("FXH01_Version:%s",FXH01_Version); + bk_printf("FXH01_Version:%s",FXH01_Version); - aos_sleep(500); - - count=20; while(count --) { @@ -5669,12 +5412,10 @@ static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程 break; bk_printf("AI_AMP_2_5_init 等待注网..... \n"); - // audio_play_tone(count%15,500);//播放提示音,测试用 - // audio_play_tone(3,500);//播放提示音,测试用 - - aos_sleep(1000); - } + //audio_play_tone(count%15,500);//播放提示音,测试用 + //audio_play_tone(3,500);//播放提示音,测试用 + aos_sleep(200); } bk_websocket_demo(); @@ -5700,8 +5441,6 @@ static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程 // aos_sleep(5000); - - ota_update_version(); // if(strlen(ota_url)>3){ @@ -5709,7 +5448,9 @@ static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程 dev_authentication_init(); - count =50; + aic_gpio_output(GPIO_15,GPIO_OUTPUT_LVL_HIGH);//lcd open ldo + + count =500; while(count --) { if(strlen(get_token()) > 5) @@ -5717,7 +5458,7 @@ static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程 break; } bk_printf("AI_AMP_2_5_init 等待鉴权..... \n"); - aos_sleep(200); + aos_sleep(20); } if(sys_10S_timer == NULL) @@ -5729,109 +5470,55 @@ static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程 aic_assert(sys_10S_timer); } - // AI_VC_60S_timer + // AI_VC_60S_timer if(AI_VC_60S_timer == NULL) { AI_VC_60S_timer = aos_create_timer("AI_VC_60S_timer", sys_60S_timeout, &AI_VC_60S_timer, - 50000, + 30000, AOS_AUTO_ACTIVATE, AOS_BE_PERIOD); aic_assert(AI_VC_60S_timer); } - - - // AI_VC_60S_timer - // if(AI_VC_60S_timer == NULL) - // { - // AI_VC_60S_timer = aos_create_timer("AI_VC_60S_timer", - // sys_60S_timeout, &AI_VC_60S_timer, - // 60000, - // AOS_AUTO_ACTIVATE, AOS_BE_PERIOD); - // aic_assert(AI_VC_60S_timer); - // } bk_printf("auth_vad token0: %s..... \n",get_token()); struct AuthInfo auth_info; - // dmp_log_level = 10086; - - // auth_info.server_addr=2; - - strcpy(auth_info.dmp_token, get_token()); + strcpy(auth_info.dmp_token, get_token()); if(strlen(auth_info.dmp_token)>0){ - for(int i=0;i<40;i++){ - + for(int i=0;i<3;i++){ int ret=auth_vad(&auth_info); if(ret==0){ - bk_printf("auth_vad fail token: %s..... \n",get_token()); + bk_printf("auth_vad fail token: %s..... \n",get_token()); - } - else - { + }else{ - bk_printf("auth_vad success token: %s..... \n",get_token()); + bk_printf("auth_vad success token: %s..... \n",get_token()); - auth_vad_status=1; - - break; - - } - - aos_sleep(100); + auth_vad_status=1; + break; } - for(int i=0;i<40;i++){ - - int ret=auth_kws(&auth_info); - - if(ret==0){ - - bk_printf("auth_kws fail token: %s..... \n",get_token()); - - } - else - { - - bk_printf("auth_kws success token: %s..... \n",get_token()); - - auth_kws_status=1; - - break; - - } - - aos_sleep(100); - } + }else{ - bk_printf("auth_vad_status: %d auth_kws_status %d..... \n",auth_vad_status,auth_kws_status); - - if(auth_vad_status==0||auth_kws_status==0) - { - - // play_audio_file_event("C:/xinhaoruo1.mp3"); - - // aos_sleep(500); + // play_audio_file_event("C:/xinhaoruo1.mp3"); + } + if(auth_vad_status==0){ - } + // play_audio_file_event("C:/xinhaoruo1.mp3"); - } - else - { + aos_sleep(2000); - // play_audio_file_event("C:/xinhaoruo1.mp3"); } - - #ifdef exptest - aos_sleep(500); + aos_sleep(50); ui_uart_handle = uart_open(2); @@ -5843,9 +5530,9 @@ static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程 // uart_write(ui_uart_handle,"123", strlen("123")); - u8 cmd_ui[7]={0xAA,0x55,0xFF,0x02,0x01,0x01,0x03}; + // u8 cmd_ui[7]={0xAA,0x55,0xFF,0x02,0x02,0x01,0x04}; - uart_write(ui_uart_handle,cmd_ui, 7); + // uart_write(ui_uart_handle,cmd_ui, 7); }else{ @@ -5853,6 +5540,7 @@ static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程 } + if(UI_UART_read_id == 0) { UI_UART_read_id = aos_create_thread( @@ -5869,29 +5557,26 @@ static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程 #endif -#if BK_SOCKET_IOT - bk_iot_init();//iot初始化 -#endif + + aic_network_enable_pdp_nic_capdump();//打开网络调试log // while(1) // { - // aos_sleep(1000); + // } - #if SUPPORT_MOT - mot_init(); -#endif + + if(vc_cfg.dev_type == DEV_JSWM)//金三完美使用dmp配置开场白 { - AI_VC_start(1); + + AI_VC_start(1); + } else{ VC_TTS_Play(vc_cfg.power_on_tone);//开启vc播放tts } - - - while (1) { if(AI_AMP_task_queue) { @@ -5919,40 +5604,17 @@ static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程 //发送打断 //AI_VC_send_cancel();//发送打断,发送完打断还有发开始音频 //app_logi("interruption!!!!!!!!!!!!!!!!!!!!!"); - - is_dialog_status=0; - VC_Play_End(); VC_state = VC_State_None; websocket_deconnect_VC(); websocket_connect_VC();//重连 AI_VC_send_satrt(0);//发送开始 - - AI_AMP_MSG_put(0,0,VC_PLAY_START);//打开声音 + VC_Play_Start(); break; case VC_CLOSE: AI_VC_Close(); - break; - case CLOSE_IOT: - - if(AI_client_IOT)//先断开再关闭读线程 - { - delete_websocket_res(AI_client_IOT);//删除该对象ws资源管控 - close_websocket_client(AI_client_IOT); - AI_client_IOT = NULL; - AI_VC_read_IOT_id=0; - - bk_printf("CLOSE_IOT"); - // AI_client_IOT - } - - break; - case RANDOM_MT: - - random_statu_mot(); - break; case VC_START: AI_VC_start(0); @@ -6005,8 +5667,6 @@ static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程 break; case AI_KEY_PRESS: - // is_dialog_status=0; - AI_key_press(); break; @@ -6031,7 +5691,8 @@ static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程 case AI_TIMER_EVENT: sys_10S_timeout_even(); break; - case AI_TIMER_EVENT_IOT: + + case AI_TIMER_EVENT_IOT: sys_60S_timeout_even(); break; @@ -6039,67 +5700,6 @@ static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程 if(AI_AMP_msg.data) uart_write(ai_uart_handle,AI_AMP_msg.data, AI_AMP_msg.len); break; - case AI_KEY2_RELEASE: - // bk_printf("AI_KEY2_RELEASE"); - - // mot_nod_status(); - if(AI_VC_stata==1) - random_chumo(2,0); - // #if SUPPORT_MOT - // mot_nod(5); - // #endif - break; - case AI_KEY3_RELEASE: - bk_printf("AI_KEY3_RELEASE"); - // #if SUPPORT_MOT - // mot_nod(5); - // #endif - if(AI_VC_stata==1) - random_chumo(0,0); - break; - case AI_KEY4_RELEASE: - bk_printf("AI_KEY4_RELEASE"); - // #if SUPPORT_MOT - // mot_nod(5); - // #endif - if(AI_VC_stata==1) - random_chumo(1,0); - break; - case AI_KEY2_LONG_PRESS: - bk_printf("AI_KEY2_LONG_PRESS"); - // #if SUPPORT_MOT - // mot_nod(5); - // #endif - if(AI_VC_stata==1) - random_chumo(2,1); - - break; - case AI_KEY3_LONG_PRESS: - bk_printf("AI_KEY3_LONG_PRESS"); - // #if SUPPORT_MOT - // mot_nod(5); - // #endif - if(AI_VC_stata==1) - random_chumo(0,1); - break; - case AI_KEY4_LONG_PRESS: - bk_printf("AI_KEY4_LONG_PRESS"); - // #if SUPPORT_MOT - // mot_nod(5); - // #endif - if(AI_VC_stata==1) - random_chumo(1,1); - break; - case MOT_GPIO_HANDLE_CB: - - mot_gpio_handle_cb(AI_AMP_msg.data); - break; - - case AI_MOT_BACK_MID: - - back_middle_statu_mot(); - break; - default: break; } @@ -6107,7 +5707,7 @@ static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程 aic_free(AI_AMP_msg.data); }else { - aos_sleep(10); + aos_sleep(10); } @@ -6135,7 +5735,7 @@ int AI_AMP_2_5_init(void) sizeof(AI_AMP_MSG_queue_t), 200); } - + bk_key_init(); AI_AMP_task_id = aos_create_thread( "AI_AMP_2_5", AI_AMP_2_5_task, @@ -6145,8 +5745,7 @@ int AI_AMP_2_5_init(void) NULL, ai_VC_task_priority, AOS_AUTO_START); - bk_key_init(); - + return AIC_SUCCESS; } diff --git a/2.code/aicos/app/AI_AMP_2_5/AI_AMP_2_5.h b/2.code/aicos/app/AI_AMP_2_5/AI_AMP_2_5.h index 1d08871..5bedec6 100644 --- a/2.code/aicos/app/AI_AMP_2_5/AI_AMP_2_5.h +++ b/2.code/aicos/app/AI_AMP_2_5/AI_AMP_2_5.h @@ -1,16 +1,12 @@ #include "aic_osa.h" #define SUPPORT_OPUS 1 -#define SUPPORT_MOT 1 //马达驱动 -#define BK_SOCKET_IOT 0 - #define BK_LOG_NONE 0//不打印 #define BK_LOG_UART 1//串口打印 #define BK_LOG_USB 2//USB打印 -// -#define BK_LOG_CFG BK_LOG_USB + #define BK_LOG_CFG BK_LOG_USB typedef enum { @@ -51,11 +47,18 @@ typedef struct int speech_rate;//语速配置 unsigned int vad_silence;//vad断句时间 ms char VC_TTS_volume; + + char alarm_name[5][50]; + char alarm_content[5][200]; + + u8 alarm_count; //unsigned unsigned int end_flag; }AI_AMP_2_5_cfg; + + //#define FXH01_Version "BK_FX01H_V202505300931" extern char FXH01_Version[]; extern AI_AMP_2_5_cfg vc_cfg; @@ -79,25 +82,12 @@ typedef enum AI_AMP_MSG AI_KEY_RELEASE,//AI键释放 AI_KEY_LONG_PRESS,//AI键长按 AI_KEY_LONG_RELEASE,//AI键长按释放 - AI_KEY2_PRESS,//KEY2 - AI_KEY3_PRESS,//KEY2 - AI_KEY4_PRESS,//KEY2 - AI_KEY2_RELEASE, - AI_KEY3_RELEASE, - AI_KEY4_RELEASE, - AI_KEY2_LONG_PRESS, - AI_KEY3_LONG_PRESS, - AI_KEY4_LONG_PRESS, PWK_KEY_RELEASE,//侧键 PLAY_AUDIO_FILE,//播放本地音频文件 PLAY_FILE_STREAM_DATA,//播放本地文件,用音频流的方式 AI_TIMER_EVENT,//定时器事件 - MOT_GPIO_HANDLE_CB, AI_PRINTF,//打印 AI_TIMER_EVENT_IOT,//定时器事件 - AI_MOT_BACK_MID, - CLOSE_IOT, - RANDOM_MT, } AI_AMP_MSG_Type; typedef struct { @@ -139,7 +129,6 @@ typedef struct char *data; u32 len; }AI_VC_audio_queue_t; -uint16_t modbus_crc16(const uint8_t *data, uint16_t length) ; int AI_VC_start(char is_greeting); void AI_VC_Close(void); @@ -153,4 +142,10 @@ int save_VC_cfg(void); int play_audio_file(char *file_name); void AI_VC_put_play_data(char *data,u32 len);//音频数据入队播放 -int bk_get_iccid(char *iccid); \ No newline at end of file +void IOT_update_statu(int type,char *type_str,char *content); + +void IOT_heart(); + +void IOT_V3_update_statu(int type,char *type_str,char *content); + +void IOT_V3_heart(); \ No newline at end of file diff --git a/2.code/aicos/app/AI_AMP_2_5/CMakeLists.txt b/2.code/aicos/app/AI_AMP_2_5/CMakeLists.txt index 27346ec..feb6784 100644 --- a/2.code/aicos/app/AI_AMP_2_5/CMakeLists.txt +++ b/2.code/aicos/app/AI_AMP_2_5/CMakeLists.txt @@ -11,8 +11,8 @@ aic_library_sources_ifdef( ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/bk_key.c ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/dev_authentication.c ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/bk_opus_coder.c - ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/bk_iot.c - ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/mot_dev.c + ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/aic_mp3decoder_api.c + ${AIC_SOURCE_ROOT}/app/AI_AMP_2_5/aic_mp3decoder_demo.c ) diff --git a/2.code/aicos/app/AI_AMP_2_5/bk_key.c b/2.code/aicos/app/AI_AMP_2_5/bk_key.c index 9552a8a..203d896 100644 --- a/2.code/aicos/app/AI_AMP_2_5/bk_key.c +++ b/2.code/aicos/app/AI_AMP_2_5/bk_key.c @@ -10,13 +10,15 @@ #include "alog_api.h" #include "pwr_key.h" #include "sysoff.h" -#include "gpo_inc.h" -#include -#define TP_POWER_EN GPO_0 + + #define LOG_MODULE AMOD_KPC + + + static int32_t bk_kpc_callback(void *p_param, uint32_t size) { kpc_key_array_t *key_arr = (kpc_key_array_t *)p_param; @@ -26,81 +28,35 @@ static int32_t bk_kpc_callback(void *p_param, uint32_t size) } for (int i = 0; i < KPC_KEY_PRESSED_MAX_KEY_NUM; i++) { - // bk_printf("bk_kpc_callback key[%d].key_value=%d",i,key_arr->key[i].key_value); + bk_printf("bk_kpc_callback key[%d].key_value=%d",i,key_arr->key[i].key_value); switch (key_arr->key[i].key_event) { case KPC_KEY_EVENT_PRESS://按下 - - // bk_printf("[%x]testkey123",key_arr->key[i].key_value); - - // bk_printf("[%x]testkey123",key_arr->key[i].); - if (key_arr->key[i].key_value == 0) { //AI键 + // bk_printf("[%d]AI_key_press",key_arr->key[i].key_value); - // bk_printf("00000000000"); + if (key_arr->key[i].key_value == 0) {//AI键 AI_AMP_MSG_put(0, 0, AI_KEY_PRESS); - // bk_printf("[%d]AI_key_press",key_arr->key[i].key_value); - }else if(key_arr->key[i].key_value == 1) {//AI键 - // bk_printf("111111111"); + AI_AMP_MSG_put(0, 0, AI_KEY_PRESS); - }else if(key_arr->key[i].key_value == 2) {//按键2键 - // bk_printf("222222"); - AI_AMP_MSG_put(0, 0, AI_KEY2_PRESS); - }else if(key_arr->key[i].key_value == 4) {//按键2键 - // bk_printf("222222"); - AI_AMP_MSG_put(0, 0, AI_KEY2_PRESS); - }else if(key_arr->key[i].key_value == 5) {//按键2键 - // bk_printf("222222"); - AI_AMP_MSG_put(0, 0, AI_KEY3_PRESS); - }else if(key_arr->key[i].key_value == 6) {//按键2键 - // bk_printf("222222"); - AI_AMP_MSG_put(0, 0, AI_KEY4_PRESS); } break; case KPC_KEY_EVENT_RELEASE://释放 - - // bk_printf("KPC_KEY_EVENT_RELEASE"); - if (key_arr->key[i].key_value == 0) {//AI键 AI_AMP_MSG_put(0, 0, AI_KEY_RELEASE); }else if(key_arr->key[i].key_value == 1) {//AI键 AI_AMP_MSG_put(0, 0, AI_KEY_RELEASE); - }else if(key_arr->key[i].key_value == 4) {// - - AI_AMP_MSG_put(0, 0, AI_KEY2_RELEASE); + }else if(key_arr->key[i].key_value == 2) {// - }else if(key_arr->key[i].key_value == 5) {// - - AI_AMP_MSG_put(0, 0, AI_KEY3_RELEASE); - - }else if(key_arr->key[i].key_value == 6) {// - - AI_AMP_MSG_put(0, 0, AI_KEY4_RELEASE); } - break; - case KPC_KEY_EVENT_LONGKEY://长按 - - bk_printf("KPC_KEY_EVENT_LONGKEY"); if (key_arr->key[i].key_value == 0) {//AI键 AI_AMP_MSG_put(0, 0, AI_KEY_LONG_PRESS); }else if(key_arr->key[i].key_value == 1) {//AI键 AI_AMP_MSG_put(0, 0, AI_KEY_LONG_PRESS); - }else if(key_arr->key[i].key_value == 5) {//AI键 - - AI_AMP_MSG_put(0, 0, AI_KEY3_LONG_PRESS); - - } - else if(key_arr->key[i].key_value == 6) {//AI键 - - AI_AMP_MSG_put(0, 0, AI_KEY4_LONG_PRESS); - - }else if(key_arr->key[i].key_value == 4) {//AI键 - - AI_AMP_MSG_put(0, 0, AI_KEY2_LONG_PRESS); } break; @@ -111,7 +67,7 @@ static int32_t bk_kpc_callback(void *p_param, uint32_t size) AI_AMP_MSG_put(0, 0, AI_KEY_LONG_RELEASE); } else if(key_arr->key[i].key_value == 2) {//PWK键 - //AI_AMP_MSG_put(0, 0, PWK_KEY_RELEASE); + AI_AMP_MSG_put(0, 0, PWK_KEY_RELEASE); } // bk_printf("[%d]AI_key_long_press",key_arr->key[i].key_value); @@ -122,7 +78,7 @@ static int32_t bk_kpc_callback(void *p_param, uint32_t size) break; } } - // bk_printf("\n"); + bk_printf("\n"); return 0; @@ -160,8 +116,6 @@ void bk_to_ups_sync(void *ptr) { // gx_ups_phy_from_rtc(); AI_AMP_MSG_put(0, 0, VC_CLOSE); - //aos_sleep(1000); - AI_AMP_MSG_put(0,0,AI_MOT_BACK_MID); // gx_ups_phy_cnt_clr(); play_audio_file("C:/zhengzaiguanji.mp3"); bk_msg_printf("bk_to_ups_sync"); @@ -171,10 +125,7 @@ void bk_to_ups_sync(void *ptr) void bk_key_init(void) { // bk_printf("开始初始化按键模块\n"); 不注释掉就卡住没日志 - aic_gpo_output(TP_POWER_EN,GPO_OUTPUT_HIGH );//tp电源 - - // aic_gpo_output(GPO_13,GPO_OUTPUT_LOW);//tp电源 - + int32_t handle = aic_srv_kpc_register("app", bk_kpc_callback); if (handle < 0) { alog_error("Failed to register KPC callback\n"); // 使用 alog_error 输出错误信息 diff --git a/2.code/aicos/app/AI_AMP_2_5/bk_opus_coder.c b/2.code/aicos/app/AI_AMP_2_5/bk_opus_coder.c index 26f663c..311e9c7 100644 --- a/2.code/aicos/app/AI_AMP_2_5/bk_opus_coder.c +++ b/2.code/aicos/app/AI_AMP_2_5/bk_opus_coder.c @@ -278,9 +278,9 @@ int ogg_opus_decode_data(char *in_ogg_data,int in_ogg_data_len) /**********1阶段判断头********** */ if(ogg_hend_len==0)//没有剩余的头数据 { - // bk_printf("ogg_hend_len123:%d",ogg_hend_len); + bk_printf("ogg_hend_len123:%d",ogg_hend_len); - // bk_printf("bk_rb_data_len:%d",bk_rb_data_len(OPUS_decoder_rb_data)); + bk_printf("bk_rb_data_len:%d",bk_rb_data_len(OPUS_decoder_rb_data)); bk_rb_read(OPUS_decoder_rb_data,ogg_hend,27); ogg_hend_len+=27;//读页头 @@ -295,7 +295,7 @@ int ogg_opus_decode_data(char *in_ogg_data,int in_ogg_data_len) { if(bk_rb_data_len(OPUS_decoder_rb_data)< seg_num)//判断可读数据够不够 { - // bk_printf("算页大小数据不够,退出当前解包:seg_num %d",seg_num); + bk_printf("算页大小数据不够,退出当前解包:seg_num %d",seg_num); break; } @@ -327,11 +327,11 @@ int ogg_opus_decode_data(char *in_ogg_data,int in_ogg_data_len) } break; } - // bk_printf("整页数据大小:%d",seg_size); + bk_printf("整页数据大小:%d",seg_size); /************3阶段读完整包****************** */ if(bk_rb_data_len(OPUS_decoder_rb_data)< seg_size)//判断可读数据够不够 { - // bk_printf("读整页数据大小不够,退出当前解包:seg_size %d,ogg_hend_len:%d",seg_size,ogg_hend_len); + bk_printf("读整页数据大小不够,退出当前解包:seg_size %d,ogg_hend_len:%d",seg_size,ogg_hend_len); break; } @@ -370,7 +370,7 @@ int ogg_opus_decode_data(char *in_ogg_data,int in_ogg_data_len) dec_inparam.outbuffer_size = 4096; ret = aic_opus_decode(&dec_inparam); - // bk_printf("opus解码 输入大小:%d,输出大小:%d", frame_length,dec_inparam.outputfrms_size); + bk_printf("opus解码 输入大小:%d,输出大小:%d", frame_length,dec_inparam.outputfrms_size); opus_encode_len++; @@ -400,7 +400,7 @@ int ogg_opus_decode_data(char *in_ogg_data,int in_ogg_data_len) // bk_printf("opus解码 输入大小:%d,输出大小:%d", frame_length,dec_inparam.outputfrms_size); - // bk_printf("ogg-opus解码 输入数据大小:%d,输出数据大小:%d,耗时:%d ms",input_tmp_len,ooutput_tmp_len,aos_get_tickcount()-timer_ms ); + bk_printf("ogg-opus解码 输入数据大小:%d,输出数据大小:%d,耗时:%d ms",input_tmp_len,ooutput_tmp_len,aos_get_tickcount()-timer_ms ); // opus_decode_len+=ooutput_tmp_len; @@ -429,6 +429,10 @@ int ogg_opus_decode_data(char *in_ogg_data,int in_ogg_data_len) #endif return 0; } + + +// char pcm_buf_back[ = aic_malloc(1920)]; + int my_opus_decode_data(char *in_ogg_data,int in_ogg_data_len) { int data_count = 0; @@ -462,7 +466,7 @@ int my_opus_decode_data(char *in_ogg_data,int in_ogg_data_len) dec_inparam.outbuffer_size = 1920; ret = aic_opus_decode(&dec_inparam); - // bk_printf("opus解码 输入大小:%d,输出大小:%d", in_ogg_data_len,dec_inparam.outputfrms_size); + bk_printf("opus解码 输入大小:%d,输出大小:%d", in_ogg_data_len,dec_inparam.outputfrms_size); opus_encode_len++; @@ -482,7 +486,7 @@ int my_opus_decode_data(char *in_ogg_data,int in_ogg_data_len) AI_VC_put_play_data(pcm_buf,dec_inparam.outputfrms_size);//发送数据到音频队列 - // audio_data(pcm_buf,dec_inparam.outputfrms_size,24); + audio_data(pcm_buf,dec_inparam.outputfrms_size,24); // aos_sleep(1); diff --git a/2.code/aicos/app/AI_AMP_2_5/bk_opus_coder.h b/2.code/aicos/app/AI_AMP_2_5/bk_opus_coder.h index 4220e30..8fc76dd 100644 --- a/2.code/aicos/app/AI_AMP_2_5/bk_opus_coder.h +++ b/2.code/aicos/app/AI_AMP_2_5/bk_opus_coder.h @@ -8,4 +8,5 @@ int ogg_opus_decode_data(char *in_ogg_data,int in_ogg_data_len); int my_opus_decode_data(char *in_ogg_data,int in_ogg_data_len); + #endif diff --git a/2.code/aicos/app/AI_AMP_2_5/bk_websocket.c b/2.code/aicos/app/AI_AMP_2_5/bk_websocket.c index 2dbcd22..42d3dcf 100644 --- a/2.code/aicos/app/AI_AMP_2_5/bk_websocket.c +++ b/2.code/aicos/app/AI_AMP_2_5/bk_websocket.c @@ -333,6 +333,8 @@ int send_handshake(WebSocketClient *client,const char *headers) { char *request =aic_zalloc(BUFFER_SIZE); if(headers!= NULL) { + + bk_printf("headers12"); snprintf(request, BUFFER_SIZE, "GET /%s?%s HTTP/1.1\r\n" "Host: %s:%d\r\n" @@ -346,6 +348,8 @@ int send_handshake(WebSocketClient *client,const char *headers) { client->path,client->query ,client->host,client->port, accept_key,client->host,client->port,headers); }else { + + bk_printf("headers13"); snprintf(request, BUFFER_SIZE, "GET /%s?%s HTTP/1.1\r\n" "Host: %s:%d\r\n" @@ -429,10 +433,122 @@ send_websocket_message_ERROR: } +// 发送 WebSocket 消息 +int send_iot_message(WebSocketClient *client, const unsigned char *message, size_t message_len) +{ + if(!client) + return -1; + unsigned char *frame=aic_zalloc(message_len + 50); + int offset = 0; + int ret = -1; + if(!frame) + { + bk_printf("send_websocket_message zalloc error"); + return -1; + } + + for (size_t i = 0; i < message_len; ++i) { + frame[offset + i] = message[i] ; + } + offset += message_len; + + // audio_data(message,message_len,27); + // 发送帧 + if (send(client->sockfd, frame, offset, 0) < 0) { + bk_printf("send message failed"); + ret = -1; + goto send_websocket_message_ERROR; + } + bk_printf("send message success"); + + ret = 0; +send_websocket_message_ERROR: + aic_free(frame); + bk_sleep(message_len/1000+1); + return ret; +} + + +// 接收 WebSocket 消息,返回读到长度 +// char websocket_tmp_b[8*1024] = {0}; +// int websocket_tmp_b_len = 0; +// char frame_t[20] = {0}; +// int frame_t_len = 0; +// int bytes_received_t_1 = 0; +// int bytes_received_t = 0; + +void deal_iot_receive(char *json); +int receive_iot_message(WebSocketClient *client) + { + + if(!client ) + return -1; + unsigned char frame[200]={0}; + + unsigned char json_data[200]={0}; + unsigned char masking_key[4]; + int bytes_received = 0; + int recv_len = 0 ; + static u8 last_byte = 0; + static u32 error_count = 0; + // while(1) + // { + // recv_len = recv(client->sockfd, frame+bytes_received, 2-bytes_received, 0); + // bytes_received +=recv_len; + // if(bytes_received>=2) + // break; + // } + + bk_printf("receive_iot_message................................."); + + while(1) + { + bytes_received = recv(client->sockfd, frame, 200, 0); + + if(bytes_received>0){ + + bk_printf("get iot message................................."); + bk_printf("bytes_received %02X %02X %02X %02X %02X %02X %02X %02X %02X ...\n",frame[0],frame[1],frame[2],frame[3],frame[4],frame[5],frame[6],frame[7],frame[8]); + + if(frame[2]==0x03){ + + int length_data=frame[3]; + + memset(json_data,0,200); + memcpy(json_data,frame+5,length_data); + bk_printf("length %d,json_data %s ...\n",length_data,json_data); + + // cJSON *root = cJSON_CreateString(json_data); + + //cJSON *cmd_obj=cJSON_GetObjectItem(root,"cmd"); + + //bk_printf(cJSON_GetStringValue(cmd_obj)); + + //switch_volume + + // deal_iot_receive(json_data); + + + // cJSON_GetStringValue + + } + + } + + if(bytes_received<0) + break; + + memset(frame,0,200); + aos_sleep(200); + } + + bk_printf("AI_VC_IOT_task exit...\n"); + +} int receive_websocket_message(WebSocketClient *client, unsigned char *buf,int len,WebSocketMessageType *code) { @@ -668,204 +784,247 @@ int receive_websocket_message(WebSocketClient *client, unsigned char *buf,int l return payload_len;//parse_frame(buf, bytes_received, buf,code); } -// 初始化 WebSocket 客户端 -WebSocketClient *init_websocket_client(const char *url, const char *headers) { - //bk_printf("init_websocket_client 1\n"); - char *buffer = NULL; - WebSocketClient *client =NULL; - BK_URL parsed_url = {0}; - parsed_url = parse_url(url);//解析url - //bk_printf("url: %s", url); - if (parsed_url.error) { - bk_printf("Error: %s", parsed_url.error_message); - goto client_ERROR; - } else { - bk_printf("Protocol: %s", parsed_url.protocol); - bk_printf("Host: %s", parsed_url.host); - bk_printf("Port: %d", parsed_url.port); - bk_printf("Path: %s", parsed_url.path); - bk_printf("Query: %s", parsed_url.query); - } - client = aic_zalloc(sizeof(WebSocketClient)) ; - if(!client) - { - bk_printf("init_websocket_client alloc error"); - goto client_ERROR; - } - struct addrinfo hints, *addr_list, *cur; - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - if( getaddrinfo( parsed_url.host, parsed_url.port_str, &hints, &addr_list ) != 0 ) - //if( getaddrinfo( "www.baidu.com", "80", &hints, &addr_list ) != 0 ) +int receive_websocket_message_V3(WebSocketClient *client, unsigned char *buf,int len,WebSocketMessageType *code) { + // u64 timer_ms = aos_get_tickcount(); + // bk_printf("receive_websocket_message 1 timer_ms=%d\n",timer_ms); + if(!client ) + return -1; + unsigned char frame[20]={0}; + unsigned char masking_key[4]; + int bytes_received = 0; + int recv_len = 0 ; + static u8 last_byte = 0; + static u32 error_count = 0; + // while(1) + // { + // recv_len = recv(client->sockfd, frame+bytes_received, 2-bytes_received, 0); + // bytes_received +=recv_len; + // if(bytes_received>=2) + // break; + // } + + while(1) { - bk_printf("init_websocket_client getaddrinfo error"); - goto client_ERROR; - } + bytes_received = recv(client->sockfd, frame, 1, 0); - for( cur = addr_list; cur != NULL; cur = cur->ai_next ) - { - client->sockfd = (int) socket( cur->ai_family, cur->ai_socktype, - cur->ai_protocol ); - if( client->sockfd < 0 ) - { - continue; + // bk_printf("receive_websocket_message:frame:0x%x,bytes_received:%d",frame[0],bytes_received); + + if (bytes_received == 0) { + bk_printf("Connection closed by server.1\n\n\n\n"); + return 0; + } else if(bytes_received<0){ + bk_printf("receive message failed1\n\n\n\n"); + return -1; } + if(frame[0]!= 0x80 && frame[0]!= 0x81 && frame[0]!= 0x82 && frame[0]!= 0x88 && frame[0]!= 0x89 && frame[0]!= 0x8A) + { + error_count++; + bk_printf("receive_websocket_message:hend =0x%X,0x%X ,last_byte =0x%x error_count =%d ERROR!!!!!!!!!",frame[0],frame[1],last_byte,error_count); - if( connect( client->sockfd , cur->ai_addr, (int)cur->ai_addrlen ) == 0 ) + if(last_byte!= 0x80 && last_byte!= 0x81 && last_byte!= 0x82 && last_byte!= 0x88 && last_byte!= 0x89 && last_byte!= 0x8A) + { + bk_printf("receive_websocket_message:hend =0x%X,0x%X ,last_byte =0x%x ERROR222222222!!!!!!!!!",frame[0],frame[1],last_byte); + continue; + } + + }else { break; } + } + // bk_printf("websocket2 timer_ms=%d\n",timer_ms- aos_get_tickcount()); + // timer_ms = aos_get_tickcount(); + //bk_sleep(5); + bytes_received = recv(client->sockfd, frame+1, 1, 0); + if (bytes_received == 0) { + bk_printf("Connection closed by server.2\n\n\n\n"); + return 0; + } else if(bytes_received<0){ + bk_printf("receive message failed 2 \n\n\n\n"); + return -1; + } + //unsigned char fin = (frame[0] & 0x80) >> 7; + *code = frame[0] & 0x0F; + unsigned char mask = (frame[1] & 0x80) >> 7; + unsigned int payload_len = frame[1] & 0x7F; + - close( client->sockfd ); - + size_t offset = 2; + if (payload_len == 126) { + unsigned short extended_payload_len; + bytes_received = 0; + while(1) + { + recv_len= recv(client->sockfd, frame+offset+bytes_received, 2-bytes_received, 0); + if (recv_len == 0) { + bk_printf("Connection closed by server 3.\n\n\n\n"); + return 0; + } else if(recv_len<0){ + bk_printf("receive message failed 3 \n\n\n\n"); + return -1; + } + bytes_received +=recv_len; + if(bytes_received>=2) + break; + + } + // bytes_received_t = bytes_received; + memcpy(&extended_payload_len, frame + 2, 2); + payload_len = ntohs(extended_payload_len); + //bk_printf("receive_websocket_message:payload_len=0x%X",extended_payload_len); + offset += 2; + } else if (payload_len == 127) { + u64 extended_payload_len; + bytes_received = 0; + while(1) + { + recv_len= recv(client->sockfd, frame+offset+bytes_received, 8-bytes_received, 0); + if (recv_len == 0) { + bk_printf("Connection closed by server 4.1\n\n\n\n"); + return 0; + } else if(recv_len<0){ + bk_printf("receive message failed 4\n\n\n\n"); + return -1; + } + bytes_received +=recv_len; + if(bytes_received>=8) + break; + + } + memcpy(&extended_payload_len, frame + 2, 8); + payload_len = ntohll(extended_payload_len); + offset += 8; } - freeaddrinfo(addr_list); // 释放资源 - if(client->sockfd<0) + if(payload_len>len) { - bk_printf("init_websocket_client connect error"); - goto client_ERROR; + bk_printf("receive_websocket_message:len =%d ERROR",payload_len); + recv(client->sockfd, buf, len, 0); + return -1; } - bk_printf("init_websocket_client connect ok,sockfd:%d",client->sockfd); -// client->sockfd = socket(AF_INET, SOCK_STREAM, 0); -// if (client->sockfd < 0) { -// bk_printf("socket creation failed"); -// goto client_ERROR; -// } - -// // bk_printf("init_websocket_client 3\n"); -// struct sockaddr_in server_addr; -// server_addr.sin_family = AF_INET; -// server_addr.sin_port = htons(parsed_url.port); -// inet_pton(AF_INET, parsed_url.host, &server_addr.sin_addr); - -// if (connect(client->sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { -// bk_printf("connection failed"); -// close(client->sockfd); -// goto client_ERROR; -// } - - - strcpy(client->host, parsed_url.host); - strcpy(client->path, parsed_url.path); - strcpy(client->query, parsed_url.query); - client->port = parsed_url.port; - if (send_handshake(client,headers) < 0) { //发送头 - close(client->sockfd); - goto client_ERROR; - } - - buffer=aic_zalloc(BUFFER_SIZE); - ssize_t bytes_received = recv(client->sockfd, buffer, BUFFER_SIZE - 1, 0); - if (bytes_received > 0) { - buffer[bytes_received] = '\0'; - bk_printf("Received handshake response:\n%s\n", buffer); - } - if(strstr(buffer,"HTTP/1.1 101") == NULL) - { + // bk_printf("receive_websocket_message :"); + // for(int i = 0;isockfd, frame+offset, 4, 0); + memcpy(masking_key, frame + offset, 4); + offset += 4; + } + + + bytes_received = 0; + // payload_len-=1;//少读一个字节,防止粘包 + //bk_sleep(1); + while(1)//读主体内容 + { + // bk_sleep(recv_len/200+1); + // bk_printf("bytes_received %d %d",payload_len,bytes_received); + recv_len = recv(client->sockfd, buf+bytes_received, payload_len-bytes_received, 0); + // bk_printf("recv_len %d %d",payload_len,recv_len); + if (recv_len == 0) { + bk_printf("Connection closed by server.5\n\n\n\n\n"); + return 0; + } else if(recv_len<0){ + bk_printf("receive message failed 5\n\n\n\n"); + return -1; + } -// 关闭 WebSocket 客户端 -void close_websocket_client(WebSocketClient *client) { - if(client) + bytes_received += recv_len; + + //bk_printf("receive_websocket_message:bytes_received=%d recv_len =%d",bytes_received,recv_len); + if(bytes_received >= payload_len) + { + //bk_printf("receive_websocket_message:payload_len=%d,bytes_received=%d",payload_len,bytes_received); + break; + } + + } + //bk_sleep(1); + // bk_printf("websocket 3 timer_ms=%d\n",timer_ms- aos_get_tickcount()); + // timer_ms= aos_get_tickcount(); + // bk_sleep(1);//等最后一字节返回,防止粘包 + // recv(client->sockfd, buf+payload_len, 1, 0);//读最后一字节 + // payload_len+=1; + if(mask) { - soc_close(client->sockfd); - aic_free(client); + for (size_t i = 0; i < payload_len; ++i) { + buf[i] = buf[i] ^ masking_key[i % 4]; + } } -} -int http_get_client(const char *url, const char *headers,const char *Content_Type,char* response,int response_len); -int bk_websocket_demo(void) { - // WebSocketClient *client; - // client = init_websocket_client("ws://118.145.158.207:22086/vc/coze?is_auth=0",NULL); - // if (client== NULL) { - // return -1; + // if (*code == WS_TEXT) { + // bk_printf("Received text message: %.*s\n", (int)payload_len, buf); + // } else if (*code == WS_BINARY) { + // bk_printf("Received binary message of length %zu\n", payload_len); // } - // close_websocket_client(client); - // aos_sleep(2); - // char *response =aic_zalloc(BUFFER_SIZE); - // //char *url = "http://dmp.raisound.com/sv/vad/auth/token?nonceStr=abc&sign=3470327e8eee163f00d5f54cc936d32595189b16d1e89c2b50155b80227c85d0×tamp=1750406765243&token=9542143a532adc10ec6ee530cd1824d53b"; - // char *url = "http://dmp.raisound.com/bz-mp-api/sv/vad/auth/token?nonceStr=abc&sign=3470327e8eee163f00d5f54cc936d32595189b16d1e89c2b50155b80227c85d0×tamp=1750406765243&token=9542143a532adc10ec6ee530cd1824d53b"; - // http_get_client(url,"bz-dt:9542143a532adc10ec6ee530cd1824d53b","application/x-www-form-urlencoded",response,BUFFER_SIZE); - // bk_printf("http GET data:%s",response); - // aic_free(response); - return 0; -} - -/************************http*********************************** */ + // if(error_count>0) + // { + // bk_printf("WS ERROR!!!!!!last_byte:0x%x bytes_received_t_1:0x%x\r\n\n\n\n\n\n\n",last_byte,bytes_received_t_1); + // bk_print_hex(frame_t,frame_t_len); + // bk_print_hex(websocket_tmp_b,websocket_tmp_b_len); + // bk_printf("WS ERROR!!!!!!\r\n\n\n\n\n\n\n"); + // bk_print_hex(frame,offset); + // bk_print_hex(buf,payload_len); + + // } + // bytes_received_t_1 = bytes_received_t; + if (*code == WS_TEXT) + { -// WebSocket 客户端结构体 -typedef struct { - int sockfd; - char host[128]; - char path[128]; - char query[512]; - int port; -} httpClient; -int send_http_get_handshake(httpClient *client,const char *headers,const char *Content_Type) { - char key[WEBSOCKET_KEY_LEN]; - bk_printf("send_handshake1"); - generate_websocket_key(key); - char accept_key[64]; - int ret = 0; - generate_accept_key(key, accept_key); - bk_printf("send_handshake2"); - char *request =aic_zalloc(BUFFER_SIZE); - if(headers!= NULL) + }else if(*code == WS_BINARY) { - snprintf(request, BUFFER_SIZE, - "GET /%s?%s HTTP/1.1\r\n" - "Host: %s:%d\r\n" - "Content-Type: %s\r\n" - "Connection: close\r\n" - "%s\r\n" - "\r\n", - client->path,client->query ,client->host,client->port,Content_Type,headers); - }else + + }else if(*code == WS_CLOSE) { - snprintf(request, BUFFER_SIZE, - "GET /%s?%s HTTP/1.1\r\n" - "Host: %s:%d\r\n" - "Content-Type: %s\r\n" - "Connection: close\r\n" - "\r\n", - client->path,client->query , client->host,client->port,Content_Type); + payload_len = 0; + }else if(*code == WS_PONG) + { + //payload_len = 1; + }else if(*code == WS_PING) + { + send_websocket_message(client,buf,payload_len,WS_PONG); + //payload_len = 1; + }else if(*code == WS_CONT) + { + //payload_len = 1; } + last_byte = buf[payload_len-1]; + //timer_ms = aos_get_tickcount(); + //bk_printf("receive_websocket_message 4 timer_ms=%d len = %d\n",timer_ms,payload_len); + error_count=0; + // websocket_tmp_b_len = payload_len; + // if(payload_len>sizeof(websocket_tmp_b)) + // { + // websocket_tmp_b_len=sizeof(websocket_tmp_b); + // } + // memcpy(websocket_tmp_b,buf,websocket_tmp_b_len); - bk_printf("send_handshake request:\r\n%s",request); - if (send(client->sockfd, request, strlen(request), 0) < 0) { - bk_printf("send handshake failed :sockfd:%d",client->sockfd); - - ret = -1; - } - bk_printf("send_handshake3"); - aic_free(request); - return ret; + + // frame_t_len = offset; + // if(frame_t_len>sizeof(frame_t)) + // { + // frame_t_len=sizeof(frame_t); + // } + // memcpy(frame_t,frame,frame_t_len); + + + return payload_len;//parse_frame(buf, bytes_received, buf,code); } -//http get 客户端 -int http_get_client(const char *url, const char *headers,const char *Content_Type,char* response,int response_len) { - //bk_printf("init_websocket_client 1\n"); - httpClient *client =NULL; +// 初始化 WebSocket 客户端 +WebSocketClient *init_websocket_client(const char *url, const char *headers) { + //bk_printf("init_websocket_client 1\n"); + char *buffer = NULL; + WebSocketClient *client =NULL; BK_URL parsed_url = {0}; parsed_url = parse_url(url);//解析url //bk_printf("url: %s", url); @@ -880,10 +1039,10 @@ int http_get_client(const char *url, const char *headers,const char *Content_Typ bk_printf("Query: %s", parsed_url.query); } - client = aic_zalloc(sizeof(httpClient)) ; + client = aic_zalloc(sizeof(WebSocketClient)) ; if(!client) { - bk_printf("http_get_client alloc error"); + bk_printf("init_websocket_client alloc error"); goto client_ERROR; } struct addrinfo hints, *addr_list, *cur; @@ -893,7 +1052,7 @@ int http_get_client(const char *url, const char *headers,const char *Content_Typ if( getaddrinfo( parsed_url.host, parsed_url.port_str, &hints, &addr_list ) != 0 ) //if( getaddrinfo( "www.baidu.com", "80", &hints, &addr_list ) != 0 ) { - bk_printf("getaddrinfo error"); + bk_printf("init_websocket_client getaddrinfo error"); goto client_ERROR; } @@ -913,48 +1072,66 @@ int http_get_client(const char *url, const char *headers,const char *Content_Typ } close( client->sockfd ); + + + } + freeaddrinfo(addr_list); // 释放资源 + if(client->sockfd<0) + { + bk_printf("init_websocket_client connect error"); goto client_ERROR; - bk_printf("http_get_client connect error"); } - freeaddrinfo(addr_list); // 释放资源 - bk_printf("http_get_client connect ok,sockfd:%d",client->sockfd); + + bk_printf("init_websocket_client connect ok,sockfd:%d",client->sockfd); +// client->sockfd = socket(AF_INET, SOCK_STREAM, 0); +// if (client->sockfd < 0) { +// bk_printf("socket creation failed"); +// goto client_ERROR; +// } + +// // bk_printf("init_websocket_client 3\n"); +// struct sockaddr_in server_addr; +// server_addr.sin_family = AF_INET; +// server_addr.sin_port = htons(parsed_url.port); +// inet_pton(AF_INET, parsed_url.host, &server_addr.sin_addr); +// if (connect(client->sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { +// bk_printf("connection failed"); +// close(client->sockfd); +// goto client_ERROR; +// } strcpy(client->host, parsed_url.host); strcpy(client->path, parsed_url.path); strcpy(client->query, parsed_url.query); client->port = parsed_url.port; - if (send_http_get_handshake(client,headers,Content_Type) < 0) { //发送头 + if (send_handshake(client,headers) < 0) { //发送头 close(client->sockfd); goto client_ERROR; } - - ssize_t bytes_received = recv(client->sockfd, response, response_len-1, 0); + buffer=aic_zalloc(BUFFER_SIZE); + ssize_t bytes_received = recv(client->sockfd, buffer, BUFFER_SIZE - 1, 0); if (bytes_received > 0) { - response[bytes_received] = '\0'; - bk_printf("Received handshake response:\n%s\n", response); - }else - { - bk_printf("recv error bytes_received %d", recv); + buffer[bytes_received] = '\0'; + bk_printf("Received handshake response:\n%s\n", buffer); } - // if(strstr(buffer,"HTTP/1.1 101") == NULL) - // { + if(strstr(buffer,"HTTP/1.1 101") == NULL) + { - // goto client_ERROR; - // } - close(client->sockfd); + goto client_ERROR; + } + aic_free(buffer); free_url(parsed_url); - if(client) - aic_free(client); - return bytes_received; + return client; client_ERROR: - + if(buffer) + aic_free(buffer); if(client) aic_free(client); free_url(parsed_url); - return -1; + return NULL; } WebSocketClient *init_websocket_IOT_V3(const char *url, const char *headers) @@ -1076,238 +1253,288 @@ client_ERROR: return NULL; } -int receive_websocket_message_V3(WebSocketClient *client, unsigned char *buf,int len,WebSocketMessageType *code) { - // u64 timer_ms = aos_get_tickcount(); - // bk_printf("receive_websocket_message 1 timer_ms=%d\n",timer_ms); - if(!client ) - return -1; - unsigned char frame[20]={0}; - unsigned char masking_key[4]; - int bytes_received = 0; - int recv_len = 0 ; - static u8 last_byte = 0; - static u32 error_count = 0; - // while(1) - // { - // recv_len = recv(client->sockfd, frame+bytes_received, 2-bytes_received, 0); - // bytes_received +=recv_len; - // if(bytes_received>=2) - // break; +WebSocketClient *init_websocket_IOT(const char *url, const char *headers) { + bk_printf("init_websocket_client 1\n"); + // char *buffer = NULL; + WebSocketClient *client =NULL; + // BK_URL parsed_url = {0}; + // parsed_url = parse_url(url);//解析url + //bk_printf("url: %s", url); + // if (parsed_url.error) { + // bk_printf("Error: %s", parsed_url.error_message); + // goto client_ERROR; + // } else { + // bk_printf("Protocol: %s", parsed_url.protocol); + // bk_printf("Host: %s", parsed_url.host); + // bk_printf("Port: %d", parsed_url.port); + // bk_printf("Path: %s", parsed_url.path); + // bk_printf("Query: %s", parsed_url.query); + // } - - while(1) + + + client = aic_zalloc(sizeof(WebSocketClient)) ; + if(!client) { - bytes_received = recv(client->sockfd, frame, 1, 0); + bk_printf("init_websocket_IOT alloc error"); + goto client_ERROR; + } - // bk_printf("receive_websocket_message:frame:0x%x,bytes_received:%d",frame[0],bytes_received); + struct addrinfo hints, *addr_list, *cur; + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + //if(getaddrinfo( parsed_url.host, parsed_url.port_str, &hints, &addr_list ) != 0 ) - if (bytes_received == 0) { - bk_printf("Connection closed by server.1\n\n\n\n"); - return 0; - } else if(bytes_received<0){ - bk_printf("receive message failed1\n\n\n\n"); - return -1; - } - if(frame[0]!= 0x80 && frame[0]!= 0x81 && frame[0]!= 0x82 && frame[0]!= 0x88 && frame[0]!= 0x89 && frame[0]!= 0x8A) + //iot.socket.thisiot.com:60501 + + bk_printf("init_websocket_client 2\n"); + + if( getaddrinfo("iot.socket.thisiot.com", "7777", &hints, &addr_list ) != 0 ) + { + bk_printf("init_websocket_IOT getaddrinfo error"); + goto client_ERROR; + } + + bk_printf("init_websocket_client 3\n"); + + for( cur = addr_list; cur != NULL; cur = cur->ai_next ) + { + client->sockfd = (int) socket( cur->ai_family, cur->ai_socktype, + cur->ai_protocol ); + if( client->sockfd < 0 ) { - error_count++; - bk_printf("receive_websocket_message:hend =0x%X,0x%X ,last_byte =0x%x error_count =%d ERROR!!!!!!!!!",frame[0],frame[1],last_byte,error_count); + continue; + } - if(last_byte!= 0x80 && last_byte!= 0x81 && last_byte!= 0x82 && last_byte!= 0x88 && last_byte!= 0x89 && last_byte!= 0x8A) - { - bk_printf("receive_websocket_message:hend =0x%X,0x%X ,last_byte =0x%x ERROR222222222!!!!!!!!!",frame[0],frame[1],last_byte); - continue; - } - - }else + bk_printf("init_websocket_client 31\n"); + if(connect( client->sockfd , cur->ai_addr, (int)cur->ai_addrlen ) == 0 ) { break; } + + bk_printf("init_websocket_client 32\n"); + close( client->sockfd ); + + } - // bk_printf("websocket2 timer_ms=%d\n",timer_ms- aos_get_tickcount()); - // timer_ms = aos_get_tickcount(); - //bk_sleep(5); - bytes_received = recv(client->sockfd, frame+1, 1, 0); - if (bytes_received == 0) { - bk_printf("Connection closed by server.2\n\n\n\n"); - return 0; - } else if(bytes_received<0){ - bk_printf("receive message failed 2 \n\n\n\n"); - return -1; - } - //unsigned char fin = (frame[0] & 0x80) >> 7; - *code = frame[0] & 0x0F; - unsigned char mask = (frame[1] & 0x80) >> 7; - unsigned int payload_len = frame[1] & 0x7F; + bk_printf("init_websocket_client 4\n"); - size_t offset = 2; - if (payload_len == 126) { - unsigned short extended_payload_len; - bytes_received = 0; - while(1) - { - recv_len= recv(client->sockfd, frame+offset+bytes_received, 2-bytes_received, 0); - if (recv_len == 0) { - bk_printf("Connection closed by server 3.\n\n\n\n"); - return 0; - } else if(recv_len<0){ - bk_printf("receive message failed 3 \n\n\n\n"); - return -1; - } - bytes_received +=recv_len; - if(bytes_received>=2) - break; - - } - - // bytes_received_t = bytes_received; - memcpy(&extended_payload_len, frame + 2, 2); - payload_len = ntohs(extended_payload_len); - //bk_printf("receive_websocket_message:payload_len=0x%X",extended_payload_len); - offset += 2; - } else if (payload_len == 127) { - u64 extended_payload_len; - bytes_received = 0; - while(1) - { - recv_len= recv(client->sockfd, frame+offset+bytes_received, 8-bytes_received, 0); - if (recv_len == 0) { - bk_printf("Connection closed by server 4.1\n\n\n\n"); - return 0; - } else if(recv_len<0){ - bk_printf("receive message failed 4\n\n\n\n"); - return -1; - } - bytes_received +=recv_len; - if(bytes_received>=8) - break; - - } - memcpy(&extended_payload_len, frame + 2, 8); - payload_len = ntohll(extended_payload_len); - offset += 8; + freeaddrinfo(addr_list); // 释放资源 + if(client->sockfd<0) + { + bk_printf("init_websocket_IOT connect error"); + goto client_ERROR; } - if(payload_len>len) + + bk_printf("init_websocket_IOT connect ok,sockfd:%d",client->sockfd); + + +// client->sockfd = socket(AF_INET, SOCK_STREAM, 0); +// if (client->sockfd < 0) { +// bk_printf("socket creation failed"); +// goto client_ERROR; +// } + +// // bk_printf("init_websocket_client 3\n"); +// struct sockaddr_in server_addr; +// server_addr.sin_family = AF_INET; +// server_addr.sin_port = htons(parsed_url.port); +// inet_pton(AF_INET, parsed_url.host, &server_addr.sin_addr); + +// if (connect(client->sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { +// bk_printf("connection failed"); +// close(client->sockfd); +// goto client_ERROR; +// } + + + + // aic_free(buffer); + // free_url(parsed_url); + + bk_printf("init_websocket_client 5\n"); + return client; +client_ERROR: + //if(buffer) + // aic_free(buffer); + if(client) + aic_free(client); + // free_url(parsed_url); + return NULL; +} +// 关闭 WebSocket 客户端 +void close_websocket_client(WebSocketClient *client) { + if(client) { - bk_printf("receive_websocket_message:len =%d ERROR",payload_len); - recv(client->sockfd, buf, len, 0); - return -1; + soc_close(client->sockfd); + aic_free(client); } - // bk_printf("receive_websocket_message :"); - // for(int i = 0;isockfd, frame+offset, 4, 0); - memcpy(masking_key, frame + offset, 4); - offset += 4; - } + // close_websocket_client(client); + // aos_sleep(2); + // char *response =aic_zalloc(BUFFER_SIZE); + // //char *url = "http://dmp.raisound.com/sv/vad/auth/token?nonceStr=abc&sign=3470327e8eee163f00d5f54cc936d32595189b16d1e89c2b50155b80227c85d0×tamp=1750406765243&token=9542143a532adc10ec6ee530cd1824d53b"; + // char *url = "http://dmp.raisound.com/bz-mp-api/sv/vad/auth/token?nonceStr=abc&sign=3470327e8eee163f00d5f54cc936d32595189b16d1e89c2b50155b80227c85d0×tamp=1750406765243&token=9542143a532adc10ec6ee530cd1824d53b"; + // http_get_client(url,"bz-dt:9542143a532adc10ec6ee530cd1824d53b","application/x-www-form-urlencoded",response,BUFFER_SIZE); + // bk_printf("http GET data:%s",response); + // aic_free(response); + return 0; +} - - bytes_received = 0; - // payload_len-=1;//少读一个字节,防止粘包 - //bk_sleep(1); - while(1)//读主体内容 +/************************http*********************************** */ + +// WebSocket 客户端结构体 +typedef struct { + int sockfd; + char host[128]; + char path[128]; + char query[512]; + int port; +} httpClient; +int send_http_get_handshake(httpClient *client,const char *headers,const char *Content_Type) { + char key[WEBSOCKET_KEY_LEN]; + bk_printf("send_handshake1"); + generate_websocket_key(key); + char accept_key[64]; + int ret = 0; + generate_accept_key(key, accept_key); + bk_printf("send_handshake2"); + char *request =aic_zalloc(BUFFER_SIZE); + if(headers!= NULL) { - // bk_sleep(recv_len/200+1); - // bk_printf("bytes_received %d %d",payload_len,bytes_received); - recv_len = recv(client->sockfd, buf+bytes_received, payload_len-bytes_received, 0); + snprintf(request, BUFFER_SIZE, + "GET /%s?%s HTTP/1.1\r\n" + "Host: %s:%d\r\n" + "Content-Type: %s\r\n" + "Connection: close\r\n" + "%s\r\n" + "\r\n", + client->path,client->query ,client->host,client->port,Content_Type,headers); + }else + { + snprintf(request, BUFFER_SIZE, + "GET /%s?%s HTTP/1.1\r\n" + "Host: %s:%d\r\n" + "Content-Type: %s\r\n" + "Connection: close\r\n" + "\r\n", + client->path,client->query , client->host,client->port,Content_Type); + } + + bk_printf("send_handshake request:\r\n%s",request); + if (send(client->sockfd, request, strlen(request), 0) < 0) { + bk_printf("send handshake failed :sockfd:%d",client->sockfd); + + ret = -1; + } + bk_printf("send_handshake3"); + aic_free(request); + return ret; +} +//http get 客户端 +int http_get_client(const char *url, const char *headers,const char *Content_Type,char* response,int response_len) { + //bk_printf("init_websocket_client 1\n"); - // bk_printf("recv_len %d %d",payload_len,recv_len); + httpClient *client =NULL; + BK_URL parsed_url = {0}; + parsed_url = parse_url(url);//解析url + //bk_printf("url: %s", url); + if (parsed_url.error) { + bk_printf("Error: %s", parsed_url.error_message); + goto client_ERROR; + } else { + bk_printf("Protocol: %s", parsed_url.protocol); + bk_printf("Host: %s", parsed_url.host); + bk_printf("Port: %d", parsed_url.port); + bk_printf("Path: %s", parsed_url.path); + bk_printf("Query: %s", parsed_url.query); - if (recv_len == 0) { - bk_printf("Connection closed by server.5\n\n\n\n\n"); - return 0; - } else if(recv_len<0){ - bk_printf("receive message failed 5\n\n\n\n"); - return -1; + } + client = aic_zalloc(sizeof(httpClient)) ; + if(!client) + { + bk_printf("http_get_client alloc error"); + goto client_ERROR; + } + struct addrinfo hints, *addr_list, *cur; + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + if( getaddrinfo( parsed_url.host, parsed_url.port_str, &hints, &addr_list ) != 0 ) + //if( getaddrinfo( "www.baidu.com", "80", &hints, &addr_list ) != 0 ) + { + bk_printf("getaddrinfo error"); + goto client_ERROR; + } + + for( cur = addr_list; cur != NULL; cur = cur->ai_next ) + { + client->sockfd = (int) socket( cur->ai_family, cur->ai_socktype, + cur->ai_protocol ); + if( client->sockfd < 0 ) + { + continue; } - bytes_received += recv_len; - - //bk_printf("receive_websocket_message:bytes_received=%d recv_len =%d",bytes_received,recv_len); - if(bytes_received >= payload_len) + if( connect( client->sockfd , cur->ai_addr, (int)cur->ai_addrlen ) == 0 ) { - //bk_printf("receive_websocket_message:payload_len=%d,bytes_received=%d",payload_len,bytes_received); + break; } - + + close( client->sockfd ); + goto client_ERROR; + bk_printf("http_get_client connect error"); } - //bk_sleep(1); - // bk_printf("websocket 3 timer_ms=%d\n",timer_ms- aos_get_tickcount()); - // timer_ms= aos_get_tickcount(); - // bk_sleep(1);//等最后一字节返回,防止粘包 - // recv(client->sockfd, buf+payload_len, 1, 0);//读最后一字节 - // payload_len+=1; - if(mask) - { - for (size_t i = 0; i < payload_len; ++i) { - buf[i] = buf[i] ^ masking_key[i % 4]; - } + freeaddrinfo(addr_list); // 释放资源 + bk_printf("http_get_client connect ok,sockfd:%d",client->sockfd); + + + + strcpy(client->host, parsed_url.host); + strcpy(client->path, parsed_url.path); + strcpy(client->query, parsed_url.query); + client->port = parsed_url.port; + if (send_http_get_handshake(client,headers,Content_Type) < 0) { //发送头 + close(client->sockfd); + goto client_ERROR; } - - // if (*code == WS_TEXT) { - // bk_printf("Received text message: %.*s\n", (int)payload_len, buf); - // } else if (*code == WS_BINARY) { - // bk_printf("Received binary message of length %zu\n", payload_len); - // } - // if(error_count>0) - // { - // bk_printf("WS ERROR!!!!!!last_byte:0x%x bytes_received_t_1:0x%x\r\n\n\n\n\n\n\n",last_byte,bytes_received_t_1); - // bk_print_hex(frame_t,frame_t_len); - // bk_print_hex(websocket_tmp_b,websocket_tmp_b_len); - // bk_printf("WS ERROR!!!!!!\r\n\n\n\n\n\n\n"); - // bk_print_hex(frame,offset); - // bk_print_hex(buf,payload_len); - - // } - // bytes_received_t_1 = bytes_received_t; - if (*code == WS_TEXT) - { - }else if(*code == WS_BINARY) - { - }else if(*code == WS_CLOSE) - { - payload_len = 0; - }else if(*code == WS_PONG) - { - //payload_len = 1; - }else if(*code == WS_PING) - { - send_websocket_message(client,buf,payload_len,WS_PONG); - //payload_len = 1; - }else if(*code == WS_CONT) + ssize_t bytes_received = recv(client->sockfd, response, response_len-1, 0); + if (bytes_received > 0) { + response[bytes_received] = '\0'; + bk_printf("Received handshake response:\n%s\n", response); + }else { - //payload_len = 1; + bk_printf("recv error bytes_received %d", recv); } - last_byte = buf[payload_len-1]; - //timer_ms = aos_get_tickcount(); - //bk_printf("receive_websocket_message 4 timer_ms=%d len = %d\n",timer_ms,payload_len); - error_count=0; - // websocket_tmp_b_len = payload_len; - // if(payload_len>sizeof(websocket_tmp_b)) - // { - // websocket_tmp_b_len=sizeof(websocket_tmp_b); - // } - // memcpy(websocket_tmp_b,buf,websocket_tmp_b_len); - - - // frame_t_len = offset; - // if(frame_t_len>sizeof(frame_t)) + // if(strstr(buffer,"HTTP/1.1 101") == NULL) // { - // frame_t_len=sizeof(frame_t); + + // goto client_ERROR; // } - // memcpy(frame_t,frame,frame_t_len); - + close(client->sockfd); + free_url(parsed_url); + if(client) + aic_free(client); + return bytes_received; +client_ERROR: - return payload_len;//parse_frame(buf, bytes_received, buf,code); + if(client) + aic_free(client); + free_url(parsed_url); + return -1; } diff --git a/2.code/aicos/app/AI_AMP_2_5/bk_websocket.h b/2.code/aicos/app/AI_AMP_2_5/bk_websocket.h index 35e673e..f2d1b69 100644 --- a/2.code/aicos/app/AI_AMP_2_5/bk_websocket.h +++ b/2.code/aicos/app/AI_AMP_2_5/bk_websocket.h @@ -24,9 +24,9 @@ typedef struct { // 初始化 WebSocket 客户端 WebSocketClient *init_websocket_client(const char *url, const char *headers); -WebSocketClient *init_websocket_IOT_V3(const char *url, const char *headers); +WebSocketClient *init_websocket_IOT(const char *url, const char *headers); -int receive_websocket_message_V3(WebSocketClient *client, unsigned char *buf,int len,WebSocketMessageType *code); +WebSocketClient *init_websocket_IOT_V3(const char *url, const char *headers); // 关闭 WebSocket 客户端 void close_websocket_client(WebSocketClient *client) ; @@ -34,11 +34,16 @@ void close_websocket_client(WebSocketClient *client) ; // 接收 WebSocket 消息 int receive_websocket_message(WebSocketClient *client, unsigned char *buf,int len,WebSocketMessageType *code); +int receive_websocket_message_V3(WebSocketClient *client, unsigned char *buf,int len,WebSocketMessageType *code); + +//receive_websocket_message_V3 + int receive_iot_message(WebSocketClient *client); // 发送 WebSocket 消息 int send_websocket_message(WebSocketClient *client, const unsigned char *message, size_t message_len, WebSocketMessageType type) ; +int send_iot_message(WebSocketClient *client, const unsigned char *message, size_t message_len); int bk_websocket_demo(void); #endif diff --git a/2.code/aicos/app/AI_AMP_2_5/dev_authentication.c b/2.code/aicos/app/AI_AMP_2_5/dev_authentication.c index fe8a2da..2402c81 100644 --- a/2.code/aicos/app/AI_AMP_2_5/dev_authentication.c +++ b/2.code/aicos/app/AI_AMP_2_5/dev_authentication.c @@ -24,11 +24,11 @@ #include "aic_http_client.h" #include "aic_fota.h" - - // #define DMPTEST - #define bk_malloc aic_malloc #define bk_free aic_free + +// #define DMPTEST + int get_dev_pass_MAX_len(void)//获取设备密码最大长度,注意要防止内存越界 { return sizeof(vc_cfg.dev_pass); @@ -329,12 +329,18 @@ char * get_token(void) //激活->登录的密钥 -const char *dev_pid = "cqxJZi5CNgzjS3mX21Zw";//PID -const char *dev_key = "uKLrChwrxA1LklgBc3VwawYjUkbT3BgX";//密钥 + const char *dev_pid = "cqxJZi5CNgzjS3mX21Zw";//PID + const char *dev_key = "uKLrChwrxA1LklgBc3VwawYjUkbT3BgX";//密钥 +//电信 +// const char *dev_pid = "DieBeXahZHLrjSnORbgN";//PID +// const char *dev_key = "FuXG4ptpGbzvKbdB4vpUypisbENgy2nB";//密钥 + #define HTTP_DEMO_CLIENT_NAME "HTTP Demo Client" #define HTTP_DEMO_URL "http://47.101.171.33/doc/download/10.txt" -#define HTTPS_DEMO_URL "https://47.101.171.33/doc/download/CK8K.txt" +#define HTTPS_DEMO_URL "https://ting.raisound.com/GKwRIUEM7KLlABfEQAQ1sw59.mp3" + +//https://ting.raisound.com/GKwRIUEM7KLlABfEQAQ1sw59.mp3 #define HTTP_DEMO_WAIT_TIME (10 * 1000) #define HTTP_DEMO_SLEEP_TIME (60 *1000) @@ -409,13 +415,16 @@ void aic_http_demotest() return; } +int32_t play_audio_done_duplex(const char *buf, uint32_t buf_len, uint32_t sample_rate, uint32_t is_file); + +void resetClose_time(); void aic_https_demotest() { u32 status = 0; LONG lbytes = 0; u8 *buff; - u32 bytes = 1500; + u32 bytes = 1024*2; u32 total_length = 0; u32 length_to_be_copied = 0; u32 chunked_mode = 0; @@ -435,7 +444,7 @@ void aic_https_demotest() client_ptr->https_client->auth_type = 0; /*wait pdp active,only for demo test.*/ - aos_sleep(HTTP_DEMO_SLEEP_TIME); + // aos_sleep(HTTP_DEMO_SLEEP_TIME); status = aic_https_client_get_start(https_demo_handle, HTTPS_DEMO_URL, NULL, NULL, 443, HTTP_DEMO_WAIT_TIME); @@ -444,7 +453,9 @@ void aic_https_demotest() return; } - buff = aos_zalloc(bytes+2000); + buff = aos_zalloc(bytes); + + bk_printf("aic_https_demotest12132..."); do { lbytes = aic_https_client_response_data_get(https_demo_handle, buff , bytes, @@ -453,7 +464,14 @@ void aic_https_demotest() break; } else { - bk_printf("https get data %d ",lbytes); + bk_printf("https get data %d ",lbytes); + + play_audio_done_duplex(buff, bytes, 16000, 0); + + //audio_data(buff,lbytes,37); + resetClose_time(); + + aos_sleep(20); chunked_mode = aic_http_client_chunked_mode_check(https_demo_handle); length_to_be_copied = aic_https_client_total_receive_bytes_get(https_demo_handle); if (!chunked_mode && length_to_be_copied) { @@ -465,7 +483,7 @@ void aic_https_demotest() // aicx_error(0x0f0971, "s", "https get data is %s", buff); - bk_printf("download123 finish..."); + bk_printf("download123 finish %d...",total_length); aic_https_client_delete(https_demo_handle); @@ -473,6 +491,80 @@ void aic_https_demotest() } +void aic_https_demotest_status() +{ + u32 status = 0; + LONG lbytes = 0; + u8 *buff; + u32 bytes = 1024*2; + u32 total_length = 0; + u32 length_to_be_copied = 0; + u32 chunked_mode = 0; + AIC_HTTPS_CLIENT_INSTANCE *client_ptr; + + bk_printf("aic_https_demotest1213..."); + + https_demo_handle = aic_https_client_create(HTTP_DEMO_CLIENT_NAME); + if (https_demo_handle == 0) { + return; + } + + bk_printf("aic_https_demotest_status..."); + + /*for https test,set auth_type to 0, do not need certifica1*/ + client_ptr = (AIC_HTTPS_CLIENT_INSTANCE *)https_demo_handle; + client_ptr->https_client->auth_type = 0; + + /*wait pdp active,only for demo test.*/ + // aos_sleep(HTTP_DEMO_SLEEP_TIME); + + status = aic_https_client_get_start(https_demo_handle, "https://app-api.raisound.com/dev/device/info/simple/867686073051904", NULL, + NULL, 443, HTTP_DEMO_WAIT_TIME); + if (status != NX_SUCCESS) { + aic_https_client_delete(https_demo_handle); + return; + } + + buff = aos_zalloc(bytes); + + bk_printf("aic_https_demotest12132..."); + + do { + lbytes = aic_https_client_response_data_get(https_demo_handle, buff , bytes, + HTTP_DEMO_WAIT_TIME); + if (lbytes <= 0) { + break; + } else { + + bk_printf("https get data %d ",lbytes); + + // bk_printf("read_bytes :%d\n",read_bytes); + + // play_audio_done_duplex(buff, bytes, 16000, 0); + + bk_printf("IOT_update_bargein :%s",buff); + //audio_data(buff,lbytes,37); + // resetClose_time(); + + // aos_sleep(20); + chunked_mode = aic_http_client_chunked_mode_check(https_demo_handle); + length_to_be_copied = aic_https_client_total_receive_bytes_get(https_demo_handle); + if (!chunked_mode && length_to_be_copied) { + total_length += lbytes; + } + } + + } while (total_length < length_to_be_copied || chunked_mode); + + // aicx_error(0x0f0971, "s", "https get data is %s", buff); + + bk_printf("download123 finish %d...",total_length); + + aic_https_client_delete(https_demo_handle); + + return; +} + void aut_active(void)//设备激活 { int ret; @@ -518,7 +610,11 @@ void aut_active(void)//设备激活 bk_printf("dev_id:%s timestamp:%s ",deviceId,timestamp_str); + //118.145.159.222:30400 + + // http://dmp.raisound.com/bz-api/dev/auth/active + // https://dmp-dev.raisound.com/dmp-api/dev/auth/active #ifdef DMPTEST char *sign_url = "http://dmp-dev.raisound.com/dmp-api/dev/auth/active"; @@ -539,7 +635,7 @@ void aut_active(void)//设备激活 int url_value = aic_process_https_url(aut_active_http_handle,sign_url,AIC_HTTP_HEAD); bk_printf("url_value:%d",url_value); http_client = (AIC_HTTPS_CLIENT_INSTANCE *)aut_active_http_handle; - http_client->login_info.server_port = 80; + http_client->login_info.server_port = 80;//80 aic_http_client_connect(aut_active_http_handle, 5000); // 创建JSON对象 @@ -674,7 +770,7 @@ void update_iccid(void)//设备激活 u32 aut_active_http_handle = 0; char *aut_buf =NULL; char *json_string =NULL; - + char form_data_string[200]={0}; char sign_url[200]={0}; @@ -895,10 +991,20 @@ void IOT_update_bargein(void)//OTA更新 goto aut_active_return; bk_get_imei(deviceId); + //// DMPTEST + //http://app-api.raisound.com/dev/device/info/simple/867686073050930 - - sprintf(sign_url,"http://app-api.raisound.com/dev/device/info/simple/%s",deviceId); + #if 1 + sprintf(sign_url,"http://dmp-dev.raisound.com/dmp-api/dev/device/info/simple/%s",deviceId); + + #else + //https://app-api.raisound.com + + sprintf(sign_url,"https://app-api.raisound.com/dev/device/info/simple/%s",deviceId); + + #endif + bk_printf(sign_url); @@ -969,7 +1075,10 @@ void IOT_update_bargein(void)//OTA更新 int temp_bag=atoi(ota_url); if(temp_bag>=0&&temp_bag<10){ - vc_cfg.VC_mode=temp_bag; + // if(temp_bag==1) + // vc_cfg.VC_mode=0; + // else + vc_cfg.VC_mode=temp_bag; } // vc_cfg.VC_mode= @@ -1274,12 +1383,13 @@ void ota_update_version(void)//OTA上报 //char dev_pass_base64[100] ={0}; // char enc_iv[65] = {0}; - + char dev_iccid[100] ={0}; // http创建客户端句柄 u32 aut_active_http_handle = 0; char *aut_buf =NULL; char *json_string =NULL; + char form_data_string[200]={0}; char sign_url[200]={0}; @@ -1371,15 +1481,15 @@ void ota_update_version(void)//OTA上报 goto aut_active_return; } - long read_bytes = aic_https_client_response_data_get(aut_active_http_handle,aut_buf,5*1024,10000); + //long read_bytes = aic_https_client_response_data_get(aut_active_http_handle,aut_buf,5*1024,10000); - bk_printf("read_bytes :%d\n",read_bytes); + // bk_printf("read_bytes :%d\n",read_bytes); - if(read_bytes<=0) - goto aut_active_return; + //if(read_bytes<=0) + // goto aut_active_return; - bk_printf("http put data update_iccid :%s",aut_buf); + bk_printf("ota_update_version_end"); aut_active_return: @@ -1451,9 +1561,12 @@ void aut_login(void)//登录 aes_cbc_pkcs5_encrypt(dev_pass, strlen(dev_pass), dev_key, enc_iv,encrypt_data,&encrypt_data_len);//加密 bk_printf("deviceId:%s password:%s nonce:%s,dev_pass:%s", deviceId, encrypt_data, enc_iv,dev_pass); - // char *sign_url = "http://dmp.raisound.com/bz-api/dev/auth/sign_in"; // 登录地址 - //char *headers_T = "\"Content-Type\":\"application/json\""; + // 118.145.159.222:30400 + + // http://dmp.raisound.com/bz-api/dev/auth/sign_in + + // https://dmp-dev.raisound.com/dmp-api/dev/auth/active #ifdef DMPTEST char *sign_url = "http://dmp-dev.raisound.com/dmp-api/dev/auth/sign_in"; // 登录地址 #else @@ -1461,6 +1574,7 @@ void aut_login(void)//登录 char *sign_url = "http://dmp.raisound.com/bz-api/dev/auth/sign_in"; // 登录地址 #endif + //char *headers_T = "\"Content-Type\":\"application/json\""; bk_printf(sign_url); u32 response = 0; aut_login_http_handle = aic_http_client_create("HTTP_DEMO_CLIENT_NAME"); @@ -1659,4 +1773,6 @@ void dev_authentication_init(void) AOS_AUTO_START); } + + // AIC_BASIC_APP_P2_INIT_EXPORT(apifota_callback_init); \ No newline at end of file diff --git a/2.code/aicos/app/AI_AMP_2_5/dev_authentication.h b/2.code/aicos/app/AI_AMP_2_5/dev_authentication.h index af64ac4..024ca15 100644 --- a/2.code/aicos/app/AI_AMP_2_5/dev_authentication.h +++ b/2.code/aicos/app/AI_AMP_2_5/dev_authentication.h @@ -24,5 +24,4 @@ typedef struct dev_authentication_MSG_Type MSG_Type; }dev_authentication_MSG_queue_t; aos_status dev_authentication_MSG_put(const char *data,u32 len,dev_authentication_MSG_Type MSG_Type); -void IOT_update_bargein(void);//OTA更新 #endif \ No newline at end of file diff --git a/2.code/aicos/app/AI_AMP_2_5/imsl_kws.h b/2.code/aicos/app/AI_AMP_2_5/imsl_kws.h index daa83b8..394e975 100644 --- a/2.code/aicos/app/AI_AMP_2_5/imsl_kws.h +++ b/2.code/aicos/app/AI_AMP_2_5/imsl_kws.h @@ -2,7 +2,7 @@ * Build Information * Git Commit: 66c47c389123d4d655eb5b1d63b5918355f15ce7 * Branch: master - * Build Date: 2025-12-17 16:12:17 + * Build Date: 2025-09-29 18:13:29 */ #ifndef _IMSL_KWS_DLL @@ -62,10 +62,9 @@ kws_conf.kws_log_level = 0; int kws_status = init_kws(&kws_conf); -// 授权部分,可以忽ç•? -// struct AuthInfo auth_info; -// strcpy(auth_info.dmp_token, dmp_token); -// auth_kws(&auth_info); +struct AuthInfo auth_info; +strcpy(auth_info.dmp_token, dmp_token); +auth_kws(&auth_info); // 在每次接收语音时调用 注意 如果是void* æˆ?int8* 的指针,长度 / 2 // 运行结束后获取kws状æ€? @@ -81,24 +80,7 @@ free_kws(); */ - - - - - - - - - - - - - - - - - -/* example 2 配合vad使用 废弃方案 +/* example 2 配合vad使用 // 初始åŒ? diff --git a/2.code/aicos/app/AI_AMP_2_5/imsl_vad.h b/2.code/aicos/app/AI_AMP_2_5/imsl_vad.h index 407f713..b95741f 100644 --- a/2.code/aicos/app/AI_AMP_2_5/imsl_vad.h +++ b/2.code/aicos/app/AI_AMP_2_5/imsl_vad.h @@ -2,7 +2,7 @@ * Build Information * Git Commit: 66c47c389123d4d655eb5b1d63b5918355f15ce7 * Branch: master - * Build Date: 2025-12-17 16:12:18 + * Build Date: 2025-09-29 18:13:30 */ #ifndef _IMSL_VAD_DLL @@ -16,7 +16,6 @@ typedef int (*imsl_nn_printf_func)(const char *format, ...); struct AuthInfo { char dmp_token[64]; - int server_addr; }; #endif @@ -95,7 +94,6 @@ void free_vad(); init_vad(&conf); struct AuthInfo auth_info; - auth_info.server_addr = 0; // 0 表示 国内 1 表示 海外 strcpy(auth_info.dmp_token, dmp_token); auth_vad(&auth_info); diff --git a/2.code/aicos/app/AI_AMP_2_5/libimslkws.a b/2.code/aicos/app/AI_AMP_2_5/libimslkws.a index fde10175a7edf57b412a498f0217dea246b4d3b2..5610ab38560e9f6a0971c022146daa59df123c86 100644 GIT binary patch delta 107774 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�wQSpa9_ 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 delta 105542 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

@iW3j0`nHiiyiYnb^F7BpXX) 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 DBEj`^ diff --git a/2.code/aicos/app/AI_AMP_2_5/libimslnn.a b/2.code/aicos/app/AI_AMP_2_5/libimslnn.a index 9ce432cc3f8672e469b6c6cf44752eb9a15a72b4..9e25eca6c456f4c58191d694485617943d8e747b 100644 GIT binary patch delta 15619 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 delta 15992 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 diff --git a/2.code/aicos/app/AI_AMP_2_5/libimslvad.a b/2.code/aicos/app/AI_AMP_2_5/libimslvad.a index 2a72056564fb06336b1e96ec0b4151155cc0fc9d..b8bf999da469ff7aca873f9a2b9a33aaceec5d78 100644 GIT binary patch delta 19732 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 delta 19793 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 xX{Pl>GZfa((#sXRyQ~@@We