| | |
| | | #include "stdafx.h" |
| | | #include "NetworkConfig.h" |
| | | |
| | | bool NetworkConfig::startupModeSelected = false; |
| | | |
| | | NetworkConfig::NetworkConfig(const std::string& xmlFilePath) |
| | | { |
| | | tinyxml2::XMLError eResult = doc.LoadFile(xmlFilePath.c_str()); |
| | | loaded = (eResult == tinyxml2::XML_SUCCESS); |
| | | |
| | | if (!startupModeSelected) { |
| | | std::string selectedMode; |
| | | std::time_t lastModifiedTime = 0; |
| | | std::cout << "Please select the startup mode (cold_start/hot_start): " << std::endl; |
| | | std::cin >> selectedMode; |
| | | |
| | | if (this->setStartupMode(selectedMode)) { |
| | | std::cout << "Selected " << selectedMode << std::endl; |
| | | if (this->saveXML("config.xml")) { |
| | | std::cout << "( XML file saved successfully )" << std::endl; |
| | | } |
| | | else { |
| | | std::cout << "( Failed to save XML file )" << std::endl; |
| | | } |
| | | |
| | | if (selectedMode == "cold_start") { |
| | | StartupMode currentMode = StartupMode::ColdStart; |
| | | this->restartServices(currentMode, "config.xml", lastModifiedTime); |
| | | } |
| | | else if (selectedMode == "hot_start") { |
| | | startupModeSelected = true; |
| | | NetworkConfig oldParser("Info.xml"); |
| | | StartupMode currentMode = StartupMode::HotStart; |
| | | this->restartServices(currentMode, "config.xml", lastModifiedTime); |
| | | } |
| | | } |
| | | else { |
| | | std::cout << "Invalid startup mode. Please enter cold_start or hot_start." << std::endl; |
| | | } |
| | | startupModeSelected = true; |
| | | } |
| | | } |
| | | |
| | | NetworkConfig::~NetworkConfig() |
| | | { |
| | | |
| | | } |
| | | |
| | | bool NetworkConfig::isLoaded() const |
| | | { |
| | | return loaded; |
| | | } |
| | | |
| | | bool NetworkConfig::getTCPConfig(std::string & ipAddress, int & portNumber) |
| | | { |
| | | if (!loaded) return false; |
| | | tinyxml2::XMLElement* tcpElement = doc.FirstChildElement("NetworkConfigurationInfo") |
| | | ->FirstChildElement("Socket")->FirstChildElement("TCP"); |
| | | |
| | | if (tcpElement) { |
| | | const char* ip = tcpElement->FirstChildElement("IPAddress")->GetText();// Get IP address text |
| | | if (ip) ipAddress = ip; |
| | | |
| | | portNumber = std::stoi(tcpElement->FirstChildElement("PortNumber")->GetText());// Get port number |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | bool NetworkConfig::getRTSPConfig(std::string & ipAddress, int & portNumber) |
| | | { |
| | | if (!loaded) return false; |
| | | tinyxml2::XMLElement* rtspElement = doc.FirstChildElement("NetworkConfigurationInfo") |
| | | ->FirstChildElement("Socket")->FirstChildElement("RTSP"); |
| | | if (rtspElement) { |
| | | const char* ip = rtspElement->FirstChildElement("IPAddress")->GetText(); // Get IP address text |
| | | if (ip) ipAddress = ip; |
| | | rtspElement->FirstChildElement("PortNumber")->QueryIntText(&portNumber);// Get port number |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | bool NetworkConfig::getLogConfig(std::string & path, int & size) |
| | | { |
| | | if (!loaded) return false; |
| | | tinyxml2::XMLElement* logElement = doc.FirstChildElement("NetworkConfigurationInfo") |
| | | ->FirstChildElement("Log"); |
| | | if (logElement) { |
| | | const char* logPath = logElement->FirstChildElement("Path")->GetText(); // Get log path text |
| | | if (logPath) path = logPath; |
| | | logElement->FirstChildElement("Size")->QueryIntText(&size);// Get log size |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | bool NetworkConfig::getMySQLConfig(std::string & ip, int & port, std::string & db, std::string & user, std::string & password) |
| | | { |
| | | if (!loaded) return false; |
| | | tinyxml2::XMLElement* mysqlElement = doc.FirstChildElement("NetworkConfigurationInfo") |
| | | ->FirstChildElement("MySQL"); |
| | | if (mysqlElement) { |
| | | const char* mysqlIp = mysqlElement->FirstChildElement("IP")->GetText(); // Get IP address text |
| | | if (mysqlIp) ip = mysqlIp; |
| | | mysqlElement->FirstChildElement("port")->QueryIntText(&port); |
| | | |
| | | const char* mysqlDb = mysqlElement->FirstChildElement("db")->GetText(); // Get database name text |
| | | if (mysqlDb) db = mysqlDb; |
| | | |
| | | const char* mysqlUser = mysqlElement->FirstChildElement("user")->GetText(); // Get username text |
| | | if (mysqlUser) user = mysqlUser; |
| | | |
| | | const char* mysqlPassword = mysqlElement->FirstChildElement("password")->GetText(); // Get password text |
| | | if (mysqlPassword) password = mysqlPassword; |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | bool NetworkConfig::getPictureManagementRootPath(std::string & rootPath) |
| | | { |
| | | if (!loaded) return false; |
| | | tinyxml2::XMLElement* pictureElement = doc.FirstChildElement("NetworkConfigurationInfo") |
| | | ->FirstChildElement("PictureManagement"); |
| | | if (pictureElement) { |
| | | const char* path = pictureElement->FirstChildElement("RootPath")->GetText(); // Get root path text |
| | | if (path) rootPath = path; |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | bool NetworkConfig::getPreprocessedPictureRootPath(std::string & rootPath) |
| | | { |
| | | if (!loaded) return false; |
| | | tinyxml2::XMLElement* preprocessedElement = doc.FirstChildElement("NetworkConfigurationInfo") |
| | | ->FirstChildElement("PreprocessedPicture"); |
| | | if (preprocessedElement) { |
| | | const char* path = preprocessedElement->FirstChildElement("RootPath")->GetText(); // Get root path text |
| | | if (path) rootPath = path; |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | bool NetworkConfig::getVideoManagementRootPath(std::string & rootPath) |
| | | { |
| | | if (!loaded) return false; |
| | | tinyxml2::XMLElement* VideoElement = doc.FirstChildElement("NetworkConfigurationInfo") |
| | | ->FirstChildElement("VideoManagement"); |
| | | if (VideoElement) { |
| | | const char* path = VideoElement->FirstChildElement("RootPath")->GetText(); // Get root path text |
| | | if (path) rootPath = path; |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | bool NetworkConfig::getCNNModelSavePath(std::string & path) |
| | | { |
| | | if (!loaded) return false; |
| | | tinyxml2::XMLElement* cnnElement = doc.FirstChildElement("NetworkConfigurationInfo") |
| | | ->FirstChildElement("CNNModelSave"); |
| | | if (cnnElement) { |
| | | const char* cnnPath = cnnElement->FirstChildElement("Path")->GetText(); // Get save path text |
| | | if (cnnPath) path = cnnPath; |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | bool NetworkConfig::getVersionManagementRootPath(std::string & rootPath) |
| | | { |
| | | if (!loaded) return false; |
| | | tinyxml2::XMLElement* versionElement = doc.FirstChildElement("NetworkConfigurationInfo") |
| | | ->FirstChildElement("VersionManagement"); |
| | | if (versionElement) { |
| | | const char* path = versionElement->FirstChildElement("RootPath")->GetText(); // Get root path text |
| | | if (path) rootPath = path; |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | bool NetworkConfig::getStartupMode(std::string & mode) |
| | | { |
| | | if (!loaded) return false; |
| | | tinyxml2::XMLElement* startupElement = doc.FirstChildElement("NetworkConfigurationInfo") |
| | | ->FirstChildElement("StartupMode"); |
| | | if (startupElement) { |
| | | const char* startupMode = startupElement->FirstChildElement("Mode")->GetText();// Get startup mode |
| | | if (startupMode) mode = startupMode; |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | bool NetworkConfig::setStartupMode(const std::string & mode) |
| | | { |
| | | if (!loaded || (mode != "cold_start" && mode != "hot_start")) return false; |
| | | tinyxml2::XMLElement* startupElement = doc.FirstChildElement("NetworkConfigurationInfo") |
| | | ->FirstChildElement("StartupMode"); |
| | | if (startupElement) { |
| | | tinyxml2::XMLElement* modeElement = startupElement->FirstChildElement("Mode"); |
| | | if (modeElement) { |
| | | modeElement->SetText(mode.c_str()); |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | bool NetworkConfig::saveXML(const std::string & xmlFilePath) |
| | | { |
| | | if (!loaded) return false; |
| | | tinyxml2::XMLError eResult = doc.SaveFile(xmlFilePath.c_str()); |
| | | return (eResult == tinyxml2::XML_SUCCESS); |
| | | } |
| | | |
| | | void NetworkConfig::coldStart() |
| | | { |
| | | std::cout << "Cold start begins..." << std::endl; |
| | | std::cout << "Initializing network connections...\n"; |
| | | std::string tcpIp; |
| | | int tcpPort; |
| | | if (this->getTCPConfig(tcpIp, tcpPort)) { |
| | | std::cout << "Establishing TCP connection: " << tcpIp << ":" << tcpPort << std::endl; |
| | | } |
| | | |
| | | std::string rtspIp; |
| | | int rtspPort; |
| | | if (this->getRTSPConfig(rtspIp, rtspPort)) { |
| | | std::cout << "Establishing RTSP connection: " << rtspIp << ":" << rtspPort << std::endl; |
| | | } |
| | | |
| | | std::string mysqlIp, mysqlDb, mysqlUser, mysqlPassword; |
| | | int mysqlPort; |
| | | if (this->getMySQLConfig(mysqlIp, mysqlPort, mysqlDb, mysqlUser, mysqlPassword)) { |
| | | std::cout << "Connecting to MySQL database: " << mysqlIp << ":" << mysqlPort << " - " << mysqlDb << std::endl; |
| | | } |
| | | |
| | | std::string cnnPath; |
| | | if (this->getCNNModelSavePath(cnnPath)) { |
| | | std::cout << "Loading CNN model: " << cnnPath << std::endl; |
| | | } |
| | | std::cout << "Cold start completed." << std::endl; |
| | | } |
| | | |
| | | void NetworkConfig::hotStart(NetworkConfig & oldParser) |
| | | { |
| | | std::cout << "Hot start begins..." << std::endl; |
| | | std::string oldTcpIp, newTcpIp; |
| | | int oldTcpPort, newTcpPort; |
| | | if (oldParser.getTCPConfig(oldTcpIp, oldTcpPort) && this->getTCPConfig(newTcpIp, newTcpPort)) { |
| | | if (oldTcpIp != newTcpIp || oldTcpPort != newTcpPort) { |
| | | std::cout << "TCP configuration updated: " << oldTcpIp << ":" << oldTcpPort |
| | | << " -> " << newTcpIp << ":" << newTcpPort << std::endl; |
| | | if (setTCPConfig(newTcpIp, newTcpPort)) { |
| | | std::cout << "TCP" << std::endl; |
| | | std::cout << " IP: " << newTcpIp << "\n Port: " << newTcpPort << std::endl; |
| | | } |
| | | } |
| | | } |
| | | |
| | | std::string oldRtspIp, newRtspIp; |
| | | int oldRtspPort, newRtspPort; |
| | | if (oldParser.getRTSPConfig(oldRtspIp, oldRtspPort) && this->getRTSPConfig(newRtspIp, newRtspPort)) { |
| | | if (oldRtspIp != newRtspIp || oldRtspPort != newRtspPort) { |
| | | std::cout << "RTSP configuration updated: " << oldRtspIp << ":" << oldRtspPort |
| | | << " -> " << newRtspIp << ":" << newRtspPort << std::endl; |
| | | } |
| | | } |
| | | std::string oldLogPath, newLogPath; |
| | | int oldLogSize, newLogSize; |
| | | if (oldParser.getLogConfig(oldLogPath, oldLogSize) && this->getLogConfig(newLogPath, newLogSize)) { |
| | | if (oldLogPath != newLogPath || oldLogSize != newLogSize) { |
| | | std::cout << "Log configuration updated: " << oldLogPath << "(" << oldLogSize << ")" |
| | | << " -> " << newLogPath << "(" << newLogSize << ")" << std::endl; |
| | | } |
| | | } |
| | | std::string oldMysqlIp, newMysqlIp, oldMysqlDb, newMysqlDb, oldMysqlUser, newMysqlUser, oldMysqlPassword, newMysqlPassword; |
| | | int oldMysqlPort, newMysqlPort; |
| | | if (oldParser.getMySQLConfig(oldMysqlIp, oldMysqlPort, oldMysqlDb, oldMysqlUser, oldMysqlPassword) && |
| | | this->getMySQLConfig(newMysqlIp, newMysqlPort, newMysqlDb, newMysqlUser, newMysqlPassword)) { |
| | | if (oldMysqlIp != newMysqlIp || oldMysqlPort != newMysqlPort || |
| | | oldMysqlDb != newMysqlDb || oldMysqlUser != newMysqlUser || oldMysqlPassword != newMysqlPassword) { |
| | | std::cout << "MySQL configuration updated: " << oldMysqlIp << ":" << oldMysqlPort << " - " << oldMysqlDb |
| | | << " -> " << newMysqlIp << ":" << newMysqlPort << " - " << newMysqlDb << std::endl; |
| | | } |
| | | } |
| | | std::string oldPictureRootPath, newPictureRootPath; |
| | | if (oldParser.getPictureManagementRootPath(oldPictureRootPath) && this->getPictureManagementRootPath(newPictureRootPath)) { |
| | | if (oldPictureRootPath != newPictureRootPath) { |
| | | std::cout << "Picture management root path updated: " << oldPictureRootPath |
| | | << " -> " << newPictureRootPath << std::endl; |
| | | } |
| | | } |
| | | std::string oldVideoRootPath, newVideoRootPath; |
| | | if (oldParser.getVideoManagementRootPath(oldVideoRootPath) && this->getVideoManagementRootPath(newVideoRootPath)) { |
| | | if (oldVideoRootPath != newVideoRootPath) { |
| | | std::cout << "Video management root path updated: " << oldVideoRootPath |
| | | << " -> " << newVideoRootPath << std::endl; |
| | | } |
| | | } |
| | | std::string oldCnnPath, newCnnPath; |
| | | if (oldParser.getCNNModelSavePath(oldCnnPath) && this->getCNNModelSavePath(newCnnPath)) { |
| | | if (oldCnnPath != newCnnPath) { |
| | | std::cout << "CNN model save path updated: " << oldCnnPath |
| | | << " -> " << newCnnPath << std::endl; |
| | | } |
| | | } |
| | | std::string oldVersionRootPath, newVersionRootPath; |
| | | if (oldParser.getVersionManagementRootPath(oldVersionRootPath) && this->getVersionManagementRootPath(newVersionRootPath)) { |
| | | if (oldVersionRootPath != newVersionRootPath) { |
| | | std::cout << "Version management root path updated: " << oldVersionRootPath |
| | | << " -> " << newVersionRootPath << std::endl; |
| | | } |
| | | } |
| | | std::cout << "Hot start completed." << std::endl; |
| | | } |
| | | |
| | | bool NetworkConfig::isConfigUpdated(const std::string & xmlFilePath, std::time_t & lastModifiedTime) |
| | | { |
| | | struct stat fileStat; |
| | | if (stat(xmlFilePath.c_str(), &fileStat) == 0) { |
| | | if (fileStat.st_mtime > lastModifiedTime) { |
| | | lastModifiedTime = fileStat.st_mtime; |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | void NetworkConfig::restartServices(StartupMode currentMode, const std::string & xmlFilePath, std::time_t & lastModifiedTime) |
| | | { |
| | | switch (currentMode) { |
| | | case StartupMode::ColdStart: |
| | | if (isConfigUpdated("Info.xml", lastModifiedTime)) { |
| | | std::cout << "Configuration file parameters changed. Performing cold start to restart the entire service..." << std::endl; |
| | | coldStart(); |
| | | } |
| | | else { |
| | | std::cout << "No changes in the configuration file. Cold start is not required." << std::endl; |
| | | } |
| | | break; |
| | | case StartupMode::HotStart: |
| | | if (this->isConfigUpdated(xmlFilePath, lastModifiedTime)) { |
| | | NetworkConfig oldParser(xmlFilePath); |
| | | this->hotStart(oldParser); |
| | | } |
| | | else { |
| | | std::cout << "No changes in the configuration file. Hot start is not required." << std::endl; |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | |
| | | bool NetworkConfig::setTCPConfig(const std::string & ipAddress, int portNumber) |
| | | { |
| | | if (!loaded) return false; |
| | | tinyxml2::XMLElement* tcpElement = doc.FirstChildElement("NetworkConfigurationInfo") |
| | | ->FirstChildElement("Socket")->FirstChildElement("TCP"); |
| | | |
| | | if (tcpElement) { |
| | | tinyxml2::XMLElement* ipElement = tcpElement->FirstChildElement("IPAddress"); |
| | | if (ipElement) { |
| | | ipElement->SetText(ipAddress.c_str()); |
| | | } |
| | | tinyxml2::XMLElement* portElement = tcpElement->FirstChildElement("PortNumber"); |
| | | if (portElement) { |
| | | portElement->SetText(portNumber); |
| | | } |
| | | return true; |
| | | } |
| | | return false; |
| | | } |