diff --git a/teensy/Lualights.ino b/teensy/Lualights.ino new file mode 100644 index 0000000..c370cbe --- /dev/null +++ b/teensy/Lualights.ino @@ -0,0 +1,36 @@ +/* + Blink + Turns on an LED on for one second, then off for one second, repeatedly. + + This example code is in the public domain. + */ + +#include "lua.hpp" +#include "wifi.h" +#include "http_lib.h" +#include "log.h" +#include "leds.h" + +void setup() { + // initialize the digital pin as an output. + // Pin 13 has an LED connected on most Arduino boards: + //pinMode(13, OUTPUT); + LogOut.begin(9600); + delay(10000); + + l_init(); + setup_cc3000(); + start_http(); + setup_leds(); +} + +void loop() { + l_frame(); + listen_http(); + loop_leds(); + + //digitalWrite(13, HIGH); // set the LED on + //delay(100); // wait for a second + //digitalWrite(13, LOW); // set the LED off + //delay(100); // wait for a second +} diff --git a/teensy/Makefile b/teensy/Makefile new file mode 100644 index 0000000..305d864 --- /dev/null +++ b/teensy/Makefile @@ -0,0 +1,13 @@ +BOARD_TAG = teensy31 +ARDUINO_LIBS = Adafruit_CC3000 FastLED SPI +ARDUINO_DIR = /home/ryan/arduino/arduino-1.6.5 + +#AVR_TOOLS_DIR=/home/ryan/arduino/gcc-4.9/prefix/ + +CFLAGS += -Iinclude -Llib -llua -flto #-DSEND_NON_BLOCKING=1 +CXXFLAGS += -Iinclude -Llib -llua -flto #-DSEND_NON_BLOCKING=1 +# CPPFLAGS += -DSEND_NON_BLOCKING=1 +# LDFLAGS += -flto +OTHER_OBJS += lib/liblua.a + +include ../extern/Arduino-Makefile/Teensy.mk diff --git a/teensy/README.md b/teensy/README.md new file mode 100644 index 0000000..fcccd34 --- /dev/null +++ b/teensy/README.md @@ -0,0 +1,15 @@ +Known issues +* CC3000 related lockups happen sometimes. Working on a solution but have not found it yet. +* HTTP server is rather slow since it sends 1 byte at a time. This is related to the above problem. sending data faster seems to cause more lockups. +* Lua evaluation is rather slow as it uses emulated floating point by default. Need to recompile with integer only math. +* No way to find out what the IP of the lights are. Need to add mDNS so that you can use "lights.local." + +TODO +* mDNS support +* Better lua apis for setting large amounts of lights and calculating colors. (expose fastled apis). +* Lua http dispatching. Provide a way for lua code to create urls and respond to them. This might need an SD card for storage to do more than just an API layer. +* Maybe an http client for lua? That way you can get data from other sources? +* Add configuration options in the Makefile, to let you select what type of leds and how many you want to support +* Setup git submodules for the Arduino-mk makefile to make building easier +* Get LTO working to reduce binary size. + diff --git a/teensy/dispatch.h b/teensy/dispatch.h new file mode 100644 index 0000000..9e80d54 --- /dev/null +++ b/teensy/dispatch.h @@ -0,0 +1,63 @@ + +#include + +#define HANDLER(meth, num) void handle_ ## meth (Adafruit_CC3000_ClientRef &client) { \ + uint8_t buffer[64]; \ + memset(buffer, 0, 63); \ + \ + for (uint8_t p = 0; p < 63; p++) { \ + buffer[p] = client.read(); \ + \ + if (buffer[p] == ' ' || buffer[p] == '?') { \ + buffer[p] = 0; \ + break; \ + } \ + } \ + \ + debug_log("GOT URL: "); \ + debug_log((const char *) buffer); \ + \ + uint16_t length = sizeof(meth ## _LIST)/sizeof(meth ## _LIST[0]); \ + \ + debug_log("GET_LIST SIZE: "); \ + debug_log(length); \ + \ + for (size_t i = 0; i < length; i++) { \ + debug_log("Checking: "); \ + debug_log(i); \ + char path[64]; \ + strncpy_P(path, meth ## _LIST[i].path, 63); \ + debug_log("Path: "); \ + debug_log(path); \ + debug_logf((int) meth ## _LIST[i].path, HEX); \ + debug_logf((int) root_path, HEX); \ + \ + if (!strncmp_P((const char *)buffer, meth ## _LIST[i].path, 63)) { \ + skip_headers(client, num); \ + (* meth ## _LIST[i].function)(client, num); \ + client.println(F("\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n")); \ + return; \ + } \ + } \ + \ + give_404(client, 0); \ +} + + + +#define PUSH(x) for(int i=0; i<3; i++) buffer[i] = buffer[i+1]; buffer[3]=x; +#define CHECK_BUF (buffer[0] == '\r' && buffer[1] == '\n' && buffer[2] == '\r' && buffer[3] == '\n') + +METHOD(skip_headers) { + uint8_t buffer[4] = {0,0,0,0}; + uint8_t c; + + // Look for a \r\n\r\n pattern in the incoming data, that'll be the end of the headers + while(! CHECK_BUF) { + c = client.read(); + PUSH(c); + } +} + +HANDLER(GET, 0); +HANDLER(POST, 1); diff --git a/teensy/docs.h b/teensy/docs.h new file mode 100644 index 0000000..5ade65c --- /dev/null +++ b/teensy/docs.h @@ -0,0 +1,6 @@ +const char doc_gzip[] = { +0x1f, 0x8b, 0x08, 0x00, 0x8c, 0x1e, 0x7c, 0x54, 0x00, 0x03, 0x9d, 0x52, 0x5d, 0x4f, 0x83, 0x30, 0x14, 0x7d, 0xef, 0xaf, 0xb8, 0x8f, 0x1a, 0x58, 0xe6, 0xd4, 0xf9, 0xa0, 0x89, 0xc9, 0x82, 0xfb, 0xd2, 0x39, 0x8c, 0x23, 0xf1, 0xc1, 0x28, 0xa9, 0x50, 0x07, 0x19, 0x6b, 0x4d, 0x29, 0x33, 0xc6, 0xf9, 0xdf, 0xbd, 0x2d, 0x03, 0x61, 0x81, 0x68, 0xbc, 0x2f, 0xed, 0xed, 0x3d, 0xe7, 0xdc, 0xd3, 0xdb, 0x0e, 0x92, 0x04, 0xde, 0xa8, 0x8a, 0x52, 0x50, 0x74, 0xc5, 0xe0, 0xce, 0x5d, 0x78, 0x40, 0x53, 0x78, 0x15, 0x72, 0x0d, 0x8c, 0x07, 0x22, 0x8c, 0xf9, 0x12, 0x28, 0x0f, 0x41, 0x32, 0x95, 0x49, 0xae, 0x6b, 0xd7, 0x0b, 0x77, 0x4e, 0xc8, 0x60, 0x43, 0xe3, 0x84, 0xbe, 0x24, 0xc8, 0xd1, 0xf4, 0x73, 0xd2, 0x85, 0x0e, 0x78, 0x51, 0x9c, 0xc2, 0x95, 0x08, 0xb2, 0x35, 0xe3, 0x0a, 0x0e, 0xc6, 0x43, 0xef, 0x90, 0x74, 0x53, 0xa6, 0x14, 0xaa, 0xa4, 0xdd, 0x20, 0x93, 0x12, 0xcf, 0xbb, 0x81, 0x48, 0x84, 0x44, 0xb4, 0x93, 0xe7, 0x90, 0xe7, 0x1a, 0x6d, 0x1b, 0x03, 0x87, 0xf0, 0x28, 0x6d, 0x58, 0xda, 0xf0, 0xf2, 0xd4, 0xc0, 0x0e, 0xa9, 0x5c, 0x21, 0x79, 0x16, 0x2f, 0x23, 0x05, 0x2a, 0x92, 0x2c, 0x8d, 0x44, 0x12, 0xc2, 0x51, 0xa7, 0x77, 0x74, 0x7c, 0x5a, 0x57, 0xd1, 0xd0, 0x26, 0x09, 0x15, 0xaf, 0x19, 0x4a, 0x2c, 0x58, 0x20, 0x78, 0x88, 0x37, 0x17, 0x90, 0x2a, 0xfa, 0x01, 0x82, 0xa3, 0xca, 0x59, 0xbf, 0x7f, 0xd2, 0xaf, 0xcb, 0x68, 0xb8, 0x96, 0x51, 0x54, 0x65, 0x69, 0xd1, 0xbf, 0x30, 0x9f, 0x18, 0x1f, 0x92, 0x51, 0x33, 0x29, 0x73, 0xe5, 0x9f, 0xc6, 0x39, 0x63, 0xd7, 0xae, 0x60, 0x98, 0x74, 0x07, 0xac, 0x4b, 0xeb, 0xa5, 0x8a, 0xcc, 0xf3, 0x47, 0xb3, 0x3c, 0x11, 0xb2, 0xd0, 0x2b, 0x4e, 0x9a, 0xf1, 0x0c, 0x1f, 0xc7, 0xcf, 0xab, 0x9f, 0x0f, 0x83, 0xa9, 0x37, 0x9d, 0x8f, 0x6d, 0x98, 0x4d, 0xc7, 0x13, 0xcf, 0x77, 0x26, 0x43, 0xe7, 0xa6, 0x48, 0xdc, 0x79, 0xb1, 0xf3, 0xa6, 0xb7, 0x43, 0x1b, 0x46, 0xee, 0xbd, 0x33, 0xf4, 0xdd, 0xd1, 0xa8, 0xdc, 0xce, 0xbf, 0xf2, 0x2e, 0x17, 0x84, 0x40, 0x25, 0xb8, 0x00, 0x73, 0xcf, 0x3f, 0xc7, 0x5a, 0xa8, 0x58, 0x70, 0xd4, 0xb0, 0x3a, 0x8d, 0x61, 0xb5, 0x11, 0x5b, 0xf0, 0x9a, 0x82, 0x6a, 0x9b, 0x66, 0xd2, 0xb6, 0x4d, 0xad, 0x05, 0xaf, 0x29, 0xc4, 0xaa, 0x9a, 0xc9, 0xfd, 0x36, 0x18, 0xc0, 0xda, 0xee, 0xe6, 0x56, 0xed, 0x10, 0x27, 0x52, 0x72, 0x6a, 0x14, 0x8b, 0x6c, 0xe1, 0x9d, 0xc6, 0xfa, 0x87, 0xa1, 0xaf, 0xf2, 0xf8, 0x12, 0x13, 0xf3, 0x37, 0xfc, 0x20, 0x62, 0xc1, 0xaa, 0x57, 0xd6, 0x7e, 0x0a, 0xa8, 0x55, 0x21, 0x54, 0x2b, 0xe6, 0x8b, 0xec, 0x39, 0x6e, 0x1d, 0x99, 0xd5, 0x54, 0xd8, 0x9b, 0xf7, 0x9e, 0x63, 0x80, 0xe7, 0xb2, 0xa4, 0x7b, 0x89, 0x4c, 0xb5, 0x0e, 0xee, 0xb7, 0xd8, 0xb6, 0x3f, 0xfa, 0x3f, 0xc2, 0x22, 0xe4, 0x1b, 0x12, 0xe3, 0x7d, 0x55, 0x93, 0x04, 0x00, 0x00, }; +const char inter_head[] = { +0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0x4c, 0x75, 0x61, 0x20, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x73, 0x20, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x20, 0x20, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x30, 0x30, 0x25, 0x3b, 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x31, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x72, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x64, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x35, 0x30, 0x25, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x22, 0x31, 0x30, 0x30, 0x25, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x6e, 0x6f, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x75, 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x79, 0x65, 0x74, 0x20, 0x2d, 0x2d, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x22, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x70, 0x6f, 0x73, 0x74, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x20, 0x72, 0x6f, 0x77, 0x73, 0x3d, 0x22, 0x34, 0x30, 0x22, 0x20, 0x63, 0x6f, 0x6c, 0x73, 0x3d, 0x22, 0x31, 0x30, 0x30, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x70, 0x72, 0x67, 0x6d, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x70, 0x72, 0x67, 0x6d, 0x22, 0x3e, 0x0a, 00}; +const char inter_foot[] = { +0x3c, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x3e, 0x0a, 0x3c, 0x62, 0x72, 0x20, 0x2f, 0x3e, 0x0a, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x20, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x22, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x64, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x35, 0x30, 0x25, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x69, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x39, 0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x31, 0x2e, 0x32, 0x31, 0x35, 0x2f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x22, 0x31, 0x30, 0x30, 0x25, 0x22, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x31, 0x30, 0x30, 0x25, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x0a, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a, 00}; diff --git a/teensy/docs.txt b/teensy/docs.txt new file mode 100644 index 0000000..b862dd6 --- /dev/null +++ b/teensy/docs.txt @@ -0,0 +1,23 @@ +All paths take POST as form encoding and return as JSON + +Available Paths: +/ - This Document (GET) +/settings/current/color - Current color (GET, POST) [r, g, b] +/settings/current/dark - Light threshold 0-1024 (GET, POST) [dark] +/settings/current/time - Seconds to stay on 0-65535 (GET, POST) [time] +/status/dark - Current light reading (GET) [dark] +/status/time - Current time (GET) [time] +/status/state - Current state [state] + +States: +enum e_state {WAITING, LIGHT_CHECK, LIGHT_ON, LIGHT_TIME, FORCE_OFF, FORCE_ON} state; + + no dark motion + +----------------------+ +-------------------------+ + v | v | ++---------+ motion +--------------+ dark +----------+ no motion +------------+ +| waiting | ---------> | light_check1 | ------> | light_on | -----------> | light_time | ++---------+ +--------------+ +----------+ +------------+ + ^ timeout | + +-------------------------------------------------------------------------+ + diff --git a/teensy/gen_docs.sh b/teensy/gen_docs.sh new file mode 100755 index 0000000..507846e --- /dev/null +++ b/teensy/gen_docs.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +echo const char doc_gzip[] = { +cat docs.txt | gzip -c | hexdump -ve '1/1 "0x%.2x, "' +echo }\; + +echo const char inter_head[] = { +cat int_head.html | hexdump -ve '1/1 "0x%.2x, "' +echo 00}\; + +echo const char inter_foot[] = { +cat int_foot.html | hexdump -ve '1/1 "0x%.2x, "' +echo 00}\; diff --git a/teensy/handlers.h b/teensy/handlers.h new file mode 100644 index 0000000..d25d45b --- /dev/null +++ b/teensy/handlers.h @@ -0,0 +1,170 @@ +#include "docs.h" +#include "log.h" +#include "lua.hpp" + +const int GET = 0; +const int POST = 1; + +#define METHOD(x) void x (Adafruit_CC3000_ClientRef &client, int method) + +METHOD(give_200) { + client.fastrprint("HTTP/1.0 200 OK\r\n" + "Server: MiniC HTTPD 0.1\r\n" + "\r\n"); +} + +METHOD(give_400) { + client.fastrprint("HTTP/1.0 400 Bad Request\r\n" + "Server: MiniC HTTPD 0.1\r\n" + "\r\n"); +} + +METHOD(give_404) { + client.fastrprint("HTTP/1.0 404 Not Found\r\n" + "Server: MiniC HTTPD 0.1\r\n" + "\r\n"); + client.fastrprint("Not found\r\n"); +} + +METHOD(give_200_gzip) { + client.fastrprint("HTTP/1.0 200 OK\r\n" + "Server: MiniC HTTPD 0.1\r\n" + "Content-Encoding: gzip\r\n" + "\r\n"); +} + +// Helpers +int read_name(Adafruit_CC3000_ClientRef &client, char *str) { + uint8_t i = 0,c = 0; + for (i=0; i<16 && c != '='; i++) { + c = client.read(); + str[i] = c; + } + + str[i-1] = 0; // end the string + + return i; +} + +int read_value(Adafruit_CC3000_ClientRef &client, char *str) { + uint8_t i = 0,c = 0; + + for (i=0; i<16 && c != '&' && client.available(); i++) { + c = client.read(); + str[i] = c; + } + + if (str[i-1] == '&') + str[i-1] = 0; + + return i; +} + +// METHODS +METHOD(root) { + give_200_gzip(client, method); + + for (uint16_t i = 0; i < sizeof(doc_gzip); i++) + client.write(pgm_read_byte(&doc_gzip[i])); +} + +/* Converts a hex character to its integer value */ +char from_hex(char ch) { + return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10; +} + +METHOD(interface) { + if (method == GET) { + give_200(client, method); + for (uint16_t i = 0; i < sizeof(inter_head); i++) + client.write(pgm_read_byte(&inter_head[i])); + + for (uint16_t i = 0; i < sizeof(l_prog_buff) && l_prog_buff[i]; i++) + client.write(pgm_read_byte(&l_prog_buff[i])); + + for (uint16_t i = 0; i < sizeof(inter_foot); i++) + client.write(pgm_read_byte(&inter_foot[i])); + } else { + if (client.available()) { + char name[16]; + read_name(client, name); + + if (!strncmp(name, "prgm", 16)) { + int i = 0; + char c; + memset(l_prog_buff, 0, sizeof(l_prog_buff)); + for (i = 0; i < sizeof(l_prog_buff) && client.available(); i++) { + c = client.read(); + + if (c != '+' && c != '%') { // non-encoded char + l_prog_buff[i] = c; + } else if (c == '+') { // url encoded space + l_prog_buff[i] = ' '; + } else if (c == '%') { // % encoded string + char a, b; + a = client.read(); + b = client.read(); + + c = from_hex(a) << 4 | from_hex(b); + l_prog_buff[i] = c; + } + } + + output_log("\n"); + output_log("Program loaded, compiling...\n"); + l_stop(); + l_start(l_prog_buff); + } + } + + interface(client, GET); // give back the same GET output that we had before + } +} + + + +METHOD(output) { + give_200(client, method); + + char *p = log_curpos+1; + if (p - log_ringbuffer >= LOG_RINGSIZE) + p = log_ringbuffer; + + + client.fastrprint("
");
+  while(p != log_curpos) {
+    if (*p)
+      client.write(*p);
+
+    p++;
+
+    if (p - log_ringbuffer >= LOG_RINGSIZE)
+      p = log_ringbuffer;    
+  }
+  client.fastrprint("
"); +} + +// Setup the path resolver +struct method_resolve { + const prog_char *path; + void (*function)(Adafruit_CC3000_ClientRef&, int method); +}; + +#define FPATH(x) const prog_char x [] PROGMEM +#define ROUTE(m, p) {(const prog_char *) &p [0], m} + +FPATH(root_path) = "/"; +FPATH(output_path) = "/output"; +FPATH(interface_path) = "/interface"; + +method_resolve GET_LIST[] = { + ROUTE(root, root_path), + ROUTE(output, output_path), + ROUTE(interface, interface_path), +}; + +method_resolve POST_LIST[] = { + ROUTE(root, root_path), + ROUTE(interface, interface_path), +}; + diff --git a/teensy/http_lib.cpp b/teensy/http_lib.cpp new file mode 100644 index 0000000..4ff9351 --- /dev/null +++ b/teensy/http_lib.cpp @@ -0,0 +1,47 @@ +#include "log.h" +#include "http_lib.h" +#include "handlers.h" +#include "dispatch.h" +#include + +Adafruit_CC3000_Server httpServer(80); + +void start_http() { + httpServer.begin(); +} + +void read_method(Adafruit_CC3000_ClientRef &client) { + uint8_t method[9]; + + for (uint8_t i = 0; i < 8; i++) { + method[i] = client.read(); + if (method[i] == ' ') { + method[i] = 0; + break; + } + } + + if (!strncmp((const char *) method, "GET", 8)) { + handle_GET(client); + } else if (!strncmp((const char *) method, "POST", 8)) { + handle_POST(client); + } else { + // return a 400 to anything else. + client.fastrprint("HTTP/1.0 400 Bad Request\r\n" + "Server: MiniC HTTPD 0.1\r\n" + "\r\n" + "The fuck is wrong with you trying other methods?\r\n"); + } +} + +void listen_http() { + Adafruit_CC3000_ClientRef client = httpServer.available(); + + if (client) { + debug_log("GOT REQUEST, READING METHOD"); + read_method(client); + client.close(); + } + + client.close(); +} diff --git a/teensy/http_lib.h b/teensy/http_lib.h new file mode 100644 index 0000000..1ae0fca --- /dev/null +++ b/teensy/http_lib.h @@ -0,0 +1,10 @@ +#ifndef __LUALIGHTS_HTTP_LIB_H +#define __LUALIGHTS_HTTP_LIB_H + +#include + +extern Adafruit_CC3000_Server httpServer; +void start_http(); +void listen_http(); + +#endif \ No newline at end of file diff --git a/teensy/int_foot.html b/teensy/int_foot.html new file mode 100644 index 0000000..4da8732 --- /dev/null +++ b/teensy/int_foot.html @@ -0,0 +1,12 @@ + +
+ + + + +