This commit is contained in:
2025-09-28 16:03:54 +08:00
commit 8587e5c84a
23 changed files with 14023 additions and 0 deletions

BIN
GetNet/bin/setNet Executable file

Binary file not shown.

229
GetNet/src/GetNet.cpp Normal file
View File

@@ -0,0 +1,229 @@
/*
本程序主要用于初始化网络配置,使4g模块可以正常上网
*/
#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <poll.h>
#include <cstring>
#include <thread>
using namespace std;
// 串口设备
string Serious = "/dev/ttyUSB2";
// 设置网络
void SetNet();
int main(int argc, char *argv[])
{
this_thread::sleep_for(chrono::seconds(3));
SetNet();
return 0;
}
// 设置网络
void SetNet()
{
auto configure_serial = [](int fd) -> bool
{
struct termios options;
if (tcgetattr(fd, &options) != 0)
return false;
cfsetispeed(&options, B115200);
cfsetospeed(&options, B115200);
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~PARENB; // 无校验
options.c_cflag &= ~CSTOPB; // 1 位停止位
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8; // 8 位数据位
options.c_cflag &= ~CRTSCTS; // 关闭硬件流控
options.c_iflag &= ~(IXON | IXOFF | IXANY); // 关闭软件流控
options.c_iflag &= ~(INLCR | ICRNL);
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // 原始模式
options.c_oflag &= ~OPOST; // 原始输出
options.c_cc[VMIN] = 0; // 非阻塞读取
options.c_cc[VTIME] = 10; // 1.0s 读超时
if (tcsetattr(fd, TCSANOW, &options) != 0)
return false;
tcflush(fd, TCIOFLUSH);
return true;
};
auto write_all = [](int fd, const std::string &data) -> bool
{
const char *p = data.c_str();
size_t left = data.size();
while (left > 0)
{
ssize_t n = write(fd, p, left);
if (n < 0)
{
if (errno == EINTR)
continue;
return false;
}
left -= static_cast<size_t>(n);
p += n;
}
return true;
};
auto send_at = [&](int fd, const std::string &cmd, std::string &resp, int timeout_ms = 3000) -> bool
{
std::string line = cmd + "\r\n";
if (!write_all(fd, line))
return false;
resp.clear();
char buf[256];
int elapsed = 0;
while (elapsed < timeout_ms)
{
struct pollfd pfd{fd, POLLIN, 0};
int pr = poll(&pfd, 1, 200);
if (pr > 0 && (pfd.revents & POLLIN))
{
ssize_t n = read(fd, buf, sizeof(buf));
if (n > 0)
{
resp.append(buf, buf + n);
if (resp.find("\r\nOK\r\n") != std::string::npos ||
resp.find("\nOK\n") != std::string::npos ||
resp.find("OK") != std::string::npos)
return true;
if (resp.find("ERROR") != std::string::npos)
return false;
}
}
elapsed += 200;
}
return false; // 超时
};
int fd = open(Serious.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd < 0)
{
std::cerr << "无法打开串口: " << Serious << "\n";
return;
}
// 设为阻塞
int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
if (!configure_serial(fd))
{
std::cerr << "串口参数配置失败\n";
close(fd);
return;
}
std::string resp;
// 0) 连续握手,确保 AT 可用(最多 10 次)
{
bool ok = false;
for (int i = 1; i <= 10; ++i)
{
if (send_at(fd, "AT", resp, 500))
{
ok = true;
break;
}
usleep(500 * 1000);
}
if (!ok)
{
std::cerr << "AT 握手失败,模块未响应\n";
close(fd);
return;
}
}
// 1) 打开功能
if (!send_at(fd, "AT+CFUN=1", resp))
{
std::cerr << "AT+CFUN=1 失败: " << resp << "\n";
}
else
{
std::cout << "AT+CFUN=1 OK\n";
}
// 1.1) 等 SIM 就绪AT+CPIN? 返回 READY最多 30 秒)
{
bool ready = false;
for (int i = 0; i < 60; ++i)
{
if (send_at(fd, "AT+CPIN?", resp, 500) && resp.find("READY") != std::string::npos)
{
ready = true;
break;
}
usleep(500 * 1000);
}
if (!ready)
std::cerr << "SIM 未就绪,后续可能失败\n";
}
// 2) 设置 PDP 上下文APN = ipn请按运营商实际 APN 调整)
if (!send_at(fd, "AT+CGDCONT=1,\"IP\",\"ipn\"", resp))
{
std::cerr << "AT+CGDCONT 设置失败: " << resp << "\n";
}
else
{
std::cout << "AT+CGDCONT OK\n";
}
// 2.1) 等驻网AT+CEREG? 返回 ,1 或 ,5最多 60 秒)
{
auto registered = [](const std::string &s)
{ return s.find(",1") != std::string::npos || s.find(",5") != std::string::npos; };
bool ok = false;
for (int i = 0; i < 60; ++i)
{
if (send_at(fd, "AT+CEREG?", resp, 500) && registered(resp))
{
ok = true;
break;
}
usleep(1000 * 1000);
}
if (!ok)
std::cerr << "未驻网,继续尝试拨号但成功率较低\n";
}
// 3) 打开网卡/拨号Quectel 私有指令示例)- 失败重试 5 次
{
bool ok = false;
for (int attempt = 1; attempt <= 5; ++attempt)
{
resp.clear();
if (send_at(fd, "AT+QNETDEVCTL=1,1,1", resp))
{
std::cout << "AT+QNETDEVCTL OK (attempt " << attempt << ")\n";
ok = true;
break;
}
std::cerr << "AT+QNETDEVCTL 失败 (attempt " << attempt << "/5): " << resp << "\n";
usleep(1000 * 1000); // 1s 间隔
}
if (!ok)
{
std::cerr << "AT+QNETDEVCTL 连续 5 次失败,退出本步骤\n";
}
}
close(fd);
}

8
GetNet/src/makefile Normal file
View File

@@ -0,0 +1,8 @@
all:SetNet
SetNet:GetNet.cpp
g++ -g -o setNet GetNet.cpp
mv ./setNet ../bin/
clean:
rm -rf ../bin/*