From 3a85bddfca280f46d675f4987615c65089c80f44 Mon Sep 17 00:00:00 2001 From: Jeremy Tan Date: Sun, 15 Sep 2013 14:45:35 +0800 Subject: [PATCH] Updated control stuff --- server/actuator.c | 141 ++++++++++++++++------------------- server/actuator.h | 16 ++-- server/common.h | 1 + server/control.c | 179 +++++++++++++++++++-------------------------- server/control.h | 18 +++-- server/data.c | 2 +- server/data.h | 2 +- server/fastcgi.c | 11 +-- server/main.c | 7 +- server/sensor.c | 162 +++++++++++++++++++--------------------- server/sensor.h | 12 +-- server/valgrind.sh | 2 +- 12 files changed, 244 insertions(+), 309 deletions(-) diff --git a/server/actuator.c b/server/actuator.c index 2caa03c..af69c7f 100644 --- a/server/actuator.c +++ b/server/actuator.c @@ -1,10 +1,9 @@ /** * @file actuator.c - * @purpose Implementation of Actuator related functionality + * @brief Implementation of Actuator related functionality */ #include "actuator.h" -#include "control.h" #include "options.h" /** Array of Actuators (global to this file) initialised by Actuator_Init **/ @@ -29,90 +28,76 @@ void Actuator_Init() } /** - * Start an Actuator - * @param a - The Actuator to start - * @param experiment_name - Prepended to DataFile filename + * Sets the actuator to the desired mode. No checks are + * done to see if setting to the desired mode will conflict with + * the current mode - the caller must guarantee this itself. + * @param a The actuator whose mode is to be changed + * @param mode The mode to be changed to + * @param arg An argument specific to the mode to be set. + * e.g for CONTROL_START it represents the experiment name. */ -void Actuator_Start(Actuator * a, const char * experiment_name) +void Actuator_SetMode(Actuator * a, ControlModes mode, void *arg) { - // Set filename - char filename[BUFSIZ]; - if (sprintf(filename, "%s_a%d", experiment_name, a->id) >= BUFSIZ) + switch (mode) { - Fatal("Experiment name \"%s\" too long (>%d)", experiment_name, BUFSIZ); - } - - Log(LOGDEBUG, "Actuator %d with DataFile \"%s\"", a->id, filename); - // Open DataFile - Data_Open(&(a->data_file), filename); - - a->activated = true; // Don't forget this - - a->control_changed = false; - - // Create the thread - pthread_create(&(a->thread), NULL, Actuator_Loop, (void*)(a)); -} - -void Actuator_Pause(Actuator *a) -{ - if (a->activated) - { - a->activated = false; - Actuator_SetControl(a, NULL); - pthread_join(a->thread, NULL); // Wait for thread to exit - } -} - -void Actuator_Resume(Actuator *a) -{ - if (!a->activated) - { - a->activated = true; - pthread_create(&(a->thread), NULL, Actuator_Loop, (void*)(a)); + case CONTROL_START: + { + char filename[BUFSIZ]; + const char *experiment_name = (const char*) arg; + int ret; + + if (snprintf(filename, BUFSIZ, "%s_a%d", experiment_name, a->id) >= BUFSIZ) + { + Fatal("Experiment name \"%s\" too long (>%d)", experiment_name, BUFSIZ); + } + + Log(LOGDEBUG, "Actuator %d with DataFile \"%s\"", a->id, filename); + // Open DataFile + Data_Open(&(a->data_file), filename); + + a->activated = true; // Don't forget this + a->allow_actuation = true; + + a->control_changed = false; + + // Create the thread + ret = pthread_create(&(a->thread), NULL, Actuator_Loop, (void*)(a)); + if (ret != 0) + { + Fatal("Failed to create Actuator_Loop for Actuator %d", a->id); + } + } + break; + + case CONTROL_EMERGENCY: //TODO add proper case for emergency + case CONTROL_PAUSE: + a->allow_actuation = false; + break; + case CONTROL_RESUME: + a->allow_actuation = true; + break; + case CONTROL_STOP: + a->allow_actuation = false; + a->activated = false; + Actuator_SetControl(a, NULL); + pthread_join(a->thread, NULL); // Wait for thread to exit + Data_Close(&(a->data_file)); // Close DataFile + break; + default: + Fatal("Unknown control mode: %d", mode); } } /** - * Stop an Actuator - * @param s - The Actuator to stop - */ -void Actuator_Stop(Actuator * a) -{ - // Stop - Actuator_Pause(a); - Data_Close(&(a->data_file)); // Close DataFile - -} - -void Actuator_PauseAll() -{ - for (int i = 0; i < NUMACTUATORS; ++i) - Actuator_Pause(g_actuators+i); -} - -void Actuator_ResumeAll() -{ - for (int i = 0; i < NUMACTUATORS; ++i) - Actuator_Resume(g_actuators+i); -} - -/** - * Stop all Actuators + * Sets all actuators to the desired mode. + * @see Actuator_SetMode for more information. + * @param mode The mode to be changed to + * @param arg An argument specific to the mode to be set. */ -void Actuator_StopAll() +void Actuator_SetModeAll(ControlModes mode, void * arg) { - for (int i = 0; i < NUMACTUATORS; ++i) - Actuator_Stop(g_actuators+i); -} - -/** - * Start all Actuators - */ -void Actuator_StartAll(const char * experiment_name) -{ - for (int i = 0; i < NUMACTUATORS; ++i) - Actuator_Start(g_actuators+i, experiment_name); + for (int i = 0; i < NUMACTUATORS; i++) + Actuator_SetMode(&g_actuators[i], mode, arg); } /** @@ -136,6 +121,8 @@ void * Actuator_Loop(void * arg) pthread_mutex_unlock(&(a->mutex)); if (!a->activated) break; + else if (!a->allow_actuation) + continue; Actuator_SetValue(a, a->control.value); } diff --git a/server/actuator.h b/server/actuator.h index 8a6b644..81150e8 100644 --- a/server/actuator.h +++ b/server/actuator.h @@ -1,6 +1,6 @@ /** * @file actuator.h - * @purpose Declarations for actuator control + * @brief Declarations for actuator control */ #ifndef _ACTUATOR_H @@ -52,21 +52,15 @@ typedef struct pthread_cond_t cond; /** Indicates whether the Actuator is running **/ bool activated; + /** Indicates whether the Actuator can be actuated or not **/ + bool allow_actuation; } Actuator; extern void Actuator_Init(); // One off initialisation of *all* Actuators - -extern void Actuator_StartAll(const char * experiment_name); // Start all Actuators -extern void Actuator_StopAll(); // Stop all Actuators - -extern void Actuator_PauseAll(); -extern void Actuator_ResumeAll(); - -extern void Actuator_Start(Actuator * a, const char * experiment_name); // Start a Actuator -extern void Actuator_Stop(Actuator * a); // Stop an Actuator - +extern void Actuator_SetModeAll(ControlModes mode, void *arg); +extern void Actuator_SetMode(Actuator * a, ControlModes mode, void *arg); extern void * Actuator_Loop(void * args); // Main loop for a thread that handles an Actuator extern void Actuator_SetValue(Actuator * a, double value); // Set an actuator by value diff --git a/server/common.h b/server/common.h index a690149..97290d2 100644 --- a/server/common.h +++ b/server/common.h @@ -26,6 +26,7 @@ #include "log.h" #include "fastcgi.h" +#include "control.h" /**Converts a timeval to a double**/ #define TIMEVAL_TO_DOUBLE(tv) ((tv).tv_sec + 1e-6 * ((tv).tv_usec)) diff --git a/server/control.c b/server/control.c index 29d9ef6..7b07ea3 100644 --- a/server/control.c +++ b/server/control.c @@ -7,26 +7,13 @@ #include "sensor.h" #include "actuator.h" -typedef enum ControlState { - STATE_STOPPED, - STATE_PAUSED, - STATE_RUNNING -} ControlState; - -typedef enum Mode { - START, - PAUSE, - RESUME, - STOP -} Mode; - typedef struct ControlData { - ControlState state; + ControlModes current_mode; pthread_mutex_t mutex; struct timeval start_time; } ControlData; -ControlData g_controls = {STATE_STOPPED, PTHREAD_MUTEX_INITIALIZER, {0}}; +ControlData g_controls = {CONTROL_STOP, PTHREAD_MUTEX_INITIALIZER, {0}}; static bool ExperimentExists(const char *experiment_name) { FILE *fp = fopen(experiment_name, "r"); @@ -45,7 +32,7 @@ static bool ExperimentExists(const char *experiment_name) { void Control_Handler(FCGIContext *context, char *params) { const char *action, *key = "", *name = ""; bool force = false; - Mode mode; + ControlModes desired_mode; FCGIValue values[4] = { {"action", &action, FCGI_REQUIRED(FCGI_STRING_T)}, @@ -60,17 +47,19 @@ void Control_Handler(FCGIContext *context, char *params) { if (!strcmp(action, "lock")) { FCGI_LockControl(context, force); return; + } else if (!strcmp(action, "emergency")) { + desired_mode = CONTROL_EMERGENCY; } else if (FCGI_HasControl(context, key)) { if (!strcmp(action, "release")) { FCGI_ReleaseControl(context); } else if (!strcmp(action, "start")) { - mode = START; + desired_mode = CONTROL_START; } else if (!strcmp(action, "pause")) { - mode = PAUSE; + desired_mode = CONTROL_PAUSE; } else if (!strcmp(action, "resume")) { - mode = RESUME; + desired_mode = CONTROL_RESUME; } else if (!strcmp(action, "stop")) { - mode = STOP; + desired_mode = CONTROL_STOP; } else { FCGI_RejectJSON(context, "Unknown action specified."); return; @@ -81,107 +70,83 @@ void Control_Handler(FCGIContext *context, char *params) { return; } - switch(mode) { - case START: - if (!*name) { - FCGI_RejectJSON(context, "An experiment name must be provided"); - } else if (ExperimentExists(name) && !force) { - FCGI_RejectJSONEx(context, STATUS_ALREADYEXISTS, - "An experiment with the specified name already exists."); - } else if (!Control_Start(name)) { - FCGI_RejectJSON(context, "An experiment is already running."); - } else { - FCGI_BeginJSON(context, STATUS_OK); - FCGI_EndJSON(); - } - break; - case PAUSE: - if (!Control_Pause()) { - FCGI_RejectJSON(context, "No experiment to pause."); - } else { - FCGI_BeginJSON(context, STATUS_OK); - FCGI_EndJSON(); - } - break; - case RESUME: - if (!Control_Resume()) { - FCGI_RejectJSON(context, "No experiment to resume."); - } else { - FCGI_BeginJSON(context, STATUS_OK); - FCGI_EndJSON(); - } - break; - case STOP: - if (!Control_Stop()) { - FCGI_RejectJSON(context, "No experiment to stop."); - } else { - FCGI_BeginJSON(context, STATUS_OK); - FCGI_EndJSON(); - } - break; + void *arg = NULL; + if (desired_mode == CONTROL_START) { + int len = strlen(name); + if (len <= 0) { + FCGI_RejectJSON(context, "An experiment name must be specified."); + return; + } else if (ExperimentExists(name) && !force) { + FCGI_RejectJSON(context, "An experiment with that name already exists."); + return; + } + arg = (void*)name; } -} - -bool Control_Start(const char *experiment_name) { - bool ret = false; - pthread_mutex_lock(&(g_controls.mutex)); - if (g_controls.state == STATE_STOPPED) { - FILE *fp = fopen(experiment_name, "a"); - if (fp) { - fclose(fp); - gettimeofday(&(g_controls.start_time), NULL); - Sensor_StartAll(experiment_name); - Actuator_StartAll(experiment_name); - g_controls.state = STATE_RUNNING; - ret = true; - } + const char *ret; + if ((ret = Control_SetMode(desired_mode, arg)) != NULL) { + FCGI_RejectJSON(context, ret); + } else { + FCGI_BeginJSON(context, STATUS_OK); + FCGI_JSONPair("description", "ok"); + FCGI_EndJSON(); } - pthread_mutex_unlock(&(g_controls.mutex)); - return ret; } +/** + * Sets the mode to the desired mode, if possible. + * @param desired_mode The mode to be set to + * @param arg An argument specific to the mode to be set. + * @return NULL on success, an error message on failure. + */ +const char* Control_SetMode(ControlModes desired_mode, void * arg) +{ + const char *ret = NULL; -bool Control_Pause() { - bool ret = false; pthread_mutex_lock(&(g_controls.mutex)); - if (g_controls.state == STATE_RUNNING) { - Actuator_PauseAll(); - Sensor_PauseAll(); - g_controls.state = STATE_PAUSED; - ret = true; + if (g_controls.current_mode == CONTROL_EMERGENCY) { + ret = "In emergency mode. Restart software."; + } else if (g_controls.current_mode == desired_mode) { + ret = "Already in desired mode."; + } else if (desired_mode == CONTROL_START) { + if (g_controls.current_mode == CONTROL_STOP) { + FILE *fp = fopen((const char*) arg, "a"); + if (fp) { + fclose(fp); + gettimeofday(&(g_controls.start_time), NULL); + } else { + ret = "Failed to create experiment placeholder"; + } + } else { + ret = "Cannot start when not in a stopped state."; + } + } else if (desired_mode == CONTROL_RESUME) { + if (g_controls.current_mode != CONTROL_PAUSE) + ret = "Cannot resume when not in a paused state."; } - pthread_mutex_unlock(&(g_controls.mutex)); - return ret; -} - -bool Control_Resume() { - bool ret = false; - pthread_mutex_lock(&(g_controls.mutex)); - if (g_controls.state == STATE_PAUSED) { - Actuator_ResumeAll(); - Sensor_ResumeAll(); - g_controls.state = STATE_RUNNING; - ret = true; + + if (ret == NULL) { + Actuator_SetModeAll(desired_mode, arg); + Sensor_SetModeAll(desired_mode, arg); + g_controls.current_mode = desired_mode; } pthread_mutex_unlock(&(g_controls.mutex)); return ret; } -bool Control_Stop() { - bool ret = false; - +/** + * Gets the current mode. + * @return The current mode + */ +ControlModes Control_GetMode() { + ControlModes ret; pthread_mutex_lock(&(g_controls.mutex)); - if (g_controls.state != STATE_STOPPED) { - Actuator_StopAll(); - Sensor_StopAll(); - g_controls.state = STATE_STOPPED; - ret = true; - } - pthread_mutex_unlock(&(g_controls.mutex)); + ret = g_controls.current_mode; + pthread_mutex_unlock(&(g_controls.mutex)); return ret; } +/* bool Control_Lock() { pthread_mutex_lock(&(g_controls.mutex)); if (g_controls.state == STATE_RUNNING || g_controls.state == STATE_PAUSED) @@ -192,8 +157,12 @@ bool Control_Lock() { void Control_Unlock() { pthread_mutex_unlock(&(g_controls.mutex)); -} +}*/ +/** + * Gets the start time for the current experiment + * @return the start time + */ const struct timeval* Control_GetStartTime() { return &g_controls.start_time; } \ No newline at end of file diff --git a/server/control.h b/server/control.h index 188b13a..05ca2fc 100644 --- a/server/control.h +++ b/server/control.h @@ -5,14 +5,20 @@ #ifndef _CONTROL_H #define _CONTROL_H +typedef enum ControlModes { + CONTROL_START, + CONTROL_PAUSE, + CONTROL_RESUME, + CONTROL_STOP, + CONTROL_EMERGENCY +} ControlModes; + /** ID codes for all the actuators **/ extern void Control_Handler(FCGIContext *context, char *params); -extern bool Control_Start(const char *experiment_name); -extern bool Control_Pause(); -extern bool Control_Resume(); -extern bool Control_Stop(); -extern bool Control_Lock(); -extern void Control_Unlock(); +extern const char* Control_SetMode(ControlModes desired_mode, void * arg); +extern ControlModes Control_GetMode(); +//extern bool Control_Lock(); +//extern void Control_Unlock(); extern const struct timeval* Control_GetStartTime(); #endif diff --git a/server/data.c b/server/data.c index ffd0b67..3824833 100644 --- a/server/data.c +++ b/server/data.c @@ -1,6 +1,6 @@ /** * @file data.c - * @purpose Implementation of data handling functions; saving, loading, displaying, selecting. + * @brief Implementation of data handling functions; saving, loading, displaying, selecting. */ #include "data.h" diff --git a/server/data.h b/server/data.h index 07ede0b..e8d887f 100644 --- a/server/data.h +++ b/server/data.h @@ -1,6 +1,6 @@ /** * @file data.h - * @purpose Declaration of data handling functions; saving, loading, displaying, selecting. + * @brief Declaration of data handling functions; saving, loading, displaying, selecting. */ #ifndef _DATAPOINT_H diff --git a/server/fastcgi.c b/server/fastcgi.c index 6b2957e..05dae34 100644 --- a/server/fastcgi.c +++ b/server/fastcgi.c @@ -439,7 +439,6 @@ void * FCGI_RequestLoop (void *data) Log(LOGDEBUG, "Got request #%d", context.response_number); ModuleHandler module_handler = NULL; char module[BUFSIZ], params[BUFSIZ]; - bool lock_required = false; //strncpy doesn't zero-truncate properly snprintf(module, BUFSIZ, "%s", getenv("DOCUMENT_URI_LOCAL")); @@ -463,21 +462,13 @@ void * FCGI_RequestLoop (void *data) module_handler = Control_Handler; } else if (!strcmp("sensors", module)) { module_handler = Sensor_Handler; - lock_required = true; } else if (!strcmp("actuators", module)) { module_handler = Actuator_Handler; - lock_required = true; } context.current_module = module; if (module_handler) { - if (lock_required && !Control_Lock()) { - FCGI_RejectJSONEx(&context, STATUS_NOTRUNNING, "Experiment is not running."); - } else { - module_handler(&context, params); - if (lock_required) - Control_Unlock(); - } + module_handler(&context, params); } else { FCGI_RejectJSON(&context, "Unhandled module"); } diff --git a/server/main.c b/server/main.c index 75dd628..4b36b20 100644 --- a/server/main.c +++ b/server/main.c @@ -81,12 +81,15 @@ int main(int argc, char ** argv) Actuator_Init(); //Sensor_StartAll("test"); //Actuator_StartAll("test"); - Control_Start("test"); + const char *ret; + if ((ret = Control_SetMode(CONTROL_START, "test")) != NULL) + Fatal("Control_SetMode failed with '%s'", ret); // run request thread in the main thread FCGI_RequestLoop(NULL); - Control_Stop(); + if ((ret = Control_SetMode(CONTROL_STOP, "test")) != NULL) + Fatal("Control_SetMode failed with '%s'", ret); //Sensor_StopAll(); //Actuator_StopAll(); diff --git a/server/sensor.c b/server/sensor.c index 867f7d4..5115f99 100644 --- a/server/sensor.c +++ b/server/sensor.c @@ -5,7 +5,6 @@ */ #include "common.h" -#include "control.h" #include "sensor.h" #include "options.h" #include @@ -45,95 +44,76 @@ void Sensor_Init() } /** - * Start a Sensor recording DataPoints - * @param s - The Sensor to start - * @param experiment_name - Prepended to DataFile filename + * Sets the sensor to the desired control mode. No checks are + * done to see if setting to the desired mode will conflict with + * the current mode - the caller must guarantee this itself. + * @param s The sensor whose mode is to be changed + * @param mode The mode to be changed to + * @param arg An argument specific to the mode to be set. + * e.g for CONTROL_START it represents the experiment name. */ -void Sensor_Start(Sensor * s, const char * experiment_name) +void Sensor_SetMode(Sensor * s, ControlModes mode, void * arg) { - // Set filename - char filename[BUFSIZ]; - if (sprintf(filename, "%s_s%d", experiment_name, s->id) >= BUFSIZ) + switch(mode) { - Fatal("Experiment name \"%s\" too long (>%d)", experiment_name, BUFSIZ); - } - - Log(LOGDEBUG, "Sensor %d with DataFile \"%s\"", s->id, filename); - // Open DataFile - Data_Open(&(s->data_file), filename); - - s->record_data = true; // Don't forget this! - - // Create the thread - pthread_create(&(s->thread), NULL, Sensor_Loop, (void*)(s)); -} - -/** - * Pause a sensor from recording DataPoints. Blocks until it is paused. - * @param s - The Sensor to pause - */ -void Sensor_Pause(Sensor *s) -{ - if (s->record_data) - { - s->record_data = false; - pthread_join(s->thread, NULL); + case CONTROL_START: + { + // Set filename + char filename[BUFSIZ]; + const char *experiment_name = (const char*) arg; + int ret; + + if (snprintf(filename, BUFSIZ, "%s_s%d", experiment_name, s->id) >= BUFSIZ) + { + Fatal("Experiment name \"%s\" too long (>%d)", experiment_name, BUFSIZ); + } + + Log(LOGDEBUG, "Sensor %d with DataFile \"%s\"", s->id, filename); + // Open DataFile + Data_Open(&(s->data_file), filename); + + s->activated = true; + s->record_data = true; // Don't forget this! + + // Create the thread + ret = pthread_create(&(s->thread), NULL, Sensor_Loop, (void*)(s)); + if (ret != 0) + { + Fatal("Failed to create Sensor_Loop for Sensor %d", s->id); + } + } + break; + case CONTROL_EMERGENCY: + case CONTROL_PAUSE: + s->record_data = false; + break; + case CONTROL_RESUME: + s->record_data = true; + break; + case CONTROL_STOP: + s->activated = false; + s->record_data = false; + pthread_join(s->thread, NULL); + + Data_Close(&(s->data_file)); // Close DataFile + s->newest_data.time_stamp = 0; + s->newest_data.value = 0; + break; + default: + Fatal("Unknown control mode: %d", mode); } } /** - * Resumes a paused sensor. - * @param s - The Sensor to resume + * Sets all sensors to the desired mode. + * @see Sensor_SetMode for more information. + * @param mode The mode to be changed to + * @param arg An argument specific to the mode to be set. */ -void Sensor_Resume(Sensor *s) +void Sensor_SetModeAll(ControlModes mode, void * arg) { - if (!s->record_data) - { - s->record_data = true; - pthread_create(&(s->thread), NULL, Sensor_Loop, (void*)(s)); - } -} - -/** - * Stop a Sensor from recording DataPoints. Blocks until it has stopped. - * @param s - The Sensor to stop - */ -void Sensor_Stop(Sensor * s) -{ - Sensor_Pause(s); - Data_Close(&(s->data_file)); // Close DataFile - s->newest_data.time_stamp = 0; - s->newest_data.value = 0; -} - -/** - * Stop all Sensors - */ -void Sensor_StopAll() -{ - for (int i = 0; i < NUMSENSORS; ++i) - Sensor_Stop(g_sensors+i); -} - -void Sensor_PauseAll() -{ - for (int i = 0; i < NUMSENSORS; ++i) - Sensor_Pause(g_sensors+i); -} - -void Sensor_ResumeAll() -{ - for (int i = 0; i < NUMSENSORS; ++i) - Sensor_Resume(g_sensors+i); -} - -/** - * Start all Sensors - */ -void Sensor_StartAll(const char * experiment_name) -{ - for (int i = 0; i < NUMSENSORS; ++i) - Sensor_Start(g_sensors+i, experiment_name); + for (int i = 0; i < NUMSENSORS; i++) + Sensor_SetMode(&g_sensors[i], mode, arg); } @@ -229,14 +209,22 @@ void * Sensor_Loop(void * arg) Log(LOGDEBUG, "Sensor %d starts", s->id); // Until the sensor is stopped, record data points - while (s->record_data) + while (s->activated) { - DataPoint d; - //Log(LOGDEBUG, "Sensor %d reads data [%f,%f]", s->id, d.time_stamp, d.value); - if (Sensor_Read(s, &d)) // If new DataPoint is read: + if (s->record_data) + { + DataPoint d; + //Log(LOGDEBUG, "Sensor %d reads data [%f,%f]", s->id, d.time_stamp, d.value); + if (Sensor_Read(s, &d)) // If new DataPoint is read: + { + //Log(LOGDEBUG, "Sensor %d saves data [%f,%f]", s->id, d.time_stamp, d.value); + Data_Save(&(s->data_file), &d, 1); // Record it + } + } + else { - //Log(LOGDEBUG, "Sensor %d saves data [%f,%f]", s->id, d.time_stamp, d.value); - Data_Save(&(s->data_file), &d, 1); // Record it + //Do something? wait? + usleep(100000); } } diff --git a/server/sensor.h b/server/sensor.h index 6c51ac1..bdab0f9 100644 --- a/server/sensor.h +++ b/server/sensor.h @@ -32,6 +32,8 @@ typedef struct SensorId id; /** DataFile to store sensor values in **/ DataFile data_file; + /** Indicates whether the Sensor is not stopped **/ + bool activated; /** Indicates whether the Sensor should record data **/ bool record_data; /** Thread the Sensor is running in **/ @@ -51,14 +53,8 @@ typedef struct extern void Sensor_Init(); // One off initialisation of *all* sensors -extern void Sensor_StartAll(const char * experiment_name); // Start all Sensors recording data -extern void Sensor_StopAll(); // Stop all Sensors recording data -extern void Sensor_Start(Sensor * s, const char * experiment_name); // Start a sensor recording datas -extern void Sensor_Stop(Sensor * s); // Stop a Sensor from recording data -extern void Sensor_Pause(Sensor *s); -extern void Sensor_Resume(Sensor *s); -extern void Sensor_PauseAll(); -extern void Sensor_ResumeAll(); +extern void Sensor_SetModeAll(ControlModes mode, void * arg); +extern void Sensor_SetMode(Sensor * s, ControlModes mode, void * arg); extern void * Sensor_Loop(void * args); // Main loop for a thread that handles a Sensor extern bool Sensor_Read(Sensor * s, DataPoint * d); // Read a single DataPoint, indicating if it has changed since the last one diff --git a/server/valgrind.sh b/server/valgrind.sh index 062c490..e5214bd 100755 --- a/server/valgrind.sh +++ b/server/valgrind.sh @@ -1,2 +1,2 @@ #!/bin/bash -valgrind --leak-check=full --track-origins=yes --show-reachable=yes ./server +valgrind --leak-check=full --show-reachable=yes ./server -- 2.20.1