HAND_DOWNLOAD_EMOJI_NOTIFY, // 下载表情通知
HAND_CHAT_STAMINA_NOTIFY, // 对话体力与流量通知
HAND_API_ERROR_NOTIFY, // 协议错误通知
+ HAND_BIND_AND_UNBIND_NOTIFY, // 绑定和解绑通知
MAX_NUM_HANDLER,
} UiServiceMsgId;
NO_NETWORK = 3, // 没有网络
};
- BindingStatus CheckBindingStatus();
// 设备状态枚举
enum class DeviceStatus {
// 哄睡模式处理函数
void HandleSleepModeStart(const char* theme);
void HandleSleepModeEnd();
+ void HandleBindAndUnbind(int is_bind);
// 减低视频帧率
void LowFrequence();
// 恢复视频帧率
{
return bind_status;
}
- //判断是否绑定
- ThunderBirdModel::BindingStatus ThunderBirdModel::CheckBindingStatus()
- {
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::CheckBindingStatus");
- // TODO: 实现实际的绑定状态检查逻辑
- if(uapi_ln_is_device_bound() == 0)//未绑定
- {
- return BindingStatus::NOT_BOUND;
- }
- else if(uapi_ln_is_device_bound() == 1)//已绑定
- {
- //存储kv
- (void)UtilsSetValue("bind_status", "1");
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::CheckBindingStatus: 已绑定");
- bind_status = true;
- return BindingStatus::BOUND;
- }
- else if(uapi_ln_is_device_bound() == 2)//认证失败
- {
- return BindingStatus::AUTH_FAILURE;
- }
- return BindingStatus::NO_NETWORK;
- }
// ==================== 对话相关函数 ====================
bool ThunderBirdModel::StartRecording()
{
//发送获取绑定用户ID
do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_GET_USER_ID, NULL, 0);
- // 获取到设备是未绑定状态,但是内部有绑定记录 需要恢复出厂
- if(bind_status == true && uapi_ln_is_device_bound() == 0)
- {
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "恢复出厂");
- restore_factory_settings();
- return;
- }
+ // // 获取到设备是未绑定状态,但是内部有绑定记录 需要恢复出厂
+ // if(bind_status == true && uapi_ln_is_device_bound() == 0)
+ // {
+ // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "恢复出厂");
+ // restore_factory_settings();
+ // return;
+ // }
// 网络连接成功,调用HTTP服务获取设备Token
// 获取一下OTA 是否有最新版本
int ota = ota_update_boot();
int currentView = ThunderBirdMainView::GetInstance()->GetCurrentView(); //获取当前视图
ThunderBirdMainView::GetInstance()->ChangeView(currentView, THUNDERBIRD_LULLABYVIEW, ThunderBirdLullabyView::THUNDERBIRD_LULLABYVIEW_5);
}
+
+ void ThunderBirdModel::HandleBindAndUnbind(int is_bind)
+ {
+ if(is_bind == 1)
+ {
+ // 判断是否已经绑定了
+ char temp[10] = { 0 };
+ (void)UtilsGetValue("bind_status", temp, 10);
+ if(strcmp(temp, "1") == 0)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleBindAndUnbind: 已绑定,无需再去绑定");
+ return;
+ }
+ else
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleBindAndUnbind: 未绑定,开始绑定");
+ //存储kv
+ (void)UtilsSetValue("bind_status", "1");
+ //绑定成功
+ int currentView = ThunderBirdMainView::GetInstance()->GetCurrentView(); //获取当前视图
+ if(ThunderBirdMainView::GetInstance()){
+ ThunderBirdMainView::GetInstance()->ChangeView(currentView, THUNDERBIRD_DIALOGUEVIEW, ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_SPEAKING);
+ }
+ }
+ }
+ else
+ {
+ // 先判断本地是否有用户数据
+ char temp[10] = { 0 };
+ (void)UtilsGetValue("bind_status", temp, 10);
+ if(strcmp(temp, "1") == 0)
+ {
+ //解绑
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleBindAndUnbind: 已解绑");
+ do_restore_factory_setting();
+ }
+ else
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleBindAndUnbind: 本地没有用户数据无需解绑");
+ }
+ }
+ }
+
//减低视频帧率 开启对话调用开启
void ThunderBirdModel::LowFrequence()
{
//如果在二维码界面 要一直判断绑定状态 绑定成功就返回主界面
if(currentSubView == ThunderBirdGuideView::THUNDERBIRD_GUIDEVIEW_3)
{
- ThunderBirdModel::BindingStatus bindingStatus = ThunderBirdModel::GetInstance()->CheckBindingStatus();
- if(bindingStatus == ThunderBirdModel::BindingStatus::BOUND)
- {
- //绑定成功
- ThunderBirdMainView::GetInstance()->ChangeView(currentView, THUNDERBIRD_DIALOGUEVIEW, ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_SPEAKING);
- }
- else
- {
- //更新二维码
- UpdateQrcodeIfValid();
- }
+ //更新二维码
+ UpdateQrcodeIfValid();
}
//如果是在对话界面 需要根据对话状态去拿对话数据进行更新
if(currentSubView == ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_SPEAKING)
static void HandChatStaminaNotify(Request *request);
static void HandDownloadEmojiNotify(Request *request);
static void HandApiErrorNotify(Request *request);
+static void HandBindAndUnbindNotify(Request *request);
// 消息处理程序项数组(每个消息类型对应一个处理函数,函数名以 Handle 开头)
MsgHandlerEntry msgHandlers[] = {
{HANDLE_JUMP_OTA_VIEW, HandleJumpOtaView},
{HAND_CHAT_STAMINA_NOTIFY,HandChatStaminaNotify},
{HAND_DOWNLOAD_EMOJI_NOTIFY,HandDownloadEmojiNotify},
{HAND_API_ERROR_NOTIFY,HandApiErrorNotify},
+ {HAND_BIND_AND_UNBIND_NOTIFY,HandBindAndUnbindNotify},
};
/* -------------------------------------------------------------------------- */
void ScreenTurnOn(int32_t timeout)
WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandApiErrorNotify msg_id = %d", request->msgId);
std::string value(static_cast<char*>(request->data), request->len);
}
+
+// 绑定和解绑通知
+void HandBindAndUnbindNotify(Request *request)
+{
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandBindAndUnbindNotify msg_id = %d", request->msgId);
+ int is_bind = *(int *)request->data;
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandBindAndUnbindNotify is_bind = %d", is_bind);
+ GraphicService::GetInstance()->PostGraphicEvent(
+ std::bind(&OHOS::ThunderBirdModel::HandleBindAndUnbind,OHOS::ThunderBirdModel::GetInstance(), is_bind));
+}
+
/* -------------------------------------------------------------------------- */
#ifdef __cplusplus
}
do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_GET_USER_ID, NULL, 0);
return ERRCODE_SUCC;
}
-/* 设备-设置绑定用户ID:AT^LN_SET_DEV_USERID */
-static uint32_t ln_device_set_userid_at(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+static uint32_t ln_notify_bind_and_unbind_at(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
{
- VAD_UNUSED(para);
- VAD_UNUSED(paraLen);
VAD_UNUSED(strCommonCmd);
- printf("[LN][DEVICE_SET_USER_ID]\n");
- uapi_ln_set_device_bound(LN_DEVICE_BIND_STATUS_BOUND);
+
+ uint8_t argv[LN_MAX_ARGC][LN_MAX_ARGV_LEN] = {0};
+ uint32_t argc = 0;
+
+ if (ConvertCmdToParam(para, paraLen, argv, &argc) != VAD_SUCCESS) {
+ printf("ERROR: Failed to parse parameters\n");
+ return ERRCODE_FAIL;
+ }
+
+ if (argc < 1) {
+ printf("ERROR: Missing parameter\n");
+ printf("Usage: AT^LN_NOTIFY_BIND_AND_UNBIND=1/0\n");
+ printf(" 1: 绑定\n");
+ printf(" 0: 解绑\n");
+ return ERRCODE_FAIL;
+ }
+
+ int is_bind = atoi((char*)argv[0]);
+ if (is_bind != 0 && is_bind != 1) {
+ printf("ERROR: Invalid value. Must be 1 or 0\n");
+ printf("Usage: AT^LN_NOTIFY_BIND_AND_UNBIND=1/0\n");
+ return ERRCODE_FAIL;
+ }
+
+ push_bind_and_unbind_notification(is_bind);
+ printf("+LN_NOTIFY_BIND_AND_UNBIND: %d\n", is_bind);
return ERRCODE_SUCC;
}
/* OTA-获取升级任务:AT^LN_OTA_GET_TASK */
{(char *)"AT^LN_STORY_FINISH", ln_story_finish_at, (char *)"确认结束哄睡(JSON): AT^LN_STORY_FINISH"},
{(char *)"AT^LN_DEV_CHARACTER", ln_device_get_character_at, (char *)"获取设备角色信息(JSON,GET): AT^LN_DEV_CHARACTER"},
{(char *)"AT^LN_DEV_USERID", ln_device_get_userid_at, (char *)"获取设备绑定用户ID(JSON,GET): AT^LN_DEV_USERID"},
- {(char *)"AT^LN_SET_DEV_USERID", ln_device_set_userid_at, (char *)"获取设备绑定用户ID(JSON,SET): AT^LN_SET_DEV_USERID"},
{(char *)"AT^LN_OTA_GET_TASK", ln_ota_get_task_at, (char *)"获取OTA升级任务(JSON,GET): AT^LN_OTA_GET_TASK"},
{(char *)"AT^LN_OTA_DOWNLOAD", ln_ota_download_at, (char *)"下载OTA升级包(JSON,GET->下载): AT^LN_OTA_DOWNLOAD"},
{(char *)"AT^LN_GET_CHAT_STAMINA", ln_get_chat_stamina_at, (char *)"获取对话体力与流量: AT^LN_GET_CHAT_STAMINA"},
{(char *)"AT^LN_CHAT_STAMINA_DEMO", ln_chat_stamina_demo_at, (char *)"演示对话体力/流量UI: AT^LN_CHAT_STAMINA_DEMO=member|enough|low|empty 或自定义"},
{(char *)"AT^LN_SWITCH_EXPRESSION", ln_switch_expression_at, (char *)"切换表情视频: AT^LN_SWITCH_EXPRESSION=<video_path>"},
{(char *)"AT^LN_API_ERROR", ln_api_error_at, (char *)"推送协议错误: AT^LN_API_ERROR[=message]"},
+ {(char *)"AT^LN_NOTIFY_BIND_AND_UNBIND", ln_notify_bind_and_unbind_at, (char *)"通知用户绑定或解绑: AT^LN_NOTIFY_BIND_AND_UNBIND=1/0"},
+
/* 内存查看相关AT命令 */
{(char *)"AT^LN_MEMORY_INFO", ln_memory_info_at, (char *)"查看系统内存信息: AT^LN_MEMORY_INFO"},
{(char *)"AT^LN_FOLDER_SIZE", ln_folder_size_at, (char *)"查看文件夹大小: AT^LN_FOLDER_SIZE[=/path/to/folder]"},
return path;
}
-/* 获取是否绑定用户 */
-int uapi_ln_is_device_bound(void)
-{
- return g_ln_is_device_bound;
-}
-
/* 获取设备绑定用户ID */
const char* uapi_ln_get_user_id(void)
{
return g_ln_device_user_id;
}
-/* 获取是否绑定用户 */
-void uapi_ln_set_device_bound(int val)
-{
- g_ln_is_device_bound = val;
-}
+
/* 下载文件
@param url 文件URL
}
case WS_CMD_DEVICE_BIND: {
printf("[WS] DeviceBind:设备绑定\n");
- uapi_ln_set_device_bound(LN_DEVICE_BIND_STATUS_BOUND);
+ push_bind_and_unbind_notification(LN_DEVICE_BIND_STATUS_BOUND);
if(json_str)
{
// ln_parse_device_bind(json_str, (int)strlen(json_str));
}
case WS_CMD_DEVICE_UNBIND: {
printf("[WS] DeviceUnbind:设备解绑\n");
- do_restore_factory_setting();
+ push_bind_and_unbind_notification(LN_DEVICE_BIND_STATUS_UNBOUND);
if(json_str)
{
// ln_parse_device_unbind(json_str, (int)strlen(json_str));
printf("[WS] DownloadEmoji:下载表情\n");
if(json_str)
{
- ln_parse_download_emoji(json_str, (int)strlen(json_str));
+ // ln_parse_download_emoji(json_str, (int)strlen(json_str));
}
break;
}
printf("[WS] Pong\n");
break;
}
+ case WS_CMD_VOICE_CHAT_RESPONSE:{
+ push_text_to_ui(data_msg->text_content);
+ break;
+ }
+ case WS_CMD_CHOOSE_STORY_RESPONSE:{
+ push_text_to_ui(data_msg->text_content);
+ break;
+ }
default: {
printf("[WS] Unknown command=%s\n", cmd_str ? cmd_str : "");
break;
}
else if (mail.cmd == LN_HTTP_SERVICE_CMD_GET_USER_ID)
{
- LnDeviceBindStatus st = LN_DEVICE_BIND_STATUS_ERROR;
- (void)uapi_ln_device_get_user_id(&st, g_ln_device_user_id, sizeof(g_ln_device_user_id));
- /* 将内部状态映射为上层更直观的 0/1/2/3 */
- if (st == LN_DEVICE_BIND_STATUS_UNBOUND ) {
- uapi_ln_set_device_bound(LN_DEVICE_BIND_STATUS_UNBOUND);//未绑定
- } else if (st == LN_DEVICE_BIND_STATUS_BOUND) {
- uapi_ln_set_device_bound(LN_DEVICE_BIND_STATUS_BOUND);//已绑定
- } else if (st == LN_DEVICE_BIND_STATUS_AUTH_FAILURE) {
- uapi_ln_set_device_bound(LN_DEVICE_BIND_STATUS_AUTH_FAILURE);//认证失败
- } else {
- uapi_ln_set_device_bound(LN_DEVICE_BIND_STATUS_ERROR);//其他错误
- g_ln_device_user_id[0] = '\0';
- }
- printf("LN_HTTP_SERVICE_CMD_GET_USER_ID:获取设备绑定用户ID: %s\n", uapi_ln_get_user_id());
- printf("LN_HTTP_SERVICE_CMD_GET_USER_ID:获取设备绑定用户ID状态: %d\n", uapi_ln_is_device_bound());
+ 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)
{
{
LN_DEVICE_BIND_STATUS_UNBOUND = 0, /* 未绑定,data 为 null */
LN_DEVICE_BIND_STATUS_BOUND = 1, /* 已绑定,返回有效用户ID */
- LN_DEVICE_BIND_STATUS_AUTH_FAILURE = 2, /* 认证失败(Token 无效或过期)*/
- LN_DEVICE_BIND_STATUS_ERROR = 3 /* 其他错误(网络/解析等)*/
} LnDeviceBindStatus;
/* =================== 设备角色信息结构体定义 =================== */
const char *uapi_ln_ota_get_saved_path(void);
/* 获取选择录音音频路径 */
const char *uapi_ln_get_audio_path(void);
-/* 获取是否绑定用户 */
-int uapi_ln_is_device_bound(void);
-/* 设置是否绑定用户 */
-void uapi_ln_set_device_bound(int val);
/* 获取设备绑定用户ID */
const char *uapi_ln_get_user_id(void);
/*文件下载函数:从URL下载到指定路径*/
uint32_t ln_token_is_expired(int *expired_out);
/* 主动刷新设备Token(调用HTTP接口),并落盘保存 */
uint32_t uapi_ln_refresh_device_token(void);
-uint32_t uapi_ln_device_get_user_id(LnDeviceBindStatus *out_status, char *out_user_id, uint32_t out_user_id_len);
/* 从本地读取角色配置 */
void ln_read_character_config(void);
if (code != 200)
{
printf("device getUserId: HTTP %d\n", code);
- if (clientData.responseBuf && clientData.responseBufLen > 0)
- {
- int real_len = clientData.responseContentLen > 0 ? clientData.responseContentLen : clientData.responseBufLen;
- }
goto end;
}
if (clientData.responseBuf && clientData.responseBufLen > 0)
{
int real_len = clientData.responseContentLen > 0 ? clientData.responseContentLen : clientData.responseBufLen;
- }
-
-end:
- HttpClientUnprepare(&clientData);
- HttpClientClse(&client);
- free(header_buf2);
- return ERRCODE_SUCC;
-}
-
-/*
- * 简单实用的同步接口:获取设备绑定用户ID
- * - LN_DEVICE_BIND_STATUS_BOUND: 已绑定,out_user_id 返回用户ID
- * - LN_DEVICE_BIND_STATUS_UNBOUND: 未绑定
- * - LN_DEVICE_BIND_STATUS_AUTH_FAILURE: 认证失败
- * - LN_DEVICE_BIND_STATUS_ERROR: 其他错误
- */
-uint32_t uapi_ln_device_get_user_id(LnDeviceBindStatus *out_status, char *out_user_id, uint32_t out_user_id_len)
-{
- if (out_status == NULL || out_user_id == NULL || out_user_id_len == 0)
- {
- return ERRCODE_FAIL;
- }
- *out_status = LN_DEVICE_BIND_STATUS_ERROR;
- out_user_id[0] = '\0';
-
- const char *device_id = uapi_ln_get_device_id();
- const char *token = uapi_ln_get_device_token();
- if (!device_id || !token)
- {
- *out_status = LN_DEVICE_BIND_STATUS_AUTH_FAILURE;
- return ERRCODE_FAIL;
- }
-
-/* 发起请求 */
-#ifdef SUPPORT_CAT1_SERVICE
- cat1_api_add_cat1_vote();
- cat1_api_wakeup_cat1(1);
- cat1_api_keep_wakeup(1);
- cat1_api_disable_cat1_cmd(0);
- LOS_Msleep(200);
-#endif
-
- HttpClient client = (HttpClient){0};
- HttpClientData clientData = (HttpClientData){0};
- client.isHttp = false;
- client.remotePort = 443;
-
- char *header_buf3 = (char *)malloc(512);
- if (!header_buf3)
- {
- return ERRCODE_FAIL;
- }
- int hdr = snprintf(header_buf3, 512,
- "deviceId: %s\r\n"
- "deviceToken: %s\r\n"
- "Content-Type: application/json\r\n",
- device_id, token);
- if (hdr <= 0)
- {
- free(header_buf3);
- return ERRCODE_FAIL;
- }
- HttpClientSetCustomHeader(&client, header_buf3);
-
- HTTPC_RESULT prep = ln_http_prepare_auto(&clientData, 2048, LN_CLIENT_PREPARE_SIZE * 2);
- if (prep != HTTP_SUCCESS)
- {
- return ERRCODE_FAIL;
- }
-
- HTTPC_RESULT res = HttpClientGetRequest(&client, LN_DEVICE_GET_USER_ID_URL, &clientData);
- if (res != HTTP_SUCCESS)
- {
- HttpClientUnprepare(&clientData);
- HttpClientClse(&client);
- return ERRCODE_FAIL;
- }
-
- int code = HttpClientGetResponseCode(&client);
- printf("device getUserId: HTTP %d\n", code);
- if (code == 200)
- {
- /* 成功响应:解析JSON,判断 data 是否为 null 或字符串 */
- if (clientData.responseBuf && clientData.responseBufLen > 0)
+ char *buf = (char *)malloc((size_t)real_len + 1);
+ if (buf)
{
- int real_len = clientData.responseContentLen > 0 ? clientData.responseContentLen : clientData.responseBufLen;
- char *buf = (char *)malloc((size_t)real_len + 1);
- if (buf)
+ memcpy(buf, clientData.responseBuf, (size_t)real_len);
+ buf[real_len] = '\0';
+ cJSON *root = cJSON_Parse(buf);
+ if (root)
{
- memcpy(buf, clientData.responseBuf, (size_t)real_len);
- buf[real_len] = '\0';
- cJSON *root = cJSON_Parse(buf);
- if (root)
+ cJSON *data = cJSON_GetObjectItem(root, "data");
+ cJSON *errorCode = cJSON_GetObjectItem(root, "errorCode");
+ cJSON *message = cJSON_GetObjectItem(root, "message");
+ // 检查errorCode是否为空
+ if (errorCode && cJSON_IsString(errorCode))
+ {
+ // 推送协议错误通知到UI
+ printf("device getUserId: errorCode=%s\n", errorCode->valuestring);
+ printf("device getUserId: message=%s\n", message->valuestring);
+ push_api_error_notification(message->valuestring);
+ }
+ else
{
- cJSON *data = cJSON_GetObjectItem(root, "data");
if (data == NULL || cJSON_IsNull(data))
{
- *out_status = LN_DEVICE_BIND_STATUS_UNBOUND;
+ push_bind_and_unbind_notification(LN_DEVICE_BIND_STATUS_UNBOUND);
}
else if (cJSON_IsString(data) && data->valuestring && data->valuestring[0])
{
- *out_status = LN_DEVICE_BIND_STATUS_BOUND;
- strncpy(out_user_id, data->valuestring, out_user_id_len - 1);
- out_user_id[out_user_id_len - 1] = '\0';
- }
- else
- {
- *out_status = LN_DEVICE_BIND_STATUS_ERROR;
+ printf("device getUserId: data=%s\n", data->valuestring);
+ push_bind_and_unbind_notification(LN_DEVICE_BIND_STATUS_BOUND);
}
- cJSON_Delete(root);
}
- free(buf);
+ cJSON_Delete(root);
}
+ free(buf);
}
}
- else if (code == 401)
- {
- /* 认证失败 */
- *out_status = LN_DEVICE_BIND_STATUS_AUTH_FAILURE;
- }
- else
- {
- *out_status = LN_DEVICE_BIND_STATUS_ERROR;
- }
-
- printf("device getUserId: out_status %d\n", *out_status);
+end:
HttpClientUnprepare(&clientData);
HttpClientClse(&client);
- free(header_buf3);
+ free(header_buf2);
return ERRCODE_SUCC;
}
SendMsgToUIService(HAND_API_ERROR_NOTIFY, 0, (void *)msg, (int32_t)strlen(msg));
}
+// 推送绑定和解绑通知到UI
+void push_bind_and_unbind_notification(int is_bind)
+{
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BIND_AND_UNBIND] is_bind=%d", is_bind);
+ SendMsgToUIService(HAND_BIND_AND_UNBIND_NOTIFY, 0, &is_bind, sizeof(is_bind));
+}
+
+
// 检测是否有外网连接
int check_internet_connection(void)
{
// 切换表情视频
bool switch_expression_video(const char *video_path);
void push_api_error_notification(const char *message);
+//通知ui绑定和解绑
+void push_bind_and_unbind_notification(int is_bind);
// 网络连接检测
int check_internet_connection(void);