1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-07-23 08:45:22 +03:00

Merge remote-tracking branch 'esp8266/master'

This commit is contained in:
me-no-dev
2015-12-10 17:56:41 +02:00
38 changed files with 976 additions and 112 deletions

View File

@ -691,3 +691,83 @@ d1_mini.menu.FlashSize.4M1M.build.spiffs_start=0x300000
d1_mini.menu.FlashSize.4M1M.build.spiffs_end=0x3FB000
d1_mini.menu.FlashSize.4M1M.build.spiffs_blocksize=8192
d1_mini.menu.FlashSize.4M1M.build.spiffs_pagesize=256
##############################################################
espino.name=ESPino
espino.upload.tool=esptool
espino.upload.speed=115200
espino.upload.resetmethod=ck
espino.upload.maximum_size=1044464
espino.upload.maximum_data_size=81920
espino.upload.wait_for_upload_port=true
espino.serial.disableDTR=true
espino.serial.disableRTS=true
espino.build.mcu=esp8266
espino.build.f_cpu=80000000L
espino.build.board=ESP8266_ESP12
espino.build.core=esp8266
espino.build.variant=espino
espino.build.flash_mode=qio
espino.build.flash_size=4M
espino.build.flash_freq=40
espino.build.spiffs_pagesize=256
espino.menu.UploadTool.esptool=Serial
espino.menu.UploadTool.esptool.upload.tool=esptool
espino.menu.UploadTool.esptool.upload.verbose=-vv
espino.menu.UploadTool.espota=OTA
espino.menu.UploadTool.espota.upload.tool=espota
espino.menu.CpuFrequency.80=80 MHz
espino.menu.CpuFrequency.80.build.f_cpu=80000000L
espino.menu.CpuFrequency.160=160 MHz
espino.menu.CpuFrequency.160.build.f_cpu=160000000L
espino.menu.FlashMode.dio=DIO
espino.menu.FlashMode.dio.build.flash_mode=dio
espino.menu.FlashMode.qio=QIO
espino.menu.FlashMode.qio.build.flash_mode=qio
espino.menu.UploadSpeed.115200=115200
espino.menu.UploadSpeed.115200.upload.speed=115200
espino.menu.UploadSpeed.9600=9600
espino.menu.UploadSpeed.9600.upload.speed=9600
espino.menu.UploadSpeed.57600=57600
espino.menu.UploadSpeed.57600.upload.speed=57600
espino.menu.UploadSpeed.256000.windows=256000
espino.menu.UploadSpeed.256000.upload.speed=256000
espino.menu.UploadSpeed.230400.linux=230400
espino.menu.UploadSpeed.230400.macosx=230400
espino.menu.UploadSpeed.230400.upload.speed=230400
espino.menu.UploadSpeed.460800.linux=460800
espino.menu.UploadSpeed.460800.macosx=460800
espino.menu.UploadSpeed.460800.upload.speed=460800
espino.menu.UploadSpeed.512000.windows=512000
espino.menu.UploadSpeed.512000.upload.speed=512000
espino.menu.UploadSpeed.921600=921600
espino.menu.UploadSpeed.921600.upload.speed=921600
espino.menu.FlashSize.4M1M=4M (1M SPIFFS)
espino.menu.FlashSize.4M1M.build.flash_size=4M
espino.menu.FlashSize.4M1M.build.flash_ld=eagle.flash.4m1m.ld
espino.menu.FlashSize.4M1M.build.spiffs_start=0x300000
espino.menu.FlashSize.4M1M.build.spiffs_end=0x3FB000
espino.menu.FlashSize.4M1M.build.spiffs_blocksize=8192
espino.menu.FlashSize.4M1M.build.spiffs_pagesize=256
espino.menu.FlashSize.4M1M.upload.maximum_size=1044464
espino.menu.FlashSize.4M3M=4M (3M SPIFFS)
espino.menu.FlashSize.4M3M.build.flash_size=4M
espino.menu.FlashSize.4M3M.build.flash_ld=eagle.flash.4m.ld
espino.menu.FlashSize.4M3M.build.spiffs_start=0x100000
espino.menu.FlashSize.4M3M.build.spiffs_end=0x3FB000
espino.menu.FlashSize.4M3M.build.spiffs_blocksize=8192
espino.menu.FlashSize.4M3M.upload.maximum_size=1044464
espino.menu.ResetMethod.ck=ck
espino.menu.ResetMethod.ck.upload.resetmethod=ck
espino.menu.ResetMethod.nodemcu=nodemcu
espino.menu.ResetMethod.nodemcu.upload.resetmethod=nodemcu

View File

@ -219,14 +219,12 @@ void loop(void);
void yield(void);
void optimistic_yield(uint32_t interval_us);
// Get the bit location within the hardware port of the given virtual pin.
// This comes from the pins_*.c file for the active board configuration.
#define digitalPinToPort(pin) (0)
#define digitalPinToBitMask(pin) (1UL << (pin))
#define digitalPinToTimer(pin) (0)
#define portOutputRegister(port) ((volatile uint32_t*) GPO)
#define portInputRegister(port) ((volatile uint32_t*) GPI)
#define portModeRegister(port) ((volatile uint32_t*) GPE)
#define portOutputRegister(port) ((volatile uint32_t*) &GPO)
#define portInputRegister(port) ((volatile uint32_t*) &GPI)
#define portModeRegister(port) ((volatile uint32_t*) &GPE)
#define NOT_A_PIN -1
#define NOT_A_PORT -1

View File

@ -617,18 +617,15 @@ size_t HardwareSerial::write(uint8_t c) {
size_t room = uart_get_tx_fifo_room(_uart);
if(room > 0 && _tx_buffer->empty()) {
uart_transmit_char(_uart, c);
if(room < 10) {
uart_arm_tx_interrupt(_uart);
}
return 1;
}
while(_tx_buffer->room() == 0) {
yield();
uart_arm_tx_interrupt(_uart);
}
_tx_buffer->write(c);
uart_arm_tx_interrupt(_uart);
return 1;
}

View File

