修复4G串口打不开,程序启动失败问题
This commit is contained in:
@@ -3,6 +3,10 @@ UUID:"mjb64bcdgdm7q"
|
||||
|
||||
#以下配置用于获取云端发送秘钥
|
||||
ServerPwd:"1905168ed33af18c0cd09d996e82e71d"
|
||||
|
||||
# 以下配置用于储存ICCID
|
||||
ICCID:898604581824D0366321
|
||||
|
||||
#以下配置存储GPIO输出高低电平--状态机
|
||||
outPutMode:false
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
Binary file not shown.
@@ -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<Dection> destCopy;
|
||||
|
||||
Binary file not shown.
@@ -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);
|
||||
|
||||
// 连接服务器
|
||||
// 连接服务器,增加重试与异常处理,避免崩溃
|
||||
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<std::mutex> 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<std::mutex> 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<unsigned char>(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 "";
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user