-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
148 lines (123 loc) · 4.86 KB
/
main.cpp
File metadata and controls
148 lines (123 loc) · 4.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include <iostream>
#include <fstream>
#include <chrono>
#include <string>
#include <stdlib.h>
#include <sstream>
#include <filesystem>
#include <csignal>
#include <atomic>
#include <future>
#include "logic/periodic_access_token_refresh.hpp"
#include "configfile.hpp"
#include "utils/log_utils.hpp"
#include "utils/io_utils.hpp"
#include "config.hpp"
#include "logic/setup.hpp"
#include "logic/accesstoken.hpp"
#include "logic/server.hpp"
#include "inifile.hpp"
namespace fs = std::filesystem;
using json = nlohmann::json;
// Initialize static members
Logger* Logger::instance = nullptr;
std::mutex Logger::mutex;
std::atomic<bool> thread_stop_flag(false);
// Signal handler function to handle external stops
void signalHandler(int signum) {
std::cout << "Interrupt signal (" << signum << ") received.\n";
thread_stop_flag.store(true);
}
/**
* Main function to set up and run a TCP echo server.
*/
int main(int argc, char* argv[]) {
// Parse command-line arguments
if (argc==1){
std::cerr << "Usage: " << argv[0] << " -f <config_file_path>" << std::endl;
return 1;
}
std::string configFilePath="";
// Parse command-line arguments
for (int i = 1; i < argc; ++i) {
std::string arg = argv[i];
if (arg == "-f" && i + 1 < argc) { // Make sure we do not go out of bounds
configFilePath = argv[++i]; // Increment 'i' to skip the file path in the next loop iteration
} else {
std::cerr << "Usage: " << argv[0] << " -f <config_file_path>" << std::endl;
return 1;
}
}
//search in pos folder if not a full abs path
if (!isFullPath(configFilePath)){
configFilePath="/home/ubuntu/pos/conf/"+configFilePath;
}
//read config ini file
auto [readConfigResult,configFile]=readIniFile(configFilePath);
if (readConfigResult>0){
std::cerr << "Config file not found at "<< configFilePath<<". Check within /home/ubuntu/pos/conf or try with an absolute path." << std::endl;
return 1;
}
// Register signal handler
std::signal(SIGINT, signalHandler);
//set appConfig
Config appConfig;
//add config params from settings.ini
appConfig.port=configFile.port;
appConfig.host=configFile.host;
appConfig.envFilePath=configFile.envfilePath;
appConfig.bufferSize=configFile.bufferSize;
appConfig.serverDispatchMode=configFile.serverDispatchMode;
appConfig.baseURL=configFile.baseURL;
appConfig.logsDir=configFile.logsDir;
appConfig.deviceSecurityParametersPath=configFile.deviceSecurityParametersPath;
//create logger
Logger* logger = Logger::getInstance();
logger->init(appConfig); // Initialize logger configuration once
logger->logSimple("Start");
logger->log("POS SERVER 0.99");
logger->log( "Port : " +std::to_string( configFile.port));
logger->log( "Base URL : " + configFile.baseURL);
logger->log( "deviceSecurityParametersPath: " + configFile.deviceSecurityParametersPath);
logger->log( "Host : " + configFile.host);
logger->log( "logsDir : " + configFile.logsDir);
logger->log( "appDir : " + configFile.appDir);
logger->log( "serverExecutable : " + configFile.serverExecutable);
//setup app: check secret tokens, activation, access token, etc
// Create a promise to hold the result of the setup function
std::promise<std::pair<bool, std::string>> promise;
std::future<std::pair<bool, std::string>> future = promise.get_future();
// Run the setup function in a new thread
std::thread setupThread([&promise, &appConfig]() {
try {
// Call the setup function and store the result in the promise
auto setupResult = setup(appConfig);
promise.set_value(setupResult);
} catch (...) {
// In case of exception, set the exception in the promise
promise.set_exception(std::current_exception());
}
});
// Wait for the setup function to complete
setupThread.join();
// Get the result from the future
try {
auto [setupResult, accessToken] = future.get();
//auto [setupResult,accessToken]=setup(appConfig);
logger->log("Setup done");
if (setupResult>0){
logger->log("Exiting program as setup failed");
std::cout<<"Exiting program..."<<std::endl;
delete logger;
return 1;
}else{
periodicTokenExpirationCheck(appConfig,thread_stop_flag);
startServer(accessToken,appConfig,thread_stop_flag);
delete logger;
return 0;
}
} catch (const std::exception& e) {
std::cerr << "Setup encountered an exception: " << e.what() << std::endl;
delete logger;
}
}