#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+#include <stdarg.h>
#include "cJSON.h" // Added for JSON parsing
#include "custom_utils.h"
#include "soc_osal.h"
#include "mbedtls/base64.h"
#include "ai_media.h" // Added for AI_RegisterWriteAudioDataCallback
+// 打印等级定义
+typedef enum {
+ LN_WS_LOG_ERROR = 0, // 错误信息
+ LN_WS_LOG_WARN = 1, // 警告信息
+ LN_WS_LOG_INFO = 2, // 一般信息
+ LN_WS_LOG_DEBUG = 3 // 调试信息
+} ln_ws_log_level_t;
+
+// 当前日志等级(可通过配置修改)
+static ln_ws_log_level_t g_log_level = LN_WS_LOG_INFO;
+
+// 打印函数
+// 日志等级字符串数组
+static const char *g_log_level_str[] = {
+ "[ERROR]", "[WARN]", "[INFO]", "[DEBUG]"
+};
+
+// 日志宏定义
+#define LN_WS_LOG(level, line, fmt, ...) do { \
+ if (level <= g_log_level) { \
+ printf("[LN][WS]%s " fmt, g_log_level_str[level], ##__VA_ARGS__); \
+ } \
+} while(0)
+
+// 便捷打印宏
+#define LN_WS_ERROR(fmt, ...) LN_WS_LOG(LN_WS_LOG_ERROR, __LINE__, fmt, ##__VA_ARGS__)
+#define LN_WS_WARN(fmt, ...) LN_WS_LOG(LN_WS_LOG_WARN, __LINE__, fmt, ##__VA_ARGS__)
+#define LN_WS_INFO(fmt, ...) LN_WS_LOG(LN_WS_LOG_INFO, __LINE__, fmt, ##__VA_ARGS__)
+#define LN_WS_DEBUG(fmt, ...) LN_WS_LOG(LN_WS_LOG_DEBUG, __LINE__, fmt, ##__VA_ARGS__)
+
/*
* - g_ws_client_fd 当前 WebSocket 客户端fd
* - g_ws_connected 连接状态:0=未连接,1=连接中,2=连接成功
static void ln_ws_on_open(int client)
{
(void)client;
- printf("WebSocketClientConstructor ln_ws_on_open\r\n");
+ LN_WS_DEBUG("WebSocketClientConstructor ln_ws_on_open\r\n");
g_ws_connected = WS_STATE_CONNECTED;
- printf("[LN][WS] 连接状态: 连接成功\n");
+ LN_WS_DEBUG("连接状态: 连接成功\n");
}
/* 消息接收回调函数 */
buf[length] = '\0';
/* 统一的消息解析处理 */
- printf("WebSocketClientConstructor data\r\n");
+ LN_WS_DEBUG("WebSocketClientConstructor data\r\n");
if (length >= 2 && buf[0] == '{' && buf[length - 1] == '}') {
// 解析消息并直接处理
ws_data_msg_t data_msg;
if (ln_ws_parse_data_message(buf, &data_msg) == 0) {
- printf("[LN][WS] Message parsed successfully: command=%d (%s)\n",
+ LN_WS_DEBUG("Message parsed successfully: command=%d (%s)\n",
data_msg.command, data_msg.command_str);
// 直接使用回调函数处理消息
// 释放消息内存
ln_ws_free_data_message(&data_msg);
} else {
- printf("[LN][WS] Failed to parse message\n");
+ LN_WS_ERROR("Failed to parse message\n");
}
}
else
{
ln_ws_incomplete_callback(raw_data,length,false);
- printf("[LN][WS] Invalid message\n");
+ LN_WS_WARN("Invalid message\n");
}
- printf("[LN][WS] on_message: %s\n", buf);
+ LN_WS_DEBUG("on_message: %s\n", buf);
free(buf);
}
{
switch (event_type) {
case WS_EVENT_CONNECTING:
- printf("[LN][WS] Event: Connecting\n");
+ LN_WS_INFO("Event: Connecting\n");
g_ws_connected = WS_STATE_CONNECTING;
break;
case WS_EVENT_CONNECTED:
- printf("[LN][WS] Event: Connected\n");
+ LN_WS_INFO("Event: Connected\n");
g_ws_connected = WS_STATE_CONNECTED;
// 触发连接成功事件
}
break;
case WS_EVENT_DISCONNECTED:
- printf("[LN][WS] Event: Disconnected\n");
- g_ws_connected = WS_STATE_DISCONNECTED;
+ LN_WS_INFO("Event: Disconnected\n");
+ g_ws_connected = WS_STATE_DISCONNECTED;
// 触发断连事件
if (g_ws_message_callback != NULL) {
}
break;
default:
- printf("[LN][WS] Event: Unknown event type %d\n", event_type);
+ LN_WS_ERROR("Event: Unknown event type %d\n", event_type);
break;
}
}
uint32_t current_tick = osKernelGetTickCount();
uint32_t elapsed_ticks = current_tick - g_last_audio_write_tick;
- printf("[LN][WS] Heartbeat callback: audio playback active, elapsed ticks: %u\n", elapsed_ticks);
+ LN_WS_DEBUG("Heartbeat callback: audio playback active, elapsed ticks: %u\n", elapsed_ticks);
// 如果超过超时时间没有音频写入,认为播放结束
if (elapsed_ticks >= g_audio_timeout_ticks) {
- printf("[LN][WS] Audio playback timeout detected, triggering end event\n");
+ LN_WS_INFO("Audio playback timeout detected, triggering end event\n");
g_audio_playback_active = false;
// 触发播放结束事件
}
}
- if (heartbeat_counter >= 15) { // 30秒 = 30次 * 1秒
+ if (heartbeat_counter >= 30) { // 30秒 = 30次 * 1秒
heartbeat_counter = 0;
ln_ws_send_ping();
return 1; // 需要发送心跳
int ln_ws_send_ping(void)
{
if (g_ws_connected != WS_STATE_CONNECTED) {
- printf("[LN][WS] Cannot send ping, connection state: %d\n", g_ws_connected);
+ LN_WS_WARN("Cannot send ping, connection state: %d\n", g_ws_connected);
return -1;
}
// 创建 JSON 对象
cJSON *json = cJSON_CreateObject();
if (!json) {
- printf("[LN][WS] Failed to create JSON object\n");
+ LN_WS_ERROR("Failed to create JSON object\n");
return -1;
}
// 转换为字符串
char *json_string = cJSON_Print(json);
if (!json_string) {
- printf("[LN][WS] Failed to print JSON\n");
+ LN_WS_ERROR("Failed to print JSON\n");
cJSON_Delete(json);
return -1;
}
// 发送 JSON 字符串
int ret = uapi_ws_send_text(json_string);
- printf("[LN][WS] Sent ping: %s\n", json_string);
+ LN_WS_DEBUG("Sent ping: %s\n", json_string);
// 清理内存
cJSON_free(json_string);
static void reset_chat_id_match(void)
{
g_chat_id_matched = false;
- printf("[LN][WS] Reset chat ID match flag\n");
+ LN_WS_DEBUG("Reset chat ID match flag\n");
}
// 设置对话ID匹配标志
static void set_chat_id_matched(void)
{
g_chat_id_matched = true;
- printf("[LN][WS] Set chat ID matched\n");
+ LN_WS_DEBUG("Set chat ID matched\n");
}
// 检查对话ID是否匹配
// 音频数据写入回调函数
static void ln_ws_audio_write_callback(uint32_t size)
{
- printf("[LN][WS] Audio data written successfully: %u bytes\n", size);
+ LN_WS_DEBUG("Audio data written successfully: %u bytes\n", size);
// 更新最后一次音频写入tick
g_last_audio_write_tick = osKernelGetTickCount();
{
// 检查结束标志位,如果设置了结束标志,则finished必须为true
if (g_audio_chat_ending && !finished) {
- printf("[LN][WS] Audio chat is ending, finished must be true\n");
+ LN_WS_WARN("Audio chat is ending, finished must be true\n");
return -1;
}
// 对于正常音频数据,必须有有效的数据
if (!finished && (!audio_data || audio_size == 0)) {
- printf("[LN][WS] Invalid audio data parameters\n");
+ LN_WS_ERROR("Invalid audio data parameters\n");
return -1;
}
if (g_ws_connected != WS_STATE_CONNECTED) {
- printf("[LN][WS] Cannot send audio data, connection state: %d\n", g_ws_connected);
+ LN_WS_WARN("Cannot send audio data, connection state: %d\n", g_ws_connected);
return -1;
}
g_audio_chat_ctx.is_active = true;
// 重置对话ID匹配标志
reset_chat_id_match();
- printf("[LN][WS] New chat started: %s\n", g_audio_chat_ctx.chat_id);
+ LN_WS_DEBUG("New chat started: %s\n", g_audio_chat_ctx.chat_id);
}
// 增加消息计数器
// 结束消息,使用空字符串
audio_base64 = (char*)malloc(1);
if (!audio_base64) {
- printf("[LN][WS] Failed to allocate memory for base64 encoding\n");
+ LN_WS_ERROR("Failed to allocate memory for base64 encoding\n");
return -1;
}
audio_base64[0] = '\0';
size_t base64_size =audio_size*2; //((audio_size + 2) / 3) * 4 + 1;
audio_base64 = (char*)malloc(base64_size);
if (!audio_base64) {
- printf("[LN][WS] Failed to allocate memory for base64 encoding\n");
+ LN_WS_ERROR("Failed to allocate memory for base64 encoding\n");
return -1;
}
int ret_encode = mbedtls_base64_encode((unsigned char*)audio_base64, base64_size - 1, &output_len,
audio_data, audio_size);
if (ret_encode != 0) {
- printf("[LN][WS] Base64 encoding failed: %d\n", ret_encode);
+ LN_WS_DEBUG("Base64 encoding failed: %d\n", ret_encode);
free(audio_base64);
return -1;
}
// 创建JSON消息
cJSON *json = cJSON_CreateObject();
if (!json) {
- printf("[LN][WS] Failed to create JSON object\n");
+ LN_WS_ERROR("Failed to create JSON object\n");
free(audio_base64);
return -1;
}
// 创建data对象
cJSON *data_obj = cJSON_CreateObject();
if (!data_obj) {
- printf("[LN][WS] Failed to create data object\n");
+ LN_WS_ERROR("Failed to create data object\n");
cJSON_Delete(json);
free(audio_base64);
return -1;
// 转换为字符串
char *json_string = cJSON_Print(json);
if (!json_string) {
- printf("[LN][WS] Failed to print JSON\n");
+ LN_WS_ERROR("Failed to print JSON\n");
cJSON_Delete(json);
free(audio_base64);
return -1;
// 发送JSON字符串
int ret = uapi_ws_send_text(json_string);
- printf("[LN][WS] Sent audio data: chatId=%s, messageId=%s, size=%u, finished=%s\n",
+ LN_WS_DEBUG("Sent audio data: chatId=%s, messageId=%s, size=%u, finished=%s\n",
g_audio_chat_ctx.chat_id, message_id, audio_size, finished ? "true" : "false");
// 清理内存
// 如果音频结束,重置聊天上下文
if (finished) {
g_audio_chat_ctx.is_active = false;
- printf("[LN][WS] Chat ended: %s\n", g_audio_chat_ctx.chat_id);
+ LN_WS_DEBUG("Chat ended: %s\n", g_audio_chat_ctx.chat_id);
// 重置对话ID匹配标志
reset_chat_id_match();
}
{
if(g_ws_connected != WS_STATE_CONNECTED)
{
- printf("[LN][WS] g_ws_connected!=WS_STATE_CONNECTED");
+ LN_WS_WARN("g_ws_connected!=WS_STATE_CONNECTED");
return 0;
}
if (g_audio_chat_ctx.is_active) {
- printf("[LN][WS] Audio chat already active: %s\n", g_audio_chat_ctx.chat_id);
+ LN_WS_WARN("Audio chat already active: %s\n", g_audio_chat_ctx.chat_id);
return 0;
}
ln_ws_send_voice_chat_interrupt("新对话开始");
const char *command_name = (command_type == LN_AUDIO_CHAT_VOICE_CHAT_REQUEST) ?
"VoiceChatRequest" : "ChooseStoryRequest";
- printf("[LN][WS] Audio chat started: %s (command: %s)\n",
+ LN_WS_DEBUG("Audio chat started: %s (command: %s)\n",
g_audio_chat_ctx.chat_id, command_name);
return 0;
}
int ln_ws_end_audio_chat(void)
{
if (!g_audio_chat_ctx.is_active) {
- printf("[LN][WS] No active audio chat to end\n");
+ LN_WS_WARN("No active audio chat to end\n");
return -1;
}
- printf("[LN][WS] Ending audio chat: %s, total messages: %u\n",
+ LN_WS_DEBUG("Ending audio chat: %s, total messages: %u\n",
g_audio_chat_ctx.chat_id, g_audio_chat_ctx.message_counter);
// 设置结束标志,等待下次AIVoiceDataCallback_ln调用时发送结束消息
g_audio_chat_ending = true;
if( g_audio_chat_ctx.is_active ==true)
{
if (g_audio_chat_ending) {
- printf("[LN][WS] Sending audio chat end message\n");
+ LN_WS_DEBUG("Sending audio chat end message\n");
// 发送结束消息
ln_ws_send_audio_data(data, size, true);
// 重置聊天上下文和结束标志
static void ai_binary_message_handler(const uint8_t *raw_data, uint32_t timestamp, uint32_t data_len)
{
- printf("[AI] Received binary message at %u, length: %d bytes\n", timestamp, data_len);
+ LN_WS_DEBUG("Received binary message at %u, length: %d bytes\n", timestamp, data_len);
if (!is_chat_id_matched()) {
- printf("[AI] Chat ID not matched\n");
+ LN_WS_WARN("Chat ID not matched\n");
return;
}
if (!raw_data || data_len == 0) {
- printf("[AI] Invalid binary data parameters\n");
+ LN_WS_ERROR("Invalid binary data parameters\n");
return;
}
if (data_len <= CHUNK_SIZE) {
// 数据小于等于1K,直接发送
- printf("[AI] Sending data directly (size: %d bytes)\n", data_len);
+ LN_WS_DEBUG("Sending data directly (size: %d bytes)\n", data_len);
AI_SendAudioDataToQueue(raw_data, data_len);
} else {
// 数据大于1K,分块发送
- printf("[AI] Data size %d bytes > %zu bytes, splitting into chunks\n", data_len, CHUNK_SIZE);
+ LN_WS_DEBUG("Data size %d bytes > %zu bytes, splitting into chunks\n", data_len, CHUNK_SIZE);
size_t remaining = data_len;
const uint8_t *current_pos = raw_data;
while (remaining > 0) {
size_t current_chunk_size = (remaining > CHUNK_SIZE) ? CHUNK_SIZE : remaining;
- printf("[AI] Sending chunk %d: %zu bytes\n", ++chunk_count, current_chunk_size);
+ LN_WS_DEBUG("Sending chunk %d: %zu bytes\n", ++chunk_count, current_chunk_size);
AI_SendAudioDataToQueue(current_pos, current_chunk_size);
current_pos += current_chunk_size;
}
- printf("[AI] All %d chunks sent successfully\n", chunk_count);
+ LN_WS_DEBUG("All %d chunks sent successfully\n", chunk_count);
}
}
return;
}
- printf("[LN][WS] Incomplete message received: length=%zu, isBinary=%s\n",
+ LN_WS_DEBUG("Incomplete message received: length=%zu, isBinary=%s\n",
length, isBinary ? "true" : "false");
// 检查是否包含 "audioBase64":" 字符串
const char *found = strstr(raw_data, audioBase64_key);
if (found) {
- printf("[LN][WS] Found audioBase64 key in incomplete message\n");
+ LN_WS_DEBUG("Found audioBase64 key in incomplete message\n");
// 找到 "audioBase64":" 后面的内容
const char *value_start = found + strlen(audioBase64_key);
if (value_end) {
// 找到结束引号,数据完整
size_t base64_length = value_end - value_start;
- printf("[LN][WS] Found complete Base64 data: length=%zu\n", base64_length);
+ LN_WS_DEBUG("Found complete Base64 data: length=%zu\n", base64_length);
// 处理完整的Base64数据
ln_ws_process_base64_data(value_start, base64_length);
} else {
// 没有找到结束引号,数据不完整
- printf("[LN][WS] No closing quote found, data incomplete\n");
+ LN_WS_DEBUG("No closing quote found, data incomplete\n");
// 处理不完整的Base64数据
size_t remaining_length = length - (value_start - raw_data);
// 找到结束引号,处理到引号位置的数据
size_t data_before_quote = end_quote - raw_data;
if (data_before_quote > 0) {
- printf("[LN][WS] Found end quote, processing data before quote: %zu bytes\n", data_before_quote);
+ LN_WS_DEBUG("Found end quote, processing data before quote: %zu bytes\n", data_before_quote);
ln_ws_process_incremental_base64_data(raw_data, data_before_quote);
}
// 处理缓存中剩余的数据(如果有的话)
if (g_base64_cache_size > 0) {
- printf("[LN][WS] Processing remaining cached data: %zu bytes\n", g_base64_cache_size);
+ LN_WS_DEBUG("Processing remaining cached data: %zu bytes\n", g_base64_cache_size);
ln_ws_process_base64_data(g_base64_cache, g_base64_cache_size);
ln_ws_base64_cache_reset();
}
// 结束Base64数据接收
g_base64_in_progress = false;
- printf("[LN][WS] Base64 data reception completed\n");
+ LN_WS_DEBUG("Base64 data reception completed\n");
} else {
// 没有结束引号,继续处理增量数据
- printf("[LN][WS] Continuing Base64 data reception, processing incrementally\n");
+ LN_WS_DEBUG("Continuing Base64 data reception, processing incrementally\n");
ln_ws_process_incremental_base64_data(raw_data, length);
}
} else {
- printf("[LN][WS] No audioBase64 key found in message\n");
+ LN_WS_DEBUG("No audioBase64 key found in message\n");
}
}
}
// 设置音频超时tick数
if (audio_timeout_ticks > 0) {
g_audio_timeout_ticks = audio_timeout_ticks;
- printf("[LN][WS] Audio timeout ticks set to: %u\n", g_audio_timeout_ticks);
+ LN_WS_DEBUG("Audio timeout ticks set to: %u\n", g_audio_timeout_ticks);
} else {
- printf("[LN][WS] Using default audio timeout ticks: %u\n", g_audio_timeout_ticks);
+ LN_WS_DEBUG("Using default audio timeout ticks: %u\n", g_audio_timeout_ticks);
}
// 注册回调函数
g_ws_message_callback = callback;
if (callback != NULL) {
- printf("[LN][WS] Message callback registered successfully\n");
+ LN_WS_DEBUG("Message callback registered successfully\n");
} else {
- printf("[LN][WS] Using default message handler\n");
+ LN_WS_WARN("Using default message handler\n");
}
// 设置回调函数结构体
// 启动WebSocket服务
int ret = uapi_ws_start(&g_ws_callbacks);
if (ret != 0) {
- printf("[LN][WS] uapi_ws_start failed: %d\n", ret);
+ LN_WS_WARN("uapi_ws_start failed: %d\n", ret);
g_ws_running = 0;
return ret;
}
{
if (!text) return -1;
if (g_ws_connected != WS_STATE_CONNECTED) {
- printf("[LN][WS] Cannot send text, connection state: %d\n", g_ws_connected);
+ LN_WS_WARN("Cannot send text, connection state: %d\n", g_ws_connected);
return -1;
}
return uapi_ws_send_text(text);
int ln_ws_send_random_story_request(const char *story_theme)
{
if (!story_theme) {
- printf("[LN][WS] Invalid story theme parameter\n");
+ LN_WS_ERROR("Invalid story theme parameter\n");
return -1;
}
if (g_ws_connected != WS_STATE_CONNECTED) {
- printf("[LN][WS] Cannot send random story request, connection state: %d\n", g_ws_connected);
+ LN_WS_WARN("Cannot send random story request, connection state: %d\n", g_ws_connected);
return -1;
}
ln_ws_send_voice_chat_interrupt("故事请求开始");
// 构建JSON消息
cJSON *json = cJSON_CreateObject();
if (!json) {
- printf("[LN][WS] Failed to create JSON object\n");
+ LN_WS_ERROR("Failed to create JSON object\n");
return -1;
}
// 添加data字段
cJSON *data = cJSON_CreateObject();
if (!data) {
- printf("[LN][WS] Failed to create data JSON object\n");
+ LN_WS_ERROR("Failed to create data JSON object\n");
cJSON_Delete(json);
return -1;
}
// 转换为字符串
char *json_string = cJSON_Print(json);
if (!json_string) {
- printf("[LN][WS] Failed to convert JSON to string\n");
+ LN_WS_ERROR("Failed to convert JSON to string\n");
cJSON_Delete(json);
return -1;
}
- printf("[LN][WS] Sending RandomStoryRequest: %s\n", json_string);
+ LN_WS_DEBUG("Sending RandomStoryRequest: %s\n", json_string);
// 发送消息
int ret = uapi_ws_send_text(json_string);
cJSON_Delete(json);
if (ret == 0) {
- printf("[LN][WS] RandomStoryRequest sent successfully\n");
+ LN_WS_DEBUG("RandomStoryRequest sent successfully\n");
} else {
- printf("[LN][WS] Failed to send RandomStoryRequest\n");
+ LN_WS_ERROR("Failed to send RandomStoryRequest\n");
}
return ret;
int ln_ws_send_voice_chat_interrupt(const char *reason)
{
if (!reason) {
- printf("[LN][WS] Invalid reason parameter\n");
+ LN_WS_ERROR("Invalid reason parameter\n");
return -1;
}
if (g_ws_connected != WS_STATE_CONNECTED) {
- printf("[LN][WS] Cannot send voice chat interrupt, connection state: %d\n", g_ws_connected);
+ LN_WS_WARN("Cannot send voice chat interrupt, connection state: %d\n", g_ws_connected);
return -1;
}
// 构建JSON消息
cJSON *json = cJSON_CreateObject();
if (!json) {
- printf("[LN][WS] Failed to create JSON object\n");
+ LN_WS_ERROR("Failed to create JSON object\n");
return -1;
}
// 添加data字段
cJSON *data = cJSON_CreateObject();
if (!data) {
- printf("[LN][WS] Failed to create data JSON object\n");
+ LN_WS_ERROR("Failed to create data JSON object\n");
cJSON_Delete(json);
return -1;
}
// 转换为字符串
char *json_string = cJSON_Print(json);
if (!json_string) {
- printf("[LN][WS] Failed to convert JSON to string\n");
+ LN_WS_ERROR("Failed to convert JSON to string\n");
cJSON_Delete(json);
return -1;
}
- printf("[LN][WS] Sending VoiceChatInterrupt: %s\n", json_string);
+ LN_WS_DEBUG("Sending VoiceChatInterrupt: %s\n", json_string);
// 发送消息
int ret = uapi_ws_send_text(json_string);
cJSON_Delete(json);
if (ret == 0) {
- printf("[LN][WS] VoiceChatInterrupt sent successfully\n");
+ LN_WS_DEBUG("VoiceChatInterrupt sent successfully\n");
} else {
- printf("[LN][WS] Failed to send VoiceChatInterrupt\n");
+ LN_WS_ERROR("Failed to send VoiceChatInterrupt\n");
}
return ret;
{
g_ws_message_callback = callback;
if (callback != NULL) {
- printf("[LN][WS] Message callback registered successfully\n");
+ LN_WS_DEBUG("Message callback registered successfully\n");
} else {
- printf("[LN][WS] Message callback unregistered\n");
+ LN_WS_WARN("Message callback unregistered\n");
}
}
static int ln_ws_parse_data_message(const char *json_str, ws_data_msg_t *data_msg)
{
if (!json_str || !data_msg) {
- printf("[LN][WS] Invalid parameters for message parsing\n");
+ LN_WS_ERROR("Invalid parameters for message parsing\n");
return -1;
}
// 解析JSON
cJSON *root = cJSON_Parse(json_str);
if (!root) {
- printf("[LN][WS] Failed to parse JSON for message\n");
+ LN_WS_ERROR("Failed to parse JSON for message\n");
return -1;
}
strncpy(data_msg->device_id, device_id->valuestring, sizeof(data_msg->device_id) - 1);
data_msg->device_id[sizeof(data_msg->device_id) - 1] = '\0';
} else {
- printf("[LN][WS] Missing or invalid deviceId in message\n");
+ LN_WS_ERROR("Missing or invalid deviceId in message\n");
cJSON_Delete(root);
return -1;
}
if (timestamp && cJSON_IsNumber(timestamp)) {
data_msg->timestamp = (uint32_t)timestamp->valuedouble;
} else {
- printf("[LN][WS] Missing or invalid timestamp in message\n");
+ LN_WS_ERROR("Missing or invalid timestamp in message\n");
cJSON_Delete(root);
return -1;
}
data_msg->message_id[sizeof(data_msg->message_id) - 1] = '\0';
} else {
- printf("[LN][WS] Missing or invalid messageId in message\n");
+ LN_WS_ERROR("Missing or invalid messageId in message\n");
cJSON_Delete(root);
return -1;
}
// 对于未知命令,记录日志但不返回错误
if (data_msg->command == WS_CMD_UNKNOWN) {
- printf("[LN][WS] Unknown command received: %s\n", command->valuestring);
+ LN_WS_WARN("Unknown command received: %s\n", command->valuestring);
}
} else {
- printf("[LN][WS] Missing or invalid command in message\n");
+ LN_WS_ERROR("Missing or invalid command in message\n");
cJSON_Delete(root);
return -1;
}
if (strcmp(g_audio_chat_ctx.chat_id, data_msg->chat_id) == 0) {
set_chat_id_matched();
} else {
- printf("[LN][WS] VoiceChatResponse from non-active chat %s, ignoring\n", data_msg->chat_id);
+ LN_WS_ERROR("VoiceChatResponse from non-active chat %s, ignoring\n", data_msg->chat_id);
cJSON_Delete(root);
return -1; // 返回错误,不处理此消息
}
}
}
- printf("[LN][WS] VoiceChatResponse parsed: finished=%s, chatId=%s, audioUrl=%s, textContent=%s\n",
+ LN_WS_DEBUG("VoiceChatResponse parsed: finished=%s, chatId=%s, audioUrl=%s, textContent=%s\n",
data_msg->finished ? "true" : "false", data_msg->chat_id, data_msg->audio_url, data_msg->text_content);
}
if (strcmp(g_audio_chat_ctx.chat_id, data_msg->chat_id) == 0) {
set_chat_id_matched();
} else {
- printf("[LN][WS] ChooseStoryResponse from non-active chat %s, ignoring\n", data_msg->chat_id);
+ LN_WS_WARN("ChooseStoryResponse from non-active chat %s, ignoring\n", data_msg->chat_id);
cJSON_Delete(root);
return -1; // 返回错误,不处理此消息
}
}
}
- printf("[LN][WS] ChooseStoryResponse parsed: finished=%s, chatId=%s, storyTheme=%s, storyAudioUrl=%s\n",
+ LN_WS_DEBUG("ChooseStoryResponse parsed: finished=%s, chatId=%s, storyTheme=%s, storyAudioUrl=%s\n",
data_msg->finished ? "true" : "false", data_msg->chat_id, data_msg->text_content, data_msg->audio_url);
}
if (strcmp(g_audio_chat_ctx.chat_id, data_msg->chat_id) == 0) {
set_chat_id_matched();
} else {
- printf("[LN][WS] RandomStoryResponse from non-active chat %s, ignoring\n", data_msg->chat_id);
+ LN_WS_WARN("RandomStoryResponse from non-active chat %s, ignoring\n", data_msg->chat_id);
cJSON_Delete(root);
return -1; // 返回错误,不处理此消息
}
}
}
- printf("[LN][WS] RandomStoryResponse parsed: finished=%s, chatId=%s, storyTheme=%s, storyContent=%s, storyAudioUrl=%s\n",
+ LN_WS_DEBUG("RandomStoryResponse parsed: finished=%s, chatId=%s, storyTheme=%s, storyContent=%s, storyAudioUrl=%s\n",
data_msg->finished ? "true" : "false", data_msg->chat_id, data_msg->text_content,
data_msg->text_content, data_msg->audio_url);
}
cJSON_Delete(root);
- printf("[LN][WS] Message parsed successfully: deviceId=%s, timestamp=%u, messageId=%s, command=%d (%s)\n",
+ LN_WS_DEBUG("Message parsed successfully: deviceId=%s, timestamp=%u, messageId=%s, command=%d (%s)\n",
data_msg->device_id, data_msg->timestamp, data_msg->message_id,
data_msg->command, data_msg->command_str);
*/
static void ln_ws_default_message_handler(const ws_data_msg_t *data_msg, ws_command_t type)
{
- printf("[LN][WS] Default handler: Processing message (type: %d)\n", type);
+ LN_WS_DEBUG("Default handler: Processing message (type: %d)\n", type);
switch (type) {
case WS_CMD_CONNECTED:
- printf("[LN][WS] Default: Processing WebSocket Connected event\n");
+ LN_WS_DEBUG("Default: Processing WebSocket Connected event\n");
break;
case WS_CMD_DISCONNECTED:
- printf("[LN][WS] Default: Processing WebSocket Disconnected event\n");
+ LN_WS_DEBUG("Default: Processing WebSocket Disconnected event\n");
break;
case WS_CMD_AUDIO_PLAYBACK_END:
- printf("[LN][WS] Default: Processing Audio Playback End event\n");
+ LN_WS_DEBUG("Default: Processing Audio Playback End event\n");
break;
case WS_CMD_PONG:
if (data_msg) {
- printf("[LN][WS] Default: Processing Pong message\n");
+ LN_WS_DEBUG("Default: Processing Pong message\n");
// 更新心跳状态、记录响应时间等
}
break;
case WS_CMD_CHARACTER_CHANGE:
if (data_msg) {
- printf("[LN][WS] Default: Processing CharacterChange message\n");
+ LN_WS_DEBUG("Default: Processing CharacterChange message\n");
}
break;
case WS_CMD_SLEEP_MODE_START:
if (data_msg) {
- printf("[LN][WS] Default: Processing SleepModeStart message\n");
+ LN_WS_DEBUG("Default: Processing SleepModeStart message\n");
}
break;
case WS_CMD_SLEEP_MODE_END:
if (data_msg) {
- printf("[LN][WS] Default: Processing SleepModeEnd message\n");
+ LN_WS_DEBUG("Default: Processing SleepModeEnd message\n");
}
break;
case WS_CMD_DEVICE_BIND:
if (data_msg) {
- printf("[LN][WS] Default: Processing DeviceBind message\n");
+ LN_WS_DEBUG("Default: Processing DeviceBind message\n");
}
break;
case WS_CMD_DEVICE_UNBIND:
if (data_msg) {
- printf("[LN][WS] Default: Processing DeviceUnbind message\n");
+ LN_WS_DEBUG("Default: Processing DeviceUnbind message\n");
}
break;
case WS_CMD_SCHEDULE_REMINDER:
if (data_msg) {
- printf("[LN][WS] Default: Processing ScheduleReminder message\n");
+ LN_WS_DEBUG("Default: Processing ScheduleReminder message\n");
}
break;
case WS_CMD_SCHEDULE_REMINDER_CFG:
if (data_msg) {
- printf("[LN][WS] Default: Processing ScheduleReminderConfig message\n");
+ LN_WS_DEBUG("Default: Processing ScheduleReminderConfig message\n");
}
break;
case WS_CMD_VOICE_CHAT_RESPONSE:
if (data_msg) {
- printf("[LN][WS] Default: Processing VoiceChatResponse message\n");
- printf("[LN][WS] VoiceChatResponse details: finished=%s, chatId=%s\n",
+ LN_WS_DEBUG("Default: Processing VoiceChatResponse message\n");
+ LN_WS_DEBUG("VoiceChatResponse details: finished=%s, chatId=%s\n",
data_msg->finished ? "true" : "false", data_msg->chat_id);
- printf("[LN][WS] Audio URL: %s\n", data_msg->audio_url);
- printf("[LN][WS] Text Content: %s\n", data_msg->text_content);
+ LN_WS_DEBUG("Audio URL: %s\n", data_msg->audio_url);
+ LN_WS_DEBUG("Text Content: %s\n", data_msg->text_content);
}
break;
case WS_CMD_CHOOSE_STORY_RESPONSE:
if (data_msg) {
- printf("[LN][WS] Default: Processing ChooseStoryResponse message\n");
- printf("[LN][WS] ChooseStoryResponse details: finished=%s, chatId=%s\n",
+ LN_WS_DEBUG("Default: Processing ChooseStoryResponse message\n");
+ LN_WS_DEBUG("ChooseStoryResponse details: finished=%s, chatId=%s\n",
data_msg->finished ? "true" : "false", data_msg->chat_id);
- printf("[LN][WS] Story Theme: %s\n", data_msg->text_content);
- printf("[LN][WS] Story Audio URL: %s\n", data_msg->audio_url);
+ LN_WS_DEBUG("Story Theme: %s\n", data_msg->text_content);
+ LN_WS_DEBUG("Story Audio URL: %s\n", data_msg->audio_url);
}
break;
case WS_CMD_RANDOM_STORY_RESPONSE:
if (data_msg) {
- printf("[LN][WS] Default: Processing RandomStoryResponse message\n");
- printf("[LN][WS] RandomStoryResponse details: finished=%s, chatId=%s\n",
+ LN_WS_DEBUG("Default: Processing RandomStoryResponse message\n");
+ LN_WS_DEBUG("RandomStoryResponse details: finished=%s, chatId=%s\n",
data_msg->finished ? "true" : "false", data_msg->chat_id);
- printf("[LN][WS] Story Theme: %s\n", data_msg->text_content);
- printf("[LN][WS] Story Audio URL: %s\n", data_msg->audio_url);
+ LN_WS_DEBUG("Story Theme: %s\n", data_msg->text_content);
+ LN_WS_DEBUG("Story Audio URL: %s\n", data_msg->audio_url);
}
break;
case WS_CMD_UNKNOWN:
if (data_msg) {
- printf("[LN][WS] Default: Processing unknown command message\n");
- printf("[LN][WS] Unknown command details: command=%s, deviceId=%s, messageId=%s\n",
+ LN_WS_DEBUG("Default: Processing unknown command message\n");
+ LN_WS_DEBUG("Unknown command details: command=%s, deviceId=%s, messageId=%s\n",
data_msg->command_str, data_msg->device_id, data_msg->message_id);
if (data_msg->raw_json) {
- printf("[LN][WS] Raw JSON: %s\n", data_msg->raw_json);
+ LN_WS_DEBUG("Raw JSON: %s\n", data_msg->raw_json);
}
}
break;
default:
- printf("[LN][WS] Default: Processing unknown command: %d\n", type);
+ LN_WS_DEBUG("Default: Processing unknown command: %d\n", type);
break;
}
}
*/
int ln_ws_enter_sleep(void)
{
- printf("[LN][WS] Entering sleep mode\n");
+ LN_WS_DEBUG("Entering sleep mode\n");
if (!g_ws_running) {
- printf("[LN][WS] WebSocket service not running, cannot enter sleep\n");
+ LN_WS_DEBUG("WebSocket service not running, cannot enter sleep\n");
return -1;
}
int ret = uapi_ws_enter_sleep();
if (ret == 0) {
g_ws_connected = WS_STATE_SLEEP;
- printf("[LN][WS] Sleep mode activated, all operations paused\n");
+ LN_WS_DEBUG("Sleep mode activated, all operations paused\n");
}
return ret;
*/
int ln_ws_exit_sleep(void)
{
- printf("[LN][WS] Exiting sleep mode\n");
+ LN_WS_DEBUG("Exiting sleep mode\n");
if (g_ws_connected != WS_STATE_SLEEP) {
- printf("[LN][WS] Not in sleep mode, current state: %s\n", ln_ws_get_connection_state_string());
+ LN_WS_DEBUG("Not in sleep mode, current state: %s\n", ln_ws_get_connection_state_string());
return -1;
}
int ret = uapi_ws_exit_sleep();
if (ret == 0) {
g_ws_connected = WS_STATE_DISCONNECTED;
- printf("[LN][WS] Sleep mode deactivated, resuming normal operations\n");
+ LN_WS_DEBUG("Sleep mode deactivated, resuming normal operations\n");
}
return ret;
if (g_base64_cache) {
g_base64_cache_size = 0;
g_base64_in_progress = false;
- printf("[LN][WS] Base64 cache initialized with capacity: %zu\n", g_base64_cache_capacity);
+ LN_WS_DEBUG("Base64 cache initialized with capacity: %zu\n", g_base64_cache_capacity);
} else {
- printf("[LN][WS] Failed to initialize Base64 cache\n");
+ LN_WS_ERROR("Failed to initialize Base64 cache\n");
g_base64_cache_capacity = 0;
}
}
g_base64_cache_size = 0;
g_base64_cache_capacity = 0;
g_base64_in_progress = false;
- printf("[LN][WS] Base64 cache cleaned up\n");
+ LN_WS_DEBUG("Base64 cache cleaned up\n");
}
}
if (g_base64_cache) {
g_base64_cache_size = 0;
g_base64_in_progress = false;
- printf("[LN][WS] Base64 cache reset\n");
+ LN_WS_DEBUG("Base64 cache reset\n");
}
}
if (new_cache) {
g_base64_cache = new_cache;
g_base64_cache_capacity = new_capacity;
- printf("[LN][WS] Base64 cache expanded to capacity: %zu\n", g_base64_cache_capacity);
+ LN_WS_DEBUG("Base64 cache expanded to capacity: %zu\n", g_base64_cache_capacity);
} else {
- printf("[LN][WS] Failed to expand Base64 cache\n");
+ LN_WS_ERROR("Failed to expand Base64 cache\n");
return -1;
}
}
g_base64_cache_size += length;
g_base64_cache[g_base64_cache_size] = '\0'; // 确保字符串结束
- printf("[LN][WS] Base64 cache appended %zu bytes, total size: %zu\n", length, g_base64_cache_size);
+ LN_WS_DEBUG("Base64 cache appended %zu bytes, total size: %zu\n", length, g_base64_cache_size);
return 0;
}
static void ln_ws_process_base64_data(const char *base64_data, size_t length)
{
if (!base64_data || length == 0) {
- printf("[LN][WS] Invalid Base64 data parameters\n");
+ LN_WS_ERROR("Invalid Base64 data parameters\n");
return;
}
- printf("[LN][WS] Processing Base64 data: length=%zu\n", length);
+ LN_WS_DEBUG("Processing Base64 data: length=%zu\n", length);
// 检查Base64长度是否有效(必须是4的倍数)
if (length % 4 != 0) {
- printf("[LN][WS] Invalid Base64 length: %zu (not multiple of 4)\n", length);
+ LN_WS_ERROR("Invalid Base64 length: %zu (not multiple of 4)\n", length);
return;
}
}
if (!valid_base64) {
- printf("[LN][WS] Invalid Base64 characters detected\n");
+ LN_WS_ERROR("Invalid Base64 characters detected\n");
return;
}
- printf("[LN][WS] Valid Base64 format detected, attempting decode\n");
+ LN_WS_DEBUG("Valid Base64 format detected, attempting decode\n");
// 计算解码后的数据长度
size_t decoded_length = (length * 3) / 4;
}
}
- printf("[LN][WS] Expected decoded length: %zu\n", decoded_length);
+ LN_WS_DEBUG("Expected decoded length: %zu\n", decoded_length);
// 分配内存进行解码
uint8_t *decoded_data = (uint8_t*)malloc(decoded_length);
length);
if (ret == 0) {
- printf("[LN][WS] Base64 decode successful: %zu bytes decoded\n", actual_decoded_length);
+ LN_WS_DEBUG("Base64 decode successful: %zu bytes decoded\n", actual_decoded_length);
// 这里可以处理解码后的音频数据
// 例如:调用音频处理回调函数
- printf("[LN][WS] Decoded audio data: first 16 bytes: ");
+ LN_WS_DEBUG("Decoded audio data: first 16 bytes: ");
for (size_t i = 0; i < (actual_decoded_length < 16 ? actual_decoded_length : 16); i++) {
printf("%02X ", decoded_data[i]);
}
AI_SendAudioDataToQueue(decoded_data, actual_decoded_length);
} else {
- printf("[LN][WS] Base64 decode failed: %d\n", ret);
+ LN_WS_DEBUG("Base64 decode failed: %d\n", ret);
}
free(temp_base64);
free(decoded_data);
} else {
- printf("[LN][WS] Failed to allocate memory for decoded data\n");
+ LN_WS_ERROR("Failed to allocate memory for decoded data\n");
}
}
return;
}
- printf("[LN][WS] Processing incremental Base64 data: length=%zu\n", new_length);
+ LN_WS_DEBUG("Processing incremental Base64 data: length=%zu\n", new_length);
// 确保缓存已初始化
if (g_base64_cache == NULL) {
// 将新数据追加到缓存
if (ln_ws_base64_cache_append(new_data, new_length) != 0) {
- printf("[LN][WS] Failed to append data to cache\n");
+ LN_WS_ERROR("Failed to append data to cache\n");
return;
}
size_t decodable_length = (g_base64_cache_size / 4) * 4;
if (decodable_length > 0) {
- printf("[LN][WS] Decodable length: %zu, total cache: %zu\n", decodable_length, g_base64_cache_size);
+ LN_WS_DEBUG("Decodable length: %zu, total cache: %zu\n", decodable_length, g_base64_cache_size);
// 解码可用的完整数据
ln_ws_process_base64_data(g_base64_cache, decodable_length);
// 保留多余的字符(不足4个字符的部分)
size_t remaining_length = g_base64_cache_size - decodable_length;
if (remaining_length > 0) {
- printf("[LN][WS] Keeping %zu remaining characters in cache\n", remaining_length);
+ LN_WS_DEBUG("Keeping %zu remaining characters in cache\n", remaining_length);
// 将剩余字符移到缓存开头
memmove(g_base64_cache, g_base64_cache + decodable_length, remaining_length);
ln_ws_base64_cache_reset();
}
} else {
- printf("[LN][WS] Not enough data for Base64 decode yet: %zu\n", g_base64_cache_size);
+ LN_WS_DEBUG("Not enough data for Base64 decode yet: %zu\n", g_base64_cache_size);
}
}
#include <string.h>
#include <stdio.h>
#include <time.h>
+#include <stdarg.h>
#include "cJSON.h" // Added for JSON parsing
#include "custom_utils.h"
#include "soc_osal.h"
#include "cmsis_os2.h"
#include "haisi_websocket.h"
+/* ============================ 日志系统 ============================ */
+
+// 打印等级定义
+typedef enum {
+ HAISI_WS_LOG_ERROR = 0, // 错误信息
+ HAISI_WS_LOG_WARN = 1, // 警告信息
+ HAISI_WS_LOG_INFO = 2, // 一般信息
+ HAISI_WS_LOG_DEBUG = 3 // 调试信息
+} haisi_ws_log_level_t;
+
+// 当前日志等级(可通过配置修改)
+static haisi_ws_log_level_t g_haisi_log_level = HAISI_WS_LOG_INFO;
+
+
+// 日志等级字符串数组
+static const char *g_log_level_str[] = {
+ "[ERROR]", "[WARN ]", "[INFO]", "[DEBUG]"
+};
+
+// 日志宏定义
+#define HAISI_WS_LOG(level, line, fmt, ...) do { \
+ if (level <= g_haisi_log_level) { \
+ printf("[HAISI_WS %d]%s " fmt, line, g_log_level_str[level], ##__VA_ARGS__); \
+ } \
+} while(0)
+
+// 便捷打印宏
+#define HAISI_WS_ERROR(fmt, ...) HAISI_WS_LOG(HAISI_WS_LOG_ERROR, __LINE__, fmt, ##__VA_ARGS__)
+#define HAISI_WS_WARN(fmt, ...) HAISI_WS_LOG(HAISI_WS_LOG_WARN, __LINE__, fmt, ##__VA_ARGS__)
+#define HAISI_WS_INFO(fmt, ...) HAISI_WS_LOG(HAISI_WS_LOG_INFO, __LINE__, fmt, ##__VA_ARGS__)
+#define HAISI_WS_DEBUG(fmt, ...) HAISI_WS_LOG(HAISI_WS_LOG_DEBUG, __LINE__, fmt, ##__VA_ARGS__)
+
/*
* - g_ws_client_fd 当前 WebSocket 客户端fd
* - g_ws_connected 连接状态:0=未连接,1=连接中,2=连接成功
{
ws_msg_info_t *msg = (ws_msg_info_t*)malloc(sizeof(ws_msg_info_t));
if (msg == NULL) {
- printf("[LN][WS] Failed to allocate memory for ws_msg_info_t\n");
+ HAISI_WS_ERROR("Failed to allocate memory for ws_msg_info_t\n");
return NULL;
}
msg->raw_data = (char*)malloc(data_len + 1); // +1 for null terminator
if (msg->raw_data == NULL) {
- printf("[LN][WS] Failed to allocate memory for raw_data (size: %d)\n", data_len);
+ HAISI_WS_ERROR("Failed to allocate memory for raw_data (size: %d)\n", data_len);
free(msg);
return NULL;
}
/* 队列创建函数 */
void uapi_ws_queue_init(void)
{
- printf("[LN][WS] uapi_ws_queue_init\n");
+ HAISI_WS_DEBUG("uapi_ws_queue_init\n");
g_ws_msg_queue = osMessageQueueNew(WS_MSG_QUEUE_COUNT, sizeof(ws_msg_info_t*), NULL);
if (g_ws_msg_queue == NULL) {
- printf("[LN][WS] uapi_ws_queue_init failed: failed to create message queue\n");
+ HAISI_WS_ERROR("uapi_ws_queue_init failed: failed to create message queue\n");
} else {
- printf("[LN][WS] uapi_ws_queue_init success: queue created\n");
+ HAISI_WS_DEBUG("uapi_ws_queue_init success: queue created\n");
}
}
static void uapi_ws_on_open(int client)
{
(void)client;
- printf("WebSocketClientConstructor uapi_ws_on_open\r\n");
+ HAISI_WS_DEBUG("WebSocketClientConstructor uapi_ws_on_open\r\n");
g_ws_connected = WS_STATE_CONNECTED;
uapi_ws_reset_close_status(); // 连接成功时重置关闭状态
uapi_ws_reset_connect_timer(); // 连接成功时重置超时计时器
- printf("[LN][WS] 连接状态: 连接成功, 关闭状态已重置为 NOT_EXECUTED (%d)\n", g_ws_close_status);
+ HAISI_WS_DEBUG("连接状态: 连接成功, 关闭状态已重置为 NOT_EXECUTED (%d)\n", g_ws_close_status);
}
/*
if (data == NULL || length == 0) return;
/* 数据完整性判断 */
- printf("WebSocketClientConstructor data %d\r\n",length);
+ HAISI_WS_DEBUG("WebSocketClientConstructor data %d\n",length);
if (isFinished) {
// 数据完整,创建消息结构体
if (g_ws_callbacks.binary_callback != NULL) {
g_ws_callbacks.binary_callback(data, timestamp, length);
} else {
- printf("[LN][WS] No binary message callback registered\n");
+ HAISI_WS_WARN("No binary message callback registered\n");
}
// 二进制消息处理完后释放内存
}
{
ws_msg_info_t *msg = ws_msg_create(length);
if (msg == NULL) {
- printf("[LN][WS] Failed to create message structure\n");
+ HAISI_WS_ERROR("Failed to create message structure\n");
return;
}
osStatus_t ret = osMessageQueuePut(g_ws_msg_queue, &msg, 0, 0);
if (ret == osOK) {
- printf("[LN][WS] Raw message queued successfully, length: %d, timestamp: %u\n", msg->data_len, msg->timestamp);
+ HAISI_WS_DEBUG("Raw message queued successfully, length: %d, timestamp: %u\n", msg->data_len, msg->timestamp);
} else {
- printf("[LN][WS] Failed to queue raw message: %d\n", ret);
+ HAISI_WS_ERROR("Failed to queue raw message: %d\n", ret);
// 队列失败时释放内存
ws_msg_free(msg);
}
}
else {
- printf("[LN][WS] Incomplete or invalid message data\n");
+ HAISI_WS_WARN("Incomplete or invalid message data\n");
// 数据不完整时调用回调函数
if (g_ws_callbacks.incomplete_callback != NULL) {
g_ws_callbacks.incomplete_callback(data, length, isBinary);
static void uapi_ws_on_error(int client, struct WebSocketErrorResult error)
{
(void)client;
- printf("WebSocketClientConstructor [LN][WS] error: code=%d msg=%s\n", error.errorCode, error.errorMessage);
+ HAISI_WS_ERROR("WebSocketClientConstructor error: code=%d msg=%s\n", error.errorCode, error.errorMessage);
}
/* 断开回调:标记为未连接。是否自动重连交由上层决定 */
static void uapi_ws_on_close(int client)
{
- printf("WebSocketClientConstructor [LN][WS] uapi_ws_on_close %d\r\n",client);
+ HAISI_WS_DEBUG("WebSocketClientConstructor uapi_ws_on_close %d\n",client);
// 在断开回调触发时,将关闭状态设置为成功
- printf("[LN][WS] WebSocket close callback triggered, status set to SUCCESS (%d)\n", g_ws_close_status);
+ HAISI_WS_INFO("WebSocket close callback triggered, status set to SUCCESS (%d)\n", g_ws_close_status);
g_ws_connected = WS_STATE_DISCONNECTED;
- printf("[LN][WS] 连接状态: 未连接\n");
+ HAISI_WS_DEBUG("连接状态: 未连接\n");
// 触发连接断开事件(注意:这里不能直接调用回调,因为不在主线程中)
// 事件回调将在主线程中处理
while (g_ws_running) {
// 处理队列消息(非阻塞)
if (osMessageQueueGet(g_ws_msg_queue, &msg, NULL, 1000) == osOK) {
- printf("[LN][WS] osMessageQueueGet: g_ws_msg_queue\n");
+ HAISI_WS_DEBUG("osMessageQueueGet: g_ws_msg_queue\n");
switch (msg->msg_type) {
case WS_MSG_TYPE_SEND_TEXT:
if (g_ws_connected == WS_STATE_CONNECTED && g_ws_client_fd >= 0) {
// 对于文本消息,我们需要特殊处理,因为现在data是ws_data_msg_t类型
// 这里需要重新设计文本消息的存储方式
- printf("[LN][WS] Text message type not supported in new structure\n");
+ HAISI_WS_WARN("Text message type not supported in new structure\n");
} else {
- printf("[LN][WS] Cannot send text, connection state: %d\n", g_ws_connected);
+ HAISI_WS_WARN("Cannot send text, connection state: %d\n", g_ws_connected);
}
ws_msg_free(msg);
break;
case WS_MSG_TYPE_FORCE_RECONNECT:
- printf("[LN][WS] Force reconnect requested\n");
+ HAISI_WS_INFO("Force reconnect requested\n");
if (g_ws_client_fd >= 0) {
- printf("[LN][WS] WebSocketClientClose\n");
+ HAISI_WS_DEBUG("WebSocketClientClose\n");
uapi_ws_close_with_status(g_ws_client_fd);
g_ws_client_fd=-1;
- printf("[LN][WS] WebSocketClientClose end\n");
+ HAISI_WS_DEBUG("WebSocketClientClose end\n");
}
g_ws_connected = WS_STATE_DISCONNECTED;
- printf("[LN][WS] 连接状态: 未连接(强制重连)\n");
+ HAISI_WS_INFO("连接状态: 未连接(强制重连)\n");
ws_msg_free(msg);
break;
case WS_MSG_TYPE_STOP:
- printf("[LN][WS] Stop requested from queue\n");
+ HAISI_WS_INFO("Stop requested from queue\n");
g_ws_running = 0;
ws_msg_free(msg);
break;
case WS_MSG_TYPE_RAW_MESSAGE:
{
- printf("[LN][WS] Received raw message: %s, timestamp: %u, isBinary: %s\n",
+ HAISI_WS_DEBUG("Received raw message: %s, timestamp: %u, isBinary: %s\n",
msg->raw_data, msg->timestamp, msg->isBinary ? "true" : "false");
// 根据消息类型调用不同的回调函数
if (g_ws_callbacks.message_callback != NULL) {
g_ws_callbacks.message_callback(msg->raw_data, msg->timestamp);
} else {
- printf("[LN][WS] No text message callback registered\n");
+ HAISI_WS_WARN("No text message callback registered\n");
}
}
// 处理完消息后释放内存
break;
default:
- printf("[LN][WS] Unknown message type: %d\n", msg->msg_type);
+ HAISI_WS_WARN("Unknown message type: %d\n", msg->msg_type);
ws_msg_free(msg);
break;
}
}
else
{
- // printf("osMessageQueueGet timeout or failed\r\n");
+ // HAISI_WS_DEBUG("osMessageQueueGet timeout or failed\r\n");
}
// 检测连接状态变化并触发事件回调
// 连接管理部分
if (g_ws_connected == WS_STATE_SLEEP) {
// 休眠状态:暂停所有操作,只打印状态信息
- printf("[LN][WS] Sleep mode: pausing all operations\n");
+ HAISI_WS_DEBUG("Sleep mode: pausing all operations\n");
usleep(1000 * 1000); // 休眠1秒
continue;
}
if (g_ws_client_fd >= 0) {
{
if(g_ws_close_status== WS_CLOSE_NOT_EXECUTED){
- printf("[LN][WS] WebSocketClientClose WS_CLOSE_NOT_EXECUTED\n");
+ HAISI_WS_DEBUG("WebSocketClientClose WS_CLOSE_NOT_EXECUTED\n");
uapi_ws_close_with_status(g_ws_client_fd);
g_ws_close_status = WS_CLOSE_NOT_EXECUTED;
g_ws_client_fd=-1;
- printf("[LN][WS] WebSocketClientClose WS_CLOSE_NOT_EXECUTED end\n");
+ HAISI_WS_DEBUG("WebSocketClientClose WS_CLOSE_NOT_EXECUTED end\n");
}
}
}
if (g_ws_client_fd < 0) {
- printf("[LN][WS] 开始创建WebSocket客户端...\n");
+ HAISI_WS_DEBUG("开始创建WebSocket客户端...\n");
// 触发连接开始事件
if (g_ws_callbacks.event_callback != NULL) {
g_ws_client_fd = WebSocketClientConstructor(uapi_ws_on_open, uapi_ws_on_message, uapi_ws_on_error, uapi_ws_on_close);
if (g_ws_client_fd < 0) {
- printf("[LN][WS] constructor failed: %d\n", g_ws_client_fd);
+ HAISI_WS_ERROR("constructor failed: %d\n", g_ws_client_fd);
g_ws_connected = WS_STATE_DISCONNECTED;
- printf("[LN][WS] 连接状态: 未连接(创建失败)\n");
+ HAISI_WS_ERROR("连接状态: 未连接(创建失败)\n");
/* 失败则短暂休眠后重试创建 */
usleep(2000 * 1000);
continue;
g_ws_callbacks.url_callback(url, sizeof(url), header_buf, sizeof(header_buf));
}
- printf("[LN][WS] 尝试连接WebSocket: %s\n", url);
- printf("[LN][WS] 使用Header: %s\n", header_buf);
+ HAISI_WS_DEBUG("尝试连接WebSocket: %s\n", url);
+ HAISI_WS_DEBUG("使用Header: %s\n", header_buf);
int ret=0;
if(strlen(header_buf)==0)
{
// int ret = WebSocketClientConnect(g_ws_client_fd,"ws://118.145.158.207:22080/chat/ws?platform=huoshan");
if (ret != 0) {
- printf("[LN][WS] connect failed: %d\n", ret);
+ HAISI_WS_ERROR("connect failed: %d\n", ret);
g_ws_connected = WS_STATE_DISCONNECTED;
- printf("[LN][WS] 连接状态: 未连接(连接失败)\n");
+ HAISI_WS_ERROR("连接状态: 未连接(连接失败)\n");
uapi_ws_reset_connect_timer(); // 连接失败时重置超时计时器
(void)uapi_ws_close_with_status(g_ws_client_fd);
g_ws_client_fd = -1;
g_ws_connected = WS_STATE_CONNECTING;
}
/* 连接请求已发送,等待握手完成 */
- printf("[LN][WS] 连接请求已发送,等待握手完成...\n");
+ HAISI_WS_DEBUG("连接请求已发送,等待握手完成...\n");
}
// 连接超时检测:在连接中状态时检查是否超时
if (g_ws_connected == WS_STATE_CONNECTING) {
if (uapi_ws_is_connect_timeout()) {
- printf("[LN][WS] Connection timeout detected, forcing disconnect and reconnect\n");
+ HAISI_WS_WARN("Connection timeout detected, forcing disconnect and reconnect\n");
// 强制关闭连接
if (g_ws_client_fd >= 0) {
g_ws_reconnect_count++;
}
- printf("[LN][WS] Connection timeout handled, will retry connection\n");
+ HAISI_WS_INFO("Connection timeout handled, will retry connection\n");
}
}
if (g_ws_callbacks.heartbeat_callback != NULL) {
if (g_ws_callbacks.heartbeat_callback()) {
// 回调函数返回1表示需要发送心跳,这里可以添加额外的处理
- printf("[LN][WS] Heartbeat callback triggered\n");
+ HAISI_WS_DEBUG("Heartbeat callback triggered\n");
}
}
}
else
{
- printf("ln ws_state %s\r\n",uapi_ws_get_connection_state_string());
+ HAISI_WS_INFO("ws_state %s\n",uapi_ws_get_connection_state_string());
}
/* 1秒间隔 */
- usleep(1000 * 1000);
+ if(g_ws_connected!=WS_STATE_CONNECTED)
+ {
+ usleep(1000 * 1000);
+
+ }
}
if (g_ws_client_fd >= 0) {
uapi_ws_close_with_status(g_ws_client_fd);
+ // g_ws_client_fd=-1
}
g_ws_connected = WS_STATE_DISCONNECTED;
ws_msg_info_t msg;
while (osMessageQueueGet(g_ws_msg_queue, &msg, NULL, 0) == osOK) {
// 原始消息数据不需要额外释放,因为存储在栈上
- printf("[LN][WS] Clearing queued message: %s\n", msg.raw_data);
+ HAISI_WS_DEBUG("Clearing queued message: %s\n", msg.raw_data);
+ ws_msg_free(&msg);
+
}
osMessageQueueDelete(g_ws_msg_queue);
g_ws_msg_queue = NULL;
// 注册回调函数结构体
if (callbacks != NULL) {
g_ws_callbacks = *callbacks;
- printf("[LN][WS] WebSocket callbacks registered successfully\n");
+ HAISI_WS_INFO("WebSocket callbacks registered successfully\n");
if (g_ws_callbacks.message_callback != NULL) {
- printf("[LN][WS] Text message callback registered\n");
+ HAISI_WS_DEBUG("Text message callback registered\n");
} else {
- printf("[LN][WS] No text message callback registered\n");
+ HAISI_WS_WARN("No text message callback registered\n");
}
if (g_ws_callbacks.binary_callback != NULL) {
- printf("[LN][WS] Binary message callback registered\n");
+ HAISI_WS_DEBUG("Binary message callback registered\n");
} else {
- printf("[LN][WS] No binary message callback registered\n");
+ HAISI_WS_WARN("No binary message callback registered\n");
}
if (g_ws_callbacks.url_callback != NULL) {
- printf("[LN][WS] URL callback registered\n");
+ HAISI_WS_DEBUG("URL callback registered\n");
} else {
- printf("[LN][WS] Using default URL handler\n");
+ HAISI_WS_DEBUG("Using default URL handler\n");
}
if (g_ws_callbacks.heartbeat_callback != NULL) {
- printf("[LN][WS] Heartbeat callback registered\n");
+ HAISI_WS_DEBUG("Heartbeat callback registered\n");
} else {
- printf("[LN][WS] No heartbeat callback registered\n");
+ HAISI_WS_WARN("No heartbeat callback registered\n");
}
if (g_ws_callbacks.event_callback != NULL) {
- printf("[LN][WS] Event callback registered\n");
+ HAISI_WS_DEBUG("Event callback registered\n");
} else {
- printf("[LN][WS] No event callback registered\n");
+ HAISI_WS_WARN("No event callback registered\n");
}
} else {
memset(&g_ws_callbacks, 0, sizeof(ws_call_backs_t));
- printf("[LN][WS] No callbacks provided, using defaults\n");
+ HAISI_WS_DEBUG("No callbacks provided, using defaults\n");
}
if (!g_ws_main_thread) {
app_task_definition_ext_t main_task = {
{
if (!text) return -1;
if (g_ws_connected != WS_STATE_CONNECTED || g_ws_client_fd < 0) {
- printf("[LN][WS] Cannot send text, connection state: %d\n", g_ws_connected);
+ HAISI_WS_WARN("Cannot send text, connection state: %d\n", g_ws_connected);
return -1;
}
return WebSocketClientSendText(g_ws_client_fd, text, strlen(text));
{
if (!data) return -1;
if (g_ws_connected != WS_STATE_CONNECTED || g_ws_client_fd < 0) {
- printf("[LN][WS] Cannot send text, connection state: %d\n", g_ws_connected);
+ HAISI_WS_WARN("Cannot send text, connection state: %d\n", g_ws_connected);
return -1;
}
if(len%3)
}
size_uapi_ws_send_BIN+=len;
- printf("[LN][WS] uapi_ws_send_BIN,size: %d %d\n", len,size_uapi_ws_send_BIN);
+ HAISI_WS_DEBUG("uapi_ws_send_BIN,size: %d %d\n", len,size_uapi_ws_send_BIN);
return 0;
}
// 由于新的数据结构不支持直接文本消息,这里暂时返回错误
// 如果需要支持文本消息,需要重新设计消息类型
- printf("[LN][WS] Text message not supported in new queue structure\n");
+ HAISI_WS_WARN("Text message not supported in new queue structure\n");
return -1;
}
ws_msg_info_t *msg = ws_msg_create(0);
if (msg == NULL) {
- printf("[LN][WS] Failed to create force reconnect message\n");
+ HAISI_WS_ERROR("Failed to create force reconnect message\n");
return -1;
}
ws_msg_info_t *msg = ws_msg_create(0);
if (msg == NULL) {
- printf("[LN][WS] Failed to create stop message\n");
+ HAISI_WS_ERROR("Failed to create stop message\n");
return -1;
}
{
g_ws_callbacks.message_callback = callback;
if (callback != NULL) {
- printf("[LN][WS] Text message callback registered successfully\n");
+ HAISI_WS_DEBUG("Text message callback registered successfully\n");
} else {
- printf("[LN][WS] Text message callback unregistered\n");
+ HAISI_WS_DEBUG("Text message callback unregistered\n");
}
}
{
g_ws_callbacks.binary_callback = callback;
if (callback != NULL) {
- printf("[LN][WS] Binary message callback registered successfully\n");
+ HAISI_WS_DEBUG("Binary message callback registered successfully\n");
} else {
- printf("[LN][WS] Binary message callback unregistered\n");
+ HAISI_WS_DEBUG("Binary message callback unregistered\n");
}
}
{
g_ws_callbacks.incomplete_callback = callback;
if (callback != NULL) {
- printf("[LN][WS] Incomplete message callback registered successfully\n");
+ HAISI_WS_DEBUG("Incomplete message callback registered successfully\n");
} else {
- printf("[LN][WS] Incomplete message callback unregistered\n");
+ HAISI_WS_DEBUG("Incomplete message callback unregistered\n");
}
}
{
g_ws_callbacks.url_callback = callback;
if (callback != NULL) {
- printf("[LN][WS] URL callback registered successfully\n");
+ HAISI_WS_DEBUG("URL callback registered successfully\n");
} else {
- printf("[LN][WS] URL callback unregistered\n");
+ HAISI_WS_DEBUG("URL callback unregistered\n");
}
}
{
g_ws_callbacks.heartbeat_callback = callback;
if (callback != NULL) {
- printf("[LN][WS] Heartbeat callback registered successfully\n");
+ HAISI_WS_DEBUG("Heartbeat callback registered successfully\n");
} else {
- printf("[LN][WS] Heartbeat callback unregistered\n");
+ HAISI_WS_DEBUG("Heartbeat callback unregistered\n");
}
}
{
g_ws_callbacks.event_callback = callback;
if (callback != NULL) {
- printf("[LN][WS] Event callback registered successfully\n");
+ HAISI_WS_DEBUG("Event callback registered successfully\n");
} else {
- printf("[LN][WS] Event callback unregistered\n");
+ HAISI_WS_DEBUG("Event callback unregistered\n");
}
}
static int uapi_ws_close_with_status(int client_fd)
{
if (client_fd < 0) {
- printf("[LN][WS] Invalid client_fd for close operation\n");
+ HAISI_WS_ERROR("Invalid client_fd for close operation\n");
return -1;
}
// 设置状态为开始执行
g_ws_close_status = WS_CLOSE_STARTING;
- printf("[LN][WS] WebSocketClientClose starting, fd=%d, status=%d\n", client_fd, g_ws_close_status);
+ HAISI_WS_DEBUG("WebSocketClientClose starting, fd=%d, status=%d\n", client_fd, g_ws_close_status);
// 执行关闭操作
int ret = WebSocketClientClose(client_fd);
// 注意:成功状态由 ln_ws_on_close 回调函数设置,这里只处理失败情况
if (ret != 0) {
g_ws_close_status = WS_CLOSE_NOT_EXECUTED;
- printf("[LN][WS] WebSocketClientClose failed, fd=%d, ret=%d, status=%d\n", client_fd, ret, g_ws_close_status);
+ HAISI_WS_ERROR("WebSocketClientClose failed, fd=%d, ret=%d, status=%d\n", client_fd, ret, g_ws_close_status);
} else {
- printf("[LN][WS] WebSocketClientClose call returned success, waiting for close callback\n");
+ HAISI_WS_DEBUG("WebSocketClientClose call returned success, waiting for close callback\n");
}
return ret;
static void uapi_ws_reset_close_status(void)
{
g_ws_close_status = WS_CLOSE_NOT_EXECUTED;
- printf("[LN][WS] WebSocket close status reset to NOT_EXECUTED (%d)\n", g_ws_close_status);
+ HAISI_WS_DEBUG("WebSocket close status reset to NOT_EXECUTED (%d)\n", g_ws_close_status);
}
/* ============================ 公共接口函数 ============================ */
*/
void uapi_ws_print_status_info(void)
{
- printf("[LN][WS] === WebSocket Status Info ===\n");
- printf("[LN][WS] Connection State: %s (%d)\n", uapi_ws_get_connection_state_string(), g_ws_connected);
- printf("[LN][WS] Close Status: %d (0=NOT_EXECUTED, 1=STARTING, 2=SUCCESS)\n", g_ws_close_status);
- printf("[LN][WS] Client FD: %d\n", g_ws_client_fd);
- printf("[LN][WS] Running: %d\n", g_ws_running);
- printf("[LN][WS] Reconnect Count: %u\n", g_ws_reconnect_count);
- printf("[LN][WS] ===============================\n");
+ HAISI_WS_DEBUG("=== WebSocket Status Info ===\n");
+ HAISI_WS_DEBUG("Connection State: %s (%d)\n", uapi_ws_get_connection_state_string(), g_ws_connected);
+ HAISI_WS_DEBUG("Close Status: %d (0=NOT_EXECUTED, 1=STARTING, 2=SUCCESS)\n", g_ws_close_status);
+ HAISI_WS_DEBUG("Client FD: %d\n", g_ws_client_fd);
+ HAISI_WS_DEBUG("Running: %d\n", g_ws_running);
+ HAISI_WS_DEBUG("Reconnect Count: %u\n", g_ws_reconnect_count);
+ HAISI_WS_DEBUG("===============================\n");
}
/**
*/
int uapi_ws_enter_sleep(void)
{
- printf("[LN][WS] Entering sleep mode\n");
+ HAISI_WS_INFO("Entering sleep mode\n");
if (!g_ws_running) {
- printf("[LN][WS] WebSocket service not running, cannot enter sleep\n");
+ HAISI_WS_WARN("WebSocket service not running, cannot enter sleep\n");
return -1;
}
// 如果当前有连接,先断开
if (g_ws_client_fd >= 0) {
- printf("[LN][WS] Disconnecting before entering sleep mode\n");
+ HAISI_WS_DEBUG("Disconnecting before entering sleep mode\n");
uapi_ws_close_with_status(g_ws_client_fd);
}
// 设置状态为休眠
g_ws_connected = WS_STATE_SLEEP;
- printf("[LN][WS] Sleep mode activated, all operations paused\n");
+ HAISI_WS_INFO("Sleep mode activated, all operations paused\n");
return 0;
}
*/
int uapi_ws_exit_sleep(void)
{
- printf("[LN][WS] Exiting sleep mode\n");
+ HAISI_WS_INFO("Exiting sleep mode\n");
if (g_ws_connected != WS_STATE_SLEEP) {
- printf("[LN][WS] Not in sleep mode, current state: %s\n", uapi_ws_get_connection_state_string());
+ HAISI_WS_WARN("Not in sleep mode, current state: %s\n", uapi_ws_get_connection_state_string());
return -1;
}
// 设置状态为断开,让主线程重新开始连接
g_ws_connected = WS_STATE_DISCONNECTED;
- printf("[LN][WS] Sleep mode deactivated, resuming normal operations\n");
+ HAISI_WS_INFO("Sleep mode deactivated, resuming normal operations\n");
return 0;
}
{
g_ws_connect_start_time = time(NULL);
g_ws_connect_timeout_occurred = 0;
- printf("[LN][WS] Connect timer started, timeout: %d seconds\n", WS_CONNECT_TIMEOUT_SECONDS);
+ HAISI_WS_DEBUG("Connect timer started, timeout: %d seconds\n", WS_CONNECT_TIMEOUT_SECONDS);
}
/**
if (elapsed >= WS_CONNECT_TIMEOUT_SECONDS) {
if (!g_ws_connect_timeout_occurred) {
g_ws_connect_timeout_occurred = 1;
- printf("[LN][WS] Connect timeout after %ld seconds (limit: %d seconds)\n",
+ HAISI_WS_WARN("Connect timeout after %ld seconds (limit: %d seconds)\n",
elapsed, WS_CONNECT_TIMEOUT_SECONDS);
}
return 1;
{
g_ws_connect_start_time = 0;
g_ws_connect_timeout_occurred = 0;
- printf("[LN][WS] Connect timer reset\n");
+ HAISI_WS_DEBUG("Connect timer reset\n");
}