├── .gitignore ├── .gitmodules ├── LICENSE.txt ├── Makefile ├── Makefile.combined ├── Makefile.ota ├── Makefile.separate ├── README.md ├── esp-link-stuff ├── config.c ├── config.h ├── crc16.c ├── crc16.h ├── gpio-helpers.c ├── gpio-helpers.h ├── log.c ├── log.h ├── serbridge.c ├── serbridge.h ├── status.c ├── status.h ├── task.c ├── task.h ├── uart.c ├── uart.h └── uart_hw.h ├── esphttpdconfig.mk ├── esptool ├── html ├── basic.min.css ├── console.js ├── dropzone.min.css ├── dropzone.min.js ├── favicon.ico ├── flash │ ├── 140medley.min.js │ └── index.html ├── index.html ├── log.html ├── logo.png ├── newpage.html ├── p2-ddloader.html ├── settings.html ├── style.css ├── ui.js ├── update-ffs.html ├── w3.css ├── websocket │ └── index.html └── wifi │ ├── 140medley.min.js │ ├── connecting.html │ ├── icons.png │ ├── style.css │ └── wifi.html ├── include ├── uart_hw.h └── user_config.h ├── ldscript_memspecific.ld ├── libesphttpd ├── .keep ├── Makefile ├── README.md ├── core │ ├── auth.c │ ├── base64.c │ ├── base64.h │ ├── httpd-freertos.c │ ├── httpd-nonos.c │ ├── httpd-platform.h │ ├── httpd.c │ ├── httpdespfs.c │ └── sha1.c ├── espfs │ ├── espfs.c │ ├── espfsformat.h │ ├── espfstest │ │ ├── Makefile │ │ └── main.c │ ├── heatshrink_config_custom.h │ ├── heatshrink_decoder.c │ └── mkespfsimage │ │ ├── Makefile │ │ ├── heatshrink_encoder.c │ │ ├── heatshrink_encoder.o │ │ ├── main.c │ │ ├── main.o │ │ └── mkespfsimage ├── include │ ├── auth.h │ ├── captdns.h │ ├── cgiflash.h │ ├── cgiwebsocket.h │ ├── cgiwifi.h │ ├── esp8266.h │ ├── espfs.h │ ├── espmissingincludes.h │ ├── httpd.h │ ├── httpdespfs.h │ ├── platform.h │ ├── sha1.h │ ├── user_config.h │ └── webpages-espfs.h ├── lib │ └── heatshrink │ │ ├── .travis.yml │ │ ├── LICENSE │ │ ├── Makefile │ │ ├── README.md │ │ ├── dec_sm.dot │ │ ├── enc_sm.dot │ │ ├── greatest.h │ │ ├── heatshrink.c │ │ ├── heatshrink_common.h │ │ ├── heatshrink_config.h │ │ ├── heatshrink_decoder.c │ │ ├── heatshrink_decoder.h │ │ ├── heatshrink_encoder.c │ │ ├── heatshrink_encoder.h │ │ ├── test_heatshrink_dynamic.c │ │ ├── test_heatshrink_dynamic_theft.c │ │ └── test_heatshrink_static.c ├── libesphttpd.a ├── libwebpages-espfs.a ├── mkupgimg │ ├── .gitignore │ ├── Makefile │ └── mkupgimg.c ├── util │ ├── captdns.c │ ├── cgiflash.c │ ├── cgiwebsocket.c │ └── cgiwifi.c ├── webpages.espfs └── webpages.espfs.ld ├── parallax-unused ├── IP_Loader.h ├── propimage.c └── propimage.h ├── parallax ├── cgiprop.c ├── cgiprop.h ├── discovery.c ├── discovery.h ├── httpdroffs.c ├── httpdroffs.h ├── mkroffsimage │ ├── Makefile │ ├── README.txt │ └── mkroffsimage.c ├── proploader.c ├── proploader.h ├── roffs.c ├── roffs.h ├── roffsformat.h ├── sscp-cmds.c ├── sscp-fs.c ├── sscp-http.c ├── sscp-settings.c ├── sscp-tcp.c ├── sscp-udp.c ├── sscp-wifi.c ├── sscp-ws.c ├── sscp.c ├── sscp.h └── user_main.c ├── release ├── Makefile ├── clear-1m.sh ├── clear-ffs.sh ├── clear.sh ├── flash-all.sh ├── patch.c ├── release-notes.txt └── update-fw.sh └── test-framework ├── Makefile └── src ├── cmd.c ├── cmd.h ├── framework.c ├── framework.h ├── main.c ├── serial.h ├── serial_mingw.c ├── serial_posix.c ├── sock.h ├── sock_posix.c ├── tests.c └── tests.h /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | nbproject/ 3 | release/release 4 | release/patch 5 | *.zip 6 | *.bin 7 | *.elf 8 | *.bak 9 | *~ 10 | test-framework-* 11 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "ESP8266_NONOS_SDK"] 2 | path = ESP8266_NONOS_SDK 3 | url = https://github.com/espressif/ESP8266_NONOS_SDK.git 4 | [submodule "esptool-ck"] 5 | path = esptool-ck 6 | url = https://github.com/igrr/esptool-ck 7 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | ┌───────────────────────────────────────────────────────────────────────────────┐ 3 | │ TERMS OF USE: MIT License │ 4 | ├───────────────────────────────────────────────────────────────────────────────┤ 5 | │Permission is hereby granted, free of charge, to any person obtaining a copy of this │ 6 | │software and associated documentation files (the "Software"), to deal in the Software │ 7 | │without restriction, including without limitation the rights to use, copy, modify, │ 8 | │merge, publish, distribute, sublicense, and/or sell copies of the Software, and to │ 9 | │permit persons to whom the Software is furnished to do so, subject to the following │ 10 | │conditions: │ 11 | │ │ 12 | │The above copyright notice and this permission notice shall be included in all copies │ 13 | │or substantial portions of the Software. │ 14 | │ │ 15 | │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, │ 16 | │INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A │ 17 | │PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT │ 18 | │HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF │ 19 | │CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE │ 20 | │OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ 21 | └───────────────────────────────────────────────────────────────────────────────┘ 22 | */ 23 | -------------------------------------------------------------------------------- /Makefile.combined: -------------------------------------------------------------------------------- 1 | #Makefile with the options specific to the build of a non-upgradable firmware with 2 | #the espfs combined into the flash binary. 3 | 4 | # linker script used for the linker step 5 | LD_SCRIPT = eagle.app.v6.ld 6 | # Extra script to tell the linker the correct irom0 memory available 7 | EXTRA_LD_SCRIPTS = ldscript_memspecific.ld 8 | 9 | TARGET_OUT := $(addprefix $(BUILD_BASE)/,$(TARGET).out) 10 | 11 | .PHONY: ldscript_memspecific.ld 12 | 13 | BLANKPOS="$$(printf "0x%X" $$(($(ESP_SPI_FLASH_SIZE_K)*1024-0x2000)))" 14 | INITDATAPOS="$$(printf "0x%X" $$(($(ESP_SPI_FLASH_SIZE_K)*1024-0x4000)))" 15 | 16 | ldscript_memspecific.ld: 17 | $(vecho) "GEN $@" 18 | $(Q) echo "MEMORY { irom0_0_seg : org = 0x40240000, len = "$$(printf "0x%X" $$(($(ESP_SPI_FLASH_SIZE_K)*1024-0x4000)))" }"> ldscript_memspecific.ld 19 | 20 | 21 | $(TARGET_OUT): $(APP_AR) $(EXTRA_LD_SCRIPTS) 22 | $(vecho) "LD $@" 23 | $(Q) $(LD) -Llibesphttpd -L$(SDK_LIBDIR) $(LD_SCRIPT) $(EXTRA_LD_SCRIPTS) $(LDFLAGS) -Wl,--start-group $(LIBS) $(APP_AR) -Wl,--end-group -o $@ 24 | 25 | 26 | $(FW_BASE): $(TARGET_OUT) 27 | $(vecho) "FW $@" 28 | $(Q) mkdir -p $@ 29 | $(Q) $(ESPTOOL) elf2image $(TARGET_OUT) --output $@/ 30 | 31 | flash: $(TARGET_OUT) $(FW_BASE) 32 | $(Q) $(ESPTOOL) $(ESPTOOL_OPTS) write_flash $(ESPTOOL_FLASHDEF) 0x00000 $(FW_BASE)/0x00000.bin 0x40000 $(FW_BASE)/0x40000.bin 33 | 34 | blankflash: 35 | $(Q) $(ESPTOOL) $(ESPTOOL_OPTS) write_flash $(ESPTOOL_FLASHDEF) $(BLANKPOS) $(SDK_BASE)/bin/blank.bin $(INITDATAPOS) $(SDK_BASE)/bin/esp_init_data_default.bin 36 | 37 | -------------------------------------------------------------------------------- /Makefile.ota: -------------------------------------------------------------------------------- 1 | #Makefile with the options specific to the build of a non-upgradable firmware with 2 | #the espfs combined into the flash binary. 3 | 4 | # Change tagname to some identifier that's unique for your project. 27 chars max. 5 | TAGNAME ?= "generic" 6 | 7 | # linker script used for the linker step 8 | 9 | LD_MAP_1:=512:eagle.app.v6.new.512.app1.ld 1024:eagle.app.v6.new.1024.app1.ld 2048:eagle.app.v6.new.2048.ld 4096:eagle.app.v6.new.2048.ld 10 | LD_MAP_2:=512:eagle.app.v6.new.512.app2.ld 1024:eagle.app.v6.new.1024.app2.ld 2048:eagle.app.v6.new.2048.ld 4096:eagle.app.v6.new.2048.ld 11 | LD_SCRIPT_USR1 := $(call maplookup,$(ESP_SPI_IMAGE_SIZE_K),$(LD_MAP_1)) 12 | LD_SCRIPT_USR2 := $(call maplookup,$(ESP_SPI_IMAGE_SIZE_K),$(LD_MAP_2)) 13 | 14 | TARGET_OUT_USR1 := $(addprefix $(BUILD_BASE)/,$(TARGET).user1.out) 15 | TARGET_OUT_USR2 := $(addprefix $(BUILD_BASE)/,$(TARGET).user2.out) 16 | TARGET_OUT := $(TARGET_OUT_USR1) $(TARGET_OUT_USR2) 17 | 18 | TARGET_BIN_USR1 := $(addprefix $(BUILD_BASE)/,$(TARGET).user1.bin) 19 | TARGET_BIN_USR2 := $(addprefix $(BUILD_BASE)/,$(TARGET).user2.bin) 20 | TARGET_BIN := $(TARGET_BIN_USR1) $(TARGET_BIN_USR2) 21 | TARGET_OTAFILE := $(addprefix $(BUILD_BASE)/,$(TARGET).ota) 22 | 23 | 24 | BLANKPOS="$$(printf "0x%X" $$(($(ESP_SPI_FLASH_SIZE_K)*512-0x2000)))" 25 | INITDATAPOS="$$(printf "0x%X" $$(($(ESP_SPI_FLASH_SIZE_K)*512-0x4000)))" 26 | 27 | #Convert SPI size into arg for appgen. Format: no=size 28 | FLASH_MAP_CONV:=512:0 1024:2 2048:5 4096:6 29 | ESP_FLASH_SIZE_IX:=$(call maplookup,$(ESP_SPI_IMAGE_SIZE_K),$(FLASH_MAP_CONV)) 30 | 31 | CFLAGS += -DOTA_TAGNAME=\"$(TAGNAME)\" 32 | 33 | define genappbin 34 | $(1): $$(APP_AR) 35 | $$(vecho) LD $$@ 36 | $$(Q) $$(LD) -Llibesphttpd -L$$(SDK_LIBDIR) $(2) $$(LDFLAGS) -Wl,--start-group $$(LIBS) $$(APP_AR) -Wl,--end-group -o $$@ 37 | 38 | $(3): $(1) 39 | $$(vecho) APPGEN $$@ 40 | $$(Q) $$(OBJCOPY) --only-section .text -O binary $1 build/eagle.app.v6.text.bin 41 | $$(Q) $$(OBJCOPY) --only-section .data -O binary $1 build/eagle.app.v6.data.bin 42 | $$(Q) $$(OBJCOPY) --only-section .rodata -O binary $1 build/eagle.app.v6.rodata.bin 43 | $$(Q) $$(OBJCOPY) --only-section .irom0.text -O binary $1 build/eagle.app.v6.irom0text.bin 44 | $$(Q) cd build; COMPILE=gcc PATH=$$(XTENSA_TOOLS_ROOT):$$(PATH) python $$(APPGEN) $(1:build/%=%) 2 $$(ESP_FLASH_MODE) $$(ESP_FLASH_FREQ_DIV) $$(ESP_FLASH_SIZE_IX) $(4) 45 | $$(Q) rm -f eagle.app.v6.*.bin 46 | $$(Q) mv build/eagle.app.flash.bin $$@ 47 | @echo "** "$$@ " uses $$$$(stat -c '%s' $$@) bytes of" $$(ESP_FLASH_MAX) "available" 48 | endef 49 | 50 | $(eval $(call genappbin,$(TARGET_OUT_USR1),$$(LD_SCRIPT_USR1),$$(TARGET_BIN_USR1),1)) 51 | $(eval $(call genappbin,$(TARGET_OUT_USR2),$$(LD_SCRIPT_USR2),$$(TARGET_BIN_USR2),2)) 52 | 53 | .PHONY: ldscript_memspecific.ld 54 | 55 | ldscript_memspecific.ld: 56 | $(vecho) "GEN $@" 57 | $(Q) echo "MEMORY { irom0_0_seg : org = 0x40240000, len = "$$(printf "0x%X" $$(($(ESP_SPI_FLASH_SIZE_K)*1024-0x4000)))" }"> ldscript_memspecific.ld 58 | 59 | 60 | #define makeuser 61 | #$1: $(APP_AR) 62 | # $(vecho) "LD $@" 63 | # $(Q) $(LD) -Llibesphttpd -L$(SDK_LIBDIR) $(LD_SCRIPT) $(EXTRA_LD_SCRIPTS) $(LDFLAGS) -Wl,--start-group $(LIBS) $(APP_AR) -Wl,--end-group -o $@ 64 | # $(Q) $(OBJCP) --only-section .text -O binary $2 build/eagle.app.v6.text.bin 65 | # $(Q) $(OBJCP) --only-section .data -O binary $2 build/eagle.app.v6.data.bin 66 | # $(Q) $(OBJCP) --only-section .rodata -O binary $2 build/eagle.app.v6.rodata.bin 67 | # $(Q) $(OBJCP) --only-section .irom0.text -O binary $2 build/eagle.app.v6.irom0text.bin 68 | # ls -ls build/eagle*bin 69 | # $(Q) COMPILE=gcc PATH=$(XTENSA_TOOLS_ROOT):$(PATH) python $(APPGEN_TOOL) $(USER1_OUT) 2 $(ESP_FLASH_MODE) $(ESP_FLASH_FREQ_DIV) $(ESP_SPI_SIZE) 70 | # $(Q) rm -f eagle.app.v6.*.bin 71 | # $(Q) mv eagle.app.flash.bin $@ 72 | # @echo "** user1.bin uses $$(stat -c '%s' $@) bytes of" $(ESP_FLASH_MAX) "available" 73 | # $(Q) if [ $$(stat -c '%s' $@) -gt $$(( $(ESP_FLASH_MAX) )) ]; then echo "$@ too big!"; false; fi 74 | #endef 75 | 76 | 77 | #user1.bin: 78 | # $(call makeuser,user1.bin,1) 79 | 80 | libesphttpd/mkupgimg/mkupgimg: libesphttpd/mkupgimg/ 81 | make -C libesphttpd/mkupgimg/ 82 | 83 | $(FW_BASE): $(TARGET_BIN) libesphttpd/mkupgimg/mkupgimg 84 | $(Q) libesphttpd/mkupgimg/mkupgimg $(TARGET_BIN_USR1) $(TARGET_BIN_USR2) $(TAGNAME) $(TARGET_OTAFILE) 85 | 86 | flash: $(TARGET_OUT) $(FW_BASE) 87 | $(Q) $(ESPTOOL) $(ESPTOOL_OPTS) write_flash $(ESPTOOL_FLASHDEF) 0x00000 "$(SDK_BASE)/bin/boot_v1.6.bin" 0x1000 $(TARGET_BIN_USR1) 88 | 89 | blankflash: 90 | $(Q) $(ESPTOOL) $(ESPTOOL_OPTS) write_flash $(ESPTOOL_FLASHDEF) $(BLANKPOS) $(SDK_BASE)/bin/blank.bin $(INITDATAPOS) $(SDK_BASE)/bin/esp_init_data_default.bin 91 | 92 | -------------------------------------------------------------------------------- /Makefile.separate: -------------------------------------------------------------------------------- 1 | #Makefile with the options specific to the build of a non-upgradable firmware with 2 | #the espfs included in the firmware binary. 3 | 4 | # linker script used for the linker step 5 | LD_SCRIPT = eagle.app.v6.ld 6 | # Extra script to tell the linker the correct irom0 memory available 7 | EXTRA_LD_SCRIPTS = ldscript_memspecific.ld 8 | 9 | TARGET_OUT := $(addprefix $(BUILD_BASE)/,$(TARGET).out) 10 | 11 | .PHONY: ldscript_memspecific.ld 12 | 13 | BLANKPOS="$$(printf "0x%X" $$(($(ESP_SPI_FLASH_SIZE_K)*1024-0x2000)))" 14 | INITDATAPOS="$$(printf "0x%X" $$(($(ESP_SPI_FLASH_SIZE_K)*1024-0x4000)))" 15 | 16 | ldscript_memspecific.ld: 17 | $(vecho) "GEN $@" 18 | $(Q) echo "MEMORY { irom0_0_seg : org = 0x40240000, len = "$$(printf "0x%X" $$(($(ESP_SPI_FLASH_SIZE)-0x4000)))" }"> ldscript_memspecific.ld 19 | 20 | $(TARGET_OUT): $(APP_AR) $(EXTRA_LD_SCRIPTS) 21 | $(vecho) "LD $@" 22 | $(Q) $(LD) -Llibesphttpd -L$(SDK_LIBDIR) $(LD_SCRIPT) $(EXTRA_LD_SCRIPTS) $(LDFLAGS) -Wl,--start-group $(LIBS) $(APP_AR) -Wl,--end-group -o $@ 23 | 24 | $(FW_BASE): $(TARGET_OUT) 25 | $(vecho) "FW $@" 26 | $(Q) mkdir -p $@ 27 | $(Q) $(ESPTOOL) elf2image $(TARGET_OUT) --output $@/ 28 | 29 | flash: $(TARGET_OUT) $(FW_BASE) 30 | $(Q) $(ESPTOOL) $(ESPTOOL_OPTS) write_flash $(ESPTOOL_FLASHDEF) 0x00000 $(FW_BASE)/0x00000.bin 0x40000 $(FW_BASE)/0x40000.bin 31 | 32 | blankflash: 33 | $(Q) $(ESPTOOL) $(ESPTOOL_OPTS) write_flash $(ESPTOOL_FLASHDEF) $(BLANKPOS) $(SDK_BASE)/bin/blank.bin $(INITDATAPOS) $(SDK_BASE)/bin/esp_init_data_default.bin 34 | 35 | htmlflash: libesphttpd 36 | $(Q) if [ $$(stat -c '%s' libesphttpd/webpages.espfs) -gt $$(( $(ESPFS_SIZE) )) ]; then echo "webpages.espfs too big!"; false; fi 37 | $(Q) $(ESPTOOL) $(ESPTOOL_OPTS) write_flash $(ESPTOOL_FLASHDEF) $(ESPFS_POS) libesphttpd/webpages.espfs 38 | -------------------------------------------------------------------------------- /esp-link-stuff/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | // Flash configuration settings. When adding new items always add them at the end and formulate 5 | // them such that a value of zero is an appropriate default or backwards compatible. Existing 6 | // modules that are upgraded will have zero in the new fields. This ensures that an upgrade does 7 | // not wipe out the old settings. 8 | typedef struct { 9 | uint32_t seq; // flash write sequence number 10 | uint16_t magic, crc; 11 | uint32_t version; 12 | int32_t loader_baud_rate; 13 | int32_t baud_rate; 14 | int32_t dbg_baud_rate; 15 | int8_t stop_bits; 16 | int8_t dbg_stop_bits; 17 | int8_t conn_led_pin; 18 | int8_t reset_pin; 19 | char module_name[32+1]; 20 | char module_descr[129]; 21 | int8_t rx_pullup; 22 | int8_t sscp_enable; 23 | char sscp_need_pause[16]; 24 | int8_t sscp_need_pause_cnt; 25 | int32_t sscp_pause_time_ms; 26 | uint8_t sscp_start; 27 | int8_t sscp_events; 28 | int8_t dbg_enable; 29 | int8_t sscp_loader; 30 | int8_t p2_ddloader_enable; 31 | } FlashConfig; 32 | 33 | extern FlashConfig flashConfig; 34 | extern FlashConfig flashDefault; 35 | 36 | bool configSave(void); 37 | bool configRestore(void); 38 | bool configRestoreDefaults(void); 39 | void configWipe(void); 40 | const size_t getFlashSize(); 41 | 42 | bool softap_get_ssid(char *ssid, int size); 43 | bool softap_set_ssid(const char *ssid, int size); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /esp-link-stuff/crc16.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005, Swedish Institute of Computer Science 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of the Institute nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | * This file is part of the Contiki operating system. 30 | * 31 | */ 32 | 33 | /** \addtogroup crc16 34 | * @{ */ 35 | 36 | /** 37 | * \file 38 | * Implementation of the CRC16 calculcation 39 | * \author 40 | * Adam Dunkels 41 | * 42 | */ 43 | 44 | /* CITT CRC16 polynomial ^16 + ^12 + ^5 + 1 */ 45 | /*---------------------------------------------------------------------------*/ 46 | unsigned short 47 | crc16_add(unsigned char b, unsigned short acc) 48 | { 49 | /* 50 | acc = (unsigned char)(acc >> 8) | (acc << 8); 51 | acc ^= b; 52 | acc ^= (unsigned char)(acc & 0xff) >> 4; 53 | acc ^= (acc << 8) << 4; 54 | acc ^= ((acc & 0xff) << 4) << 1; 55 | */ 56 | 57 | acc ^= b; 58 | acc = (acc >> 8) | (acc << 8); 59 | acc ^= (acc & 0xff00) << 4; 60 | acc ^= (acc >> 8) >> 4; 61 | acc ^= (acc & 0xff00) >> 5; 62 | return acc; 63 | } 64 | /*---------------------------------------------------------------------------*/ 65 | unsigned short 66 | crc16_data(const unsigned char *data, int len, unsigned short acc) 67 | { 68 | int i; 69 | 70 | for(i = 0; i < len; ++i) { 71 | acc = crc16_add(*data, acc); 72 | ++data; 73 | } 74 | return acc; 75 | } 76 | /*---------------------------------------------------------------------------*/ 77 | 78 | /** @} */ 79 | -------------------------------------------------------------------------------- /esp-link-stuff/crc16.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005, Swedish Institute of Computer Science 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of the Institute nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | * This file is part of the Contiki operating system. 30 | * 31 | */ 32 | 33 | /** 34 | * \file 35 | * Header file for the CRC16 calculcation 36 | * \author 37 | * Adam Dunkels 38 | * 39 | */ 40 | 41 | /** \addtogroup lib 42 | * @{ */ 43 | 44 | /** 45 | * \defgroup crc16 Cyclic Redundancy Check 16 (CRC16) calculation 46 | * 47 | * The Cyclic Redundancy Check 16 is a hash function that produces a 48 | * checksum that is used to detect errors in transmissions. The CRC16 49 | * calculation module is an iterative CRC calculator that can be used 50 | * to cumulatively update a CRC checksum for every incoming byte. 51 | * 52 | * @{ 53 | */ 54 | 55 | #ifndef CRC16_H_ 56 | #define CRC16_H_ 57 | #ifdef __cplusplus 58 | extern "C" { 59 | #endif 60 | /** 61 | * \brief Update an accumulated CRC16 checksum with one byte. 62 | * \param b The byte to be added to the checksum 63 | * \param crc The accumulated CRC that is to be updated. 64 | * \return The updated CRC checksum. 65 | * 66 | * This function updates an accumulated CRC16 checksum 67 | * with one byte. It can be used as a running checksum, or 68 | * to checksum an entire data block. 69 | * 70 | * \note The algorithm used in this implementation is 71 | * tailored for a running checksum and does not perform as 72 | * well as a table-driven algorithm when checksumming an 73 | * entire data block. 74 | * 75 | */ 76 | unsigned short crc16_add(unsigned char b, unsigned short crc); 77 | 78 | /** 79 | * \brief Calculate the CRC16 over a data area 80 | * \param data Pointer to the data 81 | * \param datalen The length of the data 82 | * \param acc The accumulated CRC that is to be updated (or zero). 83 | * \return The CRC16 checksum. 84 | * 85 | * This function calculates the CRC16 checksum of a data area. 86 | * 87 | * \note The algorithm used in this implementation is 88 | * tailored for a running checksum and does not perform as 89 | * well as a table-driven algorithm when checksumming an 90 | * entire data block. 91 | */ 92 | unsigned short crc16_data(const unsigned char *data, int datalen, 93 | unsigned short acc); 94 | #ifdef __cplusplus 95 | } 96 | #endif 97 | #endif /* CRC16_H_ */ 98 | 99 | /** @} */ 100 | /** @} */ 101 | -------------------------------------------------------------------------------- /esp-link-stuff/gpio-helpers.c: -------------------------------------------------------------------------------- 1 | #include "esp8266.h" 2 | #include "gpio.h" 3 | 4 | // Make a pin be GPIO, i.e. set the mux so the pin has the gpio function 5 | void ICACHE_FLASH_ATTR makeGpio(uint8_t pin) { 6 | uint32_t addr; 7 | uint8_t func = 3; 8 | switch (pin) { 9 | case 0: 10 | addr = PERIPHS_IO_MUX_GPIO0_U; 11 | func = 0; 12 | break; 13 | case 1: 14 | addr = PERIPHS_IO_MUX_U0TXD_U; 15 | break; 16 | case 2: 17 | addr = PERIPHS_IO_MUX_GPIO2_U; 18 | func = 0; 19 | break; 20 | case 3: 21 | addr = PERIPHS_IO_MUX_U0RXD_U; 22 | break; 23 | case 4: 24 | addr = PERIPHS_IO_MUX_GPIO4_U; 25 | func = 0; 26 | break; 27 | case 5: 28 | addr = PERIPHS_IO_MUX_GPIO5_U; 29 | func = 0; 30 | break; 31 | case 6: 32 | case 7: 33 | case 8: 34 | case 9: 35 | case 10: 36 | case 11: 37 | addr = PERIPHS_IO_MUX_SD_CMD_U - 4 * (11-pin); 38 | break; 39 | case 12: 40 | case 13: 41 | case 14: 42 | case 15: 43 | addr = PERIPHS_IO_MUX_MTDO_U - 4 * (15-pin); 44 | break; 45 | default: 46 | return; 47 | } 48 | PIN_FUNC_SELECT(addr, func); 49 | } 50 | 51 | -------------------------------------------------------------------------------- /esp-link-stuff/gpio-helpers.h: -------------------------------------------------------------------------------- 1 | #ifndef __GPIO_HELPERS_H__ 2 | #define __GPIO_HELPERS_H__ 3 | 4 | void makeGpio(uint8_t pin); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /esp-link-stuff/log.h: -------------------------------------------------------------------------------- 1 | #ifndef LOG_H 2 | #define LOG_H 3 | 4 | #include "httpd.h" 5 | 6 | #define LOG_MODE_AUTO 0 // start by logging to uart0, turn aff after we get an IP 7 | #define LOG_MODE_OFF 1 // always off 8 | #define LOG_MODE_ON0 2 // always log to uart0 9 | #define LOG_MODE_ON1 3 // always log to uart1 10 | 11 | void logInit(void); 12 | void log_uart(bool enable); 13 | int ajaxLog(HttpdConnData *connData); 14 | int ajaxLogDbg(HttpdConnData *connData); 15 | 16 | void dumpMem(void *addr, int len); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /esp-link-stuff/serbridge.h: -------------------------------------------------------------------------------- 1 | #ifndef __SER_BRIDGE_H__ 2 | #define __SER_BRIDGE_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #define MAX_CONN 4 9 | #define SER_BRIDGE_TIMEOUT 300 // 300 seconds = 5 minutes 10 | 11 | // Send buffer size 12 | #define MAX_TXBUFFER (2*1460) 13 | 14 | enum connModes { 15 | cmInit = 0, // initialization mode: nothing received yet 16 | cmPGMInit, // initialization mode for programming 17 | cmTransparent, // transparent mode 18 | cmPGM, // Arduino/AVR/ARM programming mode 19 | cmTelnet, // use telnet escape sequences for programming mode 20 | }; 21 | 22 | typedef struct serbridgeConnData { 23 | struct espconn *conn; 24 | enum connModes conn_mode; // connection mode 25 | uint8_t telnet_state; 26 | uint16 txbufferlen; // length of data in txbuffer 27 | char *txbuffer; // buffer for the data to send 28 | char *sentbuffer; // buffer sent, awaiting callback to get freed 29 | uint32_t txoverflow_at; // when the transmitter started to overflow 30 | bool readytosend; // true, if txbuffer can be sent by espconn_sent 31 | } serbridgeConnData; 32 | 33 | // port1 is transparent&programming, second port is programming only 34 | void ICACHE_FLASH_ATTR serbridgeInit(int port); 35 | void ICACHE_FLASH_ATTR serbridgeInitPins(void); 36 | void ICACHE_FLASH_ATTR serbridgeUartCb(char *buf, short len); 37 | 38 | // callback when receiving UART chars when in programming mode 39 | extern void (*programmingCB)(char *buffer, short length); 40 | 41 | #endif /* __SER_BRIDGE_H__ */ 42 | -------------------------------------------------------------------------------- /esp-link-stuff/status.c: -------------------------------------------------------------------------------- 1 | // Copyright 2015 by Thorsten von Eicken, see LICENSE.txt 2 | 3 | #include 4 | #include "config.h" 5 | //#include "serled.h" 6 | #include "cgiwifi.h" 7 | 8 | #ifdef MQTT 9 | #include "mqtt.h" 10 | #include "mqtt_client.h" 11 | extern MQTT_Client mqttClient; 12 | 13 | //#define STATUS_LED_ACTIVE_LOW 14 | 15 | //===== MQTT Status update 16 | 17 | // Every minute... 18 | #define MQTT_STATUS_INTERVAL (60*1000) 19 | 20 | static ETSTimer mqttStatusTimer; 21 | 22 | int ICACHE_FLASH_ATTR 23 | mqttStatusMsg(char *buf) { 24 | sint8 rssi = wifi_station_get_rssi(); 25 | if (rssi > 0) rssi = 0; // not connected or other error 26 | //os_printf("timer rssi=%d\n", rssi); 27 | 28 | // compose MQTT message 29 | return os_sprintf(buf, 30 | "{\"rssi\":%d, \"heap_free\":%ld}", 31 | rssi, (unsigned long)system_get_free_heap_size()); 32 | } 33 | 34 | // Timer callback to send an RSSI update to a monitoring system 35 | static void ICACHE_FLASH_ATTR mqttStatusCb(void *v) { 36 | if (!flashConfig.mqtt_status_enable || os_strlen(flashConfig.mqtt_status_topic) == 0 || 37 | mqttClient.connState != MQTT_CONNECTED) 38 | return; 39 | 40 | char buf[128]; 41 | mqttStatusMsg(buf); 42 | MQTT_Publish(&mqttClient, flashConfig.mqtt_status_topic, buf, os_strlen(buf), 1, 0); 43 | } 44 | 45 | 46 | 47 | #endif // MQTT 48 | 49 | //===== "CONN" LED status indication 50 | 51 | enum { wifiIsDisconnected, wifiIsConnected, wifiGotIP }; 52 | uint8_t wifiState = wifiIsDisconnected; 53 | 54 | // in serbridge.c 55 | void makeGpio(uint8_t pin); 56 | 57 | static ETSTimer ledTimer; 58 | 59 | // Set the LED on or off, respecting the defined polarity 60 | static void ICACHE_FLASH_ATTR setLed(int on) { 61 | int8_t pin = flashConfig.conn_led_pin; 62 | if (pin < 0) return; // disabled 63 | #ifdef STATUS_LED_ACTIVE_LOW 64 | // LED is active-low 65 | if (on) { 66 | gpio_output_set(0, (1<event) { 183 | case EVENT_STAMODE_CONNECTED: 184 | statusWifiUpdate(wifiIsConnected); 185 | break; 186 | case EVENT_STAMODE_DISCONNECTED: 187 | statusWifiUpdate(wifiIsDisconnected); 188 | break; 189 | case EVENT_STAMODE_AUTHMODE_CHANGE: 190 | break; 191 | case EVENT_STAMODE_GOT_IP: 192 | statusWifiUpdate(wifiGotIP); 193 | break; 194 | case EVENT_SOFTAPMODE_STACONNECTED: 195 | break; 196 | case EVENT_SOFTAPMODE_STADISCONNECTED: 197 | break; 198 | default: 199 | break; 200 | } 201 | } 202 | 203 | //===== Init status stuff 204 | 205 | void ICACHE_FLASH_ATTR statusInit(void) { 206 | if (flashConfig.conn_led_pin >= 0) { 207 | makeGpio(flashConfig.conn_led_pin); 208 | setLed(1); 209 | } 210 | #ifdef STATUS_DBG 211 | os_printf("CONN led=%d\n", flashConfig.conn_led_pin); 212 | #endif 213 | 214 | os_timer_disarm(&ledTimer); 215 | os_timer_setfn(&ledTimer, ledTimerCb, NULL); 216 | os_timer_arm(&ledTimer, 2000, 0); 217 | 218 | wifi_set_event_handler_cb(wifiHandleEventCb); 219 | 220 | #ifdef MQTT 221 | os_timer_disarm(&mqttStatusTimer); 222 | os_timer_setfn(&mqttStatusTimer, mqttStatusCb, NULL); 223 | os_timer_arm(&mqttStatusTimer, MQTT_STATUS_INTERVAL, 1); // recurring timer 224 | #endif // MQTT 225 | } 226 | 227 | 228 | -------------------------------------------------------------------------------- /esp-link-stuff/status.h: -------------------------------------------------------------------------------- 1 | #ifndef STATUS_H 2 | #define STATUS_H 3 | 4 | int mqttStatusMsg(char *buf); 5 | void statusWifiUpdate(uint8_t state); 6 | void statusInit(void); 7 | 8 | #endif 9 | 10 | -------------------------------------------------------------------------------- /esp-link-stuff/task.c: -------------------------------------------------------------------------------- 1 | /* 2 | * task.c 3 | * 4 | * Copyright 2015 Susi's Strolch 5 | * 6 | * For license information see projects "License.txt" 7 | * 8 | * Not sure if it's save to use ICACHE_FLASH_ATTR, so we're running from RAM 9 | */ 10 | 11 | #undef USRTASK_DBG 12 | 13 | #include "esp8266.h" 14 | #include 15 | 16 | #define MAXUSRTASKS 8 17 | 18 | #ifdef USRTASK_DBG 19 | #define DBG_USRTASK(format, ...) os_printf(format, ## __VA_ARGS__) 20 | #else 21 | #define DBG_USRTASK(format, ...) do { } while(0) 22 | #endif 23 | 24 | LOCAL os_event_t *_task_queue = NULL; // system_os_task queue 25 | LOCAL os_task_t *usr_task_queue = NULL; // user task queue 26 | 27 | // it seems save to run the usr_event_handler from RAM, so no ICACHE_FLASH_ATTR here... 28 | 29 | LOCAL void usr_event_handler(os_event_t *e) 30 | { 31 | DBG_USRTASK("usr_event_handler: event %p (sig=%d, par=%p)\n", e, (int)e->sig, (void *)e->par); 32 | if (usr_task_queue[e->sig] == NULL || e->sig < 0 || e->sig >= MAXUSRTASKS) { 33 | os_printf("usr_event_handler: task %d %s\n", (int)e->sig, 34 | usr_task_queue[e->sig] == NULL ? "not registered" : "out of range"); 35 | return; 36 | } 37 | (usr_task_queue[e->sig])(e); 38 | } 39 | 40 | LOCAL void init_usr_task() { 41 | if (_task_queue == NULL) 42 | _task_queue = (os_event_t *)os_zalloc(sizeof(os_event_t) * _task_queueLen); 43 | 44 | if (usr_task_queue == NULL) 45 | usr_task_queue = (os_task_t *)os_zalloc(sizeof(os_task_t) * MAXUSRTASKS); 46 | 47 | system_os_task(usr_event_handler, _taskPrio, _task_queue, _task_queueLen); 48 | } 49 | 50 | // public functions 51 | bool post_usr_task(uint8_t task, os_param_t par) 52 | { 53 | return system_os_post(_taskPrio, task, par); 54 | } 55 | 56 | uint8_t register_usr_task (os_task_t event) 57 | { 58 | int task; 59 | 60 | DBG_USRTASK("register_usr_task: %p\n", event); 61 | if (_task_queue == NULL || usr_task_queue == NULL) 62 | init_usr_task(); 63 | 64 | for (task = 0; task < MAXUSRTASKS; task++) { 65 | if (usr_task_queue[task] == event) 66 | return task; // task already registered - bail out... 67 | } 68 | 69 | for (task = 0; task < MAXUSRTASKS; task++) { 70 | if (usr_task_queue[task] == NULL) { 71 | DBG_USRTASK("register_usr_task: assign task #%d\n", task); 72 | usr_task_queue[task] = event; 73 | break; 74 | } 75 | } 76 | return task; 77 | } 78 | 79 | -------------------------------------------------------------------------------- /esp-link-stuff/task.h: -------------------------------------------------------------------------------- 1 | /* 2 | * task.h 3 | * 4 | * Copyright 2015 Susi's Strolch 5 | * 6 | * For license information see projects "License.txt" 7 | * 8 | * 9 | */ 10 | 11 | #ifndef USRTASK_H 12 | #define USRTASK_H 13 | 14 | #define _taskPrio 1 15 | #define _task_queueLen 64 16 | 17 | uint8_t register_usr_task (os_task_t event); 18 | bool post_usr_task(uint8_t task, os_param_t par); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /esp-link-stuff/uart.h: -------------------------------------------------------------------------------- 1 | #ifndef __UART_H__ 2 | #define __UART_H__ 3 | 4 | #include "uart_hw.h" 5 | 6 | // Receive callback function signature 7 | typedef void (*UartRecv_cb)(char *buf, short len); 8 | 9 | // Initialize UARTs to the provided baud rates (115200 recommended). This also makes the os_printf 10 | // calls use uart1 for output (for debugging purposes) 11 | void uart_init(UartBaudRate uart0_br, UartBaudRate uart1_br); 12 | 13 | void uart_tx_buffer(uint8 uart, char *buf, uint16 len); 14 | STATUS uart_tx_one_char(uint8 uart, uint8 c); 15 | STATUS uart_try_tx_one_char(uint8 uart, uint8 c); 16 | STATUS uart_drain_tx_buffer(uint8 uart); 17 | 18 | // Add a receive callback function, this is called on the uart receive task each time a chunk 19 | // of bytes are received. A small number of callbacks can be added and they are all called 20 | // with all new characters. 21 | void uart_add_recv_cb(UartRecv_cb cb); 22 | 23 | // Turn UART interrupts off and poll for nchars or until timeout hits 24 | uint16_t uart0_rx_poll(char *buff, uint16_t nchars, uint32_t timeout_us); 25 | 26 | void uart0_config(int baudRate, int stopBits); 27 | void uart1_config(int baudRate, int stopBits); 28 | 29 | 30 | #endif /* __UART_H__ */ 31 | -------------------------------------------------------------------------------- /esphttpdconfig.mk: -------------------------------------------------------------------------------- 1 | # --------------- esphttpd config options --------------- 2 | 3 | # If GZIP_COMPRESSION is set to "yes" then the static css, js, and html files will be compressed with gzip before added to the espfs image 4 | # and will be served with gzip Content-Encoding header. 5 | # This could speed up the downloading of these files, but might break compatibility with older web browsers not supporting gzip encoding 6 | # because Accept-Encoding is simply ignored. Enable this option if you have large static files to serve (for e.g. JQuery, Twitter bootstrap) 7 | # By default only js, css and html files are compressed. 8 | # If you have text based static files with different extensions what you want to serve compressed then you will need to add the extension to the following places: 9 | # - Add the extension to this Makefile at the webpages.espfs target to the find command 10 | # - Add the extension to the gzippedFileTypes array in the user/httpd.c file 11 | # 12 | # Adding JPG or PNG files (and any other compressed formats) is not recommended, because GZIP compression does not works effectively on compressed files. 13 | 14 | #Static gzipping is disabled by default. 15 | GZIP_COMPRESSION ?= no 16 | 17 | # If COMPRESS_W_YUI is set to "yes" then the static css and js files will be compressed with yui-compressor 18 | # This option works only when GZIP_COMPRESSION is set to "yes" 19 | # http://yui.github.io/yuicompressor/ 20 | #Disabled by default. 21 | COMPRESS_W_YUI ?= no 22 | YUI-COMPRESSOR ?= /usr/bin/yui-compressor 23 | 24 | #If USE_HEATSHRINK is set to "yes" then the espfs files will be compressed with Heatshrink and decompressed 25 | #on the fly while reading the file. Because the decompression is done in the esp8266, it does not require 26 | #any support in the browser. 27 | USE_HEATSHRINK ?= yes 28 | 29 | -------------------------------------------------------------------------------- /esptool: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-ESP/f6e49a2c4132bdf364697d486b58d9062e72796b/esptool -------------------------------------------------------------------------------- /html/basic.min.css: -------------------------------------------------------------------------------- 1 | .dropzone,.dropzone *{box-sizing:border-box}.dropzone{position:relative}.dropzone .dz-preview{position:relative;display:inline-block;width:120px;margin:0.5em}.dropzone .dz-preview .dz-progress{display:block;height:15px;border:1px solid #aaa}.dropzone .dz-preview .dz-progress .dz-upload{display:block;height:100%;width:0;background:green}.dropzone .dz-preview .dz-error-message{color:red;display:none}.dropzone .dz-preview.dz-error .dz-error-message,.dropzone .dz-preview.dz-error .dz-error-mark{display:block}.dropzone .dz-preview.dz-success .dz-success-mark{display:block}.dropzone .dz-preview .dz-error-mark,.dropzone .dz-preview .dz-success-mark{position:absolute;display:none;left:30px;top:30px;width:54px;height:58px;left:50%;margin-left:-27px} 2 | -------------------------------------------------------------------------------- /html/console.js: -------------------------------------------------------------------------------- 1 | //===== Fetching console text 2 | 3 | function fetchText(delay, repeat) { 4 | var el = $("#console"); 5 | if (el.textEnd == undefined) { 6 | el.textEnd = 0; 7 | el.innerHTML = ""; 8 | } 9 | window.setTimeout(function() { 10 | ajaxJson('GET', console_url + "?start=" + el.textEnd, 11 | function(resp) { 12 | var dly = updateText(resp); 13 | if (repeat) fetchText(dly, repeat); 14 | }, 15 | function() { retryLoad(repeat); }); 16 | }, delay); 17 | } 18 | 19 | function updateText(resp) { 20 | var el = $("#console"); 21 | 22 | var delay = 3000; 23 | if (resp != null && resp.len > 0) { 24 | // console.log("updateText got", resp.len, "chars at", resp.start); 25 | var isScrolledToBottom = el.scrollHeight - el.clientHeight <= el.scrollTop + 1; 26 | //console.log("isScrolledToBottom="+isScrolledToBottom, "scrollHeight="+el.scrollHeight, 27 | // "clientHeight="+el.clientHeight, "scrollTop="+el.scrollTop, 28 | // "" + (el.scrollHeight - el.clientHeight) + "<=" + (el.scrollTop + 1)); 29 | 30 | // append the text 31 | if (resp.start > el.textEnd) { 32 | el.innerHTML = el.innerHTML.concat("\r\n/g, '>') 38 | .replace(/"/g, '"')); 39 | el.textEnd = resp.start + resp.len; 40 | delay = 500; 41 | 42 | // scroll to bottom 43 | if(isScrolledToBottom) el.scrollTop = el.scrollHeight - el.clientHeight; 44 | } 45 | return delay; 46 | } 47 | 48 | function retryLoad(repeat) { 49 | fetchText(1000, repeat); 50 | } 51 | 52 | //===== Text entry 53 | 54 | function consoleSendInit() { 55 | var sendHistory = $("#send-history"); 56 | var inputText = $("#input-text"); 57 | var inputAddCr = $("#input-add-cr"); 58 | var inputAddLf = $("#input-add-lf"); 59 | 60 | function findHistory(text) { 61 | for (var i = 0; i < sendHistory.children.length; i++) { 62 | if (text == sendHistory.children[i].value) { 63 | return i; 64 | } 65 | } 66 | return null; 67 | } 68 | 69 | function loadHistory(idx) { 70 | sendHistory.value = sendHistory.children[idx].value; 71 | inputText.value = sendHistory.children[idx].value; 72 | } 73 | 74 | function navHistory(rel) { 75 | var idx = findHistory(sendHistory.value) + rel; 76 | if (idx < 0) { 77 | idx = sendHistory.children.length - 1; 78 | } 79 | if (idx >= sendHistory.children.length) { 80 | idx = 0; 81 | } 82 | loadHistory(idx); 83 | } 84 | 85 | sendHistory.addEventListener("change", function(e) { 86 | inputText.value = sendHistory.value; 87 | }); 88 | 89 | function pushHistory(text) { 90 | var idx = findHistory(text); 91 | if (idx !== null) { 92 | loadHistory(idx); 93 | return false; 94 | } 95 | var newOption = m(''); 102 | newOption.value = text; 103 | sendHistory.appendChild(newOption); 104 | sendHistory.value = text; 105 | for (; sendHistory.children.length > 15; ) { 106 | sendHistory.removeChild(sendHistory.children[0]); 107 | } 108 | return true; 109 | } 110 | 111 | inputText.addEventListener("keydown", function(e) { 112 | switch (e.keyCode) { 113 | case 38: /* the up arrow key pressed */ 114 | e.preventDefault(); 115 | navHistory(-1); 116 | break; 117 | case 40: /* the down arrow key pressed */ 118 | e.preventDefault(); 119 | navHistory(+1); 120 | break; 121 | case 27: /* the escape key pressed */ 122 | e.preventDefault(); 123 | inputText.value = ""; 124 | sendHistory.value = ""; 125 | break; 126 | case 13: /* the enter key pressed */ 127 | e.preventDefault(); 128 | var text = inputText.value; 129 | if (inputAddCr.checked) text += '\r'; 130 | if (inputAddLf.checked) text += '\n'; 131 | pushHistory(inputText.value); 132 | inputText.value = ""; 133 | ajaxSpin('POST', "/console/send?text=" + encodeURIComponent(text), 134 | function(resp) { showNotification("Text sent"); }, 135 | function(s, st) { showWarning("Error sending text"); } 136 | ); 137 | break; 138 | } 139 | }); 140 | } 141 | 142 | //===== Log page 143 | 144 | function showDbgMode(mode) { 145 | var btns = $('.dbg-btn'); 146 | for (var i=0; i < btns.length; i++) { 147 | if (btns[i].id === "dbg-"+mode) 148 | addClass(btns[i], "button-selected"); 149 | else 150 | removeClass(btns[i], "button-selected"); 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /html/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-ESP/f6e49a2c4132bdf364697d486b58d9062e72796b/html/favicon.ico -------------------------------------------------------------------------------- /html/flash/140medley.min.js: -------------------------------------------------------------------------------- 1 | var t=function(a,b){return function(c,d){return a.replace(/#{([^}]*)}/g,function(a,f){return Function("x","with(x)return "+f).call(c,d||b||{})})}},s=function(a,b){return b?{get:function(c){return a[c]&&b.parse(a[c])},set:function(c,d){a[c]=b.stringify(d)}}:{}}(this.localStorage||{},JSON),p=function(a,b,c,d){c=c||document;d=c[b="on"+b];a=c[b]=function(e){d=d&&d(e=e||c.event);return(a=a&&b(e))?b:d};c=this},m=function(a,b,c){b=document;c=b.createElement("p");c.innerHTML=a;for(a=b.createDocumentFragment();b= 2 | c.firstChild;)a.appendChild(b);return a},$=function(a,b){a=a.match(/^(\W)?(.*)/);return(b||document)["getElement"+(a[1]?a[1]=="#"?"ById":"sByClassName":"sByTagName")](a[2])},j=function(a){for(a=0;a<4;a++)try{return a?new ActiveXObject([,"Msxml2","Msxml3","Microsoft"][a]+".XMLHTTP"):new XMLHttpRequest}catch(b){}}; 3 | -------------------------------------------------------------------------------- /html/flash/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Parallax Wi-Fi Module Configuration - Update Firmware 5 | 6 | 7 | 8 | 80 | 81 | 82 |
83 | 86 |
87 |
88 |
Please select an .ota file to load...
89 | 90 | 91 |
92 |
93 | 105 |
106 |
107 | 112 |
113 | 114 | -------------------------------------------------------------------------------- /html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Parallax Wi-Fi Module Configuration 4 | 5 | 6 | 33 | 34 | 35 |
36 | 39 |
40 |
41 |

