}
cJSON_Delete(root);
}
+/* ============================ WebSocket 业务消息 上层处理 End============================ */
-// 发送队列
-static void ln_http_server_send_task(void const *arg)
+
+
+
+/* ============================ mp3下载功能 ============================ */
+
+/**
+ * 高级MP3下载函数,支持自定义保存目录和文件名
+ * @param audio_url 音频文件URL
+ * @param save_dir 保存目录
+ * @param filename 文件名(不包含路径)
+ * @return ERRCODE_SUCC 成功,ERRCODE_FAIL 失败
+ */
+static uint32_t ln_download_mp3_file_advanced(const char *audio_url, const char *save_dir, const char *filename)
{
- errcode_t ret;
+ if (!audio_url || !save_dir || !filename)
+ {
+ printf("[SSE] download_mp3_advanced: invalid parameters\n");
+ return ERRCODE_FAIL;
+ }
- ln_http_data_mail_t mail = {0};
- uint32_t msgsize = sizeof(ln_http_data_mail_t);
+ // 构建完整保存路径
+ char save_path[512];
+ snprintf(save_path, sizeof(save_path), "%s/%s", save_dir, filename);
- while (1)
+ // 确保目录存在
+ if (access(save_dir, F_OK) == -1)
{
- ret = osal_msg_queue_read_copy(g_ln_send_queue, (void *)&mail, &msgsize,
- OSAL_MSGQ_WAIT_FOREVER);
- if (ret != OSAL_SUCCESS)
- {
- continue;
- }
- if (mail.cmd == LN_HTTP_SERVICE_CMD_GET_DEVICE_TOKEN)
- {
- if (mail.data != NULL && mail.len == sizeof(ln_device_token_req_t))
- {
- printf("LN_HTTP_SERVICE_CMD_GET_DEVICE_TOKEN:获取雷鸟设备Token\n");
- ln_device_token_req_t req;
- memcpy(&req, mail.data, sizeof(req));
- ln_get_device_token_http(req.device_id, req.device_iccid, req.device_model, req.device_version);
- }
- }
- else if (mail.cmd == LN_HTTP_SERVICE_CMD_SPEECH_CHAT_STREAM)
- {
- if (mail.data != NULL && mail.len == sizeof(ln_speech_chat_req_t))
- {
- printf("LN_HTTP_SERVICE_CMD_SPEECH_CHAT_STREAM\n");
- ln_speech_chat_req_t req;
- memcpy(&req, mail.data, sizeof(req));
- ln_speech_chat_stream_http(req.device_id, req.device_token, req.audio_path);
- }
- }
- else if (mail.cmd == LN_HTTP_SERVICE_CMD_STORY_CHOOSE)
- {
- if (mail.data && mail.len == sizeof(ln_story_choose_req_t)) {
- printf("LN_HTTP_SERVICE_CMD_STORY_CHOOSE:选择故事\n");
- ln_story_choose_req_t req; memcpy(&req, mail.data, sizeof(req));
- ln_story_choose_http(uapi_ln_get_device_id(), uapi_ln_get_device_token(), req.audio_path);
- }
- }
- else if (mail.cmd == LN_HTTP_SERVICE_CMD_STORY_RANDOM)
- {
- if (mail.data && mail.len == sizeof(ln_story_random_req_t)) {
- printf("LN_HTTP_SERVICE_CMD_STORY_RANDOM:随机故事\n");
- ln_story_random_req_t req; memcpy(&req, mail.data, sizeof(req));
- ln_story_random_http(uapi_ln_get_device_id(), uapi_ln_get_device_token(), req.story_theme[0] ? req.story_theme : NULL);
- }
- }
- else if (mail.cmd == LN_HTTP_SERVICE_CMD_STORY_EXIT_INQUIRY)
- {
- printf("LN_HTTP_SERVICE_CMD_STORY_EXIT_INQUIRY:获取退出哄睡询问\n");
- ln_story_exit_inquiry_http(uapi_ln_get_device_id(), uapi_ln_get_device_token());
- }
- else if (mail.cmd == LN_HTTP_SERVICE_CMD_STORY_FINISH)
- {
- printf("LN_HTTP_SERVICE_CMD_STORY_FINISH:确认结束哄睡\n");
- ln_story_finish_http(uapi_ln_get_device_id(), uapi_ln_get_device_token());
- }
- else if (mail.cmd == LN_HTTP_SERVICE_CMD_GET_CHARACTER)
- {
- printf("LN_HTTP_SERVICE_CMD_GET_CHARACTER:获取设备角色信息\n");
- ln_device_get_character_http(uapi_ln_get_device_id(), uapi_ln_get_device_token());
- }
- else if (mail.cmd == LN_HTTP_SERVICE_CMD_GET_USER_ID)
- {
- printf("LN_HTTP_SERVICE_CMD_GET_USER_ID:获取设备绑定用户ID\n");
- ln_device_get_user_id_http(uapi_ln_get_device_id(), uapi_ln_get_device_token());
- }
- else if (mail.cmd == LN_HTTP_SERVICE_CMD_OTA_GET_TASK)
- {
- printf("LN_HTTP_SERVICE_CMD_OTA_GET_TASK:获取OTA升级任务\n");
- ln_ota_get_task_http(uapi_ln_get_device_id(), uapi_ln_get_device_token(), uapi_ln_get_device_version());
- }
- else if (mail.cmd == LN_HTTP_SERVICE_CMD_OTA_DOWNLOAD)
- {
- printf("LN_HTTP_SERVICE_CMD_OTA_DOWNLOAD:下载OTA升级包\n");
- ln_ota_download_flow_http(uapi_ln_get_device_id(), uapi_ln_get_device_token(), uapi_ln_get_device_version());
- }
- else if (mail.cmd == LN_HTTP_SERVICE_CMD_AUDIO_PLAY)
- {
- printf("LN_HTTP_SERVICE_CMD_AUDIO_PLAY:播放音频\n");
- #ifdef BOARD_N9
- if (ln_story_player_simple_start("/user/leiniao/story/choose"))
- {
- printf("播放开始成功\n");
- }
- #endif
- }
- else if (mail.cmd == LN_HTTP_SERVICE_CMD_AUDIO_STOP)
- {
- printf("LN_HTTP_SERVICE_CMD_AUDIO_STOP:停止播放音频\n");
- #ifdef BOARD_N9
- ln_story_player_simple_stop();
- #endif
- }
- else if (mail.cmd == LN_HTTP_SERVICE_CMD_AUDIO_PLAY_NEXT)
- {
- printf("LN_HTTP_SERVICE_CMD_AUDIO_PLAY_NEXT:播放下一首\n");
- #ifdef BOARD_N9
- ln_story_player_simple_handle_message(LN_HTTP_SERVICE_CMD_AUDIO_PLAY_NEXT, NULL, 0);
- #endif
- }
- else if (mail.cmd == LN_HTTP_SERVICE_CMD_AUDIO_PLAY_FILE)
+ uapi_create_folder(save_dir);
+ }
+
+ printf("[SSE] downloading MP3: %s -> %s\n", audio_url, save_path);
+
+ #ifdef SUPPORT_CAT1_SERVICE
+ /* CAT1 网络保活处理 */
+ cat1_api_add_cat1_vote();
+ cat1_api_wakeup_cat1(1);
+ cat1_api_keep_wakeup(1);
+ cat1_api_disable_cat1_cmd(0);
+ LOS_Msleep(300);
+ #endif
+
+ HttpClient client = {0};
+ HttpClientData client_data = {0};
+ int ret = -1;
+ size_t total_written = 0;
+
+ // 打开文件准备写入
+ FILE *fd = fopen(save_path, "wb");
+ if (!fd)
+ {
+ printf("[SSE] fopen failed for %s\n", save_path);
+ return ERRCODE_FAIL;
+ }
+
+ HTTPC_RESULT prep = ln_http_prepare_auto(&client_data, 2048, LN_CLIENT_PREPARE_SIZE * 2);
+ if (prep != HTTP_SUCCESS)
+ {
+ printf("[SSE] prepare failed: %d\n", prep);
+ fclose(fd);
+ return ERRCODE_FAIL;
+ }
+
+ // 建立连接
+ ret = HttpClientConn(&client, audio_url);
+ if (ret != 0)
+ {
+ printf("[SSE] connection failed, ret=0x%x\n", ret);
+ fclose(fd);
+ HttpClientUnprepare(&client_data);
+ return ERRCODE_FAIL;
+ }
+
+ // 发送GET请求
+ ret = HttpClientSend(&client, audio_url, HTTP_GET, &client_data);
+ if (ret != 0)
+ {
+ printf("[SSE] send request failed, ret=0x%x\n", ret);
+ fclose(fd);
+ HttpClientClse(&client);
+ HttpClientUnprepare(&client_data);
+ return ERRCODE_FAIL;
+ }
+
+ // 接收响应数据
+ do
+ {
+ HTTPC_RESULT recv_res = HttpClientRecvResponse(&client, &client_data);
+ if (recv_res == HTTP_SUCCESS || recv_res == HTTP_EAGAIN)
{
- printf("LN_HTTP_SERVICE_CMD_AUDIO_PLAY_FILE:播放指定文件\n");
- #ifdef BOARD_N9
- if (mail.data != NULL)
+ if (client_data.contentBlockLen > 0)
{
- char *file_path = (char*)mail.data;
- printf("Playing file: %s\n", file_path);
- if (ln_story_player_simple_play_file(file_path))
- {
- printf("File playback started successfully\n");
- }
- else
+ /* 一边下载到文件,一边推送到播放器队列,尝试边下边播 */
+ size_t written = fwrite(client_data.responseBuf, 1, client_data.contentBlockLen, fd);
+ if (written != client_data.contentBlockLen)
{
- printf("Failed to start file playback\n");
+ printf("[SSE] write failed, written=%zu, expected=%d\n",
+ written, client_data.contentBlockLen);
+ fclose(fd);
+ HttpClientClse(&client);
+ HttpClientUnprepare(&client_data);
+ return ERRCODE_FAIL;
}
+
+ /* 非阻塞入队,队列满则忽略该块 */
+ (void)ln_audio_player_write((const uint8_t*)client_data.responseBuf, (uint32_t)client_data.contentBlockLen);
+
+ total_written += written;
}
- else
- {
- printf("Error: No file path provided\n");
- }
- #endif
- }
- else if (mail.cmd == LN_HTTP_SERVICE_CMD_AUDIO_PAUSE)
- {
- printf("LN_HTTP_SERVICE_CMD_AUDIO_PAUSE:暂停播放\n");
- #ifdef BOARD_N9
- if (ln_story_player_simple_pause())
- {
- printf("Playback paused successfully\n");
- }
- else
- {
- printf("Failed to pause playback\n");
- }
- #endif
- }
- else if (mail.cmd == LN_HTTP_SERVICE_CMD_AUDIO_RESUME)
- {
- printf("LN_HTTP_SERVICE_CMD_AUDIO_RESUME:恢复播放\n");
- #ifdef BOARD_N9
- if (ln_story_player_simple_resume())
- {
- printf("Playback resumed successfully\n");
- }
- else
- {
- printf("Failed to resume playback\n");
- }
- #endif
}
- if (mail.data != NULL)
+ else
{
- printf("free(mail.data)\n");
- free(mail.data);
+ printf("[SSE] receive ended (code: %d)\n", recv_res);
+ break;
}
- }
+ } while (client_data.isMore);
+
+ fclose(fd);
+ HttpClientUnprepare(&client_data);
+ HttpClientClse(&client);
+
+ printf("[SSE] download completed, total bytes: %zu\n", total_written);
+ return ERRCODE_SUCC;
}
-// 接收队列
-static void ln_http_server_recv_task(void const *arg)
+/**
+ * 解析JSON数据,下载MP3并推送消息
+ * @param json_data JSON数据字符串
+ * @param interface_type 接口类型
+ * @param segment_index 片段索引
+ * @return ERRCODE_SUCC 成功,ERRCODE_FAIL 失败
+ */
+static uint32_t ln_parse_and_process_json_data(const char *json_data, int interface_type, int segment_index)
{
- errcode_t ret;
+ if (!json_data)
+ {
+ printf("[JSON_PARSE] invalid json_data\n");
+ return ERRCODE_FAIL;
+ }
- ln_http_data_mail_t mail = {0};
- uint32_t msgsize = sizeof(ln_http_data_mail_t);
+ printf("[JSON_PARSE] parsing JSON data (interface_type=%d, segment=%d): %s\n",
+ interface_type, segment_index, json_data);
- while (1)
+ // 解析JSON数据
+ cJSON *root = cJSON_Parse(json_data);
+ if (!root)
{
- ret = osal_msg_queue_read_copy(g_ln_recv_queue, (void *)&mail, &msgsize,
- OSAL_MSGQ_WAIT_FOREVER);
- if (ret != OSAL_SUCCESS)
- {
- continue;
- }
+ printf("[JSON_PARSE] JSON parse failed: %s\n", json_data);
+ return ERRCODE_FAIL;
+ }
- // 消息有效性检查
- if (!mail.data || mail.len <= 0)
- {
- continue;
- }
+ // 检查是否有错误
+ cJSON *errorCode = cJSON_GetObjectItem(root, "errorCode");
+ if (errorCode && !cJSON_IsNull(errorCode))
+ {
+ printf("[JSON_PARSE] server error: %s\n",
+ cJSON_IsString(errorCode) ? errorCode->valuestring : "unknown");
+ cJSON_Delete(root);
+ return ERRCODE_FAIL;
+ }
- // 分类处理消息
- const char *tag = "UNKNOWN";
- if (mail.cmd == LN_HTTP_SERVICE_CMD_SSE_RECV) {
- tag = "SPEECH_CHAT";
- } else if (mail.cmd == LN_HTTP_RECV_STORY_CHOOSE) {
- tag = "STORY_CHOOSE";
- } else if (mail.cmd == LN_HTTP_RECV_STORY_RANDOM) {
- tag = "STORY_RANDOM";
- } else if (mail.cmd == LN_HTTP_RECV_STORY_EXIT) {
- tag = "STORY_EXIT";
- } else if (mail.cmd == LN_HTTP_RECV_STORY_FINISH) {
- tag = "STORY_FINISH";
- } else if (mail.cmd == LN_HTTP_RECV_DEVICE_CHARACTER) {
- tag = "DEVICE_CHARACTER";
- } else if (mail.cmd == LN_HTTP_RECV_DEVICE_USER_ID) {
- tag = "DEVICE_USER_ID";
- } else if (mail.cmd == LN_HTTP_RECV_OTA_TASK) {
- tag = "OTA_TASK";
- } else if (mail.cmd == LN_HTTP_RECV_OTA_DOWNLOAD_MSG) {
- tag = "OTA_DOWNLOAD_MSG";
- }
+ // 获取data字段
+ cJSON *data = cJSON_GetObjectItem(root, "data");
+ if (!data || !cJSON_IsObject(data))
+ {
+ printf("[JSON_PARSE] no data field found\n");
+ cJSON_Delete(root);
+ return ERRCODE_FAIL;
+ }
- printf("[%s] 数据长度: %u\n", tag, mail.len);
- /* 确保可打印:追加\0 */
- char *buf = (char *)malloc(mail.len + 1);
- if (buf) {
- memcpy(buf, mail.data, mail.len);
- buf[mail.len] = '\0';
- printf("[%s] 原始数据:%s\n", tag, buf);
- /* 在收到 OTA_TASK 后,根据升级策略决定是否触发下载 */
- if (mail.cmd == LN_HTTP_RECV_OTA_TASK) {
- ln_handle_ota_task_response(buf, (int)mail.len);
- }
- /* 在收到 OTA_DOWNLOAD_MSG 后,解析状态并回调处理(进度/完成/失败) */
- if (mail.cmd == LN_HTTP_RECV_OTA_DOWNLOAD_MSG) {
- OtaDownloadMsg m = {0};
- if (parse_ota_download_msg(buf, &m) == 0) {
- handle_ota_download_msg(&m);
- }
- }
- free(buf);
+ // 根据接口类型获取音频URL
+ char *audio_url = NULL;
+ if (interface_type == LN_HTTP_SERVICE_CMD_SSE_RECV)
+ {
+ // 语音对话接口:使用 audioUrl 字段
+ cJSON *audioUrl = cJSON_GetObjectItem(data, "audioUrl");
+ if (audioUrl && cJSON_IsString(audioUrl))
+ {
+ audio_url = audioUrl->valuestring;
}
}
-}
-
-static void create_ln_http_send_queue(void)
-{
- if (osal_msg_queue_create("ln_http_send_queue", 24, &g_ln_send_queue,
- 0, sizeof(ln_http_data_mail_t)) != ERRCODE_SUCC)
+ else if (interface_type == LN_HTTP_RECV_STORY_CHOOSE || interface_type == LN_HTTP_RECV_STORY_RANDOM)
{
- printf("[ln][service] app create mail fail\n");
+ // 故事接口:使用 storyAudioUrl 字段
+ cJSON *storyAudioUrl = cJSON_GetObjectItem(data, "storyAudioUrl");
+ if (storyAudioUrl && cJSON_IsString(storyAudioUrl))
+ {
+ audio_url = storyAudioUrl->valuestring;
+ }
}
-}
-
-static void create_ln_http_recv_queue(void)
-{
- if (osal_msg_queue_create("ln_http_recv_queue", 24, &g_ln_recv_queue,
- 0, sizeof(ln_http_data_mail_t)) != ERRCODE_SUCC)
+ else
{
- printf("[ln][service] app create mail fail\n");
+ // 默认尝试 audioUrl 字段
+ cJSON *audioUrl = cJSON_GetObjectItem(data, "audioUrl");
+ if (audioUrl && cJSON_IsString(audioUrl))
+ {
+ audio_url = audioUrl->valuestring;
+ }
}
-}
-// 雷鸟http服务初始化
-errcode_t uapi_ln_http_server_init(void)
-{
- printf("uapi_ln_http_server_init !\r\n");
-
- ln_send_taskcfg.create_queue_handle = create_ln_http_send_queue;
- ln_send_taskcfg.attr.name = "ln_http_server_send_task";
- ln_send_taskcfg.attr.priority = osPriorityNormal;
- ln_send_taskcfg.attr.stack_size = LN_HTTP_BOARD_TASK_SIZE;
- ln_send_taskcfg.func = ln_http_server_send_task;
- ln_send_taskcfg.use_mem = USE_EXTEND_MEM;
-
- errcode_t ret = uapi_create_osThread_custom(&ln_send_taskcfg);
- if (ret != ERRCODE_SUCC)
+ // 获取textContent
+ cJSON *textContent = cJSON_GetObjectItem(data, "textContent");
+ char *text_content = NULL;
+ if (textContent && cJSON_IsString(textContent))
{
- printf("create ln_send_service failed %d!\r\n", ret);
- return ERRCODE_FAIL;
+ text_content = textContent->valuestring;
}
- ln_recv_taskcfg.create_queue_handle = create_ln_http_recv_queue;
- ln_recv_taskcfg.attr.name = "ln_http_server_recv_task";
- ln_recv_taskcfg.attr.priority = osPriorityNormal;
- ln_recv_taskcfg.attr.stack_size = LN_HTTP_BOARD_TASK_SIZE;
- ln_recv_taskcfg.func = ln_http_server_recv_task;
- ln_recv_taskcfg.use_mem = USE_EXTEND_MEM;
-
- ret = uapi_create_osThread_custom(&ln_recv_taskcfg);
- if (ret != ERRCODE_SUCC)
+ // 获取intention
+ cJSON *intention = cJSON_GetObjectItem(data, "intention");
+ char *intention_str = NULL;
+ if (intention && cJSON_IsString(intention))
{
- printf("create gnss_recv_service failed %d!\r\n", ret);
- return ERRCODE_FAIL;
+ intention_str = intention->valuestring;
}
- /* 初始化音频播放器(流式输出) */
- if (ln_audio_player_init() != ERRCODE_SUCC)
+ // 获取storyTheme(故事接口特有)
+ cJSON *storyTheme = cJSON_GetObjectItem(data, "storyTheme");
+ char *story_theme = NULL;
+ if (storyTheme && cJSON_IsString(storyTheme))
{
- printf("[LN_AUDIO] init failed in http server init\n");
- /* 不中断HTTP服务,按需可返回失败 */
+ story_theme = storyTheme->valuestring;
}
- return ERRCODE_SUCC;
-}
+ // 获取storyContent(故事接口特有)
+ cJSON *storyContent = cJSON_GetObjectItem(data, "storyContent");
+ char *story_content = NULL;
+ if (storyContent && cJSON_IsString(storyContent))
+ {
+ story_content = storyContent->valuestring;
+ }
-/* 通用发送接口:向 LN HTTP 发送队列投递消息 */
-void do_ln_http_server_send_data(int cmd, char *data, uint32_t len)
-{
- errcode_t ret;
- ln_http_data_mail_t send_data = {0};
- send_data.cmd = cmd;
- if (len && data)
+ // 创建推送数据
+ cJSON *push_data = cJSON_CreateObject();
+
+ // 根据接口类型添加相应字段
+ if (text_content && strlen(text_content) > 0)
{
- send_data.len = len;
- send_data.data = (char *)malloc(len);
- if (send_data.data == NULL)
- {
- printf("malloc failed\n");
- return;
- }
- memcpy(send_data.data, data, len);
+ cJSON_AddStringToObject(push_data, "textContent", text_content);
+ }
+
+ if (story_content && strlen(story_content) > 0)
+ {
+ cJSON_AddStringToObject(push_data, "storyContent", story_content);
+ }
+
+ if (intention_str && strlen(intention_str) > 0)
+ {
+ cJSON_AddStringToObject(push_data, "intention", intention_str);
+ }
+
+ if (story_theme && strlen(story_theme) > 0)
+ {
+ cJSON_AddStringToObject(push_data, "storyTheme", story_theme);
}
- uint32_t send_len = sizeof(send_data);
-
- ret = osal_msg_queue_write_copy(g_ln_send_queue, (void *)&send_data,
- send_len, 0);
- if (ret != OSAL_SUCCESS)
+ // 推送到相应的接收线程
+ char *json_string = cJSON_Print(push_data);
+ if (json_string)
{
- printf("Error ln http send failed! err=0x%x! \r\n", ret);
+ printf("[JSON_PARSE] pushing data to interface_type=%d: %s\n", interface_type, json_string);
+ do_ln_http_server_recv_data(interface_type, json_string, strlen(json_string));
+ free(json_string);
}
-}
+ cJSON_Delete(push_data);
-/* 通用接收接口:向 LN HTTP 接收队列投递消息 */
-void do_ln_http_server_recv_data(int cmd, char *data, uint32_t len)
-{
- errcode_t ret;
- ln_http_data_mail_t recv_data = {0};
- recv_data.cmd = cmd;
- if (len && data)
+ // 下载音频文件
+ if (audio_url && strlen(audio_url) > 0)
{
- recv_data.len = len;
- recv_data.data = (char *)malloc(len);
- if (recv_data.data == NULL)
+ char save_dir[256];
+ char filename[128];
+
+ // 根据接口类型确定保存目录和文件名
+ switch (interface_type)
{
- printf("malloc failed\n");
- return;
+ case LN_HTTP_SERVICE_CMD_SSE_RECV:
+ snprintf(save_dir, sizeof(save_dir), "%s/speech", LN_DATA_PATH);
+ snprintf(filename, sizeof(filename), "%d.mp3", segment_index);
+ break;
+ case LN_HTTP_RECV_STORY_CHOOSE:
+ snprintf(save_dir, sizeof(save_dir), "%s/story/choose", LN_DATA_PATH);
+ snprintf(filename, sizeof(filename), "%d.mp3", segment_index);
+ break;
+ case LN_HTTP_RECV_STORY_RANDOM:
+ snprintf(save_dir, sizeof(save_dir), "%s/story/random", LN_DATA_PATH);
+ snprintf(filename, sizeof(filename), "%d.mp3", segment_index);
+ break;
+ default:
+ snprintf(save_dir, sizeof(save_dir), "%s", LN_DATA_PATH);
+ snprintf(filename, sizeof(filename), "%d.mp3", segment_index);
+ break;
}
- memcpy(recv_data.data, data, len);
- }
-
- uint32_t send_len = sizeof(recv_data);
- ret = osal_msg_queue_write_copy(g_ln_recv_queue, (void *)&recv_data,
- send_len, 0);
- if (ret != OSAL_SUCCESS)
+ printf("[JSON_PARSE] found audio URL (interface_type=%d): %s\n", interface_type, audio_url);
+ printf("[JSON_PARSE] downloading audio to: %s/%s\n", save_dir, filename);
+
+ uint32_t download_result = ln_download_mp3_file_advanced(audio_url, save_dir, filename);
+ if (download_result == ERRCODE_SUCC)
+ {
+ printf("[JSON_PARSE] audio downloaded successfully: %s/%s\n", save_dir, filename);
+ }
+ else
+ {
+ printf("[JSON_PARSE] audio download failed\n");
+ }
+ }
+ else
{
- printf("Error ln http recv send failed! err=0x%x! \r\n", ret);
- if (recv_data.data) free(recv_data.data);
+ printf("[JSON_PARSE] no audio URL found for interface_type=%d, skipping download\n", interface_type);
}
-}
+ cJSON_Delete(root);
+ return ERRCODE_SUCC;
+}
/**
- * 高级MP3下载函数,支持自定义保存目录和文件名
- * @param audio_url 音频文件URL
- * @param save_dir 保存目录
- * @param filename 文件名(不包含路径)
+ * 从文件中解析data数据,下载MP3并推送消息
+ * @param file_path 文件路径
+ * @param interface_type 接口类型
* @return ERRCODE_SUCC 成功,ERRCODE_FAIL 失败
*/
-static uint32_t ln_download_mp3_file_advanced(const char *audio_url, const char *save_dir, const char *filename)
+uint32_t ln_parse_file_and_process_data(const char *file_path, int interface_type)
{
- if (!audio_url || !save_dir || !filename)
+ if (!file_path)
{
- printf("[SSE] download_mp3_advanced: invalid parameters\n");
+ printf("[FILE_PARSE] invalid file path\n");
return ERRCODE_FAIL;
}
- // 构建完整保存路径
- char save_path[512];
- snprintf(save_path, sizeof(save_path), "%s/%s", save_dir, filename);
+ printf("[FILE_PARSE] processing file: %s (interface_type=%d)\n", file_path, interface_type);
- // 确保目录存在
- if (access(save_dir, F_OK) == -1)
+ FILE *fp = fopen(file_path, "r");
+ if (!fp)
{
- uapi_create_folder(save_dir);
+ printf("[FILE_PARSE] failed to open file: %s\n", file_path);
+ return ERRCODE_FAIL;
}
- printf("[SSE] downloading MP3: %s -> %s\n", audio_url, save_path);
+ char line[2048];
+ int line_count = 0;
+ int success_count = 0;
+ int error_count = 0;
- #ifdef SUPPORT_CAT1_SERVICE
- /* CAT1 网络保活处理 */
- cat1_api_add_cat1_vote();
- cat1_api_wakeup_cat1(1);
- cat1_api_keep_wakeup(1);
- cat1_api_disable_cat1_cmd(0);
- LOS_Msleep(300);
- #endif
+ while (fgets(line, sizeof(line), fp))
+ {
+ line_count++;
+
+ // 去除行尾的换行符
+ size_t len = strlen(line);
+ if (len > 0 && line[len - 1] == '\n')
+ {
+ line[len - 1] = '\0';
+ len--;
+ }
+ if (len > 0 && line[len - 1] == '\r')
+ {
+ line[len - 1] = '\0';
+ len--;
+ }
- HttpClient client = {0};
- HttpClientData client_data = {0};
- int ret = -1;
- size_t total_written = 0;
+ // 跳过空行
+ if (len == 0)
+ {
+ continue;
+ }
- // 打开文件准备写入
- FILE *fd = fopen(save_path, "wb");
- if (!fd)
- {
- printf("[SSE] fopen failed for %s\n", save_path);
- return ERRCODE_FAIL;
- }
+ // 检查是否是SSE数据格式 (data: {...})
+ if (strncmp(line, "data:", 5) == 0)
+ {
+ char *json_start = line + 5;
+ // 跳过可能的空格
+ while (*json_start == ' ' || *json_start == '\t')
+ {
+ json_start++;
+ }
- HTTPC_RESULT prep = ln_http_prepare_auto(&client_data, 2048, LN_CLIENT_PREPARE_SIZE * 2);
- if (prep != HTTP_SUCCESS)
- {
- printf("[SSE] prepare failed: %d\n", prep);
- fclose(fd);
- return ERRCODE_FAIL;
+ printf("[FILE_PARSE] line %d: processing JSON: %s\n", line_count, json_start);
+
+ uint32_t result = ln_parse_and_process_json_data(json_start, interface_type, line_count);
+ if (result == ERRCODE_SUCC)
+ {
+ success_count++;
+ }
+ else
+ {
+ error_count++;
+ }
+ }
+ else
+ {
+ printf("[FILE_PARSE] line %d: invalid format (not SSE data): %s\n", line_count, line);
+ error_count++;
+ }
}
- // 建立连接
- ret = HttpClientConn(&client, audio_url);
- if (ret != 0)
- {
- printf("[SSE] connection failed, ret=0x%x\n", ret);
- fclose(fd);
- HttpClientUnprepare(&client_data);
- return ERRCODE_FAIL;
- }
+ fclose(fp);
- // 发送GET请求
- ret = HttpClientSend(&client, audio_url, HTTP_GET, &client_data);
- if (ret != 0)
- {
- printf("[SSE] send request failed, ret=0x%x\n", ret);
- fclose(fd);
- HttpClientClse(&client);
- HttpClientUnprepare(&client_data);
- return ERRCODE_FAIL;
- }
+ printf("[FILE_PARSE] processing completed: total lines=%d, success=%d, errors=%d\n",
+ line_count, success_count, error_count);
- // 接收响应数据
- do
+ return (error_count == 0) ? ERRCODE_SUCC : ERRCODE_FAIL;
+}
+/* ============================ mp3下载功能 End ============================ */
+
+/* ============================ 队列相关代码 ============================ */
+// 发送队列
+static void ln_http_server_send_task(void const *arg)
+{
+ errcode_t ret;
+
+ ln_http_data_mail_t mail = {0};
+ uint32_t msgsize = sizeof(ln_http_data_mail_t);
+
+ while (1)
{
- HTTPC_RESULT recv_res = HttpClientRecvResponse(&client, &client_data);
- if (recv_res == HTTP_SUCCESS || recv_res == HTTP_EAGAIN)
+ ret = osal_msg_queue_read_copy(g_ln_send_queue, (void *)&mail, &msgsize,
+ OSAL_MSGQ_WAIT_FOREVER);
+ if (ret != OSAL_SUCCESS)
+ {
+ continue;
+ }
+ if (mail.cmd == LN_HTTP_SERVICE_CMD_GET_DEVICE_TOKEN)
+ {
+ if (mail.data != NULL && mail.len == sizeof(ln_device_token_req_t))
+ {
+ printf("LN_HTTP_SERVICE_CMD_GET_DEVICE_TOKEN:获取雷鸟设备Token\n");
+ ln_device_token_req_t req;
+ memcpy(&req, mail.data, sizeof(req));
+ ln_get_device_token_http(req.device_id, req.device_iccid, req.device_model, req.device_version);
+ }
+ }
+ else if (mail.cmd == LN_HTTP_SERVICE_CMD_SPEECH_CHAT_STREAM)
+ {
+ if (mail.data != NULL && mail.len == sizeof(ln_speech_chat_req_t))
+ {
+ printf("LN_HTTP_SERVICE_CMD_SPEECH_CHAT_STREAM\n");
+ ln_speech_chat_req_t req;
+ memcpy(&req, mail.data, sizeof(req));
+ ln_speech_chat_stream_http(req.device_id, req.device_token, req.audio_path);
+ }
+ }
+ else if (mail.cmd == LN_HTTP_SERVICE_CMD_STORY_CHOOSE)
+ {
+ if (mail.data && mail.len == sizeof(ln_story_choose_req_t)) {
+ printf("LN_HTTP_SERVICE_CMD_STORY_CHOOSE:选择故事\n");
+ ln_story_choose_req_t req; memcpy(&req, mail.data, sizeof(req));
+ ln_story_choose_http(uapi_ln_get_device_id(), uapi_ln_get_device_token(), req.audio_path);
+ }
+ }
+ else if (mail.cmd == LN_HTTP_SERVICE_CMD_STORY_RANDOM)
{
- if (client_data.contentBlockLen > 0)
+ if (mail.data && mail.len == sizeof(ln_story_random_req_t)) {
+ printf("LN_HTTP_SERVICE_CMD_STORY_RANDOM:随机故事\n");
+ ln_story_random_req_t req; memcpy(&req, mail.data, sizeof(req));
+ ln_story_random_http(uapi_ln_get_device_id(), uapi_ln_get_device_token(), req.story_theme[0] ? req.story_theme : NULL);
+ }
+ }
+ else if (mail.cmd == LN_HTTP_SERVICE_CMD_STORY_EXIT_INQUIRY)
+ {
+ printf("LN_HTTP_SERVICE_CMD_STORY_EXIT_INQUIRY:获取退出哄睡询问\n");
+ ln_story_exit_inquiry_http(uapi_ln_get_device_id(), uapi_ln_get_device_token());
+ }
+ else if (mail.cmd == LN_HTTP_SERVICE_CMD_STORY_FINISH)
+ {
+ printf("LN_HTTP_SERVICE_CMD_STORY_FINISH:确认结束哄睡\n");
+ ln_story_finish_http(uapi_ln_get_device_id(), uapi_ln_get_device_token());
+ }
+ else if (mail.cmd == LN_HTTP_SERVICE_CMD_GET_CHARACTER)
+ {
+ printf("LN_HTTP_SERVICE_CMD_GET_CHARACTER:获取设备角色信息\n");
+ ln_device_get_character_http(uapi_ln_get_device_id(), uapi_ln_get_device_token());
+ }
+ else if (mail.cmd == LN_HTTP_SERVICE_CMD_GET_USER_ID)
+ {
+ printf("LN_HTTP_SERVICE_CMD_GET_USER_ID:获取设备绑定用户ID\n");
+ ln_device_get_user_id_http(uapi_ln_get_device_id(), uapi_ln_get_device_token());
+ }
+ else if (mail.cmd == LN_HTTP_SERVICE_CMD_OTA_GET_TASK)
+ {
+ printf("LN_HTTP_SERVICE_CMD_OTA_GET_TASK:获取OTA升级任务\n");
+ ln_ota_get_task_http(uapi_ln_get_device_id(), uapi_ln_get_device_token(), uapi_ln_get_device_version());
+ }
+ else if (mail.cmd == LN_HTTP_SERVICE_CMD_OTA_DOWNLOAD)
+ {
+ printf("LN_HTTP_SERVICE_CMD_OTA_DOWNLOAD:下载OTA升级包\n");
+ ln_ota_download_flow_http(uapi_ln_get_device_id(), uapi_ln_get_device_token(), uapi_ln_get_device_version());
+ }
+ else if (mail.cmd == LN_HTTP_SERVICE_CMD_AUDIO_PLAY)
+ {
+ printf("LN_HTTP_SERVICE_CMD_AUDIO_PLAY:播放音频\n");
+ #ifdef BOARD_N9
+ if (ln_story_player_simple_start("/user/leiniao/story/choose"))
{
- /* 一边下载到文件,一边推送到播放器队列,尝试边下边播 */
- size_t written = fwrite(client_data.responseBuf, 1, client_data.contentBlockLen, fd);
- if (written != client_data.contentBlockLen)
+ printf("播放开始成功\n");
+ }
+ #endif
+ }
+ else if (mail.cmd == LN_HTTP_SERVICE_CMD_AUDIO_STOP)
+ {
+ printf("LN_HTTP_SERVICE_CMD_AUDIO_STOP:停止播放音频\n");
+ #ifdef BOARD_N9
+ ln_story_player_simple_stop();
+ #endif
+ }
+ else if (mail.cmd == LN_HTTP_SERVICE_CMD_AUDIO_PLAY_NEXT)
+ {
+ printf("LN_HTTP_SERVICE_CMD_AUDIO_PLAY_NEXT:播放下一首\n");
+ #ifdef BOARD_N9
+ ln_story_player_simple_handle_message(LN_HTTP_SERVICE_CMD_AUDIO_PLAY_NEXT, NULL, 0);
+ #endif
+ }
+ else if (mail.cmd == LN_HTTP_SERVICE_CMD_AUDIO_PLAY_FILE)
+ {
+ printf("LN_HTTP_SERVICE_CMD_AUDIO_PLAY_FILE:播放指定文件\n");
+ #ifdef BOARD_N9
+ if (mail.data != NULL)
+ {
+ char *file_path = (char*)mail.data;
+ printf("Playing file: %s\n", file_path);
+ if (ln_story_player_simple_play_file(file_path))
{
- printf("[SSE] write failed, written=%zu, expected=%d\n",
- written, client_data.contentBlockLen);
- fclose(fd);
- HttpClientClse(&client);
- HttpClientUnprepare(&client_data);
- return ERRCODE_FAIL;
+ printf("File playback started successfully\n");
}
-
- /* 非阻塞入队,队列满则忽略该块 */
- (void)ln_audio_player_write((const uint8_t*)client_data.responseBuf, (uint32_t)client_data.contentBlockLen);
-
- total_written += written;
+ else
+ {
+ printf("Failed to start file playback\n");
+ }
+ }
+ else
+ {
+ printf("Error: No file path provided\n");
}
+ #endif
}
- else
+ else if (mail.cmd == LN_HTTP_SERVICE_CMD_AUDIO_PAUSE)
{
- printf("[SSE] receive ended (code: %d)\n", recv_res);
- break;
+ printf("LN_HTTP_SERVICE_CMD_AUDIO_PAUSE:暂停播放\n");
+ #ifdef BOARD_N9
+ if (ln_story_player_simple_pause())
+ {
+ printf("Playback paused successfully\n");
+ }
+ else
+ {
+ printf("Failed to pause playback\n");
+ }
+ #endif
}
- } while (client_data.isMore);
-
- fclose(fd);
- HttpClientUnprepare(&client_data);
- HttpClientClse(&client);
-
- printf("[SSE] download completed, total bytes: %zu\n", total_written);
- return ERRCODE_SUCC;
+ else if (mail.cmd == LN_HTTP_SERVICE_CMD_AUDIO_RESUME)
+ {
+ printf("LN_HTTP_SERVICE_CMD_AUDIO_RESUME:恢复播放\n");
+ #ifdef BOARD_N9
+ if (ln_story_player_simple_resume())
+ {
+ printf("Playback resumed successfully\n");
+ }
+ else
+ {
+ printf("Failed to resume playback\n");
+ }
+ #endif
+ }
+ if (mail.data != NULL)
+ {
+ printf("free(mail.data)\n");
+ free(mail.data);
+ }
+ }
}
-/**
- * 解析JSON数据,下载MP3并推送消息
- * @param json_data JSON数据字符串
- * @param interface_type 接口类型
- * @param segment_index 片段索引
- * @return ERRCODE_SUCC 成功,ERRCODE_FAIL 失败
- */
-uint32_t ln_parse_and_process_json_data(const char *json_data, int interface_type, int segment_index)
+// 接收队列
+static void ln_http_server_recv_task(void const *arg)
{
- if (!json_data)
- {
- printf("[JSON_PARSE] invalid json_data\n");
- return ERRCODE_FAIL;
- }
-
- printf("[JSON_PARSE] parsing JSON data (interface_type=%d, segment=%d): %s\n",
- interface_type, segment_index, json_data);
-
- // 解析JSON数据
- cJSON *root = cJSON_Parse(json_data);
- if (!root)
- {
- printf("[JSON_PARSE] JSON parse failed: %s\n", json_data);
- return ERRCODE_FAIL;
- }
-
- // 检查是否有错误
- cJSON *errorCode = cJSON_GetObjectItem(root, "errorCode");
- if (errorCode && !cJSON_IsNull(errorCode))
- {
- printf("[JSON_PARSE] server error: %s\n",
- cJSON_IsString(errorCode) ? errorCode->valuestring : "unknown");
- cJSON_Delete(root);
- return ERRCODE_FAIL;
- }
+ errcode_t ret;
- // 获取data字段
- cJSON *data = cJSON_GetObjectItem(root, "data");
- if (!data || !cJSON_IsObject(data))
- {
- printf("[JSON_PARSE] no data field found\n");
- cJSON_Delete(root);
- return ERRCODE_FAIL;
- }
+ ln_http_data_mail_t mail = {0};
+ uint32_t msgsize = sizeof(ln_http_data_mail_t);
- // 根据接口类型获取音频URL
- char *audio_url = NULL;
- if (interface_type == LN_HTTP_SERVICE_CMD_SSE_RECV)
+ while (1)
{
- // 语音对话接口:使用 audioUrl 字段
- cJSON *audioUrl = cJSON_GetObjectItem(data, "audioUrl");
- if (audioUrl && cJSON_IsString(audioUrl))
+ ret = osal_msg_queue_read_copy(g_ln_recv_queue, (void *)&mail, &msgsize,
+ OSAL_MSGQ_WAIT_FOREVER);
+ if (ret != OSAL_SUCCESS)
{
- audio_url = audioUrl->valuestring;
+ continue;
}
- }
- else if (interface_type == LN_HTTP_RECV_STORY_CHOOSE || interface_type == LN_HTTP_RECV_STORY_RANDOM)
- {
- // 故事接口:使用 storyAudioUrl 字段
- cJSON *storyAudioUrl = cJSON_GetObjectItem(data, "storyAudioUrl");
- if (storyAudioUrl && cJSON_IsString(storyAudioUrl))
- {
- audio_url = storyAudioUrl->valuestring;
+
+ // 消息有效性检查
+ if (!mail.data || mail.len <= 0)
+ {
+ continue;
}
- }
- else
- {
- // 默认尝试 audioUrl 字段
- cJSON *audioUrl = cJSON_GetObjectItem(data, "audioUrl");
- if (audioUrl && cJSON_IsString(audioUrl))
- {
- audio_url = audioUrl->valuestring;
+
+ // 分类处理消息
+ const char *tag = "UNKNOWN";
+ if (mail.cmd == LN_HTTP_SERVICE_CMD_SSE_RECV) {
+ tag = "SPEECH_CHAT";
+ } else if (mail.cmd == LN_HTTP_RECV_STORY_CHOOSE) {
+ tag = "STORY_CHOOSE";
+ } else if (mail.cmd == LN_HTTP_RECV_STORY_RANDOM) {
+ tag = "STORY_RANDOM";
+ } else if (mail.cmd == LN_HTTP_RECV_STORY_EXIT) {
+ tag = "STORY_EXIT";
+ } else if (mail.cmd == LN_HTTP_RECV_STORY_FINISH) {
+ tag = "STORY_FINISH";
+ } else if (mail.cmd == LN_HTTP_RECV_DEVICE_CHARACTER) {
+ tag = "DEVICE_CHARACTER";
+ } else if (mail.cmd == LN_HTTP_RECV_DEVICE_USER_ID) {
+ tag = "DEVICE_USER_ID";
+ } else if (mail.cmd == LN_HTTP_RECV_OTA_TASK) {
+ tag = "OTA_TASK";
+ } else if (mail.cmd == LN_HTTP_RECV_OTA_DOWNLOAD_MSG) {
+ tag = "OTA_DOWNLOAD_MSG";
+ }
+
+ printf("[%s] 数据长度: %u\n", tag, mail.len);
+ /* 确保可打印:追加\0 */
+ char *buf = (char *)malloc(mail.len + 1);
+ if (buf) {
+ memcpy(buf, mail.data, mail.len);
+ buf[mail.len] = '\0';
+ printf("[%s] 原始数据:%s\n", tag, buf);
+ /* 在收到 OTA_TASK 后,根据升级策略决定是否触发下载 */
+ if (mail.cmd == LN_HTTP_RECV_OTA_TASK) {
+ ln_handle_ota_task_response(buf, (int)mail.len);
+ }
+ /* 在收到 OTA_DOWNLOAD_MSG 后,解析状态并回调处理(进度/完成/失败) */
+ if (mail.cmd == LN_HTTP_RECV_OTA_DOWNLOAD_MSG) {
+ OtaDownloadMsg m = {0};
+ if (parse_ota_download_msg(buf, &m) == 0) {
+ handle_ota_download_msg(&m);
+ }
+ }
+ free(buf);
}
}
+}
- // 获取textContent
- cJSON *textContent = cJSON_GetObjectItem(data, "textContent");
- char *text_content = NULL;
- if (textContent && cJSON_IsString(textContent))
- {
- text_content = textContent->valuestring;
- }
-
- // 获取intention
- cJSON *intention = cJSON_GetObjectItem(data, "intention");
- char *intention_str = NULL;
- if (intention && cJSON_IsString(intention))
+/* 创建雷鸟http发送队列 */
+static void create_ln_http_send_queue(void)
+{
+ if (osal_msg_queue_create("ln_http_send_queue", 24, &g_ln_send_queue,
+ 0, sizeof(ln_http_data_mail_t)) != ERRCODE_SUCC)
{
- intention_str = intention->valuestring;
+ printf("[ln][service] app create mail fail\n");
}
+}
- // 获取storyTheme(故事接口特有)
- cJSON *storyTheme = cJSON_GetObjectItem(data, "storyTheme");
- char *story_theme = NULL;
- if (storyTheme && cJSON_IsString(storyTheme))
+/* 创建雷鸟http接收队列 */
+static void create_ln_http_recv_queue(void)
+{
+ if (osal_msg_queue_create("ln_http_recv_queue", 24, &g_ln_recv_queue,
+ 0, sizeof(ln_http_data_mail_t)) != ERRCODE_SUCC)
{
- story_theme = storyTheme->valuestring;
+ printf("[ln][service] app create mail fail\n");
}
+}
- // 获取storyContent(故事接口特有)
- cJSON *storyContent = cJSON_GetObjectItem(data, "storyContent");
- char *story_content = NULL;
- if (storyContent && cJSON_IsString(storyContent))
+/* 通用发送接口:向 LN HTTP 发送队列投递消息 */
+void do_ln_http_server_send_data(int cmd, char *data, uint32_t len)
+{
+ errcode_t ret;
+ ln_http_data_mail_t send_data = {0};
+ send_data.cmd = cmd;
+ if (len && data)
{
- story_content = storyContent->valuestring;
+ send_data.len = len;
+ send_data.data = (char *)malloc(len);
+ if (send_data.data == NULL)
+ {
+ printf("malloc failed\n");
+ return;
+ }
+ memcpy(send_data.data, data, len);
}
- // 创建推送数据
- cJSON *push_data = cJSON_CreateObject();
-
- // 根据接口类型添加相应字段
- if (text_content && strlen(text_content) > 0)
- {
- cJSON_AddStringToObject(push_data, "textContent", text_content);
- }
-
- if (story_content && strlen(story_content) > 0)
- {
- cJSON_AddStringToObject(push_data, "storyContent", story_content);
- }
-
- if (intention_str && strlen(intention_str) > 0)
- {
- cJSON_AddStringToObject(push_data, "intention", intention_str);
- }
-
- if (story_theme && strlen(story_theme) > 0)
- {
- cJSON_AddStringToObject(push_data, "storyTheme", story_theme);
- }
+ uint32_t send_len = sizeof(send_data);
- // 推送到相应的接收线程
- char *json_string = cJSON_Print(push_data);
- if (json_string)
+ ret = osal_msg_queue_write_copy(g_ln_send_queue, (void *)&send_data,
+ send_len, 0);
+ if (ret != OSAL_SUCCESS)
{
- printf("[JSON_PARSE] pushing data to interface_type=%d: %s\n", interface_type, json_string);
- do_ln_http_server_recv_data(interface_type, json_string, strlen(json_string));
- free(json_string);
+ printf("Error ln http send failed! err=0x%x! \r\n", ret);
}
- cJSON_Delete(push_data);
+}
- // 下载音频文件
- if (audio_url && strlen(audio_url) > 0)
+/* 通用接收接口:向 LN HTTP 接收队列投递消息 */
+void do_ln_http_server_recv_data(int cmd, char *data, uint32_t len)
+{
+ errcode_t ret;
+ ln_http_data_mail_t recv_data = {0};
+ recv_data.cmd = cmd;
+ if (len && data)
{
- char save_dir[256];
- char filename[128];
-
- // 根据接口类型确定保存目录和文件名
- switch (interface_type)
- {
- case LN_HTTP_SERVICE_CMD_SSE_RECV:
- snprintf(save_dir, sizeof(save_dir), "%s/speech", LN_DATA_PATH);
- snprintf(filename, sizeof(filename), "%d.mp3", segment_index);
- break;
- case LN_HTTP_RECV_STORY_CHOOSE:
- snprintf(save_dir, sizeof(save_dir), "%s/story/choose", LN_DATA_PATH);
- snprintf(filename, sizeof(filename), "%d.mp3", segment_index);
- break;
- case LN_HTTP_RECV_STORY_RANDOM:
- snprintf(save_dir, sizeof(save_dir), "%s/story/random", LN_DATA_PATH);
- snprintf(filename, sizeof(filename), "%d.mp3", segment_index);
- break;
- default:
- snprintf(save_dir, sizeof(save_dir), "%s", LN_DATA_PATH);
- snprintf(filename, sizeof(filename), "%d.mp3", segment_index);
- break;
- }
-
- printf("[JSON_PARSE] found audio URL (interface_type=%d): %s\n", interface_type, audio_url);
- printf("[JSON_PARSE] downloading audio to: %s/%s\n", save_dir, filename);
-
- uint32_t download_result = ln_download_mp3_file_advanced(audio_url, save_dir, filename);
- if (download_result == ERRCODE_SUCC)
- {
- printf("[JSON_PARSE] audio downloaded successfully: %s/%s\n", save_dir, filename);
- }
- else
+ recv_data.len = len;
+ recv_data.data = (char *)malloc(len);
+ if (recv_data.data == NULL)
{
- printf("[JSON_PARSE] audio download failed\n");
+ printf("malloc failed\n");
+ return;
}
+ memcpy(recv_data.data, data, len);
}
- else
+
+ uint32_t send_len = sizeof(recv_data);
+
+ ret = osal_msg_queue_write_copy(g_ln_recv_queue, (void *)&recv_data,
+ send_len, 0);
+ if (ret != OSAL_SUCCESS)
{
- printf("[JSON_PARSE] no audio URL found for interface_type=%d, skipping download\n", interface_type);
+ printf("Error ln http recv send failed! err=0x%x! \r\n", ret);
+ if (recv_data.data) free(recv_data.data);
}
-
- cJSON_Delete(root);
- return ERRCODE_SUCC;
}
-
-/**
- * 从文件中解析data数据,下载MP3并推送消息
- * @param file_path 文件路径
- * @param interface_type 接口类型
- * @return ERRCODE_SUCC 成功,ERRCODE_FAIL 失败
- */
-uint32_t ln_parse_file_and_process_data(const char *file_path, int interface_type)
+// 雷鸟http服务初始化
+errcode_t uapi_ln_http_server_init(void)
{
- if (!file_path)
+ printf("uapi_ln_http_server_init !\r\n");
+
+ ln_send_taskcfg.create_queue_handle = create_ln_http_send_queue;
+ ln_send_taskcfg.attr.name = "ln_http_server_send_task";
+ ln_send_taskcfg.attr.priority = osPriorityNormal;
+ ln_send_taskcfg.attr.stack_size = LN_HTTP_BOARD_TASK_SIZE;
+ ln_send_taskcfg.func = ln_http_server_send_task;
+ ln_send_taskcfg.use_mem = USE_EXTEND_MEM;
+
+ errcode_t ret = uapi_create_osThread_custom(&ln_send_taskcfg);
+ if (ret != ERRCODE_SUCC)
{
- printf("[FILE_PARSE] invalid file path\n");
+ printf("create ln_send_service failed %d!\r\n", ret);
return ERRCODE_FAIL;
}
- printf("[FILE_PARSE] processing file: %s (interface_type=%d)\n", file_path, interface_type);
+ ln_recv_taskcfg.create_queue_handle = create_ln_http_recv_queue;
+ ln_recv_taskcfg.attr.name = "ln_http_server_recv_task";
+ ln_recv_taskcfg.attr.priority = osPriorityNormal;
+ ln_recv_taskcfg.attr.stack_size = LN_HTTP_BOARD_TASK_SIZE;
+ ln_recv_taskcfg.func = ln_http_server_recv_task;
+ ln_recv_taskcfg.use_mem = USE_EXTEND_MEM;
- FILE *fp = fopen(file_path, "r");
- if (!fp)
+ ret = uapi_create_osThread_custom(&ln_recv_taskcfg);
+ if (ret != ERRCODE_SUCC)
{
- printf("[FILE_PARSE] failed to open file: %s\n", file_path);
+ printf("create gnss_recv_service failed %d!\r\n", ret);
return ERRCODE_FAIL;
}
- char line[2048];
- int line_count = 0;
- int success_count = 0;
- int error_count = 0;
-
- while (fgets(line, sizeof(line), fp))
+ /* 初始化音频播放器(流式输出) */
+ if (ln_audio_player_init() != ERRCODE_SUCC)
{
- line_count++;
-
- // 去除行尾的换行符
- size_t len = strlen(line);
- if (len > 0 && line[len - 1] == '\n')
- {
- line[len - 1] = '\0';
- len--;
- }
- if (len > 0 && line[len - 1] == '\r')
- {
- line[len - 1] = '\0';
- len--;
- }
-
- // 跳过空行
- if (len == 0)
- {
- continue;
- }
-
- // 检查是否是SSE数据格式 (data: {...})
- if (strncmp(line, "data:", 5) == 0)
- {
- char *json_start = line + 5;
- // 跳过可能的空格
- while (*json_start == ' ' || *json_start == '\t')
- {
- json_start++;
- }
-
- printf("[FILE_PARSE] line %d: processing JSON: %s\n", line_count, json_start);
-
- uint32_t result = ln_parse_and_process_json_data(json_start, interface_type, line_count);
- if (result == ERRCODE_SUCC)
- {
- success_count++;
- }
- else
- {
- error_count++;
- }
- }
- else
- {
- printf("[FILE_PARSE] line %d: invalid format (not SSE data): %s\n", line_count, line);
- error_count++;
- }
+ printf("[LN_AUDIO] init failed in http server init\n");
+ /* 不中断HTTP服务,按需可返回失败 */
}
- fclose(fp);
-
- printf("[FILE_PARSE] processing completed: total lines=%d, success=%d, errors=%d\n",
- line_count, success_count, error_count);
-
- return (error_count == 0) ? ERRCODE_SUCC : ERRCODE_FAIL;
+ return ERRCODE_SUCC;
}
-
+/* ============================ 队列相关代码 End ============================ */
\ No newline at end of file