Merge pull request #20 from con-f-use/master

Modularize esp8266 components
This commit is contained in:
CNLohr 2016-08-18 20:11:24 -04:00 committed by GitHub
commit 6c93368b90
42 changed files with 70 additions and 4028 deletions

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "embedded8266/esp82xx"]
path = embedded8266/esp82xx
url = git@github.com:cnlohr/esp82xx.git

View file

@ -1,31 +0,0 @@
*Note if you use the ESP8266 port, you are bound to this license as well as
the regular ColorChord license.* (Yes, I'm aware one is a BSD-based license
and the other is a MIT-based license, but this is not really a problem for
the ESP8266 as long as you follow the ColorChord license and only use it on
the ESP8266)
ESPRSSIF MIT License
Copyright (c) 2015 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
Portions Copyright (c) 2015 Charles Lohr
Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only,
in which case, it is free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

1
embedded8266/LICENSE Symbolic link
View file

@ -0,0 +1 @@
esp82xx/LICENSE

View file

@ -1,79 +1,13 @@
include makeconf.inc # Look here for user configuration
include user.cfg
include esp82xx/common.mf
include esp82xx/main.mf
.PHONY : all clean cleanall netburn burnweb burn
uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
TARGET = image.elf
FW_FILE1 = $(TARGET)-0x00000.bin
FW_FILE2 = $(TARGET)-0x40000.bin
SRCS = \
driver/uart.c \
common/mystuff.c \
common/flash_rewriter.c \
common/http.c \
common/http_custom.c \
common/mfs.c \
user/ws2812_i2s.c \
SRCS += user/ws2812_i2s.c \
user/hpatimer.c \
user/custom_commands.c \
driver/adc.c \
user/adc.c \
../embeddedcommon/DFT32.c \
../embeddedcommon/embeddednf.c \
../embeddedcommon/embeddedout.c \
user/user_main.c \
common/commonservices.c
../embeddedcommon/embeddedout.c
LIBS = main lwip ssl upgrade net80211 wpa net80211 phy lwip pp crypto
INCL = $(SDK)/include myclib include .
LDFLAGS_CORE += -Wl,-Map,output.map
CFLAGS = -mlongcalls -Os $(addprefix -I,$(INCL) $(call uniq, $(patsubst %/,%,$(dir $(SRCS))))) $(OPTS)
LDFLAGS_CORE = -nostdlib -L$(XTLIB) -L$(XTGCCLIB) \
$(addprefix $(SDK)/lib/lib,$(addsuffix .a,$(LIBS))) \
$(XTGCCLIB) -T $(SDK)/ld/eagle.app.v6.ld -Wl,-Map,output.map
# -flto -Wl,--relax -Wl,--gc-sections
LINKFLAGS = $(LDFLAGS_CORE) -B$(XTLIB)
##########################################################################RULES
all : $(FW_FILE1) $(FW_FILE2)
$(FW_FILE1) $(FW_FILE2) : $(TARGET)
@echo "FW $@"
export PATH="$(FOLDERPREFIX):$$PATH"; $(ESPTOOL_PY) elf2image $(TARGET)
$(TARGET) : $(SRCS)
$(CC) $(CFLAGS) $^ $(LINKFLAGS) -o $@
ifeq ($(CHIP), 8285)
burn : $(FW_FILE1) $(FW_FILE2)
($(ESPTOOL_PY) --port $(PORT) write_flash -fs 8m -fm dout 0x00000 $(FW_FILE1) 0x40000 $(FW_FILE2))||(true)
else ifeq ($(CHIP), 8266)
burn : $(FW_FILE1) $(FW_FILE2)
($(ESPTOOL_PY) --port $(PORT) write_flash 0x00000 $(FW_FILE1) 0x40000 $(FW_FILE2))||(true)
else
$(error Error: Unknown chip '$(CHIP)')
endif
burnweb :
@cd web && $(MAKE) $(MFLAGS) $(MAKEOVERRIDES) page.mpfs
($(ESPTOOL_PY) --port $(PORT) write_flash 0x10000 web/page.mpfs)||(true)
#If you have space, MFS should live at 0x100000. It can also live at
#0x10000. But, then it is limited to 180kB. You might need to do this if
# you have a 512kB ESP variant.
netburn : $(FW_FILE1) $(FW_FILE2)
@cd web && $(MAKE) $(MFLAGS) $(MAKEOVERRIDES) execute_reflash
web/execute_reflash $(IP) $(FW_FILE1) $(FW_FILE2)
netweb :
@cd web && $(MAKE) $(MFLAGS) $(MAKEOVERRIDES) push
clean :
$(RM) $(patsubst %.c,%.o,$(SRCS)) $(TARGET)
purge : clean
@cd web && $(MAKE) $(MFLAGS) $(MAKEOVERRIDES) clean
$(RM) $(FW_FILE1) $(FW_FILE2)

View file

@ -1,7 +1,7 @@
#ifndef _CCCONFIG_H
#define _CCCONFIG_H
#include "c_types.h"
#include <c_types.h>
#define HPABUFFSIZE 512

View file

