PM_ID_BUTTON_GPIO,//gpio按键
PM_ID_BP,//血压
PM_ID_4G_AI,//4g AI
+ PM_ID_GPS,//4g AI
#ifdef SUPPORT_ALIPAY_SEC
PM_ID_ALIPAY,//支付宝
#endif
#include "components/ui_button.h"
#include "components/ui_image_view.h"
#include "components/ui_label_button_ext.h"
+#include "cmsis_os2.h"
namespace OHOS
{
bool testQRCodeScrollViewInit(uint8_t id);
std::string GenerateQRCodeContent();
void ClearAll(void);
+ void RefreshQRCodeContent(); // 刷新二维码内容
private:
UIScrollView *testQRCodeScrollView{nullptr};
UIQrcode *QRCodeView{nullptr};
UILabelButtonExt *labelButton_next{nullptr};
bool initViewStatus{false};
+
+ // 定时器相关
+ static osTimerId_t qrcode_refresh_timer;
// 内容生成相关函数
std::string GenerateProductInfo(); // 生成产品信息
* @Author: penglei 1624952103@qq.com
* @Date: 2025-01-27 10:00:00
* @LastEditors: penglei 1624952103@qq.com
- * @LastEditTime: 2025-01-27 10:00:00
+ * @LastEditTime: 2025-10-10 14:50:58
* @FilePath: /FD230/code/sdk/zhihui/UI/producttest/src/testQRCode.cpp
* @Description: 产测二维码视图实现文件
*/
#include "ConfigModel.h"
#include "custom_utils.h"
+#include "cmsis_os2.h"
#include "components/ui_label.h"
#include "components/ui_label_button_ext.h"
#include "components/ui_qrcode.h"
#include "securec.h"
#include <string>
+#include "custom_runtime.h"
+
namespace OHOS
{
static testQRCodeView *g_pTestQRCodeView{nullptr};
+
+ // 定时器变量定义
+ osTimerId_t testQRCodeView::qrcode_refresh_timer = NULL;
+
+ // IMEI超时管理全局变量和常量
+ static uint32_t g_imei_timeout_counter = 0;
+ static const uint32_t IMEI_TIMEOUT_LIMIT = 6; // 6秒超时限制
+
+ // 定时器回调函数
+ static void qrcodeRefreshTimerCallback(int data)
+ {
+ // 检查4G电源状态,如果关闭则自动打开
+ uint8_t cat1_power_status = uapi_dev_runtime_get_cat1_powerstat();
+ if (cat1_power_status == 0) {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "4G power is OFF, turning ON...");
+ uapi_set4GCapability(true);
+ // 重置IMEI超时计数器
+ g_imei_timeout_counter = 0;
+ } else {
+ // 4G已开启,检查IMEI获取情况
+ char* cat1_imei = uapi_dev_runtime_get_cat1_imei();
+ bool imei_available = (cat1_imei != nullptr && strlen(cat1_imei) > 0);
+
+ if (!imei_available) {
+ // IMEI还没有获取到,增加超时计数器
+ g_imei_timeout_counter++;
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "IMEI not available, timeout counter: %d/%d",
+ g_imei_timeout_counter, IMEI_TIMEOUT_LIMIT);
+
+ // 检查是否超时
+ if (g_imei_timeout_counter >= IMEI_TIMEOUT_LIMIT) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "IMEI timeout (%ds), restarting 4G...",
+ IMEI_TIMEOUT_LIMIT);
+
+ // 重新开关4G:先关闭再开启
+ uapi_set4GCapability(false);
+ LOS_Msleep(500); // 等待500ms
+ uapi_set4GCapability(true);
+
+ // 重置超时计数器
+ g_imei_timeout_counter = 0;
+ }
+ } else {
+ // IMEI已获取到,重置超时计数器
+ if (g_imei_timeout_counter > 0) {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "IMEI obtained: %s, resetting timeout counter", cat1_imei);
+ g_imei_timeout_counter = 0;
+ }
+ }
+ }
+
+ // 刷新二维码内容
+ testQRCodeView *pview = testQRCodeView::GetInstance();
+ if (pview != nullptr) {
+ pview->RefreshQRCodeContent();
+ }
+ }
testQRCodeView::testQRCodeView()
{
void testQRCodeView::ClearAll(void)
{
+ // 停止并删除定时器
+ if (qrcode_refresh_timer != NULL) {
+ osTimerStop(qrcode_refresh_timer);
+ osTimerDelete(qrcode_refresh_timer);
+ qrcode_refresh_timer = NULL;
+ }
+
+ // 重置IMEI超时计数器
+ g_imei_timeout_counter = 0;
+
if (testQRCodeScrollView)
{
testQRCodeScrollView->RemoveAll();
// labelButton_next = testAboutView::GetInstance()->init_button_next(167, 378, Test_ViewMapper_t[id].viewid_str_next);
// testQRCodeScrollView->Add(labelButton_next);
+ // 启动1秒定时器刷新二维码内容
+ uint32_t tick;
+ osStatus_t retTimer;
+
+ // 重置IMEI超时计数器
+ g_imei_timeout_counter = 0;
+
+ qrcode_refresh_timer = osTimerNew((osTimerFunc_t)qrcodeRefreshTimerCallback, osTimerPeriodic, NULL, NULL);
+ tick = 1000; // 1秒刷新一次
+ retTimer = osTimerStart(qrcode_refresh_timer, tick);
+ if (retTimer != osOK && qrcode_refresh_timer != NULL) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "QRCode refresh timer start failed, ret = %lx!!", retTimer);
+ osTimerDelete(qrcode_refresh_timer);
+ qrcode_refresh_timer = NULL;
+ } else {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "QRCode refresh timer started successfully with IMEI timeout monitoring");
+ }
+
return true;
}
// 压缩版本:只保留最核心信息,确保在256字符以内
// 1. 产品型号
- content += GenerateProductInfo();
+ // content += GenerateProductInfo();
// 2. 测试时间
- content += GenerateTestTimeInfo();
+ // content += GenerateTestTimeInfo();
// 3. 核心设备信息
content += GenerateDeviceInfo();
// 4. 测试结果
- content += GenerateTestSummary();
+ // content += GenerateTestSummary();
std::string content;
// 蓝牙地址
- content += "BT: ";
+ content += "MAC: ";
content += GetBluetoothAddress();
content += "\n";
// IMEI号
content += "IMEI: ";
if (ConfigModel::GetInstance()) {
- content += ConfigModel::GetInstance()->Getimei();
+ // content += ConfigModel::GetInstance()->Getimei();
+
+ // 安全地添加CAT1 IMEI
+ char* cat1_imei = uapi_dev_runtime_get_cat1_imei();
+ if (cat1_imei != nullptr && strlen(cat1_imei) > 0) {
+ content += cat1_imei;
+ } else {
+ content += "N/A";
+ }
} else {
content += "fail";
}
content += "\n";
- // 固件版本号
- content += "VER: ";
- content += GetFirmwareVersion();
- content += "\n";
+ // // 固件版本号
+ // content += "VER: ";
+ // content += GetFirmwareVersion();
+ // content += "\n";
- // Modem
- content += "MODEM: ";
- if (ConfigModel::GetInstance()) {
- content += ConfigModel::GetInstance()->GetmoderVer();
- } else {
- content += "fail";
- }
- content += "\n";
+ // // Modem
+ // content += "MODEM: ";
+ // if (ConfigModel::GetInstance()) {
+ // // content += ConfigModel::GetInstance()->GetmoderVer();
+ // content += uapi_dev_runtime_get_cat1_modemver();
+ // } else {
+ // content += "fail";
+ // }
+ // content += "\n";
// Python版本
- content += "PY: ";
- if (ConfigModel::GetInstance()) {
- content += ConfigModel::GetInstance()->GetpyVer();
- } else {
- content += "fail";
- }
- content += "\n";
+ // content += "PY: ";
+ // if (ConfigModel::GetInstance()) {
+ // // content += ConfigModel::GetInstance()->GetpyVer();
+ // content += uapi_dev_runtime_get_cat1_pyver();
+ // } else {
+ // content += "fail";
+ // }
+ // content += "\n";
return content;
}
uint32_t len = 6;
errcode_t ret = uapi_get_nv_btaddr((uint8_t *)btaddr, &len);
if (ret == ERRCODE_SUCC) {
- sprintf((char *)btaddr_str, "%02X:%02X:%02X:%02X:%02X:%02X",
+ sprintf((char *)btaddr_str, "%02X%02X%02X%02X%02X%02X",
btaddr[0], btaddr[1], btaddr[2], btaddr[3], btaddr[4], btaddr[5]);
return (char *)btaddr_str;
} else {
return content;
}
+
+ // 刷新二维码内容
+ void testQRCodeView::RefreshQRCodeContent()
+ {
+ if (QRCodeView != nullptr) {
+ // 获取当前4G状态用于调试
+ uint8_t cat1_power = uapi_dev_runtime_get_cat1_powerstat();
+ char* cat1_imei = uapi_dev_runtime_get_cat1_imei();
+
+ // 重新生成二维码内容
+ std::string qrContent = GenerateQRCodeContent();
+
+ // 更新二维码显示
+ QRCodeView->SetQrcodeInfo(qrContent.c_str());
+
+ // 强制刷新显示
+ QRCodeView->Invalidate();
+
+ // 调试信息:显示4G状态、IMEI和超时计数器
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "QRCode refreshed - 4G power: %d, IMEI: %s, timeout: %d/%d",
+ cat1_power, (cat1_imei && strlen(cat1_imei) > 0) ? cat1_imei : "N/A",
+ g_imei_timeout_counter, IMEI_TIMEOUT_LIMIT);
+ }
+ }
}
// 2.ViewMapper[] 是一个静态的视图映射数组,将视图ID与MainStopWatchView类中的特定成员函数指针进行了绑定。
test_ext Test_ViewMapper_t[] = {
{TESTVIEW, "", "", "", &testView::ChangeSystemAboutView, false}, // 占位,空的
- // {QRCODE, "QRCodeButton", "QRCode", "QRCodeButton_next", &testView::ChangeQRCodeTESTView, true},
+ {QRCODE, "QRCodeButton", "QRCode", "QRCodeButton_next", &testView::ChangeQRCodeTESTView, true},
{VISON, "AboutTheWatchButton", "Verison", "AboutTheWatchButton_next", &testView::ChangeSystemAboutView, true},
{LCD, "LCDButton", "LCD", "LCDButton_next", &testView::ChangeLCDTESTView, true},
{TP, "TPButton", "TP", "TPButton_next", &testView::ChangeTPTESTView, true},
static void mgdataTimerCallBack(int data)
{
+ // 检查4G电源状态,如果关闭则自动打开
+ uint8_t cat1_power_status = uapi_dev_runtime_get_cat1_powerstat();
+ if (cat1_power_status == 0) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CAT1 test: 4G power is OFF, turning ON...");
+ uapi_set4GCapability(true);
+ } else {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CAT1 test: 4G power is ON");
+ }
+
cat1_at_cmd("at*mrd_cdf=Q,LteCalData.nvm");
cat1_getsignal();
cat1_getver();
// 等待数据监听停止(最多等待6秒)
int wait_count = 0;
- const int max_wait_ms = 6000; // 最大等待6秒
- const int check_interval_ms = 500; // 每500ms检查一次
+ const int max_wait_ms = 8000;
+ const int check_interval_ms = 100;
while (g_is_listening_data == 0 && wait_count < (max_wait_ms / check_interval_ms)) {
LOS_Msleep(check_interval_ms);
wait_count++;
- if (wait_count % 2 == 0) { // 每秒打印一次状态(500ms * 2 = 1秒)
+ if (wait_count % 2 == 0) {
printf("PGnssServerStop: Waiting for data listening to stop... (%d/%d)\r\n",
wait_count * check_interval_ms, max_wait_ms);
}
}
// 更新文件下载进度
+// 自适应HTTP客户端准备函数 - 带重试机制
+static HTTPC_RESULT gnss_http_prepare_auto(HttpClientData *clientData, int header_size, int resp_size)
+{
+ if (header_size < 2048)
+ header_size = 2048;
+ if (resp_size < 2048)
+ resp_size = 2048;
+
+ HTTPC_RESULT ret = HttpClientPrepare(clientData, header_size, resp_size);
+ if (ret == HTTP_SUCCESS)
+ return ret;
+
+ // 如果失败,尝试逐步减少缓冲区大小重试
+ int tries = 0;
+ while (ret != HTTP_SUCCESS && tries < 3) {
+ tries++;
+ // 每次重试减少缓冲区大小
+ resp_size = resp_size / 2;
+ if (resp_size < 4096) {
+ resp_size = 4096; // 最小4KB响应缓冲区
+ }
+
+ printf("GNSS HTTP prepare retry %d: header=%d, resp=%d\n", tries, header_size, resp_size);
+ ret = HttpClientPrepare(clientData, header_size, resp_size);
+
+ if (ret != HTTP_SUCCESS) {
+ LOS_Msleep(100); // 短暂等待后重试
+ }
+ }
+
+ if (ret != HTTP_SUCCESS) {
+ printf("GNSS HTTP prepare failed after %d retries, error: %d\n", tries, ret);
+ }
+
+ return ret;
+}
+
static void update_file_progress(const char *filename)
{
g_downloaded_files++;
}
}
+// 显示文件下载失败信息 - 不增加计数器
+static void update_file_progress_failed(const char *filename, HTTPC_RESULT error)
+{
+ if (g_total_files > 0) {
+ int actual_percent = (g_downloaded_files * 100) / g_total_files;
+ printf("✗ %s: request failed %d (进度保持 %d%% [%d/%d])\\n",
+ filename, error, actual_percent, g_downloaded_files, g_total_files);
+ } else {
+ printf("✗ %s: request failed %d\\n", filename, error);
+ }
+}
+
static HTTPC_RESULT download_file_with_httpclient(const char *filename, const char *url)
{
- // 更新文件下载进度
- update_file_progress(filename);
+ // 不在开始时更新进度,只在成功时更新
// 解析URL
char host[256] = {0};
client.isHttp = true;
client.remotePort = port;
- // 准备客户端数据
- HTTPC_RESULT prep_result = HttpClientPrepare(&clientData, 2048, 256 * 1024);
+ // 准备客户端数据 - 使用自适应准备函数
+ HTTPC_RESULT prep_result = gnss_http_prepare_auto(&clientData, 2048, 256 * 1024);
if (prep_result != HTTP_SUCCESS) {
printf("HTTP客户端准备失败: %d\n", prep_result);
g_download_status = -1;
fclose(fp);
if (written == actual_size) {
+ update_file_progress(filename); // 成功时更新进度
result = HTTP_SUCCESS;
} else {
printf("文件写入失败: %s\n", filename);
+ update_file_progress_failed(filename, HTTP_ESEND); // 失败时显示错误
g_download_status = -1;
result = HTTP_ESEND;
}
} else {
printf("文件打开失败: %s\n", filename);
+ update_file_progress_failed(filename, HTTP_ESEND); // 失败时显示错误
g_download_status = -1;
result = HTTP_ESEND;
}
} else {
printf("无响应数据: %s\n", filename);
+ update_file_progress_failed(filename, HTTP_ERECV); // 失败时显示错误
g_download_status = -1;
result = HTTP_ERECV;
}
} else {
printf("HTTP响应错误 %d: %s\n", response_code, filename);
+ update_file_progress_failed(filename, HTTP_EPROTO); // 失败时显示错误
g_download_status = -1;
result = HTTP_EPROTO;
}
if (written == actual_size) {
printf("✓ %s (%zu bytes)\n", filename, written);
+ update_file_progress(filename); // 成功时更新进度
result = HTTP_SUCCESS;
} else {
printf("✗ %s: write failed\n", filename);
+ update_file_progress_failed(filename, HTTP_ESEND); // 失败时显示错误
g_download_status = -1;
result = HTTP_ESEND;
}
} else {
printf("✗ %s: file open failed\n", filename);
+ update_file_progress_failed(filename, HTTP_ESEND); // 失败时显示错误
g_download_status = -1;
result = HTTP_ESEND;
}
} else {
printf("✗ %s: no data\n", filename);
+ update_file_progress_failed(filename, HTTP_ERECV); // 失败时显示错误
g_download_status = -1;
result = HTTP_ERECV;
}
} else {
printf("✗ %s: HTTP %d\n", filename, response_code);
+ update_file_progress_failed(filename, HTTP_EPROTO); // 失败时显示错误
g_download_status = -1;
result = HTTP_EPROTO;
}
if (written == actual_size) {
printf("✓ %s (%zu bytes)\n", filename, written);
+ update_file_progress(filename); // 成功时更新进度
result = HTTP_SUCCESS;
} else {
printf("✗ %s: write failed\n", filename);
+ update_file_progress_failed(filename, HTTP_ESEND); // 失败时显示错误
result = HTTP_ESEND;
}
} else {
}
} else {
printf("✗ %s: no data\n", filename);
+ update_file_progress_failed(filename, HTTP_ERECV); // 失败时显示错误
result = HTTP_ERECV;
}
} else {
printf("✗ %s: HTTP %d\n", filename, response_code);
+ update_file_progress_failed(filename, HTTP_EPROTO); // 失败时显示错误
result = HTTP_EPROTO;
}
} else {
printf("✗ %s: recv failed %d\n", filename, recv_result);
+ update_file_progress_failed(filename, recv_result); // 失败时显示错误
result = recv_result;
}
}
} else {
printf("✗ %s: request failed %d\n", filename, result);
+ update_file_progress_failed(filename, result); // 失败时显示错误
}
// 清理资源
printf("Starting AGNSS download, set download flag, status: 0 (连接中)\n");
+ // 添加GPS睡眠阻止,确保下载过程中系统不会睡眠
+ uint8_t cnt = pm_veto_get_id_cnt(PM_ID_GPS);
+ if (cnt == 0)
+ {
+ uapi_pm_add_sleep_veto(PM_ID_GPS);
+ printf("Added GPS sleep veto for AGNSS download\n");
+ }
+
//通讯开始,唤醒cat1
#ifdef SUPPORT_CAT1_SERVICE
cat1_api_add_cat1_vote();
cat1_api_wakeup_cat1(1);
cat1_api_keep_wakeup(1);
- cat1_api_disable_cat1_cmd(1);
+ cat1_api_disable_cat1_cmd(0); // 修改:允许CAT1命令,确保DNS查询可用
#endif
// 等待CAT1就绪
- LOS_Msleep(1000);
+ LOS_Msleep(500); // 修改:减少等待时间,参考ln_api_device_info.c
// 获取当前时间戳
uint32_t timestamp = 0;
client.isHttp = true;
client.remotePort = 80;
- // 准备客户端数据
- HTTPC_RESULT prep_result = HttpClientPrepare(&clientData, 2048, 256 * 1024);
+ // 准备客户端数据 - 使用自适应准备函数
+ HTTPC_RESULT prep_result = gnss_http_prepare_auto(&clientData, 2048, 256 * 1024);
if (prep_result != HTTP_SUCCESS) {
+ printf("AGNSS HTTP prepare failed: %d, retry: %d\n", prep_result, retry_count);
retry_count++;
continue;
}
cleanup_agnss_response_buffer();
LOS_Msleep(300);
} else if (result == HTTP_ENOBUFS) {
+ printf("缓冲区空间不足,等待更长时间...\n");
cleanup_agnss_response_buffer();
- LOS_Msleep(300);
+ LOS_Msleep(2000); // 增加等待时间到2秒,缓解缓冲区压力
}
}
g_download_status = -1;
g_has_valid_json_data = 0;
printf("Download failed, status: -1, cleared download flag\n");
+
+ // 移除GPS睡眠阻止
+ cnt = pm_veto_get_id_cnt(PM_ID_GPS);
+ if (cnt == 1)
+ {
+ uapi_pm_remove_sleep_veto(PM_ID_GPS);
+ printf("Removed GPS sleep veto after download failure\n");
+ }
#ifdef SUPPORT_CAT1_SERVICE
cat1_api_remove_cat1_vote();
// 下载成功,清除标志位
g_has_valid_json_data = 0;
printf("Download completed successfully, cleared download flag\n");
+
+ // 移除GPS睡眠阻止
+ cnt = pm_veto_get_id_cnt(PM_ID_GPS);
+ if (cnt == 1)
+ {
+ uapi_pm_remove_sleep_veto(PM_ID_GPS);
+ printf("Removed GPS sleep veto after download success\n");
+ }
}
return 0;
}
return ERRCODE_SUCC;
}
+static uint32_t custom_get_btmac(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+{
+
+ UNUSED(strCommonCmd);
+
+ uapi_gei_btmac_and_chipinfo();
+
+ return ERRCODE_SUCC;
+}
+
+
static const at_cmd_table_t g_custom_utils_cmd[] = {
{ (char *)"AT^CUSTOM_SN", custom_utils_setsn, (char *)"123456789ABCDEF2345678" },
{ (char *)"AT^AUDIOTEST", custom_audio_test, (char *)" " },
{ (char *)"AT^FACTORY", custom_enter_factory_test_mode, (char *)" " },
{ (char *)"AT^SETUART", custom_set_uart_status, (char *)" " },
+ { (char *)"AT^GETBTMAC", custom_get_btmac, (char *)" " },
};