Module Name:

42 |

Version:

43 |
44 | 55 |
56 |

Based on ESP-HTTPD by Jeroen Domburg and ESP-LINK by Thorsten von Eicken

57 | 62 |
63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /html/log.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Parallax Wi-Fi Module Configuration - Debug Log 5 | 6 | 7 | 8 | 9 |
10 | 13 |
14 |
15 |

Shows the most recent characters printed by the WX firmware.

16 |
17 |

18 | 19 |

20 |
21 |

22 |     
23 | 35 |
36 |
37 | 42 |
43 | 44 | 45 | 46 | 47 | 78 | 79 | -------------------------------------------------------------------------------- /html/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-ESP/f6e49a2c4132bdf364697d486b58d9062e72796b/html/logo.png -------------------------------------------------------------------------------- /html/newpage.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Page Title 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 15 |
16 |
17 | 18 | 19 |
20 | 31 |
32 | 33 |
34 | 40 |
41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /html/p2-ddloader.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Parallax P2 Loader - Upload P2 binary code file 6 | 7 | 8 | 9 | 64 | 65 | 66 | 67 |
68 | 71 | 72 |
73 |
74 |

Upload binary code files to the Propeller P2.

75 |

Tip: If using Parallax WiFi module and the P2 WX Adapter, must set Reset Pin to CTS on the Settings Page!

76 |

Tip: To program the P2, ensure the P2 dipswitch no.4 (down-arrow) is OFF!

77 |
78 | 79 |
80 |
81 | 82 | 83 |
84 | 85 |
86 | 87 |

88 |

P2 Programming Progress

89 |

90 | 0% complete 91 |

 

92 |