@ -1,629 +0,0 @@
//Copyright 2015 <>< Charles Lohr Under the MIT/x11 License, NewBSD License or
// ColorChord License. You Choose.
#include "commonservices.h"
#include "mem.h"
#include "c_types.h"
#include "user_interface.h"
#include "ets_sys.h"
#include "osapi.h"
#include "espconn.h"
#include "mystuff.h"
#include "ip_addr.h"
#include "http.h"
#include "spi_flash.h"
#include "esp8266_rom.h"
#include <gpio.h>
#include "flash_rewriter.h"
static struct espconn *pUdpServer;
static struct espconn *pHTTPServer;
struct espconn *pespconn;
uint16_t g_gpiooutputmask = 0;
int ets_str2macaddr(void *, void *);
static int need_to_switch_back_to_soft_ap = 0; //0 = no, 1 = will need to. 2 = do it now.
#define MAX_STATIONS 20
struct totalscan_t
{
char name[32];
char mac[18]; //string
int8_t rssi;
uint8_t channel;
uint8_t encryption;
} totalscan[MAX_STATIONS];
int scanplace = 0;
static void ICACHE_FLASH_ATTR scandone(void *arg, STATUS status)
{
scaninfo *c = arg;
struct bss_info *inf;
if( need_to_switch_back_to_soft_ap == 1 )
need_to_switch_back_to_soft_ap = 2;
printf("!%p\n",c->pbss);
if (!c->pbss) {
scanplace = -1;
return;
}
// printf("!%s\n",inf->ssid);
STAILQ_FOREACH(inf, c->pbss, next) {
printf( "%s\n", inf->ssid );
ets_memcpy( totalscan[scanplace].name, inf->ssid, 32 );
ets_sprintf( totalscan[scanplace].mac, MACSTR, MAC2STR( inf->bssid ) );
//ets_memcpy( totalscan[scanplace].mac, "not implemented", 16 );
totalscan[scanplace].rssi = inf->rssi;
totalscan[scanplace].channel = inf->channel;
totalscan[scanplace].encryption = inf->authmode;
inf = (struct bss_info *) &inf->next;
scanplace++;
if( scanplace == MAX_STATIONS ) break;
}
}
int ICACHE_FLASH_ATTR issue_command(char * buffer, int retsize, char *pusrdata, unsigned short len)
{
char * buffend = buffer;
pusrdata[len] = 0;
switch( pusrdata[0] )
{
case 'e': case 'E': //Echo
if( retsize > len )
{
ets_memcpy( buffend, pusrdata, len );
return len;
}
else
{
return -1;
}
case 'f': case 'F': //Flashing commands (F_)
{
flashchip->chip_size = 0x01000000;
const char * colon = (const char *) ets_strstr( (char*)&pusrdata[2], "\t" );
int nr = my_atoi( &pusrdata[2] );
switch (pusrdata[1])
{
case 'e': case 'E': //(FE#\n) <- # = sector.
{
if( nr < 16 )
{
buffend += ets_sprintf(buffend, "!FE%d\r\n", nr );
break;
}
EnterCritical();
spi_flash_erase_sector( nr ); //SPI_FLASH_SEC_SIZE 4096
ExitCritical();
buffend += ets_sprintf(buffend, "FE%d\r\n", nr );
break;
}
case 'b': case 'B': //(FB#\n) <- # = block.
{
if( nr < 1 ) //Not allowed to erase boot sector.
{
buffend += ets_sprintf(buffend, "!FB%d\r\n", nr );
break;
}
EnterCritical();
SPIEraseBlock( nr );
ExitCritical();
buffend += ets_sprintf(buffend, "FB%d\r\n", nr );
break;
}
case 'm': case 'M': //Execute the flash re-writer
{
int r = (*GlobalRewriteFlash)( &pusrdata[2], len-2 );
buffend += ets_sprintf( buffend, "!FM%d\r\n", r );
break;
}
case 'w': case 'W': //Flash Write (FW#\n) <- # = byte pos. Reads until end-of-packet.
if( colon )
{
colon++;
const char * colon2 = (const char *) ets_strstr( (char*)colon, "\t" );
if( colon2 && nr >= 65536)
{
colon2++;
int datlen = (int)len - (colon2 - pusrdata);
ets_memcpy( buffer, colon2, datlen );
EnterCritical();
spi_flash_write( nr, (uint32*)buffer, (datlen/4)*4 );
ExitCritical();
#ifdef VERIFY_FLASH_WRITE
#define VFW_SIZE 128
printf( "FW%d\r\n", nr );
int jj;
uint8_t __attribute__ ((aligned (32))) buf[VFW_SIZE];
for(jj=0; jj<datlen; jj+=VFW_SIZE) {
spi_flash_read( nr+jj, (uint32*)buf, VFW_SIZE );
if( ets_memcmp( buf, buffer+jj, jj+VFW_SIZE>datlen ? datlen%VFW_SIZE : VFW_SIZE ) != 0 ) goto failw;
}
#endif
buffend += ets_sprintf(buffend, "FW%d\r\n", nr );
break;
}
}
failw:
buffend += ets_sprintf(buffend, "!FW\r\n" );
break;
case 'x': case 'X': //Flash Write Hex (FX#\t#\tDATTAAAAA) <- a = byte pos. b = length (in hex-pairs). Generally used for web-browser.
if( colon )
{
int i;
int siz = 0;
colon++;
char * colon2 = (char *) ets_strstr( (char*)colon, "\t" );
if( colon2 )
{
*colon2 = 0;
siz = my_atoi( colon );
}
//nr = place to write.
//siz = size to write.
//colon2 = data start.
if( colon2 && nr >= 524288)
{
colon2++;
int datlen = ((int)len - (colon2 - pusrdata))/2;
if( datlen > siz ) datlen = siz;
for( i = 0; i < datlen; i++ )
{
int8_t r1 = fromhex1( *(colon2++) );
int8_t r2 = fromhex1( *(colon2++) );
if( r1 == -1 || r2 == -1 ) goto failfx;
buffend[i] = (r1 << 4) | r2;
}
//ets_memcpy( buffer, colon2, datlen );
EnterCritical();
spi_flash_write( nr, (uint32*)buffend, (datlen/4)*4 );
ExitCritical();
#ifdef VERIFY_FLASH_WRITE
// uint8_t __attribute__ ((aligned (32))) buf[1300];
// spi_flash_read( nr, (uint32*)buf, (datlen/4)*4 );
// if( ets_memcmp( buf, buffer, (datlen/4)*4 ) != 0 ) break;
// Rather do it in chunks, to avoid allocationg huge buf
#define VFW_SIZE 128
printf( "FW%d\r\n", nr );
int jj;
uint8_t __attribute__ ((aligned (32))) buf[VFW_SIZE];
for(jj=0; jj<datlen; jj+=VFW_SIZE) {
spi_flash_read( nr+jj, (uint32*)buf, VFW_SIZE );
if( ets_memcmp( buf, buffer+jj, jj+VFW_SIZE>datlen ? datlen%VFW_SIZE : VFW_SIZE ) != 0 ) goto failfx;
}
#endif
buffend += ets_sprintf(buffend, "FX%d\t%d\r\n", nr, siz );
break;
}
}
failfx:
buffend += ets_sprintf(buffend, "!FX\r\n" );
break;
case 'r': case 'R': //Flash Read (FR#\n) <- # = sector.
if( colon )
{
colon++;
int datlen = my_atoi( colon );
datlen = (datlen/4)*4; //Must be multiple of 4 bytes
if( datlen <= 1280 )
{
buffend += ets_sprintf(buffend, "FR%08d\t%04d\t", nr, datlen ); //Caution: This string must be a multiple of 4 bytes.
spi_flash_read( nr, (uint32*)buffend, datlen );
buffend += datlen;
break;
}
}
buffend += ets_sprintf(buffend, "!FR\r\n" );
break;
}
flashchip->chip_size = 0x00080000;
return buffend - buffer;
}
case 'i': case 'I': //Respond with device info.
{
buffend += ets_sprintf(buffend, "I" );
int i;
for( i = 0; i < 2 ;i++ )
{
struct ip_info ipi;
wifi_get_ip_info( i, &ipi );
buffend += ets_sprintf(buffend, "\t"IPSTR, IP2STR(&ipi.ip) );
}
buffend += ets_sprintf(buffend, "\r\n" );
return buffend - buffer;
}
case 'w': case 'W': // (W1:SSID:PASSWORD) (To connect) or (W2) to be own base station. ...or WI, to get info... or WS to scan.
{
int c1l = 0;
int c2l = 0;
char * colon = (char *) ets_strstr( (char*)&pusrdata[2], "\t" );
char * colon2 = (colon)?((char *)ets_strstr( (char*)(colon+1), "\t" )):0;
char * colon3 = (colon2)?((char *)ets_strstr( (char*)(colon2+1), "\t" )):0;
char * colon4 = (colon3)?((char *)ets_strstr( (char*)(colon3+1), "\t" )):0;
char * extra = colon2;
char mac[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
int bssid_set = 0;
if( colon ) { *colon = 0; colon++; }
if( colon2 ) { *colon2 = 0; colon2++; }
if( colon3 ) { *colon3 = 0; colon3++; }
if( colon4 ) { *colon4 = 0; colon4++; }
if( colon ) { c1l = ets_strlen( colon ); }
if( colon2 ) { c2l = ets_strlen( colon2 ); }
if( colon3 )
{
bssid_set = ets_str2macaddr( mac, colon3 )?1:0;
if( ( mac[0] == 0x00 || mac[0] == 0xff ) &&
( mac[1] == 0x00 || mac[1] == 0xff ) &&
( mac[2] == 0x00 || mac[2] == 0xff ) &&
( mac[3] == 0x00 || mac[3] == 0xff ) &&
( mac[4] == 0x00 || mac[4] == 0xff ) &&
( mac[5] == 0x00 || mac[5] == 0xff ) ) bssid_set = 0;
}
if( extra )
{
for( ; *extra; extra++ )
{
if( *extra < 32 )
{
*extra = 0;
break;
}
}
}
switch (pusrdata[1])
{
case '1': //Station mode
case '2': //AP Mode
if( colon && colon2 && ets_strlen( colon ) > 1 )
{
if( c1l > 31 ) c1l = 31;
if( c2l > 63 ) c2l = 63;
printf( "Switching to: \"%s\"/\"%s\" (%d/%d). BSSID_SET: %d [%c]\n", colon, colon2, c1l, c2l, bssid_set, pusrdata[1] );
if( pusrdata[1] == '1' )
{
struct station_config stationConf;
wifi_station_get_config(&stationConf);
os_memcpy(&stationConf.ssid, colon, c1l);
os_memcpy(&stationConf.password, colon2, c2l);
stationConf.ssid[c1l] = 0;
stationConf.password[c2l] = 0;
stationConf.bssid_set = bssid_set;
os_memcpy( stationConf.bssid, mac, 6 );
printf( "-->'%s'\n",stationConf.ssid);
printf( "-->'%s'\n",stationConf.password);
EnterCritical();
// wifi_station_set_config(&stationConf);
wifi_set_opmode( 1 );
wifi_station_set_config(&stationConf);
wifi_station_connect();
ExitCritical();
// wifi_station_get_config( &stationConf );
buffend += ets_sprintf( buffend, "W1\r\n" );
printf( "Switching.\n" );
}
else
{
struct softap_config config;
char macaddr[6];
wifi_softap_get_config( &config );
wifi_get_macaddr(SOFTAP_IF, macaddr);
os_memcpy( &config.ssid, colon, c1l );
os_memcpy( &config.password, colon2, c2l );
config.ssid_len = c1l;
#if 0 //We don't support encryption.
config.ssid[c1l] = 0;
config.password[c2l] = 0;
config.authmode = 0;
if( colon3 )
{
int k;
for( k = 0; enctypes[k]; k++ )
{
if( strcmp( colon3, enctypes[k] ) == 0 )
config.authmode = k;
}
}
#endif
int chan = (colon4)?my_atoi(colon4):config.channel;
if( chan == 0 || chan > 13 ) chan = 1;
config.channel = chan;
// printf( "Mode now. %s %s %d %d %d %d %d\n", config.ssid, config.password, config.ssid_len, config.channel, config.authmode, config.max_connection );
// printf( "Mode Set. %d\n", wifi_get_opmode() );
EnterCritical();
wifi_softap_set_config(&config);
wifi_set_opmode( 2 );
ExitCritical();
printf( "Switching SoftAP: %d %d.\n", chan, config.authmode );
buffend += ets_sprintf( buffend, "W2\r\n" );
}
}
break;
case 'I':
{
char macmap[15];
int mode = wifi_get_opmode();
buffend += ets_sprintf( buffend, "WI%d", mode );
if( mode == 2 )
{
uint8_t mac[6];
struct softap_config ap;
wifi_softap_get_config( &ap );
wifi_get_macaddr( 1, mac );
ets_sprintf( macmap, MACSTR, MAC2STR( mac ) );
buffend += ets_sprintf( buffend, "\t%s\t%s\t%s\t%d", ap.ssid, ap.password, macmap, ap.channel );
}
else
{
struct station_config sc;
ets_memset( &sc, 0, sizeof( sc ) );
wifi_station_get_config( &sc );
if( sc.bssid_set )
ets_sprintf( macmap, MACSTR, MAC2STR( sc.bssid ) );
else
macmap[0] = 0;
buffend += ets_sprintf( buffend, "\t%s\t%s\t%s\t%d", sc.ssid, sc.password, macmap, wifi_get_channel() );
}
}
break;
case 'X': case 'x':
{
int rssi = wifi_station_get_rssi();
if( rssi >= 0 )
{
buffend += ets_sprintf( buffend, "WX-" );
}
else
{
buffend += ets_sprintf( buffend, "WX%d", wifi_station_get_rssi() );
}
break;
}
case 'S': case 's':
{
int i, r;
struct scan_config sc;
scanplace = 0;
sc.ssid = 0;
sc.bssid = 0;
sc.channel = 0;
sc.show_hidden = 1;
EnterCritical();
if( wifi_get_opmode() == SOFTAP_MODE )
{
wifi_set_opmode_current( STATION_MODE );
need_to_switch_back_to_soft_ap = 1;
}
r = wifi_station_scan(&sc, scandone );
ExitCritical();
buffend += ets_sprintf( buffend, "WS%d\n", r );
uart0_sendStr(buffer);
break;
}
break;
case 'R': case 'r':
{
int i, r;
buffend += ets_sprintf( buffend, "WR%d\n", scanplace );
for( i = 0; i < scanplace && buffend - buffer < retsize - 64; i++ )
{
buffend += ets_sprintf( buffend, "#%s\t%s\t%d\t%d\t%s\n",
totalscan[i].name, totalscan[i].mac, totalscan[i].rssi, totalscan[i].channel, enctypes[totalscan[i].encryption] );
}
break;
}
break;
}
return buffend - buffer;
}
case 'G': case 'g':
{
static const uint32_t AFMapper[16] = {
0, PERIPHS_IO_MUX_U0TXD_U, 0, PERIPHS_IO_MUX_U0RXD_U,
0, 0, 1, 1,
1, 1, 1, 1,
PERIPHS_IO_MUX_MTDI_U, PERIPHS_IO_MUX_MTCK_U, PERIPHS_IO_MUX_MTMS_U, PERIPHS_IO_MUX_MTDO_U };
int nr = my_atoi( &pusrdata[2] );
if( AFMapper[nr] == 1 )
{
buffend += ets_sprintf( buffend, "!G%c%d\n", pusrdata[1], nr );
return buffend - buffer;
}
else if( AFMapper[nr] )
{
PIN_FUNC_SELECT( AFMapper[nr], 3); //Select AF pin to be GPIO.
}
switch( pusrdata[1] )
{
case '0':
case '1':
GPIO_OUTPUT_SET(GPIO_ID_PIN(nr), pusrdata[1]-'0' );
buffend += ets_sprintf( buffend, "G%c%d", pusrdata[1], nr );
g_gpiooutputmask |= (1<<nr);
break;
case 'i': case 'I':
GPIO_DIS_OUTPUT(GPIO_ID_PIN(nr));
buffend += ets_sprintf( buffend, "GI%d\n", nr );
g_gpiooutputmask &= ~(1<<nr);
break;
case 'f': case 'F':
{
int on = GPIO_INPUT_GET( GPIO_ID_PIN(nr) );
on = !on;
GPIO_OUTPUT_SET(GPIO_ID_PIN(nr), on );
g_gpiooutputmask |= (1<<nr);
buffend += ets_sprintf( buffend, "GF%d\t%d\n", nr, on );
break;
}
case 'g': case 'G':
buffend += ets_sprintf( buffend, "GG%d\t%d\n", nr, GPIO_INPUT_GET( GPIO_ID_PIN(nr) ) );
break;
case 's': case 'S':
{
uint32_t rmask = 0;
int i;
for( i = 0; i < 16; i++ )
{
rmask |= GPIO_INPUT_GET( GPIO_ID_PIN(i) )?(1<<i):0;
}
buffend += ets_sprintf( buffend, "GS\t%d\t%d\n", g_gpiooutputmask, rmask );
break;
}
}
return buffend - buffer;
}
case 'c': case 'C':
return CustomCommand( buffer, retsize, pusrdata, len);
}
return -1;
}
void ICACHE_FLASH_ATTR issue_command_udp(void *arg, char *pusrdata, unsigned short len)
{
char __attribute__ ((aligned (32))) retbuf[1300];
int r = issue_command( retbuf, 1300, pusrdata, len );
if( r > 0 )
{
//YUCK! Since SDK 1.4.0, we have to do this ridiculous thing to respond to senders.
struct espconn * rc = (struct espconn *)arg;
remot_info * ri = 0;
espconn_get_connection_info( rc, &ri, 0);
ets_memcpy( rc->proto.udp->remote_ip, ri->remote_ip, 4 );
rc->proto.udp->remote_port = ri->remote_port;
espconn_sendto( rc, retbuf, r );
}
}
void ICACHE_FLASH_ATTR CSPreInit()
{
int opmode = wifi_get_opmode();
printf( "Opmode: %d\n", opmode );
if( opmode == 1 )
{
struct station_config sc;
wifi_station_get_config(&sc);
printf( "Station mode: \"%s\":\"%s\" (bssid_set:%d)\n", sc.ssid, sc.password, sc.bssid_set );
if( sc.ssid[0] == 0 && !sc.bssid_set )
{
wifi_set_opmode( 2 );
opmode = 2;
}
else
{
wifi_station_connect();
}
}
if( opmode == 2 )
{
struct softap_config sc;
wifi_softap_get_config(&sc);
printf( "SoftAP mode: \"%s\":\"%s\"\n", sc.ssid, sc.password );
}
}
void ICACHE_FLASH_ATTR CSInit()
{
pUdpServer = (struct espconn *)os_zalloc(sizeof(struct espconn));
ets_memset( pUdpServer, 0, sizeof( struct espconn ) );
pUdpServer->type = ESPCONN_UDP;
pUdpServer->proto.udp = (esp_udp *)os_zalloc(sizeof(esp_udp));
pUdpServer->proto.udp->local_port = 7878;
espconn_regist_recvcb(pUdpServer, issue_command_udp);
espconn_create( pUdpServer );
pHTTPServer = (struct espconn *)os_zalloc(sizeof(struct espconn));
ets_memset( pHTTPServer, 0, sizeof( struct espconn ) );
espconn_create( pHTTPServer );
pHTTPServer->type = ESPCONN_TCP;
pHTTPServer->state = ESPCONN_NONE;
pHTTPServer->proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp));
pHTTPServer->proto.tcp->local_port = 80;
espconn_regist_connectcb(pHTTPServer, httpserver_connectcb);
espconn_accept(pHTTPServer);
espconn_regist_time(pHTTPServer, 15, 0); //timeout
}
void ICACHE_FLASH_ATTR CSTick( int slowtick )
{
static uint8_t tick_flag = 0;
if( slowtick )
{
tick_flag = 1;
return;
}
if( need_to_switch_back_to_soft_ap == 2 )
{
need_to_switch_back_to_soft_ap = 0;
EnterCritical();
wifi_set_opmode_current( SOFTAP_MODE );
ExitCritical();
}
HTTPTick(0);
//TRICKY! If we use the timer to initiate this, connecting to people's networks
//won't work! I don't know why, so I do it here. this does mean sometimes it'll
//pause, though.
if( tick_flag )
{
tick_flag = 0;
HTTPTick(1);
}
}

View file

@ -1,30 +0,0 @@
//Copyright 2015 <>< Charles Lohr Under the MIT/x11 License, NewBSD License or
// ColorChord License. You Choose.
#ifndef _COMMON_H
#define _COMMON_H
#include "c_types.h"
//Returns nr bytes to return. You must allocate retdata.
//It MUST be at least 1,300 bytes large and it MUST be 32-bit aligned.
//NOTE: It is SAFE to use pusrdata and retdata as the same buffer.
int ICACHE_FLASH_ATTR issue_command(char * retdata, int retsize, char *pusrdata, unsigned short len);
//Includes UDP Control + HTTP Interfaces
void ICACHE_FLASH_ATTR CSPreInit();
void ICACHE_FLASH_ATTR CSInit();
void ICACHE_FLASH_ATTR CSTick( int slowtick );
//You must provide:
//Critical should not lock interrupts, just disable services that have problems
//with double-interrupt faults. I.e. turn off/on any really fast timer interrupts.
//These generally only get called when doing serious operations like reflashing.
void EnterCritical();
void ExitCritical();
//If we receive a command that's not F, E or W (Flash Echo Wifi)
int ICACHE_FLASH_ATTR CustomCommand(char * buffer, int retsize, char *pusrdata, unsigned short len);
#endif

View file

