// 对话状态相关函数
int GetConversationStatus();
+ bool Get_is_all_services_ready();
+ void init_all_callback(void);
+
private:
ThunderBirdModel();
virtual ~ThunderBirdModel();
int m_networkType; // 网络类型
bool m_hasNetwork; // 网络连接标志位
bool m_networkStatusChanged; // 网络状态变化标志位
+
+ bool is_all_services_ready = false;
};
}
}
if(ThunderBirdModel::GetInstance()->IsTextEmpty() == true)
{
- UpdateDialogueText("保镖小姐 , 你来啦");
+ UpdateDialogueText("等待网络连接");
}
else
{
}
void ThunderBirdDialogueView::UpdateDialogueText(const char *text)
{
+ if(!TextLabel || !TextLabel_Y) return;
TextLabel->SetText(text);
TextLabel_Y->SetText(text);
}
#include "custom_runtime.h"
#include "ln_api.h"
#include "kv_store.h"
+
+ #define JUHEPINGTAI 1
+ #if JUHEPINGTAI
+ #include "websocket_server_manager.h"
+ #endif
namespace OHOS
{
enum OTA_STATUS
// 添加文本内容
m_currentTimeStr = textId;
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetTextStr: added text, current length: %zu", m_currentTimeStr.length());
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SetTextStr: added text, current length: %zu", m_currentTimeStr.length());
}
void ThunderBirdModel::ClearTextStr()
// 获取一下OTA 是否有最新版本
ota_update_boot();
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Network connected, calling HTTP service");
+ #if JUHEPINGTAI
+ uapi_init_all_websocket_servers();
+ uapi_start_all_websocket_servers(); // 连接服务器
+ #endif
} else {
// 网络断开,记录状态变化日志
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Network disconnected");
SetNetworkStatusChanged(false);
}
+ #if JUHEPINGTAI
+ if(is_all_services_ready == false)
+ {
+ if (are_all_services_ready())//如果返回的是true就可以开始对话了
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Network disconnected");
+ init_all_callback();
+ is_all_services_ready = true;
+ }
+ }
+ #endif
+
// 更新设备状态
UpdateDeviceStatus();
WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "StatusCallback: status=%d", static_cast<int>(m_currentStatus));
}
+
+ bool ThunderBirdModel::Get_is_all_services_ready()
+ {
+ return is_all_services_ready;
+ }
// ==================== 状态管理相关函数实现 ====================
/**
m_networkStatusChanged = changed;
}
+
+ void ws_register_chat_filter_cb(char *result)
+ {
+ }
+ void ws_register_ai_question_cb(char *buf)
+ {
+ }
+
+ void ws_register_ai_answer_cb(char *buf, uint8_t type)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ws_register_ai_answer_cb:%s\n", buf ? buf : "<null>");
+ if (buf && buf[0] != '\0') {
+ // 先写入文本,再置对话标志,避免UI读到标志已置但文本尚未更新
+ ThunderBirdModel::GetInstance()->SetTextStr(buf);
+ set_start_conversation_flag(START_CONVERSATION_FLAG_START);
+ } else {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ws_register_ai_answer_cb: empty buf, skip update");
+ }
+ }
+
+ void ThunderBirdModel::init_all_callback(void)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "init_all_callback\n");
+ // ws_register_chat_filter_callback(ws_register_chat_filter_cb);
+ // ws_register_ai_question_callback(ws_register_ai_question_cb);
+ ws_register_ai_answer_callback(ws_register_ai_answer_cb);
+ }
+
}
\ No newline at end of file
{
//判断是否为开始对话 如果是开始对话 则更新对话数据
if(ThunderBirdModel::GetInstance()->GetConversationStatus() == 1){
- //更新对话数据
- std::string dialogueText = ThunderBirdModel::GetInstance()->GetTextStr();
- //只有一行 是拼接 还是直接覆盖?
- ThunderBirdDialogueView::GetInstance()->UpdateDialogueText(dialogueText.c_str());
+ //更新对话数据
+ std::string dialogueText = ThunderBirdModel::GetInstance()->GetTextStr();
+ //只有一行 是拼接 还是直接覆盖?
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateDialogueText:%s\n",dialogueText.c_str());
+ ThunderBirdDialogueView::GetInstance()->UpdateDialogueText(dialogueText.c_str());
+ }
+ else{
+ //如果不是对话 需要判断 是否服务准备好
+ if(ThunderBirdModel::GetInstance()->Get_is_all_services_ready() == false)
+ {
+ ThunderBirdDialogueView::GetInstance()->UpdateDialogueText( "等待网络连接" );
+ }
+ else
+ {
+ ThunderBirdDialogueView::GetInstance()->UpdateDialogueText( "网络连接成功" );
+ }
}
}
}
*/
void ThunderBirdPresenter::HandleDialogueFunction(int16_t currentView, int16_t currentSubView)
{
+ bool flag = ThunderBirdModel::GetInstance()->Get_is_all_services_ready();
if (currentView == THUNDERBIRD_DIALOGUEVIEW &&
- currentSubView == ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_LISTENING) {
+ currentSubView == ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_LISTENING && flag == true) {
// 停止录音并发送
- ThunderBirdModel::GetInstance()->StopRecording();
+ // ThunderBirdModel::GetInstance()->StopRecording();
ThunderBirdMainView::GetInstance()->ChangeView(currentView, THUNDERBIRD_DIALOGUEVIEW, ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_SPEAKING);
- ThunderBirdModel::GetInstance()->SendRecording();
+ // ThunderBirdModel::GetInstance()->SendRecording();
+ uapi_stop_AI_asr();
} else {
// 开始录音
ThunderBirdMainView::GetInstance()->ChangeView(currentView, THUNDERBIRD_DIALOGUEVIEW, ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_LISTENING);
- ThunderBirdModel::GetInstance()->StartRecording();
+ // ThunderBirdModel::GetInstance()->StartRecording();
+ uapi_start_AI_asr();
}
}
tts_ready_status_t tts_is_ready = TTS_READY_NOT_SENT;
-/* 外部函数声明 */
+/* 可注册回调:通过管理器注册 */
+static void (*g_ai_question_cb)(char *buf) = NULL;
+static void (*g_ai_answer_cb)(char *buf, uint8_t type) = NULL;
+static void (*g_chat_filter_cb)(char *result) = NULL;
+
+/* 不再使用默认BLE回退,未注册时打印日志 */
extern void ble_set_ai_Question_str(char *str);
extern void ble_set_ai_Answer_str(char *str, uint8_t type);
extern int send_msg_data_into_Ai_msg_queue(void *data, uint16_t len, uint16_t type);
if(data.is_end)
{
ai_chat_send_txt(0, data.result_text, g_chat_server->client,false);
- ble_set_ai_Question_str(data.result_text);
+ if (g_ai_question_cb) g_ai_question_cb(data.result_text); else printf("[WS][ASR] ai_question 回调未注册,丢弃内容: %s\n", data.result_text);
}
break;
// 解析Chat结果
char buf[512]={0};
chat_event_type_t ret=chat_result_analysis((char*)event_data->data, buf, 512);
+ if (g_chat_filter_cb) {
+ g_chat_filter_cb(buf);
+ } else {
+ printf("[WS][CHAT] chat_filter_result_chars 未注册,使用原始内容\n");
+ }
// 根据事件类型进行处理
switch (ret) {
case CHAT_EVENT_MIDDLE:
printf("Chat event: MIDDLE - Content: %s\n", buf);
- ble_set_ai_Answer_str(buf, 2);
+ if (g_ai_answer_cb) g_ai_answer_cb(buf, 2); else printf("[WS][CHAT] ai_answer 回调未注册,丢弃内容: %s\n", buf);
uapi_tts_process_text(g_tts_server->client,buf,(tts_is_ready == TTS_READY_SUCCESS_READY));
break;
case CHAT_EVENT_END:
printf("Chat event: END - Final content: %s\n", buf);
- ble_set_ai_Answer_str(buf, 2);
+ if (g_ai_answer_cb) g_ai_answer_cb(buf, 2); else printf("[WS][CHAT] ai_answer 回调未注册,丢弃内容: %s\n", buf);
uapi_tts_process_text(g_tts_server->client,buf,(tts_is_ready == TTS_READY_SUCCESS_READY));
uapi_cache_stop_command(g_tts_server->client,(tts_is_ready == TTS_READY_SUCCESS_READY));
}
}
+/* 对外注册接口实现 */
+void ws_register_chat_filter_callback(chat_filter_result_chars_cb_t cb)
+{
+ g_chat_filter_cb = cb;
+}
+
+void ws_register_ai_question_callback(ai_question_cb_t cb)
+{
+ g_ai_question_cb = cb;
+}
+
+void ws_register_ai_answer_callback(ai_answer_cb_t cb)
+{
+ g_ai_answer_cb = cb;
+}
+
/**
* @brief 提取JSON内容(简化实现)
// ai_media_init();
old_Start_AIVoice(AIVoiceDataCallback_,nullptr);
+ /* 不进行默认回退注册,未注册时仅打印错误日志 */
+
printf("All WebSocket servers started successfully\n");
return ERRCODE_SUCC;
}
*/
uint8_t ws_server_get_interrupt_flag(ws_server_type_t server_type);
+/* ========================= AI 文本回调注册(新增) ========================= */
+/* 聊天结果过滤回调:可对结果字符串进行原地过滤/修改 */
+typedef void (*chat_filter_result_chars_cb_t)(char *result);
+/* BLE 问题/答案上报回调 */
+typedef void (*ai_question_cb_t)(char *buf);
+typedef void (*ai_answer_cb_t)(char *buf, uint8_t type);
+
+/* 注册接口(线程安全由调用方保证)*/
+void ws_register_chat_filter_callback(chat_filter_result_chars_cb_t cb);
+void ws_register_ai_question_callback(ai_question_cb_t cb);
+void ws_register_ai_answer_callback(ai_answer_cb_t cb);
+
#ifdef __cplusplus
}
{
if (client_data.contentBlockLen > 0)
{
+ printf("download mp3 file advanced: contentBlockLen=%d\n", client_data.contentBlockLen);
#if TEST_MP3_DOWNLOAD
/* 一边下载到文件,一边推送到播放器队列,尝试边下边播 */
size_t written = fwrite(client_data.responseBuf, 1, client_data.contentBlockLen, fd);
/* 非阻塞入队,队列满则忽略该块 */
//播放下载的音频
- (void)ln_audio_player_write((const uint8_t*)client_data.responseBuf, (uint32_t)client_data.contentBlockLen);
-
+ int ret = ln_audio_player_write((const uint8_t*)client_data.responseBuf, (uint32_t)client_data.contentBlockLen);
+ if (ret != 0)
+ {
+ printf("download mp3 file advanced: write failed, ret=%d\n", ret);
+ // 写失败重新写
+ LOS_Msleep(100);
+ ret = ln_audio_player_write((const uint8_t*)client_data.responseBuf, (uint32_t)client_data.contentBlockLen);
+ if (ret != 0)
+ {
+ printf("download mp3 file advanced: write failed, ret=%d\n", ret);
+ }
+ }
}
else
{
if (mail.cmd == LN_HTTP_SERVICE_CMD_GET_DEVICE_TOKEN)
{
printf("LN_HTTP_SERVICE_CMD_GET_DEVICE_TOKEN:获取雷鸟设备Token\n");
- uapi_ln_get_device_token();
+ uint32_t ret = ln_get_device_token_http(uapi_ln_get_device_id(), uapi_ln_get_device_iccid(), uapi_ln_get_device_model(), uapi_ln_get_device_version());
+ if (ret == ERRCODE_SUCC)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[LN_HTTP_SERVER_SEND_TASK] 获取雷鸟设备Token成功\n");
+ ret = ln_ws_start(ln_ws_process_message);
+ if (ret != 0)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[LN_HTTP_SERVER_SEND_TASK] 启动WebSocket失败: %d\n", ret);
+ }
+ }
+ else
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[LN_HTTP_SERVER_SEND_TASK] 获取雷鸟设备Token失败\n");
+ }
}
else if (mail.cmd == LN_HTTP_SERVICE_CMD_SPEECH_CHAT_STREAM)
{
//推送给ui
if(mail.data)
{
- push_text_to_ui(mail.data);
}
} else if (mail.cmd == LN_HTTP_RECV_STORY_CHOOSE) {
tag = "STORY_CHOOSE";
//推送给ui
if(mail.data)
{
- push_text_to_ui(mail.data);
}
} else if (mail.cmd == LN_HTTP_RECV_STORY_RANDOM) {
tag = "STORY_RANDOM";
//推送给ui
if(mail.data)
{
- push_text_to_ui(mail.data);
}
} else if (mail.cmd == LN_HTTP_RECV_STORY_EXIT) {
tag = "STORY_EXIT";
/* 不中断HTTP服务,按需可返回失败 */
}
- /* 创建WebSocket自动启动任务:每3秒检测一次网络并启动WS */
- ln_ws_autostart_taskcfg.create_queue_handle = NULL;
- ln_ws_autostart_taskcfg.attr.name = "ln_ws_autostart_task";
- ln_ws_autostart_taskcfg.attr.priority = osPriorityNormal;
- ln_ws_autostart_taskcfg.attr.stack_size = 0x500;
- ln_ws_autostart_taskcfg.func = ln_ws_autostart_task;
- ln_ws_autostart_taskcfg.use_mem = USE_EXTEND_MEM;
- (void)uapi_create_osThread_custom(&ln_ws_autostart_taskcfg);
+ // /* 创建WebSocket自动启动任务:每3秒检测一次网络并启动WS */
+ // ln_ws_autostart_taskcfg.create_queue_handle = NULL;
+ // ln_ws_autostart_taskcfg.attr.name = "ln_ws_autostart_task";
+ // ln_ws_autostart_taskcfg.attr.priority = osPriorityNormal;
+ // ln_ws_autostart_taskcfg.attr.stack_size = 0x1000;
+ // ln_ws_autostart_taskcfg.func = ln_ws_autostart_task;
+ // ln_ws_autostart_taskcfg.use_mem = USE_EXTEND_MEM;
+ // (void)uapi_create_osThread_custom(&ln_ws_autostart_taskcfg);
return ERRCODE_SUCC;
}