This commit is contained in:
2025-10-24 16:56:35 +08:00
commit 7462b7aa93
49 changed files with 28483 additions and 0 deletions

190
DeviceActivate/src/main.cpp Normal file
View File

@@ -0,0 +1,190 @@
/*
本程序用于设备激活
当检测配置文件发现设备未激活时,则系统阻塞
进行激活,并保存密文
*/
#include <iostream>
#include <mqtt/async_client.h> //和App进行MQTT数据交互
#include <boost/process.hpp>
#include <nlohmann/json.hpp> //用于操作JSON文件
#include "Netra.hpp"
using namespace std;
using namespace QCL;
using namespace chrono_literals;
// 配置相对路径
const string envPath = "/home/orangepi/RKApp/InitAuth/conf/.env";
// MQTT相关配置
const string mqtt_url = "tcp://192.168.12.1:1883";
const string clientId = "RK3588_SubTest";
const string Topic = "/bsd_camera/cmd";
const int Qos = 1;
atomic<bool> isRunning(true);
mqtt::async_client client(mqtt_url, clientId);
// 获取SIM卡号
// 通过串口发送 AT+CCID 指令读取并解析返回的ICCID号
string GetSimICCID(const string &tty = "/dev/ttyUSB2");
// MQTT初始化
void mqttInit();
// 连接成功的回调
void connectCallback(const string &cause);
// 接受消息的回调
void messageCallback(mqtt::const_message_ptr msg);
// 检测设备是否已进行初始化
bool checkUUID();
int main()
{
if (checkUUID())
{
// 设备已被激活,调用验证程序,退出本程序
return 0;
}
// 初始化MQTT
mqttInit();
while (isRunning)
{
this_thread::sleep_for(1s); // 防止系统占用过高
}
return 0;
}
// 检测设备是否已经激活
bool checkUUID()
{
bool flag = false;
// 读取文件
ReadFile *rf = new ReadFile(envPath);
if (rf->Open() == false)
{
cerr << "文件打开失败" << endl;
}
// 读取文本每一行
auto lines = rf->ReadLines();
for (auto &ii : lines)
{
if (ii.find("ServerPwd:null") != string::npos)
{
flag = false;
break;
}
else
flag = true;
}
return flag;
}
// 接受消息的回调
void messageCallback(mqtt::const_message_ptr msg)
{
// 接受App传来的密文,并保存在配置文件中
auto buffer = msg->to_string();
cout << "msg: " << buffer << endl;
if (buffer.find("Activate") != string::npos)
{
// 接受请求,发送SIM卡号
string ICCID = GetSimICCID();
client.publish(Topic, ICCID, Qos, false); // 不保存
}
else if (buffer.find("ServerPwd") != string::npos)
{
// 接受UUID,保存至配置文件中,退出程序,调用设备验证程序
auto res = nlohmann::json::parse(buffer); // 准备解析接受到的秘钥
auto pwd = res["Data"];
cout << pwd << endl;
}
}
// 连接成功的回调
void connectCallback(const string &cause)
{
cout << "连接成功" << endl;
}
void mqttInit()
{
client.set_message_callback(messageCallback);
client.set_connected_handler(connectCallback);
client.connect()->wait(); // 进行连接
client.subscribe(Topic, Qos)->wait(); // 订阅话题
}
// 获取SIM卡号
// 通过串口发送 AT+CCID 指令读取并解析返回的ICCID号
string GetSimICCID(const string &tty)
{
int retry = 0; // 重试次数
while (retry < 5) // 最多重试5次
{
int fd = open(tty.c_str(), O_RDWR | O_NOCTTY | O_NDELAY); // 打开串口
if (fd < 0)
{
std::cerr << "无法打开串口: " << tty << std::endl;
return "";
}
// 配置串口参数
struct termios options;
tcgetattr(fd, &options);
cfsetispeed(&options, B115200);
cfsetospeed(&options, B115200);
options.c_cflag |= (CLOCAL | CREAD);
tcsetattr(fd, TCSANOW, &options);
// 发送 AT+CCID 指令
write(fd, "AT+CCID\r\n", 9);
std::string result;
char buf[256] = {0};
// 循环多次读取,拼接内容,防止数据分包
for (int i = 0; i < 10; ++i)
{
usleep(100000); // 每次等待100ms
int n = read(fd, buf, sizeof(buf) - 1);
if (n > 0)
result.append(buf, n);
}
close(fd); // 关闭串口
// 检查是否有ERROR若有则重试
if (result.find("ERROR") != std::string::npos)
{
retry++;
usleep(200000); // 等待200ms再重试
continue;
}
// 用正则提取ICCID+CCID: 后面的数字)
std::smatch m;
std::regex reg(R"(\+CCID:\s*([0-9]+))");
if (std::regex_search(result, m, reg))
return m[1];
// 兜底直接找19~22位数字兼容不同长度的ICCID
std::regex reg2(R"((\d{19,22}))");
if (std::regex_search(result, m, reg2))
return m[1];
// 没有ERROR但也没读到ICCID直接退出循环
break;
}
return ""; // 多次重试失败,返回空
}