@ -1,92 +0,0 @@
#ifndef _ESP8266_ROM_FUNCTS
#define _ESP8266_ROM_FUNCTS
//This is my best guess at some of the ROM functions for the ESP8266.
//I have no idea if this stuff is correct!
#include <spi_flash.h>
#include <c_types.h>
void Cache_Read_Disable(); //Can't seem to operate...
void Cache_Read_Enable();
//PROVIDE ( Cache_Read_Disable = 0x400047f0 );
//PROVIDE ( Cache_Read_Enable = 0x40004678 );
typedef struct {
uint32_t i[2];
uint32_t buf[4];
unsigned char in[64];
unsigned char digest[16];
} MD5_CTX;
void MD5Init ( MD5_CTX *mdContext);
void MD5Update( MD5_CTX *mdContext, const unsigned char *inBuf, unsigned int inLen);
void MD5Final ( unsigned char hash[], MD5_CTX *mdContext);
//SHA Stuff from: https://github.com/pvvx/esp8266web/blob/master/app/include/bios/cha1.h
#define SHA1_HASH_LEN 20
typedef struct {
uint32 state[5];
uint32 count[2];
uint8 buffer[64];
uint8 extra[40];
} SHA1_CTX;
void SHA1Init(SHA1_CTX* context);
void SHA1Update(SHA1_CTX* context,
const uint8 *data,
size_t len);
void SHA1Final(uint8 digest[SHA1_HASH_LEN], SHA1_CTX* context);
void SHA1Transform(uint32 state[5], const uint8 buffer[64]);
//SPI_FLASH_SEC_SIZE 4096
void SPIEraseSector(uint16 sec);
void SPIEraseArea(uint32 start,uint32 len); //Doesn't work?
void SPIEraseBlock(uint16 blk);
void SPIWrite(uint32 des_addr, uint32_t *src_addr, uint32_t size);
void SPIRead(uint32 src_addr, uint32_t *des_addr, uint16_t size);
void SPILock( uint16_t sec ); //??? I don't use this?
void SPIUnlock( ); //??? I don't use this? -> Seems to crash.
extern SpiFlashChip * flashchip; //don't forget: flashchip->chip_size = 0x01000000;
/*
flashchip->chip_size = 0x01000000;
{
uint32_t __attribute__ ((aligned (16))) t[1024];
t[0] = 0xAABBCCDD;
t[1] = 0xEEFF0011;
for( i = 0; i < 10000; i++ ) uart0_sendStr("A\n");
SPIEraseSector( 1000000/4096 );
for( i = 0; i < 10000; i++ ) uart0_sendStr("B\n");
SPIWrite( 1000000, t, 8 );
}
for( i = 0; i < 10000; i++ ) uart0_sendStr("C\n");
while(1)
{
char ct[32];
uint32_t __attribute__ ((aligned (16))) ret = 0x12345678;
// SPIRead( 1000000, &ret, 4 );
ret = *(uint32_t*)(0x40200000+1000004);
ets_sprintf( ct, "%08x\n", ret );
printf( ct );
}
*/
void software_reset();
#endif

View file

@ -1,285 +0,0 @@
//Copyright 2015 <>< Charles Lohr Under the MIT/x11 License, NewBSD License or
// ColorChord License. You Choose.
#include "flash_rewriter.h"
#include <c_types.h>
#include <esp8266_rom.h>
#include <stdio.h>
#define SRCSIZE 4096
#define BLKSIZE 65536
static const char * key = "";
static int keylen = 0;
static int MyRewriteFlash( char * command, int commandlen )
{
MD5_CTX md5ctx;
char __attribute__ ((aligned (32))) buffer[512];
char * colons[8];
int i, ipl = 0;
int p;
//[from_address]\t[to_address]\t[size]\t[MD5(key+data)]\t[from_address]\t[to_address]\t[size]\t[MD5(key+data)]
command[commandlen] = 0;
flashchip->chip_size = 0x01000000;
ets_wdt_disable();
colons[ipl++] = &command[0];
for( i = 0; i < commandlen; i++ )
{
if( command[i] == 0 ) break;
if( command[i] == '\t' )
{
if( ipl >= 8 ) break;
command[i] = 0;
colons[ipl++] = &command[i+1];
}
}
if( ipl != 8 )
{
return 1;
}
uint32_t from1 = my_atoi( colons[0] );
uint32_t to1 = my_atoi( colons[1] );
int32_t size1 = my_atoi( colons[2] );
char * md51 = colons[3];
char md5h1raw[48];
char md5h1[48];
uint32_t from2 = my_atoi( colons[4] );
uint32_t to2 = my_atoi( colons[5] );
int32_t size2 = my_atoi( colons[6] );
char * md52 = colons[7];
char md5h2raw[48];
char md5h2[48];
if( from1 == 0 || from2 == 0 || size1 == 0 )
{
return 2;
}
if( ( from1 & 0xfff ) || ( from2 & 0xfff ) || ( to1 & 0xfff ) || ( to2 & 0xfff ) )
{
return 3;
}
///////////////////////////////
char st[400];
/*
ets_sprintf( st, "!!%08x", (((uint32_t*)(0x40200000 + from1))) );
uart0_sendStr( st );
for( i = 0; i < 200; i++ )
{
ets_sprintf( st, "%08x", (uint32_t)(((uint32_t*)(0x40200000 + from1))[i]) );
uart0_sendStr( st );
}
uart0_sendStr( "+\n" );
/*
uint32_t __attribute__ ((aligned (32))) readr = 0xAAAAAAAA;
SPIRead( from1, &readr, 4 );
ets_sprintf( st, ":%08x\n", readr );
uart0_sendStr( st );
readr = 0x12345678;
SPIRead( from1+4, &readr, 4 );
ets_sprintf( st, ":%08x\n", readr );
uart0_sendStr( st );
uart0_sendStr( "\n" );
ets_sprintf( st, "TT: %08x ADDY: %08x\n", from1, &readr );
uart0_sendStr( st );
readr = 0xAAAAAAAA;
spi_flash_read( from1, &readr, 4 );
ets_sprintf( st, "+%08x\n", readr );
uart0_sendStr( st );
readr = 0xbbbbbbbb;
spi_flash_read( from1+4, &readr, 4 );
ets_sprintf( st, "+%08x\n", readr );
uart0_sendStr( st );
*/
/*
MD5Init( &md5ctx );
MD5Update( &md5ctx, (uint8_t*)0x40200000 + from1, 4 );
MD5Final( md5h1raw, &md5ctx );
for( i = 0; i < 16; i++ )
{
ets_sprintf( md5h1+i*2, "%02x", md5h1raw[i] );
}
uart0_sendStr( "Hash 1:" );
uart0_sendStr( md5h1 );
uart0_sendStr( "!\n" );
*/
//////////////////////////////
ets_sprintf( st, "Computing Hash 1: %08x size %d\n", from1, size1 );
uart0_sendStr( st );
MD5Init( &md5ctx );
if( keylen )
MD5Update( &md5ctx, key, keylen );
// MD5Update( &md5ctx, (uint8_t*)0x40200000 + from1, size1 );
SafeMD5Update( &md5ctx, (uint8_t*)0x40200000 + from1, size1 );
MD5Final( md5h1raw, &md5ctx );
for( i = 0; i < 16; i++ )
{
ets_sprintf( md5h1+i*2, "%02x", md5h1raw[i] );
}
uart0_sendStr( "Hash 1:" );
uart0_sendStr( md5h1 );
uart0_sendStr( "\n" );
for( i = 0; i < 32; i++ )
{
if( md5h1[i] != md51[i] )
{
//printf( "%s != %s", md5h1, md51 );
uart0_sendStr( "File 1 MD5 mismatch\nActual:" );
uart0_sendStr( md5h1 );
uart0_sendStr( "\nExpected:" );
uart0_sendStr( md51 );
uart0_sendStr( "\n" );
return 4;
}
}
ets_sprintf( st, "Computing Hash 2: %08x size %d\n", from2, size2 );
uart0_sendStr( st );
MD5Init( &md5ctx );
if( keylen )
MD5Update( &md5ctx, key, keylen );
SafeMD5Update( &md5ctx, (uint8_t*)0x40200000 + from2, size2 );
MD5Final( md5h2raw, &md5ctx );
for( i = 0; i < 16; i++ )
{
ets_sprintf( md5h2+i*2, "%02x", md5h2raw[i] );
}
uart0_sendStr( "Hash 2:" );
uart0_sendStr( md5h2 );
uart0_sendStr( "\n" );
/* for( i = 0; i <= size2/4; i++ )
{
uint32_t j = ((uint32_t*)(0x40200000 + from2))[i];
ets_sprintf( st, "%02x%02x%02x%02x\n", (uint8_t)(j>>0), (uint8_t)(j>>8), (uint8_t)(j>>16), (uint8_t)(j>>24) );
uart0_sendStr( st );
}*/
for( i = 0; i < 32; i++ )
{
if( md5h2[i] != md52[i] )
{
uart0_sendStr( "File 2 MD5 mismatch\nActual:" );
uart0_sendStr( md5h2 );
uart0_sendStr( "\nExpected:" );
uart0_sendStr( md52 );
uart0_sendStr( "\n" );
return 5;
}
}
//Need to round sizes up.
size1 = ((size1-1)&(~0xfff))+1;
size2 = ((size2-1)&(~0xfff))+1;
ets_sprintf( st, "Copy 1: %08x to %08x, size %d\n", from1, to1, size1 );
uart0_sendStr( st );
ets_sprintf( st, "Copy 2: %08x to %08x, size %d\n", from2, to2, size2 );
uart0_sendStr( st );
//Everything checked out... Need to move the flashes.
ets_delay_us( 1000 );
//Disable all interrupts.
ets_intr_lock();
uart_tx_one_char( 'A' );
int j;
ipl = (size1/BLKSIZE)+1;
p = to1/BLKSIZE;
for( i = 0; i < ipl; i++ )
{
SPIEraseBlock( p++ );
for( j = 0; j < BLKSIZE/SRCSIZE; j++ )
{
SPIWrite( to1, (uint32_t*)(0x40200000 + from1), SRCSIZE );
to1 += SRCSIZE;
from1 += SRCSIZE;
}
}
uart_tx_one_char( 'B' );
ipl = (size2/BLKSIZE)+1;
p = to2/BLKSIZE;
for( i = 0; i < ipl; i++ )
{
SPIEraseBlock( p++ );
for( j = 0; j < BLKSIZE/SRCSIZE; j++ )
{
SPIWrite( to2, (uint32_t*)(0x40200000 + from2), SRCSIZE );
to2 += SRCSIZE;
from2 += SRCSIZE;
}
}
uart_tx_one_char( 'C' );
void(*rebootme)() = (void(*)())0x40000080;
rebootme();
// system_upgrade_reboot();
// software_reset(); //Doesn't seem to boot back in.
//Destinations are erased. Copy over the other part.
// for( i = 0; i < ; i++ )
/*Things I know:
flashchip->chip_size = 0x01000000;
SPIEraseSector( 1000000/4096 );
SPIWrite( 1000000, &t, 4 ); <<This looks right.
SPIRead( 1000000, &t, 4 ); <<Will read if we just wrote, but not from cache.
uint32_t * v = (uint32_t*)(0x40200000 + 1000000); //This will read, but from cache.
//Looks like you can copy this way...
// SPIWrite( 1000004, 0x40200000 + 1000000, 4 );
*/
/*
MD5Init( &c );
MD5Update( &c, "apple", 5 );
MD5Final( hash, &c );*/
//Once we hit this stage we cannot do too much, otherwise we'll cause major crashing.
}
int (*GlobalRewriteFlash)( char * command, int commandlen ) = MyRewriteFlash;

View file

@ -1,20 +0,0 @@
//Copyright 2015 <>< Charles Lohr Under the MIT/x11 License, NewBSD License or
// ColorChord License. You Choose.
#ifndef _FLASH_REWRITER_H
#define _FLASH_REWRITER_H
//Unusual, but guarentees that the code resides in IRAM.
/*
Usage:
[from_address]:[to_address]:[size]:[MD5(key+data)]:[from_address]:[to_address]:[size]:[MD5(key+data)][extra byte required]
NOTE: YOU MUST USE 4096-byte-aligned boundaries.
Note: this will modify the text in "command"
*/
extern int (*GlobalRewriteFlash)( char * command, int commandlen );
#endif

View file

