WLG/threadfunc/thread_func.cpp
2024-10-24 16:34:11 +08:00

510 lines
17 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 <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;
static std::string uptime;
static long long connect_lost_time = 0; // ms
static long long connect_time = 0; // ms
Dial dial;
void StartCgiServer() {
zlog_info(zbt,"start deal cgi");
while (1) {
TcpCgi::startCgiServer();
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() {
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());
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(10);
}
}
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("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, ",");
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");
#ifdef IMX6UL_GATEWAY
InitGpio(GlobalConfig::GPIO_G.errorLed, 1); //指示灯
gpio_set(GlobalConfig::GPIO_G.errorLed, 0);
InitGpio(GlobalConfig::GPIO_G.power, 1); // power reset
gpio_set(GlobalConfig::GPIO_G.power, 0);
#endif
#ifdef G2UL_GATEWAY
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);
#endif
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
#ifdef G2UL_GATEWAY
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
#ifdef IMX6UL_GATEWAY
InitGpio(GlobalConfig::GPIO_G.commRest, 1);
gpio_set(GlobalConfig::GPIO_G.commRest, 1); //
#endif
#endif
#ifdef Q4G_MODULE
#ifdef G2UL_GATEWAY
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);
#endif
#endif
#ifdef WIFI_MODULE
zlog_info(zbt,"Init WiFi!");
#ifdef IMX6UL_GATEWAY
InitGpio(GlobalConfig::GPIO_G.wifiReset, 1); // WiFi模组复位0复位1取消复位
gpio_set(GlobalConfig::GPIO_G.wifiReset, 1);
sleep(10);
wifi::WPAClient wpa;
wpa.ReconnectWiFi();
system("/etc/init.d/wpa_restart");
system("udhcpc -i wlan2 &");
#endif
#ifdef G2UL_GATEWAY
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
#endif
}
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);
}
//static const char *LOCAL_WILL_TOPIC = "up/uart/will";
void my_publish_callback(struct mosquitto *mosq, void *obj, int mid) {}
void my_connect_callback(struct mosquitto *mosq, void *obj, int result) {
struct userdata *ud;
ud = (struct userdata *)obj;
if (!result) {
for (int i = 0; i < ud->topic_count; i++) {
zlog_info(zct,"mosquitto_subscribe ud->topics[%d]:%s", i, ud->topics[i]);
int iret = mosquitto_subscribe(mosq, NULL, ud->topics[i], ud->topic_qos);
zlog_info(zct,"mosquitto_subscribe ret:%d", iret);
}
int iret = mosquitto_subscribe(mosq, NULL, GlobalConfig::Topic_G.mSubData.c_str(), 1);
zlog_info(zct,"mosquitto_subscribe's return value: %d", iret);
char gwTime[32] = {0};
GetTimeNet(gwTime, 0);
connect_time = strtoll(gwTime, NULL, 10);
zlog_info(zct,"connect_time:%lld", connect_time);
long long difftime_ms = connect_time - connect_lost_time;
if (difftime_ms > 20 * 1000) { // 超过20秒判定为连接断开
char reply_string[256] = {0};
std::string startStatus = "0";
if (access(SYSTEMSTART, 0) >= 0) {
startStatus = GetFileContent(SYSTEMSTART, 1);
}
sprintf(reply_string, "{\"dataNodeGatewayNo\":\"%s\",\"softVersion\":\"%s\",\"status\":\"%s\"}", GlobalConfig::MacAddr_G.c_str(), GlobalConfig::Version.c_str(), startStatus.c_str());
Json::Value jsData;
Json::Value jsVal;
Json::FastWriter fw;
jsData["cmd"] = "15";
jsData["dataNodeGatewayNo"] = GlobalConfig::MacAddr_G;
std::string strCmd15 = fw.write(jsData);
std::string instr = std::string(reply_string);
std::string topic = "equipment/state/" + GlobalConfig::MacAddr_G;
int ret = data_publish(instr.c_str(), topic.c_str());
if (ret != MOSQ_ERR_SUCCESS) {
zlog_info(zct,"Publish failed:%d, %s", ret, instr.c_str());
disconnect();
}
}
GlobalConfig::LinkStatus_G = 1;
zlog_info(zct,"Connect to server success.");
char buf[256] = {0};
sprintf(buf, "{\"dataNodeGatewayNo\":\"%s\",\"cmd\":\"12\",\"status\":\"REQ\"}", GlobalConfig::MacAddr_G.c_str());
std::string str = std::string(buf);
std::string runinfo = "本地服务器连接成功";
} else {
if (result && !ud->quiet) {
fprintf(stderr, "%s\n", mosquitto_connack_string(result));
if (result == 1) {
// Connection Refused: unacceptable protocol version
} else if (result == 2) {
// Connection Refused: identifier rejected
} else if (result == 3) {
// Connection Refused: server unavailable
} else if (result == 4) {
// Connection Refused: bad user name or password
// exit(0);
} else if (result == 5) {
// Connection Refused: not authorized
}
}
}
}
void my_disconnect_callback(struct mosquitto *mosq, void *obj, int result) {
disconnect();
zlog_info(zct,"The MQTT connection lost\n");
char gwTime[32] = {0};
GetTimeNet(gwTime, 0);
uptime = std::string(gwTime);
connect_lost_time = strtoll(uptime.c_str(), NULL, 10);
zlog_info(zct,"connect_lost_time:%lld\n", connect_lost_time);
GlobalConfig::LinkStatus_G = 0;
GlobalConfig::LinkCount = GlobalConfig::LinkCount + 1;
#ifdef WIFI_MODULE
char buf[128] = {0};
std::string wpa_state = "";
#ifdef G2UL_GATEWAY
wpa_state = "/usr/sbin/wpa_cli status|grep wpa_state | cut -f 2 -d '='";
#endif
#ifdef IMX6UL_GATEWAY
wpa_state = "/opt/Cidn/wpa_cli status|grep wpa_state | cut -f 2 -d '='";
#endif
system_custom(wpa_state.c_str(), buf);
std::string state = std::string(buf);
std::string RSSI_cmd = "";
#ifdef G2UL_GATEWAY
RSSI_cmd = "/usr/sbin/wpa_cli signal_poll|grep RSSI | cut -f 2 -d '='";
#endif
#ifdef IMX6UL_GATEWAY
RSSI_cmd = "/opt/Cidn/wpa_cli signal_poll|grep RSSI | cut -f 2 -d '='";
#endif
system_custom(RSSI_cmd.c_str(), buf);
std::string RSSI = std::string(buf);
int iRet = reconnect();
memset(buf, 0, sizeof(buf));
sprintf(buf, "wifi RSSI:%s,state:%s,MQTT reconnect :%d\n", RSSI.c_str(), state.c_str(), iRet);
zlog_info(zct,"%s\n", buf);
#else
#endif
}
void my_message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) {
struct userdata *ud;
bool res;
assert(obj);
ud = (struct userdata *)obj;
if (message->retain && ud->no_retain) return;
if (ud->filter_outs) {
for (int i = 0; i < ud->filter_out_count; i++) {
mosquitto_topic_matches_sub(ud->filter_outs[i], message->topic, &res);
if (res) return;
}
}
if (ud->verbose) {
if (message->payloadlen) {
std::string strtopic(message->topic);
zlog_info(zct,"strtopic : %s \n", strtopic.c_str());
LocalServer::HandleFromServer((const char *)message->payload, message->payloadlen, message->topic);
if (ud->eol) {
}
} else {
if (ud->eol) {
zlog_info(zct,"%s (null)\n", message->topic);
}
}
fflush(stdout);
} else {
if (message->payloadlen) {
fwrite(message->payload, 1, message->payloadlen, stdout);
if (ud->eol) {
}
fflush(stdout);
}
}
}
void my_subscribe_callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos) {
int i;
struct userdata *ud;
assert(obj);
ud = (struct userdata *)obj;
if (!ud->quiet) zlog_info(zct,"Subscribed (mid: %d): %d", mid, granted_qos[0]);
for (i = 1; i < qos_count; i++) {
if (!ud->quiet) zlog_info(zct,", %d", granted_qos[i]);
}
}
void my_log_callback(struct mosquitto *mosq, void *obj, int level, const char *str) {
if (level == MOSQ_LOG_ERR) {
// LOG_ERROR("%s\n", str);
} else if (level == MOSQ_LOG_WARNING) {
// LOG_WARN("%s\n", str);
} else if (level == MOSQ_LOG_NOTICE) {
// LOG_INFO("%s\n", str);
}
}
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;
register_collback(my_connect_callback, my_message_callback, my_subscribe_callback, my_log_callback, my_disconnect_callback, my_publish_callback);
start_client(strEqupNo.c_str(), GlobalConfig::MacAddr_G.c_str(), GlobalConfig::ServerIP.c_str(), strVersion.c_str(), "11111111", salt);
}
sleep(3);
}
}
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_info(zct,"File:\t Can Not Open To Write");
exit(1);
}
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(zct, "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);
system("/etc/init.d/sysupgrade.sh");
}
}