123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- // LogModule.cpp : 定义 DLL 应用程序的导出函数。
- //
- #include "stdafx.h"
- #include "LogModule.h"
- #include <Shlwapi.h>
- #include "SynSerial.h"
- #include <process.h>
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #endif
- // 唯一的应用程序对象
- CWinApp theApp;
- using namespace std;
- CIOCPModel g_IOCP; // 主要对象,完成端口模型
- // 线程:用于监听串口消息;
- bool g_bStopThread = false;
- HANDLE g_hThread = NULL;
- unsigned int g_threadID = 0;
- unsigned int __stdcall ThreadWathTVPort(PVOID pM)
- {
- CSynSerial tv;
- std::string buffer;
- TCHAR szLastPort[10] = {0};
- _tcscpy_s(szLastPort, Global::g_szTVPort);
- std::vector<std::string> vtNotifyReboot;
- std::vector<std::string> vtNotifyShutdown;
- DWORD dwTickCount = GetTickCount();
- while(!g_bStopThread)
- {
- // 读取配置文件;
- Global::GetResourceCfg();
- if ( !Global::g_bWatchTVPort )
- {
- Sleep(5000);
- continue;
- }
- if ( GetTickCount() - dwTickCount > 5000 )
- {// 5秒更新一次;
- dwTickCount = GetTickCount();
- vtNotifyReboot.clear();
- vtNotifyShutdown.clear();
- Global::Split(Global::g_szTVReboot, _T(";"), vtNotifyReboot);
- Global::Split(Global::g_szTVShutdown, _T(";"), vtNotifyShutdown);
- }
- // 串口是否变更;
- if ( _tcsicmp(szLastPort, Global::g_szTVPort) )
- {
- _tcscpy_s(szLastPort, Global::g_szTVPort);
- // 重启打开串口;
- tv.CloseSerialPort();
- }
-
- if ( !tv.IsOpen() )
- {
- tv.OpenSerialPort(szLastPort, 115200, 8, 0, 1, 0, 1000);
- }
- if ( tv.IsOpen() )
- {
- BYTE szBuffer[1024] = {0};
- DWORD dwBuffer = tv.ReadComm(szBuffer, 1024, 1000);
- if ( dwBuffer != 0 )
- {
- int nType = 0; // 0表示无异常类型,-1表示关机异常,1表示重启异常;
- bool bAbnormal = false;
- buffer = (char*)szBuffer;
- __time64_t gmt = time(NULL);// 获取当前日历时间(1900-01-01开始的Unix时间戳);
- // 遍历是否有符合的子串;
- for ( std::vector<std::string>::iterator it = vtNotifyReboot.begin(); it != vtNotifyReboot.end(); it++ )
- {
- if ( _tcsstr(buffer.c_str(), it->c_str()) )
- {
- nType = 1;
- bAbnormal = true;
- break;
- }
- }
- if ( !bAbnormal )
- {
- for ( std::vector<std::string>::iterator it = vtNotifyShutdown.begin(); it != vtNotifyShutdown.end(); it++ )
- {
- if ( _tcsstr(buffer.c_str(), it->c_str()) )
- {
- nType = -1;
- bAbnormal = true;
- break;
- }
- }
- }
- // 1分钟前,是否有收到脚本通知;
- if ( Global::g_notify.notify )
- {
- __int64 nd = gmt - Global::g_notify.datetime;
- #ifdef _DEBUG
- TRACE3("判断时间%ld-通知时间%ld=相差时间%ld\n\n", gmt, Global::g_notify.datetime, nd);
- #endif
- if ( nd < 60)
- {
- // 监测的类型与通知类型是否一致;
- if ( (nType == 1 && Global::g_notify.report_type == _T("reboot")) ||
- (nType == -1 && Global::g_notify.report_type == _T("shutdown")) )
- {
- bAbnormal = false;
- // 重置;
- Global::g_notify.notify = false;
- Global::g_notify.datetime = 0;
- Global::g_notify.report_type.clear();
- }
- }
- }
-
- if (bAbnormal)
- {
- if ( nType == -1 )
- {
- // 遥控:重启电视机;
- if ( Global::g_SendPowerKey )
- Global::g_SendPowerKey();
- }
- // 压入容器中;
- Global::TLog tlog;
- if ( nType == -1 )
- tlog.report_type = "Abnormal shutdown";
- else if ( nType == 1 )
- tlog.report_type = "Abnormal restart";
- tlog.datetime = gmt; // 发生时间;
- struct tm gmtm = {0};
- localtime_s(&gmtm, &gmt); // 时间戳转成本地时间;
- TCHAR szDataTime[64] = {0};
- _stprintf_s(szDataTime,_T("Time of exception:%04d-%02d-%02d %02d:%02d:%02d"), gmtm.tm_year + 1900, gmtm.tm_mon+1, gmtm.tm_mday, gmtm.tm_hour, gmtm.tm_min, gmtm.tm_sec);
- tlog.report_data = szDataTime;
- Global::g_vtAbnormal.push_back(tlog);
- // 最后,重置;
- Global::g_notify.notify = false;
- Global::g_notify.datetime = 0;
- Global::g_notify.report_type.clear();
- }
- }
- }
- Sleep(200);
- }
- return 0;
- }
- // 启动tcp服务;
- BOOL StartServer(unsigned int port)
- {
- // 1.加载配置文件;
- TCHAR szDrive[_MAX_DRIVE] = { 0 };
- TCHAR szDir[_MAX_DIR] = { 0 };
- TCHAR szExt[_MAX_DIR] = { 0 };
- ::GetModuleFileName(NULL, Global::g_szCurModulePath, sizeof(Global::g_szCurModulePath) / sizeof(TCHAR));
- _tsplitpath_s(Global::g_szCurModulePath, szDrive, szDir, Global::g_szFna, szExt);
- _tcscpy_s(Global::g_szCurModuleDir, szDrive);
- _tcscat_s(Global::g_szCurModuleDir, szDir);
- // 初始化网络库;
- if ( !g_IOCP.LoadSocketLib() )
- {
- return FALSE;
- }
- Global::WriteTextLog(_T("初始化网络库成功"));
- // 开启tcp服务;
- if ( !g_IOCP.Start(port) )
- {
- return FALSE;
- }
- Global::g_time = time(NULL);
- Global::g_lastTime = COleDateTime::GetCurrentTime();
- Global::WriteTextLog(_T("开启TCP服务成功"));
- if ( PathFileExists(Global::g_szConfig) )
- {
- // runner_tcp_port
- TCHAR szTcpPort[10] = {0};
- _itoa_s(port, szTcpPort, 10);
- Global::WriteTextLog(_T("配置文件路径:%s"), Global::g_szConfig);
- for ( int i = 0; i < 10; i++ )
- {
- if (!WritePrivateProfileString(_T("COMM"), _T("runner_tcp_port"), szTcpPort, Global::g_szConfig))
- Global::WriteTextLog(_T("保存端口号:%d 失败; 原因:%d"), port, GetLastError());
- else
- {
- Global::WriteTextLog(_T("保存端口号:%d 成功;"), port);
- break;
- }
- }
- }
- #ifdef _DEBUG
- Sleep(10000);
- #endif
- Global::GetResourceCfg();
- // 启动线程;
- g_hThread = (HANDLE)_beginthreadex( NULL, 0, &ThreadWathTVPort, NULL, 0, &g_threadID );
- return TRUE;
- }
- // 停止tcp服务;
- void StopServer()
- {
- g_IOCP.Stop();
- // 等待线程结束;
- g_bStopThread = true;
- WaitForSingleObject( g_hThread, INFINITE );
- CloseHandle( g_hThread );
- }
- // 是否写入日志文件;
- void EnableWriteLog(bool bEnable)
- {
- Global::g_bEnableLog = bEnable;
- if ( !bEnable )
- Global::ClosePythonLog();
- Global::WriteTextLog(_T("当前日志路径:%s; 状态:%s"), Global::g_szLogPath, bEnable ? _T("启用日志") : _T("禁用日志") );
- }
- void SetCaselogPath(LPCTSTR lpCaselogPath)
- {
- if ( lpCaselogPath == NULL || lpCaselogPath[0] == '\0')
- {
- Global::WriteTextLog(_T("日志路径无效"));
- return;
- }
- Global::WriteTextLog(_T("设置日志路径:%s"), lpCaselogPath);
- _stprintf_s(Global::g_szLogPath, _T("%s"), lpCaselogPath);
- }
- void SetConfigPath(LPCTSTR lpConfigPath)
- {
- if ( lpConfigPath == NULL || lpConfigPath[0] == '\0')
- return;
- _stprintf_s(Global::g_szConfig, _T("%s"), lpConfigPath);
- }
- void SetSendPowerKeyCB(void *pCB)
- {
- Global::g_SendPowerKey = (Global::SENDPOWERKEY)pCB;
- }
- LPCTSTR GetCaselogPath()
- {
- return Global::g_szLogPath;
- }
- __int64 GetReceivePrintTime()
- {
- return Global::g_time;
- }
- void SetReceivePrintTime(__int64 dt)
- {
- Global::g_time = dt;
- }
- void ClosePythonLog()
- {
- Global::ClosePythonLog();
- }
- BOOL AddAbnormaltoXML(LPCTSTR lpXMLPath)
- {
- // 参数有效性判断;
- if ( !lpXMLPath || !PathFileExists(lpXMLPath) )
- {
- return FALSE;
- }
- // 解析xml;
- tinyxml2::XMLDocument doc;
- if (tinyxml2::XML_SUCCESS != doc.LoadFile(lpXMLPath) )
- {
- return FALSE;
- }
- tinyxml2::XMLElement *pXmlRoot = NULL;
- if ((pXmlRoot = doc.RootElement()) != NULL)
- {
- int i = 0;
- TCHAR szNumber[10] = {0};
- for ( std::vector<Global::TLog>::iterator it = Global::g_vtAbnormal.begin(); it != Global::g_vtAbnormal.end(); it++ )
- {
- tinyxml2::XMLElement *pItem = doc.NewElement("item");
- tinyxml2::XMLElement *pName = doc.NewElement("name");
- tinyxml2::XMLElement *pResult = doc.NewElement("result");
- tinyxml2::XMLElement *pData = doc.NewElement("data");
- tinyxml2::XMLElement *pLog = doc.NewElement("log");
- tinyxml2::XMLElement *pRemark = doc.NewElement("remark");
- memset(szNumber, 0, 10);
- _stprintf_s(szNumber, _T("100%04d@%s"), i++, it->report_type.c_str());
- pName->SetText(szNumber);
- pResult->SetText("PASS");
- pData->SetText(it->report_data.c_str());
- pItem->InsertEndChild(pName);
- pItem->InsertEndChild(pResult);
- pItem->InsertEndChild(pData);
- pItem->InsertEndChild(pLog);
- pItem->InsertEndChild(pRemark);
- pXmlRoot->InsertEndChild(pItem);
- }
- }
- // 保存;
- doc.SaveFile(lpXMLPath);
- Global::g_vtAbnormal.clear();
- }
|