@ -1,625 +0,0 @@
//Copyright 2015 <>< Charles Lohr Under the MIT/x11 License, NewBSD License or
// ColorChord License. You Choose.
#include "http.h"
#include "mystuff.h"
#include "esp8266_rom.h"
#define HTDEBUG( x... ) printf( x )
//#define ISKEEPALIVE "keep-alive"
#define ISKEEPALIVE "close"
struct HTTPConnection HTTPConnections[HTTP_CONNECTIONS];
struct HTTPConnection * curhttp;
uint8 * curdata;
uint16 curlen;
uint8 wsmask[4];
uint8 wsmaskplace;
ICACHE_FLASH_ATTR void InternalStartHTTP( );
ICACHE_FLASH_ATTR void HTTPHandleInternalCallback( );
ICACHE_FLASH_ATTR void HTTPClose( )
{
//This is dead code, but it is a testament to Charles.
//Do not do this here. Wait for the ESP to tell us the
//socket is successfully closed.
//curhttp->state = HTTP_STATE_NONE;
curhttp->state = HTTP_WAIT_CLOSE;
espconn_disconnect( curhttp->socket );
}
void ICACHE_FLASH_ATTR HTTPGotData( )
{
uint8 c;
curhttp->timeout = 0;
while( curlen-- )
{
c = HTTPPOP;
// sendhex2( h->state ); sendchr( ' ' );
switch( curhttp->state )
{
case HTTP_STATE_WAIT_METHOD:
if( c == ' ' )
{
curhttp->state = HTTP_STATE_WAIT_PATH;
curhttp->state_deets = 0;
}
break;
case HTTP_STATE_WAIT_PATH:
curhttp->pathbuffer[curhttp->state_deets++] = c;
if( curhttp->state_deets == MAX_PATHLEN )
{
curhttp->state_deets--;
}
if( c == ' ' )
{
//Tricky: If we're a websocket, we need the whole header.
curhttp->pathbuffer[curhttp->state_deets-1] = 0;
curhttp->state_deets = 0;
if( strncmp( (const char*)curhttp->pathbuffer, "/d/ws", 5 ) == 0 )
{
curhttp->state = HTTP_STATE_DATA_WEBSOCKET;
curhttp->state_deets = 0;
}
else
{
curhttp->state = HTTP_STATE_WAIT_PROTO;
}
}
break;
case HTTP_STATE_WAIT_PROTO:
if( c == '\n' )
{
curhttp->state = HTTP_STATE_WAIT_FLAG;
}
break;
case HTTP_STATE_WAIT_FLAG:
if( c == '\n' )
{
curhttp->state = HTTP_STATE_DATA_XFER;
InternalStartHTTP( );
}
else if( c != '\r' )
{
curhttp->state = HTTP_STATE_WAIT_INFLAG;
}
break;
case HTTP_STATE_WAIT_INFLAG:
if( c == '\n' )
{
curhttp->state = HTTP_STATE_WAIT_FLAG;
curhttp->state_deets = 0;
}
break;
case HTTP_STATE_DATA_XFER:
//Ignore any further data?
curlen = 0;
break;
case HTTP_STATE_DATA_WEBSOCKET:
WebSocketGotData( c );
break;
case HTTP_WAIT_CLOSE:
if( curhttp->keep_alive )
{
curhttp->state = HTTP_STATE_WAIT_METHOD;
}
else
{
HTTPClose( );
}
break;
default:
break;
};
}
}
static void DoHTTP( uint8_t timed )
{
switch( curhttp->state )
{
case HTTP_STATE_NONE: //do nothing if no state.
break;
case HTTP_STATE_DATA_XFER:
if( TCPCanSend( curhttp->socket, 1024 ) ) //TCPDoneSend
{
if( curhttp->is_dynamic )
{
HTTPCustomCallback( );
}
else
{
HTTPHandleInternalCallback( );
}
}
break;
case HTTP_WAIT_CLOSE:
if( TCPDoneSend( curhttp->socket ) )
{
if( curhttp->keep_alive )
{
curhttp->state = HTTP_STATE_WAIT_METHOD;
}
else
{
HTTPClose( );
}
}
break;
case HTTP_STATE_DATA_WEBSOCKET:
if( TCPCanSend( curhttp->socket, 1024 ) ) //TCPDoneSend
{
WebSocketTickInternal();
}
break;
default:
if( timed )
{
if( curhttp->timeout++ > HTTP_SERVER_TIMEOUT )
{
HTTPClose( );
}
}
}
}
void HTTPTick( uint8_t timed )
{
uint8_t i;
for( i = 0; i < HTTP_CONNECTIONS; i++ )
{
if( curhttp ) { printf( "Unexpected Race Condition\n" );}
curhttp = &HTTPConnections[i];
DoHTTP( timed );
curhttp = 0;
}
}
void ICACHE_FLASH_ATTR HTTPHandleInternalCallback( )
{
uint16_t i, bytestoread;
if( curhttp->isdone )
{
HTTPClose( );
return;
}
if( curhttp->is404 )
{
START_PACK
PushString("HTTP/1.1 404 Not Found\r\nConnection: close\r\n\r\nFile not found.");
EndTCPWrite( curhttp->socket );
curhttp->isdone = 1;
return;
}
if( curhttp->isfirst )
{
char stto[10];
uint8_t slen = os_strlen( curhttp->pathbuffer );
const char * k;
START_PACK;
//TODO: Content Length? MIME-Type?
PushString("HTTP/1.1 200 Ok\r\n");
if( curhttp->bytesleft < 0xfffffffe )
{
PushString("Connection: "ISKEEPALIVE"\r\nContent-Length: ");
Uint32To10Str( stto, curhttp->bytesleft );
PushBlob( stto, os_strlen( stto ) );
curhttp->keep_alive = 1;
}
else
{
PushString("Connection: close\r\n");
curhttp->keep_alive = 0;
}
PushString( "\r\nContent-Type: " );
//Content-Type?
while( slen && ( curhttp->pathbuffer[--slen] != '.' ) );
k = &curhttp->pathbuffer[slen+1];
if( strcmp( k, "mp3" ) == 0 )
{
PushString( "audio/mpeg3" );
}
else if( strcmp( k, "gz" ) == 0 )
{
PushString( "text/plain\r\nContent-Encoding: gzip\r\nCache-Control: public, max-age=3600" );
}
else if( curhttp->bytesleft == 0xfffffffe )
{
PushString( "text/plain" );
}
else
{
PushString( "text/html" );
}
PushString( "\r\n\r\n" );
EndTCPWrite( curhttp->socket );
curhttp->isfirst = 0;
return;
}
START_PACK
for( i = 0; i < 4 && curhttp->bytesleft; i++ )
{
int bpt = curhttp->bytesleft;
if( bpt > MFS_SECTOR ) bpt = MFS_SECTOR;
curhttp->bytesleft = MFSReadSector( generic_ptr, &curhttp->data.filedescriptor );
generic_ptr += bpt;
}
EndTCPWrite( curhttp->socket );
if( !curhttp->bytesleft )
curhttp->isdone = 1;
}
void InternalStartHTTP( )
{
int32_t clusterno;
int8_t i;
const char * path = &curhttp->pathbuffer[0];
if( curhttp->pathbuffer[0] == '/' )
path++;
if( path[0] == 'd' && path[1] == '/' )
{
curhttp->is_dynamic = 1;
curhttp->isfirst = 1;
curhttp->isdone = 0;
curhttp->is404 = 0;
HTTPCustomStart();
return;
}
if( !path[0] )
{
path = "index.html";
}
i = MFSOpenFile( path, &curhttp->data.filedescriptor );
curhttp->bytessofar = 0;
if( i < 0 )
{
HTDEBUG( "404(%s)\n", path );
curhttp->is404 = 1;
curhttp->isfirst = 1;
curhttp->isdone = 0;
curhttp->is_dynamic = 0;
}
else
{
curhttp->isfirst = 1;
curhttp->isdone = 0;
curhttp->is404 = 0;
curhttp->is_dynamic = 0;
curhttp->bytesleft = curhttp->data.filedescriptor.filelen;
}
}
LOCAL void ICACHE_FLASH_ATTR
http_disconnetcb(void *arg) {
struct espconn *pespconn = (struct espconn *) arg;
((struct HTTPConnection * )pespconn->reverse)->state = 0;
}
LOCAL void ICACHE_FLASH_ATTR
http_recvcb(void *arg, char *pusrdata, unsigned short length)
{
struct espconn *pespconn = (struct espconn *) arg;
//Though it might be possible for this to interrupt the other
//tick task, I don't know if this is actually a probelem.
//I'm adding this back-up-the-register just in case.
if( curhttp ) { printf( "Unexpected Race Condition\n" );}
curhttp = (struct HTTPConnection * )pespconn->reverse;
curdata = (uint8*)pusrdata;
curlen = length;
HTTPGotData();
curhttp = 0 ;
}
void ICACHE_FLASH_ATTR
httpserver_connectcb(void *arg)
{
int i;
struct espconn *pespconn = (struct espconn *)arg;
for( i = 0; i < HTTP_CONNECTIONS; i++ )
{
if( HTTPConnections[i].state == 0 )
{
pespconn->reverse = &HTTPConnections[i];
HTTPConnections[i].socket = pespconn;
HTTPConnections[i].state = HTTP_STATE_WAIT_METHOD;
break;
}
}
if( i == HTTP_CONNECTIONS )
{
espconn_disconnect( pespconn );
return;
}
// espconn_set_opt(pespconn, ESPCONN_NODELAY);
// espconn_set_opt(pespconn, ESPCONN_COPY);
espconn_regist_recvcb( pespconn, http_recvcb );
espconn_regist_disconcb( pespconn, http_disconnetcb );
}
int ICACHE_FLASH_ATTR URLDecode( char * decodeinto, int maxlen, const char * buf )
{
int i = 0;
for( ; buf && *buf; buf++ )
{
char c = *buf;
if( c == '+' )
{
decodeinto[i++] = ' ';
}
else if( c == '?' || c == '&' )
{
break;
}
else if( c == '%' )
{
if( *(buf+1) && *(buf+2) )
{
decodeinto[i++] = hex2byte( buf+1 );
buf += 2;
}
}
else
{
decodeinto[i++] = c;
}
if( i >= maxlen -1 ) break;
}
decodeinto[i] = 0;
return i;
}
void ICACHE_FLASH_ATTR WebSocketGotData( uint8_t c )
{
switch( curhttp->state_deets )
{
case 0:
{
int i = 0;
char inkey[120];
unsigned char hash[SHA1_HASH_LEN];
SHA1_CTX c;
int inkeylen = 0;
curhttp->is_dynamic = 1;
while( curlen > 20 )
{
curdata++; curlen--;
if( strncmp( curdata, "Sec-WebSocket-Key: ", 19 ) == 0 )
{
break;
}
}
if( curlen <= 21 )
{
HTDEBUG( "No websocket key found.\n" );
curhttp->state = HTTP_WAIT_CLOSE;
return;
}
curdata+= 19;
curlen -= 19;
#define WS_KEY_LEN 36
#define WS_KEY "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
#define WS_RETKEY_SIZEM1 32
while( curlen > 1 )
{
uint8_t lc = *(curdata++);
inkey[i] = lc;
curlen--;
if( lc == '\r' )
{
inkey[i] = 0;
break;
}
i++;
if( i >= sizeof( inkey ) - WS_KEY_LEN - 5 )
{
HTDEBUG( "Websocket key too big.\n" );
curhttp->state = HTTP_WAIT_CLOSE;
return;
}
}
if( curlen <= 1 )
{
HTDEBUG( "Invalid websocket key found.\n" );
curhttp->state = HTTP_WAIT_CLOSE;
return;
}
if( i + WS_KEY_LEN + 1 >= sizeof( inkey ) )
{
HTDEBUG( "WSKEY Too Big.\n" );
curhttp->state = HTTP_WAIT_CLOSE;
return;
}
ets_memcpy( &inkey[i], WS_KEY, WS_KEY_LEN + 1 );
i += WS_KEY_LEN;
SHA1_Init( &c );
SHA1_Update( &c, inkey, i );
SHA1_Final( hash, &c );
#if (WS_RETKEY_SIZE > MAX_PATHLEN - 10 )
#error MAX_PATHLEN too short.
#endif
my_base64_encode( hash, SHA1_HASH_LEN, curhttp->pathbuffer + (MAX_PATHLEN-WS_RETKEY_SIZEM1) );
curhttp->bytessofar = 0;
curhttp->bytesleft = 0;
NewWebSocket();
//Respond...
curhttp->state_deets = 1;
break;
}
case 1:
if( c == '\n' ) curhttp->state_deets = 2;
break;
case 2:
if( c == '\r' ) curhttp->state_deets = 3;
else curhttp->state_deets = 1;
break;
case 3:
if( c == '\n' ) curhttp->state_deets = 4;
else curhttp->state_deets = 1;
break;
case 5: //Established connection.
{
//XXX TODO: Seems to malfunction on large-ish packets. I know it has problems with 140-byte payloads.
if( curlen < 5 ) //Can't interpret packet.
break;
uint8_t fin = c & 1;
uint8_t opcode = c << 4;
uint16_t payloadlen = *(curdata++);
curlen--;
if( !(payloadlen & 0x80) )
{
HTDEBUG( "Unmasked packet.\n" );
curhttp->state = HTTP_WAIT_CLOSE;
break;
}
payloadlen &= 0x7f;
if( payloadlen == 127 )
{
//Very long payload.
//Not supported.
HTDEBUG( "Unsupported payload packet.\n" );
curhttp->state = HTTP_WAIT_CLOSE;
break;
}
else if( payloadlen == 126 )
{
payloadlen = (curdata[0] << 8) | curdata[1];
curdata += 2;
curlen -= 2;
}
wsmask[0] = curdata[0];
wsmask[1] = curdata[1];
wsmask[2] = curdata[2];
wsmask[3] = curdata[3];
curdata += 4;
curlen -= 4;
wsmaskplace = 0;
//XXX Warning: When packets get larger, they may split the
//websockets packets into multiple parts. We could handle this
//but at the cost of prescious RAM. I am chosing to just drop those
//packets on the floor, and restarting the connection.
if( curlen < payloadlen )
{
HTDEBUG( "Websocket Fragmented. %d %d\n", curlen, payloadlen );
curhttp->state = HTTP_WAIT_CLOSE;
return;
}
WebSocketData( payloadlen );
curlen -= payloadlen;
curdata += payloadlen;
break;
}
default:
break;
}
}
void ICACHE_FLASH_ATTR WebSocketTickInternal()
{
switch( curhttp->state_deets )
{
case 4: //Has key full HTTP header, etc. wants response.
START_PACK;
PushString( "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: " );
PushString( curhttp->pathbuffer + (MAX_PATHLEN-WS_RETKEY_SIZEM1) );
PushString( "\r\n\r\n" );
EndTCPWrite( curhttp->socket );
curhttp->state_deets = 5;
curhttp->keep_alive = 0;
break;
case 5:
WebSocketTick();
break;
}
}
void ICACHE_FLASH_ATTR WebSocketSend( uint8_t * data, int size )
{
START_PACK;
PushByte( 0x81 );
if( size >= 126 )
{
PushByte( 0x00 | 126 );
PushByte( size>>8 );
PushByte( size&0xff );
}
else
{
PushByte( 0x00 | size );
}
PushBlob( data, size );
EndTCPWrite( curhttp->socket );
}
uint8_t WSPOPMASK()
{
uint8_t mask = wsmask[wsmaskplace];
wsmaskplace = (wsmaskplace+1)&3;
return (*curdata++)^(mask);
}

View file

