Modularize esp8266 components
This commit is contained in:
parent
1dd31cc7c3
commit
63be61e225
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
[submodule "embedded8266/esp82xx"]
|
||||
path = embedded8266/esp82xx
|
||||
url = git@github.com:cnlohr/esp82xx.git
|
|
@ -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
1
embedded8266/LICENSE
Symbolic link
|
@ -0,0 +1 @@
|
|||
esp82xx/LICENSE
|
|
@ -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)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef _CCCONFIG_H
|
||||
#define _CCCONFIG_H
|
||||
|
||||
#include "c_types.h"
|
||||
#include <c_types.h>
|
||||
|
||||
#define HPABUFFSIZE 512
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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;
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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 );
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
1
embedded8266/esp82xx
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit cd8c2f130055a7cf60f05dc7da8590f1c913fc3f
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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
|
||||
|
|
@ -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
|
|
@ -1,3 +0,0 @@
|
|||
//This exists to make sure anything including stdint.h includes this instead.
|
||||
|
||||
#include "c_types.h"
|
|
@ -1 +0,0 @@
|
|||
//Nothing here. Just a file to make things that include <string.h> happy.
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -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
|
||||
|
22
embedded8266/user.cfg
Normal file
22
embedded8266/user.cfg
Normal file
|
@ -0,0 +1,22 @@
|
|||
###############################################################################
|
||||
# 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_SCRIPT =
|
||||
|
|
@ -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
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
1
embedded8266/web/Makefile
Symbolic link
|
@ -0,0 +1 @@
|
|||
../esp82xx/web/Makefile
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
1
embedded8266/web/execute_reflash.c
Symbolic link
1
embedded8266/web/execute_reflash.c
Symbolic link
|
@ -0,0 +1 @@
|
|||
../esp82xx/web/execute_reflash.c
|
|
@ -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
1
embedded8266/web/md5.c
Symbolic link
|
@ -0,0 +1 @@
|
|||
../esp82xx/web/md5.c
|
|
@ -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
1
embedded8266/web/md5.h
Symbolic link
|
@ -0,0 +1 @@
|
|||
../esp82xx/web/md5.h
|
|
@ -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
1
embedded8266/web/mfsmaker.c
Symbolic link
|
@ -0,0 +1 @@
|
|||
../esp82xx/web/mfsmaker.c
|
|
@ -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>
|
||||
<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%; }
|
||||
|
@ -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 <>< Charles Lohr, See LICENSE file for more info.</font></p>
|
||||
<font size=-2>
|
||||
<p>Copyright (C) 2015-2016 <>< Charles Lohr, See LICENSE file for more info.</p>
|
||||
<p id=version><font size=-2>{{VERSSTR}}</font></p>
|
||||
<p style="margin-left: auto; float: left; font-size: 70%; text-align: left;"><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>
|
||||
|
|
Binary file not shown.
1
embedded8266/web/page/jquery-2.1.4.min.js.gz
Symbolic link
1
embedded8266/web/page/jquery-2.1.4.min.js.gz
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../esp82xx/web/page/jquery-2.1.4.min.js.gz
|
|
@ -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 ); });
|
||||
|
|
|
@ -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;
|
||||
}
|
1
embedded8266/web/pushtodev.c
Symbolic link
1
embedded8266/web/pushtodev.c
Symbolic link
|
@ -0,0 +1 @@
|
|||
../esp82xx/web/pushtodev.c
|
Loading…
Reference in a new issue