From 4772e759d4f275e9422f292e63a99f29c9aed913 Mon Sep 17 00:00:00 2001 From: Paul Dino Jones Date: Sat, 13 Jan 2024 17:23:18 +0000 Subject: [PATCH] Code to read in config for browse mode --- src/gilles/gameloop/CMakeLists.txt | 2 + src/gilles/gameloop/browseloop.c | 571 +++++++++++++++++++++-------- src/gilles/gameloop/browseloop.h | 2 +- src/gilles/gameloop/gameloop.c | 87 ++--- src/gilles/gameloop/session.h | 4 +- src/gilles/gilles.c | 81 ++-- src/gilles/helper/confighelper.c | 61 ++- src/gilles/helper/confighelper.h | 9 - src/gilles/helper/dirhelper.c | 110 +++--- src/gilles/helper/dirhelper.h | 7 +- src/gilles/helper/parameters.c | 34 +- src/gilles/helper/parameters.h | 23 +- 12 files changed, 649 insertions(+), 342 deletions(-) diff --git a/src/gilles/gameloop/CMakeLists.txt b/src/gilles/gameloop/CMakeLists.txt index aeb7bd9..5840683 100644 --- a/src/gilles/gameloop/CMakeLists.txt +++ b/src/gilles/gameloop/CMakeLists.txt @@ -1,6 +1,8 @@ set(gameloop_source_files gameloop.c gameloop.h + browseloop.c + browseloop.h ) diff --git a/src/gilles/gameloop/browseloop.c b/src/gilles/gameloop/browseloop.c index 14ab830..b4d8333 100644 --- a/src/gilles/gameloop/browseloop.c +++ b/src/gilles/gameloop/browseloop.c @@ -14,6 +14,8 @@ #include #include +#include + #include "session.h" #include "gameloop.h" #include "../helper/parameters.h" @@ -31,26 +33,28 @@ #define STINTS_SCREEN 2 #define LAPS_SCREEN 3 -char datestring[30]; -WINDOW* win1; -WINDOW* win2; -WINDOW* win3; -WINDOW* win4; +WINDOW* bwin1; +WINDOW* bwin2; +WINDOW* bwin3; +WINDOW* bwin4; -int winx, winy; +int bwinx, bwiny; -int win23y, win23x; +char blanks[100]; +void set_spaces(int spaces) +{ + blanks[spaces] = '\0'; +} - -void handle_winch(int sig) +void b_handle_winch(int sig) { endwin(); refresh(); clear(); - getmaxyx(stdscr, winx, winy); + getmaxyx(stdscr, bwinx, bwiny); //win23y = winy/3; //win23x = winx/3; //win1 = newwin(winx,winy,0,0); @@ -60,20 +64,21 @@ void handle_winch(int sig) refresh(); } -void rectangle(int y1, int x1, int y2, int x2) -{ - mvhline(y1, x1, 0, x2-x1); - mvhline(y2, x1, 0, x2-x1); - mvvline(y1, x1, 0, y2-y1); - mvvline(y1, x2, 0, y2-y1); - mvaddch(y1, x1, ACS_ULCORNER); - mvaddch(y2, x1, ACS_LLCORNER); - mvaddch(y1, x2, ACS_URCORNER); - mvaddch(y2, x2, ACS_LRCORNER); -} +//void rectangle(int y1, int x1, int y2, int x2) +//{ +// mvhline(y1, x1, 0, x2-x1); +// mvhline(y2, x1, 0, x2-x1); +// mvvline(y1, x1, 0, y2-y1); +// mvvline(y1, x2, 0, y2-y1); +// mvaddch(y1, x1, ACS_ULCORNER); +// mvaddch(y2, x1, ACS_LLCORNER); +// mvaddch(y1, x2, ACS_URCORNER); +// mvaddch(y2, x2, ACS_LRCORNER); +//} -int curses_init() +int b_curses_init() { + memset(blanks,' ',sizeof(blanks)); initscr(); start_color(); @@ -82,89 +87,160 @@ int curses_init() init_pair(3,COLOR_MAGENTA,0); init_pair(4,COLOR_WHITE,0); - getmaxyx(stdscr, winx, winy); - win1 = newwin(winx,winy,0,0); + getmaxyx(stdscr, bwinx, bwiny); + slogt("windowx %i, windowy %i", bwinx, bwiny); + bwin1 = newwin(bwinx,bwiny,0,0); //win23y = winy/3; //win23x = winx/3; //win2 = newwin(win23x,win23y,1,win23y-1); //win3 = newwin(win23x,win23y,1,win23y*2-1); //win4 = newwin(winx-win23x-2,winy-win23y,win23x+1,win23y-1); - wbkgd(win1,COLOR_PAIR(1)); - wbkgd(win2,COLOR_PAIR(1)); - wbkgd(win3,COLOR_PAIR(1)); - wbkgd(win4,COLOR_PAIR(1)); + wbkgd(bwin1,COLOR_PAIR(1)); + wbkgd(bwin2,COLOR_PAIR(1)); + wbkgd(bwin3,COLOR_PAIR(1)); + wbkgd(bwin4,COLOR_PAIR(1)); - signal(SIGWINCH, handle_winch); + signal(SIGWINCH, b_handle_winch); cbreak(); noecho(); - box(win1, 0, 0); - box(win2, 0, 0); - box(win3, 0, 0); - box(win4, 0, 0); + box(bwin1, 0, 0); + box(bwin2, 0, 0); + box(bwin3, 0, 0); + box(bwin4, 0, 0); } -char * removeSpacesFromStr(char *string) -{ - int non_space_count = 0; - for (int i = 0; string[i] != '\0'; i++) - { - if (string[i] != ' ') - { - string[non_space_count] = string[i]; - non_space_count++; - } - } - - string[non_space_count] = '\0'; - return string; -} - -void update_date() -{ - time_t rawtime; - struct tm * timeinfo; - time ( &rawtime ); - timeinfo = localtime ( &rawtime ); - sprintf(datestring, "%.24s", asctime (timeinfo)); -} - -void print_result(struct _h_result result) { +int telem_result(struct _h_result result, int doublefields, int intfields, int* intarrays, double* doublearrays) { int col, row, i; char buf[64]; - slogi("rows: %d, col: %d", result.nb_rows, result.nb_columns); + slogt("rows: %d, col: %d", result.nb_rows, result.nb_columns); + //int* intarrays; + int points = 0; + //int doublefields = 3; + //int intfields = 3; + //int* intarrays; + //int* doublearrays; + //int* intarrays = malloc((sizeof(int)*1736)*3); + //double* doublearrays = malloc((sizeof(double)*1736)*3); + int intarrayoffset = 0; + int doublearrayoffset = 0; + for (row = 0; rowvalue); + int cc = ((struct _h_type_int *)result.data[row][col].t_data)->value; + if (col == 1) + { + points = cc; + } break; case HOEL_COL_TYPE_DOUBLE: - printf("| %f ", ((struct _h_type_double *)result.data[row][col].t_data)->value); + //intarrays = malloc((sizeof(int)*1736)*3); break; case HOEL_COL_TYPE_TEXT: - printf("| %s ", ((struct _h_type_text *)result.data[row][col].t_data)->value); + slogi("| %s ", ((struct _h_type_text *)result.data[row][col].t_data)->value); break; case HOEL_COL_TYPE_BLOB: - for (i=0; i<((struct _h_type_blob *)result.data[row][col].t_data)->length; i++) { - printf("%c", *((char*)(((struct _h_type_blob *)result.data[row][col].t_data)->value+i))); - if (i%80 == 0 && i>0) { - printf("\n"); - } + int offset2 = 0; + + int j = 0; + i = 2; + if (col < 5) + { + while (i<((struct _h_type_blob *)result.data[row][col].t_data)->length) + { + char sss[10]; + sss[0] = '0'; + sss[1] = 'x'; + sss[2] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+2); + sss[3] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+3); + sss[4] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+4); + sss[5] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+5); + sss[6] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+6); + sss[7] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+7); + sss[8] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+8); + sss[9] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+9); + long val; + int number = (int)strtol(sss, NULL, 16); + int swapped = __bswap_32(number); + + intarrays[j+intarrayoffset] = __bswap_32(number); + offset2 = offset2 + 8; + i+=8; + j++; } + intarrayoffset += points; + } + else + { + while (i<((struct _h_type_blob *)result.data[row][col].t_data)->length) + { + char sss[18]; + sss[0] = '0'; + sss[1] = 'x'; + sss[2] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+2); + sss[3] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+3); + sss[4] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+4); + sss[5] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+5); + sss[6] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+6); + sss[7] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+7); + sss[8] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+8); + sss[9] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+9); + sss[2+8] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+2+8); + sss[3+8] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+3+8); + sss[4+8] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+4+8); + sss[5+8] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+5+8); + sss[6+8] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+6+8); + sss[7+8] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+7+8); + sss[8+8] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+8+8); + sss[9+8] = *((char*)((struct _h_type_blob *)result.data[row][col].t_data)->value+offset2+9+8); + long val; + int64_t number = (int64_t) strtoll(sss, NULL, 16); + int64_t swapped = __bswap_64(number); + double d = *((double*)&swapped); + doublearrays[j+doublearrayoffset] = (double) d; + offset2 = offset2 + 16; + i+=16; + j++; + } + doublearrayoffset += points; + + } + //snprintf( "blob value: %.*s", ((struct _h_type_blob *)result.data[row][col].t_data)->length, ((struct _h_type_blob *)result.data[row][col].t_data)->value); + //char* b = malloc(sizeof(int)*1736); + //for (i=0; i<((struct _h_type_blob *)result.data[row][col].t_data)->length; i++) { + // //slogi("%c", *((char*)(((struct _h_type_blob *)result.data[row][col].t_data)->value+i))); + // memcpy(&b[i], ((struct _h_type_blob *)result.data[row][col].t_data)->value+1*sizeof(char), sizeof(char)); + //} +// FILE *out = fopen("memory.bin", "wb"); +// if(out != NULL) +// { +// size_t to_go = sizeof(int)*1736; +// while(to_go > 0) +// { +// const size_t wrote = fwrite(b, to_go, 1, out); +// if(wrote == 0) +// break; +// to_go -= wrote; +// } +// fclose(out); +// } break; case HOEL_COL_TYPE_DATE: strftime(buf, 64, "%Y-%m-%d %H:%M:%S", &((struct _h_type_datetime *)result.data[row][col].t_data)->value); printf("| %s ", buf); case HOEL_COL_TYPE_NULL: - printf("| [null] "); + slogi("| [null] "); break; } } printf("|\n"); } + + return points; } void get_row_results(struct _h_result result, DBField* fields, void* rows, size_t rowsize) { @@ -214,7 +290,7 @@ void get_row_results(struct _h_result result, DBField* fields, void* rows, size_ } -int getsessions(struct _h_connection* conn, const char* sessionname, SessionDbo* sess) +int getsessions(struct _h_connection* conn, int* err, const char* sessionname, SessionDbo* sess) { struct _h_result result; struct _h_data * data; @@ -222,14 +298,19 @@ int getsessions(struct _h_connection* conn, const char* sessionname, SessionDbo* slogt("Performing query"); //sprintf(query, "select session_id, event_id, event_type, duration_min, elapsed_ms, laps, air_temp, road_temp, start_grip, current_grip, is_finished, http_port from %s", "Sessions"); - sprintf(query, "select session_id, event_id, event_type, laps FROM %s", "Sessions"); + sprintf(query, "select session_id, event_id, event_type, laps FROM %s ORDER BY session_id DESC LIMIT 25", "Sessions"); if (h_query_select(conn, query, &result) == H_OK) { sess->rows = malloc(sizeof(SessionRowData) * result.nb_rows); get_row_results(result, sess->fields, sess->rows, sizeof(SessionRowData)); //get_session_result(result, sess); h_clean_result(&result); - } else { + } + else + { printf("Error executing query\n"); + *err = E_DB_QUERY_FAIL;; + free(query); + return 0; } free(query); @@ -245,6 +326,7 @@ int getstints(struct _h_connection* conn, const char* sessionname, StintDbo* sti sprintf(query, "select stint_id, driver_id, team_member_id, session_id, car_id, game_car_id, laps, valid_laps, best_lap_id FROM %s WHERE session_id=%i", "Stints", use_id); + slogt("execute query %s", query); if (h_query_select(conn, query, &result) == H_OK) { stint->rows = malloc(sizeof(StintRowData) * result.nb_rows); get_row_results(result, stint->fields, stint->rows, sizeof(StintRowData)); @@ -266,10 +348,11 @@ int getlaps(struct _h_connection* conn, const char* sessionname, LapDbo* laps, i slogt("Performing query laps"); - sprintf(query, "select * FROM %s WHERE stint_id=%i", "Laps", use_id); + sprintf(query, "select * FROM %s WHERE %s=%i", "Laps", "stint_id", use_id); if (h_query_select(conn, query, &result) == H_OK) { laps->rows = malloc(sizeof(LapRowData) * result.nb_rows); get_row_results(result, laps->fields, laps->rows, sizeof(LapRowData)); + //print_result(result); //get_stint_result(result, stint); h_clean_result(&result); } else { @@ -280,6 +363,89 @@ int getlaps(struct _h_connection* conn, const char* sessionname, LapDbo* laps, i return result.nb_rows; } +int dumptelemetrytofile(struct _h_connection* conn, char* datadir, int lap1id, int lap2id) +{ + + slogt("dumping telemetry to temp file"); + + int points = 0; + int intfields = 3; + int doublefields = 3; + + struct _h_result result; + struct _h_data *data; + char* query = malloc(150 * sizeof(char)); + sprintf(query, "SELECT lap_id, points FROM %s WHERE %s=%i", "telemetry", "lap_id", lap1id); + if (h_query_select(conn, query, &result) == H_OK) { + //laps->rows = malloc(sizeof(LapRowData) * result.nb_rows); + //get_row_results(result, laps->fields, laps->rows, sizeof(LapRowData)); + points = telem_result(result, 3, 3, NULL, NULL); + //get_stint_result(result, stint); + h_clean_result(&result); + } else { + printf("Error executing query\n"); + } + free(query); + + + int* intarrays1 = malloc((sizeof(int))*points*intfields); + double* doublearrays1 = malloc((sizeof(double))*points*doublefields); + int* intarrays2 = malloc((sizeof(int))*points*intfields); + double* doublearrays2 = malloc((sizeof(double))*points*doublefields); + + struct _h_result result1; + struct _h_data * data1; + char* query1 = malloc(150 * sizeof(char)); + sprintf(query1, "SELECT lap_id, points, speed, gear, rpms, brake, accel, steer FROM %s WHERE %s=%i", "telemetry", "lap_id", lap1id); + if (h_query_select(conn, query1, &result1) == H_OK) { + //laps->rows = malloc(sizeof(LapRowData) * result.nb_rows); + //get_row_results(result, laps->fields, laps->rows, sizeof(LapRowData)); + points = telem_result(result1, intfields, doublefields, intarrays1, doublearrays1); + //get_stint_result(result, stint); + h_clean_result(&result1); + } else { + printf("Error executing query\n"); + } + free(query1); + + struct _h_result result2; + struct _h_data * data2; + char* query2 = malloc(150 * sizeof(char)); + sprintf(query2, "SELECT lap_id, points, speed, gear, rpms, brake, accel, steer FROM %s WHERE %s=%i", "telemetry", "lap_id", lap2id); + if (h_query_select(conn, query2, &result2) == H_OK) { + //laps->rows = malloc(sizeof(LapRowData) * result.nb_rows); + //get_row_results(result, laps->fields, laps->rows, sizeof(LapRowData)); + points = telem_result(result2, intfields, doublefields, intarrays2, doublearrays2); + //get_stint_result(result, stint); + h_clean_result(&result2); + } else { + printf("Error executing query\n"); + } + free(query2); + + char* filename1= "data.out"; + size_t strsize = strlen(datadir) + strlen(filename1) + 1; + char* datafile = malloc(strsize); + + snprintf(datafile, strsize, "%s%s", datadir, filename1); + slogt("dumping %i points to file %s", points, datafile); + FILE *out = fopen(datafile, "w"); + fprintf(out, "%s %s %s %s %s %s %s %s %s %s %s %s %s\n", "point", "speed1", "gear1", "rpms1", "brake1", "accel1", "steer1", "speed2", "gear2", "rpms2", "brake2", "accel2", "steer2" ); + for (int i=0; idb_conn); + + if (conn == NULL) + { + slogf("Unable to connect to configured Gilles database. Are the parameters in the config correct? Is the user allowed to access from this address?"); + p->err = E_FAILED_DB_CONN; + return 0; + } slogt("Starting analyzer"); - curses_init(); + b_curses_init(); timeout(DEFAULT_UPDATE_RATE); @@ -459,6 +631,30 @@ void* browseloop(Parameters* p) DBField avgspeed; avgspeed.type = HOEL_COL_TYPE_INT; avgspeed.offset = offsetof(LapRowData, avg_speed); + DBField f_tyre_temp; + f_tyre_temp.type = HOEL_COL_TYPE_DOUBLE; + f_tyre_temp.offset = offsetof(LapRowData, f_tyre_temp); + DBField r_tyre_temp; + r_tyre_temp.type = HOEL_COL_TYPE_DOUBLE; + r_tyre_temp.offset = offsetof(LapRowData, r_tyre_temp); + DBField f_tyre_wear; + f_tyre_wear.type = HOEL_COL_TYPE_DOUBLE; + f_tyre_wear.offset = offsetof(LapRowData, f_tyre_wear); + DBField r_tyre_wear; + r_tyre_wear.type = HOEL_COL_TYPE_DOUBLE; + r_tyre_wear.offset = offsetof(LapRowData, r_tyre_wear); + DBField f_tyre_press; + f_tyre_press.type = HOEL_COL_TYPE_DOUBLE; + f_tyre_press.offset = offsetof(LapRowData, f_tyre_press); + DBField r_tyre_press; + r_tyre_press.type = HOEL_COL_TYPE_DOUBLE; + r_tyre_press.offset = offsetof(LapRowData, r_tyre_press); + DBField f_brake_temp; + f_brake_temp.type = HOEL_COL_TYPE_DOUBLE; + f_brake_temp.offset = offsetof(LapRowData, f_brake_temp); + DBField r_brake_temp; + r_brake_temp.type = HOEL_COL_TYPE_DOUBLE; + r_brake_temp.offset = offsetof(LapRowData, r_brake_temp); DBField lapsdbfinishedat; lapsdbfinishedat.type = HOEL_COL_TYPE_DATE; lapsdbfinishedat.offset = offsetof(LapRowData, finished_at); @@ -477,6 +673,14 @@ void* browseloop(Parameters* p) lapsdb.fields[10] = maxspeed; lapsdb.fields[11] = avgspeed; lapsdb.fields[12] = lapsdbfinishedat; + lapsdb.fields[13] = f_tyre_temp; + lapsdb.fields[14] = r_tyre_temp; + lapsdb.fields[15] = f_tyre_wear; + lapsdb.fields[16] = r_tyre_wear; + lapsdb.fields[17] = f_tyre_press; + lapsdb.fields[18] = r_tyre_press; + lapsdb.fields[19] = f_brake_temp; + lapsdb.fields[20] = r_brake_temp; //slogt("sessions has %i rows", sess.numrows); @@ -488,9 +692,10 @@ void* browseloop(Parameters* p) int screen = SESSIONS_SCREEN; char ch; - box(win1, 0, 0); - wrefresh(win1); - int useid = 0; + box(bwin1, 0, 0); + wrefresh(bwin1); + int stint_useid = 0; + int lap_useid = 0; while (go == true) { @@ -503,30 +708,38 @@ void* browseloop(Parameters* p) if (action == 2) { slogt("going to perform an action"); - sessions = getsessions(conn, "Sessions", &sess); - curresults = sessions; + int err = 0; + sessions = getsessions(conn, &err, "Sessions", &sess); + if (err != E_NO_ERROR) + { + go = false; + } + else + { + curresults = sessions; + } } if (action == 3) { slogt("going to perform an action"); - stintsid = getstints(conn, "Stints", &stints, useid); + stintsid = getstints(conn, "Stints", &stints, stint_useid); curresults = stintsid; } if (action == 4) { slogt("going to perform an action"); - lapsresults = getlaps(conn, "laps", &lapsdb, useid); + lapsresults = getlaps(conn, "laps", &lapsdb, lap_useid); curresults = lapsresults; } if (action > 0) { - wclear(win1); + wclear(bwin1); - wprintw(win1, "\n"); + wprintw(bwin1, "\n"); switch(screen) { case SESSIONS_SCREEN: for(int i=0; i 0 && selection2 > 0) + { + dumptelemetrytofile(conn, datadir, selection1, selection2); + + slogt("finished dumping data"); + size_t strsize = strlen(datadir) + strlen(p->gnuplot_file) + 1; + char* plotfile = malloc(strsize); + snprintf(plotfile, strsize, "%s%s", datadir, p->gnuplot_file); + static char* argv1[]={"gnuplot", "-p", "plotfile.gp", NULL}; + argv1[2] = plotfile; + slogi("Using gnu plot file %s", plotfile); + if(!fork()) + { + execv("/usr/bin/gnuplot", argv1); + } + //wait(NULL); + } + action = 4; + } if (ch == 'B') { selection++; @@ -828,12 +1095,12 @@ void* browseloop(Parameters* p) } if (ch == '1') { - selection1 = selection; + selection1 = lapsdb.rows[selection-1].lap_id; action = 1; } if (ch == '2') { - selection2 = selection; + selection2 = lapsdb.rows[selection-1].lap_id; action = 1; } @@ -841,20 +1108,20 @@ void* browseloop(Parameters* p) } - wrefresh(win4); - delwin(win4); + wrefresh(bwin4); + delwin(bwin4); endwin(); - wrefresh(win3); - delwin(win3); + wrefresh(bwin3); + delwin(bwin3); endwin(); - wrefresh(win2); - delwin(win2); + wrefresh(bwin2); + delwin(bwin2); endwin(); - wrefresh(win1); - delwin(win1); + wrefresh(bwin1); + delwin(bwin1); endwin(); h_close_db(conn); diff --git a/src/gilles/gameloop/browseloop.h b/src/gilles/gameloop/browseloop.h index 6439d79..6d95661 100644 --- a/src/gilles/gameloop/browseloop.h +++ b/src/gilles/gameloop/browseloop.h @@ -1,4 +1,4 @@ #include "../helper/parameters.h" #include "../helper/confighelper.h" -int browseloop(Parameters* p); +int browseloop(Parameters* p, char* datadir); diff --git a/src/gilles/gameloop/gameloop.c b/src/gilles/gameloop/gameloop.c index 703c431..c9cd427 100644 --- a/src/gilles/gameloop/gameloop.c +++ b/src/gilles/gameloop/gameloop.c @@ -308,7 +308,7 @@ void* looper(void* thargs) int go = true; char lastsimstatus = false; - while (go == true) + while (go == true && simdata->simstatus > 1) { simdatamap(simdata, simmap, p->sim); @@ -907,7 +907,7 @@ int closestint(struct _h_connection* conn, int stintid, int stintlaps, int valid return res1; } -int closelap(struct _h_connection* conn, int lapid, int sector1, int sector2, int sector3, int cuts, int crashes, int maxspeed, int avgspeed, +int closelapquery(struct _h_connection* conn, int lapid, int sector1, int sector2, int sector3, int cuts, int crashes, int maxspeed, int avgspeed, double fbraketemp, double rbraketemp, double ftyrewear, double rtyrewear, double ftyretemp, double rtyretemp, double ftyrepress, double rtyrepress) { @@ -932,6 +932,20 @@ int closelap(struct _h_connection* conn, int lapid, int sector1, int sector2, in return res1; } +int closelap(struct _h_connection* conn, SimData* simdata, int lapid, int sector1, int sector2, int sector3, int cuts, int crashes, int maxspeed, int avgspeed) +{ + double fbraketemp = (simdata->braketemp[0] + simdata->braketemp[1])/2; + double rbraketemp = (simdata->braketemp[2] + simdata->braketemp[3])/2; + double ftyrewear = (simdata->tyrewear[0] + simdata->tyrewear[1])/2; + double rtyrewear = (simdata->tyrewear[2] + simdata->tyrewear[3])/2; + double ftyretemp = (simdata->tyretemp[0] + simdata->tyretemp[1])/2; + double rtyretemp = (simdata->tyretemp[2] + simdata->tyretemp[3])/2; + double ftyrepress = (simdata->tyrepressure[0] + simdata->tyrepressure[1])/2; + double rtyrepress = (simdata->tyrepressure[2] + simdata->tyrepressure[3])/2; + + closelapquery(conn, lapid, sector1, sector2, sector3, 0, 0, 0, 0, fbraketemp, rbraketemp, ftyrewear, rtyrewear, ftyretemp, rtyretemp, ftyrepress, rtyrepress); + +} int addstintlap(struct _h_connection* conn, int stintid) { @@ -1162,6 +1176,20 @@ void print_bytes(void *ptr, int size) } +int updatetelemetrydata(struct _h_connection* conn, int tracksamples, int telemid, int lapid, + int* speeddata, int* rpmdata, int* geardata, + double* steerdata, double* acceldata, double* brakedata) +{ + int b = 0; + b = updatetelemetry(conn, telemid, tracksamples*sizeof(double), "steer", steerdata); + b = updatetelemetry(conn, telemid, tracksamples*sizeof(double), "accel", acceldata); + b = updatetelemetry(conn, telemid, tracksamples*sizeof(double), "brake", brakedata); + b = updatetelemetry(conn, telemid, tracksamples*sizeof(int), "rpms", rpmdata); + b = updatetelemetry(conn, telemid, tracksamples*sizeof(int), "gear", geardata); + b = updatetelemetry(conn, telemid, tracksamples*sizeof(int), "speed", speeddata); + + return b; +} void* simviewmysql(void* thargs) { @@ -1171,7 +1199,7 @@ void* simviewmysql(void* thargs) struct _h_result result; struct _h_connection * conn; - char* connectionstring = "host=zorak.brak dbname=gilles user=test password=thisisatest"; + char* connectionstring = "host=zorak.brak dbname=gilles user=gilles password=MyRandomPasswordIsGood"; conn = h_connect_pgsql(connectionstring); @@ -1214,7 +1242,7 @@ void* simviewmysql(void* thargs) int track_samples = simdata->trackspline / TRACK_SAMPLE_RATE; slogt("track samples %i", track_samples); - int stintlaps = 0; + int stintlaps = 1; int validstintlaps = 0; bool validind = true; @@ -1225,18 +1253,6 @@ void* simviewmysql(void* thargs) double* acceldata = malloc(track_samples * sizeof(simdata->gas)); double* brakedata = malloc(track_samples * sizeof(simdata->brake)); - //double* tyretemp0 = malloc(track_samples * sizeof(simdata->tyretemp[0])); - //double* tyretemp1 = malloc(track_samples * sizeof(simdata->tyretemp[0])); - //double* tyretemp2 = malloc(track_samples * sizeof(simdata->tyretemp[0])); - //double* tyretemp3 = malloc(track_samples * sizeof(simdata->tyretemp[0])); - //double* tyrepressure0 = malloc(track_samples * sizeof(simdata->tyrepressure[0])); - //double* tyrepressure1 = malloc(track_samples * sizeof(simdata->tyrepressure[0])); - //double* tyrepressure2 = malloc(track_samples * sizeof(simdata->tyrepressure[0])); - //double* tyrepressure3 = malloc(track_samples * sizeof(simdata->tyrepressure[0])); - //double* braketemp0 = malloc(track_samples * sizeof(simdata->braketemp[0])); - //double* braketemp1 = malloc(track_samples * sizeof(simdata->braketemp[0])); - //double* braketemp2 = malloc(track_samples * sizeof(simdata->braketemp[0])); - //double* braketemp3 = malloc(track_samples * sizeof(simdata->braketemp[0])); int sectortimes[4]; if (p->program_state < 0) @@ -1259,19 +1275,6 @@ void* simviewmysql(void* thargs) geardata[pos] = simdata->gear; - //tyretemp0[pos] = simdata->tyretemp[0]; - //tyretemp1[pos] = simdata->tyretemp[1]; - //tyretemp2[pos] = simdata->tyretemp[2]; - //tyretemp3[pos] = simdata->tyretemp[3]; - //tyrepressure0[pos] = simdata->tyrepressure[0]; - //tyrepressure1[pos] = simdata->tyrepressure[1]; - //tyrepressure2[pos] = simdata->tyrepressure[2]; - //tyrepressure3[pos] = simdata->tyrepressure[3]; - //braketemp0[pos] = simdata->braketemp[0]; - //braketemp1[pos] = simdata->braketemp[1]; - //braketemp2[pos] = simdata->braketemp[2]; - //braketemp3[pos] = simdata->braketemp[3]; - sessionstatus = simdata->session; @@ -1292,7 +1295,7 @@ void* simviewmysql(void* thargs) } //pitstatus = 1; - stintlaps = 0; + stintlaps = 1; validstintlaps = 0; } pitstatus = simdata->inpit; @@ -1306,7 +1309,7 @@ void* simviewmysql(void* thargs) closestint(conn, stintid, stintlaps, validstintlaps); stintid = addstint(conn, sessionid, driverid, carid); - stintlaps = 0; + stintlaps = 1; validstintlaps = 0; } if (lap != lastlap) @@ -1318,26 +1321,11 @@ void* simviewmysql(void* thargs) validstintlaps++; } - double fbraketemp = (simdata->braketemp[0] + simdata->braketemp[1])/2; - double rbraketemp = (simdata->braketemp[2] + simdata->braketemp[3])/2; - double ftyrewear = (simdata->tyrewear[0] + simdata->tyrewear[1])/2; - double rtyrewear = (simdata->tyrewear[2] + simdata->tyrewear[3])/2; - double ftyretemp = (simdata->tyretemp[0] + simdata->tyretemp[1])/2; - double rtyretemp = (simdata->tyretemp[2] + simdata->tyretemp[3])/2; - double ftyrepress = (simdata->tyrepressure[0] + simdata->tyrepressure[1])/2; - double rtyrepress = (simdata->tyrepressure[2] + simdata->tyrepressure[3])/2; - - closelap(conn, stintlapid, sectortimes[1], sectortimes[2], simdata->lastsectorinms, 0, 0, 0, 0, fbraketemp, rbraketemp, ftyrewear, rtyrewear, ftyretemp, rtyretemp, ftyrepress, rtyrepress); + closelap(conn, simdata, stintlapid, sectortimes[1], sectortimes[2], simdata->lastsectorinms, 0, 0, 0, 0); stintlapid = addstintlap(conn, stintid); int telemid = addtelemetry(conn, track_samples, stintlapid); - int b = updatetelemetry(conn, telemid, track_samples*sizeof(double), "steer", steerdata); - b = updatetelemetry(conn, telemid, track_samples*sizeof(double), "accel", acceldata); - b = updatetelemetry(conn, telemid, track_samples*sizeof(double), "brake", brakedata); - b = updatetelemetry(conn, telemid, track_samples*sizeof(int), "rpms", rpmdata); - b = updatetelemetry(conn, telemid, track_samples*sizeof(int), "gear", geardata); - b = updatetelemetry(conn, telemid, track_samples*sizeof(int), "speed", speeddata); - + int b = updatetelemetrydata(conn, track_samples, telemid, stintlapid, speeddata, geardata, rpmdata, steerdata, acceldata, brakedata); tick = 0; // assume lap is valid until it isn't validind = true; @@ -1354,6 +1342,9 @@ void* simviewmysql(void* thargs) if (p->program_state < 0) { + int telemid = addtelemetry(conn, track_samples, stintlapid); + int b = updatetelemetrydata(conn, track_samples, telemid, stintlapid, speeddata, geardata, rpmdata, steerdata, acceldata, brakedata); + closelap(conn, simdata, stintlapid, sectortimes[1], sectortimes[2], simdata->lastsectorinms, 0, 0, 0, 0); closestint(conn, stintid, stintlaps, validstintlaps); closesession(conn, sessionid); go = false; diff --git a/src/gilles/gameloop/session.h b/src/gilles/gameloop/session.h index f9779a7..562ca83 100644 --- a/src/gilles/gameloop/session.h +++ b/src/gilles/gameloop/session.h @@ -10,7 +10,7 @@ typedef struct DBField DBField; typedef struct SessionFieldsData SessionFieldsData; typedef struct SessionFields SessionFields; typedef struct Session Session; -typedef unsigned char PDBTimeStamp[26]; +typedef unsigned char PDBTimeStamp[27]; struct DBField { @@ -85,6 +85,7 @@ typedef struct LapRowData int crashes; int max_speed; int avg_speed; + PDBTimeStamp finished_at; double f_tyre_temp; double r_tyre_temp; double f_tyre_wear; @@ -93,7 +94,6 @@ typedef struct LapRowData double r_tyre_press; double f_brake_temp; double r_brake_temp; - PDBTimeStamp finished_at; } LapRowData; diff --git a/src/gilles/gilles.c b/src/gilles/gilles.c index f784bcd..8a17f60 100644 --- a/src/gilles/gilles.c +++ b/src/gilles/gilles.c @@ -9,45 +9,13 @@ #include #include "gameloop/gameloop.h" +#include "gameloop/browseloop.h" #include "helper/parameters.h" #include "helper/dirhelper.h" #include "helper/confighelper.h" #include "slog/slog.h" -int create_dir(char* dir) -{ - struct stat st = {0}; - if (stat(dir, &st) == -1) - { - mkdir(dir, 0700); - } -} - -char* create_user_dir(const char* dirtype) -{ - char* config_dir_str = ( char* ) malloc(1 + strlen(dirtype) + strlen("/gilles")); - strcpy(config_dir_str, dirtype); - strcat(config_dir_str, "/gilles"); - - create_dir(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); -} - - +#define PROGRAM_NAME "gilles" int main(int argc, char** argv) { @@ -63,18 +31,15 @@ int main(int argc, char** argv) p->program_state = 1; char* home_dir_str = gethome(); - create_user_dir("/.config/"); - create_user_dir("/.cache/"); - char* cache_dir_str = ( char* ) malloc(1 + strlen(home_dir_str) + strlen("/.cache/gilles/")); - strcpy(cache_dir_str, home_dir_str); - strcat(cache_dir_str, "/.cache/gilles/"); + + char* cachedir = create_user_dir(home_dir_str, ".cache", PROGRAM_NAME); slog_config_t slgCfg; slog_config_get(&slgCfg); slgCfg.eColorFormat = SLOG_COLORING_TAG; slgCfg.eDateControl = SLOG_TIME_ONLY; strcpy(slgCfg.sFileName, "gilles.log"); - strcpy(slgCfg.sFilePath, cache_dir_str); + strcpy(slgCfg.sFilePath, cachedir); slgCfg.nTraceTid = 0; slgCfg.nToScreen = 1; slgCfg.nUseHeap = 0; @@ -91,25 +56,37 @@ int main(int argc, char** argv) slog_disable(SLOG_DEBUG); } + char* configdir = create_user_dir(home_dir_str, ".config", PROGRAM_NAME); + char* datadir = create_user_dir(home_dir_str, ".local/share", PROGRAM_NAME); + + xdgHandle xdg; if(!xdgInitHandle(&xdg)) { slogf("Function xdgInitHandle() failed, is $HOME unset?"); } - char* config_file_str = get_config_file("/home/paul/.config/gilles/gilles.config", &xdg); - loadconfig(config_file_str, p); - //slogi("mysql user is %s", p->mysql_user); + char* config_file_str = get_config_file(p->config_path, &xdg); + int err = loadconfig(config_file_str, p); free(config_file_str); - free(cache_dir_str); xdgWipeHandle(&xdg); - mainloop(p); - //free(config_file_str); - //free(cache_dir_str); - //free(simmap); - //free(simdata); + if (err == E_NO_ERROR) + { + if (p->program_action == A_PLAY) + { + mainloop(p); + } + else + { + browseloop(p, datadir); + } + if (p->err != E_NO_ERROR) + { + sloge("Error occured during execution."); + } + } configcleanup: @@ -119,7 +96,11 @@ cleanup_final: freeparams(p); free(gs); free(p); + + free(configdir); + free(datadir); + free(cachedir); + exit(0); } - diff --git a/src/gilles/helper/confighelper.c b/src/gilles/helper/confighelper.c index 6cab60d..c2e944a 100644 --- a/src/gilles/helper/confighelper.c +++ b/src/gilles/helper/confighelper.c @@ -7,6 +7,7 @@ #include "confighelper.h" #include "../slog/slog.h" +#include "parameters.h" //int strtogame(const char* game, GillesSettings* gs) //{ @@ -30,21 +31,34 @@ // return GILLES_ERROR_NONE; //} -int loadmysql(config_t* cfg, Parameters* p) +int loaddbconfig(config_t* cfg, Parameters* p) { - config_setting_t* config_mysql_array = NULL; - config_mysql_array = config_lookup(cfg, "mysql"); + config_setting_t* config_db_array = NULL; + config_db_array = config_lookup(cfg, "db"); - config_setting_t* config_mysql = NULL; - config_mysql = config_setting_get_elem(config_mysql_array, 0); + config_setting_t* config_db = NULL; + config_db = config_setting_get_elem(config_db_array, 0); - if (config_mysql == NULL) { - slogi("found no mysql settings"); + if (config_db == NULL) { + slogi("found no db settings"); + return E_BAD_CONFIG; } const char* temp; - config_setting_lookup_string(config_mysql, "user", &temp); - p->mysql_user = strdup(temp); - return 0; + config_setting_lookup_string(config_db, "user", &temp); + p->db_user = strdup(temp); + config_setting_lookup_string(config_db, "password", &temp); + p->db_pass = strdup(temp); + config_setting_lookup_string(config_db, "server", &temp); + p->db_serv = strdup(temp); + config_setting_lookup_string(config_db, "database", &temp); + p->db_dbnm = strdup(temp); + + size_t strsize = strlen(p->db_user) + strlen(p->db_pass) + strlen(p->db_serv) + strlen(p->db_dbnm) + 29 + 1; + p->db_conn = malloc(strsize); + + snprintf(p->db_conn, strsize, "host=%s dbname=%s user=%s password=%s", p->db_serv, p->db_dbnm, p->db_user, p->db_pass); + + return E_NO_ERROR; } int loadconfig(const char* config_file_str, Parameters* p) @@ -58,9 +72,32 @@ int loadconfig(const char* config_file_str, Parameters* p) else { slogi("Parsing config file"); - if (p->mysql == true) + + if (p->program_action == A_BROWSE) { - loadmysql(&cfg, p); + config_setting_t* config_graph_array = NULL; + config_graph_array = config_lookup(&cfg, "graph"); + + config_setting_t* config_graph = NULL; + config_graph = config_setting_get_elem(config_graph_array, 0); + + if (config_graph == NULL) { + slogi("found no graph settings"); + return E_BAD_CONFIG; + } + const char* temp; + config_setting_lookup_string(config_graph, "gnuplotfile", &temp); + p->gnuplot_file = strdup(temp); + slogi("set gnuplot config file %s", p->gnuplot_file); + } + + if (p->mysql == true || p->program_action == A_BROWSE) + { + int err = loaddbconfig(&cfg, p); + if (err != E_NO_ERROR) + { + return err; + } } } diff --git a/src/gilles/helper/confighelper.h b/src/gilles/helper/confighelper.h index a76ff7c..632342f 100644 --- a/src/gilles/helper/confighelper.h +++ b/src/gilles/helper/confighelper.h @@ -18,15 +18,6 @@ typedef enum } SimulatorUpdate; -typedef enum -{ - GILLES_ERROR_NONE = 0, - GILLES_ERROR_UNKNOWN = 1, - GILLES_ERROR_INVALID_SIM = 2, - GILLES_ERROR_NODATA = 4, -} -GillesError; - typedef struct { ProgramAction program_action; diff --git a/src/gilles/helper/dirhelper.c b/src/gilles/helper/dirhelper.c index 93faec1..ebf8b9a 100644 --- a/src/gilles/helper/dirhelper.c +++ b/src/gilles/helper/dirhelper.c @@ -3,22 +3,72 @@ #include #include #include +#include + #include +#include +#include +#include #include + #include -#include -#include -#if defined(OS_WIN) - #include -#else - #include // for *Nix directory access - #include -#endif + +#include "../slog/slog.h" +#define CONFIG_FILE "gilles/gilles.config" + +void create_dir(char* dir) +{ + struct stat st = {0}; + if (stat(dir, &st) == -1) + { + mkdir(dir, 0700); + } +} + +char* create_user_dir(char* home_dir_str, const char* dirtype, const char* programname) +{ + // +3 for slashes + size_t ss = (4 + strlen(home_dir_str) + strlen(dirtype) + strlen(programname)); + char* config_dir_str = malloc(ss); + + snprintf (config_dir_str, ss, "%s/%s/%s/", home_dir_str, dirtype, programname); + + slogt("creating dir for %s if necessary", config_dir_str); + create_dir(config_dir_str); + return config_dir_str; +} + + +char* get_config_file(const char* confpath, xdgHandle* xdg) +{ + if ((confpath != NULL) && (strcmp(confpath, "") != 0)) + { + slogw("Using custom config path %s", confpath); + return strdup(confpath); + } + + const char* relpath = CONFIG_FILE; + char* confpath1 = xdgConfigFind(relpath, xdg); + slogi("config path is %s", confpath1); + return confpath1; +} + + +char* get_dir_with_default(const char* dirpath, char* defaultpath) +{ + if ((dirpath != NULL) && (strcmp(dirpath, "") != 0)) + { + slogw("Using custom config path %s", dirpath); + return strdup(dirpath); + } + + return defaultpath; +} char* gethome() { @@ -207,47 +257,3 @@ bool does_directory_exist(char* path, char* dirname) 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 -} diff --git a/src/gilles/helper/dirhelper.h b/src/gilles/helper/dirhelper.h index 40de8d2..2eeadf4 100644 --- a/src/gilles/helper/dirhelper.h +++ b/src/gilles/helper/dirhelper.h @@ -3,11 +3,16 @@ #include +#include + +void create_dir(char* dir); +char* create_user_dir(char* home_dir_str, const char* dirtype, const char* programpath); char* gethome(); char* str2md5(const char* str, int length); bool does_directory_exist(char* path, char* dirname); void restrict_folders_to_cache(char* path, int cachesize); void delete_dir(char* path); -bool file_exists(const char* file); +char* get_config_file(const char* confpath, xdgHandle* xdg); +char* get_dir_with_default(const char* dirpath, char* defaultpath); #endif diff --git a/src/gilles/helper/parameters.c b/src/gilles/helper/parameters.c index c70b9fc..86c37ff 100644 --- a/src/gilles/helper/parameters.c +++ b/src/gilles/helper/parameters.c @@ -14,12 +14,20 @@ int freeparams(Parameters* p) { free(p->sim_string); } - if (p->mysql == true) + if (p->mysql == true || p->program_action == A_BROWSE) { - if(p->mysql_user != NULL) + if(p->db_user != NULL) { - free(p->mysql_user); + free(p->db_user); } + if(p->db_conn != NULL) + { + free(p->db_conn); + } + } + if (p->config_path != NULL) + { + free(p->config_path); } return 0; } @@ -45,6 +53,7 @@ ConfigError getParameters(int argc, char** argv, Parameters* p) struct arg_rex* cmd1 = arg_rex1(NULL, NULL, "play", NULL, REG_ICASE, NULL); struct arg_rex* cmd2 = arg_rex1(NULL, NULL, "browse", NULL, REG_ICASE, NULL); + struct arg_str* arg_cpath = arg_strn("f", "configpath", "", 0, 1, NULL); struct arg_str* arg_sim = arg_strn("s", "sim", "", 0, 1, NULL); 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"); @@ -93,17 +102,22 @@ ConfigError getParameters(int argc, char** argv, Parameters* p) { p->mysql = true; } + if (arg_cpath->sval[0] != NULL) + { + p->config_path = strdup(arg_cpath->sval[0]); + } exitcode = E_SUCCESS_AND_DO; } - - if (nerrors1==0) + else { - p->program_action = A_BROWSE; - //p->sim_string = strdup(arg_sim->sval[0]); - p->verbosity_count = arg_verbosity1->count; - exitcode = E_SUCCESS_AND_DO; + if (nerrors1==0) + { + p->program_action = A_BROWSE; + //p->sim_string = strdup(arg_sim->sval[0]); + p->verbosity_count = arg_verbosity1->count; + exitcode = E_SUCCESS_AND_DO; + } } - // interpret some special cases before we go through trouble of reading the config file if (help0->count > 0) { diff --git a/src/gilles/helper/parameters.h b/src/gilles/helper/parameters.h index edb8007..b14488b 100644 --- a/src/gilles/helper/parameters.h +++ b/src/gilles/helper/parameters.h @@ -12,17 +12,21 @@ typedef struct char* sim_string; int program_action; int program_state; + char* config_path; + char* gnuplot_file; bool cli; bool mqtt; bool mysql; bool simon; int verbosity_count; + int err; - char* mysql_user; - char* mysql_serv; - char* mysql_dbnm; - char* mysql_pass; + char* db_user; + char* db_serv; + char* db_dbnm; + char* db_pass; + char* db_conn; Simulator sim; SimData* simdata; @@ -33,7 +37,7 @@ Parameters; typedef enum { A_PLAY = 0, - A_BROWSE = 0 + A_BROWSE = 1, } ProgramAction; @@ -45,6 +49,15 @@ typedef enum } ConfigError; +typedef enum +{ + E_NO_ERROR = 0, + E_BAD_CONFIG = 1, + E_FAILED_DB_CONN = 2, + E_DB_QUERY_FAIL = 3, +} +GillesError; + ConfigError getParameters(int argc, char** argv, Parameters* p); int freeparams(Parameters* p);