@ -1,99 +0,0 @@
//Copyright 2015 <>< Charles Lohr Under the MIT/x11 License, NewBSD License or
// ColorChord License. You Choose.
#ifndef _HTTP_H
#define _HTTP_H
#include "mem.h"
#include "c_types.h"
#include "user_interface.h"
#include "ets_sys.h"
#include "driver/uart.h"
#include "osapi.h"
#include "espconn.h"
#include "mfs.h"
#include "mystuff.h"
#define HTTP_SERVER_TIMEOUT 500
#define HTTP_CONNECTIONS 8
#define MAX_PATHLEN 80
//You must provide:
void ICACHE_FLASH_ATTR HTTPCustomStart( );
void ICACHE_FLASH_ATTR HTTPCustomCallback( ); //called when we can send more data
void ICACHE_FLASH_ATTR WebSocketData( int len );
void ICACHE_FLASH_ATTR WebSocketTick( );
void ICACHE_FLASH_ATTR WebSocketNew();
extern struct HTTPConnection * curhttp;
extern uint8 * curdata;
extern uint16 curlen;
extern uint8 wsmask[4];
extern uint8 wsmaskplace;
uint8_t WSPOPMASK();
#define HTTPPOP (*curdata++)
#define HTTP_STATE_NONE 0
#define HTTP_STATE_WAIT_METHOD 1
#define HTTP_STATE_WAIT_PATH 2
#define HTTP_STATE_WAIT_PROTO 3
#define HTTP_STATE_WAIT_FLAG 4
#define HTTP_STATE_WAIT_INFLAG 5
#define HTTP_STATE_DATA_XFER 7
#define HTTP_STATE_DATA_WEBSOCKET 8
#define HTTP_WAIT_CLOSE 15
struct HTTPConnection
{
uint8_t state:4;
uint8_t state_deets;
//Provides path, i.e. "/index.html" but, for websockets, the last
//32 bytes of the buffer are used for the websockets key.
uint8_t pathbuffer[MAX_PATHLEN];
uint8_t is_dynamic:1;
uint16_t timeout;
union data_t
{
struct MFSFileInfo filedescriptor;
struct UserData { uint16_t a, b, c; } user;
} data;
void * rcb;
void * rcbDat; //For websockets primarily.
uint32_t bytesleft;
uint32_t bytessofar;
uint8_t is404:1;
uint8_t isdone:1;
uint8_t isfirst:1;
uint8_t keep_alive:1;
uint8_t need_resend:1;
struct espconn * socket;
} HTTPConnections[HTTP_CONNECTIONS];
void ICACHE_FLASH_ATTR httpserver_connectcb(void *arg);
void HTTPTick( uint8_t timedtick );
//you can call this a LOT if you want fast transfers, but be sure only to call it with a 1 at the update tick rate.
int ICACHE_FLASH_ATTR URLDecode( char * decodeinto, int maxlen, const char * buf );
void ICACHE_FLASH_ATTR WebSocketGotData( uint8_t c );
void ICACHE_FLASH_ATTR WebSocketTickInternal();
void ICACHE_FLASH_ATTR WebSocketSend( uint8_t * data, int size );
#endif

View file

@ -1,176 +0,0 @@
//Copyright 2015 <>< Charles Lohr Under the MIT/x11 License, NewBSD License or
// ColorChord License. You Choose.
#include "http.h"
#include "mystuff.h"
#include "commonservices.h"
static ICACHE_FLASH_ATTR void huge()
{
uint8_t i = 0;
START_PACK;
do
{
PushByte( 0 );
PushByte( i );
} while( ++i ); //Tricky: this will roll-over to 0, and thus only execute 256 times.
EndTCPWrite( curhttp->socket );
}
static ICACHE_FLASH_ATTR void echo()
{
char mydat[128];
int len = URLDecode( mydat, 128, curhttp->pathbuffer+8 );
START_PACK;
PushBlob( mydat, len );
EndTCPWrite( curhttp->socket );
curhttp->state = HTTP_WAIT_CLOSE;
}
static ICACHE_FLASH_ATTR void issue()
{
uint8_t __attribute__ ((aligned (32))) buf[1300];
int len = URLDecode( buf, 1300, curhttp->pathbuffer+9 );
int r = issue_command(buf, 1300, buf, len );
if( r > 0 )
{
START_PACK;
PushBlob( buf, r );
EndTCPWrite( curhttp->socket );
}
curhttp->state = HTTP_WAIT_CLOSE;
}
void ICACHE_FLASH_ATTR HTTPCustomStart( )
{
if( strncmp( (const char*)curhttp->pathbuffer, "/d/huge", 7 ) == 0 )
{
curhttp->rcb = (void(*)())&huge;
curhttp->bytesleft = 0xffffffff;
}
else
if( strncmp( (const char*)curhttp->pathbuffer, "/d/echo?", 8 ) == 0 )
{
curhttp->rcb = (void(*)())&echo;
curhttp->bytesleft = 0xfffffffe;
}
else
if( strncmp( (const char*)curhttp->pathbuffer, "/d/issue?", 9 ) == 0 )
{
curhttp->rcb = (void(*)())&issue;
curhttp->bytesleft = 0xfffffffe;
}
else
{
curhttp->rcb = 0;
curhttp->bytesleft = 0;
}
curhttp->isfirst = 1;
HTTPHandleInternalCallback();
}
void ICACHE_FLASH_ATTR HTTPCustomCallback( )
{
if( curhttp->rcb )
((void(*)())curhttp->rcb)();
else
curhttp->isdone = 1;
}
static void ICACHE_FLASH_ATTR WSEchoData( int len )
{
char cbo[len];
int i;
for( i = 0; i < len; i++ )
{
cbo[i] = WSPOPMASK();
}
WebSocketSend( cbo, len );
}
static void ICACHE_FLASH_ATTR WSEvalData( int len )
{
char cbo[128];
int l = ets_sprintf( cbo, "output.innerHTML = %d; doSend('x' );", curhttp->bytessofar++ );
WebSocketSend( cbo, l );
}
static void ICACHE_FLASH_ATTR WSCommandData( int len )
{
uint8_t __attribute__ ((aligned (32))) buf[1300];
int i;
for( i = 0; i < len; i++ )
{
buf[i] = WSPOPMASK();
}
i = issue_command(buf, 1300, buf, len );
if( i < 0 ) i = 0;
WebSocketSend( buf, i );
}
// output.innerHTML = msg++ + " " + lasthz;
// doSend('x' );
void ICACHE_FLASH_ATTR NewWebSocket()
{
if( strcmp( (const char*)curhttp->pathbuffer, "/d/ws/echo" ) == 0 )
{
curhttp->rcb = 0;
curhttp->rcbDat = (void*)&WSEchoData;
}
else if( strcmp( (const char*)curhttp->pathbuffer, "/d/ws/evaltest" ) == 0 )
{
curhttp->rcb = 0;
curhttp->rcbDat = (void*)&WSEvalData;
}
else if( strncmp( (const char*)curhttp->pathbuffer, "/d/ws/issue", 11 ) == 0 )
{
curhttp->rcb = 0;
curhttp->rcbDat = (void*)&WSCommandData;
}
else
{
curhttp->is404 = 1;
}
}
void ICACHE_FLASH_ATTR WebSocketTick()
{
if( curhttp->rcb )
{
((void(*)())curhttp->rcb)();
}
}
void ICACHE_FLASH_ATTR WebSocketData( int len )
{
if( curhttp->rcbDat )
{
((void(*)( int ))curhttp->rcbDat)( len );
}
}

View file

@ -1,97 +0,0 @@
//Copyright 2015 <>< Charles Lohr Under the MIT/x11 License, NewBSD License or
// ColorChord License. You Choose.
#include "mystuff.h"
#include "mfs.h"
#include "spi_flash.h"
#include "ets_sys.h"
uint32 mfs_at = 0;
void ICACHE_FLASH_ATTR FindMPFS()
{
uint32 mfs_check[2];
EnterCritical();
flashchip->chip_size = 0x01000000;
spi_flash_read( MFS_START, mfs_check, sizeof( mfs_check ) );
if( strncmp( "MPFSMPFS", mfs_check, 8 ) == 0 ) { mfs_at = MFS_START; goto done; }
printf( "MFS Not found at regular address (%08x).\n", mfs_check[0], mfs_check[1] );
spi_flash_read( MFS_ALTERNATIVE_START, mfs_check, sizeof( mfs_check ) );
if( strncmp( "MPFSMPFS", mfs_check, 8 ) == 0 ) { mfs_at = MFS_ALTERNATIVE_START; goto done; }
printf( "MFS Not found at alternative address (%08x%08x).\n", mfs_check[0], mfs_check[1] );
done:
printf( "MFS Found at: %08x\n", mfs_at );
flashchip->chip_size = 0x00080000;
ExitCritical();
}
extern SpiFlashChip * flashchip;
//Returns 0 on succses.
//Returns size of file if non-empty
//If positive, populates mfi.
//Returns -1 if can't find file or reached end of file list.
int8_t ICACHE_FLASH_ATTR MFSOpenFile( const char * fname, struct MFSFileInfo * mfi )
{
if( mfs_at == 0 )
{
FindMPFS();
}
if( mfs_at == 0 )
{
return -1;
}
EnterCritical();
flashchip->chip_size = 0x01000000;
uint32 ptr = mfs_at;
struct MFSFileEntry e;
while(1)
{
spi_flash_read( ptr, (uint32*)&e, sizeof( e ) );
ptr += sizeof(e);
if( e.name[0] == 0xff || ets_strlen( e.name ) == 0 ) break;
if( ets_strcmp( e.name, fname ) == 0 )
{
mfi->offset = e.start;
mfi->filelen = e.len;
flashchip->chip_size = 0x00080000;
ExitCritical();
return 0;
}
}
flashchip->chip_size = 0x00080000;
ExitCritical();
return -1;
}
int32_t MFSReadSector( uint8_t* data, struct MFSFileInfo * mfi )
{
//returns # of bytes left tin file.
if( !mfi->filelen )
{
return 0;
}
int toread = mfi->filelen;
if( toread > MFS_SECTOR ) toread = MFS_SECTOR;
EnterCritical();
flashchip->chip_size = 0x01000000;
spi_flash_read( mfs_at+mfi->offset, (uint32*)data, MFS_SECTOR );
flashchip->chip_size = 0x00080000;
ExitCritical();
mfi->offset += toread;
mfi->filelen -= toread;
return mfi->filelen;
}

View file

@ -1,55 +0,0 @@
//Copyright 2015 <>< Charles Lohr Under the MIT/x11 License, NewBSD License or
// ColorChord License. You Choose.
//Not to be confused with MFS for the AVR.
#ifndef _MFS_H
#define _MFS_H
#include "mem.h"
#include "c_types.h"
#include "mystuff.h"
//SPI_FLASH_SEC_SIZE 4096
//If you are on a chip with limited space, MFS can alternatively live here, with a max size of 180kB.
#define MFS_ALTERNATIVE_START 0x10000
#define MFS_STARTFLASHSECTOR 0x100
#define MFS_START (MFS_STARTFLASHSECTOR*SPI_FLASH_SEC_SIZE)
#define MFS_SECTOR 256
#define MFS_FILENAMELEN 32-8
//Format:
// [FILE NAME (24)] [Start (4)] [Len (4)]
// NOTE: Filename must be null-terminated within the 24.
struct MFSFileEntry
{
char name[MFS_FILENAMELEN];
uint32 start; //From beginning of mfs thing.
uint32 len;
};
struct MFSFileInfo
{
uint32 offset;
uint32 filelen;
};
//Returns 0 on succses.
//Returns size of file if non-empty
//If positive, populates mfi.
//Returns -1 if can't find file or reached end of file list.
ICACHE_FLASH_ATTR int8_t MFSOpenFile( const char * fname, struct MFSFileInfo * mfi );
ICACHE_FLASH_ATTR int32_t MFSReadSector( uint8_t* data, struct MFSFileInfo * mfi ); //returns # of bytes left in file.
#endif

View file

