--- /dev/null
+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
--- /dev/null
+#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"));
+ }
+}
--- /dev/null
+ #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;
+ }
--- /dev/null
+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
--- /dev/null
+#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);
+ }
+}
--- /dev/null
+<?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