93 |
94 | 95 |
96 | 108 |
109 |
110 | 115 |
116 | 117 | 205 | 206 | 207 | -------------------------------------------------------------------------------- /html/style.css: -------------------------------------------------------------------------------- 1 | /** HTML and Body Normalizing, excluding IE and non-modern browsers **/ 2 | html{ 3 | /* Declaration for all normalized fonts on the page */ 4 | font-family:Calibri,Arial,Helvetica,Tahoma,Segoe,"Segoe UI",Verdana,sans-serif; 5 | /* 14px base font size. 16px x .875 = 14px */ 6 | font-size: 100%; /* 16px */ 7 | line-height: 1.3em; 8 | } 9 | * { 10 | box-sizing: border-box; 11 | } 12 | button, 13 | input, 14 | select, 15 | textarea, 16 | progress { 17 | font-family: Calibri, Arial, Helvetica, Tahoma, Segoe, "Segoe UI", Verdana, sans-serif; 18 | } 19 | body { 20 | margin: 0; 21 | padding: 0; 22 | } 23 | body, h1, h2, h3, h4, h5, h6, h1 img, h2 img, h3 img, h4 img, h5 img, h6 img, em, dfn, del, ins, a, tbody, tfoot, thead, tr, li, label, legend, figure, figcaption { 24 | margin: 0; 25 | padding: 0; 26 | } 27 | h1, h2, h3, h4, h5, h6 { 28 | margin-bottom: 0.5em; 29 | } 30 | h1 { 31 | font-size: 1.8em; 32 | } 33 | h2 { 34 | font-size: 1.416em; 35 | } 36 | h3 { 37 | font-size: 1.25em; 38 | } 39 | h4, h5, h6 { 40 | font-size: 1em; 41 | } 42 | img { 43 | border: 0 none; 44 | height: auto; 45 | max-width: 100%; 46 | width: auto; 47 | } 48 | a:link, 49 | a:visited { 50 | color: #4c7897; 51 | } 52 | a:hover, 53 | a:focus { 54 | color: #3694D6; 55 | text-decoration: underline; 56 | } 57 | .clearfix::after { 58 | clear: both; 59 | content: "."; 60 | display: block; 61 | height: 0; 62 | visibility: hidden; 63 | } 64 | 65 | /** Main Content Block Styling **/ 66 | /* Static */ 67 | body { 68 | background-color: #001E42; 69 | } 70 | .title { 71 | text-align: center; 72 | } 73 | #header { 74 | height: 3em; 75 | /* Some lengths of header titles overflow into content due to static height */ 76 | overflow: hidden; 77 | } 78 | #main { 79 | background-color: #EEEEEE; 80 | } 81 | #page { 82 | margin-left: auto; 83 | margin-right: auto; 84 | max-width: 900px; 85 | } 86 | #content > *:first-child { 87 | margin-top: 0.5em; 88 | } 89 | #content > * { 90 | padding-left: 0.5em; 91 | padding-right: 0.5em; 92 | } 93 | #ack { 94 | width: 100%; 95 | } 96 | /* Responsive Handling */ 97 | @media all and (min-width: 481px) { 98 | #content { 99 | float: left; 100 | margin-left: 15%; 101 | margin-right: -100%; 102 | width: 85%; 103 | } 104 | #navigation { 105 | float: left; 106 | margin-left: 0; 107 | margin-right: -15%; 108 | width: 15%; 109 | margin-bottom: 0.5em 110 | } 111 | #footer { 112 | background: #001E42; 113 | text-align: right; 114 | padding: 10px 0px 0px 0px; 115 | margin: 0 auto; 116 | } 117 | } 118 | @media (max-width: 480px) { 119 | #content { 120 | float: left; 121 | width: 100%; 122 | } 123 | #navigation { 124 | float: left; 125 | width: 100%; 126 | } 127 | #footer { 128 | background: #001E42; 129 | text-align: right; 130 | padding: 10px 0px 0px 0px; 131 | margin: 0 auto; 132 | } 133 | } 134 | 135 | /** Navigational Styling **/ 136 | /* Static */ 137 | nav [type="checkbox"], 138 | nav label { 139 | display: none; 140 | } 141 | #navigation ul { 142 | margin: 0; 143 | padding: 0; 144 | } 145 | #navigation li { 146 | list-style: outside none none; 147 | } 148 | nav li a:link, 149 | nav li a:visited { 150 | color: #000; 151 | background:#95afc0; 152 | text-decoration: none; 153 | } 154 | nav li a:hover, 155 | nav li a:focus { 156 | background: #4c7897; 157 | } 158 | /* Responsive Handling */ 159 | @media all and (min-width: 481px) { 160 | nav li a { 161 | display: block; 162 | line-height: 2em; 163 | text-decoration: none; 164 | border: 1px solid #777; 165 | margin: 0.5em 2px 0px; 166 | border-radius: 5px; 167 | font-weight: bold; 168 | width: 100%; 169 | padding: 0px 5px; 170 | } 171 | } 172 | @media (max-width: 480px) { 173 | nav ul { 174 | display: none; 175 | position: absolute; 176 | top: 3em; 177 | right: 0; 178 | background: #001E42; 179 | width: 100%; 180 | box-shadow: 0 3px 20px #000; 181 | } 182 | nav label { 183 | display: block; 184 | background: #001E42; 185 | width: 2.7em; 186 | height: 3em; 187 | cursor: pointer; 188 | position: absolute; 189 | left: 0.5em; 190 | top: 0px; 191 | } 192 | nav label:after{ 193 | content:''; 194 | display: block; 195 | width: 2em; 196 | height: 5px; 197 | background: #95afc0; 198 | margin: 7px 5px; 199 | box-shadow: 0px 10px 0px #95afc0, 0px 20px 0px #95afc0; 200 | } 201 | nav [type="checkbox"]:checked ~ ul { 202 | display: block; 203 | z-index: 9999; 204 | position: absolute; 205 | } 206 | nav li a { 207 | display: inline-block; 208 | width: 50%; 209 | min-width: 100px; 210 | margin: 0.3em; 211 | padding: 0.2em; 212 | font-weight: bold; 213 | border-radius: 5px; 214 | text-align: left; 215 | } 216 | } 217 | 218 | /** Content and Page styles **/ 219 | /* Static */ 220 | #header h1 { 221 | background: radial-gradient(black 15%, transparent 16%) 0 0, radial-gradient(black 15%, transparent 16%) 8px 8px, radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 0 1px, radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 8px 9px; 222 | background-color:#282828; 223 | background-size:16px 16px; 224 | line-height: 1.64em; 225 | color:#fff; 226 | padding-left: 2.5em; 227 | margin: 0; 228 | } 229 | #settings td { 230 | text-align: left; 231 | height: 35px; 232 | overflow: hidden; 233 | } 234 | progress { 235 | padding: 0; 236 | border: 1px solid #000; 237 | height: 20px; 238 | width: 200px; 239 | background-color: #DDD; 240 | box-shadow: 0 2px 5px rgba(0, 0, 0, 0.10) inset; 241 | border-radius: 5px; 242 | } 243 | progress[value]::-webkit-progress-value { 244 | background-image: 245 | -webkit-linear-gradient(-45deg, transparent 33%, rgba(0, 0, 0, .1) 33%, rgba(0,0, 0, .1) 66%, transparent 66%), -webkit-linear-gradient(left, #001E42, #E9FE04); 246 | border-radius: 5px; 247 | background-size: 35px 20px, 100% 100%, 100% 100%; 248 | } 249 | progress[value]::-moz-progress-bar { 250 | background-image: 251 | -moz-linear-gradient(135deg, transparent 33%, rgba(0, 0, 0, 0.1) 33%, rgba(0, 0, 0, 0.1) 66%, transparent 66%), 252 | -moz-linear-gradient(left, #001E42, #E9FE04); 253 | border-radius: 5px; 254 | background-size: 35px 20px, 100% 100%, 100% 100%; 255 | } 256 | #ack > p { 257 | display: block; 258 | background: #4c7897; 259 | margin: 0px; 260 | font-style: italic; 261 | color: #DDD; 262 | } 263 | /* Responsive Handling */ 264 | @media all and (min-width: 481px) { 265 | #ack > p { 266 | padding: 0.5em 15%; 267 | } 268 | } 269 | @media (max-width: 480px) { 270 | #ack > p { 271 | padding: 0.5em; 272 | } 273 | } 274 | 275 | .nodisplay { display: none !important; } 276 | 277 | -------------------------------------------------------------------------------- /html/update-ffs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Parallax Wi-Fi Module Configuration - Update Flash Filesystem 5 | 6 | 7 | 8 | 9 |
10 | 13 |
14 |
15 |

Here, you can upload files for the ESP8266 micro web server. For example, if your 16 | ESP module's IP address is 192.168.4.1 and your file is mypage.html, use this page to 17 | upload the file. To view the page, just send your web browser to 18 | http://192.168.4.1/files/mypage.html.

19 |
20 |

21 | 22 |

23 |

Empty the Filesystem

24 |

25 | 26 |

27 |

Progress

28 |

29 | 0% complete 30 |

 

31 |

32 |
33 |
34 | 46 |
47 |
48 | 53 |
54 | 55 | 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /html/websocket/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | WebSocket Test 5 | 6 | 7 | 8 | 9 | 68 | 69 | 70 |
71 | 74 |
75 |
76 |
77 |
78 | 88 |
89 |
90 | 95 |
96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /html/wifi/140medley.min.js: -------------------------------------------------------------------------------- 1 | var t=function(a,b){return function(c,d){return a.replace(/#{([^}]*)}/g,function(a,f){return Function("x","with(x)return "+f).call(c,d||b||{})})}},s=function(a,b){return b?{get:function(c){return a[c]&&b.parse(a[c])},set:function(c,d){a[c]=b.stringify(d)}}:{}}(this.localStorage||{},JSON),p=function(a,b,c,d){c=c||document;d=c[b="on"+b];a=c[b]=function(e){d=d&&d(e=e||c.event);return(a=a&&b(e))?b:d};c=this},m=function(a,b,c){b=document;c=b.createElement("p");c.innerHTML=a;for(a=b.createDocumentFragment();b= 2 | c.firstChild;)a.appendChild(b);return a},$=function(a,b){a=a.match(/^(\W)?(.*)/);return(b||document)["getElement"+(a[1]?a[1]=="#"?"ById":"sByClassName":"sByTagName")](a[2])},j=function(a){for(a=0;a<4;a++)try{return a?new ActiveXObject([,"Msxml2","Msxml3","Microsoft"][a]+".XMLHTTP"):new XMLHttpRequest}catch(b){}}; 3 | -------------------------------------------------------------------------------- /html/wifi/connecting.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Connecting... 5 | 6 | 7 | 8 | 38 | 39 | 40 |
41 | 44 |
45 |
46 |

Connecting to AP...

47 |

Status:
48 |

...
49 |

50 |
51 | 61 |
62 |
63 | 68 |
69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /html/wifi/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-ESP/f6e49a2c4132bdf364697d486b58d9062e72796b/html/wifi/icons.png -------------------------------------------------------------------------------- /html/wifi/style.css: -------------------------------------------------------------------------------- 1 | @import url("../style.css"); 2 | 3 | .icon { 4 | background-image: url("icons.png"); 5 | background-color: transparent; 6 | width: 32px; 7 | height: 32px; 8 | display: inline-block; 9 | } -------------------------------------------------------------------------------- /include/uart_hw.h: -------------------------------------------------------------------------------- 1 | //Generated at 2012-07-03 18:44:06 2 | /* 3 | * Copyright (c) 2010 - 2011 Espressif System 4 | * 5 | */ 6 | 7 | #ifndef UART_REGISTER_H_INCLUDED 8 | #define UART_REGISTER_H_INCLUDED 9 | #define REG_UART_BASE( i ) (0x60000000+(i)*0xf00) 10 | //version value:32'h062000 11 | 12 | #define UART_FIFO( i ) (REG_UART_BASE( i ) + 0x0) 13 | #define UART_RXFIFO_RD_BYTE 0x000000FF 14 | #define UART_RXFIFO_RD_BYTE_S 0 15 | 16 | #define UART_INT_RAW( i ) (REG_UART_BASE( i ) + 0x4) 17 | #define UART_RXFIFO_TOUT_INT_RAW (BIT(8)) 18 | #define UART_BRK_DET_INT_RAW (BIT(7)) 19 | #define UART_CTS_CHG_INT_RAW (BIT(6)) 20 | #define UART_DSR_CHG_INT_RAW (BIT(5)) 21 | #define UART_RXFIFO_OVF_INT_RAW (BIT(4)) 22 | #define UART_FRM_ERR_INT_RAW (BIT(3)) 23 | #define UART_PARITY_ERR_INT_RAW (BIT(2)) 24 | #define UART_TXFIFO_EMPTY_INT_RAW (BIT(1)) 25 | #define UART_RXFIFO_FULL_INT_RAW (BIT(0)) 26 | 27 | #define UART_INT_ST( i ) (REG_UART_BASE( i ) + 0x8) 28 | #define UART_RXFIFO_TOUT_INT_ST (BIT(8)) 29 | #define UART_BRK_DET_INT_ST (BIT(7)) 30 | #define UART_CTS_CHG_INT_ST (BIT(6)) 31 | #define UART_DSR_CHG_INT_ST (BIT(5)) 32 | #define UART_RXFIFO_OVF_INT_ST (BIT(4)) 33 | #define UART_FRM_ERR_INT_ST (BIT(3)) 34 | #define UART_PARITY_ERR_INT_ST (BIT(2)) 35 | #define UART_TXFIFO_EMPTY_INT_ST (BIT(1)) 36 | #define UART_RXFIFO_FULL_INT_ST (BIT(0)) 37 | 38 | #define UART_INT_ENA( i ) (REG_UART_BASE( i ) + 0xC) 39 | #define UART_RXFIFO_TOUT_INT_ENA (BIT(8)) 40 | #define UART_BRK_DET_INT_ENA (BIT(7)) 41 | #define UART_CTS_CHG_INT_ENA (BIT(6)) 42 | #define UART_DSR_CHG_INT_ENA (BIT(5)) 43 | #define UART_RXFIFO_OVF_INT_ENA (BIT(4)) 44 | #define UART_FRM_ERR_INT_ENA (BIT(3)) 45 | #define UART_PARITY_ERR_INT_ENA (BIT(2)) 46 | #define UART_TXFIFO_EMPTY_INT_ENA (BIT(1)) 47 | #define UART_RXFIFO_FULL_INT_ENA (BIT(0)) 48 | 49 | #define UART_INT_CLR( i ) (REG_UART_BASE( i ) + 0x10) 50 | #define UART_RXFIFO_TOUT_INT_CLR (BIT(8)) 51 | #define UART_BRK_DET_INT_CLR (BIT(7)) 52 | #define UART_CTS_CHG_INT_CLR (BIT(6)) 53 | #define UART_DSR_CHG_INT_CLR (BIT(5)) 54 | #define UART_RXFIFO_OVF_INT_CLR (BIT(4)) 55 | #define UART_FRM_ERR_INT_CLR (BIT(3)) 56 | #define UART_PARITY_ERR_INT_CLR (BIT(2)) 57 | #define UART_TXFIFO_EMPTY_INT_CLR (BIT(1)) 58 | #define UART_RXFIFO_FULL_INT_CLR (BIT(0)) 59 | 60 | #define UART_CLKDIV( i ) (REG_UART_BASE( i ) + 0x14) 61 | #define UART_CLKDIV_CNT 0x000FFFFF 62 | #define UART_CLKDIV_S 0 63 | 64 | #define UART_AUTOBAUD( i ) (REG_UART_BASE( i ) + 0x18) 65 | #define UART_GLITCH_FILT 0x000000FF 66 | #define UART_GLITCH_FILT_S 8 67 | #define UART_AUTOBAUD_EN (BIT(0)) 68 | 69 | #define UART_STATUS( i ) (REG_UART_BASE( i ) + 0x1C) 70 | #define UART_TXD (BIT(31)) 71 | #define UART_RTSN (BIT(30)) 72 | #define UART_DTRN (BIT(29)) 73 | #define UART_TXFIFO_CNT 0x000000FF 74 | #define UART_TXFIFO_CNT_S 16 75 | #define UART_RXD (BIT(15)) 76 | #define UART_CTSN (BIT(14)) 77 | #define UART_DSRN (BIT(13)) 78 | #define UART_RXFIFO_CNT 0x000000FF 79 | #define UART_RXFIFO_CNT_S 0 80 | 81 | #define UART_CONF0( i ) (REG_UART_BASE( i ) + 0x20) 82 | #define UART_TXFIFO_RST (BIT(18)) 83 | #define UART_RXFIFO_RST (BIT(17)) 84 | #define UART_IRDA_EN (BIT(16)) 85 | #define UART_TX_FLOW_EN (BIT(15)) 86 | #define UART_LOOPBACK (BIT(14)) 87 | #define UART_IRDA_RX_INV (BIT(13)) 88 | #define UART_IRDA_TX_INV (BIT(12)) 89 | #define UART_IRDA_WCTL (BIT(11)) 90 | #define UART_IRDA_TX_EN (BIT(10)) 91 | #define UART_IRDA_DPLX (BIT(9)) 92 | #define UART_TXD_BRK (BIT(8)) 93 | #define UART_SW_DTR (BIT(7)) 94 | #define UART_SW_RTS (BIT(6)) 95 | #define UART_STOP_BIT_NUM 0x00000003 96 | #define UART_STOP_BIT_NUM_S 4 97 | #define UART_BIT_NUM 0x00000003 98 | #define UART_BIT_NUM_S 2 99 | #define UART_PARITY_EN (BIT(1)) 100 | #define UART_PARITY (BIT(0)) 101 | 102 | #define UART_CONF1( i ) (REG_UART_BASE( i ) + 0x24) 103 | #define UART_RX_TOUT_EN (BIT(31)) 104 | #define UART_RX_TOUT_THRHD 0x0000007F 105 | #define UART_RX_TOUT_THRHD_S 24 106 | #define UART_RX_FLOW_EN (BIT(23)) 107 | #define UART_RX_FLOW_THRHD 0x0000007F 108 | #define UART_RX_FLOW_THRHD_S 16 109 | #define UART_TXFIFO_EMPTY_THRHD 0x0000007F 110 | #define UART_TXFIFO_EMPTY_THRHD_S 8 111 | #define UART_RXFIFO_FULL_THRHD 0x0000007F 112 | #define UART_RXFIFO_FULL_THRHD_S 0 113 | 114 | #define UART_LOWPULSE( i ) (REG_UART_BASE( i ) + 0x28) 115 | #define UART_LOWPULSE_MIN_CNT 0x000FFFFF 116 | #define UART_LOWPULSE_MIN_CNT_S 0 117 | 118 | #define UART_HIGHPULSE( i ) (REG_UART_BASE( i ) + 0x2C) 119 | #define UART_HIGHPULSE_MIN_CNT 0x000FFFFF 120 | #define UART_HIGHPULSE_MIN_CNT_S 0 121 | 122 | #define UART_PULSE_NUM( i ) (REG_UART_BASE( i ) + 0x30) 123 | #define UART_PULSE_NUM_CNT 0x0003FF 124 | #define UART_PULSE_NUM_CNT_S 0 125 | 126 | #define UART_DATE( i ) (REG_UART_BASE( i ) + 0x78) 127 | #define UART_ID( i ) (REG_UART_BASE( i ) + 0x7C) 128 | #endif // UART_REGISTER_H_INCLUDED 129 | 130 | #define RX_BUFF_SIZE 256 131 | #define TX_BUFF_SIZE 100 132 | #define UART0 0 133 | #define UART1 1 134 | 135 | typedef enum { 136 | FIVE_BITS = 0x0, 137 | SIX_BITS = 0x1, 138 | SEVEN_BITS = 0x2, 139 | EIGHT_BITS = 0x3 140 | } UartBitsNum4Char; 141 | 142 | typedef enum { 143 | ONE_STOP_BIT = 0, 144 | ONE_HALF_STOP_BIT = BIT2, 145 | TWO_STOP_BIT = BIT2 146 | } UartStopBitsNum; 147 | 148 | typedef enum { 149 | NONE_BITS = 0, 150 | ODD_BITS = 0, 151 | EVEN_BITS = BIT4 152 | } UartParityMode; 153 | 154 | typedef enum { 155 | STICK_PARITY_DIS = 0, 156 | STICK_PARITY_EN = BIT3 | BIT5 157 | } UartExistParity; 158 | 159 | typedef enum { 160 | BIT_RATE_9600 = 9600, 161 | BIT_RATE_19200 = 19200, 162 | BIT_RATE_38400 = 38400, 163 | BIT_RATE_57600 = 57600, 164 | BIT_RATE_74880 = 74880, 165 | BIT_RATE_115200 = 115200, 166 | BIT_RATE_230400 = 230400, 167 | BIT_RATE_460800 = 460800, 168 | BIT_RATE_921600 = 921600 169 | } UartBautRate; 170 | 171 | typedef enum { 172 | NONE_CTRL, 173 | HARDWARE_CTRL, 174 | XON_XOFF_CTRL 175 | } UartFlowCtrl; 176 | 177 | typedef enum { 178 | EMPTY, 179 | UNDER_WRITE, 180 | WRITE_OVER 181 | } RcvMsgBuffState; 182 | 183 | typedef struct { 184 | uint32 TrxBuffSize; 185 | uint8 *pTrxBuff; 186 | } TrxMsgBuff; 187 | 188 | typedef enum { 189 | BAUD_RATE_DET, 190 | WAIT_SYNC_FRM, 191 | SRCH_MSG_HEAD, 192 | RCV_MSG_BODY, 193 | RCV_ESC_CHAR, 194 | } RcvMsgState; 195 | 196 | -------------------------------------------------------------------------------- /include/user_config.h: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /ldscript_memspecific.ld: -------------------------------------------------------------------------------- 1 | MEMORY { irom0_0_seg : org = 0x40240000, len = 0xFFFFFFFFFFFFC000 } 2 | -------------------------------------------------------------------------------- /libesphttpd/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-ESP/f6e49a2c4132bdf364697d486b58d9062e72796b/libesphttpd/.keep -------------------------------------------------------------------------------- /libesphttpd/core/auth.c: -------------------------------------------------------------------------------- 1 | /* 2 | HTTP auth implementation. Only does basic authentication for now. 3 | */ 4 | 5 | /* 6 | * ---------------------------------------------------------------------------- 7 | * "THE BEER-WARE LICENSE" (Revision 42): 8 | * Jeroen Domburg wrote this file. As long as you retain 9 | * this notice you can do whatever you want with this stuff. If we meet some day, 10 | * and you think this stuff is worth it, you can buy me a beer in return. 11 | * ---------------------------------------------------------------------------- 12 | */ 13 | 14 | 15 | #include 16 | #include "auth.h" 17 | #include "base64.h" 18 | 19 | int ICACHE_FLASH_ATTR authBasic(HttpdConnData *connData) { 20 | const char *forbidden="401 Forbidden."; 21 | int no=0; 22 | int r; 23 | char hdr[(AUTH_MAX_USER_LEN+AUTH_MAX_PASS_LEN+2)*10]; 24 | char userpass[AUTH_MAX_USER_LEN+AUTH_MAX_PASS_LEN+2]; 25 | char user[AUTH_MAX_USER_LEN]; 26 | char pass[AUTH_MAX_PASS_LEN]; 27 | if (connData->conn==NULL) { 28 | //Connection aborted. Clean up. 29 | return HTTPD_CGI_DONE; 30 | } 31 | 32 | r=httpdGetHeader(connData, "Authorization", hdr, sizeof(hdr)); 33 | if (r && strncmp(hdr, "Basic", 5)==0) { 34 | r=base64_decode(strlen(hdr)-6, hdr+6, sizeof(userpass), (unsigned char *)userpass); 35 | if (r<0) r=0; //just clean out string on decode error 36 | userpass[r]=0; //zero-terminate user:pass string 37 | // printf("Auth: %s\n", userpass); 38 | while (((AuthGetUserPw)(connData->cgiArg))(connData, no, 39 | user, AUTH_MAX_USER_LEN, pass, AUTH_MAX_PASS_LEN)) { 40 | //Check user/pass against auth header 41 | if (strlen(userpass)==strlen(user)+strlen(pass)+1 && 42 | strncmp(userpass, user, strlen(user))==0 && 43 | userpass[strlen(user)]==':' && 44 | strcmp(userpass+strlen(user)+1, pass)==0) { 45 | //Authenticated. Yay! 46 | return HTTPD_CGI_AUTHENTICATED; 47 | } 48 | no++; //Not authenticated with this user/pass. Check next user/pass combo. 49 | } 50 | } 51 | 52 | //Not authenticated. Go bug user with login screen. 53 | httpdStartResponse(connData, 401); 54 | httpdHeader(connData, "Content-Type", "text/plain"); 55 | httpdHeader(connData, "WWW-Authenticate", "Basic realm=\""HTTP_AUTH_REALM"\""); 56 | httpdEndHeaders(connData); 57 | httpdSend(connData, forbidden, -1); 58 | //Okay, all done. 59 | return HTTPD_CGI_DONE; 60 | } 61 | 62 | -------------------------------------------------------------------------------- /libesphttpd/core/base64.c: -------------------------------------------------------------------------------- 1 | /* base64.c : base-64 / MIME encode/decode */ 2 | /* PUBLIC DOMAIN - Jon Mayo - November 13, 2003 */ 3 | #include 4 | #include "base64.h" 5 | 6 | static const int base64dec_tab[256] ICACHE_RODATA_ATTR={ 7 | 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 8 | 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 9 | 255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63, 10 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255, 11 | 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 12 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255, 13 | 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 14 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255, 15 | 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 16 | 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 17 | 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 18 | 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 19 | 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 20 | 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 21 | 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 22 | 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 23 | }; 24 | 25 | #if 0 26 | static int ICACHE_FLASH_ATTR base64decode(const char in[4], char out[3]) { 27 | uint8_t v[4]; 28 | 29 | v[0]=base64dec_tab[(unsigned)in[0]]; 30 | v[1]=base64dec_tab[(unsigned)in[1]]; 31 | v[2]=base64dec_tab[(unsigned)in[2]]; 32 | v[3]=base64dec_tab[(unsigned)in[3]]; 33 | 34 | out[0]=(v[0]<<2)|(v[1]>>4); 35 | out[1]=(v[1]<<4)|(v[2]>>2); 36 | out[2]=(v[2]<<6)|(v[3]); 37 | return (v[0]|v[1]|v[2]|v[3])!=255 ? in[3]=='=' ? in[2]=='=' ? 1 : 2 : 3 : 0; 38 | } 39 | #endif 40 | 41 | /* decode a base64 string in one shot */ 42 | int ICACHE_FLASH_ATTR base64_decode(size_t in_len, const char *in, size_t out_len, unsigned char *out) { 43 | unsigned int ii, io; 44 | uint32_t v; 45 | unsigned int rem; 46 | 47 | for(io=0,ii=0,v=0,rem=0;ii=8) { 56 | rem-=8; 57 | if(io>=out_len) return -1; /* truncation is failure */ 58 | out[io++]=(v>>rem)&255; 59 | } 60 | } 61 | if(rem>=8) { 62 | rem-=8; 63 | if(io>=out_len) return -1; /* truncation is failure */ 64 | out[io++]=(v>>rem)&255; 65 | } 66 | return io; 67 | } 68 | 69 | static const uint8_t base64enc_tab[64]= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 70 | 71 | #if 0 72 | void base64encode(const unsigned char in[3], unsigned char out[4], int count) { 73 | out[0]=base64enc_tab[(in[0]>>2)]; 74 | out[1]=base64enc_tab[((in[0]&3)<<4)|(in[1]>>4)]; 75 | out[2]=count<2 ? '=' : base64enc_tab[((in[1]&15)<<2)|(in[2]>>6)]; 76 | out[3]=count<3 ? '=' : base64enc_tab[(in[2]&63)]; 77 | } 78 | #endif 79 | 80 | int ICACHE_FLASH_ATTR base64_encode(size_t in_len, const unsigned char *in, size_t out_len, char *out) { 81 | unsigned ii, io; 82 | uint32_t v; 83 | unsigned rem; 84 | 85 | for(io=0,ii=0,v=0,rem=0;ii=6) { 91 | rem-=6; 92 | if(io>=out_len) return -1; /* truncation is failure */ 93 | out[io++]=base64enc_tab[(v>>rem)&63]; 94 | } 95 | } 96 | if(rem) { 97 | v<<=(6-rem); 98 | if(io>=out_len) return -1; /* truncation is failure */ 99 | out[io++]=base64enc_tab[v&63]; 100 | } 101 | while(io&3) { 102 | if(io>=out_len) return -1; /* truncation is failure */ 103 | out[io++]='='; 104 | } 105 | if(io>=out_len) return -1; /* no room for null terminator */ 106 | out[io]=0; 107 | return io; 108 | } 109 | 110 | -------------------------------------------------------------------------------- /libesphttpd/core/base64.h: -------------------------------------------------------------------------------- 1 | #ifndef BASE64_H 2 | #define BASE64_H 3 | 4 | int base64_decode(size_t in_len, const char *in, size_t out_len, unsigned char *out); 5 | int base64_encode(size_t in_len, const unsigned char *in, size_t out_len, char *out); 6 | #endif -------------------------------------------------------------------------------- /libesphttpd/core/httpd-nonos.c: -------------------------------------------------------------------------------- 1 | /* 2 | ESP8266 web server - platform-dependent routines, nonos version 3 | */ 4 | 5 | #include 6 | #include "httpd.h" 7 | #include "platform.h" 8 | #include "httpd-platform.h" 9 | 10 | #ifndef FREERTOS 11 | 12 | //Listening connection data 13 | static struct espconn httpdConn; 14 | static esp_tcp httpdTcp; 15 | 16 | 17 | static void ICACHE_FLASH_ATTR platReconCb(void *arg, sint8 err) { 18 | ConnTypePtr conn=arg; 19 | httpdReconCb(conn, (char*)conn->proto.tcp->remote_ip, conn->proto.tcp->remote_port, err); 20 | } 21 | 22 | static void ICACHE_FLASH_ATTR platDisconCb(void *arg) { 23 | ConnTypePtr conn=arg; 24 | httpdDisconCb(conn, (char*)conn->proto.tcp->remote_ip, conn->proto.tcp->remote_port); 25 | } 26 | 27 | static void ICACHE_FLASH_ATTR platRecvCb(void *arg, char *data, unsigned short len) { 28 | ConnTypePtr conn=arg; 29 | httpdRecvCb(conn, (char*)conn->proto.tcp->remote_ip, conn->proto.tcp->remote_port, data, len); 30 | } 31 | 32 | static void ICACHE_FLASH_ATTR platSentCb(void *arg) { 33 | ConnTypePtr conn=arg; 34 | httpdSentCb(conn, (char*)conn->proto.tcp->remote_ip, conn->proto.tcp->remote_port); 35 | } 36 | 37 | static void ICACHE_FLASH_ATTR platConnCb(void *arg) { 38 | ConnTypePtr conn=arg; 39 | if (httpdConnectCb(conn, (char*)conn->proto.tcp->remote_ip, conn->proto.tcp->remote_port)) { 40 | espconn_regist_recvcb(conn, platRecvCb); 41 | espconn_regist_reconcb(conn, platReconCb); 42 | espconn_regist_disconcb(conn, platDisconCb); 43 | espconn_regist_sentcb(conn, platSentCb); 44 | } else { 45 | espconn_disconnect(conn); 46 | } 47 | } 48 | 49 | 50 | int ICACHE_FLASH_ATTR httpdPlatSendData(ConnTypePtr conn, const char *buff, int len) { 51 | int r; 52 | r=espconn_sent(conn, (uint8_t*)buff, len); 53 | return (r>=0); 54 | } 55 | 56 | void ICACHE_FLASH_ATTR httpdPlatDisconnect(ConnTypePtr conn) { 57 | espconn_disconnect(conn); 58 | } 59 | 60 | void ICACHE_FLASH_ATTR httpdPlatDisableTimeout(ConnTypePtr conn) { 61 | //Can't disable timeout; set to 2 hours instead. 62 | espconn_regist_time(conn, 7199, 1); 63 | } 64 | 65 | //Initialize listening socket, do general initialization 66 | void ICACHE_FLASH_ATTR httpdPlatInit(int port, int maxConnCt) { 67 | httpdConn.type=ESPCONN_TCP; 68 | httpdConn.state=ESPCONN_NONE; 69 | httpdTcp.local_port=port; 70 | httpdConn.proto.tcp=&httpdTcp; 71 | espconn_regist_connectcb(&httpdConn, platConnCb); 72 | espconn_accept(&httpdConn); 73 | espconn_tcp_set_max_con_allow(&httpdConn, maxConnCt); 74 | } 75 | 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /libesphttpd/core/httpd-platform.h: -------------------------------------------------------------------------------- 1 | #ifndef HTTPD_PLATFORM_H 2 | #define HTTPD_PLATFORM_H 3 | 4 | int httpdPlatSendData(ConnTypePtr conn, const char *buff, int len); 5 | void httpdPlatDisconnect(ConnTypePtr conn); 6 | void httpdPlatDisableTimeout(ConnTypePtr conn); 7 | void httpdPlatInit(int port, int maxConnCt); 8 | 9 | #endif -------------------------------------------------------------------------------- /libesphttpd/core/httpdespfs.c: -------------------------------------------------------------------------------- 1 | /* 2 | Connector to let httpd use the espfs filesystem to serve the files in it. 3 | */ 4 | 5 | /* 6 | * ---------------------------------------------------------------------------- 7 | * "THE BEER-WARE LICENSE" (Revision 42): 8 | * Jeroen Domburg wrote this file. As long as you retain 9 | * this notice you can do whatever you want with this stuff. If we meet some day, 10 | * and you think this stuff is worth it, you can buy me a beer in return. 11 | * ---------------------------------------------------------------------------- 12 | */ 13 | 14 | #include 15 | #include "httpdespfs.h" 16 | #include "espfs.h" 17 | #include "espfsformat.h" 18 | 19 | // The static files marked with FLAG_GZIP are compressed and will be served with GZIP compression. 20 | // If the client does not advertise that he accepts GZIP send following warning message (telnet users for e.g.) 21 | static const char *gzipNonSupportedMessage = "HTTP/1.0 501 Not implemented\r\nServer: esp8266-httpd/"HTTPDVER"\r\nConnection: close\r\nContent-Type: text/plain\r\nContent-Length: 52\r\n\r\nYour browser does not accept gzip-compressed data.\r\n"; 22 | 23 | 24 | //This is a catch-all cgi function. It takes the url passed to it, looks up the corresponding 25 | //path in the filesystem and if it exists, passes the file through. This simulates what a normal 26 | //webserver would do with static files. 27 | int ICACHE_FLASH_ATTR cgiEspFsHook(HttpdConnData *connData) { 28 | EspFsFile *file=connData->cgiData; 29 | int len; 30 | char buff[1024]; 31 | char acceptEncodingBuffer[64]; 32 | int isGzip; 33 | 34 | if (connData->conn==NULL) { 35 | //Connection aborted. Clean up. 36 | espFsClose(file); 37 | return HTTPD_CGI_DONE; 38 | } 39 | 40 | if (file==NULL) { 41 | //First call to this cgi. Open the file so we can read it. 42 | file=espFsOpen(connData->url); 43 | if (file==NULL) { 44 | return HTTPD_CGI_NOTFOUND; 45 | } 46 | 47 | // The gzip checking code is intentionally without #ifdefs because checking 48 | // for FLAG_GZIP (which indicates gzip compressed file) is very easy, doesn't 49 | // mean additional overhead and is actually safer to be on at all times. 50 | // If there are no gzipped files in the image, the code bellow will not cause any harm. 51 | 52 | // Check if requested file was GZIP compressed 53 | isGzip = espFsFlags(file) & FLAG_GZIP; 54 | if (isGzip) { 55 | // Check the browser's "Accept-Encoding" header. If the client does not 56 | // advertise that he accepts GZIP send a warning message (telnet users for e.g.) 57 | httpdGetHeader(connData, "Accept-Encoding", acceptEncodingBuffer, 64); 58 | if (strstr(acceptEncodingBuffer, "gzip") == NULL) { 59 | //No Accept-Encoding: gzip header present 60 | httpdSend(connData, gzipNonSupportedMessage, -1); 61 | espFsClose(file); 62 | return HTTPD_CGI_DONE; 63 | } 64 | } 65 | 66 | connData->cgiData=file; 67 | httpdStartResponse(connData, 200); 68 | httpdHeader(connData, "Content-Type", httpdGetMimetype(connData->url)); 69 | if (isGzip) { 70 | httpdHeader(connData, "Content-Encoding", "gzip"); 71 | } 72 | httpdHeader(connData, "Cache-Control", "max-age=3600, must-revalidate"); 73 | httpdEndHeaders(connData); 74 | return HTTPD_CGI_MORE; 75 | } 76 | 77 | len=espFsRead(file, buff, 1024); 78 | if (len>0) httpdSend(connData, buff, len); 79 | if (len!=1024) { 80 | //We're done. 81 | espFsClose(file); 82 | return HTTPD_CGI_DONE; 83 | } else { 84 | //Ok, till next time. 85 | return HTTPD_CGI_MORE; 86 | } 87 | } 88 | 89 | 90 | //cgiEspFsTemplate can be used as a template. 91 | 92 | typedef struct { 93 | EspFsFile *file; 94 | void *tplArg; 95 | char token[64]; 96 | int tokenPos; 97 | } TplData; 98 | 99 | typedef void (* TplCallback)(HttpdConnData *connData, char *token, void **arg); 100 | 101 | int ICACHE_FLASH_ATTR cgiEspFsTemplate(HttpdConnData *connData) { 102 | TplData *tpd=connData->cgiData; 103 | int len; 104 | int x, sp=0; 105 | char *e=NULL; 106 | char buff[1025]; 107 | 108 | if (connData->conn==NULL) { 109 | //Connection aborted. Clean up. 110 | ((TplCallback)(connData->cgiArg))(connData, NULL, &tpd->tplArg); 111 | espFsClose(tpd->file); 112 | free(tpd); 113 | return HTTPD_CGI_DONE; 114 | } 115 | 116 | if (tpd==NULL) { 117 | //First call to this cgi. Open the file so we can read it. 118 | tpd=(TplData *)malloc(sizeof(TplData)); 119 | tpd->file=espFsOpen(connData->url); 120 | tpd->tplArg=NULL; 121 | tpd->tokenPos=-1; 122 | if (tpd->file==NULL) { 123 | espFsClose(tpd->file); 124 | free(tpd); 125 | return HTTPD_CGI_NOTFOUND; 126 | } 127 | if (espFsFlags(tpd->file) & FLAG_GZIP) { 128 | httpd_printf("cgiEspFsTemplate: Trying to use gzip-compressed file %s as template!\n", connData->url); 129 | espFsClose(tpd->file); 130 | free(tpd); 131 | return HTTPD_CGI_NOTFOUND; 132 | } 133 | connData->cgiData=tpd; 134 | httpdStartResponse(connData, 200); 135 | httpdHeader(connData, "Content-Type", httpdGetMimetype(connData->url)); 136 | httpdEndHeaders(connData); 137 | return HTTPD_CGI_MORE; 138 | } 139 | 140 | len=espFsRead(tpd->file, buff, 1024); 141 | if (len>0) { 142 | sp=0; 143 | e=buff; 144 | for (x=0; xtokenPos==-1) { 146 | //Inside ordinary text. 147 | if (buff[x]=='%') { 148 | //Send raw data up to now 149 | if (sp!=0) httpdSend(connData, e, sp); 150 | sp=0; 151 | //Go collect token chars. 152 | tpd->tokenPos=0; 153 | } else { 154 | sp++; 155 | } 156 | } else { 157 | if (buff[x]=='%') { 158 | if (tpd->tokenPos==0) { 159 | //This is the second % of a %% escape string. 160 | //Send a single % and resume with the normal program flow. 161 | httpdSend(connData, "%", 1); 162 | } else { 163 | //This is an actual token. 164 | tpd->token[tpd->tokenPos++]=0; //zero-terminate token 165 | ((TplCallback)(connData->cgiArg))(connData, tpd->token, &tpd->tplArg); 166 | } 167 | //Go collect normal chars again. 168 | e=&buff[x+1]; 169 | tpd->tokenPos=-1; 170 | } else { 171 | if (tpd->tokenPos<(sizeof(tpd->token)-1)) tpd->token[tpd->tokenPos++]=buff[x]; 172 | } 173 | } 174 | } 175 | } 176 | //Send remaining bit. 177 | if (sp!=0) httpdSend(connData, e, sp); 178 | if (len!=1024) { 179 | //We're done. 180 | ((TplCallback)(connData->cgiArg))(connData, NULL, &tpd->tplArg); 181 | espFsClose(tpd->file); 182 | free(tpd); 183 | return HTTPD_CGI_DONE; 184 | } else { 185 | //Ok, till next time. 186 | return HTTPD_CGI_MORE; 187 | } 188 | } 189 | 190 | -------------------------------------------------------------------------------- /libesphttpd/core/sha1.c: -------------------------------------------------------------------------------- 1 | /* This code is public-domain - it is based on libcrypt 2 | * placed in the public domain by Wei Dai and other contributors. 3 | */ 4 | // gcc -Wall -DSHA1TEST -o sha1test sha1.c && ./sha1test 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "sha1.h" 11 | 12 | //according to http://ip.cadence.com/uploads/pdf/xtensalx_overview_handbook.pdf 13 | // the cpu is normally defined as little ending, but can be big endian too. 14 | // for the esp this seems to work 15 | //#define SHA_BIG_ENDIAN 16 | 17 | 18 | 19 | /* code */ 20 | #define SHA1_K0 0x5a827999 21 | #define SHA1_K20 0x6ed9eba1 22 | #define SHA1_K40 0x8f1bbcdc 23 | #define SHA1_K60 0xca62c1d6 24 | 25 | void ICACHE_FLASH_ATTR sha1_init(sha1nfo *s) { 26 | s->state[0] = 0x67452301; 27 | s->state[1] = 0xefcdab89; 28 | s->state[2] = 0x98badcfe; 29 | s->state[3] = 0x10325476; 30 | s->state[4] = 0xc3d2e1f0; 31 | s->byteCount = 0; 32 | s->bufferOffset = 0; 33 | } 34 | 35 | uint32_t ICACHE_FLASH_ATTR sha1_rol32(uint32_t number, uint8_t bits) { 36 | return ((number << bits) | (number >> (32-bits))); 37 | } 38 | 39 | void ICACHE_FLASH_ATTR sha1_hashBlock(sha1nfo *s) { 40 | uint8_t i; 41 | uint32_t a,b,c,d,e,t; 42 | 43 | a=s->state[0]; 44 | b=s->state[1]; 45 | c=s->state[2]; 46 | d=s->state[3]; 47 | e=s->state[4]; 48 | for (i=0; i<80; i++) { 49 | if (i>=16) { 50 | t = s->buffer[(i+13)&15] ^ s->buffer[(i+8)&15] ^ s->buffer[(i+2)&15] ^ s->buffer[i&15]; 51 | s->buffer[i&15] = sha1_rol32(t,1); 52 | } 53 | if (i<20) { 54 | t = (d ^ (b & (c ^ d))) + SHA1_K0; 55 | } else if (i<40) { 56 | t = (b ^ c ^ d) + SHA1_K20; 57 | } else if (i<60) { 58 | t = ((b & c) | (d & (b | c))) + SHA1_K40; 59 | } else { 60 | t = (b ^ c ^ d) + SHA1_K60; 61 | } 62 | t+=sha1_rol32(a,5) + e + s->buffer[i&15]; 63 | e=d; 64 | d=c; 65 | c=sha1_rol32(b,30); 66 | b=a; 67 | a=t; 68 | } 69 | s->state[0] += a; 70 | s->state[1] += b; 71 | s->state[2] += c; 72 | s->state[3] += d; 73 | s->state[4] += e; 74 | } 75 | 76 | void ICACHE_FLASH_ATTR sha1_addUncounted(sha1nfo *s, uint8_t data) { 77 | uint8_t * const b = (uint8_t*) s->buffer; 78 | #ifdef SHA_BIG_ENDIAN 79 | b[s->bufferOffset] = data; 80 | #else 81 | b[s->bufferOffset ^ 3] = data; 82 | #endif 83 | s->bufferOffset++; 84 | if (s->bufferOffset == BLOCK_LENGTH) { 85 | sha1_hashBlock(s); 86 | s->bufferOffset = 0; 87 | } 88 | } 89 | 90 | void ICACHE_FLASH_ATTR sha1_writebyte(sha1nfo *s, uint8_t data) { 91 | ++s->byteCount; 92 | sha1_addUncounted(s, data); 93 | } 94 | 95 | void ICACHE_FLASH_ATTR sha1_write(sha1nfo *s, const char *data, size_t len) { 96 | for (;len--;) sha1_writebyte(s, (uint8_t) *data++); 97 | } 98 | 99 | void ICACHE_FLASH_ATTR sha1_pad(sha1nfo *s) { 100 | // Implement SHA-1 padding (fips180-2 §5.1.1) 101 | 102 | // Pad with 0x80 followed by 0x00 until the end of the block 103 | sha1_addUncounted(s, 0x80); 104 | while (s->bufferOffset != 56) sha1_addUncounted(s, 0x00); 105 | 106 | // Append length in the last 8 bytes 107 | sha1_addUncounted(s, 0); // We're only using 32 bit lengths 108 | sha1_addUncounted(s, 0); // But SHA-1 supports 64 bit lengths 109 | sha1_addUncounted(s, 0); // So zero pad the top bits 110 | sha1_addUncounted(s, s->byteCount >> 29); // Shifting to multiply by 8 111 | sha1_addUncounted(s, s->byteCount >> 21); // as SHA-1 supports bitstreams as well as 112 | sha1_addUncounted(s, s->byteCount >> 13); // byte. 113 | sha1_addUncounted(s, s->byteCount >> 5); 114 | sha1_addUncounted(s, s->byteCount << 3); 115 | } 116 | 117 | uint8_t* ICACHE_FLASH_ATTR sha1_result(sha1nfo *s) { 118 | // Pad to complete the last block 119 | sha1_pad(s); 120 | 121 | #ifndef SHA_BIG_ENDIAN 122 | // Swap byte order back 123 | int i; 124 | for (i=0; i<5; i++) { 125 | s->state[i]= 126 | (((s->state[i])<<24)& 0xff000000) 127 | | (((s->state[i])<<8) & 0x00ff0000) 128 | | (((s->state[i])>>8) & 0x0000ff00) 129 | | (((s->state[i])>>24)& 0x000000ff); 130 | } 131 | #endif 132 | 133 | // Return pointer to hash (20 characters) 134 | return (uint8_t*) s->state; 135 | } 136 | 137 | #define HMAC_IPAD 0x36 138 | #define HMAC_OPAD 0x5c 139 | 140 | void ICACHE_FLASH_ATTR sha1_initHmac(sha1nfo *s, const uint8_t* key, int keyLength) { 141 | uint8_t i; 142 | memset(s->keyBuffer, 0, BLOCK_LENGTH); 143 | if (keyLength > BLOCK_LENGTH) { 144 | // Hash long keys 145 | sha1_init(s); 146 | for (;keyLength--;) sha1_writebyte(s, *key++); 147 | memcpy(s->keyBuffer, sha1_result(s), HASH_LENGTH); 148 | } else { 149 | // Block length keys are used as is 150 | memcpy(s->keyBuffer, key, keyLength); 151 | } 152 | // Start inner hash 153 | sha1_init(s); 154 | for (i=0; ikeyBuffer[i] ^ HMAC_IPAD); 156 | } 157 | } 158 | 159 | uint8_t* ICACHE_FLASH_ATTR sha1_resultHmac(sha1nfo *s) { 160 | uint8_t i; 161 | // Complete inner hash 162 | memcpy(s->innerHash,sha1_result(s),HASH_LENGTH); 163 | // Calculate outer hash 164 | sha1_init(s); 165 | for (i=0; ikeyBuffer[i] ^ HMAC_OPAD); 166 | for (i=0; iinnerHash[i]); 167 | return sha1_result(s); 168 | } 169 | -------------------------------------------------------------------------------- /libesphttpd/espfs/espfsformat.h: -------------------------------------------------------------------------------- 1 | #ifndef ESPROFSFORMAT_H 2 | #define ESPROFSFORMAT_H 3 | 4 | /* 5 | Stupid cpio-like tool to make read-only 'filesystems' that live on the flash SPI chip of the module. 6 | Can (will) use lzf compression (when I come around to it) to make shit quicker. Aligns names, files, 7 | headers on 4-byte boundaries so the SPI abstraction hardware in the ESP8266 doesn't crap on itself 8 | when trying to do a <4byte or unaligned read. 9 | */ 10 | 11 | /* 12 | The idea 'borrows' from cpio: it's basically a concatenation of {header, filename, file} data. 13 | Header, filename and file data is 32-bit aligned. The last file is indicated by data-less header 14 | with the FLAG_LASTFILE flag set. 15 | */ 16 | 17 | 18 | #define FLAG_LASTFILE (1<<0) 19 | #define FLAG_GZIP (1<<1) 20 | #define COMPRESS_NONE 0 21 | #define COMPRESS_HEATSHRINK 1 22 | #define ESPFS_MAGIC 0x73665345 23 | 24 | typedef struct { 25 | int32_t magic; 26 | int8_t flags; 27 | int8_t compression; 28 | int16_t nameLen; 29 | int32_t fileLenComp; 30 | int32_t fileLenDecomp; 31 | } __attribute__((packed)) EspFsHeader; 32 | 33 | #endif -------------------------------------------------------------------------------- /libesphttpd/espfs/espfstest/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-I../../lib/heatshrink -I.. -std=gnu99 -DESPFS_HEATSHRINK 2 | 3 | espfstest: main.o espfs.o heatshrink_decoder.o 4 | $(CC) -o $@ $^ 5 | 6 | espfs.o: ../espfs.c 7 | $(CC) $(CFLAGS) -c $^ -o $@ 8 | 9 | heatshrink_decoder.o: ../heatshrink_decoder.c 10 | $(CC) $(CFLAGS) -c $^ -o $@ 11 | 12 | clean: 13 | rm -f *.o espfstest 14 | -------------------------------------------------------------------------------- /libesphttpd/espfs/espfstest/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | Simple and stupid file decompressor for an espfs image. Mostly used as a testbed for espfs.c and 3 | the decompressors: code compiled natively is way easier to debug using gdb et all :) 4 | */ 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | #include "espfs.h" 16 | 17 | char *espFsData; 18 | 19 | int main(int argc, char **argv) { 20 | int f, out; 21 | int len; 22 | char buff[128]; 23 | EspFsFile *ef; 24 | off_t size; 25 | EspFsInitResult ir; 26 | 27 | if (argc!=3) { 28 | printf("Usage: %s espfs-image file\nExpands file from the espfs-image archive.\n", argv[0]); 29 | exit(0); 30 | } 31 | 32 | f=open(argv[1], O_RDONLY); 33 | if (f<=0) { 34 | perror(argv[1]); 35 | exit(1); 36 | } 37 | size=lseek(f, 0, SEEK_END); 38 | espFsData=mmap(NULL, size, PROT_READ, MAP_SHARED, f, 0); 39 | if (espFsData==MAP_FAILED) { 40 | perror("mmap"); 41 | exit(1); 42 | } 43 | 44 | ir=espFsInit(espFsData); 45 | if (ir != ESPFS_INIT_RESULT_OK) { 46 | printf("Couldn't init espfs filesystem (code %d)\n", ir); 47 | exit(1); 48 | } 49 | 50 | ef=espFsOpen(argv[2]); 51 | if (ef==NULL) { 52 | printf("Couldn't find %s in image.\n", argv[2]); 53 | exit(1); 54 | } 55 | 56 | out=open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0644); 57 | if (out<=0) { 58 | perror(argv[2]); 59 | exit(1); 60 | } 61 | 62 | while ((len=espFsRead(ef, buff, 128))!=0) { 63 | write(out, buff, len); 64 | } 65 | espFsClose(ef); 66 | //munmap, close, ... I can't be bothered. 67 | } 68 | -------------------------------------------------------------------------------- /libesphttpd/espfs/heatshrink_config_custom.h: -------------------------------------------------------------------------------- 1 | //Heatshrink config for the decompressor. 2 | #ifndef HEATSHRINK_CONFIG_H 3 | #define HEATSHRINK_CONFIG_H 4 | 5 | /* Should functionality assuming dynamic allocation be used? */ 6 | #define HEATSHRINK_DYNAMIC_ALLOC 1 7 | 8 | #if HEATSHRINK_DYNAMIC_ALLOC 9 | /* Optional replacement of malloc/free */ 10 | #define HEATSHRINK_MALLOC(SZ) malloc(SZ) 11 | #define HEATSHRINK_FREE(P, SZ) free(P) 12 | #else 13 | /* Required parameters for static configuration */ 14 | #define HEATSHRINK_STATIC_INPUT_BUFFER_SIZE 32 15 | #define HEATSHRINK_STATIC_WINDOW_BITS 8 16 | #define HEATSHRINK_STATIC_LOOKAHEAD_BITS 4 17 | #endif 18 | 19 | /* Turn on logging for debugging. */ 20 | #define HEATSHRINK_DEBUGGING_LOGS 0 21 | 22 | /* Use indexing for faster compression. (This requires additional space.) */ 23 | #define HEATSHRINK_USE_INDEX 1 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /libesphttpd/espfs/heatshrink_decoder.c: -------------------------------------------------------------------------------- 1 | #include "espfs.h" 2 | #ifdef ESPFS_HEATSHRINK 3 | //Stupid wrapper so we don't have to move c-files around 4 | //Also loads httpd-specific config. 5 | 6 | #ifdef __ets__ 7 | //esp build 8 | 9 | #include 10 | 11 | #endif 12 | 13 | #include "heatshrink_config_custom.h" 14 | #include "../lib/heatshrink/heatshrink_decoder.c" 15 | 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /libesphttpd/espfs/mkespfsimage/Makefile: -------------------------------------------------------------------------------- 1 | GZIP_COMPRESSION ?= no 2 | USE_HEATSHRINK ?= yes 3 | 4 | CFLAGS=-I../../lib/heatshrink -I../../include -I.. -std=gnu99 5 | ifeq ("$(GZIP_COMPRESSION)","yes") 6 | CFLAGS += -DESPFS_GZIP 7 | endif 8 | 9 | ifeq ("$(USE_HEATSHRINK)","yes") 10 | CFLAGS += -DESPFS_HEATSHRINK 11 | endif 12 | 13 | OBJS=main.o heatshrink_encoder.o 14 | TARGET=mkespfsimage 15 | 16 | $(TARGET): $(OBJS) 17 | ifeq ("$(GZIP_COMPRESSION)","yes") 18 | $(CC) -o $@ $^ -lz 19 | else 20 | $(CC) -o $@ $^ 21 | endif 22 | 23 | clean: 24 | rm -f $(TARGET) $(OBJS) -------------------------------------------------------------------------------- /libesphttpd/espfs/mkespfsimage/heatshrink_encoder.c: -------------------------------------------------------------------------------- 1 | //Stupid wraparound include to make sure object file doesn't end up in heatshrink dir 2 | #ifdef ESPFS_HEATSHRINK 3 | #include "../lib/heatshrink/heatshrink_encoder.c" 4 | #endif -------------------------------------------------------------------------------- /libesphttpd/espfs/mkespfsimage/heatshrink_encoder.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-ESP/f6e49a2c4132bdf364697d486b58d9062e72796b/libesphttpd/espfs/mkespfsimage/heatshrink_encoder.o -------------------------------------------------------------------------------- /libesphttpd/espfs/mkespfsimage/main.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-ESP/f6e49a2c4132bdf364697d486b58d9062e72796b/libesphttpd/espfs/mkespfsimage/main.o -------------------------------------------------------------------------------- /libesphttpd/espfs/mkespfsimage/mkespfsimage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-ESP/f6e49a2c4132bdf364697d486b58d9062e72796b/libesphttpd/espfs/mkespfsimage/mkespfsimage -------------------------------------------------------------------------------- /libesphttpd/include/auth.h: -------------------------------------------------------------------------------- 1 | #ifndef AUTH_H 2 | #define AUTH_H 3 | 4 | #include "httpd.h" 5 | 6 | #ifndef HTTP_AUTH_REALM 7 | #define HTTP_AUTH_REALM "Protected" 8 | #endif 9 | 10 | #define HTTPD_AUTH_SINGLE 0 11 | #define HTTPD_AUTH_CALLBACK 1 12 | 13 | #define AUTH_MAX_USER_LEN 32 14 | #define AUTH_MAX_PASS_LEN 32 15 | 16 | //Parameter given to authWhatever functions. This callback returns the usernames/passwords the device 17 | //has. 18 | typedef int (* AuthGetUserPw)(HttpdConnData *connData, int no, char *user, int userLen, char *pass, int passLen); 19 | 20 | int ICACHE_FLASH_ATTR authBasic(HttpdConnData *connData); 21 | 22 | #endif -------------------------------------------------------------------------------- /libesphttpd/include/captdns.h: -------------------------------------------------------------------------------- 1 | #ifndef CAPTDNS_H 2 | #define CAPTDNS_H 3 | void ICACHE_FLASH_ATTR captdnsInit(void); 4 | 5 | #endif -------------------------------------------------------------------------------- /libesphttpd/include/cgiflash.h: -------------------------------------------------------------------------------- 1 | #ifndef CGIFLASH_H 2 | #define CGIFLASH_H 3 | 4 | #include "httpd.h" 5 | 6 | #define CGIFLASH_TYPE_FW 0 7 | #define CGIFLASH_TYPE_ESPFS 1 8 | 9 | typedef struct { 10 | int type; 11 | int fw1Pos; 12 | int fw2Pos; 13 | int fwSize; 14 | char *tagName; 15 | } CgiUploadFlashDef; 16 | 17 | int cgiGetFirmwareNext(HttpdConnData *connData); 18 | int cgiUploadFirmware(HttpdConnData *connData); 19 | int cgiRebootFirmware(HttpdConnData *connData); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /libesphttpd/include/cgiwebsocket.h: -------------------------------------------------------------------------------- 1 | #ifndef CGIWEBSOCKET_H 2 | #define CGIWEBSOCKET_H 3 | 4 | #include "httpd.h" 5 | 6 | #define WEBSOCK_FLAG_NONE 0 7 | #define WEBSOCK_FLAG_CONT (1<<0) //Set if the data is not the final data in the message; more follows 8 | #define WEBSOCK_FLAG_BIN (1<<1) //Set if the data is binary instead of text 9 | 10 | 11 | 12 | typedef struct Websock Websock; 13 | typedef struct WebsockPriv WebsockPriv; 14 | 15 | typedef void(*WsConnectedCb)(Websock *ws); 16 | typedef void(*WsRecvCb)(Websock *ws, char *data, int len, int flags); 17 | typedef void(*WsSentCb)(Websock *ws); 18 | typedef void(*WsCloseCb)(Websock *ws); 19 | 20 | struct Websock { 21 | void *userData; 22 | HttpdConnData *conn; 23 | uint8_t status; 24 | WsRecvCb recvCb; 25 | WsSentCb sentCb; 26 | WsCloseCb closeCb; 27 | WebsockPriv *priv; 28 | }; 29 | 30 | int ICACHE_FLASH_ATTR cgiWebsocket(HttpdConnData *connData); 31 | int ICACHE_FLASH_ATTR cgiWebsocketSend(Websock *ws, char *data, int len, int flags); 32 | void ICACHE_FLASH_ATTR cgiWebsocketClose(Websock *ws, int reason); 33 | int ICACHE_FLASH_ATTR cgiWebSocketRecv(HttpdConnData *connData, char *data, int len); 34 | int ICACHE_FLASH_ATTR cgiWebsockBroadcast(char *resource, char *data, int len, int flags); 35 | 36 | 37 | #endif -------------------------------------------------------------------------------- /libesphttpd/include/cgiwifi.h: -------------------------------------------------------------------------------- 1 | #ifndef CGIWIFI_H 2 | #define CGIWIFI_H 3 | 4 | #include "httpd.h" 5 | 6 | //WiFi access point data 7 | typedef struct { 8 | char ssid[32]; 9 | char bssid[8]; 10 | int channel; 11 | char rssi; 12 | char enc; 13 | } ApData; 14 | 15 | int cgiWiFiScan(HttpdConnData *connData); 16 | int tplWlan(HttpdConnData *connData, char *token, void **arg); 17 | int cgiWiFi(HttpdConnData *connData); 18 | int cgiWiFiConnect(HttpdConnData *connData); 19 | int cgiWiFiSetMode(HttpdConnData *connData); 20 | int cgiWiFiConnStatus(HttpdConnData *connData); 21 | 22 | int wifiJoin(char *ssid, char *passwd); 23 | 24 | int cgiWiFiStartScan(void (*callback)(void *data, int count), void *data); 25 | int cgiWiFiScanDone(void); 26 | ApData *cgiWiFiScanResult(int n); 27 | int cgiWifiScanResultCount(void); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /libesphttpd/include/esp8266.h: -------------------------------------------------------------------------------- 1 | // Combined include file for esp8266 2 | // Actually misnamed, as it also works for ESP32. 3 | // ToDo: Figure out better name 4 | 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #ifdef FREERTOS 12 | #include 13 | 14 | #ifdef ESP32 15 | #include 16 | #else 17 | #include 18 | #endif 19 | 20 | #else 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #endif 31 | 32 | #include "platform.h" 33 | #include "espmissingincludes.h" 34 | #if 0 35 | void *ets_memcpy(void *dest, const void *src, size_t n); 36 | void *ets_memset(void *s, int c, size_t n); 37 | int ets_strcmp(const char *s1, const char *s2); 38 | int ets_strncmp(const char *s1, const char *s2, int len); 39 | size_t ets_strlen(const char *s); 40 | char *ets_strcpy(char *dest, const char *src); 41 | char *ets_strstr(const char *haystack, const char *needle); 42 | int ets_sprintf(char *str, const char *format, ...) __attribute__ ((format (printf, 2, 3))); 43 | int os_printf_plus(const char *format, ...) __attribute__ ((format (printf, 1, 2))); 44 | int strcasecmp(const char *a, const char *b); 45 | 46 | void *pvPortMalloc(size_t xWantedSize, const char *file, int line); 47 | void vPortFree(void *ptr, const char *file, int line); 48 | #endif 49 | -------------------------------------------------------------------------------- /libesphttpd/include/espfs.h: -------------------------------------------------------------------------------- 1 | #ifndef ESPFS_H 2 | #define ESPFS_H 3 | 4 | // This define is done in Makefile. If you do not use default Makefile, uncomment 5 | // to be able to use Heatshrink-compressed espfs images. 6 | //#define ESPFS_HEATSHRINK 7 | 8 | typedef enum { 9 | ESPFS_INIT_RESULT_OK, 10 | ESPFS_INIT_RESULT_NO_IMAGE, 11 | ESPFS_INIT_RESULT_BAD_ALIGN, 12 | } EspFsInitResult; 13 | 14 | typedef struct EspFsFile EspFsFile; 15 | 16 | EspFsInitResult espFsInit(void *flashAddress); 17 | EspFsFile *espFsOpen(char *fileName); 18 | int espFsFlags(EspFsFile *fh); 19 | int espFsRead(EspFsFile *fh, char *buff, int len); 20 | void espFsClose(EspFsFile *fh); 21 | 22 | 23 | #endif -------------------------------------------------------------------------------- /libesphttpd/include/espmissingincludes.h: -------------------------------------------------------------------------------- 1 | #ifndef ESPMISSINGINCLUDES_H 2 | #define ESPMISSINGINCLUDES_H 3 | 4 | #define NONOS_SDK 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | int strcasecmp(const char *a, const char *b); 12 | #ifndef FREERTOS 13 | #include 14 | #include 15 | //Missing function prototypes in include folders. Gcc will warn on these if we don't define 'em anywhere. 16 | //MOST OF THESE ARE GUESSED! but they seem to swork and shut up the compiler. 17 | typedef struct espconn espconn; 18 | 19 | #ifndef NONOS_SDK 20 | 21 | void ets_install_putc1(void *routine); 22 | void ets_isr_attach(int intr, void *handler, void *arg); 23 | size_t ets_strlen(const char *s); 24 | int ets_strncmp(const char *s1, const char *s2, int len); 25 | void ets_timer_arm_new(os_timer_t *a, int b, int c, int isMstimer); 26 | void uart_div_modify(int no, unsigned int freq); 27 | void ets_delay_us(int ms); 28 | 29 | #endif 30 | 31 | 32 | 33 | int atoi(const char *nptr); 34 | 35 | void ets_isr_mask(unsigned intr); 36 | void ets_isr_unmask(unsigned intr); 37 | int ets_memcmp(const void *s1, const void *s2, size_t n); 38 | void *ets_memcpy(void *dest, const void *src, size_t n); 39 | void *ets_memset(void *s, int c, size_t n); 40 | int ets_sprintf(char *str, const char *format, ...) __attribute__ ((format (printf, 2, 3))); 41 | int ets_str2macaddr(void *, void *); 42 | int ets_strcmp(const char *s1, const char *s2); 43 | char *ets_strcpy(char *dest, const char *src); 44 | 45 | char *ets_strncpy(char *dest, const char *src, size_t n); 46 | char *ets_strstr(const char *haystack, const char *needle); 47 | 48 | void ets_timer_disarm(os_timer_t *a); 49 | void ets_timer_setfn(os_timer_t *t, ETSTimerFunc *fn, void *parg); 50 | void ets_update_cpu_frequency(int freqmhz); 51 | void *os_memmove(void *dest, const void *src, size_t n); 52 | int os_printf(const char *format, ...) __attribute__ ((format (printf, 1, 2))); 53 | int os_snprintf(char *str, size_t size, const char *format, ...) __attribute__ ((format (printf, 3, 4))); 54 | int os_printf_plus(const char *format, ...) __attribute__ ((format (printf, 1, 2))); 55 | 56 | uint8 wifi_get_opmode(void); 57 | uint32 system_get_time(); 58 | int rand(void); 59 | void ets_bzero(void *s, size_t n); 60 | 61 | 62 | //Hack: this is defined in SDK 1.4.0 and undefined in 1.3.0. It's only used for this, the symbol itself 63 | //has no meaning here. 64 | #ifndef RC_LIMIT_P2P_11N 65 | //Defs for SDK <1.4.0 66 | void *pvPortMalloc(size_t xWantedSize); 67 | void *pvPortZalloc(size_t); 68 | void vPortFree(void *ptr); 69 | void *vPortMalloc(size_t xWantedSize); 70 | void pvPortFree(void *ptr); 71 | #else 72 | 73 | #ifndef NONOS_SDK 74 | void *pvPortMalloc(size_t xWantedSize, const char *file, int line); 75 | void *pvPortZalloc(size_t, const char *file, int line); 76 | void vPortFree(void *ptr, const char *file, int line); 77 | void *vPortMalloc(size_t xWantedSize, const char *file, int line); 78 | void pvPortFree(void *ptr, const char *file, int line); 79 | #else 80 | void *vPortMalloc(size_t xWantedSize, const char *file, int line); 81 | void pvPortFree(void *ptr, const char *file, int line); 82 | #endif 83 | 84 | #endif 85 | 86 | //Standard PIN_FUNC_SELECT gives a warning. Replace by a non-warning one. 87 | #ifdef PIN_FUNC_SELECT 88 | #undef PIN_FUNC_SELECT 89 | #define PIN_FUNC_SELECT(PIN_NAME, FUNC) do { \ 90 | WRITE_PERI_REG(PIN_NAME, \ 91 | (READ_PERI_REG(PIN_NAME) \ 92 | & (~(PERIPHS_IO_MUX_FUNC< 2 | All rights reserved. 3 | 4 | Permission to use, copy, modify, and/or distribute this software for any 5 | purpose with or without fee is hereby granted, provided that the above 6 | copyright notice and this permission notice appear in all copies. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | -------------------------------------------------------------------------------- /libesphttpd/lib/heatshrink/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT = heatshrink 2 | #OPTIMIZE = -O0 3 | #OPTIMIZE = -Os 4 | OPTIMIZE = -O3 5 | WARN = -Wall -Wextra -pedantic #-Werror 6 | CFLAGS += -std=c99 -g ${WARN} ${OPTIMIZE} 7 | CFLAGS += -Wmissing-prototypes 8 | CFLAGS += -Wstrict-prototypes 9 | CFLAGS += -Wmissing-declarations 10 | 11 | # If libtheft is available, build additional property-based tests. 12 | # Uncomment these to use it in test_heatshrink_dynamic. 13 | #CFLAGS += -DHEATSHRINK_HAS_THEFT 14 | #LDFLAGS += -ltheft 15 | 16 | all: 17 | @echo "For tests, make test_heatshrink_dynamic (default) or change the" 18 | @echo "config.h to disable static memory and build test_heatshrink_static." 19 | @echo "For the standalone command-line tool, make heatshrink." 20 | 21 | ${PROJECT}: heatshrink.c 22 | 23 | OBJS= heatshrink_encoder.o \ 24 | heatshrink_decoder.o \ 25 | 26 | heatshrink: ${OBJS} 27 | test_heatshrink_dynamic: ${OBJS} test_heatshrink_dynamic_theft.o 28 | test_heatshrink_static: ${OBJS} 29 | 30 | *.o: Makefile heatshrink_config.h 31 | 32 | heatshrink_decoder.o: heatshrink_decoder.h heatshrink_common.h 33 | heatshrink_encoder.o: heatshrink_encoder.h heatshrink_common.h 34 | 35 | tags: TAGS 36 | 37 | TAGS: 38 | etags *.[ch] 39 | 40 | diagrams: dec_sm.png enc_sm.png 41 | 42 | dec_sm.png: dec_sm.dot 43 | dot -o $@ -Tpng $< 44 | 45 | enc_sm.png: enc_sm.dot 46 | dot -o $@ -Tpng $< 47 | 48 | clean: 49 | rm -f ${PROJECT} test_heatshrink_{dynamic,static} *.o *.core {dec,enc}_sm.png TAGS 50 | -------------------------------------------------------------------------------- /libesphttpd/lib/heatshrink/README.md: -------------------------------------------------------------------------------- 1 | # heatshrink 2 | 3 | A data compression/decompression library for embedded/real-time systems. 4 | 5 | ## Key Features: 6 | 7 | - **Low memory usage (as low as 50 bytes)** 8 | It is useful for some cases with less than 50 bytes, and useful 9 | for many general cases with < 300 bytes. 10 | - **Incremental, bounded CPU use** 11 | You can chew on input data in arbitrarily tiny bites. 12 | This is a useful property in hard real-time environments. 13 | - **Can use either static or dynamic memory allocation** 14 | The library doesn't impose any constraints on memory management. 15 | - **ISC license** 16 | You can use it freely, even for commercial purposes. 17 | 18 | ## Getting Started: 19 | 20 | There is a standalone command-line program, `heatshrink`, but the 21 | encoder and decoder can also be used as libraries, independent of each 22 | other. To do so, copy `heatshrink_common.h`, `heatshrink_config.h`, and 23 | either `heatshrink_encoder.c` or `heatshrink_decoder.c` (and their 24 | respective header) into your project. 25 | 26 | Dynamic allocation is used by default, but in an embedded context, you 27 | probably want to statically allocate the encoder/decoder. Set 28 | `HEATSHRINK_DYNAMIC_ALLOC` to 0 in `heatshrink_config.h`. 29 | 30 | ## More Information and Benchmarks: 31 | 32 | heatshrink is based on [LZSS], since it's particularly suitable for 33 | compression in small amounts of memory. It can use an optional, small 34 | [index] to make compression significantly faster, but otherwise can run 35 | in under 100 bytes of memory. The index currently adds 2^(window size+1) 36 | bytes to memory usage for compression, and temporarily allocates 512 37 | bytes on the stack during index construction. 38 | 39 | For more information, see the [blog post] for an overview, and the 40 | `heatshrink_encoder.h` / `heatshrink_decoder.h` header files for API 41 | documentation. 42 | 43 | [blog post]: http://spin.atomicobject.com/2013/03/14/heatshrink-embedded-data-compression/ 44 | [index]: http://spin.atomicobject.com/2014/01/13/lightweight-indexing-for-embedded-systems/ 45 | [LZSS]: http://en.wikipedia.org/wiki/Lempel-Ziv-Storer-Szymanski 46 | 47 | ## Build Status 48 | 49 | [![Build Status](https://travis-ci.org/atomicobject/heatshrink.png)](http://travis-ci.org/atomicobject/heatshrink) 50 | -------------------------------------------------------------------------------- /libesphttpd/lib/heatshrink/dec_sm.dot: -------------------------------------------------------------------------------- 1 | digraph { 2 | graph [label="Decoder state machine", labelloc="t"] 3 | Start [style="invis", shape="point"] 4 | empty 5 | input_available 6 | yield_literal 7 | backref_index_msb 8 | backref_index_lsb 9 | backref_count_msb 10 | backref_count_lsb 11 | yield_backref 12 | check_for_more_input 13 | done [peripheries=2] 14 | 15 | empty->input_available [label="sink()", color="blue", weight=10] 16 | Start->empty 17 | 18 | input_available->yield_literal [label="pop 1-bit"] 19 | input_available->backref_index_msb [label="pop 0-bit", weight=10] 20 | input_available->backref_index_lsb [label="pop 0-bit, index <8 bits", weight=10] 21 | 22 | yield_literal->yield_literal [label="sink()", color="blue"] 23 | yield_literal->yield_literal [label="poll()", color="red"] 24 | yield_literal->check_for_more_input [label="poll(), done", color="red"] 25 | 26 | backref_index_msb->backref_index_msb [label="sink()", color="blue"] 27 | backref_index_msb->backref_index_lsb [label="pop index, upper bits", weight=10] 28 | backref_index_msb->done [label="finish()", color="blue"] 29 | 30 | backref_index_lsb->backref_index_lsb [label="sink()", color="blue"] 31 | backref_index_lsb->backref_count_msb [label="pop index, lower bits", weight=10] 32 | backref_index_lsb->backref_count_lsb [label="pop index, count <=8 bits", weight=10] 33 | backref_index_lsb->done [label="finish()", color="blue"] 34 | 35 | backref_count_msb->backref_count_msb [label="sink()", color="blue"] 36 | backref_count_msb->backref_count_lsb [label="pop count, upper bits", weight=10] 37 | backref_count_msb->done [label="finish()", color="blue"] 38 | 39 | backref_count_lsb->backref_count_lsb [label="sink()", color="blue"] 40 | backref_count_lsb->yield_backref [label="pop count, lower bits", weight=10] 41 | backref_count_lsb->done [label="finish()", color="blue"] 42 | 43 | yield_backref->yield_backref [label="sink()", color="blue"] 44 | yield_backref->yield_backref [label="poll()", color="red"] 45 | yield_backref->check_for_more_input [label="poll(), done", 46 | color="red", weight=10] 47 | 48 | check_for_more_input->empty [label="no"] 49 | check_for_more_input->input_available [label="yes"] 50 | 51 | empty->done [label="finish()", color="blue"] 52 | } 53 | -------------------------------------------------------------------------------- /libesphttpd/lib/heatshrink/enc_sm.dot: -------------------------------------------------------------------------------- 1 | digraph { 2 | graph [label="Encoder state machine", labelloc="t"] 3 | start [style="invis", shape="point"] 4 | not_full 5 | filled 6 | search 7 | yield_tag_bit 8 | yield_literal 9 | yield_br_length 10 | yield_br_index 11 | save_backlog 12 | flush_bits 13 | done [peripheries=2] 14 | 15 | start->not_full [label="start"] 16 | 17 | not_full->not_full [label="sink(), not full", color="blue"] 18 | not_full->filled [label="sink(), buffer is full", color="blue"] 19 | not_full->filled [label="finish(), set is_finished", color="blue"] 20 | 21 | filled->search [label="indexing (if any)"] 22 | 23 | search->search [label="step"] 24 | search->yield_tag_bit [label="literal"] 25 | search->yield_tag_bit [label="match found"] 26 | search->save_backlog [label="input exhausted"] 27 | 28 | yield_tag_bit->yield_tag_bit [label="poll(), full buf", color="red"] 29 | yield_tag_bit->yield_literal [label="poll(), literal", color="red"] 30 | yield_tag_bit->yield_br_index [label="poll(), no literal", color="red"] 31 | yield_tag_bit->flush_bits [label="finishing, no literal"] 32 | 33 | yield_literal->yield_literal [label="poll(), full buf", color="red"] 34 | yield_literal->search [label="poll(), no match", color="red"] 35 | yield_literal->yield_tag_bit [label="poll(), match", color="red"] 36 | yield_literal->flush_bits [label="poll(), final literal", color="red"] 37 | 38 | yield_br_index->yield_br_index [label="poll(), full buf", color="red"] 39 | yield_br_index->yield_br_length [label="poll()", color="red"] 40 | 41 | yield_br_length->yield_br_length [label="poll(), full buf", color="red"] 42 | yield_br_length->search [label="done"] 43 | 44 | save_backlog->flush_bits [label="finishing, no literal"] 45 | save_backlog->yield_tag_bit [label="finishing, literal"] 46 | save_backlog->not_full [label="expect more input"] 47 | 48 | flush_bits->flush_bits [label="poll(), full buf", color="red"] 49 | flush_bits->done [label="poll(), flushed", color="red"] 50 | flush_bits->done [label="no more output"] 51 | } 52 | -------------------------------------------------------------------------------- /libesphttpd/lib/heatshrink/heatshrink_common.h: -------------------------------------------------------------------------------- 1 | #ifndef HEATSHRINK_H 2 | #define HEATSHRINK_H 3 | 4 | #define HEATSHRINK_AUTHOR "Scott Vokes " 5 | #define HEATSHRINK_URL "https://github.com/atomicobject/heatshrink" 6 | 7 | /* Version 0.3.1 */ 8 | #define HEATSHRINK_VERSION_MAJOR 0 9 | #define HEATSHRINK_VERSION_MINOR 3 10 | #define HEATSHRINK_VERSION_PATCH 1 11 | 12 | #define HEATSHRINK_MIN_WINDOW_BITS 4 13 | #define HEATSHRINK_MAX_WINDOW_BITS 15 14 | 15 | #define HEATSHRINK_MIN_LOOKAHEAD_BITS 2 16 | 17 | #define HEATSHRINK_LITERAL_MARKER 0x01 18 | #define HEATSHRINK_BACKREF_MARKER 0x00 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /libesphttpd/lib/heatshrink/heatshrink_config.h: -------------------------------------------------------------------------------- 1 | #ifndef HEATSHRINK_CONFIG_H 2 | #define HEATSHRINK_CONFIG_H 3 | 4 | /* Should functionality assuming dynamic allocation be used? */ 5 | #define HEATSHRINK_DYNAMIC_ALLOC 1 6 | 7 | #if HEATSHRINK_DYNAMIC_ALLOC 8 | /* Optional replacement of malloc/free */ 9 | #define HEATSHRINK_MALLOC(SZ) malloc(SZ) 10 | #define HEATSHRINK_FREE(P, SZ) free(P) 11 | #else 12 | /* Required parameters for static configuration */ 13 | #define HEATSHRINK_STATIC_INPUT_BUFFER_SIZE 32 14 | #define HEATSHRINK_STATIC_WINDOW_BITS 8 15 | #define HEATSHRINK_STATIC_LOOKAHEAD_BITS 4 16 | #endif 17 | 18 | /* Turn on logging for debugging. */ 19 | #define HEATSHRINK_DEBUGGING_LOGS 0 20 | 21 | /* Use indexing for faster compression. (This requires additional space.) */ 22 | #define HEATSHRINK_USE_INDEX 1 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /libesphttpd/lib/heatshrink/heatshrink_decoder.h: -------------------------------------------------------------------------------- 1 | #ifndef HEATSHRINK_DECODER_H 2 | #define HEATSHRINK_DECODER_H 3 | 4 | #include 5 | #include 6 | #include "heatshrink_common.h" 7 | #include "heatshrink_config.h" 8 | 9 | typedef enum { 10 | HSDR_SINK_OK, /* data sunk, ready to poll */ 11 | HSDR_SINK_FULL, /* out of space in internal buffer */ 12 | HSDR_SINK_ERROR_NULL=-1, /* NULL argument */ 13 | } HSD_sink_res; 14 | 15 | typedef enum { 16 | HSDR_POLL_EMPTY, /* input exhausted */ 17 | HSDR_POLL_MORE, /* more data remaining, call again w/ fresh output buffer */ 18 | HSDR_POLL_ERROR_NULL=-1, /* NULL arguments */ 19 | HSDR_POLL_ERROR_UNKNOWN=-2, 20 | } HSD_poll_res; 21 | 22 | typedef enum { 23 | HSDR_FINISH_DONE, /* output is done */ 24 | HSDR_FINISH_MORE, /* more output remains */ 25 | HSDR_FINISH_ERROR_NULL=-1, /* NULL arguments */ 26 | } HSD_finish_res; 27 | 28 | #if HEATSHRINK_DYNAMIC_ALLOC 29 | #define HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(BUF) \ 30 | ((BUF)->input_buffer_size) 31 | #define HEATSHRINK_DECODER_WINDOW_BITS(BUF) \ 32 | ((BUF)->window_sz2) 33 | #define HEATSHRINK_DECODER_LOOKAHEAD_BITS(BUF) \ 34 | ((BUF)->lookahead_sz2) 35 | #else 36 | #define HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(_) \ 37 | HEATSHRINK_STATIC_INPUT_BUFFER_SIZE 38 | #define HEATSHRINK_DECODER_WINDOW_BITS(_) \ 39 | (HEATSHRINK_STATIC_WINDOW_BITS) 40 | #define HEATSHRINK_DECODER_LOOKAHEAD_BITS(BUF) \ 41 | (HEATSHRINK_STATIC_LOOKAHEAD_BITS) 42 | #endif 43 | 44 | typedef struct { 45 | uint16_t input_size; /* bytes in input buffer */ 46 | uint16_t input_index; /* offset to next unprocessed input byte */ 47 | uint16_t output_count; /* how many bytes to output */ 48 | uint16_t output_index; /* index for bytes to output */ 49 | uint16_t head_index; /* head of window buffer */ 50 | uint16_t bit_accumulator; 51 | uint8_t state; /* current state machine node */ 52 | uint8_t current_byte; /* current byte of input */ 53 | uint8_t bit_index; /* current bit index */ 54 | 55 | #if HEATSHRINK_DYNAMIC_ALLOC 56 | /* Fields that are only used if dynamically allocated. */ 57 | uint8_t window_sz2; /* window buffer bits */ 58 | uint8_t lookahead_sz2; /* lookahead bits */ 59 | uint16_t input_buffer_size; /* input buffer size */ 60 | 61 | /* Input buffer, then expansion window buffer */ 62 | uint8_t buffers[]; 63 | #else 64 | /* Input buffer, then expansion window buffer */ 65 | uint8_t buffers[(1 << HEATSHRINK_DECODER_WINDOW_BITS(_)) 66 | + HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(_)]; 67 | #endif 68 | } heatshrink_decoder; 69 | 70 | #if HEATSHRINK_DYNAMIC_ALLOC 71 | /* Allocate a decoder with an input buffer of INPUT_BUFFER_SIZE bytes, 72 | * an expansion buffer size of 2^WINDOW_SZ2, and a lookahead 73 | * size of 2^lookahead_sz2. (The window buffer and lookahead sizes 74 | * must match the settings used when the data was compressed.) 75 | * Returns NULL on error. */ 76 | heatshrink_decoder *heatshrink_decoder_alloc(uint16_t input_buffer_size, 77 | uint8_t expansion_buffer_sz2, uint8_t lookahead_sz2); 78 | 79 | /* Free a decoder. */ 80 | void heatshrink_decoder_free(heatshrink_decoder *hsd); 81 | #endif 82 | 83 | /* Reset a decoder. */ 84 | void heatshrink_decoder_reset(heatshrink_decoder *hsd); 85 | 86 | /* Sink at most SIZE bytes from IN_BUF into the decoder. *INPUT_SIZE is set to 87 | * indicate how many bytes were actually sunk (in case a buffer was filled). */ 88 | HSD_sink_res heatshrink_decoder_sink(heatshrink_decoder *hsd, 89 | uint8_t *in_buf, size_t size, size_t *input_size); 90 | 91 | /* Poll for output from the decoder, copying at most OUT_BUF_SIZE bytes into 92 | * OUT_BUF (setting *OUTPUT_SIZE to the actual amount copied). */ 93 | HSD_poll_res heatshrink_decoder_poll(heatshrink_decoder *hsd, 94 | uint8_t *out_buf, size_t out_buf_size, size_t *output_size); 95 | 96 | /* Notify the dencoder that the input stream is finished. 97 | * If the return value is HSDR_FINISH_MORE, there is still more output, so 98 | * call heatshrink_decoder_poll and repeat. */ 99 | HSD_finish_res heatshrink_decoder_finish(heatshrink_decoder *hsd); 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /libesphttpd/lib/heatshrink/heatshrink_encoder.h: -------------------------------------------------------------------------------- 1 | #ifndef HEATSHRINK_ENCODER_H 2 | #define HEATSHRINK_ENCODER_H 3 | 4 | #include 5 | #include 6 | #include "heatshrink_common.h" 7 | #include "heatshrink_config.h" 8 | 9 | typedef enum { 10 | HSER_SINK_OK, /* data sunk into input buffer */ 11 | HSER_SINK_ERROR_NULL=-1, /* NULL argument */ 12 | HSER_SINK_ERROR_MISUSE=-2, /* API misuse */ 13 | } HSE_sink_res; 14 | 15 | typedef enum { 16 | HSER_POLL_EMPTY, /* input exhausted */ 17 | HSER_POLL_MORE, /* poll again for more output */ 18 | HSER_POLL_ERROR_NULL=-1, /* NULL argument */ 19 | HSER_POLL_ERROR_MISUSE=-2, /* API misuse */ 20 | } HSE_poll_res; 21 | 22 | typedef enum { 23 | HSER_FINISH_DONE, /* encoding is complete */ 24 | HSER_FINISH_MORE, /* more output remaining; use poll */ 25 | HSER_FINISH_ERROR_NULL=-1, /* NULL argument */ 26 | } HSE_finish_res; 27 | 28 | #if HEATSHRINK_DYNAMIC_ALLOC 29 | #define HEATSHRINK_ENCODER_WINDOW_BITS(HSE) \ 30 | ((HSE)->window_sz2) 31 | #define HEATSHRINK_ENCODER_LOOKAHEAD_BITS(HSE) \ 32 | ((HSE)->lookahead_sz2) 33 | #define HEATSHRINK_ENCODER_INDEX(HSE) \ 34 | ((HSE)->search_index) 35 | struct hs_index { 36 | uint16_t size; 37 | int16_t index[]; 38 | }; 39 | #else 40 | #define HEATSHRINK_ENCODER_WINDOW_BITS(_) \ 41 | (HEATSHRINK_STATIC_WINDOW_BITS) 42 | #define HEATSHRINK_ENCODER_LOOKAHEAD_BITS(_) \ 43 | (HEATSHRINK_STATIC_LOOKAHEAD_BITS) 44 | #define HEATSHRINK_ENCODER_INDEX(HSE) \ 45 | (&(HSE)->search_index) 46 | struct hs_index { 47 | uint16_t size; 48 | int16_t index[2 << HEATSHRINK_STATIC_WINDOW_BITS]; 49 | }; 50 | #endif 51 | 52 | typedef struct { 53 | uint16_t input_size; /* bytes in input buffer */ 54 | uint16_t match_scan_index; 55 | uint16_t match_length; 56 | uint16_t match_pos; 57 | uint16_t outgoing_bits; /* enqueued outgoing bits */ 58 | uint8_t outgoing_bits_count; 59 | uint8_t flags; 60 | uint8_t state; /* current state machine node */ 61 | uint8_t current_byte; /* current byte of output */ 62 | uint8_t bit_index; /* current bit index */ 63 | #if HEATSHRINK_DYNAMIC_ALLOC 64 | uint8_t window_sz2; /* 2^n size of window */ 65 | uint8_t lookahead_sz2; /* 2^n size of lookahead */ 66 | #if HEATSHRINK_USE_INDEX 67 | struct hs_index *search_index; 68 | #endif 69 | /* input buffer and / sliding window for expansion */ 70 | uint8_t buffer[]; 71 | #else 72 | #if HEATSHRINK_USE_INDEX 73 | struct hs_index search_index; 74 | #endif 75 | /* input buffer and / sliding window for expansion */ 76 | uint8_t buffer[2 << HEATSHRINK_ENCODER_WINDOW_BITS(_)]; 77 | #endif 78 | } heatshrink_encoder; 79 | 80 | #if HEATSHRINK_DYNAMIC_ALLOC 81 | /* Allocate a new encoder struct and its buffers. 82 | * Returns NULL on error. */ 83 | heatshrink_encoder *heatshrink_encoder_alloc(uint8_t window_sz2, 84 | uint8_t lookahead_sz2); 85 | 86 | /* Free an encoder. */ 87 | void heatshrink_encoder_free(heatshrink_encoder *hse); 88 | #endif 89 | 90 | /* Reset an encoder. */ 91 | void heatshrink_encoder_reset(heatshrink_encoder *hse); 92 | 93 | /* Sink up to SIZE bytes from IN_BUF into the encoder. 94 | * INPUT_SIZE is set to the number of bytes actually sunk (in case a 95 | * buffer was filled.). */ 96 | HSE_sink_res heatshrink_encoder_sink(heatshrink_encoder *hse, 97 | uint8_t *in_buf, size_t size, size_t *input_size); 98 | 99 | /* Poll for output from the encoder, copying at most OUT_BUF_SIZE bytes into 100 | * OUT_BUF (setting *OUTPUT_SIZE to the actual amount copied). */ 101 | HSE_poll_res heatshrink_encoder_poll(heatshrink_encoder *hse, 102 | uint8_t *out_buf, size_t out_buf_size, size_t *output_size); 103 | 104 | /* Notify the encoder that the input stream is finished. 105 | * If the return value is HSER_FINISH_MORE, there is still more output, so 106 | * call heatshrink_encoder_poll and repeat. */ 107 | HSE_finish_res heatshrink_encoder_finish(heatshrink_encoder *hse); 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /libesphttpd/lib/heatshrink/test_heatshrink_static.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "heatshrink_encoder.h" 5 | #include "heatshrink_decoder.h" 6 | #include "greatest.h" 7 | 8 | #if HEATSHRINK_DYNAMIC_ALLOC 9 | #error HEATSHRINK_DYNAMIC_ALLOC must be false for static allocation test suite. 10 | #endif 11 | 12 | SUITE(integration); 13 | 14 | /* The majority of the tests are in test_heatshrink_dynamic, because that allows 15 | * instantiating encoders/decoders with different settings at run-time. */ 16 | 17 | static heatshrink_encoder hse; 18 | static heatshrink_decoder hsd; 19 | 20 | static void fill_with_pseudorandom_letters(uint8_t *buf, uint16_t size, uint32_t seed) { 21 | uint64_t rn = 9223372036854775783; /* prime under 2^64 */ 22 | for (int i=0; i 1) { 50 | printf("\n^^ COMPRESSING\n"); 51 | dump_buf("input", input, input_size); 52 | } 53 | 54 | uint32_t sunk = 0; 55 | uint32_t polled = 0; 56 | while (sunk < input_size) { 57 | ASSERT(heatshrink_encoder_sink(&hse, &input[sunk], input_size - sunk, &count) >= 0); 58 | sunk += count; 59 | if (log_lvl > 1) printf("^^ sunk %zd\n", count); 60 | if (sunk == input_size) { 61 | ASSERT_EQ(HSER_FINISH_MORE, heatshrink_encoder_finish(&hse)); 62 | } 63 | 64 | HSE_poll_res pres; 65 | do { /* "turn the crank" */ 66 | pres = heatshrink_encoder_poll(&hse, &comp[polled], comp_sz - polled, &count); 67 | ASSERT(pres >= 0); 68 | polled += count; 69 | if (log_lvl > 1) printf("^^ polled %zd\n", count); 70 | } while (pres == HSER_POLL_MORE); 71 | ASSERT_EQ(HSER_POLL_EMPTY, pres); 72 | if (polled >= comp_sz) FAILm("compression should never expand that much"); 73 | if (sunk == input_size) { 74 | ASSERT_EQ(HSER_FINISH_DONE, heatshrink_encoder_finish(&hse)); 75 | } 76 | } 77 | if (log_lvl > 0) printf("in: %u compressed: %u ", input_size, polled); 78 | uint32_t compressed_size = polled; 79 | sunk = 0; 80 | polled = 0; 81 | 82 | if (log_lvl > 1) { 83 | printf("\n^^ DECOMPRESSING\n"); 84 | dump_buf("comp", comp, compressed_size); 85 | } 86 | while (sunk < compressed_size) { 87 | ASSERT(heatshrink_decoder_sink(&hsd, &comp[sunk], compressed_size - sunk, &count) >= 0); 88 | sunk += count; 89 | if (log_lvl > 1) printf("^^ sunk %zd\n", count); 90 | if (sunk == compressed_size) { 91 | ASSERT_EQ(HSDR_FINISH_MORE, heatshrink_decoder_finish(&hsd)); 92 | } 93 | 94 | HSD_poll_res pres; 95 | do { 96 | pres = heatshrink_decoder_poll(&hsd, &decomp[polled], 97 | decomp_sz - polled, &count); 98 | ASSERT(pres >= 0); 99 | polled += count; 100 | if (log_lvl > 1) printf("^^ polled %zd\n", count); 101 | } while (pres == HSDR_POLL_MORE); 102 | ASSERT_EQ(HSDR_POLL_EMPTY, pres); 103 | if (sunk == compressed_size) { 104 | HSD_finish_res fres = heatshrink_decoder_finish(&hsd); 105 | ASSERT_EQ(HSDR_FINISH_DONE, fres); 106 | } 107 | 108 | if (polled > input_size) { 109 | FAILm("Decompressed data is larger than original input"); 110 | } 111 | } 112 | if (log_lvl > 0) printf("decompressed: %u\n", polled); 113 | if (polled != input_size) { 114 | FAILm("Decompressed length does not match original input length"); 115 | } 116 | 117 | if (log_lvl > 1) dump_buf("decomp", decomp, polled); 118 | for (size_t i=0; i out[%zd] == 0x%02x ('%c')\n", 124 | j, input[j], isprint(input[j]) ? input[j] : '.', 125 | j, decomp[j], isprint(decomp[j]) ? decomp[j] : '.'); 126 | } 127 | } 128 | } 129 | ASSERT_EQ(input[i], decomp[i]); 130 | } 131 | free(comp); 132 | free(decomp); 133 | PASS(); 134 | } 135 | 136 | TEST pseudorandom_data_should_match(uint32_t size, uint32_t seed) { 137 | uint8_t input[size]; 138 | fill_with_pseudorandom_letters(input, size, seed); 139 | return compress_and_expand_and_check(input, size, 0); 140 | } 141 | 142 | SUITE(integration) { 143 | #if __STDC_VERSION__ >= 19901L 144 | for (uint32_t size=1; size < 64*1024; size <<= 1) { 145 | if (GREATEST_IS_VERBOSE()) printf(" -- size %u\n", size); 146 | for (uint32_t seed=1; seed<=100; seed++) { 147 | if (GREATEST_IS_VERBOSE()) printf(" -- seed %u\n", seed); 148 | RUN_TESTp(pseudorandom_data_should_match, size, seed); 149 | } 150 | } 151 | #endif 152 | } 153 | 154 | /* Add all the definitions that need to be in the test runner's main file. */ 155 | GREATEST_MAIN_DEFS(); 156 | 157 | int main(int argc, char **argv) { 158 | GREATEST_MAIN_BEGIN(); /* command-line arguments, initialization. */ 159 | printf("INPUT_BUFFER_SIZE: %u\n", HEATSHRINK_STATIC_INPUT_BUFFER_SIZE); 160 | printf("WINDOW_BITS: %u\n", HEATSHRINK_STATIC_WINDOW_BITS); 161 | printf("LOOKAHEAD_BITS: %u\n", HEATSHRINK_STATIC_LOOKAHEAD_BITS); 162 | 163 | printf("sizeof(heatshrink_encoder): %zd\n", sizeof(heatshrink_encoder)); 164 | printf("sizeof(heatshrink_decoder): %zd\n", sizeof(heatshrink_decoder)); 165 | RUN_SUITE(integration); 166 | GREATEST_MAIN_END(); /* display results */ 167 | } 168 | -------------------------------------------------------------------------------- /libesphttpd/libesphttpd.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-ESP/f6e49a2c4132bdf364697d486b58d9062e72796b/libesphttpd/libesphttpd.a -------------------------------------------------------------------------------- /libesphttpd/libwebpages-espfs.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-ESP/f6e49a2c4132bdf364697d486b58d9062e72796b/libesphttpd/libwebpages-espfs.a -------------------------------------------------------------------------------- /libesphttpd/mkupgimg/.gitignore: -------------------------------------------------------------------------------- 1 | mkupgimg 2 | -------------------------------------------------------------------------------- /libesphttpd/mkupgimg/Makefile: -------------------------------------------------------------------------------- 1 | mkupgimg: mkupgimg.c 2 | $(CC) -o $@ $^ 3 | 4 | clean: 5 | rm -f mkupgimg 6 | -------------------------------------------------------------------------------- /libesphttpd/mkupgimg/mkupgimg.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | //Cygwin e.a. needs O_BINARY. Don't miscompile if it's not set. 11 | #ifndef O_BINARY 12 | #define O_BINARY 0 13 | #endif 14 | 15 | typedef struct __attribute__((packed)) { 16 | char magic[4]; 17 | char tag[28]; 18 | int32_t len1; 19 | int32_t len2; 20 | } Header; 21 | 22 | 23 | int openFile(char *file) { 24 | int r=open(file, O_RDONLY|O_BINARY); 25 | if (r<=0) { 26 | perror(file); 27 | exit(1); 28 | } 29 | return r; 30 | } 31 | 32 | int32_t intToEsp(int32_t v) { 33 | int32_t ret; 34 | char *p=(char*)&ret; 35 | *p++=(v>>0)&0xff; 36 | *p++=(v>>8)&0xff; 37 | *p++=(v>>16)&0xff; 38 | *p++=(v>>24)&0xff; 39 | return ret; 40 | } 41 | 42 | size_t fileLen(int f) { 43 | size_t r; 44 | r=lseek(f, 0, SEEK_END); 45 | lseek(f, 0, SEEK_SET); 46 | return r; 47 | } 48 | 49 | 50 | int main(int argc, char **argv) { 51 | int u1, u2; 52 | size_t l1, l2; 53 | int of; 54 | char *fc1, *fc2; 55 | Header hdr; 56 | if (argc!=5) { 57 | printf("Usage: %s user1.bin user2.bin tagname outfile.bin\n", argv[0]); 58 | exit(1); 59 | } 60 | if (strlen(argv[3])>27) { 61 | printf("Error: Tag can't be longer than 27 characters.\n"); 62 | exit(1); 63 | } 64 | memset(&hdr, 0, sizeof(hdr)); 65 | memcpy(hdr.magic, "EHUG", 4); 66 | strcpy(hdr.tag, argv[3]); 67 | u1=openFile(argv[1]); 68 | u2=openFile(argv[2]); 69 | l1=fileLen(u1); 70 | l2=fileLen(u2); 71 | hdr.len1=intToEsp(l1); 72 | hdr.len2=intToEsp(l2); 73 | fc1=malloc(l1); 74 | fc2=malloc(l2); 75 | if (read(u1, fc1, l1)!=l1) { 76 | perror(argv[1]); 77 | exit(1); 78 | } 79 | if (read(u2, fc2, l2)!=l2) { 80 | perror(argv[2]); 81 | exit(1); 82 | } 83 | close(u1); 84 | close(u2); 85 | of=open(argv[4], O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666); 86 | if (of<=0) { 87 | perror(argv[4]); 88 | exit(1); 89 | } 90 | write(of, &hdr, sizeof(hdr)); 91 | write(of, fc1, l1); 92 | write(of, fc2, l2); 93 | printf("Header: %ld bytes, user1: %d bytes, user2: %d bytes.\n", sizeof(hdr), (int)l1, (int)l2); 94 | close(of); 95 | exit(0); 96 | } 97 | 98 | -------------------------------------------------------------------------------- /libesphttpd/webpages.espfs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-ESP/f6e49a2c4132bdf364697d486b58d9062e72796b/libesphttpd/webpages.espfs -------------------------------------------------------------------------------- /libesphttpd/webpages.espfs.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_FORMAT("elf32-xtensa-le") 2 | 3 | 4 | SECTIONS 5 | { 6 | .irom0.literal : ALIGN(4) SUBALIGN(4) { 7 | webpages_espfs_start = .; 8 | *(*) 9 | webpages_espfs_end = .; 10 | webpages_espfs_size = webpages_espfs_end - webpages_espfs_start; 11 | } 12 | } -------------------------------------------------------------------------------- /parallax-unused/IP_Loader.h: -------------------------------------------------------------------------------- 1 | static uint8_t rawLoaderImage[] = { 2 | /* 0000 */ 0x00,0xB4,0xC4,0x04,0x6F,0x93,0x10,0x00,0x88,0x01,0x90,0x01,0x80,0x01,0x94,0x01, 3 | /* 0010 */ 0x78,0x01,0x02,0x00,0x70,0x01,0x00,0x00,0x4D,0xE8,0xBF,0xA0,0x4D,0xEC,0xBF,0xA0, 4 | /* 0020 */ 0x51,0xB8,0xBC,0xA1,0x01,0xB8,0xFC,0x28,0xF1,0xB9,0xBC,0x80,0xA0,0xB6,0xCC,0xA0, 5 | /* 0030 */ 0x51,0xB8,0xBC,0xF8,0xF2,0x99,0x3C,0x61,0x05,0xB6,0xFC,0xE4,0x59,0x24,0xFC,0x54, 6 | /* 0040 */ 0x62,0xB4,0xBC,0xA0,0x02,0xBC,0xFC,0xA0,0x51,0xB8,0xBC,0xA0,0xF1,0xB9,0xBC,0x80, 7 | /* 0050 */ 0x04,0xBE,0xFC,0xA0,0x08,0xC0,0xFC,0xA0,0x51,0xB8,0xBC,0xF8,0x4D,0xE8,0xBF,0x64, 8 | /* 0060 */ 0x01,0xB2,0xFC,0x21,0x51,0xB8,0xBC,0xF8,0x4D,0xE8,0xBF,0x70,0x12,0xC0,0xFC,0xE4, 9 | /* 0070 */ 0x51,0xB8,0xBC,0xF8,0x4D,0xE8,0xBF,0x68,0x0F,0xBE,0xFC,0xE4,0x48,0x24,0xBC,0x80, 10 | /* 0080 */ 0x0E,0xBC,0xFC,0xE4,0x52,0xA2,0xBC,0xA0,0x54,0x44,0xFC,0x50,0x61,0xB4,0xFC,0xA0, 11 | /* 0090 */ 0x5A,0x5E,0xBC,0x54,0x5A,0x60,0xBC,0x54,0x5A,0x62,0xBC,0x54,0x04,0xBE,0xFC,0xA0, 12 | /* 00a0 */ 0x54,0xB6,0xBC,0xA0,0x53,0xB8,0xBC,0xA1,0x00,0xBA,0xFC,0xA0,0x80,0xBA,0xFC,0x72, 13 | /* 00b0 */ 0xF2,0x99,0x3C,0x61,0x25,0xB6,0xF8,0xE4,0x36,0x00,0x78,0x5C,0xF1,0xB9,0xBC,0x80, 14 | /* 00c0 */ 0x51,0xB8,0xBC,0xF8,0xF2,0x99,0x3C,0x61,0x00,0xBB,0xFC,0x70,0x01,0xBA,0xFC,0x29, 15 | /* 00d0 */ 0x2A,0x00,0x4C,0x5C,0xFF,0xC2,0xFC,0x64,0x5D,0xC2,0xBC,0x68,0x08,0xC2,0xFC,0x20, 16 | /* 00e0 */ 0x55,0x44,0xFC,0x50,0x22,0xBE,0xFC,0xE4,0x01,0xB4,0xFC,0x80,0x1E,0x00,0x7C,0x5C, 17 | /* 00f0 */ 0x22,0xB6,0xBC,0xA0,0xFF,0xB7,0xFC,0x60,0x54,0xB6,0x7C,0x86,0x00,0x8E,0x68,0x0C, 18 | /* 0100 */ 0x59,0xC2,0x3C,0xC2,0x09,0x00,0x54,0x5C,0x01,0xB2,0xFC,0xC1,0x63,0x00,0x70,0x5C, 19 | /* 0110 */ 0x63,0xB4,0xFC,0x84,0x45,0xC6,0x3C,0x08,0x04,0x8A,0xFC,0x80,0x48,0x7E,0xBC,0x80, 20 | /* 0120 */ 0x3F,0xB4,0xFC,0xE4,0x63,0x7E,0xFC,0x54,0x09,0x00,0x7C,0x5C,0x00,0x00,0x00,0x00, 21 | /* 0130 */ 0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x80,0x00,0x00, 22 | /* 0140 */ 0xFF,0xFF,0xF9,0xFF,0x10,0xC0,0x07,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x40, 23 | /* 0150 */ 0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x10,0x07,0x00,0x00,0x00,0xB6,0x02,0x00,0x00, 24 | /* 0160 */ 0x56,0x00,0x00,0x00,0x82,0x00,0x00,0x00,0x55,0x73,0xCB,0x00,0x18,0x51,0x00,0x00, 25 | /* 0170 */ 0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 26 | /* 0350 */ 0x35,0xC7,0x08,0x35,0x2C,0x32,0x00,0x00}; 27 | 28 | static uint8_t verifyRAM[] = { 29 | /* 0184 */ 0x49,0xBC,0xBC,0xA0,0x45,0xBC,0xBC,0x84,0x02,0xBC,0xFC,0x2A,0x45,0x8C,0x14,0x08, 30 | /* 0194 */ 0x04,0x8A,0xD4,0x80,0x66,0xBC,0xD4,0xE4,0x0A,0xBC,0xFC,0x04,0x04,0xBC,0xFC,0x84, 31 | /* 01a4 */ 0x5E,0x94,0x3C,0x08,0x04,0xBC,0xFC,0x84,0x5E,0x94,0x3C,0x08,0x01,0x8A,0xFC,0x84, 32 | /* 01b4 */ 0x45,0xBE,0xBC,0x00,0x5F,0x8C,0xBC,0x80,0x6E,0x8A,0x7C,0xE8,0x46,0xB2,0xBC,0xA4, 33 | /* 01c4 */ 0x09,0x00,0x7C,0x5C}; 34 | 35 | static uint8_t programVerifyEEPROM[] = { 36 | /* 01cc */ 0x03,0x8C,0xFC,0x2C,0x4F,0xEC,0xBF,0x68,0x82,0x18,0xFD,0x5C,0x40,0xBE,0xFC,0xA0, 37 | /* 01dc */ 0x45,0xBA,0xBC,0x00,0xA0,0x62,0xFD,0x5C,0x79,0x00,0x70,0x5C,0x01,0x8A,0xFC,0x80, 38 | /* 01ec */ 0x67,0xBE,0xFC,0xE4,0x8F,0x3E,0xFD,0x5C,0x49,0x8A,0x3C,0x86,0x65,0x00,0x54,0x5C, 39 | /* 01fc */ 0x00,0x8A,0xFC,0xA0,0x49,0xBE,0xBC,0xA0,0x7D,0x02,0xFD,0x5C,0xA3,0x62,0xFD,0x5C, 40 | /* 020c */ 0x45,0xC0,0xBC,0x00,0x5D,0xC0,0x3C,0x86,0x79,0x00,0x54,0x5C,0x01,0x8A,0xFC,0x80, 41 | /* 021c */ 0x72,0xBE,0xFC,0xE4,0x01,0x8C,0xFC,0x28,0x8F,0x3E,0xFD,0x5C,0x01,0x8C,0xFC,0x28, 42 | /* 022c */ 0x46,0xB2,0xBC,0xA4,0x09,0x00,0x7C,0x5C,0x82,0x18,0xFD,0x5C,0xA1,0xBA,0xFC,0xA0, 43 | /* 023c */ 0x8D,0x62,0xFD,0x5C,0x79,0x00,0x70,0x5C,0x00,0x00,0x7C,0x5C,0xFF,0xBD,0xFC,0xA0, 44 | /* 024c */ 0xA0,0xBA,0xFC,0xA0,0x8D,0x62,0xFD,0x5C,0x83,0xBC,0xF0,0xE4,0x45,0xBA,0x8C,0xA0, 45 | /* 025c */ 0x08,0xBA,0xCC,0x28,0xA0,0x62,0xCD,0x5C,0x45,0xBA,0x8C,0xA0,0xA0,0x62,0xCD,0x5C, 46 | /* 026c */ 0x79,0x00,0x70,0x5C,0x00,0x00,0x7C,0x5C,0x47,0x8E,0x3C,0x62,0x90,0x00,0x7C,0x5C, 47 | /* 027c */ 0x47,0x8E,0x3C,0x66,0x09,0xC0,0xFC,0xA0,0x58,0xB8,0xBC,0xA0,0xF1,0xB9,0xBC,0x80, 48 | /* 028c */ 0x4F,0xE8,0xBF,0x64,0x4E,0xEC,0xBF,0x78,0x56,0xB8,0xBC,0xF8,0x4F,0xE8,0xBF,0x68, 49 | /* 029c */ 0xF2,0x9D,0x3C,0x61,0x56,0xB8,0xBC,0xF8,0x4E,0xEC,0xBB,0x7C,0x00,0xB8,0xF8,0xF8, 50 | /* 02ac */ 0xF2,0x9D,0x28,0x61,0x91,0xC0,0xCC,0xE4,0x79,0x00,0x44,0x5C,0x7B,0x00,0x48,0x5C, 51 | /* 02bc */ 0x00,0x00,0x68,0x5C,0x01,0xBA,0xFC,0x2C,0x01,0xBA,0xFC,0x68,0xA4,0x00,0x7C,0x5C, 52 | /* 02cc */ 0xFE,0xBB,0xFC,0xA0,0x09,0xC0,0xFC,0xA0,0x58,0xB8,0xBC,0xA0,0xF1,0xB9,0xBC,0x80, 53 | /* 02dc */ 0x4F,0xE8,0xBF,0x64,0x00,0xBB,0x7C,0x62,0x01,0xBA,0xFC,0x34,0x4E,0xEC,0xBF,0x78, 54 | /* 02ec */ 0x57,0xB8,0xBC,0xF8,0x4F,0xE8,0xBF,0x68,0xF2,0x9D,0x3C,0x61,0x58,0xB8,0xBC,0xF8, 55 | /* 02fc */ 0xA7,0xC0,0xFC,0xE4,0xFF,0xBA,0xFC,0x60,0x00,0x00,0x7C,0x5C}; 56 | 57 | static uint8_t readyToLaunch[] = { 58 | /* 030c */ 0xB8,0x72,0xFC,0x58,0x66,0x72,0xFC,0x50,0x09,0x00,0x7C,0x5C,0x06,0xBE,0xFC,0x04, 59 | /* 031c */ 0x10,0xBE,0x7C,0x86,0x00,0x8E,0x54,0x0C,0x04,0xBE,0xFC,0x00,0x78,0xBE,0xFC,0x60, 60 | /* 032c */ 0x50,0xBE,0xBC,0x68,0x00,0xBE,0x7C,0x0C,0x40,0xAE,0xFC,0x2C,0x6E,0xAE,0xFC,0xE4, 61 | /* 033c */ 0x04,0xBE,0xFC,0x00,0x00,0xBE,0x7C,0x0C,0x02,0x96,0x7C,0x0C}; 62 | 63 | static uint8_t launchNow[] = { 64 | /* 034c */ 0x66,0x00,0x7C,0x5C}; 65 | 66 | -------------------------------------------------------------------------------- /parallax-unused/propimage.c: -------------------------------------------------------------------------------- 1 | /* 2 | propimage.c - support for the Parallax Propeller binary images 3 | 4 | Copyright (c) 2016 Parallax Inc. 5 | See the file LICENSE.txt for licensing information. 6 | */ 7 | 8 | #include "propimage.h" 9 | 10 | #define OFFSET_OF(_s, _f) ((int)&((_s *)0)->_f) 11 | 12 | void ICACHE_FLASH_ATTR pimageSetImage(PropellerImage *image, uint8_t *imageData, int imageSize) 13 | { 14 | image->imageData = imageData; 15 | image->imageSize = imageSize; 16 | } 17 | 18 | uint32_t ICACHE_FLASH_ATTR pimageClkFreq(PropellerImage *image) 19 | { 20 | return pimageGetLong(image, OFFSET_OF(SpinHdr, clkfreq)); 21 | } 22 | 23 | void ICACHE_FLASH_ATTR pimageSetClkFreq(PropellerImage *image, uint32_t clkFreq) 24 | { 25 | pimageSetLong(image, OFFSET_OF(SpinHdr, clkfreq), clkFreq); 26 | } 27 | 28 | uint8_t ICACHE_FLASH_ATTR pimageClkMode(PropellerImage *image) 29 | { 30 | return pimageGetByte(image, OFFSET_OF(SpinHdr, clkmode)); 31 | } 32 | 33 | void ICACHE_FLASH_ATTR pimageSetClkMode(PropellerImage *image, uint8_t clkMode) 34 | { 35 | pimageSetByte(image, OFFSET_OF(SpinHdr, clkmode), clkMode); 36 | } 37 | 38 | uint8_t ICACHE_FLASH_ATTR pimageUpdateChecksum(PropellerImage *image) 39 | { 40 | SpinHdr *spinHdr = (SpinHdr *)image->imageData; 41 | uint8_t *p = image->imageData; 42 | int chksum, cnt; 43 | spinHdr->chksum = chksum = 0; 44 | for (cnt = image->imageSize; --cnt >= 0; ) 45 | chksum += *p++; 46 | spinHdr->chksum = SPIN_TARGET_CHECKSUM - chksum; 47 | return chksum & 0xff; 48 | } 49 | 50 | uint8_t ICACHE_FLASH_ATTR pimageGetByte(PropellerImage *image, int offset) 51 | { 52 | uint8_t *buf = image->imageData + offset; 53 | return buf[0]; 54 | } 55 | 56 | void ICACHE_FLASH_ATTR pimageSetByte(PropellerImage *image, int offset, uint8_t value) 57 | { 58 | uint8_t *buf = image->imageData + offset; 59 | buf[0] = value; 60 | } 61 | 62 | uint16_t ICACHE_FLASH_ATTR pimageGetWord(PropellerImage *image, int offset) 63 | { 64 | uint8_t *buf = image->imageData + offset; 65 | return (buf[1] << 8) | buf[0]; 66 | } 67 | 68 | void ICACHE_FLASH_ATTR pimageSetWord(PropellerImage *image, int offset, uint16_t value) 69 | { 70 | uint8_t *buf = image->imageData + offset; 71 | buf[1] = value >> 8; 72 | buf[0] = value; 73 | } 74 | 75 | uint32_t ICACHE_FLASH_ATTR pimageGetLong(PropellerImage *image, int offset) 76 | { 77 | uint8_t *buf = image->imageData + offset; 78 | return (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; 79 | } 80 | 81 | void ICACHE_FLASH_ATTR pimageSetLong(PropellerImage *image, int offset, uint32_t value) 82 | { 83 | uint8_t *buf = image->imageData + offset; 84 | buf[3] = value >> 24; 85 | buf[2] = value >> 16; 86 | buf[1] = value >> 8; 87 | buf[0] = value; 88 | } 89 | 90 | -------------------------------------------------------------------------------- /parallax-unused/propimage.h: -------------------------------------------------------------------------------- 1 | /* 2 | propimage.h - definitions for the Parallax Propeller binary images 3 | 4 | Copyright (c) 2016 Parallax Inc. 5 | See the file LICENSE.txt for licensing information. 6 | */ 7 | 8 | #ifndef PROPIMAGE_H 9 | #define PROPIMAGE_H 10 | 11 | //#include 12 | #include "os_type.h" 13 | 14 | /* target checksum for a binary file */ 15 | #define SPIN_TARGET_CHECKSUM 0x14 16 | 17 | /* spin object file header */ 18 | typedef struct { 19 | uint32_t clkfreq; 20 | uint8_t clkmode; 21 | uint8_t chksum; 22 | uint16_t pbase; 23 | uint16_t vbase; 24 | uint16_t dbase; 25 | uint16_t pcurr; 26 | uint16_t dcurr; 27 | } SpinHdr; 28 | 29 | typedef struct { 30 | uint8_t *imageData; 31 | int imageSize; 32 | } PropellerImage; 33 | 34 | void pimageSetImage(PropellerImage *image, uint8_t *imageData, int imageSize); 35 | uint32_t pimageClkFreq(PropellerImage *image); 36 | void pimageSetClkFreq(PropellerImage *image, uint32_t clkFreq); 37 | uint8_t pimageClkMode(PropellerImage *image); 38 | void pimageSetClkMode(PropellerImage *image, uint8_t clkMode); 39 | uint8_t pimageUpdateChecksum(PropellerImage *image); 40 | uint8_t pimageGetByte(PropellerImage *image, int offset); 41 | void pimageSetByte(PropellerImage *image, int offset, uint8_t value); 42 | uint16_t pimageGetWord(PropellerImage *image, int offset); 43 | void pimageSetWord(PropellerImage *image, int offset, uint16_t value); 44 | uint32_t pimageGetLong(PropellerImage *image, int offset); 45 | void pimageSetLong(PropellerImage *image, int offset, uint32_t value); 46 | 47 | #endif 48 | 49 | -------------------------------------------------------------------------------- /parallax/cgiprop.h: -------------------------------------------------------------------------------- 1 | /* 2 | cgiprop.h - definitions for HTTP requests related to the Parallax Propeller 3 | 4 | Copyright (c) 2016 Parallax Inc. 5 | See the file LICENSE.txt for licensing information. 6 | */ 7 | 8 | #ifndef CGIPROP_H 9 | #define CGIPROP_H 10 | 11 | #include 12 | 13 | int cgiPropInit(); 14 | int cgiPropVersion(HttpdConnData *connData); 15 | int cgiPropLoad(HttpdConnData *connData); 16 | int cgiPropLoadFile(HttpdConnData *connData); 17 | int cgiPropLoadP1File(HttpdConnData *connData); 18 | int cgiPropLoadP2File(HttpdConnData *connData); 19 | int cgiPropReset(HttpdConnData *connData); 20 | 21 | void httpdSendResponse(HttpdConnData *connData, int code, char *message, int len); 22 | 23 | int IsAutoLoadEnabled(void); 24 | int IsAutoLoadEnabledOnly(void); 25 | 26 | #endif 27 | 28 | -------------------------------------------------------------------------------- /parallax/discovery.c: -------------------------------------------------------------------------------- 1 | /* 2 | discovery.c - support for the Parallax WX module discovery protocol 3 | 4 | Copyright (c) 2016 Parallax Inc. 5 | See the file LICENSE.txt for licensing information. 6 | */ 7 | 8 | #include 9 | #include "config.h" 10 | #include "discovery.h" 11 | 12 | #define DISCOVER_PORT 32420 13 | 14 | static struct espconn discoverConn; 15 | static esp_udp discoverUdp; 16 | 17 | static void ICACHE_FLASH_ATTR sentCallback(void *arg) 18 | { 19 | struct espconn *conn = (struct espconn *)arg; 20 | int *pDone = (int *)conn->reverse; 21 | *pDone = 1; 22 | // os_printf("Send completed\n"); 23 | } 24 | 25 | static void ICACHE_FLASH_ATTR discoverRecvCallback(void *arg, char *data, unsigned short len) 26 | { 27 | struct espconn *conn = (struct espconn *)arg; 28 | remot_info *remoteInfo; 29 | struct espconn responseConn; 30 | esp_udp responseUdp; 31 | uint32_t *rxNext; 32 | uint32_t myAddress = (conn->proto.udp->local_ip[3] << 24) 33 | | (conn->proto.udp->local_ip[2] << 16) 34 | | (conn->proto.udp->local_ip[1] << 8) 35 | | conn->proto.udp->local_ip[0]; 36 | struct ip_info info; 37 | uint8 macAddr[6]; 38 | 39 | #if 0 40 | os_printf("DISCOVER: myAddress %d.%d.%d.%d\n", conn->proto.udp->local_ip[0], 41 | conn->proto.udp->local_ip[1], 42 | conn->proto.udp->local_ip[2], 43 | conn->proto.udp->local_ip[3]); 44 | #endif 45 | 46 | // check to see if we already replied to this request 47 | if (flashConfig.sscp_loader != 0) 48 | return; 49 | 50 | rxNext = (uint32_t *)data; 51 | if (len > sizeof(uint32_t)) { 52 | if (*rxNext++ != 0) { 53 | os_printf("DISCOVER: received a bogus discover request\n"); 54 | return; 55 | } 56 | len -= sizeof(uint32_t); 57 | while (len >= sizeof(uint32_t)) { 58 | #if 0 59 | os_printf("DISCOVER: Checking %d.%d.%d.%d\n", (int)( *rxNext & 0xff), 60 | (int)((*rxNext >> 8) & 0xff), 61 | (int)((*rxNext >> 16) & 0xff), 62 | (int)((*rxNext >> 24) & 0xff)); 63 | #endif 64 | if (*rxNext++ == myAddress) { 65 | // os_printf("DISCOVER: already replied\n"); 66 | return; 67 | } 68 | len -= sizeof(uint32_t); 69 | } 70 | } 71 | 72 | // insert a random delay to avoid udp packet collisions from multiple modules 73 | os_delay_us(10000 + (unsigned)os_random() % 50000); 74 | 75 | if (espconn_get_connection_info(conn, &remoteInfo, 0) != 0) { 76 | os_printf("DISCOVER: espconn_get_connection_info failed\n"); 77 | return; 78 | } 79 | 80 | os_memset(&responseConn, 0, sizeof(responseConn)); 81 | responseConn.type = ESPCONN_UDP; 82 | responseConn.state = ESPCONN_NONE; 83 | responseConn.proto.udp = &responseUdp; 84 | os_memcpy(responseConn.proto.udp->remote_ip, remoteInfo->remote_ip, 4); 85 | responseConn.proto.udp->remote_port = remoteInfo->remote_port; 86 | 87 | if (wifi_get_ip_info(STATION_IF, &info) && info.ip.addr == myAddress) 88 | wifi_get_macaddr(STATION_IF, macAddr); 89 | else if (wifi_get_ip_info(SOFTAP_IF, &info) && info.ip.addr == myAddress) 90 | wifi_get_macaddr(SOFTAP_IF, macAddr); 91 | else 92 | memset(macAddr, 0, sizeof(macAddr)); 93 | 94 | if (espconn_create(&responseConn) == 0) { 95 | char buf[1024]; 96 | volatile int done = 0; 97 | int retries = 100; 98 | int len = os_sprintf(buf, 99 | "{ " 100 | "\"name\": \"%s\", " 101 | "\"description\": \"%s\", " 102 | "\"reset pin\": \"%d\", " 103 | "\"rx pullup\": \"%s\", " 104 | "\"mac address\": \"%02x:%02x:%02x:%02x:%02x:%02x\"" 105 | " }\n", 106 | flashConfig.module_name, 107 | flashConfig.module_descr, 108 | flashConfig.reset_pin, 109 | flashConfig.rx_pullup ? "enabled" : "disabled", 110 | macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]); 111 | // os_printf("Sending %d byte discover response: %s", len, buf); 112 | espconn_regist_sentcb(&responseConn, sentCallback); 113 | responseConn.reverse = (int *)&done; 114 | espconn_send(&responseConn, (uint8 *)buf, len); 115 | // os_printf("Waiting for send to complete\n"); 116 | while (!done && --retries >= 0) 117 | os_delay_us(10000); 118 | if (!done) 119 | os_printf("DISCOVER: failed to send discovery response\n"); 120 | // os_printf("Done waiting for send to complete\n"); 121 | espconn_delete(&responseConn); 122 | } 123 | } 124 | 125 | void ICACHE_FLASH_ATTR initDiscovery(void) 126 | { 127 | discoverConn.type = ESPCONN_UDP; 128 | discoverConn.state = ESPCONN_NONE; 129 | discoverUdp.local_port = DISCOVER_PORT; 130 | discoverConn.proto.udp = &discoverUdp; 131 | 132 | if (espconn_create(&discoverConn) != 0) { 133 | os_printf("DISCOVER: espconn_create failed\n"); 134 | return; 135 | } 136 | 137 | if (espconn_regist_recvcb(&discoverConn, discoverRecvCallback) != 0) { 138 | os_printf("DISCOVER: espconn_regist_recvcb failed\n"); 139 | return; 140 | } 141 | 142 | os_printf("DISCOVER: initialized\n"); 143 | } 144 | -------------------------------------------------------------------------------- /parallax/discovery.h: -------------------------------------------------------------------------------- 1 | /* 2 | discovery.h - definitions for the Parallax WX module discovery protocol 3 | 4 | Copyright (c) 2016 Parallax Inc. 5 | See the file LICENSE.txt for licensing information. 6 | */ 7 | 8 | #ifndef DISCOVERY_H 9 | #define DISCOVERY_H 10 | 11 | void initDiscovery(void); 12 | 13 | #endif 14 | 15 | -------------------------------------------------------------------------------- /parallax/httpdroffs.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 Parallax Inc. 3 | See the file LICENSE.txt for licensing information. 4 | 5 | Derived from: 6 | 7 | Connector to let httpd use the espfs filesystem to serve the files in it. 8 | */ 9 | 10 | /* 11 | * ---------------------------------------------------------------------------- 12 | * "THE BEER-WARE LICENSE" (Revision 42): 13 | * Jeroen Domburg wrote this file. As long as you retain 14 | * this notice you can do whatever you want with this stuff. If we meet some day, 15 | * and you think this stuff is worth it, you can buy me a beer in return. 16 | * ---------------------------------------------------------------------------- 17 | * Modified and enhanced by Thorsten von Eicken in 2015 18 | * ---------------------------------------------------------------------------- 19 | */ 20 | #ifndef HTTPDROFFS_H 21 | #define HTTPDROFFS_H 22 | 23 | #include 24 | #include "httpd.h" 25 | 26 | int cgiRoffsHook(HttpdConnData *connData); 27 | int cgiRoffsFormat(HttpdConnData *connData); 28 | int cgiRoffsWriteFile(HttpdConnData *connData); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /parallax/mkroffsimage/Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(CROSS),win32) 2 | PREFIX=i586-mingw32msvc- 3 | EXT=.exe 4 | endif 5 | 6 | CC=$(PREFIX)gcc 7 | 8 | GZIP_COMPRESSION ?= no 9 | 10 | CFLAGS=-I.. -std=gnu99 11 | ifeq ("$(GZIP_COMPRESSION)","yes") 12 | CFLAGS += -DESPFS_GZIP 13 | endif 14 | 15 | OBJS=mkroffsimage.o 16 | TARGET=mkroffsimage$(EXT) 17 | 18 | $(TARGET): $(OBJS) 19 | ifeq ("$(GZIP_COMPRESSION)","yes") 20 | $(CC) -o $@ $^ -lz 21 | else 22 | $(CC) -o $@ $^ 23 | endif 24 | 25 | clean: 26 | rm -f $(TARGET) $(OBJS) 27 | -------------------------------------------------------------------------------- /parallax/mkroffsimage/README.txt: -------------------------------------------------------------------------------- 1 | Use mingw32-make to build under MinGW-W64. 2 | -------------------------------------------------------------------------------- /parallax/proploader.h: -------------------------------------------------------------------------------- 1 | /* 2 | proploader.h - definitions for the Parallax Propeller binary image loader 3 | 4 | Copyright (c) 2016 Parallax Inc. 5 | See the file LICENSE.txt for licensing information. 6 | */ 7 | 8 | #ifndef PROPLOADER_H 9 | #define PROPLOADER_H 10 | 11 | #include 12 | #include "os_type.h" 13 | #include "httpd.h" 14 | #include "roffs.h" 15 | 16 | //#define PROP_DBG 17 | 18 | #ifdef PROP_DBG 19 | #define DBG(format, ...) os_printf(format, ## __VA_ARGS__) 20 | #else 21 | #define DBG(format, ...) 22 | #endif 23 | 24 | typedef enum { 25 | ltShutdown = 0, 26 | ltDownloadAndRun = (1 << 0), 27 | ltDownloadAndProgram = (1 << 1), 28 | ltDownloadAndProgramAndRun = ltDownloadAndRun | ltDownloadAndProgram 29 | } LoadType; 30 | 31 | typedef enum { 32 | /* 0 */ stIdle, 33 | /* 1 */ stReset, 34 | /* 2 */ stTxHandshake, 35 | /* 3 */ stRxHandshakeStart, 36 | /* 4 */ stRxHandshake, 37 | /* 5 */ stLoadContinue, 38 | /* 6 */ stVerifyChecksum, 39 | /* 7 */ stStartAck, 40 | stMAX 41 | } LoadState; 42 | 43 | typedef enum { 44 | lsOK, 45 | lsAckResponse, 46 | lsFirstError, 47 | lsBusy = lsFirstError, 48 | lsFileNotFound, 49 | lsRXHandshakeTimeout, 50 | lsChecksumTimeout, 51 | lsStartAckTImeout, 52 | lsRXHandshakeFailed, 53 | lsWrongPropellerVersion, 54 | lsLoadImageFailed, 55 | lsChecksumError 56 | } LoadStatus; 57 | 58 | 59 | typedef enum { 60 | /* 0 */ ddoff, 61 | /* 1 */ dragdrop 62 | 63 | } P2LoaderMode; 64 | 65 | typedef struct PropellerConnection PropellerConnection; 66 | 67 | struct PropellerConnection { 68 | HttpdConnData *connData; 69 | ETSTimer timer; 70 | int resetPin; 71 | int baudRate; 72 | int finalBaudRate; 73 | int responseSize; 74 | int responseTimeout; 75 | LoadType loadType; 76 | ROFFS_FILE *file; // this is set for loading a file 77 | const uint8_t *image; // this is set for loading an image in memory 78 | int imageSize; 79 | int encodedSize; 80 | LoadState state; 81 | int retriesRemaining; 82 | int retryDelay; 83 | uint8_t buffer[125 + 4]; // sizeof(rxHandshake) + 4 84 | int bytesReceived; 85 | int bytesRemaining; 86 | int version; 87 | int p2LoaderMode; 88 | int st_load_segment_delay; 89 | int st_load_segment_max_size; 90 | int st_reset_delay_2; 91 | void (*completionCB)(PropellerConnection *connection, LoadStatus status); 92 | }; 93 | 94 | #define RESET_BUTTON_PIN 0 95 | #define RESET_BUTTON_SAMPLE_INTERVAL 5 96 | #define RESET_BUTTON_THRESHOLD 5 97 | #define RESET_BUTTON_PRESS_DELTA 500 98 | #define RESET_BUTTON_PRESS_DELTA_MAX 1000 99 | #define RESET_BUTTON_PRESS_COUNT 4 100 | #define RESET_BUTTON_PRESS_COUNT_OLED 3 101 | 102 | #define RESET_DELAY_1 10 103 | #define CALIBRATE_DELAY 10 104 | 105 | #define RX_HANDSHAKE_TIMEOUT 2000 106 | #define RX_CHECKSUM_TIMEOUT 250 107 | #define EEPROM_PROGRAM_TIMEOUT 5000 108 | #define EEPROM_VERIFY_TIMEOUT 2000 109 | 110 | LoadStatus loadBuffer(const uint8_t *image, int imageSize); 111 | LoadStatus loadFile(char *fileName); 112 | 113 | int ploadInitiateHandshake(PropellerConnection *connection); 114 | int ploadVerifyHandshakeResponse(PropellerConnection *connection); 115 | int ploadLoadImage(PropellerConnection *connection, LoadType loadType, int *pFinished); 116 | int ploadLoadImageContinue(PropellerConnection *connection, LoadType loadType, int *pFinished); 117 | 118 | void httpdSendResponse(HttpdConnData *connData, int code, char *message, int len); 119 | 120 | // P1 121 | #define P1_RESET_DELAY_2 100 122 | #define P1_LOAD_SEGMENT_DELAY 50 123 | #define P1_LOAD_SEGMENT_MAX_SIZE 1024 124 | 125 | 126 | // P2 127 | #define P2_RESET_DELAY_2 35 // 20 // Delay after reset pulse, allowing Propeller to perform the reset (P2 needs 15ms)) 128 | #define P2_LOAD_SEGMENT_DELAY 0 129 | #define P2_LOAD_SEGMENT_MAX_SIZE 1023 // multiple of 3 for base64 encoding 130 | 131 | 132 | #endif 133 | 134 | -------------------------------------------------------------------------------- /parallax/roffs.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 Parallax Inc. 3 | See the file LICENSE.txt for licensing information. 4 | 5 | Derived from: 6 | 7 | Connector to let httpd use the espfs filesystem to serve the files in it. 8 | */ 9 | 10 | /* 11 | * ---------------------------------------------------------------------------- 12 | * "THE BEER-WARE LICENSE" (Revision 42): 13 | * Jeroen Domburg wrote this file. As long as you retain 14 | * this notice you can do whatever you want with this stuff. If we meet some day, 15 | * and you think this stuff is worth it, you can buy me a beer in return. 16 | * ---------------------------------------------------------------------------- 17 | * Modified and enhanced by Thorsten von Eicken in 2015 18 | * ---------------------------------------------------------------------------- 19 | */ 20 | #ifndef __ROFFS_H__ 21 | #define __ROFFS_H__ 22 | 23 | #include 24 | 25 | /* must match definitions in roffsformat.h */ 26 | #define ROFFS_FLAG_GZIP (1<<1) 27 | 28 | #include "roffsformat.h" 29 | typedef struct ROFFS_FILE_STRUCT ROFFS_FILE; 30 | 31 | uint32_t roffs_base_address(uint32_t *pSize); 32 | int roffs_mount(uint32_t flashAddress, uint32_t flashSize); 33 | int roffs_format(uint32_t flashAddress); 34 | int roffs_filecount(int *pCount); 35 | int roffs_fileinfo(int index, char *fileName, int *pFileSize); 36 | ROFFS_FILE *roffs_open(const char *fileName); 37 | int roffs_file_size(ROFFS_FILE *file); 38 | int roffs_file_flags(ROFFS_FILE *file); 39 | int roffs_read(ROFFS_FILE *file, char *buf, int len); 40 | int roffs_close(ROFFS_FILE *file); 41 | 42 | ROFFS_FILE *roffs_create(const char *fileName); 43 | int roffs_write(ROFFS_FILE *file, char *buf, int len); 44 | 45 | #endif 46 | 47 | 48 | -------------------------------------------------------------------------------- /parallax/roffsformat.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 Parallax Inc. 3 | See the file LICENSE.txt for licensing information. 4 | 5 | Derived from: 6 | 7 | Connector to let httpd use the espfs filesystem to serve the files in it. 8 | */ 9 | 10 | /* 11 | * ---------------------------------------------------------------------------- 12 | * "THE BEER-WARE LICENSE" (Revision 42): 13 | * Jeroen Domburg wrote this file. As long as you retain 14 | * this notice you can do whatever you want with this stuff. If we meet some day, 15 | * and you think this stuff is worth it, you can buy me a beer in return. 16 | * ---------------------------------------------------------------------------- 17 | * Modified and enhanced by Thorsten von Eicken in 2015 18 | * ---------------------------------------------------------------------------- 19 | */ 20 | #ifndef ROFSFORMAT_H 21 | #define ROFSFORMAT_H 22 | 23 | /* 24 | Stupid cpio-like tool to make read-only 'filesystems' that live on the flash SPI chip of the module. 25 | Can (will) use lzf compression (when I come around to it) to make shit quicker. Aligns names, files, 26 | headers on 4-byte boundaries so the SPI abstraction hardware in the ESP8266 doesn't crap on itself 27 | when trying to do a <4byte or unaligned read. 28 | */ 29 | 30 | /* 31 | The idea 'borrows' from cpio: it's basically a concatenation of {header, filename, file} data. 32 | Header, filename and file data is 32-bit aligned. The last file is indicated by data-less header 33 | with the FLAG_LASTFILE flag set. 34 | */ 35 | 36 | 37 | #define FLAG_LASTFILE (1 << 0) 38 | #define FLAG_GZIP (1 << 1) 39 | #define FLAG_ACTIVE (1 << 2) 40 | #define FLAG_PENDING (1 << 3) 41 | #define COMPRESS_NONE 0 42 | #define ROFS_MAGIC ('R' | ('O' << 8) | ('f' << 16) | ('s' << 24)) 43 | 44 | typedef struct { 45 | int32_t magic; 46 | int8_t flags; 47 | int8_t compression; 48 | int16_t nameLen; 49 | int32_t fileLenComp; 50 | int32_t fileLenDecomp; 51 | } __attribute__((packed)) RoFsHeader; 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /parallax/sscp-fs.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sscp.h" 3 | #include "roffs.h" 4 | #include "proploader.h" 5 | 6 | // FINFO,n 7 | void ICACHE_FLASH_ATTR fs_do_finfo(int argc, char *argv[]) 8 | { 9 | char fileName[128]; 10 | int fileSize; 11 | 12 | if (argc != 2) { 13 | sscp_sendResponse("E,%d", SSCP_ERROR_WRONG_ARGUMENT_COUNT); 14 | return; 15 | } 16 | 17 | if (roffs_fileinfo(atoi(argv[1]), fileName, &fileSize) == 0) { 18 | sscp_sendResponse("S,%s,%d", fileName, fileSize); 19 | return; 20 | } 21 | 22 | sscp_sendResponse("N,0"); 23 | } 24 | 25 | // FCOUNT 26 | void ICACHE_FLASH_ATTR fs_do_fcount(int argc, char *argv[]) 27 | { 28 | int count; 29 | 30 | if (argc != 1) { 31 | sscp_sendResponse("E,%d", SSCP_ERROR_WRONG_ARGUMENT_COUNT); 32 | return; 33 | } 34 | 35 | if (roffs_filecount(&count) == 0) { 36 | sscp_sendResponse("S,%d", count); 37 | return; 38 | } 39 | 40 | sscp_sendResponse("N,0"); 41 | } 42 | 43 | // FRUN,name 44 | void ICACHE_FLASH_ATTR fs_do_frun(int argc, char *argv[]) 45 | { 46 | int sts; 47 | 48 | if (argc != 2) { 49 | sscp_sendResponse("E,%d", SSCP_ERROR_WRONG_ARGUMENT_COUNT); 50 | return; 51 | } 52 | 53 | if ((sts = loadFile(argv[1])) == lsOK) { 54 | sscp_sendResponse("S,0"); 55 | return; 56 | } 57 | 58 | sscp_sendResponse("N,%d", sts); 59 | } 60 | 61 | -------------------------------------------------------------------------------- /parallax/sscp-wifi.c: -------------------------------------------------------------------------------- 1 | /* this code is derived from the code in cgiwifi.c that is part of libhttpd */ 2 | 3 | #include 4 | #include "sscp.h" 5 | #include "cgiwifi.h" 6 | #include "config.h" 7 | 8 | static int scanDone = 0; 9 | static int scanCount; 10 | 11 | static void ICACHE_FLASH_ATTR send_scan_complete_event(int prefix) 12 | { 13 | sscp_send(prefix, "A,%d,0", scanCount); 14 | } 15 | 16 | static void ICACHE_FLASH_ATTR scan_complete(void *data, int count) 17 | { 18 | os_printf("scan done callback, found %d\n", count); 19 | 20 | scanCount = count; 21 | 22 | if (flashConfig.sscp_events) 23 | send_scan_complete_event('!'); 24 | else 25 | scanDone = 1; 26 | } 27 | 28 | int ICACHE_FLASH_ATTR wifi_check_for_events(void) 29 | { 30 | int sentEvent = 0; 31 | if (scanDone) { 32 | send_scan_complete_event('='); 33 | scanDone = 0; 34 | sentEvent = 1; 35 | } 36 | return sentEvent; 37 | } 38 | 39 | 40 | // Connect using credentials already in flash memory 41 | int ICACHE_FLASH_ATTR wifiJoinAuto(void) 42 | { 43 | struct station_config stconf; 44 | wifi_station_get_config(&stconf); 45 | 46 | os_printf("Calling wifiJoin on stored AP %s\n", (char*)stconf.ssid); 47 | return wifiJoin( (char*)stconf.ssid, (char*)stconf.password ); 48 | 49 | } 50 | 51 | 52 | // Get Credentials already in flash memory 53 | void ICACHE_FLASH_ATTR wifi_do_creget(int argc, char *argv[]) 54 | { 55 | if (argc != 1) { 56 | sscp_sendResponse("E,%d", SSCP_ERROR_WRONG_ARGUMENT_COUNT); 57 | return; 58 | } 59 | 60 | struct station_config stconf; 61 | wifi_station_get_config(&stconf); 62 | 63 | os_printf("Calling getCred on stored AP %s\n", (char*)stconf.ssid); 64 | 65 | sscp_sendResponse("S,%s,%s", (char*)stconf.ssid, (char*)stconf.password); 66 | 67 | 68 | } 69 | 70 | 71 | // APSCAN 72 | void ICACHE_FLASH_ATTR wifi_do_apscan(int argc, char *argv[]) 73 | { 74 | if (argc != 1) { 75 | sscp_sendResponse("E,%d", SSCP_ERROR_WRONG_ARGUMENT_COUNT); 76 | return; 77 | } 78 | 79 | scanDone = 0; 80 | 81 | if (cgiWiFiStartScan(scan_complete, NULL) == 1) { 82 | sscp_sendResponse("S,0"); 83 | } else { 84 | sscp_sendResponse("E,%d", SSCP_ERROR_BUSY); 85 | } 86 | } 87 | 88 | // APGET:index 89 | void ICACHE_FLASH_ATTR wifi_do_apget(int argc, char *argv[]) 90 | { 91 | int index; 92 | 93 | if (argc != 2) { 94 | sscp_sendResponse("E,%d", SSCP_ERROR_WRONG_ARGUMENT_COUNT); 95 | return; 96 | } 97 | 98 | index = atoi(argv[1]); 99 | 100 | os_printf("ENTRY:%d\n", index); 101 | 102 | if (!cgiWiFiScanDone()) 103 | sscp_sendResponse("N,0"); 104 | else { 105 | ApData *entry = cgiWiFiScanResult(index); 106 | if (entry) 107 | //sscp_sendResponse("S,%d,%s,%d", entry->enc, entry->ssid, entry->rssi); //Originally released with variable-length string as second-to-last field; inconsistent with rest of API 108 | sscp_sendResponse("S,%d,%d,%s", entry->enc, entry->rssi, entry->ssid); 109 | else 110 | sscp_sendResponse("E,%d", SSCP_ERROR_INVALID_ARGUMENT); 111 | } 112 | } 113 | 114 | -------------------------------------------------------------------------------- /parallax/sscp-ws.c: -------------------------------------------------------------------------------- 1 | /* 2 | sscp-ws.c - Simple Serial Command Protocol WebSockets support 3 | 4 | Copyright (c) 2016 Parallax Inc. 5 | See the file LICENSE.txt for licensing information. 6 | */ 7 | 8 | #include "esp8266.h" 9 | #include "sscp.h" 10 | #include "config.h" 11 | 12 | static void send_connect_event(sscp_connection *connection, int prefix); 13 | static void send_disconnect_event(sscp_connection *connection, int prefix); 14 | static void send_data_event(sscp_connection *connection, int prefix); 15 | static int checkForEvents_handler(sscp_hdr *hdr); 16 | static void path_handler(sscp_hdr *hdr); 17 | static void send_handler(sscp_hdr *hdr, int size); 18 | static void recv_handler(sscp_hdr *hdr, int size); 19 | static void close_handler(sscp_hdr *hdr); 20 | 21 | static sscp_dispatch wsDispatch = { 22 | .checkForEvents = checkForEvents_handler, 23 | .path = path_handler, 24 | .send = send_handler, 25 | .recv = recv_handler, 26 | .close = close_handler 27 | }; 28 | 29 | static void ICACHE_FLASH_ATTR websocketRecvCb(Websock *ws, char *data, int len, int flags) 30 | { 31 | sscp_connection *connection = (sscp_connection *)ws->userData; 32 | if (!(connection->flags & CONNECTION_RXFULL)) { 33 | if (len > SSCP_RX_BUFFER_MAX) 34 | len = SSCP_RX_BUFFER_MAX; 35 | os_memcpy(connection->rxBuffer, data, len); 36 | connection->rxCount = len; 37 | connection->rxIndex = 0; 38 | connection->flags |= CONNECTION_RXFULL; 39 | if (flashConfig.sscp_events) 40 | send_data_event(connection, '!'); 41 | } 42 | } 43 | 44 | static void ICACHE_FLASH_ATTR websocketSentCb(Websock *ws) 45 | { 46 | sscp_connection *connection = (sscp_connection *)ws->userData; 47 | connection->flags |= CONNECTION_TXDONE; 48 | } 49 | 50 | static void ICACHE_FLASH_ATTR websocketCloseCb(Websock *ws) 51 | { 52 | sscp_connection *connection = (sscp_connection *)ws->userData; 53 | connection->d.ws.ws = NULL; 54 | } 55 | 56 | void ICACHE_FLASH_ATTR sscp_websocketConnect(Websock *ws) 57 | { 58 | sscp_listener *listener; 59 | sscp_connection *connection; 60 | 61 | // find a matching listener 62 | if (!(listener = sscp_find_listener(ws->conn->url, TYPE_WEBSOCKET_LISTENER))) { 63 | cgiWebsocketClose(ws, 0); 64 | return; 65 | } 66 | 67 | // find an unused connection 68 | if (!(connection = sscp_allocate_connection(TYPE_WEBSOCKET_CONNECTION, &wsDispatch))) { 69 | cgiWebsocketClose(ws, 0); 70 | return; 71 | } 72 | connection->listenerHandle = listener->hdr.handle; 73 | connection->d.ws.ws = ws; 74 | 75 | sscp_log("sscp_websocketConnect: url '%s'", ws->conn->url); 76 | ws->recvCb = websocketRecvCb; 77 | ws->sentCb = websocketSentCb; 78 | ws->closeCb = websocketCloseCb; 79 | ws->userData = connection; 80 | } 81 | 82 | static void ICACHE_FLASH_ATTR send_connect_event(sscp_connection *connection, int prefix) 83 | { 84 | connection->flags &= ~CONNECTION_INIT; 85 | sscp_sendResponse("W,%d,%d", connection->hdr.handle, connection->listenerHandle); 86 | } 87 | 88 | static void ICACHE_FLASH_ATTR send_disconnect_event(sscp_connection *connection, int prefix) 89 | { 90 | connection->flags &= ~CONNECTION_TERM; 91 | sscp_sendResponse("X,%d,0", connection->hdr.handle); 92 | } 93 | 94 | static void ICACHE_FLASH_ATTR send_data_event(sscp_connection *connection, int prefix) 95 | { 96 | sscp_sendResponse("D,%d,%d", connection->hdr.handle, connection->rxCount); 97 | } 98 | 99 | static int ICACHE_FLASH_ATTR checkForEvents_handler(sscp_hdr *hdr) 100 | { 101 | sscp_connection *connection = (sscp_connection *)hdr; 102 | 103 | if (!connection->d.ws.ws) 104 | return 0; 105 | 106 | if (connection->flags & CONNECTION_TERM) { 107 | send_disconnect_event(connection, '='); 108 | return 1; 109 | } 110 | 111 | else if (connection->flags & CONNECTION_INIT) { 112 | send_connect_event(connection, '='); 113 | return 1; 114 | } 115 | 116 | else if (connection->flags & CONNECTION_RXFULL) { 117 | send_data_event(connection, '='); 118 | return 1; 119 | } 120 | 121 | return 0; 122 | } 123 | 124 | static void ICACHE_FLASH_ATTR path_handler(sscp_hdr *hdr) 125 | { 126 | sscp_connection *connection = (sscp_connection *)hdr; 127 | Websock *ws = (Websock *)connection->d.ws.ws; 128 | 129 | if (!ws || !ws->conn) { 130 | sscp_sendResponse("E,%d", SSCP_ERROR_INVALID_STATE); 131 | return; 132 | } 133 | 134 | sscp_sendResponse("S,%s", ws->conn->url); 135 | } 136 | 137 | // this is called after all of the data for a SEND has been received from the MCU 138 | static void ICACHE_FLASH_ATTR send_cb(void *data, int count) 139 | { 140 | sscp_connection *connection = (sscp_connection *)data; 141 | Websock *ws = (Websock *)connection->d.ws.ws; 142 | 143 | char sendBuff[1024]; 144 | httpdSetSendBuffer(ws->conn, sendBuff, sizeof(sendBuff)); 145 | cgiWebsocketSend(ws, connection->txBuffer, count, WEBSOCK_FLAG_NONE); 146 | connection->flags &= ~CONNECTION_TXFULL; 147 | 148 | sscp_sendResponse("S,%d", count); 149 | } 150 | 151 | static void ICACHE_FLASH_ATTR send_handler(sscp_hdr *hdr, int size) 152 | { 153 | sscp_connection *connection = (sscp_connection *)hdr; 154 | 155 | if (size == 0) 156 | sscp_sendResponse("S,0"); 157 | else { 158 | // response is sent by tcp_sent_cb 159 | sscp_capturePayload(connection->txBuffer, size, send_cb, connection); 160 | connection->flags |= CONNECTION_TXFULL; 161 | } 162 | } 163 | 164 | static void ICACHE_FLASH_ATTR recv_handler(sscp_hdr *hdr, int size) 165 | { 166 | sscp_connection *connection = (sscp_connection *)hdr; 167 | 168 | if (!(connection->flags & CONNECTION_RXFULL)) { 169 | sscp_sendResponse("S,0"); 170 | return; 171 | } 172 | 173 | if (connection->rxIndex + size > connection->rxCount) 174 | size = connection->rxCount - connection->rxIndex; 175 | 176 | sscp_sendResponse("S,%d", size); 177 | if (size > 0) { 178 | sscp_sendPayload(connection->rxBuffer + connection->rxIndex, size); 179 | connection->rxIndex += size; 180 | } 181 | 182 | if (connection->rxIndex >= connection->rxCount) 183 | connection->flags &= ~CONNECTION_RXFULL; 184 | } 185 | 186 | static void ICACHE_FLASH_ATTR close_handler(sscp_hdr *hdr) 187 | { 188 | sscp_connection *connection = (sscp_connection *)hdr; 189 | Websock *ws = connection->d.ws.ws; 190 | if (ws) 191 | cgiWebsocketClose(ws, 0); 192 | } 193 | -------------------------------------------------------------------------------- /release/Makefile: -------------------------------------------------------------------------------- 1 | SDK=../ESP8266_NONOS_SDK 2 | 3 | ZIP=parallax-esp-$(shell date "+%Y-%m-%d-%H%M").zip 4 | $(info ZIP $(ZIP)) 5 | 6 | IMAGES=\ 7 | release/httpd.user1.bin \ 8 | release/httpd.user2.bin \ 9 | release/Parallax-ESP.ota \ 10 | release/blank.bin \ 11 | release/esp_init_data_default_v08.bin 12 | 13 | TOOLS=\ 14 | release/esptool 15 | 16 | BOOTBIN=boot_v1.7.bin 17 | IMAGES+=release/$(BOOTBIN) 18 | 19 | CP=cp 20 | 21 | # this rule doesn't seem to work but running build followed by zip does 22 | all: clean 23 | $(MAKE) build 24 | $(MAKE) zip 25 | 26 | zip: staged-files 27 | cd release; zip -r ../$(ZIP) * 28 | 29 | build: 30 | $(MAKE) -C .. STA_SSID= STA_PASS= clean 31 | $(MAKE) -C .. STA_SSID= STA_PASS= 32 | 33 | ../esptool-ck/esptool: 34 | $(MAKE) -C ../esptool-ck 35 | 36 | staged-files: release release/release-notes.txt $(IMAGES) $(TOOLS) 37 | $(CP) flash-all.sh update-fw.sh clear.sh clear-ffs.sh release 38 | 39 | release/release-notes.txt: release-notes.txt 40 | $(CP) release-notes.txt release 41 | 42 | release/$(BOOTBIN): $(SDK)/bin/$(BOOTBIN) patch 43 | ./patch $< $@ 2M 44 | 45 | release/%: ../build/% 46 | $(CP) $< $@ 47 | 48 | release/Parallax-ESP.ota: ../build/httpd.ota 49 | $(CP) $< $@ 50 | 51 | release/blank.bin: $(SDK)/bin/blank.bin 52 | $(CP) $< $@ 53 | 54 | release/esp_init_data_default_v08.bin: $(SDK)/bin/esp_init_data_default_v08.bin 55 | $(CP) $< $@ 56 | 57 | release/esptool: ../esptool-ck/esptool 58 | $(CP) $< $@ 59 | 60 | release: 61 | mkdir -p release 62 | 63 | patch: patch.c 64 | cc -o $@ $< 65 | 66 | clean: 67 | rm -rf release patch ../esptool-ck/esptool 68 | -------------------------------------------------------------------------------- /release/clear-1m.sh: -------------------------------------------------------------------------------- 1 | # clear out all settings and the user flash filesystem 2 | 3 | PORT=/dev/ttyUSB0 4 | if [ ! -z $1 ] 5 | then 6 | PORT=$1 7 | fi 8 | echo Using port $PORT 9 | 10 | BAUD=115200 11 | BOARD=none # none, ck, nodemcu, wifio 12 | FLASH_SIZE=4M 13 | FLASH_BLOCK_SIZE=1024 14 | FLASH_SPEED=80 15 | FLASH_INTERFACE=qio 16 | 17 | USER_SETTINGS1=0x07E000 18 | USER_SETTINGS2=0x07F000 19 | 20 | #use for 1MB flash 21 | WIFI_SETTINGS1=0x0FC000 22 | WIFI_SETTINGS2=0x0FE000 23 | WIFI_SETTINGS3=0x0FA000 24 | 25 | #use for 4MB flash 26 | #WIFI_SETTINGS1=0x3FC000 27 | #WIFI_SETTINGS2=0x3FE000 28 | #WIFI_SETTINGS3=0x3FA000 29 | 30 | #flash filesystem base 31 | FFS_BASE=0x100000 32 | 33 | ./esptool \ 34 | -cp $PORT \ 35 | -cd $BOARD \ 36 | -cb $BAUD \ 37 | -bz $FLASH_SIZE \ 38 | -bf $FLASH_SPEED \ 39 | -bm $FLASH_INTERFACE \ 40 | -ca $USER_SETTINGS1 -cf blank.bin \ 41 | -ca $USER_SETTINGS2 -cf blank.bin \ 42 | -ca $WIFI_SETTINGS1 -cf esp_init_data_default_v08.bin \ 43 | -ca $WIFI_SETTINGS2 -cf blank.bin \ 44 | -ca $WIFI_SETTINGS3 -cf blank.bin \ 45 | -ca $FFS_BASE -cf blank.bin 46 | -------------------------------------------------------------------------------- /release/clear-ffs.sh: -------------------------------------------------------------------------------- 1 | # clear out the user flash filesystem 2 | 3 | PORT=/dev/ttyUSB0 4 | if [ ! -z $1 ] 5 | then 6 | PORT=$1 7 | fi 8 | echo Using port $PORT 9 | 10 | BAUD=115200 11 | BOARD=none # none, ck, nodemcu, wifio 12 | FLASH_SIZE=2M 13 | FLASH_BLOCK_SIZE=1024 14 | FLASH_SPEED=80 15 | FLASH_INTERFACE=qio 16 | 17 | #flash filesystem base 18 | FFS_BASE=0x100000 19 | 20 | ./esptool \ 21 | -cp $PORT \ 22 | -cd $BOARD \ 23 | -cb $BAUD \ 24 | -bz $FLASH_SIZE \ 25 | -bf $FLASH_SPEED \ 26 | -bm $FLASH_INTERFACE \ 27 | -ca $FFS_BASE -cf blank.bin 28 | -------------------------------------------------------------------------------- /release/clear.sh: -------------------------------------------------------------------------------- 1 | # clear out all settings and the user flash filesystem 2 | 3 | PORT=/dev/ttyUSB0 4 | if [ ! -z $1 ] 5 | then 6 | PORT=$1 7 | fi 8 | echo Using port $PORT 9 | 10 | BAUD=115200 11 | BOARD=none # none, ck, nodemcu, wifio 12 | FLASH_SIZE=2M 13 | FLASH_BLOCK_SIZE=1024 14 | FLASH_SPEED=80 15 | FLASH_INTERFACE=qio 16 | 17 | USER_SETTINGS1=0x07E000 18 | USER_SETTINGS2=0x07F000 19 | 20 | if [ $FLASH_SIZE = 1M ]; then 21 | WIFI_SETTINGS1=0x0FC000 22 | WIFI_SETTINGS2=0x0FE000 23 | WIFI_SETTINGS3=0x0FA000 24 | elif [ $FLASH_SIZE = 2M ]; then 25 | WIFI_SETTINGS1=0x1FC000 26 | WIFI_SETTINGS2=0x1FE000 27 | WIFI_SETTINGS3=0x1FA000 28 | elif [ $FLASH_SIZE = 4M ]; then 29 | WIFI_SETTINGS1=0x3FC000 30 | WIFI_SETTINGS2=0x3FE000 31 | WIFI_SETTINGS3=0x3FA000 32 | else 33 | echo Unsupported flash size $FLASH_SIZE 34 | exit 1 35 | fi 36 | 37 | #flash filesystem base 38 | FFS_BASE=0x100000 39 | 40 | ./esptool \ 41 | -cp $PORT \ 42 | -cd $BOARD \ 43 | -cb $BAUD \ 44 | -bz $FLASH_SIZE \ 45 | -bf $FLASH_SPEED \ 46 | -bm $FLASH_INTERFACE \ 47 | -ca $USER_SETTINGS1 -cf blank.bin \ 48 | -ca $USER_SETTINGS2 -cf blank.bin \ 49 | -ca $WIFI_SETTINGS1 -cf esp_init_data_default_v08.bin \ 50 | -ca $WIFI_SETTINGS2 -cf blank.bin \ 51 | -ca $WIFI_SETTINGS3 -cf blank.bin \ 52 | -ca $FFS_BASE -cf blank.bin 53 | -------------------------------------------------------------------------------- /release/flash-all.sh: -------------------------------------------------------------------------------- 1 | # flash the firmware 2 | # and clear out all settings and the user flash filesystem 3 | 4 | PORT=/dev/ttyUSB0 5 | if [ ! -z $1 ] 6 | then 7 | PORT=$1 8 | fi 9 | echo Using port $PORT 10 | 11 | BAUD=115200 12 | BOARD=none # none, ck, nodemcu, wifio 13 | FLASH_SIZE=2M 14 | FLASH_BLOCK_SIZE=1024 15 | FLASH_SPEED=80 16 | FLASH_INTERFACE=qio 17 | 18 | BOOT_LOADER=0x000000 19 | USER1_IMAGE=0x001000 20 | 21 | USER_SETTINGS1=0x07E000 22 | USER_SETTINGS2=0x07F000 23 | 24 | if [ $FLASH_SIZE = 1M ]; then 25 | WIFI_SETTINGS1=0x0FC000 26 | WIFI_SETTINGS2=0x0FE000 27 | WIFI_SETTINGS3=0x0FA000 28 | elif [ $FLASH_SIZE = 2M ]; then 29 | WIFI_SETTINGS1=0x1FC000 30 | WIFI_SETTINGS2=0x1FE000 31 | WIFI_SETTINGS3=0x1FA000 32 | elif [ $FLASH_SIZE = 4M ]; then 33 | WIFI_SETTINGS1=0x3FC000 34 | WIFI_SETTINGS2=0x3FE000 35 | WIFI_SETTINGS3=0x3FA000 36 | else 37 | echo Unsupported flash size $FLASH_SIZE 38 | exit 1 39 | fi 40 | 41 | #flash filesystem base 42 | FFS_BASE=0x100000 43 | 44 | ./esptool \ 45 | -cp $PORT \ 46 | -cd $BOARD \ 47 | -cb $BAUD \ 48 | -bz $FLASH_SIZE \ 49 | -bf $FLASH_SPEED \ 50 | -bm $FLASH_INTERFACE \ 51 | -ca $BOOT_LOADER -cf boot_v1.7.bin \ 52 | -ca $USER1_IMAGE -cf httpd.user1.bin \ 53 | -ca $USER_SETTINGS1 -cf blank.bin \ 54 | -ca $USER_SETTINGS2 -cf blank.bin \ 55 | -ca $WIFI_SETTINGS1 -cf esp_init_data_default_v08.bin \ 56 | -ca $WIFI_SETTINGS2 -cf blank.bin \ 57 | -ca $WIFI_SETTINGS3 -cf blank.bin \ 58 | -ca $FFS_BASE -cf blank.bin 59 | -------------------------------------------------------------------------------- /release/patch.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define MODE_QIO 0x00 6 | #define MODE_QOUT 0x01 7 | #define MODE_DIO 0x02 8 | #define MODE_DOUT 0x03 9 | 10 | #define SIZE_4M 0x00 11 | #define SIZE_2M 0x10 12 | #define SIZE_8M 0x20 13 | #define SIZE_16M 0x30 14 | #define SIZE_32M 0x40 15 | 16 | #define FREQ_40M 0x00 17 | #define FREQ_26M 0x01 18 | #define FREQ_20M 0x02 19 | #define FREQ_80M 0x0f 20 | 21 | int main(int argc, char *argv[]) 22 | { 23 | int flashSize, size; 24 | FILE *ifp, *ofp; 25 | char *image; 26 | 27 | if (argc < 3 || argc > 4) { 28 | printf("usage: patch in-file out-file [1M|2M|4M]\n"); 29 | return 1; 30 | } 31 | 32 | if (argc < 4) 33 | flashSize = SIZE_16M; 34 | else { 35 | if (strcmp(argv[3], "1M") == 0) 36 | flashSize = SIZE_8M; 37 | else if (strcmp(argv[3], "2M") == 0) 38 | flashSize = SIZE_16M; 39 | else if (strcmp(argv[3], "4M") == 0) 40 | flashSize = SIZE_32M; 41 | else { 42 | printf("error: unsupported flash size '%s'\n", argv[3]); 43 | return 1; 44 | } 45 | } 46 | 47 | if (!(ifp = fopen(argv[1], "rb"))) { 48 | printf("error: can't open %s\n", argv[2]); 49 | return 1; 50 | } 51 | 52 | fseek(ifp, 0, SEEK_END); 53 | size = ftell(ifp); 54 | fseek(ifp, 0, SEEK_SET); 55 | 56 | if (!(image = malloc(size))) { 57 | printf("error: insufficient memory\n"); 58 | return 1; 59 | } 60 | 61 | if (fread(image, 1, size, ifp) != size) { 62 | printf("error: reading %s\n", argv[1]); 63 | return 1; 64 | } 65 | 66 | fclose(ifp); 67 | 68 | image[2] = MODE_QIO; 69 | image[3] = flashSize | FREQ_80M; 70 | 71 | if (!(ofp = fopen(argv[2], "wb"))) { 72 | printf("error: can't create %s\n", argv[3]); 73 | return 1; 74 | } 75 | 76 | if (fwrite(image, 1, size, ofp) != size) { 77 | printf("error: writing %s\n", argv[2]); 78 | return 1; 79 | } 80 | 81 | fclose(ofp); 82 | 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /release/release-notes.txt: -------------------------------------------------------------------------------- 1 | February 6, 2018 2 | Added tokens for APSCAN and APGET. 3 | Made APGET return the RSSI. 4 | 5 | October 11, 2016 6 | Switched from SDK 1.5.2 to 2.0.0.p1 7 | 8 | September 28, 2016 9 | Added a setting for enabling command events. 10 | Made the command start character setting persistent. 11 | -------------------------------------------------------------------------------- /release/update-fw.sh: -------------------------------------------------------------------------------- 1 | # flash the firmware 2 | 3 | PORT=/dev/ttyUSB0 4 | if [ ! -z $1 ] 5 | then 6 | PORT=$1 7 | fi 8 | echo Using port $PORT 9 | 10 | BAUD=115200 11 | BOARD=none # none, ck, nodemcu, wifio 12 | FLASH_SIZE=2M 13 | FLASH_BLOCK_SIZE=1024 14 | FLASH_SPEED=80 15 | FLASH_INTERFACE=qio 16 | 17 | BOOT_LOADER=0x000000 18 | USER1_IMAGE=0x001000 19 | 20 | ./esptool \ 21 | -cp $PORT \ 22 | -cd $BOARD \ 23 | -cb $BAUD \ 24 | -bz $FLASH_SIZE \ 25 | -bf $FLASH_SPEED \ 26 | -bm $FLASH_INTERFACE \ 27 | -ca $BOOT_LOADER -cf boot_v1.7.bin \ 28 | -ca $USER1_IMAGE -cf httpd.user1.bin 29 | -------------------------------------------------------------------------------- /test-framework/Makefile: -------------------------------------------------------------------------------- 1 | MKDIR=mkdir 2 | TOUCH=touch 3 | RM=rm -r -f 4 | 5 | ifeq ($(CROSS),) 6 | PREFIX= 7 | else 8 | ifeq ($(CROSS),win32) 9 | PREFIX=x86_64-w64-mingw32- 10 | OS=msys 11 | else 12 | ifeq ($(CROSS),rpi) 13 | PREFIX=arm-linux-gnueabihf- 14 | OS=linux 15 | else 16 | echo "Unknown cross compilation selected" 17 | endif 18 | endif 19 | endif 20 | 21 | CC=$(PREFIX)gcc 22 | CPP=$(PREFIX)g++ 23 | 24 | CFLAGS=-Wall 25 | 26 | ifeq ($(OS),Windows_NT) 27 | OS=msys 28 | endif 29 | 30 | ifeq ($(OS),linux) 31 | CFLAGS+=-DLINUX 32 | EXT= 33 | OSINT=$(OBJDIR)/sock_posix.o $(OBJDIR)/serial_posix.o 34 | LIBS= 35 | 36 | else ifeq ($(OS),msys) 37 | CFLAGS+=-DMINGW 38 | EXT=.exe 39 | OSINT=$(OBJDIR)/serial_mingw.o $(OBJDIR)/sock_posix.o 40 | LIBS=-lws2_32 -liphlpapi -lsetupapi 41 | 42 | else ifeq ($(OS),macosx) 43 | CFLAGS+=-DMACOSX 44 | EXT= 45 | OSINT=$(OBJDIR)/serial_posix.o $(OBJDIR)/sock_posix.o 46 | LIBS= 47 | 48 | else ifeq ($(OS),) 49 | $(error OS not set) 50 | 51 | else 52 | $(error Unknown OS $(OS)) 53 | endif 54 | 55 | APP=test-framework 56 | 57 | BUILD=$(realpath ..)/$(APP)-$(OS)-build 58 | $(info Writing build to $(BUILD)) 59 | 60 | SRCDIR=src 61 | OBJDIR=$(BUILD)/obj 62 | BINDIR=$(BUILD)/bin 63 | 64 | HDRS=\ 65 | $(SRCDIR)/cmd.h \ 66 | $(SRCDIR)/serial.h \ 67 | $(SRCDIR)/sock.h 68 | 69 | OBJS=\ 70 | $(OBJDIR)/main.o \ 71 | $(OBJDIR)/tests.o \ 72 | $(OBJDIR)/cmd.o \ 73 | $(OBJDIR)/framework.o \ 74 | $(OSINT) 75 | 76 | CFLAGS+=-I$(OBJDIR) 77 | CPPFLAGS=$(CFLAGS) 78 | 79 | all: $(BINDIR)/$(APP)$(EXT) 80 | 81 | $(OBJS): $(OBJDIR)/created $(HDRS) Makefile 82 | 83 | $(BINDIR)/$(APP)$(EXT): $(BINDIR)/created $(OBJS) 84 | $(CPP) -o $@ $(OBJS) $(LIBS) -lstdc++ 85 | 86 | $(OBJDIR)/%.o: $(SRCDIR)/%.c $(HDRS) 87 | $(CC) $(CFLAGS) -c $< -o $@ 88 | 89 | $(OBJDIR)/%.o: $(SRCDIR)/%.cpp $(HDRS) 90 | $(CPP) $(CPPFLAGS) -c $< -o $@ 91 | 92 | run: $(BINDIR)/$(APP)$(EXT) 93 | $(BINDIR)/$(APP)$(EXT) -i 10.0.1.32 94 | 95 | clean: 96 | $(RM) $(BUILD) 97 | 98 | %/created: 99 | @$(MKDIR) -p $(@D) 100 | @$(TOUCH) $@ 101 | -------------------------------------------------------------------------------- /test-framework/src/cmd.h: -------------------------------------------------------------------------------- 1 | #ifndef __CMD_H__ 2 | #define __CMD_H__ 3 | 4 | #include 5 | #include 6 | #include "serial.h" 7 | 8 | #define CMD_START_BYTE 0xFE 9 | #define CMD_END_BYTE '\r' 10 | 11 | #define CMD_START "\xFE" 12 | #define CMD_INT8 "\xFD" 13 | #define CMD_UINT8 "\xFC" 14 | #define CMD_INT16 "\xFB" 15 | #define CMD_UINT16 "\xFA" 16 | #define CMD_INT32 "\xF9" 17 | #define CMD_UINT32 "\xF8" 18 | 19 | #define CMD_HTTP "\xF7" 20 | #define CMD_WS "\xF6" 21 | #define CMD_TCP "\xF5" 22 | #define CMD_STA "\xF4" 23 | #define CMD_AP "\xF3" 24 | #define CMD_STA_AP "\xF2" 25 | 26 | #define CMD_JOIN "\xEF" 27 | #define CMD_CHECK "\xEE" 28 | #define CMD_SET "\xED" 29 | #define CMD_POLL "\xEC" 30 | #define CMD_PATH "\xEB" 31 | #define CMD_SEND "\xEA" 32 | #define CMD_RECV "\xE9" 33 | #define CMD_CLOSE "\xE8" 34 | #define CMD_LISTEN "\xE7" 35 | #define CMD_ARG "\xE6" 36 | #define CMD_REPLY "\xE5" 37 | #define CMD_CONNECT "\xE4" 38 | 39 | #define CMD_END "\r" 40 | 41 | #define CMD_MAX_RESPONSE 1024 42 | #define CMD_MAX_ARGS 16 43 | 44 | #define WIFI_BUFFER_MAX 64 45 | #define WIFI_QUEUE_MAX 1024 46 | 47 | typedef enum { 48 | WIFI_STATE_START, 49 | WIFI_STATE_DATA 50 | } wifi_state; 51 | 52 | typedef struct wifi wifi; 53 | 54 | struct wifi { 55 | SERIAL *port; 56 | uint8_t inputBuffer[WIFI_BUFFER_MAX]; 57 | int inputNext; 58 | int inputCount; 59 | wifi_state messageState; 60 | char messageBuffer[WIFI_QUEUE_MAX]; 61 | int messageHead; 62 | int messageTail; 63 | int messageStart; 64 | }; 65 | 66 | int sscpOpen(wifi *dev, const char *deviceName); 67 | int sscpClose(wifi *dev); 68 | int sscpRequest(wifi *dev, const char *fmt, ...); 69 | int sscpRequestV(wifi *dev, const char *fmt, va_list ap); 70 | int sscpRequestPayload(wifi *dev, const char *buf, int len); 71 | int sscpCollectPayload(wifi *dev, char *buf, int count); 72 | int sscpGetResponse(wifi *dev, char *buf, int maxSize); 73 | int sscpCheckForEvent(wifi *dev, char *buf, int maxSize); 74 | int sscpParseResponse(char *buf, char *argv[], int maxArgs); 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /test-framework/src/framework.h: -------------------------------------------------------------------------------- 1 | #ifndef __FRAMEWORK_H__ 2 | #define __FRAMEWORK_H__ 3 | 4 | #include 5 | #include "cmd.h" 6 | #include "sock.h" 7 | 8 | extern int verbose; 9 | 10 | typedef struct { 11 | const char *ssid; 12 | const char *passwd; 13 | SOCKADDR_IN moduleAddr; 14 | wifi *dev; 15 | const char *prefix; 16 | int testNumber; 17 | const char *testName; 18 | int testPassed; 19 | int skipRemainingTests; 20 | int passCount; 21 | int failCount; 22 | int skipCount; 23 | int selectedTest; 24 | } TestState; 25 | 26 | void initState(TestState *state, const char *prefix, TestState *parent); 27 | int startTest(TestState *state, const char *name); 28 | void infoTest(TestState *state, const char *fmt, ...); 29 | void passTest(TestState *state, const char *fmt, ...); 30 | void failTest(TestState *state, const char *fmt, ...); 31 | void beginGroup(TestState *state); 32 | int skipTest(TestState *state); 33 | void testResults(TestState *state); 34 | 35 | /* serial requests */ 36 | int serialRequest(TestState *state, const char *fmt, ...); 37 | void checkSerialResponse(TestState *state, const char *fmt, ...); 38 | int waitAndCheckSerialResponse(TestState *state, const char *idle, const char *fmt, ...); 39 | 40 | /* http requests */ 41 | int sendRequest(SOCKADDR_IN *addr, const char *method, const char *url, const char *body); 42 | int receiveResponse(uint8_t *res, int resMax, int *pResult); 43 | 44 | #endif 45 | 46 | 47 | -------------------------------------------------------------------------------- /test-framework/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "tests.h" 7 | #include "framework.h" 8 | #include "cmd.h" 9 | #include "serial.h" 10 | #include "sock.h" 11 | 12 | #ifndef TRUE 13 | #define TRUE 1 14 | #define FALSE 0 15 | #endif 16 | 17 | static void usage(const char *progname) 18 | { 19 | printf("\ 20 | usage: %s [options] []\n\ 21 | \n\ 22 | options:\n\ 23 | -i IP address of the Wi-Fi module\n\ 24 | -p serial port connected to DI/DO on the Wi-Fi module\n\ 25 | -s specify an AP SSID\n\ 26 | -t select a specific test\n\ 27 | -v enable verbose output\n\ 28 | -x specify an AP password\n\ 29 | -? display a usage message and exit\n\ 30 | ", progname); 31 | exit(1); 32 | } 33 | 34 | int main(int argc, char *argv[]) 35 | { 36 | #ifdef MINGW 37 | char *serialDevice = "COM1"; 38 | #else 39 | char *serialDevice = "/dev/ttyUSB0"; 40 | #endif 41 | char *moduleAddress = "0.0.0.0"; 42 | TestState globalState; 43 | int selectedTest = 0; 44 | wifi dev; 45 | int i; 46 | 47 | initState(&globalState, "", NULL); 48 | globalState.passwd = ""; 49 | 50 | /* get the arguments */ 51 | for (i = 1; i < argc; ++i) { 52 | 53 | /* handle switches */ 54 | if (argv[i][0] == '-') { 55 | switch (argv[i][1]) { 56 | case 'i': // set the ip address 57 | if (argv[i][2]) 58 | moduleAddress = &argv[i][2]; 59 | else if (++i < argc) 60 | moduleAddress = argv[i]; 61 | else 62 | usage(argv[0]); 63 | break; 64 | case 'p': // select a serial port 65 | if (argv[i][2]) 66 | serialDevice = &argv[i][2]; 67 | else if (++i < argc) 68 | serialDevice = argv[i]; 69 | else 70 | usage(argv[0]); 71 | break; 72 | case 's': // specify an AP ssid 73 | if (argv[i][2]) 74 | globalState.ssid = &argv[i][2]; 75 | else if (++i < argc) 76 | globalState.ssid = argv[i]; 77 | else 78 | usage(argv[0]); 79 | break; 80 | case 't': // select a target board 81 | if (argv[i][2]) 82 | selectedTest = atoi(&argv[i][2]); 83 | else if (++i < argc) 84 | selectedTest = atoi(argv[i]); 85 | else 86 | usage(argv[0]); 87 | break; 88 | case 'v': 89 | verbose = TRUE; 90 | break; 91 | case 'x': // specify an AP password 92 | if (argv[i][2]) 93 | globalState.passwd = &argv[i][2]; 94 | else if (++i < argc) 95 | globalState.passwd = argv[i]; 96 | else 97 | usage(argv[0]); 98 | break; 99 | default: 100 | usage(argv[0]); 101 | break; 102 | } 103 | } 104 | 105 | /* remember the file to load */ 106 | else { 107 | usage(argv[0]); 108 | } 109 | } 110 | 111 | printf("Welcome to the WX test framework!\n"); 112 | 113 | if (globalState.ssid) 114 | printf("[ using: SSID '%s', PASSWD '%s' ]\n", globalState.ssid, globalState.passwd); 115 | 116 | if (GetInternetAddress(moduleAddress, 80, &globalState.moduleAddr) != 0) { 117 | fprintf(stderr, "error: failed to parse IP address '%s'\n", moduleAddress); 118 | return 1; 119 | } 120 | 121 | if (sscpOpen(&dev, serialDevice) != 0) { 122 | fprintf(stderr, "error: failed to open '%s'\n", serialDevice); 123 | return 1; 124 | } 125 | globalState.dev = &dev; 126 | 127 | run_tests(&globalState, selectedTest); 128 | 129 | sscpClose(globalState.dev); 130 | 131 | return 0; 132 | } 133 | 134 | -------------------------------------------------------------------------------- /test-framework/src/serial.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file osint.h 3 | * 4 | * Serial I/O functions used by PLoadLib.c 5 | * 6 | * Copyright (c) 2009 by John Steven Denson 7 | * Modified in 2011 by David Michael Betz 8 | * 9 | * MIT License 10 | * 11 | * Permission is hereby granted, free of charge, to any person obtaining a copy 12 | * of this software and associated documentation files (the "Software"), to deal 13 | * in the Software without restriction, including without limitation the rights 14 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | * copies of the Software, and to permit persons to whom the Software is 16 | * furnished to do so, subject to the following conditions: 17 | * 18 | * The above copyright notice and this permission notice shall be included in 19 | * all copies or substantial portions of the Software. 20 | * 21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING FROM, 26 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | * THE SOFTWARE. 28 | * 29 | */ 30 | #ifndef __SERIAL_IO_H__ 31 | #define __SERIAL_IO_H__ 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /* Method of issuing reset to the Propeller chip. */ 38 | typedef enum { 39 | RESET_WITH_RTS, 40 | RESET_WITH_DTR, 41 | RESET_WITH_GPIO 42 | } reset_method_t; 43 | 44 | typedef struct SERIAL SERIAL; 45 | 46 | int SerialUseResetMethod(SERIAL *serial, char *method); 47 | int OpenSerial(const char *port, int baud, SERIAL **pSerial); 48 | void CloseSerial(SERIAL *serial); 49 | int SetSerialBaud(SERIAL *serial, int baud); 50 | int SendSerialBreak(SERIAL *serial); 51 | int SerialGenerateResetSignal(SERIAL *serial); 52 | int SendSerialData(SERIAL *serial, const void *buf, int len); 53 | int FlushSerialData(SERIAL *serial); 54 | int ReceiveSerialData(SERIAL *serial, void *buf, int len); 55 | int ReceiveSerialDataTimeout(SERIAL *serial, void *buf, int len, int timeout); 56 | int ReceiveSerialDataExactTimeout(SERIAL *serial, void *buf, int len, int timeout); 57 | int SerialFind(const char *prefix, int (*check)(const char *port, void *data), void *data); 58 | void SerialTerminal(SERIAL *serial, int check_for_exit, int pst_mode); 59 | void msleep(int ms); 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /test-framework/src/sock.h: -------------------------------------------------------------------------------- 1 | #ifndef __SOCK_H__ 2 | #define __SOCK_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | /* for windows builds */ 9 | #ifdef __MINGW32__ 10 | #include 11 | #include 12 | #include 13 | typedef unsigned long in_addr_t; 14 | 15 | /* for linux and mac builds */ 16 | #else 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #define IN_ADDR struct in_addr 27 | #define SOCKADDR_IN struct sockaddr_in 28 | #define SOCKADDR struct sockaddr 29 | #define HOSTENT struct hostent 30 | #define closesocket(x) close(x) 31 | typedef int SOCKET; 32 | #define INVALID_SOCKET -1 33 | #endif 34 | 35 | typedef struct { 36 | SOCKADDR_IN addr; 37 | SOCKADDR_IN mask; 38 | SOCKADDR_IN bcast; 39 | } IFADDR; 40 | 41 | int GetInterfaceAddresses(IFADDR *addrs, int max); 42 | int GetInternetAddress(const char *hostName, short port, SOCKADDR_IN *addr); 43 | const char *AddrToString(uint32_t addr); 44 | int StringToAddr(const char *addr, uint32_t *pAddr); 45 | int OpenBroadcastSocket(short port, SOCKET *pSocket); 46 | int ConnectSocket(SOCKADDR_IN *addr, SOCKET *pSocket); 47 | int ConnectSocketTimeout(SOCKADDR_IN *addr, int timeout, SOCKET *pSocket); 48 | int BindSocket(short port, SOCKET *pSocket); 49 | void CloseSocket(SOCKET sock); 50 | int SocketDataAvailableP(SOCKET sock, int timeout); 51 | int SendSocketData(SOCKET sock, const void *buf, int len); 52 | int ReceiveSocketData(SOCKET sock, void *buf, int len); 53 | int ReceiveSocketDataTimeout(SOCKET sock, void *buf, int len, int timeout); 54 | int ReceiveSocketDataExactTimeout(SOCKET sock, void *buf, int len, int timeout); 55 | int SendSocketDataTo(SOCKET sock, const void *buf, int len, SOCKADDR_IN *addr); 56 | int ReceiveSocketDataFrom(SOCKET sock, void *buf, int len, SOCKADDR_IN *addr); 57 | int ReceiveSocketDataAndAddress(SOCKET sock, void *buf, int len, SOCKADDR_IN *addr); 58 | const char *AddressToString(SOCKADDR_IN *addr); 59 | void SocketTerminal(SOCKET sock, int check_for_exit, int pst_mode); 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /test-framework/src/tests.h: -------------------------------------------------------------------------------- 1 | #ifndef __TESTS_H__ 2 | #define __TESTS_H__ 3 | 4 | #include "framework.h" 5 | 6 | void run_tests(TestState *parent, int selectedTest); 7 | 8 | #endif 9 | 10 | --------------------------------------------------------------------------------