@ -26,7 +26,7 @@ class UpdaterClass {
Call this to check the space needed for the update
Will return false if there is not enough space
*/
bool begin(size_t size, int = U_FLASH);
bool begin(size_t size, int command = U_FLASH);
/*
Writes a buffer to the flash and increments the address

View File

@ -68,6 +68,10 @@ void __throw_length_error(char const*) {
void __throw_bad_alloc() {
panic();
}
void __throw_logic_error(const char* str) {
panic();
}
}
// TODO: rebuild windows toolchain to make this unnecessary:

63
cores/esp8266/base64.cpp Normal file
View File

@ -0,0 +1,63 @@
/**
* base64.cpp
*
* Created on: 09.12.2015
*
* Copyright (c) 2015 Markus Sattler. All rights reserved.
* This file is part of the ESP8266 core for Arduino.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "Arduino.h"
extern "C" {
#include "libb64/cdecode.h"
#include "libb64/cencode.h"
}
#include "base64.h"
/**
* convert input data to base64
* @param data uint8_t *
* @param length size_t
* @return String
*/
String base64::encode(uint8_t * data, size_t length) {
// base64 needs more size then the source data
size_t size = ((length * 1.6f) + 1);
char * buffer = (char *) malloc(size);
if(buffer) {
base64_encodestate _state;
base64_init_encodestate(&_state);
int len = base64_encode_block((const char *) &data[0], length, &buffer[0], &_state);
len = base64_encode_blockend((buffer + len), &_state);
String base64 = String(buffer);
free(buffer);
return base64;
}
return String("-FAIL-");
}
/**
* convert input data to base64
* @param text String
* @return String
*/
String base64::encode(String text) {
return base64::encode((uint8_t *) text.c_str(), text.length());
}

36
cores/esp8266/base64.h Normal file
View File

@ -0,0 +1,36 @@
/**
* base64.h
*
* Created on: 09.12.2015
*
* Copyright (c) 2015 Markus Sattler. All rights reserved.
* This file is part of the ESP8266 core for Arduino.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef CORE_BASE64_H_
#define CORE_BASE64_H_
class base64 {
public:
static String encode(uint8_t * data, size_t length);
static String encode(String text);
private:
};
#endif /* CORE_BASE64_H_ */

View File

@ -42,9 +42,6 @@ class cbuf {
if(_end >= _begin) {
return _size - (_end - _begin) - 1;
}
if(_begin == _end) {
return _size;
}
return _begin - _end - 1;
}
@ -62,7 +59,7 @@ class cbuf {
if(getSize() == 0) return -1;
char result = *_begin;
if(++_begin == _bufend) _begin = _buf;
_begin = wrap_if_bufend(_begin + 1);
return static_cast<int>(result);
}
@ -78,8 +75,7 @@ class cbuf {
dst += top_size;
}
memcpy(dst, _begin, size_to_read);
_begin += size_to_read;
if(_begin == _bufend) _begin = _buf;
_begin = wrap_if_bufend(_begin + size_to_read);
return size_read;
}
@ -87,7 +83,7 @@ class cbuf {
if(room() == 0) return 0;
*_end = c;
if(++_end == _bufend) _end = _buf;
_end = wrap_if_bufend(_end + 1);
return 1;
}
@ -103,8 +99,7 @@ class cbuf {
src += top_size;
}
memcpy(_end, src, size_to_write);
_end += size_to_write;
if(_end == _bufend) _end = _buf;
_end = wrap_if_bufend(_end + size_to_write);
return size_written;
}
@ -114,6 +109,10 @@ class cbuf {
}
private:
inline char* wrap_if_bufend(char* ptr) {
return (ptr == _bufend) ? _buf : ptr;
}
size_t _size;
char* _buf;
char* _bufend;

View File

@ -26,6 +26,7 @@
#define CORE_HAS_LIBB64
#define CORE_HAS_BASE64_CLASS
#endif

View File

@ -494,7 +494,7 @@ extern uint8_t esp8266_gpioToFn[16];
//SPI Phase Length Locations
#define SPILCOMMAND 28 //4 bit in SPIxU2 default 7 (8bit)
#define SPILADDR 16 //6 bit in SPIxU1 default:23 (24bit)
#define SPILADDR 26 //6 bit in SPIxU1 default:23 (24bit)
#define SPILDUMMY 0 //8 bit in SPIxU1 default:0 (0 cycles)
#define SPILMISO 8 //9 bit in SPIxU1 default:0 (1bit)
#define SPILMOSI 17 //9 bit in SPIxU1 default:0 (1bit)
@ -834,4 +834,10 @@ extern uint8_t esp8266_gpioToFn[16];
#define I2STXCMM (0x7) //I2S_TX_CHAN_MOD
#define I2STXCM (0) //I2S_TX_CHAN_MOD_S
/**
Random Number Generator 32bit
http://esp8266-re.foogod.com/wiki/Random_Number_Generator
**/
#define RANDOM_REG32 ESP8266_DREG(0x20E44)
#endif

View File

@ -78,7 +78,7 @@ int vsnprintf_P(char *str, size_t strSize, PGM_P formatP, va_list ap) __attribut
(__extension__({ \
PGM_P __local = (PGM_P)(addr); /* isolate varible for macro expansion */ \
ptrdiff_t __offset = ((uint32_t)__local & 0x00000003); /* byte aligned mask */ \
const uint32_t* __addr32 = reinterpret_cast<const uint32_t*>(reinterpret_cast<const uint8_t*>(__local)-__offset); \
const uint32_t* __addr32 = (const uint32_t*)((const uint8_t*)(__local)-__offset); \
uint8_t __result = ((*__addr32) >> (__offset * 8)); \
__result; \
}))
@ -87,7 +87,7 @@ int vsnprintf_P(char *str, size_t strSize, PGM_P formatP, va_list ap) __attribut
(__extension__({ \
PGM_P __local = (PGM_P)(addr); /* isolate varible for macro expansion */ \
ptrdiff_t __offset = ((uint32_t)__local & 0x00000002); /* word aligned mask */ \
const uint32_t* __addr32 = reinterpret_cast<const uint32_t*>(reinterpret_cast<const uint8_t*>(__local) - __offset); \
const uint32_t* __addr32 = (const uint32_t*)((const uint8_t*)(__local) - __offset); \
uint16_t __result = ((*__addr32) >> (__offset * 8)); \
__result; \
}))

View File

