Merge pull request #27 from jtanx/master
[matches/MCTX3420.git] / server / control.c
1 /**
2  * @file control.c
3  * @brief Handles all client control requests (admin/actuator related)
4  */
5 #include "common.h"
6 #include "control.h"
7
8 const char * g_actuator_names[NUMACTUATORS] = { 
9         "Pressure regulator", "Solenoid 1" 
10 };
11
12 /**
13  * Handles control of the actuators.
14  */
15 void ActuatorHandler(FCGIContext *context, ActuatorId id, const char *set_value) {
16         char *ptr;
17         
18         switch(id) { //Add new actuators here
19                 case ACT_PRESSURE: //Suppose is pressure regulator. 0-700 input (kPa)
20                 {
21                         int value = strtol(set_value, &ptr, 10);
22                         if (*ptr == '\0' && value >= 0 && value <= 700) {
23                                 FCGI_BeginJSON(context, STATUS_OK);
24                                 FCGI_JSONKey("description");
25                                 FCGI_JSONValue("\"Set pressure to %d kPa!\"", value);
26                                 FCGI_EndJSON();
27                         } else {
28                                 FCGI_RejectJSONEx(context, 
29                                         STATUS_ERROR, "Invalid pressure specified.");
30                         }
31                 } break;
32                 case ACT_SOLENOID1:
33                 {
34                         int value = strtol(set_value, &ptr, 10);
35                         if (*ptr == '\0') {
36                                 const char *state = "off";
37                                 if (value)
38                                         state = "on";
39                                 FCGI_BeginJSON(context, STATUS_OK);
40                                 FCGI_JSONKey("description");
41                                 FCGI_JSONValue("\"Solenoid 1 turned %s!\"", state);
42                                 FCGI_EndJSON();
43                         } else {
44                                 FCGI_RejectJSON(context, "Invalid actuator value specified");
45                         }
46                 } break;
47                 default:
48                         FCGI_RejectJSONEx(context, 
49                                 STATUS_ERROR, "Invalid actuator id specified.");
50         }
51 }
52
53 /**
54  * System control handler. This covers control over all aspects of the system.
55  * E.g: Actuators, system commands (start/stop experiment/recording) etc
56  * @param context The context to work in
57  * @param params The input parameters
58  */
59 void Control_Handler(FCGIContext *context, char *params) {
60         const char *key, *value, *control_key = NULL;
61         const char *action = NULL, *set_value = NULL;
62         bool force = false;
63         char *ptr;
64         int id = -1;
65         
66         while ((params = FCGI_KeyPair(params, &key, &value))) {
67                 if (!strcmp(key, "action"))
68                         action = value;
69                 else if (!strcmp(key, "key"))
70                         control_key = value;
71                 else if (!strcmp(key, "force"))
72                         force = !force;
73                 else if (!strcmp(key, "id") && *value) { //Ensure non-empty value
74                         int parsed = strtol(value, &ptr, 10);
75                         if (*ptr == '\0') {
76                                 id = parsed;
77                         }
78                 } else if (!strcmp(key, "value")) {
79                         set_value = value;
80                 }
81         }
82         
83         if (action == NULL) { //Must have an action
84                 FCGI_RejectJSON(context, "No action specified");
85         } else if (!strcmp(action, "start")) {
86                 FCGI_BeginControl(context, force);
87         } else if (!strcmp(action, "stop")) { //Don't require control key to stop...
88                 //EMERGENCY STOP!! TODO - replace!
89                 FCGI_BeginJSON(context, STATUS_OK);
90                 FCGI_JSONPair("description", "stopped! (not)");
91                 FCGI_EndJSON();
92         } else { //Under this section, the user must have the current control key.
93                 if (!FCGI_HasControl(context, control_key)) {
94                         FCGI_RejectJSONEx(context, 
95                                 STATUS_UNAUTHORIZED, "Invalid control key specified.");
96                 } else if (!strcmp(action, "end")) {
97                         FCGI_EndControl(context);
98                 } else if (!strcmp(action, "set")) {
99                         if (set_value == NULL || *set_value == '\0') {
100                                 FCGI_RejectJSONEx(context, 
101                                         STATUS_ERROR, "Set called but no value specified.");
102                         } else {
103                                 ActuatorHandler(context, id, set_value);
104                         }
105                 }
106         }
107 }

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