From: Timo Kokkonen Date: Sun, 3 Nov 2013 20:11:39 +0000 (+0200) Subject: Implement state machine based architecture X-Git-Url: http://git.itanic.dy.fi/?p=log-plotter;a=commitdiff_plain;h=3870f4e94d04c2f900ab07100d2f2a4b577c851a Implement state machine based architecture The main loop is now at the main function, where we control all of the actual functions of the program, and really do nothing. All other functions happen elsewhere and are being called only when interesting events occur. Signed-off-by: Timo Kokkonen --- diff --git a/data.c b/data.c index b663cd5..3111370 100644 --- a/data.c +++ b/data.c @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include #include #include @@ -14,9 +16,11 @@ #include "event.h" #include "utils.h" #include "event.h" +#include "plotter_status.h" struct dataparser_struct { struct eventhandler_entry evhandler; + char *log_path; int infd; int outfd; int offset; @@ -212,6 +216,8 @@ static int read_log_line(int infd, char *buf, size_t bufsize, int *offset) if (ret == 0) { pr_err("Read EOF, stopping\n"); + + set_plotter_system_status(SYSTEM_STATUS_NO_USB); return -1; } buf[*offset + ret] = 0; @@ -243,6 +249,27 @@ static int read_log_line(int infd, char *buf, size_t bufsize, int *offset) return 0; } +static int open_new_logfile(struct dataparser_struct *dt) +{ + char path[2048]; + struct tm *tm; + time_t cur_time = time(NULL); + + tm = localtime(&cur_time); + strftime(path, sizeof(path), dt->log_path, tm); + + pr_debug("Opening %s for writing the log file\n", path); + + dt->outfd = open(path, O_CREAT | O_APPEND | O_WRONLY, 0664); + if (dt->outfd < 0) { + pr_err("Failed to open file %s for writing: %m\n", + path); + return -1; + } + + return 0; +} + static int read_data(struct eventhandler_entry *h) { struct dataparser_struct *dt; @@ -274,6 +301,8 @@ static int read_data(struct eventhandler_entry *h) parse_logline(dt->buf, &data); + set_plotter_system_status(data.state); + /* Fill in possibly missing timestamp */ if (isnan(data.timestamp) || data.timestamp == 0) data.timestamp = cur_time - dt->start_time; @@ -283,9 +312,15 @@ static int read_data(struct eventhandler_entry *h) if (0) dump_data(&data); - if (!dt->outfd) + if (!dt->log_path) return 0; + if (state_has_changed()) { + ret = open_new_logfile(dt); + if (ret < 0) + return ret; + } + len = snprintf(str, sizeof(str), "%d;%d;%.1f;" "%.3f;%.3f;%.3f;" @@ -328,13 +363,13 @@ static struct dataparser_struct dataparser = { .evhandler.handle_event = read_data, }; -int init_data_parser(int infd, int outfd) +int init_data_parser(int infd, struct plotter_config *cfg) { int ret; dataparser.evhandler.fd = infd; dataparser.infd = infd; - dataparser.outfd = outfd; + dataparser.log_path = cfg->log_path; ret = register_event_handler(&dataparser.evhandler); if (ret < 0) diff --git a/data.h b/data.h index 90934a1..6e286fa 100644 --- a/data.h +++ b/data.h @@ -1,6 +1,8 @@ #ifndef _DATA_H_ #define _DATA_H_ +#include "config.h" + #define MAX_CELLS 10 struct charger_data { @@ -17,6 +19,6 @@ struct charger_data { double ext_temp; }; -int init_data_parser(int infd, int outfd); +int init_data_parser(int infd, struct plotter_config *cfg); #endif diff --git a/main.c b/main.c index 1057d09..9356d91 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,5 @@ #include #include -#include #include #include "options.h" @@ -9,12 +8,15 @@ #include "trace.h" #include "data.h" #include "event.h" +#include "plotter_status.h" + +struct log_plotter_status plotter_state; int main(int argc, char *argv[]) { struct plotter_options options; struct plotter_config cfg; - int fd, baud, ret = 0, out_fd = 0; + int fd, baud, ret = 0; bzero(&cfg, sizeof(cfg)); @@ -36,25 +38,20 @@ int main(int argc, char *argv[]) goto out; } - if (options.output_path) { - pr_debug("Opening %s for writing the log file\n", - options.output_path); - - out_fd = open(options.output_path, - O_CREAT | O_APPEND | O_WRONLY, 0664); - if (out_fd < 0) { - pr_err("Failed to open file %s for writing: %m\n", - options.output_path); - ret = 1; - goto out; - } - } + init_data_parser(fd, &cfg); + while (plotter_state.system_status != SYSTEM_STATUS_NO_USB) { + poll_events(10000); - init_data_parser(fd, out_fd); + if (plotter_state.old_system_status != + plotter_state.system_status) { + pr_debug("Status changing from %s to %s", + state_to_str(plotter_state.old_system_status), + state_to_str(plotter_state.system_status)); - while (1) { - poll_events(10000); + plotter_state.old_system_status = + plotter_state.system_status; + } } out: diff --git a/plotter_status.h b/plotter_status.h new file mode 100644 index 0000000..a920c9e --- /dev/null +++ b/plotter_status.h @@ -0,0 +1,53 @@ +#ifndef _PLOTTER_STATE_ +#define _PLOTTER_STATE_ + +enum system_status { + SYSTEM_STATUS_NO_USB = -1, + SYSTEM_STATUS_UNKNOWN, + SYSTEM_STATUS_CHARGING, + SYSTEM_STATUS_DISCHARGING, + SYSTEM_STATUS_MONITORING, + SYSTEM_STATUS_COMPLETED = 6, +}; + +struct log_plotter_status { + int old_system_status; + int system_status; +}; + +extern struct log_plotter_status plotter_state; + +static inline void set_plotter_system_status(int new_status) +{ + plotter_state.system_status = new_status; +} + +static inline char *state_to_str(int state) +{ + switch (state) { + case SYSTEM_STATUS_NO_USB: + return "No USB"; + + case SYSTEM_STATUS_CHARGING: + return "Charging"; + + case SYSTEM_STATUS_DISCHARGING: + return "Discharging"; + + case SYSTEM_STATUS_MONITORING: + return "Monitoring"; + + case SYSTEM_STATUS_COMPLETED: + return "Completed"; + + default: + return "Unknown"; + } +} + +static inline int state_has_changed(void) +{ + return plotter_state.old_system_status != plotter_state.system_status; +} + +#endif