Manual merge of semi-updated control code
[matches/MCTX3420.git] / server / control.c
1 /**
2  * @file control.c
3  * @brief Handles all client control requests (admin related)
4  */
5 #include "common.h"
6 #include "control.h"
7
8
9 const char * g_actuator_names[NUMACTUATORS] = { 
10         "Pressure regulator", "Solenoid 1" 
11 };
12
13 /*
14 void ActuatorHandler(FCGIContext *context, ActuatorId id, const char *set_value) {
15         char *ptr;
16         
17         switch(id) { //Add new actuators here
18                 case ACT_PRESSURE: //Suppose is pressure regulator. 0-700 input (kPa)
19                 {
20                         int value = strtol(set_value, &ptr, 10);
21                         if (*ptr == '\0' && value >= 0 && value <= 700) {
22                                 FCGI_BeginJSON(context, STATUS_OK);
23                                 FCGI_JSONKey("description");
24                                 FCGI_JSONValue("\"Set pressure to %d kPa!\"", value);
25                                 FCGI_EndJSON();
26                         } else {
27                                 FCGI_RejectJSONEx(context, 
28                                         STATUS_ERROR, "Invalid pressure specified.");
29                         }
30                 } break;
31                 case ACT_SOLENOID1:
32                 {
33                         int value = strtol(set_value, &ptr, 10);
34                         if (*ptr == '\0') {
35                                 const char *state = "off";
36                                 if (value)
37                                         state = "on";
38                                 FCGI_BeginJSON(context, STATUS_OK);
39                                 FCGI_JSONKey("description");
40                                 FCGI_JSONValue("\"Solenoid 1 turned %s!\"", state);
41                                 FCGI_EndJSON();
42                         } else {
43                                 FCGI_RejectJSON(context, "Invalid actuator value specified");
44                         }
45                 } break;
46                 default:
47                         FCGI_RejectJSONEx(context, 
48                                 STATUS_ERROR, "Invalid actuator id specified.");
49         }
50 }*/
51
52 typedef enum ControlState {
53         STATE_STOPPED,
54         STATE_PAUSED,
55         STATE_RUNNING
56 } ControlState;
57
58 typedef struct ControlData {
59         ControlState state;
60         pthread_mutex_t mutex;
61         struct timeval start_time;
62 } ControlData;
63
64 ControlData g_controls = {STATE_STOPPED, PTHREAD_MUTEX_INITIALIZER, {0}};
65
66 /**
67  * System control handler. This covers high-level control, including
68  * admin related functions and starting/stopping experiments..
69  * @param context The context to work in
70  * @param params The input parameters
71  */
72 void Control_Handler(FCGIContext *context, char *params) {
73         const char *action, *key = "", *name = "";
74         bool force = false;
75
76         FCGIValue values[4] = {
77                 {"action", &action, FCGI_REQUIRED(FCGI_STRING_T)},
78                 {"key", &key, FCGI_STRING_T},
79                 {"force", &force, FCGI_BOOL_T},
80                 {"name", &name, FCGI_STRING_T}
81         };
82
83         if (!FCGI_ParseRequest(context, params, values, 4))
84                 return;
85         
86         if (!strcmp(action, "lock")) {
87                 FCGI_LockControl(context, force);
88         } else if (FCGI_HasControl(context, key)) {
89                 if (!strcmp(action, "release")) {
90                         FCGI_ReleaseControl(context);
91                 } else if (!strcmp(action, "start")) {
92                         FCGI_BeginJSON(context, STATUS_OK);
93                         FCGI_JSONPair("description", "start");
94                         FCGI_EndJSON();
95                 } else if (!strcmp(action, "pause")) {
96                         FCGI_BeginJSON(context, STATUS_OK);
97                         FCGI_JSONPair("description", "stop");
98                         FCGI_EndJSON();
99                 } else if (!strcmp(action, "end")) {
100                         FCGI_BeginJSON(context, STATUS_OK);
101                         FCGI_JSONPair("description", "stop");
102                         FCGI_EndJSON();
103                 } else {
104                         FCGI_RejectJSON(context, "Unknown action specified.");
105                 }
106         } else {
107                 FCGI_RejectJSONEx(context, STATUS_UNAUTHORIZED, 
108                         "Invalid control key specified.");
109         }
110 }
111
112 bool Control_Start(const char *experiment_name) {
113         pthread_mutex_lock(&(g_controls.mutex));
114         if (g_controls.state == STATE_STOPPED) {
115                 gettimeofday(&(g_controls.start_time), NULL);
116                 Sensor_StartAll(experiment_name);
117                 g_controls.state = STATE_RUNNING;
118
119                 pthread_mutex_unlock(&(g_controls.mutex));
120                 return true;
121         }
122         return false;
123         pthread_mutex_unlock(&(g_controls.mutex));
124 }
125
126 void Control_Pause() {
127         pthread_mutex_lock(&(g_controls.mutex));
128         pthread_mutex_unlock(&(g_controls.mutex));
129 }
130
131 bool Control_End() {
132         pthread_mutex_lock(&(g_controls.mutex));
133         if (g_controls.state != STATE_STOPPED) {
134                 Sensor_StopAll();
135                 g_controls.state = STATE_STOPPED;
136
137                 pthread_mutex_unlock(&(g_controls.mutex));      
138                 return true;
139         }
140         pthread_mutex_unlock(&(g_controls.mutex));      
141         return false;
142 }

UCC git Repository :: git.ucc.asn.au