[Z5_CIRCLE_240_240] voicechat
author@CHENG <2393524978@qq.com>
Tue, 10 Sep 2024 09:59:29 +0000 (17:59 +0800)
committer@CHENG <2393524978@qq.com>
Tue, 10 Sep 2024 09:59:29 +0000 (17:59 +0800)
27 files changed:
2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/primary_function/list/ICON_VOICECHAT_LIST.png [new file with mode: 0644]
2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ANIM_VOICECHAT_LISTENING.gif [new file with mode: 0644]
2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ANIM_VOICECHAT_THINKING.gif [new file with mode: 0644]
2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_CANCEL_BUTTON.png [new file with mode: 0644]
2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_DEFAULT.png [new file with mode: 0644]
2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_PROMPT.png [new file with mode: 0644]
2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_RECORD_BUTTON_DEFAULT.png [new file with mode: 0644]
2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_RECORD_BUTTON_PRESSED.png [new file with mode: 0644]
2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_THINKING.png [new file with mode: 0644]
2.sdk/project/Z5_CIRCLE_240_240/product/craneg_modem/config/watch/lv_watch_conf_CUSTOM.h
2.sdk/sdk/gui/lv_watch/framework/language/lang_ch.c
2.sdk/sdk/gui/lv_watch/framework/language/lang_en.c
2.sdk/sdk/gui/lv_watch/include/ui_activity_id.h
2.sdk/sdk/gui/lv_watch/include/ui_textid.h
2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/custom_function.c
2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/custom_function.h
2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/mmi_voicechat_data.c [new file with mode: 0644]
2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/mmi_voicechat_data.h [new file with mode: 0644]
2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/mmi_voicechat_ui.c [new file with mode: 0644]
2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/mmi_voicechat_ui.h [new file with mode: 0644]
2.sdk/sdk/gui/lv_watch/lv_apps/primary_menu/primary_menu_data.c
2.sdk/sdk/gui/lv_watch/lv_watch_res.h
2.sdk/sdk/product/craneg_modem/pcac/wsclient/build/wsclient.mak
2.sdk/sdk/product/craneg_modem/pcac/wsclient/libwebsockets/inc/mmi_voicechat_websocket.h [new file with mode: 0644]
2.sdk/sdk/product/craneg_modem/pcac/wsclient/libwebsockets/inc/mmi_voicechat_websocket_client.h [new file with mode: 0644]
2.sdk/sdk/product/craneg_modem/pcac/wsclient/libwebsockets/src/mmi_voicechat_websocket.c [new file with mode: 0644]
2.sdk/sdk/product/craneg_modem/pcac/wsclient/libwebsockets/src/mmi_voicechat_websocket_client.c [new file with mode: 0644]