@ -1,213 +0,0 @@
//Unless what else is individually marked, all code in this file is
//Copyright 2015 <>< Charles Lohr Under the MIT/x11 License, NewBSD License or
// ColorChord License. You Choose.
#include "mystuff.h"
const char * enctypes[6] = { "open", "wep", "wpa", "wpa2", "wpa_wpa2", 0 };
char generic_print_buffer[384];
char generic_buffer[1500];
char * generic_ptr;
int32 my_atoi( const char * in )
{
int positive = 1; //1 if negative.
int hit = 0;
int val = 0;
while( *in && hit < 11 )
{
if( *in == '-' )
{
if( positive == -1 ) return val*positive;
positive = -1;
} else if( *in >= '0' && *in <= '9' )
{
val *= 10;
val += *in - '0';
hit++;
} else if (!hit && ( *in == ' ' || *in == '\t' ) )
{
//okay
} else
{
//bad.
return val*positive;
}
in++;
}
return val*positive;
}
void Uint32To10Str( char * out, uint32 dat )
{
int tens = 1000000000;
int val;
int place = 0;
while( tens > 1 )
{
if( dat/tens ) break;
tens/=10;
}
while( tens )
{
val = dat/tens;
dat -= val*tens;
tens /= 10;
out[place++] = val + '0';
}
out[place] = 0;
}
char tohex1( uint8_t i )
{
i = i&0x0f;
return (i<10)?('0'+i):('a'-10+i);
}
int8_t fromhex1( char c )
{
if( c >= '0' && c <= '9' )
return c - '0';
else if( c >= 'a' && c <= 'f' )
return c - 'a' + 10;
else if( c >= 'A' && c <= 'F' )
return c - 'A' + 10;
else
return -1;
}
void ICACHE_FLASH_ATTR EndTCPWrite( struct espconn * conn )
{
if(generic_ptr!=generic_buffer)
{
int r = espconn_sent(conn,generic_buffer,generic_ptr-generic_buffer);
}
}
void PushString( const char * buffer )
{
char c;
while( c = *(buffer++) )
PushByte( c );
}
void PushBlob( const uint8 * buffer, int len )
{
int i;
for( i = 0; i < len; i++ )
PushByte( buffer[i] );
}
int8_t ICACHE_FLASH_ATTR TCPCanSend( struct espconn * conn, int size )
{
#ifdef SAFESEND
return TCPDoneSend( conn );
#else
struct espconn_packet infoarg;
sint8 r = espconn_get_packet_info(conn, &infoarg);
if( infoarg.snd_buf_size >= size && infoarg.snd_queuelen > 0 )
return 1;
else
return 0;
#endif
}
int8_t ICACHE_FLASH_ATTR TCPDoneSend( struct espconn * conn )
{
return conn->state == ESPCONN_CONNECT;
}
const char * ICACHE_FLASH_ATTR my_strchr( const char * st, char c )
{
while( *st && *st != c ) st++;
if( !*st ) return 0;
return st;
}
int ICACHE_FLASH_ATTR ColonsToInts( const char * str, int32_t * vals, int max_quantity )
{
int i;
for( i = 0; i < max_quantity; i++ )
{
const char * colon = my_strchr( str, ':' );
vals[i] = my_atoi( str );
if( !colon ) break;
str = colon+1;
}
return i+1;
}
//from http://stackoverflow.com/questions/342409/how-do-i-base64-encode-decode-in-c
static const char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'};
static const int mod_table[] = {0, 2, 1};
void ICACHE_FLASH_ATTR my_base64_encode(const unsigned char *data, size_t input_length, uint8_t * encoded_data )
{
int i, j;
int output_length = 4 * ((input_length + 2) / 3);
if( !encoded_data ) return;
if( !data ) { encoded_data[0] = '='; encoded_data[1] = 0; return; }
for (i = 0, j = 0; i < input_length; ) {
uint32_t octet_a = i < input_length ? (unsigned char)data[i++] : 0;
uint32_t octet_b = i < input_length ? (unsigned char)data[i++] : 0;
uint32_t octet_c = i < input_length ? (unsigned char)data[i++] : 0;
uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
encoded_data[j++] = encoding_table[(triple >> 3 * 6) & 0x3F];
encoded_data[j++] = encoding_table[(triple >> 2 * 6) & 0x3F];
encoded_data[j++] = encoding_table[(triple >> 1 * 6) & 0x3F];
encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F];
}
for (i = 0; i < mod_table[input_length % 3]; i++)
encoded_data[output_length - 1 - i] = '=';
encoded_data[j] = 0;
}
void ICACHE_FLASH_ATTR SafeMD5Update( MD5_CTX * md5ctx, uint8_t*from, uint32_t size1 )
{
char __attribute__ ((aligned (32))) buffer[32];
while( size1 > 32 )
{
ets_memcpy( buffer, from, 32 );
MD5Update( md5ctx, buffer, 32 );
size1-=32;
from+=32;
}
ets_memcpy( buffer, from, 32 );
MD5Update( md5ctx, buffer, size1 );
}

View file

@ -1,60 +0,0 @@
//Unless what else is individually marked, all code in this file is
//Copyright 2015 <>< Charles Lohr Under the MIT/x11 License, NewBSD License or
// ColorChord License. You Choose.
#ifndef _MYSTUFF_H
#define _MYSTUFF_H
#include <mem.h>
#include <c_types.h>
#include <user_interface.h>
#include <ets_sys.h>
#include <espconn.h>
#include <esp8266_rom.h>
//XXX WARNING As of 1.3.0, "cansend" doesn't work.
//the SDK seems to misbehave when trying to send without a full
//response packet.
#define SAFESEND
extern char generic_print_buffer[384];
extern const char * enctypes[6];// = { "open", "wep", "wpa", "wpa2", "wpa_wpa2", 0 };
#define printf( ... ) ets_sprintf( generic_print_buffer, __VA_ARGS__ ); uart0_sendStr( generic_print_buffer );
char tohex1( uint8_t i );
int8_t fromhex1( char c ); //returns -1 if not hex char.
int32 my_atoi( const char * in );
void Uint32To10Str( char * out, uint32 dat );
//For holding TX packet buffers
extern char generic_buffer[1500];
extern char * generic_ptr;
int8_t ICACHE_FLASH_ATTR TCPCanSend( struct espconn * conn, int size );
int8_t ICACHE_FLASH_ATTR TCPDoneSend( struct espconn * conn );
void ICACHE_FLASH_ATTR EndTCPWrite( struct espconn * conn );
#define PushByte( c ) { *(generic_ptr++) = c; }
void PushString( const char * buffer );
void PushBlob( const uint8 * buffer, int len );
#define START_PACK {generic_ptr=generic_buffer;}
#define PACK_LENGTH (generic_ptr-&generic_buffer[0]}
int ICACHE_FLASH_ATTR ColonsToInts( const char * str, int32_t * vals, int max_quantity );
//As much as it pains me, we shouldn't be using the esp8266's base64_encode() function
//as it does stuff with dynamic memory.
void ICACHE_FLASH_ATTR my_base64_encode(const unsigned char *data, size_t input_length, uint8_t * encoded_data );
void ICACHE_FLASH_ATTR SafeMD5Update( MD5_CTX * md5ctx, uint8_t*from, uint32_t size1 );
#endif

View file

