Merge branch 'master' of https://github.com/szmoore/MCTX3420.git
authorJeremy Tan <[email protected]>
Thu, 15 Aug 2013 00:29:58 +0000 (08:29 +0800)
committerJeremy Tan <[email protected]>
Thu, 15 Aug 2013 00:29:58 +0000 (08:29 +0800)
testing/fastcgi-approach/README.txt [new file with mode: 0644]
testing/fastcgi-approach/fastcgi_test.c [new file with mode: 0644]
testing/fastcgi-approach/nginx_server_config.txt [new file with mode: 0644]
testing/sqlite-approach/README.txt [new file with mode: 0644]
testing/sqlite-approach/db/data.db [new file with mode: 0644]
testing/sqlite-approach/testapp/test.c [new file with mode: 0644]
testing/sqlite-approach/www/sqlite.php [new file with mode: 0644]

diff --git a/testing/fastcgi-approach/README.txt b/testing/fastcgi-approach/README.txt
new file mode 100644 (file)
index 0000000..29cfd2c
--- /dev/null
@@ -0,0 +1,20 @@
+The application could be quite easily made to use FastCGI. Unlike normal CGI,
+with FastCGI (fcgi), the process is executed once, and continues to run. The
+process will receive responses from the browser in the response loop. Hence,
+sensor data can be read in another thread while the response loop runs.
+
+Setup:
+Compile fastcgi_test.c with: (the libfcgi-dev package must be installed)
+gcc fastcgi_test.c -lfcgi -o fastcgi_test
+
+Configure nginx to pass all requests to the address /cgi/ to the application:
+Edit /etc/nginx/sites-enabled/default by adding the contents of nginx_server_config.txt
+
+Restart nginx:
+/etc/init.d/nginx restart
+
+Run the application:
+spawn-fcgi -p9005 -n ./fastcgi_test
+
+You can see the results at:
+http://your.domain/cgi
\ No newline at end of file
diff --git a/testing/fastcgi-approach/fastcgi_test.c b/testing/fastcgi-approach/fastcgi_test.c
new file mode 100644 (file)
index 0000000..40543c6
--- /dev/null
@@ -0,0 +1,67 @@
+#include "fcgi_stdio.h" /* fcgi library; put it first*/
+#include <stdlib.h>
+
+/*
+       But the suggestion was: FunctionName, variable_name (local or member),
+    Structure, ENUMVALUE, Extern_FunctionName, g_global
+*/
+
+typedef struct Data Data;
+
+typedef void (*ModuleHandler) (Data *data, const char *params);
+
+static void SensorsHandler(Data *data, const char *params) {
+    printf("Sensors module!<br>");
+}
+
+/*
+   API Schema:
+   Sensors:
+   /cgi/sensors?get=x
+   *get=x is optional. Retrieves info for sensor with id x
+   Devices:
+   /cgi/devices?status=x&power=y&id=z
+   *status and power is optional
+   *status retrieves whether device with id x is operational
+   *power tells whether or not to power on/off the device with id z
+   
+   Response format:
+   200 OK if request was ok
+   400 bad request for malformed request
+      
+*/
+int main (int argc, char *argv[])
+{
+  Data *data = NULL;
+  int count = 0;
+
+  //FCGI Accept loop
+  while (FCGI_Accept() >= 0)   {
+    ModuleHandler module_handler = NULL;
+    const char *module = getenv("DOCUMENT_URI_LOCAL");
+    const char *params = getenv("QUERY_STRING");
+
+    if (!strcmp("sensors", module)) {
+        module_handler = SensorsHandler; //Replace with pointer to sensors handler
+    } else if (!strcmp("admin"), module) {
+        module_handler = NULL; //Replace with pointer to admin handler
+        printf("Admin module selected!\n");
+    }
+    
+    if (module_handler) {
+        printf("Content-type: text/html\r\n\r\n"); //Replace with actual type
+        module_handler(data, params);
+    } else {
+        printf("Status: 400 Bad Request\r\n"
+               "Content-type: text/html\r\n\r\n"
+               "<title>400 Bad Request</title>\n"
+               "Unknown module '%s' selected.<br>\n",
+               module);   
+    }
+    
+    //Debgging:
+    printf("Module: %s, Params: %s<br>\n", module, params);
+    printf("Request number %d, host <i>%s</i>\n",
+        count++, getenv("SERVER_HOSTNAME"));
+  }
+}
diff --git a/testing/fastcgi-approach/nginx_server_config.txt b/testing/fastcgi-approach/nginx_server_config.txt
new file mode 100644 (file)
index 0000000..c76a4e5
--- /dev/null
@@ -0,0 +1,27 @@
+        #Custom cgi
+        location ~ ^/cgi/([^?]*) {
+                fastcgi_pass 127.0.0.1:9005;
+                fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
+                fastcgi_param  SERVER_HOSTNAME    mctxsoft;
+                fastcgi_param  SERVER_SOFTWARE    nginx;
+
+                #Regex removed /cgi/ part, and any args
+                fastcgi_param  DOCUMENT_URI_LOCAL  $1;
+                fastcgi_param  QUERY_STRING       $query_string;
+
+                #Unused for now
+                fastcgi_param  REQUEST_METHOD     $request_method;
+                fastcgi_param  CONTENT_TYPE       $content_type;
+                fastcgi_param  CONTENT_LENGTH     $content_length;
+                fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script$
+                fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
+                fastcgi_param  REQUEST_URI        $request_uri;
+                fastcgi_param  DOCUMENT_URI       $document_uri;
+                fastcgi_param  DOCUMENT_ROOT      $document_root;
+                fastcgi_param  SERVER_PROTOCOL    $server_protocol;
+                fastcgi_param  REMOTE_ADDR        $remote_addr;
+                fastcgi_param  REMOTE_PORT        $remote_port;
+                fastcgi_param  SERVER_ADDR        $server_addr;
+                fastcgi_param  SERVER_PORT        $server_port;
+                fastcgi_param  SERVER_NAME        $server_name;
+        }
diff --git a/testing/sqlite-approach/README.txt b/testing/sqlite-approach/README.txt
new file mode 100644 (file)
index 0000000..8f2e398
--- /dev/null
@@ -0,0 +1,14 @@
+Note: Should be discarded in favour of the fastcgi approach
+
+SQLite approach to interfacing with web frontend:
+
+*Main program reads in sensor data and updates the sqlite database 
+ with this new data
+*When sqlite.php is called, the database is queried, and the values returned
+ to the caller (format can be anything you like)
+*You could have a main webpage, ie index.html
+*Whenever you need to update the page, you use jQuery (or other method)
+ to call sqlite.php, which returns the data needed
+
+This works because SQLite allows concurrent access to the database
+(or it should).
\ No newline at end of file
diff --git a/testing/sqlite-approach/db/data.db b/testing/sqlite-approach/db/data.db
new file mode 100644 (file)
index 0000000..4d7095b
Binary files /dev/null and b/testing/sqlite-approach/db/data.db differ
diff --git a/testing/sqlite-approach/testapp/test.c b/testing/sqlite-approach/testapp/test.c
new file mode 100644 (file)
index 0000000..cd6e850
--- /dev/null
@@ -0,0 +1,52 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sqlite3.h>
+
+static void updateSensor(sqlite3* db, int id, int value);
+
+int main(int argc, char *argv[]) {
+       if (argc != 2) {
+               printf ("Usage: %s db_location\n", argv[0]);
+               return 1;
+       }
+
+       sqlite3* db;
+       int ret;
+
+       if (ret = sqlite3_open(argv[1], &db) != SQLITE_OK) {
+               printf("Error opening database: %s\n",
+                       sqlite3_errstr(ret));
+               return 1;
+       }
+
+       sqlite3_stmt *statement;
+       char *query = "insert into sensors values(3,4)";
+       if (ret = sqlite3_prepare(db, query, (int)strlen(query) + 1, &statement, NULL) != SQLITE_OK) {
+               printf("Error in query: %s\n",
+                       sqlite3_errstr(ret));
+       }
+
+       sqlite3_step(statement);
+       sqlite3_finalize(statement);
+
+       updateSensor(db, 44, 2332);
+       sqlite3_close(db);
+       return 0;
+}
+
+static void updateSensor(sqlite3* db, int id, int value) {
+       char query[BUFSIZ];
+       snprintf(query, BUFSIZ, "update sensors set value=%d where id=%d", value, id);
+
+       //Needs error checking
+       int ret;
+       if (ret = sqlite3_exec(db, query, NULL, NULL, NULL) != SQLITE_OK) {
+               printf("Error: %s\n", sqlite3_errstr(ret));
+       }
+       if (!sqlite3_changes(db)) {
+               printf("Record doesn't exist; creating!\n");
+               snprintf(query, BUFSIZ, "insert into sensors values(%d, %d)", id, value);
+               sqlite3_exec(db, query, NULL, NULL, NULL);
+       }
+}
diff --git a/testing/sqlite-approach/www/sqlite.php b/testing/sqlite-approach/www/sqlite.php
new file mode 100644 (file)
index 0000000..bd8496e
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+       class MyDB extends SQLite3
+       {
+               function __construct()
+               {
+                       $this->open('../db/data.db');
+               }
+
+               function getSensorValue($id)
+               {
+                       //needs error checking, but you get the idea
+                       $ret = $this->query("select value from sensors where sensor_id={$id}");
+                       $row = $ret->fetchArray(SQLITE3_NUM);
+                       return $row[0];
+               }
+       }
+
+       $db = new MyDB();
+       if (!$db) {
+               echo $db->lastErrorMsg();
+       } else {
+               echo "yay<br>\n";
+       }
+
+       $ret = $db->query('SELECT * from test');
+       while ($row = $ret->fetchArray(SQLITE3_ASSOC)) {
+               echo "NUM = ". $row['num'] . "<br>\n";
+       }
+
+       echo "Sensor 1 value: " . $db->getSensorValue(1). "<br>\n";
+       $db->close();
+
+?>
\ No newline at end of file

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