#include #include #include #include #include #include #include #include #include #include "app.hpp" // for app_info struct #include "file.hpp" // for parce_args #include "log.h" // for logging #include "net.hpp" // for socket operations #include "server_structs.h" // for api_packet and ACSP_MessageType #include "session.hpp" // for SessionManager const u_int8_t UPDATE_INTERVAL = 120; // in milliseconds using namespace std; volatile bool STOP_PROGRAM = false; void signal_handler(int signum) { if (signum == SIGINT || signum == SIGTERM) { STOP_PROGRAM = true; } } int main(int argc, char *argv[]) { app_info app = parce_args(argc, argv); api_packet packet; Socket sock; SessionManager session_manager(app.app_id); // Server ID 1 for now char buffer[2048]; try { // Connect socket to API // sock.connect_unix(app.app_api_socket_path.c_str(), app.app_port_out); // Connect socket to Server sock.connect_server(app.app_server_out_ip.c_str(), app.app_port_out); sock.bind_server("127.0.0.1", app.app_port_in); // Await server for initial data sock.receive_server(buffer, sizeof(buffer)); log_info("Connected to server, awaiting version confirmation...\n"); if (buffer[0] == ACSP_VERSION) { log_info("Server version confirmed. Sending update rate request @ %ums\n", UPDATE_INTERVAL); } else { throw runtime_error("Did not receive version confirmation from server."); } char request[516] = {0}; request[0] = ACSP_REALTIMEPOS_INTERVAL; request[1] = UPDATE_INTERVAL; sock.send_server(request, sizeof(request)); log_debug("Info:\n"); log_debug("\tApp ID: %d\n", app.app_id); log_debug("\tAPI Socket Path: %s\n", app.app_api_socket_path.c_str()); log_debug("\tServer Out IP: %s\n", app.app_server_out_ip.c_str()); log_debug("\tApp Port In: %d\n", app.app_port_in); log_debug("\tApp Port Out: %d\n", app.app_port_out); } catch (const runtime_error &e) { cerr << "Error: " << e.what() << endl; return 1; } // TODO: Implement Cache // TAG: Because sometimes the parser doesnt have the name of the server because it started after the server init // we can cache it and reuse it to avoid NULL names in the DB while (STOP_PROGRAM == false) { // Receive data from server ssize_t received = sock.receive_server(buffer, sizeof(buffer)); if (received > 0) { switch (buffer[0]) { // DONE: case ACSP_VERSION: { log_warn("Received Version Again? (Probably server restart) Resending Update Request @ %ums\n", UPDATE_INTERVAL); char request[516] = {0}; request[0] = ACSP_REALTIMEPOS_INTERVAL; request[1] = UPDATE_INTERVAL; sock.send_server(request, sizeof(request)); break; } // TODO: case ACSP_CAR_UPDATE: { log_info("Received car update.\n"); break; } // TODO: case ACSP_NEW_SESSION: { log_info("New session started.\n"); break; } default: { break; } } } } return 0; }