@ -410,6 +410,17 @@ protected:
FileImplPtr SPIFFSImpl::open(const char* path, OpenMode openMode, AccessMode accessMode) {
int mode = getSpiffsMode(openMode, accessMode);
int fd = SPIFFS_open(&_fs, path, mode, 0);
if (fd < 0 && _fs.err_code == SPIFFS_ERR_DELETED && (openMode & OM_CREATE)) {
DEBUGV("SPIFFSImpl::open: fd=%d path=`%s` openMode=%d accessMode=%d err=%d, trying to remove\r\n",
fd, path, openMode, accessMode, _fs.err_code);
auto rc = SPIFFS_remove(&_fs, path);
if (rc != SPIFFS_OK) {
DEBUGV("SPIFFSImpl::open: SPIFFS_ERR_DELETED, but failed to remove path=`%s` openMode=%d accessMode=%d err=%d\r\n",
path, openMode, accessMode, _fs.err_code);
return FileImplPtr();
}
fd = SPIFFS_open(&_fs, path, mode, 0);
}
if (fd < 0) {
DEBUGV("SPIFFSImpl::open: fd=%d path=`%s` openMode=%d accessMode=%d err=%d\r\n",
fd, path, openMode, accessMode, _fs.err_code);

View File

@ -11,6 +11,7 @@ title: Supported Hardware
* [Olimex MOD\-WIFI\-ESP8266](#olimex-mod-wifi-esp8266)
* [SparkFun ESP8266 Thing](#sparkfun-esp8266-thing)
* [SweetPea ESP\-210](#sweetpea-esp-210)
* [ESPino](#espino)
* [Generic ESP8266 modules](#generic-esp8266-modules)
* [Serial Adapter](#serial-adapter)
* [Minimal Hardware Setup for Bootloading and Usage](#minimal-hardware-setup-for-bootloading-and-usage)
@ -91,6 +92,14 @@ Product page: https://www.sparkfun.com/products/13231
*TODO: add notes*
## ESPino
ESPino integrates the ESP-12 module with a 3.3v regulator, CP2104 USB-Serial bridge and a micro USB connector for easy programming. It is designed for fitting in a breadboard and has an RGB Led and two buttons for easy prototyping.
For more information about the hardware, pinout diagram and programming procedures, please see the [datasheet](https://github.com/makerlabmx/ESPino-tools/raw/master/Docs/ESPino-Datasheet-EN.pdf).
Product page: http://www.espino.io/en
## Generic ESP8266 modules
These modules come in different form factors and pinouts. See the page at ESP8266 community wiki for more info:

39
doc/eclipse/makefile.init Normal file
View File

@ -0,0 +1,39 @@
vecho := @echo
Q := @
PROJECT_NAME=project_name
OTA_IP=192.168.254.100
OTA_PORT=8266
SERIAL_PORT=COM3
SERIAL_BAUD=230400
ARDUINO_BASE = D:/Coding/avr/Programme/arduino-nightly
ESP8266_BASE = $(ARDUINO_BASE)/hardware/esp8266com/esp8266
ESP8266_TOOLS = $(ESP8266_BASE)/tools
XTENSA_TOOLS_ROOT = $(ESP8266_TOOLS)/xtensa-lx106-elf/bin
PYTHON_BIN = python
ESPTOOL_PY_BIN = $(ESP8266_TOOLS)/esptool.py
ESPOTA_PY_BIN = $(ESP8266_TOOLS)/espota.py
ESPTOOL_BIN = $(ESP8266_TOOLS)/esptool/esptool.exe
ota:
$(vecho) ota...
$(PYTHON_BIN) $(ESPOTA_PY_BIN) -i $(OTA_IP) -p $(OTA_PORT) --auth= -f ./$(PROJECT_NAME).bin
ota_spiffs:
$(vecho) ota spiffs...
$(PYTHON_BIN) $(ESPOTA_PY_BIN) -i $(OTA_IP) -p $(OTA_PORT) --auth= -s -f ./$(PROJECT_NAME)_spiffs.bin
erase_flash:
$(vecho) "Erase Flash"
$(PYTHON_BIN) $(ESPTOOL_PY_BIN) -p $(SERIAL_PORT) -b $(SERIAL_BAUD) erase_flash
dumpmem:
$(vecho) "Read Flash need some time..."
$(PYTHON_BIN) $(ESPTOOL_PY_BIN) -p $(SERIAL_PORT) -b $(SERIAL_BAUD) read_flash 0 4194304 dump.bin
objdump:
"$(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-objdump" -S $(PROJECT_NAME).elf > $(PROJECT_NAME).dobj

View File

@ -140,15 +140,17 @@ While many RC servo motors will accept the 3.3V IO data pin from a ESP8266, most
Libraries that don't rely on low-level access to AVR registers should work well. Here are a few libraries that were verified to work:
- [Adafruit_ILI9341](https://github.com/Links2004/Adafruit_ILI9341) - Port of the Adafruit ILI9341 for the ESP8266
- [arduinoWebSockets](https://github.com/Links2004/arduinoWebSockets) - WebSocket Server and Client compatible with ESP8266 (RFC6455)
- [aREST](https://github.com/marcoschwartz/aREST) REST API handler library.
- [aREST](https://github.com/marcoschwartz/aREST) - REST API handler library.
- [Blynk](https://github.com/blynkkk/blynk-library) - easy IoT framework for Makers (check out the [Kickstarter page](http://tiny.cc/blynk-kick)).
- [DallasTemperature](https://github.com/milesburton/Arduino-Temperature-Control-Library.git)
- [DHT-sensor-library](https://github.com/adafruit/DHT-sensor-library) - Arduino library for the DHT11/DHT22 temperature and humidity sensors. Download latest v1.1.1 library and no changes are necessary. Older versions should initialize DHT as follows: `DHT dht(DHTPIN, DHTTYPE, 15)`
- [NeoPixel](https://github.com/adafruit/Adafruit_NeoPixel) - Adafruit's NeoPixel library, now with support for the ESP8266 (use version 1.0.2 or higher from Arduino's library manager).
- [NeoPixelBus](https://github.com/Makuna/NeoPixelBus) - Arduino NeoPixel library compatible with ESP8266. Use the "NeoPixelAnimator" branch for ESP8266 to get HSL color support and more.
- [PubSubClient](https://github.com/Imroy/pubsubclient) MQTT library by @Imroy.
- [PubSubClient](https://github.com/Imroy/pubsubclient) - MQTT library by @Imroy.
- [RTC](https://github.com/Makuna/Rtc) - Arduino Library for Ds1307 & Ds3231 compatible with ESP8266.
- [Souliss, Smart Home](https://github.com/souliss/souliss) - Framework for Smart Home based on Arduino, Android and openHAB.
- [ST7735](https://github.com/nzmichaelh/Adafruit-ST7735-Library) - Adafruit's ST7735 library modified to be compatible with ESP8266. Just make sure to modify the pins in the examples as they are still AVR specific.
- [UTFT-ESP8266](https://github.com/gnulabis/UTFT-ESP8266) - UTFT display library with support for ESP8266. Only serial interface (SPI) displays are supported for now (no 8-bit parallel mode, etc). Also includes support for the hardware SPI controller of the ESP8266.
- [WiFiManager](https://github.com/tzapu/WiFiManager) - WiFi Connection manager with web captive portal. If it can't connect, it starts AP mode and a configuration portal so you can choose and enter WiFi credentials.

View File

@ -0,0 +1,84 @@
/**
* Authorization.ino
*
* Created on: 09.12.2015
*
*/
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#define USE_SERIAL Serial
ESP8266WiFiMulti WiFiMulti;
void setup() {
USE_SERIAL.begin(115200);
// USE_SERIAL.setDebugOutput(true);
USE_SERIAL.println();
USE_SERIAL.println();
USE_SERIAL.println();
for(uint8_t t = 4; t > 0; t--) {
USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
USE_SERIAL.flush();
delay(1000);
}
WiFiMulti.addAP("SSID", "PASSWORD");
}
void loop() {
// wait for WiFi connection
if((WiFiMulti.run() == WL_CONNECTED)) {
HTTPClient http;
USE_SERIAL.print("[HTTP] begin...\n");
// configure traged server and url
http.begin("http://user:password@192.168.1.12/test.html");
/*
// or
http.begin("http://192.168.1.12/test.html");
http.setAuthorization("user", "password");
// or
http.begin("http://192.168.1.12/test.html");
http.setAuthorization("dXNlcjpwYXN3b3Jk");
*/
USE_SERIAL.print("[HTTP] GET...\n");
// start connection and send HTTP header
int httpCode = http.GET();
// httpCode will be negative on error
if(httpCode) {
// HTTP header has been send and Server response header has been handled
USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
// file found at server
if(httpCode == HTTP_CODE_OK) {
String payload = http.getString();
USE_SERIAL.println(payload);
}
} else {
USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
}
delay(10000);
}

View File

@ -43,24 +43,28 @@ void loop() {
USE_SERIAL.print("[HTTP] begin...\n");
// configure traged server and url
//http.begin("192.168.1.12", 443, "/test.html", true, "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS
http.begin("192.168.1.12", 80, "/test.html"); //HTTP
//http.begin("https://192.168.1.12/test.html", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS
http.begin("http://192.168.1.12/test.html"); //HTTP
USE_SERIAL.print("[HTTP] GET...\n");
// start connection and send HTTP header
int httpCode = http.GET();
// httpCode will be negative on error
if(httpCode) {
// HTTP header has been send and Server response header has been handled
USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
// file found at server
if(httpCode == 200) {
if(httpCode == HTTP_CODE_OK) {
String payload = http.getString();
USE_SERIAL.println(payload);
}
} else {
USE_SERIAL.print("[HTTP] GET... failed, no connection or no HTTP server\n");
USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
}
delay(10000);

View File

@ -36,26 +36,31 @@ void setup() {
WiFiMulti.addAP("SSID", "PASSWORD");
// allow reuse (if server supports it)
http.setReuse(true);
}
void loop() {
// wait for WiFi connection
if((WiFiMulti.run() == WL_CONNECTED)) {
http.begin("192.168.1.12", 80, "/test.html");
http.begin("http://192.168.1.12/test.html");
//http.begin("192.168.1.12", 80, "/test.html");
int httpCode = http.GET();
if(httpCode) {
USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
// file found at server
if(httpCode == 200) {
if(httpCode == HTTP_CODE_OK) {
http.writeToStream(&USE_SERIAL);
}
} else {
USE_SERIAL.print("[HTTP] GET... failed, no connection or no HTTP server\n");
USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
}
delay(1000);

View File

@ -42,19 +42,20 @@ void loop() {
HTTPClient http;
USE_SERIAL.print("[HTTP] begin...\n");
// configure traged server and url
http.begin("192.168.1.12", 80, "/test.html");
// configure server and url
http.begin("http://192.168.1.12/test.html");
//http.begin("192.168.1.12", 80, "/test.html");
USE_SERIAL.print("[HTTP] GET...\n");
// start connection and send HTTP header
int httpCode = http.GET();
if(httpCode) {
// HTTP header has been send and Server response header has been handled
USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
// file found at server
if(httpCode == 200) {
if(httpCode == HTTP_CODE_OK) {
// get lenght of document (is -1 when Server sends no Content-Length header)
int len = http.getSize();
@ -89,8 +90,10 @@ void loop() {
}
} else {
USE_SERIAL.print("[HTTP] GET... failed, no connection or no HTTP server\n");
USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
}
delay(10000);

View File

@ -26,9 +26,11 @@
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <StreamString.h>
#include <base64.h>
#include "ESP8266HTTPClient.h"
/**
* constractor
*/
@ -100,27 +102,34 @@ void HTTPClient::begin(String url, String httpsFingerprint) {
String protocol;
// check for : (http: or https:
int index = url.indexOf(':');
int index2;
//int index2;
bool hasPort = false;
if(index) {
protocol = url.substring(0, index);
url.remove(0, (index + 3)); // remove http:// or https://
index = url.indexOf(':');
index2 = url.indexOf('/');
index = url.indexOf('/');
String host = url.substring(0, index);
url.remove(0, index); // remove host part
if(index >= 0 && ((index2 >= 0 && index < index2) || index2 == 0)) { // do we have a port?
_host = url.substring(0, index); // hostname
url.remove(0, (index + 1)); // remove hostname + :
// get Authorization
index = host.indexOf('@');
if(index >= 0) {
// auth info
String auth = host.substring(0, index);
host.remove(0, index +1); // remove auth part including @
_base64Authorization = base64::encode(auth);
}
index = url.indexOf('/');
_port = url.substring(0, index).toInt(); // get port
url.remove(0, index); // remove port
// get port
index = host.indexOf(':');
if(index >= 0) {
_host = host.substring(0, index); // hostname
host.remove(0, (index + 1)); // remove hostname + :
_port = host.toInt(); // get port
hasPort = true;
} else {
index = index2;
_host = url.substring(0, index);
url.remove(0, index); // remove hostname
_host = host;
}
_url = url;
@ -139,6 +148,7 @@ void HTTPClient::begin(String url, String httpsFingerprint) {
DEBUG_HTTPCLIENT("[HTTP-Client][begin] protocol: %s unknown?!\n", protocol.c_str());
return;
}
}
DEBUG_HTTPCLIENT("[HTTP-Client][begin] host: %s port: %d url: %s https: %d httpsFingerprint: %s\n", _host.c_str(), _port, _url.c_str(), _https, _httpsFingerprint.c_str());
@ -219,6 +229,30 @@ void HTTPClient::setUserAgent(const char * userAgent) {
_userAgent = userAgent;
}
/**
* set the Authorizatio for the http request
* @param user const char *
* @param password const char *
*/
void HTTPClient::setAuthorization(const char * user, const char * password) {
if(user && password) {
String auth = user;
auth += ":";
auth += password;
_base64Authorization = base64::encode(auth);
}
}
/**
* set the Authorizatio for the http request
* @param auth const char * base64
*/
void HTTPClient::setAuthorization(const char * auth) {
if(auth) {
_base64Authorization = auth;
}
}
/**
* send a GET request
* @return http code
@ -454,6 +488,33 @@ String HTTPClient::getString(void) {
return sstring;
}
/**
* converts error code to String
* @param error int
* @return String
*/
String HTTPClient::errorToString(int error) {
switch(error) {
case HTTPC_ERROR_CONNECTION_REFUSED:
return String("connection refused");
case HTTPC_ERROR_SEND_HEADER_FAILED:
return String("send header failed");
case HTTPC_ERROR_SEND_PAYLOAD_FAILED:
return String("send payload failed");
case HTTPC_ERROR_NOT_CONNECTED:
return String("not connected");
case HTTPC_ERROR_CONNECTION_LOST:
return String("connection lost");
case HTTPC_ERROR_NO_STREAM:
return String("no stream");
case HTTPC_ERROR_NO_HTTP_SERVER:
return String("no HTTP server");
default:
return String();
}
}
/**
* adds Header to the request
* @param name
@ -463,7 +524,7 @@ String HTTPClient::getString(void) {
void HTTPClient::addHeader(const String& name, const String& value, bool first) {
// not allow set of Header handled by code
if(!name.equalsIgnoreCase("Connection") && !name.equalsIgnoreCase("User-Agent") && !name.equalsIgnoreCase("Host")) {
if(!name.equalsIgnoreCase("Connection") && !name.equalsIgnoreCase("User-Agent") && !name.equalsIgnoreCase("Host") && !(_base64Authorization.length() && name.equalsIgnoreCase("Authorization"))) {
String headerLine = name;
headerLine += ": ";
headerLine += value;
@ -595,7 +656,13 @@ bool HTTPClient::sendHeader(const char * type) {
} else {
header += "close";
}
header += "\r\n" + _Headers + "\r\n";
header += "\r\n";
if(_base64Authorization.length()) {
header += "Authorization: Basic " + _base64Authorization + "\r\n";
}
header += _Headers + "\r\n";
return (_tcp->write(header.c_str(), header.length()) == header.length());
}

View File

@ -42,6 +42,67 @@
#define HTTPC_ERROR_NO_STREAM (-6)
#define HTTPC_ERROR_NO_HTTP_SERVER (-7)
/// HTTP codes see RFC7231
typedef enum {
HTTP_CODE_CONTINUE = 100,
HTTP_CODE_SWITCHING_PROTOCOLS = 101,
HTTP_CODE_PROCESSING = 102,
HTTP_CODE_OK = 200,
HTTP_CODE_CREATED = 201,
HTTP_CODE_ACCEPTED = 202,
HTTP_CODE_NON_AUTHORITATIVE_INFORMATION = 203,
HTTP_CODE_NO_CONTENT = 204,
HTTP_CODE_RESET_CONTENT = 205,
HTTP_CODE_PARTIAL_CONTENT = 206,
HTTP_CODE_MULTI_STATUS = 207,
HTTP_CODE_ALREADY_REPORTED = 208,
HTTP_CODE_IM_USED = 226,
HTTP_CODE_MULTIPLE_CHOICES = 300,
HTTP_CODE_MOVED_PERMANENTLY = 301,
HTTP_CODE_FOUND = 302,
HTTP_CODE_SEE_OTHER = 303,
HTTP_CODE_NOT_MODIFIED = 304,
HTTP_CODE_USE_PROXY = 305,
HTTP_CODE_TEMPORARY_REDIRECT = 307,
HTTP_CODE_PERMANENT_REDIRECT = 308,
HTTP_CODE_BAD_REQUEST = 400,
HTTP_CODE_UNAUTHORIZED = 401,
HTTP_CODE_PAYMENT_REQUIRED = 402,
HTTP_CODE_FORBIDDEN = 403,
HTTP_CODE_NOT_FOUND = 404,
HTTP_CODE_METHOD_NOT_ALLOWED = 405,
HTTP_CODE_NOT_ACCEPTABLE = 406,
HTTP_CODE_PROXY_AUTHENTICATION_REQUIRED = 407,
HTTP_CODE_REQUEST_TIMEOUT = 408,
HTTP_CODE_CONFLICT = 409,
HTTP_CODE_GONE = 410,
HTTP_CODE_LENGTH_REQUIRED = 411,
HTTP_CODE_PRECONDITION_FAILED = 412,
HTTP_CODE_PAYLOAD_TOO_LARGE = 413,
HTTP_CODE_URI_TOO_LONG = 414,
HTTP_CODE_UNSUPPORTED_MEDIA_TYPE = 415,
HTTP_CODE_RANGE_NOT_SATISFIABLE = 416,
HTTP_CODE_EXPECTATION_FAILED = 417,
HTTP_CODE_MISDIRECTED_REQUEST = 421,
HTTP_CODE_UNPROCESSABLE_ENTITY = 422,
HTTP_CODE_LOCKED = 423,
HTTP_CODE_FAILED_DEPENDENCY = 424,
HTTP_CODE_UPGRADE_REQUIRED = 426,
HTTP_CODE_PRECONDITION_REQUIRED = 428,
HTTP_CODE_TOO_MANY_REQUESTS = 429,
HTTP_CODE_REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
HTTP_CODE_INTERNAL_SERVER_ERROR = 500,
HTTP_CODE_NOT_IMPLEMENTED = 501,
HTTP_CODE_BAD_GATEWAY = 502,
HTTP_CODE_SERVICE_UNAVAILABLE = 503,
HTTP_CODE_GATEWAY_TIMEOUT = 504,
HTTP_CODE_HTTP_VERSION_NOT_SUPPORTED = 505,
HTTP_CODE_VARIANT_ALSO_NEGOTIATES = 506,
HTTP_CODE_INSUFFICIENT_STORAGE = 507,
HTTP_CODE_LOOP_DETECTED = 508,
HTTP_CODE_NOT_EXTENDED = 510,
HTTP_CODE_NETWORK_AUTHENTICATION_REQUIRED = 511
} t_http_codes;
class HTTPClient {
public:
@ -60,6 +121,8 @@ class HTTPClient {
void setReuse(bool reuse); /// keep-alive
void setUserAgent(const char * userAgent);
void setAuthorization(const char * user, const char * password);
void setAuthorization(const char * auth);
/// request handling
int GET();
@ -86,6 +149,8 @@ class HTTPClient {
int writeToStream(Stream * stream);
String getString(void);
String errorToString(int error);
protected:
struct RequestArgument {
@ -109,6 +174,7 @@ class HTTPClient {
String _Headers;
String _userAgent;
String _base64Authorization;
/// Response handling
RequestArgument* _currentHeaders;

View File

@ -71,6 +71,7 @@ ESP8266WebServer::~ESP8266WebServer() {
delete handler;
handler = next;
}
close();
}
void ESP8266WebServer::begin() {
@ -173,6 +174,14 @@ void ESP8266WebServer::handleClient() {
_handleRequest();
}
void ESP8266WebServer::close() {
_server.close();
}
void ESP8266WebServer::stop() {
close();
}
void ESP8266WebServer::sendHeader(const String& name, const String& value, bool first) {
String headerLine = name;
headerLine += ": ";

View File

@ -66,6 +66,9 @@ public:
void begin();
void handleClient();
void close();
void stop();
bool authenticate(const char * username, const char * password);
void requestAuthentication();

View File

@ -4,7 +4,7 @@
* This example demonstrates how to use
* WiFiClientSecure class to access HTTPS API.
* We fetch and display the status of
* esp8266/Arduino project continous integration
* esp8266/Arduino project continuous integration
* build.
*
* Created by Ivan Grokhotkov, 2015.
@ -54,7 +54,7 @@ void setup() {
Serial.println("certificate doesn't match");
}
String url = "/repos/esp8266/Arduino/commits/esp8266/status";
String url = "/repos/esp8266/Arduino/commits/master/status";
Serial.print("requesting URL: ");
Serial.println(url);

View File

@ -71,7 +71,14 @@ void loop() {
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
delay(10);
int timeout = millis() + 5000;
while (client.available() == 0) {
if (timeout - millis() < 0) {
Serial.println(">>> Client Timeout !");
client.stop();
return;
}
}
// Read all the lines of the reply from server and print them to Serial
while(client.available()){

View File

@ -0,0 +1,68 @@
/*
* This sketch sends a message to a TCP server
*
*/
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
ESP8266WiFiMulti WiFiMulti;
void setup() {
Serial.begin(115200);
delay(10);
// We start by connecting to a WiFi network
WiFiMulti.addAP("SSID", "passpasspass");
Serial.println();
Serial.println();
Serial.print("Wait for WiFi... ");
while(WiFiMulti.run() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
delay(500);
}
void loop() {
const uint16_t port = 80;
const char * host = "192.168.1.1"; // ip or dns
Serial.print("connecting to ");
Serial.println(host);
// Use WiFiClient class to create TCP connections
WiFiClient client;
if (!client.connect(host, port)) {
Serial.println("connection failed");
Serial.println("wait 5 sec...");
delay(5000);
return;
}
// This will send the request to the server
client.print("Send this data to server");
//read back one line from server
String line = client.readStringUntil('\r');
client.println(line);
Serial.println("closing connection");
client.stop();
Serial.println("wait 5 sec...");
delay(5000);
}

View File

@ -29,7 +29,6 @@ extern "C"
}
#include <errno.h>
#include "debug.h"
#include "cbuf.h"
#include "ESP8266WiFi.h"
#include "WiFiClientSecure.h"
#include "WiFiClient.h"
@ -50,6 +49,17 @@ extern "C"
#define SSL_DEBUG_OPTS 0
#endif
uint8_t* default_private_key = 0;
uint32_t default_private_key_len = 0;
static bool default_private_key_dynamic = false;
static int s_pk_refcnt = 0;
uint8_t* default_certificate = 0;
uint32_t default_certificate_len = 0;
static bool default_certificate_dynamic = false;
static void clear_private_key();
static void clear_certificate();
class SSLContext {
public:
@ -172,12 +182,17 @@ int SSLContext::_ssl_ctx_refcnt = 0;
WiFiClientSecure::WiFiClientSecure() {
++s_pk_refcnt;
}
WiFiClientSecure::~WiFiClientSecure() {
if (_ssl) {
_ssl->unref();
}
if (--s_pk_refcnt == 0) {
clear_private_key();
clear_certificate();
}
}
WiFiClientSecure::WiFiClientSecure(const WiFiClientSecure& other)
@ -337,6 +352,66 @@ bool WiFiClientSecure::verify(const char* fp, const char* url) {
return true;
}
void WiFiClientSecure::setCertificate(const uint8_t* cert_data, size_t size) {
clear_certificate();
default_certificate = (uint8_t*) cert_data;
default_certificate_len = size;
}
void WiFiClientSecure::setPrivateKey(const uint8_t* pk, size_t size) {
clear_private_key();
default_private_key = (uint8_t*) pk;
default_private_key_len = size;
}
bool WiFiClientSecure::loadCertificate(Stream& stream, size_t size) {
clear_certificate();
default_certificate = new uint8_t[size];
if (!default_certificate) {
return false;
}
if (stream.readBytes(default_certificate, size) != size) {
delete[] default_certificate;
return false;
}
default_certificate_dynamic = true;
default_certificate_len = size;
return true;
}
bool WiFiClientSecure::loadPrivateKey(Stream& stream, size_t size) {
clear_private_key();
default_private_key = new uint8_t[size];
if (!default_private_key) {
return false;
}
if (stream.readBytes(default_private_key, size) != size) {
delete[] default_private_key;
return false;
}
default_private_key_dynamic = true;
default_private_key_len = size;
return true;
}
static void clear_private_key() {
if (default_private_key && default_private_key_dynamic) {
delete[] default_private_key;
default_private_key_dynamic = false;
}
default_private_key = 0;
default_private_key_len = 0;
}
static void clear_certificate() {
if (default_certificate && default_certificate_dynamic) {
delete[] default_certificate;
default_certificate_dynamic = false;
}
default_certificate = 0;
default_certificate_len = 0;
}
extern "C" int ax_port_read(int fd, uint8_t* buffer, size_t count) {
ClientContext* _client = reinterpret_cast<ClientContext*>(fd);
if (_client->state() != ESTABLISHED && !_client->getSize()) {

View File

@ -48,6 +48,22 @@ public:
int peek() override;
void stop() override;
void setCertificate(const uint8_t* cert_data, size_t size);
void setPrivateKey(const uint8_t* pk, size_t size);
bool loadCertificate(Stream& stream, size_t size);
bool loadPrivateKey(Stream& stream, size_t size);
template<typename TFile>
bool loadCertificate(TFile& file) {
return loadCertificate(file, file.size());
}
template<typename TFile>
bool loadPrivateKey(TFile& file) {
return loadPrivateKey(file, file.size());
}
protected:
int _connectSSL();

View File

@ -121,6 +121,16 @@ uint8_t WiFiServer::status() {
return _pcb->state;
}
void WiFiServer::close() {
if (!_pcb) {
return;
}
tcp_close(_pcb);
}
void WiFiServer::stop() {
close();
}
size_t WiFiServer::write(uint8_t b) {
return write(&b, 1);

View File

@ -54,6 +54,8 @@ public:
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *buf, size_t size);
uint8_t status();
void close();
void stop();
using Print::write;

View File

@ -1,9 +1,9 @@
/*
/*
UdpContext.h - UDP connection handling on top of lwIP
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
@ -206,10 +206,10 @@ public:
size_t max_size = _rx_buf->len - _rx_buf_offset;
size = (size < max_size) ? size : max_size;
DEBUGV(":urd %d, %d, %d\r\n", size, _rx_buf->len, _rx_buf_offset);
os_memcpy(dst, reinterpret_cast<char*>(_rx_buf->payload) + _rx_buf_offset, size);
memcpy(dst, reinterpret_cast<char*>(_rx_buf->payload) + _rx_buf_offset, size);
_consume(size);
return size;
}
@ -236,7 +236,7 @@ public:
{
_reserve(_tx_buf_offset + size);
}
size_t left_to_copy = size;
while(left_to_copy)
{
@ -249,7 +249,7 @@ public:
continue;
}
size_t will_copy = (left_to_copy < free_cur) ? left_to_copy : free_cur;
os_memcpy(reinterpret_cast<char*>(_tx_buf_cur->payload) + used_cur, data, will_copy);
memcpy(reinterpret_cast<char*>(_tx_buf_cur->payload) + used_cur, data, will_copy);
_tx_buf_offset += will_copy;
left_to_copy -= will_copy;
data += will_copy;
@ -259,18 +259,20 @@ public:
void send(ip_addr_t* addr = 0, uint16_t port = 0)
{
size_t orig_size = _tx_buf_head->tot_len;
size_t data_size = _tx_buf_offset;
size_t size_adjustment = orig_size - data_size;
for (pbuf* p = _tx_buf_head; p; p = p->next)
{
p->tot_len -= size_adjustment;
if (!p->next)
{
p->len = p->tot_len;
}
pbuf* tx_copy = pbuf_alloc(PBUF_TRANSPORT, data_size, PBUF_RAM);
uint8_t* dst = reinterpret_cast<uint8_t*>(tx_copy->payload);
for (pbuf* p = _tx_buf_head; p; p = p->next) {
size_t will_copy = (data_size < p->len) ? data_size : p->len;
memcpy(dst, p->payload, will_copy);
dst += will_copy;
data_size -= will_copy;
}
pbuf_free(_tx_buf_head);
_tx_buf_head = 0;
_tx_buf_cur = 0;
_tx_buf_offset = 0;
if (!addr) {
addr = &_dest_addr;
@ -282,30 +284,16 @@ public:
_pcb->ttl = _multicast_ttl;
}
udp_sendto(_pcb, _tx_buf_head, addr, port);
udp_sendto(_pcb, tx_copy, addr, port);
_pcb->ttl = old_ttl;
for (pbuf* p = _tx_buf_head; p; p = p->next)
{
p->tot_len += size_adjustment;
if (!p->next)
{
p->len = p->tot_len;
}
}
pbuf_free(_tx_buf_head);
_tx_buf_head = 0;
_tx_buf_cur = 0;
_tx_buf_offset = 0;
pbuf_free(tx_copy);
}
private:
void _reserve(size_t size)
{
const size_t pbuf_unit_size = 512;
const size_t pbuf_unit_size = 128;
if (!_tx_buf_head)
{
_tx_buf_head = pbuf_alloc(PBUF_TRANSPORT, pbuf_unit_size, PBUF_RAM);
@ -357,7 +345,7 @@ private:
}
static void _s_recv(void *arg,
static void _s_recv(void *arg,
udp_pcb *upcb, pbuf *p,
ip_addr_t *addr, u16_t port)
{

View File

@ -0,0 +1,65 @@
/**
* httpUpdateSPIFFS.ino
*
* Created on: 05.12.2015
*
*/
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266httpUpdate.h>
#define USE_SERIAL Serial
ESP8266WiFiMulti WiFiMulti;
void setup() {
USE_SERIAL.begin(115200);
// USE_SERIAL.setDebugOutput(true);
USE_SERIAL.println();
USE_SERIAL.println();
USE_SERIAL.println();
for(uint8_t t = 4; t > 0; t--) {
USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
USE_SERIAL.flush();
delay(1000);
}
WiFiMulti.addAP("SSID", "PASSWORD");
}
void loop() {
// wait for WiFi connection
if((WiFiMulti.run() == WL_CONNECTED)) {
USE_SERIAL.println("Update SPIFFS...");
t_httpUpdate_return ret = ESPhttpUpdate.updateSpiffs("https://server/spiffs.bin");
if(ret == HTTP_UPDATE_OK) {
USE_SERIAL.println("Update sketch...");
ret = ESPhttpUpdate.update("https://server/file.bin");
switch(ret) {
case HTTP_UPDATE_FAILED:
USE_SERIAL.println("HTTP_UPDATE_FAILD");
break;
case HTTP_UPDATE_NO_UPDATES:
USE_SERIAL.println("HTTP_UPDATE_NO_UPDATES");
break;
case HTTP_UPDATE_OK:
USE_SERIAL.println("HTTP_UPDATE_OK");
break;
}
}
}
}

View File

@ -23,9 +23,11 @@
*
*/
#include "ESP8266httpUpdate.h"
#include <StreamString.h>
extern "C" uint32_t _SPIFFS_start;
extern "C" uint32_t _SPIFFS_end;
ESP8266HTTPUpdate::ESP8266HTTPUpdate(void) {
}
@ -46,6 +48,19 @@ t_httpUpdate_return ESP8266HTTPUpdate::update(const char * url, const char * cur
return handleUpdate(&http, current_version);
}
/**
*
* @param url const char *
* @param current_version const char *
* @param httpsFingerprint const char *
* @return t_httpUpdate_return
*/
t_httpUpdate_return ESP8266HTTPUpdate::updateSpiffs(const char * url, const char * current_version, const char * httpsFingerprint) {
HTTPClient http;
http.begin(url, httpsFingerprint);
return handleUpdate(&http, current_version, false, true);
}
/**
*
* @param host const char *
@ -73,7 +88,7 @@ t_httpUpdate_return ESP8266HTTPUpdate::update(String host, uint16_t port, String
* @param current_version const char *
* @return t_httpUpdate_return
*/
t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const char * current_version) {
t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const char * current_version, bool reboot, bool spiffs) {
t_httpUpdate_return ret = HTTP_UPDATE_FAILED;
@ -85,6 +100,12 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha
http->addHeader("x-ESP8266-chip-size", String(ESP.getFlashChipRealSize()));
http->addHeader("x-ESP8266-sdk-version", ESP.getSdkVersion());
if(spiffs) {
http->addHeader("x-ESP8266-mode", "spiffs");
} else {
http->addHeader("x-ESP8266-mode", "sketch");
}
if(current_version && current_version[0] != 0x00) {
http->addHeader("x-ESP8266-version", current_version);
}
@ -99,6 +120,12 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha
int code = http->GET();
int len = http->getSize();
if(code <= 0) {
DEBUG_HTTP_UPDATE("[httpUpdate] HTTP error: %s\n", http->errorToString(code).c_str());
http->end();
return HTTP_UPDATE_FAILED;
}
DEBUG_HTTP_UPDATE("[httpUpdate] Header read fin.\n");
DEBUG_HTTP_UPDATE("[httpUpdate] Server header:\n");
DEBUG_HTTP_UPDATE("[httpUpdate] - code: %d\n", code);
@ -117,11 +144,24 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha
}
switch(code) {
case 200: ///< OK (Start Update)
case HTTP_CODE_OK: ///< OK (Start Update)
if(len > 0) {
if(len > ESP.getFreeSketchSpace()) {
bool startUpdate = true;
if(spiffs) {
size_t spiffsSize = ((size_t) &_SPIFFS_end - (size_t) &_SPIFFS_start);
if(len > (int) spiffsSize) {
DEBUG_HTTP_UPDATE("[httpUpdate] spiffsSize to low (%d) needed: %d\n", spiffsSize, len);
startUpdate = false;
}
} else {
if(len > (int) ESP.getFreeSketchSpace()) {
DEBUG_HTTP_UPDATE("[httpUpdate] FreeSketchSpace to low (%d) needed: %d\n", ESP.getFreeSketchSpace(), len);
startUpdate = false;
}
}
if(!startUpdate) {
ret = HTTP_UPDATE_FAILED;
DEBUG_HTTP_UPDATE("[httpUpdate] FreeSketchSpace to low (%d) needed: %d\n", ESP.getFreeSketchSpace(), len);
} else {
WiFiClient * tcp = http->getStreamPtr();
@ -131,11 +171,25 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha
delay(100);
if(runUpdate(*tcp, len, http->header("x-MD5"))) {
int command;
if(spiffs) {
command = U_SPIFFS;
DEBUG_HTTP_UPDATE("[httpUpdate] runUpdate spiffs...\n");
} else {
command = U_FLASH;
DEBUG_HTTP_UPDATE("[httpUpdate] runUpdate flash...\n");
}
if(runUpdate(*tcp, len, http->header("x-MD5"), command)) {
ret = HTTP_UPDATE_OK;
DEBUG_HTTP_UPDATE("[httpUpdate] Update ok\n");
http->end();
ESP.restart();
if(reboot) {
ESP.restart();
}
} else {
ret = HTTP_UPDATE_FAILED;
DEBUG_HTTP_UPDATE("[httpUpdate] Update failed\n");
@ -146,19 +200,18 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha
DEBUG_HTTP_UPDATE("[httpUpdate] Content-Length is 0 or not set by Server?!\n");
}
break;
case 304:
case HTTP_CODE_NOT_MODIFIED:
///< Not Modified (No updates)
ret = HTTP_UPDATE_NO_UPDATES;
break;
case 403:
///< Forbidden
// todo handle login
default:
ret = HTTP_UPDATE_FAILED;
DEBUG_HTTP_UPDATE("[httpUpdate] Code is (%d)\n", code);
DEBUG_HTTP_UPDATE("[httpUpdate] HTTP Code is (%d)\n", code);
//http->writeToStream(&Serial1);
break;
}
http->end();
return ret;
@ -171,10 +224,14 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha
* @param md5 String
* @return true if Update ok
*/
bool ESP8266HTTPUpdate::runUpdate(Stream& in, uint32_t size, String md5) {
bool ESP8266HTTPUpdate::runUpdate(Stream& in, uint32_t size, String md5, int command) {
if(!Update.begin(size)) {
DEBUG_HTTP_UPDATE("[httpUpdate] Update.begin failed!\n");
StreamString error;
if(!Update.begin(size, command)) {
Update.printError(error);
error.trim(); // remove line ending
DEBUG_HTTP_UPDATE("[httpUpdate] Update.begin failed! (%s)\n", error.c_str());
return false;
}
@ -183,12 +240,16 @@ bool ESP8266HTTPUpdate::runUpdate(Stream& in, uint32_t size, String md5) {
}
if(Update.writeStream(in) != size) {
DEBUG_HTTP_UPDATE("[httpUpdate] Update.writeStream failed!\n");
Update.printError(error);
error.trim(); // remove line ending
DEBUG_HTTP_UPDATE("[httpUpdate] Update.writeStream failed! (%s)\n", error.c_str());
return false;
}
if(!Update.end()) {
DEBUG_HTTP_UPDATE("[httpUpdate] Update.end failed!\n");
Update.printError(error);
error.trim(); // remove line ending
DEBUG_HTTP_UPDATE("[httpUpdate] Update.end failed! (%s)\n", error.c_str());
return false;
}

View File

@ -53,9 +53,11 @@ class ESP8266HTTPUpdate {
t_httpUpdate_return update(const char * host, uint16_t port, const char * url = "/", const char * current_version = "", bool https = false, const char * httpsFingerprint = "");
t_httpUpdate_return update(String host, uint16_t port, String url = "/", String current_version = "", bool https = false, String httpsFingerprint = "");
t_httpUpdate_return updateSpiffs(const char * url, const char * current_version = "", const char * httpsFingerprint = "");
protected:
t_httpUpdate_return handleUpdate(HTTPClient * http, const char * current_version);
bool runUpdate(Stream& in, uint32_t size, String md5);
t_httpUpdate_return handleUpdate(HTTPClient * http, const char * current_version, bool reboot = true, bool spiffs = false);
bool runUpdate(Stream& in, uint32_t size, String md5, int command = U_FLASH);
};
extern ESP8266HTTPUpdate ESPhttpUpdate;

View File

@ -43,11 +43,14 @@
{
"name": "SweetPea ESP-210"
},
{
{
"name": "WeMos D1"
},
{
{
"name": "WeMos D1 mini"
},
{
"name": "ESPino"
}
],
"toolsDependencies": [

View File

@ -139,7 +139,15 @@ void setup() {
fail("some files left after format");
}
}
{
File tmp = SPIFFS.open("/tmp.txt", "w");
}
{
File tmp = SPIFFS.open("/tmp.txt", "w");
if (!tmp) {
fail("failed to re-open empty file");
}
}
Serial.println("success");
}

Binary file not shown.

View File

@ -0,0 +1,73 @@
/*
pins_arduino.h - Pin definition functions for Arduino
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2007 David A. Mellis
Modified for ESP8266 platform by Ivan Grokhotkov, 2014-2015.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
$Id: wiring.h 249 2007-02-03 16:52:51Z mellis $
*/
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#define EXTERNAL_NUM_INTERRUPTS 16
#define NUM_DIGITAL_PINS 17
#define NUM_ANALOG_INPUTS 1
#define analogInputToDigitalPin(p) ((p > 0)?NOT_A_PIN:0)
#define digitalPinToInterrupt(p) (((p) < EXTERNAL_NUM_INTERRUPTS)?p:NOT_A_PIN)
#define digitalPinHasPWM(p) (((p) < NUM_DIGITAL_PINS)?p:NOT_A_PIN)
static const uint8_t SDA = 4;
static const uint8_t SCL = 5;
static const uint8_t SS = 15;
static const uint8_t MOSI = 13;
static const uint8_t MISO = 12;
static const uint8_t SCK = 14;
static const uint8_t BUILTIN_LED = 2;
static const uint8_t BUILTIN_LEDR = 2;
static const uint8_t BUILTIN_LEDG = 4;
static const uint8_t BUILTIN_LEDB = 5;
static const uint8_t BUILTIN_BUTTON = 0;
static const uint8_t A0 = 17;
// These serial port names are intended to allow libraries and architecture-neutral
// sketches to automatically default to the correct port name for a particular type
// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN,
// the first hardware serial port whose RX/TX pins are not dedicated to another use.
//
// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor
//
// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial
//
// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library
//
// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins.
//
// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX
// pins are NOT connected to anything by default.
#define SERIAL_PORT_MONITOR Serial
#define SERIAL_PORT_USBVIRTUAL Serial
#define SERIAL_PORT_HARDWARE Serial
#define SERIAL_PORT_HARDWARE_OPEN Serial
#endif /* Pins_Arduino_h */