WLG/threadfunc/thread_func.cpp
2025-01-09 20:00:34 +08:00

422 lines
14 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "thread_func.hpp"
#include <map>
#include <time.h>
#include <math.h>
#include <string.h>
#include <cstdlib>
#include <linux/types.h>
#include <sys/sysinfo.h>
#include <dirent.h>
#include <boost/typeof/typeof.hpp>
#include <boost/filesystem.hpp>
#include <zlog.h>
#include <json/json.h>
#include "mqttclient/mqtt_client.h"
#include "uart/uart.hpp"
#include "common/common_func.hpp"
#include "wifi_5g/dial.h"
#include "wifi_5g/wpa_client.h"
#include "utility/tcp_cgi.hpp"
#include "utility/udp_scan.hpp"
#include "utility/search_dev.hpp"
#include "localserver/local_server.hpp"
extern zlog_category_t *zct;
extern zlog_category_t *zbt;
static std::string serverPort;
Dial dial;
static int clean_memory = 0;
void StartCgiServer() {
zlog_info(zbt, "start deal cgi");
while (1) {
TcpCgi::startCgiServer();
sleep(10);
}
}
void StartTCPServer() {
zlog_info(zbt, "start deal TCP");
while (1) {
TcpCgi::startTCPServer();
sleep(10);
}
}
void RunLED() {
while (1) {
gpio_set(GlobalConfig::GPIO_G.runLed, 1);
sleep(1);
gpio_set(GlobalConfig::GPIO_G.runLed, 0);
sleep(1);
}
}
void HeartRep() {
int count = 0;
while (1) {
Json::Value jsHeart;
Json::FastWriter fw;
jsHeart["dataNodeGatewayNo"] = GlobalConfig::MacAddr_G;
jsHeart["status"] = "online_V" + GlobalConfig::Version;
jsHeart["IP"] = GlobalConfig::IpAddr_G;
std::string strJson = fw.write(jsHeart);
int iRet = data_publish(strJson.c_str(), GlobalConfig::Topic_G.mPubHeart.c_str());
if (iRet != 0) {
zlog_warn(zct, "fail to send heart mqtt msg");
}
if (count == 10){
zlog_warn(zct, "heart = %s,iRet = %d", strJson.c_str(), iRet);
count = 0;
}else{
zlog_info(zct, "heart = %s,iRet = %d", strJson.c_str(), iRet);
}
if (iRet != 0) {
gpio_set(GlobalConfig::GPIO_G.errorLed, 1);
sleep(1);
gpio_set(GlobalConfig::GPIO_G.errorLed, 0);
sleep(1);
gpio_set(GlobalConfig::GPIO_G.errorLed, 1);
sleep(1);
gpio_set(GlobalConfig::GPIO_G.errorLed, 0);
sleep(1);
gpio_set(GlobalConfig::GPIO_G.errorLed, 1);
sleep(1);
GlobalConfig::serverStatus = 1;
} else {
GlobalConfig::serverStatus = 0;
gpio_set(GlobalConfig::GPIO_G.errorLed, 0);
}
sleep(30);
count ++;
}
}
void GetCSQ() {
#ifdef NR5G_MODULE
// 5G
int iRet = -1;
open5G:
iRet = dial.openPort("/dev/ttyUSB2");
if (iRet < 0) {
sleep(5);
goto open5G;
}
#ifdef NR5G_MEIGE
dial.closePort();
char szquectel[100] = {0x00};
std::string strAPN = ReadStrByOpt(SERVERCONFIG, "Server", "APN");
sprintf(szquectel, "/opt/quectel-CM/Meig-CM -s %s &", strAPN.c_str());
system(szquectel);
#else
dial.recvData();
#endif
#endif
#ifdef Q4G_MODULE
// 4G
int fd = -1;
open4G:
fd = config_uart("/dev/ttyUSB2", 115200);
if (fd < 0) {
sleep(5);
goto open4G;
}
char szbuffer[200] = {0x00};
int offSize = 0;
int timeoutflag = 0;
write_data(fd, "AT+QENG=\"servingcell\"\r\n", 27);
while (1) {
char buff[1024] = {0x00};
int ret = read_data(fd, buff, 1024, 10);
if (ret <= 0) {
timeoutflag++;
if (timeoutflag > 5) {
zlog_info(zbt,"timeoutflag = %d\n", timeoutflag);
timeoutflag = 0;
const char *str2 = "+QENG: ";
char csq[128] = {0};
char *pdata = strstr((char *)szbuffer, str2);
if (pdata) {
strncpy(csq, pdata + 7, sizeof(csq));
GlobalConfig::NetStatus = GetOneContent(csq, 1, ",");
std::string signal = GetOneContent(csq, 13, ",");
GlobalConfig::NetSignal = atoi(signal.c_str());
GlobalConfig::NetType = GetOneContent(csq, 2, ",");
zlog_info(zct, "NetStatus = %s,NetSignal = %d", GlobalConfig::NetStatus.c_str(), GlobalConfig::NetSignal);
}
memset(szbuffer, 0x00, sizeof(szbuffer));
offSize = 0;
write_data(fd, "AT+QENG=\"servingcell\"\r\n", 27);
}
usleep(10000);
} else if (ret > 0) {
zlog_info(zct, "ret = %d,buff = %s", ret, buff);
memcpy(szbuffer + offSize, buff, ret);
offSize = offSize + ret;
zlog_info(zct, "szbuffer = %s", szbuffer);
continue;
}
sleep(10);
}
#endif
}
void Dial5G() {
sleep(2);
dial5G:
if (dial.m_fd > 0) {
dial.dial5G();
} else {
sleep(5);
goto dial5G;
}
}
void UartStart() {
zlog_info(zbt, "zigAckrep = %d,zigAckreset = %d,zigReset = %d,errorLed = %d,power = %d", GlobalConfig::GPIO_G.zigAckrep, GlobalConfig::GPIO_G.zigAckreset, GlobalConfig::GPIO_G.zigReset, GlobalConfig::GPIO_G.errorLed, GlobalConfig::GPIO_G.power);
InitGpio(GlobalConfig::GPIO_G.zigAckrep, 0); // ACK
InitGpio(GlobalConfig::GPIO_G.zigAckreset, 1); // ACK reset
InitGpio(GlobalConfig::GPIO_G.zigReset, 1); // Zigbee reset
gpio_set(GlobalConfig::GPIO_G.zigAckreset, 1);
gpio_set(GlobalConfig::GPIO_G.zigReset, 1);
zlog_info(zbt, "GPIO Init");
InitGpio(GlobalConfig::GPIO_G.runLed, 1);
InitGpio(GlobalConfig::GPIO_G.errorLed, 1);
gpio_set(GlobalConfig::GPIO_G.runLed, 1);
gpio_set(GlobalConfig::GPIO_G.errorLed, 0);
InitGpio(GlobalConfig::GPIO_G.netResetNet0, 1);
gpio_set(GlobalConfig::GPIO_G.netResetNet0, 0);
GlobalConfig::Zigbee_G.Serial_Rate = 0x07;
GlobalConfig::Zigbee_G.Serial_DataB = 0x08;
GlobalConfig::Zigbee_G.Serial_StopB = 0x01;
uart_inst::instance().InitUart(B115200);
char buffer[1100] = {0x00};
sleep(1);
uart_inst::instance().UartRecv(uart_inst::instance().fd, 1, buffer);
sleep(1);
}
void InitModule() {
#ifdef NR5G_MODULE
InitGpio(GlobalConfig::GPIO_G.commPower, 1); // 4G,5G模组供电
gpio_set(GlobalConfig::GPIO_G.commPower, 1);
InitGpio(GlobalConfig::GPIO_G.vol3_8, 1); // 5G 高电平3.8V低电平3.3V
gpio_set(GlobalConfig::GPIO_G.vol3_8, 1);
InitGpio(GlobalConfig::GPIO_G.commRest, 1);
gpio_set(GlobalConfig::GPIO_G.commRest, 0); //高电平复位
#endif // NR5G_MODULE
#ifdef Q4G_MODULE
system("killall daemon_CM");
InitGpio(GlobalConfig::GPIO_G.commPower,1);//4G,5G模组供电
gpio_set(GlobalConfig::GPIO_G.commPower,1);
InitGpio(GlobalConfig::GPIO_G.commRest,1);
gpio_set(GlobalConfig::GPIO_G.commRest,0);//高电平复位
sleep(10);
char szquectel[100]={0x00};
std::string strAPN = ReadStrByOpt(SERVERCONFIG, "Server", "APN");
sprintf(szquectel,"/opt/quectel-CM/quectel-CM -s %s &",strAPN.c_str());
system(szquectel);
sleep(2);
system("/opt/Cidn/daemon_CM &");
#endif // Q4G_MODULE
#ifdef WIFI_MODULE
zlog_info(zbt, "Init WiFi!");
InitGpio(GlobalConfig::GPIO_G.wifiReset, 1); // WiFi模组复位1复位0取消复位
gpio_set(GlobalConfig::GPIO_G.wifiReset, 0);
InitGpio(GlobalConfig::GPIO_G.wifiPower, 1); // WiFi模组上电
gpio_set(GlobalConfig::GPIO_G.wifiPower, 1);
sleep(10);
wifi::WPAClient wpa;
wpa.ReconnectWiFi();
system("/usr/sbin/wpa_supplicant -Dnl80211 -iwlan0 -c/etc/wpa_supplicant.conf &");
system("udhcpc -b -i wlan0 &");
#endif // WIFI_MODULE
}
void TestUart() {
uart_inst::instance().InitTestUart(B115200);
uart_inst::instance().ReadTestUart();
}
void UartStartWave() { uart_inst::instance().DealWaveThread(); }
void StartUdpSys() { udp_sys::instance().StartConnectSysUdp(); }
void WatchDog() {
int fd = OpenWatchDog();
while (1) {
WriteWatchDog(fd);
sleep(50);
}
close(fd);
}
void StartMqttClient() {
zlog_info(zct, "start mqtt \n");
std::string runinfo = "MQTT通信模块启动";
while (1) {
if (GlobalConfig::ServerIP.length() > 0) {
std::string strEqupNo = GlobalConfig::MacAddr_G;
std::string strVersion = GlobalConfig::Version;
std::string salt;
start_client(strEqupNo.c_str(), GlobalConfig::MacAddr_G.c_str(), GlobalConfig::ServerIP.c_str(), strVersion.c_str(), "11111111", salt);
zlog_error(zct, "fail to connect server");
}
sleep(10);
}
}
void SearchThread() {
std::string runinfo = "设备搜索模块启动";
while (GlobalConfig::QuitFlag_G) {
if (GlobalConfig::IpAddr_G.length() > 0 && 0 != GlobalConfig::IpAddr_G.compare("0.0.0.0")) {
zlog_info(zct, "%s\n", runinfo.c_str());
boost::asio::io_service io_service;
SearchDev *searchDevObj = new SearchDev(io_service);
searchDevObj->MultiCastRecv();
io_service.run();
delete searchDevObj;
}
sleep(5);
zlog_info(zct, "SearchThread restart.");
}
}
void RecvUpdateFile() {
boost::asio::io_service iosev;
boost::asio::ip::tcp::acceptor acceptor(iosev, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 7304));
for (;;) {
boost::asio::ip::tcp::socket socket(iosev);
acceptor.accept(socket);
boost::system::error_code ec;
if (ec) {
zlog_error(zct, "%s\n", boost::system::system_error(ec).what());
}
FILE *fp;
char buffer[1024];
size_t len = 0;
size_t write_len;
bzero(buffer, 1024);
fp = fopen("/tmp/upgrade.tar.gz", "w");
if (NULL == fp) {
zlog_error(zbt, "File:/tmp/upgrade.tar.gz Can Not Open");
return;
}
while ((len = socket.read_some(boost::asio::buffer(buffer), ec))) {
write_len = fwrite(buffer, sizeof(char), len, fp);
if (write_len < len) {
zlog_info(zct, "File:test Write Failed!");
break;
}
bzero(buffer, 1024);
}
zlog_info(zbt, "Receive File From Server Finished!");
fclose(fp);
Json::Value jsData;
Json::FastWriter fw;
jsData["cmd"] = "03";
jsData["updatefilename"] = "updatefile";
std::string str = fw.write(jsData);
zlog_warn(zbt, "==============upgrade start===============");
system("/etc/init.d/sysupgrade.sh");
}
}
bool InsufficientFreeMemory() {
long mem_free = -1;
char name1[20];
std::string strMemFree = GetFileContent("/proc/meminfo", 2);
sscanf(strMemFree.c_str(), "%s%ld", name1, &mem_free);
mem_free = mem_free / 1024;
if (mem_free < 80) {
zlog_warn(zct, "free memory: %ld MB", mem_free);
return true;
} else {
return false;
}
}
void CleanLogFile(std::string log_dir, size_t retain) {
std::vector<LogFileProperty> vec;
boost::filesystem::path directory = log_dir;
try {
if (boost::filesystem::exists(directory) && boost::filesystem::is_directory(directory)) {
for (auto&& file : boost::filesystem::directory_iterator(directory)) {
if (boost::filesystem::is_regular_file(file)) {
LogFileProperty file_prop;
std::cout<<"["<<file.path()<<"]"<<std::endl;
file_prop.name = file.path().string();
file_prop.time_stamp = boost::filesystem::last_write_time(file);
vec.push_back(file_prop);
}
}
if (vec.size() > 0) {
std::sort(vec.begin(), vec.end());
if (vec.size() <= retain) {
zlog_warn(zct, "[DiskSpaceCheck] there is no enough file to clean:%d", vec.size());
return;
}
int total = vec.size();
for (int i = retain; i < total; ++i) {
boost::filesystem::remove(vec[i].name);
zlog_warn(zct, "[DiskSpaceCheck] *** delete %s", vec[i].name.c_str());
}
}
}
} catch (const boost::filesystem::filesystem_error& ex) {
zlog_error(zct, " Error accessing directory: %s", ex.what());
}
}
void DiskSpaceCheck() {
std::string directory = "/opt/log";
std::string directory_data = "/opt/data";
while (1) {
boost::filesystem::space_info si = boost::filesystem::space("/opt");
if (si.free <= 512000000) {
zlog_warn(zct, "disk free space:%llu for /opt", si.free);
CleanLogFile(directory, 10);
CleanLogFile(directory_data, 100);
boost::filesystem::space_info si1 = boost::filesystem::space("/opt");
if (si1.free <= 512000000) {
zlog_warn(zct, "[DiskSpaceCheck] can not release enough space and clean more log file");
CleanLogFile(directory, 5);
}
}
if (clean_memory == 10) { // 10*30 = 300秒清理一次内存
clean_memory = 0;
if (InsufficientFreeMemory()) {
system("sync");
sleep(10);
system("echo 3 > /proc/sys/vm/drop_caches");
if (InsufficientFreeMemory()) {
zlog_error(zct, "can not release more space, so reboot");
system("sync");
sleep(3);
system("reboot");
}
}
} else {
clean_memory++;
}
sleep(30);
}
}