diff --git a/InitAuth/conf/.env b/InitAuth/conf/.env index 952f01c..842c5fc 100644 --- a/InitAuth/conf/.env +++ b/InitAuth/conf/.env @@ -3,6 +3,10 @@ UUID:"mjb64bcdgdm7q" #以下配置用于获取云端发送秘钥 ServerPwd:"1905168ed33af18c0cd09d996e82e71d" + +# 以下配置用于储存ICCID +ICCID:898604581824D0366321 + #以下配置存储GPIO输出高低电平--状态机 outPutMode:false diff --git a/PyApp/upload.log b/PyApp/upload.log index 9755893..c8f2080 100644 --- a/PyApp/upload.log +++ b/PyApp/upload.log @@ -16864,3 +16864,13 @@ 2026-01-10 09:30:10 - 读取ICCID异常: (5, 'Input/output error') 2026-03-05 11:00:05 - ICCID刷新线程启动 2026-03-05 11:00:05 - 主程序异常: [Errno 2] No such file or directory: '/mnt/save/warning' +2026-03-05 12:38:03 - ICCID刷新线程启动 +2026-03-05 12:38:03 - 主程序异常: [Errno 2] No such file or directory: '/mnt/save/warning' +2026-03-05 12:46:00 - ICCID刷新线程启动 +2026-03-05 12:46:00 - 主程序异常: [Errno 2] No such file or directory: '/mnt/save/warning' +2026-03-05 12:51:05 - ICCID刷新线程启动 +2026-03-05 12:51:05 - 主程序异常: [Errno 2] No such file or directory: '/mnt/save/warning' +2026-03-05 13:27:21 - ICCID刷新线程启动 +2026-03-05 13:27:21 - 主程序异常: [Errno 2] No such file or directory: '/mnt/save/warning' +2026-03-05 13:36:37 - ICCID刷新线程启动 +2026-03-05 13:36:37 - 主程序异常: [Errno 2] No such file or directory: '/mnt/save/warning' diff --git a/VideoProsessing/bin/video b/VideoProsessing/bin/video index 3078042..36140ec 100755 Binary files a/VideoProsessing/bin/video and b/VideoProsessing/bin/video differ diff --git a/VideoProsessing/src/main.cpp b/VideoProsessing/src/main.cpp index d554afc..d07047a 100644 --- a/VideoProsessing/src/main.cpp +++ b/VideoProsessing/src/main.cpp @@ -839,6 +839,7 @@ bool videoInit(VideoCapture &cap) cap.set(CAP_PROP_FRAME_HEIGHT, 480); cap.set(CAP_PROP_FPS, 30); cap.set(CAP_PROP_BUFFERSIZE, 1); + // 尝试 MJPG,若不支持则忽略 cap.set(CAP_PROP_FOURCC, VideoWriter::fourcc('M', 'J', 'P', 'G')); double fccv = cap.get(CAP_PROP_FOURCC); @@ -887,6 +888,7 @@ bool processFrame(VideoCapture &cap, FILE *pipe, Mat &frame, int64 &count, chron this_thread::sleep_for(50ms); return true; } + handleFrame = frame; vector destCopy; diff --git a/softWareInit/bin/verification b/softWareInit/bin/verification index 6cc39dd..a3eea71 100755 Binary files a/softWareInit/bin/verification and b/softWareInit/bin/verification differ diff --git a/softWareInit/src/main.cpp b/softWareInit/src/main.cpp index 6d2f77a..c7d47f3 100644 --- a/softWareInit/src/main.cpp +++ b/softWareInit/src/main.cpp @@ -267,14 +267,40 @@ void startCamera() // 初始化MQTT void mqttInit() { - client.set_connected_handler([](const string &cause) { cout << "Connected Successed!\n"; }); client.set_message_callback(getMsgCallback); - // 连接服务器 - client.connect()->wait(); - client.subscribe(Topic, Qos)->wait(); + // 连接服务器,增加重试与异常处理,避免崩溃 + const int maxAttempts = 3; + int attempt = 0; + while (attempt < maxAttempts) + { + try + { + client.connect()->wait(); + client.subscribe(Topic, Qos)->wait(); + cout << "MQTT 已连接并订阅主题\n"; + return; + } + catch (const mqtt::exception &e) + { + cerr << "MQTT 连接失败: " << e.what() << " (尝试 " << (attempt + 1) << "/" << maxAttempts << ")\n"; + } + catch (const std::exception &e) + { + cerr << "MQTT 连接异常: " << e.what() << " (尝试 " << (attempt + 1) << "/" << maxAttempts << ")\n"; + } + catch (...) + { + cerr << "MQTT 连接发生未知异常 (尝试 " << (attempt + 1) << "/" << maxAttempts << ")\n"; + } + + attempt++; + std::this_thread::sleep_for(2s); + } + + cerr << "MQTT 初始化失败,程序将继续运行但不使用 MQTT\n"; } // 接收消息回调 @@ -472,6 +498,102 @@ void Exit(int sig) // 通过串口发送 AT+CCID 指令,读取并解析返回的ICCID号 string GetSimICCID(const string &tty) { + auto trim = [](std::string s) -> std::string + { + auto is_ws = [](unsigned char c) + { return std::isspace(c) != 0; }; + while (!s.empty() && (is_ws((unsigned char)s.front()) || s.front() == '\"')) + s.erase(s.begin()); + while (!s.empty() && (is_ws((unsigned char)s.back()) || s.back() == '\r' || s.back() == '\n' || s.back() == '\"')) + s.pop_back(); + return s; + }; + + // 从配置文件读取 ICCID(支持 ICCID:null / ICCID:xxxxx / ICCID=xxxxx) + auto read_iccid_from_file = [&]() -> std::string + { + std::lock_guard lk(envMutex); + ReadFile rf(filepath); + if (!rf.Open()) + return ""; + + auto lines = rf.ReadLines(); + rf.Close(); + + for (auto &line : lines) + { + // 允许空格: "ICCID: 8986..." 或 "ICCID=null" + auto posColon = line.find("ICCID:"); + auto posEq = line.find("ICCID="); + size_t pos = std::string::npos; + size_t keyLen = 0; + + if (posColon != std::string::npos) + { + pos = posColon; + keyLen = sizeof("ICCID:") - 1; + } + else if (posEq != std::string::npos) + { + pos = posEq; + keyLen = sizeof("ICCID=") - 1; + } + + if (pos != std::string::npos) + { + std::string v = trim(line.substr(pos + keyLen)); + if (v == "null" || v.empty()) + return ""; + return v; + } + } + return ""; + }; + + // 写回 ICCID:优先替换已有 ICCID 行;没有则追加一行 "ICCID:xxxx" + auto write_iccid_to_file = [&](const std::string &iccid) -> void + { + if (iccid.empty()) + return; + + std::lock_guard lk(envMutex); + ReadFile rf(filepath); + if (!rf.Open()) + { + std::cerr << "ICCID 写入失败,无法打开文件: " << filepath << std::endl; + return; + } + + auto lines = rf.ReadLines(); + rf.Close(); + + bool replaced = false; + for (auto &line : lines) + { + // 覆盖这几类:ICCID:null / ICCID:old / ICCID=old + if (line.rfind("ICCID:", 0) == 0 || line.rfind("ICCID=", 0) == 0) + { + line = std::string("ICCID:") + iccid; + replaced = true; + break; + } + } + if (!replaced) + lines.push_back(std::string("ICCID:") + iccid); + + std::string out; + out.reserve(4096); + for (size_t i = 0; i < lines.size(); ++i) + { + out += lines[i]; + if (i + 1 < lines.size()) + out += "\n"; + } + + WriteFile wf(filepath); + wf.overwriteText(out); + }; + int retry = 0; while (retry < 5) { @@ -480,6 +602,13 @@ string GetSimICCID(const string &tty) if (fd < 0) { std::cerr << "无法打开串口: " << tty << std::endl; + + // 1) 无法打开串口 -> 读取文件上次写入的 ICCID 返回 + std::string cached = read_iccid_from_file(); + if (!cached.empty()) + return cached; + + std::cerr << "未找到可用的缓存 ICCID(文件无 ICCID 或为 null)" << std::endl; return ""; } @@ -498,12 +627,10 @@ string GetSimICCID(const string &tty) auto send_and_read = [&](const char *cmd) -> std::string { - // 清空缓冲并发送 tcflush(fd, TCIOFLUSH); write(fd, cmd, strlen(cmd)); std::string result; char buf[256] = {0}; - // 轮询读取,累计约2秒 for (int i = 0; i < 20; ++i) { int n = read(fd, buf, sizeof(buf)); @@ -514,7 +641,6 @@ string GetSimICCID(const string &tty) return result; }; - // 先试 AT+QCCID,失败再试 AT+CCID std::string result = send_and_read("AT+QCCID\r\n"); if (result.find("+QCCID") == std::string::npos) { @@ -524,16 +650,12 @@ string GetSimICCID(const string &tty) } close(fd); - // 打印原始回应便于调试 std::string debug = result; - // 清理换行 debug.erase(std::remove_if(debug.begin(), debug.end(), [](unsigned char c) { return c == '\r' || c == '\n'; }), debug.end()); - // std::cout << "ICCID原始回应: " << debug << std::endl; - // 错误重试 if (result.find("ERROR") != std::string::npos) { retry++; @@ -541,22 +663,21 @@ string GetSimICCID(const string &tty) continue; } - // 解析(支持字母数字) std::smatch m; - // +QCCID 或 +CCID 后取字母数字 std::regex reg(R"(\+(?:Q)?CCID:\s*([0-9A-Za-z]+))"); if (std::regex_search(debug, m, reg)) { std::string iccid = m[1]; - // 去掉尾部OK或非字母数字 while (!iccid.empty() && !std::isalnum(static_cast(iccid.back()))) iccid.pop_back(); if (iccid.size() >= 2 && iccid.substr(iccid.size() - 2) == "OK") iccid.erase(iccid.size() - 2); + + // 2) 成功读到 ICCID -> 写入/更新文件 + write_iccid_to_file(iccid); return iccid; } - // 兜底:19~22位的字母数字(如尾部含 D) std::regex reg2(R"(([0-9A-Za-z]{19,22}))"); if (std::regex_search(debug, m, reg2)) { @@ -565,10 +686,11 @@ string GetSimICCID(const string &tty) iccid.pop_back(); if (iccid.size() >= 2 && iccid.substr(iccid.size() - 2) == "OK") iccid.erase(iccid.size() - 2); + + write_iccid_to_file(iccid); return iccid; } - // 进一步兜底:手工截取 +QCCID: / +CCID: 后的连续字母数字 auto parse_after = [&](const std::string &s, const std::string &key) -> std::string { size_t pos = s.find(key); @@ -585,17 +707,32 @@ string GetSimICCID(const string &tty) iccid.erase(iccid.size() - 2); return iccid; }; + { std::string iccid = parse_after(debug, "+QCCID:"); if (iccid.empty()) iccid = parse_after(debug, "+CCID:"); if (!iccid.empty()) + { + write_iccid_to_file(iccid); return iccid; + } } retry++; usleep(200000); } + + // 多次重试失败:最后再尝试用缓存兜底(可选,但更符合“尽量别失败”) + std::string cached = read_iccid_from_file(); + if (!cached.empty()) + { + std::cerr << "多次尝试失败,使用缓存的 ICCID 作为兜底: " << cached << std::endl; + return cached; + } + + std::cerr << "未找到可用的缓存 ICCID(文件无 ICCID 或为 null)" << std::endl; + return ""; }