diff --git a/include/meter.h b/include/meter.h index 3d3893c..fb0fb43 100644 --- a/include/meter.h +++ b/include/meter.h @@ -91,6 +91,7 @@ typedef struct { /* function pointers */ int (*init_func)(meter_t *mtr, list_t options); + void (*free_func)(meter_t *mtr); int (*open_func)(meter_t *mtr); int (*close_func)(meter_t *mtr); size_t (*read_func)(meter_t *mtr, reading_t *rds, size_t n); diff --git a/include/protocols/d0.h b/include/protocols/d0.h index 4b32fd8..87a14e9 100644 --- a/include/protocols/d0.h +++ b/include/protocols/d0.h @@ -47,6 +47,7 @@ struct meter; struct reading; int meter_init_d0(struct meter *mtr, list_t options); +void meter_free_d0(struct meter *mtr); int meter_open_d0(struct meter *mtr); int meter_close_d0(struct meter *mtr); size_t meter_read_d0(struct meter *mtr, struct reading *rds, size_t n); diff --git a/include/protocols/exec.h b/include/protocols/exec.h index 71494af..588a34f 100644 --- a/include/protocols/exec.h +++ b/include/protocols/exec.h @@ -38,6 +38,7 @@ struct meter; struct reading; int meter_init_exec(struct meter *mtr, list_t options); +void meter_free_exec(struct meter *mtr); int meter_open_exec(struct meter *mtr); int meter_close_exec(struct meter *mtr); size_t meter_read_exec(struct meter *mtr, struct reading *rds, size_t n); diff --git a/include/protocols/file.h b/include/protocols/file.h index 232c3d5..b39ad8e 100644 --- a/include/protocols/file.h +++ b/include/protocols/file.h @@ -41,6 +41,7 @@ struct meter; struct reading; int meter_init_file(struct meter *mtr, list_t options); +void meter_free_file(struct meter *mtr); int meter_open_file(struct meter *mtr); int meter_close_file(struct meter *mtr); size_t meter_read_file(struct meter *mtr, struct reading *rds, size_t n); diff --git a/include/protocols/fluksov2.h b/include/protocols/fluksov2.h index 24754f3..0df8cac 100644 --- a/include/protocols/fluksov2.h +++ b/include/protocols/fluksov2.h @@ -26,6 +26,8 @@ #ifndef _FLUKSOV2_H_ #define _FLUKSOV2_H_ +#define FLUKSOV2_DEFAULT_FIFO "/var/run/spid/delta/out" + typedef struct { char *fifo; @@ -37,6 +39,7 @@ struct meter; struct reading; int meter_init_fluksov2(struct meter *mtr, list_t options); +void meter_free_fluksov2(struct meter *mtr); int meter_open_fluksov2(struct meter *mtr); int meter_close_fluksov2(struct meter *mtr); size_t meter_read_fluksov2(struct meter *mtr, struct reading *rds, size_t n); diff --git a/include/protocols/random.h b/include/protocols/random.h index 8b04cf6..9c8ce2c 100644 --- a/include/protocols/random.h +++ b/include/protocols/random.h @@ -38,6 +38,7 @@ struct reading; double ltqnorm(double p); int meter_init_random(struct meter *mtr, list_t options); +void meter_free_random(struct meter *mtr); int meter_open_random(struct meter *mtr); int meter_close_random(struct meter *mtr); size_t meter_read_random(struct meter *mtr, struct reading *rds, size_t n); diff --git a/include/protocols/s0.h b/include/protocols/s0.h index 27e7b73..eaf9c93 100644 --- a/include/protocols/s0.h +++ b/include/protocols/s0.h @@ -41,6 +41,7 @@ struct meter; struct reading; int meter_init_s0(struct meter *mtr, list_t options); +void meter_free_s0(struct meter *mtr); int meter_open_s0(struct meter *mtr); int meter_close_s0(struct meter *mtr); size_t meter_read_s0(struct meter *mtr, struct reading *rds, size_t n); diff --git a/include/protocols/sml.h b/include/protocols/sml.h index 9169a5e..15f88ea 100644 --- a/include/protocols/sml.h +++ b/include/protocols/sml.h @@ -61,6 +61,13 @@ struct reading; */ int meter_init_sml(struct meter *mtr, list_t options); +/** + * Freeing allocated resources during initialization + * + * @param mtr the meter structure + */ +void meter_free_sml(struct meter *mtr); + /** * Open connection via serial port or socket to meter * diff --git a/src/meter.c b/src/meter.c index fa2a116..129801e 100644 --- a/src/meter.c +++ b/src/meter.c @@ -29,7 +29,7 @@ #include "meter.h" #include "options.h" -#define METER_DETAIL(NAME, DESC, MAX_RDS, PERIODIC) { meter_protocol_##NAME, #NAME, DESC, MAX_RDS, PERIODIC, meter_init_##NAME, meter_open_##NAME, meter_close_##NAME, meter_read_##NAME } +#define METER_DETAIL(NAME, DESC, MAX_RDS, PERIODIC) { meter_protocol_##NAME, #NAME, DESC, MAX_RDS, PERIODIC, meter_init_##NAME, meter_free_##NAME, meter_open_##NAME, meter_close_##NAME, meter_read_##NAME } static const meter_details_t protocols[] = { /* alias description max_rds periodic @@ -77,14 +77,9 @@ int meter_init(meter_t *mtr, list_t options) { return details->init_func(mtr, options); } -int meter_lookup_protocol(const char* name, meter_protocol_t *protocol) { - for (const meter_details_t *it = meter_get_protocols(); it != NULL; it++) { - if (strcmp(it->name, name) == 0) { - *protocol = it->id; - return SUCCESS; - } - } - return ERR_NOT_FOUND; +void meter_free(meter_t *mtr) { + const meter_details_t *details = meter_get_details(mtr->protocol); + return details->free_func(mtr); } int meter_open(meter_t *mtr) { @@ -102,6 +97,16 @@ size_t meter_read(meter_t *mtr, reading_t rds[], size_t n) { return details->read_func(mtr, rds, n); } +int meter_lookup_protocol(const char* name, meter_protocol_t *protocol) { + for (const meter_details_t *it = meter_get_protocols(); it != NULL; it++) { + if (strcmp(it->name, name) == 0) { + *protocol = it->id; + return SUCCESS; + } + } + return ERR_NOT_FOUND; +} + const meter_details_t * meter_get_protocols() { return protocols; } diff --git a/src/protocols/d0.c b/src/protocols/d0.c index 8708066..6dc1af4 100644 --- a/src/protocols/d0.c +++ b/src/protocols/d0.c @@ -98,6 +98,18 @@ int meter_init_d0(meter_t *mtr, list_t options) { return SUCCESS; } +void meter_free_d0(meter_t *mtr) { + meter_handle_d0_t *handle = &mtr->handle.d0; + + if (handle->device != NULL) { + free(handle->device); + } + + if (handle->host != NULL) { + free(handle->host); + } +} + int meter_open_d0(meter_t *mtr) { meter_handle_d0_t *handle = &mtr->handle.d0; diff --git a/src/protocols/exec.c b/src/protocols/exec.c index 585af97..839a35f 100644 --- a/src/protocols/exec.c +++ b/src/protocols/exec.c @@ -62,6 +62,16 @@ int meter_init_exec(meter_t *mtr, list_t options) { return SUCCESS; } +void meter_free_exec(meter_t *mtr) { + meter_handle_exec_t *handle = &mtr->handle.exec; + + free(handle->command); + + if (handle->format != NULL) { + free(handle->format); + } +} + int meter_open_exec(meter_t *mtr) { //meter_handle_exec_t *handle = &mtr->handle.exec; diff --git a/src/protocols/file.c b/src/protocols/file.c index c111738..37be9e6 100644 --- a/src/protocols/file.c +++ b/src/protocols/file.c @@ -126,6 +126,16 @@ int meter_init_file(meter_t *mtr, list_t options) { return SUCCESS; } +void meter_free_file(meter_t *mtr) { + meter_handle_file_t *handle = &mtr->handle.file; + + free(handle->path); + + if (handle->format != NULL) { + free(handle->format); + } +} + int meter_open_file(meter_t *mtr) { meter_handle_file_t *handle = &mtr->handle.file; diff --git a/src/protocols/fluksov2.c b/src/protocols/fluksov2.c index 6109fe8..36dbb5d 100644 --- a/src/protocols/fluksov2.c +++ b/src/protocols/fluksov2.c @@ -41,12 +41,18 @@ int meter_init_fluksov2(meter_t *mtr, list_t options) { handle->fifo = strdup(fifo); } else { - handle->fifo = "/var/run/spid/delta/out"; /* use default path */ + handle->fifo = strdup(FLUKSOV2_DEFAULT_FIFO); /* use default path */ } return SUCCESS; } +void meter_free_fluksov2(meter_t *mtr) { + meter_handle_fluksov2_t *handle = &mtr->handle.fluksov2; + + free(handle->fifo); +} + int meter_open_fluksov2(meter_t *mtr) { meter_handle_fluksov2_t *handle = &mtr->handle.fluksov2; diff --git a/src/protocols/random.c b/src/protocols/random.c index 2b191b2..c00238f 100644 --- a/src/protocols/random.c +++ b/src/protocols/random.c @@ -55,6 +55,10 @@ int meter_init_random(meter_t *mtr, list_t options) { return SUCCESS; } +void meter_free_random(meter_t *mtr) { + //meter_handle_random_t *handle = &mtr->handle.random; +} + int meter_open_random(meter_t *mtr) { //meter_handle_random_t *handle = &mtr->handle.random; diff --git a/src/protocols/s0.c b/src/protocols/s0.c index 31edc16..a4c53f4 100644 --- a/src/protocols/s0.c +++ b/src/protocols/s0.c @@ -59,6 +59,12 @@ int meter_init_s0(meter_t *mtr, list_t options) { return SUCCESS; } +void meter_free_s0(meter_t *mtr) { + meter_handle_s0_t *handle = &mtr->handle.s0; + + free(handle->device); +} + int meter_open_s0(meter_t *mtr) { meter_handle_s0_t *handle = &mtr->handle.s0; diff --git a/src/protocols/sml.c b/src/protocols/sml.c index d3ccaa2..9e90d84 100644 --- a/src/protocols/sml.c +++ b/src/protocols/sml.c @@ -104,6 +104,18 @@ int meter_init_sml(meter_t *mtr, list_t options) { return SUCCESS; } +void meter_free_sml(meter_t *mtr) { + meter_handle_sml_t *handle = &mtr->handle.sml; + + if (handle->device != NULL) { + free(handle->device); + } + + if (handle->host != NULL) { + free(handle->host); + } +} + int meter_open_sml(meter_t *mtr) { meter_handle_sml_t *handle = &mtr->handle.sml;