@ -1,225 +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.
* [various] Not released, Modified by Charles Lohr to change the RX behavior
*******************************************************************************/
#include <c_types.h>
#include <osapi.h>
#include <ets_sys.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
uart1_write_char(char c)
{
if (c == '\n')
{
uart_tx_one_char(UART1, '\r');
uart_tx_one_char(UART1, '\n');
}
else if (c == '\r')
{
}
else
{
uart_tx_one_char(UART1, 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 charrx( uint8_t c );
LOCAL void
uart0_rx_intr_handler(void *para)
{
static uint8_t history[4];
static uint8_t hhead;
uint8 uart_no = UART0;//UartDev.buff_uart_no;
volatile uint8_t v = READ_PERI_REG(UART_FIFO(uart_no)) & 0xFF;
WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR);
history[hhead++] = v;
if( hhead > 3 ) hhead = 0;
//Detect a request to reboot into bootloader.
if( history[hhead&3] == 0xc2 && history[(hhead+1)&3] == 0x42 && history[(hhead+2)&3] == 0x56 && history[(hhead+3)&3] == 0xff )
{
system_restart();
}
charrx( v );
}
/******************************************************************************
* 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 uart1 putc callback
os_install_putc1((void *)uart1_write_char);
}
void ICACHE_FLASH_ATTR
uart_reattach()
{
uart_init(BIT_RATE_74880, BIT_RATE_74880);
}

1
embedded8266/esp82xx Submodule

@ -0,0 +1 @@
Subproject commit 6dbcc51d030d05360696925a8cb1963ca3f6747e

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,101 +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

View file

@ -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

View file

@ -1,3 +0,0 @@
//This exists to make sure anything including stdint.h includes this instead.
#include "c_types.h"

View file

@ -1 +0,0 @@
//Nothing here. Just a file to make things that include <string.h> happy.

View file

@ -1 +0,0 @@

View file

@ -1,37 +0,0 @@
###############################################################################
# USER OPTIONS
###############################################################################
CHIP ?= 8266
IP ?= 192.168.4.1 # does not actually set the IP in firmware
PORT ?= /dev/ttyUSB0 # could also be /dev/ttyACM0
PAGE_OFFSET ?= 65536 # 1048576
SDK_DEFAULT ?= $(HOME)/esp8266/esp-open-sdk
ESP_GCC_VERS ?= 4.8.5
OPTS += -DICACHE_FLASH
#OPTS += THIS_DEBUG
#OPTS += -DVERIFY_FLASH_WRITE
#OPTS += -DFREQ=12500
###########################################################################VARS
GCC_FOLDER = $(ESP_ROOT)/xtensa-lx106-elf
ESPTOOL_PY = $(ESP_ROOT)/esptool/esptool.py
SDK = $(ESP_ROOT)/sdk
XTLIB = $(SDK)/lib
XTGCCLIB = $(GCC_FOLDER)/lib/gcc/xtensa-lx106-elf/$(ESP_GCC_VERS)/libgcc.a
FOLDERPREFIX = $(GCC_FOLDER)/bin
PREFIX = $(FOLDERPREFIX)/xtensa-lx106-elf-
CC = $(PREFIX)gcc
LD = $(PREFIX)ld
AR = $(PREFIX)ar
ESP_ROOT := $(shell echo "$$ESP_ROOT")
ifeq ($(strip $(ESP_ROOT)),)
$(warning Warning: No shell variable 'ESP_ROOT', using '$(SDK_DEFAULT)')
ESP_ROOT := $(SDK_DEFAULT)
endif

25
embedded8266/user.cfg Normal file
View file

@ -0,0 +1,25 @@
###############################################################################
# User Options
###############################################################################
CHIP = 8266
IP = 192.168.4.1 # does not actually set the IP in firmware
PORT = /dev/ttyUSB0 # could also be /dev/ttyACM0
WEB_PORT = 80
COM_PORT = 7777
BACKEND_PORT = 7878
PAGE_OFFSET = 65536 # 1048576
SDK_DEFAULT = $(HOME)/esp8266/esp-open-sdk
ESP_GCC_VERS = 4.8.5
OPTS += -DICACHE_FLASH
#OPTS += -DVERIFY_FLASH_WRITE
#OPTS += -DDEBUG
#OPTS += -DFREQ=12500
PAGE_TITLE = ColorChord Control Panel
PAGE_SCRIPT =
PAGE_HEADING = ColorChord: Embedded
PAGE_INFO =

View file

@ -6,7 +6,7 @@
#include "ets_sys.h"
#include "osapi.h"
#include "driver/adc.h"
#include "adc.h"
#define i2c_bbpll 0x67
#define i2c_bbpll_en_audio_clock_out 4

View file

@ -2,7 +2,7 @@
// ColorChord License. You Choose.
#include "hpatimer.h"
#include <driver/adc.h>
#include "adc.h"
#include "osapi.h"
#include "mem.h"
#include "eagle_soc.h"

View file

@ -5,13 +5,13 @@
#include "c_types.h"
#include "user_interface.h"
#include "ets_sys.h"
#include "driver/uart.h"
#include "uart.h"
#include "osapi.h"
#include "espconn.h"
#include "mystuff.h"
#include "ws2812_i2s.h"
#include "hpatimer.h"
#include <DFT32.h>
#include "DFT32.h"
#include "ccconfig.h"
#include <embeddednf.h>
#include <embeddedout.h>

View file

@ -1,23 +0,0 @@
include ../makeconf.inc # Look here for user configuration
.PHONY : all clean push
all : execute_reflash push
CC = gcc
mfsmaker : mfsmaker.c
pushtodev : pushtodev.c
execute_reflash : execute_reflash.c md5.c
page.mpfs : mfsmaker page
# cat to_compress/*.js | gzip -9 > page/compressed.js.gz
./mfsmaker page page.mpfs
#mfsmaker pushtodev execute_reflash:
# $(CC) $(CFLAGS) -o $@ $^
push : pushtodev page.mpfs
./pushtodev $(IP) $(PAGE_OFFSET) page.mpfs
clean :
$(RM) mfsmaker page.mpfs pushtodev execute_reflash

1
embedded8266/web/Makefile Symbolic link
View file

@ -0,0 +1 @@
../esp82xx/web/Makefile

View file

@ -1,274 +0,0 @@
//Copyright 2015 <>< Charles Lohr Under the MIT/x11 License, NewBSD License or
// ColorChord License. You Choose.
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/poll.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "md5.h"
#define BLOCK_SIZE 65536
#define SECTOR_SIZE 4096
#define PADDING 1024
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0x0 //Don't request NOSIGNAL on systems where this is not implemented.
#endif
int sockfd;
struct sockaddr_in servaddr,cliaddr;
int PushMatch( const char * match )
{
struct timeval tva, tvb;
gettimeofday( &tva, 0 );
gettimeofday( &tvb, 0 );
while( tvb.tv_sec - tva.tv_sec < 3 )
{
struct pollfd ufds;
ufds.fd = sockfd;
ufds.events = POLLIN;
int rv = poll(&ufds, 1, 100);
if( rv > 0 )
{
char recvline[10000];
int n=recvfrom(sockfd,recvline,10000,0,NULL,NULL);
// printf( "%s === %s\n", recvline, match );
if( strncmp( recvline, match, strlen( match ) ) == 0 )
{
printf( "Ok - " ); fflush( stdout );
return 0;
}
}
gettimeofday( &tvb, 0 );
}
return 1;
}
uint32_t Push( uint32_t offset, const char * file )
{
char sendline[1000];
char recvline[1000];
if( offset <= 0 )
{
fprintf( stderr, "Error: Cannot write to address 0 or before.\n" );
exit(-2);
}
FILE * f = fopen( file, "rb" );
if( !f || feof( f ) )
{
fprintf( stderr, "Error: cannot open file.\n" );
exit(-3);
}
int devo = 0;
int lastblock = -1;
while( !feof( f ) )
{
int tries;
int thissuccess;
char buffer[PADDING];
char bufferout[2000];
int reads = fread( buffer, 1, PADDING, f );
int sendplace = offset + devo;
int sendsize = PADDING;//reads;
int block = sendplace / BLOCK_SIZE;
memset( buffer + reads, 0, sendsize-reads );
if( block != lastblock )
{
char se[64];
int sel = sprintf( se, "FB%d\r\n", block );
thissuccess = 0;
for( tries = 0; tries < 10; tries++ )
{
char match[75];
printf( "Erase: %d\n", block );
sendto( sockfd, se, sel, MSG_NOSIGNAL, (struct sockaddr *)&servaddr,sizeof(servaddr));
sprintf( match, "FB%d", block );
if( PushMatch(match) == 0 ) { thissuccess = 1; break; }
printf( "Retry.\n" );
}
if( !thissuccess )
{
fprintf( stderr, "Error: Timeout in communications.\n" );
exit( -6 );
}
lastblock = block;
}
int r = sprintf( bufferout, "FW%d\t%d\t", sendplace, sendsize );
memcpy( bufferout + r, buffer, sendsize );
printf( "bufferout: %d %d\n", sendplace, sendsize );
thissuccess = 0;
for( tries = 0; tries < 10; tries++ )
{
char match[75];
sendto( sockfd, bufferout, sendsize + r, MSG_NOSIGNAL, (struct sockaddr *)&servaddr,sizeof(servaddr));
sprintf( match, "FW%d", sendplace );
if( PushMatch(match) == 0 ) { thissuccess = 1; break; }
printf( "Retry.\n" );
}
if( !thissuccess )
{
fprintf( stderr, "Error: Timeout in communications.\n" );
exit( -6 );
}
if( reads != 0 )
devo += sendsize;
}
return devo;
}
void ComputeMD5WithKey( char * md5retText, const char * filename, const char * key )
{
uint8_t retmd5[16];
MD5_CTX ctx;
FILE * f = fopen( filename, "rb" );
if( !f )
{
fprintf( stderr, "Error opening %s\n", filename );
exit( -9 );
}
fseek( f, 0, SEEK_END );
int l = ftell( f );
printf("MD5 Size: %d\n", l );
int padl = ((l-1) / PADDING)*PADDING+PADDING;
printf("MD5 Pad: %d\n", padl );
fseek( f, 0, SEEK_SET );
uint8_t data[padl];
fread( data, l, 1, f );
fclose( f );
memset( data+l, 0, padl-l );
MD5_Init( &ctx );
if( !strlen(key) )
MD5_Update( &ctx, key, strlen( key ) );
MD5_Update( &ctx, data, padl );
MD5_Final( retmd5, &ctx );
for( l = 0; l < 16; l++ )
{
sprintf( md5retText + l*2, "%02x", retmd5[l] );
}
return;
}
uint32_t roundup( uint32_t r )
{
return ((r-1)&(~0xFFF))+0x1000;
}
int main(int argc, char**argv)
{
int n;
char sendline[1000];
char recvline[1000];
char md5_f1[48];
char md5_f2[48];
if (argc < 4 )
{
printf("usage: pushtodev [IP address] [file_lower] [file_upper] [key (optional)]\n");
exit(-1);
}
const char * file1 = argv[2];
const char * file2 = argv[3];
sockfd=socket(AF_INET,SOCK_DGRAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr=inet_addr(argv[1]);
servaddr.sin_port=htons(7878);
uint32_t fs1 = Push( 0x080000, file1 );
uint32_t fs2 = Push( 0x0c0000, file2 );
if( !fs1 || !fs2 )
{
fprintf( stderr, "Error: File size not acceptable.\n" );
return 0;
}
const char * dat = "";
if( argc == 5 )
{
dat = argv[4];
}
ComputeMD5WithKey( md5_f1, file1, dat );
ComputeMD5WithKey( md5_f2, file2, dat );
printf( "%s %s\n", md5_f1, md5_f2 );
//FM[from_address]\t[to_address]\t[size]\t[MD5(key+data)]\t[from_address]\t[to_address]\t[size]\t[MD5(key+data)]
char cmd[1024];
sprintf( cmd, "FM%d\t%d\t%d\t%s\t%d\t%d\t%d\t%s\n",
0x080000,
0x000000,
fs1, //roundup( fs1 ),
md5_f1,
0x0C0000,
0x040000,
fs2, //roundup( fs2 ),
md5_f2 );
printf( "Issuing: %s\n", cmd );
sendto( sockfd, cmd, strlen(cmd), MSG_NOSIGNAL, (struct sockaddr *)&servaddr,sizeof(servaddr));
usleep(10000);
sendto( sockfd, cmd, strlen(cmd), MSG_NOSIGNAL, (struct sockaddr *)&servaddr,sizeof(servaddr));
struct pollfd ufds;
ufds.fd = sockfd;
ufds.events = POLLIN;
int rv = poll(&ufds, 1, 100);
if( rv > 0 )
{
char recvline[10000];
int n=recvfrom(sockfd,recvline,10000,0,NULL,NULL);
printf( "Response: %s\n",recvline );
return 0;
}
else
{
printf( "Timeout. Good? Maybe?\n" );
return 0;
}
return 0;
}

View file

@ -0,0 +1 @@
../esp82xx/web/execute_reflash.c

View file

@ -1,296 +0,0 @@
/*
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
* MD5 Message-Digest Algorithm (RFC 1321).
*
* Homepage:
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
*
* Author:
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
*
* This software was written by Alexander Peslyak in 2001. No copyright is
* claimed, and the software is hereby placed in the public domain.
* In case this attempt to disclaim copyright and place the software in the
* public domain is deemed null and void, then the software is
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
* general public under the following terms:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted.
*
* There's ABSOLUTELY NO WARRANTY, express or implied.
*
* (This is a heavily cut-down "BSD license".)
*
* This differs from Colin Plumb's older public domain implementation in that
* no exactly 32-bit integer data type is required (any 32-bit or wider
* unsigned integer data type will do), there's no compile-time endianness
* configuration, and the function prototypes match OpenSSL's. No code from
* Colin Plumb's implementation has been reused; this comment merely compares
* the properties of the two independent implementations.
*
* The primary goals of this implementation are portability and ease of use.
* It is meant to be fast, but not as fast as possible. Some known
* optimizations are not included to reduce source code size and avoid
* compile-time configuration.
*/
#ifndef HAVE_OPENSSL
#include <string.h>
#include "md5.h"
/*
* The basic MD5 functions.
*
* F and G are optimized compared to their RFC 1321 definitions for
* architectures that lack an AND-NOT instruction, just like in Colin Plumb's
* implementation.
*/
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
#define H(x, y, z) (((x) ^ (y)) ^ (z))
#define H2(x, y, z) ((x) ^ ((y) ^ (z)))
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
/*
* The MD5 transformation for all four rounds.
*/
#define STEP(f, a, b, c, d, x, t, s) \
(a) += f((b), (c), (d)) + (x) + (t); \
(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
(a) += (b);
/*
* SET reads 4 input bytes in little-endian byte order and stores them
* in a properly aligned word in host byte order.
*
* The check for little-endian architectures that tolerate unaligned
* memory accesses is just an optimization. Nothing will break if it
* doesn't work.
*/
#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
#define SET(n) \
(*(MD5_u32plus *)&ptr[(n) * 4])
#define GET(n) \
SET(n)
#else
#define SET(n) \
(ctx->block[(n)] = \
(MD5_u32plus)ptr[(n) * 4] | \
((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
#define GET(n) \
(ctx->block[(n)])
#endif
/*
* This processes one or more 64-byte data blocks, but does NOT update
* the bit counters. There are no alignment requirements.
*/
static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
{
const unsigned char *ptr;
MD5_u32plus a, b, c, d;
MD5_u32plus saved_a, saved_b, saved_c, saved_d;
ptr = (const unsigned char *)data;
a = ctx->a;
b = ctx->b;
c = ctx->c;
d = ctx->d;
do {
saved_a = a;
saved_b = b;
saved_c = c;
saved_d = d;
/* Round 1 */
STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
/* Round 2 */
STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
/* Round 3 */
STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
/* Round 4 */
STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
a += saved_a;
b += saved_b;
c += saved_c;
d += saved_d;
ptr += 64;
} while (size -= 64);
ctx->a = a;
ctx->b = b;
ctx->c = c;
ctx->d = d;
return ptr;
}
void MD5_Init(MD5_CTX *ctx)
{
ctx->a = 0x67452301;
ctx->b = 0xefcdab89;
ctx->c = 0x98badcfe;
ctx->d = 0x10325476;
ctx->lo = 0;
ctx->hi = 0;
}
void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
{
MD5_u32plus saved_lo;
unsigned long used, available;
saved_lo = ctx->lo;
if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
ctx->hi++;
ctx->hi += size >> 29;
used = saved_lo & 0x3f;
if (used) {
available = 64 - used;
if (size < available) {
memcpy(&ctx->buffer[used], data, size);
return;
}
memcpy(&ctx->buffer[used], data, available);
data = (const unsigned char *)data + available;
size -= available;
body(ctx, ctx->buffer, 64);
}
if (size >= 64) {
data = body(ctx, data, size & ~(unsigned long)0x3f);
size &= 0x3f;
}
memcpy(ctx->buffer, data, size);
}
void MD5_Final(unsigned char *result, MD5_CTX *ctx)
{
unsigned long used, available;
used = ctx->lo & 0x3f;
ctx->buffer[used++] = 0x80;
available = 64 - used;
if (available < 8) {
memset(&ctx->buffer[used], 0, available);
body(ctx, ctx->buffer, 64);
used = 0;
available = 64;
}
memset(&ctx->buffer[used], 0, available - 8);
ctx->lo <<= 3;
ctx->buffer[56] = ctx->lo;
ctx->buffer[57] = ctx->lo >> 8;
ctx->buffer[58] = ctx->lo >> 16;
ctx->buffer[59] = ctx->lo >> 24;
ctx->buffer[60] = ctx->hi;
ctx->buffer[61] = ctx->hi >> 8;
ctx->buffer[62] = ctx->hi >> 16;
ctx->buffer[63] = ctx->hi >> 24;
body(ctx, ctx->buffer, 64);
result[0] = ctx->a;
result[1] = ctx->a >> 8;
result[2] = ctx->a >> 16;
result[3] = ctx->a >> 24;
result[4] = ctx->b;
result[5] = ctx->b >> 8;
result[6] = ctx->b >> 16;
result[7] = ctx->b >> 24;
result[8] = ctx->c;
result[9] = ctx->c >> 8;
result[10] = ctx->c >> 16;
result[11] = ctx->c >> 24;
result[12] = ctx->d;
result[13] = ctx->d >> 8;
result[14] = ctx->d >> 16;
result[15] = ctx->d >> 24;
memset(ctx, 0, sizeof(*ctx));
}
#endif

1
embedded8266/web/md5.c Symbolic link
View file

@ -0,0 +1 @@
../esp82xx/web/md5.c

View file

@ -1,45 +0,0 @@
/*
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
* MD5 Message-Digest Algorithm (RFC 1321).
*
* Homepage:
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
*
* Author:
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
*
* This software was written by Alexander Peslyak in 2001. No copyright is
* claimed, and the software is hereby placed in the public domain.
* In case this attempt to disclaim copyright and place the software in the
* public domain is deemed null and void, then the software is
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
* general public under the following terms:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted.
*
* There's ABSOLUTELY NO WARRANTY, express or implied.
*
* See md5.c for more information.
*/
#ifdef HAVE_OPENSSL
#include <openssl/md5.h>
#elif !defined(_MD5_H)
#define _MD5_H
/* Any 32-bit or wider unsigned integer data type will do */
typedef unsigned int MD5_u32plus;
typedef struct {
MD5_u32plus lo, hi;
MD5_u32plus a, b, c, d;
unsigned char buffer[64];
MD5_u32plus block[16];
} MD5_CTX;
extern void MD5_Init(MD5_CTX *ctx);
extern void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
extern void MD5_Final(unsigned char *result, MD5_CTX *ctx);
#endif

1
embedded8266/web/md5.h Symbolic link
View file

@ -0,0 +1 @@
../esp82xx/web/md5.h

View file

@ -1,146 +0,0 @@
//Copyright 2015 <>< Charles Lohr Under the MIT/x11 License, NewBSD License or
// ColorChord License. You Choose.
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>
#include <stdint.h>
#define SPI_FLASH_SEC_SIZE 4096
#define MFS_STARTFLASHSECTOR 0x100
#define MFS_START (MFS_STARTFLASHSECTOR*SPI_FLASH_SEC_SIZE)
#define MFS_SECTOR 256
#define MFS_FILENAMELEN 32-8
#define ENTRIES 8192
#define ENDIAN(x) x//htonl
struct MFSFileEntry
{
char name[MFS_FILENAMELEN];
uint32_t start; //From beginning of mfs thing.
uint32_t len;
} mfsfat[ENTRIES];
unsigned char mfsdata[131072*8];
unsigned long fatpointer = 0;
unsigned long datapointer = 0;
int main( int argc, char ** argv )
{
int i;
DIR *d;
struct dirent *dir;
if( argc != 3 )
{
fprintf( stderr, "Error: [tool] [directory to pack] [output packed .dat file]\n" );
return -1;
}
d = opendir( argv[1] );
if (!d)
{
fprintf( stderr, "Error: cannot open folder for packing.\n" );
return -2;
}
memcpy( mfsfat[fatpointer].name, "MPFSMPFS", 8 );
mfsfat[fatpointer].start = 0;
mfsfat[fatpointer].len = 0;
fatpointer++;
while ((dir = readdir(d)) != NULL)
{
if( dir->d_type & DT_REG )
{
char thisfile[1024];
struct stat buf;
int dlen = strlen( dir->d_name );
int sprret = snprintf( thisfile, 1023, "%s/%s", argv[1], dir->d_name );
if( sprret > 1023 || sprret < 1 )
{
fprintf( stderr, "Error processing \"%s\" (snprintf)\n", dir->d_name );
continue;
}
int statret = stat( thisfile, &buf );
if( statret )
{
fprintf( stderr, "Error processing \"%s\" (stat)\n", dir->d_name );
continue;
}
if( dlen >= MFS_FILENAMELEN )
{
fprintf( stderr, "Warning: Fle \"%s\" too long.\n", dir->d_name );
continue;
}
if( fatpointer > ENTRIES )
{
fprintf( stderr, "Warning: Not enough entries to fit \"%s\".\n", dir->d_name );
continue;
}
if( buf.st_size + datapointer > sizeof( mfsdata ) )
{
fprintf( stderr, "Error: no space left.\n" );
return -1;
}
memcpy( mfsfat[fatpointer].name, dir->d_name, dlen );
mfsfat[fatpointer].start = datapointer;
mfsfat[fatpointer].len = ENDIAN( buf.st_size );
fatpointer++;
if( buf.st_size )
{
FILE * f = fopen( thisfile, "rb" );
if( !f )
{
fprintf( stderr, "Error: cannot open \"%s\" for reading.\n", dir->d_name );
return -9;
}
fread( &mfsdata[datapointer], 1, buf.st_size, f );
fclose( f );
int rs = buf.st_size;
rs = (rs+1+MFS_SECTOR)&(~(MFS_SECTOR-1));
datapointer += rs;
printf( "%s: %d (%ld)\n", thisfile, rs, datapointer );
}
}
}
closedir(d);
int rs = (fatpointer+1)*sizeof(struct MFSFileEntry);
rs = (rs+1+MFS_SECTOR)&(~(MFS_SECTOR-1));
for( i = 0; i < fatpointer; i++ )
{
mfsfat[i].start = ENDIAN(mfsfat[i].start + rs );
}
printf( "%d %ld\n", rs, datapointer );
FILE * f = fopen( argv[2], "w" );
if( !f || ferror( f ) )
{
fprintf( stderr, "Error: cannot open \"%s\" for writing.\n", argv[2] );
}
fwrite( mfsfat, rs, 1, f );
fwrite( mfsdata, datapointer, 1, f );
fclose( f );
return 0;
}

1
embedded8266/web/mfsmaker.c Symbolic link
View file

@ -0,0 +1 @@
../esp82xx/web/mfsmaker.c

View file

@ -1,11 +1,11 @@
<html>
<!-- Copyright (C) 2015 <>< Charles Lohr, see LICENSE file for more info.
This particular file may be licensed under the MIT/x11, New BSD or ColorChord Licenses. -->
<!-- Copyright (C) 2015 <>< Charles Lohr, see LICENSE file for more info. -->
<head>
<title>ColorChord Control Panel</title>
<script language="javascript" type="text/javascript" src=jquery-2.1.4.min.js.gz></script>
<title>{{PAGE_TITLE}}</title>
<script language="javascript" type="text/javascript" src={{PAGE_JQUERYFL}}></script>
<script language="javascript" type="text/javascript" src=menuinterface.js></script>
<script language="javascript" type="text/javascript" src=main.js></script>
{{PAGE_SCRIPT}}
<meta charset="UTF-8">
<style>
table { width: 100%; }
@ -20,7 +20,7 @@ input[type="range"]:before {left:0em; content: attr(min);}input[type="range"]:af
</style>
</head>
<body>
<h2>ColorChord: Embedded</h2>
<h2>{{PAGE_HEADING}}</h2>
<hr>
<table id="MainMenu">
@ -82,7 +82,11 @@ input[type="range"]:before {left:0em; content: attr(min);}input[type="range"]:af
</table>
<p><font size=-2>Copyright (C) 2015 &lt&gt&lt Charles Lohr, See LICENSE file for more info.</font></p>
<font size=-2>
<p>Copyright (C) 2015-2016 &lt&gt&lt Charles Lohr, See LICENSE file for more info.</p>
<p id=version><font size=-2>{{VERSSTR}}</font></p>
<p><a href={{PROJECT_URL}}><img src="https://raw.githubusercontent.com/github-archive/media/master/octocats/blacktocat-16.png" style="height: 1em;" alt="github-logo">{{PROJECT_NAME}}</a></p>
</font>
<div id=SystemMessage>...</div>
</body>
</html>

View file

@ -0,0 +1 @@
../../esp82xx/web/page/jquery-2.1.4.min.js.gz

View file

@ -47,6 +47,13 @@ function QueueOperation( command, callback )
function init()
{
GPIOlines = '';
for(var i=0; i<16; ++i)
GPIOlines += "<td align=center>"+ i
+ "<input type=button id=ButtonGPIO"+ i +" value=0 onclick=\"TwiddleGPIO("+ i +");\">"
+ "<input type=button id=BGPIOIn"+ i +" value=In onclick=\"GPIOInput("+ i +");\" class=\"inbutton\">"
+ "</td>";
$('#MainMenu > tbody:first-child').before( "\
<tr><td width=1> \
<input type=submit onclick=\"ShowHideEvent( 'SystemStatus' );\" value='System Status' id=SystemStatusClicker></td><td> \
@ -85,28 +92,17 @@ function init()
<tr><td width=1> \
<input type=submit onclick=\"ShowHideEvent( 'GPIOs' ); GPIODataTicker();\" value=\"GPIOs\"></td><td> \
<div id=GPIOs class=\"collapsible\"> \
<table width=100% border=1><tr> \
<td align=center>0<input type=button id=ButtonGPIO0 value=0 onclick=\"TwiddleGPIO(0);\"><input type=button id=BGPIOIn0 value=In onclick=\"GPIOInput(0);\" class=\"inbutton\"></td> \
<td align=center>1<input type=button id=ButtonGPIO1 value=0 onclick=\"TwiddleGPIO(1);\"><input type=button id=BGPIOIn1 value=In onclick=\"GPIOInput(1);\" class=\"inbutton\"></td> \
<td align=center>2<input type=button id=ButtonGPIO2 value=0 onclick=\"TwiddleGPIO(2);\"><input type=button id=BGPIOIn2 value=In onclick=\"GPIOInput(2);\" class=\"inbutton\"></td> \
<td align=center>3<input type=button id=ButtonGPIO3 value=0 onclick=\"TwiddleGPIO(3);\"><input type=button id=BGPIOIn3 value=In onclick=\"GPIOInput(3);\" class=\"inbutton\"></td> \
<td align=center>4<input type=button id=ButtonGPIO4 value=0 onclick=\"TwiddleGPIO(4);\"><input type=button id=BGPIOIn4 value=In onclick=\"GPIOInput(4);\" class=\"inbutton\"></td> \
<td align=center>5<input type=button id=ButtonGPIO5 value=0 onclick=\"TwiddleGPIO(5);\"><input type=button id=BGPIOIn5 value=In onclick=\"GPIOInput(5);\" class=\"inbutton\"></td> \
<td>...</td> \
<td align=center>12<input type=button id=ButtonGPIO12 value=0 onclick=\"TwiddleGPIO(12);\"><input type=button id=BGPIOIn12 value=In onclick=\"GPIOInput(12);\" class=\"inbutton\"></td> \
<td align=center>13<input type=button id=ButtonGPIO13 value=0 onclick=\"TwiddleGPIO(13);\"><input type=button id=BGPIOIn13 value=In onclick=\"GPIOInput(13);\" class=\"inbutton\"></td> \
<td align=center>14<input type=button id=ButtonGPIO14 value=0 onclick=\"TwiddleGPIO(14);\"><input type=button id=BGPIOIn14 value=In onclick=\"GPIOInput(14);\" class=\"inbutton\"></td> \
<td align=center>15<input type=button id=ButtonGPIO15 value=0 onclick=\"TwiddleGPIO(15);\"><input type=button id=BGPIOIn15 value=In onclick=\"GPIOInput(15);\" class=\"inbutton\"></td> \
</tr></table></div></td></tr>\
<table width=100% border=1><tr>" +
GPIOlines
+ "</tr></table></div></td></tr>\
\
<tr><td width=1>\
<input type=submit onclick=\"ShowHideEvent( 'SystemReflash' );\" value=\"System Reflash\"></td><td>\
<div id=SystemReflash class=\"collapsible\">\
<div id=InnerSystemReflash class=\"dragandrophandler\">\
<input id=\"dragndropersystem\" type=\"file\" multiple> <div id=innersystemflashtext>Drop or browse for system (0x000.. 0x400...) or web (.mpfs) reflash files.</div>\
</div></div></td></tr>\
");
</div></div></td></tr>"
);
MakeDragDrop( "InnerSystemReflash", DragDropSystemFiles );
$("#dragndropersystem").change(function() { DragDropSystemFiles(this.files ); });

View file

@ -1,236 +0,0 @@
//Unless what else is individually marked, all code in this file is
//Copyright 2015 <>< Charles Lohr Under the MIT/x11 License, NewBSD License or
// ColorChord License. You Choose.
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/poll.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#define sector_SIZE 4096
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0x0 //Don't request NOSIGNAL on systems where this is not implemented.
#endif
int sockfd;
char recvline[10000];
int PushMatch( const char * match )
{
struct timeval tva, tvb;
gettimeofday( &tva, 0 );
gettimeofday( &tvb, 0 );
while( tvb.tv_sec - tva.tv_sec < 3 ) //3 second timeout.
{
struct pollfd ufds;
ufds.fd = sockfd;
ufds.events = POLLIN;
int rv = poll(&ufds, 1, 500);
if( rv > 0 )
{
// tbuf = recvline;
int n=recvfrom(sockfd,recvline,10000,0,NULL,NULL);
// printf( "!!%d ->%s\n", n,recvline );
// printf( "%s === %s\n", recvline, match );
if( strncmp( recvline, match, strlen( match ) ) == 0 )
{
// printf( "Ok\n" ); fflush( stdout );
return 0;
}
}
gettimeofday( &tvb, 0 );
}
return 1;
}
int main(int argc, char**argv)
{
int n;
struct sockaddr_in servaddr,cliaddr;
char sendline[1000];
// char recvline[1000];
if (argc != 4)
{
printf("usage: pushtodev [IP address] [address offset] [file]\n");
exit(-1);
}
int offset = atoi( argv[2] );
const char * file = argv[3];
if( offset <= 0 )
{
fprintf( stderr, "Error: Cannot write to address 0 or before.\n" );
exit(-2);
}
FILE * f = fopen( file, "rb" );
if( !f || feof( f ) )
{
fprintf( stderr, "Error: cannot open file.\n" );
exit(-3);
}
sockfd=socket(AF_INET,SOCK_DGRAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr=inet_addr(argv[1]);
servaddr.sin_port=htons(7878);
int devo = 0;
int lastsector_block = -1;
int resend_times = 0;
int r;
while( !feof( f ) )
{
int tries;
int thissuccess;
char buffer[1024];
char bufferout[1600];
int reads = fread( buffer, 1, 1024, f );
int sendplace = offset + devo;
int sendsize = reads;
#ifdef SECTOR
int sector = sendplace / sector_SIZE;
if( sector != lastsector_block )
{
char se[64];
int sel = sprintf( se, "FE%d\r\n", sector );
thissuccess = 0;
for( tries = 0; tries < 10; tries++ )
{
char match[75];
printf( "Erase: %d\n", sector );
sendto( sockfd, se, sel, MSG_NOSIGNAL, (struct sockaddr *)&servaddr,sizeof(servaddr));
sprintf( match, "FE%d", sector );
if( PushMatch(match) == 0 ) { thissuccess = 1; break; }
printf( "Retry.\n" );
}
if( !thissuccess )
{
fprintf( stderr, "Error: Timeout in communications.\n" );
exit( -6 );
}
lastsector_block = sector;
}
#else //block
int block = sendplace / 65536;
if( block != lastsector_block )
{
char se[64];
int sel = sprintf( se, "FB%d\r\n", block );
thissuccess = 0;
for( tries = 0; tries < 10; tries++ )
{
char match[75];
printf( "Erase: %d\n", block );
sendto( sockfd, se, sel, MSG_NOSIGNAL, (struct sockaddr *)&servaddr,sizeof(servaddr));
sprintf( match, "FB%d", block );
if( PushMatch(match) == 0 ) { thissuccess = 1; break; }
printf( "Retry.\n" );
}
if( !thissuccess )
{
fprintf( stderr, "Error: Timeout in communications.\n" );
exit( -6 );
}
lastsector_block = block;
}
#endif
resend_times = 0;
resend:
r = sprintf( bufferout, "FW%d\t%d\t", sendplace, sendsize );
printf( "bufferout: %d %d %s\n", sendplace, sendsize, bufferout );
memcpy( bufferout + r, buffer, sendsize );
thissuccess = 0;
for( tries = 0; tries < 10; tries++ )
{
char match[75];
sendto( sockfd, bufferout, reads + r, MSG_NOSIGNAL, (struct sockaddr *)&servaddr,sizeof(servaddr));
sprintf( match, "FW%d", sendplace );
if( PushMatch(match) == 0 ) { thissuccess = 1; break; }
printf( "Retry.\n" );
}
if( !thissuccess )
{
fprintf( stderr, "Error: Timeout in communications.\n" );
exit( -6 );
}
/*
printf( "Verifying..." );
fflush( stdout );
int r = sprintf( bufferout, "FR%d:%d", sendplace, sendsize );
bufferout[r] = 0;
thissuccess = 0;
for( tries = 0; tries < 10; tries++ )
{
char match[1600];
sendto( sockfd, bufferout, r, MSG_NOSIGNAL, (struct sockaddr *)&servaddr,sizeof(servaddr));
devo += reads;
sprintf( match, "FR%08d", sendplace );
if( PushMatch(match) == 0 ) {
//Check data...
//printf( "RR:%s\n", recvline );
char * colon1 = strchr( recvline, ':' );
char * colon2 = (colon1)?strchr( colon1+1, ':' ):0;
//printf( "::%p %p \"%s\"\n", colon1, colon2,recvline );
if( colon2 )
{
if( memcmp( colon2+1, buffer, sendsize ) == 0 )
thissuccess = 1;
}
if( !thissuccess )
{
if( resend_times > 2 )
{
break;
}
resend_times++;
goto resend;
}
break;
}
printf( "Retry.\n" );
}
if( !thissuccess )
{
fprintf( stderr, "Error: Fault verifying.\n" );
exit( -6 );
}
*/
devo += reads;
}
return 0;
}

View file

@ -0,0 +1 @@
../esp82xx/web/pushtodev.c