adding database calls
This commit is contained in:
parent
3318610cd2
commit
496e875e70
|
|
@ -24,7 +24,8 @@ add_subdirectory(src/gilles/helper)
|
||||||
add_subdirectory(src/gilles/slog)
|
add_subdirectory(src/gilles/slog)
|
||||||
|
|
||||||
add_executable(gilles src/gilles/gilles.c)
|
add_executable(gilles src/gilles/gilles.c)
|
||||||
target_link_libraries(gilles m ncursesw argtable2 config gameloop helper slog simulatorapi eclipse-paho-mqtt-c::paho-mqtt3c pthread json-c)
|
target_link_libraries(gilles xdg-basedir m ncursesw argtable2 config gameloop helper slog simulatorapi eclipse-paho-mqtt-c::paho-mqtt3c pthread hoel jansson)
|
||||||
|
add_compile_definitions(gilles SIMMAP_ALL)
|
||||||
|
|
||||||
# used for enabling additional compiler options if supported
|
# used for enabling additional compiler options if supported
|
||||||
include(CheckCXXCompilerFlag)
|
include(CheckCXXCompilerFlag)
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,6 @@ set(gameloop_source_files
|
||||||
gameloop.h
|
gameloop.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(LIBXML_INCLUDE_DIR /usr/include/libxml2)
|
|
||||||
include_directories("." ${LIBXML_INCLUDE_DIR})
|
|
||||||
|
|
||||||
|
|
||||||
add_library(gameloop STATIC ${gameloop_source_files})
|
add_library(gameloop STATIC ${gameloop_source_files})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,26 @@
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <ncurses.h>
|
#include <ncurses.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <MQTTClient.h>
|
#include <MQTTClient.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <hoel.h>
|
||||||
|
#include <jansson.h>
|
||||||
|
|
||||||
#include "gameloop.h"
|
#include "gameloop.h"
|
||||||
#include "../helper/parameters.h"
|
#include "../helper/parameters.h"
|
||||||
#include "../helper/confighelper.h"
|
#include "../helper/confighelper.h"
|
||||||
|
#include "../helper/dirhelper.h"
|
||||||
#include "../simulatorapi/simapi/simapi/simdata.h"
|
#include "../simulatorapi/simapi/simapi/simdata.h"
|
||||||
#include "../simulatorapi/simapi/simapi/simmapper.h"
|
#include "../simulatorapi/simapi/simapi/simmapper.h"
|
||||||
#include "../slog/slog.h"
|
#include "../slog/slog.h"
|
||||||
|
|
||||||
#include <json-c/json.h>
|
|
||||||
|
|
||||||
#define DEFAULT_UPDATE_RATE 100
|
#define DEFAULT_UPDATE_RATE 100
|
||||||
|
|
||||||
#define ADDRESS "tcp://localhost:1883"
|
#define ADDRESS "tcp://localhost:1883"
|
||||||
|
|
@ -125,19 +130,184 @@ void update_date()
|
||||||
sprintf(datestring, "%.24s", asctime (timeinfo));
|
sprintf(datestring, "%.24s", asctime (timeinfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
void* looper(void* thargs)
|
|
||||||
|
int mainloop(Parameters* p)
|
||||||
{
|
{
|
||||||
Parameters* p = (Parameters*) thargs;
|
pthread_t ui_thread;
|
||||||
|
pthread_t mqtt_thread;
|
||||||
|
pthread_t mysql_thread;
|
||||||
|
|
||||||
SimData* simdata = malloc(sizeof(SimData));
|
SimData* simdata = malloc(sizeof(SimData));
|
||||||
SimMap* simmap = malloc(sizeof(SimMap));
|
SimMap* simmap = malloc(sizeof(SimMap));
|
||||||
|
|
||||||
int error = siminit(simdata, simmap, 1);
|
struct termios newsettings, canonicalmode;
|
||||||
if (error != GILLES_ERROR_NONE)
|
tcgetattr(0, &canonicalmode);
|
||||||
|
newsettings = canonicalmode;
|
||||||
|
newsettings.c_lflag &= (~ICANON & ~ECHO);
|
||||||
|
newsettings.c_cc[VMIN] = 1;
|
||||||
|
newsettings.c_cc[VTIME] = 0;
|
||||||
|
tcsetattr(0, TCSANOW, &newsettings);
|
||||||
|
char ch;
|
||||||
|
struct pollfd mypoll = { STDIN_FILENO, POLLIN|POLLPRI };
|
||||||
|
|
||||||
|
p->simdata = simdata;
|
||||||
|
p->simmap = simmap;
|
||||||
|
fprintf(stdout, "Searching for sim data... Press q to quit...\n");
|
||||||
|
|
||||||
|
double update_rate = 1;
|
||||||
|
int go = true;
|
||||||
|
char lastsimstatus = false;
|
||||||
|
while (go == true)
|
||||||
{
|
{
|
||||||
slogf("Fatal error getting simulator data");
|
|
||||||
//return error;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// check for running sims
|
||||||
|
if (file_exists("/dev/shm/acpmf_physics"))
|
||||||
|
{
|
||||||
|
if (file_exists("/dev/shm/acpmf_static"))
|
||||||
|
{
|
||||||
|
p->sim = SIMULATOR_ASSETTO_CORSA;
|
||||||
|
int error = siminit(simdata, simmap, 1);
|
||||||
|
if (error == 0)
|
||||||
|
{
|
||||||
|
slogi("found Assetto Corsa, starting application...");
|
||||||
|
p->simon = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->simon == true)
|
||||||
|
{
|
||||||
|
if (p->cli == true)
|
||||||
|
{
|
||||||
|
if (pthread_create(&ui_thread, NULL, &clilooper, p) != 0)
|
||||||
|
{
|
||||||
|
printf("Uh-oh!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pthread_create(&ui_thread, NULL, &looper, p) != 0)
|
||||||
|
{
|
||||||
|
printf("Uh-oh!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//if (p->mqtt == true)
|
||||||
|
//{
|
||||||
|
// if (pthread_create(&mqtt_thread, NULL, &b4madmqtt, p) != 0)
|
||||||
|
// {
|
||||||
|
// printf("Uh-oh!\n");
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
if (p->mysql == true)
|
||||||
|
{
|
||||||
|
if (pthread_create(&mysql_thread, NULL, &simviewmysql, p) != 0)
|
||||||
|
{
|
||||||
|
printf("Uh-oh!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_join(ui_thread, NULL);
|
||||||
|
p->program_state = -1;
|
||||||
|
//if (p->mqtt == true)
|
||||||
|
//{
|
||||||
|
// pthread_join(mqtt_thread, NULL);
|
||||||
|
//}
|
||||||
|
if (p->mysql == true)
|
||||||
|
{
|
||||||
|
pthread_join(mysql_thread, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->simon == true)
|
||||||
|
{
|
||||||
|
p->simon = false;
|
||||||
|
fprintf(stdout, "Searching for sim data... Press q again to quit...\n");
|
||||||
|
sleep(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( poll(&mypoll, 1, 1000.0/update_rate) )
|
||||||
|
{
|
||||||
|
scanf("%c", &ch);
|
||||||
|
if(ch == 'q')
|
||||||
|
{
|
||||||
|
go = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
fflush(stdout);
|
||||||
|
tcsetattr(0, TCSANOW, &canonicalmode);
|
||||||
|
|
||||||
|
free(simdata);
|
||||||
|
free(simmap);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* clilooper(void* thargs)
|
||||||
|
{
|
||||||
|
Parameters* p = (Parameters*) thargs;
|
||||||
|
SimData* simdata = p->simdata;
|
||||||
|
SimMap* simmap = p->simmap;
|
||||||
|
|
||||||
|
struct termios newsettings, canonicalmode;
|
||||||
|
tcgetattr(0, &canonicalmode);
|
||||||
|
newsettings = canonicalmode;
|
||||||
|
newsettings.c_lflag &= (~ICANON & ~ECHO);
|
||||||
|
newsettings.c_cc[VMIN] = 1;
|
||||||
|
newsettings.c_cc[VTIME] = 0;
|
||||||
|
tcsetattr(0, TCSANOW, &newsettings);
|
||||||
|
char ch;
|
||||||
|
struct pollfd mypoll = { STDIN_FILENO, POLLIN|POLLPRI };
|
||||||
|
|
||||||
|
fprintf(stdout, "Press q to quit...\n");
|
||||||
|
fprintf(stdout, "Press c for a useful readout of car telemetry...\n");
|
||||||
|
fprintf(stdout, "Press s for basic sesion information...\n");
|
||||||
|
fprintf(stdout, "Press l for basic lap / stint information...\n");
|
||||||
|
|
||||||
|
double update_rate = DEFAULT_UPDATE_RATE;
|
||||||
|
int go = true;
|
||||||
|
char lastsimstatus = false;
|
||||||
|
while (go == true)
|
||||||
|
{
|
||||||
|
simdatamap(simdata, simmap, p->sim);
|
||||||
|
|
||||||
|
if( poll(&mypoll, 1, 1000.0/update_rate) )
|
||||||
|
{
|
||||||
|
scanf("%c", &ch);
|
||||||
|
if(ch == 'q')
|
||||||
|
{
|
||||||
|
go = false;
|
||||||
|
}
|
||||||
|
if(ch == 'c')
|
||||||
|
{
|
||||||
|
slogi("speed: %i gear: %i", simdata->velocity, simdata->gear);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
fflush(stdout);
|
||||||
|
tcsetattr(0, TCSANOW, &canonicalmode);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* looper(void* thargs)
|
||||||
|
{
|
||||||
|
Parameters* p = (Parameters*) thargs;
|
||||||
|
SimData* simdata = p->simdata;
|
||||||
|
SimMap* simmap = p->simmap;
|
||||||
|
|
||||||
curses_init();
|
curses_init();
|
||||||
|
|
||||||
timeout(DEFAULT_UPDATE_RATE);
|
timeout(DEFAULT_UPDATE_RATE);
|
||||||
|
|
@ -146,7 +316,7 @@ void* looper(void* thargs)
|
||||||
char lastsimstatus = false;
|
char lastsimstatus = false;
|
||||||
while (go == true)
|
while (go == true)
|
||||||
{
|
{
|
||||||
simdatamap(simdata, simmap, 1);
|
simdatamap(simdata, simmap, p->sim);
|
||||||
|
|
||||||
wclear(win1);
|
wclear(win1);
|
||||||
wclear(win2);
|
wclear(win2);
|
||||||
|
|
@ -553,159 +723,273 @@ void* looper(void* thargs)
|
||||||
delwin(win1);
|
delwin(win1);
|
||||||
endwin();
|
endwin();
|
||||||
|
|
||||||
free(simdata);
|
|
||||||
free(simmap);
|
|
||||||
|
|
||||||
//return 0;
|
//return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* b4madmqtt(void* thargs)
|
int getLastInsertID(struct _h_connection* conn)
|
||||||
|
{
|
||||||
|
json_t* last_id = (h_last_insert_id(conn));
|
||||||
|
int id = json_integer_value(last_id);
|
||||||
|
json_decref(last_id);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
int adddriver(struct _h_connection* conn, int driverid, const char* drivername)
|
||||||
|
{
|
||||||
|
if (driverid > 0)
|
||||||
|
{
|
||||||
|
return driverid;
|
||||||
|
}
|
||||||
|
json_t *root = json_object();
|
||||||
|
json_t *json_arr = json_array();
|
||||||
|
|
||||||
|
json_object_set_new( root, "table", json_string("drivers") );
|
||||||
|
json_object_set_new( root, "values", json_arr );
|
||||||
|
|
||||||
|
json_t* values = json_object();
|
||||||
|
json_object_set_new(values, "driver_name", json_string(drivername));
|
||||||
|
json_object_set_new(values, "prev_name", json_string(drivername));
|
||||||
|
json_object_set_new(values, "steam64_id", json_integer(17));
|
||||||
|
json_object_set_new(values, "country", json_string("USA"));
|
||||||
|
json_array_append(json_arr, values);
|
||||||
|
int res = h_insert(conn, root, NULL);
|
||||||
|
json_decref(root);
|
||||||
|
json_decref(values);
|
||||||
|
|
||||||
|
driverid = getLastInsertID(conn);
|
||||||
|
return driverid;
|
||||||
|
}
|
||||||
|
|
||||||
|
int addtrackconfig(struct _h_connection* conn, int trackconfigid, const char* track, int length)
|
||||||
|
{
|
||||||
|
//track_config_id | track_name | config_name | display_name | country | city | length
|
||||||
|
if (trackconfigid > 0)
|
||||||
|
{
|
||||||
|
return trackconfigid;
|
||||||
|
}
|
||||||
|
json_t *root = json_object();
|
||||||
|
json_t *json_arr = json_array();
|
||||||
|
|
||||||
|
json_object_set_new( root, "table", json_string(track) );
|
||||||
|
json_object_set_new( root, "values", json_arr );
|
||||||
|
|
||||||
|
json_t* values = json_object();
|
||||||
|
json_object_set_new(values, "track_name", json_string(track));
|
||||||
|
json_object_set_new(values, "config_name", json_string("default"));
|
||||||
|
json_object_set_new(values, "display_name", json_string(track));
|
||||||
|
json_object_set_new(values, "country", json_string("USA"));
|
||||||
|
json_object_set_new(values, "city", json_string("USA"));
|
||||||
|
json_object_set_new(values, "length", json_integer(length));
|
||||||
|
|
||||||
|
json_array_append(json_arr, values);
|
||||||
|
int res = h_insert(conn, root, NULL);
|
||||||
|
trackconfigid = getLastInsertID(conn);
|
||||||
|
json_decref(root);
|
||||||
|
json_decref(values);
|
||||||
|
|
||||||
|
return trackconfigid;
|
||||||
|
}
|
||||||
|
|
||||||
|
int addevent(struct _h_connection* conn, int track_config)
|
||||||
|
{
|
||||||
|
|
||||||
|
json_t *root = json_object();
|
||||||
|
json_t *json_arr = json_array();
|
||||||
|
|
||||||
|
json_object_set_new( root, "table", json_string("events") );
|
||||||
|
json_object_set_new( root, "values", json_arr );
|
||||||
|
|
||||||
|
json_t* values = json_object();
|
||||||
|
json_object_set_new(values, "track_config_id", json_integer(track_config));
|
||||||
|
json_object_set_new(values, "event_name", json_string("default"));
|
||||||
|
//event_id | server_name | track_config_id | event_name | team_event | active | livery_preview | use_number | practice_duration | quali_duration | race_duration | race_duration_type | race_wait_time | race_extra_laps | reverse_grid_positions
|
||||||
|
json_array_append(json_arr, values);
|
||||||
|
int res = h_insert(conn, root, NULL);
|
||||||
|
json_decref(root);
|
||||||
|
json_decref(values);
|
||||||
|
return getLastInsertID(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
int addcar(struct _h_connection* conn, int carid, const char* carname)
|
||||||
|
{
|
||||||
|
|
||||||
|
// car_id | display_name | car_name | manufacturer | car_class
|
||||||
|
|
||||||
|
if (carid > 0)
|
||||||
|
{
|
||||||
|
return carid;
|
||||||
|
}
|
||||||
|
json_t *root = json_object();
|
||||||
|
json_t *json_arr = json_array();
|
||||||
|
|
||||||
|
json_object_set_new( root, "table", json_string("cars") );
|
||||||
|
json_object_set_new( root, "values", json_arr );
|
||||||
|
|
||||||
|
json_t* values = json_object();
|
||||||
|
json_object_set_new(values, "display_name", json_string(carname));
|
||||||
|
json_object_set_new(values, "car_name", json_string(carname));
|
||||||
|
json_object_set_new(values, "manufacturer", json_string("Unknown"));
|
||||||
|
json_object_set_new(values, "car_class", json_string("Unknown"));
|
||||||
|
json_array_append(json_arr, values);
|
||||||
|
int res = h_insert(conn, root, NULL);
|
||||||
|
json_decref(root);
|
||||||
|
json_decref(values);
|
||||||
|
|
||||||
|
carid = getLastInsertID(conn);
|
||||||
|
return carid;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int gettrack(struct _h_connection* conn, const char* trackname)
|
||||||
|
{
|
||||||
|
|
||||||
|
json_t *j_result;
|
||||||
|
char* where_clause = h_build_where_clause(conn, "config_name=%s AND track_name=%s", "default", trackname);
|
||||||
|
json_t* j_query = json_pack("{sss[s]s{s{ssss}}}", "table", "track_config", "columns", "track_config_id", "where", " ", "operator", "raw",
|
||||||
|
"value", where_clause);
|
||||||
|
|
||||||
|
//char* qq;
|
||||||
|
int res = h_select(conn, j_query, &j_result, NULL);
|
||||||
|
//slogi("here your query: %s", qq);
|
||||||
|
// Deallocate j_query since it won't be needed anymore
|
||||||
|
json_decref(j_query);
|
||||||
|
h_free(where_clause);
|
||||||
|
int track_config = -1;
|
||||||
|
// Test query execution result
|
||||||
|
if (res == H_OK) {
|
||||||
|
// Print result
|
||||||
|
char* dump = json_dumps(j_result, JSON_INDENT(2));
|
||||||
|
slogi("json select result is\n%s", dump);
|
||||||
|
int index1 = json_array_size(j_result);
|
||||||
|
if (index1 == 0)
|
||||||
|
{
|
||||||
|
slogw("no config for this track");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
json_t* jj = json_array_get(j_result, index1-1);
|
||||||
|
track_config = json_integer_value(json_object_get(jj, "track_config_id"));
|
||||||
|
}
|
||||||
|
// Deallocate data result
|
||||||
|
json_decref(j_result);
|
||||||
|
free(dump);
|
||||||
|
} else {
|
||||||
|
sloge("Error executing select query: %d", res);
|
||||||
|
}
|
||||||
|
return track_config;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getdriver(struct _h_connection* conn, const char* driver_name)
|
||||||
|
{
|
||||||
|
json_t *j_result;
|
||||||
|
char* where_clause = h_build_where_clause(conn, "driver_name=%s", driver_name);
|
||||||
|
json_t* j_query = json_pack("{sss[s]s{s{ssss}}}","table", "drivers", "columns", "driver_id", "where", " ", "operator", "raw",
|
||||||
|
"value", where_clause);
|
||||||
|
|
||||||
|
slogi("Looking for driver named %s", driver_name);
|
||||||
|
//char* qq;
|
||||||
|
int res = h_select(conn, j_query, &j_result, NULL);
|
||||||
|
//slogi("here your query: %s", qq);
|
||||||
|
// Deallocate j_query since it won't be needed anymore
|
||||||
|
json_decref(j_query);
|
||||||
|
h_free(where_clause);
|
||||||
|
int driver_id = -1;
|
||||||
|
// Test query execution result
|
||||||
|
if (res == H_OK) {
|
||||||
|
// Print result
|
||||||
|
char* dump = json_dumps(j_result, JSON_INDENT(2));
|
||||||
|
slogi("json select result is\n%s", dump);
|
||||||
|
int index1 = json_array_size(j_result);
|
||||||
|
if (index1 == 0)
|
||||||
|
{
|
||||||
|
slogw("no driver by this name");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
json_t* jj = json_array_get(j_result, index1-1);
|
||||||
|
driver_id = json_integer_value(json_object_get(jj, "driver_id"));
|
||||||
|
}
|
||||||
|
// Deallocate data result
|
||||||
|
json_decref(j_result);
|
||||||
|
free(dump);
|
||||||
|
} else {
|
||||||
|
sloge("Error executing select query: %d", res);
|
||||||
|
}
|
||||||
|
return driver_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getcar(struct _h_connection* conn, const char* carname)
|
||||||
|
{
|
||||||
|
json_t *j_result;
|
||||||
|
char* where_clause = h_build_where_clause(conn, "car_name=%s", carname);
|
||||||
|
json_t* j_query = json_pack("{sss[s]s{s{ssss}}}","table", "cars", "columns", "car_id", "where", " ", "operator", "raw",
|
||||||
|
"value", where_clause);
|
||||||
|
|
||||||
|
slogi("Looking for car named %s", carname);
|
||||||
|
//char* qq;
|
||||||
|
int res = h_select(conn, j_query, &j_result, NULL);
|
||||||
|
//slogi("here your query: %s", qq);
|
||||||
|
// Deallocate j_query since it won't be needed anymore
|
||||||
|
json_decref(j_query);
|
||||||
|
h_free(where_clause);
|
||||||
|
int car_id = -1;
|
||||||
|
// Test query execution result
|
||||||
|
if (res == H_OK) {
|
||||||
|
// Print result
|
||||||
|
char* dump = json_dumps(j_result, JSON_INDENT(2));
|
||||||
|
slogi("json select result is\n%s", dump);
|
||||||
|
int index1 = json_array_size(j_result);
|
||||||
|
if (index1 == 0)
|
||||||
|
{
|
||||||
|
slogw("no car by this name");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
json_t* jj = json_array_get(j_result, index1-1);
|
||||||
|
car_id = json_integer_value(json_object_get(jj, "car_id"));
|
||||||
|
}
|
||||||
|
// Deallocate data result
|
||||||
|
json_decref(j_result);
|
||||||
|
free(dump);
|
||||||
|
} else {
|
||||||
|
sloge("Error executing select query: %d", res);
|
||||||
|
}
|
||||||
|
return car_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void* simviewmysql(void* thargs)
|
||||||
{
|
{
|
||||||
Parameters* p = (Parameters*) thargs;
|
Parameters* p = (Parameters*) thargs;
|
||||||
SimData* simdata = malloc(sizeof(SimData));
|
SimData* simdata = p->simdata;
|
||||||
SimMap* simmap = malloc(sizeof(SimMap));
|
SimMap* simmap = p->simmap;
|
||||||
long unix_time_start;
|
|
||||||
char time_buff[11];
|
|
||||||
|
|
||||||
int error = siminit(simdata, simmap, 1);
|
struct _h_result result;
|
||||||
if (error != GILLES_ERROR_NONE)
|
struct _h_connection * conn;
|
||||||
{
|
char* connectionstring = "host=zorak.brak dbname=gilles user=test password=thisisatest";
|
||||||
slogf("Fatal error getting simulator data");
|
conn = h_connect_pgsql(connectionstring);
|
||||||
//return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool mqtt = p->mqtt;
|
int trackconfig = gettrack(conn, simdata->track);
|
||||||
bool mqtt_connected = false;
|
trackconfig = addtrackconfig(conn, trackconfig, simdata->track, simdata->trackdistancearound);
|
||||||
|
int eventid = addevent(conn, trackconfig);
|
||||||
|
int driverid = getdriver(conn, simdata->driver);
|
||||||
|
driverid = adddriver(conn, driverid, simdata->driver);
|
||||||
|
int carid = getcar(conn, simdata->car);
|
||||||
|
carid = addcar(conn, carid, simdata->car);
|
||||||
|
|
||||||
MQTTClient client;
|
// sessions
|
||||||
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
|
// session_id | event_id | event_type | track_time | session_name | start_time | duration_min | elapsed_ms | laps | weather | air_temp | road_temp | start_grip | current_grip | is_finished | finish_time | last_activity | http_port
|
||||||
MQTTClient_message pubmsg = MQTTClient_message_initializer;
|
|
||||||
MQTTClient_deliveryToken token;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
// Create a new MQTT client
|
// stints
|
||||||
MQTTClient_create(&client, ADDRESS, CLIENTID,
|
// session_stint_id | driver_id | team_member_id | session_id | car_id | game_car_id | laps | valid_laps | best_lap_id | is_finished | started_at | finished_at
|
||||||
MQTTCLIENT_PERSISTENCE_NONE, NULL);
|
|
||||||
|
|
||||||
// Connect to the MQTT server
|
// stint laps
|
||||||
if (mqtt == true)
|
// stint_lap_id | stint_id | sector_1 | sector_2 | sector_3 | grip | tyre | time | cuts | crashes | car_crashes | max_speed | avg_speed | finished_at
|
||||||
{
|
|
||||||
conn_opts.keepAliveInterval = 20;
|
|
||||||
conn_opts.cleansession = 1;
|
|
||||||
if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) {
|
|
||||||
MQTTClient_disconnect(client, 10000);
|
|
||||||
sloge("Failed to connect, return code %d", rc);
|
|
||||||
return NULL;
|
|
||||||
//exit(-1);
|
|
||||||
}
|
|
||||||
mqtt_connected = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int go = false;
|
// telemetry
|
||||||
if (mqtt_connected == true)
|
// lap_id | telemetry
|
||||||
{
|
|
||||||
go = true;
|
|
||||||
}
|
|
||||||
char lastsimstatus = false;
|
|
||||||
while (go == true && p->program_state == 1)
|
|
||||||
{
|
|
||||||
|
|
||||||
char simstatus = (simdata->simstatus > 0) ? true : false;
|
|
||||||
if (simdata->simstatus > 0 && simstatus != lastsimstatus)
|
|
||||||
{
|
|
||||||
//update_date();
|
|
||||||
unix_time_start = (unsigned long) time(NULL);
|
|
||||||
sprintf(time_buff, "%lu", unix_time_start);
|
|
||||||
//sprintf(time_buff, "%lu", (unsigned long)time(NULL));
|
|
||||||
//newdatestring = removeSpacesFromStr(datestring);
|
|
||||||
}
|
|
||||||
lastsimstatus = simstatus;
|
|
||||||
simdatamap(simdata, simmap, 1);
|
|
||||||
|
|
||||||
if (mqtt_connected == true && simdata->simstatus > 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
json_object *root = json_object_new_object();
|
h_close_db(conn);
|
||||||
//if (!root)
|
h_clean_connection(conn);
|
||||||
// return;
|
|
||||||
|
|
||||||
json_object *child = json_object_new_object();
|
|
||||||
|
|
||||||
struct timeval tv;
|
|
||||||
gettimeofday(&tv, NULL);
|
|
||||||
unsigned long long millisecondsSinceEpoch = (unsigned long long)(tv.tv_sec) * 1000 + (unsigned long long)(tv.tv_usec) / 1000;
|
|
||||||
|
|
||||||
json_object_object_add(root, "time", json_object_new_int64(millisecondsSinceEpoch)); //unix time milliseconds
|
|
||||||
|
|
||||||
const char* topic_root = "racing/gilles/TuxRacerX";
|
|
||||||
//const char* game_name = "Assetto Corsa (64 bit)";
|
|
||||||
const char* game_name = "assetto_64_bit";
|
|
||||||
const char* session_type = "Practice";
|
|
||||||
|
|
||||||
json_object_object_add(child, "CarModel", json_object_new_string(simdata->car));
|
|
||||||
json_object_object_add(child, "GameName", json_object_new_string(game_name));
|
|
||||||
json_object_object_add(child, "SessionId", json_object_new_int(unix_time_start));
|
|
||||||
json_object_object_add(child, "SessionTypeName", json_object_new_string("Practice"));
|
|
||||||
json_object_object_add(child, "TrackCode", json_object_new_string(simdata->track));
|
|
||||||
|
|
||||||
json_object_object_add(child, "Clutch", json_object_new_double(simdata->clutch));
|
|
||||||
json_object_object_add(child, "Brake", json_object_new_double(simdata->brake));
|
|
||||||
json_object_object_add(child, "Throtte", json_object_new_double(simdata->gas));
|
|
||||||
json_object_object_add(child, "HandBrake", json_object_new_double(simdata->handbrake));
|
|
||||||
json_object_object_add(child, "SteeringAngle", json_object_new_double(simdata->steer));
|
|
||||||
json_object_object_add(child, "Rpms", json_object_new_int(simdata->rpms));
|
|
||||||
json_object_object_add(child, "Gear", json_object_new_int(simdata->gear));
|
|
||||||
json_object_object_add(child, "SpeedMs", json_object_new_double(simdata->velocity * 0.2777778));
|
|
||||||
json_object_object_add(child, "DistanceRoundTrack", json_object_new_double(simdata->trackdistancearound));
|
|
||||||
json_object_object_add(child, "WorldPosition_x", json_object_new_double(simdata->worldposx));
|
|
||||||
json_object_object_add(child, "WorldPosition_y", json_object_new_double(simdata->worldposy));
|
|
||||||
json_object_object_add(child, "WorldPosition_z", json_object_new_double(simdata->worldposz));
|
|
||||||
json_object_object_add(child, "CurrentLap", json_object_new_int(simdata->playerlaps));
|
|
||||||
json_object_object_add(child, "CurrentLapTime", json_object_new_int(simdata->currentlapinseconds));
|
|
||||||
json_object_object_add(child, "LapTimePrevious", json_object_new_int(simdata->lastlapinseconds));
|
|
||||||
json_object_object_add(child, "CurrentLapIsValid", json_object_new_int(simdata->lapisvalid));
|
|
||||||
json_object_object_add(child, "PreviousLapWasValid", json_object_new_int(1));
|
|
||||||
|
|
||||||
json_object_object_add(root, "telemetry", child);
|
|
||||||
|
|
||||||
slogi(json_object_to_json_string_ext(root, JSON_C_TO_STRING_PRETTY));
|
|
||||||
|
|
||||||
// TODO: generate this topic string only once
|
|
||||||
char* topic = ( char* ) malloc(1 + strlen(topic_root) + strlen("/") + strlen(game_name) + strlen("/") + strlen(session_type)
|
|
||||||
+ strlen("/") + strlen(simdata->car) + strlen("/") + strlen(simdata->track) + strlen("/") + 11);
|
|
||||||
strcpy(topic, topic_root);
|
|
||||||
strcat(topic, "/");
|
|
||||||
strcat(topic, time_buff);
|
|
||||||
strcat(topic, "/");
|
|
||||||
strcat(topic, game_name);
|
|
||||||
strcat(topic, "/");
|
|
||||||
strcat(topic, simdata->track);
|
|
||||||
strcat(topic, "/");
|
|
||||||
strcat(topic, simdata->car);
|
|
||||||
strcat(topic, "/");
|
|
||||||
strcat(topic, session_type);
|
|
||||||
|
|
||||||
char* payload1;
|
|
||||||
sprintf(payload1, json_object_to_json_string_ext(root, JSON_C_TO_STRING_PRETTY));
|
|
||||||
pubmsg.payload = payload1;
|
|
||||||
//pubmsg.payload = json_object_to_json_string_ext(root, JSON_C_TO_STRING_PRETTY);
|
|
||||||
//pubmsg.payloadlen = strlen(json_object_to_json_string_ext(root, JSON_C_TO_STRING_PRETTY));
|
|
||||||
pubmsg.payloadlen = strlen(payload1);
|
|
||||||
pubmsg.qos= QOS;
|
|
||||||
pubmsg.retained = 0;
|
|
||||||
|
|
||||||
MQTTClient_publishMessage(client, topic, &pubmsg, &token);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if (mqtt_connected == true)
|
|
||||||
{
|
|
||||||
MQTTClient_disconnect(client, 10000);
|
|
||||||
}
|
|
||||||
MQTTClient_destroy(&client);
|
|
||||||
|
|
||||||
free(simdata);
|
|
||||||
free(simmap);
|
|
||||||
return NULL;
|
|
||||||
//return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
#include "../helper/parameters.h"
|
#include "../helper/parameters.h"
|
||||||
#include "../helper/confighelper.h"
|
#include "../helper/confighelper.h"
|
||||||
|
|
||||||
|
int mainloop(Parameters* p);
|
||||||
|
void* clilooper(void* params);
|
||||||
void* looper(void* params);
|
void* looper(void* params);
|
||||||
void* b4madmqtt(void* params);
|
void* b4madmqtt(void* params);
|
||||||
|
void* simviewmysql(void* params);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
@ -5,6 +6,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <libconfig.h>
|
#include <libconfig.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <basedir_fs.h>
|
||||||
|
|
||||||
#include "gameloop/gameloop.h"
|
#include "gameloop/gameloop.h"
|
||||||
#include "helper/parameters.h"
|
#include "helper/parameters.h"
|
||||||
|
|
@ -12,7 +14,6 @@
|
||||||
#include "helper/confighelper.h"
|
#include "helper/confighelper.h"
|
||||||
#include "slog/slog.h"
|
#include "slog/slog.h"
|
||||||
|
|
||||||
|
|
||||||
int create_dir(char* dir)
|
int create_dir(char* dir)
|
||||||
{
|
{
|
||||||
struct stat st = {0};
|
struct stat st = {0};
|
||||||
|
|
@ -22,25 +23,37 @@ int create_dir(char* dir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char* create_user_dir(char* dirtype)
|
char* create_user_dir(const char* dirtype)
|
||||||
{
|
{
|
||||||
char* home_dir_str = gethome();
|
char* config_dir_str = ( char* ) malloc(1 + strlen(dirtype) + strlen("/gilles"));
|
||||||
char* config_dir_str = ( char* ) malloc(1 + strlen(home_dir_str) + strlen(dirtype) + strlen("gilles/"));
|
strcpy(config_dir_str, dirtype);
|
||||||
strcpy(config_dir_str, home_dir_str);
|
strcat(config_dir_str, "/gilles");
|
||||||
strcat(config_dir_str, dirtype);
|
|
||||||
strcat(config_dir_str, "gilles/");
|
|
||||||
|
|
||||||
create_dir(config_dir_str);
|
create_dir(config_dir_str);
|
||||||
free(config_dir_str);
|
free(config_dir_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* get_config_file(const char* confpath, xdgHandle* xdg)
|
||||||
|
{
|
||||||
|
if(strcmp(confpath, "") != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "no config path specified");
|
||||||
|
return strdup(confpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* relpath = "gilles/gilles.config";
|
||||||
|
const char* confpath1 = xdgConfigFind(relpath, xdg);
|
||||||
|
slogi("path is %s", confpath1);
|
||||||
|
return strdup(confpath1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|
||||||
Parameters* p = malloc(sizeof(Parameters));
|
Parameters* p = malloc(sizeof(Parameters));
|
||||||
GillesSettings* gs = malloc(sizeof(GillesSettings));;
|
GillesSettings* gs = malloc(sizeof(GillesSettings));;
|
||||||
|
|
||||||
ConfigError ppe = getParameters(argc, argv, p);
|
ConfigError ppe = getParameters(argc, argv, p);
|
||||||
if (ppe == E_SUCCESS_AND_EXIT)
|
if (ppe == E_SUCCESS_AND_EXIT)
|
||||||
{
|
{
|
||||||
|
|
@ -52,13 +65,9 @@ int main(int argc, char** argv)
|
||||||
char* home_dir_str = gethome();
|
char* home_dir_str = gethome();
|
||||||
create_user_dir("/.config/");
|
create_user_dir("/.config/");
|
||||||
create_user_dir("/.cache/");
|
create_user_dir("/.cache/");
|
||||||
char* config_file_str = ( char* ) malloc(1 + strlen(home_dir_str) + strlen("/.config/") + strlen("gilles/gilles.config"));
|
|
||||||
char* cache_dir_str = ( char* ) malloc(1 + strlen(home_dir_str) + strlen("/.cache/gilles/"));
|
char* cache_dir_str = ( char* ) malloc(1 + strlen(home_dir_str) + strlen("/.cache/gilles/"));
|
||||||
strcpy(config_file_str, home_dir_str);
|
|
||||||
strcat(config_file_str, "/.config/");
|
|
||||||
strcpy(cache_dir_str, home_dir_str);
|
strcpy(cache_dir_str, home_dir_str);
|
||||||
strcat(cache_dir_str, "/.cache/gilles/");
|
strcat(cache_dir_str, "/.cache/gilles/");
|
||||||
strcat(config_file_str, "gilles/gilles.config");
|
|
||||||
|
|
||||||
slog_config_t slgCfg;
|
slog_config_t slgCfg;
|
||||||
slog_config_get(&slgCfg);
|
slog_config_get(&slgCfg);
|
||||||
|
|
@ -82,39 +91,32 @@ int main(int argc, char** argv)
|
||||||
slog_disable(SLOG_DEBUG);
|
slog_disable(SLOG_DEBUG);
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_t ui_thread;
|
xdgHandle xdg;
|
||||||
pthread_t mqtt_thread;
|
if(!xdgInitHandle(&xdg))
|
||||||
|
{
|
||||||
|
slogf("Function xdgInitHandle() failed, is $HOME unset?");
|
||||||
|
}
|
||||||
|
char* config_file_str = get_config_file("/home/paul/.config/gilles/gilles.config", &xdg);
|
||||||
|
|
||||||
if (pthread_create(&ui_thread, NULL, &looper, p) != 0)
|
loadconfig(config_file_str, p);
|
||||||
{
|
//slogi("mysql user is %s", p->mysql_user);
|
||||||
printf("Uh-oh!\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (p->mqtt == true)
|
|
||||||
{
|
|
||||||
if (pthread_create(&mqtt_thread, NULL, &b4madmqtt, p) != 0)
|
|
||||||
{
|
|
||||||
printf("Uh-oh!\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_join(ui_thread, NULL);
|
|
||||||
p->program_state = -1;
|
|
||||||
if (p->mqtt == true)
|
|
||||||
{
|
|
||||||
pthread_join(mqtt_thread, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(config_file_str);
|
free(config_file_str);
|
||||||
free(cache_dir_str);
|
free(cache_dir_str);
|
||||||
|
xdgWipeHandle(&xdg);
|
||||||
|
|
||||||
|
mainloop(p);
|
||||||
|
//free(config_file_str);
|
||||||
|
//free(cache_dir_str);
|
||||||
|
//free(simmap);
|
||||||
|
//free(simdata);
|
||||||
|
|
||||||
|
|
||||||
configcleanup:
|
configcleanup:
|
||||||
//config_destroy(&cfg);
|
//config_destroy(&cfg);
|
||||||
|
|
||||||
cleanup_final:
|
cleanup_final:
|
||||||
|
freeparams(p);
|
||||||
free(gs);
|
free(gs);
|
||||||
free(p);
|
free(p);
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
|
||||||
|
|
@ -2,37 +2,70 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "confighelper.h"
|
#include "confighelper.h"
|
||||||
|
|
||||||
#include "../slog/slog.h"
|
#include "../slog/slog.h"
|
||||||
|
|
||||||
int strtogame(const char* game, GillesSettings* gs)
|
//int strtogame(const char* game, GillesSettings* gs)
|
||||||
|
//{
|
||||||
|
// slogd("Checking for %s in list of supported simulators.", game);
|
||||||
|
// if (strcmp(game, "ac") == 0)
|
||||||
|
// {
|
||||||
|
// slogd("Setting simulator to Assetto Corsa");
|
||||||
|
// gs->sim_name = SIMULATOR_ASSETTO_CORSA;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// if (strcmp(game, "test") == 0)
|
||||||
|
// {
|
||||||
|
// slogd("Setting simulator to Test Data");
|
||||||
|
// gs->sim_name = SIMULATOR_GILLES_TEST;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// slogi("%s does not appear to be a supported simulator.", game);
|
||||||
|
// return GILLES_ERROR_INVALID_SIM;
|
||||||
|
// }
|
||||||
|
// return GILLES_ERROR_NONE;
|
||||||
|
//}
|
||||||
|
|
||||||
|
int loadmysql(config_t* cfg, Parameters* p)
|
||||||
{
|
{
|
||||||
slogd("Checking for %s in list of supported simulators.", game);
|
config_setting_t* config_mysql_array = NULL;
|
||||||
if (strcmp(game, "ac") == 0)
|
config_mysql_array = config_lookup(cfg, "mysql");
|
||||||
{
|
|
||||||
slogd("Setting simulator to Assetto Corsa");
|
config_setting_t* config_mysql = NULL;
|
||||||
gs->sim_name = SIMULATOR_ASSETTO_CORSA;
|
config_mysql = config_setting_get_elem(config_mysql_array, 0);
|
||||||
|
|
||||||
|
if (config_mysql == NULL) {
|
||||||
|
slogi("found no mysql settings");
|
||||||
}
|
}
|
||||||
else
|
const char* temp;
|
||||||
if (strcmp(game, "test") == 0)
|
config_setting_lookup_string(config_mysql, "user", &temp);
|
||||||
{
|
p->mysql_user = strdup(temp);
|
||||||
slogd("Setting simulator to Test Data");
|
return 0;
|
||||||
gs->sim_name = SIMULATOR_GILLES_TEST;
|
}
|
||||||
}
|
|
||||||
else
|
int loadconfig(const char* config_file_str, Parameters* p)
|
||||||
{
|
{
|
||||||
slogi("%s does not appear to be a supported simulator.", game);
|
config_t cfg;
|
||||||
return GILLES_ERROR_INVALID_SIM;
|
config_init(&cfg);
|
||||||
}
|
if (!config_read_file(&cfg, config_file_str))
|
||||||
return GILLES_ERROR_NONE;
|
{
|
||||||
}
|
fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg));
|
||||||
|
}
|
||||||
|
else
|
||||||
int loadconfig(const char* config_file)
|
{
|
||||||
{
|
slogi("Parsing config file");
|
||||||
|
if (p->mysql == true)
|
||||||
|
{
|
||||||
|
loadmysql(&cfg, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config_destroy(&cfg);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,6 @@
|
||||||
|
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
SIMULATOR_GILLES_TEST = 0,
|
|
||||||
SIMULATOR_ASSETTO_CORSA = 1
|
|
||||||
}
|
|
||||||
Simulator;
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
SIMULATOR_UPDATE_DEFAULT = 0,
|
SIMULATOR_UPDATE_DEFAULT = 0,
|
||||||
|
|
@ -41,6 +34,8 @@ typedef struct
|
||||||
}
|
}
|
||||||
GillesSettings;
|
GillesSettings;
|
||||||
|
|
||||||
|
int loadconfig(const char* config_file_str, Parameters* p);
|
||||||
|
|
||||||
int strtogame(const char* game, GillesSettings* gs);
|
int strtogame(const char* game, GillesSettings* gs);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,23 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <dirent.h>
|
|
||||||
|
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#include <dirent.h> // for *Nix directory access
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
char* gethome()
|
char* gethome()
|
||||||
{
|
{
|
||||||
char* homedir = getenv("HOME");
|
char* homedir = getenv("HOME");
|
||||||
|
|
@ -200,3 +207,47 @@ bool does_directory_exist(char* path, char* dirname)
|
||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool file_exists(const char* file)
|
||||||
|
{
|
||||||
|
if (file == NULL) { return false; }
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
#if defined(WIN_API)
|
||||||
|
// if you want the WinAPI, versus CRT
|
||||||
|
if (strnlen(file, MAX_PATH+1) > MAX_PATH) {
|
||||||
|
// ... throw error here or ...
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
DWORD res = GetFileAttributesA(file);
|
||||||
|
return (res != INVALID_FILE_ATTRIBUTES &&
|
||||||
|
!(res & FILE_ATTRIBUTE_DIRECTORY));
|
||||||
|
#else
|
||||||
|
// Use Win CRT
|
||||||
|
struct stat fi;
|
||||||
|
if (_stat(file, &fi) == 0) {
|
||||||
|
#if defined(S_ISSOCK)
|
||||||
|
// sockets come back as a 'file' on some systems
|
||||||
|
// so make sure it's not a socket or directory
|
||||||
|
// (in other words, make sure it's an actual file)
|
||||||
|
return !(S_ISDIR(fi.st_mode)) &&
|
||||||
|
!(S_ISSOCK(fi.st_mode));
|
||||||
|
#else
|
||||||
|
return !(S_ISDIR(fi.st_mode));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
struct stat fi;
|
||||||
|
if (stat(file, &fi) == 0) {
|
||||||
|
#if defined(S_ISSOCK)
|
||||||
|
return !(S_ISDIR(fi.st_mode)) &&
|
||||||
|
!(S_ISSOCK(fi.st_mode));
|
||||||
|
#else
|
||||||
|
return !(S_ISDIR(fi.st_mode));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,5 +8,6 @@ char* str2md5(const char* str, int length);
|
||||||
bool does_directory_exist(char* path, char* dirname);
|
bool does_directory_exist(char* path, char* dirname);
|
||||||
void restrict_folders_to_cache(char* path, int cachesize);
|
void restrict_folders_to_cache(char* path, int cachesize);
|
||||||
void delete_dir(char* path);
|
void delete_dir(char* path);
|
||||||
|
bool file_exists(const char* file);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,22 @@
|
||||||
#include <argtable2.h>
|
#include <argtable2.h>
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
|
|
||||||
|
int freeparams(Parameters* p)
|
||||||
|
{
|
||||||
|
if(p->sim_string != NULL)
|
||||||
|
{
|
||||||
|
free(p->sim_string);
|
||||||
|
}
|
||||||
|
if (p->mysql == true)
|
||||||
|
{
|
||||||
|
if(p->mysql_user != NULL)
|
||||||
|
{
|
||||||
|
free(p->mysql_user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ConfigError getParameters(int argc, char** argv, Parameters* p)
|
ConfigError getParameters(int argc, char** argv, Parameters* p)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -15,21 +31,26 @@ ConfigError getParameters(int argc, char** argv, Parameters* p)
|
||||||
|
|
||||||
// set return structure defaults
|
// set return structure defaults
|
||||||
p->program_action = 0;
|
p->program_action = 0;
|
||||||
|
p->cli = false;
|
||||||
p->mqtt = false;
|
p->mqtt = false;
|
||||||
|
p->mysql = false;
|
||||||
|
p->simon = false;
|
||||||
p->verbosity_count = 0;
|
p->verbosity_count = 0;
|
||||||
|
|
||||||
// setup argument handling structures
|
// setup argument handling structures
|
||||||
const char* progname = "gilles";
|
const char* progname = "Gilles";
|
||||||
|
|
||||||
struct arg_lit* arg_verbosity = arg_litn("v","verbose", 0, 2, "increase logging verbosity");
|
struct arg_lit* arg_verbosity = arg_litn("v","verbose", 0, 2, "increase logging verbosity");
|
||||||
|
|
||||||
struct arg_rex* cmd1 = arg_rex1(NULL, NULL, "play", NULL, REG_ICASE, NULL);
|
struct arg_rex* cmd1 = arg_rex1(NULL, NULL, "play", NULL, REG_ICASE, NULL);
|
||||||
struct arg_str* arg_sim = arg_strn("s", "sim", "<gamename>", 0, 1, NULL);
|
struct arg_str* arg_sim = arg_strn("s", "sim", "<gamename>", 0, 1, NULL);
|
||||||
struct arg_lit* arg_mqtt = arg_lit0("S", NULL, "send data to local mqtt server");
|
struct arg_lit* arg_cli = arg_lit0("c", "textui", "text only ui");
|
||||||
|
struct arg_lit* arg_mqtt = arg_lit0("Q", "mqtt", "send data to local mqtt server with connection settings speciifed in config");
|
||||||
|
struct arg_lit* arg_mysql = arg_lit0("M", "mysql", "send data to local mysql server with connection settings specified in config");
|
||||||
struct arg_lit* help = arg_litn(NULL,"help", 0, 1, "print this help and exit");
|
struct arg_lit* help = arg_litn(NULL,"help", 0, 1, "print this help and exit");
|
||||||
struct arg_lit* vers = arg_litn(NULL,"version", 0, 1, "print version information and exit");
|
struct arg_lit* vers = arg_litn(NULL,"version", 0, 1, "print version information and exit");
|
||||||
struct arg_end* end = arg_end(20);
|
struct arg_end* end = arg_end(20);
|
||||||
void* argtable[] = {cmd1,arg_sim,arg_verbosity,arg_mqtt,help,vers,end};
|
void* argtable[] = {cmd1,arg_sim,arg_verbosity,arg_cli,arg_mqtt,arg_mysql,help,vers,end};
|
||||||
int nerrors;
|
int nerrors;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -45,12 +66,20 @@ ConfigError getParameters(int argc, char** argv, Parameters* p)
|
||||||
if (nerrors==0)
|
if (nerrors==0)
|
||||||
{
|
{
|
||||||
p->program_action = A_PLAY;
|
p->program_action = A_PLAY;
|
||||||
p->sim_string = arg_sim->sval[0];
|
p->sim_string = strdup(arg_sim->sval[0]);
|
||||||
p->verbosity_count = arg_verbosity->count;
|
p->verbosity_count = arg_verbosity->count;
|
||||||
|
if (arg_cli->count > 0)
|
||||||
|
{
|
||||||
|
p->cli = true;
|
||||||
|
}
|
||||||
if (arg_mqtt->count > 0)
|
if (arg_mqtt->count > 0)
|
||||||
{
|
{
|
||||||
p->mqtt = true;
|
p->mqtt = true;
|
||||||
}
|
}
|
||||||
|
if (arg_mysql->count > 0)
|
||||||
|
{
|
||||||
|
p->mysql = true;
|
||||||
|
}
|
||||||
exitcode = E_SUCCESS_AND_DO;
|
exitcode = E_SUCCESS_AND_DO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,14 +87,15 @@ ConfigError getParameters(int argc, char** argv, Parameters* p)
|
||||||
if (help->count > 0)
|
if (help->count > 0)
|
||||||
{
|
{
|
||||||
printf("Usage: %s\n", progname);
|
printf("Usage: %s\n", progname);
|
||||||
printf("\nReport bugs on the github github.com/spacefreak18/csimtelem.\n");
|
arg_print_syntax(stdout,argtable,"\n");
|
||||||
|
printf("\nReport bugs on the github github.com/spacefreak18/gilles.\n");
|
||||||
exitcode = E_SUCCESS_AND_EXIT;
|
exitcode = E_SUCCESS_AND_EXIT;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vers->count > 0)
|
if (vers->count > 0)
|
||||||
{
|
{
|
||||||
printf("%s Simulator Hardware Manager\n",progname);
|
printf("%s Simulator Monitor\n",progname);
|
||||||
printf("October 2022, Paul Dino Jones\n");
|
printf("October 2022, Paul Dino Jones\n");
|
||||||
exitcode = E_SUCCESS_AND_EXIT;
|
exitcode = E_SUCCESS_AND_EXIT;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,30 @@
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "../simulatorapi/simapi/simapi/simapi.h"
|
||||||
|
#include "../simulatorapi/simapi/simapi/simdata.h"
|
||||||
|
#include "../simulatorapi/simapi/simapi/simmapper.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
char* sim_string;
|
||||||
int program_action;
|
int program_action;
|
||||||
int program_state;
|
int program_state;
|
||||||
const char* sim_string;
|
|
||||||
bool mqtt;
|
bool cli;
|
||||||
int verbosity_count;
|
bool mqtt;
|
||||||
|
bool mysql;
|
||||||
|
bool simon;
|
||||||
|
int verbosity_count;
|
||||||
|
|
||||||
|
char* mysql_user;
|
||||||
|
char* mysql_serv;
|
||||||
|
char* mysql_dbnm;
|
||||||
|
char* mysql_pass;
|
||||||
|
|
||||||
|
Simulator sim;
|
||||||
|
SimData* simdata;
|
||||||
|
SimMap* simmap;
|
||||||
}
|
}
|
||||||
Parameters;
|
Parameters;
|
||||||
|
|
||||||
|
|
@ -28,6 +45,7 @@ typedef enum
|
||||||
ConfigError;
|
ConfigError;
|
||||||
|
|
||||||
ConfigError getParameters(int argc, char** argv, Parameters* p);
|
ConfigError getParameters(int argc, char** argv, Parameters* p);
|
||||||
|
int freeparams(Parameters* p);
|
||||||
|
|
||||||
struct _errordesc
|
struct _errordesc
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue