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 );
|
||||
|
||||