Getting ready for release...

v0.9.0
Jeroen Domburg 10 years ago
parent 290fe32e46
commit aef27aaa5b
  1. 5
      Makefile
  2. 44
      driver/Makefile
  3. 248
      driver/uart.c
  4. 13
      html/led.html
  5. 7
      html/test.html
  6. 12
      html/test2.html
  7. 10
      html/test3.html
  8. 103
      include/driver/uart.h
  9. 128
      include/driver/uart_register.h
  10. 1
      include/espmissingincludes.h
  11. 7
      mkespfsimage/Makefile
  12. 205
      user/cgi.c
  13. 6
      user/cgi.h
  14. 42
      user/espfs.c
  15. 1
      user/heatshrink_config_httpd.h
  16. 41
      user/httpd.c
  17. 6
      user/httpd.h
  18. 14
      user/httpdespfs.c
  19. 11
      user/io.c
  20. 21
      user/user_main.c

@ -14,6 +14,9 @@ FW_BASE = firmware
# Base directory for the compiler # Base directory for the compiler
XTENSA_TOOLS_ROOT ?= /opt/Espressif/crosstool-NG/builds/xtensa-lx106-elf/bin XTENSA_TOOLS_ROOT ?= /opt/Espressif/crosstool-NG/builds/xtensa-lx106-elf/bin
#Extra Tensilica includes from the ESS VM
SDK_EXTRA_INCLUDES ?= /opt/Espressif/include
# base directory of the ESP8266 SDK package, absolute # base directory of the ESP8266 SDK package, absolute
SDK_BASE ?= /opt/Espressif/ESP8266_SDK SDK_BASE ?= /opt/Espressif/ESP8266_SDK
@ -29,7 +32,7 @@ MODULES = driver user
EXTRA_INCDIR = include \ EXTRA_INCDIR = include \
. \ . \
lib/heatshrink/ \ lib/heatshrink/ \
./../esp_iot_sdk_novm_unpacked/usr/xtensa/XtDevTools/install/builds/RC-2010.1-win32/lx106/xtensa-elf/include/ $(SDK_EXTRA_INCLUDES)
# libraries used in this project, mainly provided by the SDK # libraries used in this project, mainly provided by the SDK
LIBS = c gcc hal phy net80211 lwip wpa main LIBS = c gcc hal phy net80211 lwip wpa main

@ -1,44 +0,0 @@
#############################################################
# Required variables for each makefile
# Discard this section from all parent makefiles
# Expected variables (with automatic defaults):
# CSRCS (all "C" files in the dir)
# SUBDIRS (all subdirs with a Makefile)
# GEN_LIBS - list of libs to be generated ()
# GEN_IMAGES - list of images to be generated ()
# COMPONENTS_xxx - a list of libs/objs in the form
# subdir/lib to be extracted and rolled up into
# a generated lib/image xxx.a ()
#
ifndef PDIR
GEN_LIBS = libdriver.a
endif
#############################################################
# Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here!
# Generally values applying to a tree are captured in the
# makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein
#
#DEFINES +=
#############################################################
# Recursion Magic - Don't touch this!!
#
# Each subtree potentially has an include directory
# corresponding to the common APIs applicable to modules
# rooted at that subtree. Accordingly, the INCLUDE PATH
# of a module can only contain the include directories up
# its parent path, and not its siblings
#
# Required for each makefile to inherit from the parent
#
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile

@ -1,248 +0,0 @@
/******************************************************************************
* Copyright 2013-2014 Espressif Systems (Wuxi)
*
* FileName: uart.c
*
* Description: Two UART mode configration and interrupt handler.
* Check your hardware connection while use this mode.
*
* Modification history:
* 2014/3/12, v1.0 create this file.
*******************************************************************************/
#include "espmissingincludes.h"
#include "ets_sys.h"
#include "osapi.h"
#include "driver/uart.h"
#include "driver/uart_register.h"
//#include "ssc.h"
//#include "at.h"
// UartDev is defined and initialized in rom code.
extern UartDevice UartDev;
//extern os_event_t at_recvTaskQueue[at_recvTaskQueueLen];
LOCAL void uart0_rx_intr_handler(void *para);
/******************************************************************************
* FunctionName : uart_config
* Description : Internal used function
* UART0 used for data TX/RX, RX buffer size is 0x100, interrupt enabled
* UART1 just used for debug output
* Parameters : uart_no, use UART0 or UART1 defined ahead
* Returns : NONE
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
uart_config(uint8 uart_no)
{
if (uart_no == UART1)
{
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK);
}
else
{
/* rcv_buff size if 0x100 */
ETS_UART_INTR_ATTACH(uart0_rx_intr_handler, &(UartDev.rcv_buff));
PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD);
// PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS);
}
uart_div_modify(uart_no, UART_CLK_FREQ / (UartDev.baut_rate));
WRITE_PERI_REG(UART_CONF0(uart_no), UartDev.exist_parity
| UartDev.parity
| (UartDev.stop_bits << UART_STOP_BIT_NUM_S)
| (UartDev.data_bits << UART_BIT_NUM_S));
//clear rx and tx fifo,not ready
SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
//set rx fifo trigger
// WRITE_PERI_REG(UART_CONF1(uart_no),
// ((UartDev.rcv_buff.TrigLvl & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) |
// ((96 & UART_TXFIFO_EMPTY_THRHD) << UART_TXFIFO_EMPTY_THRHD_S) |
// UART_RX_FLOW_EN);
if (uart_no == UART0)
{
//set rx fifo trigger
WRITE_PERI_REG(UART_CONF1(uart_no),
((0x01 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) |
((0x01 & UART_RX_FLOW_THRHD) << UART_RX_FLOW_THRHD_S) |
UART_RX_FLOW_EN);
}
else
{
WRITE_PERI_REG(UART_CONF1(uart_no),
((UartDev.rcv_buff.TrigLvl & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S));
}
//clear all interrupt
WRITE_PERI_REG(UART_INT_CLR(uart_no), 0xffff);
//enable rx_interrupt
SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA);
}
/******************************************************************************
* FunctionName : uart1_tx_one_char
* Description : Internal used function
* Use uart1 interface to transfer one char
* Parameters : uint8 TxChar - character to tx
* Returns : OK
*******************************************************************************/
LOCAL STATUS
uart_tx_one_char(uint8 uart, uint8 TxChar)
{
while (true)
{
uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT<<UART_TXFIFO_CNT_S);
if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) {
break;
}
}
WRITE_PERI_REG(UART_FIFO(uart) , TxChar);
return OK;
}
/******************************************************************************
* FunctionName : uart1_write_char
* Description : Internal used function
* Do some special deal while tx char is '\r' or '\n'
* Parameters : char c - character to tx
* Returns : NONE
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
uart0_write_char(char c)
{
if (c == '\n')
{
uart_tx_one_char(UART0, '\r');
uart_tx_one_char(UART0, '\n');
}
else if (c == '\r')
{
}
else
{
uart_tx_one_char(UART0, c);
}
}
/******************************************************************************
* FunctionName : uart0_tx_buffer
* Description : use uart0 to transfer buffer
* Parameters : uint8 *buf - point to send buffer
* uint16 len - buffer len
* Returns :
*******************************************************************************/
void ICACHE_FLASH_ATTR
uart0_tx_buffer(uint8 *buf, uint16 len)
{
uint16 i;
for (i = 0; i < len; i++)
{
uart_tx_one_char(UART0, buf[i]);
}
}
/******************************************************************************
* FunctionName : uart0_sendStr
* Description : use uart0 to transfer buffer
* Parameters : uint8 *buf - point to send buffer
* uint16 len - buffer len
* Returns :
*******************************************************************************/
void ICACHE_FLASH_ATTR
uart0_sendStr(const char *str)
{
while(*str)
{
uart_tx_one_char(UART0, *str++);
}
}
/******************************************************************************
* FunctionName : uart0_rx_intr_handler
* Description : Internal used function
* UART0 interrupt handler, add self handle code inside
* Parameters : void *para - point to ETS_UART_INTR_ATTACH's arg
* Returns : NONE
*******************************************************************************/
//extern void at_recvTask(void);
LOCAL void
uart0_rx_intr_handler(void *para)
{
/* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents
* uart1 and uart0 respectively
*/
// RcvMsgBuff *pRxBuff = (RcvMsgBuff *)para;
// uint8 RcvChar;
uint8 uart_no = UART0;//UartDev.buff_uart_no;
// if (UART_RXFIFO_FULL_INT_ST != (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST))
// {
// return;
// }
if (UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST))
{
// at_recvTask();
WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR);
}
// WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR);
// if (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S))
// {
// RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xFF;
// at_recvTask();
// *(pRxBuff->pWritePos) = RcvChar;
// system_os_post(at_recvTaskPrio, NULL, RcvChar);
// //insert here for get one command line from uart
// if (RcvChar == '\r')
// {
// pRxBuff->BuffState = WRITE_OVER;
// }
//
// pRxBuff->pWritePos++;
//
// if (pRxBuff->pWritePos == (pRxBuff->pRcvMsgBuff + RX_BUFF_SIZE))
// {
// // overflow ...we may need more error handle here.
// pRxBuff->pWritePos = pRxBuff->pRcvMsgBuff ;
// }
// }
}
/******************************************************************************
* FunctionName : uart_init
* Description : user interface for init uart
* Parameters : UartBautRate uart0_br - uart0 bautrate
* UartBautRate uart1_br - uart1 bautrate
* Returns : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR
uart_init(UartBautRate uart0_br, UartBautRate uart1_br)
{
// rom use 74880 baut_rate, here reinitialize
UartDev.baut_rate = uart0_br;
uart_config(UART0);
UartDev.baut_rate = uart1_br;
uart_config(UART1);
ETS_UART_INTR_ENABLE();
// install uart0 putc callback
os_install_putc1((void *)uart0_write_char);
}
void ICACHE_FLASH_ATTR
uart_reattach()
{
uart_init(BIT_RATE_74880, BIT_RATE_74880);
// ETS_UART_INTR_ATTACH(uart_rx_intr_handler_ssc, &(UartDev.rcv_buff));
// ETS_UART_INTR_ENABLE();
}

@ -1,13 +0,0 @@
<html><head><title>Test</title></head>
<body>
<p>
There's a LED. You can't see it, so it's no use clicking any of the buttons below. The buttons
do, however, turn the LED on and off.
</p>
<form method="post" action="led.cgi">
<input type="submit" name="led" value="1">
<input type="submit" name="led" value="0">
</form>
</body></html>

@ -1,7 +0,0 @@
<html>
<head><title>Test</title></head>
<body>
<h1>Test!</h1>
<p>Yay, the cpio filesystem thingy works. Click <a href="/test2.html">here</a> to see
if the 2nd page works too.
</p>

@ -1,12 +0,0 @@
<html>
<head><title>Test</title></head>
<body>
<h1>Test2!</h1>
<p><b>New!</b>You can also control the <a href="led.html">LED</a>...</p>
<p>Here's an image of a cat (hopefully...)<br />
<img src="cat.jpeg"><br />
<img src="ceilingcat.jpg"><br />
<img src="disapprove.jpg"><br />
<img src="invisiblepogostick.jpg"><br />
</p>
</body></html>

@ -1,10 +0,0 @@
<html><head><title>Test</title></head>
<body>
<form method="post" action="test.cgi">
<input type="text" name="Test1" value="t1">
<input type="text" name="Test2" value="t2">
<input type="submit" name="DoIt" value="Do It">
</form>
</body></html>

@ -1,103 +0,0 @@
#ifndef UART_APP_H
#define UART_APP_H
#include "uart_register.h"
#include "eagle_soc.h"
#include "c_types.h"
#define RX_BUFF_SIZE 256
#define TX_BUFF_SIZE 100
#define UART0 0
#define UART1 1
typedef enum {
FIVE_BITS = 0x0,
SIX_BITS = 0x1,
SEVEN_BITS = 0x2,
EIGHT_BITS = 0x3
} UartBitsNum4Char;
typedef enum {
ONE_STOP_BIT = 0,
ONE_HALF_STOP_BIT = BIT2,
TWO_STOP_BIT = BIT2
} UartStopBitsNum;
typedef enum {
NONE_BITS = 0,
ODD_BITS = 0,
EVEN_BITS = BIT4
} UartParityMode;
typedef enum {
STICK_PARITY_DIS = 0,
STICK_PARITY_EN = BIT3 | BIT5
} UartExistParity;
typedef enum {
BIT_RATE_9600 = 9600,
BIT_RATE_19200 = 19200,
BIT_RATE_38400 = 38400,
BIT_RATE_57600 = 57600,
BIT_RATE_74880 = 74880,
BIT_RATE_115200 = 115200,
BIT_RATE_230400 = 230400,
BIT_RATE_460800 = 460800,
BIT_RATE_921600 = 921600
} UartBautRate;
typedef enum {
NONE_CTRL,
HARDWARE_CTRL,
XON_XOFF_CTRL
} UartFlowCtrl;
typedef enum {
EMPTY,
UNDER_WRITE,
WRITE_OVER
} RcvMsgBuffState;
typedef struct {
uint32 RcvBuffSize;
uint8 *pRcvMsgBuff;
uint8 *pWritePos;
uint8 *pReadPos;
uint8 TrigLvl; //JLU: may need to pad
RcvMsgBuffState BuffState;
} RcvMsgBuff;
typedef struct {
uint32 TrxBuffSize;
uint8 *pTrxBuff;
} TrxMsgBuff;
typedef enum {
BAUD_RATE_DET,
WAIT_SYNC_FRM,
SRCH_MSG_HEAD,
RCV_MSG_BODY,
RCV_ESC_CHAR,
} RcvMsgState;
typedef struct {
UartBautRate baut_rate;
UartBitsNum4Char data_bits;
UartExistParity exist_parity;
UartParityMode parity; // chip size in byte
UartStopBitsNum stop_bits;
UartFlowCtrl flow_ctrl;
RcvMsgBuff rcv_buff;
TrxMsgBuff trx_buff;
RcvMsgState rcv_state;
int received;
int buff_uart_no; //indicate which uart use tx/rx buffer
} UartDevice;
void uart_init(UartBautRate uart0_br, UartBautRate uart1_br);
void uart0_sendStr(const char *str);
#endif

@ -1,128 +0,0 @@
//Generated at 2012-07-03 18:44:06
/*
* Copyright (c) 2010 - 2011 Espressif System
*
*/
#ifndef UART_REGISTER_H_INCLUDED
#define UART_REGISTER_H_INCLUDED
#define REG_UART_BASE( i ) (0x60000000+(i)*0xf00)
//version value:32'h062000
#define UART_FIFO( i ) (REG_UART_BASE( i ) + 0x0)
#define UART_RXFIFO_RD_BYTE 0x000000FF
#define UART_RXFIFO_RD_BYTE_S 0
#define UART_INT_RAW( i ) (REG_UART_BASE( i ) + 0x4)
#define UART_RXFIFO_TOUT_INT_RAW (BIT(8))
#define UART_BRK_DET_INT_RAW (BIT(7))
#define UART_CTS_CHG_INT_RAW (BIT(6))
#define UART_DSR_CHG_INT_RAW (BIT(5))
#define UART_RXFIFO_OVF_INT_RAW (BIT(4))
#define UART_FRM_ERR_INT_RAW (BIT(3))
#define UART_PARITY_ERR_INT_RAW (BIT(2))
#define UART_TXFIFO_EMPTY_INT_RAW (BIT(1))
#define UART_RXFIFO_FULL_INT_RAW (BIT(0))
#define UART_INT_ST( i ) (REG_UART_BASE( i ) + 0x8)
#define UART_RXFIFO_TOUT_INT_ST (BIT(8))
#define UART_BRK_DET_INT_ST (BIT(7))
#define UART_CTS_CHG_INT_ST (BIT(6))
#define UART_DSR_CHG_INT_ST (BIT(5))
#define UART_RXFIFO_OVF_INT_ST (BIT(4))
#define UART_FRM_ERR_INT_ST (BIT(3))
#define UART_PARITY_ERR_INT_ST (BIT(2))
#define UART_TXFIFO_EMPTY_INT_ST (BIT(1))
#define UART_RXFIFO_FULL_INT_ST (BIT(0))
#define UART_INT_ENA( i ) (REG_UART_BASE( i ) + 0xC)
#define UART_RXFIFO_TOUT_INT_ENA (BIT(8))
#define UART_BRK_DET_INT_ENA (BIT(7))
#define UART_CTS_CHG_INT_ENA (BIT(6))
#define UART_DSR_CHG_INT_ENA (BIT(5))
#define UART_RXFIFO_OVF_INT_ENA (BIT(4))
#define UART_FRM_ERR_INT_ENA (BIT(3))
#define UART_PARITY_ERR_INT_ENA (BIT(2))
#define UART_TXFIFO_EMPTY_INT_ENA (BIT(1))
#define UART_RXFIFO_FULL_INT_ENA (BIT(0))
#define UART_INT_CLR( i ) (REG_UART_BASE( i ) + 0x10)
#define UART_RXFIFO_TOUT_INT_CLR (BIT(8))
#define UART_BRK_DET_INT_CLR (BIT(7))
#define UART_CTS_CHG_INT_CLR (BIT(6))
#define UART_DSR_CHG_INT_CLR (BIT(5))
#define UART_RXFIFO_OVF_INT_CLR (BIT(4))
#define UART_FRM_ERR_INT_CLR (BIT(3))
#define UART_PARITY_ERR_INT_CLR (BIT(2))
#define UART_TXFIFO_EMPTY_INT_CLR (BIT(1))
#define UART_RXFIFO_FULL_INT_CLR (BIT(0))
#define UART_CLKDIV( i ) (REG_UART_BASE( i ) + 0x14)
#define UART_CLKDIV_CNT 0x000FFFFF
#define UART_CLKDIV_S 0
#define UART_AUTOBAUD( i ) (REG_UART_BASE( i ) + 0x18)
#define UART_GLITCH_FILT 0x000000FF
#define UART_GLITCH_FILT_S 8
#define UART_AUTOBAUD_EN (BIT(0))
#define UART_STATUS( i ) (REG_UART_BASE( i ) + 0x1C)
#define UART_TXD (BIT(31))
#define UART_RTSN (BIT(30))
#define UART_DTRN (BIT(29))
#define UART_TXFIFO_CNT 0x000000FF
#define UART_TXFIFO_CNT_S 16
#define UART_RXD (BIT(15))
#define UART_CTSN (BIT(14))
#define UART_DSRN (BIT(13))
#define UART_RXFIFO_CNT 0x000000FF
#define UART_RXFIFO_CNT_S 0
#define UART_CONF0( i ) (REG_UART_BASE( i ) + 0x20)
#define UART_TXFIFO_RST (BIT(18))
#define UART_RXFIFO_RST (BIT(17))
#define UART_IRDA_EN (BIT(16))
#define UART_TX_FLOW_EN (BIT(15))
#define UART_LOOPBACK (BIT(14))
#define UART_IRDA_RX_INV (BIT(13))
#define UART_IRDA_TX_INV (BIT(12))
#define UART_IRDA_WCTL (BIT(11))
#define UART_IRDA_TX_EN (BIT(10))
#define UART_IRDA_DPLX (BIT(9))
#define UART_TXD_BRK (BIT(8))
#define UART_SW_DTR (BIT(7))
#define UART_SW_RTS (BIT(6))
#define UART_STOP_BIT_NUM 0x00000003
#define UART_STOP_BIT_NUM_S 4
#define UART_BIT_NUM 0x00000003
#define UART_BIT_NUM_S 2
#define UART_PARITY_EN (BIT(1))
#define UART_PARITY (BIT(0))
#define UART_CONF1( i ) (REG_UART_BASE( i ) + 0x24)
#define UART_RX_TOUT_EN (BIT(31))
#define UART_RX_TOUT_THRHD 0x0000007F
#define UART_RX_TOUT_THRHD_S 24
#define UART_RX_FLOW_EN (BIT(23))
#define UART_RX_FLOW_THRHD 0x0000007F
#define UART_RX_FLOW_THRHD_S 16
#define UART_TXFIFO_EMPTY_THRHD 0x0000007F
#define UART_TXFIFO_EMPTY_THRHD_S 8
#define UART_RXFIFO_FULL_THRHD 0x0000007F
#define UART_RXFIFO_FULL_THRHD_S 0
#define UART_LOWPULSE( i ) (REG_UART_BASE( i ) + 0x28)
#define UART_LOWPULSE_MIN_CNT 0x000FFFFF
#define UART_LOWPULSE_MIN_CNT_S 0
#define UART_HIGHPULSE( i ) (REG_UART_BASE( i ) + 0x2C)
#define UART_HIGHPULSE_MIN_CNT 0x000FFFFF
#define UART_HIGHPULSE_MIN_CNT_S 0
#define UART_PULSE_NUM( i ) (REG_UART_BASE( i ) + 0x30)
#define UART_PULSE_NUM_CNT 0x0003FF
#define UART_PULSE_NUM_CNT_S 0
#define UART_DATE( i ) (REG_UART_BASE( i ) + 0x78)
#define UART_ID( i ) (REG_UART_BASE( i ) + 0x7C)
#endif // UART_REGISTER_H_INCLUDED

@ -26,6 +26,7 @@ char *ets_strcpy(char *dest, const char *src);
char *ets_strncpy(char *dest, const char *src, size_t n); char *ets_strncpy(char *dest, const char *src, size_t n);
char *ets_strstr(const char *haystack, const char *needle); char *ets_strstr(const char *haystack, const char *needle);
int ets_sprintf(char *str, const char *format, ...) __attribute__ ((format (printf, 2, 3))); int ets_sprintf(char *str, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
int os_snprintf(char *str, size_t size, const char *format, ...) __attribute__ ((format (printf, 3, 4)));
int os_printf(const char *format, ...) __attribute__ ((format (printf, 1, 2))); int os_printf(const char *format, ...) __attribute__ ((format (printf, 1, 2)));
void uart_div_modify(int no, int freq); void uart_div_modify(int no, int freq);
void ets_isr_unmask(int intr); void ets_isr_unmask(int intr);

@ -1,5 +1,10 @@
CFLAGS=-I../lib/heatshrink -std=gnu99 CFLAGS=-I../lib/heatshrink -std=gnu99
OBJS=main.o heatshrink_encoder.o
TARGET=mkespfsimage
mkespfsimage: main.o heatshrink_encoder.o $(TARGET): $(OBJS)
$(CC) -o $@ $^ $(CC) -o $@ $^
clean:
rm -f $(TARGET) $(OBJS)

@ -2,6 +2,16 @@
Some random cgi routines. Some random cgi routines.
*/ */
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* Jeroen Domburg <jeroen@spritesmods.com> wrote this file. As long as you retain
* this notice you can do whatever you want with this stuff. If we meet some day,
* and you think this stuff is worth it, you can buy me a beer in return.
* ----------------------------------------------------------------------------
*/
#include <string.h> #include <string.h>
#include <osapi.h> #include <osapi.h>
#include "user_interface.h" #include "user_interface.h"
@ -11,6 +21,10 @@ Some random cgi routines.
#include "io.h" #include "io.h"
#include "espmissingincludes.h" #include "espmissingincludes.h"
//cause I can't be bothered to write an ioGetLed()
static char currLedState=0;
//Cgi that turns the LED on or off according to the 'led' param in the POST data
int ICACHE_FLASH_ATTR cgiLed(HttpdConnData *connData) { int ICACHE_FLASH_ATTR cgiLed(HttpdConnData *connData) {
int len; int len;
char buff[1024]; char buff[1024];
@ -21,169 +35,35 @@ int ICACHE_FLASH_ATTR cgiLed(HttpdConnData *connData) {
} }
len=httpdFindArg(connData->postBuff, "led", buff, sizeof(buff)); len=httpdFindArg(connData->postBuff, "led", buff, sizeof(buff));
if (len!=0) ioLed(atoi(buff)); if (len!=0) {
currLedState=atoi(buff);
ioLed(currLedState);
}
httpdRedirect(connData, "led.html"); httpdRedirect(connData, "led.html");
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
//WiFi access point data
typedef struct {
char ssid[32];
char rssi;
char enc;
} ApData;
//Scan resolt
typedef struct {
char scanInProgress;
ApData **apData;
int noAps;
} ScanResultData;
//Static scan status storage.
ScanResultData cgiWifiAps;
void ICACHE_FLASH_ATTR wifiScanDoneCb(void *arg, STATUS status) {
int n;
struct bss_info *bss_link = (struct bss_info *)arg;
os_printf("wifiScanDoneCb %d\n", status);
if (status!=OK) {
cgiWifiAps.scanInProgress=0;
wifi_station_disconnect(); //test HACK
return;
}
//Clear prev ap data if needed.
if (cgiWifiAps.apData!=NULL) {
for (n=0; n<cgiWifiAps.noAps; n++) os_free(cgiWifiAps.apData[n]);
os_free(cgiWifiAps.apData);
}
//Count amount of access points found.
n=0;
while (bss_link != NULL) {
bss_link = bss_link->next.stqe_next;
n++;
}
//Allocate memory for access point data
cgiWifiAps.apData=(ApData **)os_malloc(sizeof(ApData *)*n);
cgiWifiAps.noAps=n;
//Copy access point data to the static struct
n=0;
bss_link = (struct bss_info *)arg;
while (bss_link != NULL) {
cgiWifiAps.apData[n]=(ApData *)os_malloc(sizeof(ApData));
cgiWifiAps.apData[n]->rssi=bss_link->rssi;
cgiWifiAps.apData[n]->enc=bss_link->authmode;
strncpy(cgiWifiAps.apData[n]->ssid, (char*)bss_link->ssid, 32);
bss_link = bss_link->next.stqe_next;
n++;
}
os_printf("Scan done: found %d APs\n", n);
//We're done.
cgiWifiAps.scanInProgress=0;
}
static void ICACHE_FLASH_ATTR wifiStartScan() {
int x;
cgiWifiAps.scanInProgress=1;
x=wifi_station_get_connect_status();
if (x!=STATION_GOT_IP) {
//Unit probably is trying to connect to a bogus AP. This messes up scanning. Stop that.
os_printf("STA status = %d. Disconnecting STA...\n", x);
wifi_station_disconnect();
}
wifi_station_scan(NULL, wifiScanDoneCb);
}
//Template code for the led page.
void ICACHE_FLASH_ATTR tplLed(HttpdConnData *connData, char *token, void **arg) {
char buff[128];
if (token==NULL) return;
int ICACHE_FLASH_ATTR cgiWiFiScan(HttpdConnData *connData) { os_strcpy(buff, "Unknown");
int len; if (os_strcmp(token, "ledstate")==0) {
int i; if (currLedState) {
char buff[1024]; os_strcpy(buff, "on");
httpdStartResponse(connData, 200); } else {
httpdHeader(connData, "Content-Type", "text/json"); os_strcpy(buff, "off");
httpdEndHeaders(connData);
if (cgiWifiAps.scanInProgress==1) {
len=os_sprintf(buff, "{\n \"result\": { \n\"inProgress\": \"1\"\n }\n}\n");
espconn_sent(connData->conn, (uint8 *)buff, len);
} else {
len=os_sprintf(buff, "{\n \"result\": { \n\"inProgress\": \"0\", \n\"APs\": [\n");
espconn_sent(connData->conn, (uint8 *)buff, len);
if (cgiWifiAps.apData==NULL) cgiWifiAps.noAps=0;
for (i=0; i<cgiWifiAps.noAps; i++) {
len=os_sprintf(buff, "{\"essid\": \"%s\", \"rssi\": \"%d\", \"enc\": \"%d\"}%s\n",
cgiWifiAps.apData[i]->ssid, cgiWifiAps.apData[i]->rssi,
cgiWifiAps.apData[i]->enc, (i==cgiWifiAps.noAps-1)?"":",");
espconn_sent(connData->conn, (uint8 *)buff, len);
} }
len=os_sprintf(buff, "]\n}\n}\n");
espconn_sent(connData->conn, (uint8 *)buff, len);
wifiStartScan();
}
return HTTPD_CGI_DONE;
}
static struct station_config stconf;
static void ICACHE_FLASH_ATTR resetTimerCb(void *arg) {
int x=wifi_station_get_connect_status();
if (x==STATION_GOT_IP) {
//Go to STA mode. This needs a reset, so do that.
wifi_set_opmode(1);
system_restart();
} else {
os_printf("Connect fail. Not going into STA-only mode.\n");
}
}
static void ICACHE_FLASH_ATTR reassTimerCb(void *arg) {
int x;
static ETSTimer resetTimer;
wifi_station_disconnect();
wifi_station_set_config(&stconf);
wifi_station_connect();
x=wifi_get_opmode();
if (x!=1) {
//Schedule disconnect/connect
os_timer_disarm(&resetTimer);
os_timer_setfn(&resetTimer, resetTimerCb, NULL);
os_timer_arm(&resetTimer, 4000, 0);
} }
espconn_sent(connData->conn, (uint8 *)buff, os_strlen(buff));
} }
int ICACHE_FLASH_ATTR cgiWiFiConnect(HttpdConnData *connData) {
char essid[128];
char passwd[128];
static ETSTimer reassTimer;
if (connData->conn==NULL) {
//Connection aborted. Clean up.
return HTTPD_CGI_DONE;
}
httpdFindArg(connData->postBuff, "essid", essid, sizeof(essid));
httpdFindArg(connData->postBuff, "passwd", passwd, sizeof(passwd));
os_strncpy((char*)stconf.ssid, essid, 32);
os_strncpy((char*)stconf.password, passwd, 64);
//Schedule disconnect/connect
os_timer_disarm(&reassTimer);
os_timer_setfn(&reassTimer, reassTimerCb, NULL);
os_timer_arm(&reassTimer, 1000, 0);
httpdRedirect(connData, "connecting.html");
return HTTPD_CGI_DONE;
}
//Cgi that reads the SPI flash. Assumes 512KByte flash. //Cgi that reads the SPI flash. Assumes 512KByte flash.
int ICACHE_FLASH_ATTR cgiReadFlash(HttpdConnData *connData) { int ICACHE_FLASH_ATTR cgiReadFlash(HttpdConnData *connData) {
@ -206,30 +86,3 @@ int ICACHE_FLASH_ATTR cgiReadFlash(HttpdConnData *connData) {
if (*pos>=0x40200000+(512*1024)) return HTTPD_CGI_DONE; else return HTTPD_CGI_MORE; if (*pos>=0x40200000+(512*1024)) return HTTPD_CGI_DONE; else return HTTPD_CGI_MORE;
} }
int ICACHE_FLASH_ATTR cgiTest(HttpdConnData *connData) {
return HTTPD_CGI_DONE;
}
void ICACHE_FLASH_ATTR tplWlan(HttpdConnData *connData, char *token, void **arg) {
char buff[1024];
int x;
static struct station_config stconf;
if (token==NULL) return;
wifi_station_get_config(&stconf);
os_strcpy(buff, "Unknown");
if (os_strcmp(token, "WiFiMode")==0) {
x=wifi_get_opmode();
if (x==1) os_strcpy(buff, "Client");
if (x==2) os_strcpy(buff, "SoftAP");
if (x==3) os_strcpy(buff, "STA+AP");
} else if (os_strcmp(token, "currSsid")==0) {
os_strcpy(buff, (char*)stconf.ssid);
} else if (os_strcmp(token, "WiFiPasswd")==0) {
os_strcpy(buff, (char*)stconf.password);
}
espconn_sent(connData->conn, (uint8 *)buff, os_strlen(buff));
}

@ -4,11 +4,7 @@
#include "httpd.h" #include "httpd.h"
int cgiLed(HttpdConnData *connData); int cgiLed(HttpdConnData *connData);
void tplLed(HttpdConnData *connData, char *token, void **arg);
int cgiReadFlash(HttpdConnData *connData); int cgiReadFlash(HttpdConnData *connData);
int cgiTest(HttpdConnData *connData);
int cgiWiFiScan(HttpdConnData *connData);
void ICACHE_FLASH_ATTR tplWlan(HttpdConnData *connData, char *token, void **arg);
int ICACHE_FLASH_ATTR cgiWiFi(HttpdConnData *connData);
int ICACHE_FLASH_ATTR cgiWiFiConnect(HttpdConnData *connData);
#endif #endif

@ -4,9 +4,22 @@ mkespfsimg tool, and can use that block to do abstracted operations on the files
It's written for use with httpd, but doesn't need to be used as such. It's written for use with httpd, but doesn't need to be used as such.
*/ */
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* Jeroen Domburg <jeroen@spritesmods.com> wrote this file. As long as you retain
* this notice you can do whatever you want with this stuff. If we meet some day,
* and you think this stuff is worth it, you can buy me a beer in return.
* ----------------------------------------------------------------------------
*/
//These routines can also be tested by comping them in with the espfstest tool. This
//simplifies debugging, but needs some slightly different headers. The #ifdef takes
//care of that.
#ifdef __ets__ #ifdef __ets__
//esp build //esp build
#include "driver/uart.h"
#include "c_types.h" #include "c_types.h"
#include "user_interface.h" #include "user_interface.h"
#include "espconn.h" #include "espconn.h"
@ -51,7 +64,7 @@ struct EspFsFile {
/* /*
Available locations, at least in my flash, with boundaries partially guessed. This Available locations, at least in my flash, with boundaries partially guessed. This
is using 0.9.1 SDK on a not-too-new module. is using 0.9.1/0.9.2 SDK on a not-too-new module.
0x00000 (0x10000): Code/data (RAM data?) 0x00000 (0x10000): Code/data (RAM data?)
0x10000 (0x02000): Gets erased by something? 0x10000 (0x02000): Gets erased by something?
0x12000 (0x2E000): Free (filled with zeroes) (parts used by ESPCloud and maybe SSL) 0x12000 (0x2E000): Free (filled with zeroes) (parts used by ESPCloud and maybe SSL)
@ -83,7 +96,7 @@ void ICACHE_FLASH_ATTR memcpyAligned(char *dst, char *src, int len) {
} }
//Open a file and return a pointer to the file desc struct.
EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) { EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) {
#ifdef __ets__ #ifdef __ets__
char *p=(char *)(ESPFS_POS+0x40200000); char *p=(char *)(ESPFS_POS+0x40200000);
@ -94,11 +107,12 @@ EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) {
char namebuf[256]; char namebuf[256];
EspFsHeader h; EspFsHeader h;
EspFsFile *r; EspFsFile *r;
//Skip initial slashes //Strip initial slashes
while(fileName[0]=='/') fileName++; while(fileName[0]=='/') fileName++;
//Go find that file! //Go find that file!
while(1) { while(1) {
hpos=p; hpos=p;
//Grab the next file header.
os_memcpy(&h, p, sizeof(EspFsHeader)); os_memcpy(&h, p, sizeof(EspFsHeader));
if (h.magic!=0x73665345) { if (h.magic!=0x73665345) {
os_printf("Magic mismatch. EspFS image broken.\n"); os_printf("Magic mismatch. EspFS image broken.\n");
@ -108,13 +122,15 @@ EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) {
os_printf("End of image.\n"); os_printf("End of image.\n");
return NULL; return NULL;
} }
p+=sizeof(EspFsHeader); //Grab the name of the file.
p+=sizeof(EspFsHeader);
os_memcpy(namebuf, p, sizeof(namebuf)); os_memcpy(namebuf, p, sizeof(namebuf));
os_printf("Found file '%s'. Namelen=%x fileLenComp=%x, compr=%d flags=%d\n", os_printf("Found file '%s'. Namelen=%x fileLenComp=%x, compr=%d flags=%d\n",
namebuf, (unsigned int)h.nameLen, (unsigned int)h.fileLenComp, h.compression, h.flags); namebuf, (unsigned int)h.nameLen, (unsigned int)h.fileLenComp, h.compression, h.flags);
if (os_strcmp(namebuf, fileName)==0) { if (os_strcmp(namebuf, fileName)==0) {
p+=h.nameLen; //Yay, this is the file we need!
r=(EspFsFile *)os_malloc(sizeof(EspFsFile)); p+=h.nameLen; //Skip to content.
r=(EspFsFile *)os_malloc(sizeof(EspFsFile)); //Alloc file desc mem
if (r==NULL) return NULL; if (r==NULL) return NULL;
r->header=(EspFsHeader *)hpos; r->header=(EspFsHeader *)hpos;
r->decompressor=h.compression; r->decompressor=h.compression;
@ -125,6 +141,7 @@ EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) {
r->decompData=NULL; r->decompData=NULL;
#ifdef EFS_HEATSHRINK #ifdef EFS_HEATSHRINK
} else if (h.compression==COMPRESS_HEATSHRINK) { } else if (h.compression==COMPRESS_HEATSHRINK) {
//File is compressed with Heatshrink.
char parm; char parm;
heatshrink_decoder *dec; heatshrink_decoder *dec;
//Decoder params are stored in 1st byte. //Decoder params are stored in 1st byte.
@ -132,7 +149,6 @@ EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) {
r->posComp++; r->posComp++;
os_printf("Heatshrink compressed file; decode parms = %x\n", parm); os_printf("Heatshrink compressed file; decode parms = %x\n", parm);
dec=heatshrink_decoder_alloc(16, (parm>>4)&0xf, parm&0xf); dec=heatshrink_decoder_alloc(16, (parm>>4)&0xf, parm&0xf);
heatshrink_decoder_reset(dec);
r->decompData=dec; r->decompData=dec;
#endif #endif
} else { } else {
@ -141,18 +157,19 @@ EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) {
} }
return r; return r;
} }
//Skip name and file //We don't need this file. Skip name and file
p+=h.nameLen+h.fileLenComp; p+=h.nameLen+h.fileLenComp;
if ((int)p&3) p+=4-((int)p&3); //align to next 32bit val if ((int)p&3) p+=4-((int)p&3); //align to next 32bit val
// os_printf("Next addr = %x\n", (int)p);
} }
} }
//Read len bytes from the given file into buff. Returns the actual amount of bytes read.
int ICACHE_FLASH_ATTR espFsRead(EspFsFile *fh, char *buff, int len) { int ICACHE_FLASH_ATTR espFsRead(EspFsFile *fh, char *buff, int len) {
int flen; int flen;
if (fh==NULL) return 0; if (fh==NULL) return 0;
memcpyAligned((char*)&flen, (char*)&fh->header->fileLenComp, 4); //Cache file length.
memcpyAligned((char*)&flen, (char*)&fh->header->fileLenComp, 4);
//Do stuff depending on the way the file is compressed.
if (fh->decompressor==COMPRESS_NONE) { if (fh->decompressor==COMPRESS_NONE) {
int toRead; int toRead;
toRead=flen-(fh->posComp-fh->posStart); toRead=flen-(fh->posComp-fh->posStart);
@ -194,6 +211,7 @@ int ICACHE_FLASH_ATTR espFsRead(EspFsFile *fh, char *buff, int len) {
return 0; return 0;
} }
//Close the file.
void ICACHE_FLASH_ATTR espFsClose(EspFsFile *fh) { void ICACHE_FLASH_ATTR espFsClose(EspFsFile *fh) {
if (fh==NULL) return; if (fh==NULL) return;
#ifdef EFS_HEATSHRINK #ifdef EFS_HEATSHRINK

@ -1,3 +1,4 @@
//Heatshrink config for the decompressor.
#ifndef HEATSHRINK_CONFIG_H #ifndef HEATSHRINK_CONFIG_H
#define HEATSHRINK_CONFIG_H #define HEATSHRINK_CONFIG_H

@ -1,5 +1,16 @@
//Esp8266 http server - core routines
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* Jeroen Domburg <jeroen@spritesmods.com> wrote this file. As long as you retain
* this notice you can do whatever you want with this stuff. If we meet some day,
* and you think this stuff is worth it, you can buy me a beer in return.
* ----------------------------------------------------------------------------
*/
#include "espmissingincludes.h" #include "espmissingincludes.h"
#include "driver/uart.h"
#include "c_types.h" #include "c_types.h"
#include "user_interface.h" #include "user_interface.h"
#include "espconn.h" #include "espconn.h"
@ -11,7 +22,7 @@
#include "io.h" #include "io.h"
#include "espfs.h" #include "espfs.h"
//Max length of head (plus POST data) //Max length of request head
#define MAX_HEAD_LEN 1024 #define MAX_HEAD_LEN 1024
//Max amount of connections //Max amount of connections
#define MAX_CONN 8 #define MAX_CONN 8
@ -41,6 +52,8 @@ typedef struct {
const char *mimetype; const char *mimetype;
} MimeMap; } MimeMap;
//The mappings from file extensions to mime types. If you need an extra mime type,
//add it here.
static const MimeMap mimeTypes[]={ static const MimeMap mimeTypes[]={
{"htm", "text/htm"}, {"htm", "text/htm"},
{"html", "text/html"}, {"html", "text/html"},
@ -49,9 +62,10 @@ static const MimeMap mimeTypes[]={
{"jpg", "image/jpeg"}, {"jpg", "image/jpeg"},
{"jpeg", "image/jpeg"}, {"jpeg", "image/jpeg"},
{"png", "image/png"}, {"png", "image/png"},
{NULL, "text/html"}, {NULL, "text/html"}, //default value
}; };
//Returns a static char* to a mime type for a given url to a file.
const char ICACHE_FLASH_ATTR *httpdGetMimetype(char *url) { const char ICACHE_FLASH_ATTR *httpdGetMimetype(char *url) {
int i=0; int i=0;
//Go find the extension //Go find the extension
@ -63,7 +77,7 @@ const char ICACHE_FLASH_ATTR *httpdGetMimetype(char *url) {
return mimeTypes[i].mimetype; return mimeTypes[i].mimetype;
} }
//Looks up the connData info for a specific esp connection
static HttpdConnData ICACHE_FLASH_ATTR *httpdFindConnData(void *arg) { static HttpdConnData ICACHE_FLASH_ATTR *httpdFindConnData(void *arg) {
int i; int i;
for (i=0; i<MAX_CONN; i++) { for (i=0; i<MAX_CONN; i++) {
@ -73,7 +87,7 @@ static HttpdConnData ICACHE_FLASH_ATTR *httpdFindConnData(void *arg) {
return NULL; //WtF? return NULL; //WtF?
} }
//Retires a connection for re-use
static void ICACHE_FLASH_ATTR httpdRetireConn(HttpdConnData *conn) { static void ICACHE_FLASH_ATTR httpdRetireConn(HttpdConnData *conn) {
if (conn->postBuff!=NULL) os_free(conn->postBuff); if (conn->postBuff!=NULL) os_free(conn->postBuff);
conn->postBuff=NULL; conn->postBuff=NULL;
@ -81,6 +95,7 @@ static void ICACHE_FLASH_ATTR httpdRetireConn(HttpdConnData *conn) {
conn->conn=NULL; conn->conn=NULL;
} }
//Stupid li'l helper function that returns the value of a hex char.
static int httpdHexVal(char c) { static int httpdHexVal(char c) {
if (c>='0' && c<='9') return c-'0'; if (c>='0' && c<='9') return c-'0';
if (c>='A' && c<='F') return c-'A'+10; if (c>='A' && c<='F') return c-'A'+10;
@ -88,7 +103,10 @@ static int httpdHexVal(char c) {
return 0; return 0;
} }
//Decode a percent-encoded value //Decode a percent-encoded value.
//Takes the valLen bytes stored in val, and converts it into at most retLen bytes that
//are stored in the ret buffer. Returns the actual amount of bytes used in ret. Also
//zero-terminates the ret buffer.
int httpdUrlDecode(char *val, int valLen, char *ret, int retLen) { int httpdUrlDecode(char *val, int valLen, char *ret, int retLen) {
int s=0, d=0; int s=0, d=0;
int esced=0, escVal=0; int esced=0, escVal=0;
@ -114,7 +132,9 @@ int httpdUrlDecode(char *val, int valLen, char *ret, int retLen) {
} }
//Find a specific arg in a string of get- or post-data. //Find a specific arg in a string of get- or post-data.
//Returns len of arg or -1 if not found. //Line is the string of post/get-data, arg is the name of the value to find. The
//zero-terminated result is written in buff, with at most buffLen bytes used. The
//function returns the length of the result, or -1 if the value wasn't found.
int ICACHE_FLASH_ATTR httpdFindArg(char *line, char *arg, char *buff, int buffLen) { int ICACHE_FLASH_ATTR httpdFindArg(char *line, char *arg, char *buff, int buffLen) {
char *p, *e; char *p, *e;
if (line==NULL) return 0; if (line==NULL) return 0;
@ -135,8 +155,8 @@ int ICACHE_FLASH_ATTR httpdFindArg(char *line, char *arg, char *buff, int buffLe
return -1; //not found return -1; //not found
} }
static const char *httpNotFoundHeader="HTTP/1.0 404 Not Found\r\nServer: esp8266-httpd/0.1\r\nContent-Type: text/plain\r\n\r\nNot Found.\r\n";
//Start the response headers.
void ICACHE_FLASH_ATTR httpdStartResponse(HttpdConnData *conn, int code) { void ICACHE_FLASH_ATTR httpdStartResponse(HttpdConnData *conn, int code) {
char buff[128]; char buff[128];
int l; int l;
@ -144,7 +164,7 @@ void ICACHE_FLASH_ATTR httpdStartResponse(HttpdConnData *conn, int code) {
espconn_sent(conn->conn, (uint8 *)buff, l); espconn_sent(conn->conn, (uint8 *)buff, l);
} }
//Send a http header.
void ICACHE_FLASH_ATTR httpdHeader(HttpdConnData *conn, const char *field, const char *val) { void ICACHE_FLASH_ATTR httpdHeader(HttpdConnData *conn, const char *field, const char *val) {
char buff[256]; char buff[256];
int l; int l;
@ -152,6 +172,7 @@ void ICACHE_FLASH_ATTR httpdHeader(HttpdConnData *conn, const char *field, const
espconn_sent(conn->conn, (uint8 *)buff, l); espconn_sent(conn->conn, (uint8 *)buff, l);
} }
//Finish the headers.
void ICACHE_FLASH_ATTR httpdEndHeaders(HttpdConnData *conn) { void ICACHE_FLASH_ATTR httpdEndHeaders(HttpdConnData *conn) {
espconn_sent(conn->conn, (uint8 *)"\r\n", 2); espconn_sent(conn->conn, (uint8 *)"\r\n", 2);
} }
@ -193,6 +214,8 @@ static void ICACHE_FLASH_ATTR httpdSentCb(void *arg) {
} }
} }
static const char *httpNotFoundHeader="HTTP/1.0 404 Not Found\r\nServer: esp8266-httpd/0.1\r\nContent-Type: text/plain\r\n\r\nNot Found.\r\n";
static void ICACHE_FLASH_ATTR httpdSendResp(HttpdConnData *conn) { static void ICACHE_FLASH_ATTR httpdSendResp(HttpdConnData *conn) {
int i=0; int i=0;
int r; int r;

@ -26,10 +26,8 @@ struct HttpdConnData {
char *postBuff; char *postBuff;
}; };
//A struct describing an url. This is the main struct that's used to send different URL requests to
//different routines.
//A struct describing an url that's not in the filesystem or otherwise available.
//Also the way cgi functions get connected to an URL.
typedef struct { typedef struct {
const char *url; const char *url;
cgiSendCallback cgiCb; cgiSendCallback cgiCb;

@ -2,6 +2,15 @@
Connector to let httpd use the espfs filesystem to serve the files in that. Connector to let httpd use the espfs filesystem to serve the files in that.
*/ */
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* Jeroen Domburg <jeroen@spritesmods.com> wrote this file. As long as you retain
* this notice you can do whatever you want with this stuff. If we meet some day,
* and you think this stuff is worth it, you can buy me a beer in return.
* ----------------------------------------------------------------------------
*/
#include "espmissingincludes.h" #include "espmissingincludes.h"
#include <string.h> #include <string.h>
#include <osapi.h> #include <osapi.h>
@ -15,6 +24,9 @@ Connector to let httpd use the espfs filesystem to serve the files in that.
#include "httpdespfs.h" #include "httpdespfs.h"
//This is a catch-all cgi function. It takes the url passed to it, looks up the corresponding
//path in the filesystem and if it exists, passes the file through. This simulates what a normal
//webserver would do with static files.
int ICACHE_FLASH_ATTR cgiEspFsHook(HttpdConnData *connData) { int ICACHE_FLASH_ATTR cgiEspFsHook(HttpdConnData *connData) {
EspFsFile *file=connData->cgiData; EspFsFile *file=connData->cgiData;
int len; int len;
@ -52,6 +64,8 @@ int ICACHE_FLASH_ATTR cgiEspFsHook(HttpdConnData *connData) {
} }
//cgiEspFsTemplate can be used as a template.
typedef struct { typedef struct {
EspFsFile *file; EspFsFile *file;
void *tplArg; void *tplArg;

@ -1,3 +1,14 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* Jeroen Domburg <jeroen@spritesmods.com> wrote this file. As long as you retain
* this notice you can do whatever you want with this stuff. If we meet some day,
* and you think this stuff is worth it, you can buy me a beer in return.
* ----------------------------------------------------------------------------
*/
#include "espmissingincludes.h" #include "espmissingincludes.h"
#include "c_types.h" #include "c_types.h"
#include "user_interface.h" #include "user_interface.h"

@ -1,30 +1,45 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* Jeroen Domburg <jeroen@spritesmods.com> wrote this file. As long as you retain
* this notice you can do whatever you want with this stuff. If we meet some day,
* and you think this stuff is worth it, you can buy me a beer in return.
* ----------------------------------------------------------------------------
*/
#include "espmissingincludes.h" #include "espmissingincludes.h"
#include "ets_sys.h" #include "ets_sys.h"
#include "driver/uart.h"
#include "osapi.h" #include "osapi.h"
#include "httpd.h" #include "httpd.h"
#include "io.h" #include "io.h"
#include "httpdespfs.h" #include "httpdespfs.h"
#include "cgi.h" #include "cgi.h"
#include "cgiwifi.h"
#include "stdout.h"
HttpdBuiltInUrl builtInUrls[]={ HttpdBuiltInUrl builtInUrls[]={
{"/", cgiRedirect, "/test2.html"}, {"/", cgiRedirect, "/test2.html"},
{"/flash.bin", cgiReadFlash, NULL}, {"/flash.bin", cgiReadFlash, NULL},
{"/led.tpl", cgiEspFsTemplate, tplLed},
{"/led.cgi", cgiLed, NULL}, {"/led.cgi", cgiLed, NULL},
//Routines to make the /wifi URL and everything beneath it work.
{"/wifi", cgiRedirect, "/wifi/wifi.tpl"}, {"/wifi", cgiRedirect, "/wifi/wifi.tpl"},
{"/wifi/", cgiRedirect, "/wifi/wifi.tpl"}, {"/wifi/", cgiRedirect, "/wifi/wifi.tpl"},
{"/wifi/wifiscan.cgi", cgiWiFiScan, NULL}, {"/wifi/wifiscan.cgi", cgiWiFiScan, NULL},
{"/wifi/wifi.tpl", cgiEspFsTemplate, tplWlan}, {"/wifi/wifi.tpl", cgiEspFsTemplate, tplWlan},
{"/wifi/connect.cgi", cgiWiFiConnect}, {"/wifi/connect.cgi", cgiWiFiConnect},
{"*", cgiEspFsHook, NULL}, {"*", cgiEspFsHook, NULL}, //Catch-all cgi function for the filesystem
{NULL, NULL, NULL} {NULL, NULL, NULL}
}; };
void user_init(void) { void user_init(void) {
uart_init(BIT_RATE_115200, BIT_RATE_115200); stdoutInit();
ioInit(); ioInit();
httpdInit(builtInUrls, 80); httpdInit(builtInUrls, 80);
os_printf("\nReady\n"); os_printf("\nReady\n");

Loading…
Cancel
Save