diff --git a/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/primary_function/list/ICON_VOICECHAT_LIST.png b/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/primary_function/list/ICON_VOICECHAT_LIST.png
new file mode 100644 (file)
index 0000000..03ee4e5
Binary files /dev/null and b/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/primary_function/list/ICON_VOICECHAT_LIST.png differ
diff --git a/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ANIM_VOICECHAT_LISTENING.gif b/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ANIM_VOICECHAT_LISTENING.gif
new file mode 100644 (file)
index 0000000..ca881c6
Binary files /dev/null and b/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ANIM_VOICECHAT_LISTENING.gif differ
diff --git a/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ANIM_VOICECHAT_THINKING.gif b/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ANIM_VOICECHAT_THINKING.gif
new file mode 100644 (file)
index 0000000..8bde133
Binary files /dev/null and b/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ANIM_VOICECHAT_THINKING.gif differ
diff --git a/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_CANCEL_BUTTON.png b/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_CANCEL_BUTTON.png
new file mode 100644 (file)
index 0000000..de9d638
Binary files /dev/null and b/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_CANCEL_BUTTON.png differ
diff --git a/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_DEFAULT.png b/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_DEFAULT.png
new file mode 100644 (file)
index 0000000..2ecf59b
Binary files /dev/null and b/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_DEFAULT.png differ
diff --git a/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_PROMPT.png b/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_PROMPT.png
new file mode 100644 (file)
index 0000000..df210ce
Binary files /dev/null and b/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_PROMPT.png differ
diff --git a/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_RECORD_BUTTON_DEFAULT.png b/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_RECORD_BUTTON_DEFAULT.png
new file mode 100644 (file)
index 0000000..2f8f452
Binary files /dev/null and b/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_RECORD_BUTTON_DEFAULT.png differ
diff --git a/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_RECORD_BUTTON_PRESSED.png b/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_RECORD_BUTTON_PRESSED.png
new file mode 100644 (file)
index 0000000..80989d0
Binary files /dev/null and b/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_RECORD_BUTTON_PRESSED.png differ
diff --git a/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_THINKING.png b/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_THINKING.png
new file mode 100644 (file)
index 0000000..b5d28b8
Binary files /dev/null and b/2.sdk/project/Z5_CIRCLE_240_240/gui/lv_watch/resource/png/voice_chat/ICON_VOICECHAT_THINKING.png differ
index be95cc8..b66aead 100644 (file)
@@ -985,6 +985,7 @@ const void * lang_text_ch[] = {
     "连接超时\n请重新开始对话", // WATCH_TEXT_ID_AIGC_CONNECT_TIMEOUT,
     "继续对话", // WATCH_TEXT_ID_AIGC_CONTINUE,
     "设备温度过高\n请暂缓使用", // WATCH_TEXT_ID_CHIP_HIGH_TEMPERATURE,
+    "Voice chat", // WATCH_TEXT_ID_VOICECHAT,
     //CHENG_MODIFY
     "确认是否跌倒?", // WATCH_TEXT_ID_falldown,
     "确认是否删除",
index 6be1b31..bc4b99f 100644 (file)
@@ -986,6 +986,7 @@ const void * lang_text_en[] = {
     "Timeout\nPlease try again", // WATCH_TEXT_ID_AIGC_CONNECT_TIMEOUT,
     "Continue", // WATCH_TEXT_ID_AIGC_CONTINUE,
     "Temperature too high\nPlease suspended use", // WATCH_TEXT_ID_CHIP_HIGH_TEMPERATURE,
+    "Voice chat", // WATCH_TEXT_ID_VOICECHAT,
     //CHENG_MODIFY
     "Confirm a fall",
     "Confirm deletion",
index bddec1e..bac5866 100644 (file)
@@ -226,6 +226,12 @@ enum
        ACT_ID_AIGC_RECORDING,
        ACT_ID_AIGC_SENDING,
 #endif
+#ifdef __MMI_CUSTOM_VOICECHAT_SUPPORT__
+       ACT_ID_VOICECHAT_MAIN,
+       ACT_ID_VOICECHAT_WAITTING,
+       ACT_ID_VOICECHAT_RECORDING,
+       ACT_ID_VOICECHAT_SENDING,
+#endif
 #ifdef __MMI_CUSTOM_BEI_KE_RUI_SHENG__
        ACT_ID_AI_TALK,
        ACT_ID_AI_TALK_RECORDING,
index 41e755f..c86b23a 100644 (file)
@@ -993,6 +993,7 @@ enum
     WATCH_TEXT_ID_AIGC_CONNECT_TIMEOUT,                 /* "连接超时\n请重新开始对话"                "Timeout\nPlease try again" */
     WATCH_TEXT_ID_AIGC_CONTINUE,                        /* "继续对话"                 "Continue" */
     WATCH_TEXT_ID_CHIP_HIGH_TEMPERATURE,                /* "设备温度过高\n请暂缓使用"        "Temperature too high\nPlease suspended use" */
+    WATCH_TEXT_ID_VOICECHAT,                            /* "Voice chat"                 "Voice chat" */
     //CHENG_MODIFY
     WATCH_TEXT_ID_FALLDWON,                            /*确认是否跌倒*/
     WATCH_TEXT_ID_CONFIRM_DELETE,                        /*确认是否删除*/
index ba55987..dd40446 100644 (file)
 #include "mmi_aigc_ui.c"
 #include "mmi_aigc_data.c"
 #endif
+#ifdef __MMI_CUSTOM_VOICECHAT_SUPPORT__
+#include "mmi_voicechat_ui.c"
+#include "mmi_voicechat_data.c"
+#endif
 
 #ifdef __MMI_CUSTOM_BEI_KE_RUI_SHENG__
 #include "bei_ke_rui_sheng.c"
index c504d78..f3e59fb 100644 (file)
@@ -34,6 +34,10 @@ extern "C" {
 #include "mmi_aigc_ui.h"
 #include "mmi_aigc_data.h"
 #endif
+#ifdef __MMI_CUSTOM_VOICECHAT_SUPPORT__
+#include "mmi_voicechat_ui.h"
+#include "mmi_voicechat_data.h"
+#endif
 
 #ifdef __MMI_CUSTOM_BEI_KE_RUI_SHENG__
 #include "bei_ke_rui_sheng.h"
diff --git a/2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/mmi_voicechat_data.c b/2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/mmi_voicechat_data.c
new file mode 100644 (file)
index 0000000..e0f1673
--- /dev/null
@@ -0,0 +1,951 @@
+
+
+
+#include "lv_watch.h"
+
+#ifdef __MMI_CUSTOM_VOICECHAT_SUPPORT__
+
+//static void mmi_voicechat_recv_trans_text_data_process(void * data_ptr, uint32_t data_len);
+//static void mmi_voicechat_recv_chat_text_data_process(void * data_ptr, uint32_t data_len);
+//static void mmi_voicechat_recv_tts_audio_data_process(void * data_ptr, uint32_t data_len);
+
+static void mmi_voicechat_send_trans_start_data_process(void * data_ptr, uint32_t data_len);
+static void mmi_voicechat_send_trans_audio_data_process(void * data_ptr, uint32_t data_len);
+static void mmi_voicechat_send_trans_stop_data_process(void * data_ptr, uint32_t data_len);
+static void mmi_voicechat_send_chat_text_data_process(void * data_ptr, uint32_t data_len);
+//static void mmi_voicechat_send_tts_start_data_process(void * data_ptr, uint32_t data_len);
+//static void mmi_voicechat_send_tts_stop_data_process(void * data_ptr, uint32_t data_len);
+static void mmi_voicechat_send_tts_text_data_process(void * data_ptr, uint32_t data_len);
+
+
+
+#if 0
+// recv task
+static TASK_HANDLE * s_voicechat_data_recv_task_id = NULL;
+
+static void mmi_voicechat_data_recv_task_msg_send(MMI_VOICECHAT_DATA_RECV_MSG_ID_E msg_id, void * param, uint32_t param_size)
+{
+       printf("[@CHENG_DEBUG][%s][%d]: msg_id=%d\n",__FUNCTION__,__LINE__, msg_id);
+       
+       if(NULL != s_voicechat_data_recv_task_id)
+       {
+               if((MMI_VOICECHAT_DATA_RECV_TASK_MSG_QUEUE_SIZE - 1) < Hal_Get_Message_Count(s_voicechat_data_recv_task_id))
+               {
+                       printf("[@CHENG_DEBUG][%s][%d]: msg queue full\n",__FUNCTION__,__LINE__);
+                       return;
+               }
+               
+               printf("[@CHENG_DEBUG][%s][%d]: \n",__FUNCTION__,__LINE__);
+               
+               void * temp_ptr = NULL;
+               if(NULL != param && 0 != param_size)
+               {
+                       temp_ptr = lv_mem_alloc(param_size + 1);
+                       if(NULL == temp_ptr)
+                       {
+                               printf("[@CHENG_DEBUG][%s][%d]: memory alloc fail\n", __FUNCTION__, __LINE__);
+                               return;
+                       }
+                       _lv_memset_00(temp_ptr, param_size + 1);
+                       _lv_memcpy(temp_ptr, param, param_size);
+               }
+                       
+        mmi_voicechat_data_task_msg_t * msg = Hal_Mem_Alloc(sizeof(mmi_voicechat_data_task_msg_t));
+               msg->cmd_type = msg_id;
+               msg->cmd_param = temp_ptr;
+               msg->param_size = param_size;
+       
+        Hal_Send_Message((TASK_ID)s_voicechat_data_recv_task_id, (void *)msg);
+    }
+}
+
+static void mm_voicechat_data_recv_task_handle(void * param)
+{
+       mmi_voicechat_data_task_msg_t * msg = (mmi_voicechat_data_task_msg_t *)param;
+       MMI_VOICECHAT_DATA_RECV_MSG_ID_E msg_id = msg->cmd_type;
+       void * msg_param = msg->cmd_param;
+       uint32_t param_size = msg->param_size;
+       
+       printf("[@CHENG_DEBUG][%s][%d]: msg_id=%d\n",__FUNCTION__,__LINE__, msg_id);
+    switch(msg_id)
+       {
+        case MMI_VOICECHAT_MSG_TRANS_TEXT_RECV:
+                       mmi_voicechat_recv_trans_text_data_process(msg_param, param_size);
+            break;
+
+               case MMI_VOICECHAT_MSG_CHAT_TEXT_RECV:
+                       mmi_voicechat_recv_chat_text_data_process(msg_param, param_size);
+                       break;
+
+               case MMI_VOICECHAT_MSG_TTS_AUDIO_RECV:
+                       mmi_voicechat_recv_tts_audio_data_process(msg_param, param_size);
+                       break;
+               
+               default:
+                       break;
+    }
+}
+
+static void mm_voicechat_data_recv_task_entry(void * para)
+{
+    while(s_voicechat_data_recv_task_id == NULL)
+       {
+        uos_sleep(10);
+    }
+
+    while(1)
+       {
+        // receive message
+        mmi_voicechat_data_task_msg_t * msg = (mmi_voicechat_data_task_msg_t *)Hal_Receive_Message((TASK_ID)s_voicechat_data_recv_task_id, TRUE);
+        if(!msg)
+            continue;
+
+               mm_voicechat_data_recv_task_handle(msg);
+               
+        Hal_Mem_Free(msg->cmd_param);
+        Hal_Mem_Free(msg);
+    }
+}
+
+static void mmi_voicechat_data_recv_task_create(void)
+{
+       if(NULL != s_voicechat_data_recv_task_id)
+               return;
+       
+       s_voicechat_data_recv_task_id = uos_create_task(mm_voicechat_data_recv_task_entry,
+                                                                                       NULL,
+                                                                                       MMI_VOICECHAT_DATA_RECV_TASK_MSG_QUEUE_SIZE,
+                                                                                       MMI_VOICECHAT_DATA_RECV_TASK_STACK_SIZE,
+                                                                                       MMI_VOICECHAT_DATA_RECV_TASK_PRIORITY,
+                                                                                       "mm_voicechat_data_recv_task");
+
+       printf("[@CHENG_DEBUG][%s][%d]: tcp_task_id=0x%x\n",__FUNCTION__,__LINE__, s_voicechat_data_recv_task_id);
+}
+
+static void mmi_voicechat_data_recv_task_delete(void)
+{
+       if(NULL != s_voicechat_data_recv_task_id)
+       {
+               uos_delete_task(s_voicechat_data_recv_task_id);
+               s_voicechat_data_recv_task_id = NULL;
+       }
+}
+#endif
+
+// send task
+static TASK_HANDLE * s_voicechat_data_send_task_id = NULL;
+
+static void mmi_voicechat_data_send_task_msg_send(MMI_VOICECHAT_DATA_SEND_MSG_ID_E msg_id, void * param, uint32_t param_size)
+{
+       printf("[@CHENG_DEBUG][%s][%d]: msg_id=%d\n",__FUNCTION__,__LINE__, msg_id);
+       
+       if(NULL != s_voicechat_data_send_task_id)
+       {
+               if((MMI_VOICECHAT_DATA_SEND_TASK_MSG_QUEUE_SIZE - 1) < Hal_Get_Message_Count(s_voicechat_data_send_task_id))
+               {
+                       printf("[@CHENG_DEBUG][%s][%d]: msg queue full\n",__FUNCTION__,__LINE__);
+                       return;
+               }
+               
+               printf("[@CHENG_DEBUG][%s][%d]: \n",__FUNCTION__,__LINE__);
+               
+               void * temp_ptr = NULL;
+               if(NULL != param && 0 != param_size)
+               {
+                       temp_ptr = lv_mem_alloc(param_size + 1);
+                       if(NULL == temp_ptr)
+                       {
+                               printf("[@CHENG_DEBUG][%s][%d]: memory alloc fail\n", __FUNCTION__, __LINE__);
+                               return;
+                       }
+                       _lv_memset_00(temp_ptr, param_size + 1);
+                       _lv_memcpy(temp_ptr, param, param_size);
+               }
+                       
+        mmi_voicechat_data_task_msg_t * msg = Hal_Mem_Alloc(sizeof(mmi_voicechat_data_task_msg_t));
+               msg->cmd_type = msg_id;
+               msg->cmd_param = temp_ptr;
+               msg->param_size = param_size;
+       
+        Hal_Send_Message((TASK_ID)s_voicechat_data_send_task_id, (void *)msg);
+    }
+}
+
+static void mm_voicechat_data_send_task_handle(void * param)
+{
+       mmi_voicechat_data_task_msg_t * msg = (mmi_voicechat_data_task_msg_t *)param;
+       MMI_VOICECHAT_DATA_SEND_MSG_ID_E msg_id = msg->cmd_type;
+       void * msg_param = msg->cmd_param;
+       uint32_t param_size = msg->param_size;
+       
+       printf("[@CHENG_DEBUG][%s][%d]: msg_id=%d\n",__FUNCTION__,__LINE__, msg_id);
+    switch(msg_id)
+       {
+               case MMI_VOICECHAT_MSG_TRANS_START_SEND:
+                       mmi_voicechat_send_trans_start_data_process(msg_param, param_size);
+                       break;
+                       
+        case MMI_VOICECHAT_MSG_TRANS_AUDIO_SEND:
+                       mmi_voicechat_send_trans_audio_data_process(msg_param, param_size);
+            break;
+
+               case MMI_VOICECHAT_MSG_TRANS_STOP_SEND:
+                       //mmi_voicechat_send_trans_stop_data_process(msg_param, param_size);
+                       break;
+
+               case MMI_VOICECHAT_MSG_CHAT_TEXT_SEND:
+                       mmi_voicechat_send_chat_text_data_process(msg_param, param_size);
+                       break;
+
+               case MMI_VOICECHAT_MSG_TTS_START_SEND:
+                       //mmi_voicechat_send_tts_start_data_process(msg_param, param_size);
+                       break;
+                       
+               case MMI_VOICECHAT_MSG_TTS_TEXT_SEND:
+                       mmi_voicechat_send_tts_text_data_process(msg_param, param_size);
+                       break;
+                               
+               case MMI_VOICECHAT_MSG_TTS_STOP_SEND:
+                       //mmi_voicechat_send_tts_stop_data_process(msg_param, param_size);
+                       break;
+               
+               default:
+                       break;
+    }
+}
+
+static void mm_voicechat_data_send_task_entry(void * para)
+{
+    while(s_voicechat_data_send_task_id == NULL)
+       {
+        uos_sleep(10);
+    }
+
+    while(1)
+       {
+        // receive message
+        mmi_voicechat_data_task_msg_t * msg = (mmi_voicechat_data_task_msg_t *)Hal_Receive_Message((TASK_ID)s_voicechat_data_send_task_id, TRUE);
+        if(!msg)
+            continue;
+
+               mm_voicechat_data_send_task_handle(msg);
+               
+        Hal_Mem_Free(msg->cmd_param);
+        Hal_Mem_Free(msg);
+    }
+}
+
+static void mmi_voicechat_data_send_task_create(void)
+{
+       if(NULL != s_voicechat_data_send_task_id)
+               return;
+       
+       s_voicechat_data_send_task_id = uos_create_task(mm_voicechat_data_send_task_entry,
+                                                                                       NULL,
+                                                                                       MMI_VOICECHAT_DATA_SEND_TASK_MSG_QUEUE_SIZE,
+                                                                                       MMI_VOICECHAT_DATA_SEND_TASK_STACK_SIZE,
+                                                                                       MMI_VOICECHAT_DATA_SEND_TASK_PRIORITY,
+                                                                                       "mm_voicechat_data_send_task");
+
+       printf("[@CHENG_DEBUG][%s][%d]: tcp_task_id=0x%x\n",__FUNCTION__,__LINE__, s_voicechat_data_send_task_id);
+}
+
+static void mmi_voicechat_data_send_task_delete(void)
+{
+       if(NULL != s_voicechat_data_send_task_id)
+       {
+               uos_delete_task(s_voicechat_data_send_task_id);
+               s_voicechat_data_send_task_id = NULL;
+       }
+}
+
+void mmi_voicechat_data_task_create(void)
+{
+       //mmi_voicechat_data_recv_task_create();
+       mmi_voicechat_data_send_task_create();
+}
+
+void mmi_voicechat_data_task_delete(void)
+{
+       //mmi_voicechat_data_recv_task_delete();
+       mmi_voicechat_data_send_task_delete();
+}
+
+
+
+// trans
+void mmi_voicechat_send_trans_start_msg(void * param, uint32_t param_size)
+{
+       mmi_voicechat_data_send_task_msg_send(MMI_VOICECHAT_MSG_TRANS_START_SEND, NULL, 0);
+}
+
+void mmi_voicechat_send_trans_audio_msg(void * param, uint32_t param_size)
+{
+       mmi_voicechat_data_send_task_msg_send(MMI_VOICECHAT_MSG_TRANS_AUDIO_SEND, param, param_size);
+}
+
+void mmi_voicechat_send_trans_stop_msg(void * param, uint32_t param_size)
+{
+       //mmi_voicechat_data_send_task_msg_send(MMI_VOICECHAT_MSG_TRANS_STOP_SEND, NULL, 0);
+}
+
+static void mmi_voicechat_send_trans_start_data_process(void * data_ptr, uint32_t data_len)
+{
+    char send_ptr[512] = {0};
+       int send_len = 0;
+
+       send_len = sprintf(send_ptr, "{\"header\":{\"event\":\"StartTranscription\",\"trace_id\":\"3fa6b9e6a30b407ea38ad7ae69e6c291\"},\"payload\":{\"format\":\"amr\",\"sample_rate\":8000}}");
+
+       //int ret = mmi_voicechat_trans_websocket_send_text_data(send_ptr, send_len);
+       //if(0 > ret)
+       {
+               //VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: error=%d,send fail\n", __FUNCTION__, __LINE__, ret);
+
+               //mmi_voicechat_trans_text_start_msg_send_fail();
+       }
+}
+
+static void mmi_voicechat_send_trans_audio_data_process(void * data_ptr, uint32_t data_len)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: size=%d,data=%s\n", __FUNCTION__, __LINE__, data_len, data_ptr);
+       
+       //int ret = mmi_voicechat_trans_websocket_send_binary_data(data_ptr, data_len);
+       //if(0 > ret)
+       {
+               //VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: error=%d,send fail\n", __FUNCTION__, __LINE__, ret);
+
+               //mmi_voicechat_trans_text_audio_msg_send_fail();
+       }
+}
+
+static void mmi_voicechat_send_trans_stop_data_process(void * data_ptr, uint32_t data_len)
+{
+#if 0
+    char send_ptr[512] = {0};
+       int send_len = 0;
+
+       send_len = sprintf(send_ptr, "{\"header\":{\"event\":\"StopTranscription\",\"trace_id\":\"3fa6b9e6a30b407ea38ad7ae69e6c291\"}}");
+
+       int ret = mmi_voicechat_trans_websocket_send_text_data(send_ptr, send_len);
+       if(0 > ret)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: error=%d,send fail\n", __FUNCTION__, __LINE__, ret);
+       }
+#endif
+}
+
+#if 0
+static void mmi_voicechat_trans_text_data_recv_msg(void * param, uint32_t param_size)
+{
+       mmi_voicechat_data_recv_task_msg_send(MMI_VOICECHAT_MSG_TRANS_TEXT_RECV, param, param_size);
+}
+
+static void mmi_voicechat_recv_trans_text_data_process(void * data_ptr, uint32_t data_len)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: len=%d\n", __FUNCTION__, __LINE__, data_len);
+       cplog_printf("[@CHENG_DEBUG][%s][%d]: len=%d\n", __FUNCTION__, __LINE__, data_len);
+       if(NULL == data_ptr)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: no data\n", __FUNCTION__, __LINE__);
+               return;
+       }
+
+#ifdef MMI_VOICECHAT_DEBUG_TO_FILE
+       mmi_debug_info_write_to_file(VOICECHAT_RECV_TRANS_FILE, data_ptr, data_len);
+#endif
+
+       cJSON * json_root = cJSON_Parse(data_ptr);
+       if(NULL != json_root)
+       {
+               cplog_printf("[@CHENG_DEBUG][%s][%d]: json root\n", __FUNCTION__, __LINE__);
+
+               // "event"
+               char * value_event_str = cJSON_GetStringValue(cJSON_GetObjectItem(json_root, "event"));
+               if(0 == strncmp(value_event_str, "TranscriptionStarted", strlen("TranscriptionStarted")))
+               {
+                       // start
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: transcription start\n", __FUNCTION__, __LINE__);
+                       
+               }
+               else if(0 == strncmp(value_event_str, "Changed", strlen("Changed")))
+               {
+                       // changed
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: changed\n", __FUNCTION__, __LINE__);
+                       cJSON * json_result = cJSON_GetObjectItem(json_root, "result");
+                       if(NULL != json_result)
+                       {
+                               char * value_result_str = cJSON_GetStringValue(cJSON_GetObjectItem(json_result, "result"));
+                               uint32_t value_result_len = strlen(value_result_str);
+                               
+                               if(true == mmi_voicechat_trans_result_text_store(value_result_str, value_result_len, false))
+                               {
+                                       // refresh ui
+                                       mmi_voicechat_trans_text_middle_screen_update();                                        
+                               }
+                       }
+               }               
+               else if(0 == strncmp(value_event_str, "SentenceEnd", strlen("SentenceEnd")))
+               {
+                       // end
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: transcription end\n", __FUNCTION__, __LINE__);
+                       cJSON * json_result = cJSON_GetObjectItem(json_root, "result");
+                       if(NULL != json_result)
+                       {
+                               char * value_result_str = cJSON_GetStringValue(cJSON_GetObjectItem(json_result, "result"));
+                               uint32_t value_result_len = strlen(value_result_str);
+                               
+                               if(true == mmi_voicechat_trans_result_text_store(value_result_str, value_result_len, true))
+                               {
+                                       // refresh ui
+                                       mmi_voicechat_trans_text_stop_screen_update();                                  
+                               }
+                       }
+               }
+               else if(0 == strncmp(value_event_str, "TranscriptionCompleted", strlen("TranscriptionCompleted")))
+               {
+                       // stop
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: transcription stop\n", __FUNCTION__, __LINE__);
+
+               }
+       }
+
+EXIT_AND_FREE:
+       if(NULL != json_root)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: free json root\n", __FUNCTION__, __LINE__);
+               cplog_printf("[@CHENG_DEBUG][%s][%d]: free json root\n", __FUNCTION__, __LINE__);
+               cJSON_Delete(json_root);
+               json_root = NULL;
+       }
+}
+
+
+void mmi_voicechat_trans_websocket_recv_data_handler(char * data_ptr, int data_len, int payload_len, int payload_offset)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: size=%d\n", __FUNCTION__, __LINE__, data_len);
+       //cplog_printf("[@CHENG_DEBUG][%s][%d]: size=%d\n", __FUNCTION__, __LINE__, data_len);
+       
+       mmi_voicechat_trans_text_data_recv_msg(data_ptr, data_len);
+}
+#else
+
+void mmi_voicechat_trans_websocket_recv_data_handler(char * data_ptr, int data_len, int payload_len, int payload_offset)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: size=%d\n", __FUNCTION__, __LINE__, data_len);
+       //cplog_printf("[@CHENG_DEBUG][%s][%d]: size=%d\n", __FUNCTION__, __LINE__, data_len);
+       
+       if(NULL == data_ptr)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: no data\n", __FUNCTION__, __LINE__);
+               return;
+       }
+
+#ifdef MMI_VOICECHAT_DEBUG_TO_FILE
+       mmi_debug_info_write_to_file(VOICECHAT_RECV_TRANS_FILE, data_ptr, data_len);
+#endif
+
+       cJSON * json_root = cJSON_Parse(data_ptr);
+       if(NULL != json_root)
+       {
+               cplog_printf("[@CHENG_DEBUG][%s][%d]: json root\n", __FUNCTION__, __LINE__);
+
+               // "event"
+               char * value_event_str = cJSON_GetStringValue(cJSON_GetObjectItem(json_root, "event"));
+               if(0 == strncmp(value_event_str, "TranscriptionStarted", strlen("TranscriptionStarted")))
+               {
+                       // start
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: transcription start\n", __FUNCTION__, __LINE__);
+                       
+               }
+               else if(0 == strncmp(value_event_str, "Changed", strlen("Changed")))
+               {
+                       // changed
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: changed\n", __FUNCTION__, __LINE__);
+                       cJSON * json_result = cJSON_GetObjectItem(json_root, "result");
+                       if(NULL != json_result)
+                       {
+                               char * value_result_str = cJSON_GetStringValue(cJSON_GetObjectItem(json_result, "result"));
+                               uint32_t value_result_len = strlen(value_result_str);
+                               
+                               if(true == mmi_voicechat_trans_result_text_store(value_result_str, value_result_len, false))
+                               {
+                                       // refresh ui
+                                       mmi_voicechat_trans_text_middle_screen_update();                                        
+                               }
+                       }
+               }               
+               else if(0 == strncmp(value_event_str, "SentenceEnd", strlen("SentenceEnd")))
+               {
+                       // end
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: transcription end\n", __FUNCTION__, __LINE__);
+                       cJSON * json_result = cJSON_GetObjectItem(json_root, "result");
+                       if(NULL != json_result)
+                       {
+                               char * value_result_str = cJSON_GetStringValue(cJSON_GetObjectItem(json_result, "result"));
+                               uint32_t value_result_len = strlen(value_result_str);
+                               
+                               if(true == mmi_voicechat_trans_result_text_store(value_result_str, value_result_len, true))
+                               {
+                                       // refresh ui
+                                       mmi_voicechat_trans_text_stop_screen_update();                                  
+                               }
+                       }
+               }
+               else if(0 == strncmp(value_event_str, "TranscriptionCompleted", strlen("TranscriptionCompleted")))
+               {
+                       // stop
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: transcription stop\n", __FUNCTION__, __LINE__);
+
+               }
+       }
+
+EXIT_AND_FREE:
+       if(NULL != json_root)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: free json root\n", __FUNCTION__, __LINE__);
+               //cplog_printf("[@CHENG_DEBUG][%s][%d]: free json root\n", __FUNCTION__, __LINE__);
+               cJSON_Delete(json_root);
+               json_root = NULL;
+       }
+}
+#endif
+
+
+
+// chat
+void mmi_voicechat_send_chat_text_msg(void * param, uint32_t param_size)
+{
+       mmi_voicechat_data_send_task_msg_send(MMI_VOICECHAT_MSG_CHAT_TEXT_SEND, param, param_size);
+}
+
+static void mmi_voicechat_send_chat_text_data_process(void * data_ptr, uint32_t data_len)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: size=%d,data=%s\n", __FUNCTION__, __LINE__, data_len, data_ptr);
+       
+       uint32_t temp_len = 0;
+       uint32_t send_buff_len = data_len + 128;
+       char * send_buff_ptr = lv_mem_alloc(send_buff_len);
+       if(NULL == send_buff_ptr)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: memory alloc fail\n", __FUNCTION__, __LINE__);
+               return;
+       }
+       _lv_memset_00(send_buff_ptr, send_buff_len);
+       
+       temp_len = sprintf(send_buff_ptr, "{\"type\":\"chat\",\"content\":\"%s\"}", data_ptr);
+
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: send_len=%d\n", __FUNCTION__, __LINE__, temp_len);
+       //int ret = mmi_voicechat_chat_websocket_send_text_data(send_buff_ptr, temp_len);
+       //if(0 > ret)
+       {
+               //VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: error=%d,send fail\n", __FUNCTION__, __LINE__, ret);
+       }
+
+       if(NULL != send_buff_ptr)
+       {
+               lv_mem_free(send_buff_ptr);
+               send_buff_ptr = NULL;
+       }
+}
+
+#if 0
+static void mmi_voicechat_chat_text_data_recv_msg(void * param, uint32_t param_size)
+{
+       mmi_voicechat_data_recv_task_msg_send(MMI_VOICECHAT_MSG_CHAT_TEXT_RECV, param, param_size);
+}
+
+static void mmi_voicechat_recv_chat_text_data_process(void * data_ptr, uint32_t data_len)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: len=%d\n", __FUNCTION__, __LINE__, data_len);
+       cplog_printf("[@CHENG_DEBUG][%s][%d]: len=%d\n", __FUNCTION__, __LINE__, data_len);
+       if(NULL == data_ptr)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: no data\n", __FUNCTION__, __LINE__);
+               return;
+       }
+
+#ifdef MMI_VOICECHAT_DEBUG_TO_FILE
+       mmi_debug_info_write_to_file(VOICECHAT_RECV_CHAT_FILE, data_ptr, data_len);
+#endif
+
+       cJSON * json_root = cJSON_Parse(data_ptr);
+       if(NULL != json_root)
+       {
+               cplog_printf("[@CHENG_DEBUG][%s][%d]: json root\n", __FUNCTION__, __LINE__);
+
+               // "type"
+               char * value_type_str = cJSON_GetStringValue(cJSON_GetObjectItem(json_root, "type"));
+               if(0 == strncmp(value_type_str, "start", strlen("start")))
+               {
+                       // start
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: chat start\n", __FUNCTION__, __LINE__);
+                       
+               }
+               else if(0 == strncmp(value_type_str, "middle", strlen("middle")))
+               {
+                       // middle
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: chat middle\n", __FUNCTION__, __LINE__);
+
+                       char * value_content_str = cJSON_GetStringValue(cJSON_GetObjectItem(json_root, "content"));
+                       uint32_t value_content_len = strlen(value_content_str);
+                       
+                       if(true == mmi_voicechat_chat_result_text_store(value_content_str, value_content_len))
+                       {
+                               // send msg to refresh ui
+                               //mmi_voicechat_chat_text_middle_screen_update();
+                       }
+               }
+               else if(0 == strncmp(value_type_str, "end", strlen("end")))
+               {
+                       // stop
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: chat stop\n", __FUNCTION__, __LINE__);
+
+                       // send msg to refresh ui
+                       mmi_voicechat_chat_text_stop_screen_update();
+               }
+       }
+
+EXIT_AND_FREE:
+       if(NULL != json_root)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: free json root\n", __FUNCTION__, __LINE__);
+               cplog_printf("[@CHENG_DEBUG][%s][%d]: free json root\n", __FUNCTION__, __LINE__);
+               cJSON_Delete(json_root);
+               json_root = NULL;
+       }
+}
+
+void mmi_voicechat_chat_websocket_recv_data_handler(char * data_ptr, int data_len, int payload_len, int payload_offset)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: size=%d\n", __FUNCTION__, __LINE__, data_len);
+       //cplog_printf("[@CHENG_DEBUG][%s][%d]: size=%d\n", __FUNCTION__, __LINE__, data_len);
+       
+       mmi_voicechat_chat_text_data_recv_msg(data_ptr, data_len);      
+}
+#else
+
+void mmi_voicechat_chat_websocket_recv_data_handler(char * data_ptr, int data_len, int payload_len, int payload_offset)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: size=%d\n", __FUNCTION__, __LINE__, data_len);
+       //cplog_printf("[@CHENG_DEBUG][%s][%d]: size=%d\n", __FUNCTION__, __LINE__, data_len);
+       
+       if(NULL == data_ptr)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: no data\n", __FUNCTION__, __LINE__);
+               return;
+       }
+
+#ifdef MMI_VOICECHAT_DEBUG_TO_FILE
+       mmi_debug_info_write_to_file(VOICECHAT_RECV_CHAT_FILE, data_ptr, data_len);
+#endif
+
+       cJSON * json_root = cJSON_Parse(data_ptr);
+       if(NULL != json_root)
+       {
+               cplog_printf("[@CHENG_DEBUG][%s][%d]: json root\n", __FUNCTION__, __LINE__);
+
+               // "type"
+               char * value_type_str = cJSON_GetStringValue(cJSON_GetObjectItem(json_root, "type"));
+               if(0 == strncmp(value_type_str, "start", strlen("start")))
+               {
+                       // start
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: chat start\n", __FUNCTION__, __LINE__);
+                       
+               }
+               else if(0 == strncmp(value_type_str, "middle", strlen("middle")))
+               {
+                       // middle
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: chat middle\n", __FUNCTION__, __LINE__);
+
+                       char * value_content_str = cJSON_GetStringValue(cJSON_GetObjectItem(json_root, "content"));
+                       uint32_t value_content_len = strlen(value_content_str);
+                       
+                       if(true == mmi_voicechat_chat_result_text_store(value_content_str, value_content_len))
+                       {
+                               // send msg to refresh ui
+                               //mmi_voicechat_chat_text_middle_screen_update();
+                       }
+               }
+               else if(0 == strncmp(value_type_str, "end", strlen("end")))
+               {
+                       // stop
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: chat stop\n", __FUNCTION__, __LINE__);
+
+                       // send msg to refresh ui
+                       mmi_voicechat_chat_text_stop_screen_update();
+               }
+       }
+
+EXIT_AND_FREE:
+       if(NULL != json_root)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: free json root\n", __FUNCTION__, __LINE__);
+               //cplog_printf("[@CHENG_DEBUG][%s][%d]: free json root\n", __FUNCTION__, __LINE__);
+               cJSON_Delete(json_root);
+               json_root = NULL;
+       }
+}
+#endif
+
+
+
+// tts
+#if 0
+void mmi_voicechat_send_tts_start_msg(void * param, uint32_t param_size)
+{
+       mmi_voicechat_data_send_task_msg_send(MMI_VOICECHAT_MSG_TTS_START_SEND, NULL, 0);
+}
+
+void mmi_voicechat_send_tts_stop_msg(void * param, uint32_t param_size)
+{
+       mmi_voicechat_data_send_task_msg_send(MMI_VOICECHAT_MSG_TTS_STOP_SEND, NULL, 0);
+}
+
+void mmi_voicechat_send_tts_text_msg(void * param, uint32_t param_size)
+{
+       mmi_voicechat_data_send_task_msg_send(MMI_VOICECHAT_MSG_TTS_TEXT_SEND, param, param_size);
+}
+
+static void mmi_voicechat_send_tts_start_data_process(void * data_ptr, uint32_t data_len)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: size=%d,data=%s\n", __FUNCTION__, __LINE__, data_len, data_ptr);
+       
+    char send_ptr[512] = {0};
+       int send_len = 0;
+
+       send_len = sprintf(send_ptr, "{\"header\":{\"event\":\"StartSynthesis\",\"trace_id\":\"3fa6b9e6a30b407ea38ad7ae69e6c291\"},\"payload\":{\"voice\":\"zhixiaomei\",\"format\":\"mp3\",\"sample_rate\":8000,\"volume\":50,\"speech_rate\":0}}");
+       //send_len = sprintf(send_ptr, "{\"header\":{\"event\":\"StartSynthesis\",\"trace_id\":\"3fa6b9e6a30b407ea38ad7ae69e6c291\"},\"payload\":{\"voice\":\"xiaoyun\",\"format\":\"WAV\",\"sample_rate\":16000,\"volume\":50,\"speech_rate\":0}}");   
+
+       int ret = mmi_voicechat_tts_websocket_send_text_data(send_ptr, send_len);
+       if(0 > ret)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: error=%d,send fail\n", __FUNCTION__, __LINE__, ret);
+       }
+}
+
+static void mmi_voicechat_send_tts_stop_data_process(void * data_ptr, uint32_t data_len)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: size=%d,data=%s\n", __FUNCTION__, __LINE__, data_len, data_ptr);
+       
+    char send_ptr[512] = {0};
+       int send_len = 0;
+
+       send_len = sprintf(send_ptr, "{\"header\":{\"event\":\"StopSynthesis\",\"trace_id\":\"3fa6b9e6a30b407ea38ad7ae69e6c291\"}}");
+
+       int ret = mmi_voicechat_tts_websocket_send_text_data(send_ptr, send_len);
+       if(0 > ret)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: error=%d,send fail\n", __FUNCTION__, __LINE__, ret);
+       }
+}
+
+static void mmi_voicechat_send_tts_text_data_process(void * data_ptr, uint32_t data_len)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: size=%d\n", __FUNCTION__, __LINE__, data_len);
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%d]: data=%s\n", __LINE__, data_ptr);
+       
+       uint32_t temp_len = 0;
+       uint32_t send_buff_len = data_len + 128;
+       char * send_buff_ptr = lv_mem_alloc(send_buff_len);
+       if(NULL == send_buff_ptr)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: memory alloc fail\n", __FUNCTION__, __LINE__);
+               return;
+       }
+       _lv_memset_00(send_buff_ptr, send_buff_len);
+       
+#if 0
+       temp_len = 0;
+       temp_len += sprintf(send_buff_ptr + temp_len, "{\"header\":{\"event\": \"LongTextStream\",\"trace_id\": \"3fa6b9e6a30b407ea38ad7ae69e6c291\"},");
+       temp_len += sprintf(send_buff_ptr + temp_len, "\"payload\":{\"voice\":\"xiaoyun\",\"format\":\"amr\",\"sample_rate\":8000,\"volume\":50,\"speech_rate\":0,");
+       temp_len += sprintf(send_buff_ptr + temp_len, "\"text\":\"%s\"}}", data_ptr);
+#else
+       temp_len = 0;
+       temp_len += sprintf(send_buff_ptr + temp_len, "{\"header\":{\"event\":\"RunSynthesis\",\"trace_id\":\"3fa6b9e6a30b407ea38ad7ae69e6c291\"},");
+       temp_len += sprintf(send_buff_ptr + temp_len, "\"payload\":{\"text\":\"%s\"}}", data_ptr);
+#endif
+
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: send_len=%d\n", __FUNCTION__, __LINE__, temp_len);
+       int ret = mmi_voicechat_tts_websocket_send_text_data(send_buff_ptr, temp_len);
+       if(0 > ret)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: error=%d,send fail\n", __FUNCTION__, __LINE__, ret);
+       }
+
+       if(NULL != send_buff_ptr)
+       {
+               lv_mem_free(send_buff_ptr);
+               send_buff_ptr = NULL;
+       }
+}
+
+#else
+
+void mmi_voicechat_send_tts_text_msg(void * param, uint32_t param_size)
+{
+       mmi_voicechat_data_send_task_msg_send(MMI_VOICECHAT_MSG_TTS_TEXT_SEND, param, param_size);
+}
+
+static void mmi_voicechat_send_tts_text_data_process(void * data_ptr, uint32_t data_len)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: size=%d\n", __FUNCTION__, __LINE__, data_len);
+       
+       uint32_t temp_len = 0;
+       uint32_t send_buff_len = data_len + 256;
+       char * send_buff_ptr = lv_mem_alloc(send_buff_len);
+       if(NULL == send_buff_ptr)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: memory alloc fail\n", __FUNCTION__, __LINE__);
+               return;
+       }
+       _lv_memset_00(send_buff_ptr, send_buff_len);
+       
+       temp_len = 0;
+       temp_len += sprintf(send_buff_ptr + temp_len, "{\"header\":{\"event\":\"LongTextStream\",\"trace_id\":\"3fa6b9e6a30b407ea38ad7ae69e6c291\"},");
+       temp_len += sprintf(send_buff_ptr + temp_len, "\"payload\":{\"voice\":\"xiaoyun\",\"format\":\"mp3\",\"sample_rate\":8000,\"volume\":50,\"speech_rate\":2,"); // 0,");
+       temp_len += sprintf(send_buff_ptr + temp_len, "\"text\":\"%s\"}}", data_ptr); // 185 + data_len
+
+#ifdef MMI_VOICECHAT_DEBUG_TO_FILE
+       mmi_debug_info_write_to_file(VOICECHAT_SEND_TTS_TEXT_FILE, send_buff_ptr, temp_len);
+#endif
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: send_len=%d\n", __FUNCTION__, __LINE__, temp_len);
+       //int ret = mmi_voicechat_tts_websocket_send_text_data(send_buff_ptr, temp_len);
+       //if(0 > ret)
+       {
+               //VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: error=%d,send fail\n", __FUNCTION__, __LINE__, ret);
+               //mmi_voicechat_list_screen_signal_weak_prompt();
+       }
+
+       if(NULL != send_buff_ptr)
+       {
+               lv_mem_free(send_buff_ptr);
+               send_buff_ptr = NULL;
+       }
+}
+
+#endif
+
+#if 0
+static void mmi_voicechat_tts_audio_data_recv_msg(void * param, uint32_t param_size)
+{
+       mmi_voicechat_data_recv_task_msg_send(MMI_VOICECHAT_MSG_TTS_AUDIO_RECV, param, param_size);
+}
+
+static void mmi_voicechat_recv_tts_audio_data_process(void * data_ptr, uint32_t data_len)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: len=%d\n", __FUNCTION__, __LINE__, data_len);
+       cplog_printf("[@CHENG_DEBUG][%s][%d]: len=%d\n", __FUNCTION__, __LINE__, data_len);
+       if(NULL == data_ptr)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: no data\n", __FUNCTION__, __LINE__);
+               return;
+       }
+
+#ifdef MMI_VOICECHAT_DEBUG_TO_FILE
+       mmi_debug_info_write_to_file(VOICECHAT_RECV_TTS_FILE, data_ptr, data_len);
+#endif
+
+       cJSON * json_root = cJSON_Parse(data_ptr);
+       if(NULL != json_root)
+       {
+               cplog_printf("[@CHENG_DEBUG][%s][%d]: json root\n", __FUNCTION__, __LINE__);
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: tts json\n", __FUNCTION__, __LINE__);
+
+               cJSON * json_header = cJSON_GetObjectItem(json_root, "header");
+               if(NULL != json_header)
+               {
+                       char * value_event_str = cJSON_GetStringValue(cJSON_GetObjectItem(json_header, "event"));
+                       if(0 == strncmp(value_event_str, "EndSynthesis", strlen("EndSynthesis")))
+                       {
+                               // end
+                               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: EndSynthesis\n", __FUNCTION__, __LINE__);
+                               
+                               mmi_voicechat_tts_end_synthesis_action();
+                       }
+               }
+       }
+       else
+       {
+               // tts data
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: tts data\n", __FUNCTION__, __LINE__);
+
+               if(true == mmi_voicechat_tts_audio_store(data_ptr, data_len))
+               {
+               
+               }
+       }
+
+       if(NULL != json_root)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: free json root\n", __FUNCTION__, __LINE__);
+               cplog_printf("[@CHENG_DEBUG][%s][%d]: free json root\n", __FUNCTION__, __LINE__);
+               cJSON_Delete(json_root);
+               json_root = NULL;
+       }
+}
+
+void mmi_voicechat_websocket_recv_data_handler(char * data_ptr, int data_len, int payload_len, int payload_offset)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: size=%d\n", __FUNCTION__, __LINE__, data_len);
+       //cplog_printf("[@CHENG_DEBUG][%s][%d]: size=%d\n", __FUNCTION__, __LINE__, data_len);
+       
+       mmi_voicechat_tts_audio_data_recv_msg(data_ptr, data_len);      
+}
+#else
+
+void mmi_voicechat_websocket_recv_data_handler(char * data_ptr, int data_len, int payload_len, int payload_offset)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: size=%d\n", __FUNCTION__, __LINE__, data_len);
+       //cplog_printf("[@CHENG_DEBUG][%s][%d]: size=%d\n", __FUNCTION__, __LINE__, data_len);
+       
+       if(NULL == data_ptr)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: no data\n", __FUNCTION__, __LINE__);
+               return;
+       }
+
+#ifdef MMI_VOICECHAT_DEBUG_TO_FILE
+       mmi_debug_info_write_to_file(VOICECHAT_RECV_TTS_FILE, data_ptr, data_len);
+#endif
+
+       cJSON * json_root = cJSON_Parse(data_ptr);
+       if(NULL != json_root)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: tts json\n", __FUNCTION__, __LINE__);
+
+               cJSON * json_header = cJSON_GetObjectItem(json_root, "header");
+               if(NULL != json_header)
+               {
+                       char * value_event_str = cJSON_GetStringValue(cJSON_GetObjectItem(json_header, "event"));
+                       if(0 == strncmp(value_event_str, "EndSynthesis", strlen("EndSynthesis")))
+                       {
+                               // end
+                               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: EndSynthesis\n", __FUNCTION__, __LINE__);
+                               
+                               mmi_voicechat_tts_end_synthesis_action();
+                       }
+               }
+       }
+       else
+       {
+               // tts data
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: tts data\n", __FUNCTION__, __LINE__);
+
+               if(true == mmi_voicechat_tts_audio_store(data_ptr, data_len))
+               {
+               
+               }
+       }
+
+       if(NULL != json_root)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: free json root\n", __FUNCTION__, __LINE__);
+               //cplog_printf("[@CHENG_DEBUG][%s][%d]: free json root\n", __FUNCTION__, __LINE__);
+               cJSON_Delete(json_root);
+               json_root = NULL;
+       }
+}
+#endif
+
+#endif
+
diff --git a/2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/mmi_voicechat_data.h b/2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/mmi_voicechat_data.h
new file mode 100644 (file)
index 0000000..fb4805b
--- /dev/null
@@ -0,0 +1,90 @@
+
+
+
+#ifndef __MMI_VOICECHAT_DATA_H__
+#define __MMI_VOICECHAT_DATA_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef LV_CONF_INCLUDE_SIMPLE
+#include "lvgl.h"
+#include "lv_watch_conf.h"
+#else
+#include "../../../lvgl/lvgl.h"
+#include "../../../lv_watch_conf.h"
+#endif
+
+#ifdef __MMI_CUSTOM_VOICECHAT_SUPPORT__
+
+//#include "../../../../../product/craneg_modem/pcac/video_call/re/include/Re_hmac.h"
+#include "hal/dm/cJSON.h"
+#include "../../../../product/craneg_modem/pcac/wsclient/libwebsockets/inc/mmi_voicechat_websocket.h"
+
+
+#define MMI_VOICECHAT_DATA_SEND_TASK_PRIORITY 220
+#define MMI_VOICECHAT_DATA_SEND_TASK_MSG_QUEUE_SIZE (TASK_MSGQ_SIZE_16)
+#define MMI_VOICECHAT_DATA_SEND_TASK_STACK_SIZE (16 * 1024)
+
+#define MMI_VOICECHAT_DATA_RECV_TASK_PRIORITY 220
+#define MMI_VOICECHAT_DATA_RECV_TASK_MSG_QUEUE_SIZE (TASK_MSGQ_SIZE_32)
+#define MMI_VOICECHAT_DATA_RECV_TASK_STACK_SIZE (80 * 1024)
+
+
+
+typedef enum
+{
+       MMI_VOICECHAT_MSG_RECV_ID_START,
+   
+    MMI_VOICECHAT_MSG_TRANS_TEXT_RECV,
+       MMI_VOICECHAT_MSG_CHAT_TEXT_RECV,
+       MMI_VOICECHAT_MSG_TTS_AUDIO_RECV,
+    
+    MMI_VOICECHAT_MSG_RECV_ID_END
+}MMI_VOICECHAT_DATA_RECV_MSG_ID_E;
+
+typedef enum
+{
+       MMI_VOICECHAT_MSG_SEND_ID_START,
+   
+    MMI_VOICECHAT_MSG_TRANS_START_SEND,
+       MMI_VOICECHAT_MSG_TRANS_AUDIO_SEND,
+       MMI_VOICECHAT_MSG_TRANS_STOP_SEND,
+       MMI_VOICECHAT_MSG_CHAT_TEXT_SEND,
+       MMI_VOICECHAT_MSG_TTS_START_SEND,
+       MMI_VOICECHAT_MSG_TTS_TEXT_SEND,
+       MMI_VOICECHAT_MSG_TTS_STOP_SEND,
+    
+    MMI_VOICECHAT_MSG_SEND_ID_END
+}MMI_VOICECHAT_DATA_SEND_MSG_ID_E;
+
+
+
+typedef struct
+{
+       uint16_t cmd_type;
+       void * cmd_param;
+       uint32_t param_size;
+}mmi_voicechat_data_task_msg_t;
+
+
+
+// data task
+void mmi_voicechat_data_task_create(void);
+void mmi_voicechat_data_task_delete(void);
+
+// trans
+void mmi_voicechat_send_trans_start_msg(void * param, uint32_t param_size);
+void mmi_voicechat_send_trans_audio_msg(void * param, uint32_t param_size);
+void mmi_voicechat_send_trans_stop_msg(void * param, uint32_t param_size);
+void mmi_voicechat_send_chat_text_msg(void * param, uint32_t param_size);
+
+
+#endif 
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
diff --git a/2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/mmi_voicechat_ui.c b/2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/mmi_voicechat_ui.c
new file mode 100644 (file)
index 0000000..756baf9
--- /dev/null
@@ -0,0 +1,2099 @@
+
+
+
+#include "lv_watch.h"
+
+#ifdef __MMI_CUSTOM_VOICECHAT_SUPPORT__
+
+static lv_signal_cb_t ancient_scrl_signal;
+
+static MMI_VOICECHAT_UI_STATE_E s_voicechat_ui_state = MMI_VOICECHAT_UI_STATE_NONE;
+static mmi_voicechat_msg_info_t s_voicechat_info_t = {0};
+static mmi_voicechat_msg_info_t * s_voicechat_info_p = &s_voicechat_info_t;
+static uint8_t s_voicechat_current_chat_index = 0; // 1 chat = 2 msg items
+
+static uint32_t s_voicechat_recording_sent_size = 0;
+static uint32_t s_voicechat_tts_text_sent_size = 0;
+static bool s_voicechat_trans_text_end = false;
+static bool s_voicechat_tts_audio_playing = false;
+
+static lv_ll_t s_voicechat_tts_audio_ll = {0};
+static mmi_voicechat_tts_audio_ll_t * s_voicechat_tts_audio_play_node = NULL;
+
+static bool s_voicechat_ws_open_flag = false;
+
+#define MMI_VOICECHAT_SEND_TTS_TEXT_MAX (150) // 50
+#define MMI_VOICECHAT_SEND_TTS_TEXT_MIN (99) // 33
+
+
+static lv_res_t mmi_voicechat_list_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param);
+static void mmi_voicechat_list_set_slide_enable(lv_watch_obj_ext_t * ext, bool enable);
+static void mmi_voicechat_default_screen_display(void);
+static void mmi_voicechat_record_button_event_cb(lv_obj_t * obj, lv_event_t e);
+
+
+#ifdef __MMI_ZHSX_SUPPORT__
+static bool s_is_ACT_ID_VOICECHAT_MAIN = false;
+
+bool mmi_is_ACT_ID_VOICECHAT_MAIN(void)
+{
+       return s_is_ACT_ID_VOICECHAT_MAIN;
+}
+#endif
+
+static void mmi_voicechat_trans_websocket_open(void)
+{
+       if(false == s_voicechat_ws_open_flag)
+       {
+               mmi_voicechat_websocket_app_start();
+               s_voicechat_ws_open_flag = true;
+       }
+}
+
+static void mmi_voicechat_chat_websocket_open(void)
+{
+
+}
+
+static void mmi_voicechat_tts_websocket_open(void)
+{
+
+}
+
+static void mmi_voicechat_trans_websocket_close(void)
+{
+       if(true == s_voicechat_ws_open_flag)
+       {
+               mmi_voicechat_websocket_app_stop();
+               s_voicechat_ws_open_flag = false;
+       }
+}
+
+static void mmi_voicechat_chat_websocket_close(void)
+{
+
+}
+
+static void mmi_voicechat_tts_websocket_close(void)
+{
+
+}
+
+static void mmi_voicechat_msg_data_clean(void)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       
+       uint8_t i = 0;
+       for(i = 0; i < s_voicechat_info_p->msg_count; i++)
+       {
+               if(NULL != s_voicechat_info_p->msg_item[i].text_data_ptr)
+               {
+                       lv_mem_free(s_voicechat_info_p->msg_item[i].text_data_ptr);
+                       s_voicechat_info_p->msg_item[i].text_data_ptr = NULL;
+               }
+
+               if(NULL != s_voicechat_info_p->msg_item[i].audio_data_ptr)
+               {
+                       lv_mem_free(s_voicechat_info_p->msg_item[i].audio_data_ptr);
+                       s_voicechat_info_p->msg_item[i].audio_data_ptr = NULL;
+               }
+       }
+
+       _lv_memset_00(s_voicechat_info_p, sizeof(mmi_voicechat_msg_info_t));
+}
+
+uint8_t mmi_voicechat_msg_count_get(void)
+{
+       uint8_t msg_count = 0;
+
+       msg_count = s_voicechat_info_p->msg_count;
+       
+       return msg_count;
+}
+
+char * mmi_voicechat_trans_result_text_get(uint32_t * data_len)
+{
+       mmi_voicechat_msg_item_info_t * t_voicechat_item_info = &(s_voicechat_info_p->msg_item[0]);
+       
+       * data_len = t_voicechat_item_info->text_data_size;
+       return (t_voicechat_item_info->text_data_ptr);
+}
+
+bool mmi_voicechat_trans_result_text_store(char * data_buff, uint32_t data_len, bool is_end)
+{
+       if(NULL == data_buff || 0 == data_len)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+               return false;
+       }
+
+       if(true == s_voicechat_trans_text_end)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+               return false;
+       }
+       s_voicechat_trans_text_end = is_end;
+
+       mmi_voicechat_msg_item_info_t * t_voicechat_item_info = &(s_voicechat_info_p->msg_item[0]);
+
+#if 1
+       char * temp_ptr = lv_mem_alloc(data_len + 1);
+       if(NULL == temp_ptr)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: alloc memory fail\n", __FUNCTION__, __LINE__);
+               return false;
+       }
+       _lv_memset_00(temp_ptr, data_len + 1);
+       _lv_memcpy(temp_ptr, data_buff, data_len);
+       
+       if(NULL != t_voicechat_item_info->text_data_ptr)
+       {
+               lv_mem_free(t_voicechat_item_info->text_data_ptr);
+               t_voicechat_item_info->text_data_ptr = NULL;
+       }
+       t_voicechat_item_info->text_data_ptr = temp_ptr;
+       t_voicechat_item_info->text_data_size = data_len;
+
+#else
+       if(NULL == t_voicechat_item_info->text_data_ptr)
+       {
+               char * temp_ptr = lv_mem_alloc(data_len + 1);
+               if(NULL == temp_ptr)
+               {
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: alloc memory fail\n", __FUNCTION__, __LINE__);
+                       return false;
+               }
+               _lv_memset_00(temp_ptr, data_len + 1);
+               _lv_memcpy(temp_ptr, data_buff, data_len);
+
+               t_voicechat_item_info->text_data_ptr = temp_ptr;
+               t_voicechat_item_info->text_data_size = data_len;
+       }
+       else
+       {
+               char * temp_ptr = lv_mem_realloc(t_voicechat_item_info->text_data_ptr, t_voicechat_item_info->text_data_size + data_len + 1);
+               if(NULL == temp_ptr)
+               {
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: realloc memory fail\n", __FUNCTION__, __LINE__);
+                       return false;
+               }
+               _lv_memset_00(temp_ptr + t_voicechat_item_info->text_data_size, data_len + 1);
+               _lv_memcpy(temp_ptr + t_voicechat_item_info->text_data_size, data_buff, data_len);
+
+               t_voicechat_item_info->text_data_ptr = temp_ptr;
+               t_voicechat_item_info->text_data_size += data_len;
+       }
+#endif
+       t_voicechat_item_info->msg_from = 0;
+       s_voicechat_info_p->msg_count = 1;
+       
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: size=%d,ptr=0x%x\n", __FUNCTION__, __LINE__, t_voicechat_item_info->text_data_size, t_voicechat_item_info->text_data_ptr);
+
+#ifdef MMI_VOICECHAT_DEBUG_TO_FILE
+       mmi_debug_info_write_to_file(VOICECHAT_RECV_TRANS_RESULT_FILE, t_voicechat_item_info->text_data_ptr, t_voicechat_item_info->text_data_size);
+#endif
+
+       return true;
+}
+
+static void mmi_voicechat_trans_text_middle_screen_task_cb(lv_task_t * task)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: ui_state=%d\n", __FUNCTION__, __LINE__, s_voicechat_ui_state);
+       
+       if(MMI_VOICECHAT_UI_STATE_LISTENING == s_voicechat_ui_state || MMI_VOICECHAT_UI_STATE_LISTENING_MIDDLE == s_voicechat_ui_state)
+       {               
+               lv_voicechat_ext_t * ext = mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+               if(NULL == ext)
+                       return;
+               
+               mmi_voicechat_list_set_slide_enable(&ext->old_ext, true);
+
+               if(0 != mmi_voicechat_msg_count_get())
+               {
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+
+                       mmi_voicechat_listening_middle_screen_display();
+               }
+       }
+}
+
+void mmi_voicechat_trans_text_middle_screen_update(void)
+{
+       lv_task_t * task_p = lv_task_create(mmi_voicechat_trans_text_middle_screen_task_cb, 10, LV_TASK_PRIO_HIGH, NULL);
+       lv_task_once(task_p);
+}
+
+static void mmi_voicechat_trans_text_screen_close_task_cb(lv_task_t * task)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       
+       mmi_voicechat_thinking_screen_display();
+
+       mmi_voicechat_chat_text_download_requst();
+}
+
+static void mmi_voicechat_trans_text_stop_screen_task_cb(void)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: ui_state=%d\n", __FUNCTION__, __LINE__, s_voicechat_ui_state);
+
+       // wb
+       mmi_voicechat_trans_websocket_close();
+       mmi_voicechat_chat_websocket_open();
+
+       if(MMI_VOICECHAT_UI_STATE_LISTENING == s_voicechat_ui_state || MMI_VOICECHAT_UI_STATE_LISTENING_MIDDLE == s_voicechat_ui_state)
+       {
+               // record
+               mmi_voicechat_listening_stop(true);
+               
+               lv_voicechat_ext_t * ext = mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+               if(NULL == ext)
+                       return;
+               
+               mmi_voicechat_list_set_slide_enable(&ext->old_ext, true);
+
+               if(0 == mmi_voicechat_msg_count_get())
+               {
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+
+                       mmi_voicechat_default_screen_display();
+               }
+               else
+               {
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+
+                       mmi_voicechat_listening_middle_screen_display();
+
+                       lv_task_t * task_p = lv_task_create(mmi_voicechat_trans_text_screen_close_task_cb, 1000, LV_TASK_PRIO_HIGH, NULL);
+                       lv_task_once(task_p);
+               }
+       }
+}
+
+void mmi_voicechat_trans_text_stop_screen_update(void)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+
+       lv_task_t * task_p = lv_task_create(mmi_voicechat_trans_text_stop_screen_task_cb, 10, LV_TASK_PRIO_HIGH, NULL);
+       lv_task_once(task_p);   
+}
+
+static void mmi_voicechat_trans_text_fail_screen_task_cb(void)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+
+       mmi_voicechat_default_screen_display();
+}
+
+void mmi_voicechat_trans_text_start_msg_send_fail(void)
+{
+       mmi_voicechat_trans_websocket_close();
+       mmi_voicechat_listening_stop(true);
+       
+       lv_voicechat_ext_t * ext = (lv_voicechat_ext_t *)mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+       if(NULL == ext) 
+               return ;
+
+       lv_obj_set_hidden(ext->listening_signal_weak_label, false);
+       
+       lv_task_t * task_p = lv_task_create(mmi_voicechat_trans_text_fail_screen_task_cb, 1500, LV_TASK_PRIO_HIGH, NULL);
+       lv_task_once(task_p);   
+}
+
+void mmi_voicechat_trans_text_audio_msg_send_fail(void)
+{
+       mmi_voicechat_trans_websocket_close();
+       mmi_voicechat_trans_websocket_open();
+}
+
+
+char * mmi_voicechat_chat_result_text_get(uint32_t * data_len)
+{
+       mmi_voicechat_msg_item_info_t * t_voicechat_item_info = &(s_voicechat_info_p->msg_item[1]);
+       
+       * data_len = t_voicechat_item_info->text_data_size;
+       return (t_voicechat_item_info->text_data_ptr);
+}
+
+bool mmi_voicechat_chat_result_text_store(char * data_buff, uint32_t data_len)
+{
+       if(NULL == data_buff || 0 == data_len)
+       {
+               printf("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+               return false;
+       }
+
+       mmi_voicechat_msg_item_info_t * t_voicechat_item_info = &(s_voicechat_info_p->msg_item[1]);
+       
+       if(NULL == t_voicechat_item_info->text_data_ptr)
+       {
+               char * temp_ptr = lv_mem_alloc(data_len + 1);
+               if(NULL == temp_ptr)
+               {
+                       printf("[@CHENG_DEBUG][%s][%d]: alloc memory fail\n", __FUNCTION__, __LINE__);
+                       return false;
+               }
+               _lv_memset_00(temp_ptr, data_len + 1);
+               _lv_memcpy(temp_ptr, data_buff, data_len);
+
+               t_voicechat_item_info->text_data_ptr = temp_ptr;
+               t_voicechat_item_info->text_data_size = data_len;
+       }
+       else
+       {
+               char * temp_ptr = lv_mem_realloc(t_voicechat_item_info->text_data_ptr, t_voicechat_item_info->text_data_size + data_len + 1);
+               if(NULL == temp_ptr)
+               {
+                       printf("[@CHENG_DEBUG][%s][%d]: realloc memory fail\n", __FUNCTION__, __LINE__);
+                       return false;
+               }
+               _lv_memset_00(temp_ptr + t_voicechat_item_info->text_data_size, data_len + 1);
+               _lv_memcpy(temp_ptr + t_voicechat_item_info->text_data_size, data_buff, data_len);
+
+               t_voicechat_item_info->text_data_ptr = temp_ptr;
+               t_voicechat_item_info->text_data_size += data_len;
+       }
+       t_voicechat_item_info->msg_from = 1;
+       s_voicechat_info_p->msg_count = 2;
+       
+       printf("[@CHENG_DEBUG][%s][%d]: size=%d,ptr=0x%x\n", __FUNCTION__, __LINE__, t_voicechat_item_info->text_data_size, t_voicechat_item_info->text_data_ptr);
+
+#ifdef MMI_VOICECHAT_DEBUG_TO_FILE
+       mmi_debug_info_write_to_file(VOICECHAT_RECV_CHAT_RESULT_FILE, t_voicechat_item_info->text_data_ptr, t_voicechat_item_info->text_data_size);
+#endif
+
+       return true;
+}
+
+void mmi_voicechat_chat_text_middle_task_cb(lv_task_t * task)
+{
+       if(MMI_VOICECHAT_UI_STATE_THINKING == s_voicechat_ui_state)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+               
+               lv_voicechat_ext_t * ext = mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+               if(NULL == ext)
+                       return;
+               
+               if(NULL != ext->thinking_task_p)
+               {
+                       lv_task_del(ext->thinking_task_p);
+                       ext->thinking_task_p = NULL;
+               }
+
+               mmi_voicechat_list_screen_display();
+       }
+       else if(MMI_VOICECHAT_UI_STATE_LIST == s_voicechat_ui_state)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+
+               lv_voicechat_ext_t * ext = mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+               if(NULL == ext)
+                       return;
+
+               mmi_voicechat_msg_item_info_t * msg_item = &(s_voicechat_info_p->msg_item[1]);
+               char * file_buf = msg_item->text_data_ptr;
+
+               lv_label_set_text(ext->list_other_label, file_buf);
+       }
+}
+
+void mmi_voicechat_chat_text_middle_screen_update(void)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+               
+       lv_task_t * task_p = lv_task_create(mmi_voicechat_chat_text_middle_task_cb, 10, LV_TASK_PRIO_HIGH, NULL);
+       lv_task_once(task_p);
+}
+
+static void mmi_voicechat_chat_text_stop_screen_task_cb(void)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: ui_state=%d\n", __FUNCTION__, __LINE__, s_voicechat_ui_state);
+
+       // wb
+       mmi_voicechat_chat_websocket_close();
+       mmi_voicechat_tts_websocket_open();
+
+       if((MMI_VOICECHAT_UI_STATE_THINKING == s_voicechat_ui_state) || (MMI_VOICECHAT_UI_STATE_LIST == s_voicechat_ui_state))
+       {
+               mmi_voicechat_main_screen_refresh();
+
+               mmi_voicechat_tts_audio_download_requst();
+       }
+}
+
+void mmi_voicechat_chat_text_stop_screen_update(void)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+
+       lv_task_t * task_p = lv_task_create(mmi_voicechat_chat_text_stop_screen_task_cb, 10, LV_TASK_PRIO_HIGH, NULL);
+       lv_task_once(task_p);
+}
+
+void mmi_voicechat_chat_text_download_requst(void)
+{
+       uint32_t data_len = 0;
+       char * data_ptr = mmi_voicechat_trans_result_text_get(&data_len);
+
+       if(NULL != data_ptr && 0 != data_len)
+       {
+               mmi_voicechat_send_chat_text_msg(data_ptr, data_len);
+       }
+}
+
+
+static void mmi_utf8_complete_character_judge(char * data_ptr, uint32_t data_len, uint32_t * output_len)
+{
+       uint32_t i = 0;
+       uint32_t p = 0;
+       char ch = 0;
+       while(1)
+       {
+               ch = data_ptr[i];
+
+               //#1111110x
+               if(ch >= 252)
+                       p = p + 6;
+               //#111110xx
+               else if(ch >= 248)
+                       p = p + 5;
+               //#11110xxx
+               else if(ch >= 240)
+                       p = p + 4;
+               //#1110xxxx
+               else if(ch >= 224)
+                       p = p + 3;
+               //#110xxxxx
+               else if(ch >= 192)
+                       p = p + 2;
+               else
+                       p = p + 1;
+
+               if(p >= data_len)
+                       break;
+               else
+                       i = p;
+       }
+
+       * output_len = i;
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: output_len=%d\n", __FUNCTION__, __LINE__, *output_len);
+}
+
+void mmi_voicechat_send_tts_text_seperate(char * data_ptr, uint32_t data_len, uint32_t * output_len)
+{
+       // cn ,
+       char cn_comma_str[4] = {0};
+       cn_comma_str[0] = 0XEF;
+       cn_comma_str[1] = 0XBC;
+       cn_comma_str[2] = 0X8C;
+       
+       // cn .
+       char cn_period_str[4] = {0};
+       cn_period_str[0] = 0XE3;
+       cn_period_str[1] = 0X80;
+       cn_period_str[2] = 0X82;
+
+       // cn ?
+       char cn_query_str[4] = {0};
+       cn_query_str[0] = 0XEF;
+       cn_query_str[1] = 0XBC;
+       cn_query_str[2] = 0X9F;
+
+       // cn !
+       char cn_mark_str[4] = {0};
+       cn_mark_str[0] = 0XEF;
+       cn_mark_str[1] = 0XBC;
+       cn_mark_str[2] = 0X81;
+
+
+       if(MMI_VOICECHAT_SEND_TTS_TEXT_MAX >= data_len)
+       {
+               * output_len = data_len;
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: output_len=%d\n", __FUNCTION__, __LINE__, *output_len);
+               return;
+       }
+
+       char * temp_ptr = lv_mem_alloc(MMI_VOICECHAT_SEND_TTS_TEXT_MAX + 1);
+       if(NULL == temp_ptr)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: alloc memory fail\n", __FUNCTION__, __LINE__);
+               return ;
+       }
+       _lv_memset_00(temp_ptr, (MMI_VOICECHAT_SEND_TTS_TEXT_MAX + 1));
+       _lv_memcpy(temp_ptr, data_ptr, MMI_VOICECHAT_SEND_TTS_TEXT_MAX);
+       
+       char * offset_ptr = NULL;
+       offset_ptr = strstr(temp_ptr, cn_comma_str);
+       if(NULL != offset_ptr)
+       {
+               * output_len = offset_ptr - temp_ptr + 2;
+               goto EXIT;
+       }
+       
+       offset_ptr = strstr(temp_ptr, cn_period_str);
+       if(NULL != offset_ptr)
+       {
+               * output_len = offset_ptr - temp_ptr + 2;
+               goto EXIT;
+       }
+       
+       offset_ptr = strstr(temp_ptr, cn_query_str);
+       if(NULL != offset_ptr)
+       {
+               * output_len = offset_ptr - temp_ptr + 2;
+               goto EXIT;
+       }
+       
+       offset_ptr = strstr(temp_ptr, cn_mark_str);
+       if(NULL != offset_ptr)
+       {
+               * output_len = offset_ptr - temp_ptr + 2;
+               goto EXIT;
+       }
+       
+       if(NULL == offset_ptr)
+       {
+               mmi_utf8_complete_character_judge(temp_ptr, MMI_VOICECHAT_SEND_TTS_TEXT_MIN, output_len);
+       }
+
+EXIT:
+       lv_mem_free(temp_ptr);
+       temp_ptr = NULL;
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: output_len=%d\n", __FUNCTION__, __LINE__, *output_len);
+}
+
+uint32_t mmi_voicechat_send_tts_text_data_escape_character(char * data_buff, int data_len, char * output_data)
+{
+    if (NULL == data_buff || 0 == data_len)
+               return;
+       
+       uint32_t curr_p = 0, i = 0;
+
+       for(i = 0; i < data_len; i++)
+       {
+               if(0X0A == data_buff[i]) // 0X0A -> 0X5C 0X6E 
+               {
+                       output_data[curr_p++] = 0X5C;
+                       output_data[curr_p++] = 0X6E;
+               }
+               else if(0X22 == data_buff[i]) // 0X22 -> 0X5C 0X22
+               {
+                       output_data[curr_p++] = 0X5C;
+                       output_data[curr_p++] = 0X22;
+               }
+               else
+               {
+                       output_data[curr_p++] = data_buff[i];
+               }
+       }
+
+       return curr_p;
+}
+
+void mmi_voicechat_send_tts_text_action(char * data_ptr, uint32_t data_len)
+{
+       uint32_t output_len = 0;
+       mmi_voicechat_send_tts_text_seperate(data_ptr, data_len, &output_len);
+       
+       uint32_t send_len = 0;
+       char * send_ptr = lv_mem_alloc((output_len + output_len / 9 + 1));
+       if(NULL == send_ptr)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: alloc memory fail\n", __FUNCTION__, __LINE__);
+               return ;
+       }
+       _lv_memset_00(send_ptr, (output_len + output_len / 9 + 1));
+       send_len = mmi_voicechat_send_tts_text_data_escape_character(data_ptr, output_len, send_ptr);
+
+#if 0
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: send_len=%d\n", __FUNCTION__, __LINE__, send_len);
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%d]: %#X %#X %#X %#X %#X %#X %#X %#X %#X %#X\n", __LINE__,
+               send_ptr[0],send_ptr[1],send_ptr[2],send_ptr[3],send_ptr[4],send_ptr[5],send_ptr[6],send_ptr[7],send_ptr[8],send_ptr[9]);
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%d]: %#X %#X %#X %#X %#X %#X %#X %#X %#X %#X\n", __LINE__,
+               send_ptr[10],send_ptr[11],send_ptr[12],send_ptr[13],send_ptr[14],send_ptr[15],send_ptr[16],send_ptr[17],send_ptr[18],send_ptr[19]);
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%d]: %#X %#X %#X %#X %#X %#X %#X %#X %#X %#X\n", __LINE__,
+               send_ptr[20],send_ptr[21],send_ptr[22],send_ptr[23],send_ptr[24],send_ptr[25],send_ptr[26],send_ptr[27],send_ptr[28],send_ptr[29]);
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%d]: %#X %#X %#X %#X %#X %#X %#X %#X %#X %#X\n", __LINE__,
+               send_ptr[30],send_ptr[31],send_ptr[32],send_ptr[33],send_ptr[34],send_ptr[35],send_ptr[36],send_ptr[37],send_ptr[38],send_ptr[39]);
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%d]: %#X %#X %#X %#X %#X %#X %#X %#X %#X %#X\n", __LINE__,
+               send_ptr[40],send_ptr[41],send_ptr[42],send_ptr[43],send_ptr[44],send_ptr[45],send_ptr[46],send_ptr[47],send_ptr[48],send_ptr[49]);
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%d]: %#X %#X %#X %#X %#X %#X %#X %#X %#X %#X\n", __LINE__,
+               send_ptr[50],send_ptr[51],send_ptr[52],send_ptr[53],send_ptr[54],send_ptr[55],send_ptr[56],send_ptr[57],send_ptr[58],send_ptr[59]);
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%d]: %#X %#X %#X %#X %#X %#X %#X %#X %#X %#X\n", __LINE__,
+               send_ptr[60],send_ptr[61],send_ptr[62],send_ptr[63],send_ptr[64],send_ptr[65],send_ptr[66],send_ptr[67],send_ptr[68],send_ptr[69]);
+#endif
+
+       mmi_voicechat_send_tts_text_msg(send_ptr, send_len);
+       s_voicechat_tts_text_sent_size += output_len;
+
+       lv_mem_free(send_ptr);
+       send_ptr = NULL;
+}
+
+void mmi_voicechat_send_tts_text_action_pre(void)
+{
+       uint32_t node_total = mmi_voicechat_tts_audio_ll_node_num();
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: node_total=%d\n", __FUNCTION__, __LINE__, node_total);
+       
+       uint32_t data_len = 0;
+       char * data_ptr = mmi_voicechat_chat_result_text_get(&data_len);
+
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: data_len=%d,sent_len=%d\n", __FUNCTION__, __LINE__, data_len, s_voicechat_tts_text_sent_size);
+       if((NULL != data_ptr) && (data_len > s_voicechat_tts_text_sent_size))
+       {
+               //mmi_voicechat_tts_audio_ll_new_tail_node();
+               
+               mmi_voicechat_send_tts_text_action(data_ptr + s_voicechat_tts_text_sent_size, data_len - s_voicechat_tts_text_sent_size);
+       }
+}
+
+void mmi_voicechat_tts_audio_download_requst(void)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+
+       s_voicechat_tts_text_sent_size = 0;
+       s_voicechat_tts_audio_playing = false;
+       mmi_voicechat_tts_audio_ll_clean();
+       mmi_voicechat_tts_audio_ll_new_tail_node();
+       mmi_voicechat_send_tts_text_action_pre();
+}
+
+
+void mmi_voicechat_tts_audio_ll_init(void)
+{
+       _lv_ll_init(&s_voicechat_tts_audio_ll, sizeof(mmi_voicechat_tts_audio_ll_t));
+       _lv_ll_clear(&s_voicechat_tts_audio_ll);
+}
+
+void mmi_voicechat_tts_audio_ll_clean(void)
+{
+       mmi_voicechat_tts_audio_ll_t * node = NULL;
+    for(node = _lv_ll_get_head(&s_voicechat_tts_audio_ll); NULL != node; node = _lv_ll_get_next((&s_voicechat_tts_audio_ll), node))
+       {
+        if(NULL != node->audio_data_ptr)
+       {
+                       lv_mem_free(node->audio_data_ptr);
+                       node->audio_data_ptr = NULL;
+               }
+    }
+
+       _lv_ll_clear(&s_voicechat_tts_audio_ll);
+}
+
+uint32_t mmi_voicechat_tts_audio_ll_node_num(void)
+{
+       uint32_t node_total = _lv_ll_get_len(&s_voicechat_tts_audio_ll);
+       
+       //VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: node_total=%d\n", __FUNCTION__, __LINE__, node_total);
+       return node_total;
+}
+
+mmi_voicechat_tts_audio_ll_t * mmi_voicechat_tts_audio_ll_new_tail_node(void)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       
+    mmi_voicechat_tts_audio_ll_t * node = _lv_ll_ins_tail(&s_voicechat_tts_audio_ll);
+       
+       node->audio_data_ptr = NULL;
+       node->audio_data_size = 0;
+       
+       return node;
+}
+
+bool mmi_voicechat_tts_audio_store(char * data_buff, uint32_t data_len)
+{
+       if(NULL == data_buff || 0 == data_len)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+               return false;
+       }
+
+       mmi_voicechat_tts_audio_ll_t * node = _lv_ll_get_tail(&s_voicechat_tts_audio_ll);
+       if(NULL == node)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+               return false;
+       }       
+
+       if(NULL == node->audio_data_ptr)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+               char * temp_ptr = lv_mem_alloc(data_len + 1);
+               if(NULL == temp_ptr)
+               {
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: alloc memory fail\n", __FUNCTION__, __LINE__);
+                       return false;
+               }
+               _lv_memset_00(temp_ptr, data_len + 1);
+               _lv_memcpy(temp_ptr, data_buff, data_len);
+
+               node->audio_data_ptr = temp_ptr;
+               node->audio_data_size = data_len;
+       }
+       else
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+               char * temp_ptr = lv_mem_realloc(node->audio_data_ptr, node->audio_data_size + data_len + 1);
+               if(NULL == temp_ptr)
+               {
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: realloc memory fail\n", __FUNCTION__, __LINE__);
+                       return false;
+               }
+               _lv_memset_00(temp_ptr + node->audio_data_size, data_len + 1);
+               _lv_memcpy(temp_ptr + node->audio_data_size, data_buff, data_len);
+
+               node->audio_data_ptr = temp_ptr;
+               node->audio_data_size += data_len;
+       }
+
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: size=%d,ptr=0x%x\n", __FUNCTION__, __LINE__, node->audio_data_size, node->audio_data_ptr);
+
+       return true;
+}
+
+void mmi_voicechat_tts_audio_ctrl_callback(AUDIO_CTRL_PRIORITY priority)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: priority=%d\n", __FUNCTION__, __LINE__, priority);
+       
+    if(MMI_VOICECHAT_TTS_AUDIO_PRI == priority)
+       {
+
+    }
+       else if(MMI_VOICECHAT_TTS_AUDIO_PRI > priority)
+       {
+               // wb
+               mmi_voicechat_tts_websocket_close();
+               
+               // res
+               mmi_voicechat_tts_audio_ll_clean();
+       
+               Hal_NFFS_File_Play_End();
+               Hal_Audio_Manage_End_Ind(MMI_VOICECHAT_TTS_AUDIO_PRI);
+    }
+}
+
+static void mmi_voicechat_tts_audio_over_cb(void * para)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+
+       s_voicechat_tts_audio_playing = false;
+       
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: node=%#X,total=%d\n", __FUNCTION__, __LINE__, s_voicechat_tts_audio_play_node, mmi_voicechat_tts_audio_ll_node_num());
+       mmi_voicechat_tts_audio_ll_t * node = _lv_ll_get_next((&s_voicechat_tts_audio_ll), s_voicechat_tts_audio_play_node);
+       _lv_ll_remove((&s_voicechat_tts_audio_ll), s_voicechat_tts_audio_play_node);
+       if(NULL != s_voicechat_tts_audio_play_node->audio_data_ptr)
+       {
+               lv_mem_free(s_voicechat_tts_audio_play_node->audio_data_ptr);
+               s_voicechat_tts_audio_play_node->audio_data_ptr = NULL;
+       }
+       lv_mem_free(s_voicechat_tts_audio_play_node);
+       s_voicechat_tts_audio_play_node = NULL;
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: node=%#X,total=%d\n", __FUNCTION__, __LINE__, node, mmi_voicechat_tts_audio_ll_node_num());
+
+       // get tts
+       //mmi_voicechat_send_tts_text_action_pre();
+       
+       if(MMI_VOICECHAT_TTS_AUDIO_PRI == Hal_Audio_Manage_Start_Req(MMI_VOICECHAT_TTS_AUDIO_PRI, mmi_voicechat_tts_audio_ctrl_callback))
+       {
+               if(NULL == node || NULL == node->audio_data_ptr)
+               {
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+                       return ;
+               }
+               s_voicechat_tts_audio_play_node = node;
+               s_voicechat_tts_audio_playing = true;
+
+               Hal_Tone_Play_Onetime((uint32_t *)node->audio_data_ptr,
+                                                               node->audio_data_size,
+                                                               HAL_AUDIO_SPK_LEVEL_MAX,
+                                                               mmi_voicechat_tts_audio_over_cb,
+                                                               NULL);  
+       }
+}
+
+bool mmi_voicechat_tts_audio_play(void)
+{
+       if(true == s_voicechat_tts_audio_playing)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+               return false;
+       }
+       
+       if(MMI_VOICECHAT_TTS_AUDIO_PRI == Hal_Audio_Manage_Start_Req(MMI_VOICECHAT_TTS_AUDIO_PRI, mmi_voicechat_tts_audio_ctrl_callback))
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+               
+               mmi_voicechat_tts_audio_ll_t * node = _lv_ll_get_head(&s_voicechat_tts_audio_ll);
+               if(NULL == node)
+               {
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: tt audio ll empty\n", __FUNCTION__, __LINE__);
+                       return false;
+               }
+               else
+               {
+                       if(NULL == node->audio_data_ptr)
+                       {
+                   node = _lv_ll_get_next((&s_voicechat_tts_audio_ll), node);
+                               if(NULL == node || NULL == node->audio_data_ptr)
+                               {
+                                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: no data\n", __FUNCTION__, __LINE__);
+#if 0
+{
+       uint32_t node_total = mmi_voicechat_tts_audio_ll_node_num();
+       uint8_t i = 0;
+       mmi_voicechat_tts_audio_ll_t * node = _lv_ll_get_head(&s_voicechat_tts_audio_ll);
+       
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: node_total=%d\n", __FUNCTION__, __LINE__, node_total);
+       for(i = 0; i < node_total; i++)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: %d,%#X,%#X\n", __FUNCTION__, __LINE__, i, node, node->audio_data_ptr);
+               
+               node = _lv_ll_get_next((&s_voicechat_tts_audio_ll), node);
+       }
+}
+#endif
+                                       return false;
+                               }
+                       }
+               }
+               s_voicechat_tts_audio_play_node = node;
+               s_voicechat_tts_audio_playing = true;
+
+               Hal_Tone_Play_Onetime((uint32_t *)node->audio_data_ptr,
+                                                               node->audio_data_size,
+                                                               HAL_AUDIO_SPK_LEVEL_MAX,
+                                                               mmi_voicechat_tts_audio_over_cb,
+                                                               NULL);  
+       }
+
+       return true;
+}
+
+void mmi_voicechat_tts_end_synthesis_action(void)
+{
+       mmi_voicechat_tts_audio_ll_new_tail_node();
+       mmi_voicechat_send_tts_text_action_pre();
+       
+       // 
+       mmi_voicechat_tts_audio_play();
+}
+
+
+void mmi_voicechat_list_screen_prompt_clean_task_cb(lv_task_t * task)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       
+       lv_voicechat_ext_t * ext = (lv_voicechat_ext_t *)mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+       if(NULL == ext) 
+               return ;
+
+       lv_obj_set_hidden(ext->list_signal_weak_label, true);
+}
+
+void mmi_voicechat_list_screen_prompt_task_cb(lv_task_t * task)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       
+       lv_voicechat_ext_t * ext = (lv_voicechat_ext_t *)mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+       if(NULL == ext) 
+               return ;
+
+       lv_obj_set_hidden(ext->list_signal_weak_label, false);
+
+       lv_task_t * task_p = lv_task_create(mmi_voicechat_list_screen_prompt_clean_task_cb, 1500, LV_TASK_PRIO_HIGH, NULL);
+       lv_task_once(task_p);
+}
+
+void mmi_voicechat_list_screen_signal_weak_prompt(void)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+
+       if(MMI_VOICECHAT_UI_STATE_LIST != s_voicechat_ui_state)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+               return;
+       }
+       
+    lv_task_t * task_p = lv_task_create(mmi_voicechat_list_screen_prompt_task_cb, 10, LV_TASK_PRIO_HIGH, NULL);
+       lv_task_once(task_p);
+}
+
+void * mmi_voicechat_actId_ext_get(lv_watch_Activity_Id_t actId)
+{
+       lv_obj_t * activity_obj = lv_watch_get_activity_obj(actId);
+       if(NULL == activity_obj) 
+               return NULL;
+       
+       lv_obj_t * watch_obj = NULL;
+       lv_watch_get_child_obj(activity_obj, lv_watch_obj_signal, &watch_obj);
+       if(NULL != watch_obj) 
+       {
+               void * ext = lv_obj_get_ext_attr(watch_obj);
+               return ext;
+       }
+
+       return NULL;
+}
+
+static void mmi_voicechat_lv_style_reset(void)
+{
+       lv_voicechat_ext_t * ext = mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+       if(NULL == ext)
+               return;
+
+       lv_style_reset(&(ext->style_cont_self));
+       lv_style_reset(&(ext->style_cont_other));
+       //lv_style_reset(&(ext->style_label_time));
+       lv_style_reset(&(ext->style_label_len_self));
+       lv_style_reset(&(ext->style_label_len_other));
+}
+
+static void mmi_voicechat_lv_style_set(void)
+{
+       lv_voicechat_ext_t * ext = mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+       if(NULL == ext)
+               return;
+
+       //lv_style_init(&(ext->style_label_time));
+       //lv_style_copy(&(ext->style_label_time), &lv_watch_font20);
+       //lv_style_set_text_color(&(ext->style_label_time), LV_STATE_DEFAULT, lv_color_make(20, 187, 242));
+
+       lv_style_init(&(ext->style_label_len_other));
+       lv_style_copy(&(ext->style_label_len_other), &lv_watch_font20);
+       lv_style_set_text_color(&(ext->style_label_len_other), LV_STATE_DEFAULT, LV_COLOR_WHITE);
+
+       lv_style_init(&(ext->style_label_len_self));
+       lv_style_copy(&(ext->style_label_len_self), &lv_watch_font20);
+       lv_style_set_text_color(&(ext->style_label_len_self), LV_STATE_DEFAULT, LV_COLOR_WHITE);
+
+       lv_style_init(&(ext->style_cont_self));
+       lv_style_set_bg_color(&(ext->style_cont_self), LV_STATE_DEFAULT, LV_COLOR_MAKE(79, 195, 76)); // LV_COLOR_MAKE(175, 242, 89));
+       lv_style_set_radius(&(ext->style_cont_self), LV_STATE_DEFAULT, 15); // 30
+       lv_style_set_pad_top(&(ext->style_cont_self), LV_STATE_DEFAULT, 10); // 8
+       lv_style_set_pad_bottom(&(ext->style_cont_self), LV_STATE_DEFAULT, 10); // 8
+       lv_style_set_pad_left(&(ext->style_cont_self), LV_STATE_DEFAULT, 5); // 8
+       lv_style_set_pad_right(&(ext->style_cont_self), LV_STATE_DEFAULT, 5); // 8
+
+       lv_style_init(&(ext->style_cont_other));
+       lv_style_set_bg_color(&(ext->style_cont_other), LV_STATE_DEFAULT, LV_COLOR_MAKE(25, 25, 25)); // LV_COLOR_MAKE(0xE2, 0xBD, 0xFF));
+       lv_style_set_radius(&(ext->style_cont_other), LV_STATE_DEFAULT, 15);
+       lv_style_set_pad_top(&(ext->style_cont_other), LV_STATE_DEFAULT, 10);
+       lv_style_set_pad_bottom(&(ext->style_cont_other), LV_STATE_DEFAULT, 10);
+       lv_style_set_pad_left(&(ext->style_cont_other), LV_STATE_DEFAULT, 5);
+       lv_style_set_pad_right(&(ext->style_cont_other), LV_STATE_DEFAULT, 5);
+}
+
+void mmi_voicechat_main_prepare_destory(lv_obj_t * activity_obj)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+
+       // websocket
+       mmi_voicechat_trans_websocket_close();
+       mmi_voicechat_chat_websocket_close();
+       mmi_voicechat_tts_websocket_close();
+
+       // data task
+       mmi_voicechat_data_task_delete();
+       watch_set_suspend_enable(true, ACT_ID_VOICECHAT_MAIN, 0);
+
+       // free resource
+       mmi_voicechat_msg_data_clean();
+       mmi_voicechat_tts_audio_ll_clean();
+       
+       // audio
+       mmi_voicechat_listening_stop(true);
+       Hal_NFFS_File_Play_End();
+       Hal_Audio_Manage_End_Ind(MMI_VOICECHAT_TTS_AUDIO_PRI);
+       //Hal_Vibrator_Play_End();
+       
+    lv_watch_png_cache_all_free();
+       mmi_voicechat_lv_style_reset();
+
+       lv_voicechat_ext_t * ext = mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+       if(NULL == ext) 
+               return ;
+
+       if(NULL != ext->record_buffer)
+       {
+               lv_mem_free(ext->record_buffer);
+               ext->record_buffer = NULL;
+       }
+       
+       if(NULL != ext->thinking_task_p)
+       {
+               lv_task_del(ext->thinking_task_p);
+               ext->thinking_task_p = NULL;
+       }
+       if(NULL != ext->gif_listening)
+       {
+               gif_close(ext->gif_listening);
+               ext->gif_listening = NULL;
+       }
+       if(NULL != ext->gif_thinking)
+       {
+               gif_close(ext->gif_thinking);
+               ext->gif_thinking = NULL;
+       }
+
+#ifdef __MMI_ZHSX_SUPPORT__
+       s_is_ACT_ID_VOICECHAT_MAIN = false;
+#endif
+}
+
+void mmi_voicechat_main_screen_clean(void)
+{
+       mmi_voicechat_main_prepare_destory(NULL);
+
+       lv_obj_t * obj = lv_watch_get_activity_obj(ACT_ID_VOICECHAT_MAIN);
+       if(NULL != obj)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+               lv_obj_del(obj);
+       }
+}
+
+static void mmi_voicechat_list_set_slide_enable(lv_watch_obj_ext_t * ext, bool enable)
+{
+    if(enable) 
+       {
+        ext->slide_enable = 1; /*enable to slide to the right*/
+    } 
+       else 
+       {
+        ext->slide_enable = 0; /*disable to slide to the right*/
+    }
+}
+
+void mmi_voicechat_timeout_screen_clean(void)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+
+       mmi_voicechat_default_screen_display();
+}
+
+void mmi_voicechat_timeout_screen_display(void)
+{      
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       
+       lv_voicechat_ext_t * ext = (lv_voicechat_ext_t *)mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+       if(NULL == ext) 
+               return ;
+
+       s_voicechat_ui_state = MMI_VOICECHAT_UI_STATE_CONNECT_TIMEOUT;
+
+       if(NULL != ext->thinking_task_p)
+       {
+               lv_task_del(ext->thinking_task_p);
+               ext->thinking_task_p = NULL;
+       }
+
+
+       // ui
+       lv_obj_t * cont = ext->cont_timeout;
+       
+       //label
+       lv_obj_t * label_state = lv_label_create(cont, NULL);
+       lv_obj_add_style(label_state, LV_LABEL_PART_MAIN, &lv_watch_font20);
+       lv_label_set_text_id(label_state, WATCH_TEXT_ID_VOICECHAT);
+       lv_label_set_align(label_state, LV_LABEL_ALIGN_CENTER);
+       lv_obj_align(label_state, NULL, LV_ALIGN_IN_TOP_MID, 0, 20);
+
+       lv_obj_t * img = lv_img_create(cont, NULL);
+       lv_img_set_src(img, ICON_VOICECHAT_PROMPT);
+       lv_obj_set_click(img, false);
+       lv_obj_align(img, NULL, LV_ALIGN_IN_TOP_MID, 0, 70);
+       
+       lv_obj_t * label = lv_label_create(cont, NULL);
+       lv_obj_add_style(label, LV_LABEL_PART_MAIN, &lv_watch_font20);
+       lv_label_set_text_id(label, WATCH_TEXT_ID_AIGC_CONNECT_TIMEOUT);
+       lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
+       lv_obj_align(label, img, LV_ALIGN_OUT_BOTTOM_MID, 0, 25);
+
+       lv_obj_t * imgbtn = lv_imgbtn_create(cont, NULL);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_RELEASED, ICON_VOICECHAT_RECORD_BUTTON_PRESSED);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_PRESSED, ICON_VOICECHAT_RECORD_BUTTON_PRESSED);
+       lv_obj_set_event_cb(imgbtn, mmi_voicechat_record_button_event_cb);
+    lv_obj_add_protect(imgbtn, LV_PROTECT_PRESS_LOST);
+       lv_watch_obj_add_element(imgbtn);
+       lv_obj_align(imgbtn, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, -20);
+
+       lv_obj_t * imgbtn_label = lv_label_create(imgbtn, NULL);
+       lv_obj_add_style(imgbtn_label, LV_LABEL_PART_MAIN, &lv_watch_font26);
+       lv_label_set_align(imgbtn_label, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(imgbtn_label, WATCH_TEXT_ID_OK);
+       lv_obj_align(imgbtn_label, NULL, LV_ALIGN_CENTER, 0, 0);        
+
+       lv_obj_set_hidden(ext->cont_default, true);
+       lv_obj_set_hidden(ext->cont_listening, true);
+       lv_obj_set_hidden(ext->cont_listening_middle, true);
+       lv_obj_set_hidden(ext->cont_thinking, true);
+       lv_obj_set_hidden(ext->cont_timeout, false);
+       lv_obj_set_hidden(ext->cont_list, true);
+}
+
+void mmi_voicechat_thinking_screen_clean(void)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       
+       mmi_voicechat_chat_websocket_close();
+       
+       lv_voicechat_ext_t * ext = (lv_voicechat_ext_t *)mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+       if(NULL == ext) 
+               return ;
+
+       if(NULL != ext->thinking_task_p)
+       {
+               lv_task_del(ext->thinking_task_p);
+               ext->thinking_task_p = NULL;
+       }
+
+       mmi_voicechat_default_screen_display();
+}
+
+static void mmi_voicechat_thinking_screen_task_cb(lv_task_t * task)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       
+       mmi_voicechat_timeout_screen_display();
+}
+
+void mmi_voicechat_listening_remain_data_send(void)
+{
+#if 0
+       lv_voicechat_ext_t * ext = (lv_voicechat_ext_t *)mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+       if(NULL == ext) 
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+               goto EXIT;
+       }
+
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: size=%d, buf=0x%x\n", __FUNCTION__, __LINE__, ext->record_size, ext->record_buffer);
+
+       int file_size = ext->record_size - s_voicechat_recording_sent_size;
+       if(0 >= file_size)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+               goto EXIT;
+       }
+    char * file_buf = lv_mem_alloc(file_size + 1);
+       if(NULL == file_buf)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+               goto EXIT;
+    }
+       _lv_memset_00(file_buf, file_size + 1);
+       _lv_memcpy(file_buf, ext->record_buffer + s_voicechat_recording_sent_size, file_size);
+       
+       mmi_voicechat_send_trans_audio_msg(file_buf, file_size);
+       lv_mem_free(file_buf);
+       file_buf = NULL;
+
+EXIT:
+       lv_mem_free(ext->record_buffer);
+       ext->record_buffer = NULL;
+       ext->record_size = 0;
+       
+       s_voicechat_recording_sent_size = 0;    
+#endif
+}
+
+void mmi_voicechat_thinking_screen_display(void)
+{      
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       
+       lv_voicechat_ext_t * ext = (lv_voicechat_ext_t *)mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+       if(NULL == ext) 
+               return ;
+
+       s_voicechat_ui_state = MMI_VOICECHAT_UI_STATE_THINKING;
+
+       //mmi_voicechat_listening_remain_data_send();
+
+       if(NULL != ext->thinking_task_p)
+       {
+               lv_task_del(ext->thinking_task_p);
+               ext->thinking_task_p = NULL;
+       }
+       ext->thinking_task_p = lv_task_create(mmi_voicechat_thinking_screen_task_cb, 60 * 1000, LV_TASK_PRIO_HIGH, NULL);
+       lv_task_once(ext->thinking_task_p);
+
+
+       // ui
+       lv_obj_t * cont = ext->cont_thinking;
+       if(NULL != ext->gif_thinking)
+       {
+               gif_close(ext->gif_thinking);
+               ext->gif_thinking = NULL;
+       }
+       lv_obj_clean(cont);
+       
+       //label
+       lv_obj_t * label_state = lv_label_create(cont, NULL);
+       lv_obj_add_style(label_state, LV_LABEL_PART_MAIN, &lv_watch_font20);
+       lv_label_set_text_id(label_state, WATCH_TEXT_ID_AIGC_THINKING);
+       lv_label_set_align(label_state, LV_LABEL_ALIGN_CENTER);
+       lv_obj_align(label_state, NULL, LV_ALIGN_IN_TOP_MID, 0, 20);
+
+       ext->gif_thinking = gif_open(cont, ANIM_VOICECHAT_THINKING, 0);
+       if(NULL == ext->gif_thinking) 
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: gif open fail\n", __FUNCTION__, __LINE__);
+       }
+       lv_obj_set_style_local_bg_color(ext->gif_thinking->container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
+       lv_obj_align(ext->gif_thinking->container, NULL, LV_ALIGN_CENTER, 0, -10);
+
+       lv_obj_t * imgbtn = lv_imgbtn_create(cont, NULL);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_RELEASED, ICON_VOICECHAT_RECORD_BUTTON_PRESSED);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_PRESSED, ICON_VOICECHAT_RECORD_BUTTON_PRESSED);
+       lv_obj_set_event_cb(imgbtn, mmi_voicechat_record_button_event_cb);
+    lv_obj_add_protect(imgbtn, LV_PROTECT_PRESS_LOST);
+       lv_watch_obj_add_element(imgbtn);
+       lv_obj_align(imgbtn, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, -20);
+
+       lv_obj_t * imgbtn_label = lv_label_create(imgbtn, NULL);
+       lv_obj_add_style(imgbtn_label, LV_LABEL_PART_MAIN, &lv_watch_font26);
+       //lv_obj_set_style_local_text_font(imgbtn_label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_THEME_WATCH_NIGHT_FONT_26);
+       //lv_obj_set_style_local_text_color(imgbtn_label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(253, 82, 19));
+       lv_label_set_align(imgbtn_label, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(imgbtn_label, WATCH_TEXT_ID_CANCEL);
+       lv_obj_align(imgbtn_label, NULL, LV_ALIGN_CENTER, 0, 0);        
+
+       lv_obj_set_hidden(ext->cont_default, true);
+       lv_obj_set_hidden(ext->cont_listening, true);
+       lv_obj_set_hidden(ext->cont_listening_middle, true);
+       lv_obj_set_hidden(ext->cont_thinking, false);
+       lv_obj_set_hidden(ext->cont_timeout, true);
+       lv_obj_set_hidden(ext->cont_list, true);
+}
+
+void mmi_voicechat_listening_middle_screen_display(void)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       
+       lv_voicechat_ext_t * ext = (lv_voicechat_ext_t *)mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+       if(NULL == ext) 
+               return ;
+
+       s_voicechat_ui_state = MMI_VOICECHAT_UI_STATE_LISTENING_MIDDLE;
+       
+       // ui
+       lv_obj_t * cont = ext->cont_listening_middle;
+       if(NULL != ext->gif_listening)
+       {
+               gif_close(ext->gif_listening);
+               ext->gif_listening = NULL;
+       }
+       lv_obj_clean(cont);
+       
+
+       lv_obj_t * list_page = lv_page_create(cont, NULL);
+       lv_obj_set_size(list_page, lv_obj_get_width(cont), lv_obj_get_height(cont) / 2);
+       lv_page_set_scrollbar_mode(list_page, LV_SCROLLBAR_MODE_OFF);
+       lv_obj_set_style_local_bg_opa(list_page, LV_PAGE_PART_BG, LV_STATE_DEFAULT, LV_OPA_0);
+       lv_obj_set_style_local_border_opa(list_page, LV_PAGE_PART_BG, LV_STATE_DEFAULT, LV_OPA_0);
+       lv_obj_set_style_local_outline_width(list_page, LV_PAGE_PART_BG, LV_STATE_DEFAULT, 0);
+       lv_obj_align(list_page, NULL, LV_ALIGN_IN_TOP_MID, 0, 20);
+
+       lv_page_set_scrl_layout(list_page, LV_LAYOUT_OFF);
+       lv_page_set_scrollable_fit2(list_page, LV_FIT_NONE, LV_FIT_TIGHT);
+       
+       lv_obj_t * scrl = lv_page_get_scrollable(list_page);
+       ancient_scrl_signal = lv_obj_get_signal_cb(scrl);
+       lv_obj_set_signal_cb(scrl, mmi_voicechat_list_scrl_signal);
+       lv_watch_obj_add_element(list_page);
+       lv_watch_obj_add_element(scrl);
+
+       
+       mmi_voicechat_msg_item_info_t * t_voicechat_item_info = &(s_voicechat_info_p->msg_item[0]);
+       char * file_buf = t_voicechat_item_info->text_data_ptr;
+
+       lv_obj_t * obj = lv_cont_create(list_page, NULL);
+       lv_obj_set_size(obj, LV_HOR_RES - 20, 50);
+       lv_cont_set_fit4(obj, LV_FIT_NONE, LV_FIT_NONE, LV_FIT_NONE, LV_FIT_TIGHT);
+       //lv_cont_set_layout(obj, LV_LAYOUT_COLUMN_LEFT);
+       lv_obj_add_style(obj, LV_CONT_PART_MAIN, &(ext->style_cont_self));
+       lv_obj_align(obj, NULL, LV_ALIGN_IN_TOP_MID, 0, 20);            
+       
+       lv_obj_t * label_text = lv_label_create(obj, NULL);
+       lv_obj_add_style(label_text, LV_LABEL_PART_MAIN, &(ext->style_label_len_self));
+       lv_label_set_align(label_text, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_long_mode(label_text, LV_LABEL_LONG_BREAK);
+       lv_obj_set_width(label_text, lv_obj_get_width(obj) - 20);
+       lv_label_set_text(label_text, file_buf);
+       lv_obj_align(label_text, NULL, LV_ALIGN_IN_LEFT_MID, 10, 0);
+
+       lv_obj_set_adv_hittest(obj, false);
+       lv_page_focus(list_page, obj, 0);
+       lv_page_glue_obj(obj, true);
+       lv_watch_obj_add_element(obj);
+
+
+       ext->gif_listening = gif_open(cont, ANIM_VOICECHAT_LISTENING, 0);
+       if(NULL == ext->gif_listening) 
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: gif open fail\n", __FUNCTION__, __LINE__);
+       }
+       lv_obj_set_style_local_bg_color(ext->gif_listening->container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
+       lv_obj_align(ext->gif_listening->container, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, -LV_VER_RES / 4);
+
+       //label
+       //lv_obj_t * label_state = lv_label_create(cont, NULL);
+       //lv_obj_add_style(label_state, LV_LABEL_PART_MAIN, &lv_watch_font20);
+       //lv_label_set_text_id(label_state, WATCH_TEXT_ID_AIGC_LISTENING);
+       //lv_label_set_align(label_state, LV_LABEL_ALIGN_CENTER);
+       //lv_obj_align(label_state, cont, LV_ALIGN_IN_BOTTOM_MID, 0, -20);
+
+
+       lv_obj_set_hidden(ext->cont_default, true);
+       lv_obj_set_hidden(ext->cont_listening, true);
+       lv_obj_set_hidden(ext->cont_listening_middle, false);
+       lv_obj_set_hidden(ext->cont_thinking, true);
+       lv_obj_set_hidden(ext->cont_timeout, true);
+       lv_obj_set_hidden(ext->cont_list, true);
+}
+
+bool mmi_voicechat_listening_stop(bool is_cancel)
+{
+       uint32_t duration_ms = 0;
+       uint32_t size = 0;
+       
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       
+       Hal_Record_Buffer_Stop_Req(&size, &duration_ms);
+    Hal_Audio_Manage_End_Ind(MMI_VOICECHAT_TTS_AUDIO_PRI);
+       
+       lv_voicechat_ext_t * ext = (lv_voicechat_ext_t *)mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+       if(NULL == ext) 
+               return false;
+
+       if(true == is_cancel)
+       {
+               printf("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+        lv_mem_free(ext->record_buffer);
+        ext->record_buffer = NULL;
+               ext->record_size = 0;
+        return false;
+    }
+       
+    if(MMI_VOICECHAT_DATA_RECORD_HEAD_SIZE >= size) 
+       {
+               printf("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+        lv_mem_free(ext->record_buffer);
+        ext->record_buffer = NULL;
+               ext->record_size = 0;
+        return false;
+    }
+       ext->record_size = size;
+
+       return true;
+}
+
+void mmi_voicechat_listening_task_cb(lv_task_t * task)
+{
+       lv_voicechat_ext_t * ext = (lv_voicechat_ext_t *)mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+       if(NULL == ext) 
+               return ;
+       
+       if(0 == ext->old_ext.element_click_en) 
+       {
+               /*sliding to the right, not click button*/
+               return;
+       }
+
+       lv_obj_t * activity_obj;
+       MCI_EVNET_T event = (MCI_EVNET_T) (task->user_data);
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: event=%d\n", __FUNCTION__, __LINE__, event);
+       
+       switch(event) 
+       {
+               case MCI_EVENT_EOS:
+                       mmi_voicechat_listening_stop(false);
+                       mmi_voicechat_thinking_screen_display();
+                       break;
+                       
+               case MCI_EVENT_ERROR:
+                       mmi_voicechat_listening_stop(true);
+                       mmi_voicechat_main_screen_clean();
+                       break;
+                       
+               //case MCI_EVENT_INFO:
+               //      break;
+                       
+               default:
+                       break;
+       }
+}
+
+void mmi_voicechat_listening_cb(MCI_EVNET_T event, MCI_INFO_T info_type, int32_t value)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: event=%d,type=%d,value=%d\n", __FUNCTION__, __LINE__, event, info_type, value);
+
+    if(MCI_EVENT_INFO != event) 
+       {
+        //recording_ext->event = event;
+           lv_task_t * record_task = lv_task_create(mmi_voicechat_listening_task_cb, 10, LV_TASK_PRIO_HIGH, event);
+       lv_task_once(record_task);
+    }
+       else // MCI_EVENT_INFO == event
+       {
+               if(MCI_INFO_RECORDER_CUR_SIZE == info_type)
+               {
+                       lv_voicechat_ext_t * ext = (lv_voicechat_ext_t *)mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+                       if(NULL == ext) 
+                       {
+                               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+                               return;
+                       }
+                       
+                       uint32_t sending_size = value - s_voicechat_recording_sent_size;
+                       if(0 >= sending_size)
+                       {
+                               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+                               return;
+                       }
+                       
+                       char * sending_buf = lv_mem_alloc(sending_size + 1);
+                       if(NULL == sending_buf)
+                       {
+                               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+                               return;
+                       }
+                       _lv_memset_00(sending_buf, sending_size + 1);
+                       _lv_memcpy(sending_buf, ext->record_buffer + s_voicechat_recording_sent_size, sending_size);
+                       
+                       mmi_voicechat_send_trans_audio_msg(sending_buf, sending_size);                  
+                       lv_mem_free(sending_buf);
+                       s_voicechat_recording_sent_size += sending_size;
+               }
+       }
+}
+
+void mmi_voicechat_listening_audio_ctrl_callback(AUDIO_CTRL_PRIORITY priority)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: priority=%d\n", __FUNCTION__, __LINE__, priority);
+       
+    if(MMI_VOICECHAT_TTS_AUDIO_PRI == priority)
+    {
+        if(false == watch_is_ready()) 
+               {
+            return;
+        }
+    }
+    else if(MMI_VOICECHAT_TTS_AUDIO_PRI > priority)
+    {
+               mmi_voicechat_listening_stop(true);
+               mmi_voicechat_main_screen_clean();
+    }
+}
+
+void mmi_voicechat_listening_screen_display(void)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       
+       lv_voicechat_ext_t * ext = (lv_voicechat_ext_t *)mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+       if(NULL == ext) 
+               return ;
+
+       s_voicechat_ui_state = MMI_VOICECHAT_UI_STATE_LISTENING;
+
+       s_voicechat_trans_text_end = false;
+       
+       // stop audio
+       Hal_NFFS_File_Play_End();
+       Hal_Audio_Manage_End_Ind(MMI_VOICECHAT_TTS_AUDIO_PRI);
+       
+       // wb
+       mmi_voicechat_tts_websocket_close();
+       mmi_voicechat_trans_websocket_open();
+       
+       // res
+       mmi_voicechat_msg_data_clean(); 
+       mmi_voicechat_tts_audio_ll_clean();
+
+       if(NULL != ext->record_buffer)
+       {
+               lv_mem_free(ext->record_buffer);
+               ext->record_buffer = NULL;
+       }
+       ext->record_buffer = (uint8_t *)lv_mem_alloc(MMI_VOICECHAT_DATA_RECORD_SIZE_MAX);
+       if(NULL != ext->record_buffer)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+               
+               _lv_memset_00(ext->record_buffer, MMI_VOICECHAT_DATA_RECORD_SIZE_MAX);
+
+               if(MMI_VOICECHAT_TTS_AUDIO_PRI == Hal_Audio_Manage_Start_Req(MMI_VOICECHAT_TTS_AUDIO_PRI, mmi_voicechat_listening_audio_ctrl_callback))
+               {
+                       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+
+                       mmi_voicechat_send_trans_start_msg(NULL, 0);
+                       
+                       s_voicechat_recording_sent_size = 0;
+                       Hal_Record_Buffer_With_Format_Req(ext->record_buffer,
+                                                                               MMI_VOICECHAT_DATA_RECORD_SIZE_MAX,
+                                                                               MMI_VOICECHAT_DATA_RECORD_DURATION_MAX * 1000,
+                                                                               mmi_voicechat_listening_cb,
+                                                                               (mci_type_enum)MMI_VOICECHAT_AUDIO_FORMAT);
+               }
+       }
+       
+       // ui
+       lv_obj_t * cont = ext->cont_listening;
+       if(NULL != ext->gif_listening)
+       {
+               gif_close(ext->gif_listening);
+               ext->gif_listening = NULL;
+       }
+       lv_obj_clean(cont);
+       
+       //label
+       lv_obj_t * label_state = lv_label_create(cont, NULL);
+       lv_obj_add_style(label_state, LV_LABEL_PART_MAIN, &lv_watch_font20);
+       lv_label_set_text_id(label_state, WATCH_TEXT_ID_AIGC_LISTENING);
+       lv_label_set_align(label_state, LV_LABEL_ALIGN_CENTER);
+       lv_obj_align(label_state, cont, LV_ALIGN_IN_TOP_MID, 0, 20);
+
+       ext->gif_listening = gif_open(cont, ANIM_VOICECHAT_LISTENING, 0);
+       if(NULL == ext->gif_listening) 
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: gif open fail\n", __FUNCTION__, __LINE__);
+       }
+       lv_obj_set_style_local_bg_color(ext->gif_listening->container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
+       lv_obj_align(ext->gif_listening->container, NULL, LV_ALIGN_CENTER, 0, 0);
+
+       // signal weak
+       lv_obj_t * label = lv_label_create(cont, NULL);
+       lv_obj_add_style(label, LV_OBJ_PART_MAIN, &lv_watch_font26);
+       lv_label_set_text_id(label, WATCH_TEXT_ID_SIGNAL_WEAK);
+       lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
+       lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, -10);
+       lv_obj_set_click(label, false);
+       ext->listening_signal_weak_label = label;
+
+       lv_obj_set_hidden(ext->cont_default, true);
+       lv_obj_set_hidden(ext->cont_listening, false);
+       lv_obj_set_hidden(ext->listening_signal_weak_label, true);
+       lv_obj_set_hidden(ext->cont_listening_middle, true);
+       lv_obj_set_hidden(ext->cont_thinking, true);
+       lv_obj_set_hidden(ext->cont_timeout, true);
+       lv_obj_set_hidden(ext->cont_list, true);
+}
+
+static void mmi_voicechat_cancel_button_event_cb(lv_obj_t * obj, lv_event_t e)
+{      
+       if(LV_EVENT_CLICKED != e)
+               return;
+       
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+
+       mmi_voicechat_main_screen_clean();      
+}
+
+static void mmi_voicechat_record_button_event_cb(lv_obj_t * obj, lv_event_t e)
+{      
+       if(LV_EVENT_CLICKED != e)
+               return;
+       
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: ui_state=%d\n", __FUNCTION__, __LINE__, s_voicechat_ui_state);
+
+       switch(s_voicechat_ui_state)
+       {
+               case MMI_VOICECHAT_UI_STATE_NONE:
+                       mmi_voicechat_listening_screen_display();
+                       break;
+                       
+               case MMI_VOICECHAT_UI_STATE_OPEN_FAIL:
+                       mmi_voicechat_main_screen_clean();
+                       break;
+
+               //case MMI_VOICECHAT_UI_STATE_LISTENING:
+                       //mmi_voicechat_listening_stop(false);
+                       //mmi_voicechat_thinking_screen_display();
+                       //break;
+
+               case MMI_VOICECHAT_UI_STATE_THINKING:
+                       mmi_voicechat_thinking_screen_clean();
+                       break;
+
+               case MMI_VOICECHAT_UI_STATE_CONNECT_TIMEOUT:
+                       mmi_voicechat_timeout_screen_clean();
+                       break;
+
+               case MMI_VOICECHAT_UI_STATE_LIST:
+                       mmi_voicechat_listening_screen_display();
+                       break;
+
+               default:
+                       break;
+       }
+}
+
+lv_obj_t * mmi_voicechat_list_msg_item_add(lv_obj_t * list_page, mmi_voicechat_msg_item_info_t * msg_item, char * time_str, uint8_t i)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       
+       lv_obj_t * obj = NULL;
+       //lv_wechat_msg_list_item_ext_t * list_item_ext = NULL;
+       //lv_voicechat_list_ext_t * list_page_ext = lv_obj_get_ext_attr(list_page);
+       lv_voicechat_ext_t * ext = mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+       lv_obj_t * scrl = lv_page_get_scrl(list_page);
+       lv_obj_t * last_obj = lv_obj_get_child(scrl, NULL);
+       lv_coord_t obj_y = 0;
+       
+       if(NULL != last_obj) 
+       {
+               obj_y = lv_obj_get_y(last_obj) + lv_obj_get_height(last_obj) + lv_obj_get_style_pad_inner(scrl, LV_STATE_DEFAULT);
+       }
+       else
+       {
+               obj_y = lv_obj_get_style_pad_top(scrl, LV_STATE_DEFAULT);
+       }
+
+       uint32_t file_size = msg_item->text_data_size;
+       char * file_buf = msg_item->text_data_ptr;
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: y=%d,size=%d\n", __FUNCTION__, __LINE__, obj_y, file_size);
+       
+       if(0 == msg_item->msg_from) // self
+       {
+               obj = lv_cont_create(list_page, NULL);
+               //list_item_ext = lv_obj_allocate_ext_attr(obj, sizeof(lv_wechat_msg_list_item_ext_t));
+               //list_item_ext->item_index = i;
+               //list_item_ext->unread_img = NULL;
+               lv_obj_set_size(obj, lv_obj_get_width(list_page) - 40, 50); //lv_obj_set_size(obj, LV_HOR_RES * 2 / 3, 50); // same with voice item
+               lv_cont_set_fit4(obj, LV_FIT_NONE, LV_FIT_NONE, LV_FIT_NONE, LV_FIT_TIGHT);
+               //lv_cont_set_layout(obj, LV_LAYOUT_COLUMN_LEFT);
+               lv_obj_add_style(obj, LV_CONT_PART_MAIN, &(ext->style_cont_self));
+               lv_obj_align(obj, scrl, LV_ALIGN_IN_TOP_RIGHT, -10, obj_y);                     
+               
+               lv_obj_t * label_text = lv_label_create(obj, NULL);
+               lv_obj_add_style(label_text, LV_LABEL_PART_MAIN, &(ext->style_label_len_self));
+               lv_label_set_align(label_text, LV_LABEL_ALIGN_LEFT); // LV_LABEL_ALIGN_CENTER);
+               lv_label_set_long_mode(label_text, LV_LABEL_LONG_BREAK);
+               lv_obj_set_width(label_text, lv_obj_get_width(obj) - 20);
+               lv_label_set_text(label_text, file_buf);
+               lv_obj_align(label_text, obj, LV_ALIGN_IN_LEFT_MID, 10, 0);
+       }
+       else
+       {
+               obj = lv_cont_create(list_page, NULL);
+               //list_item_ext = lv_obj_allocate_ext_attr(obj, sizeof(lv_wechat_msg_list_item_ext_t));
+               //list_item_ext->item_index = i;
+               //list_item_ext->unread_img = NULL;
+           lv_obj_set_size(obj, lv_obj_get_width(list_page) - 40, 50); //lv_obj_set_size(obj, LV_HOR_RES * 2 / 3, 50); // same with voice item
+               lv_cont_set_fit4(obj, LV_FIT_NONE, LV_FIT_NONE, LV_FIT_NONE, LV_FIT_TIGHT);
+               //lv_cont_set_layout(obj, LV_LAYOUT_COLUMN_LEFT);
+               lv_obj_add_style(obj, LV_CONT_PART_MAIN, &(ext->style_cont_other));
+               lv_obj_align(obj, scrl, LV_ALIGN_IN_TOP_LEFT, 10, obj_y);                       
+
+               lv_obj_t * label_text = lv_label_create(obj, NULL);
+               lv_obj_add_style(label_text, LV_LABEL_PART_MAIN, &(ext->style_label_len_other));
+               lv_label_set_align(label_text, LV_LABEL_ALIGN_LEFT); // LV_LABEL_ALIGN_CENTER);
+               lv_label_set_long_mode(label_text, LV_LABEL_LONG_BREAK);
+               lv_obj_set_width(label_text, lv_obj_get_width(obj) - 20);
+               lv_label_set_text(label_text, file_buf);
+               lv_obj_align(label_text, obj, LV_ALIGN_IN_LEFT_MID, 10, 0);
+               ext->list_other_label = label_text;
+
+               //if(lv_obj_get_width(list_page) <= (lv_obj_get_y(obj) + lv_obj_get_height(obj)))
+               //{
+               //      lv_obj_align(obj, scrl, LV_ALIGN_IN_BOTTOM_LEFT, 10, -10);              
+               //}
+       }
+
+       //lv_obj_set_click(obj, true);
+       //lv_obj_set_event_cb(obj, wechat_chat_list_text_item_event_cb);
+       lv_obj_set_adv_hittest(obj, false);
+       lv_page_focus(list_page, obj, 0);
+       lv_page_glue_obj(obj, true);
+       lv_watch_obj_add_element(obj);
+       
+       return obj;
+}
+
+static lv_res_t mmi_voicechat_list_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param)
+{
+    lv_res_t res;
+
+    /* Include the ancient signal function */
+    res = ancient_scrl_signal(scrl, sign, param);
+    if(res != LV_RES_OK) 
+               return res;
+
+    if(LV_SIGNAL_COORD_CHG == sign) 
+       {
+        lv_obj_t * list_page = lv_obj_get_parent(scrl);
+               lv_voicechat_list_ext_t * list_page_ext = (lv_voicechat_list_ext_t *)lv_obj_get_ext_attr(list_page);
+               if(NULL == list_page_ext)
+                       return;
+
+        if(true == list_page_ext->pressing) 
+               {
+            list_page_ext->pressing = false;
+        }
+    }
+
+    return LV_RES_OK;
+}
+
+lv_obj_t * mmi_voicechat_list_create(lv_obj_t * obj)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       
+       lv_obj_t * list_page = lv_page_create(obj, NULL);
+       lv_voicechat_list_ext_t * list_page_ext = lv_obj_allocate_ext_attr(list_page, sizeof(lv_voicechat_list_ext_t));
+       if(NULL == list_page_ext)
+               return NULL;
+       
+       //lv_obj_set_size(list_page, lv_obj_get_width(obj) - 20, lv_obj_get_height(obj) - 20 - 80);
+       lv_obj_set_size(list_page, lv_obj_get_width(obj), lv_obj_get_height(obj) - 20 - 80);
+       lv_page_set_scrollbar_mode(list_page, LV_SCROLLBAR_MODE_OFF);
+       //lv_list_set_scrollbar_mode(list_page, LV_SCROLLBAR_MODE_AUTO);
+       lv_obj_set_style_local_bg_opa(list_page, LV_PAGE_PART_BG, LV_STATE_DEFAULT, LV_OPA_0);
+       lv_obj_set_style_local_border_opa(list_page, LV_PAGE_PART_BG, LV_STATE_DEFAULT, LV_OPA_0);
+       lv_obj_set_style_local_outline_width(list_page, LV_PAGE_PART_BG, LV_STATE_DEFAULT, 0);
+       lv_obj_align(list_page, NULL, LV_ALIGN_IN_TOP_MID, 0, 20);
+
+       lv_page_set_scrl_layout(list_page, LV_LAYOUT_OFF);
+       lv_page_set_scrollable_fit2(list_page, LV_FIT_NONE, LV_FIT_TIGHT);
+       
+       lv_obj_t * scrl = lv_page_get_scrollable(list_page);
+       ancient_scrl_signal = lv_obj_get_signal_cb(scrl);
+       lv_obj_set_signal_cb(scrl, mmi_voicechat_list_scrl_signal);
+
+       lv_watch_obj_add_element(list_page);
+       lv_watch_obj_add_element(scrl);
+
+       //_lv_memset_00(&(list_page_ext->voice_playing_anim), sizeof(lv_anim_t));
+       //list_page_ext->voice_playing_msg_from = 0;
+       list_page_ext->pressing = false;     
+
+       uint8_t i = 0;
+       uint8_t msg_count = mmi_voicechat_msg_count_get();
+       
+       for(i = 0; i < msg_count; i++)
+       {
+               mmi_voicechat_msg_item_info_t * msg_item = &(s_voicechat_info_p->msg_item[i]);
+
+               mmi_voicechat_list_msg_item_add(list_page, msg_item, NULL, i);
+       }       
+
+       //if((lv_obj_get_height(list_page) - lv_obj_get_style_pad_top(list_page, LV_LIST_PART_BG) * 2) > lv_obj_get_height(scrl))
+       //{
+       //      lv_cont_set_layout(scrl, LV_LAYOUT_OFF);
+       //}
+
+       return list_page;
+}
+
+void mmi_voicechat_list_screen_display(void)
+{      
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       
+       lv_voicechat_ext_t * ext = (lv_voicechat_ext_t *)mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+       if(NULL == ext) 
+               return ;
+
+       s_voicechat_ui_state = MMI_VOICECHAT_UI_STATE_LIST;
+       
+       // ui
+       lv_obj_t * cont = ext->cont_list;
+       lv_obj_clean(cont);
+       
+       ext->list = mmi_voicechat_list_create(cont);
+
+       // signal weak
+       lv_obj_t * label = lv_label_create(cont, NULL);
+       lv_obj_add_style(label, LV_OBJ_PART_MAIN, &lv_watch_font26);
+       lv_label_set_text_id(label, WATCH_TEXT_ID_SIGNAL_WEAK);
+       lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
+       lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, -10);
+       lv_obj_set_click(label, false);
+       ext->list_signal_weak_label = label;
+
+       lv_obj_t * imgbtn_cancel = lv_imgbtn_create(cont, NULL);
+       lv_imgbtn_set_src(imgbtn_cancel, LV_BTN_STATE_RELEASED, ICON_VOICECHAT_CANCEL_BUTTON);
+       lv_imgbtn_set_src(imgbtn_cancel, LV_BTN_STATE_PRESSED, ICON_VOICECHAT_CANCEL_BUTTON);
+       lv_obj_set_event_cb(imgbtn_cancel, mmi_voicechat_cancel_button_event_cb);
+    lv_obj_add_protect(imgbtn_cancel, LV_PROTECT_PRESS_LOST);
+       lv_watch_obj_add_element(imgbtn_cancel);
+       lv_obj_align(imgbtn_cancel, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 15, -20);
+       
+       lv_obj_t * imgbtn = lv_imgbtn_create(cont, NULL);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_RELEASED, ICON_VOICECHAT_RECORD_BUTTON_PRESSED);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_PRESSED, ICON_VOICECHAT_RECORD_BUTTON_PRESSED);
+       lv_obj_set_event_cb(imgbtn, mmi_voicechat_record_button_event_cb);
+    lv_obj_add_protect(imgbtn, LV_PROTECT_PRESS_LOST);
+       lv_watch_obj_add_element(imgbtn);
+       lv_obj_align(imgbtn, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, -15, -20);
+
+       lv_obj_t * imgbtn_label = lv_label_create(imgbtn, NULL);
+       lv_obj_add_style(imgbtn_label, LV_LABEL_PART_MAIN, &lv_watch_font26);
+       lv_label_set_align(imgbtn_label, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(imgbtn_label, WATCH_TEXT_ID_AIGC_CONTINUE);
+       lv_obj_align(imgbtn_label, NULL, LV_ALIGN_CENTER, 0, 0);        
+
+       lv_obj_set_hidden(ext->cont_default, true);
+       lv_obj_set_hidden(ext->cont_listening, true);
+       lv_obj_set_hidden(ext->cont_listening_middle, true);
+       lv_obj_set_hidden(ext->cont_thinking, true);
+       lv_obj_set_hidden(ext->cont_timeout, true);
+       lv_obj_set_hidden(ext->cont_list, false);
+       lv_obj_set_hidden(ext->list_signal_weak_label, true);
+}
+
+static void mmi_voicechat_default_screen_display(void)
+{      
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       
+       lv_voicechat_ext_t * ext = (lv_voicechat_ext_t *)mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+       if(NULL == ext) 
+               return ;
+
+       s_voicechat_ui_state = MMI_VOICECHAT_UI_STATE_NONE;
+
+       // ui
+       lv_obj_t * cont = ext->cont_default;
+       lv_obj_clean(cont);
+       
+       lv_obj_t * label_state = lv_label_create(cont, NULL);
+       lv_obj_add_style(label_state, LV_LABEL_PART_MAIN, &lv_watch_font20);
+       lv_label_set_text_id(label_state, WATCH_TEXT_ID_VOICECHAT);
+       lv_label_set_align(label_state, LV_LABEL_ALIGN_CENTER);
+       lv_obj_align(label_state, NULL, LV_ALIGN_IN_TOP_MID, 0, 20);
+
+       lv_obj_t * img = lv_img_create(cont, NULL);
+       lv_img_set_src(img, ICON_VOICECHAT_DEFAULT);
+       lv_obj_set_click(img, false);
+       lv_obj_align(img, NULL, LV_ALIGN_CENTER, 0, -10);
+
+       lv_obj_t * imgbtn = lv_imgbtn_create(cont, NULL);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_RELEASED, ICON_VOICECHAT_RECORD_BUTTON_DEFAULT);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_PRESSED, ICON_VOICECHAT_RECORD_BUTTON_DEFAULT);
+       lv_obj_set_event_cb(imgbtn, mmi_voicechat_record_button_event_cb);
+    lv_obj_add_protect(imgbtn, LV_PROTECT_PRESS_LOST);
+       lv_watch_obj_add_element(imgbtn);
+       lv_obj_align(imgbtn, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, -20);
+
+       lv_obj_t * imgbtn_label = lv_label_create(imgbtn, NULL);
+       lv_obj_add_style(imgbtn_label, LV_LABEL_PART_MAIN, &lv_watch_font26);
+       lv_label_set_align(imgbtn_label, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(imgbtn_label, WATCH_TEXT_ID_AIGC_CONVERSATION);
+       lv_obj_align(imgbtn_label, NULL, LV_ALIGN_CENTER, 0, 0);                
+       
+       lv_obj_set_hidden(ext->cont_default, false);
+       lv_obj_set_hidden(ext->cont_listening, true);
+       lv_obj_set_hidden(ext->cont_listening_middle, true);
+       lv_obj_set_hidden(ext->cont_thinking, true);
+       lv_obj_set_hidden(ext->cont_timeout, true);
+       lv_obj_set_hidden(ext->cont_list, true);
+}
+
+static void mmi_voicechat_no_network_screen_display(lv_obj_t * obj)
+{      
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       
+       lv_voicechat_ext_t * ext = (lv_voicechat_ext_t *)mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+       if(NULL == ext) 
+               return ;
+
+       // ui
+       s_voicechat_ui_state = MMI_VOICECHAT_UI_STATE_OPEN_FAIL;
+       
+       lv_obj_t * cont = lv_cont_create(obj, NULL);
+       lv_obj_set_size(cont, lv_obj_get_width(obj), lv_obj_get_height(obj));
+       lv_obj_align(cont, NULL, LV_ALIGN_CENTER, 0, 0);
+       lv_obj_set_style_local_bg_color(cont, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
+       lv_watch_obj_add_element(cont);
+       
+       //label
+       lv_obj_t * label_state = lv_label_create(cont, NULL);
+       lv_obj_add_style(label_state, LV_LABEL_PART_MAIN, &lv_watch_font20);
+       lv_label_set_text_id(label_state, WATCH_TEXT_ID_VOICECHAT);
+       lv_label_set_align(label_state, LV_LABEL_ALIGN_CENTER);
+       lv_obj_align(label_state, NULL, LV_ALIGN_IN_TOP_MID, 0, 20);
+       
+       lv_obj_t * img = lv_img_create(cont, NULL);
+       lv_img_set_src(img, ICON_VOICECHAT_PROMPT);
+       lv_obj_set_click(img, false);
+       lv_obj_align(img, NULL, LV_ALIGN_IN_TOP_MID, 0, 70);
+       
+       lv_obj_t * label = lv_label_create(cont, NULL);
+       lv_obj_add_style(label, LV_LABEL_PART_MAIN, &lv_watch_font20);
+       lv_label_set_text_id(label, WATCH_TEXT_ID_AIGC_OPEN_FAIL);
+       lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
+       lv_obj_align(label, img, LV_ALIGN_OUT_BOTTOM_MID, 0, 25);
+       
+       lv_obj_t * imgbtn = lv_imgbtn_create(cont, NULL);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_RELEASED, ICON_VOICECHAT_RECORD_BUTTON_PRESSED);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_PRESSED, ICON_VOICECHAT_RECORD_BUTTON_PRESSED);
+       lv_obj_set_event_cb(imgbtn, mmi_voicechat_record_button_event_cb);
+       lv_obj_align(imgbtn, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, -20);
+       
+       lv_obj_t * imgbtn_label = lv_label_create(imgbtn, NULL);
+       lv_obj_add_style(imgbtn_label, LV_LABEL_PART_MAIN, &lv_watch_font26);
+       lv_label_set_align(imgbtn_label, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(imgbtn_label, WATCH_TEXT_ID_OK);
+       lv_obj_align(imgbtn_label, NULL, LV_ALIGN_CENTER, 0, 0);                
+}
+
+void mmi_voicechat_main_screen_refresh(void)
+{
+       printf("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+
+       lv_voicechat_ext_t * ext = mmi_voicechat_actId_ext_get(ACT_ID_VOICECHAT_MAIN);
+       if(NULL == ext)
+               return;
+       
+       mmi_voicechat_list_set_slide_enable(&ext->old_ext, true);
+
+       if(NULL != ext->thinking_task_p)
+       {
+               lv_task_del(ext->thinking_task_p);
+               ext->thinking_task_p = NULL;
+       }
+               
+       uint8_t msg_count = mmi_voicechat_msg_count_get();
+       //mmi_voicechat_list_create(ext->cont, ext);
+       if(0 == msg_count)
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+
+               mmi_voicechat_default_screen_display();
+       }
+       else
+       {
+               VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+               
+               mmi_voicechat_list_screen_display();
+       }
+}
+
+lv_obj_t * mmi_voicechat_main_create(lv_obj_t * activity_obj)
+{
+       VOICECHAT_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+
+    if(activity_obj == NULL) 
+       {
+        lv_watch_activity_ext_t activity_ext;
+               
+               _lv_memset_00(&activity_ext, sizeof(lv_watch_activity_ext_t));
+        activity_ext.actId = ACT_ID_VOICECHAT_MAIN;
+        activity_ext.create = (lv_watch_activity_create_f_t)mmi_voicechat_main_create; //NULL;
+        activity_ext.prepare_destory = mmi_voicechat_main_prepare_destory;
+        activity_obj = lv_watch_creat_activity_obj(&activity_ext);
+        LV_ASSERT_MEM(activity_obj);
+    }
+
+#ifdef __MMI_ZHSX_SUPPORT__
+       s_is_ACT_ID_VOICECHAT_MAIN = true;
+#endif
+
+    lv_obj_t * obj = lv_watch_obj_create(activity_obj);
+       if(NULL == obj)
+               return NULL;
+    /*Allocate the tab type specific extended data*/
+       lv_voicechat_ext_t * ext = lv_obj_allocate_ext_attr(obj, sizeof(lv_voicechat_ext_t));
+       if(NULL == ext)
+               return NULL;
+
+       ext->cont_default = NULL;
+       ext->cont_listening = NULL;
+       ext->cont_thinking = NULL;
+       ext->cont_timeout = NULL;
+       ext->cont_list = NULL;
+
+       ext->list = NULL;
+       ext->record_buffer = NULL;
+       ext->record_size = 0;
+       ext->thinking_task_p = NULL;
+       ext->gif_listening = NULL;
+       ext->gif_thinking = NULL;
+
+       s_voicechat_ui_state = MMI_VOICECHAT_UI_STATE_NONE;
+       
+    if(false == watch_modem_sim_present_check_req() // no sim
+               //|| (MMI_MODEM_SIGNAL_BAR_0 == watch_modem_get_signal_bar_req()) // no signal
+               //|| (false == watch_modem_sim_present_check_req()) // not activated
+               )
+    {
+               mmi_voicechat_no_network_screen_display(obj);
+               
+        return obj;
+    }
+
+       // data task
+       mmi_voicechat_data_task_create();
+       watch_set_suspend_enable(false, ACT_ID_VOICECHAT_MAIN, 0);
+
+       // cont_default
+       lv_obj_t * cont_default = lv_cont_create(obj, NULL);
+       lv_obj_set_size(cont_default, lv_obj_get_width(obj), lv_obj_get_height(obj));
+       lv_obj_align(cont_default, NULL, LV_ALIGN_CENTER, 0, 0);
+       lv_obj_set_style_local_bg_color(cont_default, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
+       lv_watch_obj_add_element(cont_default);
+       ext->cont_default = cont_default;
+
+       // cont_listening
+       lv_obj_t * cont_listening = lv_cont_create(obj, NULL);
+       lv_obj_set_size(cont_listening, lv_obj_get_width(obj), lv_obj_get_height(obj));
+       lv_obj_align(cont_listening, NULL, LV_ALIGN_CENTER, 0, 0);
+       lv_obj_set_style_local_bg_color(cont_listening, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
+       lv_watch_obj_add_element(cont_listening);
+       ext->cont_listening = cont_listening;
+
+       // cont_listening middle
+       lv_obj_t * cont_listening_middle = lv_cont_create(obj, NULL);
+       lv_obj_set_size(cont_listening_middle, lv_obj_get_width(obj), lv_obj_get_height(obj));
+       lv_obj_align(cont_listening_middle, NULL, LV_ALIGN_CENTER, 0, 0);
+       lv_obj_set_style_local_bg_color(cont_listening_middle, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
+       lv_watch_obj_add_element(cont_listening_middle);
+       ext->cont_listening_middle = cont_listening_middle;
+
+       // cont_thinking
+       lv_obj_t * cont_thinking = lv_cont_create(obj, NULL);
+       lv_obj_set_size(cont_thinking, lv_obj_get_width(obj), lv_obj_get_height(obj));
+       lv_obj_align(cont_thinking, NULL, LV_ALIGN_CENTER, 0, 0);
+       lv_obj_set_style_local_bg_color(cont_thinking, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
+       lv_watch_obj_add_element(cont_thinking);
+       ext->cont_thinking = cont_thinking;
+
+       // cont_timeout
+       lv_obj_t * cont_timeout = lv_cont_create(obj, NULL);
+       lv_obj_set_size(cont_timeout, lv_obj_get_width(obj), lv_obj_get_height(obj));
+       lv_obj_align(cont_timeout, NULL, LV_ALIGN_CENTER, 0, 0);
+       lv_obj_set_style_local_bg_color(cont_timeout, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
+       lv_watch_obj_add_element(cont_timeout);
+       ext->cont_timeout = cont_timeout;
+
+       // cont_list
+       lv_obj_t * cont_list = lv_cont_create(obj, NULL);
+       lv_obj_set_size(cont_list, lv_obj_get_width(obj), lv_obj_get_height(obj));
+       lv_obj_align(cont_list, NULL, LV_ALIGN_CENTER, 0, 0);
+       lv_obj_set_style_local_bg_color(cont_list, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
+       lv_watch_obj_add_element(cont_list);
+       ext->cont_list = cont_list;
+
+       // style
+       mmi_voicechat_lv_style_set();
+
+       mmi_voicechat_default_screen_display();
+       
+       return obj;
+}
+
+void mmi_voicechat_create_event_cb(lv_obj_t * btn, lv_event_t e)
+{
+    if(LV_EVENT_CLICKED == e) 
+       {
+               // free resource
+               mmi_voicechat_msg_data_clean();
+               mmi_voicechat_tts_audio_ll_init();
+               mmi_voicechat_tts_audio_ll_clean();
+               
+        lv_watch_png_cache_all_free();
+        lv_obj_t * obj = mmi_voicechat_main_create(NULL);
+        LV_ASSERT_MEM(obj);
+    }
+}
+
+#endif
+
diff --git a/2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/mmi_voicechat_ui.h b/2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/mmi_voicechat_ui.h
new file mode 100644 (file)
index 0000000..136fdb0
--- /dev/null
@@ -0,0 +1,164 @@
+
+
+
+#ifndef __MMI_VOICECHAT_UI_H__
+#define __MMI_VOICECHAT_UI_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef LV_CONF_INCLUDE_SIMPLE
+#include "lvgl.h"
+#include "lv_watch_conf.h"
+#else
+#include "../../../lvgl/lvgl.h"
+#include "../../../lv_watch_conf.h"
+#endif
+
+#ifdef __MMI_CUSTOM_VOICECHAT_SUPPORT__
+
+
+#define __MMI_VOICECHAT_DEBUG__
+#ifdef __MMI_VOICECHAT_DEBUG__
+#define VOICECHAT_DEBUG_PRINTF(fmt, ...)       printf("[VOICECHAT]"fmt, ##__VA_ARGS__)
+//#define VOICECHAT_DEBUG_PRINTF(fmt, ...)     CPUartLogPrintf("[VOICECHAT]"fmt, ##__VA_ARGS__)
+//#define VOICECHAT_DEBUG_PRINTF(fmt, ...)     cplog_printf("[VOICECHAT]"fmt, ##__VA_ARGS__)
+#else
+#define VOICECHAT_DEBUG_PRINTF(fmt, ...)
+#endif
+
+
+//#define MMI_VOICECHAT_DEBUG_TO_FILE
+#ifdef MMI_VOICECHAT_DEBUG_TO_FILE
+#define VOICECHAT_RECV_TRANS_FILE "C:/aigc_trans.txt"
+#define VOICECHAT_RECV_TRANS_RESULT_FILE "C:/aigc_trans_result.txt"
+#define VOICECHAT_RECV_CHAT_FILE "C:/aigc_chat.txt"
+#define VOICECHAT_RECV_CHAT_RESULT_FILE "C:/aigc_chat_result.txt"
+#define VOICECHAT_RECV_TTS_FILE "C:/aigc_tts.txt"
+#define VOICECHAT_SEND_TTS_TEXT_FILE "C:/aigc_tts_text.txt"
+#endif
+
+
+
+#define MMI_VOICECHAT_AUDIO_FORMAT (3) // 7-pcm8; 3-amr
+//#define MMI_VOICECHAT_AUDIO_FORMAT_STR       (".wav") // ".amr"
+
+#if 1 // amr
+#define MMI_VOICECHAT_DATA_RECORD_HEAD_SIZE            (6)
+#define MMI_VOICECHAT_DATA_RECORD_DURATION_MAX         (60) // seconds
+#define MMI_VOICECHAT_DATA_RECORD_SIZE_MAX             ((MMI_VOICECHAT_DATA_RECORD_DURATION_MAX + 2) * HAL_AMR_BUFSIZE_PER_SECOND + MMI_VOICECHAT_DATA_RECORD_HEAD_SIZE)
+#else // pcm
+#define MMI_VOICECHAT_DATA_RECORD_HEAD_SIZE            (44)
+#define MMI_VOICECHAT_DATA_RECORD_DURATION_MAX         (10) // seconds
+#define MMI_VOICECHAT_DATA_RECORD_SIZE_MAX             (MMI_VOICECHAT_DATA_RECORD_DURATION_MAX * 16000 + MMI_VOICECHAT_DATA_RECORD_HEAD_SIZE)
+#endif
+
+#define MMI_VOICECHAT_TTS_AUDIO_PRI (AUDIO_CTRL_PRIORITY_2)
+
+
+#define MMI_VOICECHAT_MSG_NUM_MAX              (2)
+//#define MMI_VOICECHAT_DATA_FILE_NAME_MAX     (64) // (LV_FS_MAX_PATH_LENGTH / 2)
+
+typedef struct
+{
+       uint8_t msg_from;               // 0-slef; 1-other
+    //hal_rtc_t msg_time;
+       void * text_data_ptr;
+       uint32_t text_data_size;
+       void * audio_data_ptr;
+       uint32_t audio_data_size;
+} mmi_voicechat_msg_item_info_t;
+
+typedef struct
+{
+    uint8_t msg_count;
+    mmi_voicechat_msg_item_info_t msg_item[MMI_VOICECHAT_MSG_NUM_MAX];
+} mmi_voicechat_msg_info_t;
+
+typedef struct
+{
+       void * audio_data_ptr;
+       uint32_t audio_data_size;
+} mmi_voicechat_tts_audio_ll_t;
+
+typedef struct
+{
+    lv_watch_obj_ext_t old_ext;
+       lv_obj_t * unread_img;
+    uint8_t item_index;
+} lv_voicechat_list_item_ext_t;
+
+typedef struct {
+    lv_page_ext_t old_ext;
+    //lv_anim_t voice_playing_anim;
+       //uint8_t voice_playing_msg_from;               // 0-slef; 1-other
+    bool pressing;
+    //lv_style_t style_cont_self;
+    //lv_style_t style_cont_other;
+    //lv_style_t style_label_time;
+    //lv_style_t style_label_len_other;
+    //lv_style_t style_label_len_self;
+} lv_voicechat_list_ext_t;
+
+typedef struct
+{
+       lv_watch_obj_ext_t old_ext;
+
+       //TIMER_ID delete_timer_id;
+       lv_obj_t * cont_default;
+       lv_obj_t * cont_listening;
+       lv_obj_t * listening_signal_weak_label;
+       lv_obj_t * cont_listening_middle;
+       lv_obj_t * cont_thinking;
+       lv_obj_t * cont_timeout;
+       lv_obj_t * cont_list;
+       lv_obj_t * list; // chat list
+       lv_obj_t * list_signal_weak_label;
+       lv_obj_t * list_other_label;
+
+    lv_style_t style_cont_self;
+    lv_style_t style_cont_other;
+    //lv_style_t style_label_time;
+    lv_style_t style_label_len_other;
+    lv_style_t style_label_len_self;
+
+    MCI_EVNET_T event;
+       uint8_t * record_buffer;
+       uint32_t record_size;
+
+       lv_task_t * thinking_task_p;
+       
+       gif_info_t * gif_listening;
+       gif_info_t * gif_thinking;      
+}lv_voicechat_ext_t;
+
+typedef enum
+{
+       MMI_VOICECHAT_UI_STATE_NONE,
+       MMI_VOICECHAT_UI_STATE_OPEN_FAIL,
+       MMI_VOICECHAT_UI_STATE_LISTENING,
+       MMI_VOICECHAT_UI_STATE_LISTENING_MIDDLE,
+       MMI_VOICECHAT_UI_STATE_THINKING,
+       MMI_VOICECHAT_UI_STATE_CONNECT_TIMEOUT,
+       MMI_VOICECHAT_UI_STATE_LIST,
+       
+       MMI_VOICECHAT_UI_STATE_MAX
+}MMI_VOICECHAT_UI_STATE_E;
+
+
+
+char * mmi_voicechat_trans_result_text_get(uint32_t * data_len);
+bool mmi_voicechat_trans_result_text_store(char * data_buff, uint32_t data_len, bool is_end);
+bool mmi_voicechat_chat_result_text_store(char * data_buff, uint32_t data_len);
+void mmi_voicechat_create_event_cb(lv_obj_t * btn, lv_event_t e);
+bool mmi_is_ACT_ID_VOICECHAT_MAIN(void);
+
+#endif 
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
+
index 69eefdb..1db16c0 100644 (file)
@@ -45,6 +45,9 @@ static watch_app_info_t s_main_menu_four_grid[] =
 #ifdef __MMI_CUSTOM_AIGC_SUPPORT__
        { ICON_AIGC_ASSISTANT, WATCH_TEXT_ID_AIGC_ASSISTANT, mmi_aigc_create_event_cb },
 #endif
+#ifdef __MMI_CUSTOM_VOICECHAT_SUPPORT__
+       { ICON_VOICECHAT, WATCH_TEXT_ID_VOICECHAT, mmi_voicechat_create_event_cb },
+#endif
 #if USE_LV_WATCH_CAMERA != 0
        { ICON_CAMERA, WATCH_TEXT_ID_CAMERA, camera_create_btn_event_cb },
        { ICON_ALBUM, WATCH_TEXT_ID_ALBUM, album_create_event_cb },
@@ -168,6 +171,9 @@ static watch_app_info_t s_main_menu_list[] =
 #ifdef __MMI_CUSTOM_AIGC_SUPPORT__
        { ICON_AIGC_ASSISTANT_LIST, WATCH_TEXT_ID_AIGC_ASSISTANT, mmi_aigc_create_event_cb },
 #endif
+#ifdef __MMI_CUSTOM_VOICECHAT_SUPPORT__
+       { ICON_VOICECHAT_LIST, WATCH_TEXT_ID_VOICECHAT, mmi_voicechat_create_event_cb },
+#endif
 #if USE_LV_WATCH_CAMERA != 0
        { ICON_CAMERA_LIST, WATCH_TEXT_ID_CAMERA, camera_create_btn_event_cb },
        { ICON_ALBUM_LIST, WATCH_TEXT_ID_ALBUM, album_create_event_cb },
index 9852904..fe599f6 100644 (file)
@@ -231,6 +231,9 @@ LV_IMG_DECLARE(img_poweron_logo);
 #ifdef __MMI_CUSTOM_AIGC_SUPPORT__
 #define ICON_AIGC_ASSISTANT          "R:/png/primary_function/ICON_AIGC_ASSISTANT.png"
 #endif
+#ifdef __MMI_CUSTOM_VOICECHAT_SUPPORT__
+#define ICON_VOICECHAT          "R:/png/primary_function/ICON_VOICECHAT.png"
+#endif
 #ifdef __MMI_CUSTOM_BEI_KE_RUI_SHENG__
 #define ICON_AI_TALK          "R:/png/primary_function/ICON_AI_TALK.png"
 #endif
@@ -298,6 +301,9 @@ LV_IMG_DECLARE(img_poweron_logo);
 #ifdef __MMI_CUSTOM_AIGC_SUPPORT__
 #define ICON_AIGC_ASSISTANT_LIST          "R:/png/primary_function/list/ICON_AIGC_ASSISTANT.png"
 #endif
+#ifdef __MMI_CUSTOM_VOICECHAT_SUPPORT__
+#define ICON_VOICECHAT_LIST          "R:/png/primary_function/list/ICON_VOICECHAT_LIST.png"
+#endif
 
 #if USE_LV_WATCH_WEATHER != 0
 #ifdef __MMI_WEATHER_MENU_SUPPORT__
@@ -1069,6 +1075,16 @@ LV_IMG_DECLARE(img_poweron_logo);
 #define ANIM_AIGC_THINKING           "R:/png/mmi_aigc/ANIM_AIGC_THINKING.gif"
 #endif
 
+#ifdef __MMI_CUSTOM_VOICECHAT_SUPPORT__
+#define ICON_VOICECHAT_RECORD_BUTTON_DEFAULT           "R:/png/voice_chat/ICON_VOICECHAT_RECORD_BUTTON_DEFAULT.png"
+#define ICON_VOICECHAT_RECORD_BUTTON_PRESSED           "R:/png/voice_chat/ICON_VOICECHAT_RECORD_BUTTON_PRESSED.png"
+#define ICON_VOICECHAT_PROMPT           "R:/png/voice_chat/ICON_VOICECHAT_PROMPT.png"
+#define ICON_VOICECHAT_DEFAULT           "R:/png/voice_chat/ICON_VOICECHAT_DEFAULT.png"
+//#define ICON_VOICECHAT_THINKING           "R:/png/voice_chat/ICON_VOICECHAT_THINKING.png"
+#define ICON_VOICECHAT_CANCEL_BUTTON           "R:/png/voice_chat/ICON_VOICECHAT_CANCEL_BUTTON.png"
+#define ANIM_VOICECHAT_LISTENING           "R:/png/voice_chat/ANIM_VOICECHAT_LISTENING.gif"
+#define ANIM_VOICECHAT_THINKING           "R:/png/voice_chat/ANIM_VOICECHAT_THINKING.gif"
+#endif
 
 #endif
 
index 3406e6f..59c739e 100644 (file)
@@ -71,7 +71,9 @@ PACKAGE_SRC_FILES =                           \
                                        mmi_aigc_chat_websocket_client.c \
                                        mmi_aigc_chat_websocket.c       \
                                        mmi_aigc_tts_websocket_client.c \
-                                       mmi_aigc_tts_websocket.c
+                                       mmi_aigc_tts_websocket.c        \
+                                       mmi_voicechat_websocket.c \
+                                       mmi_voicechat_websocket_client.c
 
 
 # These are the tool flags specific to the ci_stub package only.
diff --git a/2.sdk/sdk/product/craneg_modem/pcac/wsclient/libwebsockets/inc/mmi_voicechat_websocket.h b/2.sdk/sdk/product/craneg_modem/pcac/wsclient/libwebsockets/inc/mmi_voicechat_websocket.h
new file mode 100644 (file)
index 0000000..349dd84
--- /dev/null
@@ -0,0 +1,39 @@
+
+
+
+#ifndef __MMI_VOICECHAT_WEBSOCKET_H__
+#define __MMI_VOICECHAT_WEBSOCKET_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../../../../config/watch/lv_watch_conf_CUSTOM.h"
+
+#ifdef __MMI_CUSTOM_VOICECHAT_SUPPORT__
+
+
+#define __MMI_VOICECHAT_WB_DEBUG__
+#ifdef __MMI_VOICECHAT_WB_DEBUG__
+//#define VOICECHAT_WB_DEBUG_PRINTF(fmt, ...)  printf("[VOICECHAT_WB]"fmt, ##__VA_ARGS__)
+//#define VOICECHAT_WB_DEBUG_PRINTF(fmt, ...)  CPUartLogPrintf("[VOICECHAT_WB]"fmt, ##__VA_ARGS__)
+#define VOICECHAT_WB_DEBUG_PRINTF(fmt, ...)    cplog_printf("[VOICECHAT_WB]"fmt, ##__VA_ARGS__)
+#else
+#define VOICECHAT_WB_DEBUG_PRINTF(fmt, ...)
+#endif
+
+
+int mmi_voicechat_websocket_send_text_data(char * data_ptr, int data_len);
+int mmi_voicechat_websocket_send_binary_data(char * data_ptr, int data_len);
+void mmi_voicechat_websocket_app_start(void);
+void mmi_voicechat_websocket_app_stop(void);
+
+
+#endif 
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
+
diff --git a/2.sdk/sdk/product/craneg_modem/pcac/wsclient/libwebsockets/inc/mmi_voicechat_websocket_client.h b/2.sdk/sdk/product/craneg_modem/pcac/wsclient/libwebsockets/inc/mmi_voicechat_websocket_client.h
new file mode 100644 (file)
index 0000000..e9cfaf3
--- /dev/null
@@ -0,0 +1,291 @@
+// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef __MMI_VOICECHAT_WEBSOCKET_CLIENT_H__
+#define __MMI_VOICECHAT_WEBSOCKET_CLIENT_H__
+
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include "web_esp_transport_ws.h"
+#include "esp_err.h"
+#include "web_esp_transport.h"
+#include "osa_old_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../../../../config/watch/lv_watch_conf_CUSTOM.h"
+
+#ifdef __MMI_CUSTOM_VOICECHAT_SUPPORT__
+
+typedef unsigned long UINT32;
+
+#define sim_portTICK_RATE_MS   1000
+#define sim_portTICK_PERIOD_MS 1000
+
+//ESP_EVENT_DECLARE_BASE(WEBSOCKET_EVENTS);         // declaration of the task events family
+
+/******************************************
+ function declared in here
+ *****************************************/
+extern char* strdup(const char* str);
+extern void free( void *p );
+extern void *malloc( size_t Size );
+extern void *calloc( size_t nItems, size_t itemSize );
+//extern int strtol(const char *p1, char **p2, int base);
+
+typedef struct sim_esp_websocket_client *sim_esp_websocket_client_handle_t;
+typedef void   (*sim_esp_event_handler_t)(int32_t event_id, void* event_data); /**< function called when an event is posted to the queue */
+
+/**
+ * @brief Websocket Client events id
+ */
+typedef enum {
+    WEBSOCKET_EVENT_ANY = -1,
+    WEBSOCKET_EVENT_ERROR = 0,      /*!< This event occurs when there are any errors during execution */
+    WEBSOCKET_EVENT_CONNECTED,      /*!< Once the Websocket has been connected to the server, no data exchange has been performed */
+    WEBSOCKET_EVENT_DISCONNECTED,   /*!< The connection has been disconnected */
+    WEBSOCKET_EVENT_DATA,           /*!< When receiving data from the server, possibly multiple portions of the packet */
+       WEBSOCKET_EVENT_CLOSED,
+       WEBSOCKET_EVENT_MAX
+} sim_esp_websocket_event_id_t;
+
+/**
+ * @brief Websocket event data
+ */
+typedef struct {
+    char *data_ptr;                   /*!< Data pointer */
+    int data_len;                           /*!< Data length */
+    uint8_t op_code;                        /*!< Received opcode */
+    sim_esp_websocket_client_handle_t client;   /*!< sim_esp_websocket_client_handle_t context */
+    void *user_context;                     /*!< user_data context, from sim_esp_websocket_client_config_t user_data */
+    int payload_len;                        /*!< Total payload length, payloads exceeding buffer will be posted through multiple events */
+    int payload_offset;                     /*!< Actual offset for the data associated with this event */
+       sim_esp_websocket_event_id_t event;
+} sim_esp_websocket_event_data_t;
+
+typedef struct {
+    UINT32                      task_stack;
+    int                         task_prio;
+    char                        *uri;
+    char                        *p_host;
+    char                        host[64];
+    char                        *p_path;
+    char                        path[1024];
+    char                        scheme[16];
+    char                        *username;
+    char                        *password;
+    int                         port;
+    bool                        auto_reconnect;
+    void                        *user_context;
+    int                         network_timeout_ms;
+    char                        *subprotocol;
+} sim_websocket_config_storage_t;
+
+typedef enum {
+    WEBSOCKET_STATE_ERROR = -1,
+    WEBSOCKET_STATE_UNKNOW = 0,
+    WEBSOCKET_STATE_INIT,
+    WEBSOCKET_STATE_CONNECTED,
+    WEBSOCKET_STATE_WAIT_TIMEOUT,
+    WEBSOCKET_STATE_CLOSING,
+} sim_websocket_client_state_t;
+
+struct sim_esp_websocket_client {
+       sim_esp_event_handler_t         handler;
+    wb_esp_transport_list_handle_t transport_list;
+    wb_esp_transport_handle_t      transport;
+    sim_websocket_config_storage_t  *config;
+    sim_websocket_client_state_t    state;
+       OSAMutexRef                 lock;
+    UINT32                      keepalive_tick_ms;
+    UINT32                      reconnect_tick_ms;
+    UINT32                      ping_tick_ms;
+    int                         wait_timeout_ms;
+    int                         auto_reconnect;
+    char                        *rx_buffer;
+    char                        *tx_buffer;
+    int                         buffer_size;
+    ws_transport_opcodes_t      last_opcode;
+    int                         payload_len;
+    int                         payload_offset;
+};
+
+/**
+ * @brief Websocket Client transport
+ */
+typedef enum {
+    WEBSOCKET_TRANSPORT_UNKNOWN = 0x0,  /*!< Transport unknown */
+    WEBSOCKET_TRANSPORT_OVER_TCP,       /*!< Transport over tcp */
+    WEBSOCKET_TRANSPORT_OVER_SSL,       /*!< Transport over ssl */
+} sim_esp_websocket_transport_t;
+
+/**
+ * @brief Websocket client setup configuration
+ */
+typedef struct {
+    const char                  *uri;                       /*!< Websocket URI, the information on the URI can be overrides the other fields below, if any */
+    const char                  *host;                      /*!< Domain or IP as string */
+    int                         port;                       /*!< Port to connect, default depend on sim_esp_websocket_transport_t (80 or 443) */
+    const char                  *username;                  /*!< Using for Http authentication - Not supported for now */
+    const char                  *password;                  /*!< Using for Http authentication - Not supported for now */
+    const char                  *path;                      /*!< HTTP Path, if not set, default is `/` */
+    bool                        disable_auto_reconnect;     /*!< Disable the automatic reconnect function when disconnected */
+    void                        *user_context;              /*!< HTTP user data context */
+    int                         task_prio;                  /*!< Websocket task priority */
+    int                         task_stack;                 /*!< Websocket task stack */
+    int                         buffer_size;                /*!< Websocket buffer size */
+    const char                  *cert_pem;                  /*!< SSL Certification, PEM format as string, if the client requires to verify server */
+    sim_esp_websocket_transport_t   transport;                  /*!< Websocket transport type, see `sim_esp_websocket_transport_t */
+    char                        *subprotocol;               /*!< Websocket subprotocol */
+} sim_esp_websocket_client_config_t;
+
+/**
+ * @brief      Start a Websocket session
+ *             This function must be the first function to call,
+ *             and it returns a sim_esp_websocket_client_handle_t that you must use as input to other functions in the interface.
+ *             This call MUST have a corresponding call to sim_esp_websocket_client_destroy when the operation is complete.
+ *
+ * @param[in]  config  The configuration
+ *
+ * @return
+ *     - `sim_esp_websocket_client_handle_t`
+ *     - NULL if any errors
+ */
+sim_esp_websocket_client_handle_t voicechat_websocket_client_init(const sim_esp_websocket_client_config_t *config);
+
+/**
+ * @brief      Set URL for client, when performing this behavior, the options in the URL will replace the old ones
+ *             Must stop the WebSocket client before set URI if the client has been connected
+ *
+ * @param[in]  client  The client
+ * @param[in]  uri     The uri
+ *
+ * @return     esp_err_t
+ */
+esp_err_t voicechat_websocket_client_set_uri(sim_esp_websocket_client_handle_t client, const char *uri);
+
+/**
+ * @brief      Open the WebSocket connection
+ *
+ * @param[in]  client  The client
+ *
+ * @return     esp_err_t
+ */
+esp_err_t voicechat_websocket_client_start(sim_esp_websocket_client_handle_t client);
+
+/**
+ * @brief      Close the WebSocket connection
+ *
+ * @param[in]  client  The client
+ *
+ * @return     esp_err_t
+ */
+esp_err_t voicechat_websocket_client_stop(sim_esp_websocket_client_handle_t client);
+
+/**
+ * @brief      Destroy the WebSocket connection and free all resources.
+ *             This function must be the last function to call for an session.
+ *             It is the opposite of the sim_esp_websocket_client_init function and must be called with the same handle as input that a esp_websocket_client_init call returned.
+ *             This might close all connections this handle has used.
+ *
+ * @param[in]  client  The client
+ *
+ * @return     esp_err_t
+ */
+esp_err_t voicechat_websocket_client_destroy(sim_esp_websocket_client_handle_t client);
+
+/**
+ * @brief      Generic write data to the WebSocket connection; defaults to binary send
+ *
+ * @param[in]  client  The client
+ * @param[in]  data    The data
+ * @param[in]  len     The length
+ * @param[in]  timeout Write data timeout
+ *
+ * @return
+ *     - Number of data was sent
+ *     - (-1) if any errors
+ */
+int voicechat_websocket_client_send(sim_esp_websocket_client_handle_t client, const char *data, int len, TickType_t timeout);
+
+/**
+ * @brief      Write binary data to the WebSocket connection (data send with WS OPCODE=02, i.e. binary)
+ *
+ * @param[in]  client  The client
+ * @param[in]  data    The data
+ * @param[in]  len     The length
+ * @param[in]  timeout Write data timeout
+ *
+ * @return
+ *     - Number of data was sent
+ *     - (-1) if any errors
+ */
+int voicechat_websocket_client_send_bin(sim_esp_websocket_client_handle_t client, const char *data, int len, TickType_t timeout);
+
+static int voicechat_websocket_client_send_close(sim_esp_websocket_client_handle_t client, int code, const char *additional_data, int total_len, TickType_t timeout);
+
+static int voicechat_websocket_client_close_with_optional_body(sim_esp_websocket_client_handle_t client, bool send_body, int code, const char *data, int len, TickType_t timeout);
+
+int voicechat_websocket_client_close_with_code(sim_esp_websocket_client_handle_t client, int code, const char *data, int len, TickType_t timeout);
+
+int voicechat_websocket_client_close(sim_esp_websocket_client_handle_t client, TickType_t timeout);
+
+/**
+ * @brief      Write textual data to the WebSocket connection (data send with WS OPCODE=01, i.e. text)
+ *
+ * @param[in]  client  The client
+ * @param[in]  data    The data
+ * @param[in]  len     The length
+ * @param[in]  timeout Write data timeout
+ *
+ * @return
+ *     - Number of data was sent
+ *     - (-1) if any errors
+ */
+int voicechat_websocket_client_send_text(sim_esp_websocket_client_handle_t client, const char *data, int len, TickType_t timeout);
+
+/**
+ * @brief      Check the WebSocket connection status
+ *
+ * @param[in]  client  The client handle
+ *
+ * @return
+ *     - true
+ *     - false
+ */
+bool voicechat_websocket_client_is_connected(sim_esp_websocket_client_handle_t client);
+
+/**
+ * @brief Register the Websocket Events
+ *
+ * @param client            The client handle
+ * @param event             The event id
+ * @param event_handler     The callback function
+ * @param event_handler_arg User context
+ * @return esp_err_t
+ */
+esp_err_t voicechat_websocket_register_events(sim_esp_websocket_client_handle_t client,
+                                                                                       sim_esp_event_handler_t event_handler);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/2.sdk/sdk/product/craneg_modem/pcac/wsclient/libwebsockets/src/mmi_voicechat_websocket.c b/2.sdk/sdk/product/craneg_modem/pcac/wsclient/libwebsockets/src/mmi_voicechat_websocket.c
new file mode 100644 (file)
index 0000000..331bd33
--- /dev/null
@@ -0,0 +1,165 @@
+
+
+
+#include "uart.h"
+#include "mmi_voicechat_websocket_client.h"
+#include "mmi_voicechat_websocket.h"
+
+
+#ifdef __MMI_CUSTOM_VOICECHAT_SUPPORT__
+
+#define MMI_VOICECHAT_WEBSOCKET_URI "wss://nls-gateway-cn-beijing.aliyuncs.com/ws/v1"
+
+static sim_esp_websocket_client_handle_t s_voicechat_ws_client_p = NULL;
+
+extern void mmi_voicechat_websocket_recv_data_handler(char * data_ptr, int data_len, int payload_len, int payload_offset);
+
+
+
+int mmi_voicechat_websocket_send_text_data(char * data_ptr, int data_len)
+{
+       int ret = -1;
+
+       VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: client_p=%#X\n", __FUNCTION__, __LINE__, s_voicechat_ws_client_p);
+       if(NULL == s_voicechat_ws_client_p)
+       {
+               return ret;
+       }
+
+    ret = voicechat_websocket_client_send_text(s_voicechat_ws_client_p, data_ptr, data_len, portMAX_DELAY);
+       if (0 > ret)
+       {
+               VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       }
+
+       return ret;
+}
+
+int mmi_voicechat_websocket_send_binary_data(char * data_ptr, int data_len)
+{
+       int ret = -1;
+
+       VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: client_p=%#X\n", __FUNCTION__, __LINE__, s_voicechat_ws_client_p);
+       if(NULL == s_voicechat_ws_client_p)
+       {
+               return ret;
+       }
+       
+    ret = voicechat_websocket_client_send_bin(s_voicechat_ws_client_p, data_ptr, data_len, portMAX_DELAY);
+       if (0 > ret)
+       {
+               VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       }
+
+       return ret;
+}
+
+static void mmi_voicechat_websocket_event_handler(int32_t event_id, void *event_data)
+{
+    sim_esp_websocket_event_data_t *data = (sim_esp_websocket_event_data_t *)event_data;
+       
+       VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: event_id=%d\n", __FUNCTION__, __LINE__, event_id);
+    switch (event_id)
+       {
+           case WEBSOCKET_EVENT_CONNECTED:
+                       VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG][%d]: WEBSOCKET_EVENT_CONNECTED\n", __LINE__);
+               break;
+                       
+           case WEBSOCKET_EVENT_DISCONNECTED:
+                       VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG][%d]: WEBSOCKET_EVENT_DISCONNECTED\n", __LINE__);
+               break;
+                       
+           case WEBSOCKET_EVENT_DATA:
+                       VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG][%d]: WEBSOCKET_EVENT_DATA\n", __LINE__);
+               VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG]: data opcode=%d,data len=%d", data->op_code, data->data_len);
+               VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG]: Total payload len=%d,current payload offset=%d\r\n", data->payload_len, data->payload_offset);
+               if (data->op_code == 0x08 && data->data_len == 2) {
+                   VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG]: Received closed message with code=%d", 256*data->data_ptr[0] + data->data_ptr[1]);
+               }
+                       else
+                       {
+                   VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG]: Received=%.*s", data->data_len, (char *)data->data_ptr);
+                               mmi_voicechat_websocket_recv_data_handler(data->data_ptr, data->data_len, data->payload_len, data->payload_offset);
+               }
+                       //OSATimerStart(shutdown_signal_timer, portMAX_DELAY, 0, shutdown_signaler, 0);
+                       break;
+                       
+           case WEBSOCKET_EVENT_ERROR:
+                       VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG][%d]: WEBSOCKET_EVENT_ERROR\n", __LINE__);
+               break;
+                       
+               case WEBSOCKET_EVENT_CLOSED:
+                       VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG][%d]: WEBSOCKET_EVENT_CLOSED\n", __LINE__);
+                       break;
+                       
+               default:
+                       VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG][%d]: default\n", __LINE__);
+                       break;
+    }
+
+       if (NULL != data)
+       {
+               if (NULL != data->data_ptr)
+               {
+                       free(data->data_ptr);
+                       data->data_ptr = NULL;
+                       VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: free data ptr\n", __FUNCTION__, __LINE__);
+               }
+
+               free(data);
+               data = NULL;
+               VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: free data\n", __FUNCTION__, __LINE__);
+       }
+}
+
+void mmi_voicechat_websocket_app_start(void)
+{
+       mmi_voicechat_websocket_app_stop();
+
+       OS_STATUS status = 0;
+       int ret = 0;
+    sim_esp_websocket_client_config_t websocket_cfg = {0};
+
+    websocket_cfg.uri = MMI_VOICECHAT_WEBSOCKET_URI;
+       websocket_cfg.transport == WEBSOCKET_TRANSPORT_OVER_SSL;
+
+       VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: url=%s\n", __FUNCTION__, __LINE__, websocket_cfg.uri);
+
+    s_voicechat_ws_client_p = voicechat_websocket_client_init(&websocket_cfg);
+       if(NULL == s_voicechat_ws_client_p)
+       {
+               VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: websocket client init fail\n", __FUNCTION__, __LINE__);
+               return;
+       }
+       
+    voicechat_websocket_register_events(s_voicechat_ws_client_p, mmi_voicechat_websocket_event_handler);
+       
+    esp_err_t err_no = voicechat_websocket_client_start(s_voicechat_ws_client_p);
+       if(ESP_OK != err_no)
+       {
+               VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: websocket client start fail,%d\n", __FUNCTION__, __LINE__, err_no);
+               return;
+       }
+       else
+       {
+
+       }
+
+       VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: client_p=%#X\n", __FUNCTION__, __LINE__, s_voicechat_ws_client_p);
+}
+
+void mmi_voicechat_websocket_app_stop(void)
+{
+       VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: client_p=%#X\n", __FUNCTION__, __LINE__, s_voicechat_ws_client_p);
+       
+       if(NULL != s_voicechat_ws_client_p)
+       {
+               voicechat_websocket_client_destroy(s_voicechat_ws_client_p);
+               s_voicechat_ws_client_p = NULL;
+       }
+
+       VOICECHAT_WB_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: client_p=%#X\n", __FUNCTION__, __LINE__, s_voicechat_ws_client_p);
+}
+
+#endif
+
diff --git a/2.sdk/sdk/product/craneg_modem/pcac/wsclient/libwebsockets/src/mmi_voicechat_websocket_client.c b/2.sdk/sdk/product/craneg_modem/pcac/wsclient/libwebsockets/src/mmi_voicechat_websocket_client.c
new file mode 100644 (file)
index 0000000..4819982
--- /dev/null
@@ -0,0 +1,832 @@
+// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <stdio.h>
+
+#include "mmi_voicechat_websocket_client.h"
+#include "web_esp_transport.h"
+#include "web_esp_transport_tcp.h"
+#include "web_esp_transport_ssl.h"
+#include "web_esp_transport_ws.h"
+
+/* using uri parser */
+#include "web_http_parser.h"
+#include "queue.h"
+#include "esp_log.h"
+#include "sockets.h"
+#include "osa.h"
+
+
+#ifdef __MMI_CUSTOM_VOICECHAT_SUPPORT__
+
+static int       task_run = 0;
+static OSTaskRef voicechat_websocket_client_ref = NULL;
+static void *    voicechat_websocket_client_stack_ptr = NULL;
+
+#define websocket_version                              "asr_websocket_v1.10_20210926"
+#define WEBSOCKET_TCP_DEFAULT_PORT      (80)
+#define WEBSOCKET_SSL_DEFAULT_PORT      (443)
+#define WEBSOCKET_BUFFER_SIZE_BYTE      (80*1024) // (8*1024)
+#define WEBSOCKET_RECONNECT_TIMEOUT_MS  (5*60*1000)
+#define WEBSOCKET_TASK_PRIORITY         (90)
+#define WEBSOCKET_TASK_STACK            (8*1024)
+#define WEBSOCKET_NETWORK_TIMEOUT_MS    (10*1000)
+#define WEBSOCKET_PING_TIMEOUT_MS       (15*60*1000)
+#define WEBSOCKET_EVENT_QUEUE_SIZE      (1)
+
+#define ESP_WS_CLIENT_MEM_CHECK(a, action) if (!(a)) {                                         \
+        ESP_LOGE("%s:%d (%s): %s", __FILE__, __LINE__, __FUNCTION__, "Memory exhausted");       \
+        action;                                                                                     \
+        }
+#define ESP_EVENT_DECLARE_BASE(id) extern esp_event_base_t id
+#define ESP_EVENT_DEFINE_BASE(id) esp_event_base_t id = #id
+
+static int voicechat_websocket_client_send_with_opcode(sim_esp_websocket_client_handle_t client, ws_transport_opcodes_t opcode, const char *data, int len, TickType_t timeout);
+static void asr_ws_loop_run_task(void *pv);
+extern OSMsgQRef asr_ws_msgQ_ref;
+extern int esp_transport_ws_poll_connection_closed(wb_esp_transport_handle_t t, int timeout_ms);
+
+static UINT32 _tick_get_ms(void)
+{
+       return (5*OSAGetTicks());       //get ms
+    //return esp_timer_get_time()/1000;
+}
+
+static int voicechat_websocket_client_dispatch_event(sim_esp_websocket_client_handle_t client,
+                                                     sim_esp_websocket_event_id_t event,
+                                                     const char *data,
+                                                     int data_len)
+{
+       if (client->handler) {
+               if (NULL == data) {
+                       client->handler(event, NULL);
+               } else {
+                       sim_esp_websocket_event_data_t *event_data = NULL;
+                       event_data = malloc(sizeof(sim_esp_websocket_event_data_t));
+                       if (NULL == event_data) {
+                               ESP_LOGE("%s, event_data malloc failed", __FUNCTION__);
+                               return -1;
+                       } else {
+                               memset(event_data, '\0', sizeof(sim_esp_websocket_event_data_t));
+                               event_data->data_ptr = malloc(data_len);
+                               if (event_data->data_ptr) {
+                                       memset(event_data->data_ptr, 0, data_len);
+                                       memcpy(event_data->data_ptr, data, data_len);
+                               }
+                       }
+
+                       event_data->data_len = data_len;
+               event_data->op_code  = client->last_opcode;
+            //shenxj+++
+            event_data->payload_len = client->payload_len;
+            event_data->payload_offset = client->payload_offset;
+            //shenxj---
+
+                       client->handler(event, event_data);
+               }
+       }
+
+       return 0;
+}
+
+static int voicechat_websocket_client_abort_connection(sim_esp_websocket_client_handle_t client)
+{
+       int ret = 0;
+       
+    wb_esp_transport_close(client->transport);
+    client->wait_timeout_ms = WEBSOCKET_RECONNECT_TIMEOUT_MS;
+    client->reconnect_tick_ms = _tick_get_ms();
+    client->state = WEBSOCKET_STATE_WAIT_TIMEOUT;
+    ESP_LOGI("Reconnect after %d ms", client->wait_timeout_ms);
+    ret = voicechat_websocket_client_dispatch_event(client, WEBSOCKET_EVENT_DISCONNECTED, NULL, 0);
+       ESP_LOGD("%s, client abort connection ret is %d", __FUNCTION__, ret);
+    return ret;
+}
+
+static esp_err_t voicechat_websocket_client_set_config(sim_esp_websocket_client_handle_t client, const sim_esp_websocket_client_config_t *config)
+{
+    sim_websocket_config_storage_t *cfg = client->config;
+    cfg->task_prio = config->task_prio;
+    if (cfg->task_prio <= 0) {
+        cfg->task_prio = WEBSOCKET_TASK_PRIORITY;
+    }
+
+    cfg->task_stack = config->task_stack;
+    if (cfg->task_stack == 0) {
+        cfg->task_stack = WEBSOCKET_TASK_STACK;
+    }
+
+    if (config->host) {
+        cfg->p_host = strdup(config->host);
+               memcpy(cfg->host, cfg->p_host, strlen(config->host));
+        ESP_WS_CLIENT_MEM_CHECK(cfg->host, return ESP_ERR_NO_MEM);
+    }
+
+    if (config->port) {
+        cfg->port = config->port;
+    }
+
+    if (config->username) {
+        //free(cfg->username);
+        cfg->username = strdup(config->username);
+        ESP_WS_CLIENT_MEM_CHECK(cfg->username, return ESP_ERR_NO_MEM);
+    }
+
+    if (config->password) {
+        //free(cfg->password);
+        cfg->password = strdup(config->password);
+        ESP_WS_CLIENT_MEM_CHECK(cfg->password, return ESP_ERR_NO_MEM);
+    }
+
+    if (config->uri) {
+        //free(cfg->uri);
+        cfg->uri = strdup(config->uri);
+        ESP_WS_CLIENT_MEM_CHECK(cfg->uri, return ESP_ERR_NO_MEM);
+    }
+    if (config->path) {
+        //free(cfg->path);
+        cfg->p_path = strdup(config->path);
+               memcpy(cfg->path, cfg->p_path, strlen(config->path));
+        ESP_WS_CLIENT_MEM_CHECK(cfg->path, return ESP_ERR_NO_MEM);
+    }
+    if (config->subprotocol) {
+        //free(cfg->subprotocol);
+        cfg->subprotocol = strdup(config->subprotocol);
+        ESP_WS_CLIENT_MEM_CHECK(cfg->subprotocol, return ESP_ERR_NO_MEM);
+    }
+
+    cfg->network_timeout_ms = WEBSOCKET_NETWORK_TIMEOUT_MS;
+    cfg->user_context = config->user_context;
+    cfg->auto_reconnect = true;
+    if (config->disable_auto_reconnect) {
+        cfg->auto_reconnect = false;
+    }
+
+
+    return ESP_OK;
+}
+
+static esp_err_t voicechat_websocket_client_destroy_config(sim_esp_websocket_client_handle_t client)
+{
+    if (client == NULL) {
+        return ESP_ERR_INVALID_ARG;
+    }
+    sim_websocket_config_storage_t *cfg = client->config;
+    if (client->config == NULL) {
+        return ESP_ERR_INVALID_ARG;
+    }
+       
+       if (NULL != cfg->p_host) {
+               free(cfg->p_host);
+               cfg->p_host = NULL;
+       }
+       if (NULL != cfg->uri) {
+               free(cfg->uri);
+               cfg->uri = NULL;
+       }
+       if (NULL != cfg->p_path) {
+               free(cfg->p_path);
+               cfg->p_path = NULL;
+       }
+       if (NULL != cfg->username) {
+               free(cfg->username);
+               cfg->username = NULL;
+       }
+       if (NULL != cfg->password) {
+               free(cfg->password);
+               cfg->password = NULL;
+       }
+       if (NULL != cfg->subprotocol) {
+               free(cfg->subprotocol);
+               cfg->subprotocol = NULL;
+       }
+
+    memset(cfg, 0, sizeof(sim_websocket_config_storage_t));
+    free(client->config);
+    client->config = NULL;
+    return ESP_OK;
+}
+
+static void set_websocket_transport_optional_settings(sim_esp_websocket_client_handle_t client, wb_esp_transport_handle_t trans)
+{
+    if (trans && client->config->path) {
+        wb_esp_transport_ws_set_path(trans, client->config->path);
+    }
+    if (trans && client->config->subprotocol) {
+        wb_esp_transport_ws_set_subprotocol(trans, client->config->subprotocol);
+    }
+}
+
+sim_esp_websocket_client_handle_t voicechat_websocket_client_init(const sim_esp_websocket_client_config_t *config)
+{
+    wb_esp_transport_handle_t tcp = NULL;
+    wb_esp_transport_handle_t ws  = NULL;
+    wb_esp_transport_handle_t ssl = NULL;
+    wb_esp_transport_handle_t wss = NULL;
+    int buffer_size = 0;    
+       OS_STATUS status;
+       
+    sim_esp_websocket_client_handle_t client = (sim_esp_websocket_client_handle_t)malloc(1*sizeof(struct sim_esp_websocket_client));
+    ESP_WS_CLIENT_MEM_CHECK(client, return NULL);
+       memset(client, '\0', sizeof(struct sim_esp_websocket_client));
+       client->state = WEBSOCKET_STATE_UNKNOW;
+       
+       status = OSAMutexCreate(&client->lock, OSA_FIFO);
+       if (OS_SUCCESS != status) {
+               ESP_LOGE("Failed to create client lock");
+       }
+       
+    client->config = calloc(1, sizeof(sim_websocket_config_storage_t));
+    ESP_WS_CLIENT_MEM_CHECK(client->config, goto _websocket_init_fail);
+
+    client->transport_list = wb_esp_transport_list_init();
+    ESP_WS_CLIENT_MEM_CHECK(client->transport_list, goto _websocket_init_fail);
+
+    tcp = wb_esp_transport_tcp_init();
+    ESP_WS_CLIENT_MEM_CHECK(tcp, goto _websocket_init_fail);
+
+    wb_esp_transport_set_default_port(tcp, WEBSOCKET_TCP_DEFAULT_PORT);
+    wb_esp_transport_list_add(client->transport_list, tcp, "_tcp"); // need to save to transport list, for cleanup
+
+
+    ws = wb_esp_transport_ws_init(tcp);
+    ESP_WS_CLIENT_MEM_CHECK(ws, goto _websocket_init_fail);
+
+    wb_esp_transport_set_default_port(ws, WEBSOCKET_TCP_DEFAULT_PORT);
+    wb_esp_transport_list_add(client->transport_list, ws, "ws");
+    if (config->transport == WEBSOCKET_TRANSPORT_OVER_TCP) {
+        sprintf(client->config->scheme, "%s", "ws");
+        ESP_WS_CLIENT_MEM_CHECK(client->config->scheme, goto _websocket_init_fail);
+    }
+
+    ssl = wb_esp_transport_ssl_init();
+    ESP_WS_CLIENT_MEM_CHECK(ssl, goto _websocket_init_fail);
+
+    wb_esp_transport_set_default_port(ssl, WEBSOCKET_SSL_DEFAULT_PORT);
+    if (config->cert_pem) {
+        wb_esp_transport_ssl_set_cert_data(ssl, config->cert_pem, strlen(config->cert_pem));
+    }
+    wb_esp_transport_list_add(client->transport_list, ssl, "_ssl"); // need to save to transport list, for cleanup
+
+    wss = wb_esp_transport_ws_init(ssl);
+    ESP_WS_CLIENT_MEM_CHECK(wss, goto _websocket_init_fail);
+
+    wb_esp_transport_set_default_port(wss, WEBSOCKET_SSL_DEFAULT_PORT);
+
+    wb_esp_transport_list_add(client->transport_list, wss, "wss");
+    if (config->transport == WEBSOCKET_TRANSPORT_OVER_SSL) {
+        sprintf(client->config->scheme, "%s", "wss");
+        ESP_WS_CLIENT_MEM_CHECK(client->config->scheme, goto _websocket_init_fail);
+    }
+
+    if (config->uri) {
+        if (voicechat_websocket_client_set_uri(client, config->uri) != ESP_OK) {
+            ESP_LOGE("Invalid uri");
+            goto _websocket_init_fail;
+        }
+    }
+
+    if (voicechat_websocket_client_set_config(client, config) != ESP_OK) {
+        ESP_LOGE("Failed to set the configuration");
+        goto _websocket_init_fail;
+    }
+
+    if (client->config->scheme == NULL) {
+        sprintf(client->config->scheme, "%s", "ws");
+        ESP_WS_CLIENT_MEM_CHECK(client->config->scheme, goto _websocket_init_fail);
+    }
+
+    set_websocket_transport_optional_settings(client, wb_esp_transport_list_get_transport(client->transport_list, "ws"));
+    set_websocket_transport_optional_settings(client, wb_esp_transport_list_get_transport(client->transport_list, "wss"));
+
+    client->keepalive_tick_ms = _tick_get_ms();
+    client->reconnect_tick_ms = _tick_get_ms();
+    client->ping_tick_ms = _tick_get_ms();
+
+    buffer_size = config->buffer_size;
+    if (buffer_size <= 0) {
+        buffer_size = WEBSOCKET_BUFFER_SIZE_BYTE;
+    }
+    client->rx_buffer = malloc(buffer_size);
+    ESP_WS_CLIENT_MEM_CHECK(client->rx_buffer, {
+        goto _websocket_init_fail;
+    });
+    client->tx_buffer = malloc(buffer_size);
+    ESP_WS_CLIENT_MEM_CHECK(client->tx_buffer, {
+        goto _websocket_init_fail;
+    });
+
+    client->buffer_size = buffer_size;
+    return client;
+
+_websocket_init_fail:
+    voicechat_websocket_client_destroy(client);
+    return NULL;
+}
+
+esp_err_t voicechat_websocket_client_destroy(sim_esp_websocket_client_handle_t client)
+{
+    if (client == NULL) {
+        return ESP_ERR_INVALID_ARG;
+    }
+    if (1 == task_run) {
+        voicechat_websocket_client_stop(client);
+    }
+       
+       OSAMutexDelete(client->lock);
+
+    voicechat_websocket_client_destroy_config(client);
+               
+    wb_esp_transport_list_destroy(client->transport_list);
+       
+       if (NULL != client->tx_buffer) {
+               free(client->tx_buffer);
+               client->tx_buffer = NULL;
+       }
+       if (NULL != client->rx_buffer) {
+               free(client->rx_buffer);
+               client->rx_buffer = NULL;
+       }
+       if (NULL != client) {
+               free(client);
+               client = NULL;
+       }
+       
+    return ESP_OK;
+}
+
+esp_err_t voicechat_websocket_client_set_uri(sim_esp_websocket_client_handle_t client, const char *uri)
+{
+    if (client == NULL || uri == NULL) {
+        return ESP_ERR_INVALID_ARG;
+    }
+    struct http_parser_url puri;
+    wb_http_parser_url_init(&puri);
+    int parser_status = wb_http_parser_parse_url(uri, strlen(uri), 0, &puri);
+    if (parser_status != 0) {
+        ESP_LOGE("Error parse uri = %s", uri);
+        return ESP_FAIL;
+    }
+    if (puri.field_data[UF_SCHEMA].len) {
+        //free(client->config->scheme);
+        sprintf(client->config->scheme, "%.*s", puri.field_data[UF_SCHEMA].len, uri + puri.field_data[UF_SCHEMA].off);
+        ESP_WS_CLIENT_MEM_CHECK(client->config->scheme, return ESP_ERR_NO_MEM);
+    }
+
+    if (puri.field_data[UF_HOST].len) {
+        //free(client->config->host);
+        sprintf(client->config->host, "%.*s", puri.field_data[UF_HOST].len, uri + puri.field_data[UF_HOST].off);
+        ESP_WS_CLIENT_MEM_CHECK(client->config->host, return ESP_ERR_NO_MEM);
+    }
+
+
+    if (puri.field_data[UF_PATH].len || puri.field_data[UF_QUERY].len) {
+        //free(client->config->path);
+        if (puri.field_data[UF_QUERY].len == 0) {
+            sprintf(client->config->path, "%.*s", puri.field_data[UF_PATH].len, uri + puri.field_data[UF_PATH].off);
+        } else if (puri.field_data[UF_PATH].len == 0)  {
+            sprintf(client->config->path, "/?%.*s", puri.field_data[UF_QUERY].len, uri + puri.field_data[UF_QUERY].off);
+        } else {
+            sprintf(client->config->path, "%.*s?%.*s", puri.field_data[UF_PATH].len, uri + puri.field_data[UF_PATH].off,
+                    puri.field_data[UF_QUERY].len, uri + puri.field_data[UF_QUERY].off);
+        }
+        ESP_WS_CLIENT_MEM_CHECK(client->config->path, return ESP_ERR_NO_MEM);
+    }
+    if (puri.field_data[UF_PORT].off) {
+        client->config->port = strtol((const char*)(uri + puri.field_data[UF_PORT].off), NULL, 10);
+    }
+
+    if (puri.field_data[UF_USERINFO].len) {
+        char user_info[1024];
+        memset(user_info, '\0', 1024);
+        sprintf(user_info, "%.*s", puri.field_data[UF_USERINFO].len, uri + puri.field_data[UF_USERINFO].off);
+        if (user_info) {
+            char *pass = strchr(user_info, ':');
+            if (pass) {
+                pass[0] = 0; //terminal username
+                pass ++;
+                //free(client->config->password);
+                client->config->password = strdup(pass);
+                ESP_WS_CLIENT_MEM_CHECK(client->config->password, return ESP_ERR_NO_MEM);
+            }
+            //free(client->config->username);
+            client->config->username = strdup(user_info);
+            ESP_WS_CLIENT_MEM_CHECK(client->config->username, return ESP_ERR_NO_MEM);
+            //free(user_info);
+        } else {
+            return ESP_ERR_NO_MEM;
+        }
+    }
+    return ESP_OK;
+}
+
+static esp_err_t voicechat_websocket_client_recv(sim_esp_websocket_client_handle_t client)
+{
+    int rlen;
+    client->payload_offset = 0;
+       memset(client->rx_buffer, 0, client->buffer_size);
+    do {
+        rlen = wb_esp_transport_read(client->transport, client->rx_buffer, client->buffer_size, client->config->network_timeout_ms);
+        if (rlen <= 0) {
+            ESP_LOGE("Error read data");
+            voicechat_websocket_client_abort_connection(client);
+            return ESP_FAIL;
+        }
+        client->payload_len = wb_esp_transport_ws_get_read_payload_len(client->transport);
+        client->last_opcode = wb_esp_transport_ws_get_read_opcode(client->transport);
+
+        voicechat_websocket_client_dispatch_event(client, WEBSOCKET_EVENT_DATA, client->rx_buffer, rlen);
+
+        client->payload_offset += rlen;
+    } while (client->payload_offset < client->payload_len);
+
+    // if a PING message received -> send out the PONG, this will not work for PING messages with payload longer than buffer len
+    if (client->last_opcode == WS_TRANSPORT_OPCODES_PING) {
+        const char *data = (client->payload_len == 0) ? NULL : client->rx_buffer;
+        wb_esp_transport_ws_send_raw(client->transport, WS_TRANSPORT_OPCODES_PONG, data, client->payload_len,
+                                  client->config->network_timeout_ms);
+    } else if (client->last_opcode == WS_TRANSPORT_OPCODES_CLOSE) {
+        ESP_LOGD("Received close frame");
+        client->state = WEBSOCKET_STATE_CLOSING;
+    }
+
+    return ESP_OK;
+}
+
+static void voicechat_websocket_client_task(void *pv)
+{
+       OSA_STATUS status;
+       int ret = 0;
+    const int lock_timeout = portMAX_DELAY;
+    sim_esp_websocket_client_handle_t client = (sim_esp_websocket_client_handle_t) pv;
+    task_run = 1;
+
+    //get transport by scheme
+    client->transport = wb_esp_transport_list_get_transport(client->transport_list, client->config->scheme);
+
+    if (client->transport == NULL) {
+        ESP_LOGE("There are no transports valid, stop websocket client");
+        task_run = 0;
+    }
+    //default port
+    if (client->config->port == 0) {
+        client->config->port = wb_esp_transport_get_default_port(client->transport);
+    }
+
+    client->state = WEBSOCKET_STATE_INIT;
+    int read_select = 0;
+    while (1) {
+               if (0 == task_run) {
+                       ESP_LOGE("%s: task_run=0 and task exit", __FUNCTION__);
+                       break;
+               }
+       
+               //ESP_LOGD("%s, client state is %d, client->run is %d", 
+               //                      __FUNCTION__, (int)client->state, task_run);
+  
+               status = OSAMutexLock(client->lock, OSA_SUSPEND);
+               if (status != OS_SUCCESS) {
+                       ESP_LOGE("%s: get lock failed and task exit", __FUNCTION__);
+                       break;
+               }
+        switch ((int)client->state) {
+            case WEBSOCKET_STATE_INIT:
+                if (client->transport == NULL) {
+                    ESP_LOGE("There are no transport");
+                    task_run = 0;
+                    break;
+                }
+                               
+                if (wb_esp_transport_connect(client->transport,
+                                          client->config->host,
+                                          client->config->port,
+                                          client->config->network_timeout_ms) < 0) {
+                    ESP_LOGE("Error transport connect");
+                    ret  = voicechat_websocket_client_abort_connection(client);
+                                       ESP_LOGD("%s, client abort connection ret is %d", __FUNCTION__, ret);
+                    break;
+                }
+                ESP_LOGD("Transport connected to %s://%s:%d", client->config->scheme, client->config->host, client->config->port);
+
+                client->state = WEBSOCKET_STATE_CONNECTED;
+                voicechat_websocket_client_dispatch_event(client, WEBSOCKET_EVENT_CONNECTED, NULL, 0);
+
+                break;
+            case WEBSOCKET_STATE_CONNECTED:
+                if (_tick_get_ms() - client->ping_tick_ms > WEBSOCKET_PING_TIMEOUT_MS) {
+                    client->ping_tick_ms = _tick_get_ms();
+                    ESP_LOGD("Sending PING...");
+                    wb_esp_transport_ws_send_raw(client->transport, WS_TRANSPORT_OPCODES_PING, NULL, 0, client->config->network_timeout_ms);
+                }
+
+                if (read_select == 0) {
+                    //ESP_LOGV("Read poll timeout: skipping esp_transport_read()...");
+                    break;
+                }
+                client->ping_tick_ms = _tick_get_ms();
+
+                if (voicechat_websocket_client_recv(client) == ESP_FAIL) {
+                    ESP_LOGE("Error receive data");
+                    voicechat_websocket_client_abort_connection(client);
+                    break;
+                }
+                break;
+            case WEBSOCKET_STATE_WAIT_TIMEOUT:
+                if (!client->config->auto_reconnect) {
+                    task_run = 0;
+                    break;
+                }
+                if (_tick_get_ms() - client->reconnect_tick_ms > client->wait_timeout_ms) {
+                    client->state = WEBSOCKET_STATE_INIT;
+                    client->reconnect_tick_ms = _tick_get_ms();
+                    ESP_LOGD("Reconnecting...");
+                } else {
+                                       client->state = WEBSOCKET_STATE_WAIT_TIMEOUT;
+                                       ESP_LOGD("Waiting connect...");
+                               }
+                break;
+                       case WEBSOCKET_STATE_CLOSING:
+                               // if closing not initiated by the client echo the close message back
+                               ESP_LOGD("Closing initiated by the server, sending close frame");
+                               wb_esp_transport_ws_send_raw(client->transport, WS_TRANSPORT_OPCODES_CLOSE | WS_TRANSPORT_OPCODES_FIN, NULL, 0, client->config->network_timeout_ms);
+                               break;
+
+                       default:                                
+                               ESP_LOGD("Client run iteration in a default state: %d", client->state);
+                               break;
+        }
+               OSAMutexUnlock(client->lock); 
+
+               if (WEBSOCKET_STATE_CONNECTED == client->state) {
+            read_select = wb_esp_transport_poll_read(client->transport, 1000); //Poll every 1000ms
+            if (read_select < 0) {
+                ESP_LOGE("Network error: esp_transport_poll_read() returned %d, errno=%d", read_select, errno);
+                voicechat_websocket_client_abort_connection(client);
+            }
+        } else if (WEBSOCKET_STATE_WAIT_TIMEOUT == client->state) {
+            // waiting for reconnecting...
+            OSATaskSleep(client->wait_timeout_ms / 2 / sim_portTICK_RATE_MS);
+        } else if (WEBSOCKET_STATE_CLOSING == client->state) {
+            ESP_LOGD(" Waiting for TCP connection to be closed by the server");
+            ret = esp_transport_ws_poll_connection_closed(client->transport, 1000);
+            if (ret == 0) {
+                // still waiting
+                break;
+            }
+            if (ret < 0) {
+                ESP_LOGW("Connection terminated while waiting for clean TCP close");
+            }
+            task_run = 0;
+            client->state = WEBSOCKET_STATE_UNKNOW;
+            voicechat_websocket_client_dispatch_event(client, WEBSOCKET_EVENT_CLOSED, NULL, 0);
+            break;
+        }
+    }
+       
+    wb_esp_transport_close(client->transport);
+    client->state = WEBSOCKET_STATE_UNKNOW;
+    ESP_LOGD("%s task exit!task_run=%d, client state=%d",
+        __FUNCTION__, task_run, client->state);
+       return;
+}
+
+esp_err_t voicechat_websocket_client_start(sim_esp_websocket_client_handle_t client)
+{
+       OS_STATUS status = OS_SUCCESS;
+
+    if (client == NULL) {
+        return ESP_ERR_INVALID_ARG;
+    }
+    if (client->state > WEBSOCKET_STATE_INIT) {
+        ESP_LOGE("The client has started and client state is %d", client->state);
+        return ESP_FAIL;
+    }
+
+       if (NULL == voicechat_websocket_client_ref) {
+               if (NULL == voicechat_websocket_client_stack_ptr) {
+                       voicechat_websocket_client_stack_ptr = malloc(8*1024);
+                       if (NULL == voicechat_websocket_client_stack_ptr)       {
+                               ESP_LOGE("websocket task stack malloc failed.");
+                               return ESP_ERR_NO_MEM;
+                       }
+               }
+               status = OSATaskCreate(&voicechat_websocket_client_ref, 
+                                                         voicechat_websocket_client_stack_ptr,
+                                                         8*1024,
+                                                         90,
+                                                         "voicechat_ws_task",
+                                                         voicechat_websocket_client_task,
+                                                         (void *)client);
+               if (OS_SUCCESS != status) {
+                       if (voicechat_websocket_client_stack_ptr) {
+                               free(voicechat_websocket_client_stack_ptr);
+                               voicechat_websocket_client_stack_ptr = NULL;
+                       }
+                       ESP_LOGE("Error create websocket task");
+               }
+       } else {
+               ESP_LOGD("websocket task is exist!");
+       }
+       
+    ESP_LOGD("websocket_version: %s.", websocket_version);
+       ESP_LOGD("create ws task SUCCESS!");
+    return ESP_OK;
+}
+
+esp_err_t voicechat_websocket_client_stop(sim_esp_websocket_client_handle_t client)
+{
+    if (client == NULL) {
+        return ESP_ERR_INVALID_ARG;
+    }
+    if (0 == task_run) {
+        ESP_LOGW("Client was not started");
+        return ESP_FAIL;
+    }
+    task_run = 0;      
+    client->state = WEBSOCKET_STATE_UNKNOW;
+    //delete task
+    if(voicechat_websocket_client_ref == NULL) {
+        ESP_LOGD("websocket task is not exist!");
+        return ESP_FAIL;
+    }
+    ESP_LOGD("task deleting...");
+#if 1 //liangrf @ fixed Bug #50522 (release select_cb)
+    lwip_trigger_process("select", voicechat_websocket_client_ref);
+#endif
+    OSA_STATUS delete_status = OSATaskDelete(voicechat_websocket_client_ref);
+    ESP_LOGD("task deleted, deleteTaskRet is %d...", delete_status);
+    if(voicechat_websocket_client_stack_ptr) {
+        free(voicechat_websocket_client_stack_ptr);
+        voicechat_websocket_client_stack_ptr = NULL;
+    }
+    voicechat_websocket_client_ref = NULL;
+    //delete task
+    
+    ESP_LOGD("%s, client state is %d, task_run is %d", 
+               __FUNCTION__, (int)client->state, task_run);
+    return ESP_OK;
+}
+
+static int voicechat_websocket_client_send_close(sim_esp_websocket_client_handle_t client, int code, const char *additional_data, int total_len, TickType_t timeout)
+{
+    char *close_status_data = NULL;
+    // RFC6455#section-5.5.1: The Close frame MAY contain a body (indicated by total_len >= 2)
+    if (total_len >= 2) {
+        close_status_data = calloc(1, total_len);
+        ESP_WS_CLIENT_MEM_CHECK(close_status_data, return -1);
+        // RFC6455#section-5.5.1: The first two bytes of the body MUST be a 2-byte representing a status
+        uint16_t *code_network_order = (uint16_t *) close_status_data;
+        *code_network_order = htons(code);
+        memcpy(close_status_data + 2, additional_data, total_len - 2);
+    }
+    int ret = voicechat_websocket_client_send_with_opcode(client, WS_TRANSPORT_OPCODES_CLOSE, close_status_data, total_len, timeout);
+       if (NULL != close_status_data) {
+               free(close_status_data);
+               close_status_data = NULL;
+       }
+    return ret;
+}
+
+
+static int voicechat_websocket_client_close_with_optional_body(sim_esp_websocket_client_handle_t client, bool send_body, int code, const char *data, int len, TickType_t timeout)
+{
+       int ret = 0;
+       
+    if (client == NULL) {
+        return ESP_ERR_INVALID_ARG;
+    }
+    if (0 == task_run) {
+        ESP_LOGW("Client was not started");
+        return ESP_FAIL;
+    }
+
+    if (send_body) {
+        ret = voicechat_websocket_client_send_close(client, code, data, len + 2, portMAX_DELAY); // len + 2 -> always sending the code
+    } else {
+        ret = voicechat_websocket_client_send_close(client, 0, NULL, 0, portMAX_DELAY); // only opcode frame
+    }
+
+    // If could not close gracefully within timeout, stop the client and disconnect
+    //task_run = 0;
+    //client->state = WEBSOCKET_STATE_UNKNOW;
+    if (ret >= 0) {
+               return ESP_OK;
+       } else {
+               ESP_LOGW("Client send close failed");
+               return ESP_FAIL;
+       }
+}
+
+int voicechat_websocket_client_close_with_code(sim_esp_websocket_client_handle_t client, int code, const char *data, int len, TickType_t timeout)
+{
+    return voicechat_websocket_client_close_with_optional_body(client, true, code, data, len, timeout);
+}
+
+int voicechat_websocket_client_close(sim_esp_websocket_client_handle_t client, TickType_t timeout)
+{
+    return voicechat_websocket_client_close_with_optional_body(client, false, 0, NULL, 0, timeout);
+}
+
+int voicechat_websocket_client_send_text(sim_esp_websocket_client_handle_t client, const char *data, int len, TickType_t timeout)
+{
+    return voicechat_websocket_client_send_with_opcode(client, WS_TRANSPORT_OPCODES_TEXT, data, len, timeout);
+}
+
+int voicechat_websocket_client_send(sim_esp_websocket_client_handle_t client, const char *data, int len, TickType_t timeout)
+{
+    return voicechat_websocket_client_send_with_opcode(client, WS_TRANSPORT_OPCODES_BINARY, data, len, timeout);
+}
+
+int voicechat_websocket_client_send_bin(sim_esp_websocket_client_handle_t client, const char *data, int len, TickType_t timeout)
+{
+    return voicechat_websocket_client_send_with_opcode(client, WS_TRANSPORT_OPCODES_BINARY, data, len, timeout);
+}
+
+static int voicechat_websocket_client_send_with_opcode(sim_esp_websocket_client_handle_t client, ws_transport_opcodes_t opcode, const char *data, int len, TickType_t timeout)
+{
+    int need_write = len;
+    int wlen = 0, widx = 0;
+    int ret = ESP_FAIL;
+    UINT32 current_opcode = opcode;
+       OSA_STATUS status;
+
+    if (client == NULL || len < 0 ||
+        (opcode != WS_TRANSPORT_OPCODES_CLOSE && (data == NULL || len <= 0))) {
+        ESP_LOGE("Invalid arguments");
+        return ESP_FAIL;
+    }
+       
+       status = OSAMutexLock(client->lock, timeout);
+       if (status != OS_SUCCESS) {
+               ESP_LOGE("%s: get lock failed and return error", __FUNCTION__);
+               return ESP_FAIL;
+       }
+    if (!voicechat_websocket_client_is_connected(client)) {
+        ESP_LOGE("Websocket client is not connected");
+        goto unlock_and_return;
+    }
+
+    if (client->transport == NULL) {
+        ESP_LOGE("Invalid transport");
+        goto unlock_and_return;
+    }
+
+    while (widx < len || current_opcode) {  // allow for sending "current_opcode" only message with len==0
+        if (need_write > client->buffer_size) {
+            need_write = client->buffer_size;
+        } else {
+            current_opcode |= WS_TRANSPORT_OPCODES_FIN;
+        }
+        memcpy(client->tx_buffer, data + widx, need_write);
+        // send with ws specific way and specific opcode
+        wlen = wb_esp_transport_ws_send_raw(client->transport, current_opcode, (char *)client->tx_buffer, need_write,
+                                        (timeout==portMAX_DELAY)? -1 : timeout * sim_portTICK_PERIOD_MS);
+        if (wlen < 0 || (wlen == 0 && need_write != 0)) {
+            ret = wlen;
+            ESP_LOGE("Network error: esp_transport_write() returned %d, errno=%d", ret, errno);
+            voicechat_websocket_client_abort_connection(client);
+            goto unlock_and_return;
+        }
+        current_opcode = 0;
+        widx += wlen;
+        need_write = len - widx;
+    }
+
+    ret = widx;
+unlock_and_return:
+       OSAMutexUnlock(client->lock);
+    return ret;
+}
+
+bool voicechat_websocket_client_is_connected(sim_esp_websocket_client_handle_t client)
+{
+    if (client == NULL) {
+        return false;
+    }
+    return client->state == WEBSOCKET_STATE_CONNECTED;
+}
+
+esp_err_t voicechat_websocket_register_events(sim_esp_websocket_client_handle_t client,
+                                        sim_esp_event_handler_t event_handler)
+{
+    if (client == NULL) {
+        return -1;
+    }
+       ESP_LOGD("client handler register success!!");
+       client->handler = event_handler;
+    return 0;
+}
+
+#endif
+