summaryrefslogtreecommitdiff
path: root/guardian.c
diff options
context:
space:
mode:
Diffstat (limited to 'guardian.c')
-rw-r--r--guardian.c153
1 files changed, 153 insertions, 0 deletions
diff --git a/guardian.c b/guardian.c
index 0e6d93c..5b5c99d 100644
--- a/guardian.c
+++ b/guardian.c
@@ -4,6 +4,8 @@
#include<ctype.h>
#include <sys/types.h>
#include <dirent.h>
+#include "rs232.h"
+#include <unistd.h>
/* struct describing the various templates that alerts can use
* these are loaded from /etc/squishy
*/
@@ -33,6 +35,10 @@ struct template {
struct template * * templates;
unsigned int templates_len = 0;
/*
+ * Comport number of the comport in use
+ */
+int comport_number;
+/*
* Reads alert template from file, returns null on failure, otherwise returns
* pointer to the template w/ all data already allocated by the function
*/
@@ -292,6 +298,11 @@ char * str_concat(char * s1, char * s2) {
strncpy(return_str + strlen(s1) + strlen(s2) ,"\0", sizeof(char) * 1);
return return_str;
}
+/*
+ * Loads all templates
+ * looks in templates/
+ * returns NULL on error
+ */
struct template * * load_templates() {
/*ensures that templates is alteast 1 element big*/
struct template * * templates = (struct template * *)malloc(sizeof(struct template * ));
@@ -347,6 +358,12 @@ struct template * * load_templates() {
closedir(templates_dir);
return templates;
}
+/*
+ * Sends alert to all pseudoterminals the process has permission to
+ * returns -1 on error
+ * template_name is used to select a template and not a pointer to a template
+ * class, this way broadcast handles template selection directly from arguments
+ */
int broadcast(char * template_name, char * message) {
struct template * tm = NULL;
/*
@@ -409,13 +426,149 @@ int broadcast(char * template_name, char * message) {
}
} while (pts_entry != NULL);
}
+/*
+ * Initializes RS232 connection with the guardian, returns -1 on error
+ */
+int startcom (char * device_path) {
+ comport_number = -1;
+ /*
+ * Looks for device in the RS232 library array comports that match the
+ * device specified by the user. If one is not found then comport_number
+ * will remain -1;
+ */
+ for (int i = 0; i < 38; i++) {
+ if (strcmp(comports[i], device_path) == 0) {
+ comport_number = i;
+ }
+ }
+ /*
+ * Deals with the condition described above
+ */
+ if (comport_number == -1 ) {
+ fprintf(stderr, "Could not find device %s\n",device_path);
+ return -1;
+ }
+ /*
+ * Opens RS232 Connection w/ the Guardian. The connection is at
+ * 9600baud. 8N1 means 8 data bits and no parity bits
+ */
+ int err = RS232_OpenComport(comport_number ,9600,"8N1");
+ if (err != 0) {
+ fprintf(stderr, "Error opening comport %s, number %d\n",
+ device_path, comport_number);
+ return -1;
+ }
+ /* waits for arduino to respond, this indicates that it is ready to
+ * accept commands. We know for a fact that the response is less than
+ * 256 bytes so the buffer is more than safe
+ */
+ char poll_buffer[256];
+ /*
+ * Timeout is implemented with a timer w/ no regard to actual time
+ * passed. For now it will be 200 tries
+ */
+ int timeout = 0;
+ do {
+ /*On EAGAIN( no data), the function returns 0, however if there
+ * is an error it returns <0. Otherwise it returns the number of
+ * bytes read
+ */
+ err = RS232_PollComport(comport_number, poll_buffer, 256);
+ timeout++;
+ /*
+ * Checks for timeout
+ */
+ if (timeout >= 200) {
+ fprintf(stderr, "Polling %s timed out\n",device_path);
+ err = -1;
+ }
+
+ } while (err == 0);
+ if (err < 0) {
+ fprintf(stderr, "Error polling from comport %s, number %d\n",
+ device_path, comport_number);
+ return -1;
+ }
+ return 0;
+}
+/*
+ * Makes the Guardian block the keyboard, returns -1 on error
+ */
+int slap(char pos) {
+ /* positions commands are sent in the form of
+ * p[int] where the letter 'p' is followed by an integer ranging 0 to
+ * 180 that determines the angle of the servo. We will cast this as an
+ * char for simplicity. On the microcontroller side this gets casted
+ * into an int 180 flat to the extreme
+ * ------
+ * =====O | 180 Degrees
+ * ------
+ *
+ * |
+ * __|___
+ * | O | 90 Degrees
+ * ------
+ */
+ char command[2] = {'p', pos};
+ int error = RS232_SendBuf(comport_number,command, 2);
+ if (error != 0) {
+ fprintf(stderr, "Error sending command to comport %d\n",
+ comport_number);
+ return error;
+ }
+ return 0;
+}
int main (int argc, char * argv[]) {
+
+ /*
+ * Checks for the proper number of arguments, also checks for argv[1] ==
+ * "raise" and there are 2 arguments.
+ */
+ if (argc < 4) {
+ /*
+ * Tests for raise
+ */
+ if (argc >= 3) {
+ if (strcmp(argv[1], "raise") == 0 ) {
+ /*
+ * Starts com based on 2nd argument device and
+ * raises the arm
+ */
+ startcom(argv[2]);
+ slap(90);
+ /* exits */
+ return 0;
+ }
+ }
+ /*
+ * Not enough arguments, display help and exit
+ */
+ fprintf(stdout, "Usage: guardian [template] [message] [guardian\
+ device]\n\
+ OR guardian raise");
+ return -1;
+ }
+ /*
+ * Loads templates for the alert
+ */
templates = load_templates();
if (templates == NULL) {
return -1;
}
+ /*
+ * Sends the alert to all pttys
+ */
if (broadcast(argv[1],argv[2])) {
return -1;
}
+ /*
+ * Starts serial communications w/ the Arduino, uses 3rd argument as the
+ * device to connect to.
+ */
+ startcom(argv[3]);
+ /*
+ * For normal operation it lowers the arm
+ */
+ slap(180);
}