init
This commit is contained in:
190
DeviceActivate/src/main.cpp
Normal file
190
DeviceActivate/src/main.cpp
Normal 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 ""; // 多次重试失败,返回空
|
||||
}
|
||||
Reference in New Issue
Block a user