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

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